Commit 463cd64c authored by Icenowy Zheng's avatar Icenowy Zheng Committed by Bernhard Nortmann
Browse files

fel: workaround H3 SID issue



H3 SID controller has some bug, that makes the initial value at
0x01c14200 wrong.

This commit workarounds this bug by reading them with register access
first.
Signed-off-by: default avatarIcenowy Zheng <icenowy@aosc.xyz>
Reviewed-by: default avatarBernhard Nortmann <bernhard.nortmann@web.de>
parent 5c501c5b
......@@ -276,6 +276,33 @@ void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val)
fel_writel_n(dev, addr, &val, 1);
}
#define EFUSE_PRCTL 0x40
#define EFUSE_RDKEY 0x60
#define EFUSE_OP_LOCK 0xAC
uint32_t aw_fel_efuse_read(feldev_handle *dev, uint32_t offset)
{
soc_info_t *soc_info = dev->soc_info;
uint32_t reg_val;
reg_val = fel_readl(dev, soc_info->sid_base + EFUSE_PRCTL);
reg_val &= ~(((0x1ff) << 16) | 0x3);
reg_val |= (offset << 16);
fel_writel(dev, soc_info->sid_base + EFUSE_PRCTL, reg_val);
reg_val &= ~(((0xff) << 8) | 0x3);
reg_val |= (EFUSE_OP_LOCK << 8) | 0x2;
fel_writel(dev, soc_info->sid_base + EFUSE_PRCTL, reg_val);
while (fel_readl(dev, soc_info->sid_base + EFUSE_PRCTL) & 0x2);
reg_val &= ~(((0x1ff) << 16) | ((0xff) << 8) | 0x3);
fel_writel(dev, soc_info->sid_base + EFUSE_PRCTL, reg_val);
return fel_readl(dev, soc_info->sid_base + EFUSE_RDKEY);
}
void aw_fel_print_sid(feldev_handle *dev)
{
soc_info_t *soc_info = dev->soc_info;
......@@ -283,6 +310,13 @@ void aw_fel_print_sid(feldev_handle *dev)
uint32_t sid_addr = soc_info->sid_base + soc_info->sid_offset;
pr_info("SID key (e-fuses) at 0x%08X\n", sid_addr);
if (soc_info->sid_fix) {
pr_info("SID key needs fix due to silicon bug.\n");
for (uint32_t i = 0; i < 0x10; i+=4) {
aw_fel_efuse_read(dev, i);
}
}
uint32_t key[4];
fel_readl_n(dev, sid_addr, key, 4);
......
......@@ -174,6 +174,7 @@ soc_info_t soc_info_table[] = {
.swap_buffers = a10_a13_a20_sram_swap_buffers,
.sid_base = 0x01C14000,
.sid_offset = 0x200,
.sid_fix = true,
},{
.soc_id = 0x1681, /* Allwinner V3s */
.name = "V3s",
......
......@@ -85,6 +85,7 @@ typedef struct {
uint32_t sid_base; /* base address for SID registers */
uint32_t sid_offset; /* offset for SID_KEY[0-3], "root key" */
uint32_t rvbar_reg; /* MMIO address of RVBARADDR0_L register */
bool sid_fix; /* Use SID workaround (read via register) */
sram_swap_buffers *swap_buffers;
} soc_info_t;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment