Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * omap-rng.c - RNG driver for TI OMAP CPU family
0003  *
0004  * Author: Deepak Saxena <dsaxena@plexity.net>
0005  *
0006  * Copyright 2005 (c) MontaVista Software, Inc.
0007  *
0008  * Mostly based on original driver:
0009  *
0010  * Copyright (C) 2005 Nokia Corporation
0011  * Author: Juha Yrjölä <juha.yrjola@nokia.com>
0012  *
0013  * This file is licensed under  the terms of the GNU General Public
0014  * License version 2. This program is licensed "as is" without any
0015  * warranty of any kind, whether express or implied.
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  * EIP76 RNG takes approx. 700us to produce 16 bytes of output data
0071  * as per testing results. And to account for the lack of udelay()'s
0072  * reliability, we keep the timeout as 1000us.
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  * struct omap_rng_pdata - RNG IP block-specific data
0140  * @regs: Pointer to the register offsets structure.
0141  * @data_size: No. of bytes in RNG output.
0142  * @data_present: Callback to determine if data is available.
0143  * @init: Callback for IP specific initialization sequence.
0144  * @cleanup: Callback for IP specific cleanup sequence.
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     /* Return if RNG is already running. */
0256     if (omap_rng_read(priv, RNG_CONTROL_REG) & RNG_CONTROL_ENABLE_TRNG_MASK)
0257         return 0;
0258 
0259     /*  Number of 512 bit blocks of raw Noise Source output data that must
0260      *  be processed by either the Conditioning Function or the
0261      *  SP 800-90 DRBG ‘BC_DF’ functionality to yield a ‘full entropy’
0262      *  output value.
0263      */
0264     val = 0x5 << RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT;
0265 
0266     /* Number of FRO samples that are XOR-ed together into one bit to be
0267      * shifted into the main shift register
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     /* Enable all available FROs */
0273     omap_rng_write(priv, RNG_FRODETUNE_REG, 0x0);
0274     omap_rng_write(priv, RNG_FROENABLE_REG, RNG_REG_FROENABLE_MASK);
0275 
0276     /* Enable TRNG */
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     /* Return if RNG is already running. */
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      * Interrupt raised by a fro shutdown threshold, do the following:
0324      * 1. Clear the alarm events.
0325      * 2. De tune the FROs which are shutdown.
0326      * 3. Re enable the shutdown FROs.
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          * On OMAP4, enabling the shutdown_oflo interrupt is
0404          * done in the interrupt mask register. There is no
0405          * such register on EIP76, and it's enabled by the
0406          * same bit in the control register
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     /* Only OMAP2/3 can be non-DT */
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");