All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] rockchip: efuse: add support for more platfroms
@ 2020-02-20  2:53 Finley Xiao
  2020-02-20  2:53 ` [PATCH 1/6] rockchip: efuse: Add support for rk3288 efuse Finley Xiao
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Finley Xiao @ 2020-02-20  2:53 UTC (permalink / raw)
  To: u-boot

Finley Xiao (6):
  rockchip: efuse: Add support for rk3288 efuse
  rockchip: efuse: Add support for rk3066a efuse
  rockchip: efuse: Add support for rk3188 efuse
  rockchip: efuse: Add support for rk322x efuse
  rockchip: efuse: Add support for rk3328 non-secure efuse
  rockchip: efuse: Add support for rk1808 non-secure efuse

 drivers/misc/rockchip-efuse.c | 271 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 267 insertions(+), 4 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/6] rockchip: efuse: Add support for rk3288 efuse
  2020-02-20  2:53 [PATCH 0/6] rockchip: efuse: add support for more platfroms Finley Xiao
@ 2020-02-20  2:53 ` Finley Xiao
  2020-02-20  2:53 ` [PATCH 1/2] rockchip: efuse: Add support for rk3328 non-secure efuse Finley Xiao
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Finley Xiao @ 2020-02-20  2:53 UTC (permalink / raw)
  To: u-boot

This adds the necessary data for handling eFuse on the rk3288.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
---
 drivers/misc/rockchip-efuse.c | 76 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 72 insertions(+), 4 deletions(-)

diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index 2520c6a38e..f01d877e33 100644
--- a/drivers/misc/rockchip-efuse.c
+++ b/drivers/misc/rockchip-efuse.c
@@ -15,6 +15,15 @@
 #include <linux/delay.h>
 #include <misc.h>
 
+#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 RK3399_A_SHIFT          16
 #define RK3399_A_MASK           0x3ff
 #define RK3399_NFUSES           32
@@ -27,6 +36,9 @@
 #define RK3399_STROBE           BIT(1)
 #define RK3399_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 +65,7 @@ static int dump_efuses(cmd_tbl_t *cmdtp, int flag,
 	 */
 
 	struct udevice *dev;
-	u8 fuses[128];
+	u8 fuses[128] = {0};
 	int ret;
 
 	/* retrieve the device */
@@ -77,12 +89,55 @@ static int dump_efuses(cmd_tbl_t *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",
 	""
 );
 #endif
 
+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_rk3399_efuse_read(struct udevice *dev, int offset,
 				      void *buf, int size)
 {
@@ -130,7 +185,13 @@ 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);
+	EFUSE_READ efuse_read = NULL;
+
+	efuse_read = (EFUSE_READ)dev_get_driver_data(dev);
+	if (!efuse_read)
+		return -EINVAL;
+
+	return (*efuse_read)(dev, offset, buf, size);
 }
 
 static const struct misc_ops rockchip_efuse_ops = {
@@ -146,7 +207,14 @@ static int rockchip_efuse_ofdata_to_platdata(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,rk3399-efuse",
+		.data = (ulong)&rockchip_rk3399_efuse_read,
+	},
 	{}
 };
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 1/2] rockchip: efuse: Add support for rk3328 non-secure efuse
  2020-02-20  2:53 [PATCH 0/6] rockchip: efuse: add support for more platfroms Finley Xiao
  2020-02-20  2:53 ` [PATCH 1/6] rockchip: efuse: Add support for rk3288 efuse Finley Xiao
