[PATCH v2 00/12] rockchip: Add efuse and otp support to more SoCs

This series refactors and add support for more SoCs to the rockchip efuse and otp driver.
Support is added for the following SoCs: - efuse: RK3036, RK3066, RK3128, RK3188, RK3228, RK3288 and RK3328 - otp: RK3568 and RK3588
This also changes so that eth1addr is also set along with ethaddr. And a small change so that ethernet mac addresses is set based on CONFIG_HASH and CONFIG_SHA256 instead of CONFIG_CMD_NET.
I have only been able to test the efuse driver on RK3288, RK3328, RK3399 and the otp driver on RK3568 and RK3588. Information on the remaining SoCs is based on information at [1], [2] and in TRM.
Alex Bee found and fixed an issue on RK3188 and RK3128, fix is included in v2, thanks!
The last patches enables use of the otp driver for RK3568 and RK3588. To handle the unique cpuid offset used on RK3568 a new const CFG_CPUID_OFFSET was added.
Ideally, we should get this cpuid offset from the id node in the fdt. Something that can be improved in a future series.
This series can also be found at [3].
Changes in v2: - Use readl instead of readb/readw (Alex Bee) - Always set eth1addr (Chen-Yu Tsai) - Collect r-b tags - Add patch to enable read of cpuid on rk3588
[1] https://github.com/rockchip-linux/kernel/blob/release-3.10/arch/arm/mach-roc... [2] https://github.com/rockchip-linux/kernel/blob/develop-5.10/drivers/nvmem/roc... [2] https://github.com/Kwiboo/u-boot-rockchip/commits/rk3568-efuse-otp
Jonas Karlman (12): rockchip: otp: Refactor to use driver data and ops rockchip: otp: Add support for RK3568 rockchip: otp: Add support for RK3588 rockchip: otp: Add dump_otp debug command rockchip: efuse: Refactor to use driver data and ops rockchip: efuse: Add support for RK3288 and more rockchip: efuse: Add support for RK3328 rockchip: efuse: Add support for RK3128 rockchip: efuse: Add support for RK3036 rockchip: misc: Set eth1addr mac address rockchip: rk3568: Read cpuid from otp rockchip: rk3588: Read cpuid from otp
arch/arm/dts/rk356x-u-boot.dtsi | 12 ++ arch/arm/dts/rk3588s-u-boot.dtsi | 12 ++ arch/arm/mach-rockchip/Kconfig | 4 + arch/arm/mach-rockchip/board.c | 2 +- arch/arm/mach-rockchip/misc.c | 6 +- drivers/misc/Kconfig | 4 - drivers/misc/rockchip-efuse.c | 333 +++++++++++++++++++++++------- drivers/misc/rockchip-otp.c | 230 +++++++++++++++++---- include/configs/rk3568_common.h | 2 + include/configs/rockchip-common.h | 4 + 10 files changed, 491 insertions(+), 118 deletions(-)

