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