@ 2020-02-20  2:53 ` Finley Xiao
  2020-02-20  2:53 ` [PATCH 2/2] rockchip: efuse: Add support for rk1808 " Finley Xiao
  2020-02-20  2:53 ` [PATCH 2/6] rockchip: efuse: Add support for rk3066a efuse Finley Xiao
  3 siblings, 0 replies; 7+ messages in thread
From: Finley Xiao @ 2020-02-20  2:53 UTC (permalink / raw)
  To: u-boot

This adds the necessary data for handling eFuse on the rk3328.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
---
 drivers/misc/rockchip-efuse.c | 69 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index 175a7fe2f5..68762d3f6f 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 RK3288_A_SHIFT          6
@@ -24,6 +25,15 @@
 #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)
+#define RK3328_NO_SECURE_BYTES	32
+#define RK3328_SECURE_BYTES	96
+
 #define RK3399_A_SHIFT          16
 #define RK3399_A_MASK           0x3ff
 #define RK3399_NFUSES           32
@@ -47,6 +57,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 {
@@ -138,6 +152,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 > RK3328_NO_SECURE_BYTES)
+		size = RK3328_NO_SECURE_BYTES;
+
+	/* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */
+	offset += RK3328_SECURE_BYTES;
+	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_rk3399_efuse_read(struct udevice *dev, int offset,
 				      void *buf, int size)
 {
@@ -224,6 +289,10 @@ static const struct udevice_id rockchip_efuse_ids[] = {
 		.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.11.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] rockchip: efuse: Add support for rk1808 non-secure efuse
  2020-02-20  2:53 [PATCH 0/6] rockchip: efuse: add support for more platfroms Finley Xiao
  2020-02-20  2:53 ` [PATCH 1/6] rockchip: efuse: Add support for rk3288 efuse Finley Xiao
  2020-02-20  2:53 ` [PATCH 1/2] rockchip: efuse: Add support for rk3328 non-secure efuse Finley Xiao
@ 2020-02-20  2:53 ` Finley Xiao
  2020-03-02  9:42   ` Kever Yang
  2020-02-20  2:53 ` [PATCH 2/6] rockchip: efuse: Add support for rk3066a efuse Finley Xiao
  3 siblings, 1 reply; 7+ messages in thread
From: Finley Xiao @ 2020-02-20  2:53 UTC (permalink / raw)
  To: u-boot

This adds the necessary data for handling eFuse on the rk1808.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
---
 drivers/misc/rockchip-efuse.c | 114 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index 68762d3f6f..778e29f30d 100644
--- a/drivers/misc/rockchip-efuse.c
+++ b/drivers/misc/rockchip-efuse.c
@@ -16,6 +16,46 @@
 #include <malloc.h>
 #include <misc.h>
 
+#define T_CSB_P_S		0
+#define T_PGENB_P_S		0
+#define T_LOAD_P_S		0
+#define T_ADDR_P_S		0
+#define T_STROBE_P_S		(0 + 110) /* 1.1us */
+#define T_CSB_P_L		(0 + 110 + 1000 + 20) /* 200ns */
+#define T_PGENB_P_L		(0 + 110 + 1000 + 20)
+#define T_LOAD_P_L		(0 + 110 + 1000 + 20)
+#define T_ADDR_P_L		(0 + 110 + 1000 + 20)
+#define T_STROBE_P_L		(0 + 110 + 1000) /* 10us */
+#define T_CSB_R_S		0
+#define T_PGENB_R_S		0
+#define T_LOAD_R_S		0
+#define T_ADDR_R_S		2
+#define T_STROBE_R_S		(2 + 3)
+#define T_CSB_R_L		(2 + 3 + 3 + 3)
+#define T_PGENB_R_L		(2 + 3 + 3 + 3)
+#define T_LOAD_R_L		(2 + 3 + 3 + 3)
+#define T_ADDR_R_L		(2 + 3 + 3 + 2)
+#define T_STROBE_R_L		(2 + 3 + 3)
+
+#define T_CSB_P			0x28
+#define T_PGENB_P		0x2c
+#define T_LOAD_P		0x30
+#define T_ADDR_P		0x34
+#define T_STROBE_P		0x38
+#define T_CSB_R			0x3c
+#define T_PGENB_R		0x40
+#define T_LOAD_R		0x44
+#define T_ADDR_R		0x48
+#define T_STROBE_R		0x4c
+
+#define RK1808_USER_MODE	BIT(0)
+#define RK1808_INT_FINISH	BIT(0)
+#define RK1808_AUTO_ENB		BIT(0)
+#define RK1808_AUTO_RD		BIT(1)
+#define RK1808_A_SHIFT		16
+#define RK1808_A_MASK		0x3ff
+#define RK1808_NBYTES		4
+
 #define RK3288_A_SHIFT          6
 #define RK3288_A_MASK           0x3ff
 #define RK3288_NFUSES           32
@@ -109,6 +149,76 @@ U_BOOT_CMD(
 );
 #endif
 
