0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/module.h>
0019 #include <linux/init.h>
0020 #include <linux/random.h>
0021 #include <linux/err.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/hw_random.h>
0024 #include <linux/delay.h>
0025 #include <linux/kernel.h>
0026 #include <linux/slab.h>
0027 #include <linux/pm_runtime.h>
0028 #include <linux/of.h>
0029 #include <linux/of_device.h>
0030 #include <linux/of_address.h>
0031 #include <linux/interrupt.h>
0032 #include <linux/clk.h>
0033 #include <linux/io.h>
0034
0035 #define RNG_REG_STATUS_RDY (1 << 0)
0036
0037 #define RNG_REG_INTACK_RDY_MASK (1 << 0)
0038 #define RNG_REG_INTACK_SHUTDOWN_OFLO_MASK (1 << 1)
0039 #define RNG_SHUTDOWN_OFLO_MASK (1 << 1)
0040
0041 #define RNG_CONTROL_STARTUP_CYCLES_SHIFT 16
0042 #define RNG_CONTROL_STARTUP_CYCLES_MASK (0xffff << 16)
0043 #define RNG_CONTROL_ENABLE_TRNG_SHIFT 10
0044 #define RNG_CONTROL_ENABLE_TRNG_MASK (1 << 10)
0045
0046 #define RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT 16
0047 #define RNG_CONFIG_MAX_REFIL_CYCLES_MASK (0xffff << 16)
0048 #define RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT 0
0049 #define RNG_CONFIG_MIN_REFIL_CYCLES_MASK (0xff << 0)
0050
0051 #define RNG_CONTROL_STARTUP_CYCLES 0xff
0052 #define RNG_CONFIG_MIN_REFIL_CYCLES 0x21
0053 #define RNG_CONFIG_MAX_REFIL_CYCLES 0x22
0054
0055 #define RNG_ALARMCNT_ALARM_TH_SHIFT 0x0
0056 #define RNG_ALARMCNT_ALARM_TH_MASK (0xff << 0)
0057 #define RNG_ALARMCNT_SHUTDOWN_TH_SHIFT 16
0058 #define RNG_ALARMCNT_SHUTDOWN_TH_MASK (0x1f << 16)
0059 #define RNG_ALARM_THRESHOLD 0xff
0060 #define RNG_SHUTDOWN_THRESHOLD 0x4
0061
0062 #define RNG_REG_FROENABLE_MASK 0xffffff
0063 #define RNG_REG_FRODETUNE_MASK 0xffffff
0064
0065 #define OMAP2_RNG_OUTPUT_SIZE 0x4
0066 #define OMAP4_RNG_OUTPUT_SIZE 0x8
0067 #define EIP76_RNG_OUTPUT_SIZE 0x10
0068
0069
0070
0071
0072
0073
0074 #define RNG_DATA_FILL_TIMEOUT 100
0075
0076 enum {
0077 RNG_OUTPUT_0_REG = 0,
0078 RNG_OUTPUT_1_REG,
0079 RNG_OUTPUT_2_REG,
0080 RNG_OUTPUT_3_REG,
0081 RNG_STATUS_REG,
0082 RNG_INTMASK_REG,
0083 RNG_INTACK_REG,
0084 RNG_CONTROL_REG,
0085 RNG_CONFIG_REG,
0086 RNG_ALARMCNT_REG,
0087 RNG_FROENABLE_REG,
0088 RNG_FRODETUNE_REG,
0089 RNG_ALARMMASK_REG,
0090 RNG_ALARMSTOP_REG,
0091 RNG_REV_REG,
0092 RNG_SYSCONFIG_REG,
0093 };
0094
0095 static const u16 reg_map_omap2[] = {
0096 [RNG_OUTPUT_0_REG] = 0x0,
0097 [RNG_STATUS_REG] = 0x4,
0098 [RNG_CONFIG_REG] = 0x28,
0099 [RNG_REV_REG] = 0x3c,
0100 [RNG_SYSCONFIG_REG] = 0x40,
0101 };
0102
0103 static const u16 reg_map_omap4[] = {
0104 [RNG_OUTPUT_0_REG] = 0x0,
0105 [RNG_OUTPUT_1_REG] = 0x4,
0106 [RNG_STATUS_REG] = 0x8,
0107 [RNG_INTMASK_REG] = 0xc,
0108 [RNG_INTACK_REG] = 0x10,
0109 [RNG_CONTROL_REG] = 0x14,
0110 [RNG_CONFIG_REG] = 0x18,
0111 [RNG_ALARMCNT_REG] = 0x1c,
0112 [RNG_FROENABLE_REG] = 0x20,
0113 [RNG_FRODETUNE_REG] = 0x24,
0114 [RNG_ALARMMASK_REG] = 0x28,
0115 [RNG_ALARMSTOP_REG] = 0x2c,
0116 [RNG_REV_REG] = 0x1FE0,
0117 [RNG_SYSCONFIG_REG] = 0x1FE4,
0118 };
0119
0120 static const u16 reg_map_eip76[] = {
0121 [RNG_OUTPUT_0_REG] = 0x0,
0122 [RNG_OUTPUT_1_REG] = 0x4,
0123 [RNG_OUTPUT_2_REG] = 0x8,
0124 [RNG_OUTPUT_3_REG] = 0xc,
0125 [RNG_STATUS_REG] = 0x10,
0126 [RNG_INTACK_REG] = 0x10,
0127 [RNG_CONTROL_REG] = 0x14,
0128 [RNG_CONFIG_REG] = 0x18,
0129 [RNG_ALARMCNT_REG] = 0x1c,
0130 [RNG_FROENABLE_REG] = 0x20,
0131 [RNG_FRODETUNE_REG] = 0x24,
0132 [RNG_ALARMMASK_REG] = 0x28,
0133 [RNG_ALARMSTOP_REG] = 0x2c,
0134 [RNG_REV_REG] = 0x7c,
0135 };
0136
0137 struct omap_rng_dev;
0138
0139
0140
0141
0142
0143
0144
0145
0146 struct omap_rng_pdata {
0147 u16 *regs;
0148 u32 data_size;
0149 u32 (*data_present)(struct omap_rng_dev *priv);
0150 int (*init)(struct omap_rng_dev *priv);
0151 void (*cleanup)(struct omap_rng_dev *priv);
0152 };
0153
0154 struct omap_rng_dev {
0155 void __iomem *base;
0156 struct device *dev;
0157 const struct omap_rng_pdata *pdata;
0158 struct hwrng rng;
0159 struct clk *clk;
0160 struct clk *clk_reg;
0161 };
0162
0163 static inline u32 omap_rng_read(struct omap_rng_dev *priv, u16 reg)
0164 {
0165 return __raw_readl(priv->base + priv->pdata->regs[reg]);
0166 }
0167
0168 static inline void omap_rng_write(struct omap_rng_dev *priv, u16 reg,
0169 u32 val)
0170 {
0171 __raw_writel(val, priv->base + priv->pdata->regs[reg]);
0172 }
0173
0174
0175 static int omap_rng_do_read(struct hwrng *rng, void *data, size_t max,
0176 bool wait)
0177 {
0178 struct omap_rng_dev *priv;
0179 int i, present;
0180
0181 priv = (struct omap_rng_dev *)rng->priv;
0182
0183 if (max < priv->pdata->data_size)
0184 return 0;
0185
0186 for (i = 0; i < RNG_DATA_FILL_TIMEOUT; i++) {
0187 present = priv->pdata->data_present(priv);
0188 if (present || !wait)
0189 break;
0190
0191 udelay(10);
0192 }
0193 if (!present)
0194 return 0;
0195
0196 memcpy_fromio(data, priv->base + priv->pdata->regs[RNG_OUTPUT_0_REG],
0197 priv->pdata->data_size);
0198
0199 if (priv->pdata->regs[RNG_INTACK_REG])
0200 omap_rng_write(priv, RNG_INTACK_REG, RNG_REG_INTACK_RDY_MASK);
0201
0202 return priv->pdata->data_size;
0203 }
0204
0205 static int omap_rng_init(struct hwrng *rng)
0206 {
0207 struct omap_rng_dev *priv;
0208
0209 priv = (struct omap_rng_dev *)rng->priv;
0210 return priv->pdata->init(priv);
0211 }
0212
0213 static void omap_rng_cleanup(struct hwrng *rng)
0214 {
0215 struct omap_rng_dev *priv;
0216
0217 priv = (struct omap_rng_dev *)rng->priv;
0218 priv->pdata->cleanup(priv);
0219 }
0220
0221
0222 static inline u32 omap2_rng_data_present(struct omap_rng_dev *priv)
0223 {
0224 return omap_rng_read(priv, RNG_STATUS_REG) ? 0 : 1;
0225 }
0226
0227 static int omap2_rng_init(struct omap_rng_dev *priv)
0228 {
0229 omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x1);
0230 return 0;
0231 }
0232
0233 static void omap2_rng_cleanup(struct omap_rng_dev *priv)
0234 {
0235 omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x0);
0236 }
0237
0238 static struct omap_rng_pdata omap2_rng_pdata = {
0239 .regs = (u16 *)reg_map_omap2,
0240 .data_size = OMAP2_RNG_OUTPUT_SIZE,
0241 .data_present = omap2_rng_data_present,
0242 .init = omap2_rng_init,
0243 .cleanup = omap2_rng_cleanup,
0244 };
0245
0246 static inline u32 omap4_rng_data_present(struct omap_rng_dev *priv)
0247 {
0248 return omap_rng_read(priv, RNG_STATUS_REG) & RNG_REG_STATUS_RDY;
0249 }
0250
0251 static int eip76_rng_init(struct omap_rng_dev *priv)
0252 {
0253 u32 val;
0254
0255
0256 if (omap_rng_read(priv, RNG_CONTROL_REG) & RNG_CONTROL_ENABLE_TRNG_MASK)
0257 return 0;
0258
0259
0260
0261
0262
0263
0264 val = 0x5 << RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT;
0265
0266
0267
0268
0269 val |= RNG_CONFIG_MAX_REFIL_CYCLES << RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT;
0270 omap_rng_write(priv, RNG_CONFIG_REG, val);
0271
0272
0273 omap_rng_write(priv, RNG_FRODETUNE_REG, 0x0);
0274 omap_rng_write(priv, RNG_FROENABLE_REG, RNG_REG_FROENABLE_MASK);
0275
0276
0277 val = RNG_CONTROL_ENABLE_TRNG_MASK;
0278 omap_rng_write(priv, RNG_CONTROL_REG, val);
0279
0280 return 0;
0281 }
0282
0283 static int omap4_rng_init(struct omap_rng_dev *priv)
0284 {
0285 u32 val;
0286
0287
0288 if (omap_rng_read(priv, RNG_CONTROL_REG) & RNG_CONTROL_ENABLE_TRNG_MASK)
0289 return 0;
0290
0291 val = RNG_CONFIG_MIN_REFIL_CYCLES << RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT;
0292 val |= RNG_CONFIG_MAX_REFIL_CYCLES << RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT;
0293 omap_rng_write(priv, RNG_CONFIG_REG, val);
0294
0295 omap_rng_write(priv, RNG_FRODETUNE_REG, 0x0);
0296 omap_rng_write(priv, RNG_FROENABLE_REG, RNG_REG_FROENABLE_MASK);
0297 val = RNG_ALARM_THRESHOLD << RNG_ALARMCNT_ALARM_TH_SHIFT;
0298 val |= RNG_SHUTDOWN_THRESHOLD << RNG_ALARMCNT_SHUTDOWN_TH_SHIFT;
0299 omap_rng_write(priv, RNG_ALARMCNT_REG, val);
0300
0301 val = RNG_CONTROL_STARTUP_CYCLES << RNG_CONTROL_STARTUP_CYCLES_SHIFT;
0302 val |= RNG_CONTROL_ENABLE_TRNG_MASK;
0303 omap_rng_write(priv, RNG_CONTROL_REG, val);
0304
0305 return 0;
0306 }
0307
0308 static void omap4_rng_cleanup(struct omap_rng_dev *priv)
0309 {
0310 int val;
0311
0312 val = omap_rng_read(priv, RNG_CONTROL_REG);
0313 val &= ~RNG_CONTROL_ENABLE_TRNG_MASK;
0314 omap_rng_write(priv, RNG_CONTROL_REG, val);
0315 }
0316
0317 static irqreturn_t omap4_rng_irq(int irq, void *dev_id)
0318 {
0319 struct omap_rng_dev *priv = dev_id;
0320 u32 fro_detune, fro_enable;
0321
0322
0323
0324
0325
0326
0327
0328 omap_rng_write(priv, RNG_ALARMMASK_REG, 0x0);
0329 omap_rng_write(priv, RNG_ALARMSTOP_REG, 0x0);
0330
0331 fro_enable = omap_rng_read(priv, RNG_FROENABLE_REG);
0332 fro_detune = ~fro_enable & RNG_REG_FRODETUNE_MASK;
0333 fro_detune = fro_detune | omap_rng_read(priv, RNG_FRODETUNE_REG);
0334 fro_enable = RNG_REG_FROENABLE_MASK;
0335
0336 omap_rng_write(priv, RNG_FRODETUNE_REG, fro_detune);
0337 omap_rng_write(priv, RNG_FROENABLE_REG, fro_enable);
0338
0339 omap_rng_write(priv, RNG_INTACK_REG, RNG_REG_INTACK_SHUTDOWN_OFLO_MASK);
0340
0341 return IRQ_HANDLED;
0342 }
0343
0344 static struct omap_rng_pdata omap4_rng_pdata = {
0345 .regs = (u16 *)reg_map_omap4,
0346 .data_size = OMAP4_RNG_OUTPUT_SIZE,
0347 .data_present = omap4_rng_data_present,
0348 .init = omap4_rng_init,
0349 .cleanup = omap4_rng_cleanup,
0350 };
0351
0352 static struct omap_rng_pdata eip76_rng_pdata = {
0353 .regs = (u16 *)reg_map_eip76,
0354 .data_size = EIP76_RNG_OUTPUT_SIZE,
0355 .data_present = omap4_rng_data_present,
0356 .init = eip76_rng_init,
0357 .cleanup = omap4_rng_cleanup,
0358 };
0359
0360 static const struct of_device_id omap_rng_of_match[] __maybe_unused = {
0361 {
0362 .compatible = "ti,omap2-rng",
0363 .data = &omap2_rng_pdata,
0364 },
0365 {
0366 .compatible = "ti,omap4-rng",
0367 .data = &omap4_rng_pdata,
0368 },
0369 {
0370 .compatible = "inside-secure,safexcel-eip76",
0371 .data = &eip76_rng_pdata,
0372 },
0373 {},
0374 };
0375 MODULE_DEVICE_TABLE(of, omap_rng_of_match);
0376
0377 static int of_get_omap_rng_device_details(struct omap_rng_dev *priv,
0378 struct platform_device *pdev)
0379 {
0380 struct device *dev = &pdev->dev;
0381 int irq, err;
0382
0383 priv->pdata = of_device_get_match_data(dev);
0384 if (!priv->pdata)
0385 return -ENODEV;
0386
0387
0388 if (of_device_is_compatible(dev->of_node, "ti,omap4-rng") ||
0389 of_device_is_compatible(dev->of_node, "inside-secure,safexcel-eip76")) {
0390 irq = platform_get_irq(pdev, 0);
0391 if (irq < 0)
0392 return irq;
0393
0394 err = devm_request_irq(dev, irq, omap4_rng_irq,
0395 IRQF_TRIGGER_NONE, dev_name(dev), priv);
0396 if (err) {
0397 dev_err(dev, "unable to request irq %d, err = %d\n",
0398 irq, err);
0399 return err;
0400 }
0401
0402
0403
0404
0405
0406
0407
0408 if (priv->pdata->regs[RNG_INTMASK_REG])
0409 omap_rng_write(priv, RNG_INTMASK_REG,
0410 RNG_SHUTDOWN_OFLO_MASK);
0411 else
0412 omap_rng_write(priv, RNG_CONTROL_REG,
0413 RNG_SHUTDOWN_OFLO_MASK);
0414 }
0415 return 0;
0416 }
0417
0418 static int get_omap_rng_device_details(struct omap_rng_dev *omap_rng)
0419 {
0420
0421 omap_rng->pdata = &omap2_rng_pdata;
0422 return 0;
0423 }
0424
0425 static int omap_rng_probe(struct platform_device *pdev)
0426 {
0427 struct omap_rng_dev *priv;
0428 struct device *dev = &pdev->dev;
0429 int ret;
0430
0431 priv = devm_kzalloc(dev, sizeof(struct omap_rng_dev), GFP_KERNEL);
0432 if (!priv)
0433 return -ENOMEM;
0434
0435 priv->rng.read = omap_rng_do_read;
0436 priv->rng.init = omap_rng_init;
0437 priv->rng.cleanup = omap_rng_cleanup;
0438 priv->rng.quality = 900;
0439
0440 priv->rng.priv = (unsigned long)priv;
0441 platform_set_drvdata(pdev, priv);
0442 priv->dev = dev;
0443
0444 priv->base = devm_platform_ioremap_resource(pdev, 0);
0445 if (IS_ERR(priv->base)) {
0446 ret = PTR_ERR(priv->base);
0447 goto err_ioremap;
0448 }
0449
0450 priv->rng.name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
0451 if (!priv->rng.name) {
0452 ret = -ENOMEM;
0453 goto err_ioremap;
0454 }
0455
0456 pm_runtime_enable(&pdev->dev);
0457 ret = pm_runtime_resume_and_get(&pdev->dev);
0458 if (ret < 0) {
0459 dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret);
0460 goto err_ioremap;
0461 }
0462
0463 priv->clk = devm_clk_get(&pdev->dev, NULL);
0464 if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
0465 return -EPROBE_DEFER;
0466 if (!IS_ERR(priv->clk)) {
0467 ret = clk_prepare_enable(priv->clk);
0468 if (ret) {
0469 dev_err(&pdev->dev,
0470 "Unable to enable the clk: %d\n", ret);
0471 goto err_register;
0472 }
0473 }
0474
0475 priv->clk_reg = devm_clk_get(&pdev->dev, "reg");
0476 if (PTR_ERR(priv->clk_reg) == -EPROBE_DEFER)
0477 return -EPROBE_DEFER;
0478 if (!IS_ERR(priv->clk_reg)) {
0479 ret = clk_prepare_enable(priv->clk_reg);
0480 if (ret) {
0481 dev_err(&pdev->dev,
0482 "Unable to enable the register clk: %d\n",
0483 ret);
0484 goto err_register;
0485 }
0486 }
0487
0488 ret = (dev->of_node) ? of_get_omap_rng_device_details(priv, pdev) :
0489 get_omap_rng_device_details(priv);
0490 if (ret)
0491 goto err_register;
0492
0493 ret = devm_hwrng_register(&pdev->dev, &priv->rng);
0494 if (ret)
0495 goto err_register;
0496
0497 dev_info(&pdev->dev, "Random Number Generator ver. %02x\n",
0498 omap_rng_read(priv, RNG_REV_REG));
0499
0500 return 0;
0501
0502 err_register:
0503 priv->base = NULL;
0504 pm_runtime_put_sync(&pdev->dev);
0505 pm_runtime_disable(&pdev->dev);
0506
0507 clk_disable_unprepare(priv->clk_reg);
0508 clk_disable_unprepare(priv->clk);
0509 err_ioremap:
0510 dev_err(dev, "initialization failed.\n");
0511 return ret;
0512 }
0513
0514 static int omap_rng_remove(struct platform_device *pdev)
0515 {
0516 struct omap_rng_dev *priv = platform_get_drvdata(pdev);
0517
0518
0519 priv->pdata->cleanup(priv);
0520
0521 pm_runtime_put_sync(&pdev->dev);
0522 pm_runtime_disable(&pdev->dev);
0523
0524 clk_disable_unprepare(priv->clk);
0525 clk_disable_unprepare(priv->clk_reg);
0526
0527 return 0;
0528 }
0529
0530 static int __maybe_unused omap_rng_suspend(struct device *dev)
0531 {
0532 struct omap_rng_dev *priv = dev_get_drvdata(dev);
0533
0534 priv->pdata->cleanup(priv);
0535 pm_runtime_put_sync(dev);
0536
0537 return 0;
0538 }
0539
0540 static int __maybe_unused omap_rng_resume(struct device *dev)
0541 {
0542 struct omap_rng_dev *priv = dev_get_drvdata(dev);
0543 int ret;
0544
0545 ret = pm_runtime_resume_and_get(dev);
0546 if (ret < 0) {
0547 dev_err(dev, "Failed to runtime_get device: %d\n", ret);
0548 return ret;
0549 }
0550
0551 priv->pdata->init(priv);
0552
0553 return 0;
0554 }
0555
0556 static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume);
0557
0558 static struct platform_driver omap_rng_driver = {
0559 .driver = {
0560 .name = "omap_rng",
0561 .pm = &omap_rng_pm,
0562 .of_match_table = of_match_ptr(omap_rng_of_match),
0563 },
0564 .probe = omap_rng_probe,
0565 .remove = omap_rng_remove,
0566 };
0567
0568 module_platform_driver(omap_rng_driver);
0569 MODULE_ALIAS("platform:omap_rng");
0570 MODULE_AUTHOR("Deepak Saxena (and others)");
0571 MODULE_LICENSE("GPL");