1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4 */
5
6 #include <common.h>
7 #include <asm/arch/cpu.h>
8 #include <asm/io.h>
9 #include <command.h>
10 #include <dm.h>
11 #include <linux/bitops.h>
12 #include <linux/delay.h>
13 #include <linux/iopoll.h>
14 #include <misc.h>
15 #include <rockchip-otp.h>
16
17 struct otp_data {
18 int (*init)(struct udevice *dev);
19 int (*read)(struct udevice *dev, int offset, void *buf, int size);
20 };
21
rockchip_otp_wait_status(struct rockchip_otp_platdata * otp,u32 flag)22 static int rockchip_otp_wait_status(struct rockchip_otp_platdata *otp,
23 u32 flag)
24 {
25 int delay = OTPC_TIMEOUT;
26
27 while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) {
28 udelay(1);
29 delay--;
30 if (delay <= 0) {
31 printf("%s: wait init status timeout\n", __func__);
32 return -ETIMEDOUT;
33 }
34 }
35
36 /* clean int status */
37 writel(flag, otp->base + OTPC_INT_STATUS);
38
39 return 0;
40 }
41
rockchip_otp_ecc_enable(struct rockchip_otp_platdata * otp,bool enable)42 static int rockchip_otp_ecc_enable(struct rockchip_otp_platdata *otp,
43 bool enable)
44 {
45 int ret = 0;
46
47 writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT),
48 otp->base + OTPC_SBPI_CTRL);
49
50 writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE);
51 writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC,
52 otp->base + OTPC_SBPI_CMD0_OFFSET);
53 if (enable)
54 writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
55 else
56 writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
57
58 writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
59
60 ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE);
61 if (ret < 0)
62 printf("%s timeout during ecc_enable\n", __func__);
63
64 return ret;
65 }
66
rockchip_px30_otp_read(struct udevice * dev,int offset,void * buf,int size)67 static int rockchip_px30_otp_read(struct udevice *dev, int offset,
68 void *buf, int size)
69 {
70 struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
71 u8 *buffer = buf;
72 int ret = 0;
73
74 ret = rockchip_otp_ecc_enable(otp, false);
75 if (ret < 0) {
76 printf("%s rockchip_otp_ecc_enable err\n", __func__);
77 return ret;
78 }
79
80 writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
81 udelay(5);
82 while (size--) {
83 writel(offset++ | OTPC_USER_ADDR_MASK,
84 otp->base + OTPC_USER_ADDR);
85 writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
86 otp->base + OTPC_USER_ENABLE);
87 ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
88 if (ret < 0) {
89 printf("%s timeout during read setup\n", __func__);
90 goto read_end;
91 }
92 *buffer++ = readb(otp->base + OTPC_USER_Q);
93 }
94
95 read_end:
96 writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
97
98 return ret;
99 }
100
rk3308bs_otp_wait_status(struct rockchip_otp_platdata * otp,u32 flag)101 static int rk3308bs_otp_wait_status(struct rockchip_otp_platdata *otp, u32 flag)
102 {
103 int delay = OTPC_TIMEOUT;
104
105 while (!(readl(otp->base + OTPC_IRQ_ST) & flag)) {
106 udelay(1);
107 delay--;
108 if (delay <= 0) {
109 printf("%s: wait init status timeout\n", __func__);
110 return -ETIMEDOUT;
111 }
112 }
113
114 /* clean int status */
115 writel(flag, otp->base + OTPC_IRQ_ST);
116
117 return 0;
118 }
119
rk3308bs_otp_active(struct rockchip_otp_platdata * otp)120 static int rk3308bs_otp_active(struct rockchip_otp_platdata *otp)
121 {
122 int ret = 0;
123 u32 mode;
124
125 mode = readl(otp->base + OTPC_MODE_CTRL);
126
127 switch (mode) {
128 case OTPC_DEEP_STANDBY:
129 writel(OTPC_STANDBY, otp->base + OTPC_MODE_CTRL);
130 ret = rk3308bs_otp_wait_status(otp, OTPC_DP2STB_IRQ_ST);
131 if (ret < 0) {
132 dev_err(otp->dev, "timeout during wait dp2stb\n");
133 return ret;
134 }
135 case OTPC_STANDBY:
136 writel(OTPC_ACTIVE, otp->base + OTPC_MODE_CTRL);
137 ret = rk3308bs_otp_wait_status(otp, OTPC_STB2ACT_IRQ_ST);
138 if (ret < 0) {
139 dev_err(otp->dev, "timeout during wait stb2act\n");
140 return ret;
141 }
142 break;
143 default:
144 break;
145 }
146
147 return ret;
148 }
149
rk3308bs_otp_standby(struct rockchip_otp_platdata * otp)150 static int rk3308bs_otp_standby(struct rockchip_otp_platdata *otp)
151 {
152 int ret = 0;
153 u32 mode;
154
155 mode = readl(otp->base + OTPC_MODE_CTRL);
156
157 switch (mode) {
158 case OTPC_ACTIVE:
159 writel(OTPC_STANDBY, otp->base + OTPC_MODE_CTRL);
160 ret = rk3308bs_otp_wait_status(otp, OTPC_ACT2STB_IRQ_ST);
161 if (ret < 0) {
162 dev_err(otp->dev, "timeout during wait act2stb\n");
163 return ret;
164 }
165 case OTPC_STANDBY:
166 writel(OTPC_DEEP_STANDBY, otp->base + OTPC_MODE_CTRL);
167 ret = rk3308bs_otp_wait_status(otp, OTPC_STB2DP_IRQ_ST);
168 if (ret < 0) {
169 dev_err(otp->dev, "timeout during wait stb2dp\n");
170 return ret;
171 }
172 break;
173 default:
174 break;
175 }
176
177 return ret;
178 }
179
rockchip_rk3308bs_otp_read(struct udevice * dev,int offset,void * buf,int size)180 static int rockchip_rk3308bs_otp_read(struct udevice *dev, int offset,
181 void *buf, int size)
182 {
183 struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
184 unsigned int addr_start, addr_end, addr_offset, addr_len;
185 u32 out_value;
186 u8 *buffer;
187 int ret = 0, i = 0;
188
189 if (offset > RK3308BS_MAX_BYTES - 1)
190 return -ENOMEM;
191 if (offset + size > RK3308BS_MAX_BYTES)
192 size = RK3308BS_MAX_BYTES - offset;
193
194 ret = rk3308bs_otp_active(otp);
195 if (ret)
196 goto out;
197
198 addr_start = rounddown(offset, RK3308BS_NBYTES) / RK3308BS_NBYTES;
199 addr_end = roundup(offset + size, RK3308BS_NBYTES) / RK3308BS_NBYTES;
200 addr_offset = offset % RK3308BS_NBYTES;
201 addr_len = addr_end - addr_start;
202
203 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3308BS_NBYTES);
204 if (!buffer) {
205 ret = -ENOMEM;
206 goto read_end;
207 }
208
209 while (addr_len--) {
210 writel(OTPC_TRANS_NUM, otp->base + OTPC_REPR_RD_TRANS_NUM);
211 writel(addr_start++, otp->base + OTPC_ACCESS_ADDR);
212 writel(OTPC_READ_ACCESS, otp->base + OTPC_MODE_CTRL);
213 ret = rk3308bs_otp_wait_status(otp, OTPC_RDM_IRQ_ST);
214 if (ret < 0) {
215 printf("timeout during wait rd\n");
216 goto read_end;
217 }
218 out_value = readl(otp->base + OTPC_RD_DATA);
219 memcpy(&buffer[i], &out_value, RK3308BS_NBYTES);
220 i += RK3308BS_NBYTES;
221 }
222 memcpy(buf, buffer + addr_offset, size);
223
224 read_end:
225 kfree(buffer);
226 rk3308bs_otp_standby(otp);
227 out:
228 return ret;
229 }
230
rockchip_rk3568_otp_read(struct udevice * dev,int offset,void * buf,int size)231 static int rockchip_rk3568_otp_read(struct udevice *dev, int offset, void *buf,
232 int size)
233 {
234 struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
235 unsigned int addr_start, addr_end, addr_offset, addr_len;
236 u32 out_value;
237 u8 *buffer;
238 int ret = 0, i = 0;
239
240 addr_start = rounddown(offset, RK3568_NBYTES) / RK3568_NBYTES;
241 addr_end = roundup(offset + size, RK3568_NBYTES) / RK3568_NBYTES;
242 addr_offset = offset % RK3568_NBYTES;
243 addr_len = addr_end - addr_start;
244
245 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3568_NBYTES);
246 if (!buffer)
247 return -ENOMEM;
248
249 ret = rockchip_otp_ecc_enable(otp, true);
250 if (ret < 0) {
251 printf("%s rockchip_otp_ecc_enable err\n", __func__);
252 return ret;
253 }
254
255 writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
256 udelay(5);
257 while (addr_len--) {
258 writel(addr_start++ | OTPC_USER_ADDR_MASK,
259 otp->base + OTPC_USER_ADDR);
260 writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
261 otp->base + OTPC_USER_ENABLE);
262 ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
263 if (ret < 0) {
264 printf("%s timeout during read setup\n", __func__);
265 goto read_end;
266 }
267 out_value = readl(otp->base + OTPC_USER_Q);
268 memcpy(&buffer[i], &out_value, RK3568_NBYTES);
269 i += RK3568_NBYTES;
270 }
271
272 memcpy(buf, buffer + addr_offset, size);
273
274 read_end:
275 writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
276
277 kfree(buffer);
278
279 return ret;
280 }
281
rockchip_rk3588_otp_read(struct udevice * dev,int offset,void * buf,int size)282 static int rockchip_rk3588_otp_read(struct udevice *dev, int offset, void *buf,
283 int size)
284 {
285 struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
286 unsigned int addr_start, addr_end, addr_offset, addr_len;
287 int ret = 0, i = 0;
288 u32 out_value, st = 0;
289 u8 *buffer;
290
291 if (offset > RK3588_MAX_BYTES - 1)
292 return -ENOMEM;
293 if (offset + size > RK3588_MAX_BYTES)
294 size = RK3588_MAX_BYTES - offset;
295
296 addr_start = rounddown(offset, RK3588_NBYTES) / RK3588_NBYTES;
297 addr_end = roundup(offset + size, RK3588_NBYTES) / RK3588_NBYTES;
298 addr_offset = offset % RK3588_NBYTES;
299 addr_len = addr_end - addr_start;
300 addr_start += RK3588_NO_SECURE_OFFSET;
301
302 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3588_NBYTES);
303 if (!buffer)
304 return -ENOMEM;
305
306 while (addr_len--) {
307 writel((addr_start << RK3588_ADDR_SHIFT) |
308 (RK3588_BURST_NUM << RK3588_BURST_SHIFT),
309 otp->base + RK3588_OTPC_AUTO_CTRL);
310 writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
311 ret = readl_poll_timeout(otp->base + RK3588_OTPC_INT_ST, st,
312 st & RK3588_RD_DONE, OTPC_TIMEOUT);
313 if (ret < 0) {
314 printf("%s timeout during read setup\n", __func__);
315 goto read_end;
316 }
317 writel(RK3588_RD_DONE, otp->base + RK3588_OTPC_INT_ST);
318
319 out_value = readl(otp->base + RK3588_OTPC_DOUT0);
320 memcpy(&buffer[i], &out_value, RK3588_NBYTES);
321 i += RK3588_NBYTES;
322 addr_start++;
323 }
324
325 memcpy(buf, buffer + addr_offset, size);
326
327 read_end:
328 kfree(buffer);
329
330 return ret;
331 }
332
rockchip_rv1126_otp_init(struct udevice * dev)333 static int rockchip_rv1126_otp_init(struct udevice *dev)
334 {
335 struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
336 u32 status = 0;
337 int ret;
338
339 writel(0x0, otp->base + RV1126_OTP_NVM_CEB);
340 ret = readl_poll_timeout(otp->base + RV1126_OTP_NVM_ST, status,
341 status & 0x1, OTPC_TIMEOUT);
342 if (ret < 0) {
343 printf("%s timeout during set ceb\n", __func__);
344 return ret;
345 }
346
347 writel(0x1, otp->base + RV1126_OTP_NVM_RSTB);
348 ret = readl_poll_timeout(otp->base + RV1126_OTP_NVM_ST, status,
349 status & 0x4, OTPC_TIMEOUT);
350 if (ret < 0) {
351 printf("%s timeout during set rstb\n", __func__);
352 return ret;
353 }
354
355 return 0;
356 }
357
rockchip_rv1126_otp_read(struct udevice * dev,int offset,void * buf,int size)358 static int rockchip_rv1126_otp_read(struct udevice *dev, int offset, void *buf,
359 int size)
360 {
361 struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
362 u32 status = 0;
363 u8 *buffer = buf;
364 int ret = 0;
365
366 while (size--) {
367 writel(offset++, otp->base + RV1126_OTP_NVM_RADDR);
368 writel(0x1, otp->base + RV1126_OTP_NVM_RSTART);
369 ret = readl_poll_timeout(otp->base + RV1126_OTP_READ_ST,
370 status, status == 0, OTPC_TIMEOUT);
371 if (ret < 0) {
372 printf("%s timeout during read setup\n", __func__);
373 return ret;
374 }
375
376 *buffer++ = readb(otp->base + RV1126_OTP_NVM_RDATA);
377 }
378
379 return 0;
380 }
381
rockchip_otp_read(struct udevice * dev,int offset,void * buf,int size)382 static int rockchip_otp_read(struct udevice *dev, int offset,
383 void *buf, int size)
384 {
385 struct otp_data *data;
386
387 data = (struct otp_data *)dev_get_driver_data(dev);
388 if (!data)
389 return -ENOSYS;
390
391 if (soc_is_rk3308bs() || soc_is_px30s())
392 return rockchip_rk3308bs_otp_read(dev, offset, buf, size);
393
394 return data->read(dev, offset, buf, size);
395 }
396
397 static const struct misc_ops rockchip_otp_ops = {
398 .read = rockchip_otp_read,
399 };
400
rockchip_otp_ofdata_to_platdata(struct udevice * dev)401 static int rockchip_otp_ofdata_to_platdata(struct udevice *dev)
402 {
403 struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
404
405 otp->base = dev_read_addr_ptr(dev);
406
407 return 0;
408 }
409
rockchip_otp_probe(struct udevice * dev)410 static int rockchip_otp_probe(struct udevice *dev)
411 {
412 struct otp_data *data;
413
414 data = (struct otp_data *)dev_get_driver_data(dev);
415 if (!data)
416 return -EINVAL;
417
418 if (data->init)
419 return data->init(dev);
420
421 return 0;
422 }
423
424 static const struct otp_data px30_data = {
425 .read = rockchip_px30_otp_read,
426 };
427
428 static const struct otp_data rk3308bs_data = {
429 .read = rockchip_rk3308bs_otp_read,
430 };
431
432 static const struct otp_data rk3568_data = {
433 .read = rockchip_rk3568_otp_read,
434 };
435
436 static const struct otp_data rk3588_data = {
437 .read = rockchip_rk3588_otp_read,
438 };
439
440 static const struct otp_data rv1126_data = {
441 .init = rockchip_rv1126_otp_init,
442 .read = rockchip_rv1126_otp_read,
443 };
444
445 static const struct udevice_id rockchip_otp_ids[] = {
446 {
447 .compatible = "rockchip,px30-otp",
448 .data = (ulong)&px30_data,
449 },
450 {
451 .compatible = "rockchip,px30s-otp",
452 .data = (ulong)&rk3308bs_data,
453 },
454 {
455 .compatible = "rockchip,rk3308-otp",
456 .data = (ulong)&px30_data,
457 },
458 {
459 .compatible = "rockchip,rk3308bs-otp",
460 .data = (ulong)&rk3308bs_data,
461 },
462 {
463 .compatible = "rockchip,rk3528-otp",
464 .data = (ulong)&rk3568_data,
465 },
466 {
467 .compatible = "rockchip,rk3562-otp",
468 .data = (ulong)&rk3568_data,
469 },
470 {
471 .compatible = "rockchip,rk3568-otp",
472 .data = (ulong)&rk3568_data,
473 },
474 {
475 .compatible = "rockchip,rk3588-otp",
476 .data = (ulong)&rk3588_data,
477 },
478 {
479 .compatible = "rockchip,rv1106-otp",
480 .data = (ulong)&rk3568_data,
481 },
482 {
483 .compatible = "rockchip,rv1126-otp",
484 .data = (ulong)&rv1126_data,
485 },
486 {}
487 };
488
489 U_BOOT_DRIVER(rockchip_otp) = {
490 .name = "rockchip_otp",
491 .id = UCLASS_MISC,
492 .of_match = rockchip_otp_ids,
493 .ops = &rockchip_otp_ops,
494 .ofdata_to_platdata = rockchip_otp_ofdata_to_platdata,
495 .platdata_auto_alloc_size = sizeof(struct rockchip_otp_platdata),
496 .probe = rockchip_otp_probe,
497 };
498