cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

omap-rng.c (14492B)


      1/*
      2 * omap-rng.c - RNG driver for TI OMAP CPU family
      3 *
      4 * Author: Deepak Saxena <dsaxena@plexity.net>
      5 *
      6 * Copyright 2005 (c) MontaVista Software, Inc.
      7 *
      8 * Mostly based on original driver:
      9 *
     10 * Copyright (C) 2005 Nokia Corporation
     11 * Author: Juha Yrjölä <juha.yrjola@nokia.com>
     12 *
     13 * This file is licensed under  the terms of the GNU General Public
     14 * License version 2. This program is licensed "as is" without any
     15 * warranty of any kind, whether express or implied.
     16 */
     17
     18#include <linux/module.h>
     19#include <linux/init.h>
     20#include <linux/random.h>
     21#include <linux/err.h>
     22#include <linux/platform_device.h>
     23#include <linux/hw_random.h>
     24#include <linux/delay.h>
     25#include <linux/kernel.h>
     26#include <linux/slab.h>
     27#include <linux/pm_runtime.h>
     28#include <linux/of.h>
     29#include <linux/of_device.h>
     30#include <linux/of_address.h>
     31#include <linux/interrupt.h>
     32#include <linux/clk.h>
     33#include <linux/io.h>
     34
     35#define RNG_REG_STATUS_RDY			(1 << 0)
     36
     37#define RNG_REG_INTACK_RDY_MASK			(1 << 0)
     38#define RNG_REG_INTACK_SHUTDOWN_OFLO_MASK	(1 << 1)
     39#define RNG_SHUTDOWN_OFLO_MASK			(1 << 1)
     40
     41#define RNG_CONTROL_STARTUP_CYCLES_SHIFT	16
     42#define RNG_CONTROL_STARTUP_CYCLES_MASK		(0xffff << 16)
     43#define RNG_CONTROL_ENABLE_TRNG_SHIFT		10
     44#define RNG_CONTROL_ENABLE_TRNG_MASK		(1 << 10)
     45
     46#define RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT	16
     47#define RNG_CONFIG_MAX_REFIL_CYCLES_MASK	(0xffff << 16)
     48#define RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT	0
     49#define RNG_CONFIG_MIN_REFIL_CYCLES_MASK	(0xff << 0)
     50
     51#define RNG_CONTROL_STARTUP_CYCLES		0xff
     52#define RNG_CONFIG_MIN_REFIL_CYCLES		0x21
     53#define RNG_CONFIG_MAX_REFIL_CYCLES		0x22
     54
     55#define RNG_ALARMCNT_ALARM_TH_SHIFT		0x0
     56#define RNG_ALARMCNT_ALARM_TH_MASK		(0xff << 0)
     57#define RNG_ALARMCNT_SHUTDOWN_TH_SHIFT		16
     58#define RNG_ALARMCNT_SHUTDOWN_TH_MASK		(0x1f << 16)
     59#define RNG_ALARM_THRESHOLD			0xff
     60#define RNG_SHUTDOWN_THRESHOLD			0x4
     61
     62#define RNG_REG_FROENABLE_MASK			0xffffff
     63#define RNG_REG_FRODETUNE_MASK			0xffffff
     64
     65#define OMAP2_RNG_OUTPUT_SIZE			0x4
     66#define OMAP4_RNG_OUTPUT_SIZE			0x8
     67#define EIP76_RNG_OUTPUT_SIZE			0x10
     68
     69/*
     70 * EIP76 RNG takes approx. 700us to produce 16 bytes of output data
     71 * as per testing results. And to account for the lack of udelay()'s
     72 * reliability, we keep the timeout as 1000us.
     73 */
     74#define RNG_DATA_FILL_TIMEOUT			100
     75
     76enum {
     77	RNG_OUTPUT_0_REG = 0,
     78	RNG_OUTPUT_1_REG,
     79	RNG_OUTPUT_2_REG,
     80	RNG_OUTPUT_3_REG,
     81	RNG_STATUS_REG,
     82	RNG_INTMASK_REG,
     83	RNG_INTACK_REG,
     84	RNG_CONTROL_REG,
     85	RNG_CONFIG_REG,
     86	RNG_ALARMCNT_REG,
     87	RNG_FROENABLE_REG,
     88	RNG_FRODETUNE_REG,
     89	RNG_ALARMMASK_REG,
     90	RNG_ALARMSTOP_REG,
     91	RNG_REV_REG,
     92	RNG_SYSCONFIG_REG,
     93};
     94
     95static const u16 reg_map_omap2[] = {
     96	[RNG_OUTPUT_0_REG]	= 0x0,
     97	[RNG_STATUS_REG]	= 0x4,
     98	[RNG_CONFIG_REG]	= 0x28,
     99	[RNG_REV_REG]		= 0x3c,
    100	[RNG_SYSCONFIG_REG]	= 0x40,
    101};
    102
    103static const u16 reg_map_omap4[] = {
    104	[RNG_OUTPUT_0_REG]	= 0x0,
    105	[RNG_OUTPUT_1_REG]	= 0x4,
    106	[RNG_STATUS_REG]	= 0x8,
    107	[RNG_INTMASK_REG]	= 0xc,
    108	[RNG_INTACK_REG]	= 0x10,
    109	[RNG_CONTROL_REG]	= 0x14,
    110	[RNG_CONFIG_REG]	= 0x18,
    111	[RNG_ALARMCNT_REG]	= 0x1c,
    112	[RNG_FROENABLE_REG]	= 0x20,
    113	[RNG_FRODETUNE_REG]	= 0x24,
    114	[RNG_ALARMMASK_REG]	= 0x28,
    115	[RNG_ALARMSTOP_REG]	= 0x2c,
    116	[RNG_REV_REG]		= 0x1FE0,
    117	[RNG_SYSCONFIG_REG]	= 0x1FE4,
    118};
    119
    120static const u16 reg_map_eip76[] = {
    121	[RNG_OUTPUT_0_REG]	= 0x0,
    122	[RNG_OUTPUT_1_REG]	= 0x4,
    123	[RNG_OUTPUT_2_REG]	= 0x8,
    124	[RNG_OUTPUT_3_REG]	= 0xc,
    125	[RNG_STATUS_REG]	= 0x10,
    126	[RNG_INTACK_REG]	= 0x10,
    127	[RNG_CONTROL_REG]	= 0x14,
    128	[RNG_CONFIG_REG]	= 0x18,
    129	[RNG_ALARMCNT_REG]	= 0x1c,
    130	[RNG_FROENABLE_REG]	= 0x20,
    131	[RNG_FRODETUNE_REG]	= 0x24,
    132	[RNG_ALARMMASK_REG]	= 0x28,
    133	[RNG_ALARMSTOP_REG]	= 0x2c,
    134	[RNG_REV_REG]		= 0x7c,
    135};
    136
    137struct omap_rng_dev;
    138/**
    139 * struct omap_rng_pdata - RNG IP block-specific data
    140 * @regs: Pointer to the register offsets structure.
    141 * @data_size: No. of bytes in RNG output.
    142 * @data_present: Callback to determine if data is available.
    143 * @init: Callback for IP specific initialization sequence.
    144 * @cleanup: Callback for IP specific cleanup sequence.
    145 */
    146struct omap_rng_pdata {
    147	u16	*regs;
    148	u32	data_size;
    149	u32	(*data_present)(struct omap_rng_dev *priv);
    150	int	(*init)(struct omap_rng_dev *priv);
    151	void	(*cleanup)(struct omap_rng_dev *priv);
    152};
    153
    154struct omap_rng_dev {
    155	void __iomem			*base;
    156	struct device			*dev;
    157	const struct omap_rng_pdata	*pdata;
    158	struct hwrng rng;
    159	struct clk 			*clk;
    160	struct clk			*clk_reg;
    161};
    162
    163static inline u32 omap_rng_read(struct omap_rng_dev *priv, u16 reg)
    164{
    165	return __raw_readl(priv->base + priv->pdata->regs[reg]);
    166}
    167
    168static inline void omap_rng_write(struct omap_rng_dev *priv, u16 reg,
    169				      u32 val)
    170{
    171	__raw_writel(val, priv->base + priv->pdata->regs[reg]);
    172}
    173
    174
    175static int omap_rng_do_read(struct hwrng *rng, void *data, size_t max,
    176			    bool wait)
    177{
    178	struct omap_rng_dev *priv;
    179	int i, present;
    180
    181	priv = (struct omap_rng_dev *)rng->priv;
    182
    183	if (max < priv->pdata->data_size)
    184		return 0;
    185
    186	for (i = 0; i < RNG_DATA_FILL_TIMEOUT; i++) {
    187		present = priv->pdata->data_present(priv);
    188		if (present || !wait)
    189			break;
    190
    191		udelay(10);
    192	}
    193	if (!present)
    194		return 0;
    195
    196	memcpy_fromio(data, priv->base + priv->pdata->regs[RNG_OUTPUT_0_REG],
    197		      priv->pdata->data_size);
    198
    199	if (priv->pdata->regs[RNG_INTACK_REG])
    200		omap_rng_write(priv, RNG_INTACK_REG, RNG_REG_INTACK_RDY_MASK);
    201
    202	return priv->pdata->data_size;
    203}
    204
    205static int omap_rng_init(struct hwrng *rng)
    206{
    207	struct omap_rng_dev *priv;
    208
    209	priv = (struct omap_rng_dev *)rng->priv;
    210	return priv->pdata->init(priv);
    211}
    212
    213static void omap_rng_cleanup(struct hwrng *rng)
    214{
    215	struct omap_rng_dev *priv;
    216
    217	priv = (struct omap_rng_dev *)rng->priv;
    218	priv->pdata->cleanup(priv);
    219}
    220
    221
    222static inline u32 omap2_rng_data_present(struct omap_rng_dev *priv)
    223{
    224	return omap_rng_read(priv, RNG_STATUS_REG) ? 0 : 1;
    225}
    226
    227static int omap2_rng_init(struct omap_rng_dev *priv)
    228{
    229	omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x1);
    230	return 0;
    231}
    232
    233static void omap2_rng_cleanup(struct omap_rng_dev *priv)
    234{
    235	omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x0);
    236}
    237
    238static struct omap_rng_pdata omap2_rng_pdata = {
    239	.regs		= (u16 *)reg_map_omap2,
    240	.data_size	= OMAP2_RNG_OUTPUT_SIZE,
    241	.data_present	= omap2_rng_data_present,
    242	.init		= omap2_rng_init,
    243	.cleanup	= omap2_rng_cleanup,
    244};
    245
    246static inline u32 omap4_rng_data_present(struct omap_rng_dev *priv)
    247{
    248	return omap_rng_read(priv, RNG_STATUS_REG) & RNG_REG_STATUS_RDY;
    249}
    250
    251static int eip76_rng_init(struct omap_rng_dev *priv)
    252{
    253	u32 val;
    254
    255	/* Return if RNG is already running. */
    256	if (omap_rng_read(priv, RNG_CONTROL_REG) & RNG_CONTROL_ENABLE_TRNG_MASK)
    257		return 0;
    258
    259	/*  Number of 512 bit blocks of raw Noise Source output data that must
    260	 *  be processed by either the Conditioning Function or the
    261	 *  SP 800-90 DRBG ‘BC_DF’ functionality to yield a ‘full entropy’
    262	 *  output value.
    263	 */
    264	val = 0x5 << RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT;
    265
    266	/* Number of FRO samples that are XOR-ed together into one bit to be
    267	 * shifted into the main shift register
    268	 */
    269	val |= RNG_CONFIG_MAX_REFIL_CYCLES << RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT;
    270	omap_rng_write(priv, RNG_CONFIG_REG, val);
    271
    272	/* Enable all available FROs */
    273	omap_rng_write(priv, RNG_FRODETUNE_REG, 0x0);
    274	omap_rng_write(priv, RNG_FROENABLE_REG, RNG_REG_FROENABLE_MASK);
    275
    276	/* Enable TRNG */
    277	val = RNG_CONTROL_ENABLE_TRNG_MASK;
    278	omap_rng_write(priv, RNG_CONTROL_REG, val);
    279
    280	return 0;
    281}
    282
    283static int omap4_rng_init(struct omap_rng_dev *priv)
    284{
    285	u32 val;
    286
    287	/* Return if RNG is already running. */
    288	if (omap_rng_read(priv, RNG_CONTROL_REG) & RNG_CONTROL_ENABLE_TRNG_MASK)
    289		return 0;
    290
    291	val = RNG_CONFIG_MIN_REFIL_CYCLES << RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT;
    292	val |= RNG_CONFIG_MAX_REFIL_CYCLES << RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT;
    293	omap_rng_write(priv, RNG_CONFIG_REG, val);
    294
    295	omap_rng_write(priv, RNG_FRODETUNE_REG, 0x0);
    296	omap_rng_write(priv, RNG_FROENABLE_REG, RNG_REG_FROENABLE_MASK);
    297	val = RNG_ALARM_THRESHOLD << RNG_ALARMCNT_ALARM_TH_SHIFT;
    298	val |= RNG_SHUTDOWN_THRESHOLD << RNG_ALARMCNT_SHUTDOWN_TH_SHIFT;
    299	omap_rng_write(priv, RNG_ALARMCNT_REG, val);
    300
    301	val = RNG_CONTROL_STARTUP_CYCLES << RNG_CONTROL_STARTUP_CYCLES_SHIFT;
    302	val |= RNG_CONTROL_ENABLE_TRNG_MASK;
    303	omap_rng_write(priv, RNG_CONTROL_REG, val);
    304
    305	return 0;
    306}
    307
    308static void omap4_rng_cleanup(struct omap_rng_dev *priv)
    309{
    310	int val;
    311
    312	val = omap_rng_read(priv, RNG_CONTROL_REG);
    313	val &= ~RNG_CONTROL_ENABLE_TRNG_MASK;
    314	omap_rng_write(priv, RNG_CONTROL_REG, val);
    315}
    316
    317static irqreturn_t omap4_rng_irq(int irq, void *dev_id)
    318{
    319	struct omap_rng_dev *priv = dev_id;
    320	u32 fro_detune, fro_enable;
    321
    322	/*
    323	 * Interrupt raised by a fro shutdown threshold, do the following:
    324	 * 1. Clear the alarm events.
    325	 * 2. De tune the FROs which are shutdown.
    326	 * 3. Re enable the shutdown FROs.
    327	 */
    328	omap_rng_write(priv, RNG_ALARMMASK_REG, 0x0);
    329	omap_rng_write(priv, RNG_ALARMSTOP_REG, 0x0);
    330
    331	fro_enable = omap_rng_read(priv, RNG_FROENABLE_REG);
    332	fro_detune = ~fro_enable & RNG_REG_FRODETUNE_MASK;
    333	fro_detune = fro_detune | omap_rng_read(priv, RNG_FRODETUNE_REG);
    334	fro_enable = RNG_REG_FROENABLE_MASK;
    335
    336	omap_rng_write(priv, RNG_FRODETUNE_REG, fro_detune);
    337	omap_rng_write(priv, RNG_FROENABLE_REG, fro_enable);
    338
    339	omap_rng_write(priv, RNG_INTACK_REG, RNG_REG_INTACK_SHUTDOWN_OFLO_MASK);
    340
    341	return IRQ_HANDLED;
    342}
    343
    344static struct omap_rng_pdata omap4_rng_pdata = {
    345	.regs		= (u16 *)reg_map_omap4,
    346	.data_size	= OMAP4_RNG_OUTPUT_SIZE,
    347	.data_present	= omap4_rng_data_present,
    348	.init		= omap4_rng_init,
    349	.cleanup	= omap4_rng_cleanup,
    350};
    351
    352static struct omap_rng_pdata eip76_rng_pdata = {
    353	.regs		= (u16 *)reg_map_eip76,
    354	.data_size	= EIP76_RNG_OUTPUT_SIZE,
    355	.data_present	= omap4_rng_data_present,
    356	.init		= eip76_rng_init,
    357	.cleanup	= omap4_rng_cleanup,
    358};
    359
    360static const struct of_device_id omap_rng_of_match[] __maybe_unused = {
    361		{
    362			.compatible	= "ti,omap2-rng",
    363			.data		= &omap2_rng_pdata,
    364		},
    365		{
    366			.compatible	= "ti,omap4-rng",
    367			.data		= &omap4_rng_pdata,
    368		},
    369		{
    370			.compatible	= "inside-secure,safexcel-eip76",
    371			.data		= &eip76_rng_pdata,
    372		},
    373		{},
    374};
    375MODULE_DEVICE_TABLE(of, omap_rng_of_match);
    376
    377static int of_get_omap_rng_device_details(struct omap_rng_dev *priv,
    378					  struct platform_device *pdev)
    379{
    380	struct device *dev = &pdev->dev;
    381	int irq, err;
    382
    383	priv->pdata = of_device_get_match_data(dev);
    384	if (!priv->pdata)
    385		return -ENODEV;
    386
    387
    388	if (of_device_is_compatible(dev->of_node, "ti,omap4-rng") ||
    389	    of_device_is_compatible(dev->of_node, "inside-secure,safexcel-eip76")) {
    390		irq = platform_get_irq(pdev, 0);
    391		if (irq < 0)
    392			return irq;
    393
    394		err = devm_request_irq(dev, irq, omap4_rng_irq,
    395				       IRQF_TRIGGER_NONE, dev_name(dev), priv);
    396		if (err) {
    397			dev_err(dev, "unable to request irq %d, err = %d\n",
    398				irq, err);
    399			return err;
    400		}
    401
    402		/*
    403		 * On OMAP4, enabling the shutdown_oflo interrupt is
    404		 * done in the interrupt mask register. There is no
    405		 * such register on EIP76, and it's enabled by the
    406		 * same bit in the control register
    407		 */
    408		if (priv->pdata->regs[RNG_INTMASK_REG])
    409			omap_rng_write(priv, RNG_INTMASK_REG,
    410				       RNG_SHUTDOWN_OFLO_MASK);
    411		else
    412			omap_rng_write(priv, RNG_CONTROL_REG,
    413				       RNG_SHUTDOWN_OFLO_MASK);
    414	}
    415	return 0;
    416}
    417
    418static int get_omap_rng_device_details(struct omap_rng_dev *omap_rng)
    419{
    420	/* Only OMAP2/3 can be non-DT */
    421	omap_rng->pdata = &omap2_rng_pdata;
    422	return 0;
    423}
    424
    425static int omap_rng_probe(struct platform_device *pdev)
    426{
    427	struct omap_rng_dev *priv;
    428	struct device *dev = &pdev->dev;
    429	int ret;
    430
    431	priv = devm_kzalloc(dev, sizeof(struct omap_rng_dev), GFP_KERNEL);
    432	if (!priv)
    433		return -ENOMEM;
    434
    435	priv->rng.read = omap_rng_do_read;
    436	priv->rng.init = omap_rng_init;
    437	priv->rng.cleanup = omap_rng_cleanup;
    438	priv->rng.quality = 900;
    439
    440	priv->rng.priv = (unsigned long)priv;
    441	platform_set_drvdata(pdev, priv);
    442	priv->dev = dev;
    443
    444	priv->base = devm_platform_ioremap_resource(pdev, 0);
    445	if (IS_ERR(priv->base)) {
    446		ret = PTR_ERR(priv->base);
    447		goto err_ioremap;
    448	}
    449
    450	priv->rng.name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
    451	if (!priv->rng.name) {
    452		ret = -ENOMEM;
    453		goto err_ioremap;
    454	}
    455
    456	pm_runtime_enable(&pdev->dev);
    457	ret = pm_runtime_resume_and_get(&pdev->dev);
    458	if (ret < 0) {
    459		dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret);
    460		goto err_ioremap;
    461	}
    462
    463	priv->clk = devm_clk_get(&pdev->dev, NULL);
    464	if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
    465		return -EPROBE_DEFER;
    466	if (!IS_ERR(priv->clk)) {
    467		ret = clk_prepare_enable(priv->clk);
    468		if (ret) {
    469			dev_err(&pdev->dev,
    470				"Unable to enable the clk: %d\n", ret);
    471			goto err_register;
    472		}
    473	}
    474
    475	priv->clk_reg = devm_clk_get(&pdev->dev, "reg");
    476	if (PTR_ERR(priv->clk_reg) == -EPROBE_DEFER)
    477		return -EPROBE_DEFER;
    478	if (!IS_ERR(priv->clk_reg)) {
    479		ret = clk_prepare_enable(priv->clk_reg);
    480		if (ret) {
    481			dev_err(&pdev->dev,
    482				"Unable to enable the register clk: %d\n",
    483				ret);
    484			goto err_register;
    485		}
    486	}
    487
    488	ret = (dev->of_node) ? of_get_omap_rng_device_details(priv, pdev) :
    489				get_omap_rng_device_details(priv);
    490	if (ret)
    491		goto err_register;
    492
    493	ret = devm_hwrng_register(&pdev->dev, &priv->rng);
    494	if (ret)
    495		goto err_register;
    496
    497	dev_info(&pdev->dev, "Random Number Generator ver. %02x\n",
    498		 omap_rng_read(priv, RNG_REV_REG));
    499
    500	return 0;
    501
    502err_register:
    503	priv->base = NULL;
    504	pm_runtime_put_sync(&pdev->dev);
    505	pm_runtime_disable(&pdev->dev);
    506
    507	clk_disable_unprepare(priv->clk_reg);
    508	clk_disable_unprepare(priv->clk);
    509err_ioremap:
    510	dev_err(dev, "initialization failed.\n");
    511	return ret;
    512}
    513
    514static int omap_rng_remove(struct platform_device *pdev)
    515{
    516	struct omap_rng_dev *priv = platform_get_drvdata(pdev);
    517
    518
    519	priv->pdata->cleanup(priv);
    520
    521	pm_runtime_put_sync(&pdev->dev);
    522	pm_runtime_disable(&pdev->dev);
    523
    524	clk_disable_unprepare(priv->clk);
    525	clk_disable_unprepare(priv->clk_reg);
    526
    527	return 0;
    528}
    529
    530static int __maybe_unused omap_rng_suspend(struct device *dev)
    531{
    532	struct omap_rng_dev *priv = dev_get_drvdata(dev);
    533
    534	priv->pdata->cleanup(priv);
    535	pm_runtime_put_sync(dev);
    536
    537	return 0;
    538}
    539
    540static int __maybe_unused omap_rng_resume(struct device *dev)
    541{
    542	struct omap_rng_dev *priv = dev_get_drvdata(dev);
    543	int ret;
    544
    545	ret = pm_runtime_resume_and_get(dev);
    546	if (ret < 0) {
    547		dev_err(dev, "Failed to runtime_get device: %d\n", ret);
    548		return ret;
    549	}
    550
    551	priv->pdata->init(priv);
    552
    553	return 0;
    554}
    555
    556static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume);
    557
    558static struct platform_driver omap_rng_driver = {
    559	.driver = {
    560		.name		= "omap_rng",
    561		.pm		= &omap_rng_pm,
    562		.of_match_table = of_match_ptr(omap_rng_of_match),
    563	},
    564	.probe		= omap_rng_probe,
    565	.remove		= omap_rng_remove,
    566};
    567
    568module_platform_driver(omap_rng_driver);
    569MODULE_ALIAS("platform:omap_rng");
    570MODULE_AUTHOR("Deepak Saxena (and others)");
    571MODULE_LICENSE("GPL");