xref: /OK3568_Linux_fs/u-boot/drivers/misc/rockchip-efuse.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
rk1808_efuse_timing_init(void __iomem * base)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 
rockchip_rk1808_efuse_read(struct udevice * dev,int offset,void * buf,int size)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 #ifndef CONFIG_SPL_BUILD
rockchip_rk3368_efuse_read(struct udevice * dev,int offset,void * buf,int size)181 static int rockchip_rk3368_efuse_read(struct udevice *dev, int offset,
182 				      void *buf, int size)
183 {
184 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
185 	struct rockchip_efuse_regs *efuse =
186 		(struct rockchip_efuse_regs *)plat->base;
187 	u8 *buffer = buf;
188 	struct arm_smccc_res res;
189 
190 	/* Switch to read mode */
191 	sip_smc_secure_reg_write((ulong)&efuse->ctrl,
192 				 RK3288_LOAD | RK3288_PGENB);
193 	udelay(1);
194 	while (size--) {
195 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
196 		sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 &
197 					 (~(RK3288_A_MASK << RK3288_A_SHIFT)));
198 		/* set addr */
199 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
200 		sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 |
201 					 ((offset++ & RK3288_A_MASK) <<
202 					  RK3288_A_SHIFT));
203 		udelay(1);
204 		/* strobe low to high */
205 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
206 		sip_smc_secure_reg_write((ulong)&efuse->ctrl,
207 					 res.a1 | RK3288_STROBE);
208 		ndelay(60);
209 		/* read data */
210 		res = sip_smc_secure_reg_read((ulong)&efuse->dout);
211 		*buffer++ = res.a1;
212 		/* reset strobe to low */
213 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
214 		sip_smc_secure_reg_write((ulong)&efuse->ctrl,
215 					 res.a1 & (~RK3288_STROBE));
216 		udelay(1);
217 	}
218 
219 	/* Switch to standby mode */
220 	sip_smc_secure_reg_write((ulong)&efuse->ctrl,
221 				 RK3288_PGENB | RK3288_CSB);
222 
223 	return 0;
224 }
225 #endif
226 
rockchip_rk3399_efuse_read(struct udevice * dev,int offset,void * buf,int size)227 static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset,
228 				      void *buf, int size)
229 {
230 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
231 	struct rockchip_efuse_regs *efuse =
232 		(struct rockchip_efuse_regs *)plat->base;
233 
234 	unsigned int addr_start, addr_end, addr_offset;
235 	u32 out_value;
236 	u8  bytes[RK3399_NFUSES * RK3399_BYTES_PER_FUSE];
237 	int i = 0;
238 	u32 addr;
239 
240 	addr_start = offset / RK3399_BYTES_PER_FUSE;
241 	addr_offset = offset % RK3399_BYTES_PER_FUSE;
242 	addr_end = DIV_ROUND_UP(offset + size, RK3399_BYTES_PER_FUSE);
243 
244 	/* cap to the size of the efuse block */
245 	if (addr_end > RK3399_NFUSES)
246 		addr_end = RK3399_NFUSES;
247 
248 	writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB,
249 	       &efuse->ctrl);
250 	udelay(1);
251 	for (addr = addr_start; addr < addr_end; addr++) {
252 		setbits_le32(&efuse->ctrl,
253 			     RK3399_STROBE | (addr << RK3399_A_SHIFT));
254 		udelay(1);
255 		out_value = readl(&efuse->dout);
256 		clrbits_le32(&efuse->ctrl, RK3399_STROBE);
257 		udelay(1);
258 
259 		memcpy(&bytes[i], &out_value, RK3399_BYTES_PER_FUSE);
260 		i += RK3399_BYTES_PER_FUSE;
261 	}
262 
263 	/* Switch to standby mode */
264 	writel(RK3399_PD | RK3399_CSB, &efuse->ctrl);
265 
266 	memcpy(buf, bytes + addr_offset, size);
267 
268 	return 0;
269 }
270 
rockchip_rk3288_efuse_read(struct udevice * dev,int offset,void * buf,int size)271 static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset,
272 				      void *buf, int size)
273 {
274 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
275 	struct rockchip_efuse_regs *efuse =
276 		(struct rockchip_efuse_regs *)plat->base;
277 	u8 *buffer = buf;
278 	int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE;
279 
280 	if (size > (max_size - offset))
281 		size = max_size - offset;
282 
283 	/* Switch to read mode */
284 	writel(RK3288_LOAD | RK3288_PGENB, &efuse->ctrl);
285 	udelay(1);
286 
287 	while (size--) {
288 		writel(readl(&efuse->ctrl) &
289 				(~(RK3288_A_MASK << RK3288_A_SHIFT)),
290 				&efuse->ctrl);
291 		/* set addr */
292 		writel(readl(&efuse->ctrl) |
293 				((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT),
294 				&efuse->ctrl);
295 		udelay(1);
296 		/* strobe low to high */
297 		writel(readl(&efuse->ctrl) |
298 				RK3288_STROBE, &efuse->ctrl);
299 		ndelay(60);
300 		/* read data */
301 		*buffer++ = readl(&efuse->dout);
302 		/* reset strobe to low */
303 		writel(readl(&efuse->ctrl) &
304 				(~RK3288_STROBE), &efuse->ctrl);
305 		udelay(1);
306 	}
307 
308 	/* Switch to standby mode */
309 	writel(RK3288_PGENB | RK3288_CSB, &efuse->ctrl);
310 
311 	return 0;
312 }
313 
314 #ifndef CONFIG_SPL_BUILD
rockchip_rk3288_efuse_secure_read(struct udevice * dev,int offset,void * buf,int size)315 static int rockchip_rk3288_efuse_secure_read(struct udevice *dev, int offset,
316 					     void *buf, int size)
317 {
318 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
319 	struct rockchip_efuse_regs *efuse =
320 		(struct rockchip_efuse_regs *)plat->base;
321 	u8 *buffer = buf;
322 	int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE;
323 	struct arm_smccc_res res;
324 
325 	if (size > (max_size - offset))
326 		size = max_size - offset;
327 
328 	/* Switch to read mode */
329 	sip_smc_secure_reg_write((ulong)&efuse->ctrl,
330 				 RK3288_LOAD | RK3288_PGENB);
331 	udelay(1);
332 	while (size--) {
333 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
334 		sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 &
335 					 (~(RK3288_A_MASK << RK3288_A_SHIFT)));
336 		/* set addr */
337 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
338 		sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 |
339 					 ((offset++ & RK3288_A_MASK) <<
340 					  RK3288_A_SHIFT));
341 		udelay(1);
342 		/* strobe low to high */
343 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
344 		sip_smc_secure_reg_write((ulong)&efuse->ctrl,
345 					 res.a1 | RK3288_STROBE);
346 		ndelay(60);
347 		/* read data */
348 		res = sip_smc_secure_reg_read((ulong)&efuse->dout);
349 		*buffer++ = res.a1;
350 		/* reset strobe to low */
351 		res = sip_smc_secure_reg_read((ulong)&efuse->ctrl);
352 		sip_smc_secure_reg_write((ulong)&efuse->ctrl,
353 					 res.a1 & (~RK3288_STROBE));
354 		udelay(1);
355 	}
356 
357 	/* Switch to standby mode */
358 	sip_smc_secure_reg_write((ulong)&efuse->ctrl,
359 				 RK3288_PGENB | RK3288_CSB);
360 
361 	return 0;
362 }
363 #endif
364 
rockchip_rk3328_efuse_read(struct udevice * dev,int offset,void * buf,int size)365 static int rockchip_rk3328_efuse_read(struct udevice *dev, int offset,
366 				      void *buf, int size)
367 {
368 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
369 	struct rockchip_efuse_regs *efuse =
370 		(struct rockchip_efuse_regs *)plat->base;
371 	unsigned int addr_start, addr_end, addr_offset, addr_len;
372 	u32 out_value, status;
373 	u8 *buffer;
374 	int ret = 0, i = 0, j = 0;
375 
376 	/* Max non-secure Byte */
377 	if (size > 32)
378 		size = 32;
379 
380 	/* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */
381 	offset += 96;
382 	addr_start = rounddown(offset, RK3399_BYTES_PER_FUSE) /
383 						RK3399_BYTES_PER_FUSE;
384 	addr_end = roundup(offset + size, RK3399_BYTES_PER_FUSE) /
385 						RK3399_BYTES_PER_FUSE;
386 	addr_offset = offset % RK3399_BYTES_PER_FUSE;
387 	addr_len = addr_end - addr_start;
388 
389 	buffer = calloc(1, sizeof(*buffer) * addr_len * RK3399_BYTES_PER_FUSE);
390 	if (!buffer)
391 		return -ENOMEM;
392 
393 	for (j = 0; j < addr_len; j++) {
394 		writel(RK3328_AUTO_RD | RK3328_AUTO_ENB |
395 		       ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT),
396 		         &efuse->auto_ctrl);
397 		udelay(5);
398 		status = readl(&efuse->int_status);
399 		if (!(status & RK3328_INT_FINISH)) {
400 			ret = -EIO;
401 			goto err;
402 		}
403 		out_value = readl(&efuse->dout2);
404 		writel(RK3328_INT_FINISH, &efuse->int_status);
405 
406 		memcpy(&buffer[i], &out_value, RK3399_BYTES_PER_FUSE);
407 		i += RK3399_BYTES_PER_FUSE;
408 	}
409 	memcpy(buf, buffer + addr_offset, size);
410 err:
411 	free(buffer);
412 
413 	return ret;
414 }
415 
rockchip_efuse_read(struct udevice * dev,int offset,void * buf,int size)416 static int rockchip_efuse_read(struct udevice *dev, int offset,
417 			       void *buf, int size)
418 {
419 	EFUSE_READ efuse_read = NULL;
420 
421 	efuse_read = (EFUSE_READ)dev_get_driver_data(dev);
422 	if (!efuse_read)
423 		return -ENOSYS;
424 
425 	return (*efuse_read)(dev, offset, buf, size);
426 }
427 
rockchip_efuse_capatiblity(struct udevice * dev,u32 * buf)428 static int rockchip_efuse_capatiblity(struct udevice *dev, u32 *buf)
429 {
430 	*buf = device_is_compatible(dev, "rockchip,rk3288-secure-efuse") ?
431 	       OTP_S : OTP_NS;
432 
433 	return 0;
434 }
435 
rockchip_efuse_ioctl(struct udevice * dev,unsigned long request,void * buf)436 static int rockchip_efuse_ioctl(struct udevice *dev, unsigned long request,
437 				void *buf)
438 {
439 	int ret = -EINVAL;
440 
441 	switch (request) {
442 	case IOCTL_REQ_CAPABILITY:
443 		ret = rockchip_efuse_capatiblity(dev, buf);
444 		break;
445 	}
446 
447 	return ret;
448 }
449 
450 static const struct misc_ops rockchip_efuse_ops = {
451 	.read = rockchip_efuse_read,
452 	.ioctl = rockchip_efuse_ioctl,
453 };
454 
rockchip_efuse_ofdata_to_platdata(struct udevice * dev)455 static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev)
456 {
457 	struct rockchip_efuse_platdata *plat = dev_get_platdata(dev);
458 
459 	plat->base = dev_read_addr_ptr(dev);
460 	return 0;
461 }
462 
463 static const struct udevice_id rockchip_efuse_ids[] = {
464 	{
465 		.compatible = "rockchip,rk1808-efuse",
466 		.data = (ulong)&rockchip_rk1808_efuse_read,
467 	},
468 #ifndef CONFIG_SPL_BUILD
469 	{
470 		.compatible = "rockchip,rk3288-secure-efuse",
471 		.data = (ulong)&rockchip_rk3288_efuse_secure_read,
472 	},
473 #endif
474 	{
475 		.compatible = "rockchip,rk3066a-efuse",
476 		.data = (ulong)&rockchip_rk3288_efuse_read,
477 	},
478 	{
479 		.compatible = "rockchip,rk3188-efuse",
480 		.data = (ulong)&rockchip_rk3288_efuse_read,
481 	},
482 	{
483 		.compatible = "rockchip,rk322x-efuse",
484 		.data = (ulong)&rockchip_rk3288_efuse_read,
485 	},
486 	{
487 		.compatible = "rockchip,rk3328-efuse",
488 		.data = (ulong)&rockchip_rk3328_efuse_read,
489 	},
490 #ifndef CONFIG_SPL_BUILD
491 	{
492 		.compatible = "rockchip,rk3368-efuse",
493 		.data = (ulong)&rockchip_rk3368_efuse_read,
494 	},
495 #endif
496 	{
497 		.compatible = "rockchip,rk3399-efuse",
498 		.data = (ulong)&rockchip_rk3399_efuse_read,
499 	},
500 	{}
501 };
502 
503 U_BOOT_DRIVER(rockchip_efuse) = {
504 	.name = "rockchip_efuse",
505 	.id = UCLASS_MISC,
506 	.of_match = rockchip_efuse_ids,
507 	.ofdata_to_platdata = rockchip_efuse_ofdata_to_platdata,
508 	.platdata_auto_alloc_size = sizeof(struct rockchip_efuse_platdata),
509 	.ops = &rockchip_efuse_ops,
510 };
511