1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * RNG driver for Exynos TRNGs 4 * 5 * Author: Łukasz Stelmach <l.stelmach@samsung.com> 6 * 7 * Copyright 2017 (c) Samsung Electronics Software, Inc. 8 * 9 * Based on the Exynos PRNG driver drivers/crypto/exynos-rng by 10 * Krzysztof Kozłowski <krzk@kernel.org> 11 */ 12 13 #include <linux/arm-smccc.h> 14 #include <linux/clk.h> 15 #include <linux/crypto.h> 16 #include <linux/delay.h> 17 #include <linux/err.h> 18 #include <linux/hw_random.h> 19 #include <linux/io.h> 20 #include <linux/iopoll.h> 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 #include <linux/mod_devicetable.h> 24 #include <linux/platform_device.h> 25 #include <linux/pm_runtime.h> 26 #include <linux/property.h> 27 28 #define EXYNOS_TRNG_CLKDIV 0x0 29 30 #define EXYNOS_TRNG_CTRL 0x20 31 #define EXYNOS_TRNG_CTRL_RNGEN BIT(31) 32 33 #define EXYNOS_TRNG_POST_CTRL 0x30 34 #define EXYNOS_TRNG_ONLINE_CTRL 0x40 35 #define EXYNOS_TRNG_ONLINE_STAT 0x44 36 #define EXYNOS_TRNG_ONLINE_MAXCHI2 0x48 37 #define EXYNOS_TRNG_FIFO_CTRL 0x50 38 #define EXYNOS_TRNG_FIFO_0 0x80 39 #define EXYNOS_TRNG_FIFO_1 0x84 40 #define EXYNOS_TRNG_FIFO_2 0x88 41 #define EXYNOS_TRNG_FIFO_3 0x8c 42 #define EXYNOS_TRNG_FIFO_4 0x90 43 #define EXYNOS_TRNG_FIFO_5 0x94 44 #define EXYNOS_TRNG_FIFO_6 0x98 45 #define EXYNOS_TRNG_FIFO_7 0x9c 46 #define EXYNOS_TRNG_FIFO_LEN 8 47 #define EXYNOS_TRNG_CLOCK_RATE 500000 48 49 /* Driver feature flags */ 50 #define EXYNOS_SMC BIT(0) 51 52 #define EXYNOS_SMC_CALL_VAL(func_num) \ 53 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ 54 ARM_SMCCC_SMC_32, \ 55 ARM_SMCCC_OWNER_SIP, \ 56 func_num) 57 58 /* SMC command for DTRNG access */ 59 #define SMC_CMD_RANDOM EXYNOS_SMC_CALL_VAL(0x1012) 60 61 /* SMC_CMD_RANDOM: arguments */ 62 #define HWRNG_INIT 0x0 63 #define HWRNG_EXIT 0x1 64 #define HWRNG_GET_DATA 0x2 65 #define HWRNG_RESUME 0x3 66 67 /* SMC_CMD_RANDOM: return values */ 68 #define HWRNG_RET_OK 0x0 69 #define HWRNG_RET_RETRY_ERROR 0x2 70 71 #define HWRNG_MAX_TRIES 100 72 73 struct exynos_trng_dev { 74 struct device *dev; 75 void __iomem *mem; 76 struct clk *clk; /* operating clock */ 77 struct clk *pclk; /* bus clock */ 78 struct hwrng rng; 79 unsigned long flags; 80 }; 81 82 static int exynos_trng_do_read_reg(struct hwrng *rng, void *data, size_t max, 83 bool wait) 84 { 85 struct exynos_trng_dev *trng = (struct exynos_trng_dev *)rng->priv; 86 int val; 87 88 max = min_t(size_t, max, (EXYNOS_TRNG_FIFO_LEN * 4)); 89 writel_relaxed(max * 8, trng->mem + EXYNOS_TRNG_FIFO_CTRL); 90 val = readl_poll_timeout(trng->mem + EXYNOS_TRNG_FIFO_CTRL, val, 91 val == 0, 200, 1000000); 92 if (val < 0) 93 return val; 94 95 memcpy_fromio(data, trng->mem + EXYNOS_TRNG_FIFO_0, max); 96 97 return max; 98 } 99 100 static int exynos_trng_do_read_smc(struct hwrng *rng, void *data, size_t max, 101 bool wait) 102 { 103 struct arm_smccc_res res; 104 unsigned int copied = 0; 105 u32 *buf = data; 106 int tries = 0; 107 108 while (copied < max) { 109 arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_GET_DATA, 0, 0, 0, 0, 0, 0, 110 &res); 111 switch (res.a0) { 112 case HWRNG_RET_OK: 113 *buf++ = res.a2; 114 *buf++ = res.a3; 115 copied += 8; 116 tries = 0; 117 break; 118 case HWRNG_RET_RETRY_ERROR: 119 if (!wait) 120 return copied; 121 if (++tries >= HWRNG_MAX_TRIES) 122 return copied; 123 cond_resched(); 124 break; 125 default: 126 return -EIO; 127 } 128 } 129 130 return copied; 131 } 132 133 static int exynos_trng_init_reg(struct hwrng *rng) 134 { 135 struct exynos_trng_dev *trng = (struct exynos_trng_dev *)rng->priv; 136 unsigned long sss_rate; 137 u32 val; 138 139 sss_rate = clk_get_rate(trng->clk); 140 141 /* 142 * For most TRNG circuits the clock frequency of under 500 kHz 143 * is safe. 144 */ 145 val = sss_rate / (EXYNOS_TRNG_CLOCK_RATE * 2); 146 if (val > 0x7fff) { 147 dev_err(trng->dev, "clock divider too large: %d\n", val); 148 return -ERANGE; 149 } 150 val = val << 1; 151 writel_relaxed(val, trng->mem + EXYNOS_TRNG_CLKDIV); 152 153 /* Enable the generator. */ 154 val = EXYNOS_TRNG_CTRL_RNGEN; 155 writel_relaxed(val, trng->mem + EXYNOS_TRNG_CTRL); 156 157 /* 158 * Disable post-processing. /dev/hwrng is supposed to deliver 159 * unprocessed data. 160 */ 161 writel_relaxed(0, trng->mem + EXYNOS_TRNG_POST_CTRL); 162 163 return 0; 164 } 165 166 static int exynos_trng_init_smc(struct hwrng *rng) 167 { 168 struct exynos_trng_dev *trng = (struct exynos_trng_dev *)rng->priv; 169 struct arm_smccc_res res; 170 int ret = 0; 171 172 arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_INIT, 0, 0, 0, 0, 0, 0, &res); 173 if (res.a0 != HWRNG_RET_OK) { 174 dev_err(trng->dev, "SMC command for TRNG init failed (%d)\n", 175 (int)res.a0); 176 ret = -EIO; 177 } 178 if ((int)res.a0 == -1) 179 dev_info(trng->dev, "Make sure LDFW is loaded by your BL\n"); 180 181 return ret; 182 } 183 184 static int exynos_trng_probe(struct platform_device *pdev) 185 { 186 struct exynos_trng_dev *trng; 187 int ret = -ENOMEM; 188 189 trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL); 190 if (!trng) 191 return ret; 192 193 platform_set_drvdata(pdev, trng); 194 trng->dev = &pdev->dev; 195 196 trng->flags = (unsigned long)device_get_match_data(&pdev->dev); 197 198 trng->rng.name = devm_kstrdup(&pdev->dev, dev_name(&pdev->dev), 199 GFP_KERNEL); 200 if (!trng->rng.name) 201 return ret; 202 203 trng->rng.priv = (unsigned long)trng; 204 205 if (trng->flags & EXYNOS_SMC) { 206 trng->rng.init = exynos_trng_init_smc; 207 trng->rng.read = exynos_trng_do_read_smc; 208 } else { 209 trng->rng.init = exynos_trng_init_reg; 210 trng->rng.read = exynos_trng_do_read_reg; 211 212 trng->mem = devm_platform_ioremap_resource(pdev, 0); 213 if (IS_ERR(trng->mem)) 214 return PTR_ERR(trng->mem); 215 } 216 217 pm_runtime_enable(&pdev->dev); 218 ret = pm_runtime_resume_and_get(&pdev->dev); 219 if (ret < 0) { 220 dev_err(&pdev->dev, "Could not get runtime PM.\n"); 221 goto err_pm_get; 222 } 223 224 trng->clk = devm_clk_get_enabled(&pdev->dev, "secss"); 225 if (IS_ERR(trng->clk)) { 226 ret = dev_err_probe(&pdev->dev, PTR_ERR(trng->clk), 227 "Could not get clock\n"); 228 goto err_clock; 229 } 230 231 trng->pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk"); 232 if (IS_ERR(trng->pclk)) { 233 ret = dev_err_probe(&pdev->dev, PTR_ERR(trng->pclk), 234 "Could not get pclk\n"); 235 goto err_clock; 236 } 237 238 ret = devm_hwrng_register(&pdev->dev, &trng->rng); 239 if (ret) { 240 dev_err(&pdev->dev, "Could not register hwrng device.\n"); 241 goto err_clock; 242 } 243 244 dev_info(&pdev->dev, "Exynos True Random Number Generator.\n"); 245 246 return 0; 247 248 err_clock: 249 pm_runtime_put_noidle(&pdev->dev); 250 251 err_pm_get: 252 pm_runtime_disable(&pdev->dev); 253 254 return ret; 255 } 256 257 static void exynos_trng_remove(struct platform_device *pdev) 258 { 259 struct exynos_trng_dev *trng = platform_get_drvdata(pdev); 260 261 if (trng->flags & EXYNOS_SMC) { 262 struct arm_smccc_res res; 263 264 arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_EXIT, 0, 0, 0, 0, 0, 0, 265 &res); 266 } 267 268 pm_runtime_put_sync(&pdev->dev); 269 pm_runtime_disable(&pdev->dev); 270 } 271 272 static int exynos_trng_suspend(struct device *dev) 273 { 274 struct exynos_trng_dev *trng = dev_get_drvdata(dev); 275 struct arm_smccc_res res; 276 277 if (trng->flags & EXYNOS_SMC) { 278 arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_EXIT, 0, 0, 0, 0, 0, 0, 279 &res); 280 if (res.a0 != HWRNG_RET_OK) 281 return -EIO; 282 } 283 284 pm_runtime_put_sync(dev); 285 286 return 0; 287 } 288 289 static int exynos_trng_resume(struct device *dev) 290 { 291 struct exynos_trng_dev *trng = dev_get_drvdata(dev); 292 int ret; 293 294 ret = pm_runtime_resume_and_get(dev); 295 if (ret < 0) { 296 dev_err(dev, "Could not get runtime PM.\n"); 297 return ret; 298 } 299 300 if (trng->flags & EXYNOS_SMC) { 301 struct arm_smccc_res res; 302 303 arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_RESUME, 0, 0, 0, 0, 0, 0, 304 &res); 305 if (res.a0 != HWRNG_RET_OK) 306 return -EIO; 307 308 arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_INIT, 0, 0, 0, 0, 0, 0, 309 &res); 310 if (res.a0 != HWRNG_RET_OK) 311 return -EIO; 312 } 313 314 return 0; 315 } 316 317 static DEFINE_SIMPLE_DEV_PM_OPS(exynos_trng_pm_ops, exynos_trng_suspend, 318 exynos_trng_resume); 319 320 static const struct of_device_id exynos_trng_dt_match[] = { 321 { 322 .compatible = "samsung,exynos5250-trng", 323 }, { 324 .compatible = "samsung,exynos850-trng", 325 .data = (void *)EXYNOS_SMC, 326 }, 327 { }, 328 }; 329 MODULE_DEVICE_TABLE(of, exynos_trng_dt_match); 330 331 static struct platform_driver exynos_trng_driver = { 332 .driver = { 333 .name = "exynos-trng", 334 .pm = pm_sleep_ptr(&exynos_trng_pm_ops), 335 .of_match_table = exynos_trng_dt_match, 336 }, 337 .probe = exynos_trng_probe, 338 .remove_new = exynos_trng_remove, 339 }; 340 341 module_platform_driver(exynos_trng_driver); 342 343 MODULE_AUTHOR("Łukasz Stelmach"); 344 MODULE_DESCRIPTION("H/W TRNG driver for Exynos chips"); 345 MODULE_LICENSE("GPL v2"); 346