xref: /rk3399_rockchip-uboot/drivers/misc/rockchip-efuse.c (revision 894688431927c1b73c64860c8aa71463c2593ea2)
1 /*
2  * eFuse driver for Rockchip devices
3  *
4  * Copyright 2017, Theobroma Systems Design und Consulting GmbH
5  * Written by Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <common.h>
11 #include <asm/io.h>
12 #include <command.h>
13 #include <display_options.h>
14 #include <dm.h>
15 #include <linux/arm-smccc.h>
16 #include <linux/bitops.h>
17 #include <linux/delay.h>
18 #include <misc.h>
19 #include <asm/arch/rockchip_smccc.h>
20 
21 #define T_CSB_P_S		0
22 #define T_PGENB_P_S		0
23 #define T_LOAD_P_S		0
24 #define T_ADDR_P_S		0
25 #define T_STROBE_P_S		(0 + 110) /* 1.1us */
26 #define T_CSB_P_L		(0 + 110 + 1000 + 20) /* 200ns */
27 #define T_PGENB_P_L		(0 + 110 + 1000 + 20)
28 #define T_LOAD_P_L		(0 + 110 + 1000 + 20)
29 #define T_ADDR_P_L		(0 + 110 + 1000 + 20)
30 #define T_STROBE_P_L		(0 + 110 + 1000) /* 10us */
31 #define T_CSB_R_S		0
32 #define T_PGENB_R_S		0
33 #define T_LOAD_R_S		0
34 #define T_ADDR_R_S		2
35 #define T_STROBE_R_S		(2 + 3)
36 #define T_CSB_R_L		(2 + 3 + 3 + 3)
37 #define T_PGENB_R_L		(2 + 3 + 3 + 3)
38 #define T_LOAD_R_L		(2 + 3 + 3 + 3)
39 #define T_ADDR_R_L		(2 + 3 + 3 + 2)
40 #define T_STROBE_R_L		(2 + 3 + 3)
41 
42 #define T_CSB_P			0x28
43 #define T_PGENB_P		0x2c
44 #define T_LOAD_P		0x30
45 #define T_ADDR_P		0x34
46 #define T_STROBE_P		0x38
47 #define T_CSB_R			0x3c
48 #define T_PGENB_R		0x40
49 #define T_LOAD_R		0x44
50 #define T_ADDR_R		0x48
51 #define T_STROBE_R		0x4c
52 
53 #define RK1808_USER_MODE	BIT(0)
54 #define RK1808_INT_FINISH	BIT(0)
55 #define RK1808_AUTO_ENB		BIT(0)
56 #define RK1808_AUTO_RD		BIT(1)
57 #define RK1808_A_SHIFT		16
58 #define RK1808_A_MASK		0x3ff
59 #define RK1808_NBYTES		4
60 
61 #define RK3399_A_SHIFT          16
62 #define RK3399_A_MASK           0x3ff
63 #define RK3399_NFUSES           32
64 #define RK3399_BYTES_PER_FUSE   4
65 #define RK3399_STROBSFTSEL      BIT(9)
66 #define RK3399_RSB              BIT(7)
67 #define RK3399_PD               BIT(5)
68 #define RK3399_PGENB            BIT(3)
69 #define RK3399_LOAD             BIT(2)
70 #define RK3399_STROBE           BIT(1)
71 #define RK3399_CSB              BIT(0)
72 
73 #define RK3288_A_SHIFT          6
74 #define RK3288_A_MASK           0x3ff
75 #define RK3288_NFUSES           32
76 #define RK3288_BYTES_PER_FUSE   1
77 #define RK3288_PGENB            BIT(3)
78 #define RK3288_LOAD             BIT(2)
79 #define RK3288_STROBE           BIT(1)
80 #define RK3288_CSB              BIT(0)
81 
82 #define RK3328_INT_STATUS	0x0018
83 #define RK3328_DOUT		0x0020
84 #define RK3328_AUTO_CTRL	0x0024
85 #define RK3328_INT_FINISH	BIT(0)
86 #define RK3328_AUTO_ENB		BIT(0)
87 #define RK3328_AUTO_RD		BIT(1)
88 
89 typedef int (*EFUSE_READ)(struct udevice *dev, int offset, void *buf, int size);
90 
91 struct rockchip_efuse_regs {
92 	u32 ctrl;      /* 0x00  efuse control register */
93 	u32 dout;      /* 0x04  efuse data out register */
94 	u32 rf;        /* 0x08  efuse redundancy bit used register */
95 	u32 _rsvd0;
96 	u32 jtag_pass; /* 0x10  JTAG password */
97 	u32 strobe_finish_ctrl;
98 		       /* 0x14	efuse strobe finish control register */
99 	u32 int_status;/* 0x18 */
100 	u32 reserved;  /* 0x1c */
101 	u32 dout2;     /* 0x20 */
102 	u32 auto_ctrl; /* 0x24 */
103 };
104 
105 struct rockchip_efuse_platdata {
106 	void __iomem *base;
107 	struct clk *clk;
108 };
109 
110 static void rk1808_efuse_timing_init(void __iomem *base)
111 {
112 	static bool init;
113 
114 	if (init)
115 		return;
116 
117 	/* enable auto mode */
118 	writel(readl(base) & (~RK1808_USER_MODE), base);
119 
120 	/* setup efuse timing */
121 	writel((T_CSB_P_S << 16) | T_CSB_P_L, base + T_CSB_P);
122 	writel((T_PGENB_P_S << 16) | T_PGENB_P_L, base + T_PGENB_P);
123 	writel((T_LOAD_P_S << 16) | T_LOAD_P_L, base + T_LOAD_P);
124 	writel((T_ADDR_P_S << 16) | T_ADDR_P_L, base + T_ADDR_P);
125 	writel((T_STROBE_P_S << 16) | T_STROBE_P_L, base + T_STROBE_P);
126 	writel((T_CSB_R_S << 16) | T_CSB_R_L, base + T_CSB_R);
127 	writel((T_PGENB_R_S << 16) | T_PGENB_R_L, base + T_PGENB_R);
128 	writel((T_LOAD_R_S << 16) | T_LOAD_R_L, base + T_LOAD_R);
129 	writel((T_ADDR_R_S << 16) | T_ADDR_R_L, base + T_ADDR_R);
130 	writel((T_STROBE_R_S << 16) | T_STROBE_R_L, base + T_STROBE_R);
131 
132 	init = true;
133 }
134 
135 static int rockchip_rk1808_efuse_read(struct udevice *dev, int offset,
136 				      void *buf, int size)
137 {
138 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
139 	struct rockchip_efuse_regs *efuse =
140 		(struct rockchip_efuse_regs *)plat->base;
141 	unsigned int addr_start, addr_end, addr_offset, addr_len;
142 	u32 out_value, status;
143 	u8 *buffer;
144 	int ret = 0, i = 0;
145 
146 	rk1808_efuse_timing_init(plat->base);
147 
148 	addr_start = rounddown(offset, RK1808_NBYTES) / RK1808_NBYTES;
149 	addr_end = roundup(offset + size, RK1808_NBYTES) / RK1808_NBYTES;
150 	addr_offset = offset % RK1808_NBYTES;
151 	addr_len = addr_end - addr_start;
152 
153 	buffer = calloc(1, sizeof(*buffer) * addr_len * RK1808_NBYTES);
154 	if (!buffer)
155 		return -ENOMEM;
156 
157 	while (addr_len--) {
158 		writel(RK1808_AUTO_RD | RK1808_AUTO_ENB |
159 		       ((addr_start++ & RK1808_A_MASK) << RK1808_A_SHIFT),
160 		       &efuse->auto_ctrl);
161 		udelay(2);
162 		status = readl(&efuse->int_status);
163 		if (!(status & RK1808_INT_FINISH)) {
164 			ret = -EIO;
165 			goto err;
166 		}
167 		out_value = readl(&efuse->dout2);
168 		writel(RK1808_INT_FINISH, &efuse->int_status);
169 
170 		memcpy(&buffer[i], &out_value, RK1808_NBYTES);
171 		i += RK1808_NBYTES;
172 	}
173 	memcpy(buf, buffer + addr_offset, size);
174 err:
175 	kfree(buffer);
176 
177 	return ret;
178 }
179 
180 static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset,
181 				      void *buf, int size)
182 {
183 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
184 	struct rockchip_efuse_regs *efuse =
185 		(struct rockchip_efuse_regs *)plat->base;
186 
187 	unsigned int addr_start, addr_end, addr_offset;
188 	u32 out_value;
189 	u8  bytes[RK3399_NFUSES * RK3399_BYTES_PER_FUSE];
190 	int i = 0;
191 	u32 addr;
192 
193 	addr_start = offset / RK3399_BYTES_PER_FUSE;
194 	addr_offset = offset % RK3399_BYTES_PER_FUSE;
195 	addr_end = DIV_ROUND_UP(offset + size, RK3399_BYTES_PER_FUSE);
196 
197 	/* cap to the size of the efuse block */
198 	if (addr_end > RK3399_NFUSES)
199 		addr_end = RK3399_NFUSES;
200 
201 	writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB,
202 	       &efuse->ctrl);
203 	udelay(1);
204 	for (addr = addr_start; addr < addr_end; addr++) {
205 		setbits_le32(&efuse->ctrl,
206 			     RK3399_STROBE | (addr << RK3399_A_SHIFT));
207 		udelay(1);
208 		out_value = readl(&efuse->dout);
209 		clrbits_le32(&efuse->ctrl, RK3399_STROBE);
210 		udelay(1);
211 
212 		memcpy(&bytes[i], &out_value, RK3399_BYTES_PER_FUSE);
213 		i += RK3399_BYTES_PER_FUSE;
214 	}
215 
216 	/* Switch to standby mode */
217 	writel(RK3399_PD | RK3399_CSB, &efuse->ctrl);
218 
219 	memcpy(buf, bytes + addr_offset, size);
220 
221 	return 0;
222 }
223 
224 static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset,
225 				      void *buf, int size)
226 {
227 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
228 	struct rockchip_efuse_regs *efuse =
229 		(struct rockchip_efuse_regs *)plat->base;
230 	u8 *buffer = buf;
231 	int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE;
232 
233 	if (size > (max_size - offset))
234 		size = max_size - offset;
235 
236 	/* Switch to read mode */
237 	writel(RK3288_LOAD | RK3288_PGENB, &efuse->ctrl);
238 	udelay(1);
239 
240 	while (size--) {
241 		writel(readl(&efuse->ctrl) &
242 				(~(RK3288_A_MASK << RK3288_A_SHIFT)),
243 				&efuse->ctrl);
244 		/* set addr */
245 		writel(readl(&efuse->ctrl) |
246 				((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT),
247 				&efuse->ctrl);
248 		udelay(1);
249 		/* strobe low to high */
250 		writel(readl(&efuse->ctrl) |
251 				RK3288_STROBE, &efuse->ctrl);
252 		ndelay(60);
253 		/* read data */
254 		*buffer++ = readl(&efuse->dout);
255 		/* reset strobe to low */
256 		writel(readl(&efuse->ctrl) &
257 				(~RK3288_STROBE), &efuse->ctrl);
258 		udelay(1);
259 	}
260 
261 	/* Switch to standby mode */
262 	writel(RK3288_PGENB | RK3288_CSB, &efuse->ctrl);
263 
264 	return 0;
265 }
266 
267 #ifndef CONFIG_SPL_BUILD
268 static int rockchip_rk3288_efuse_secure_read(struct udevice *dev, int offset,
269 					     void *buf, int size)
270 {
271 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
272 	struct rockchip_efuse_regs *efuse =
273 		(struct rockchip_efuse_regs *)plat->base;
274 	u8 *buffer = buf;
275 	int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE;
276 	struct arm_smccc_res res;
277 
278 	if (size > (max_size - offset))
279 		size = max_size - offset;
280 
281 	/* Switch to read mode */
282 	sip_smc_secure_reg_write((ulong)&efuse->ctrl,
283 				 RK3288_LOAD | RK3288_PGENB);
284 	udelay(1);
285 	while (size--) {
286 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
287 		sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 &
288 					 (~(RK3288_A_MASK << RK3288_A_SHIFT)));
289 		/* set addr */
290 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
291 		sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 |
292 					 ((offset++ & RK3288_A_MASK) <<
293 					  RK3288_A_SHIFT));
294 		udelay(1);
295 		/* strobe low to high */
296 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
297 		sip_smc_secure_reg_write((ulong)&efuse->ctrl,
298 					 res.a1 | RK3288_STROBE);
299 		ndelay(60);
300 		/* read data */
301 		res = sip_smc_secure_reg_read((ulong)&efuse->dout);
302 		*buffer++ = res.a1;
303 		/* reset strobe to low */
304 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
305 		sip_smc_secure_reg_write((ulong)&efuse->ctrl,
306 					 res.a1 & (~RK3288_STROBE));
307 		udelay(1);
308 	}
309 
310 	/* Switch to standby mode */
311 	sip_smc_secure_reg_write((ulong)&efuse->ctrl,
312 				 RK3288_PGENB | RK3288_CSB);
313 
314 	return 0;
315 }
316 #endif
317 
318 static int rockchip_rk3328_efuse_read(struct udevice *dev, int offset,
319 				      void *buf, int size)
320 {
321 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
322 	struct rockchip_efuse_regs *efuse =
323 		(struct rockchip_efuse_regs *)plat->base;
324 	unsigned int addr_start, addr_end, addr_offset, addr_len;
325 	u32 out_value, status;
326 	u8 *buffer;
327 	int ret = 0, i = 0, j = 0;
328 
329 	/* Max non-secure Byte */
330 	if (size > 32)
331 		size = 32;
332 
333 	/* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */
334 	offset += 96;
335 	addr_start = rounddown(offset, RK3399_BYTES_PER_FUSE) /
336 						RK3399_BYTES_PER_FUSE;
337 	addr_end = roundup(offset + size, RK3399_BYTES_PER_FUSE) /
338 						RK3399_BYTES_PER_FUSE;
339 	addr_offset = offset % RK3399_BYTES_PER_FUSE;
340 	addr_len = addr_end - addr_start;
341 
342 	buffer = calloc(1, sizeof(*buffer) * addr_len * RK3399_BYTES_PER_FUSE);
343 	if (!buffer)
344 		return -ENOMEM;
345 
346 	for (j = 0; j < addr_len; j++) {
347 		writel(RK3328_AUTO_RD | RK3328_AUTO_ENB |
348 		       ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT),
349 		         &efuse->auto_ctrl);
350 		udelay(5);
351 		status = readl(&efuse->int_status);
352 		if (!(status & RK3328_INT_FINISH)) {
353 			ret = -EIO;
354 			goto err;
355 		}
356 		out_value = readl(&efuse->dout2);
357 		writel(RK3328_INT_FINISH, &efuse->int_status);
358 
359 		memcpy(&buffer[i], &out_value, RK3399_BYTES_PER_FUSE);
360 		i += RK3399_BYTES_PER_FUSE;
361 	}
362 	memcpy(buf, buffer + addr_offset, size);
363 err:
364 	free(buffer);
365 
366 	return ret;
367 }
368 
369 static int rockchip_efuse_read(struct udevice *dev, int offset,
370 			       void *buf, int size)
371 {
372 	EFUSE_READ efuse_read = NULL;
373 
374 	efuse_read = (EFUSE_READ)dev_get_driver_data(dev);
375 	if (!efuse_read)
376 		return -ENOSYS;
377 
378 	return (*efuse_read)(dev, offset, buf, size);
379 }
380 
381 static int rockchip_efuse_capatiblity(struct udevice *dev, u32 *buf)
382 {
383 	*buf = device_is_compatible(dev, "rockchip,rk3288-secure-efuse") ?
384 	       OTP_S : OTP_NS;
385 
386 	return 0;
387 }
388 
389 static int rockchip_efuse_ioctl(struct udevice *dev, unsigned long request,
390 				void *buf)
391 {
392 	int ret = -EINVAL;
393 
394 	switch (request) {
395 	case IOCTL_REQ_CAPABILITY:
396 		ret = rockchip_efuse_capatiblity(dev, buf);
397 		break;
398 	}
399 
400 	return ret;
401 }
402 
403 static const struct misc_ops rockchip_efuse_ops = {
404 	.read = rockchip_efuse_read,
405 	.ioctl = rockchip_efuse_ioctl,
406 };
407 
408 static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev)
409 {
410 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
411 
412 	plat->base = dev_read_addr_ptr(dev);
413 	return 0;
414 }
415 
416 static const struct udevice_id rockchip_efuse_ids[] = {
417 	{
418 		.compatible = "rockchip,rk1808-efuse",
419 		.data = (ulong)&rockchip_rk1808_efuse_read,
420 	},
421 #ifndef CONFIG_SPL_BUILD
422 	{
423 		.compatible = "rockchip,rk3288-secure-efuse",
424 		.data = (ulong)&rockchip_rk3288_efuse_secure_read,
425 	},
426 #endif
427 	{
428 		.compatible = "rockchip,rk3066a-efuse",
429 		.data = (ulong)&rockchip_rk3288_efuse_read,
430 	},
431 	{
432 		.compatible = "rockchip,rk3188-efuse",
433 		.data = (ulong)&rockchip_rk3288_efuse_read,
434 	},
435 	{
436 		.compatible = "rockchip,rk322x-efuse",
437 		.data = (ulong)&rockchip_rk3288_efuse_read,
438 	},
439 	{
440 		.compatible = "rockchip,rk3328-efuse",
441 		.data = (ulong)&rockchip_rk3328_efuse_read,
442 	},
443 	{
444 		.compatible = "rockchip,rk3399-efuse",
445 		.data = (ulong)&rockchip_rk3399_efuse_read,
446 	},
447 	{}
448 };
449 
450 U_BOOT_DRIVER(rockchip_efuse) = {
451 	.name = "rockchip_efuse",
452 	.id = UCLASS_MISC,
453 	.of_match = rockchip_efuse_ids,
454 	.ofdata_to_platdata = rockchip_efuse_ofdata_to_platdata,
455 	.platdata_auto_alloc_size = sizeof(struct rockchip_efuse_platdata),
456 	.ops = &rockchip_efuse_ops,
457 };
458