Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cdeadd71 authored by Heiko Schocher's avatar Heiko Schocher Committed by David Woodhouse
Browse files

mtd: nand: davinci: add OF support for davinci nand controller



add OF support for the davinci nand controller.

Signed-off-by: default avatarHeiko Schocher <hs@denx.de>
Acked-by: default avatarSekhar Nori <nsekhar@ti.com>
Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent a445f784
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
* Texas Instruments Davinci NAND

This file provides information, what the device node for the
davinci nand interface contain.

Required properties:
- compatible: "ti,davinci-nand";
- reg : contain 2 offset/length values:
        - offset and length for the access window
        - offset and length for accessing the aemif control registers
- ti,davinci-chipselect: Indicates on the davinci_nand driver which
                         chipselect is used for accessing the nand.

Recommended properties :
- ti,davinci-mask-ale: mask for ale
- ti,davinci-mask-cle: mask for cle
- ti,davinci-mask-chipsel: mask for chipselect
- ti,davinci-ecc-mode: ECC mode valid values for davinci driver:
		- "none"
		- "soft"
		- "hw"
- ti,davinci-ecc-bits: used ECC bits, currently supported 1 or 4.
- ti,davinci-nand-buswidth: buswidth 8 or 16
- ti,davinci-nand-use-bbt: use flash based bad block table support.

Example (enbw_cmc board):
aemif@60000000 {
	compatible = "ti,davinci-aemif";
	#address-cells = <2>;
	#size-cells = <1>;
	reg = <0x68000000 0x80000>;
	ranges = <2 0 0x60000000 0x02000000
		  3 0 0x62000000 0x02000000
		  4 0 0x64000000 0x02000000
		  5 0 0x66000000 0x02000000
		  6 0 0x68000000 0x02000000>;
	nand@3,0 {
		compatible = "ti,davinci-nand";
		reg = <3 0x0 0x807ff
			6 0x0 0x8000>;
		#address-cells = <1>;
		#size-cells = <1>;
		ti,davinci-chipselect = <1>;
		ti,davinci-mask-ale = <0>;
		ti,davinci-mask-cle = <0>;
		ti,davinci-mask-chipsel = <0>;
		ti,davinci-ecc-mode = "hw";
		ti,davinci-ecc-bits = <4>;
		ti,davinci-nand-use-bbt;
	};
};
+71 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/slab.h>
#include <linux/of_device.h>

#include <mach/nand.h>
#include <mach/aemif.h>
@@ -518,9 +519,75 @@ static struct nand_ecclayout hwecc4_2048 __initconst = {
	},
};

#if defined(CONFIG_OF)
static const struct of_device_id davinci_nand_of_match[] = {
	{.compatible = "ti,davinci-nand", },
	{},
}
MODULE_DEVICE_TABLE(of, davinci_nand_of_match);

static struct davinci_nand_pdata
	*nand_davinci_get_pdata(struct platform_device *pdev)
{
	if (!pdev->dev.platform_data && pdev->dev.of_node) {
		struct davinci_nand_pdata *pdata;
		const char *mode;
		u32 prop;
		int len;

		pdata =  devm_kzalloc(&pdev->dev,
				sizeof(struct davinci_nand_pdata),
				GFP_KERNEL);
		pdev->dev.platform_data = pdata;
		if (!pdata)
			return NULL;
		if (!of_property_read_u32(pdev->dev.of_node,
			"ti,davinci-chipselect", &prop))
			pdev->id = prop;
		if (!of_property_read_u32(pdev->dev.of_node,
			"ti,davinci-mask-ale", &prop))
			pdata->mask_ale = prop;
		if (!of_property_read_u32(pdev->dev.of_node,
			"ti,davinci-mask-cle", &prop))
			pdata->mask_cle = prop;
		if (!of_property_read_u32(pdev->dev.of_node,
			"ti,davinci-mask-chipsel", &prop))
			pdata->mask_chipsel = prop;
		if (!of_property_read_string(pdev->dev.of_node,
			"ti,davinci-ecc-mode", &mode)) {
			if (!strncmp("none", mode, 4))
				pdata->ecc_mode = NAND_ECC_NONE;
			if (!strncmp("soft", mode, 4))
				pdata->ecc_mode = NAND_ECC_SOFT;
			if (!strncmp("hw", mode, 2))
				pdata->ecc_mode = NAND_ECC_HW;
		}
		if (!of_property_read_u32(pdev->dev.of_node,
			"ti,davinci-ecc-bits", &prop))
			pdata->ecc_bits = prop;
		if (!of_property_read_u32(pdev->dev.of_node,
			"ti,davinci-nand-buswidth", &prop))
			if (prop == 16)
				pdata->options |= NAND_BUSWIDTH_16;
		if (of_find_property(pdev->dev.of_node,
			"ti,davinci-nand-use-bbt", &len))
			pdata->bbt_options = NAND_BBT_USE_FLASH;
	}

	return pdev->dev.platform_data;
}
#else
#define davinci_nand_of_match NULL
static struct davinci_nand_pdata
	*nand_davinci_get_pdata(struct platform_device *pdev)
{
	return pdev->dev.platform_data;
}
#endif

static int __init nand_davinci_probe(struct platform_device *pdev)
{
	struct davinci_nand_pdata	*pdata = pdev->dev.platform_data;
	struct davinci_nand_pdata	*pdata;
	struct davinci_nand_info	*info;
	struct resource			*res1;
	struct resource			*res2;
@@ -530,6 +597,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
	uint32_t			val;
	nand_ecc_modes_t		ecc_mode;

	pdata = nand_davinci_get_pdata(pdev);
	/* insist on board-specific configuration */
	if (!pdata)
		return -ENODEV;
@@ -816,6 +884,8 @@ static struct platform_driver nand_davinci_driver = {
	.remove		= __exit_p(nand_davinci_remove),
	.driver		= {
		.name	= "davinci_nand",
		.owner	= THIS_MODULE,
		.of_match_table = davinci_nand_of_match,
	},
};
MODULE_ALIAS("platform:davinci_nand");