1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/clk.h>
18#include <linux/device.h>
19#include <linux/io.h>
20#include <linux/module.h>
21#include <linux/nvmem-provider.h>
22#include <linux/of.h>
23#include <linux/of_device.h>
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27
28#define IMX_OCOTP_OFFSET_B0W0 0x400
29
30
31#define IMX_OCOTP_OFFSET_PER_WORD 0x10
32
33
34
35#define IMX_OCOTP_ADDR_CTRL 0x0000
36#define IMX_OCOTP_ADDR_CTRL_SET 0x0004
37#define IMX_OCOTP_ADDR_CTRL_CLR 0x0008
38#define IMX_OCOTP_ADDR_TIMING 0x0010
39#define IMX_OCOTP_ADDR_DATA0 0x0020
40#define IMX_OCOTP_ADDR_DATA1 0x0030
41#define IMX_OCOTP_ADDR_DATA2 0x0040
42#define IMX_OCOTP_ADDR_DATA3 0x0050
43
44#define IMX_OCOTP_BM_CTRL_ADDR 0x000000FF
45#define IMX_OCOTP_BM_CTRL_BUSY 0x00000100
46#define IMX_OCOTP_BM_CTRL_ERROR 0x00000200
47#define IMX_OCOTP_BM_CTRL_REL_SHADOWS 0x00000400
48
49#define IMX_OCOTP_BM_CTRL_ADDR_8MP 0x000001FF
50#define IMX_OCOTP_BM_CTRL_BUSY_8MP 0x00000200
51#define IMX_OCOTP_BM_CTRL_ERROR_8MP 0x00000400
52#define IMX_OCOTP_BM_CTRL_REL_SHADOWS_8MP 0x00000800
53
54#define IMX_OCOTP_BM_CTRL_DEFAULT \
55 { \
56 .bm_addr = IMX_OCOTP_BM_CTRL_ADDR, \
57 .bm_busy = IMX_OCOTP_BM_CTRL_BUSY, \
58 .bm_error = IMX_OCOTP_BM_CTRL_ERROR, \
59 .bm_rel_shadows = IMX_OCOTP_BM_CTRL_REL_SHADOWS,\
60 }
61
62#define IMX_OCOTP_BM_CTRL_8MP \
63 { \
64 .bm_addr = IMX_OCOTP_BM_CTRL_ADDR_8MP, \
65 .bm_busy = IMX_OCOTP_BM_CTRL_BUSY_8MP, \
66 .bm_error = IMX_OCOTP_BM_CTRL_ERROR_8MP, \
67 .bm_rel_shadows = IMX_OCOTP_BM_CTRL_REL_SHADOWS_8MP,\
68 }
69
70#define TIMING_STROBE_PROG_US 10
71#define TIMING_STROBE_READ_NS 37
72#define TIMING_RELAX_NS 17
73#define DEF_FSOURCE 1001
74#define DEF_STROBE_PROG 10000
75#define IMX_OCOTP_WR_UNLOCK 0x3E770000
76#define IMX_OCOTP_READ_LOCKED_VAL 0xBADABADA
77
78static DEFINE_MUTEX(ocotp_mutex);
79
80struct ocotp_priv {
81 struct device *dev;
82 struct clk *clk;
83 void __iomem *base;
84 const struct ocotp_params *params;
85 struct nvmem_config *config;
86};
87
88struct ocotp_ctrl_reg {
89 u32 bm_addr;
90 u32 bm_busy;
91 u32 bm_error;
92 u32 bm_rel_shadows;
93};
94
95struct ocotp_params {
96 unsigned int nregs;
97 unsigned int bank_address_words;
98 void (*set_timing)(struct ocotp_priv *priv);
99 struct ocotp_ctrl_reg ctrl;
100 bool reverse_mac_address;
101};
102
103static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags)
104{
105 int count;
106 u32 c, mask;
107 u32 bm_ctrl_busy, bm_ctrl_error;
108 void __iomem *base = priv->base;
109
110 bm_ctrl_busy = priv->params->ctrl.bm_busy;
111 bm_ctrl_error = priv->params->ctrl.bm_error;
112
113 mask = bm_ctrl_busy | bm_ctrl_error | flags;
114
115 for (count = 10000; count >= 0; count--) {
116 c = readl(base + IMX_OCOTP_ADDR_CTRL);
117 if (!(c & mask))
118 break;
119 cpu_relax();
120 }
121
122 if (count < 0) {
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 if (c & bm_ctrl_error)
138 return -EPERM;
139 return -ETIMEDOUT;
140 }
141
142 return 0;
143}
144
145static void imx_ocotp_clr_err_if_set(struct ocotp_priv *priv)
146{
147 u32 c, bm_ctrl_error;
148 void __iomem *base = priv->base;
149
150 bm_ctrl_error = priv->params->ctrl.bm_error;
151
152 c = readl(base + IMX_OCOTP_ADDR_CTRL);
153 if (!(c & bm_ctrl_error))
154 return;
155
156 writel(bm_ctrl_error, base + IMX_OCOTP_ADDR_CTRL_CLR);
157}
158
159static int imx_ocotp_read(void *context, unsigned int offset,
160 void *val, size_t bytes)
161{
162 struct ocotp_priv *priv = context;
163 unsigned int count;
164 u8 *buf, *p;
165 int i, ret;
166 u32 index, num_bytes;
167
168 index = offset >> 2;
169 num_bytes = round_up((offset % 4) + bytes, 4);
170 count = num_bytes >> 2;
171
172 if (count > (priv->params->nregs - index))
173 count = priv->params->nregs - index;
174
175 p = kzalloc(num_bytes, GFP_KERNEL);
176 if (!p)
177 return -ENOMEM;
178
179 mutex_lock(&ocotp_mutex);
180
181 buf = p;
182
183 ret = clk_prepare_enable(priv->clk);
184 if (ret < 0) {
185 mutex_unlock(&ocotp_mutex);
186 dev_err(priv->dev, "failed to prepare/enable ocotp clk\n");
187 kfree(p);
188 return ret;
189 }
190
191 ret = imx_ocotp_wait_for_busy(priv, 0);
192 if (ret < 0) {
193 dev_err(priv->dev, "timeout during read setup\n");
194 goto read_end;
195 }
196
197 for (i = index; i < (index + count); i++) {
198 *(u32 *)buf = readl(priv->base + IMX_OCOTP_OFFSET_B0W0 +
199 i * IMX_OCOTP_OFFSET_PER_WORD);
200
201
202
203
204
205
206
207 if (*((u32 *)buf) == IMX_OCOTP_READ_LOCKED_VAL)
208 imx_ocotp_clr_err_if_set(priv);
209
210 buf += 4;
211 }
212
213 index = offset % 4;
214 memcpy(val, &p[index], bytes);
215
216read_end:
217 clk_disable_unprepare(priv->clk);
218 mutex_unlock(&ocotp_mutex);
219
220 kfree(p);
221
222 return ret;
223}
224
225static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset,
226 void *data, size_t bytes)
227{
228 struct ocotp_priv *priv = context;
229
230
231 if (id && !strcmp(id, "mac-address")) {
232 if (priv->params->reverse_mac_address) {
233 u8 *buf = data;
234 int i;
235
236 for (i = 0; i < bytes/2; i++)
237 swap(buf[i], buf[bytes - i - 1]);
238 }
239 }
240
241 return 0;
242}
243
244static void imx_ocotp_set_imx6_timing(struct ocotp_priv *priv)
245{
246 unsigned long clk_rate;
247 unsigned long strobe_read, relax, strobe_prog;
248 u32 timing;
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278 clk_rate = clk_get_rate(priv->clk);
279
280 relax = DIV_ROUND_UP(clk_rate * TIMING_RELAX_NS, 1000000000) - 1;
281 strobe_read = DIV_ROUND_UP(clk_rate * TIMING_STROBE_READ_NS,
282 1000000000);
283 strobe_read += 2 * (relax + 1) - 1;
284 strobe_prog = DIV_ROUND_CLOSEST(clk_rate * TIMING_STROBE_PROG_US,
285 1000000);
286 strobe_prog += 2 * (relax + 1) - 1;
287
288 timing = readl(priv->base + IMX_OCOTP_ADDR_TIMING) & 0x0FC00000;
289 timing |= strobe_prog & 0x00000FFF;
290 timing |= (relax << 12) & 0x0000F000;
291 timing |= (strobe_read << 16) & 0x003F0000;
292
293 writel(timing, priv->base + IMX_OCOTP_ADDR_TIMING);
294}
295
296static void imx_ocotp_set_imx7_timing(struct ocotp_priv *priv)
297{
298 unsigned long clk_rate;
299 u64 fsource, strobe_prog;
300 u32 timing;
301
302
303
304
305 clk_rate = clk_get_rate(priv->clk);
306 fsource = DIV_ROUND_UP_ULL((u64)clk_rate * DEF_FSOURCE,
307 NSEC_PER_SEC) + 1;
308 strobe_prog = DIV_ROUND_CLOSEST_ULL((u64)clk_rate * DEF_STROBE_PROG,
309 NSEC_PER_SEC) + 1;
310
311 timing = strobe_prog & 0x00000FFF;
312 timing |= (fsource << 12) & 0x000FF000;
313
314 writel(timing, priv->base + IMX_OCOTP_ADDR_TIMING);
315}
316
317static int imx_ocotp_write(void *context, unsigned int offset, void *val,
318 size_t bytes)
319{
320 struct ocotp_priv *priv = context;
321 u32 *buf = val;
322 int ret;
323
324 u32 ctrl;
325 u8 waddr;
326 u8 word = 0;
327
328
329 if ((bytes != priv->config->word_size) ||
330 (offset % priv->config->word_size))
331 return -EINVAL;
332
333 mutex_lock(&ocotp_mutex);
334
335 ret = clk_prepare_enable(priv->clk);
336 if (ret < 0) {
337 mutex_unlock(&ocotp_mutex);
338 dev_err(priv->dev, "failed to prepare/enable ocotp clk\n");
339 return ret;
340 }
341
342
343 priv->params->set_timing(priv);
344
345
346
347
348
349
350
351 ret = imx_ocotp_wait_for_busy(priv, 0);
352 if (ret < 0) {
353 dev_err(priv->dev, "timeout during timing setup\n");
354 goto write_end;
355 }
356
357
358
359
360
361
362
363
364 if (priv->params->bank_address_words != 0) {
365
366
367
368
369
370 offset = offset / priv->config->word_size;
371 waddr = offset / priv->params->bank_address_words;
372 word = offset & (priv->params->bank_address_words - 1);
373 } else {
374
375
376
377
378
379 waddr = offset / 4;
380 }
381
382 ctrl = readl(priv->base + IMX_OCOTP_ADDR_CTRL);
383 ctrl &= ~priv->params->ctrl.bm_addr;
384 ctrl |= waddr & priv->params->ctrl.bm_addr;
385 ctrl |= IMX_OCOTP_WR_UNLOCK;
386
387 writel(ctrl, priv->base + IMX_OCOTP_ADDR_CTRL);
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411 if (priv->params->bank_address_words != 0) {
412
413 switch (word) {
414 case 0:
415 writel(0, priv->base + IMX_OCOTP_ADDR_DATA1);
416 writel(0, priv->base + IMX_OCOTP_ADDR_DATA2);
417 writel(0, priv->base + IMX_OCOTP_ADDR_DATA3);
418 writel(*buf, priv->base + IMX_OCOTP_ADDR_DATA0);
419 break;
420 case 1:
421 writel(*buf, priv->base + IMX_OCOTP_ADDR_DATA1);
422 writel(0, priv->base + IMX_OCOTP_ADDR_DATA2);
423 writel(0, priv->base + IMX_OCOTP_ADDR_DATA3);
424 writel(0, priv->base + IMX_OCOTP_ADDR_DATA0);
425 break;
426 case 2:
427 writel(0, priv->base + IMX_OCOTP_ADDR_DATA1);
428 writel(*buf, priv->base + IMX_OCOTP_ADDR_DATA2);
429 writel(0, priv->base + IMX_OCOTP_ADDR_DATA3);
430 writel(0, priv->base + IMX_OCOTP_ADDR_DATA0);
431 break;
432 case 3:
433 writel(0, priv->base + IMX_OCOTP_ADDR_DATA1);
434 writel(0, priv->base + IMX_OCOTP_ADDR_DATA2);
435 writel(*buf, priv->base + IMX_OCOTP_ADDR_DATA3);
436 writel(0, priv->base + IMX_OCOTP_ADDR_DATA0);
437 break;
438 }
439 } else {
440
441 writel(*buf, priv->base + IMX_OCOTP_ADDR_DATA0);
442 }
443
444
445
446
447
448
449
450
451 ret = imx_ocotp_wait_for_busy(priv, 0);
452 if (ret < 0) {
453 if (ret == -EPERM) {
454 dev_err(priv->dev, "failed write to locked region");
455 imx_ocotp_clr_err_if_set(priv);
456 } else {
457 dev_err(priv->dev, "timeout during data write\n");
458 }
459 goto write_end;
460 }
461
462
463
464
465
466
467
468 udelay(2);
469
470
471 writel(priv->params->ctrl.bm_rel_shadows,
472 priv->base + IMX_OCOTP_ADDR_CTRL_SET);
473 ret = imx_ocotp_wait_for_busy(priv,
474 priv->params->ctrl.bm_rel_shadows);
475 if (ret < 0)
476 dev_err(priv->dev, "timeout during shadow register reload\n");
477
478write_end:
479 clk_disable_unprepare(priv->clk);
480 mutex_unlock(&ocotp_mutex);
481 return ret < 0 ? ret : bytes;
482}
483
484static struct nvmem_config imx_ocotp_nvmem_config = {
485 .name = "imx-ocotp",
486 .read_only = false,
487 .word_size = 4,
488 .stride = 1,
489 .reg_read = imx_ocotp_read,
490 .reg_write = imx_ocotp_write,
491 .cell_post_process = imx_ocotp_cell_pp,
492};
493
494static const struct ocotp_params imx6q_params = {
495 .nregs = 128,
496 .bank_address_words = 0,
497 .set_timing = imx_ocotp_set_imx6_timing,
498 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
499};
500
501static const struct ocotp_params imx6sl_params = {
502 .nregs = 64,
503 .bank_address_words = 0,
504 .set_timing = imx_ocotp_set_imx6_timing,
505 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
506};
507
508static const struct ocotp_params imx6sll_params = {
509 .nregs = 128,
510 .bank_address_words = 0,
511 .set_timing = imx_ocotp_set_imx6_timing,
512 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
513};
514
515static const struct ocotp_params imx6sx_params = {
516 .nregs = 128,
517 .bank_address_words = 0,
518 .set_timing = imx_ocotp_set_imx6_timing,
519 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
520};
521
522static const struct ocotp_params imx6ul_params = {
523 .nregs = 128,
524 .bank_address_words = 0,
525 .set_timing = imx_ocotp_set_imx6_timing,
526 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
527};
528
529static const struct ocotp_params imx6ull_params = {
530 .nregs = 64,
531 .bank_address_words = 0,
532 .set_timing = imx_ocotp_set_imx6_timing,
533 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
534};
535
536static const struct ocotp_params imx7d_params = {
537 .nregs = 64,
538 .bank_address_words = 4,
539 .set_timing = imx_ocotp_set_imx7_timing,
540 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
541};
542
543static const struct ocotp_params imx7ulp_params = {
544 .nregs = 256,
545 .bank_address_words = 0,
546 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
547};
548
549static const struct ocotp_params imx8mq_params = {
550 .nregs = 256,
551 .bank_address_words = 0,
552 .set_timing = imx_ocotp_set_imx6_timing,
553 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
554 .reverse_mac_address = true,
555};
556
557static const struct ocotp_params imx8mm_params = {
558 .nregs = 256,
559 .bank_address_words = 0,
560 .set_timing = imx_ocotp_set_imx6_timing,
561 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
562 .reverse_mac_address = true,
563};
564
565static const struct ocotp_params imx8mn_params = {
566 .nregs = 256,
567 .bank_address_words = 0,
568 .set_timing = imx_ocotp_set_imx6_timing,
569 .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
570 .reverse_mac_address = true,
571};
572
573static const struct ocotp_params imx8mp_params = {
574 .nregs = 384,
575 .bank_address_words = 0,
576 .set_timing = imx_ocotp_set_imx6_timing,
577 .ctrl = IMX_OCOTP_BM_CTRL_8MP,
578 .reverse_mac_address = true,
579};
580
581static const struct of_device_id imx_ocotp_dt_ids[] = {
582 { .compatible = "fsl,imx6q-ocotp", .data = &imx6q_params },
583 { .compatible = "fsl,imx6sl-ocotp", .data = &imx6sl_params },
584 { .compatible = "fsl,imx6sx-ocotp", .data = &imx6sx_params },
585 { .compatible = "fsl,imx6ul-ocotp", .data = &imx6ul_params },
586 { .compatible = "fsl,imx6ull-ocotp", .data = &imx6ull_params },
587 { .compatible = "fsl,imx7d-ocotp", .data = &imx7d_params },
588 { .compatible = "fsl,imx6sll-ocotp", .data = &imx6sll_params },
589 { .compatible = "fsl,imx7ulp-ocotp", .data = &imx7ulp_params },
590 { .compatible = "fsl,imx8mq-ocotp", .data = &imx8mq_params },
591 { .compatible = "fsl,imx8mm-ocotp", .data = &imx8mm_params },
592 { .compatible = "fsl,imx8mn-ocotp", .data = &imx8mn_params },
593 { .compatible = "fsl,imx8mp-ocotp", .data = &imx8mp_params },
594 { },
595};
596MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
597
598static int imx_ocotp_probe(struct platform_device *pdev)
599{
600 struct device *dev = &pdev->dev;
601 struct ocotp_priv *priv;
602 struct nvmem_device *nvmem;
603
604 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
605 if (!priv)
606 return -ENOMEM;
607
608 priv->dev = dev;
609
610 priv->base = devm_platform_ioremap_resource(pdev, 0);
611 if (IS_ERR(priv->base))
612 return PTR_ERR(priv->base);
613
614 priv->clk = devm_clk_get(dev, NULL);
615 if (IS_ERR(priv->clk))
616 return PTR_ERR(priv->clk);
617
618 priv->params = of_device_get_match_data(&pdev->dev);
619 imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
620 imx_ocotp_nvmem_config.dev = dev;
621 imx_ocotp_nvmem_config.priv = priv;
622 priv->config = &imx_ocotp_nvmem_config;
623
624 clk_prepare_enable(priv->clk);
625 imx_ocotp_clr_err_if_set(priv);
626 clk_disable_unprepare(priv->clk);
627
628 nvmem = devm_nvmem_register(dev, &imx_ocotp_nvmem_config);
629
630 return PTR_ERR_OR_ZERO(nvmem);
631}
632
633static struct platform_driver imx_ocotp_driver = {
634 .probe = imx_ocotp_probe,
635 .driver = {
636 .name = "imx_ocotp",
637 .of_match_table = imx_ocotp_dt_ids,
638 },
639};
640module_platform_driver(imx_ocotp_driver);
641
642MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
643MODULE_DESCRIPTION("i.MX6/i.MX7 OCOTP fuse box driver");
644MODULE_LICENSE("GPL v2");
645