+static void rk1808_efuse_timing_init(void __iomem *base)
+{
+	static bool init;
+
+	if (init)
+		return;
+
+	/* enable auto mode */
+	writel(readl(base) & (~RK1808_USER_MODE), base);
+
+	/* setup efuse timing */
+	writel((T_CSB_P_S << 16) | T_CSB_P_L, base + T_CSB_P);
+	writel((T_PGENB_P_S << 16) | T_PGENB_P_L, base + T_PGENB_P);
+	writel((T_LOAD_P_S << 16) | T_LOAD_P_L, base + T_LOAD_P);
+	writel((T_ADDR_P_S << 16) | T_ADDR_P_L, base + T_ADDR_P);
+	writel((T_STROBE_P_S << 16) | T_STROBE_P_L, base + T_STROBE_P);
+	writel((T_CSB_R_S << 16) | T_CSB_R_L, base + T_CSB_R);
+	writel((T_PGENB_R_S << 16) | T_PGENB_R_L, base + T_PGENB_R);
+	writel((T_LOAD_R_S << 16) | T_LOAD_R_L, base + T_LOAD_R);
+	writel((T_ADDR_R_S << 16) | T_ADDR_R_L, base + T_ADDR_R);
+	writel((T_STROBE_R_S << 16) | T_STROBE_R_L, base + T_STROBE_R);
+
+	init = true;
+}
+
+static int rockchip_rk1808_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;
+
+	rk1808_efuse_timing_init(plat->base);
+
+	addr_start = rounddown(offset, RK1808_NBYTES) / RK1808_NBYTES;
+	addr_end = roundup(offset + size, RK1808_NBYTES) / RK1808_NBYTES;
+	addr_offset = offset % RK1808_NBYTES;
+	addr_len = addr_end - addr_start;
+
+	buffer = calloc(1, sizeof(*buffer) * addr_len * RK1808_NBYTES);
+	if (!buffer)
+		return -ENOMEM;
+
+	while (addr_len--) {
+		writel(RK1808_AUTO_RD | RK1808_AUTO_ENB |
+		       ((addr_start++ & RK1808_A_MASK) << RK1808_A_SHIFT),
+		       &efuse->auto_ctrl);
+		udelay(2);
+		status = readl(&efuse->int_status);
+		if (!(status & RK1808_INT_FINISH)) {
+			ret = -EIO;
+			goto err;
+		}
+		out_value = readl(&efuse->dout2);
+		writel(RK1808_INT_FINISH, &efuse->int_status);
+
+		memcpy(&buffer[i], &out_value, RK1808_NBYTES);
+		i += RK1808_NBYTES;
+	}
+	memcpy(buf, buffer + addr_offset, size);
+err:
+	free(buffer);
+
+	return ret;
+}
+
 static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset,
 				      void *buf, int size)
 {
@@ -273,6 +383,10 @@ static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev)
 
 static const struct udevice_id rockchip_efuse_ids[] = {
 	{
+		.compatible = "rockchip,rk1808-efuse",
+		.data = (ulong)&rockchip_rk1808_efuse_read,
+	},
+	{
 		.compatible = "rockchip,rk3066a-efuse",
 		.data = (ulong)&rockchip_rk3288_efuse_read,
 	},
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/6] rockchip: efuse: Add support for rk3066a efuse
  2020-02-20  2:53 [PATCH 0/6] rockchip: efuse: add support for more platfroms Finley Xiao
                   ` (2 preceding siblings ...)
  2020-02-20  2:53 ` [PATCH 2/2] rockchip: efuse: Add support for rk1808 " Finley Xiao
@ 2020-02-20  2:53 ` Finley Xiao
  3 siblings, 0 replies; 7+ messages in thread
From: Finley Xiao @ 2020-02-20  2:53 UTC (permalink / raw)
  To: u-boot

This adds the necessary data for handling eFuse on the rk3066a.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
---
 drivers/misc/rockchip-efuse.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index f01d877e33..3f2c64b105 100644
--- a/drivers/misc/rockchip-efuse.c
+++ b/drivers/misc/rockchip-efuse.c
@@ -208,6 +208,10 @@ static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev)
 
 static const struct udevice_id rockchip_efuse_ids[] = {
 	{
+		.compatible = "rockchip,rk3066a-efuse",
+		.data = (ulong)&rockchip_rk3288_efuse_read,
+	},
+	{
 		.compatible = "rockchip,rk3288-efuse",
 		.data = (ulong)&rockchip_rk3288_efuse_read,
 	},
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] rockchip: efuse: Add support for rk1808 non-secure efuse
  2020-02-20  2:53 ` [PATCH 2/2] rockchip: efuse: Add support for rk1808 " Finley Xiao
