diff options
| author | Pekon Gupta <pekon@ti.com> | 2013-10-24 18:20:17 +0530 | 
|---|---|---|
| committer | Evan Wilson <evan@oliodevices.com> | 2014-11-29 14:48:16 -0800 | 
| commit | 0ed0fbbcdd33c043f3f2df02ef3253d894decd33 (patch) | |
| tree | b622a305c32b067510c8cf5df0ba9e0e134138dc | |
| parent | 838f03096ca7e681dcf08ee2c6fe15bbdf445a86 (diff) | |
| download | olio-linux-3.10-0ed0fbbcdd33c043f3f2df02ef3253d894decd33.tar.xz olio-linux-3.10-0ed0fbbcdd33c043f3f2df02ef3253d894decd33.zip | |
ARM: OMAP2+: cleaned-up DT support of various ECC schemes
OMAP NAND driver support multiple ECC scheme, which can used in different
flavours, depending on in-build Hardware engines present on SoC.
This patch updates following in DT bindings related to sectionion of ecc-schemes
- ti,elm-id: replaces elm_id (maintains backward compatibility)
- ti,nand-ecc-opts: selection of h/w or s/w implementation of an ecc-scheme
	depends on ti,elm-id. (supported values ham1, bch4, and bch8)
- maintain backward compatibility to deprecated DT bindings (sw, hw, hw-romcode)
Below table shows different flavours of ecc-schemes supported by OMAP devices
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
|(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
|(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
| ti,elm-id in DT)                      |               |               |
+---------------------------------------+---------------+---------------+
To optimize footprint of omap2-nand driver, selection of some ECC schemes
also require enabling following Kconfigs, in addition to setting appropriate
DT bindings
- Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
- Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine
Signed-off-by: Pekon Gupta <pekon@ti.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
| -rw-r--r-- | Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 8 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 48 | ||||
| -rw-r--r-- | include/linux/platform_data/mtd-nand-omap2.h | 13 | 
3 files changed, 51 insertions, 18 deletions
| diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt index df338cb5059..bfe07e15273 100644 --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt @@ -36,8 +36,12 @@ Optional properties:  		"prefetch-dma"		Prefetch enabled sDMA mode  		"prefetch-irq"		Prefetch enabled irq mode - - elm_id:	Specifies elm device node. This is required to support BCH - 		error correction using ELM module. + - elm_id:	<deprecated> use "ti,elm-id" instead + - ti,elm-id:	Specifies phandle of the ELM devicetree node. +		ELM is an on-chip hardware engine on TI SoC which is used for +		locating ECC errors for BCHx algorithms. SoC devices which have +		ELM hardware engines should specify this device node in .dtsi +		Using ELM for ECC error correction frees some CPU cycles.  For inline partiton table parsing (optional): diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 579697adaae..c877129142b 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1341,14 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,  #ifdef CONFIG_MTD_NAND -static const char * const nand_ecc_opts[] = { -	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw", -	[OMAP_ECC_HAMMING_CODE_HW]		= "hw", -	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-romcode", -	[OMAP_ECC_BCH4_CODE_HW]			= "bch4", -	[OMAP_ECC_BCH8_CODE_HW]			= "bch8", -}; -  static const char * const nand_xfer_types[] = {  	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",  	[NAND_OMAP_POLLED]			= "polled", @@ -1378,13 +1370,41 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,  	gpmc_nand_data->cs = val;  	gpmc_nand_data->of_node = child; -	if (!of_property_read_string(child, "ti,nand-ecc-opt", &s)) -		for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++) -			if (!strcasecmp(s, nand_ecc_opts[val])) { -				gpmc_nand_data->ecc_opt = val; -				break; -			} +	/* Detect availability of ELM module */ +	gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0); +	if (gpmc_nand_data->elm_of_node == NULL) +		gpmc_nand_data->elm_of_node = +					of_parse_phandle(child, "elm_id", 0); +	if (gpmc_nand_data->elm_of_node == NULL) +		pr_warn("%s: ti,elm-id property not found\n", __func__); + +	/* select ecc-scheme for NAND */ +	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) { +		pr_err("%s: ti,nand-ecc-opt not found\n", __func__); +		return -ENODEV; +	} +	if (!strcmp(s, "ham1") || !strcmp(s, "sw") || +		!strcmp(s, "hw") || !strcmp(s, "hw-romcode")) +		gpmc_nand_data->ecc_opt = +				OMAP_ECC_HAM1_CODE_HW; +	else if (!strcmp(s, "bch4")) +		if (gpmc_nand_data->elm_of_node) +			gpmc_nand_data->ecc_opt = +				OMAP_ECC_BCH4_CODE_HW; +		else +			gpmc_nand_data->ecc_opt = +				OMAP_ECC_BCH4_CODE_HW_DETECTION_SW; +	else if (!strcmp(s, "bch8")) +		if (gpmc_nand_data->elm_of_node) +			gpmc_nand_data->ecc_opt = +				OMAP_ECC_BCH8_CODE_HW; +		else +			gpmc_nand_data->ecc_opt = +				OMAP_ECC_BCH8_CODE_HW_DETECTION_SW; +	else +		pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__); +	/* select data transfer mode for NAND controller */  	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))  		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)  			if (!strcasecmp(s, nand_xfer_types[val])) { diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h index 6bf9ef43ddb..e4128f1510b 100644 --- a/include/linux/platform_data/mtd-nand-omap2.h +++ b/include/linux/platform_data/mtd-nand-omap2.h @@ -28,8 +28,16 @@ enum omap_ecc {  	OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */  		/* 1-bit ecc: stored at beginning of spare area as romcode */  	OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ -	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */ -	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */ +	/* 1-bit  ECC calculation by GPMC, Error detection by Software */ +	OMAP_ECC_HAM1_CODE_HW, +	/* 4-bit  ECC calculation by GPMC, Error detection by Software */ +	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW, +	/* 4-bit  ECC calculation by GPMC, Error detection by ELM */ +	OMAP_ECC_BCH4_CODE_HW, +	/* 8-bit  ECC calculation by GPMC, Error detection by Software */ +	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW, +	/* 8-bit  ECC calculation by GPMC, Error detection by ELM */ +	OMAP_ECC_BCH8_CODE_HW,  };  struct gpmc_nand_regs { @@ -63,5 +71,6 @@ struct omap_nand_platform_data {  	/* for passing the partitions */  	struct device_node	*of_node; +	struct device_node	*elm_of_node;  };  #endif |