[PATCH 0/3] rockchip: efuse: add RK3288/RK3328 support

This extends rockchip efuse driver with support for RK3288 and RK3328.
Patch 1 and 2 was picked from vendor u-boot and updated to work with mainline u-boot.
Patch 3 updates and enable the efuse node in rk3288.dtsi.
This makes it possible to get a persisted ethaddr using:
CONFIG_MISC=y CONFIG_MISC_INIT_R=y CONFIG_ROCKCHIP_EFUSE=y CONFIG_SHA256=y
Best regards, Jonas
Francis Fan (1): rockchip: efuse: add support for RK3288 non-secure efuse
Jonas Karlman (1): rockchip: dts: rk3288: enable efuse node
Joseph Chen (1): rockchip: efuse: add support for RK3328 non-secure efuse
arch/arm/dts/rk3288.dtsi | 3 +- drivers/misc/rockchip-efuse.c | 158 +++++++++++++++++++++++++++++++++- 2 files changed, 155 insertions(+), 6 deletions(-)

From: Francis Fan francis.fan@rock-chips.com
Extend rockchip efuse driver with support for RK3288 non-secure efuse.
Signed-off-by: Francis Fan francis.fan@rock-chips.com Signed-off-by: Cody Xie cody.xie@rock-chips.com Signed-off-by: Jonas Karlman jonas@kwiboo.se --- drivers/misc/rockchip-efuse.c | 91 +++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 46ce6305fe..20423544d9 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -27,6 +27,17 @@ #define RK3399_STROBE BIT(1) #define RK3399_CSB BIT(0)
+#define RK3288_A_SHIFT 6 +#define RK3288_A_MASK 0x3ff +#define RK3288_NFUSES 32 +#define RK3288_BYTES_PER_FUSE 1 +#define RK3288_PGENB BIT(3) +#define RK3288_LOAD BIT(2) +#define RK3288_STROBE BIT(1) +#define RK3288_CSB BIT(0) + +typedef int (*EFUSE_READ)(struct udevice *dev, int offset, void *buf, int size); + struct rockchip_efuse_regs { u32 ctrl; /* 0x00 efuse control register */ u32 dout; /* 0x04 efuse data out register */ @@ -53,7 +64,7 @@ static int dump_efuses(struct cmd_tbl *cmdtp, int flag, */
struct udevice *dev; - u8 fuses[128]; + u8 fuses[128] = {0}; int ret;
/* retrieve the device */ @@ -77,7 +88,7 @@ static int dump_efuses(struct cmd_tbl *cmdtp, int flag, }
U_BOOT_CMD( - rk3399_dump_efuses, 1, 1, dump_efuses, + rockchip_dump_efuses, 1, 1, dump_efuses, "Dump the content of the efuses", "" ); @@ -127,10 +138,59 @@ static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, return 0; }
+static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset, + void *buf, int size) +{ + struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); + struct rockchip_efuse_regs *efuse = + (struct rockchip_efuse_regs *)plat->base; + u8 *buffer = buf; + int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE; + + if (size > (max_size - offset)) + size = max_size - offset; + + /* Switch to read mode */ + writel(RK3288_LOAD | RK3288_PGENB, &efuse->ctrl); + udelay(1); + + while (size--) { + writel(readl(&efuse->ctrl) & + (~(RK3288_A_MASK << RK3288_A_SHIFT)), + &efuse->ctrl); + /* set addr */ + writel(readl(&efuse->ctrl) | + ((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT), + &efuse->ctrl); + udelay(1); + /* strobe low to high */ + writel(readl(&efuse->ctrl) | + RK3288_STROBE, &efuse->ctrl); + ndelay(60); + /* read data */ + *buffer++ = readl(&efuse->dout); + /* reset strobe to low */ + writel(readl(&efuse->ctrl) & + (~RK3288_STROBE), &efuse->ctrl); + udelay(1); + } + + /* Switch to standby mode */ + writel(RK3288_PGENB | RK3288_CSB, &efuse->ctrl); + + return 0; +} + static int rockchip_efuse_read(struct udevice *dev, int offset, void *buf, int size) { - return rockchip_rk3399_efuse_read(dev, offset, buf, size); + EFUSE_READ efuse_read = NULL; + + efuse_read = (EFUSE_READ)dev_get_driver_data(dev); + if (!efuse_read) + return -ENOSYS; + + return (*efuse_read)(dev, offset, buf, size); }
static const struct misc_ops rockchip_efuse_ops = { @@ -146,7 +206,30 @@ static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev) }
static const struct udevice_id rockchip_efuse_ids[] = { - { .compatible = "rockchip,rk3399-efuse" }, + { + .compatible = "rockchip,rk3066a-efuse", + .data = (ulong)&rockchip_rk3288_efuse_read, + }, + { + .compatible = "rockchip,rk3188-efuse", + .data = (ulong)&rockchip_rk3288_efuse_read, + }, + { + .compatible = "rockchip,rk3228-efuse", + .data = (ulong)&rockchip_rk3288_efuse_read, + }, + { + .compatible = "rockchip,rk3288-efuse", + .data = (ulong)&rockchip_rk3288_efuse_read, + }, + { + .compatible = "rockchip,rk3368-efuse", + .data = (ulong)&rockchip_rk3288_efuse_read, + }, + { + .compatible = "rockchip,rk3399-efuse", + .data = (ulong)&rockchip_rk3399_efuse_read, + }, {} };

