hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/nvmem/imx-ocotp.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * i.MX6 OCOTP fusebox driver
34 *
....@@ -9,13 +10,6 @@
910 *
1011 * Write support based on the fsl_otp driver,
1112 * Copyright (C) 2010-2013 Freescale Semiconductor, Inc
12
- *
13
- * This program is free software; you can redistribute it and/or modify
14
- * it under the terms of the GNU General Public License version 2
15
- * as published by the Free Software Foundation.
16
- *
17
- * http://www.opensource.org/licenses/gpl-license.html
18
- * http://www.gnu.org/copyleft/gpl.html
1913 */
2014
2115 #include <linux/clk.h>
....@@ -45,10 +39,31 @@
4539 #define IMX_OCOTP_ADDR_DATA2 0x0040
4640 #define IMX_OCOTP_ADDR_DATA3 0x0050
4741
48
-#define IMX_OCOTP_BM_CTRL_ADDR 0x0000007F
42
+#define IMX_OCOTP_BM_CTRL_ADDR 0x000000FF
4943 #define IMX_OCOTP_BM_CTRL_BUSY 0x00000100
5044 #define IMX_OCOTP_BM_CTRL_ERROR 0x00000200
5145 #define IMX_OCOTP_BM_CTRL_REL_SHADOWS 0x00000400
46
+
47
+#define IMX_OCOTP_BM_CTRL_ADDR_8MP 0x000001FF
48
+#define IMX_OCOTP_BM_CTRL_BUSY_8MP 0x00000200
49
+#define IMX_OCOTP_BM_CTRL_ERROR_8MP 0x00000400
50
+#define IMX_OCOTP_BM_CTRL_REL_SHADOWS_8MP 0x00000800
51
+
52
+#define IMX_OCOTP_BM_CTRL_DEFAULT \
53
+ { \
54
+ .bm_addr = IMX_OCOTP_BM_CTRL_ADDR, \
55
+ .bm_busy = IMX_OCOTP_BM_CTRL_BUSY, \
56
+ .bm_error = IMX_OCOTP_BM_CTRL_ERROR, \
57
+ .bm_rel_shadows = IMX_OCOTP_BM_CTRL_REL_SHADOWS,\
58
+ }
59
+
60
+#define IMX_OCOTP_BM_CTRL_8MP \
61
+ { \
62
+ .bm_addr = IMX_OCOTP_BM_CTRL_ADDR_8MP, \
63
+ .bm_busy = IMX_OCOTP_BM_CTRL_BUSY_8MP, \
64
+ .bm_error = IMX_OCOTP_BM_CTRL_ERROR_8MP, \
65
+ .bm_rel_shadows = IMX_OCOTP_BM_CTRL_REL_SHADOWS_8MP,\
66
+ }
5267
5368 #define TIMING_STROBE_PROG_US 10 /* Min time to blow a fuse */
5469 #define TIMING_STROBE_READ_NS 37 /* Min time before read */
....@@ -68,18 +83,31 @@
6883 struct nvmem_config *config;
6984 };
7085
86
+struct ocotp_ctrl_reg {
87
+ u32 bm_addr;
88
+ u32 bm_busy;
89
+ u32 bm_error;
90
+ u32 bm_rel_shadows;
91
+};
92
+
7193 struct ocotp_params {
7294 unsigned int nregs;
7395 unsigned int bank_address_words;
7496 void (*set_timing)(struct ocotp_priv *priv);
97
+ struct ocotp_ctrl_reg ctrl;
7598 };
7699
77
-static int imx_ocotp_wait_for_busy(void __iomem *base, u32 flags)
100
+static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags)
78101 {
79102 int count;
80103 u32 c, mask;
104
+ u32 bm_ctrl_busy, bm_ctrl_error;
105
+ void __iomem *base = priv->base;
81106
82
- mask = IMX_OCOTP_BM_CTRL_BUSY | IMX_OCOTP_BM_CTRL_ERROR | flags;
107
+ bm_ctrl_busy = priv->params->ctrl.bm_busy;
108
+ bm_ctrl_error = priv->params->ctrl.bm_error;
109
+
110
+ mask = bm_ctrl_busy | bm_ctrl_error | flags;
83111
84112 for (count = 10000; count >= 0; count--) {
85113 c = readl(base + IMX_OCOTP_ADDR_CTRL);
....@@ -103,7 +131,7 @@
103131 * - A read is performed to from a fuse word which has been read
104132 * locked.
105133 */
106
- if (c & IMX_OCOTP_BM_CTRL_ERROR)
134
+ if (c & bm_ctrl_error)
107135 return -EPERM;
108136 return -ETIMEDOUT;
109137 }
....@@ -111,15 +139,18 @@
111139 return 0;
112140 }
113141
114
-static void imx_ocotp_clr_err_if_set(void __iomem *base)
142
+static void imx_ocotp_clr_err_if_set(struct ocotp_priv *priv)
115143 {
116
- u32 c;
144
+ u32 c, bm_ctrl_error;
145
+ void __iomem *base = priv->base;
146
+
147
+ bm_ctrl_error = priv->params->ctrl.bm_error;
117148
118149 c = readl(base + IMX_OCOTP_ADDR_CTRL);
119
- if (!(c & IMX_OCOTP_BM_CTRL_ERROR))
150
+ if (!(c & bm_ctrl_error))
120151 return;
121152
122
- writel(IMX_OCOTP_BM_CTRL_ERROR, base + IMX_OCOTP_ADDR_CTRL_CLR);
153
+ writel(bm_ctrl_error, base + IMX_OCOTP_ADDR_CTRL_CLR);
123154 }
124155
125156 static int imx_ocotp_read(void *context, unsigned int offset,
....@@ -146,7 +177,7 @@
146177 return ret;
147178 }
148179
149
- ret = imx_ocotp_wait_for_busy(priv->base, 0);
180
+ ret = imx_ocotp_wait_for_busy(priv, 0);
150181 if (ret < 0) {
151182 dev_err(priv->dev, "timeout during read setup\n");
152183 goto read_end;
....@@ -163,9 +194,8 @@
163194 * issued
164195 */
165196 if (*(buf - 1) == IMX_OCOTP_READ_LOCKED_VAL)
166
- imx_ocotp_clr_err_if_set(priv->base);
197
+ imx_ocotp_clr_err_if_set(priv);
167198 }
168
- ret = 0;
169199
170200 read_end:
171201 clk_disable_unprepare(priv->clk);
....@@ -175,9 +205,9 @@
175205
176206 static void imx_ocotp_set_imx6_timing(struct ocotp_priv *priv)
177207 {
178
- unsigned long clk_rate = 0;
208
+ unsigned long clk_rate;
179209 unsigned long strobe_read, relax, strobe_prog;
180
- u32 timing = 0;
210
+ u32 timing;
181211
182212 /* 47.3.1.3.1
183213 * Program HW_OCOTP_TIMING[STROBE_PROG] and HW_OCOTP_TIMING[RELAX]
....@@ -227,9 +257,9 @@
227257
228258 static void imx_ocotp_set_imx7_timing(struct ocotp_priv *priv)
229259 {
230
- unsigned long clk_rate = 0;
260
+ unsigned long clk_rate;
231261 u64 fsource, strobe_prog;
232
- u32 timing = 0;
262
+ u32 timing;
233263
234264 /* i.MX 7Solo Applications Processor Reference Manual, Rev. 0.1
235265 * 6.4.3.3
....@@ -280,7 +310,7 @@
280310 * write or reload must be completed before a write access can be
281311 * requested.
282312 */
283
- ret = imx_ocotp_wait_for_busy(priv->base, 0);
313
+ ret = imx_ocotp_wait_for_busy(priv, 0);
284314 if (ret < 0) {
285315 dev_err(priv->dev, "timeout during timing setup\n");
286316 goto write_end;
....@@ -312,8 +342,8 @@
312342 }
313343
314344 ctrl = readl(priv->base + IMX_OCOTP_ADDR_CTRL);
315
- ctrl &= ~IMX_OCOTP_BM_CTRL_ADDR;
316
- ctrl |= waddr & IMX_OCOTP_BM_CTRL_ADDR;
345
+ ctrl &= ~priv->params->ctrl.bm_addr;
346
+ ctrl |= waddr & priv->params->ctrl.bm_addr;
317347 ctrl |= IMX_OCOTP_WR_UNLOCK;
318348
319349 writel(ctrl, priv->base + IMX_OCOTP_ADDR_CTRL);
....@@ -380,11 +410,11 @@
380410 * be set. It must be cleared by software before any new write access
381411 * can be issued.
382412 */
383
- ret = imx_ocotp_wait_for_busy(priv->base, 0);
413
+ ret = imx_ocotp_wait_for_busy(priv, 0);
384414 if (ret < 0) {
385415 if (ret == -EPERM) {
386416 dev_err(priv->dev, "failed write to locked region");
387
- imx_ocotp_clr_err_if_set(priv->base);
417
+ imx_ocotp_clr_err_if_set(priv);
388418 } else {
389419 dev_err(priv->dev, "timeout during data write\n");
390420 }
....@@ -400,21 +430,17 @@
400430 udelay(2);
401431
402432 /* reload all shadow registers */
403
- writel(IMX_OCOTP_BM_CTRL_REL_SHADOWS,
433
+ writel(priv->params->ctrl.bm_rel_shadows,
404434 priv->base + IMX_OCOTP_ADDR_CTRL_SET);
405
- ret = imx_ocotp_wait_for_busy(priv->base,
406
- IMX_OCOTP_BM_CTRL_REL_SHADOWS);
407
- if (ret < 0) {
435
+ ret = imx_ocotp_wait_for_busy(priv,
436
+ priv->params->ctrl.bm_rel_shadows);
437
+ if (ret < 0)
408438 dev_err(priv->dev, "timeout during shadow register reload\n");
409
- goto write_end;
410
- }
411439
412440 write_end:
413441 clk_disable_unprepare(priv->clk);
414442 mutex_unlock(&ocotp_mutex);
415
- if (ret < 0)
416
- return ret;
417
- return bytes;
443
+ return ret < 0 ? ret : bytes;
418444 }
419445
420446 static struct nvmem_config imx_ocotp_nvmem_config = {
....@@ -430,36 +456,83 @@
430456 .nregs = 128,
431457 .bank_address_words = 0,
432458 .set_timing = imx_ocotp_set_imx6_timing,
459
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
433460 };
434461
435462 static const struct ocotp_params imx6sl_params = {
436463 .nregs = 64,
437464 .bank_address_words = 0,
438465 .set_timing = imx_ocotp_set_imx6_timing,
466
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
439467 };
440468
441469 static const struct ocotp_params imx6sll_params = {
442470 .nregs = 128,
443471 .bank_address_words = 0,
444472 .set_timing = imx_ocotp_set_imx6_timing,
473
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
445474 };
446475
447476 static const struct ocotp_params imx6sx_params = {
448477 .nregs = 128,
449478 .bank_address_words = 0,
450479 .set_timing = imx_ocotp_set_imx6_timing,
480
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
451481 };
452482
453483 static const struct ocotp_params imx6ul_params = {
454484 .nregs = 128,
455485 .bank_address_words = 0,
456486 .set_timing = imx_ocotp_set_imx6_timing,
487
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
488
+};
489
+
490
+static const struct ocotp_params imx6ull_params = {
491
+ .nregs = 64,
492
+ .bank_address_words = 0,
493
+ .set_timing = imx_ocotp_set_imx6_timing,
494
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
457495 };
458496
459497 static const struct ocotp_params imx7d_params = {
460498 .nregs = 64,
461499 .bank_address_words = 4,
462500 .set_timing = imx_ocotp_set_imx7_timing,
501
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
502
+};
503
+
504
+static const struct ocotp_params imx7ulp_params = {
505
+ .nregs = 256,
506
+ .bank_address_words = 0,
507
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
508
+};
509
+
510
+static const struct ocotp_params imx8mq_params = {
511
+ .nregs = 256,
512
+ .bank_address_words = 0,
513
+ .set_timing = imx_ocotp_set_imx6_timing,
514
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
515
+};
516
+
517
+static const struct ocotp_params imx8mm_params = {
518
+ .nregs = 256,
519
+ .bank_address_words = 0,
520
+ .set_timing = imx_ocotp_set_imx6_timing,
521
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
522
+};
523
+
524
+static const struct ocotp_params imx8mn_params = {
525
+ .nregs = 256,
526
+ .bank_address_words = 0,
527
+ .set_timing = imx_ocotp_set_imx6_timing,
528
+ .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
529
+};
530
+
531
+static const struct ocotp_params imx8mp_params = {
532
+ .nregs = 384,
533
+ .bank_address_words = 0,
534
+ .set_timing = imx_ocotp_set_imx6_timing,
535
+ .ctrl = IMX_OCOTP_BM_CTRL_8MP,
463536 };
464537
465538 static const struct of_device_id imx_ocotp_dt_ids[] = {
....@@ -467,8 +540,14 @@
467540 { .compatible = "fsl,imx6sl-ocotp", .data = &imx6sl_params },
468541 { .compatible = "fsl,imx6sx-ocotp", .data = &imx6sx_params },
469542 { .compatible = "fsl,imx6ul-ocotp", .data = &imx6ul_params },
543
+ { .compatible = "fsl,imx6ull-ocotp", .data = &imx6ull_params },
470544 { .compatible = "fsl,imx7d-ocotp", .data = &imx7d_params },
471545 { .compatible = "fsl,imx6sll-ocotp", .data = &imx6sll_params },
546
+ { .compatible = "fsl,imx7ulp-ocotp", .data = &imx7ulp_params },
547
+ { .compatible = "fsl,imx8mq-ocotp", .data = &imx8mq_params },
548
+ { .compatible = "fsl,imx8mm-ocotp", .data = &imx8mm_params },
549
+ { .compatible = "fsl,imx8mn-ocotp", .data = &imx8mn_params },
550
+ { .compatible = "fsl,imx8mp-ocotp", .data = &imx8mp_params },
472551 { },
473552 };
474553 MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
....@@ -476,7 +555,6 @@
476555 static int imx_ocotp_probe(struct platform_device *pdev)
477556 {
478557 struct device *dev = &pdev->dev;
479
- struct resource *res;
480558 struct ocotp_priv *priv;
481559 struct nvmem_device *nvmem;
482560
....@@ -486,8 +564,7 @@
486564
487565 priv->dev = dev;
488566
489
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
490
- priv->base = devm_ioremap_resource(dev, res);
567
+ priv->base = devm_platform_ioremap_resource(pdev, 0);
491568 if (IS_ERR(priv->base))
492569 return PTR_ERR(priv->base);
493570
....@@ -495,17 +572,17 @@
495572 if (IS_ERR(priv->clk))
496573 return PTR_ERR(priv->clk);
497574
498
- clk_prepare_enable(priv->clk);
499
- imx_ocotp_clr_err_if_set(priv->base);
500
- clk_disable_unprepare(priv->clk);
501
-
502575 priv->params = of_device_get_match_data(&pdev->dev);
503576 imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
504577 imx_ocotp_nvmem_config.dev = dev;
505578 imx_ocotp_nvmem_config.priv = priv;
506579 priv->config = &imx_ocotp_nvmem_config;
507
- nvmem = devm_nvmem_register(dev, &imx_ocotp_nvmem_config);
508580
581
+ clk_prepare_enable(priv->clk);
582
+ imx_ocotp_clr_err_if_set(priv);
583
+ clk_disable_unprepare(priv->clk);
584
+
585
+ nvmem = devm_nvmem_register(dev, &imx_ocotp_nvmem_config);
509586
510587 return PTR_ERR_OR_ZERO(nvmem);
511588 }