All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mugunthan V N <mugunthanvnm@ti.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 5/9] drivers: nand: omap_gpmc: convert driver to adopt driver model
Date: Fri, 1 Apr 2016 16:59:46 +0530	[thread overview]
Message-ID: <1459510190-26306-6-git-send-email-mugunthanvnm@ti.com> (raw)
In-Reply-To: <1459510190-26306-1-git-send-email-mugunthanvnm@ti.com>

adopt omap_gpmc driver to driver model.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/mtd/nand/omap_gpmc.c | 205 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 205 insertions(+)

diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 4814fa2..df63491 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -16,6 +16,10 @@
 #include <nand.h>
 #include <linux/mtd/omap_elm.h>
 
+#include <dm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
 #define BADBLOCK_MARKER_LENGTH	2
 #define SECTOR_BYTES		512
 #define ECCCLEAR		(0x1 << 8)
@@ -46,11 +50,22 @@ struct omap_nand_info {
 	enum omap_ecc ecc_scheme;
 	uint8_t cs;
 	uint8_t ws;		/* wait status pin (0,1) */
+	uint8_t bus_width;	/* Bus width of NAND device */
 };
 
+#ifndef CONFIG_DM_NAND
 /* We are wasting a bit of memory but al least we are safe */
 static struct omap_nand_info omap_nand_info[GPMC_MAX_CS];
 
+#else
+
+struct omap_gpmc_platdata {
+	struct omap_nand_info *omap_nand_info;
+	struct gpmc *gpmc_cfg;
+	int max_cs;
+};
+#endif
+
 /*
  * omap_nand_hwcontrol - Set the address pointers corretly for the
  *			following address/data/command operation
@@ -943,6 +958,8 @@ int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
 }
 #endif /* CONFIG_SPL_BUILD */
 