Hi Jonas,
On Tue, 13 Oct 2020 at 14:21, Jonas Karlman jonas@kwiboo.se wrote:
From: Francis Fan francis.fan@rock-chips.com
Extend rockchip efuse driver with support for RK3288 non-secure efuse.
Signed-off-by: Francis Fan francis.fan@rock-chips.com Signed-off-by: Cody Xie cody.xie@rock-chips.com Signed-off-by: Jonas Karlman jonas@kwiboo.se
drivers/misc/rockchip-efuse.c | 91 +++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 46ce6305fe..20423544d9 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -27,6 +27,17 @@ #define RK3399_STROBE BIT(1) #define RK3399_CSB BIT(0)
+#define RK3288_A_SHIFT 6 +#define RK3288_A_MASK 0x3ff +#define RK3288_NFUSES 32 +#define RK3288_BYTES_PER_FUSE 1 +#define RK3288_PGENB BIT(3) +#define RK3288_LOAD BIT(2) +#define RK3288_STROBE BIT(1) +#define RK3288_CSB BIT(0)
+typedef int (*EFUSE_READ)(struct udevice *dev, int offset, void *buf, int size);
Lower case, also how about efuse_read_func?
struct rockchip_efuse_regs { u32 ctrl; /* 0x00 efuse control register */ u32 dout; /* 0x04 efuse data out register */ @@ -53,7 +64,7 @@ static int dump_efuses(struct cmd_tbl *cmdtp, int flag, */
struct udevice *dev;
u8 fuses[128];
u8 fuses[128] = {0};
comment - what does this actually contain
int ret; /* retrieve the device */
@@ -77,7 +88,7 @@ static int dump_efuses(struct cmd_tbl *cmdtp, int flag, }
U_BOOT_CMD(
rk3399_dump_efuses, 1, 1, dump_efuses,
rockchip_dump_efuses, 1, 1, dump_efuses, "Dump the content of the efuses", ""
); @@ -127,10 +138,59 @@ static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, return 0; }
+static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset,
void *buf, int size)
+{
struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
struct rockchip_efuse_regs *efuse =
(struct rockchip_efuse_regs *)plat->base;
u8 *buffer = buf;
int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE;
if (size > (max_size - offset))
size = max_size - offset;
/* Switch to read mode */
writel(RK3288_LOAD | RK3288_PGENB, &efuse->ctrl);
udelay(1);
while (size--) {
writel(readl(&efuse->ctrl) &
(~(RK3288_A_MASK << RK3288_A_SHIFT)),
&efuse->ctrl);
/* set addr */
writel(readl(&efuse->ctrl) |
((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT),
Can offset++ go at the end of this loop?
&efuse->ctrl);
udelay(1);
/* strobe low to high */
writel(readl(&efuse->ctrl) |
RK3288_STROBE, &efuse->ctrl);
setbits_le32(&efuse->ctrl), RK3288_STROBE)l;
ndelay(60);
/* read data */
*buffer++ = readl(&efuse->dout);
/* reset strobe to low */
writel(readl(&efuse->ctrl) &
(~RK3288_STROBE), &efuse->ctrl);
clrbits_le32
udelay(1);
}
/* Switch to standby mode */
writel(RK3288_PGENB | RK3288_CSB, &efuse->ctrl);
as above
return 0;
+}
static int rockchip_efuse_read(struct udevice *dev, int offset, void *buf, int size) {
return rockchip_rk3399_efuse_read(dev, offset, buf, size);
efuse_read = NULL;
efuse_read = (EFUSE_READ)dev_get_driver_data(dev);
if (!efuse_read)
return -ENOSYS;
return (*efuse_read)(dev, offset, buf, size);
Drop the *
}
static const struct misc_ops rockchip_efuse_ops = { @@ -146,7 +206,30 @@ static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev) }
static const struct udevice_id rockchip_efuse_ids[] = {
{ .compatible = "rockchip,rk3399-efuse" },
{
.compatible = "rockchip,rk3066a-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
You could use an enum to set the type, but it's up to you.
},
{
.compatible = "rockchip,rk3188-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
},
{
.compatible = "rockchip,rk3228-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
},
{
.compatible = "rockchip,rk3288-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
},
{
.compatible = "rockchip,rk3368-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
},
{
.compatible = "rockchip,rk3399-efuse",
.data = (ulong)&rockchip_rk3399_efuse_read,
}, {}
};
-- 2.17.1
Regards, Simon

