363 lines
10 KiB
Diff
363 lines
10 KiB
Diff
|
From 768ff9ab40cc54e03895a46a4818d36dec150cac Mon Sep 17 00:00:00 2001
|
||
|
From: Paolo Sabatino <paolo.sabatino@gmail.com>
|
||
|
Date: Sun, 4 Apr 2021 10:29:29 +0000
|
||
|
Subject: [PATCH] Enable rockchip efuse for rk322x, rk3288 and rk3328
|
||
|
|
||
|
---
|
||
|
arch/arm/dts/rk322x.dtsi | 14 +++
|
||
|
arch/arm/dts/rk3288.dtsi | 3 +-
|
||
|
configs/evb-rk3229_defconfig | 3 +
|
||
|
configs/evb-rk3328_defconfig | 3 +
|
||
|
configs/miqi-rk3288_defconfig | 2 +
|
||
|
configs/rock64-rk3328_defconfig | 2 +
|
||
|
configs/tinker-rk3288_defconfig | 1 +
|
||
|
configs/tinker-s-rk3288_defconfig | 1 +
|
||
|
drivers/misc/rockchip-efuse.c | 142 ++++++++++++++++++++++++-
|
||
|
include/dt-bindings/clock/rk3228-cru.h | 4 +
|
||
|
10 files changed, 169 insertions(+), 6 deletions(-)
|
||
|
|
||
|
diff --git a/arch/arm/dts/rk322x.dtsi b/arch/arm/dts/rk322x.dtsi
|
||
|
index 4a8be5dabb..255e3a7a28 100644
|
||
|
--- a/arch/arm/dts/rk322x.dtsi
|
||
|
+++ b/arch/arm/dts/rk322x.dtsi
|
||
|
@@ -212,6 +212,20 @@
|
||
|
status = "disabled";
|
||
|
};
|
||
|
|
||
|
+ efuse: efuse@11040000 {
|
||
|
+ compatible = "rockchip,rk3228-efuse", "rockchip,rk3288-efuse";
|
||
|
+ reg = <0x11040000 0x20>;
|
||
|
+ clocks = <&cru PCLK_EFUSE_256>;
|
||
|
+ clock-names = "pclk_efuse";
|
||
|
+ #address-cells = <1>;
|
||
|
+ #size-cells = <1>;
|
||
|
+
|
||
|
+ /* Data cells */
|
||
|
+ cpu_id: cpu_id@7 {
|
||
|
+ reg = <0x7 0x10>;
|
||
|
+ };
|
||
|
+ };
|
||
|
+
|
||
|
i2c0: i2c@11050000 {
|
||
|
compatible = "rockchip,rk3228-i2c";
|
||
|
reg = <0x11050000 0x1000>;
|
||
|
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 {
|
||
|
diff --git a/configs/evb-rk3229_defconfig b/configs/evb-rk3229_defconfig
|
||
|
index e708ed4909..e3ba0651fd 100644
|
||
|
--- a/configs/evb-rk3229_defconfig
|
||
|
+++ b/configs/evb-rk3229_defconfig
|
||
|
@@ -49,6 +49,8 @@ CONFIG_FASTBOOT_BUF_SIZE=0x04000000
|
||
|
CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
|
||
|
CONFIG_ROCKCHIP_GPIO=y
|
||
|
CONFIG_SYS_I2C_ROCKCHIP=y
|
||
|
+CONFIG_MISC=y
|
||
|
+CONFIG_ROCKCHIP_EFUSE=y
|
||
|
CONFIG_MMC_DW=y
|
||
|
CONFIG_MMC_DW_ROCKCHIP=y
|
||
|
CONFIG_MTD=y
|
||
|
@@ -68,3 +70,4 @@ CONFIG_USB_GADGET=y
|
||
|
CONFIG_USB_GADGET_DWC2_OTG=y
|
||
|
CONFIG_TPL_TINY_MEMSET=y
|
||
|
CONFIG_ERRNO_STR=y
|
||
|
+CONFIG_MISC_INIT_R=y
|
||
|
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
|
||
|
index 9cbfeb0279..f0acfd8abd 100644
|
||
|
--- a/configs/evb-rk3328_defconfig
|
||
|
+++ b/configs/evb-rk3328_defconfig
|
||
|
@@ -20,6 +20,7 @@ CONFIG_FIT=y
|
||
|
CONFIG_FIT_VERBOSE=y
|
||
|
CONFIG_SPL_LOAD_FIT=y
|
||
|
CONFIG_DEFAULT_FDT_FILE="rockchip/rk3328-evb.dtb"
|
||
|
+CONFIG_MISC_INIT_R=y
|
||
|
# CONFIG_DISPLAY_CPUINFO is not set
|
||
|
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||
|
# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
|
||
|
@@ -56,6 +57,8 @@ CONFIG_FASTBOOT_BUF_ADDR=0x800800
|
||
|
CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
|
||
|
CONFIG_ROCKCHIP_GPIO=y
|
||
|
CONFIG_SYS_I2C_ROCKCHIP=y
|
||
|
+CONFIG_MISC=y
|
||
|
+CONFIG_ROCKCHIP_EFUSE=y
|
||
|
CONFIG_MMC_DW=y
|
||
|
CONFIG_MMC_DW_ROCKCHIP=y
|
||
|
CONFIG_SF_DEFAULT_SPEED=20000000
|
||
|
diff --git a/configs/miqi-rk3288_defconfig b/configs/miqi-rk3288_defconfig
|
||
|
index 234ced5ab0..3d42e93866 100644
|
||
|
--- a/configs/miqi-rk3288_defconfig
|
||
|
+++ b/configs/miqi-rk3288_defconfig
|
||
|
@@ -49,6 +49,8 @@ CONFIG_SPL_CLK=y
|
||
|
CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
|
||
|
CONFIG_ROCKCHIP_GPIO=y
|
||
|
CONFIG_SYS_I2C_ROCKCHIP=y
|
||
|
+CONFIG_MISC=y
|
||
|
+CONFIG_ROCKCHIP_EFUSE=y
|
||
|
CONFIG_MMC_DW=y
|
||
|
CONFIG_MMC_DW_ROCKCHIP=y
|
||
|
CONFIG_MTD=y
|
||
|
diff --git a/configs/rock64-rk3328_defconfig b/configs/rock64-rk3328_defconfig
|
||
|
index cb79cea821..dacb57165e 100644
|
||
|
--- a/configs/rock64-rk3328_defconfig
|
||
|
+++ b/configs/rock64-rk3328_defconfig
|
||
|
@@ -57,6 +57,8 @@ CONFIG_FASTBOOT_BUF_ADDR=0x800800
|
||
|
CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
|
||
|
CONFIG_ROCKCHIP_GPIO=y
|
||
|
CONFIG_SYS_I2C_ROCKCHIP=y
|
||
|
+CONFIG_MISC=y
|
||
|
+CONFIG_ROCKCHIP_EFUSE=y
|
||
|
CONFIG_MMC_DW=y
|
||
|
CONFIG_MMC_DW_ROCKCHIP=y
|
||
|
CONFIG_SF_DEFAULT_SPEED=20000000
|
||
|
diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig
|
||
|
index 8686a66d13..b7dc845451 100644
|
||
|
--- a/configs/tinker-rk3288_defconfig
|
||
|
+++ b/configs/tinker-rk3288_defconfig
|
||
|
@@ -52,6 +52,7 @@ CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
|
||
|
CONFIG_ROCKCHIP_GPIO=y
|
||
|
CONFIG_SYS_I2C_ROCKCHIP=y
|
||
|
CONFIG_MISC=y
|
||
|
+CONFIG_ROCKCHIP_EFUSE=y
|
||
|
CONFIG_I2C_EEPROM=y
|
||
|
CONFIG_MMC_DW=y
|
||
|
CONFIG_MMC_DW_ROCKCHIP=y
|
||
|
diff --git a/configs/tinker-s-rk3288_defconfig b/configs/tinker-s-rk3288_defconfig
|
||
|
index 22714833cc..19aa314164 100644
|
||
|
--- a/configs/tinker-s-rk3288_defconfig
|
||
|
+++ b/configs/tinker-s-rk3288_defconfig
|
||
|
@@ -53,6 +53,7 @@ CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
|
||
|
CONFIG_ROCKCHIP_GPIO=y
|
||
|
CONFIG_SYS_I2C_ROCKCHIP=y
|
||
|
CONFIG_MISC=y
|
||
|
+CONFIG_ROCKCHIP_EFUSE=y
|
||
|
CONFIG_I2C_EEPROM=y
|
||
|
CONFIG_MMC_DW=y
|
||
|
CONFIG_MMC_DW_ROCKCHIP=y
|
||
|
diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
|
||
|
index 083ee65e0a..0fcbcfc69a 100644
|
||
|
--- a/drivers/misc/rockchip-efuse.c
|
||
|
+++ b/drivers/misc/rockchip-efuse.c
|
||
|
@@ -14,6 +14,7 @@
|
||
|
#include <linux/bitops.h>
|
||
|
#include <linux/delay.h>
|
||
|
#include <misc.h>
|
||
|
+#include <stdlib.h>
|
||
|
|
||
|
#define RK3399_A_SHIFT 16
|
||
|
#define RK3399_A_MASK 0x3ff
|
||
|
@@ -27,6 +28,24 @@
|
||
|
#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)
|
||
|
+
|
||
|
+#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 {
|
||
|
u32 ctrl; /* 0x00 efuse control register */
|
||
|
u32 dout; /* 0x04 efuse data out register */
|
||
|
@@ -35,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_plat {
|
||
|
@@ -53,7 +76,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 +100,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 +150,110 @@ 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_plat *plat = dev_get_plat(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_rk3328_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, 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)
|
||
|
{
|
||
|
- 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 +269,18 @@ static int rockchip_efuse_of_to_plat(struct udevice *dev)
|
||
|
}
|
||
|
|
||
|
static const struct udevice_id rockchip_efuse_ids[] = {
|
||
|
- { .compatible = "rockchip,rk3399-efuse" },
|
||
|
+ {
|
||
|
+ .compatible = "rockchip,rk3288-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,
|
||
|
+ },
|
||
|
{}
|
||
|
};
|
||
|
|
||
|
diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h
|
||
|
index 1217d5239f..13b2f4e4a4 100644
|
||
|
--- a/include/dt-bindings/clock/rk3228-cru.h
|
||
|
+++ b/include/dt-bindings/clock/rk3228-cru.h
|
||
|
@@ -67,6 +67,10 @@
|
||
|
#define PCLK_GPIO1 321
|
||
|
#define PCLK_GPIO2 322
|
||
|
#define PCLK_GPIO3 323
|
||
|
+#define PCLK_VIO_H2P 324
|
||
|
+#define PCLK_HDCP 325
|
||
|
+#define PCLK_EFUSE_1024 326
|
||
|
+#define PCLK_EFUSE_256 327
|
||
|
#define PCLK_GRF 329
|
||
|
#define PCLK_I2C0 332
|
||
|
#define PCLK_I2C1 333
|
||
|
--
|
||
|
2.25.1
|
||
|
|