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 (*init)(struct udevice *dev); 19 int (*read)(struct udevice *dev, int offset, void *buf, int size); 20 }; 21 22 static int rockchip_otp_wait_status(struct rockchip_otp_platdata *otp, 23 u32 flag) 24 { 25 int delay = OTPC_TIMEOUT; 26 27 while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) { 28 udelay(1); 29 delay--; 30 if (delay <= 0) { 31 printf("%s: wait init status timeout\n", __func__); 32 return -ETIMEDOUT; 33 } 34 } 35 36 /* clean int status */ 37 writel(flag, otp->base + OTPC_INT_STATUS); 38 39 return 0; 40 } 41 42 static int rockchip_otp_ecc_enable(struct rockchip_otp_platdata *otp, 43 bool enable) 44 { 45 int ret = 0; 46 47 writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT), 48 otp->base + OTPC_SBPI_CTRL); 49 50 writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE); 51 writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC, 52 otp->base + OTPC_SBPI_CMD0_OFFSET); 53 if (enable) 54 writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET); 55 else 56 writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET); 57 58 writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL); 59 60 ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE); 61 if (ret < 0) 62 printf("%s timeout during ecc_enable\n", __func__); 63 64 return ret; 65 } 66 67 static int rockchip_px30_otp_read(struct udevice *dev, int offset, 68 void *buf, int size) 69 { 70 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 71 u8 *buffer = buf; 72 int ret = 0; 73 74 ret = rockchip_otp_ecc_enable(otp, false); 75 if (ret < 0) { 76 printf("%s rockchip_otp_ecc_enable err\n", __func__); 77 return ret; 78 } 79 80 writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); 81 udelay(5); 82 while (size--) { 83 writel(offset++ | OTPC_USER_ADDR_MASK, 84 otp->base + OTPC_USER_ADDR); 85 writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, 86 otp->base + OTPC_USER_ENABLE); 87 ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); 88 if (ret < 0) { 89 printf("%s timeout during read setup\n", __func__); 90 goto read_end; 91 } 92 *buffer++ = readb(otp->base + OTPC_USER_Q); 93 } 94 95 read_end: 96 writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); 97 98 return ret; 99 } 100 101 static int rk3308bs_otp_wait_status(struct rockchip_otp_platdata *otp, u32 flag) 102 { 103 int delay = OTPC_TIMEOUT; 104 105 while (!(readl(otp->base + OTPC_IRQ_ST) & flag)) { 106 udelay(1); 107 delay--; 108 if (delay <= 0) { 109 printf("%s: wait init status timeout\n", __func__); 110 return -ETIMEDOUT; 111 } 112 } 113 114 /* clean int status */ 115 writel(flag, otp->base + OTPC_IRQ_ST); 116 117 return 0; 118 } 119 120 static int rk3308bs_otp_active(struct rockchip_otp_platdata *otp) 121 { 122 int ret = 0; 123 u32 mode; 124 125 mode = readl(otp->base + OTPC_MODE_CTRL); 126 127 switch (mode) { 128 case OTPC_DEEP_STANDBY: 129 writel(OTPC_STANDBY, otp->base + OTPC_MODE_CTRL); 130 ret = rk3308bs_otp_wait_status(otp, OTPC_DP2STB_IRQ_ST); 131 if (ret < 0) { 132 dev_err(otp->dev, "timeout during wait dp2stb\n"); 133 return ret; 134 } 135 case OTPC_STANDBY: 136 writel(OTPC_ACTIVE, otp->base + OTPC_MODE_CTRL); 137 ret = rk3308bs_otp_wait_status(otp, OTPC_STB2ACT_IRQ_ST); 138 if (ret < 0) { 139 dev_err(otp->dev, "timeout during wait stb2act\n"); 140 return ret; 141 } 142 break; 143 default: 144 break; 145 } 146 147 return ret; 148 } 149 150 static int rk3308bs_otp_standby(struct rockchip_otp_platdata *otp) 151 { 152 int ret = 0; 153 u32 mode; 154 155 mode = readl(otp->base + OTPC_MODE_CTRL); 156 157 switch (mode) { 158 case OTPC_ACTIVE: 159 writel(OTPC_STANDBY, otp->base + OTPC_MODE_CTRL); 160 ret = rk3308bs_otp_wait_status(otp, OTPC_ACT2STB_IRQ_ST); 161 if (ret < 0) { 162 dev_err(otp->dev, "timeout during wait act2stb\n"); 163 return ret; 164 } 165 case OTPC_STANDBY: 166 writel(OTPC_DEEP_STANDBY, otp->base + OTPC_MODE_CTRL); 167 ret = rk3308bs_otp_wait_status(otp, OTPC_STB2DP_IRQ_ST); 168 if (ret < 0) { 169 dev_err(otp->dev, "timeout during wait stb2dp\n"); 170 return ret; 171 } 172 break; 173 default: 174 break; 175 } 176 177 return ret; 178 } 179 180 static int rockchip_rk3308bs_otp_read(struct udevice *dev, int offset, 181 void *buf, int size) 182 { 183 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 184 unsigned int addr_start, addr_end, addr_offset, addr_len; 185 u32 out_value; 186 u8 *buffer; 187 int ret = 0, i = 0; 188 189 if (offset > RK3308BS_MAX_BYTES - 1) 190 return -ENOMEM; 191 if (offset + size > RK3308BS_MAX_BYTES) 192 size = RK3308BS_MAX_BYTES - offset; 193 194 ret = rk3308bs_otp_active(otp); 195 if (ret) 196 goto out; 197 198 addr_start = rounddown(offset, RK3308BS_NBYTES) / RK3308BS_NBYTES; 199 addr_end = roundup(offset + size, RK3308BS_NBYTES) / RK3308BS_NBYTES; 200 addr_offset = offset % RK3308BS_NBYTES; 201 addr_len = addr_end - addr_start; 202 203 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3308BS_NBYTES); 204 if (!buffer) { 205 ret = -ENOMEM; 206 goto read_end; 207 } 208 209 while (addr_len--) { 210 writel(OTPC_TRANS_NUM, otp->base + OTPC_REPR_RD_TRANS_NUM); 211 writel(addr_start++, otp->base + OTPC_ACCESS_ADDR); 212 writel(OTPC_READ_ACCESS, otp->base + OTPC_MODE_CTRL); 213 ret = rk3308bs_otp_wait_status(otp, OTPC_RDM_IRQ_ST); 214 if (ret < 0) { 215 printf("timeout during wait rd\n"); 216 goto read_end; 217 } 218 out_value = readl(otp->base + OTPC_RD_DATA); 219 memcpy(&buffer[i], &out_value, RK3308BS_NBYTES); 220 i += RK3308BS_NBYTES; 221 } 222 memcpy(buf, buffer + addr_offset, size); 223 224 read_end: 225 kfree(buffer); 226 rk3308bs_otp_standby(otp); 227 out: 228 return ret; 229 } 230 231 static int rockchip_rk3568_otp_read(struct udevice *dev, int offset, void *buf, 232 int size) 233 { 234 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 235 unsigned int addr_start, addr_end, addr_offset, addr_len; 236 u32 out_value; 237 u8 *buffer; 238 int ret = 0, i = 0; 239 240 addr_start = rounddown(offset, RK3568_NBYTES) / RK3568_NBYTES; 241 addr_end = roundup(offset + size, RK3568_NBYTES) / RK3568_NBYTES; 242 addr_offset = offset % RK3568_NBYTES; 243 addr_len = addr_end - addr_start; 244 245 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3568_NBYTES); 246 if (!buffer) 247 return -ENOMEM; 248 249 ret = rockchip_otp_ecc_enable(otp, false); 250 if (ret < 0) { 251 printf("%s rockchip_otp_ecc_enable err\n", __func__); 252 return ret; 253 } 254 255 writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); 256 udelay(5); 257 while (addr_len--) { 258 writel(addr_start++ | OTPC_USER_ADDR_MASK, 259 otp->base + OTPC_USER_ADDR); 260 writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, 261 otp->base + OTPC_USER_ENABLE); 262 ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); 263 if (ret < 0) { 264 printf("%s timeout during read setup\n", __func__); 265 goto read_end; 266 } 267 out_value = readl(otp->base + OTPC_USER_Q); 268 memcpy(&buffer[i], &out_value, RK3568_NBYTES); 269 i += RK3568_NBYTES; 270 } 271 272 memcpy(buf, buffer + addr_offset, size); 273 274 read_end: 275 writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); 276 277 kfree(buffer); 278 279 return ret; 280 } 281 282 static int rockchip_rv1126_otp_init(struct udevice *dev) 283 { 284 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 285 u32 status = 0; 286 int ret; 287 288 writel(0x0, otp->base + RV1126_OTP_NVM_CEB); 289 ret = readl_poll_timeout(otp->base + RV1126_OTP_NVM_ST, status, 290 status & 0x1, OTPC_TIMEOUT); 291 if (ret < 0) { 292 printf("%s timeout during set ceb\n", __func__); 293 return ret; 294 } 295 296 writel(0x1, otp->base + RV1126_OTP_NVM_RSTB); 297 ret = readl_poll_timeout(otp->base + RV1126_OTP_NVM_ST, status, 298 status & 0x4, OTPC_TIMEOUT); 299 if (ret < 0) { 300 printf("%s timeout during set rstb\n", __func__); 301 return ret; 302 } 303 304 return 0; 305 } 306 307 static int rockchip_rv1126_otp_read(struct udevice *dev, int offset, void *buf, 308 int size) 309 { 310 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 311 u32 status = 0; 312 u8 *buffer = buf; 313 int ret = 0; 314 315 while (size--) { 316 writel(offset++, otp->base + RV1126_OTP_NVM_RADDR); 317 writel(0x1, otp->base + RV1126_OTP_NVM_RSTART); 318 ret = readl_poll_timeout(otp->base + RV1126_OTP_READ_ST, 319 status, status == 0, OTPC_TIMEOUT); 320 if (ret < 0) { 321 printf("%s timeout during read setup\n", __func__); 322 return ret; 323 } 324 325 *buffer++ = readb(otp->base + RV1126_OTP_NVM_RDATA); 326 } 327 328 return 0; 329 } 330 331 static int rockchip_otp_read(struct udevice *dev, int offset, 332 void *buf, int size) 333 { 334 struct otp_data *data; 335 336 data = (struct otp_data *)dev_get_driver_data(dev); 337 if (!data) 338 return -ENOSYS; 339 340 if (soc_is_rk3308bs()) 341 return rockchip_rk3308bs_otp_read(dev, offset, buf, size); 342 343 return data->read(dev, offset, buf, size); 344 } 345 346 static const struct misc_ops rockchip_otp_ops = { 347 .read = rockchip_otp_read, 348 }; 349 350 static int rockchip_otp_ofdata_to_platdata(struct udevice *dev) 351 { 352 struct rockchip_otp_platdata *otp = dev_get_platdata(dev); 353 354 otp->base = dev_read_addr_ptr(dev); 355 356 return 0; 357 } 358 359 static int rockchip_otp_probe(struct udevice *dev) 360 { 361 struct otp_data *data; 362 363 data = (struct otp_data *)dev_get_driver_data(dev); 364 if (!data) 365 return -EINVAL; 366 367 if (data->init) 368 return data->init(dev); 369 370 return 0; 371 } 372 373 static const struct otp_data px30_data = { 374 .read = rockchip_px30_otp_read, 375 }; 376 377 static const struct otp_data rk3308bs_data = { 378 .read = rockchip_rk3308bs_otp_read, 379 }; 380 381 static const struct otp_data rk3568_data = { 382 .read = rockchip_rk3568_otp_read, 383 }; 384 385 static const struct otp_data rv1126_data = { 386 .init = rockchip_rv1126_otp_init, 387 .read = rockchip_rv1126_otp_read, 388 }; 389 390 static const struct udevice_id rockchip_otp_ids[] = { 391 { 392 .compatible = "rockchip,px30-otp", 393 .data = (ulong)&px30_data, 394 }, 395 { 396 .compatible = "rockchip,rk3308-otp", 397 .data = (ulong)&px30_data, 398 }, 399 { 400 .compatible = "rockchip,rk3308bs-otp", 401 .data = (ulong)&rk3308bs_data, 402 }, 403 { 404 .compatible = "rockchip,rk3568-otp", 405 .data = (ulong)&rk3568_data, 406 }, 407 { 408 .compatible = "rockchip,rv1126-otp", 409 .data = (ulong)&rv1126_data, 410 }, 411 {} 412 }; 413 414 U_BOOT_DRIVER(rockchip_otp) = { 415 .name = "rockchip_otp", 416 .id = UCLASS_MISC, 417 .of_match = rockchip_otp_ids, 418 .ops = &rockchip_otp_ops, 419 .ofdata_to_platdata = rockchip_otp_ofdata_to_platdata, 420 .platdata_auto_alloc_size = sizeof(struct rockchip_otp_platdata), 421 .probe = rockchip_otp_probe, 422 }; 423