u-boot/drivers/crypto/aspeed/aspeed_acry.c
Tom Rini d678a59d2d Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
When bringing in the series 'arm: dts: am62-beagleplay: Fix Beagleplay
Ethernet"' I failed to notice that b4 noticed it was based on next and
so took that as the base commit and merged that part of next to master.

This reverts commit c8ffd1356d, reversing
changes made to 2ee6f3a5f7.

Reported-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Tom Rini <trini@konsulko.com>
2024-05-19 08:16:36 -06:00

191 lines
4.6 KiB
C

// 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->base + 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,
};