xref: /linux/drivers/nvmem/imx-ocotp.c (revision ead5d1f4d877e92c051e1a1ade623d0d30e71619)
1acee2e8dSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
23edba6b4SPhilipp Zabel /*
33edba6b4SPhilipp Zabel  * i.MX6 OCOTP fusebox driver
43edba6b4SPhilipp Zabel  *
53edba6b4SPhilipp Zabel  * Copyright (c) 2015 Pengutronix, Philipp Zabel <p.zabel@pengutronix.de>
63edba6b4SPhilipp Zabel  *
73edba6b4SPhilipp Zabel  * Based on the barebox ocotp driver,
83edba6b4SPhilipp Zabel  * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>,
93edba6b4SPhilipp Zabel  *	Orex Computed Radiography
103edba6b4SPhilipp Zabel  *
110642bac7SRichard Leitner  * Write support based on the fsl_otp driver,
120642bac7SRichard Leitner  * Copyright (C) 2010-2013 Freescale Semiconductor, Inc
133edba6b4SPhilipp Zabel  */
143edba6b4SPhilipp Zabel 
15deb31970SPeng Fan #include <linux/clk.h>
163edba6b4SPhilipp Zabel #include <linux/device.h>
173edba6b4SPhilipp Zabel #include <linux/io.h>
183edba6b4SPhilipp Zabel #include <linux/module.h>
193edba6b4SPhilipp Zabel #include <linux/nvmem-provider.h>
203edba6b4SPhilipp Zabel #include <linux/of.h>
213edba6b4SPhilipp Zabel #include <linux/of_device.h>
223edba6b4SPhilipp Zabel #include <linux/platform_device.h>
233edba6b4SPhilipp Zabel #include <linux/slab.h>
240642bac7SRichard Leitner #include <linux/delay.h>
253edba6b4SPhilipp Zabel 
269b66587eSRichard Leitner #define IMX_OCOTP_OFFSET_B0W0		0x400 /* Offset from base address of the
279b66587eSRichard Leitner 					       * OTP Bank0 Word0
289b66587eSRichard Leitner 					       */
299b66587eSRichard Leitner #define IMX_OCOTP_OFFSET_PER_WORD	0x10  /* Offset between the start addr
309b66587eSRichard Leitner 					       * of two consecutive OTP words.
319b66587eSRichard Leitner 					       */
320642bac7SRichard Leitner 
339b66587eSRichard Leitner #define IMX_OCOTP_ADDR_CTRL		0x0000
340642bac7SRichard Leitner #define IMX_OCOTP_ADDR_CTRL_SET		0x0004
359b66587eSRichard Leitner #define IMX_OCOTP_ADDR_CTRL_CLR		0x0008
360642bac7SRichard Leitner #define IMX_OCOTP_ADDR_TIMING		0x0010
37ffd9115fSBryan O'Donoghue #define IMX_OCOTP_ADDR_DATA0		0x0020
38ffd9115fSBryan O'Donoghue #define IMX_OCOTP_ADDR_DATA1		0x0030
39ffd9115fSBryan O'Donoghue #define IMX_OCOTP_ADDR_DATA2		0x0040
40ffd9115fSBryan O'Donoghue #define IMX_OCOTP_ADDR_DATA3		0x0050
419b66587eSRichard Leitner 
42c03bb448SBryan O'Donoghue #define IMX_OCOTP_BM_CTRL_ADDR		0x000000FF
430642bac7SRichard Leitner #define IMX_OCOTP_BM_CTRL_BUSY		0x00000100
449b66587eSRichard Leitner #define IMX_OCOTP_BM_CTRL_ERROR		0x00000200
450642bac7SRichard Leitner #define IMX_OCOTP_BM_CTRL_REL_SHADOWS	0x00000400
469b66587eSRichard Leitner 
47c3f4af8bSPeng Fan #define IMX_OCOTP_BM_CTRL_ADDR_8MP		0x000001FF
48c3f4af8bSPeng Fan #define IMX_OCOTP_BM_CTRL_BUSY_8MP		0x00000200
49c3f4af8bSPeng Fan #define IMX_OCOTP_BM_CTRL_ERROR_8MP		0x00000400
50c3f4af8bSPeng Fan #define IMX_OCOTP_BM_CTRL_REL_SHADOWS_8MP	0x00000800
51c3f4af8bSPeng Fan 
52226c5126SPeng Fan #define IMX_OCOTP_BM_CTRL_DEFAULT				\
53226c5126SPeng Fan 	{							\
54226c5126SPeng Fan 		.bm_addr = IMX_OCOTP_BM_CTRL_ADDR,		\
55226c5126SPeng Fan 		.bm_busy = IMX_OCOTP_BM_CTRL_BUSY,		\
56226c5126SPeng Fan 		.bm_error = IMX_OCOTP_BM_CTRL_ERROR,		\
57226c5126SPeng Fan 		.bm_rel_shadows = IMX_OCOTP_BM_CTRL_REL_SHADOWS,\
58226c5126SPeng Fan 	}
59226c5126SPeng Fan 
60c3f4af8bSPeng Fan #define IMX_OCOTP_BM_CTRL_8MP					\
61c3f4af8bSPeng Fan 	{							\
62c3f4af8bSPeng Fan 		.bm_addr = IMX_OCOTP_BM_CTRL_ADDR_8MP,		\
63c3f4af8bSPeng Fan 		.bm_busy = IMX_OCOTP_BM_CTRL_BUSY_8MP,		\
64c3f4af8bSPeng Fan 		.bm_error = IMX_OCOTP_BM_CTRL_ERROR_8MP,	\
65c3f4af8bSPeng Fan 		.bm_rel_shadows = IMX_OCOTP_BM_CTRL_REL_SHADOWS_8MP,\
66c3f4af8bSPeng Fan 	}
67c3f4af8bSPeng Fan 
68159dbaf5SBryan O'Donoghue #define TIMING_STROBE_PROG_US		10	/* Min time to blow a fuse */
69159dbaf5SBryan O'Donoghue #define TIMING_STROBE_READ_NS		37	/* Min time before read */
70159dbaf5SBryan O'Donoghue #define TIMING_RELAX_NS			17
71828ae7a4SBryan O'Donoghue #define DEF_FSOURCE			1001	/* > 1000 ns */
72828ae7a4SBryan O'Donoghue #define DEF_STROBE_PROG			10000	/* IPG clocks */
730642bac7SRichard Leitner #define IMX_OCOTP_WR_UNLOCK		0x3E770000
749b66587eSRichard Leitner #define IMX_OCOTP_READ_LOCKED_VAL	0xBADABADA
759b66587eSRichard Leitner 
760642bac7SRichard Leitner static DEFINE_MUTEX(ocotp_mutex);
770642bac7SRichard Leitner 
783edba6b4SPhilipp Zabel struct ocotp_priv {
793edba6b4SPhilipp Zabel 	struct device *dev;
80deb31970SPeng Fan 	struct clk *clk;
813edba6b4SPhilipp Zabel 	void __iomem *base;
82e20d2b29SBryan O'Donoghue 	const struct ocotp_params *params;
830642bac7SRichard Leitner 	struct nvmem_config *config;
843edba6b4SPhilipp Zabel };
853edba6b4SPhilipp Zabel 
86226c5126SPeng Fan struct ocotp_ctrl_reg {
87226c5126SPeng Fan 	u32 bm_addr;
88226c5126SPeng Fan 	u32 bm_busy;
89226c5126SPeng Fan 	u32 bm_error;
90226c5126SPeng Fan 	u32 bm_rel_shadows;
91226c5126SPeng Fan };
92226c5126SPeng Fan 
93828ae7a4SBryan O'Donoghue struct ocotp_params {
94828ae7a4SBryan O'Donoghue 	unsigned int nregs;
95828ae7a4SBryan O'Donoghue 	unsigned int bank_address_words;
96828ae7a4SBryan O'Donoghue 	void (*set_timing)(struct ocotp_priv *priv);
97226c5126SPeng Fan 	struct ocotp_ctrl_reg ctrl;
98828ae7a4SBryan O'Donoghue };
99828ae7a4SBryan O'Donoghue 
100226c5126SPeng Fan static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags)
1010642bac7SRichard Leitner {
1020642bac7SRichard Leitner 	int count;
1030642bac7SRichard Leitner 	u32 c, mask;
104226c5126SPeng Fan 	u32 bm_ctrl_busy, bm_ctrl_error;
105226c5126SPeng Fan 	void __iomem *base = priv->base;
1060642bac7SRichard Leitner 
107226c5126SPeng Fan 	bm_ctrl_busy = priv->params->ctrl.bm_busy;
108226c5126SPeng Fan 	bm_ctrl_error = priv->params->ctrl.bm_error;
109226c5126SPeng Fan 
110226c5126SPeng Fan 	mask = bm_ctrl_busy | bm_ctrl_error | flags;
1110642bac7SRichard Leitner 
1120642bac7SRichard Leitner 	for (count = 10000; count >= 0; count--) {
1130642bac7SRichard Leitner 		c = readl(base + IMX_OCOTP_ADDR_CTRL);
1140642bac7SRichard Leitner 		if (!(c & mask))
1150642bac7SRichard Leitner 			break;
1160642bac7SRichard Leitner 		cpu_relax();
1170642bac7SRichard Leitner 	}
1180642bac7SRichard Leitner 
1190642bac7SRichard Leitner 	if (count < 0) {
1200642bac7SRichard Leitner 		/* HW_OCOTP_CTRL[ERROR] will be set under the following
1210642bac7SRichard Leitner 		 * conditions:
1220642bac7SRichard Leitner 		 * - A write is performed to a shadow register during a shadow
1230642bac7SRichard Leitner 		 *   reload (essentially, while HW_OCOTP_CTRL[RELOAD_SHADOWS] is
1240642bac7SRichard Leitner 		 *   set. In addition, the contents of the shadow register shall
1250642bac7SRichard Leitner 		 *   not be updated.
1260642bac7SRichard Leitner 		 * - A write is performed to a shadow register which has been
1270642bac7SRichard Leitner 		 *   locked.
1280642bac7SRichard Leitner 		 * - A read is performed to from a shadow register which has
1290642bac7SRichard Leitner 		 *   been read locked.
1300642bac7SRichard Leitner 		 * - A program is performed to a fuse word which has been locked
1310642bac7SRichard Leitner 		 * - A read is performed to from a fuse word which has been read
1320642bac7SRichard Leitner 		 *   locked.
1330642bac7SRichard Leitner 		 */
134226c5126SPeng Fan 		if (c & bm_ctrl_error)
1350642bac7SRichard Leitner 			return -EPERM;
1360642bac7SRichard Leitner 		return -ETIMEDOUT;
1370642bac7SRichard Leitner 	}
1380642bac7SRichard Leitner 
1390642bac7SRichard Leitner 	return 0;
1400642bac7SRichard Leitner }
1410642bac7SRichard Leitner 
142226c5126SPeng Fan static void imx_ocotp_clr_err_if_set(struct ocotp_priv *priv)
1439b66587eSRichard Leitner {
144226c5126SPeng Fan 	u32 c, bm_ctrl_error;
145226c5126SPeng Fan 	void __iomem *base = priv->base;
146226c5126SPeng Fan 
147226c5126SPeng Fan 	bm_ctrl_error = priv->params->ctrl.bm_error;
1489b66587eSRichard Leitner 
1499b66587eSRichard Leitner 	c = readl(base + IMX_OCOTP_ADDR_CTRL);
150226c5126SPeng Fan 	if (!(c & bm_ctrl_error))
1519b66587eSRichard Leitner 		return;
1529b66587eSRichard Leitner 
153226c5126SPeng Fan 	writel(bm_ctrl_error, base + IMX_OCOTP_ADDR_CTRL_CLR);
1549b66587eSRichard Leitner }
1559b66587eSRichard Leitner 
15633e5e29cSSrinivas Kandagatla static int imx_ocotp_read(void *context, unsigned int offset,
15733e5e29cSSrinivas Kandagatla 			  void *val, size_t bytes)
1583edba6b4SPhilipp Zabel {
1593edba6b4SPhilipp Zabel 	struct ocotp_priv *priv = context;
1603edba6b4SPhilipp Zabel 	unsigned int count;
16133e5e29cSSrinivas Kandagatla 	u32 *buf = val;
162deb31970SPeng Fan 	int i, ret;
1633edba6b4SPhilipp Zabel 	u32 index;
1643edba6b4SPhilipp Zabel 
1653edba6b4SPhilipp Zabel 	index = offset >> 2;
16633e5e29cSSrinivas Kandagatla 	count = bytes >> 2;
1673edba6b4SPhilipp Zabel 
168e20d2b29SBryan O'Donoghue 	if (count > (priv->params->nregs - index))
169e20d2b29SBryan O'Donoghue 		count = priv->params->nregs - index;
1703edba6b4SPhilipp Zabel 
1710642bac7SRichard Leitner 	mutex_lock(&ocotp_mutex);
1720642bac7SRichard Leitner 
173deb31970SPeng Fan 	ret = clk_prepare_enable(priv->clk);
174deb31970SPeng Fan 	if (ret < 0) {
1750642bac7SRichard Leitner 		mutex_unlock(&ocotp_mutex);
176deb31970SPeng Fan 		dev_err(priv->dev, "failed to prepare/enable ocotp clk\n");
177deb31970SPeng Fan 		return ret;
178deb31970SPeng Fan 	}
1799b66587eSRichard Leitner 
180226c5126SPeng Fan 	ret = imx_ocotp_wait_for_busy(priv, 0);
1810642bac7SRichard Leitner 	if (ret < 0) {
1820642bac7SRichard Leitner 		dev_err(priv->dev, "timeout during read setup\n");
1830642bac7SRichard Leitner 		goto read_end;
1840642bac7SRichard Leitner 	}
1850642bac7SRichard Leitner 
1869b66587eSRichard Leitner 	for (i = index; i < (index + count); i++) {
1879b66587eSRichard Leitner 		*buf++ = readl(priv->base + IMX_OCOTP_OFFSET_B0W0 +
1889b66587eSRichard Leitner 			       i * IMX_OCOTP_OFFSET_PER_WORD);
1899b66587eSRichard Leitner 
1909b66587eSRichard Leitner 		/* 47.3.1.2
1919b66587eSRichard Leitner 		 * For "read locked" registers 0xBADABADA will be returned and
1929b66587eSRichard Leitner 		 * HW_OCOTP_CTRL[ERROR] will be set. It must be cleared by
1939b66587eSRichard Leitner 		 * software before any new write, read or reload access can be
1949b66587eSRichard Leitner 		 * issued
1959b66587eSRichard Leitner 		 */
1969b66587eSRichard Leitner 		if (*(buf - 1) == IMX_OCOTP_READ_LOCKED_VAL)
197226c5126SPeng Fan 			imx_ocotp_clr_err_if_set(priv);
1989b66587eSRichard Leitner 	}
1993edba6b4SPhilipp Zabel 
2000642bac7SRichard Leitner read_end:
201deb31970SPeng Fan 	clk_disable_unprepare(priv->clk);
2020642bac7SRichard Leitner 	mutex_unlock(&ocotp_mutex);
2030642bac7SRichard Leitner 	return ret;
2040642bac7SRichard Leitner }
2050642bac7SRichard Leitner 
206b50cb68fSBryan O'Donoghue static void imx_ocotp_set_imx6_timing(struct ocotp_priv *priv)
2070642bac7SRichard Leitner {
20813d588baSAnson Huang 	unsigned long clk_rate;
2090642bac7SRichard Leitner 	unsigned long strobe_read, relax, strobe_prog;
21013d588baSAnson Huang 	u32 timing;
2110642bac7SRichard Leitner 
2120642bac7SRichard Leitner 	/* 47.3.1.3.1
2130642bac7SRichard Leitner 	 * Program HW_OCOTP_TIMING[STROBE_PROG] and HW_OCOTP_TIMING[RELAX]
2140642bac7SRichard Leitner 	 * fields with timing values to match the current frequency of the
2150642bac7SRichard Leitner 	 * ipg_clk. OTP writes will work at maximum bus frequencies as long
2160642bac7SRichard Leitner 	 * as the HW_OCOTP_TIMING parameters are set correctly.
217159dbaf5SBryan O'Donoghue 	 *
218159dbaf5SBryan O'Donoghue 	 * Note: there are minimum timings required to ensure an OTP fuse burns
219159dbaf5SBryan O'Donoghue 	 * correctly that are independent of the ipg_clk. Those values are not
220159dbaf5SBryan O'Donoghue 	 * formally documented anywhere however, working from the minimum
221159dbaf5SBryan O'Donoghue 	 * timings given in u-boot we can say:
222159dbaf5SBryan O'Donoghue 	 *
223159dbaf5SBryan O'Donoghue 	 * - Minimum STROBE_PROG time is 10 microseconds. Intuitively 10
224159dbaf5SBryan O'Donoghue 	 *   microseconds feels about right as representative of a minimum time
225159dbaf5SBryan O'Donoghue 	 *   to physically burn out a fuse.
226159dbaf5SBryan O'Donoghue 	 *
227159dbaf5SBryan O'Donoghue 	 * - Minimum STROBE_READ i.e. the time to wait post OTP fuse burn before
228159dbaf5SBryan O'Donoghue 	 *   performing another read is 37 nanoseconds
229159dbaf5SBryan O'Donoghue 	 *
230159dbaf5SBryan O'Donoghue 	 * - Minimum RELAX timing is 17 nanoseconds. This final RELAX minimum
231159dbaf5SBryan O'Donoghue 	 *   timing is not entirely clear the documentation says "This
232159dbaf5SBryan O'Donoghue 	 *   count value specifies the time to add to all default timing
233159dbaf5SBryan O'Donoghue 	 *   parameters other than the Tpgm and Trd. It is given in number
234159dbaf5SBryan O'Donoghue 	 *   of ipg_clk periods." where Tpgm and Trd refer to STROBE_PROG
235159dbaf5SBryan O'Donoghue 	 *   and STROBE_READ respectively. What the other timing parameters
236159dbaf5SBryan O'Donoghue 	 *   are though, is not specified. Experience shows a zero RELAX
237159dbaf5SBryan O'Donoghue 	 *   value will mess up a re-load of the shadow registers post OTP
238159dbaf5SBryan O'Donoghue 	 *   burn.
2390642bac7SRichard Leitner 	 */
2400642bac7SRichard Leitner 	clk_rate = clk_get_rate(priv->clk);
2410642bac7SRichard Leitner 
242159dbaf5SBryan O'Donoghue 	relax = DIV_ROUND_UP(clk_rate * TIMING_RELAX_NS, 1000000000) - 1;
243159dbaf5SBryan O'Donoghue 	strobe_read = DIV_ROUND_UP(clk_rate * TIMING_STROBE_READ_NS,
244159dbaf5SBryan O'Donoghue 				   1000000000);
245159dbaf5SBryan O'Donoghue 	strobe_read += 2 * (relax + 1) - 1;
246159dbaf5SBryan O'Donoghue 	strobe_prog = DIV_ROUND_CLOSEST(clk_rate * TIMING_STROBE_PROG_US,
247159dbaf5SBryan O'Donoghue 					1000000);
248159dbaf5SBryan O'Donoghue 	strobe_prog += 2 * (relax + 1) - 1;
2490642bac7SRichard Leitner 
2500493c479SBryan O'Donoghue 	timing = readl(priv->base + IMX_OCOTP_ADDR_TIMING) & 0x0FC00000;
2510493c479SBryan O'Donoghue 	timing |= strobe_prog & 0x00000FFF;
2520642bac7SRichard Leitner 	timing |= (relax       << 12) & 0x0000F000;
2530642bac7SRichard Leitner 	timing |= (strobe_read << 16) & 0x003F0000;
2540642bac7SRichard Leitner 
2550642bac7SRichard Leitner 	writel(timing, priv->base + IMX_OCOTP_ADDR_TIMING);
256b50cb68fSBryan O'Donoghue }
257b50cb68fSBryan O'Donoghue 
258828ae7a4SBryan O'Donoghue static void imx_ocotp_set_imx7_timing(struct ocotp_priv *priv)
259828ae7a4SBryan O'Donoghue {
26013d588baSAnson Huang 	unsigned long clk_rate;
261828ae7a4SBryan O'Donoghue 	u64 fsource, strobe_prog;
26213d588baSAnson Huang 	u32 timing;
263828ae7a4SBryan O'Donoghue 
264828ae7a4SBryan O'Donoghue 	/* i.MX 7Solo Applications Processor Reference Manual, Rev. 0.1
265828ae7a4SBryan O'Donoghue 	 * 6.4.3.3
266828ae7a4SBryan O'Donoghue 	 */
267828ae7a4SBryan O'Donoghue 	clk_rate = clk_get_rate(priv->clk);
268828ae7a4SBryan O'Donoghue 	fsource = DIV_ROUND_UP_ULL((u64)clk_rate * DEF_FSOURCE,
269828ae7a4SBryan O'Donoghue 				   NSEC_PER_SEC) + 1;
270828ae7a4SBryan O'Donoghue 	strobe_prog = DIV_ROUND_CLOSEST_ULL((u64)clk_rate * DEF_STROBE_PROG,
271828ae7a4SBryan O'Donoghue 					    NSEC_PER_SEC) + 1;
272828ae7a4SBryan O'Donoghue 
273828ae7a4SBryan O'Donoghue 	timing = strobe_prog & 0x00000FFF;
274828ae7a4SBryan O'Donoghue 	timing |= (fsource << 12) & 0x000FF000;
275828ae7a4SBryan O'Donoghue 
276828ae7a4SBryan O'Donoghue 	writel(timing, priv->base + IMX_OCOTP_ADDR_TIMING);
277828ae7a4SBryan O'Donoghue }
278828ae7a4SBryan O'Donoghue 
279b50cb68fSBryan O'Donoghue static int imx_ocotp_write(void *context, unsigned int offset, void *val,
280b50cb68fSBryan O'Donoghue 			   size_t bytes)
281b50cb68fSBryan O'Donoghue {
282b50cb68fSBryan O'Donoghue 	struct ocotp_priv *priv = context;
283b50cb68fSBryan O'Donoghue 	u32 *buf = val;
284b50cb68fSBryan O'Donoghue 	int ret;
285b50cb68fSBryan O'Donoghue 
286b50cb68fSBryan O'Donoghue 	u32 ctrl;
287b50cb68fSBryan O'Donoghue 	u8 waddr;
288b50cb68fSBryan O'Donoghue 	u8 word = 0;
289b50cb68fSBryan O'Donoghue 
290b50cb68fSBryan O'Donoghue 	/* allow only writing one complete OTP word at a time */
291b50cb68fSBryan O'Donoghue 	if ((bytes != priv->config->word_size) ||
292b50cb68fSBryan O'Donoghue 	    (offset % priv->config->word_size))
293b50cb68fSBryan O'Donoghue 		return -EINVAL;
294b50cb68fSBryan O'Donoghue 
295b50cb68fSBryan O'Donoghue 	mutex_lock(&ocotp_mutex);
296b50cb68fSBryan O'Donoghue 
297b50cb68fSBryan O'Donoghue 	ret = clk_prepare_enable(priv->clk);
298b50cb68fSBryan O'Donoghue 	if (ret < 0) {
299b50cb68fSBryan O'Donoghue 		mutex_unlock(&ocotp_mutex);
300b50cb68fSBryan O'Donoghue 		dev_err(priv->dev, "failed to prepare/enable ocotp clk\n");
301b50cb68fSBryan O'Donoghue 		return ret;
302b50cb68fSBryan O'Donoghue 	}
303b50cb68fSBryan O'Donoghue 
304b50cb68fSBryan O'Donoghue 	/* Setup the write timing values */
305828ae7a4SBryan O'Donoghue 	priv->params->set_timing(priv);
3060642bac7SRichard Leitner 
3070642bac7SRichard Leitner 	/* 47.3.1.3.2
3080642bac7SRichard Leitner 	 * Check that HW_OCOTP_CTRL[BUSY] and HW_OCOTP_CTRL[ERROR] are clear.
3090642bac7SRichard Leitner 	 * Overlapped accesses are not supported by the controller. Any pending
3100642bac7SRichard Leitner 	 * write or reload must be completed before a write access can be
3110642bac7SRichard Leitner 	 * requested.
3120642bac7SRichard Leitner 	 */
313226c5126SPeng Fan 	ret = imx_ocotp_wait_for_busy(priv, 0);
3140642bac7SRichard Leitner 	if (ret < 0) {
3150642bac7SRichard Leitner 		dev_err(priv->dev, "timeout during timing setup\n");
3160642bac7SRichard Leitner 		goto write_end;
3170642bac7SRichard Leitner 	}
3180642bac7SRichard Leitner 
3190642bac7SRichard Leitner 	/* 47.3.1.3.3
3200642bac7SRichard Leitner 	 * Write the requested address to HW_OCOTP_CTRL[ADDR] and program the
3210642bac7SRichard Leitner 	 * unlock code into HW_OCOTP_CTRL[WR_UNLOCK]. This must be programmed
3220642bac7SRichard Leitner 	 * for each write access. The lock code is documented in the register
3230642bac7SRichard Leitner 	 * description. Both the unlock code and address can be written in the
3240642bac7SRichard Leitner 	 * same operation.
3250642bac7SRichard Leitner 	 */
326ffd9115fSBryan O'Donoghue 	if (priv->params->bank_address_words != 0) {
327ffd9115fSBryan O'Donoghue 		/*
328ffd9115fSBryan O'Donoghue 		 * In banked/i.MX7 mode the OTP register bank goes into waddr
329ffd9115fSBryan O'Donoghue 		 * see i.MX 7Solo Applications Processor Reference Manual, Rev.
330ffd9115fSBryan O'Donoghue 		 * 0.1 section 6.4.3.1
331ffd9115fSBryan O'Donoghue 		 */
332ffd9115fSBryan O'Donoghue 		offset = offset / priv->config->word_size;
333ffd9115fSBryan O'Donoghue 		waddr = offset / priv->params->bank_address_words;
334ffd9115fSBryan O'Donoghue 		word  = offset & (priv->params->bank_address_words - 1);
335ffd9115fSBryan O'Donoghue 	} else {
336ffd9115fSBryan O'Donoghue 		/*
337ffd9115fSBryan O'Donoghue 		 * Non-banked i.MX6 mode.
338ffd9115fSBryan O'Donoghue 		 * OTP write/read address specifies one of 128 word address
339ffd9115fSBryan O'Donoghue 		 * locations
340ffd9115fSBryan O'Donoghue 		 */
3410642bac7SRichard Leitner 		waddr = offset / 4;
342ffd9115fSBryan O'Donoghue 	}
3430642bac7SRichard Leitner 
3440642bac7SRichard Leitner 	ctrl = readl(priv->base + IMX_OCOTP_ADDR_CTRL);
345226c5126SPeng Fan 	ctrl &= ~priv->params->ctrl.bm_addr;
346226c5126SPeng Fan 	ctrl |= waddr & priv->params->ctrl.bm_addr;
3470642bac7SRichard Leitner 	ctrl |= IMX_OCOTP_WR_UNLOCK;
3480642bac7SRichard Leitner 
3490642bac7SRichard Leitner 	writel(ctrl, priv->base + IMX_OCOTP_ADDR_CTRL);
3500642bac7SRichard Leitner 
3510642bac7SRichard Leitner 	/* 47.3.1.3.4
3520642bac7SRichard Leitner 	 * Write the data to the HW_OCOTP_DATA register. This will automatically
3530642bac7SRichard Leitner 	 * set HW_OCOTP_CTRL[BUSY] and clear HW_OCOTP_CTRL[WR_UNLOCK]. To
3540642bac7SRichard Leitner 	 * protect programming same OTP bit twice, before program OCOTP will
3550642bac7SRichard Leitner 	 * automatically read fuse value in OTP and use read value to mask
3560642bac7SRichard Leitner 	 * program data. The controller will use masked program data to program
3570642bac7SRichard Leitner 	 * a 32-bit word in the OTP per the address in HW_OCOTP_CTRL[ADDR]. Bit
3580642bac7SRichard Leitner 	 * fields with 1's will result in that OTP bit being programmed. Bit
3590642bac7SRichard Leitner 	 * fields with 0's will be ignored. At the same time that the write is
3600642bac7SRichard Leitner 	 * accepted, the controller makes an internal copy of
3610642bac7SRichard Leitner 	 * HW_OCOTP_CTRL[ADDR] which cannot be updated until the next write
3620642bac7SRichard Leitner 	 * sequence is initiated. This copy guarantees that erroneous writes to
3630642bac7SRichard Leitner 	 * HW_OCOTP_CTRL[ADDR] will not affect an active write operation. It
3640642bac7SRichard Leitner 	 * should also be noted that during the programming HW_OCOTP_DATA will
3650642bac7SRichard Leitner 	 * shift right (with zero fill). This shifting is required to program
3660642bac7SRichard Leitner 	 * the OTP serially. During the write operation, HW_OCOTP_DATA cannot be
3670642bac7SRichard Leitner 	 * modified.
368ffd9115fSBryan O'Donoghue 	 * Note: on i.MX7 there are four data fields to write for banked write
369ffd9115fSBryan O'Donoghue 	 *       with the fuse blowing operation only taking place after data0
370ffd9115fSBryan O'Donoghue 	 *	 has been written. This is why data0 must always be the last
371ffd9115fSBryan O'Donoghue 	 *	 register written.
3720642bac7SRichard Leitner 	 */
373ffd9115fSBryan O'Donoghue 	if (priv->params->bank_address_words != 0) {
374ffd9115fSBryan O'Donoghue 		/* Banked/i.MX7 mode */
375ffd9115fSBryan O'Donoghue 		switch (word) {
376ffd9115fSBryan O'Donoghue 		case 0:
377ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA1);
378ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA2);
379ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA3);
380ffd9115fSBryan O'Donoghue 			writel(*buf, priv->base + IMX_OCOTP_ADDR_DATA0);
381ffd9115fSBryan O'Donoghue 			break;
382ffd9115fSBryan O'Donoghue 		case 1:
383ffd9115fSBryan O'Donoghue 			writel(*buf, priv->base + IMX_OCOTP_ADDR_DATA1);
384ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA2);
385ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA3);
386ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA0);
387ffd9115fSBryan O'Donoghue 			break;
388ffd9115fSBryan O'Donoghue 		case 2:
389ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA1);
390ffd9115fSBryan O'Donoghue 			writel(*buf, priv->base + IMX_OCOTP_ADDR_DATA2);
391ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA3);
392ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA0);
393ffd9115fSBryan O'Donoghue 			break;
394ffd9115fSBryan O'Donoghue 		case 3:
395ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA1);
396ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA2);
397ffd9115fSBryan O'Donoghue 			writel(*buf, priv->base + IMX_OCOTP_ADDR_DATA3);
398ffd9115fSBryan O'Donoghue 			writel(0, priv->base + IMX_OCOTP_ADDR_DATA0);
399ffd9115fSBryan O'Donoghue 			break;
400ffd9115fSBryan O'Donoghue 		}
401ffd9115fSBryan O'Donoghue 	} else {
402ffd9115fSBryan O'Donoghue 		/* Non-banked i.MX6 mode */
403ffd9115fSBryan O'Donoghue 		writel(*buf, priv->base + IMX_OCOTP_ADDR_DATA0);
404ffd9115fSBryan O'Donoghue 	}
4050642bac7SRichard Leitner 
4060642bac7SRichard Leitner 	/* 47.4.1.4.5
4070642bac7SRichard Leitner 	 * Once complete, the controller will clear BUSY. A write request to a
4080642bac7SRichard Leitner 	 * protected or locked region will result in no OTP access and no
4090642bac7SRichard Leitner 	 * setting of HW_OCOTP_CTRL[BUSY]. In addition HW_OCOTP_CTRL[ERROR] will
4100642bac7SRichard Leitner 	 * be set. It must be cleared by software before any new write access
4110642bac7SRichard Leitner 	 * can be issued.
4120642bac7SRichard Leitner 	 */
413226c5126SPeng Fan 	ret = imx_ocotp_wait_for_busy(priv, 0);
4140642bac7SRichard Leitner 	if (ret < 0) {
4150642bac7SRichard Leitner 		if (ret == -EPERM) {
4160642bac7SRichard Leitner 			dev_err(priv->dev, "failed write to locked region");
417226c5126SPeng Fan 			imx_ocotp_clr_err_if_set(priv);
4180642bac7SRichard Leitner 		} else {
4190642bac7SRichard Leitner 			dev_err(priv->dev, "timeout during data write\n");
4200642bac7SRichard Leitner 		}
4210642bac7SRichard Leitner 		goto write_end;
4220642bac7SRichard Leitner 	}
4230642bac7SRichard Leitner 
4240642bac7SRichard Leitner 	/* 47.3.1.4
4250642bac7SRichard Leitner 	 * Write Postamble: Due to internal electrical characteristics of the
4260642bac7SRichard Leitner 	 * OTP during writes, all OTP operations following a write must be
4270642bac7SRichard Leitner 	 * separated by 2 us after the clearing of HW_OCOTP_CTRL_BUSY following
4280642bac7SRichard Leitner 	 * the write.
4290642bac7SRichard Leitner 	 */
4300642bac7SRichard Leitner 	udelay(2);
4310642bac7SRichard Leitner 
4320642bac7SRichard Leitner 	/* reload all shadow registers */
433226c5126SPeng Fan 	writel(priv->params->ctrl.bm_rel_shadows,
4340642bac7SRichard Leitner 	       priv->base + IMX_OCOTP_ADDR_CTRL_SET);
435226c5126SPeng Fan 	ret = imx_ocotp_wait_for_busy(priv,
436226c5126SPeng Fan 				      priv->params->ctrl.bm_rel_shadows);
437*0e2abffdSAnson Huang 	if (ret < 0)
4380642bac7SRichard Leitner 		dev_err(priv->dev, "timeout during shadow register reload\n");
4390642bac7SRichard Leitner 
4400642bac7SRichard Leitner write_end:
4410642bac7SRichard Leitner 	clk_disable_unprepare(priv->clk);
4420642bac7SRichard Leitner 	mutex_unlock(&ocotp_mutex);
443*0e2abffdSAnson Huang 	return ret < 0 ? ret : bytes;
4443edba6b4SPhilipp Zabel }
4453edba6b4SPhilipp Zabel 
4463edba6b4SPhilipp Zabel static struct nvmem_config imx_ocotp_nvmem_config = {
4473edba6b4SPhilipp Zabel 	.name = "imx-ocotp",
4480642bac7SRichard Leitner 	.read_only = false,
44933e5e29cSSrinivas Kandagatla 	.word_size = 4,
45033e5e29cSSrinivas Kandagatla 	.stride = 4,
45133e5e29cSSrinivas Kandagatla 	.reg_read = imx_ocotp_read,
4520642bac7SRichard Leitner 	.reg_write = imx_ocotp_write,
4533edba6b4SPhilipp Zabel };
4543edba6b4SPhilipp Zabel 
455e20d2b29SBryan O'Donoghue static const struct ocotp_params imx6q_params = {
456e20d2b29SBryan O'Donoghue 	.nregs = 128,
457ffd9115fSBryan O'Donoghue 	.bank_address_words = 0,
458828ae7a4SBryan O'Donoghue 	.set_timing = imx_ocotp_set_imx6_timing,
459226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
460e20d2b29SBryan O'Donoghue };
461e20d2b29SBryan O'Donoghue 
462e20d2b29SBryan O'Donoghue static const struct ocotp_params imx6sl_params = {
463e20d2b29SBryan O'Donoghue 	.nregs = 64,
464ffd9115fSBryan O'Donoghue 	.bank_address_words = 0,
465828ae7a4SBryan O'Donoghue 	.set_timing = imx_ocotp_set_imx6_timing,
466226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
467e20d2b29SBryan O'Donoghue };
468e20d2b29SBryan O'Donoghue 
4696da27821SAnson Huang static const struct ocotp_params imx6sll_params = {
4706da27821SAnson Huang 	.nregs = 128,
4716da27821SAnson Huang 	.bank_address_words = 0,
4726da27821SAnson Huang 	.set_timing = imx_ocotp_set_imx6_timing,
473226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
4746da27821SAnson Huang };
4756da27821SAnson Huang 
476e20d2b29SBryan O'Donoghue static const struct ocotp_params imx6sx_params = {
477e20d2b29SBryan O'Donoghue 	.nregs = 128,
478ffd9115fSBryan O'Donoghue 	.bank_address_words = 0,
479828ae7a4SBryan O'Donoghue 	.set_timing = imx_ocotp_set_imx6_timing,
480226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
481e20d2b29SBryan O'Donoghue };
482e20d2b29SBryan O'Donoghue 
483e20d2b29SBryan O'Donoghue static const struct ocotp_params imx6ul_params = {
484e20d2b29SBryan O'Donoghue 	.nregs = 128,
485ffd9115fSBryan O'Donoghue 	.bank_address_words = 0,
486828ae7a4SBryan O'Donoghue 	.set_timing = imx_ocotp_set_imx6_timing,
487226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
488e20d2b29SBryan O'Donoghue };
489e20d2b29SBryan O'Donoghue 
490ffbc34bfSStefan Wahren static const struct ocotp_params imx6ull_params = {
491ffbc34bfSStefan Wahren 	.nregs = 64,
492ffbc34bfSStefan Wahren 	.bank_address_words = 0,
493ffbc34bfSStefan Wahren 	.set_timing = imx_ocotp_set_imx6_timing,
494226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
495ffbc34bfSStefan Wahren };
496ffbc34bfSStefan Wahren 
497e20d2b29SBryan O'Donoghue static const struct ocotp_params imx7d_params = {
498e20d2b29SBryan O'Donoghue 	.nregs = 64,
499ffd9115fSBryan O'Donoghue 	.bank_address_words = 4,
500828ae7a4SBryan O'Donoghue 	.set_timing = imx_ocotp_set_imx7_timing,
501226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
502e20d2b29SBryan O'Donoghue };
503e20d2b29SBryan O'Donoghue 
504c8b63ddcSAnson Huang static const struct ocotp_params imx7ulp_params = {
505c8b63ddcSAnson Huang 	.nregs = 256,
506c8b63ddcSAnson Huang 	.bank_address_words = 0,
507226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
508c8b63ddcSAnson Huang };
509c8b63ddcSAnson Huang 
51038e7b6efSLucas Stach static const struct ocotp_params imx8mq_params = {
51138e7b6efSLucas Stach 	.nregs = 256,
5125a1c1724SLeonard Crestez 	.bank_address_words = 0,
5135a1c1724SLeonard Crestez 	.set_timing = imx_ocotp_set_imx6_timing,
514226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
51538e7b6efSLucas Stach };
51638e7b6efSLucas Stach 
5174112c853SBryan O'Donoghue static const struct ocotp_params imx8mm_params = {
5184112c853SBryan O'Donoghue 	.nregs = 256,
5194112c853SBryan O'Donoghue 	.bank_address_words = 0,
5204112c853SBryan O'Donoghue 	.set_timing = imx_ocotp_set_imx6_timing,
521226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
5224112c853SBryan O'Donoghue };
5234112c853SBryan O'Donoghue 
524d93b5d4aSAnson Huang static const struct ocotp_params imx8mn_params = {
525d93b5d4aSAnson Huang 	.nregs = 256,
526d93b5d4aSAnson Huang 	.bank_address_words = 0,
527d93b5d4aSAnson Huang 	.set_timing = imx_ocotp_set_imx6_timing,
528226c5126SPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
529d93b5d4aSAnson Huang };
530d93b5d4aSAnson Huang 
531c3f4af8bSPeng Fan static const struct ocotp_params imx8mp_params = {
532c3f4af8bSPeng Fan 	.nregs = 384,
533c3f4af8bSPeng Fan 	.bank_address_words = 0,
534c3f4af8bSPeng Fan 	.set_timing = imx_ocotp_set_imx6_timing,
535c3f4af8bSPeng Fan 	.ctrl = IMX_OCOTP_BM_CTRL_8MP,
536c3f4af8bSPeng Fan };
537c3f4af8bSPeng Fan 
5383edba6b4SPhilipp Zabel static const struct of_device_id imx_ocotp_dt_ids[] = {
539e20d2b29SBryan O'Donoghue 	{ .compatible = "fsl,imx6q-ocotp",  .data = &imx6q_params },
540e20d2b29SBryan O'Donoghue 	{ .compatible = "fsl,imx6sl-ocotp", .data = &imx6sl_params },
541e20d2b29SBryan O'Donoghue 	{ .compatible = "fsl,imx6sx-ocotp", .data = &imx6sx_params },
542e20d2b29SBryan O'Donoghue 	{ .compatible = "fsl,imx6ul-ocotp", .data = &imx6ul_params },
543ffbc34bfSStefan Wahren 	{ .compatible = "fsl,imx6ull-ocotp", .data = &imx6ull_params },
544e20d2b29SBryan O'Donoghue 	{ .compatible = "fsl,imx7d-ocotp",  .data = &imx7d_params },
5456da27821SAnson Huang 	{ .compatible = "fsl,imx6sll-ocotp", .data = &imx6sll_params },
546c8b63ddcSAnson Huang 	{ .compatible = "fsl,imx7ulp-ocotp", .data = &imx7ulp_params },
54738e7b6efSLucas Stach 	{ .compatible = "fsl,imx8mq-ocotp", .data = &imx8mq_params },
5484112c853SBryan O'Donoghue 	{ .compatible = "fsl,imx8mm-ocotp", .data = &imx8mm_params },
549d93b5d4aSAnson Huang 	{ .compatible = "fsl,imx8mn-ocotp", .data = &imx8mn_params },
550c3f4af8bSPeng Fan 	{ .compatible = "fsl,imx8mp-ocotp", .data = &imx8mp_params },
5513edba6b4SPhilipp Zabel 	{ },
5523edba6b4SPhilipp Zabel };
5533edba6b4SPhilipp Zabel MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
5543edba6b4SPhilipp Zabel 
5553edba6b4SPhilipp Zabel static int imx_ocotp_probe(struct platform_device *pdev)
5563edba6b4SPhilipp Zabel {
5573edba6b4SPhilipp Zabel 	struct device *dev = &pdev->dev;
5583edba6b4SPhilipp Zabel 	struct ocotp_priv *priv;
5593edba6b4SPhilipp Zabel 	struct nvmem_device *nvmem;
5603edba6b4SPhilipp Zabel 
5613edba6b4SPhilipp Zabel 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
5623edba6b4SPhilipp Zabel 	if (!priv)
5633edba6b4SPhilipp Zabel 		return -ENOMEM;
5643edba6b4SPhilipp Zabel 
5654cefb74aSRichard Leitner 	priv->dev = dev;
5664cefb74aSRichard Leitner 
5673b26cd88SAnson Huang 	priv->base = devm_platform_ioremap_resource(pdev, 0);
5683edba6b4SPhilipp Zabel 	if (IS_ERR(priv->base))
5693edba6b4SPhilipp Zabel 		return PTR_ERR(priv->base);
5703edba6b4SPhilipp Zabel 
5714cefb74aSRichard Leitner 	priv->clk = devm_clk_get(dev, NULL);
572deb31970SPeng Fan 	if (IS_ERR(priv->clk))
573deb31970SPeng Fan 		return PTR_ERR(priv->clk);
574deb31970SPeng Fan 
575e20d2b29SBryan O'Donoghue 	priv->params = of_device_get_match_data(&pdev->dev);
576e20d2b29SBryan O'Donoghue 	imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
5773edba6b4SPhilipp Zabel 	imx_ocotp_nvmem_config.dev = dev;
57833e5e29cSSrinivas Kandagatla 	imx_ocotp_nvmem_config.priv = priv;
5790642bac7SRichard Leitner 	priv->config = &imx_ocotp_nvmem_config;
5800642bac7SRichard Leitner 
581226c5126SPeng Fan 	clk_prepare_enable(priv->clk);
582226c5126SPeng Fan 	imx_ocotp_clr_err_if_set(priv);
583226c5126SPeng Fan 	clk_disable_unprepare(priv->clk);
584226c5126SPeng Fan 
585226c5126SPeng Fan 	nvmem = devm_nvmem_register(dev, &imx_ocotp_nvmem_config);
5863edba6b4SPhilipp Zabel 
587a830274fSAndrey Smirnov 	return PTR_ERR_OR_ZERO(nvmem);
5883edba6b4SPhilipp Zabel }
5893edba6b4SPhilipp Zabel 
5903edba6b4SPhilipp Zabel static struct platform_driver imx_ocotp_driver = {
5913edba6b4SPhilipp Zabel 	.probe	= imx_ocotp_probe,
5923edba6b4SPhilipp Zabel 	.driver = {
5933edba6b4SPhilipp Zabel 		.name	= "imx_ocotp",
5943edba6b4SPhilipp Zabel 		.of_match_table = imx_ocotp_dt_ids,
5953edba6b4SPhilipp Zabel 	},
5963edba6b4SPhilipp Zabel };
5973edba6b4SPhilipp Zabel module_platform_driver(imx_ocotp_driver);
5983edba6b4SPhilipp Zabel 
5993edba6b4SPhilipp Zabel MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
600aef9a4deSBryan O'Donoghue MODULE_DESCRIPTION("i.MX6/i.MX7 OCOTP fuse box driver");
6013edba6b4SPhilipp Zabel MODULE_LICENSE("GPL v2");
602