1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <asm/arch/cpu.h> 8 #include <asm/io.h> 9 #include <command.h> 10 #include <dm.h> 11 #include <linux/bitops.h> 12 #include <linux/delay.h> 13 #include <linux/iopoll.h> 14 #include <misc.h> 15 #include <rockchip-otp.h> 16 17 struct otp_data { 18 int size; 19 int ns_offset; 20 int (*init)(struct udevice *dev); 21 int (*read)(struct udevice *dev, int offset, void *buf, int size); 22 }; 23 24 static int rockchip_otp_wait_status(struct rockchip_otp_platdata *otp, 25 u32 flag) 26 { 27 int delay = OTPC_TIMEOUT; 28 29 while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) { 30 udelay(1); 31 delay--; 32 if (delay <= 0) { 33 printf("%s: wait init status timeout\n", __func__); 34 return -ETIMEDOUT; 35 } 36 } 37 38 /* clean int status */ 39 writel(flag, otp->base + OTPC_INT_STATUS); 40 41 return 0; 42 } 43 44 static int rockchip_otp_ecc_enable(struct rockchip_otp_platdata *otp, 45 bool enable) 46 { 47 int ret = 0; 48 49 writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT), 50 otp->base + OTPC_SBPI_CTRL); 51 52 writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE); 53 writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC, 54 otp->base + OTPC_SBPI_CMD0_OFFSET); 55 if (enable) 56 writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET); 57 else 58 writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET); 59 60 writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL); 61 62 ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE); 63 if (ret < 0) 64 printf("%s timeout during ecc_enable\n", __func__); 65 66 return ret; 67 } 68 69 static int rockchip_px30_otp_read(struct udevice *dev, int offset, 70 void *buf, int size) 71 { 72 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 73 u8 *buffer = buf; 74 int ret = 0; 75 76 ret = rockchip_otp_ecc_enable(otp, false); 77 if (ret < 0) { 78 printf("%s rockchip_otp_ecc_enable err\n", __func__); 79 return ret; 80 } 81 82 writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); 83 udelay(5); 84 while (size--) { 85 writel(offset++ | OTPC_USER_ADDR_MASK, 86 otp->base + OTPC_USER_ADDR); 87 writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, 88 otp->base + OTPC_USER_ENABLE); 89 ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); 90 if (ret < 0) { 91 printf("%s timeout during read setup\n", __func__); 92 goto read_end; 93 } 94 *buffer++ = readb(otp->base + OTPC_USER_Q); 95 } 96 97 read_end: 98 writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); 99 100 return ret; 101 } 102 103 static int rk3308bs_otp_wait_status(struct rockchip_otp_platdata *otp, u32 flag) 104 { 105 int delay = OTPC_TIMEOUT; 106 107 while (!(readl(otp->base + OTPC_IRQ_ST) & flag)) { 108 udelay(1); 109 delay--; 110 if (delay <= 0) { 111 printf("%s: wait init status timeout\n", __func__); 112 return -ETIMEDOUT; 113 } 114 } 115 116 /* clean int status */ 117 writel(flag, otp->base + OTPC_IRQ_ST); 118 119 return 0; 120 } 121 122 static int rk3308bs_otp_active(struct rockchip_otp_platdata *otp) 123 { 124 int ret = 0; 125 u32 mode; 126 127 mode = readl(otp->base + OTPC_MODE_CTRL); 128 129 switch (mode) { 130 case OTPC_DEEP_STANDBY: 131 writel(OTPC_STANDBY, otp->base + OTPC_MODE_CTRL); 132 ret = rk3308bs_otp_wait_status(otp, OTPC_DP2STB_IRQ_ST); 133 if (ret < 0) { 134 dev_err(otp->dev, "timeout during wait dp2stb\n"); 135 return ret; 136 } 137 case OTPC_STANDBY: 138 writel(OTPC_ACTIVE, otp->base + OTPC_MODE_CTRL); 139 ret = rk3308bs_otp_wait_status(otp, OTPC_STB2ACT_IRQ_ST); 140 if (ret < 0) { 141 dev_err(otp->dev, "timeout during wait stb2act\n"); 142 return ret; 143 } 144 break; 145 default: 146 break; 147 } 148 149 return ret; 150 } 151 152 static int rk3308bs_otp_standby(struct rockchip_otp_platdata *otp) 153 { 154 int ret = 0; 155 u32 mode; 156 157 mode = readl(otp->base + OTPC_MODE_CTRL); 158 159 switch (mode) { 160 case OTPC_ACTIVE: 161 writel(OTPC_STANDBY, otp->base + OTPC_MODE_CTRL); 162 ret = rk3308bs_otp_wait_status(otp, OTPC_ACT2STB_IRQ_ST); 163 if (ret < 0) { 164 dev_err(otp->dev, "timeout during wait act2stb\n"); 165 return ret; 166 } 167 case OTPC_STANDBY: 168 writel(OTPC_DEEP_STANDBY, otp->base + OTPC_MODE_CTRL); 169 ret = rk3308bs_otp_wait_status(otp, OTPC_STB2DP_IRQ_ST); 170 if (ret < 0) { 171 dev_err(otp->dev, "timeout during wait stb2dp\n"); 172 return ret; 173 } 174 break; 175 default: 176 break; 177 } 178 179 return ret; 180 } 181 182 static int rockchip_rk3308bs_otp_read(struct udevice *dev, int offset, 183 void *buf, int size) 184 { 185 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 186 unsigned int addr_start, addr_end, addr_offset, addr_len; 187 u32 out_value; 188 u8 *buffer; 189 int ret = 0, i = 0; 190 191 if (offset > RK3308BS_MAX_BYTES - 1) 192 return -ENOMEM; 193 if (offset + size > RK3308BS_MAX_BYTES) 194 size = RK3308BS_MAX_BYTES - offset; 195 196 ret = rk3308bs_otp_active(otp); 197 if (ret) 198 goto out; 199 200 addr_start = rounddown(offset, RK3308BS_NBYTES) / RK3308BS_NBYTES; 201 addr_end = roundup(offset + size, RK3308BS_NBYTES) / RK3308BS_NBYTES; 202 addr_offset = offset % RK3308BS_NBYTES; 203 addr_len = addr_end - addr_start; 204 205 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3308BS_NBYTES); 206 if (!buffer) { 207 ret = -ENOMEM; 208 goto read_end; 209 } 210 211 while (addr_len--) { 212 writel(OTPC_TRANS_NUM, otp->base + OTPC_REPR_RD_TRANS_NUM); 213 writel(addr_start++, otp->base + OTPC_ACCESS_ADDR); 214 writel(OTPC_READ_ACCESS, otp->base + OTPC_MODE_CTRL); 215 ret = rk3308bs_otp_wait_status(otp, OTPC_RDM_IRQ_ST); 216 if (ret < 0) { 217 printf("timeout during wait rd\n"); 218 goto read_end; 219 } 220 out_value = readl(otp->base + OTPC_RD_DATA); 221 memcpy(&buffer[i], &out_value, RK3308BS_NBYTES); 222 i += RK3308BS_NBYTES; 223 } 224 memcpy(buf, buffer + addr_offset, size); 225 226 read_end: 227 kfree(buffer); 228 rk3308bs_otp_standby(otp); 229 out: 230 return ret; 231 } 232 233 static int rockchip_rk3568_otp_read(struct udevice *dev, int offset, void *buf, 234 int size) 235 { 236 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 237 unsigned int addr_start, addr_end, addr_offset, addr_len; 238 u32 out_value; 239 u8 *buffer; 240 int ret = 0, i = 0; 241 242 addr_start = rounddown(offset, RK3568_NBYTES) / RK3568_NBYTES; 243 addr_end = roundup(offset + size, RK3568_NBYTES) / RK3568_NBYTES; 244 addr_offset = offset % RK3568_NBYTES; 245 addr_len = addr_end - addr_start; 246 247 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3568_NBYTES); 248 if (!buffer) 249 return -ENOMEM; 250 251 ret = rockchip_otp_ecc_enable(otp, true); 252 if (ret < 0) { 253 printf("%s rockchip_otp_ecc_enable err\n", __func__); 254 return ret; 255 } 256 257 writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); 258 udelay(5); 259 while (addr_len--) { 260 writel(addr_start++ | OTPC_USER_ADDR_MASK, 261 otp->base + OTPC_USER_ADDR); 262 writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, 263 otp->base + OTPC_USER_ENABLE); 264 ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); 265 if (ret < 0) { 266 printf("%s timeout during read setup\n", __func__); 267 goto read_end; 268 } 269 out_value = readl(otp->base + OTPC_USER_Q); 270 memcpy(&buffer[i], &out_value, RK3568_NBYTES); 271 i += RK3568_NBYTES; 272 } 273 274 memcpy(buf, buffer + addr_offset, size); 275 276 read_end: 277 writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); 278 279 kfree(buffer); 280 281 return ret; 282 } 283 284 static int rockchip_rk3588_otp_read(struct udevice *dev, int offset, void *buf, 285 int size) 286 { 287 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 288 struct otp_data *data; 289 unsigned int addr_start, addr_end, addr_offset, addr_len; 290 int ret = 0, i = 0; 291 u32 out_value, st = 0; 292 u8 *buffer; 293 294 data = (struct otp_data *)dev_get_driver_data(dev); 295 if (!data) 296 return -ENOSYS; 297 298 if (offset > data->size - 1) 299 return -ENOMEM; 300 if (offset + size > data->size) 301 size = data->size - offset; 302 303 addr_start = rounddown(offset, RK3588_NBYTES) / RK3588_NBYTES; 304 addr_end = roundup(offset + size, RK3588_NBYTES) / RK3588_NBYTES; 305 addr_offset = offset % RK3588_NBYTES; 306 addr_len = addr_end - addr_start; 307 addr_start += data->ns_offset; 308 309 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3588_NBYTES); 310 if (!buffer) 311 return -ENOMEM; 312 313 while (addr_len--) { 314 writel((addr_start << RK3588_ADDR_SHIFT) | 315 (RK3588_BURST_NUM << RK3588_BURST_SHIFT), 316 otp->base + RK3588_OTPC_AUTO_CTRL); 317 writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN); 318 ret = readl_poll_timeout(otp->base + RK3588_OTPC_INT_ST, st, 319 st & RK3588_RD_DONE, OTPC_TIMEOUT); 320 if (ret < 0) { 321 printf("%s timeout during read setup\n", __func__); 322 goto read_end; 323 } 324 writel(RK3588_RD_DONE, otp->base + RK3588_OTPC_INT_ST); 325 326 out_value = readl(otp->base + RK3588_OTPC_DOUT0); 327 memcpy(&buffer[i], &out_value, RK3588_NBYTES); 328 i += RK3588_NBYTES; 329 addr_start++; 330 } 331 332 memcpy(buf, buffer + addr_offset, size); 333 334 read_end: 335 kfree(buffer); 336 337 return ret; 338 } 339 340 static int rockchip_rv1126_otp_init(struct udevice *dev) 341 { 342 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 343 u32 status = 0; 344 int ret; 345 346 writel(0x0, otp->base + RV1126_OTP_NVM_CEB); 347 ret = readl_poll_timeout(otp->base + RV1126_OTP_NVM_ST, status, 348 status & 0x1, OTPC_TIMEOUT); 349 if (ret < 0) { 350 printf("%s timeout during set ceb\n", __func__); 351 return ret; 352 } 353 354 writel(0x1, otp->base + RV1126_OTP_NVM_RSTB); 355 ret = readl_poll_timeout(otp->base + RV1126_OTP_NVM_ST, status, 356 status & 0x4, OTPC_TIMEOUT); 357 if (ret < 0) { 358 printf("%s timeout during set rstb\n", __func__); 359 return ret; 360 } 361 362 return 0; 363 } 364 365 static int rockchip_rv1126_otp_read(struct udevice *dev, int offset, void *buf, 366 int size) 367 { 368 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 369 u32 status = 0; 370 u8 *buffer = buf; 371 int ret = 0; 372 373 while (size--) { 374 writel(offset++, otp->base + RV1126_OTP_NVM_RADDR); 375 writel(0x1, otp->base + RV1126_OTP_NVM_RSTART); 376 ret = readl_poll_timeout(otp->base + RV1126_OTP_READ_ST, 377 status, status == 0, OTPC_TIMEOUT); 378 if (ret < 0) { 379 printf("%s timeout during read setup\n", __func__); 380 return ret; 381 } 382 383 *buffer++ = readb(otp->base + RV1126_OTP_NVM_RDATA); 384 } 385 386 return 0; 387 } 388 389 static int rockchip_otp_read(struct udevice *dev, int offset, 390 void *buf, int size) 391 { 392 struct otp_data *data; 393 394 data = (struct otp_data *)dev_get_driver_data(dev); 395 if (!data) 396 return -ENOSYS; 397 398 if (soc_is_rk3308bs() || soc_is_px30s()) 399 return rockchip_rk3308bs_otp_read(dev, offset, buf, size); 400 401 return data->read(dev, offset, buf, size); 402 } 403 404 static const struct misc_ops rockchip_otp_ops = { 405 .read = rockchip_otp_read, 406 }; 407 408 static int rockchip_otp_ofdata_to_platdata(struct udevice *dev) 409 { 410 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 411 412 otp->base = dev_read_addr_ptr(dev); 413 414 return 0; 415 } 416 417 static int rockchip_otp_probe(struct udevice *dev) 418 { 419 struct otp_data *data; 420 421 data = (struct otp_data *)dev_get_driver_data(dev); 422 if (!data) 423 return -EINVAL; 424 425 if (data->init) 426 return data->init(dev); 427 428 return 0; 429 } 430 431 static const struct otp_data px30_data = { 432 .read = rockchip_px30_otp_read, 433 }; 434 435 static const struct otp_data rk3308bs_data = { 436 .read = rockchip_rk3308bs_otp_read, 437 }; 438 439 static const struct otp_data rk3568_data = { 440 .read = rockchip_rk3568_otp_read, 441 }; 442 443 static const struct otp_data rk3576_data = { 444 .size = 0x100, 445 .ns_offset = RK3576_NO_SECURE_OFFSET, 446 .read = rockchip_rk3588_otp_read, 447 }; 448 449 static const struct otp_data rk3588_data = { 450 .size = 0x400, 451 .ns_offset = RK3588_NO_SECURE_OFFSET, 452 .read = rockchip_rk3588_otp_read, 453 }; 454 455 static const struct otp_data rv1126_data = { 456 .init = rockchip_rv1126_otp_init, 457 .read = rockchip_rv1126_otp_read, 458 }; 459 460 static const struct udevice_id rockchip_otp_ids[] = { 461 { 462 .compatible = "rockchip,px30-otp", 463 .data = (ulong)&px30_data, 464 }, 465 { 466 .compatible = "rockchip,px30s-otp", 467 .data = (ulong)&rk3308bs_data, 468 }, 469 { 470 .compatible = "rockchip,rk3308-otp", 471 .data = (ulong)&px30_data, 472 }, 473 { 474 .compatible = "rockchip,rk3308bs-otp", 475 .data = (ulong)&rk3308bs_data, 476 }, 477 { 478 .compatible = "rockchip,rk3528-otp", 479 .data = (ulong)&rk3568_data, 480 }, 481 { 482 .compatible = "rockchip,rk3562-otp", 483 .data = (ulong)&rk3568_data, 484 }, 485 { 486 .compatible = "rockchip,rk3568-otp", 487 .data = (ulong)&rk3568_data, 488 }, 489 { 490 .compatible = "rockchip,rk3576-otp", 491 .data = (ulong)&rk3576_data, 492 }, 493 { 494 .compatible = "rockchip,rk3588-otp", 495 .data = (ulong)&rk3588_data, 496 }, 497 { 498 .compatible = "rockchip,rv1106-otp", 499 .data = (ulong)&rk3568_data, 500 }, 501 { 502 .compatible = "rockchip,rv1126-otp", 503 .data = (ulong)&rv1126_data, 504 }, 505 {} 506 }; 507 508 U_BOOT_DRIVER(rockchip_otp) = { 509 .name = "rockchip_otp", 510 .id = UCLASS_MISC, 511 .of_match = rockchip_otp_ids, 512 .ops = &rockchip_otp_ops, 513 .ofdata_to_platdata = rockchip_otp_ofdata_to_platdata, 514 .platdata_auto_alloc_size = sizeof(struct rockchip_otp_platdata), 515 .probe = rockchip_otp_probe, 516 }; 517