Hi Jonas,
Could you help to format the coding style as required so that we can merge this patch to the mainline?
Thanks, - Kever On 2020/10/14 上午4:21, Jonas Karlman wrote:
From: Francis Fan francis.fan@rock-chips.com
Extend rockchip efuse driver with support for RK3288 non-secure efuse.
Signed-off-by: Francis Fan francis.fan@rock-chips.com Signed-off-by: Cody Xie cody.xie@rock-chips.com Signed-off-by: Jonas Karlman jonas@kwiboo.se
drivers/misc/rockchip-efuse.c | 91 +++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 46ce6305fe..20423544d9 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -27,6 +27,17 @@ #define RK3399_STROBE BIT(1) #define RK3399_CSB BIT(0)
+#define RK3288_A_SHIFT 6 +#define RK3288_A_MASK 0x3ff +#define RK3288_NFUSES 32 +#define RK3288_BYTES_PER_FUSE 1 +#define RK3288_PGENB BIT(3) +#define RK3288_LOAD BIT(2) +#define RK3288_STROBE BIT(1) +#define RK3288_CSB BIT(0)
+typedef int (*EFUSE_READ)(struct udevice *dev, int offset, void *buf, int size);
- struct rockchip_efuse_regs { u32 ctrl; /* 0x00 efuse control register */ u32 dout; /* 0x04 efuse data out register */
@@ -53,7 +64,7 @@ static int dump_efuses(struct cmd_tbl *cmdtp, int flag, */
struct udevice *dev;
- u8 fuses[128];
u8 fuses[128] = {0}; int ret;
/* retrieve the device */
@@ -77,7 +88,7 @@ static int dump_efuses(struct cmd_tbl *cmdtp, int flag, }
U_BOOT_CMD(
- rk3399_dump_efuses, 1, 1, dump_efuses,
- rockchip_dump_efuses, 1, 1, dump_efuses, "Dump the content of the efuses", "" );
@@ -127,10 +138,59 @@ static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, return 0; }
+static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset,
void *buf, int size)
+{
- struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
- struct rockchip_efuse_regs *efuse =
(struct rockchip_efuse_regs *)plat->base;
- u8 *buffer = buf;
- int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE;
- if (size > (max_size - offset))
size = max_size - offset;
- /* Switch to read mode */
- writel(RK3288_LOAD | RK3288_PGENB, &efuse->ctrl);
- udelay(1);
- while (size--) {
writel(readl(&efuse->ctrl) &
(~(RK3288_A_MASK << RK3288_A_SHIFT)),
&efuse->ctrl);
/* set addr */
writel(readl(&efuse->ctrl) |
((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT),
&efuse->ctrl);
udelay(1);
/* strobe low to high */
writel(readl(&efuse->ctrl) |
RK3288_STROBE, &efuse->ctrl);
ndelay(60);
/* read data */
*buffer++ = readl(&efuse->dout);
/* reset strobe to low */
writel(readl(&efuse->ctrl) &
(~RK3288_STROBE), &efuse->ctrl);
udelay(1);
- }
- /* Switch to standby mode */
- writel(RK3288_PGENB | RK3288_CSB, &efuse->ctrl);
- return 0;
+}
- static int rockchip_efuse_read(struct udevice *dev, int offset, void *buf, int size) {
- return rockchip_rk3399_efuse_read(dev, offset, buf, size);
EFUSE_READ efuse_read = NULL;
efuse_read = (EFUSE_READ)dev_get_driver_data(dev);
if (!efuse_read)
return -ENOSYS;
return (*efuse_read)(dev, offset, buf, size); }
static const struct misc_ops rockchip_efuse_ops = {
@@ -146,7 +206,30 @@ static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev) }
static const struct udevice_id rockchip_efuse_ids[] = {
- { .compatible = "rockchip,rk3399-efuse" },
- {
.compatible = "rockchip,rk3066a-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
- },
- {
.compatible = "rockchip,rk3188-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
- },
- {
.compatible = "rockchip,rk3228-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
- },
- {
.compatible = "rockchip,rk3288-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
- },
- {
.compatible = "rockchip,rk3368-efuse",
.data = (ulong)&rockchip_rk3288_efuse_read,
- },
- {
.compatible = "rockchip,rk3399-efuse",
.data = (ulong)&rockchip_rk3399_efuse_read,
- }, {} };

