Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
Hi Dmitry, Looking at the driver based on your comments it is following models of older hwrng drivers. I will work on cleaning up based on your comments as well. On 15-02-25 10:43 AM, Dmitry Torokhov wrote: Hi Scott, On Wed, Feb 25, 2015 at 10:16:24AM -0800, Scott Branden wrote: This adds a driver for random number generator present on Broadcom IPROC devices. Reviewed-by: Ray Jui Signed-off-by: Scott Branden --- drivers/char/hw_random/Kconfig| 13 ++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/iproc-rng200.c | 239 ++ 3 files changed, 253 insertions(+) create mode 100644 drivers/char/hw_random/iproc-rng200.c diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index de57b38..f48cf11 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -101,6 +101,19 @@ config HW_RANDOM_BCM2835 If unsure, say Y. +config HW_RANDOM_IPROC_RNG200 + tristate "Broadcom iProc RNG200 support" + depends on ARCH_BCM_IPROC + default HW_RANDOM + ---help--- + This driver provides kernel-side support for the RNG200 + hardware found on the Broadcom iProc SoCs. + + To compile this driver as a module, choose M here: the + module will be called iproc-rng200 + + If unsure, say Y. + config HW_RANDOM_GEODE tristate "AMD Geode HW Random Number Generator support" depends on X86_32 && PCI diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 0b4cd57..055bb01 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -28,5 +28,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o obj-$(CONFIG_HW_RANDOM_EXYNOS)+= exynos-rng.o obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o +obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o diff --git a/drivers/char/hw_random/iproc-rng200.c b/drivers/char/hw_random/iproc-rng200.c new file mode 100644 index 000..4643aa9 --- /dev/null +++ b/drivers/char/hw_random/iproc-rng200.c @@ -0,0 +1,239 @@ +/* +* Copyright (C) 2014 Broadcom Corporation +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation version 2. +* +* This program is distributed "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ +/* + * DESCRIPTION: The Broadcom iProc RNG200 Driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Registers */ +#define RNG_CTRL_OFFSET0x00 +#define RNG_CTRL_RNG_RBGEN_MASK0x1FFF +#define RNG_CTRL_RNG_RBGEN_ENABLE 0x0001 +#define RNG_CTRL_RNG_RBGEN_DISABLE 0x + +#define RNG_SOFT_RESET_OFFSET 0x04 +#define RNG_SOFT_RESET_RNG_SOFT_RESET_MASK 0x0001 +#define RNG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE 0x0001 +#define RNG_SOFT_RESET_RNG_SOFT_RESET_CLEAR0x + +#define RBG_SOFT_RESET_OFFSET 0x08 +#define RBG_SOFT_RESET_RNG_SOFT_RESET_MASK 0x0001 +#define RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE 0x0001 +#define RBG_SOFT_RESET_RNG_SOFT_RESET_CLEAR0x + +#define RNG_INT_STATUS_OFFSET 0x18 +#define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK0x8000 +#define RNG_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK0x0002 +#define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK 0x0020 +#define RNG_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK 0x0001 + +#define RNG_FIFO_DATA_OFFSET 0x20 + +#define RNG_FIFO_COUNT_OFFSET 0x24 +#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK 0x00FF + +static void iproc_rng200_restart(void __iomem *rng_base) +{ + uint32_t val; + + /* Disable RBG */ + val = ioread32(rng_base + RNG_CTRL_OFFSET); + val &= ~RNG_CTRL_RNG_RBGEN_MASK; + val |= RNG_CTRL_RNG_RBGEN_DISABLE; + iowrite32(val, rng_base + RNG_CTRL_OFFSET); + + /* Clear all interrupt status */ + iowrite32(0xUL, rng_base + RNG_INT_STATUS_OFFSET); + + /* Reset RNG and RBG */ + val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET); + val &= ~RBG_SOFT_RESET_RNG_SOFT_RESET_MASK; + val |= RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE; + iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET); + + val = ioread32(rng_base + RNG_SOFT_RESET_
Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
Hi Arnd, Thanks for the suggested change. On 15-02-28 11:31 AM, Arnd Bergmann wrote: On Saturday 28 February 2015 08:01:11 Scott Branden wrote: The udelay(10) that the other drivers have seems about appropriate then, and we can independently think of a way to refine the interface. Please add a comment that explains the rate. Also, is there some kind of FIFO present in the hwrng device? If it can store close to 1ms work of data (1000 bits), you can just use an msleep(1) to wait for the pool to recover. FIFO is 512 bits. I will look as to whether we can live with 1/2 throughput. In that case, I think usleep_range(min(len * 8, 500), 500)) would be a good compromise: it waits at most until the fifo is full, but might return earlier if enough bits are available to fulfill the request. OK, will change in next version. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
On Saturday 28 February 2015 08:01:11 Scott Branden wrote: > > The udelay(10) that the other drivers have seems about appropriate then, > > and we can independently think of a way to refine the interface. > > Please add a comment that explains the rate. Also, is there some kind > > of FIFO present in the hwrng device? If it can store close to 1ms work > > of data (1000 bits), you can just use an msleep(1) to wait for the > > pool to recover. > FIFO is 512 bits. I will look as to whether we can live with 1/2 > throughput. In that case, I think usleep_range(min(len * 8, 500), 500)) would be a good compromise: it waits at most until the fifo is full, but might return earlier if enough bits are available to fulfill the request. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
On 15-02-27 01:14 AM, Arnd Bergmann wrote: On Thursday 26 February 2015 14:26:02 Scott Branden wrote: On 15-02-26 12:15 PM, Arnd Bergmann wrote: On 15-02-25 11:17 AM, Arnd Bergmann wrote: On Wednesday 25 February 2015 10:16:24 Scott Branden wrote: This code was following examples of other open source drivers - bcm2835 and exynos both use cpu_relax. I'll have to look into this more to understand. The majority of the driver apparently use udelay(10) to wait, which is not much better but at least consistent. The cpu_relax() call probably gives better throughput. I don't understand why none of the drivers actually attempts to msleep(), but that may be because the delay is much too long. Can you find out what the expected latency is for new data to become available on your hardware? RNG generates at a nominal 1 Mbps. So to generate 32 bits of data takes approximately 32 us. The udelay(10) that the other drivers have seems about appropriate then, and we can independently think of a way to refine the interface. Please add a comment that explains the rate. Also, is there some kind of FIFO present in the hwrng device? If it can store close to 1ms work of data (1000 bits), you can just use an msleep(1) to wait for the pool to recover. FIFO is 512 bits. I will look as to whether we can live with 1/2 throughput. Another option would be to use usleep_range() with the exact amount of time to wait for, the lower bound being the minimum number of bytes asked for and the fifo size, the upper bound being the fifo size. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
On Thursday 26 February 2015 14:26:02 Scott Branden wrote: > On 15-02-26 12:15 PM, Arnd Bergmann wrote: > >> On 15-02-25 11:17 AM, Arnd Bergmann wrote: > >>> On Wednesday 25 February 2015 10:16:24 Scott Branden wrote: > >> This code was following examples of other open source drivers - bcm2835 > >> and exynos both use cpu_relax. I'll have to look into this more to > >> understand. > >> > > > > The majority of the driver apparently use udelay(10) to wait, which is > > not much better but at least consistent. The cpu_relax() call probably > > gives better throughput. > > > > I don't understand why none of the drivers actually attempts to > > msleep(), but that may be because the delay is much too long. > > > > Can you find out what the expected latency is for new data to > > become available on your hardware? > RNG generates at a nominal 1 Mbps. So to generate 32 bits of data takes > approximately 32 us. The udelay(10) that the other drivers have seems about appropriate then, and we can independently think of a way to refine the interface. Please add a comment that explains the rate. Also, is there some kind of FIFO present in the hwrng device? If it can store close to 1ms work of data (1000 bits), you can just use an msleep(1) to wait for the pool to recover. Another option would be to use usleep_range() with the exact amount of time to wait for, the lower bound being the minimum number of bytes asked for and the fifo size, the upper bound being the fifo size. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
Hi Arnd, Latency is 32 us for 32bits of data - commented inline. What delay call do you recommend in this case? On 15-02-26 12:15 PM, Arnd Bergmann wrote: On Thursday 26 February 2015 11:37:20 Scott Branden wrote: Response inline. On 15-02-25 11:17 AM, Arnd Bergmann wrote: On Wednesday 25 February 2015 10:16:24 Scott Branden wrote: This adds a driver for random number generator present on Broadcom IPROC devices. Reviewed-by: Ray Jui Signed-off-by: Scott Branden The driver looks reasonable overall, I have just one question about something that sticks out: +while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { ... + +/* Are there any random numbers available? */ +if ((ioread32(rng_base + RNG_FIFO_COUNT_OFFSET) & +RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) { ... +} else { +if (!wait) +/* Cannot wait, return immediately */ +return max - num_remaining; + +/* Can wait, give others chance to run */ +cpu_relax(); +} +} + It looks like you do a busy-loop around cpu_relax here if asked to wait. Is this intentional? I would normally expect either cond_resched() or some msleep() instead. This code was following examples of other open source drivers - bcm2835 and exynos both use cpu_relax. I'll have to look into this more to understand. The majority of the driver apparently use udelay(10) to wait, which is not much better but at least consistent. The cpu_relax() call probably gives better throughput. I don't understand why none of the drivers actually attempts to msleep(), but that may be because the delay is much too long. Can you find out what the expected latency is for new data to become available on your hardware? RNG generates at a nominal 1 Mbps. So to generate 32 bits of data takes approximately 32 us. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
On Thursday 26 February 2015 11:37:20 Scott Branden wrote: > Response inline. > > On 15-02-25 11:17 AM, Arnd Bergmann wrote: > > On Wednesday 25 February 2015 10:16:24 Scott Branden wrote: > >> This adds a driver for random number generator present on Broadcom > >> IPROC devices. > >> > >> Reviewed-by: Ray Jui > >> Signed-off-by: Scott Branden > > > > The driver looks reasonable overall, I have just one question about > > something that sticks out: > > > >> +while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { > > ... > >> + > >> +/* Are there any random numbers available? */ > >> +if ((ioread32(rng_base + RNG_FIFO_COUNT_OFFSET) & > >> +RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) { > > ... > >> +} else { > >> +if (!wait) > >> +/* Cannot wait, return immediately */ > >> +return max - num_remaining; > >> + > >> +/* Can wait, give others chance to run */ > >> +cpu_relax(); > >> +} > >> +} > >> + > > > > It looks like you do a busy-loop around cpu_relax here if asked to wait. > > Is this intentional? I would normally expect either cond_resched() or > > some msleep() instead. > > This code was following examples of other open source drivers - bcm2835 > and exynos both use cpu_relax. I'll have to look into this more to > understand. > The majority of the driver apparently use udelay(10) to wait, which is not much better but at least consistent. The cpu_relax() call probably gives better throughput. I don't understand why none of the drivers actually attempts to msleep(), but that may be because the delay is much too long. Can you find out what the expected latency is for new data to become available on your hardware? Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
Response inline. On 15-02-25 11:17 AM, Arnd Bergmann wrote: On Wednesday 25 February 2015 10:16:24 Scott Branden wrote: This adds a driver for random number generator present on Broadcom IPROC devices. Reviewed-by: Ray Jui Signed-off-by: Scott Branden The driver looks reasonable overall, I have just one question about something that sticks out: + while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { ... + + /* Are there any random numbers available? */ + if ((ioread32(rng_base + RNG_FIFO_COUNT_OFFSET) & + RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) { ... + } else { + if (!wait) + /* Cannot wait, return immediately */ + return max - num_remaining; + + /* Can wait, give others chance to run */ + cpu_relax(); + } + } + It looks like you do a busy-loop around cpu_relax here if asked to wait. Is this intentional? I would normally expect either cond_resched() or some msleep() instead. This code was following examples of other open source drivers - bcm2835 and exynos both use cpu_relax. I'll have to look into this more to understand. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
On Wednesday 25 February 2015 10:16:24 Scott Branden wrote: > This adds a driver for random number generator present on Broadcom > IPROC devices. > > Reviewed-by: Ray Jui > Signed-off-by: Scott Branden The driver looks reasonable overall, I have just one question about something that sticks out: > + while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { ... > + > + /* Are there any random numbers available? */ > + if ((ioread32(rng_base + RNG_FIFO_COUNT_OFFSET) & > + RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) { ... > + } else { > + if (!wait) > + /* Cannot wait, return immediately */ > + return max - num_remaining; > + > + /* Can wait, give others chance to run */ > + cpu_relax(); > + } > + } > + It looks like you do a busy-loop around cpu_relax here if asked to wait. Is this intentional? I would normally expect either cond_resched() or some msleep() instead. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
Hi Scott, On Wed, Feb 25, 2015 at 10:16:24AM -0800, Scott Branden wrote: > This adds a driver for random number generator present on Broadcom > IPROC devices. > > Reviewed-by: Ray Jui > Signed-off-by: Scott Branden > --- > drivers/char/hw_random/Kconfig| 13 ++ > drivers/char/hw_random/Makefile | 1 + > drivers/char/hw_random/iproc-rng200.c | 239 > ++ > 3 files changed, 253 insertions(+) > create mode 100644 drivers/char/hw_random/iproc-rng200.c > > diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig > index de57b38..f48cf11 100644 > --- a/drivers/char/hw_random/Kconfig > +++ b/drivers/char/hw_random/Kconfig > @@ -101,6 +101,19 @@ config HW_RANDOM_BCM2835 > > If unsure, say Y. > > +config HW_RANDOM_IPROC_RNG200 > + tristate "Broadcom iProc RNG200 support" > + depends on ARCH_BCM_IPROC > + default HW_RANDOM > + ---help--- > + This driver provides kernel-side support for the RNG200 > + hardware found on the Broadcom iProc SoCs. > + > + To compile this driver as a module, choose M here: the > + module will be called iproc-rng200 > + > + If unsure, say Y. > + > config HW_RANDOM_GEODE > tristate "AMD Geode HW Random Number Generator support" > depends on X86_32 && PCI > diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile > index 0b4cd57..055bb01 100644 > --- a/drivers/char/hw_random/Makefile > +++ b/drivers/char/hw_random/Makefile > @@ -28,5 +28,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o > obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o > obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o > obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o > +obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o > obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o > obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o > diff --git a/drivers/char/hw_random/iproc-rng200.c > b/drivers/char/hw_random/iproc-rng200.c > new file mode 100644 > index 000..4643aa9 > --- /dev/null > +++ b/drivers/char/hw_random/iproc-rng200.c > @@ -0,0 +1,239 @@ > +/* > +* Copyright (C) 2014 Broadcom Corporation > +* > +* This program is free software; you can redistribute it and/or > +* modify it under the terms of the GNU General Public License as > +* published by the Free Software Foundation version 2. > +* > +* This program is distributed "as is" WITHOUT ANY WARRANTY of any > +* kind, whether express or implied; without even the implied warranty > +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +* GNU General Public License for more details. > +*/ > +/* > + * DESCRIPTION: The Broadcom iProc RNG200 Driver > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > + > +/* Registers */ > +#define RNG_CTRL_OFFSET 0x00 > +#define RNG_CTRL_RNG_RBGEN_MASK 0x1FFF > +#define RNG_CTRL_RNG_RBGEN_ENABLE0x0001 > +#define RNG_CTRL_RNG_RBGEN_DISABLE 0x > + > +#define RNG_SOFT_RESET_OFFSET0x04 > +#define RNG_SOFT_RESET_RNG_SOFT_RESET_MASK 0x0001 > +#define RNG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE 0x0001 > +#define RNG_SOFT_RESET_RNG_SOFT_RESET_CLEAR 0x > + > +#define RBG_SOFT_RESET_OFFSET0x08 > +#define RBG_SOFT_RESET_RNG_SOFT_RESET_MASK 0x0001 > +#define RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE 0x0001 > +#define RBG_SOFT_RESET_RNG_SOFT_RESET_CLEAR 0x > + > +#define RNG_INT_STATUS_OFFSET0x18 > +#define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK 0x8000 > +#define RNG_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK 0x0002 > +#define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK0x0020 > +#define RNG_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK 0x0001 > + > +#define RNG_FIFO_DATA_OFFSET 0x20 > + > +#define RNG_FIFO_COUNT_OFFSET0x24 > +#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK 0x00FF > + > +static void iproc_rng200_restart(void __iomem *rng_base) > +{ > + uint32_t val; > + > + /* Disable RBG */ > + val = ioread32(rng_base + RNG_CTRL_OFFSET); > + val &= ~RNG_CTRL_RNG_RBGEN_MASK; > + val |= RNG_CTRL_RNG_RBGEN_DISABLE; > + iowrite32(val, rng_base + RNG_CTRL_OFFSET); > + > + /* Clear all interrupt status */ > + iowrite32(0xUL, rng_base + RNG_INT_STATUS_OFFSET); > + > + /* Reset RNG and RBG */ > + val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET); > + val &= ~RBG_SOFT_RESET_RNG_SOFT_RESET_MASK; > + val |= RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE; > + iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET); > + > + val = ioread32(rng_base + RNG_SOFT_RESET_OFFSET); > + val &= ~RN
[PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver
This adds a driver for random number generator present on Broadcom IPROC devices. Reviewed-by: Ray Jui Signed-off-by: Scott Branden --- drivers/char/hw_random/Kconfig| 13 ++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/iproc-rng200.c | 239 ++ 3 files changed, 253 insertions(+) create mode 100644 drivers/char/hw_random/iproc-rng200.c diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index de57b38..f48cf11 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -101,6 +101,19 @@ config HW_RANDOM_BCM2835 If unsure, say Y. +config HW_RANDOM_IPROC_RNG200 + tristate "Broadcom iProc RNG200 support" + depends on ARCH_BCM_IPROC + default HW_RANDOM + ---help--- + This driver provides kernel-side support for the RNG200 + hardware found on the Broadcom iProc SoCs. + + To compile this driver as a module, choose M here: the + module will be called iproc-rng200 + + If unsure, say Y. + config HW_RANDOM_GEODE tristate "AMD Geode HW Random Number Generator support" depends on X86_32 && PCI diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 0b4cd57..055bb01 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -28,5 +28,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o +obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o diff --git a/drivers/char/hw_random/iproc-rng200.c b/drivers/char/hw_random/iproc-rng200.c new file mode 100644 index 000..4643aa9 --- /dev/null +++ b/drivers/char/hw_random/iproc-rng200.c @@ -0,0 +1,239 @@ +/* +* Copyright (C) 2014 Broadcom Corporation +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation version 2. +* +* This program is distributed "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ +/* + * DESCRIPTION: The Broadcom iProc RNG200 Driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Registers */ +#define RNG_CTRL_OFFSET0x00 +#define RNG_CTRL_RNG_RBGEN_MASK0x1FFF +#define RNG_CTRL_RNG_RBGEN_ENABLE 0x0001 +#define RNG_CTRL_RNG_RBGEN_DISABLE 0x + +#define RNG_SOFT_RESET_OFFSET 0x04 +#define RNG_SOFT_RESET_RNG_SOFT_RESET_MASK 0x0001 +#define RNG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE 0x0001 +#define RNG_SOFT_RESET_RNG_SOFT_RESET_CLEAR0x + +#define RBG_SOFT_RESET_OFFSET 0x08 +#define RBG_SOFT_RESET_RNG_SOFT_RESET_MASK 0x0001 +#define RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE 0x0001 +#define RBG_SOFT_RESET_RNG_SOFT_RESET_CLEAR0x + +#define RNG_INT_STATUS_OFFSET 0x18 +#define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK0x8000 +#define RNG_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK0x0002 +#define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK 0x0020 +#define RNG_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK 0x0001 + +#define RNG_FIFO_DATA_OFFSET 0x20 + +#define RNG_FIFO_COUNT_OFFSET 0x24 +#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK 0x00FF + +static void iproc_rng200_restart(void __iomem *rng_base) +{ + uint32_t val; + + /* Disable RBG */ + val = ioread32(rng_base + RNG_CTRL_OFFSET); + val &= ~RNG_CTRL_RNG_RBGEN_MASK; + val |= RNG_CTRL_RNG_RBGEN_DISABLE; + iowrite32(val, rng_base + RNG_CTRL_OFFSET); + + /* Clear all interrupt status */ + iowrite32(0xUL, rng_base + RNG_INT_STATUS_OFFSET); + + /* Reset RNG and RBG */ + val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET); + val &= ~RBG_SOFT_RESET_RNG_SOFT_RESET_MASK; + val |= RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE; + iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET); + + val = ioread32(rng_base + RNG_SOFT_RESET_OFFSET); + val &= ~RNG_SOFT_RESET_RNG_SOFT_RESET_MASK; + val |= RNG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE; + iowrite32(val, rng_base + RNG_SOFT_RESET_OFFSET); + + val = ioread32(rng_base + RNG_SOFT_RESET_OFFSET); + val &= ~RNG_SOFT_RESET_RNG_SOFT_RESET_MASK; + val |= RNG_SOF