1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2022-2023 Microchip Technology Inc.
3// PCI1xxxx OTP/EEPROM driver
4
5#include <linux/auxiliary_bus.h>
6#include <linux/device.h>
7#include <linux/iopoll.h>
8#include <linux/module.h>
9#include <linux/nvmem-provider.h>
10
11#include "mchp_pci1xxxx_gp.h"
12
13#define AUX_DRIVER_NAME			"PCI1xxxxOTPE2P"
14#define EEPROM_NAME			"pci1xxxx_eeprom"
15#define OTP_NAME			"pci1xxxx_otp"
16
17#define PERI_PF3_SYSTEM_REG_ADDR_BASE	0x2000
18#define PERI_PF3_SYSTEM_REG_LENGTH	0x4000
19
20#define EEPROM_SIZE_BYTES		8192
21#define OTP_SIZE_BYTES			8192
22
23#define CONFIG_REG_ADDR_BASE		0
24#define EEPROM_REG_ADDR_BASE		0x0E00
25#define OTP_REG_ADDR_BASE		0x1000
26
27#define MMAP_OTP_OFFSET(x)		(OTP_REG_ADDR_BASE + (x))
28#define MMAP_EEPROM_OFFSET(x)		(EEPROM_REG_ADDR_BASE + (x))
29#define MMAP_CFG_OFFSET(x)		(CONFIG_REG_ADDR_BASE + (x))
30
31#define EEPROM_CMD_REG			0x00
32#define EEPROM_DATA_REG			0x04
33
34#define EEPROM_CMD_EPC_WRITE		(BIT(29) | BIT(28))
35#define EEPROM_CMD_EPC_TIMEOUT_BIT	BIT(17)
36#define EEPROM_CMD_EPC_BUSY_BIT		BIT(31)
37
38#define STATUS_READ_DELAY_US		1
39#define STATUS_READ_TIMEOUT_US		20000
40
41#define OTP_ADDR_HIGH_OFFSET		0x04
42#define OTP_ADDR_LOW_OFFSET		0x08
43#define OTP_PRGM_DATA_OFFSET		0x10
44#define OTP_PRGM_MODE_OFFSET		0x14
45#define OTP_RD_DATA_OFFSET		0x18
46#define OTP_FUNC_CMD_OFFSET		0x20
47#define OTP_CMD_GO_OFFSET		0x28
48#define OTP_PASS_FAIL_OFFSET		0x2C
49#define OTP_STATUS_OFFSET		0x30
50
51#define OTP_FUNC_RD_BIT			BIT(0)
52#define OTP_FUNC_PGM_BIT		BIT(1)
53#define OTP_CMD_GO_BIT			BIT(0)
54#define OTP_STATUS_BUSY_BIT		BIT(0)
55#define OTP_PGM_MODE_BYTE_BIT		BIT(0)
56#define OTP_FAIL_BIT			BIT(0)
57
58#define OTP_PWR_DN_BIT			BIT(0)
59#define OTP_PWR_DN_OFFSET		0x00
60
61#define CFG_SYS_LOCK_OFFSET		0xA0
62#define CFG_SYS_LOCK_PF3		BIT(5)
63
64#define BYTE_LOW			(GENMASK(7, 0))
65#define BYTE_HIGH			(GENMASK(12, 8))
66
67struct pci1xxxx_otp_eeprom_device {
68	struct auxiliary_device *pdev;
69	void __iomem *reg_base;
70	struct nvmem_config nvmem_config_eeprom;
71	struct nvmem_device *nvmem_eeprom;
72	struct nvmem_config nvmem_config_otp;
73	struct nvmem_device *nvmem_otp;
74};
75
76static int set_sys_lock(struct pci1xxxx_otp_eeprom_device *priv)
77{
78	void __iomem *sys_lock = priv->reg_base +
79				 MMAP_CFG_OFFSET(CFG_SYS_LOCK_OFFSET);
80	u8 data;
81
82	writel(CFG_SYS_LOCK_PF3, sys_lock);
83	data = readl(sys_lock);
84	if (data != CFG_SYS_LOCK_PF3)
85		return -EPERM;
86
87	return 0;
88}
89
90static void release_sys_lock(struct pci1xxxx_otp_eeprom_device *priv)
91{
92	void __iomem *sys_lock = priv->reg_base +
93				 MMAP_CFG_OFFSET(CFG_SYS_LOCK_OFFSET);
94	writel(0, sys_lock);
95}
96
97static bool is_eeprom_responsive(struct pci1xxxx_otp_eeprom_device *priv)
98{
99	void __iomem *rb = priv->reg_base;
100	u32 regval;
101	int ret;
102
103	writel(EEPROM_CMD_EPC_TIMEOUT_BIT,
104	       rb + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
105	writel(EEPROM_CMD_EPC_BUSY_BIT,
106	       rb + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
107
108	/* Wait for the EPC_BUSY bit to get cleared or timeout bit to get set*/
109	ret = read_poll_timeout(readl, regval, !(regval & EEPROM_CMD_EPC_BUSY_BIT),
110				STATUS_READ_DELAY_US, STATUS_READ_TIMEOUT_US,
111				true, rb + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
112
113	/* Return failure if either of software or hardware timeouts happen */
114	if (ret < 0 || (!ret && (regval & EEPROM_CMD_EPC_TIMEOUT_BIT)))
115		return false;
116
117	return true;
118}
119
120static int pci1xxxx_eeprom_read(void *priv_t, unsigned int off,
121				void *buf_t, size_t count)
122{
123	struct pci1xxxx_otp_eeprom_device *priv = priv_t;
124	void __iomem *rb = priv->reg_base;
125	char *buf = buf_t;
126	u32 regval;
127	u32 byte;
128	int ret;
129
130	if (off >= priv->nvmem_config_eeprom.size)
131		return -EFAULT;
132
133	if ((off + count) > priv->nvmem_config_eeprom.size)
134		count = priv->nvmem_config_eeprom.size - off;
135
136	ret = set_sys_lock(priv);
137	if (ret)
138		return ret;
139
140	for (byte = 0; byte < count; byte++) {
141		writel(EEPROM_CMD_EPC_BUSY_BIT | (off + byte), rb +
142		       MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
143
144		ret = read_poll_timeout(readl, regval,
145					!(regval & EEPROM_CMD_EPC_BUSY_BIT),
146					STATUS_READ_DELAY_US,
147					STATUS_READ_TIMEOUT_US, true,
148					rb + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
149		if (ret < 0 || (!ret && (regval & EEPROM_CMD_EPC_TIMEOUT_BIT))) {
150			ret = -EIO;
151			goto error;
152		}
153
154		buf[byte] = readl(rb + MMAP_EEPROM_OFFSET(EEPROM_DATA_REG));
155	}
156	ret = byte;
157error:
158	release_sys_lock(priv);
159	return ret;
160}
161
162static int pci1xxxx_eeprom_write(void *priv_t, unsigned int off,
163				 void *value_t, size_t count)
164{
165	struct pci1xxxx_otp_eeprom_device *priv = priv_t;
166	void __iomem *rb = priv->reg_base;
167	char *value = value_t;
168	u32 regval;
169	u32 byte;
170	int ret;
171
172	if (off >= priv->nvmem_config_eeprom.size)
173		return -EFAULT;
174
175	if ((off + count) > priv->nvmem_config_eeprom.size)
176		count = priv->nvmem_config_eeprom.size - off;
177
178	ret = set_sys_lock(priv);
179	if (ret)
180		return ret;
181
182	for (byte = 0; byte < count; byte++) {
183		writel(*(value + byte), rb + MMAP_EEPROM_OFFSET(EEPROM_DATA_REG));
184		regval = EEPROM_CMD_EPC_TIMEOUT_BIT | EEPROM_CMD_EPC_WRITE |
185			 (off + byte);
186		writel(regval, rb + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
187		writel(EEPROM_CMD_EPC_BUSY_BIT | regval,
188		       rb + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
189
190		ret = read_poll_timeout(readl, regval,
191					!(regval & EEPROM_CMD_EPC_BUSY_BIT),
192					STATUS_READ_DELAY_US,
193					STATUS_READ_TIMEOUT_US, true,
194					rb + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG));
195		if (ret < 0 || (!ret && (regval & EEPROM_CMD_EPC_TIMEOUT_BIT))) {
196			ret = -EIO;
197			goto error;
198		}
199	}
200	ret = byte;
201error:
202	release_sys_lock(priv);
203	return ret;
204}
205
206static void otp_device_set_address(struct pci1xxxx_otp_eeprom_device *priv,
207				   u16 address)
208{
209	u16 lo, hi;
210
211	lo = address & BYTE_LOW;
212	hi = (address & BYTE_HIGH) >> 8;
213	writew(lo, priv->reg_base + MMAP_OTP_OFFSET(OTP_ADDR_LOW_OFFSET));
214	writew(hi, priv->reg_base + MMAP_OTP_OFFSET(OTP_ADDR_HIGH_OFFSET));
215}
216
217static int pci1xxxx_otp_read(void *priv_t, unsigned int off,
218			     void *buf_t, size_t count)
219{
220	struct pci1xxxx_otp_eeprom_device *priv = priv_t;
221	void __iomem *rb = priv->reg_base;
222	char *buf = buf_t;
223	u32 regval;
224	u32 byte;
225	int ret;
226	u8 data;
227
228	if (off >= priv->nvmem_config_otp.size)
229		return -EFAULT;
230
231	if ((off + count) > priv->nvmem_config_otp.size)
232		count = priv->nvmem_config_otp.size - off;
233
234	ret = set_sys_lock(priv);
235	if (ret)
236		return ret;
237
238	for (byte = 0; byte < count; byte++) {
239		otp_device_set_address(priv, (u16)(off + byte));
240		data = readl(rb + MMAP_OTP_OFFSET(OTP_FUNC_CMD_OFFSET));
241		writel(data | OTP_FUNC_RD_BIT,
242		       rb + MMAP_OTP_OFFSET(OTP_FUNC_CMD_OFFSET));
243		data = readl(rb + MMAP_OTP_OFFSET(OTP_CMD_GO_OFFSET));
244		writel(data | OTP_CMD_GO_BIT,
245		       rb + MMAP_OTP_OFFSET(OTP_CMD_GO_OFFSET));
246
247		ret = read_poll_timeout(readl, regval,
248					!(regval & OTP_STATUS_BUSY_BIT),
249					STATUS_READ_DELAY_US,
250					STATUS_READ_TIMEOUT_US, true,
251					rb + MMAP_OTP_OFFSET(OTP_STATUS_OFFSET));
252
253		data = readl(rb + MMAP_OTP_OFFSET(OTP_PASS_FAIL_OFFSET));
254		if (ret < 0 || data & OTP_FAIL_BIT) {
255			ret = -EIO;
256			goto error;
257		}
258
259		buf[byte] = readl(rb + MMAP_OTP_OFFSET(OTP_RD_DATA_OFFSET));
260	}
261	ret = byte;
262error:
263	release_sys_lock(priv);
264	return ret;
265}
266
267static int pci1xxxx_otp_write(void *priv_t, unsigned int off,
268			      void *value_t, size_t count)
269{
270	struct pci1xxxx_otp_eeprom_device *priv = priv_t;
271	void __iomem *rb = priv->reg_base;
272	char *value = value_t;
273	u32 regval;
274	u32 byte;
275	int ret;
276	u8 data;
277
278	if (off >= priv->nvmem_config_otp.size)
279		return -EFAULT;
280
281	if ((off + count) > priv->nvmem_config_otp.size)
282		count = priv->nvmem_config_otp.size - off;
283
284	ret = set_sys_lock(priv);
285	if (ret)
286		return ret;
287
288	for (byte = 0; byte < count; byte++) {
289		otp_device_set_address(priv, (u16)(off + byte));
290
291		/*
292		 * Set OTP_PGM_MODE_BYTE command bit in OTP_PRGM_MODE register
293		 * to enable Byte programming
294		 */
295		data = readl(rb + MMAP_OTP_OFFSET(OTP_PRGM_MODE_OFFSET));
296		writel(data | OTP_PGM_MODE_BYTE_BIT,
297		       rb + MMAP_OTP_OFFSET(OTP_PRGM_MODE_OFFSET));
298		writel(*(value + byte), rb + MMAP_OTP_OFFSET(OTP_PRGM_DATA_OFFSET));
299		data = readl(rb + MMAP_OTP_OFFSET(OTP_FUNC_CMD_OFFSET));
300		writel(data | OTP_FUNC_PGM_BIT,
301		       rb + MMAP_OTP_OFFSET(OTP_FUNC_CMD_OFFSET));
302		data = readl(rb + MMAP_OTP_OFFSET(OTP_CMD_GO_OFFSET));
303		writel(data | OTP_CMD_GO_BIT,
304		       rb + MMAP_OTP_OFFSET(OTP_CMD_GO_OFFSET));
305
306		ret = read_poll_timeout(readl, regval,
307					!(regval & OTP_STATUS_BUSY_BIT),
308					STATUS_READ_DELAY_US,
309					STATUS_READ_TIMEOUT_US, true,
310					rb + MMAP_OTP_OFFSET(OTP_STATUS_OFFSET));
311
312		data = readl(rb + MMAP_OTP_OFFSET(OTP_PASS_FAIL_OFFSET));
313		if (ret < 0 || data & OTP_FAIL_BIT) {
314			ret = -EIO;
315			goto error;
316		}
317	}
318	ret = byte;
319error:
320	release_sys_lock(priv);
321	return ret;
322}
323
324static int pci1xxxx_otp_eeprom_probe(struct auxiliary_device *aux_dev,
325				     const struct auxiliary_device_id *id)
326{
327	struct auxiliary_device_wrapper *aux_dev_wrapper;
328	struct pci1xxxx_otp_eeprom_device *priv;
329	struct gp_aux_data_type *pdata;
330	int ret;
331	u8 data;
332
333	aux_dev_wrapper = container_of(aux_dev, struct auxiliary_device_wrapper,
334				       aux_dev);
335	pdata = &aux_dev_wrapper->gp_aux_data;
336	if (!pdata)
337		return -EINVAL;
338
339	priv = devm_kzalloc(&aux_dev->dev, sizeof(*priv), GFP_KERNEL);
340	if (!priv)
341		return -ENOMEM;
342
343	priv->pdev = aux_dev;
344
345	if (!devm_request_mem_region(&aux_dev->dev, pdata->region_start +
346				     PERI_PF3_SYSTEM_REG_ADDR_BASE,
347				     PERI_PF3_SYSTEM_REG_LENGTH,
348				     aux_dev->name))
349		return -ENOMEM;
350
351	priv->reg_base = devm_ioremap(&aux_dev->dev, pdata->region_start +
352				      PERI_PF3_SYSTEM_REG_ADDR_BASE,
353				      PERI_PF3_SYSTEM_REG_LENGTH);
354	if (!priv->reg_base)
355		return -ENOMEM;
356
357	ret = set_sys_lock(priv);
358	if (ret)
359		return ret;
360
361	/* Set OTP_PWR_DN to 0 to make OTP Operational */
362	data = readl(priv->reg_base + MMAP_OTP_OFFSET(OTP_PWR_DN_OFFSET));
363	writel(data & ~OTP_PWR_DN_BIT,
364	       priv->reg_base + MMAP_OTP_OFFSET(OTP_PWR_DN_OFFSET));
365
366	dev_set_drvdata(&aux_dev->dev, priv);
367
368	if (is_eeprom_responsive(priv)) {
369		priv->nvmem_config_eeprom.type = NVMEM_TYPE_EEPROM;
370		priv->nvmem_config_eeprom.name = EEPROM_NAME;
371		priv->nvmem_config_eeprom.dev = &aux_dev->dev;
372		priv->nvmem_config_eeprom.owner = THIS_MODULE;
373		priv->nvmem_config_eeprom.reg_read = pci1xxxx_eeprom_read;
374		priv->nvmem_config_eeprom.reg_write = pci1xxxx_eeprom_write;
375		priv->nvmem_config_eeprom.priv = priv;
376		priv->nvmem_config_eeprom.stride = 1;
377		priv->nvmem_config_eeprom.word_size = 1;
378		priv->nvmem_config_eeprom.size = EEPROM_SIZE_BYTES;
379
380		priv->nvmem_eeprom = devm_nvmem_register(&aux_dev->dev,
381							 &priv->nvmem_config_eeprom);
382		if (IS_ERR(priv->nvmem_eeprom))
383			return PTR_ERR(priv->nvmem_eeprom);
384	}
385
386	release_sys_lock(priv);
387
388	priv->nvmem_config_otp.type = NVMEM_TYPE_OTP;
389	priv->nvmem_config_otp.name = OTP_NAME;
390	priv->nvmem_config_otp.dev = &aux_dev->dev;
391	priv->nvmem_config_otp.owner = THIS_MODULE;
392	priv->nvmem_config_otp.reg_read = pci1xxxx_otp_read;
393	priv->nvmem_config_otp.reg_write = pci1xxxx_otp_write;
394	priv->nvmem_config_otp.priv = priv;
395	priv->nvmem_config_otp.stride = 1;
396	priv->nvmem_config_otp.word_size = 1;
397	priv->nvmem_config_otp.size = OTP_SIZE_BYTES;
398
399	priv->nvmem_otp = devm_nvmem_register(&aux_dev->dev,
400					      &priv->nvmem_config_otp);
401	if (IS_ERR(priv->nvmem_otp))
402		return PTR_ERR(priv->nvmem_otp);
403
404	return ret;
405}
406
407static void pci1xxxx_otp_eeprom_remove(struct auxiliary_device *aux_dev)
408{
409	struct pci1xxxx_otp_eeprom_device *priv;
410	void __iomem *sys_lock;
411
412	priv = dev_get_drvdata(&aux_dev->dev);
413	sys_lock = priv->reg_base + MMAP_CFG_OFFSET(CFG_SYS_LOCK_OFFSET);
414	writel(CFG_SYS_LOCK_PF3, sys_lock);
415
416	/* Shut down OTP */
417	writel(OTP_PWR_DN_BIT,
418	       priv->reg_base + MMAP_OTP_OFFSET(OTP_PWR_DN_OFFSET));
419
420	writel(0, sys_lock);
421}
422
423static const struct auxiliary_device_id pci1xxxx_otp_eeprom_auxiliary_id_table[] = {
424	{.name = "mchp_pci1xxxx_gp.gp_otp_e2p"},
425	{},
426};
427MODULE_DEVICE_TABLE(auxiliary, pci1xxxx_otp_eeprom_auxiliary_id_table);
428
429static struct auxiliary_driver pci1xxxx_otp_eeprom_driver = {
430	.driver = {
431		.name = AUX_DRIVER_NAME,
432	},
433	.probe = pci1xxxx_otp_eeprom_probe,
434	.remove = pci1xxxx_otp_eeprom_remove,
435	.id_table = pci1xxxx_otp_eeprom_auxiliary_id_table
436};
437module_auxiliary_driver(pci1xxxx_otp_eeprom_driver);
438
439MODULE_LICENSE("GPL");
440MODULE_AUTHOR("Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>");
441MODULE_AUTHOR("Tharun Kumar P <tharunkumar.pasumarthi@microchip.com>");
442MODULE_AUTHOR("Vaibhaav Ram T.L <vaibhaavram.tl@microchip.com>");
443MODULE_DESCRIPTION("Microchip Technology Inc. PCI1xxxx OTP EEPROM Programmer");
444