1 /* 2 * eFuse driver for Rockchip devices 3 * 4 * Copyright 2017, Theobroma Systems Design und Consulting GmbH 5 * Written by Philipp Tomsich <philipp.tomsich@theobroma-systems.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <asm/io.h> 12 #include <command.h> 13 #include <display_options.h> 14 #include <dm.h> 15 #include <linux/arm-smccc.h> 16 #include <linux/bitops.h> 17 #include <linux/delay.h> 18 #include <misc.h> 19 #include <asm/arch/rockchip_smccc.h> 20 21 #define T_CSB_P_S 0 22 #define T_PGENB_P_S 0 23 #define T_LOAD_P_S 0 24 #define T_ADDR_P_S 0 25 #define T_STROBE_P_S (0 + 110) /* 1.1us */ 26 #define T_CSB_P_L (0 + 110 + 1000 + 20) /* 200ns */ 27 #define T_PGENB_P_L (0 + 110 + 1000 + 20) 28 #define T_LOAD_P_L (0 + 110 + 1000 + 20) 29 #define T_ADDR_P_L (0 + 110 + 1000 + 20) 30 #define T_STROBE_P_L (0 + 110 + 1000) /* 10us */ 31 #define T_CSB_R_S 0 32 #define T_PGENB_R_S 0 33 #define T_LOAD_R_S 0 34 #define T_ADDR_R_S 2 35 #define T_STROBE_R_S (2 + 3) 36 #define T_CSB_R_L (2 + 3 + 3 + 3) 37 #define T_PGENB_R_L (2 + 3 + 3 + 3) 38 #define T_LOAD_R_L (2 + 3 + 3 + 3) 39 #define T_ADDR_R_L (2 + 3 + 3 + 2) 40 #define T_STROBE_R_L (2 + 3 + 3) 41 42 #define T_CSB_P 0x28 43 #define T_PGENB_P 0x2c 44 #define T_LOAD_P 0x30 45 #define T_ADDR_P 0x34 46 #define T_STROBE_P 0x38 47 #define T_CSB_R 0x3c 48 #define T_PGENB_R 0x40 49 #define T_LOAD_R 0x44 50 #define T_ADDR_R 0x48 51 #define T_STROBE_R 0x4c 52 53 #define RK1808_USER_MODE BIT(0) 54 #define RK1808_INT_FINISH BIT(0) 55 #define RK1808_AUTO_ENB BIT(0) 56 #define RK1808_AUTO_RD BIT(1) 57 #define RK1808_A_SHIFT 16 58 #define RK1808_A_MASK 0x3ff 59 #define RK1808_NBYTES 4 60 61 #define RK3399_A_SHIFT 16 62 #define RK3399_A_MASK 0x3ff 63 #define RK3399_NFUSES 32 64 #define RK3399_BYTES_PER_FUSE 4 65 #define RK3399_STROBSFTSEL BIT(9) 66 #define RK3399_RSB BIT(7) 67 #define RK3399_PD BIT(5) 68 #define RK3399_PGENB BIT(3) 69 #define RK3399_LOAD BIT(2) 70 #define RK3399_STROBE BIT(1) 71 #define RK3399_CSB BIT(0) 72 73 #define RK3288_A_SHIFT 6 74 #define RK3288_A_MASK 0x3ff 75 #define RK3288_NFUSES 32 76 #define RK3288_BYTES_PER_FUSE 1 77 #define RK3288_PGENB BIT(3) 78 #define RK3288_LOAD BIT(2) 79 #define RK3288_STROBE BIT(1) 80 #define RK3288_CSB BIT(0) 81 82 #define RK3328_INT_STATUS 0x0018 83 #define RK3328_DOUT 0x0020 84 #define RK3328_AUTO_CTRL 0x0024 85 #define RK3328_INT_FINISH BIT(0) 86 #define RK3328_AUTO_ENB BIT(0) 87 #define RK3328_AUTO_RD BIT(1) 88 89 typedef int (*EFUSE_READ)(struct udevice *dev, int offset, void *buf, int size); 90 91 struct rockchip_efuse_regs { 92 u32 ctrl; /* 0x00 efuse control register */ 93 u32 dout; /* 0x04 efuse data out register */ 94 u32 rf; /* 0x08 efuse redundancy bit used register */ 95 u32 _rsvd0; 96 u32 jtag_pass; /* 0x10 JTAG password */ 97 u32 strobe_finish_ctrl; 98 /* 0x14 efuse strobe finish control register */ 99 u32 int_status;/* 0x18 */ 100 u32 reserved; /* 0x1c */ 101 u32 dout2; /* 0x20 */ 102 u32 auto_ctrl; /* 0x24 */ 103 }; 104 105 struct rockchip_efuse_platdata { 106 void __iomem *base; 107 struct clk *clk; 108 }; 109 110 static void rk1808_efuse_timing_init(void __iomem *base) 111 { 112 static bool init; 113 114 if (init) 115 return; 116 117 /* enable auto mode */ 118 writel(readl(base) & (~RK1808_USER_MODE), base); 119 120 /* setup efuse timing */ 121 writel((T_CSB_P_S << 16) | T_CSB_P_L, base + T_CSB_P); 122 writel((T_PGENB_P_S << 16) | T_PGENB_P_L, base + T_PGENB_P); 123 writel((T_LOAD_P_S << 16) | T_LOAD_P_L, base + T_LOAD_P); 124 writel((T_ADDR_P_S << 16) | T_ADDR_P_L, base + T_ADDR_P); 125 writel((T_STROBE_P_S << 16) | T_STROBE_P_L, base + T_STROBE_P); 126 writel((T_CSB_R_S << 16) | T_CSB_R_L, base + T_CSB_R); 127 writel((T_PGENB_R_S << 16) | T_PGENB_R_L, base + T_PGENB_R); 128 writel((T_LOAD_R_S << 16) | T_LOAD_R_L, base + T_LOAD_R); 129 writel((T_ADDR_R_S << 16) | T_ADDR_R_L, base + T_ADDR_R); 130 writel((T_STROBE_R_S << 16) | T_STROBE_R_L, base + T_STROBE_R); 131 132 init = true; 133 } 134 135 static int rockchip_rk1808_efuse_read(struct udevice *dev, int offset, 136 void *buf, int size) 137 { 138 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 139 struct rockchip_efuse_regs *efuse = 140 (struct rockchip_efuse_regs *)plat->base; 141 unsigned int addr_start, addr_end, addr_offset, addr_len; 142 u32 out_value, status; 143 u8 *buffer; 144 int ret = 0, i = 0; 145 146 rk1808_efuse_timing_init(plat->base); 147 148 addr_start = rounddown(offset, RK1808_NBYTES) / RK1808_NBYTES; 149 addr_end = roundup(offset + size, RK1808_NBYTES) / RK1808_NBYTES; 150 addr_offset = offset % RK1808_NBYTES; 151 addr_len = addr_end - addr_start; 152 153 buffer = calloc(1, sizeof(*buffer) * addr_len * RK1808_NBYTES); 154 if (!buffer) 155 return -ENOMEM; 156 157 while (addr_len--) { 158 writel(RK1808_AUTO_RD | RK1808_AUTO_ENB | 159 ((addr_start++ & RK1808_A_MASK) << RK1808_A_SHIFT), 160 &efuse->auto_ctrl); 161 udelay(2); 162 status = readl(&efuse->int_status); 163 if (!(status & RK1808_INT_FINISH)) { 164 ret = -EIO; 165 goto err; 166 } 167 out_value = readl(&efuse->dout2); 168 writel(RK1808_INT_FINISH, &efuse->int_status); 169 170 memcpy(&buffer[i], &out_value, RK1808_NBYTES); 171 i += RK1808_NBYTES; 172 } 173 memcpy(buf, buffer + addr_offset, size); 174 err: 175 kfree(buffer); 176 177 return ret; 178 } 179 180 #ifndef CONFIG_SPL_BUILD 181 static int rockchip_rk3368_efuse_read(struct udevice *dev, int offset, 182 void *buf, int size) 183 { 184 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 185 struct rockchip_efuse_regs *efuse = 186 (struct rockchip_efuse_regs *)plat->base; 187 u8 *buffer = buf; 188 struct arm_smccc_res res; 189 190 /* Switch to read mode */ 191 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 192 RK3288_LOAD | RK3288_PGENB); 193 udelay(1); 194 while (size--) { 195 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 196 sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 & 197 (~(RK3288_A_MASK << RK3288_A_SHIFT))); 198 /* set addr */ 199 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 200 sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 | 201 ((offset++ & RK3288_A_MASK) << 202 RK3288_A_SHIFT)); 203 udelay(1); 204 /* strobe low to high */ 205 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 206 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 207 res.a1 | RK3288_STROBE); 208 ndelay(60); 209 /* read data */ 210 res = sip_smc_secure_reg_read((ulong)&efuse->dout); 211 *buffer++ = res.a1; 212 /* reset strobe to low */ 213 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 214 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 215 res.a1 & (~RK3288_STROBE)); 216 udelay(1); 217 } 218 219 /* Switch to standby mode */ 220 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 221 RK3288_PGENB | RK3288_CSB); 222 223 return 0; 224 } 225 #endif 226 227 static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, 228 void *buf, int size) 229 { 230 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 231 struct rockchip_efuse_regs *efuse = 232 (struct rockchip_efuse_regs *)plat->base; 233 234 unsigned int addr_start, addr_end, addr_offset; 235 u32 out_value; 236 u8 bytes[RK3399_NFUSES * RK3399_BYTES_PER_FUSE]; 237 int i = 0; 238 u32 addr; 239 240 addr_start = offset / RK3399_BYTES_PER_FUSE; 241 addr_offset = offset % RK3399_BYTES_PER_FUSE; 242 addr_end = DIV_ROUND_UP(offset + size, RK3399_BYTES_PER_FUSE); 243 244 /* cap to the size of the efuse block */ 245 if (addr_end > RK3399_NFUSES) 246 addr_end = RK3399_NFUSES; 247 248 writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB, 249 &efuse->ctrl); 250 udelay(1); 251 for (addr = addr_start; addr < addr_end; addr++) { 252 setbits_le32(&efuse->ctrl, 253 RK3399_STROBE | (addr << RK3399_A_SHIFT)); 254 udelay(1); 255 out_value = readl(&efuse->dout); 256 clrbits_le32(&efuse->ctrl, RK3399_STROBE); 257 udelay(1); 258 259 memcpy(&bytes[i], &out_value, RK3399_BYTES_PER_FUSE); 260 i += RK3399_BYTES_PER_FUSE; 261 } 262 263 /* Switch to standby mode */ 264 writel(RK3399_PD | RK3399_CSB, &efuse->ctrl); 265 266 memcpy(buf, bytes + addr_offset, size); 267 268 return 0; 269 } 270 271 static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset, 272 void *buf, int size) 273 { 274 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 275 struct rockchip_efuse_regs *efuse = 276 (struct rockchip_efuse_regs *)plat->base; 277 u8 *buffer = buf; 278 int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE; 279 280 if (size > (max_size - offset)) 281 size = max_size - offset; 282 283 /* Switch to read mode */ 284 writel(RK3288_LOAD | RK3288_PGENB, &efuse->ctrl); 285 udelay(1); 286 287 while (size--) { 288 writel(readl(&efuse->ctrl) & 289 (~(RK3288_A_MASK << RK3288_A_SHIFT)), 290 &efuse->ctrl); 291 /* set addr */ 292 writel(readl(&efuse->ctrl) | 293 ((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT), 294 &efuse->ctrl); 295 udelay(1); 296 /* strobe low to high */ 297 writel(readl(&efuse->ctrl) | 298 RK3288_STROBE, &efuse->ctrl); 299 ndelay(60); 300 /* read data */ 301 *buffer++ = readl(&efuse->dout); 302 /* reset strobe to low */ 303 writel(readl(&efuse->ctrl) & 304 (~RK3288_STROBE), &efuse->ctrl); 305 udelay(1); 306 } 307 308 /* Switch to standby mode */ 309 writel(RK3288_PGENB | RK3288_CSB, &efuse->ctrl); 310 311 return 0; 312 } 313 314 #ifndef CONFIG_SPL_BUILD 315 static int rockchip_rk3288_efuse_secure_read(struct udevice *dev, int offset, 316 void *buf, int size) 317 { 318 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 319 struct rockchip_efuse_regs *efuse = 320 (struct rockchip_efuse_regs *)plat->base; 321 u8 *buffer = buf; 322 int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE; 323 struct arm_smccc_res res; 324 325 if (size > (max_size - offset)) 326 size = max_size - offset; 327 328 /* Switch to read mode */ 329 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 330 RK3288_LOAD | RK3288_PGENB); 331 udelay(1); 332 while (size--) { 333 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 334 sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 & 335 (~(RK3288_A_MASK << RK3288_A_SHIFT))); 336 /* set addr */ 337 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 338 sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 | 339 ((offset++ & RK3288_A_MASK) << 340 RK3288_A_SHIFT)); 341 udelay(1); 342 /* strobe low to high */ 343 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 344 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 345 res.a1 | RK3288_STROBE); 346 ndelay(60); 347 /* read data */ 348 res = sip_smc_secure_reg_read((ulong)&efuse->dout); 349 *buffer++ = res.a1; 350 /* reset strobe to low */ 351 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 352 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 353 res.a1 & (~RK3288_STROBE)); 354 udelay(1); 355 } 356 357 /* Switch to standby mode */ 358 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 359 RK3288_PGENB | RK3288_CSB); 360 361 return 0; 362 } 363 #endif 364 365 static int rockchip_rk3328_efuse_read(struct udevice *dev, int offset, 366 void *buf, int size) 367 { 368 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 369 struct rockchip_efuse_regs *efuse = 370 (struct rockchip_efuse_regs *)plat->base; 371 unsigned int addr_start, addr_end, addr_offset, addr_len; 372 u32 out_value, status; 373 u8 *buffer; 374 int ret = 0, i = 0, j = 0; 375 376 /* Max non-secure Byte */ 377 if (size > 32) 378 size = 32; 379 380 /* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */ 381 offset += 96; 382 addr_start = rounddown(offset, RK3399_BYTES_PER_FUSE) / 383 RK3399_BYTES_PER_FUSE; 384 addr_end = roundup(offset + size, RK3399_BYTES_PER_FUSE) / 385 RK3399_BYTES_PER_FUSE; 386 addr_offset = offset % RK3399_BYTES_PER_FUSE; 387 addr_len = addr_end - addr_start; 388 389 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3399_BYTES_PER_FUSE); 390 if (!buffer) 391 return -ENOMEM; 392 393 for (j = 0; j < addr_len; j++) { 394 writel(RK3328_AUTO_RD | RK3328_AUTO_ENB | 395 ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT), 396 &efuse->auto_ctrl); 397 udelay(5); 398 status = readl(&efuse->int_status); 399 if (!(status & RK3328_INT_FINISH)) { 400 ret = -EIO; 401 goto err; 402 } 403 out_value = readl(&efuse->dout2); 404 writel(RK3328_INT_FINISH, &efuse->int_status); 405 406 memcpy(&buffer[i], &out_value, RK3399_BYTES_PER_FUSE); 407 i += RK3399_BYTES_PER_FUSE; 408 } 409 memcpy(buf, buffer + addr_offset, size); 410 err: 411 free(buffer); 412 413 return ret; 414 } 415 416 static int rockchip_efuse_read(struct udevice *dev, int offset, 417 void *buf, int size) 418 { 419 EFUSE_READ efuse_read = NULL; 420 421 efuse_read = (EFUSE_READ)dev_get_driver_data(dev); 422 if (!efuse_read) 423 return -ENOSYS; 424 425 return (*efuse_read)(dev, offset, buf, size); 426 } 427 428 static int rockchip_efuse_capatiblity(struct udevice *dev, u32 *buf) 429 { 430 *buf = device_is_compatible(dev, "rockchip,rk3288-secure-efuse") ? 431 OTP_S : OTP_NS; 432 433 return 0; 434 } 435 436 static int rockchip_efuse_ioctl(struct udevice *dev, unsigned long request, 437 void *buf) 438 { 439 int ret = -EINVAL; 440 441 switch (request) { 442 case IOCTL_REQ_CAPABILITY: 443 ret = rockchip_efuse_capatiblity(dev, buf); 444 break; 445 } 446 447 return ret; 448 } 449 450 static const struct misc_ops rockchip_efuse_ops = { 451 .read = rockchip_efuse_read, 452 .ioctl = rockchip_efuse_ioctl, 453 }; 454 455 static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev) 456 { 457 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 458 459 plat->base = dev_read_addr_ptr(dev); 460 return 0; 461 } 462 463 static const struct udevice_id rockchip_efuse_ids[] = { 464 { 465 .compatible = "rockchip,rk1808-efuse", 466 .data = (ulong)&rockchip_rk1808_efuse_read, 467 }, 468 #ifndef CONFIG_SPL_BUILD 469 { 470 .compatible = "rockchip,rk3288-secure-efuse", 471 .data = (ulong)&rockchip_rk3288_efuse_secure_read, 472 }, 473 #endif 474 { 475 .compatible = "rockchip,rk3066a-efuse", 476 .data = (ulong)&rockchip_rk3288_efuse_read, 477 }, 478 { 479 .compatible = "rockchip,rk3188-efuse", 480 .data = (ulong)&rockchip_rk3288_efuse_read, 481 }, 482 { 483 .compatible = "rockchip,rk322x-efuse", 484 .data = (ulong)&rockchip_rk3288_efuse_read, 485 }, 486 { 487 .compatible = "rockchip,rk3328-efuse", 488 .data = (ulong)&rockchip_rk3328_efuse_read, 489 }, 490 #ifndef CONFIG_SPL_BUILD 491 { 492 .compatible = "rockchip,rk3368-efuse", 493 .data = (ulong)&rockchip_rk3368_efuse_read, 494 }, 495 #endif 496 { 497 .compatible = "rockchip,rk3399-efuse", 498 .data = (ulong)&rockchip_rk3399_efuse_read, 499 }, 500 {} 501 }; 502 503 U_BOOT_DRIVER(rockchip_efuse) = { 504 .name = "rockchip_efuse", 505 .id = UCLASS_MISC, 506 .of_match = rockchip_efuse_ids, 507 .ofdata_to_platdata = rockchip_efuse_ofdata_to_platdata, 508 .platdata_auto_alloc_size = sizeof(struct rockchip_efuse_platdata), 509 .ops = &rockchip_efuse_ops, 510 }; 511