+#ifndef CONFIG_DM_NAND
+
 /*
  * Board-specific NAND initialization. The following members of the
  * argument are board-specific:
@@ -1034,3 +1051,191 @@ int board_nand_init(struct nand_chip *nand)
 
 	return 0;
 }
+
+#else /* CONFIG_DM_NAND */
+
+static int omap_gpmc_probe(struct udevice *dev)
+{
+	struct nand_chip *nand = dev_get_priv(dev);
+	struct omap_gpmc_platdata *pdata = dev_get_platdata(dev);
+	struct gpmc *gpmc_cfg = pdata->gpmc_cfg;
+	int32_t gpmc_config = 0;
+	int ecc_opt;
+	int cs = cs_next++;
+	int err = 0;
+
+	while (cs < pdata->max_cs) {
+		/* Check if NAND type is set */
+		if ((readl(&gpmc_cfg->cs[cs].config1) & 0xC00) == 0x800) {
+			/* Found it!! */
+			break;
+		}
+		cs++;
+	}
+
+	if (cs >= pdata->max_cs) {
+		printf("nand: error: Unable to find NAND settings in GPMC Configuration - quitting\n");
+		return -ENODEV;
+	}
+
+	gpmc_config = readl(&gpmc_cfg->config);
+	/* Disable Write protect */
+	gpmc_config |= 0x10;
+	writel(gpmc_config, &gpmc_cfg->config);
+
+	nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;
+	nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
+	nand->priv	= &pdata->omap_nand_info[cs];
+	nand->cmd_ctrl	= omap_nand_hwcontrol;
+	nand->options	|= NAND_NO_PADDING | NAND_CACHEPRG;
+	nand->chip_delay = 100;
+	nand->ecc.layout = &omap_ecclayout;
+
+	/* configure driver and controller based on NAND device bus-width */
+	gpmc_config = readl(&gpmc_cfg->cs[cs].config1);
+	if (pdata->omap_nand_info[cs].bus_width == 16) {
+		nand->options |= NAND_BUSWIDTH_16;
+		writel(gpmc_config | (0x1 << 12), &gpmc_cfg->cs[cs].config1);
+	} else {
+		nand->options &= ~NAND_BUSWIDTH_16;
+		writel(gpmc_config & ~(0x1 << 12), &gpmc_cfg->cs[cs].config1);
+	}
+
+	ecc_opt = pdata->omap_nand_info[cs].ecc_scheme;
+	/* select ECC scheme */
+	if (ecc_opt != OMAP_ECC_HAM1_CODE_SW) {
+		err = omap_select_ecc_scheme(nand, ecc_opt,
+					     CONFIG_SYS_NAND_PAGE_SIZE,
+					     CONFIG_SYS_NAND_OOBSIZE);
+	} else {
+		/*
+		 * pagesize and oobsize are not required to
+		 * configure sw ecc-scheme
+		 */
+		err = omap_select_ecc_scheme(nand, ecc_opt, 0, 0);
+	}
+	if (err)
+		return err;
+
+#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
+	nand->read_buf = omap_nand_read_prefetch;
+#else
+	if (nand->options & NAND_BUSWIDTH_16)
+		nand->read_buf = nand_read_buf16;
+	else
+		nand->read_buf = nand_read_buf;
+#endif
+
+	nand->dev_ready = omap_dev_ready;
+
+	return 0;
+}
+
+static int omap_gpmc_get_ecc_opt(int node, int elm_node)
+{
+	const void *fdt = gd->fdt_blob;
+	const char *ecc_str;
+	int ecc_opt = -ENOENT;
+
+	ecc_str = fdt_getprop(fdt, node, "ti,nand-ecc-opt", NULL);
+	if (!ecc_str) {
+		error("DT entry for ti,nand-ecc-opt not found\n");
+		return -ENOENT;
+	}
+
+	if (!strcmp(ecc_str, "sw")) {
+		ecc_opt = OMAP_ECC_HAM1_CODE_SW;
+	} else if (!strcmp(ecc_str, "ham1") ||
+		   !strcmp(ecc_str, "hw") ||
+		   !strcmp(ecc_str, "hw-romcode")) {
+		ecc_opt = OMAP_ECC_HAM1_CODE_HW;
+	} else if (!strcmp(ecc_str, "bch4")) {
+		if (elm_node > 0)
+			ecc_opt = OMAP_ECC_BCH4_CODE_HW;
+		else
+			ecc_opt = OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
+	} else if (!strcmp(ecc_str, "bch8")) {
+		if (elm_node > 0)
+			ecc_opt = OMAP_ECC_BCH8_CODE_HW;
+		else
+			ecc_opt = OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
+	} else if (!strcmp(ecc_str, "bch16")) {
+		if (elm_node > 0)
+			ecc_opt = OMAP_ECC_BCH16_CODE_HW;
+		else
+			error("BCH16 requires ELM support\n");
+	} else {
+		error("ti,nand-ecc-opt invalid value\n");
+		return -EINVAL;
+	}
+
+	return ecc_opt;
+}
+
+static int omap_gpmc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct omap_gpmc_platdata *pdata = dev_get_platdata(dev);
+	const void *fdt = gd->fdt_blob;
+	int node = dev->of_offset;
+	int subnode;
+
+	pdata->gpmc_cfg = (struct gpmc *)dev_get_addr(dev);
+	pdata->max_cs = fdtdec_get_int(fdt, node, "gpmc,num-cs", -1);
+	if (pdata->max_cs < 0) {
+		error("max chip select not found in DT\n");
+		return -ENOENT;
+	}
+
+	pdata->omap_nand_info = calloc(pdata->max_cs,
+				       sizeof(struct omap_nand_info));
+	if (!pdata->omap_nand_info)
+		return -ENOMEM;
+
+	fdt_for_each_subnode(fdt, subnode, node) {
+		int cs;
+		int len;
+		int elm_node;
+		const char *name;
+		struct omap_nand_info *nand_info;
+
+		name = fdt_get_name(fdt, subnode, &len);
+		if (strncmp(name, "nand", 4))
+			continue;
+
+		cs = fdtdec_get_int(fdt, subnode, "reg", -1);
+		if (cs < 0 || cs >= pdata->max_cs) {
+			error("Invalid cs for nand device\n");
+			return -EINVAL;
+		}
+		nand_info = &pdata->omap_nand_info[cs];
+
+		/* get bus width 8 or 16, if not present 8 */
+		nand_info->bus_width = fdtdec_get_int(fdt, subnode,
+						      "nand-bus-width", 8);
+
+		elm_node = fdtdec_lookup_phandle(fdt, subnode, "ti,elm-id");
+
+		nand_info->ecc_scheme = omap_gpmc_get_ecc_opt(subnode,
+							      elm_node);
+		if (nand_info->ecc_scheme < 0)
+			return nand_info->ecc_scheme;
+	}
+	return 0;
+}
+
+static const struct udevice_id omap_gpmc_ids[] = {
+	{ .compatible = "ti,am3352-gpmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(omap_gpmc) = {
+	.name	= "omap_gpmc",
+	.id	= UCLASS_NAND,
+	.of_match = omap_gpmc_ids,
+	.ofdata_to_platdata = omap_gpmc_ofdata_to_platdata,
+	.probe	= omap_gpmc_probe,
+	.priv_auto_alloc_size = sizeof(struct nand_chip),
+	.platdata_auto_alloc_size = sizeof(struct omap_gpmc_platdata),
+	.flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif /* CONFIG_DM_NAND */
-- 
2.8.0.rc3.9.g44915db

  parent reply	other threads:[~2016-04-01 11:29 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-01 11:29 [U-Boot] [PATCH 0/9] device model bringup of nand on am335x gp evm and am437x gp evm Mugunthan V N
2016-04-01 11:29 ` [U-Boot] [PATCH 1/9] include: nand: move endif to end of file Mugunthan V N
2016-04-01 12:51   ` Tom Rini
2016-04-20 14:39   ` Simon Glass
2016-04-01 11:29 ` [U-Boot] [PATCH 2/9] cmd: nand: abstract global variable usage for dm conversion Mugunthan V N
2016-04-01 12:51   ` Tom Rini
2016-04-01 22:57   ` Scott Wood
2016-04-13 11:01     ` Mugunthan V N
2016-04-14 11:50   ` Mugunthan V N
2016-04-01 11:29 ` [U-Boot] [PATCH 3/9] drivers: nand: Kconfig: add NAND as Kconfig option Mugunthan V N
2016-04-01 12:51   ` Tom Rini
2016-04-01 14:57     ` Mugunthan V N
2016-04-01 23:07     ` Scott Wood
2016-04-01 23:41       ` Tom Rini
2016-04-01 23:45         ` Scott Wood
2016-04-02  0:25           ` Tom Rini
2016-04-05  8:37             ` Mugunthan V N
2016-04-08 19:45               ` Tom Rini
2016-04-17  1:38                 ` Scott Wood
2016-04-01 11:29 ` [U-Boot] [PATCH 4/9] drivers: nand: implement a NAND uclass Mugunthan V N
2016-04-01 12:51   ` Tom Rini
2016-04-01 14:59     ` Mugunthan V N
2016-04-01 23:25   ` Scott Wood
2016-04-01 23:31     ` Scott Wood
2016-04-05  8:27       ` Mugunthan V N
2016-04-20 14:39   ` Simon Glass
2016-04-21  5:55     ` Mugunthan V N
2016-04-21 14:11       ` Simon Glass
2016-04-22  5:06         ` Mugunthan V N
2016-04-01 11:29 ` Mugunthan V N [this message]
2016-04-01 12:51   ` [U-Boot] [PATCH 5/9] drivers: nand: omap_gpmc: convert driver to adopt driver model Tom Rini
2016-04-04 17:22   ` Scott Wood
2016-04-05  8:41     ` Mugunthan V N
2016-04-01 11:29 ` [U-Boot] [PATCH 6/9] am43xx_evm: nand: do not define DM_NAND for spl Mugunthan V N
2016-04-01 12:51   ` Tom Rini
2016-04-20 14:39   ` Simon Glass
2016-04-01 11:29 ` [U-Boot] [PATCH 7/9] defconfig: am437x_gp_evm: enable NAND driver model Mugunthan V N
2016-04-01 12:52   ` Tom Rini
2016-04-20 14:39     ` Simon Glass
2016-04-01 11:29 ` [U-Boot] [PATCH 8/9] am335x_evm: nand: do not define DM_NAND for spl Mugunthan V N
2016-04-01 12:52   ` Tom Rini
2016-04-20 14:39     ` Simon Glass
2016-04-01 11:29 ` [U-Boot] [PATCH 9/9] defconfig: am335x_gp_evm: enable NAND driver model Mugunthan V N
2016-04-20 14:39   ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1459510190-26306-6-git-send-email-mugunthanvnm@ti.com \
    --to=mugunthanvnm@ti.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.