Refactor the driver to use driver data and ops to simplify handling of SoCs that require a unique read op.
Use readl_poll_sleep_timeout instead of a custom poll loop, and add validation of input parameter to main read op.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Use readl instead of readb - Collect r-b tag
drivers/misc/rockchip-otp.c | 85 +++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 41 deletions(-)
diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c index cc9a5450e0ce..80bf9c1aeacc 100644 --- a/drivers/misc/rockchip-otp.c +++ b/drivers/misc/rockchip-otp.c @@ -5,10 +5,10 @@
#include <common.h> #include <asm/io.h> -#include <command.h> #include <dm.h> #include <linux/bitops.h> #include <linux/delay.h> +#include <linux/iopoll.h> #include <misc.h>
/* OTP Register Offsets */ @@ -49,35 +49,31 @@
struct rockchip_otp_plat { void __iomem *base; - unsigned long secure_conf_base; - unsigned long otp_mask_base; };
-static int rockchip_otp_wait_status(struct rockchip_otp_plat *otp, - u32 flag) +struct rockchip_otp_data { + int (*read)(struct udevice *dev, int offset, void *buf, int size); + int size; +}; + +static int rockchip_otp_poll_timeout(struct rockchip_otp_plat *otp, u32 flag) { - int delay = OTPC_TIMEOUT; - - while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) { - udelay(1); - delay--; - if (delay <= 0) { - printf("%s: wait init status timeout\n", __func__); - return -ETIMEDOUT; - } - } + u32 status; + int ret; + + ret = readl_poll_sleep_timeout(otp->base + OTPC_INT_STATUS, status, + (status & flag), 1, OTPC_TIMEOUT); + if (ret) + return ret;
- /* clean int status */ + /* Clear int flag */ writel(flag, otp->base + OTPC_INT_STATUS);
return 0; }
-static int rockchip_otp_ecc_enable(struct rockchip_otp_plat *otp, - bool enable) +static int rockchip_otp_ecc_enable(struct rockchip_otp_plat *otp, bool enable) { - int ret = 0; - writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT), otp->base + OTPC_SBPI_CTRL);
@@ -92,11 +88,7 @@ static int rockchip_otp_ecc_enable(struct rockchip_otp_plat *otp,
writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
- ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE); - if (ret < 0) - printf("%s timeout during ecc_enable\n", __func__); - - return ret; + return rockchip_otp_poll_timeout(otp, OTPC_SBPI_DONE); }
static int rockchip_px30_otp_read(struct udevice *dev, int offset, @@ -104,29 +96,26 @@ static int rockchip_px30_otp_read(struct udevice *dev, int offset, { struct rockchip_otp_plat *otp = dev_get_plat(dev); u8 *buffer = buf; - int ret = 0; + int ret;
ret = rockchip_otp_ecc_enable(otp, false); - if (ret < 0) { - printf("%s rockchip_otp_ecc_enable err\n", __func__); + if (ret) return ret; - }
writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); udelay(5); + while (size--) { writel(offset++ | OTPC_USER_ADDR_MASK, otp->base + OTPC_USER_ADDR); writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, otp->base + OTPC_USER_ENABLE);
- ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); - if (ret < 0) { - printf("%s timeout during read setup\n", __func__); + ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE); + if (ret) goto read_end; - }
- *buffer++ = readb(otp->base + OTPC_USER_Q); + *buffer++ = (u8)(readl(otp->base + OTPC_USER_Q) & 0xFF); }
read_end: @@ -138,7 +127,16 @@ read_end: static int rockchip_otp_read(struct udevice *dev, int offset, void *buf, int size) { - return rockchip_px30_otp_read(dev, offset, buf, size); + const struct rockchip_otp_data *data = + (void *)dev_get_driver_data(dev); + + if (offset < 0 || !buf || size <= 0 || offset + size > data->size) + return -EINVAL; + + if (!data->read) + return -ENOSYS; + + return data->read(dev, offset, buf, size); }
static const struct misc_ops rockchip_otp_ops = { @@ -147,21 +145,26 @@ static const struct misc_ops rockchip_otp_ops = {
static int rockchip_otp_of_to_plat(struct udevice *dev) { - struct rockchip_otp_plat *otp = dev_get_plat(dev); + struct rockchip_otp_plat *plat = dev_get_plat(dev);
- otp->base = dev_read_addr_ptr(dev); + plat->base = dev_read_addr_ptr(dev);
return 0; }
+static const struct rockchip_otp_data px30_data = { + .read = rockchip_px30_otp_read, + .size = 0x40, +}; + static const struct udevice_id rockchip_otp_ids[] = { { .compatible = "rockchip,px30-otp", - .data = (ulong)&rockchip_px30_otp_read, + .data = (ulong)&px30_data, }, { .compatible = "rockchip,rk3308-otp", - .data = (ulong)&rockchip_px30_otp_read, + .data = (ulong)&px30_data, }, {} }; @@ -170,7 +173,7 @@ U_BOOT_DRIVER(rockchip_otp) = { .name = "rockchip_otp", .id = UCLASS_MISC, .of_match = rockchip_otp_ids, - .ops = &rockchip_otp_ops, .of_to_plat = rockchip_otp_of_to_plat, - .plat_auto = sizeof(struct rockchip_otp_plat), + .plat_auto = sizeof(struct rockchip_otp_plat), + .ops = &rockchip_otp_ops, };

Add support for rk3568 compatible.
Handle allocation of an aligned bounce buffer in main read op in order to keep the SoC unique read op simple.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Use readl instead of readw - Collect r-b tag
drivers/misc/rockchip-otp.c | 67 ++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-)
diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c index 80bf9c1aeacc..fea3ca7c2882 100644 --- a/drivers/misc/rockchip-otp.c +++ b/drivers/misc/rockchip-otp.c @@ -9,6 +9,7 @@ #include <linux/bitops.h> #include <linux/delay.h> #include <linux/iopoll.h> +#include <malloc.h> #include <misc.h>
/* OTP Register Offsets */ @@ -54,6 +55,7 @@ struct rockchip_otp_plat { struct rockchip_otp_data { int (*read)(struct udevice *dev, int offset, void *buf, int size); int size; + int block_size; };
static int rockchip_otp_poll_timeout(struct rockchip_otp_plat *otp, u32 flag) @@ -124,11 +126,47 @@ read_end: return ret; }
+static int rockchip_rk3568_otp_read(struct udevice *dev, int offset, + void *buf, int size) +{ + struct rockchip_otp_plat *otp = dev_get_plat(dev); + u16 *buffer = buf; + int ret; + + ret = rockchip_otp_ecc_enable(otp, false); + if (ret) + return ret; + + writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); + udelay(5); + + while (size--) { + writel(offset++ | OTPC_USER_ADDR_MASK, + otp->base + OTPC_USER_ADDR); + writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, + otp->base + OTPC_USER_ENABLE); + + ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE); + if (ret) + goto read_end; + + *buffer++ = (u16)(readl(otp->base + OTPC_USER_Q) & 0xFFFF); + } + +read_end: + writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); + + return ret; +} + static int rockchip_otp_read(struct udevice *dev, int offset, void *buf, int size) { const struct rockchip_otp_data *data = (void *)dev_get_driver_data(dev); + u32 block_start, block_end, block_offset, blocks; + u8 *buffer; + int ret;
if (offset < 0 || !buf || size <= 0 || offset + size > data->size) return -EINVAL; @@ -136,7 +174,24 @@ static int rockchip_otp_read(struct udevice *dev, int offset, if (!data->read) return -ENOSYS;
- return data->read(dev, offset, buf, size); + if (data->block_size <= 1) + return data->read(dev, offset, buf, size); + + block_start = offset / data->block_size; + block_offset = offset % data->block_size; + block_end = DIV_ROUND_UP(offset + size, data->block_size); + blocks = block_end - block_start; + + buffer = calloc(blocks, data->block_size); + if (!buffer) + return -ENOMEM; + + ret = data->read(dev, block_start, buffer, blocks); + if (!ret) + memcpy(buf, buffer + block_offset, size); + + free(buffer); + return ret; }
static const struct misc_ops rockchip_otp_ops = { @@ -157,6 +212,12 @@ static const struct rockchip_otp_data px30_data = { .size = 0x40, };
+static const struct rockchip_otp_data rk3568_data = { + .read = rockchip_rk3568_otp_read, + .size = 0x80, + .block_size = 2, +}; + static const struct udevice_id rockchip_otp_ids[] = { { .compatible = "rockchip,px30-otp", @@ -166,6 +227,10 @@ static const struct udevice_id rockchip_otp_ids[] = { .compatible = "rockchip,rk3308-otp", .data = (ulong)&px30_data, }, + { + .compatible = "rockchip,rk3568-otp", + .data = (ulong)&rk3568_data, + }, {} };

Refactor the driver to use driver data and ops to simplify handling of SoCs that require a unique read op.
Move handling of the aligned bounce buffer to main read op in order to keep the SoC unique read op simple.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Print 4 bytes instead of one 32-bit word - Collect r-b tag
drivers/misc/rockchip-efuse.c | 160 ++++++++++++++++++---------------- 1 file changed, 85 insertions(+), 75 deletions(-)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 083ee65e0ad7..7d4a984dce34 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -13,50 +13,40 @@ #include <dm.h> #include <linux/bitops.h> #include <linux/delay.h> +#include <malloc.h> #include <misc.h>
-#define RK3399_A_SHIFT 16 -#define RK3399_A_MASK 0x3ff -#define RK3399_NFUSES 32 -#define RK3399_BYTES_PER_FUSE 4 -#define RK3399_STROBSFTSEL BIT(9) -#define RK3399_RSB BIT(7) -#define RK3399_PD BIT(5) -#define RK3399_PGENB BIT(3) -#define RK3399_LOAD BIT(2) -#define RK3399_STROBE BIT(1) -#define RK3399_CSB BIT(0) - -struct rockchip_efuse_regs { - u32 ctrl; /* 0x00 efuse control register */ - u32 dout; /* 0x04 efuse data out register */ - u32 rf; /* 0x08 efuse redundancy bit used register */ - u32 _rsvd0; - u32 jtag_pass; /* 0x10 JTAG password */ - u32 strobe_finish_ctrl; - /* 0x14 efuse strobe finish control register */ -}; +#define EFUSE_CTRL 0x0000 +#define RK3399_A_SHIFT 16 +#define RK3399_A_MASK GENMASK(25, 16) +#define RK3399_ADDR(n) ((n) << RK3399_A_SHIFT) +#define RK3399_STROBSFTSEL BIT(9) +#define RK3399_RSB BIT(7) +#define RK3399_PD BIT(5) +#define RK3399_PGENB BIT(3) +#define RK3399_LOAD BIT(2) +#define RK3399_STROBE BIT(1) +#define RK3399_CSB BIT(0) +#define EFUSE_DOUT 0x0004
struct rockchip_efuse_plat { void __iomem *base; - struct clk *clk; +}; + +struct rockchip_efuse_data { + int (*read)(struct udevice *dev, int offset, void *buf, int size); + int size; + int block_size; };
#if defined(DEBUG) -static int dump_efuses(struct cmd_tbl *cmdtp, int flag, - int argc, char *const argv[]) +static int dump_efuse(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]) { - /* - * N.B.: This function is tailored towards the RK3399 and assumes that - * there's always 32 fuses x 32 bits (i.e. 128 bytes of data) to - * be read. - */ - struct udevice *dev; - u8 fuses[128]; - int ret; + u8 data[4]; + int ret, i;
- /* retrieve the device */ ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(rockchip_efuse), &dev); if (ret) { @@ -64,21 +54,20 @@ static int dump_efuses(struct cmd_tbl *cmdtp, int flag, return 0; }
- ret = misc_read(dev, 0, &fuses, sizeof(fuses)); - if (ret < 0) { - printf("%s: misc_read failed\n", __func__); - return 0; - } + for (i = 0; true; i += sizeof(data)) { + ret = misc_read(dev, i, &data, sizeof(data)); + if (ret < 0) + return 0;
- printf("efuse-contents:\n"); - print_buffer(0, fuses, 1, 128, 16); + print_buffer(i, data, 1, sizeof(data), sizeof(data)); + }
return 0; }
U_BOOT_CMD( - rk3399_dump_efuses, 1, 1, dump_efuses, - "Dump the content of the efuses", + dump_efuse, 1, 1, dump_efuse, + "Dump the content of the efuse", "" ); #endif @@ -86,43 +75,25 @@ U_BOOT_CMD( static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, void *buf, int size) { - struct rockchip_efuse_plat *plat = dev_get_plat(dev); - struct rockchip_efuse_regs *efuse = - (struct rockchip_efuse_regs *)plat->base; - - unsigned int addr_start, addr_end, addr_offset; - u32 out_value; - u8 bytes[RK3399_NFUSES * RK3399_BYTES_PER_FUSE]; - int i = 0; - u32 addr; - - addr_start = offset / RK3399_BYTES_PER_FUSE; - addr_offset = offset % RK3399_BYTES_PER_FUSE; - addr_end = DIV_ROUND_UP(offset + size, RK3399_BYTES_PER_FUSE); - - /* cap to the size of the efuse block */ - if (addr_end > RK3399_NFUSES) - addr_end = RK3399_NFUSES; + struct rockchip_efuse_plat *efuse = dev_get_plat(dev); + u32 *buffer = buf;
+ /* Switch to array read mode */ writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB, - &efuse->ctrl); + efuse->base + EFUSE_CTRL); udelay(1); - for (addr = addr_start; addr < addr_end; addr++) { - setbits_le32(&efuse->ctrl, - RK3399_STROBE | (addr << RK3399_A_SHIFT)); + + while (size--) { + setbits_le32(efuse->base + EFUSE_CTRL, + RK3399_STROBE | RK3399_ADDR(offset++)); udelay(1); - out_value = readl(&efuse->dout); - clrbits_le32(&efuse->ctrl, RK3399_STROBE); + *buffer++ = readl(efuse->base + EFUSE_DOUT); + clrbits_le32(efuse->base + EFUSE_CTRL, RK3399_STROBE); udelay(1); - - memcpy(&bytes[i], &out_value, RK3399_BYTES_PER_FUSE); - i += RK3399_BYTES_PER_FUSE; }
- /* Switch to standby mode */ - writel(RK3399_PD | RK3399_CSB, &efuse->ctrl); - - memcpy(buf, bytes + addr_offset, size); + /* Switch to power-down mode */ + writel(RK3399_PD | RK3399_CSB, efuse->base + EFUSE_CTRL);
return 0; } @@ -130,7 +101,36 @@ static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, static int rockchip_efuse_read(struct udevice *dev, int offset, void *buf, int size) { - return rockchip_rk3399_efuse_read(dev, offset, buf, size); + const struct rockchip_efuse_data *data = + (void *)dev_get_driver_data(dev); + u32 block_start, block_end, block_offset, blocks; + u8 *buffer; + int ret; + + if (offset < 0 || !buf || size <= 0 || offset + size > data->size) + return -EINVAL; + + if (!data->read) + return -ENOSYS; + + if (data->block_size <= 1) + return data->read(dev, offset, buf, size); + + block_start = offset / data->block_size; + block_offset = offset % data->block_size; + block_end = DIV_ROUND_UP(offset + size, data->block_size); + blocks = block_end - block_start; + + buffer = calloc(blocks, data->block_size); + if (!buffer) + return -ENOMEM; + + ret = data->read(dev, block_start, buffer, blocks); + if (!ret) + memcpy(buf, buffer + block_offset, size); + + free(buffer); + return ret; }
static const struct misc_ops rockchip_efuse_ops = { @@ -142,11 +142,21 @@ static int rockchip_efuse_of_to_plat(struct udevice *dev) struct rockchip_efuse_plat *plat = dev_get_plat(dev);
plat->base = dev_read_addr_ptr(dev); + return 0; }
+static const struct rockchip_efuse_data rk3399_data = { + .read = rockchip_rk3399_efuse_read, + .size = 0x80, + .block_size = 4, +}; + static const struct udevice_id rockchip_efuse_ids[] = { - { .compatible = "rockchip,rk3399-efuse" }, + { + .compatible = "rockchip,rk3399-efuse", + .data = (ulong)&rk3399_data, + }, {} };
@@ -155,6 +165,6 @@ U_BOOT_DRIVER(rockchip_efuse) = { .id = UCLASS_MISC, .of_match = rockchip_efuse_ids, .of_to_plat = rockchip_efuse_of_to_plat, - .plat_auto = sizeof(struct rockchip_efuse_plat), + .plat_auto = sizeof(struct rockchip_efuse_plat), .ops = &rockchip_efuse_ops, };