@ 2020-03-02  9:42   ` Kever Yang
  0 siblings, 0 replies; 7+ messages in thread
From: Kever Yang @ 2020-03-02  9:42 UTC (permalink / raw)
  To: u-boot

Hi Finley,


 ??? NAK for this patch, rk1808 is not support by upstream U-Boot now.


Thanks,

- Kever

On 2020/2/20 ??10:53, Finley Xiao wrote:
> This adds the necessary data for handling eFuse on the rk1808.
>
> Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
> ---
>   drivers/misc/rockchip-efuse.c | 114 ++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 114 insertions(+)
>
> diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
> index 68762d3f6f..778e29f30d 100644
> --- a/drivers/misc/rockchip-efuse.c
> +++ b/drivers/misc/rockchip-efuse.c
> @@ -16,6 +16,46 @@
>   #include <malloc.h>
>   #include <misc.h>
>   
> +#define T_CSB_P_S		0
> +#define T_PGENB_P_S		0
> +#define T_LOAD_P_S		0
> +#define T_ADDR_P_S		0
> +#define T_STROBE_P_S		(0 + 110) /* 1.1us */
> +#define T_CSB_P_L		(0 + 110 + 1000 + 20) /* 200ns */
> +#define T_PGENB_P_L		(0 + 110 + 1000 + 20)
> +#define T_LOAD_P_L		(0 + 110 + 1000 + 20)
> +#define T_ADDR_P_L		(0 + 110 + 1000 + 20)
> +#define T_STROBE_P_L		(0 + 110 + 1000) /* 10us */
> +#define T_CSB_R_S		0
> +#define T_PGENB_R_S		0
> +#define T_LOAD_R_S		0
> +#define T_ADDR_R_S		2
> +#define T_STROBE_R_S		(2 + 3)
> +#define T_CSB_R_L		(2 + 3 + 3 + 3)
> +#define T_PGENB_R_L		(2 + 3 + 3 + 3)
> +#define T_LOAD_R_L		(2 + 3 + 3 + 3)
> +#define T_ADDR_R_L		(2 + 3 + 3 + 2)
> +#define T_STROBE_R_L		(2 + 3 + 3)
> +
> +#define T_CSB_P			0x28
> +#define T_PGENB_P		0x2c
> +#define T_LOAD_P		0x30
> +#define T_ADDR_P		0x34
> +#define T_STROBE_P		0x38
> +#define T_CSB_R			0x3c
> +#define T_PGENB_R		0x40
> +#define T_LOAD_R		0x44
> +#define T_ADDR_R		0x48
> +#define T_STROBE_R		0x4c
> +
> +#define RK1808_USER_MODE	BIT(0)
> +#define RK1808_INT_FINISH	BIT(0)
> +#define RK1808_AUTO_ENB		BIT(0)
> +#define RK1808_AUTO_RD		BIT(1)
> +#define RK1808_A_SHIFT		16
> +#define RK1808_A_MASK		0x3ff
> +#define RK1808_NBYTES		4
> +
>   #define RK3288_A_SHIFT          6
>   #define RK3288_A_MASK           0x3ff
>   #define RK3288_NFUSES           32
> @@ -109,6 +149,76 @@ U_BOOT_CMD(
>   );
>   #endif
>   
> +static void rk1808_efuse_timing_init(void __iomem *base)
> +{
> +	static bool init;
> +
> +	if (init)
> +		return;
> +
> +	/* enable auto mode */
> +	writel(readl(base) & (~RK1808_USER_MODE), base);
> +
> +	/* setup efuse timing */
> +	writel((T_CSB_P_S << 16) | T_CSB_P_L, base + T_CSB_P);
> +	writel((T_PGENB_P_S << 16) | T_PGENB_P_L, base + T_PGENB_P);
> +	writel((T_LOAD_P_S << 16) | T_LOAD_P_L, base + T_LOAD_P);
> +	writel((T_ADDR_P_S << 16) | T_ADDR_P_L, base + T_ADDR_P);
> +	writel((T_STROBE_P_S << 16) | T_STROBE_P_L, base + T_STROBE_P);
> +	writel((T_CSB_R_S << 16) | T_CSB_R_L, base + T_CSB_R);
> +	writel((T_PGENB_R_S << 16) | T_PGENB_R_L, base + T_PGENB_R);
> +	writel((T_LOAD_R_S << 16) | T_LOAD_R_L, base + T_LOAD_R);
> +	writel((T_ADDR_R_S << 16) | T_ADDR_R_L, base + T_ADDR_R);
> +	writel((T_STROBE_R_S << 16) | T_STROBE_R_L, base + T_STROBE_R);
> +
> +	init = true;
> +}
> +
> +static int rockchip_rk1808_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;
> +
> +	rk1808_efuse_timing_init(plat->base);
> +
> +	addr_start = rounddown(offset, RK1808_NBYTES) / RK1808_NBYTES;
> +	addr_end = roundup(offset + size, RK1808_NBYTES) / RK1808_NBYTES;
> +	addr_offset = offset % RK1808_NBYTES;
> +	addr_len = addr_end - addr_start;
> +
> +	buffer = calloc(1, sizeof(*buffer) * addr_len * RK1808_NBYTES);
> +	if (!buffer)
> +		return -ENOMEM;
> +
> +	while (addr_len--) {
> +		writel(RK1808_AUTO_RD | RK1808_AUTO_ENB |
> +		       ((addr_start++ & RK1808_A_MASK) << RK1808_A_SHIFT),
> +		       &efuse->auto_ctrl);
> +		udelay(2);
> +		status = readl(&efuse->int_status);
> +		if (!(status & RK1808_INT_FINISH)) {
> +			ret = -EIO;
> +			goto err;
> +		}
> +		out_value = readl(&efuse->dout2);
> +		writel(RK1808_INT_FINISH, &efuse->int_status);
> +
> +		memcpy(&buffer[i], &out_value, RK1808_NBYTES);
> +		i += RK1808_NBYTES;
> +	}
> +	memcpy(buf, buffer + addr_offset, size);
> +err:
> +	free(buffer);
> +
> +	return ret;
> +}
> +
>   static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset,
>   				      void *buf, int size)
>   {
> @@ -273,6 +383,10 @@ static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev)
>   
>   static const struct udevice_id rockchip_efuse_ids[] = {
>   	{
> +		.compatible = "rockchip,rk1808-efuse",
> +		.data = (ulong)&rockchip_rk1808_efuse_read,
> +	},
> +	{
>   		.compatible = "rockchip,rk3066a-efuse",
>   		.data = (ulong)&rockchip_rk3288_efuse_read,
>   	},

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] rockchip: efuse: Add support for rk3328 non-secure efuse
  2020-02-20  2:38 [PATCH 0/6] rockchip: efuse: add support for more platfroms Finley Xiao
@ 2020-02-20  2:38 ` Finley Xiao
  0 siblings, 0 replies; 7+ messages in thread
