[PATCH 0/5] mtd: pxa3xx_nand: add support for Armada 8k

This series adds NAND flash support to Aramda 8k systems. Patches make the necessary changes to the pxa3xx_nand driver and DT files.
v3: Address Stefan's comments on patch #3
Move hunks from patch #3 to #5 to fix bisectability
v2: Rebase on current master. Fixes conflict with commit 661c98121d4 ("mtd: nand: pxa3xx: Fix not calling dev_xxx with a device")
Baruch Siach (2): arm: dts: armada-cp110-master: update nand-controller mtd: pxa3xx_nand: remove dead code
Shmuel Hazan (3): arm: dts: armada-cp110-slave: add missing cps_nand mtd: pxa3xx_nand: port to use driver model mtd: nand: pxa3xx: enable NAND controller if the SoC needs it
arch/arm/dts/armada-cp110-master.dtsi | 15 ++- arch/arm/dts/armada-cp110-slave.dtsi | 16 +++ drivers/mtd/nand/raw/Kconfig | 2 + drivers/mtd/nand/raw/pxa3xx_nand.c | 180 ++++++++++++++------------ 4 files changed, 125 insertions(+), 88 deletions(-)

From: Shmuel Hazan shmuel.h@siklu.com
Align node properties to kernel dts node.
Keep U-Boot specific nand-enable-arbiter, and num-cs for compatibility with the current driver.
Reviewed-by: Stefan Roese sr@denx.de Signed-off-by: Shmuel Hazan shmuel.h@siklu.com Signed-off-by: Baruch Siach baruch@tkos.co.il --- arch/arm/dts/armada-cp110-slave.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/arch/arm/dts/armada-cp110-slave.dtsi b/arch/arm/dts/armada-cp110-slave.dtsi index b426a4eb6910..6cf217783709 100644 --- a/arch/arm/dts/armada-cp110-slave.dtsi +++ b/arch/arm/dts/armada-cp110-slave.dtsi @@ -267,6 +267,22 @@ utmi-port = <UTMI_PHY_TO_USB3_HOST0>; status = "disabled"; }; + + cps_nand: nand@720000 { + compatible = "marvell,armada-8k-nand-controller", + "marvell,armada370-nand-controller"; + reg = <0x720000 0x54>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "core", "reg"; + clocks = <&cps_syscon0 1 2>, + <&cps_syscon0 1 17>; + marvell,system-controller = <&cps_syscon0>; + nand-enable-arbiter; + num-cs = <1>; + status = "disabled"; + }; };
cps_pcie0: pcie@f4600000 {

Align node properties to kernel dts node.
The change of compatible property does not affect any currently supported board.
Keep U-Boot specific nand-enable-arbiter, and num-cs for compatibility with the current driver.
Reviewed-by: Stefan Roese sr@denx.de Signed-off-by: Baruch Siach baruch@tkos.co.il --- arch/arm/dts/armada-cp110-master.dtsi | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/arm/dts/armada-cp110-master.dtsi b/arch/arm/dts/armada-cp110-master.dtsi index cd5c974482e6..7d0d31da306d 100644 --- a/arch/arm/dts/armada-cp110-master.dtsi +++ b/arch/arm/dts/armada-cp110-master.dtsi @@ -285,15 +285,18 @@ };
cpm_nand: nand@720000 { - compatible = "marvell,mvebu-pxa3xx-nand"; - reg = <0x720000 0x100>; + compatible = "marvell,armada-8k-nand-controller", + "marvell,armada370-nand-controller"; + reg = <0x720000 0x54>; #address-cells = <1>; - - clocks = <&cpm_syscon0 1 2>; + #size-cells = <0>; + interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "core", "reg"; + clocks = <&cpm_syscon0 1 2>, + <&cpm_syscon0 1 17>; + marvell,system-controller = <&cpm_syscon0>; nand-enable-arbiter; num-cs = <1>; - nand-ecc-strength = <4>; - nand-ecc-step-size = <512>; status = "disabled"; };

From: Shmuel Hazan shmuel.h@siklu.com
Use the generic DT code to find the device compatible property for us. This makes the driver look more like other current drivers. It also make it easier to add support for other variants like Armada 8K in a future commit.
Signed-off-by: Shmuel Hazan shmuel.h@siklu.com Signed-off-by: Baruch Siach baruch@tkos.co.il --- drivers/mtd/nand/raw/Kconfig | 1 + drivers/mtd/nand/raw/pxa3xx_nand.c | 116 +++++++++++++---------------- 2 files changed, 54 insertions(+), 63 deletions(-)
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index cd7e598aa8a7..160b599b3464 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -195,6 +195,7 @@ endif config NAND_PXA3XX bool "Support for NAND on PXA3xx and Armada 370/XP/38x" select SYS_NAND_SELF_INIT + select DM_MTD imply CMD_NAND help This enables the driver for the NAND flash device found on diff --git a/drivers/mtd/nand/raw/pxa3xx_nand.c b/drivers/mtd/nand/raw/pxa3xx_nand.c index 5fb3081c8390..c9b7a4251b4e 100644 --- a/drivers/mtd/nand/raw/pxa3xx_nand.c +++ b/drivers/mtd/nand/raw/pxa3xx_nand.c @@ -22,6 +22,8 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/rawnand.h> #include <linux/types.h> +#include <dm/uclass.h> +#include <dm/read.h>
#include "pxa3xx_nand.h"
@@ -417,6 +419,14 @@ static struct nand_ecclayout ecc_layout_8KB_bch8bit = { /* convert nano-seconds to nand flash controller clock cycles */ #define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000)
+static const struct udevice_id pxa3xx_nand_dt_ids[] = { + { + .compatible = "marvell,mvebu-pxa3xx-nand", + .data = PXA3XX_NAND_VARIANT_ARMADA370, + }, + {} +}; + static enum pxa3xx_nand_variant pxa3xx_nand_get_variant(void) { /* We only support the Armada 370/XP/38x for now */ @@ -1809,74 +1819,52 @@ fail_disable_clk: return ret; }
-static int pxa3xx_nand_probe_dt(struct pxa3xx_nand_info *info) +static int pxa3xx_nand_probe_dt(struct udevice *dev, struct pxa3xx_nand_info *info) { struct pxa3xx_nand_platform_data *pdata; - const void *blob = gd->fdt_blob; - int node = -1;
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM;
- /* Get address decoding nodes from the FDT blob */ - do { - node = fdt_node_offset_by_compatible(blob, node, - "marvell,mvebu-pxa3xx-nand"); - if (node < 0) - break; - - /* Bypass disabeld nodes */ - if (!fdtdec_get_is_enabled(blob, node)) - continue; - - /* Get the first enabled NAND controler base address */ - info->mmio_base = - (void __iomem *)fdtdec_get_addr_size_auto_noparent( - blob, node, "reg", 0, NULL, true); + info->mmio_base = dev_read_addr_ptr(dev);
- pdata->num_cs = fdtdec_get_int(blob, node, "num-cs", 1); - if (pdata->num_cs != 1) { - pr_err("pxa3xx driver supports single CS only\n"); - break; - } - - if (fdtdec_get_bool(blob, node, "nand-enable-arbiter")) - pdata->enable_arbiter = 1; - - if (fdtdec_get_bool(blob, node, "nand-keep-config")) - pdata->keep_config = 1; + pdata->num_cs = dev_read_u32_default(dev, "num-cs", 1); + if (pdata->num_cs != 1) { + pr_err("pxa3xx driver supports single CS only\n"); + return -EINVAL; + }
- /* - * ECC parameters. - * If these are not set, they will be selected according - * to the detected flash type. - */ - /* ECC strength */ - pdata->ecc_strength = fdtdec_get_int(blob, node, - "nand-ecc-strength", 0); + if (dev_read_bool(dev, "nand-enable-arbiter")) + pdata->enable_arbiter = 1;
- /* ECC step size */ - pdata->ecc_step_size = fdtdec_get_int(blob, node, - "nand-ecc-step-size", 0); + if (dev_read_bool(dev, "nand-keep-config")) + pdata->keep_config = 1;
- info->pdata = pdata; + /* + * ECC parameters. + * If these are not set, they will be selected according + * to the detected flash type. + */ + /* ECC strength */ + pdata->ecc_strength = dev_read_u32_default(dev, "nand-ecc-strength", 0);
- /* Currently support only a single NAND controller */ - return 0; + /* ECC step size */ + pdata->ecc_step_size = dev_read_u32_default(dev, "nand-ecc-step-size", + 0);
- } while (node >= 0); + info->pdata = pdata;
- return -EINVAL; + return 0; }
-static int pxa3xx_nand_probe(struct pxa3xx_nand_info *info) +static int pxa3xx_nand_probe(struct udevice *dev) { - struct mtd_info *mtd = &info->controller.active->mtd; struct pxa3xx_nand_platform_data *pdata; int ret, cs, probe_success; + struct pxa3xx_nand_info *info = dev_get_priv(dev);
- ret = pxa3xx_nand_probe_dt(info); + ret = pxa3xx_nand_probe_dt(dev, info); if (ret) return ret;
@@ -1884,7 +1872,7 @@ static int pxa3xx_nand_probe(struct pxa3xx_nand_info *info)
ret = alloc_nand_resource(info); if (ret) { - dev_err(mtd->dev, "alloc nand resource failed\n"); + dev_err(dev, "alloc nand resource failed\n"); return ret; }
@@ -1918,22 +1906,24 @@ static int pxa3xx_nand_probe(struct pxa3xx_nand_info *info) return 0; }
-/* - * Main initialization routine - */ +U_BOOT_DRIVER(pxa3xx_nand) = { + .name = "pxa3xx-nand", + .id = UCLASS_MTD, + .of_match = pxa3xx_nand_dt_ids, + .probe = pxa3xx_nand_probe, + .priv_auto_alloc_size = sizeof(struct pxa3xx_nand_info) + + sizeof(struct pxa3xx_nand_host) * CONFIG_SYS_MAX_NAND_DEVICE, +}; + void board_nand_init(void) { - struct pxa3xx_nand_info *info; - struct pxa3xx_nand_host *host; + struct udevice *dev; int ret;
- info = kzalloc(sizeof(*info) + - sizeof(*host) * CONFIG_SYS_MAX_NAND_DEVICE, - GFP_KERNEL); - if (!info) - return; - - ret = pxa3xx_nand_probe(info); - if (ret) - return; + ret = uclass_get_device_by_driver(UCLASS_MTD, + DM_GET_DRIVER(pxa3xx_nand), &dev); + if (ret && ret != -ENODEV) { + pr_err("Failed to initialize %s. (error %d)\n", dev->name, + ret); + } }

The kfree() call is unreachable, and is not needed. Remove this call and the fail_disable_clk label.
Reviewed-by: Stefan Roese sr@denx.de Signed-off-by: Baruch Siach baruch@tkos.co.il --- drivers/mtd/nand/raw/pxa3xx_nand.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/nand/raw/pxa3xx_nand.c b/drivers/mtd/nand/raw/pxa3xx_nand.c index c9b7a4251b4e..8481c6e3bf91 100644 --- a/drivers/mtd/nand/raw/pxa3xx_nand.c +++ b/drivers/mtd/nand/raw/pxa3xx_nand.c @@ -1768,7 +1768,7 @@ static int alloc_nand_resource(struct pxa3xx_nand_info *info) struct pxa3xx_nand_host *host; struct nand_chip *chip = NULL; struct mtd_info *mtd; - int ret, cs; + int cs;
pdata = info->pdata; if (pdata->num_cs <= 0) @@ -1804,19 +1804,13 @@ static int alloc_nand_resource(struct pxa3xx_nand_info *info) /* Allocate a buffer to allow flash detection */ info->buf_size = INIT_BUFFER_SIZE; info->data_buff = kmalloc(info->buf_size, GFP_KERNEL); - if (info->data_buff == NULL) { - ret = -ENOMEM; - goto fail_disable_clk; - } + if (info->data_buff == NULL) + return -ENOMEM;
/* initialize all interrupts to be disabled */ disable_int(info, NDSR_MASK);
return 0; - - kfree(info->data_buff); -fail_disable_clk: - return ret; }
static int pxa3xx_nand_probe_dt(struct udevice *dev, struct pxa3xx_nand_info *info)

From: Shmuel Hazan shmuel.h@siklu.com
Based on Linux kernel commit fc256f5789cb ("mtd: nand: pxa3xx: enable NAND controller if the SoC needs it"). This commit adds support for the Armada 8040 nand controller.
The kernel commit says this:
Marvell recent SoCs like A7k/A8k do not boot with NAND flash controller activated by default. Enabling the controller is a matter of writing in a system controller register that may also be used for other NAND related choices.
Reviewed-by: Stefan Roese sr@denx.de Signed-off-by: Shmuel Hazan shmuel.h@siklu.com Signed-off-by: Baruch Siach baruch@tkos.co.il --- drivers/mtd/nand/raw/Kconfig | 1 + drivers/mtd/nand/raw/pxa3xx_nand.c | 52 ++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 10 deletions(-)
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 160b599b3464..08df12a3daf9 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -196,6 +196,7 @@ config NAND_PXA3XX bool "Support for NAND on PXA3xx and Armada 370/XP/38x" select SYS_NAND_SELF_INIT select DM_MTD + select SYSCON imply CMD_NAND help This enables the driver for the NAND flash device found on diff --git a/drivers/mtd/nand/raw/pxa3xx_nand.c b/drivers/mtd/nand/raw/pxa3xx_nand.c index 8481c6e3bf91..361a9e32935b 100644 --- a/drivers/mtd/nand/raw/pxa3xx_nand.c +++ b/drivers/mtd/nand/raw/pxa3xx_nand.c @@ -22,6 +22,8 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/rawnand.h> #include <linux/types.h> +#include <syscon.h> +#include <regmap.h> #include <dm/uclass.h> #include <dm/read.h>
@@ -119,6 +121,10 @@ DECLARE_GLOBAL_DATA_PTR; #define EXT_CMD_TYPE_LAST_RW 1 /* Last naked read/write */ #define EXT_CMD_TYPE_MONO 0 /* Monolithic read/write */
+/* System control register and bit to enable NAND on some SoCs */ +#define GENCONF_SOC_DEVICE_MUX 0x208 +#define GENCONF_SOC_DEVICE_MUX_NFC_EN BIT(0) + /* * This should be large enough to read 'ONFI' and 'JEDEC'. * Let's use 7 bytes, which is the maximum ID count supported @@ -159,6 +165,7 @@ enum { enum pxa3xx_nand_variant { PXA3XX_NAND_VARIANT_PXA, PXA3XX_NAND_VARIANT_ARMADA370, + PXA3XX_NAND_VARIANT_ARMADA_8K, };
struct pxa3xx_nand_host { @@ -424,13 +431,16 @@ static const struct udevice_id pxa3xx_nand_dt_ids[] = { .compatible = "marvell,mvebu-pxa3xx-nand", .data = PXA3XX_NAND_VARIANT_ARMADA370, }, + { + .compatible = "marvell,armada-8k-nand-controller", + .data = PXA3XX_NAND_VARIANT_ARMADA_8K, + }, {} };
-static enum pxa3xx_nand_variant pxa3xx_nand_get_variant(void) +static enum pxa3xx_nand_variant pxa3xx_nand_get_variant(struct udevice *dev) { - /* We only support the Armada 370/XP/38x for now */ - return PXA3XX_NAND_VARIANT_ARMADA370; + return dev_get_driver_data(dev); }
static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host, @@ -707,7 +717,8 @@ static irqreturn_t pxa3xx_nand_irq(struct pxa3xx_nand_info *info) info->retcode = ERR_UNCORERR; if (status & NDSR_CORERR) { info->retcode = ERR_CORERR; - if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 && + if ((info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || + info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) && info->ecc_bch) info->ecc_err_cnt = NDSR_ERR_CNT(status); else @@ -762,7 +773,8 @@ static irqreturn_t pxa3xx_nand_irq(struct pxa3xx_nand_info *info) nand_writel(info, NDCB0, info->ndcb2);
/* NDCB3 register is available in NFCv2 (Armada 370/XP SoC) */ - if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370) + if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || + info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) nand_writel(info, NDCB0, info->ndcb3); }
@@ -1676,7 +1688,8 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) }
/* Device detection must be done with ECC disabled */ - if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370) + if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || + info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) nand_writel(info, NDECCCTRL, 0x0);
if (nand_scan_ident(mtd, 1, NULL)) @@ -1726,7 +1739,8 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) * (aka split) command handling, */ if (mtd->writesize > info->chunk_size) { - if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370) { + if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || + info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) { chip->cmdfunc = nand_cmdfunc_extended; } else { dev_err(mtd->dev, @@ -1762,7 +1776,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) return nand_scan_tail(mtd); }
-static int alloc_nand_resource(struct pxa3xx_nand_info *info) +static int alloc_nand_resource(struct udevice *dev, struct pxa3xx_nand_info *info) { struct pxa3xx_nand_platform_data *pdata; struct pxa3xx_nand_host *host; @@ -1774,7 +1788,7 @@ static int alloc_nand_resource(struct pxa3xx_nand_info *info) if (pdata->num_cs <= 0) return -ENODEV;
- info->variant = pxa3xx_nand_get_variant(); + info->variant = pxa3xx_nand_get_variant(dev); for (cs = 0; cs < pdata->num_cs; cs++) { chip = (struct nand_chip *) ((u8 *)&info[1] + sizeof(*host) * cs); @@ -1810,6 +1824,24 @@ static int alloc_nand_resource(struct pxa3xx_nand_info *info) /* initialize all interrupts to be disabled */ disable_int(info, NDSR_MASK);
+ /* + * Some SoCs like A7k/A8k need to enable manually the NAND + * controller to avoid being bootloader dependent. This is done + * through the use of a single bit in the System Functions registers. + */ + if (pxa3xx_nand_get_variant(dev) == PXA3XX_NAND_VARIANT_ARMADA_8K) { + struct regmap *sysctrl_base = syscon_regmap_lookup_by_phandle( + dev, "marvell,system-controller"); + u32 reg; + + if (IS_ERR(sysctrl_base)) + return PTR_ERR(sysctrl_base); + + regmap_read(sysctrl_base, GENCONF_SOC_DEVICE_MUX, ®); + reg |= GENCONF_SOC_DEVICE_MUX_NFC_EN; + regmap_write(sysctrl_base, GENCONF_SOC_DEVICE_MUX, reg); + } + return 0; }
@@ -1864,7 +1896,7 @@ static int pxa3xx_nand_probe(struct udevice *dev)
pdata = info->pdata;
- ret = alloc_nand_resource(info); + ret = alloc_nand_resource(dev, info); if (ret) { dev_err(dev, "alloc nand resource failed\n"); return ret;

Hi Baruch,
On 29.10.20 07:52, Baruch Siach wrote:
From: Shmuel Hazan shmuel.h@siklu.com
Based on Linux kernel commit fc256f5789cb ("mtd: nand: pxa3xx: enable NAND controller if the SoC needs it"). This commit adds support for the Armada 8040 nand controller.
The kernel commit says this:
Marvell recent SoCs like A7k/A8k do not boot with NAND flash controller activated by default. Enabling the controller is a matter of writing in a system controller register that may also be used for other NAND related choices.
Reviewed-by: Stefan Roese sr@denx.de Signed-off-by: Shmuel Hazan shmuel.h@siklu.com Signed-off-by: Baruch Siach baruch@tkos.co.il
drivers/mtd/nand/raw/Kconfig | 1 + drivers/mtd/nand/raw/pxa3xx_nand.c | 52 ++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 10 deletions(-)
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 160b599b3464..08df12a3daf9 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -196,6 +196,7 @@ config NAND_PXA3XX bool "Support for NAND on PXA3xx and Armada 370/XP/38x" select SYS_NAND_SELF_INIT select DM_MTD
- select SYSCON
It seems REGMAP dependency is missing here. I get some errors while building for some MVEBU boards, like x530:
WARNING: unmet direct dependencies detected for SYSCON Depends on [n]: REGMAP [=n] Selected by [y]: - NAND_PXA3XX [=y] && MTD_RAW_NAND [=y]
WARNING: unmet direct dependencies detected for SYSCON Depends on [n]: REGMAP [=n] Selected by [y]: - NAND_PXA3XX [=y] && MTD_RAW_NAND [=y]
WARNING: unmet direct dependencies detected for SYSCON Depends on [n]: REGMAP [=n] Selected by [y]: - NAND_PXA3XX [=y] && MTD_RAW_NAND [=y] /opt/kernel.org/gcc-10.1.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-ld.bfd: drivers/built-in.o: in function `syscon_pre_probe': /home/stefan/git/u-boot/u-boot-marvell/drivers/core/syscon-uclass.c:64: undefined reference to `regmap_init_mem' /opt/kernel.org/gcc-10.1.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-ld.bfd: drivers/built-in.o: in function `alloc_nand_resource': /home/stefan/git/u-boot/u-boot-marvell/drivers/mtd/nand/raw/pxa3xx_nand.c:1840: undefined reference to `regmap_read' /opt/kernel.org/gcc-10.1.0-nolibc/arm-linux-gnueabi/bin/arm-linux-gnueabi-ld.bfd: /home/stefan/git/u-boot/u-boot-marvell/drivers/mtd/nand/raw/pxa3xx_nand.c:1842: undefined reference to `regmap_write'
I'll add "select REGMAP" to this patch and re-run the world build again shortly.
Thanks, Stefan
imply CMD_NAND help This enables the driver for the NAND flash device found on diff --git a/drivers/mtd/nand/raw/pxa3xx_nand.c b/drivers/mtd/nand/raw/pxa3xx_nand.c index 8481c6e3bf91..361a9e32935b 100644 --- a/drivers/mtd/nand/raw/pxa3xx_nand.c +++ b/drivers/mtd/nand/raw/pxa3xx_nand.c @@ -22,6 +22,8 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/rawnand.h> #include <linux/types.h> +#include <syscon.h> +#include <regmap.h> #include <dm/uclass.h> #include <dm/read.h>
@@ -119,6 +121,10 @@ DECLARE_GLOBAL_DATA_PTR; #define EXT_CMD_TYPE_LAST_RW 1 /* Last naked read/write */ #define EXT_CMD_TYPE_MONO 0 /* Monolithic read/write */
+/* System control register and bit to enable NAND on some SoCs */ +#define GENCONF_SOC_DEVICE_MUX 0x208 +#define GENCONF_SOC_DEVICE_MUX_NFC_EN BIT(0)
- /*
- This should be large enough to read 'ONFI' and 'JEDEC'.
- Let's use 7 bytes, which is the maximum ID count supported
@@ -159,6 +165,7 @@ enum { enum pxa3xx_nand_variant { PXA3XX_NAND_VARIANT_PXA, PXA3XX_NAND_VARIANT_ARMADA370,
PXA3XX_NAND_VARIANT_ARMADA_8K, };
struct pxa3xx_nand_host {
@@ -424,13 +431,16 @@ static const struct udevice_id pxa3xx_nand_dt_ids[] = { .compatible = "marvell,mvebu-pxa3xx-nand", .data = PXA3XX_NAND_VARIANT_ARMADA370, },
- {
.compatible = "marvell,armada-8k-nand-controller",
.data = PXA3XX_NAND_VARIANT_ARMADA_8K,
- }, {} };
-static enum pxa3xx_nand_variant pxa3xx_nand_get_variant(void) +static enum pxa3xx_nand_variant pxa3xx_nand_get_variant(struct udevice *dev) {
- /* We only support the Armada 370/XP/38x for now */
- return PXA3XX_NAND_VARIANT_ARMADA370;
return dev_get_driver_data(dev); }
static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
@@ -707,7 +717,8 @@ static irqreturn_t pxa3xx_nand_irq(struct pxa3xx_nand_info *info) info->retcode = ERR_UNCORERR; if (status & NDSR_CORERR) { info->retcode = ERR_CORERR;
if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 &&
if ((info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
info->ecc_bch) info->ecc_err_cnt = NDSR_ERR_CNT(status); elseinfo->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) &&
@@ -762,7 +773,8 @@ static irqreturn_t pxa3xx_nand_irq(struct pxa3xx_nand_info *info) nand_writel(info, NDCB0, info->ndcb2);
/* NDCB3 register is available in NFCv2 (Armada 370/XP SoC) */
if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
}info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) nand_writel(info, NDCB0, info->ndcb3);
@@ -1676,7 +1688,8 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) }
/* Device detection must be done with ECC disabled */
- if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K)
nand_writel(info, NDECCCTRL, 0x0);
if (nand_scan_ident(mtd, 1, NULL))
@@ -1726,7 +1739,8 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) * (aka split) command handling, */ if (mtd->writesize > info->chunk_size) {
if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370) {
if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 ||
} else { dev_err(mtd->dev,info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) { chip->cmdfunc = nand_cmdfunc_extended;
@@ -1762,7 +1776,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) return nand_scan_tail(mtd); }
-static int alloc_nand_resource(struct pxa3xx_nand_info *info) +static int alloc_nand_resource(struct udevice *dev, struct pxa3xx_nand_info *info) { struct pxa3xx_nand_platform_data *pdata; struct pxa3xx_nand_host *host; @@ -1774,7 +1788,7 @@ static int alloc_nand_resource(struct pxa3xx_nand_info *info) if (pdata->num_cs <= 0) return -ENODEV;
- info->variant = pxa3xx_nand_get_variant();
- info->variant = pxa3xx_nand_get_variant(dev); for (cs = 0; cs < pdata->num_cs; cs++) { chip = (struct nand_chip *) ((u8 *)&info[1] + sizeof(*host) * cs);
@@ -1810,6 +1824,24 @@ static int alloc_nand_resource(struct pxa3xx_nand_info *info) /* initialize all interrupts to be disabled */ disable_int(info, NDSR_MASK);
- /*
* Some SoCs like A7k/A8k need to enable manually the NAND
* controller to avoid being bootloader dependent. This is done
* through the use of a single bit in the System Functions registers.
*/
- if (pxa3xx_nand_get_variant(dev) == PXA3XX_NAND_VARIANT_ARMADA_8K) {
struct regmap *sysctrl_base = syscon_regmap_lookup_by_phandle(
dev, "marvell,system-controller");
u32 reg;
if (IS_ERR(sysctrl_base))
return PTR_ERR(sysctrl_base);
regmap_read(sysctrl_base, GENCONF_SOC_DEVICE_MUX, ®);
reg |= GENCONF_SOC_DEVICE_MUX_NFC_EN;
regmap_write(sysctrl_base, GENCONF_SOC_DEVICE_MUX, reg);
- }
- return 0; }
@@ -1864,7 +1896,7 @@ static int pxa3xx_nand_probe(struct udevice *dev)
pdata = info->pdata;
- ret = alloc_nand_resource(info);
- ret = alloc_nand_resource(dev, info); if (ret) { dev_err(dev, "alloc nand resource failed\n"); return ret;
Viele Grüße, Stefan

Hi Baruch,
On 29.10.20 07:52, Baruch Siach wrote:
This series adds NAND flash support to Aramda 8k systems. Patches make the necessary changes to the pxa3xx_nand driver and DT files.
v3: Address Stefan's comments on patch #3
Move hunks from patch #3 to #5 to fix bisectability
Thanks. I'll look into it soonish.
One general comment though. You missed the v3 in the patch subject this time and you also missed adding the patch revision history to the patches:
http://www.denx.de/wiki/view/U-Boot/Patches#Sending_updated_patch_versions
No need to re-send now. But please make sure to send with a correct history next time.
Thanks, Stefan
v2: Rebase on current master. Fixes conflict with commit 661c98121d4 ("mtd: nand: pxa3xx: Fix not calling dev_xxx with a device")
Baruch Siach (2): arm: dts: armada-cp110-master: update nand-controller mtd: pxa3xx_nand: remove dead code
Shmuel Hazan (3): arm: dts: armada-cp110-slave: add missing cps_nand mtd: pxa3xx_nand: port to use driver model mtd: nand: pxa3xx: enable NAND controller if the SoC needs it
arch/arm/dts/armada-cp110-master.dtsi | 15 ++- arch/arm/dts/armada-cp110-slave.dtsi | 16 +++ drivers/mtd/nand/raw/Kconfig | 2 + drivers/mtd/nand/raw/pxa3xx_nand.c | 180 ++++++++++++++------------ 4 files changed, 125 insertions(+), 88 deletions(-)
Viele Grüße, Stefan

On 29.10.20 07:52, Baruch Siach wrote:
This series adds NAND flash support to Aramda 8k systems. Patches make the necessary changes to the pxa3xx_nand driver and DT files.
v3: Address Stefan's comments on patch #3
Move hunks from patch #3 to #5 to fix bisectability
v2: Rebase on current master. Fixes conflict with commit 661c98121d4 ("mtd: nand: pxa3xx: Fix not calling dev_xxx with a device")
Baruch Siach (2): arm: dts: armada-cp110-master: update nand-controller mtd: pxa3xx_nand: remove dead code
Shmuel Hazan (3): arm: dts: armada-cp110-slave: add missing cps_nand mtd: pxa3xx_nand: port to use driver model mtd: nand: pxa3xx: enable NAND controller if the SoC needs it
arch/arm/dts/armada-cp110-master.dtsi | 15 ++- arch/arm/dts/armada-cp110-slave.dtsi | 16 +++ drivers/mtd/nand/raw/Kconfig | 2 + drivers/mtd/nand/raw/pxa3xx_nand.c | 180 ++++++++++++++------------ 4 files changed, 125 insertions(+), 88 deletions(-)
Applied to u-boot-marvell/master
Thanks, Stefan
participants (2)
-
Baruch Siach
-
Stefan Roese