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 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 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 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 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 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 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 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 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