From: Finley Xiao @ 2020-02-20  2:38 UTC (permalink / raw)
  To: u-boot

This adds the necessary data for handling eFuse on the rk3328.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
---
 drivers/misc/rockchip-efuse.c | 69 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/misc/rockchip-efuse.c b/drivers/misc/rockchip-efuse.c
index 175a7fe2f5..68762d3f6f 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 RK3288_A_SHIFT          6
@@ -24,6 +25,15 @@
 #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)
+#define RK3328_NO_SECURE_BYTES	32
+#define RK3328_SECURE_BYTES	96
+
 #define RK3399_A_SHIFT          16
 #define RK3399_A_MASK           0x3ff
 #define RK3399_NFUSES           32
@@ -47,6 +57,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 {
@@ -138,6 +152,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 > RK3328_NO_SECURE_BYTES)
+		size = RK3328_NO_SECURE_BYTES;
+
+	/* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */
+	offset += RK3328_SECURE_BYTES;
+	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_rk3399_efuse_read(struct udevice *dev, int offset,
 				      void *buf, int size)
 {
@@ -224,6 +289,10 @@ static const struct udevice_id rockchip_efuse_ids[] = {
 		.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.11.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-03-02  9:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-20  2:53 [PATCH 0/6] rockchip: efuse: add support for more platfroms Finley Xiao
2020-02-20  2:53 ` [PATCH 1/6] rockchip: efuse: Add support for rk3288 efuse Finley Xiao
2020-02-20  2:53 ` [PATCH 1/2] rockchip: efuse: Add support for rk3328 non-secure efuse Finley Xiao
2020-02-20  2:53 ` [PATCH 2/2] rockchip: efuse: Add support for rk1808 " Finley Xiao
2020-03-02  9:42   ` Kever Yang
2020-02-20  2:53 ` [PATCH 2/6] rockchip: efuse: Add support for rk3066a efuse Finley Xiao
  -- strict thread matches above, loose matches on Subject: below --
2020-02-20  2:38 [PATCH 0/6] rockchip: efuse: add support for more platfroms Finley Xiao
2020-02-20  2:38 ` [PATCH 1/2] rockchip: efuse: Add support for rk3328 non-secure efuse Finley Xiao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.