diff mbox series

[1/3] ARM: pxa: cm-x270: Use gen_nand to expose the NAND device

Message ID 20200429223134.789322-2-boris.brezillon@collabora.com (mailing list archive)
State New, archived
Headers show
Series mtd: rawnand: Get rid of the cmx270 driver | expand

Commit Message

Boris Brezillon April 29, 2020, 10:31 p.m. UTC
No need to have a dedicated driver for this controller, all we need to
do is adjust the memory range offset to account for the fact that the
chip is connected to D[16:23] and not D[0:7].

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
---
 arch/arm/mach-pxa/cm-x270.c | 131 ++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)
diff mbox series

Patch

diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index 9baad11314f2..63bd3be60322 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -23,6 +23,8 @@ 
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 #include <linux/platform_data/mmc-pxamci.h>
 
+#include <linux/mtd/platnand.h>
+
 #include "generic.h"
 
 /* physical address if local-bus attached devices */
@@ -36,6 +38,10 @@ 
 /* MMC power enable */
 #define GPIO105_MMC_POWER	(105)
 
+/* NAND GPIOs */
+#define GPIO11_NAND_CS		(11)
+#define GPIO89_NAND_RB		(89)
+
 /* WLAN GPIOS */
 #define GPIO19_WLAN_STRAP	(19)
 #define GPIO102_WLAN_RST	(102)
@@ -309,6 +315,130 @@  static void __init cmx270_init_mmc(void)
 static inline void cmx270_init_mmc(void) {}
 #endif
 
+/* NAND flash */
+#if IS_ENABLED(CONFIG_MTD_NAND_PLATFORM)
+static inline void nand_cs_on(void)
+{
+	gpio_set_value(GPIO11_NAND_CS, 0);
+}
+
+static void nand_cs_off(void)
+{
+	dsb();
+
+	gpio_set_value(GPIO11_NAND_CS, 1);
+}
+
+/* hardware specific access to control-lines */
+static void cmx270_nand_cmd_ctl(struct nand_chip *this, int dat,
+				unsigned int ctrl)
+{
+	unsigned long nandaddr = (unsigned long)this->legacy.IO_ADDR_W;
+
+	dsb();
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if (ctrl & NAND_ALE)
+			nandaddr |=  (1 << 3);
+		else
+			nandaddr &= ~(1 << 3);
+		if (ctrl & NAND_CLE)
+			nandaddr |=  (1 << 2);
+		else
+			nandaddr &= ~(1 << 2);
+		if (ctrl & NAND_NCE)
+			nand_cs_on();
+		else
+			nand_cs_off();
+	}
+
+	dsb();
+	this->legacy.IO_ADDR_W = (void __iomem *)nandaddr;
+	if (dat != NAND_CMD_NONE)
+		writeb(dat, this->legacy.IO_ADDR_W);
+
+	dsb();
+}
+
+/* read device ready pin */
+static int cmx270_nand_device_ready(struct nand_chip *this)
+{
+	dsb();
+
+	return gpio_get_value(GPIO89_NAND_RB);
+}
+
+static struct mtd_partition cmx270_partition_info[] = {
+	[0] = {
+		.name	= "cmx270-0",
+		.offset	= 0,
+		.size	= MTDPART_SIZ_FULL
+	},
+};
+
+struct platform_nand_data cmx270_nand_platdata = {
+	.chip = {
+		.nr_chips = 1,
+		.chip_offset = 0,
+		.nr_partitions = ARRAY_SIZE(cmx270_partition_info),
+		.partitions = cmx270_partition_info,
+		.chip_delay = 20,
+	},
+	.ctrl = {
+		.dev_ready = cmx270_nand_device_ready,
+		.cmd_ctrl = cmx270_nand_cmd_ctl,
+	},
+};
+
+static struct resource cmx270_nand_resource[] = {
+	[0] = {
+		/*
+		 * The NAND is connected to D[16:23], hence the 2 byte offset
+		 * here.
+		 */
+		.start = PXA_CS1_PHYS + 2,
+		.end   = PXA_CS1_PHYS + 2 + 12,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device cmx270_nand = {
+	.name		= "gen_nand",
+	.num_resources	= ARRAY_SIZE(cmx270_nand_resource),
+	.resource	= cmx270_nand_resource,
+	.id		= -1,
+	.dev		= {
+		.platform_data = &cmx270_nand_platdata,
+	}
+};
+
+static void __init cmx270_init_nand(void)
+{
+	int err;
+
+	err = gpio_request(GPIO11_NAND_CS, "NAND CS");
+	if (err) {
+		pr_warn("CMX270: failed to request NAND CS gpio\n");
+		return;
+	}
+
+	gpio_direction_output(GPIO11_NAND_CS, 1);
+
+	err = gpio_request(GPIO89_NAND_RB, "NAND R/B");
+	if (err) {
+		pr_warn("CMX270: failed to request NAND R/B gpio\n");
+		gpio_free(GPIO11_NAND_CS);
+		return;
+	}
+
+	gpio_direction_input(GPIO89_NAND_RB);
+
+	platform_device_register(&cmx270_nand);
+}
+#else
+static inline void cmx270_init_nand(void) {}
+#endif
+
 #if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
 static struct pxa2xx_spi_controller cm_x270_spi_info = {
 	.num_chipselect	= 1,
@@ -413,6 +543,7 @@  void __init cmx270_init(void)
 
 	cmx270_init_rtc();
 	cmx270_init_mmc();
+	cmx270_init_nand();
 	cmx270_init_ohci();
 	cmx270_init_2700G();
 	cmx270_init_spi();