* [PATCH 1/5] arm: dts: armada-cp110-slave: add missing cps_nand
2020-09-15 11:07 [PATCH 0/5] mtd: pxa3xx_nand: add support for Armada 8k Baruch Siach
@ 2020-09-15 11:07 ` Baruch Siach
2020-09-15 11:07 ` [PATCH 2/5] arm: dts: armada-cp110-master: update nand-controller Baruch Siach
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Baruch Siach @ 2020-09-15 11:07 UTC (permalink / raw)
To: u-boot
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.
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 at 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 at f4600000 {
--
2.28.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 2/5] arm: dts: armada-cp110-master: update nand-controller
2020-09-15 11:07 [PATCH 0/5] mtd: pxa3xx_nand: add support for Armada 8k Baruch Siach
2020-09-15 11:07 ` [PATCH 1/5] arm: dts: armada-cp110-slave: add missing cps_nand Baruch Siach
@ 2020-09-15 11:07 ` Baruch Siach
2020-09-15 11:07 ` [PATCH 3/5] mtd: pxa3xx_nand: port to use driver model Baruch Siach
` (2 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Baruch Siach @ 2020-09-15 11:07 UTC (permalink / raw)
To: u-boot
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.
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 at 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";
};
--
2.28.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 3/5] mtd: pxa3xx_nand: port to use driver model
2020-09-15 11:07 [PATCH 0/5] mtd: pxa3xx_nand: add support for Armada 8k Baruch Siach
2020-09-15 11:07 ` [PATCH 1/5] arm: dts: armada-cp110-slave: add missing cps_nand Baruch Siach
2020-09-15 11:07 ` [PATCH 2/5] arm: dts: armada-cp110-master: update nand-controller Baruch Siach
@ 2020-09-15 11:07 ` Baruch Siach
2020-09-15 11:07 ` [PATCH 4/5] mtd: pxa3xx_nand: remove dead code Baruch Siach
2020-09-15 11:07 ` [PATCH 5/5] mtd: nand: pxa3xx: enable NAND controller if the SoC needs it Baruch Siach
4 siblings, 0 replies; 9+ messages in thread
From: Baruch Siach @ 2020-09-15 11:07 UTC (permalink / raw)
To: u-boot
From: Shmuel Hazan <shmuel.h@siklu.com>
Signed-off-by: Shmuel Hazan <shmuel.h@siklu.com>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
drivers/mtd/nand/raw/Kconfig | 2 +
drivers/mtd/nand/raw/pxa3xx_nand.c | 114 +++++++++++++----------------
2 files changed, 54 insertions(+), 62 deletions(-)
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 06b2ff972cad..bcfaa09ac720 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -195,6 +195,8 @@ endif
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 a30e82166b96..d455201b91a3 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 */
@@ -1810,79 +1820,58 @@ 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;
+ 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;
+ }
- if (fdtdec_get_bool(blob, node, "nand-keep-config"))
- pdata->keep_config = 1;
+ if (dev_read_bool(dev, "nand-enable-arbiter"))
+ pdata->enable_arbiter = 1;
- /*
- * 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-keep-config"))
+ pdata->keep_config = 1;
- /* ECC step size */
- pdata->ecc_step_size = fdtdec_get_int(blob, node,
- "nand-ecc-step-size", 0);
-
- 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 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;
pdata = info->pdata;
- ret = alloc_nand_resource(info);
+ ret = alloc_nand_resource(dev, info);
if (ret) {
dev_err(&pdev->dev, "alloc nand resource failed\n");
return ret;
@@ -1918,22 +1907,23 @@ 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);
}
--
2.28.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 4/5] mtd: pxa3xx_nand: remove dead code
2020-09-15 11:07 [PATCH 0/5] mtd: pxa3xx_nand: add support for Armada 8k Baruch Siach
` (2 preceding siblings ...)
2020-09-15 11:07 ` [PATCH 3/5] mtd: pxa3xx_nand: port to use driver model Baruch Siach
@ 2020-09-15 11:07 ` Baruch Siach
2020-09-15 11:07 ` [PATCH 5/5] mtd: nand: pxa3xx: enable NAND controller if the SoC needs it Baruch Siach
4 siblings, 0 replies; 9+ messages in thread
From: Baruch Siach @ 2020-09-15 11:07 UTC (permalink / raw)
To: u-boot
The kfree() call is unreachable, and is not needed. Remove this call and
the fail_disable_clk label.
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 d455201b91a3..54ba65fa8202 100644
--- a/drivers/mtd/nand/raw/pxa3xx_nand.c
+++ b/drivers/mtd/nand/raw/pxa3xx_nand.c
@@ -1769,7 +1769,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)
@@ -1805,19 +1805,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)
--
2.28.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 5/5] mtd: nand: pxa3xx: enable NAND controller if the SoC needs it
2020-09-15 11:07 [PATCH 0/5] mtd: pxa3xx_nand: add support for Armada 8k Baruch Siach
` (3 preceding siblings ...)
2020-09-15 11:07 ` [PATCH 4/5] mtd: pxa3xx_nand: remove dead code Baruch Siach
@ 2020-09-15 11:07 ` Baruch Siach
4 siblings, 0 replies; 9+ messages in thread
From: Baruch Siach @ 2020-09-15 11:07 UTC (permalink / raw)
To: u-boot
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.
Signed-off-by: Shmuel Hazan <shmuel.h@siklu.com>
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
drivers/mtd/nand/raw/pxa3xx_nand.c | 50 ++++++++++++++++++++++++------
1 file changed, 41 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/nand/raw/pxa3xx_nand.c b/drivers/mtd/nand/raw/pxa3xx_nand.c
index 54ba65fa8202..7506c5bb2884 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);
}
@@ -1677,7 +1689,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))
@@ -1727,7 +1740,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(&info->pdev->dev,
@@ -1763,7 +1777,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;
@@ -1775,7 +1789,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);
@@ -1811,6 +1825,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;
}
--
2.28.0
^ permalink raw reply related [flat|nested] 9+ messages in thread