Enable efuse node so that boards can use cpu id in efuse as a source for serial# and ethaddr.
Signed-off-by: Jonas Karlman jonas@kwiboo.se --- arch/arm/dts/rk3288.dtsi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/dts/rk3288.dtsi b/arch/arm/dts/rk3288.dtsi index 22bb06cec5..381391360c 100644 --- a/arch/arm/dts/rk3288.dtsi +++ b/arch/arm/dts/rk3288.dtsi @@ -919,8 +919,7 @@
efuse: efuse@ffb40000 { compatible = "rockchip,rk3288-efuse"; - reg = <0xffb40000 0x10000>; - status = "disabled"; + reg = <0xffb40000 0x20>; };
gic: interrupt-controller@ffc01000 {

On Tue, 13 Oct 2020 at 14:21, Jonas Karlman jonas@kwiboo.se wrote:
Enable efuse node so that boards can use cpu id in efuse as a source for serial# and ethaddr.
Signed-off-by: Jonas Karlman jonas@kwiboo.se
arch/arm/dts/rk3288.dtsi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

From: Joseph Chen chenjh@rock-chips.com
Extend rockchip efuse driver with support for RK3328 non-secure efuse.
Signed-off-by: Joseph Chen chenjh@rock-chips.com Signed-off-by: Jonas Karlman jonas@kwiboo.se --- drivers/misc/rockchip-efuse.c | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 20423544d9..9b5a525322 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -13,6 +13,7 @@ #include <dm.h> #include <linux/bitops.h> #include <linux/delay.h> +#include <malloc.h> #include <misc.h>
#define RK3399_A_SHIFT 16 @@ -36,6 +37,13 @@ #define RK3288_STROBE BIT(1) #define RK3288_CSB BIT(0)
+#define RK3328_INT_STATUS 0x0018 +#define RK3328_DOUT 0x0020 +#define RK3328_AUTO_CTRL 0x0024 +#define RK3328_INT_FINISH BIT(0) +#define RK3328_AUTO_ENB BIT(0) +#define RK3328_AUTO_RD BIT(1) + typedef int (*EFUSE_READ)(struct udevice *dev, int offset, void *buf, int size);
struct rockchip_efuse_regs { @@ -46,6 +54,10 @@ struct rockchip_efuse_regs { u32 jtag_pass; /* 0x10 JTAG password */ u32 strobe_finish_ctrl; /* 0x14 efuse strobe finish control register */ + u32 int_status;/* 0x18 */ + u32 reserved; /* 0x1c */ + u32 dout2; /* 0x20 */ + u32 auto_ctrl; /* 0x24 */ };
struct rockchip_efuse_platdata { @@ -181,6 +193,57 @@ static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset, return 0; }
+static int rockchip_rk3328_efuse_read(struct udevice *dev, int offset, + void *buf, int size) +{ + struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); + struct rockchip_efuse_regs *efuse = + (struct rockchip_efuse_regs *)plat->base; + unsigned int addr_start, addr_end, addr_offset, addr_len; + u32 out_value, status; + u8 *buffer; + int ret = 0, i = 0, j = 0; + + /* Max non-secure Byte */ + if (size > 32) + size = 32; + + /* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */ + offset += 96; + addr_start = rounddown(offset, RK3399_BYTES_PER_FUSE) / + RK3399_BYTES_PER_FUSE; + addr_end = roundup(offset + size, RK3399_BYTES_PER_FUSE) / + RK3399_BYTES_PER_FUSE; + addr_offset = offset % RK3399_BYTES_PER_FUSE; + addr_len = addr_end - addr_start; + + buffer = calloc(1, sizeof(*buffer) * addr_len * RK3399_BYTES_PER_FUSE); + if (!buffer) + return -ENOMEM; + + for (j = 0; j < addr_len; j++) { + writel(RK3328_AUTO_RD | RK3328_AUTO_ENB | + ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT), + &efuse->auto_ctrl); + udelay(5); + status = readl(&efuse->int_status); + if (!(status & RK3328_INT_FINISH)) { + ret = -EIO; + goto err; + } + out_value = readl(&efuse->dout2); + writel(RK3328_INT_FINISH, &efuse->int_status); + + memcpy(&buffer[i], &out_value, RK3399_BYTES_PER_FUSE); + i += RK3399_BYTES_PER_FUSE; + } + memcpy(buf, buffer + addr_offset, size); +err: + free(buffer); + + return ret; +} + static int rockchip_efuse_read(struct udevice *dev, int offset, void *buf, int size) { @@ -226,6 +289,10 @@ static const struct udevice_id rockchip_efuse_ids[] = { .compatible = "rockchip,rk3368-efuse", .data = (ulong)&rockchip_rk3288_efuse_read, }, + { + .compatible = "rockchip,rk3328-efuse", + .data = (ulong)&rockchip_rk3328_efuse_read, + }, { .compatible = "rockchip,rk3399-efuse", .data = (ulong)&rockchip_rk3399_efuse_read,

Hi Jonas,
On Tue, 13 Oct 2020 at 14:21, Jonas Karlman jonas@kwiboo.se wrote:
From: Joseph Chen chenjh@rock-chips.com
Extend rockchip efuse driver with support for RK3328 non-secure efuse.
Signed-off-by: Joseph Chen chenjh@rock-chips.com Signed-off-by: Jonas Karlman jonas@kwiboo.se
drivers/misc/rockchip-efuse.c | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 20423544d9..9b5a525322 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -13,6 +13,7 @@ #include <dm.h> #include <linux/bitops.h> #include <linux/delay.h> +#include <malloc.h> #include <misc.h>
#define RK3399_A_SHIFT 16 @@ -36,6 +37,13 @@ #define RK3288_STROBE BIT(1) #define RK3288_CSB BIT(0)
+#define RK3328_INT_STATUS 0x0018 +#define RK3328_DOUT 0x0020 +#define RK3328_AUTO_CTRL 0x0024 +#define RK3328_INT_FINISH BIT(0) +#define RK3328_AUTO_ENB BIT(0) +#define RK3328_AUTO_RD BIT(1)
typedef int (*EFUSE_READ)(struct udevice *dev, int offset, void *buf, int size);
struct rockchip_efuse_regs { @@ -46,6 +54,10 @@ struct rockchip_efuse_regs { u32 jtag_pass; /* 0x10 JTAG password */ u32 strobe_finish_ctrl; /* 0x14 efuse strobe finish control register */
u32 int_status;/* 0x18 */
u32 reserved; /* 0x1c */
u32 dout2; /* 0x20 */
u32 auto_ctrl; /* 0x24 */
};
struct rockchip_efuse_platdata { @@ -181,6 +193,57 @@ static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset, return 0; }
+static int rockchip_rk3328_efuse_read(struct udevice *dev, int offset,
void *buf, int size)
Is this a completely different algorithm from rk3399, or just different parameters?
+{
struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
struct rockchip_efuse_regs *efuse =
(struct rockchip_efuse_regs *)plat->base;
unsigned int addr_start, addr_end, addr_offset, addr_len;
u32 out_value, status;
u8 *buffer;
int ret = 0, i = 0, j = 0;
Don't init unless needed.
/* Max non-secure Byte */
if (size > 32)
size = 32;
/* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */
offset += 96;
addr_start = rounddown(offset, RK3399_BYTES_PER_FUSE) /
RK3399_BYTES_PER_FUSE;
addr_end = roundup(offset + size, RK3399_BYTES_PER_FUSE) /
RK3399_BYTES_PER_FUSE;
addr_offset = offset % RK3399_BYTES_PER_FUSE;
addr_len = addr_end - addr_start;
buffer = calloc(1, sizeof(*buffer) * addr_len * RK3399_BYTES_PER_FUSE);
if (!buffer)
return -ENOMEM;
for (j = 0; j < addr_len; j++) {
writel(RK3328_AUTO_RD | RK3328_AUTO_ENB |
((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT),
Move addr_start to end of loop
&efuse->auto_ctrl);
udelay(5);
status = readl(&efuse->int_status);
if (!(status & RK3328_INT_FINISH)) {
ret = -EIO;
goto err;
}
out_value = readl(&efuse->dout2);
writel(RK3328_INT_FINISH, &efuse->int_status);
memcpy(&buffer[i], &out_value, RK3399_BYTES_PER_FUSE);
i += RK3399_BYTES_PER_FUSE;
Please use a proper descriptive variable name instead of i.
}
memcpy(buf, buffer + addr_offset, size);
+err:
free(buffer);
return ret;
+}
static int rockchip_efuse_read(struct udevice *dev, int offset, void *buf, int size) { @@ -226,6 +289,10 @@ static const struct udevice_id rockchip_efuse_ids[] = { .compatible = "rockchip,rk3368-efuse", .data = (ulong)&rockchip_rk3288_efuse_read, },
{
.compatible = "rockchip,rk3328-efuse",
.data = (ulong)&rockchip_rk3328_efuse_read,
}, { .compatible = "rockchip,rk3399-efuse", .data = (ulong)&rockchip_rk3399_efuse_read,
-- 2.17.1
Regards, Simon
participants (3)
-
Jonas Karlman
-
Kever Yang
-
Simon Glass