arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / drivers / misc / mchp_pci1xxxx / mchp_pci1xxxx_otpe2p.c
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
67 struct 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
76 static 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
90 static 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
97 static 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
120 static 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;
157 error:
158         release_sys_lock(priv);
159         return ret;
160 }
161
162 static 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;
201 error:
202         release_sys_lock(priv);
203         return ret;
204 }
205
206 static 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
217 static 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;
262 error:
263         release_sys_lock(priv);
264         return ret;
265 }
266
267 static 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;
319 error:
320         release_sys_lock(priv);
321         return ret;
322 }
323
324 static 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
407 static 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
423 static const struct auxiliary_device_id pci1xxxx_otp_eeprom_auxiliary_id_table[] = {
424         {.name = "mchp_pci1xxxx_gp.gp_otp_e2p"},
425         {},
426 };
427 MODULE_DEVICE_TABLE(auxiliary, pci1xxxx_otp_eeprom_auxiliary_id_table);
428
429 static 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 };
437 module_auxiliary_driver(pci1xxxx_otp_eeprom_driver);
438
439 MODULE_LICENSE("GPL");
440 MODULE_AUTHOR("Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>");
441 MODULE_AUTHOR("Tharun Kumar P <tharunkumar.pasumarthi@microchip.com>");
442 MODULE_AUTHOR("Vaibhaav Ram T.L <vaibhaavram.tl@microchip.com>");
443 MODULE_DESCRIPTION("Microchip Technology Inc. PCI1xxxx OTP EEPROM Programmer");