xref: /linux/drivers/nvmem/rockchip-otp.c (revision cb4eb6771c0f8fd1c52a8f6fdec7762fb087380a)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Rockchip OTP Driver
4  *
5  * Copyright (c) 2018 Rockchip Electronics Co. Ltd.
6  * Author: Finley Xiao <finley.xiao@rock-chips.com>
7  */
8 
9 #include <linux/clk.h>
10 #include <linux/delay.h>
11 #include <linux/device.h>
12 #include <linux/io.h>
13 #include <linux/iopoll.h>
14 #include <linux/module.h>
15 #include <linux/nvmem-provider.h>
16 #include <linux/reset.h>
17 #include <linux/slab.h>
18 #include <linux/of.h>
19 #include <linux/of_platform.h>
20 #include <linux/platform_device.h>
21 
22 /* OTP Register Offsets */
23 #define OTPC_SBPI_CTRL			0x0020
24 #define OTPC_SBPI_CMD_VALID_PRE		0x0024
25 #define OTPC_SBPI_CS_VALID_PRE		0x0028
26 #define OTPC_SBPI_STATUS		0x002C
27 #define OTPC_USER_CTRL			0x0100
28 #define OTPC_USER_ADDR			0x0104
29 #define OTPC_USER_ENABLE		0x0108
30 #define OTPC_USER_QP			0x0120
31 #define OTPC_USER_Q			0x0124
32 #define OTPC_INT_STATUS			0x0304
33 #define OTPC_SBPI_CMD0_OFFSET		0x1000
34 #define OTPC_SBPI_CMD1_OFFSET		0x1004
35 
36 /* OTP Register bits and masks */
37 #define OTPC_USER_ADDR_MASK		GENMASK(31, 16)
38 #define OTPC_USE_USER			BIT(0)
39 #define OTPC_USE_USER_MASK		GENMASK(16, 16)
40 #define OTPC_USER_FSM_ENABLE		BIT(0)
41 #define OTPC_USER_FSM_ENABLE_MASK	GENMASK(16, 16)
42 #define OTPC_SBPI_DONE			BIT(1)
43 #define OTPC_USER_DONE			BIT(2)
44 
45 #define SBPI_DAP_ADDR			0x02
46 #define SBPI_DAP_ADDR_SHIFT		8
47 #define SBPI_DAP_ADDR_MASK		GENMASK(31, 24)
48 #define SBPI_CMD_VALID_MASK		GENMASK(31, 16)
49 #define SBPI_DAP_CMD_WRF		0xC0
50 #define SBPI_DAP_REG_ECC		0x3A
51 #define SBPI_ECC_ENABLE			0x00
52 #define SBPI_ECC_DISABLE		0x09
53 #define SBPI_ENABLE			BIT(0)
54 #define SBPI_ENABLE_MASK		GENMASK(16, 16)
55 
56 #define OTPC_TIMEOUT			10000
57 
58 /* RK3588 Register */
59 #define RK3588_OTPC_AUTO_CTRL		0x04
60 #define RK3588_OTPC_AUTO_EN		0x08
61 #define RK3588_OTPC_INT_ST		0x84
62 #define RK3588_OTPC_DOUT0		0x20
63 #define RK3588_BURST_NUM		1
64 #define RK3588_BURST_SHIFT		8
65 #define RK3588_ADDR_SHIFT		16
66 #define RK3588_AUTO_EN			BIT(0)
67 #define RK3588_RD_DONE			BIT(1)
68 
69 struct rockchip_data {
70 	int size;
71 	int read_offset;
72 	int word_size;
73 	const char * const *clks;
74 	int num_clks;
75 	nvmem_reg_read_t reg_read;
76 };
77 
78 struct rockchip_otp {
79 	struct device *dev;
80 	void __iomem *base;
81 	struct clk_bulk_data *clks;
82 	struct reset_control *rst;
83 	const struct rockchip_data *data;
84 };
85 
rockchip_otp_reset(struct rockchip_otp * otp)86 static int rockchip_otp_reset(struct rockchip_otp *otp)
87 {
88 	int ret;
89 
90 	ret = reset_control_assert(otp->rst);
91 	if (ret) {
92 		dev_err(otp->dev, "failed to assert otp phy %d\n", ret);
93 		return ret;
94 	}
95 
96 	udelay(2);
97 
98 	ret = reset_control_deassert(otp->rst);
99 	if (ret) {
100 		dev_err(otp->dev, "failed to deassert otp phy %d\n", ret);
101 		return ret;
102 	}
103 
104 	return 0;
105 }
106 
rockchip_otp_wait_status(struct rockchip_otp * otp,unsigned int reg,u32 flag)107 static int rockchip_otp_wait_status(struct rockchip_otp *otp,
108 				    unsigned int reg, u32 flag)
109 {
110 	u32 status = 0;
111 	int ret;
112 
113 	ret = readl_poll_timeout_atomic(otp->base + reg, status,
114 					(status & flag), 1, OTPC_TIMEOUT);
115 	if (ret)
116 		return ret;
117 
118 	/* clean int status */
119 	writel(flag, otp->base + reg);
120 
121 	return 0;
122 }
123 
rockchip_otp_ecc_enable(struct rockchip_otp * otp,bool enable)124 static int rockchip_otp_ecc_enable(struct rockchip_otp *otp, bool enable)
125 {
126 	int ret = 0;
127 
128 	writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT),
129 	       otp->base + OTPC_SBPI_CTRL);
130 
131 	writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE);
132 	writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC,
133 	       otp->base + OTPC_SBPI_CMD0_OFFSET);
134 	if (enable)
135 		writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
136 	else
137 		writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
138 
139 	writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
140 
141 	ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_SBPI_DONE);
142 	if (ret < 0)
143 		dev_err(otp->dev, "timeout during ecc_enable\n");
144 
145 	return ret;
146 }
147 
px30_otp_read(void * context,unsigned int offset,void * val,size_t bytes)148 static int px30_otp_read(void *context, unsigned int offset,
149 			 void *val, size_t bytes)
150 {
151 	struct rockchip_otp *otp = context;
152 	u8 *buf = val;
153 	int ret;
154 
155 	ret = rockchip_otp_reset(otp);
156 	if (ret) {
157 		dev_err(otp->dev, "failed to reset otp phy\n");
158 		return ret;
159 	}
160 
161 	ret = rockchip_otp_ecc_enable(otp, false);
162 	if (ret < 0) {
163 		dev_err(otp->dev, "rockchip_otp_ecc_enable err\n");
164 		return ret;
165 	}
166 
167 	writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
168 	udelay(5);
169 	while (bytes--) {
170 		writel(offset++ | OTPC_USER_ADDR_MASK,
171 		       otp->base + OTPC_USER_ADDR);
172 		writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
173 		       otp->base + OTPC_USER_ENABLE);
174 		ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_USER_DONE);
175 		if (ret < 0) {
176 			dev_err(otp->dev, "timeout during read setup\n");
177 			goto read_end;
178 		}
179 		*buf++ = readb(otp->base + OTPC_USER_Q);
180 	}
181 
182 read_end:
183 	writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
184 
185 	return ret;
186 }
187 
rk3568_otp_read(void * context,unsigned int offset,void * val,size_t count)188 static int rk3568_otp_read(void *context, unsigned int offset, void *val,
189 			   size_t count)
190 {
191 	struct rockchip_otp *otp = context;
192 	u16 *buf = val;
193 	u32 otp_qp;
194 	int ret;
195 
196 	ret = rockchip_otp_reset(otp);
197 	if (ret) {
198 		dev_err(otp->dev, "failed to reset otp phy\n");
199 		return ret;
200 	}
201 
202 	ret = rockchip_otp_ecc_enable(otp, true);
203 	if (ret) {
204 		dev_err(otp->dev, "rockchip_otp_ecc_enable err\n");
205 		return ret;
206 	}
207 
208 	writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
209 	udelay(5);
210 
211 	while (count--) {
212 		writel(offset++ | OTPC_USER_ADDR_MASK,
213 		       otp->base + OTPC_USER_ADDR);
214 		writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
215 		       otp->base + OTPC_USER_ENABLE);
216 
217 		ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS,
218 					       OTPC_USER_DONE);
219 		if (ret) {
220 			dev_err(otp->dev, "timeout during read setup\n");
221 			goto read_end;
222 		}
223 
224 		otp_qp = readl(otp->base + OTPC_USER_QP);
225 		if (((otp_qp & 0xc0) == 0xc0) || (otp_qp & 0x20)) {
226 			ret = -EIO;
227 			dev_err(otp->dev, "ecc check error during read setup\n");
228 			goto read_end;
229 		}
230 
231 		*buf++ = readl(otp->base + OTPC_USER_Q);
232 	}
233 
234 read_end:
235 	writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
236 
237 	return ret;
238 }
239 
rk3588_otp_read(void * context,unsigned int offset,void * val,size_t count)240 static int rk3588_otp_read(void *context, unsigned int offset,
241 			   void *val, size_t count)
242 {
243 	struct rockchip_otp *otp = context;
244 	u32 *buf = val;
245 	int ret;
246 
247 	while (count--) {
248 		writel((offset++ << RK3588_ADDR_SHIFT) |
249 		       (RK3588_BURST_NUM << RK3588_BURST_SHIFT),
250 		       otp->base + RK3588_OTPC_AUTO_CTRL);
251 		writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
252 
253 		ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST,
254 					       RK3588_RD_DONE);
255 		if (ret) {
256 			dev_err(otp->dev, "timeout during read setup\n");
257 			return ret;
258 		}
259 
260 		*buf++ = readl(otp->base + RK3588_OTPC_DOUT0);
261 	}
262 
263 	return ret;
264 }
265 
rockchip_otp_read(void * context,unsigned int offset,void * val,size_t bytes)266 static int rockchip_otp_read(void *context, unsigned int offset,
267 			     void *val, size_t bytes)
268 {
269 	struct rockchip_otp *otp = context;
270 	int ret, word_size;
271 
272 	if (!otp->data || !otp->data->reg_read)
273 		return -EINVAL;
274 
275 	ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks);
276 	if (ret < 0) {
277 		dev_err(otp->dev, "failed to prepare/enable clks\n");
278 		return ret;
279 	}
280 
281 	offset += otp->data->read_offset;
282 	word_size = otp->data->word_size;
283 
284 	if (word_size > 1) {
285 		unsigned int addr_start, addr_end;
286 		size_t count;
287 		u8 *buf;
288 
289 		addr_start = offset / word_size;
290 		addr_end = DIV_ROUND_UP(offset + bytes, word_size);
291 		count = addr_end - addr_start;
292 
293 		buf = kzalloc(array_size(count, word_size), GFP_KERNEL);
294 		if (!buf) {
295 			ret = -ENOMEM;
296 			goto err;
297 		}
298 
299 		ret = otp->data->reg_read(context, addr_start, buf, count);
300 		if (!ret)
301 			memcpy(val, buf + (offset % word_size), bytes);
302 
303 		kfree(buf);
304 	} else {
305 		ret = otp->data->reg_read(context, offset, val, bytes);
306 	}
307 
308 err:
309 	clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks);
310 
311 	return ret;
312 }
313 
314 static struct nvmem_config otp_config = {
315 	.name = "rockchip-otp",
316 	.owner = THIS_MODULE,
317 	.add_legacy_fixed_of_cells = true,
318 	.type = NVMEM_TYPE_OTP,
319 	.read_only = true,
320 	.stride = 1,
321 	.word_size = sizeof(u8),
322 	.reg_read = rockchip_otp_read,
323 };
324 
325 static const char * const px30_otp_clocks[] = {
326 	"otp", "apb_pclk", "phy",
327 };
328 
329 static const struct rockchip_data px30_data = {
330 	.size = 0x40,
331 	.clks = px30_otp_clocks,
332 	.num_clks = ARRAY_SIZE(px30_otp_clocks),
333 	.reg_read = px30_otp_read,
334 };
335 
336 static const char * const rk3528_otp_clocks[] = {
337 	"otp", "apb_pclk", "sbpi",
338 };
339 
340 static const struct rockchip_data rk3528_data = {
341 	.size = 0x80,
342 	.word_size = sizeof(u16),
343 	.clks = rk3528_otp_clocks,
344 	.num_clks = ARRAY_SIZE(rk3528_otp_clocks),
345 	.reg_read = rk3568_otp_read,
346 };
347 
348 static const char * const rk3568_otp_clocks[] = {
349 	"otp", "apb_pclk", "phy", "sbpi",
350 };
351 
352 static const struct rockchip_data rk3568_data = {
353 	.size = 0x80,
354 	.word_size = sizeof(u16),
355 	.clks = rk3568_otp_clocks,
356 	.num_clks = ARRAY_SIZE(rk3568_otp_clocks),
357 	.reg_read = rk3568_otp_read,
358 };
359 
360 static const struct rockchip_data rk3576_data = {
361 	.size = 0x100,
362 	.read_offset = 0x700,
363 	.word_size = sizeof(u32),
364 	.clks = px30_otp_clocks,
365 	.num_clks = ARRAY_SIZE(px30_otp_clocks),
366 	.reg_read = rk3588_otp_read,
367 };
368 
369 static const char * const rk3588_otp_clocks[] = {
370 	"otp", "apb_pclk", "phy", "arb",
371 };
372 
373 static const struct rockchip_data rk3588_data = {
374 	.size = 0x400,
375 	.read_offset = 0xc00,
376 	.word_size = sizeof(u32),
377 	.clks = rk3588_otp_clocks,
378 	.num_clks = ARRAY_SIZE(rk3588_otp_clocks),
379 	.reg_read = rk3588_otp_read,
380 };
381 
382 static const struct of_device_id rockchip_otp_match[] = {
383 	{
384 		.compatible = "rockchip,px30-otp",
385 		.data = &px30_data,
386 	},
387 	{
388 		.compatible = "rockchip,rk3308-otp",
389 		.data = &px30_data,
390 	},
391 	{
392 		.compatible = "rockchip,rk3528-otp",
393 		.data = &rk3528_data,
394 	},
395 	{
396 		.compatible = "rockchip,rk3562-otp",
397 		.data = &rk3568_data,
398 	},
399 	{
400 		.compatible = "rockchip,rk3568-otp",
401 		.data = &rk3568_data,
402 	},
403 	{
404 		.compatible = "rockchip,rk3576-otp",
405 		.data = &rk3576_data,
406 	},
407 	{
408 		.compatible = "rockchip,rk3588-otp",
409 		.data = &rk3588_data,
410 	},
411 	{ /* sentinel */ },
412 };
413 MODULE_DEVICE_TABLE(of, rockchip_otp_match);
414 
rockchip_otp_probe(struct platform_device * pdev)415 static int rockchip_otp_probe(struct platform_device *pdev)
416 {
417 	struct device *dev = &pdev->dev;
418 	struct rockchip_otp *otp;
419 	const struct rockchip_data *data;
420 	struct nvmem_device *nvmem;
421 	int ret, i;
422 
423 	data = of_device_get_match_data(dev);
424 	if (!data)
425 		return dev_err_probe(dev, -EINVAL, "failed to get match data\n");
426 
427 	otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp),
428 			   GFP_KERNEL);
429 	if (!otp)
430 		return -ENOMEM;
431 
432 	otp->data = data;
433 	otp->dev = dev;
434 	otp->base = devm_platform_ioremap_resource(pdev, 0);
435 	if (IS_ERR(otp->base))
436 		return dev_err_probe(dev, PTR_ERR(otp->base),
437 				     "failed to ioremap resource\n");
438 
439 	otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
440 				 GFP_KERNEL);
441 	if (!otp->clks)
442 		return -ENOMEM;
443 
444 	for (i = 0; i < data->num_clks; ++i)
445 		otp->clks[i].id = data->clks[i];
446 
447 	ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
448 	if (ret)
449 		return dev_err_probe(dev, ret, "failed to get clocks\n");
450 
451 	otp->rst = devm_reset_control_array_get_exclusive(dev);
452 	if (IS_ERR(otp->rst))
453 		return dev_err_probe(dev, PTR_ERR(otp->rst),
454 				     "failed to get resets\n");
455 
456 	otp_config.size = data->size;
457 	otp_config.priv = otp;
458 	otp_config.dev = dev;
459 
460 	nvmem = devm_nvmem_register(dev, &otp_config);
461 	if (IS_ERR(nvmem))
462 		return dev_err_probe(dev, PTR_ERR(nvmem),
463 				     "failed to register nvmem device\n");
464 	return 0;
465 }
466 
467 static struct platform_driver rockchip_otp_driver = {
468 	.probe = rockchip_otp_probe,
469 	.driver = {
470 		.name = "rockchip-otp",
471 		.of_match_table = rockchip_otp_match,
472 	},
473 };
474 
475 module_platform_driver(rockchip_otp_driver);
476 MODULE_DESCRIPTION("Rockchip OTP driver");
477 MODULE_LICENSE("GPL v2");
478