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 static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, 181 void *buf, int size) 182 { 183 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 184 struct rockchip_efuse_regs *efuse = 185 (struct rockchip_efuse_regs *)plat->base; 186 187 unsigned int addr_start, addr_end, addr_offset; 188 u32 out_value; 189 u8 bytes[RK3399_NFUSES * RK3399_BYTES_PER_FUSE]; 190 int i = 0; 191 u32 addr; 192 193 addr_start = offset / RK3399_BYTES_PER_FUSE; 194 addr_offset = offset % RK3399_BYTES_PER_FUSE; 195 addr_end = DIV_ROUND_UP(offset + size, RK3399_BYTES_PER_FUSE); 196 197 /* cap to the size of the efuse block */ 198 if (addr_end > RK3399_NFUSES) 199 addr_end = RK3399_NFUSES; 200 201 writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB, 202 &efuse->ctrl); 203 udelay(1); 204 for (addr = addr_start; addr < addr_end; addr++) { 205 setbits_le32(&efuse->ctrl, 206 RK3399_STROBE | (addr << RK3399_A_SHIFT)); 207 udelay(1); 208 out_value = readl(&efuse->dout); 209 clrbits_le32(&efuse->ctrl, RK3399_STROBE); 210 udelay(1); 211 212 memcpy(&bytes[i], &out_value, RK3399_BYTES_PER_FUSE); 213 i += RK3399_BYTES_PER_FUSE; 214 } 215 216 /* Switch to standby mode */ 217 writel(RK3399_PD | RK3399_CSB, &efuse->ctrl); 218 219 memcpy(buf, bytes + addr_offset, size); 220 221 return 0; 222 } 223 224 static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset, 225 void *buf, int size) 226 { 227 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 228 struct rockchip_efuse_regs *efuse = 229 (struct rockchip_efuse_regs *)plat->base; 230 u8 *buffer = buf; 231 int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE; 232 233 if (size > (max_size - offset)) 234 size = max_size - offset; 235 236 /* Switch to read mode */ 237 writel(RK3288_LOAD | RK3288_PGENB, &efuse->ctrl); 238 udelay(1); 239 240 while (size--) { 241 writel(readl(&efuse->ctrl) & 242 (~(RK3288_A_MASK << RK3288_A_SHIFT)), 243 &efuse->ctrl); 244 /* set addr */ 245 writel(readl(&efuse->ctrl) | 246 ((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT), 247 &efuse->ctrl); 248 udelay(1); 249 /* strobe low to high */ 250 writel(readl(&efuse->ctrl) | 251 RK3288_STROBE, &efuse->ctrl); 252 ndelay(60); 253 /* read data */ 254 *buffer++ = readl(&efuse->dout); 255 /* reset strobe to low */ 256 writel(readl(&efuse->ctrl) & 257 (~RK3288_STROBE), &efuse->ctrl); 258 udelay(1); 259 } 260 261 /* Switch to standby mode */ 262 writel(RK3288_PGENB | RK3288_CSB, &efuse->ctrl); 263 264 return 0; 265 } 266 267 #ifndef CONFIG_SPL_BUILD 268 static int rockchip_rk3288_efuse_secure_read(struct udevice *dev, int offset, 269 void *buf, int size) 270 { 271 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 272 struct rockchip_efuse_regs *efuse = 273 (struct rockchip_efuse_regs *)plat->base; 274 u8 *buffer = buf; 275 int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE; 276 struct arm_smccc_res res; 277 278 if (size > (max_size - offset)) 279 size = max_size - offset; 280 281 /* Switch to read mode */ 282 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 283 RK3288_LOAD | RK3288_PGENB); 284 udelay(1); 285 while (size--) { 286 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 287 sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 & 288 (~(RK3288_A_MASK << RK3288_A_SHIFT))); 289 /* set addr */ 290 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 291 sip_smc_secure_reg_write((ulong)&efuse->ctrl, res.a1 | 292 ((offset++ & RK3288_A_MASK) << 293 RK3288_A_SHIFT)); 294 udelay(1); 295 /* strobe low to high */ 296 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 297 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 298 res.a1 | RK3288_STROBE); 299 ndelay(60); 300 /* read data */ 301 res = sip_smc_secure_reg_read((ulong)&efuse->dout); 302 *buffer++ = res.a1; 303 /* reset strobe to low */ 304 res = sip_smc_secure_reg_read((ulong)&efuse->ctrl); 305 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 306 res.a1 & (~RK3288_STROBE)); 307 udelay(1); 308 } 309 310 /* Switch to standby mode */ 311 sip_smc_secure_reg_write((ulong)&efuse->ctrl, 312 RK3288_PGENB | RK3288_CSB); 313 314 return 0; 315 } 316 #endif 317 318 static int rockchip_rk3328_efuse_read(struct udevice *dev, int offset, 319 void *buf, int size) 320 { 321 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 322 struct rockchip_efuse_regs *efuse = 323 (struct rockchip_efuse_regs *)plat->base; 324 unsigned int addr_start, addr_end, addr_offset, addr_len; 325 u32 out_value, status; 326 u8 *buffer; 327 int ret = 0, i = 0, j = 0; 328 329 /* Max non-secure Byte */ 330 if (size > 32) 331 size = 32; 332 333 /* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */ 334 offset += 96; 335 addr_start = rounddown(offset, RK3399_BYTES_PER_FUSE) / 336 RK3399_BYTES_PER_FUSE; 337 addr_end = roundup(offset + size, RK3399_BYTES_PER_FUSE) / 338 RK3399_BYTES_PER_FUSE; 339 addr_offset = offset % RK3399_BYTES_PER_FUSE; 340 addr_len = addr_end - addr_start; 341 342 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3399_BYTES_PER_FUSE); 343 if (!buffer) 344 return -ENOMEM; 345 346 for (j = 0; j < addr_len; j++) { 347 writel(RK3328_AUTO_RD | RK3328_AUTO_ENB | 348 ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT), 349 &efuse->auto_ctrl); 350 udelay(5); 351 status = readl(&efuse->int_status); 352 if (!(status & RK3328_INT_FINISH)) { 353 ret = -EIO; 354 goto err; 355 } 356 out_value = readl(&efuse->dout2); 357 writel(RK3328_INT_FINISH, &efuse->int_status); 358 359 memcpy(&buffer[i], &out_value, RK3399_BYTES_PER_FUSE); 360 i += RK3399_BYTES_PER_FUSE; 361 } 362 memcpy(buf, buffer + addr_offset, size); 363 err: 364 free(buffer); 365 366 return ret; 367 } 368 369 static int rockchip_efuse_read(struct udevice *dev, int offset, 370 void *buf, int size) 371 { 372 EFUSE_READ efuse_read = NULL; 373 374 efuse_read = (EFUSE_READ)dev_get_driver_data(dev); 375 if (!efuse_read) 376 return -ENOSYS; 377 378 return (*efuse_read)(dev, offset, buf, size); 379 } 380 381 static int rockchip_efuse_capatiblity(struct udevice *dev, u32 *buf) 382 { 383 *buf = device_is_compatible(dev, "rockchip,rk3288-secure-efuse") ? 384 OTP_S : OTP_NS; 385 386 return 0; 387 } 388 389 static int rockchip_efuse_ioctl(struct udevice *dev, unsigned long request, 390 void *buf) 391 { 392 int ret = -EINVAL; 393 394 switch (request) { 395 case IOCTL_REQ_CAPABILITY: 396 ret = rockchip_efuse_capatiblity(dev, buf); 397 break; 398 } 399 400 return ret; 401 } 402 403 static const struct misc_ops rockchip_efuse_ops = { 404 .read = rockchip_efuse_read, 405 .ioctl = rockchip_efuse_ioctl, 406 }; 407 408 static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev) 409 { 410 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 411 412 plat->base = dev_read_addr_ptr(dev); 413 return 0; 414 } 415 416 static const struct udevice_id rockchip_efuse_ids[] = { 417 { 418 .compatible = "rockchip,rk1808-efuse", 419 .data = (ulong)&rockchip_rk1808_efuse_read, 420 }, 421 #ifndef CONFIG_SPL_BUILD 422 { 423 .compatible = "rockchip,rk3288-secure-efuse", 424 .data = (ulong)&rockchip_rk3288_efuse_secure_read, 425 }, 426 #endif 427 { 428 .compatible = "rockchip,rk3066a-efuse", 429 .data = (ulong)&rockchip_rk3288_efuse_read, 430 }, 431 { 432 .compatible = "rockchip,rk3188-efuse", 433 .data = (ulong)&rockchip_rk3288_efuse_read, 434 }, 435 { 436 .compatible = "rockchip,rk322x-efuse", 437 .data = (ulong)&rockchip_rk3288_efuse_read, 438 }, 439 { 440 .compatible = "rockchip,rk3328-efuse", 441 .data = (ulong)&rockchip_rk3328_efuse_read, 442 }, 443 { 444 .compatible = "rockchip,rk3399-efuse", 445 .data = (ulong)&rockchip_rk3399_efuse_read, 446 }, 447 {} 448 }; 449 450 U_BOOT_DRIVER(rockchip_efuse) = { 451 .name = "rockchip_efuse", 452 .id = UCLASS_MISC, 453 .of_match = rockchip_efuse_ids, 454 .ofdata_to_platdata = rockchip_efuse_ofdata_to_platdata, 455 .platdata_auto_alloc_size = sizeof(struct rockchip_efuse_platdata), 456 .ops = &rockchip_efuse_ops, 457 }; 458