From: Clement Leger <cleger@xxxxxxxxx> Backport Linux driver to barebox to access nvmem. Signed-off-by: Clement Leger <cleger@xxxxxxxxx> Signed-off-by: Jules Maselbas <jmaselbas@xxxxxxxxx> --- drivers/nvmem/Kconfig | 7 +++ drivers/nvmem/Makefile | 3 ++ drivers/nvmem/kvx-otp-nv.c | 99 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 drivers/nvmem/kvx-otp-nv.c diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index 07320101b8..3624cc64b6 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -66,6 +66,13 @@ config STM32_BSEC This adds support for the STM32 OTP controller. Reads and writes to will go to the shadow RAM, not the OTP fuses themselvers. +config KVX_OTP_NV + tristate "kalray KVX OTP Non volatile regs Support" + depends on KVX + help + This is a simple driver to dump specified values of KVX OTP non + volatile regs. + config STARFIVE_OTP tristate "Starfive OTP Supprot" depends on SOC_STARFIVE diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile index cd970aaea1..81629ddb27 100644 --- a/drivers/nvmem/Makefile +++ b/drivers/nvmem/Makefile @@ -24,4 +24,7 @@ nvmem_eeprom_93xx46-y := eeprom_93xx46.o obj-$(CONFIG_STM32_BSEC) += nvmem_bsec.o nvmem_bsec-y := bsec.o +obj-$(CONFIG_KVX_OTP_NV) += nvmem-kvx-otp-nv.o +nvmem-kvx-otp-nv-y := kvx-otp-nv.o + obj-$(CONFIG_STARFIVE_OTP) += starfive-otp.o diff --git a/drivers/nvmem/kvx-otp-nv.c b/drivers/nvmem/kvx-otp-nv.c new file mode 100644 index 0000000000..f997f8a63b --- /dev/null +++ b/drivers/nvmem/kvx-otp-nv.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Kalray Inc., Clément Léger + */ + +#include <common.h> +#include <driver.h> +#include <malloc.h> +#include <xfuncs.h> +#include <errno.h> +#include <init.h> +#include <net.h> +#include <io.h> + +#include <linux/nvmem-provider.h> + +#define OTP_NV_ALIGN 4 +#define OTP_NV_ALIGN_MASK (OTP_NV_ALIGN - 1) + +struct kvx_otp_nv_priv { + void __iomem *base; +}; + +static int kvx_otp_nv_read(void *context, unsigned int offset, + void *_val, size_t bytes) +{ + struct kvx_otp_nv_priv *priv = context; + u8 *val = _val; + u32 tmp, copy_size; + u8 skip = offset & OTP_NV_ALIGN_MASK; + + offset &= ~OTP_NV_ALIGN_MASK; + + while (bytes) { + tmp = readl(priv->base + offset); + if (skip != 0) + copy_size = min(OTP_NV_ALIGN - skip, (int) bytes); + else + copy_size = min(bytes, sizeof(tmp)); + + memcpy(val, ((u8 *) &tmp) + skip, copy_size); + if (skip != 0) + skip = 0; + + bytes -= copy_size; + val += copy_size; + offset += OTP_NV_ALIGN; + } + + return 0; +} + +static const struct nvmem_bus kvx_otp_nv_bus = { + .read = kvx_otp_nv_read, +}; + +static const struct of_device_id kvx_otp_nv_match[] = { + { .compatible = "kalray,kvx-otp-nv" }, + { /* sentinel */}, +}; + +static int kvx_otp_nv_probe(struct device_d *dev) +{ + struct resource *res; + struct nvmem_device *nvmem; + struct nvmem_config econfig = { 0 }; + struct kvx_otp_nv_priv *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + res = dev_request_mem_resource(dev, 0); + if (IS_ERR(res)) + return PTR_ERR(res); + + priv->base = IOMEM(res->start); + + econfig.name = "kvx-nv-regbank"; + econfig.stride = 1; + econfig.word_size = 1; + econfig.size = resource_size(res); + econfig.dev = dev; + econfig.priv = priv; + econfig.bus = &kvx_otp_nv_bus; + + dev->priv = priv; + + nvmem = nvmem_register(&econfig); + + return PTR_ERR_OR_ZERO(nvmem); +} + +static struct driver_d kvx_otp_nv_driver = { + .name = "kvx-otp-nv", + .probe = kvx_otp_nv_probe, + .of_compatible = DRV_OF_COMPAT(kvx_otp_nv_match), +}; +postcore_platform_driver(kvx_otp_nv_driver); -- 2.17.1 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox