1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd 4 */ 5 #include <common.h> 6 #include <clk-uclass.h> 7 #include <dm.h> 8 #include <rng.h> 9 #include <asm/arch-rockchip/hardware.h> 10 #include <asm/io.h> 11 #include <linux/iopoll.h> 12 #include <linux/string.h> 13 14 #define RK_HW_RNG_MAX 32 15 16 #define _SBF(s, v) ((v) << (s)) 17 18 /* start of CRYPTO V1 register define */ 19 #define CRYPTO_V1_CTRL 0x0008 20 #define CRYPTO_V1_RNG_START BIT(8) 21 #define CRYPTO_V1_RNG_FLUSH BIT(9) 22 23 #define CRYPTO_V1_TRNG_CTRL 0x0200 24 #define CRYPTO_V1_OSC_ENABLE BIT(16) 25 #define CRYPTO_V1_TRNG_SAMPLE_PERIOD(x) (x) 26 27 #define CRYPTO_V1_TRNG_DOUT_0 0x0204 28 /* end of CRYPTO V1 register define */ 29 30 /* start of CRYPTO V2 register define */ 31 #define CRYPTO_V2_RNG_CTL 0x0400 32 #define CRYPTO_V2_RNG_64_BIT_LEN _SBF(4, 0x00) 33 #define CRYPTO_V2_RNG_128_BIT_LEN _SBF(4, 0x01) 34 #define CRYPTO_V2_RNG_192_BIT_LEN _SBF(4, 0x02) 35 #define CRYPTO_V2_RNG_256_BIT_LEN _SBF(4, 0x03) 36 #define CRYPTO_V2_RNG_FATESY_SOC_RING _SBF(2, 0x00) 37 #define CRYPTO_V2_RNG_SLOWER_SOC_RING_0 _SBF(2, 0x01) 38 #define CRYPTO_V2_RNG_SLOWER_SOC_RING_1 _SBF(2, 0x02) 39 #define CRYPTO_V2_RNG_SLOWEST_SOC_RING _SBF(2, 0x03) 40 #define CRYPTO_V2_RNG_ENABLE BIT(1) 41 #define CRYPTO_V2_RNG_START BIT(0) 42 #define CRYPTO_V2_RNG_SAMPLE_CNT 0x0404 43 #define CRYPTO_V2_RNG_DOUT_0 0x0410 44 /* end of CRYPTO V2 register define */ 45 46 /* start of TRNG V1 register define */ 47 #define TRNG_V1_CTRL 0x0000 48 #define TRNG_V1_CTRL_NOP _SBF(0, 0x00) 49 #define TRNG_V1_CTRL_RAND _SBF(0, 0x01) 50 #define TRNG_V1_CTRL_SEED _SBF(0, 0x02) 51 52 #define TRNG_V1_MODE 0x0008 53 #define TRNG_V1_MODE_128_BIT _SBF(3, 0x00) 54 #define TRNG_V1_MODE_256_BIT _SBF(3, 0x01) 55 56 #define TRNG_V1_IE 0x0010 57 #define TRNG_V1_IE_GLBL_EN BIT(31) 58 #define TRNG_V1_IE_SEED_DONE_EN BIT(1) 59 #define TRNG_V1_IE_RAND_RDY_EN BIT(0) 60 61 #define TRNG_V1_ISTAT 0x0014 62 #define TRNG_V1_ISTAT_RAND_RDY BIT(0) 63 64 /* RAND0 ~ RAND7 */ 65 #define TRNG_V1_RAND0 0x0020 66 #define TRNG_V1_RAND7 0x003C 67 68 #define TRNG_V1_AUTO_RQSTS 0x0060 69 70 #define TRNG_V1_VERSION 0x00F0 71 #define TRNG_v1_VERSION_CODE 0x46BC 72 /* end of TRNG V1 register define */ 73 74 /* start of RKRNG register define */ 75 #define RKRNG_CTRL 0x0010 76 #define RKRNG_CTRL_INST_REQ BIT(0) 77 #define RKRNG_CTRL_RESEED_REQ BIT(1) 78 #define RKRNG_CTRL_TEST_REQ BIT(2) 79 #define RKRNG_CTRL_SW_DRNG_REQ BIT(3) 80 #define RKRNG_CTRL_SW_TRNG_REQ BIT(4) 81 82 #define RKRNG_STATE 0x0014 83 #define RKRNG_STATE_INST_ACK BIT(0) 84 #define RKRNG_STATE_RESEED_ACK BIT(1) 85 #define RKRNG_STATE_TEST_ACK BIT(2) 86 #define RKRNG_STATE_SW_DRNG_ACK BIT(3) 87 #define RKRNG_STATE_SW_TRNG_ACK BIT(4) 88 89 /* DRNG_DATA_0 ~ DNG_DATA_7 */ 90 #define RKRNG_DRNG_DATA_0 0x0070 91 #define RKRNG_DRNG_DATA_7 0x008C 92 93 /* end of RKRNG register define */ 94 95 #define RK_RNG_TIME_OUT 50000 /* max 50ms */ 96 97 #define trng_write(pdata, pos, val) writel(val, (pdata)->base + (pos)) 98 #define trng_read(pdata, pos) readl((pdata)->base + (pos)) 99 100 struct rk_rng_soc_data { 101 int (*rk_rng_init)(struct udevice *dev); 102 int (*rk_rng_read)(struct udevice *dev, void *data, size_t len); 103 }; 104 105 struct rk_rng_platdata { 106 fdt_addr_t base; 107 struct rk_rng_soc_data *soc_data; 108 struct clk hclk; 109 }; 110 111 static int rk_rng_do_enable_clk(struct udevice *dev, int enable) 112 { 113 struct rk_rng_platdata *pdata = dev_get_priv(dev); 114 int ret; 115 116 if (!pdata->hclk.dev) 117 return 0; 118 119 ret = enable ? clk_enable(&pdata->hclk) : clk_disable(&pdata->hclk); 120 if (ret == -ENOSYS || !ret) 121 return 0; 122 123 printf("rk rng: failed to %s clk, ret=%d\n", 124 enable ? "enable" : "disable", ret); 125 126 return ret; 127 } 128 129 static int rk_rng_enable_clk(struct udevice *dev) 130 { 131 return rk_rng_do_enable_clk(dev, 1); 132 } 133 134 static int rk_rng_disable_clk(struct udevice *dev) 135 { 136 return rk_rng_do_enable_clk(dev, 0); 137 } 138 139 static int rk_rng_read_regs(fdt_addr_t addr, void *buf, size_t size) 140 { 141 u32 count = RK_HW_RNG_MAX / sizeof(u32); 142 u32 reg, tmp_len; 143 144 if (size > RK_HW_RNG_MAX) 145 return -EINVAL; 146 147 while (size && count) { 148 reg = readl(addr); 149 tmp_len = min(size, sizeof(u32)); 150 memcpy(buf, ®, tmp_len); 151 addr += sizeof(u32); 152 buf += tmp_len; 153 size -= tmp_len; 154 count--; 155 } 156 157 return 0; 158 } 159 160 static int cryptov1_rng_read(struct udevice *dev, void *data, size_t len) 161 { 162 struct rk_rng_platdata *pdata = dev_get_priv(dev); 163 u32 reg = 0; 164 int retval; 165 166 if (len > RK_HW_RNG_MAX) 167 return -EINVAL; 168 169 /* enable osc_ring to get entropy, sample period is set as 100 */ 170 writel(CRYPTO_V1_OSC_ENABLE | CRYPTO_V1_TRNG_SAMPLE_PERIOD(100), 171 pdata->base + CRYPTO_V1_TRNG_CTRL); 172 173 rk_clrsetreg(pdata->base + CRYPTO_V1_CTRL, CRYPTO_V1_RNG_START, 174 CRYPTO_V1_RNG_START); 175 176 retval = readl_poll_timeout(pdata->base + CRYPTO_V1_CTRL, reg, 177 !(reg & CRYPTO_V1_RNG_START), 178 RK_RNG_TIME_OUT); 179 if (retval) 180 goto exit; 181 182 rk_rng_read_regs(pdata->base + CRYPTO_V1_TRNG_DOUT_0, data, len); 183 184 exit: 185 /* close TRNG */ 186 rk_clrreg(pdata->base + CRYPTO_V1_CTRL, CRYPTO_V1_RNG_START); 187 188 return 0; 189 } 190 191 static int cryptov2_rng_read(struct udevice *dev, void *data, size_t len) 192 { 193 struct rk_rng_platdata *pdata = dev_get_priv(dev); 194 u32 reg = 0; 195 int retval; 196 197 if (len > RK_HW_RNG_MAX) 198 return -EINVAL; 199 200 /* enable osc_ring to get entropy, sample period is set as 100 */ 201 writel(100, pdata->base + CRYPTO_V2_RNG_SAMPLE_CNT); 202 203 reg |= CRYPTO_V2_RNG_256_BIT_LEN; 204 reg |= CRYPTO_V2_RNG_SLOWER_SOC_RING_0; 205 reg |= CRYPTO_V2_RNG_ENABLE; 206 reg |= CRYPTO_V2_RNG_START; 207 208 rk_clrsetreg(pdata->base + CRYPTO_V2_RNG_CTL, 0xffff, reg); 209 210 retval = readl_poll_timeout(pdata->base + CRYPTO_V2_RNG_CTL, reg, 211 !(reg & CRYPTO_V2_RNG_START), 212 RK_RNG_TIME_OUT); 213 if (retval) 214 goto exit; 215 216 rk_rng_read_regs(pdata->base + CRYPTO_V2_RNG_DOUT_0, data, len); 217 218 exit: 219 /* close TRNG */ 220 rk_clrreg(pdata->base + CRYPTO_V2_RNG_CTL, 0xffff); 221 222 return retval; 223 } 224 225 static int trngv1_init(struct udevice *dev) 226 { 227 u32 status, version; 228 u32 auto_reseed_cnt = 1000; 229 struct rk_rng_platdata *pdata = dev_get_priv(dev); 230 231 version = trng_read(pdata, TRNG_V1_VERSION); 232 if (version != TRNG_v1_VERSION_CODE) { 233 printf("wrong trng version, expected = %08x, actual = %08x", 234 TRNG_V1_VERSION, version); 235 return -EFAULT; 236 } 237 238 /* wait in case of RND_RDY triggered at firs power on */ 239 readl_poll_timeout(pdata->base + TRNG_V1_ISTAT, status, 240 (status & TRNG_V1_ISTAT_RAND_RDY), 241 RK_RNG_TIME_OUT); 242 243 /* clear RAND_RDY flag for first power on */ 244 trng_write(pdata, TRNG_V1_ISTAT, status); 245 246 /* auto reseed after (auto_reseed_cnt * 16) byte rand generate */ 247 trng_write(pdata, TRNG_V1_AUTO_RQSTS, auto_reseed_cnt); 248 249 return 0; 250 } 251 252 static int trngv1_rng_read(struct udevice *dev, void *data, size_t len) 253 { 254 struct rk_rng_platdata *pdata = dev_get_priv(dev); 255 u32 reg = 0; 256 int retval; 257 258 if (len > RK_HW_RNG_MAX) 259 return -EINVAL; 260 261 trng_write(pdata, TRNG_V1_MODE, TRNG_V1_MODE_256_BIT); 262 trng_write(pdata, TRNG_V1_CTRL, TRNG_V1_CTRL_RAND); 263 264 retval = readl_poll_timeout(pdata->base + TRNG_V1_ISTAT, reg, 265 (reg & TRNG_V1_ISTAT_RAND_RDY), 266 RK_RNG_TIME_OUT); 267 /* clear ISTAT */ 268 trng_write(pdata, TRNG_V1_ISTAT, reg); 269 270 if (retval) 271 goto exit; 272 273 rk_rng_read_regs(pdata->base + TRNG_V1_RAND0, data, len); 274 275 exit: 276 /* close TRNG */ 277 trng_write(pdata, TRNG_V1_CTRL, TRNG_V1_CTRL_NOP); 278 279 return retval; 280 } 281 282 static int rkrng_init(struct udevice *dev) 283 { 284 struct rk_rng_platdata *pdata = dev_get_priv(dev); 285 u32 reg = 0; 286 287 rk_clrreg(pdata->base + RKRNG_CTRL, 0xffff); 288 289 reg = trng_read(pdata, RKRNG_STATE); 290 trng_write(pdata, RKRNG_STATE, reg); 291 292 return 0; 293 } 294 295 static int rkrng_rng_read(struct udevice *dev, void *data, size_t len) 296 { 297 struct rk_rng_platdata *pdata = dev_get_priv(dev); 298 u32 reg = 0; 299 int retval; 300 301 if (len > RK_HW_RNG_MAX) 302 return -EINVAL; 303 304 rk_rng_enable_clk(dev); 305 306 reg = RKRNG_CTRL_SW_DRNG_REQ; 307 308 rk_clrsetreg(pdata->base + RKRNG_CTRL, 0xffff, reg); 309 310 retval = readl_poll_timeout(pdata->base + RKRNG_STATE, reg, 311 (reg & RKRNG_STATE_SW_DRNG_ACK), 312 RK_RNG_TIME_OUT); 313 if (retval) 314 goto exit; 315 316 trng_write(pdata, RKRNG_STATE, reg); 317 318 rk_rng_read_regs(pdata->base + RKRNG_DRNG_DATA_0, data, len); 319 320 exit: 321 /* close TRNG */ 322 rk_clrreg(pdata->base + RKRNG_CTRL, 0xffff); 323 324 rk_rng_disable_clk(dev); 325 326 return retval; 327 } 328 329 static int rockchip_rng_read(struct udevice *dev, void *data, size_t len) 330 { 331 unsigned char *buf = data; 332 unsigned int i; 333 int ret = -EIO; 334 335 struct rk_rng_platdata *pdata = dev_get_priv(dev); 336 337 if (!len) 338 return 0; 339 340 if (!pdata->soc_data || !pdata->soc_data->rk_rng_read) 341 return -EINVAL; 342 343 for (i = 0; i < len / RK_HW_RNG_MAX; i++, buf += RK_HW_RNG_MAX) { 344 ret = pdata->soc_data->rk_rng_read(dev, buf, RK_HW_RNG_MAX); 345 if (ret) 346 goto exit; 347 } 348 349 if (len % RK_HW_RNG_MAX) 350 ret = pdata->soc_data->rk_rng_read(dev, buf, 351 len % RK_HW_RNG_MAX); 352 353 exit: 354 return ret; 355 } 356 357 static int rockchip_rng_ofdata_to_platdata(struct udevice *dev) 358 { 359 struct rk_rng_platdata *pdata = dev_get_priv(dev); 360 361 memset(pdata, 0x00, sizeof(*pdata)); 362 363 pdata->base = (fdt_addr_t)dev_read_addr_ptr(dev); 364 if (!pdata->base) 365 return -ENOMEM; 366 367 clk_get_by_index(dev, 0, &pdata->hclk); 368 369 return 0; 370 } 371 372 static int rockchip_rng_probe(struct udevice *dev) 373 { 374 struct rk_rng_platdata *pdata = dev_get_priv(dev); 375 int ret = 0; 376 377 pdata->soc_data = (struct rk_rng_soc_data *)dev_get_driver_data(dev); 378 379 if (pdata->soc_data->rk_rng_init) 380 ret = pdata->soc_data->rk_rng_init(dev); 381 382 return ret; 383 } 384 385 static const struct rk_rng_soc_data cryptov1_soc_data = { 386 .rk_rng_read = cryptov1_rng_read, 387 }; 388 389 static const struct rk_rng_soc_data cryptov2_soc_data = { 390 .rk_rng_read = cryptov2_rng_read, 391 }; 392 393 static const struct rk_rng_soc_data trngv1_soc_data = { 394 .rk_rng_init = trngv1_init, 395 .rk_rng_read = trngv1_rng_read, 396 }; 397 398 static const struct rk_rng_soc_data rkrng_soc_data = { 399 .rk_rng_init = rkrng_init, 400 .rk_rng_read = rkrng_rng_read, 401 }; 402 403 static const struct dm_rng_ops rockchip_rng_ops = { 404 .read = rockchip_rng_read, 405 }; 406 407 static const struct udevice_id rockchip_rng_match[] = { 408 { 409 .compatible = "rockchip,cryptov1-rng", 410 .data = (ulong)&cryptov1_soc_data, 411 }, 412 { 413 .compatible = "rockchip,cryptov2-rng", 414 .data = (ulong)&cryptov2_soc_data, 415 }, 416 { 417 .compatible = "rockchip,trngv1", 418 .data = (ulong)&trngv1_soc_data, 419 }, 420 { 421 .compatible = "rockchip,rkrng", 422 .data = (ulong)&rkrng_soc_data, 423 }, 424 {}, 425 }; 426 427 U_BOOT_DRIVER(rockchip_rng) = { 428 .name = "rockchip-rng", 429 .id = UCLASS_RNG, 430 .of_match = rockchip_rng_match, 431 .ops = &rockchip_rng_ops, 432 .probe = rockchip_rng_probe, 433 .ofdata_to_platdata = rockchip_rng_ofdata_to_platdata, 434 .priv_auto_alloc_size = sizeof(struct rk_rng_platdata), 435 }; 436