// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright 2021 ASPEED Technology Inc.
 */
#include <config.h>
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <asm/types.h>
#include <asm/io.h>
#include <dm/device.h>
#include <dm/fdtaddr.h>
#include <linux/delay.h>
#include <u-boot/rsa-mod-exp.h>

/* ACRY register offsets */
#define ACRY_CTRL1		0x00
#define   ACRY_CTRL1_RSA_DMA		BIT(1)
#define   ACRY_CTRL1_RSA_START		BIT(0)
#define ACRY_CTRL2		0x44
#define ACRY_CTRL3		0x48
#define   ACRY_CTRL3_SRAM_AHB_ACCESS	BIT(8)
#define   ACRY_CTRL3_ECC_RSA_MODE_MASK	GENMASK(5, 4)
#define   ACRY_CTRL3_ECC_RSA_MODE_SHIFT	4
#define ACRY_DMA_DRAM_SADDR	0x4c
#define ACRY_DMA_DMEM_TADDR	0x50
#define   ACRY_DMA_DMEM_TADDR_LEN_MASK	GENMASK(15, 0)
#define   ACRY_DMA_DMEM_TADDR_LEN_SHIFT	0
#define ACRY_RSA_PARAM		0x58
#define   ACRY_RSA_PARAM_EXP_MASK	GENMASK(31, 16)
#define   ACRY_RSA_PARAM_EXP_SHIFT	16
#define   ACRY_RSA_PARAM_MOD_MASK	GENMASK(15, 0)
#define   ACRY_RSA_PARAM_MOD_SHIFT	0
#define ACRY_RSA_INT_EN		0x3f8
#define   ACRY_RSA_INT_EN_RSA_READY	BIT(2)
#define   ACRY_RSA_INT_EN_RSA_CMPLT	BIT(1)
#define ACRY_RSA_INT_STS	0x3fc
#define   ACRY_RSA_INT_STS_RSA_READY	BIT(2)
#define   ACRY_RSA_INT_STS_RSA_CMPLT	BIT(1)

/* misc. constant */
#define ACRY_ECC_MODE	2
#define ACRY_RSA_MODE	3
#define ACRY_CTX_BUFSZ	0x600

struct aspeed_acry {
	phys_addr_t base;
	phys_addr_t sram_base; /* internal sram */
	struct clk clk;
};

static int aspeed_acry_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
			       struct key_prop *prop, uint8_t *out)
{
	int i, j;
	u8 *ctx;
	u8 *ptr;
	u32 reg;
	struct aspeed_acry *acry = dev_get_priv(dev);

	ctx = memalign(16, ACRY_CTX_BUFSZ);
	if (!ctx)
		return -ENOMEM;

	memset(ctx, 0, ACRY_CTX_BUFSZ);

	ptr = (u8 *)prop->public_exponent;
	for (i = prop->exp_len - 1, j = 0; i >= 0; --i) {
		ctx[j] = ptr[i];
		j++;
		j = (j % 16) ? j : j + 32;
	}

	ptr = (u8 *)prop->modulus;
	for (i = (prop->num_bits >> 3) - 1, j = 0; i >= 0; --i) {
		ctx[j + 16] = ptr[i];
		j++;
		j = (j % 16) ? j : j + 32;
	}

	ptr = (u8 *)sig;
	for (i = sig_len - 1, j = 0; i >= 0; --i) {
		ctx[j + 32] = ptr[i];
		j++;
		j = (j % 16) ? j : j + 32;
	}

	writel((u32)ctx, acry->base + ACRY_DMA_DRAM_SADDR);

	reg = (((prop->exp_len << 3) << ACRY_RSA_PARAM_EXP_SHIFT) & ACRY_RSA_PARAM_EXP_MASK) |
		  ((prop->num_bits << ACRY_RSA_PARAM_MOD_SHIFT) & ACRY_RSA_PARAM_MOD_MASK);
	writel(reg, acry->base + ACRY_RSA_PARAM);

	reg = (ACRY_CTX_BUFSZ << ACRY_DMA_DMEM_TADDR_LEN_SHIFT) & ACRY_DMA_DMEM_TADDR_LEN_MASK;
	writel(reg, acry->base + ACRY_DMA_DMEM_TADDR);

	reg = (ACRY_RSA_MODE << ACRY_CTRL3_ECC_RSA_MODE_SHIFT) & ACRY_CTRL3_ECC_RSA_MODE_MASK;
	writel(reg, acry->base + ACRY_CTRL3);

	writel(ACRY_CTRL1_RSA_DMA | ACRY_CTRL1_RSA_START, acry->base + ACRY_CTRL1);

	/* polling RSA status */
	while (1) {
		reg = readl(acry->base + ACRY_RSA_INT_STS);
		if ((reg & ACRY_RSA_INT_STS_RSA_READY) && (reg & ACRY_RSA_INT_STS_RSA_CMPLT)) {
			writel(reg, ACRY_RSA_INT_STS);
			break;
		}
		udelay(20);
	}

	/* grant SRAM access permission to CPU */
	writel(0x0, acry->base + ACRY_CTRL1);
	writel(ACRY_CTRL3_SRAM_AHB_ACCESS, acry->base + ACRY_CTRL3);
	udelay(20);

	for (i = (prop->num_bits / 8) - 1, j = 0; i >= 0; --i) {
		out[i] = readb(acry->sram_base + (j + 32));
		j++;
		j = (j % 16) ? j : j + 32;
	}

	/* return SRAM access permission to ACRY */
	writel(0, acry->base + ACRY_CTRL3);

	free(ctx);

	return 0;
}

static int aspeed_acry_probe(struct udevice *dev)
{
	struct aspeed_acry *acry = dev_get_priv(dev);
	int ret;

	ret = clk_get_by_index(dev, 0, &acry->clk);
	if (ret < 0) {
		debug("Can't get clock for %s: %d\n", dev->name, ret);
		return ret;
	}

	ret = clk_enable(&acry->clk);
	if (ret) {
		debug("Failed to enable acry clock (%d)\n", ret);
		return ret;
	}

	acry->base = devfdt_get_addr_index(dev, 0);
	if (acry->base == FDT_ADDR_T_NONE) {
		debug("Failed to get acry base\n");
		return acry->base;
	}

	acry->sram_base = devfdt_get_addr_index(dev, 1);
	if (acry->sram_base == FDT_ADDR_T_NONE) {
		debug("Failed to get acry SRAM base\n");
		return acry->sram_base;
	}

	return ret;
}

static int aspeed_acry_remove(struct udevice *dev)
{
	struct aspeed_acry *acry = dev_get_priv(dev);

	clk_disable(&acry->clk);

	return 0;
}

static const struct mod_exp_ops aspeed_acry_ops = {
	.mod_exp = aspeed_acry_mod_exp,
};

static const struct udevice_id aspeed_acry_ids[] = {
	{ .compatible = "aspeed,ast2600-acry" },
	{ }
};

U_BOOT_DRIVER(aspeed_acry) = {
	.name = "aspeed_acry",
	.id = UCLASS_MOD_EXP,
	.of_match = aspeed_acry_ids,
	.probe = aspeed_acry_probe,
	.remove = aspeed_acry_remove,
	.priv_auto = sizeof(struct aspeed_acry),
	.ops = &aspeed_acry_ops,
	.flags = DM_FLAG_PRE_RELOC,
};