Add support for rk3588 compatible.
Adjust offset using driver data in main read op.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Collect r-b tag
drivers/misc/rockchip-otp.c | 63 +++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c index fea3ca7c2882..3da99e83179b 100644 --- a/drivers/misc/rockchip-otp.c +++ b/drivers/misc/rockchip-otp.c @@ -48,28 +48,41 @@
#define OTPC_TIMEOUT 10000
+#define RK3588_OTPC_AUTO_CTRL 0x0004 +#define RK3588_ADDR_SHIFT 16 +#define RK3588_ADDR(n) ((n) << RK3588_ADDR_SHIFT) +#define RK3588_BURST_SHIFT 8 +#define RK3588_BURST(n) ((n) << RK3588_BURST_SHIFT) +#define RK3588_OTPC_AUTO_EN 0x0008 +#define RK3588_AUTO_EN BIT(0) +#define RK3588_OTPC_DOUT0 0x0020 +#define RK3588_OTPC_INT_ST 0x0084 +#define RK3588_RD_DONE BIT(1) + struct rockchip_otp_plat { void __iomem *base; };
struct rockchip_otp_data { int (*read)(struct udevice *dev, int offset, void *buf, int size); + int offset; int size; int block_size; };
-static int rockchip_otp_poll_timeout(struct rockchip_otp_plat *otp, u32 flag) +static int rockchip_otp_poll_timeout(struct rockchip_otp_plat *otp, + u32 flag, u32 reg) { u32 status; int ret;
- ret = readl_poll_sleep_timeout(otp->base + OTPC_INT_STATUS, status, + ret = readl_poll_sleep_timeout(otp->base + reg, status, (status & flag), 1, OTPC_TIMEOUT); if (ret) return ret;
/* Clear int flag */ - writel(flag, otp->base + OTPC_INT_STATUS); + writel(flag, otp->base + reg);
return 0; } @@ -90,7 +103,7 @@ static int rockchip_otp_ecc_enable(struct rockchip_otp_plat *otp, bool enable)
writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
- return rockchip_otp_poll_timeout(otp, OTPC_SBPI_DONE); + return rockchip_otp_poll_timeout(otp, OTPC_SBPI_DONE, OTPC_INT_STATUS); }
static int rockchip_px30_otp_read(struct udevice *dev, int offset, @@ -113,7 +126,8 @@ static int rockchip_px30_otp_read(struct udevice *dev, int offset, writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, otp->base + OTPC_USER_ENABLE);
- ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE); + ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE, + OTPC_INT_STATUS); if (ret) goto read_end;
@@ -146,7 +160,8 @@ static int rockchip_rk3568_otp_read(struct udevice *dev, int offset, writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, otp->base + OTPC_USER_ENABLE);
- ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE); + ret = rockchip_otp_poll_timeout(otp, OTPC_USER_DONE, + OTPC_INT_STATUS); if (ret) goto read_end;
@@ -159,6 +174,29 @@ read_end: return ret; }
+static int rockchip_rk3588_otp_read(struct udevice *dev, int offset, + void *buf, int size) +{ + struct rockchip_otp_plat *otp = dev_get_plat(dev); + u32 *buffer = buf; + int ret; + + while (size--) { + writel(RK3588_ADDR(offset++) | RK3588_BURST(1), + otp->base + RK3588_OTPC_AUTO_CTRL); + writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN); + + ret = rockchip_otp_poll_timeout(otp, RK3588_RD_DONE, + RK3588_OTPC_INT_ST); + if (ret) + return ret; + + *buffer++ = readl(otp->base + RK3588_OTPC_DOUT0); + } + + return 0; +} + static int rockchip_otp_read(struct udevice *dev, int offset, void *buf, int size) { @@ -174,6 +212,8 @@ static int rockchip_otp_read(struct udevice *dev, int offset, if (!data->read) return -ENOSYS;
+ offset += data->offset; + if (data->block_size <= 1) return data->read(dev, offset, buf, size);
@@ -218,6 +258,13 @@ static const struct rockchip_otp_data rk3568_data = { .block_size = 2, };
+static const struct rockchip_otp_data rk3588_data = { + .read = rockchip_rk3588_otp_read, + .offset = 0xC00, + .size = 0x400, + .block_size = 4, +}; + static const struct udevice_id rockchip_otp_ids[] = { { .compatible = "rockchip,px30-otp", @@ -231,6 +278,10 @@ static const struct udevice_id rockchip_otp_ids[] = { .compatible = "rockchip,rk3568-otp", .data = (ulong)&rk3568_data, }, + { + .compatible = "rockchip,rk3588-otp", + .data = (ulong)&rk3588_data, + }, {} };

Add a simple debug command to dump the content of the otp.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Print 4 bytes instead of one 32-bit word - Collect r-b tag
drivers/misc/rockchip-otp.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c index 3da99e83179b..c19cd5ce625e 100644 --- a/drivers/misc/rockchip-otp.c +++ b/drivers/misc/rockchip-otp.c @@ -5,6 +5,8 @@
#include <common.h> #include <asm/io.h> +#include <command.h> +#include <display_options.h> #include <dm.h> #include <linux/bitops.h> #include <linux/delay.h> @@ -70,6 +72,39 @@ struct rockchip_otp_data { int block_size; };
+#if defined(DEBUG) +static int dump_otp(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]) +{ + struct udevice *dev; + u8 data[4]; + int ret, i; + + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_DRIVER_GET(rockchip_otp), &dev); + if (ret) { + printf("%s: no misc-device found\n", __func__); + return 0; + } + + for (i = 0; true; i += sizeof(data)) { + ret = misc_read(dev, i, &data, sizeof(data)); + if (ret < 0) + return 0; + + print_buffer(i, data, 1, sizeof(data), sizeof(data)); + } + + return 0; +} + +U_BOOT_CMD( + dump_otp, 1, 1, dump_otp, + "Dump the content of the otp", + "" +); +#endif + static int rockchip_otp_poll_timeout(struct rockchip_otp_plat *otp, u32 flag, u32 reg) {

Set eth1addr in addition to ethaddr.
Also allow fdt fixup of ethernet mac addresses when CMD_NET is disabled. Set ethaddr and eth1addr based on HASH and SHA256 options.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Always set eth1addr along with ethaddr - Collect r-b tag
arch/arm/mach-rockchip/misc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-rockchip/misc.c b/arch/arm/mach-rockchip/misc.c index b350f18f1140..849014d2fb7d 100644 --- a/arch/arm/mach-rockchip/misc.c +++ b/arch/arm/mach-rockchip/misc.c @@ -23,7 +23,7 @@
int rockchip_setup_macaddr(void) { -#if IS_ENABLED(CONFIG_CMD_NET) +#if CONFIG_IS_ENABLED(HASH) && CONFIG_IS_ENABLED(SHA256) int ret; const char *cpuid = env_get("cpuid#"); u8 hash[SHA256_SUM_LEN]; @@ -52,6 +52,10 @@ int rockchip_setup_macaddr(void) mac_addr[0] &= 0xfe; /* clear multicast bit */ mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ eth_env_set_enetaddr("ethaddr", mac_addr); + + /* Make a valid MAC address for ethernet1 */ + mac_addr[5] ^= 0x01; + eth_env_set_enetaddr("eth1addr", mac_addr); #endif return 0; }

Add support for rk3328 compatible.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Collect r-b tag
drivers/misc/rockchip-efuse.c | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 99220d5b1eab..8cf61e36aeff 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 <linux/iopoll.h> #include <malloc.h> #include <misc.h>
@@ -31,6 +32,12 @@ #define EFUSE_STROBE BIT(1) #define EFUSE_CSB BIT(0) #define EFUSE_DOUT 0x0004 +#define RK3328_INT_STATUS 0x0018 +#define RK3328_INT_FINISH BIT(0) +#define RK3328_DOUT 0x0020 +#define RK3328_AUTO_CTRL 0x0024 +#define RK3328_AUTO_RD BIT(1) +#define RK3328_AUTO_ENB BIT(0)
struct rockchip_efuse_plat { void __iomem *base; @@ -38,6 +45,7 @@ struct rockchip_efuse_plat {
struct rockchip_efuse_data { int (*read)(struct udevice *dev, int offset, void *buf, int size); + int offset; int size; int block_size; }; @@ -103,6 +111,30 @@ 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_plat *efuse = dev_get_plat(dev); + u32 status, *buffer = buf; + int ret; + + while (size--) { + writel(RK3328_AUTO_RD | RK3328_AUTO_ENB | RK3399_ADDR(offset++), + efuse->base + RK3328_AUTO_CTRL); + udelay(1); + + ret = readl_poll_sleep_timeout(efuse->base + RK3328_INT_STATUS, + status, (status & RK3328_INT_FINISH), 1, 50); + if (ret) + return ret; + + *buffer++ = readl(efuse->base + RK3328_DOUT); + writel(RK3328_INT_FINISH, efuse->base + RK3328_INT_STATUS); + } + + return 0; +} + static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, void *buf, int size) { @@ -144,6 +176,8 @@ static int rockchip_efuse_read(struct udevice *dev, int offset, if (!data->read) return -ENOSYS;
+ offset += data->offset; + if (data->block_size <= 1) return data->read(dev, offset, buf, size);
@@ -182,6 +216,13 @@ static const struct rockchip_efuse_data rk3288_data = { .size = 0x20, };
+static const struct rockchip_efuse_data rk3328_data = { + .read = rockchip_rk3328_efuse_read, + .offset = 0x60, + .size = 0x20, + .block_size = 4, +}; + static const struct rockchip_efuse_data rk3399_data = { .read = rockchip_rk3399_efuse_read, .size = 0x80, @@ -205,6 +246,10 @@ static const struct udevice_id rockchip_efuse_ids[] = { .compatible = "rockchip,rk3288-efuse", .data = (ulong)&rk3288_data, }, + { + .compatible = "rockchip,rk3328-efuse", + .data = (ulong)&rk3328_data, + }, { .compatible = "rockchip,rk3399-efuse", .data = (ulong)&rk3399_data,

Add support for rk3036 compatible.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Use readl instead of readb - Collect r-b tag
drivers/misc/rockchip-efuse.c | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index bc73fd3baa10..60931a513121 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -18,6 +18,9 @@ #include <misc.h>
#define EFUSE_CTRL 0x0000 +#define RK3036_A_SHIFT 8 +#define RK3036_A_MASK GENMASK(15, 8) +#define RK3036_ADDR(n) ((n) << RK3036_A_SHIFT) #define RK3128_A_SHIFT 7 #define RK3128_A_MASK GENMASK(15, 7) #define RK3128_ADDR(n) ((n) << RK3128_A_SHIFT) @@ -86,6 +89,33 @@ U_BOOT_CMD( ); #endif
+static int rockchip_rk3036_efuse_read(struct udevice *dev, int offset, + void *buf, int size) +{ + struct rockchip_efuse_plat *efuse = dev_get_plat(dev); + u8 *buffer = buf; + + /* Switch to read mode */ + writel(EFUSE_LOAD, efuse->base + EFUSE_CTRL); + udelay(2); + + while (size--) { + clrsetbits_le32(efuse->base + EFUSE_CTRL, RK3036_A_MASK, + RK3036_ADDR(offset++)); + udelay(2); + setbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE); + udelay(2); + *buffer++ = (u8)(readl(efuse->base + EFUSE_DOUT) & 0xFF); + clrbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE); + udelay(2); + } + + /* Switch to inactive mode */ + writel(0x0, efuse->base + EFUSE_CTRL); + + return 0; +} + static int rockchip_rk3128_efuse_read(struct udevice *dev, int offset, void *buf, int size) { @@ -241,6 +271,11 @@ static int rockchip_efuse_of_to_plat(struct udevice *dev) return 0; }
+static const struct rockchip_efuse_data rk3036_data = { + .read = rockchip_rk3036_efuse_read, + .size = 0x20, +}; + static const struct rockchip_efuse_data rk3128_data = { .read = rockchip_rk3128_efuse_read, .size = 0x40, @@ -265,6 +300,10 @@ static const struct rockchip_efuse_data rk3399_data = { };
static const struct udevice_id rockchip_efuse_ids[] = { + { + .compatible = "rockchip,rk3036-efuse", + .data = (ulong)&rk3036_data, + }, { .compatible = "rockchip,rk3066a-efuse", .data = (ulong)&rk3288_data,

Add support for rk3066a, rk3188, rk322x and rk3288 compatible.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Use readl instead of readb - Collect r-b tag
drivers/misc/Kconfig | 4 --- drivers/misc/rockchip-efuse.c | 68 ++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b07261d3db5a..b5707a15c504 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -92,10 +92,6 @@ config ROCKCHIP_EFUSE or through child-nodes that are generated based on the e-fuse map retrieved from the DTS.
- This driver currently supports the RK3399 only, but can easily be - extended (by porting the read function from the Linux kernel sources) - to support other recent Rockchip devices. - config ROCKCHIP_OTP bool "Rockchip OTP Support" depends on MISC diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 7d4a984dce34..99220d5b1eab 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -17,16 +17,19 @@ #include <misc.h>
#define EFUSE_CTRL 0x0000 +#define RK3288_A_SHIFT 6 +#define RK3288_A_MASK GENMASK(15, 6) +#define RK3288_ADDR(n) ((n) << RK3288_A_SHIFT) #define RK3399_A_SHIFT 16 #define RK3399_A_MASK GENMASK(25, 16) #define RK3399_ADDR(n) ((n) << RK3399_A_SHIFT) #define RK3399_STROBSFTSEL BIT(9) #define RK3399_RSB BIT(7) #define RK3399_PD BIT(5) -#define RK3399_PGENB BIT(3) -#define RK3399_LOAD BIT(2) -#define RK3399_STROBE BIT(1) -#define RK3399_CSB BIT(0) +#define EFUSE_PGENB BIT(3) +#define EFUSE_LOAD BIT(2) +#define EFUSE_STROBE BIT(1) +#define EFUSE_CSB BIT(0) #define EFUSE_DOUT 0x0004
struct rockchip_efuse_plat { @@ -72,6 +75,34 @@ U_BOOT_CMD( ); #endif
+static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset, + void *buf, int size) +{ + struct rockchip_efuse_plat *efuse = dev_get_plat(dev); + u8 *buffer = buf; + + /* Switch to read mode */ + writel(EFUSE_CSB, efuse->base + EFUSE_CTRL); + writel(EFUSE_LOAD | EFUSE_PGENB, efuse->base + EFUSE_CTRL); + udelay(2); + + while (size--) { + clrsetbits_le32(efuse->base + EFUSE_CTRL, RK3288_A_MASK, + RK3288_ADDR(offset++)); + udelay(2); + setbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE); + udelay(2); + *buffer++ = (u8)(readl(efuse->base + EFUSE_DOUT) & 0xFF); + clrbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE); + udelay(2); + } + + /* Switch to standby mode */ + writel(EFUSE_CSB | EFUSE_PGENB, efuse->base + EFUSE_CTRL); + + return 0; +} + static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, void *buf, int size) { @@ -79,21 +110,21 @@ static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, u32 *buffer = buf;
/* Switch to array read mode */ - writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB, + writel(EFUSE_LOAD | EFUSE_PGENB | RK3399_STROBSFTSEL | RK3399_RSB, efuse->base + EFUSE_CTRL); udelay(1);
while (size--) { setbits_le32(efuse->base + EFUSE_CTRL, - RK3399_STROBE | RK3399_ADDR(offset++)); + EFUSE_STROBE | RK3399_ADDR(offset++)); udelay(1); *buffer++ = readl(efuse->base + EFUSE_DOUT); - clrbits_le32(efuse->base + EFUSE_CTRL, RK3399_STROBE); + clrbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE); udelay(1); }
/* Switch to power-down mode */ - writel(RK3399_PD | RK3399_CSB, efuse->base + EFUSE_CTRL); + writel(RK3399_PD | EFUSE_CSB, efuse->base + EFUSE_CTRL);
return 0; } @@ -146,6 +177,11 @@ static int rockchip_efuse_of_to_plat(struct udevice *dev) return 0; }
+static const struct rockchip_efuse_data rk3288_data = { + .read = rockchip_rk3288_efuse_read, + .size = 0x20, +}; + static const struct rockchip_efuse_data rk3399_data = { .read = rockchip_rk3399_efuse_read, .size = 0x80, @@ -153,6 +189,22 @@ static const struct rockchip_efuse_data rk3399_data = { };
static const struct udevice_id rockchip_efuse_ids[] = { + { + .compatible = "rockchip,rk3066a-efuse", + .data = (ulong)&rk3288_data, + }, + { + .compatible = "rockchip,rk3188-efuse", + .data = (ulong)&rk3288_data, + }, + { + .compatible = "rockchip,rk3228-efuse", + .data = (ulong)&rk3288_data, + }, + { + .compatible = "rockchip,rk3288-efuse", + .data = (ulong)&rk3288_data, + }, { .compatible = "rockchip,rk3399-efuse", .data = (ulong)&rk3399_data,

Add support for rk3128 compatible.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Use readl instead of readb - Collect r-b tag
drivers/misc/rockchip-efuse.c | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c index 8cf61e36aeff..bc73fd3baa10 100644 --- a/drivers/misc/rockchip-efuse.c +++ b/drivers/misc/rockchip-efuse.c @@ -18,6 +18,9 @@ #include <misc.h>
#define EFUSE_CTRL 0x0000 +#define RK3128_A_SHIFT 7 +#define RK3128_A_MASK GENMASK(15, 7) +#define RK3128_ADDR(n) ((n) << RK3128_A_SHIFT) #define RK3288_A_SHIFT 6 #define RK3288_A_MASK GENMASK(15, 6) #define RK3288_ADDR(n) ((n) << RK3288_A_SHIFT) @@ -83,6 +86,33 @@ U_BOOT_CMD( ); #endif
+static int rockchip_rk3128_efuse_read(struct udevice *dev, int offset, + void *buf, int size) +{ + struct rockchip_efuse_plat *efuse = dev_get_plat(dev); + u8 *buffer = buf; + + /* Switch to read mode */ + writel(EFUSE_LOAD, efuse->base + EFUSE_CTRL); + udelay(2); + + while (size--) { + clrsetbits_le32(efuse->base + EFUSE_CTRL, RK3128_A_MASK, + RK3128_ADDR(offset++)); + udelay(2); + setbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE); + udelay(2); + *buffer++ = (u8)(readl(efuse->base + EFUSE_DOUT) & 0xFF); + clrbits_le32(efuse->base + EFUSE_CTRL, EFUSE_STROBE); + udelay(2); + } + + /* Switch to inactive mode */ + writel(0x0, efuse->base + EFUSE_CTRL); + + return 0; +} + static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset, void *buf, int size) { @@ -211,6 +241,11 @@ static int rockchip_efuse_of_to_plat(struct udevice *dev) return 0; }
+static const struct rockchip_efuse_data rk3128_data = { + .read = rockchip_rk3128_efuse_read, + .size = 0x40, +}; + static const struct rockchip_efuse_data rk3288_data = { .read = rockchip_rk3288_efuse_read, .size = 0x20, @@ -234,6 +269,10 @@ static const struct udevice_id rockchip_efuse_ids[] = { .compatible = "rockchip,rk3066a-efuse", .data = (ulong)&rk3288_data, }, + { + .compatible = "rockchip,rk3128-efuse", + .data = (ulong)&rk3128_data, + }, { .compatible = "rockchip,rk3188-efuse", .data = (ulong)&rk3288_data,

Read cpuid from otp and set ethaddr for RK3588.
Signed-off-by: Jonas Karlman jonas@kwiboo.se --- v2: - New patch
arch/arm/dts/rk3588s-u-boot.dtsi | 12 ++++++++++++ arch/arm/mach-rockchip/Kconfig | 2 ++ 2 files changed, 14 insertions(+)
diff --git a/arch/arm/dts/rk3588s-u-boot.dtsi b/arch/arm/dts/rk3588s-u-boot.dtsi index 58123489f3c1..f880f4a16741 100644 --- a/arch/arm/dts/rk3588s-u-boot.dtsi +++ b/arch/arm/dts/rk3588s-u-boot.dtsi @@ -31,6 +31,18 @@ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; status = "disabled"; }; + + otp: nvmem@fecc0000 { + compatible = "rockchip,rk3588-otp"; + reg = <0x0 0xfecc0000 0x0 0x400>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + cpu_id: id@7 { + reg = <0x07 0x10>; + }; + }; };
&xin24m { diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 88be06811c53..0390431601f9 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -310,6 +310,8 @@ config ROCKCHIP_RK3588 select SYSCON select BOARD_LATE_INIT imply ROCKCHIP_COMMON_BOARD + imply ROCKCHIP_OTP + imply MISC_INIT_R help The Rockchip RK3588 is a ARM-based SoC with quad-core Cortex-A76 and quad-core Cortex-A55 including NEON and GPU, 6TOPS NPU, Mali-G610 MP4,

On 2023/2/23 06:44, Jonas Karlman wrote:
Read cpuid from otp and set ethaddr for RK3588.
Signed-off-by: Jonas Karlman jonas@kwiboo.se
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
v2:
New patch
arch/arm/dts/rk3588s-u-boot.dtsi | 12 ++++++++++++ arch/arm/mach-rockchip/Kconfig | 2 ++ 2 files changed, 14 insertions(+)
diff --git a/arch/arm/dts/rk3588s-u-boot.dtsi b/arch/arm/dts/rk3588s-u-boot.dtsi index 58123489f3c1..f880f4a16741 100644 --- a/arch/arm/dts/rk3588s-u-boot.dtsi +++ b/arch/arm/dts/rk3588s-u-boot.dtsi @@ -31,6 +31,18 @@ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>; status = "disabled"; };
otp: nvmem@fecc0000 {
compatible = "rockchip,rk3588-otp";
reg = <0x0 0xfecc0000 0x0 0x400>;
#address-cells = <1>;
#size-cells = <1>;
status = "okay";
cpu_id: id@7 {
reg = <0x07 0x10>;
};
}; };
&xin24m {
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 88be06811c53..0390431601f9 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -310,6 +310,8 @@ config ROCKCHIP_RK3588 select SYSCON select BOARD_LATE_INIT imply ROCKCHIP_COMMON_BOARD
- imply ROCKCHIP_OTP
- imply MISC_INIT_R help The Rockchip RK3588 is a ARM-based SoC with quad-core Cortex-A76 and quad-core Cortex-A55 including NEON and GPU, 6TOPS NPU, Mali-G610 MP4,

The cpuid on RK3568 is located at 0xa instead of 0x7 as all other SoCs. Add and use a CFG_CPUID_OFFSET to define this offset.
Signed-off-by: Jonas Karlman jonas@kwiboo.se Reviewed-by: Kever Yang kever.yang@rock-chips.com --- v2: - Use ifdef instead of undef - Collect r-b tag
arch/arm/dts/rk356x-u-boot.dtsi | 12 ++++++++++++ arch/arm/mach-rockchip/Kconfig | 2 ++ arch/arm/mach-rockchip/board.c | 2 +- include/configs/rk3568_common.h | 2 ++ include/configs/rockchip-common.h | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/rk356x-u-boot.dtsi b/arch/arm/dts/rk356x-u-boot.dtsi index 4e2d059fcf7d..23316410496d 100644 --- a/arch/arm/dts/rk356x-u-boot.dtsi +++ b/arch/arm/dts/rk356x-u-boot.dtsi @@ -20,6 +20,18 @@ u-boot,dm-pre-reloc; status = "okay"; }; + + otp: nvmem@fe38c000 { + compatible = "rockchip,rk3568-otp"; + reg = <0x0 0xfe38c000 0x0 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + cpu_id: id@a { + reg = <0x0a 0x10>; + }; + }; };
&combphy1 { diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 26ba9deff8a5..88be06811c53 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -289,6 +289,8 @@ config ROCKCHIP_RK3568 select DM_REGULATOR_FIXED select DM_RESET imply ROCKCHIP_COMMON_BOARD + imply ROCKCHIP_OTP + imply MISC_INIT_R help The Rockchip RK3568 is a ARM-based SoC with quad-core Cortex-A55, including NEON and GPU, 512K L3 cache, Mali-G52 based graphics, diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c index ebffb6c3ff0c..f1f70c81d0ca 100644 --- a/arch/arm/mach-rockchip/board.c +++ b/arch/arm/mach-rockchip/board.c @@ -323,7 +323,7 @@ int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) #ifdef CONFIG_MISC_INIT_R __weak int misc_init_r(void) { - const u32 cpuid_offset = 0x7; + const u32 cpuid_offset = CFG_CPUID_OFFSET; const u32 cpuid_length = 0x10; u8 cpuid[cpuid_length]; int ret; diff --git a/include/configs/rk3568_common.h b/include/configs/rk3568_common.h index ae360105d508..a5e1dde50888 100644 --- a/include/configs/rk3568_common.h +++ b/include/configs/rk3568_common.h @@ -6,6 +6,8 @@ #ifndef __CONFIG_RK3568_COMMON_H #define __CONFIG_RK3568_COMMON_H
+#define CFG_CPUID_OFFSET 0xa + #include "rockchip-common.h"
#define CFG_IRAM_BASE 0xfdcc0000 diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h index ff8123dabd69..b7c5c6634394 100644 --- a/include/configs/rockchip-common.h +++ b/include/configs/rockchip-common.h @@ -7,6 +7,10 @@ #define _ROCKCHIP_COMMON_H_ #include <linux/sizes.h>
+#ifndef CFG_CPUID_OFFSET +#define CFG_CPUID_OFFSET 0x7 +#endif + /* ((CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR - 64) * 512) */
#ifndef CONFIG_SPL_BUILD
participants (2)
-
Jonas Karlman
-
Kever Yang