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 error: 157 release_sys_lock(priv); 158 return ret; 159 } 160 161 static int pci1xxxx_eeprom_write(void *priv_t, unsigned int off, 162 void *value_t, size_t count) 163 { 164 struct pci1xxxx_otp_eeprom_device *priv = priv_t; 165 void __iomem *rb = priv->reg_base; 166 char *value = value_t; 167 u32 regval; 168 u32 byte; 169 int ret; 170 171 if (off >= priv->nvmem_config_eeprom.size) 172 return -EFAULT; 173 174 if ((off + count) > priv->nvmem_config_eeprom.size) 175 count = priv->nvmem_config_eeprom.size - off; 176 177 ret = set_sys_lock(priv); 178 if (ret) 179 return ret; 180 181 for (byte = 0; byte < count; byte++) { 182 writel(*(value + byte), rb + MMAP_EEPROM_OFFSET(EEPROM_DATA_REG)); 183 regval = EEPROM_CMD_EPC_TIMEOUT_BIT | EEPROM_CMD_EPC_WRITE | 184 (off + byte); 185 writel(regval, rb + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG)); 186 writel(EEPROM_CMD_EPC_BUSY_BIT | regval, 187 rb + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG)); 188 189 ret = read_poll_timeout(readl, regval, 190 !(regval & EEPROM_CMD_EPC_BUSY_BIT), 191 STATUS_READ_DELAY_US, 192 STATUS_READ_TIMEOUT_US, true, 193 rb + MMAP_EEPROM_OFFSET(EEPROM_CMD_REG)); 194 if (ret < 0 || (!ret && (regval & EEPROM_CMD_EPC_TIMEOUT_BIT))) { 195 ret = -EIO; 196 goto error; 197 } 198 } 199 error: 200 release_sys_lock(priv); 201 return ret; 202 } 203 204 static void otp_device_set_address(struct pci1xxxx_otp_eeprom_device *priv, 205 u16 address) 206 { 207 u16 lo, hi; 208 209 lo = address & BYTE_LOW; 210 hi = (address & BYTE_HIGH) >> 8; 211 writew(lo, priv->reg_base + MMAP_OTP_OFFSET(OTP_ADDR_LOW_OFFSET)); 212 writew(hi, priv->reg_base + MMAP_OTP_OFFSET(OTP_ADDR_HIGH_OFFSET)); 213 } 214 215 static int pci1xxxx_otp_read(void *priv_t, unsigned int off, 216 void *buf_t, size_t count) 217 { 218 struct pci1xxxx_otp_eeprom_device *priv = priv_t; 219 void __iomem *rb = priv->reg_base; 220 char *buf = buf_t; 221 u32 regval; 222 u32 byte; 223 int ret; 224 u8 data; 225 226 if (off >= priv->nvmem_config_otp.size) 227 return -EFAULT; 228 229 if ((off + count) > priv->nvmem_config_otp.size) 230 count = priv->nvmem_config_otp.size - off; 231 232 ret = set_sys_lock(priv); 233 if (ret) 234 return ret; 235 236 for (byte = 0; byte < count; byte++) { 237 otp_device_set_address(priv, (u16)(off + byte)); 238 data = readl(rb + MMAP_OTP_OFFSET(OTP_FUNC_CMD_OFFSET)); 239 writel(data | OTP_FUNC_RD_BIT, 240 rb + MMAP_OTP_OFFSET(OTP_FUNC_CMD_OFFSET)); 241 data = readl(rb + MMAP_OTP_OFFSET(OTP_CMD_GO_OFFSET)); 242 writel(data | OTP_CMD_GO_BIT, 243 rb + MMAP_OTP_OFFSET(OTP_CMD_GO_OFFSET)); 244 245 ret = read_poll_timeout(readl, regval, 246 !(regval & OTP_STATUS_BUSY_BIT), 247 STATUS_READ_DELAY_US, 248 STATUS_READ_TIMEOUT_US, true, 249 rb + MMAP_OTP_OFFSET(OTP_STATUS_OFFSET)); 250 251 data = readl(rb + MMAP_OTP_OFFSET(OTP_PASS_FAIL_OFFSET)); 252 if (ret < 0 || data & OTP_FAIL_BIT) { 253 ret = -EIO; 254 goto error; 255 } 256 257 buf[byte] = readl(rb + MMAP_OTP_OFFSET(OTP_RD_DATA_OFFSET)); 258 } 259 error: 260 release_sys_lock(priv); 261 return ret; 262 } 263 264 static int pci1xxxx_otp_write(void *priv_t, unsigned int off, 265 void *value_t, size_t count) 266 { 267 struct pci1xxxx_otp_eeprom_device *priv = priv_t; 268 void __iomem *rb = priv->reg_base; 269 char *value = value_t; 270 u32 regval; 271 u32 byte; 272 int ret; 273 u8 data; 274 275 if (off >= priv->nvmem_config_otp.size) 276 return -EFAULT; 277 278 if ((off + count) > priv->nvmem_config_otp.size) 279 count = priv->nvmem_config_otp.size - off; 280 281 ret = set_sys_lock(priv); 282 if (ret) 283 return ret; 284 285 for (byte = 0; byte < count; byte++) { 286 otp_device_set_address(priv, (u16)(off + byte)); 287 288 /* 289 * Set OTP_PGM_MODE_BYTE command bit in OTP_PRGM_MODE register 290 * to enable Byte programming 291 */ 292 data = readl(rb + MMAP_OTP_OFFSET(OTP_PRGM_MODE_OFFSET)); 293 writel(data | OTP_PGM_MODE_BYTE_BIT, 294 rb + MMAP_OTP_OFFSET(OTP_PRGM_MODE_OFFSET)); 295 writel(*(value + byte), rb + MMAP_OTP_OFFSET(OTP_PRGM_DATA_OFFSET)); 296 data = readl(rb + MMAP_OTP_OFFSET(OTP_FUNC_CMD_OFFSET)); 297 writel(data | OTP_FUNC_PGM_BIT, 298 rb + MMAP_OTP_OFFSET(OTP_FUNC_CMD_OFFSET)); 299 data = readl(rb + MMAP_OTP_OFFSET(OTP_CMD_GO_OFFSET)); 300 writel(data | OTP_CMD_GO_BIT, 301 rb + MMAP_OTP_OFFSET(OTP_CMD_GO_OFFSET)); 302 303 ret = read_poll_timeout(readl, regval, 304 !(regval & OTP_STATUS_BUSY_BIT), 305 STATUS_READ_DELAY_US, 306 STATUS_READ_TIMEOUT_US, true, 307 rb + MMAP_OTP_OFFSET(OTP_STATUS_OFFSET)); 308 309 data = readl(rb + MMAP_OTP_OFFSET(OTP_PASS_FAIL_OFFSET)); 310 if (ret < 0 || data & OTP_FAIL_BIT) { 311 ret = -EIO; 312 goto error; 313 } 314 } 315 error: 316 release_sys_lock(priv); 317 return ret; 318 } 319 320 static int pci1xxxx_otp_eeprom_probe(struct auxiliary_device *aux_dev, 321 const struct auxiliary_device_id *id) 322 { 323 struct auxiliary_device_wrapper *aux_dev_wrapper; 324 struct pci1xxxx_otp_eeprom_device *priv; 325 struct gp_aux_data_type *pdata; 326 int ret; 327 u8 data; 328 329 aux_dev_wrapper = container_of(aux_dev, struct auxiliary_device_wrapper, 330 aux_dev); 331 pdata = &aux_dev_wrapper->gp_aux_data; 332 if (!pdata) 333 return -EINVAL; 334 335 priv = devm_kzalloc(&aux_dev->dev, sizeof(*priv), GFP_KERNEL); 336 if (!priv) 337 return -ENOMEM; 338 339 priv->pdev = aux_dev; 340 341 if (!devm_request_mem_region(&aux_dev->dev, pdata->region_start + 342 PERI_PF3_SYSTEM_REG_ADDR_BASE, 343 PERI_PF3_SYSTEM_REG_LENGTH, 344 aux_dev->name)) 345 return -ENOMEM; 346 347 priv->reg_base = devm_ioremap(&aux_dev->dev, pdata->region_start + 348 PERI_PF3_SYSTEM_REG_ADDR_BASE, 349 PERI_PF3_SYSTEM_REG_LENGTH); 350 if (!priv->reg_base) 351 return -ENOMEM; 352 353 ret = set_sys_lock(priv); 354 if (ret) 355 return ret; 356 357 /* Set OTP_PWR_DN to 0 to make OTP Operational */ 358 data = readl(priv->reg_base + MMAP_OTP_OFFSET(OTP_PWR_DN_OFFSET)); 359 writel(data & ~OTP_PWR_DN_BIT, 360 priv->reg_base + MMAP_OTP_OFFSET(OTP_PWR_DN_OFFSET)); 361 362 dev_set_drvdata(&aux_dev->dev, priv); 363 364 if (is_eeprom_responsive(priv)) { 365 priv->nvmem_config_eeprom.type = NVMEM_TYPE_EEPROM; 366 priv->nvmem_config_eeprom.name = EEPROM_NAME; 367 priv->nvmem_config_eeprom.id = NVMEM_DEVID_AUTO; 368 priv->nvmem_config_eeprom.dev = &aux_dev->dev; 369 priv->nvmem_config_eeprom.owner = THIS_MODULE; 370 priv->nvmem_config_eeprom.reg_read = pci1xxxx_eeprom_read; 371 priv->nvmem_config_eeprom.reg_write = pci1xxxx_eeprom_write; 372 priv->nvmem_config_eeprom.priv = priv; 373 priv->nvmem_config_eeprom.stride = 1; 374 priv->nvmem_config_eeprom.word_size = 1; 375 priv->nvmem_config_eeprom.size = EEPROM_SIZE_BYTES; 376 377 priv->nvmem_eeprom = devm_nvmem_register(&aux_dev->dev, 378 &priv->nvmem_config_eeprom); 379 if (IS_ERR(priv->nvmem_eeprom)) 380 return PTR_ERR(priv->nvmem_eeprom); 381 } 382 383 release_sys_lock(priv); 384 385 priv->nvmem_config_otp.type = NVMEM_TYPE_OTP; 386 priv->nvmem_config_otp.name = OTP_NAME; 387 priv->nvmem_config_otp.id = NVMEM_DEVID_AUTO; 388 priv->nvmem_config_otp.dev = &aux_dev->dev; 389 priv->nvmem_config_otp.owner = THIS_MODULE; 390 priv->nvmem_config_otp.reg_read = pci1xxxx_otp_read; 391 priv->nvmem_config_otp.reg_write = pci1xxxx_otp_write; 392 priv->nvmem_config_otp.priv = priv; 393 priv->nvmem_config_otp.stride = 1; 394 priv->nvmem_config_otp.word_size = 1; 395 priv->nvmem_config_otp.size = OTP_SIZE_BYTES; 396 397 priv->nvmem_otp = devm_nvmem_register(&aux_dev->dev, 398 &priv->nvmem_config_otp); 399 if (IS_ERR(priv->nvmem_otp)) 400 return PTR_ERR(priv->nvmem_otp); 401 402 return ret; 403 } 404 405 static void pci1xxxx_otp_eeprom_remove(struct auxiliary_device *aux_dev) 406 { 407 struct pci1xxxx_otp_eeprom_device *priv; 408 void __iomem *sys_lock; 409 410 priv = dev_get_drvdata(&aux_dev->dev); 411 sys_lock = priv->reg_base + MMAP_CFG_OFFSET(CFG_SYS_LOCK_OFFSET); 412 writel(CFG_SYS_LOCK_PF3, sys_lock); 413 414 /* Shut down OTP */ 415 writel(OTP_PWR_DN_BIT, 416 priv->reg_base + MMAP_OTP_OFFSET(OTP_PWR_DN_OFFSET)); 417 418 writel(0, sys_lock); 419 } 420 421 static const struct auxiliary_device_id pci1xxxx_otp_eeprom_auxiliary_id_table[] = { 422 {.name = "mchp_pci1xxxx_gp.gp_otp_e2p"}, 423 {}, 424 }; 425 MODULE_DEVICE_TABLE(auxiliary, pci1xxxx_otp_eeprom_auxiliary_id_table); 426 427 static struct auxiliary_driver pci1xxxx_otp_eeprom_driver = { 428 .driver = { 429 .name = AUX_DRIVER_NAME, 430 }, 431 .probe = pci1xxxx_otp_eeprom_probe, 432 .remove = pci1xxxx_otp_eeprom_remove, 433 .id_table = pci1xxxx_otp_eeprom_auxiliary_id_table 434 }; 435 module_auxiliary_driver(pci1xxxx_otp_eeprom_driver); 436 437 MODULE_LICENSE("GPL"); 438 MODULE_AUTHOR("Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>"); 439 MODULE_AUTHOR("Tharun Kumar P <tharunkumar.pasumarthi@microchip.com>"); 440 MODULE_AUTHOR("Vaibhaav Ram T.L <vaibhaavram.tl@microchip.com>"); 441 MODULE_DESCRIPTION("Microchip Technology Inc. PCI1xxxx OTP EEPROM Programmer"); 442