diff options
-rw-r--r-- | Documentation/arm/microchip.rst | 4 | ||||
-rw-r--r-- | drivers/memory/atmel-ebi.c | 11 | ||||
-rw-r--r-- | drivers/soc/atmel/Kconfig | 11 | ||||
-rw-r--r-- | drivers/soc/atmel/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/atmel/sfr.c | 99 | ||||
-rw-r--r-- | include/linux/mfd/syscon/atmel-matrix.h | 1 |
6 files changed, 118 insertions, 9 deletions
diff --git a/Documentation/arm/microchip.rst b/Documentation/arm/microchip.rst index c9a44c98e868..1adf53dfc494 100644 --- a/Documentation/arm/microchip.rst +++ b/Documentation/arm/microchip.rst @@ -103,7 +103,7 @@ the Microchip website: http://www.microchip.com. * Datasheet - http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11121-32-bit-Cortex-A5-Microcontroller-SAMA5D3_Datasheet.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11121-32-bit-Cortex-A5-Microcontroller-SAMA5D3_Datasheet_B.pdf * ARM Cortex-A5 + NEON based SoCs - sama5d4 family @@ -167,7 +167,7 @@ the Microchip website: http://www.microchip.com. * Datasheet - http://ww1.microchip.com/downloads/en/DeviceDoc/60001527A.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/SAM-E70-S70-V70-V71-Family-Data-Sheet-DS60001527D.pdf Linux kernel information diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index 0322df9dc249..14386d0b5f57 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * EBI driver for Atmel chips * inspired by the fsl weim bus driver * * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include <linux/clk.h> @@ -19,6 +16,8 @@ #include <linux/regmap.h> #include <soc/at91/atmel-sfr.h> +#define AT91_EBI_NUM_CS 8 + struct atmel_ebi_dev_config { int cs; struct atmel_smc_cs_conf smcconf; @@ -314,7 +313,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np, if (ret) return ret; - if (cs >= AT91_MATRIX_EBI_NUM_CS || + if (cs >= AT91_EBI_NUM_CS || !(ebi->caps->available_cs & BIT(cs))) { dev_err(dev, "invalid reg property in %pOF\n", np); return -EINVAL; @@ -344,7 +343,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np, apply = true; i = 0; - for_each_set_bit(cs, &cslines, AT91_MATRIX_EBI_NUM_CS) { + for_each_set_bit(cs, &cslines, AT91_EBI_NUM_CS) { ebid->configs[i].cs = cs; if (apply) { diff --git a/drivers/soc/atmel/Kconfig b/drivers/soc/atmel/Kconfig index 05528139b023..50caf6db9c0e 100644 --- a/drivers/soc/atmel/Kconfig +++ b/drivers/soc/atmel/Kconfig @@ -5,3 +5,14 @@ config AT91_SOC_ID default ARCH_AT91 help Include support for the SoC bus on the Atmel ARM SoCs. + +config AT91_SOC_SFR + tristate "Special Function Registers support" + depends on ARCH_AT91 || COMPILE_TEST + help + This is a driver for the Special Function Registers available on + Atmel SAMA5Dx SoCs, providing access to specific aspects of the + integrated memory, bridge implementations, processor etc. + + This driver can also be built as a module. If so, the module + will be called sfr. diff --git a/drivers/soc/atmel/Makefile b/drivers/soc/atmel/Makefile index 7ca355d10553..d849a897cd77 100644 --- a/drivers/soc/atmel/Makefile +++ b/drivers/soc/atmel/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_AT91_SOC_ID) += soc.o +obj-$(CONFIG_AT91_SOC_SFR) += sfr.o diff --git a/drivers/soc/atmel/sfr.c b/drivers/soc/atmel/sfr.c new file mode 100644 index 000000000000..0525eef49d1a --- /dev/null +++ b/drivers/soc/atmel/sfr.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * sfr.c - driver for special function registers + * + * Copyright (C) 2019 Bootlin. + * + */ +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/nvmem-provider.h> +#include <linux/random.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define SFR_SN0 0x4c +#define SFR_SN_SIZE 8 + +struct atmel_sfr_priv { + struct regmap *regmap; +}; + +static int atmel_sfr_read(void *context, unsigned int offset, + void *buf, size_t bytes) +{ + struct atmel_sfr_priv *priv = context; + + return regmap_bulk_read(priv->regmap, SFR_SN0 + offset, + buf, bytes / 4); +} + +static struct nvmem_config atmel_sfr_nvmem_config = { + .name = "atmel-sfr", + .read_only = true, + .word_size = 4, + .stride = 4, + .size = SFR_SN_SIZE, + .reg_read = atmel_sfr_read, +}; + +static int atmel_sfr_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct nvmem_device *nvmem; + struct atmel_sfr_priv *priv; + u8 sn[SFR_SN_SIZE]; + int ret; + + priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->regmap = syscon_node_to_regmap(np); + if (IS_ERR(priv->regmap)) { + dev_err(dev, "cannot get parent's regmap\n"); + return PTR_ERR(priv->regmap); + } + + atmel_sfr_nvmem_config.dev = dev; + atmel_sfr_nvmem_config.priv = priv; + + nvmem = devm_nvmem_register(dev, &atmel_sfr_nvmem_config); + if (IS_ERR(nvmem)) { + dev_err(dev, "error registering nvmem config\n"); + return PTR_ERR(nvmem); + } + + ret = atmel_sfr_read(priv, 0, sn, SFR_SN_SIZE); + if (ret == 0) + add_device_randomness(sn, SFR_SN_SIZE); + + return ret; +} + +static const struct of_device_id atmel_sfr_dt_ids[] = { + { + .compatible = "atmel,sama5d2-sfr", + }, { + .compatible = "atmel,sama5d4-sfr", + }, { + /* sentinel */ + }, +}; +MODULE_DEVICE_TABLE(of, atmel_sfr_dt_ids); + +static struct platform_driver atmel_sfr_driver = { + .probe = atmel_sfr_probe, + .driver = { + .name = "atmel-sfr", + .of_match_table = atmel_sfr_dt_ids, + }, +}; +module_platform_driver(atmel_sfr_driver); + +MODULE_AUTHOR("Kamel Bouhara <kamel.bouhara@bootlin.com>"); +MODULE_DESCRIPTION("Atmel SFR SN driver for SAMA5D2/4 SoC family"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/syscon/atmel-matrix.h b/include/linux/mfd/syscon/atmel-matrix.h index f61cd127a852..20c25665216a 100644 --- a/include/linux/mfd/syscon/atmel-matrix.h +++ b/include/linux/mfd/syscon/atmel-matrix.h @@ -106,7 +106,6 @@ #define AT91_MATRIX_DDR_IOSR BIT(18) #define AT91_MATRIX_NFD0_SELECT BIT(24) #define AT91_MATRIX_DDR_MP_EN BIT(25) -#define AT91_MATRIX_EBI_NUM_CS 8 #define AT91_MATRIX_USBPUCR_PUON BIT(30) |