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/bitops.h> 16 #include <linux/delay.h> 17 #include <misc.h> 18 19 #define T_CSB_P_S 0 20 #define T_PGENB_P_S 0 21 #define T_LOAD_P_S 0 22 #define T_ADDR_P_S 0 23 #define T_STROBE_P_S (0 + 110) /* 1.1us */ 24 #define T_CSB_P_L (0 + 110 + 1000 + 20) /* 200ns */ 25 #define T_PGENB_P_L (0 + 110 + 1000 + 20) 26 #define T_LOAD_P_L (0 + 110 + 1000 + 20) 27 #define T_ADDR_P_L (0 + 110 + 1000 + 20) 28 #define T_STROBE_P_L (0 + 110 + 1000) /* 10us */ 29 #define T_CSB_R_S 0 30 #define T_PGENB_R_S 0 31 #define T_LOAD_R_S 0 32 #define T_ADDR_R_S 2 33 #define T_STROBE_R_S (2 + 3) 34 #define T_CSB_R_L (2 + 3 + 3 + 3) 35 #define T_PGENB_R_L (2 + 3 + 3 + 3) 36 #define T_LOAD_R_L (2 + 3 + 3 + 3) 37 #define T_ADDR_R_L (2 + 3 + 3 + 2) 38 #define T_STROBE_R_L (2 + 3 + 3) 39 40 #define T_CSB_P 0x28 41 #define T_PGENB_P 0x2c 42 #define T_LOAD_P 0x30 43 #define T_ADDR_P 0x34 44 #define T_STROBE_P 0x38 45 #define T_CSB_R 0x3c 46 #define T_PGENB_R 0x40 47 #define T_LOAD_R 0x44 48 #define T_ADDR_R 0x48 49 #define T_STROBE_R 0x4c 50 51 #define RK1808_USER_MODE BIT(0) 52 #define RK1808_INT_FINISH BIT(0) 53 #define RK1808_AUTO_ENB BIT(0) 54 #define RK1808_AUTO_RD BIT(1) 55 #define RK1808_A_SHIFT 16 56 #define RK1808_A_MASK 0x3ff 57 #define RK1808_NBYTES 4 58 59 #define RK3399_A_SHIFT 16 60 #define RK3399_A_MASK 0x3ff 61 #define RK3399_NFUSES 32 62 #define RK3399_BYTES_PER_FUSE 4 63 #define RK3399_STROBSFTSEL BIT(9) 64 #define RK3399_RSB BIT(7) 65 #define RK3399_PD BIT(5) 66 #define RK3399_PGENB BIT(3) 67 #define RK3399_LOAD BIT(2) 68 #define RK3399_STROBE BIT(1) 69 #define RK3399_CSB BIT(0) 70 71 #define RK3288_A_SHIFT 6 72 #define RK3288_A_MASK 0x3ff 73 #define RK3288_NFUSES 32 74 #define RK3288_BYTES_PER_FUSE 1 75 #define RK3288_PGENB BIT(3) 76 #define RK3288_LOAD BIT(2) 77 #define RK3288_STROBE BIT(1) 78 #define RK3288_CSB BIT(0) 79 80 #define RK3328_INT_STATUS 0x0018 81 #define RK3328_DOUT 0x0020 82 #define RK3328_AUTO_CTRL 0x0024 83 #define RK3328_INT_FINISH BIT(0) 84 #define RK3328_AUTO_ENB BIT(0) 85 #define RK3328_AUTO_RD BIT(1) 86 87 typedef int (*EFUSE_READ)(struct udevice *dev, int offset, void *buf, int size); 88 89 struct rockchip_efuse_regs { 90 u32 ctrl; /* 0x00 efuse control register */ 91 u32 dout; /* 0x04 efuse data out register */ 92 u32 rf; /* 0x08 efuse redundancy bit used register */ 93 u32 _rsvd0; 94 u32 jtag_pass; /* 0x10 JTAG password */ 95 u32 strobe_finish_ctrl; 96 /* 0x14 efuse strobe finish control register */ 97 u32 int_status;/* 0x18 */ 98 u32 reserved; /* 0x1c */ 99 u32 dout2; /* 0x20 */ 100 u32 auto_ctrl; /* 0x24 */ 101 }; 102 103 struct rockchip_efuse_platdata { 104 void __iomem *base; 105 struct clk *clk; 106 }; 107 108 static void rk1808_efuse_timing_init(void __iomem *base) 109 { 110 static bool init; 111 112 if (init) 113 return; 114 115 /* enable auto mode */ 116 writel(readl(base) & (~RK1808_USER_MODE), base); 117 118 /* setup efuse timing */ 119 writel((T_CSB_P_S << 16) | T_CSB_P_L, base + T_CSB_P); 120 writel((T_PGENB_P_S << 16) | T_PGENB_P_L, base + T_PGENB_P); 121 writel((T_LOAD_P_S << 16) | T_LOAD_P_L, base + T_LOAD_P); 122 writel((T_ADDR_P_S << 16) | T_ADDR_P_L, base + T_ADDR_P); 123 writel((T_STROBE_P_S << 16) | T_STROBE_P_L, base + T_STROBE_P); 124 writel((T_CSB_R_S << 16) | T_CSB_R_L, base + T_CSB_R); 125 writel((T_PGENB_R_S << 16) | T_PGENB_R_L, base + T_PGENB_R); 126 writel((T_LOAD_R_S << 16) | T_LOAD_R_L, base + T_LOAD_R); 127 writel((T_ADDR_R_S << 16) | T_ADDR_R_L, base + T_ADDR_R); 128 writel((T_STROBE_R_S << 16) | T_STROBE_R_L, base + T_STROBE_R); 129 130 init = true; 131 } 132 133 static int rockchip_rk1808_efuse_read(struct udevice *dev, int offset, 134 void *buf, int size) 135 { 136 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 137 struct rockchip_efuse_regs *efuse = 138 (struct rockchip_efuse_regs *)plat->base; 139 unsigned int addr_start, addr_end, addr_offset, addr_len; 140 u32 out_value, status; 141 u8 *buffer; 142 int ret = 0, i = 0; 143 144 rk1808_efuse_timing_init(plat->base); 145 146 addr_start = rounddown(offset, RK1808_NBYTES) / RK1808_NBYTES; 147 addr_end = roundup(offset + size, RK1808_NBYTES) / RK1808_NBYTES; 148 addr_offset = offset % RK1808_NBYTES; 149 addr_len = addr_end - addr_start; 150 151 buffer = calloc(1, sizeof(*buffer) * addr_len * RK1808_NBYTES); 152 if (!buffer) 153 return -ENOMEM; 154 155 while (addr_len--) { 156 writel(RK1808_AUTO_RD | RK1808_AUTO_ENB | 157 ((addr_start++ & RK1808_A_MASK) << RK1808_A_SHIFT), 158 &efuse->auto_ctrl); 159 udelay(2); 160 status = readl(&efuse->int_status); 161 if (!(status & RK1808_INT_FINISH)) { 162 ret = -EIO; 163 goto err; 164 } 165 out_value = readl(&efuse->dout2); 166 writel(RK1808_INT_FINISH, &efuse->int_status); 167 168 memcpy(&buffer[i], &out_value, RK1808_NBYTES); 169 i += RK1808_NBYTES; 170 } 171 memcpy(buf, buffer + addr_offset, size); 172 err: 173 kfree(buffer); 174 175 return ret; 176 } 177 178 static int rockchip_rk3399_efuse_read(struct udevice *dev, int offset, 179 void *buf, int size) 180 { 181 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 182 struct rockchip_efuse_regs *efuse = 183 (struct rockchip_efuse_regs *)plat->base; 184 185 unsigned int addr_start, addr_end, addr_offset; 186 u32 out_value; 187 u8 bytes[RK3399_NFUSES * RK3399_BYTES_PER_FUSE]; 188 int i = 0; 189 u32 addr; 190 191 addr_start = offset / RK3399_BYTES_PER_FUSE; 192 addr_offset = offset % RK3399_BYTES_PER_FUSE; 193 addr_end = DIV_ROUND_UP(offset + size, RK3399_BYTES_PER_FUSE); 194 195 /* cap to the size of the efuse block */ 196 if (addr_end > RK3399_NFUSES) 197 addr_end = RK3399_NFUSES; 198 199 writel(RK3399_LOAD | RK3399_PGENB | RK3399_STROBSFTSEL | RK3399_RSB, 200 &efuse->ctrl); 201 udelay(1); 202 for (addr = addr_start; addr < addr_end; addr++) { 203 setbits_le32(&efuse->ctrl, 204 RK3399_STROBE | (addr << RK3399_A_SHIFT)); 205 udelay(1); 206 out_value = readl(&efuse->dout); 207 clrbits_le32(&efuse->ctrl, RK3399_STROBE); 208 udelay(1); 209 210 memcpy(&bytes[i], &out_value, RK3399_BYTES_PER_FUSE); 211 i += RK3399_BYTES_PER_FUSE; 212 } 213 214 /* Switch to standby mode */ 215 writel(RK3399_PD | RK3399_CSB, &efuse->ctrl); 216 217 memcpy(buf, bytes + addr_offset, size); 218 219 return 0; 220 } 221 222 static int rockchip_rk3288_efuse_read(struct udevice *dev, int offset, 223 void *buf, int size) 224 { 225 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 226 struct rockchip_efuse_regs *efuse = 227 (struct rockchip_efuse_regs *)plat->base; 228 u8 *buffer = buf; 229 int max_size = RK3288_NFUSES * RK3288_BYTES_PER_FUSE; 230 231 if (size > (max_size - offset)) 232 size = max_size - offset; 233 234 /* Switch to read mode */ 235 writel(RK3288_LOAD | RK3288_PGENB, &efuse->ctrl); 236 udelay(1); 237 238 while (size--) { 239 writel(readl(&efuse->ctrl) & 240 (~(RK3288_A_MASK << RK3288_A_SHIFT)), 241 &efuse->ctrl); 242 /* set addr */ 243 writel(readl(&efuse->ctrl) | 244 ((offset++ & RK3288_A_MASK) << RK3288_A_SHIFT), 245 &efuse->ctrl); 246 udelay(1); 247 /* strobe low to high */ 248 writel(readl(&efuse->ctrl) | 249 RK3288_STROBE, &efuse->ctrl); 250 ndelay(60); 251 /* read data */ 252 *buffer++ = readl(&efuse->dout); 253 /* reset strobe to low */ 254 writel(readl(&efuse->ctrl) & 255 (~RK3288_STROBE), &efuse->ctrl); 256 udelay(1); 257 } 258 259 /* Switch to standby mode */ 260 writel(RK3288_PGENB | RK3288_CSB, &efuse->ctrl); 261 262 return 0; 263 } 264 265 static int rockchip_rk3328_efuse_read(struct udevice *dev, int offset, 266 void *buf, int size) 267 { 268 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 269 struct rockchip_efuse_regs *efuse = 270 (struct rockchip_efuse_regs *)plat->base; 271 unsigned int addr_start, addr_end, addr_offset, addr_len; 272 u32 out_value, status; 273 u8 *buffer; 274 int ret = 0, i = 0, j = 0; 275 276 /* Max non-secure Byte */ 277 if (size > 32) 278 size = 32; 279 280 /* 128 Byte efuse, 96 Byte for secure, 32 Byte for non-secure */ 281 offset += 96; 282 addr_start = rounddown(offset, RK3399_BYTES_PER_FUSE) / 283 RK3399_BYTES_PER_FUSE; 284 addr_end = roundup(offset + size, RK3399_BYTES_PER_FUSE) / 285 RK3399_BYTES_PER_FUSE; 286 addr_offset = offset % RK3399_BYTES_PER_FUSE; 287 addr_len = addr_end - addr_start; 288 289 buffer = calloc(1, sizeof(*buffer) * addr_len * RK3399_BYTES_PER_FUSE); 290 if (!buffer) 291 return -ENOMEM; 292 293 for (j = 0; j < addr_len; j++) { 294 writel(RK3328_AUTO_RD | RK3328_AUTO_ENB | 295 ((addr_start++ & RK3399_A_MASK) << RK3399_A_SHIFT), 296 &efuse->auto_ctrl); 297 udelay(5); 298 status = readl(&efuse->int_status); 299 if (!(status & RK3328_INT_FINISH)) { 300 ret = -EIO; 301 goto err; 302 } 303 out_value = readl(&efuse->dout2); 304 writel(RK3328_INT_FINISH, &efuse->int_status); 305 306 memcpy(&buffer[i], &out_value, RK3399_BYTES_PER_FUSE); 307 i += RK3399_BYTES_PER_FUSE; 308 } 309 memcpy(buf, buffer + addr_offset, size); 310 err: 311 free(buffer); 312 313 return ret; 314 } 315 316 static int rockchip_efuse_read(struct udevice *dev, int offset, 317 void *buf, int size) 318 { 319 EFUSE_READ efuse_read = NULL; 320 321 efuse_read = (EFUSE_READ)dev_get_driver_data(dev); 322 if (!efuse_read) 323 return -ENOSYS; 324 325 return (*efuse_read)(dev, offset, buf, size); 326 } 327 328 static const struct misc_ops rockchip_efuse_ops = { 329 .read = rockchip_efuse_read, 330 }; 331 332 static int rockchip_efuse_ofdata_to_platdata(struct udevice *dev) 333 { 334 struct rockchip_efuse_platdata *plat = dev_get_platdata(dev); 335 336 plat->base = dev_read_addr_ptr(dev); 337 return 0; 338 } 339 340 static const struct udevice_id rockchip_efuse_ids[] = { 341 { 342 .compatible = "rockchip,rk1808-efuse", 343 .data = (ulong)&rockchip_rk1808_efuse_read, 344 }, 345 { 346 .compatible = "rockchip,rockchip-efuse", 347 .data = (ulong)&rockchip_rk3288_efuse_read, 348 }, 349 { 350 .compatible = "rockchip,rk3066a-efuse", 351 .data = (ulong)&rockchip_rk3288_efuse_read, 352 }, 353 { 354 .compatible = "rockchip,rk3188-efuse", 355 .data = (ulong)&rockchip_rk3288_efuse_read, 356 }, 357 { 358 .compatible = "rockchip,rk322x-efuse", 359 .data = (ulong)&rockchip_rk3288_efuse_read, 360 }, 361 { 362 .compatible = "rockchip,rk3328-efuse", 363 .data = (ulong)&rockchip_rk3328_efuse_read, 364 }, 365 { 366 .compatible = "rockchip,rk3399-efuse", 367 .data = (ulong)&rockchip_rk3399_efuse_read, 368 }, 369 {} 370 }; 371 372 U_BOOT_DRIVER(rockchip_efuse) = { 373 .name = "rockchip_efuse", 374 .id = UCLASS_MISC, 375 .of_match = rockchip_efuse_ids, 376 .ofdata_to_platdata = rockchip_efuse_ofdata_to_platdata, 377 .platdata_auto_alloc_size = sizeof(struct rockchip_efuse_platdata), 378 .ops = &rockchip_efuse_ops, 379 }; 380