All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/8] NAND support for AM33XX
@ 2012-11-06 23:06 Ilya Yanok
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 1/8] OMAP: include sys_proto.h from boot-common Ilya Yanok
                   ` (8 more replies)
  0 siblings, 9 replies; 21+ messages in thread
From: Ilya Yanok @ 2012-11-06 23:06 UTC (permalink / raw)
  To: u-boot

These series add support for NAND on AM33XX. AM33XX has the same GPMC
controller as OMAP3 so the first part of the series just add required
defines/initialization to enable the existing omap_gpmc driver to work
on AM33XX. The rest of the series adds support for BCH8 error correction
code. We use GPMC to generate codes/syndromes and ELM to find the
errors.

Changes in v2:
 -fix nand mux settings (profiles 2&3 don't have NAND)
 - rebased on current master
 - clean up mem.c (remove unused stuff that was copied from OMAP3)
 - nand headers: remove unneeded stuff
 - rebased onto master
 - minor config style fix (wrt nand)
 - fix wrong braces in Makefile

Ilya Yanok (6):
  OMAP: include sys_proto.h from boot-common
  am335x_evm: add nand pinmux definition
  am33xx: NAND support
  am335x_evm: enable NAND support
  am33xx_spl_bch: simple SPL nand loader for AM33XX
  am335x_evm: enable SPL NAND support

Mansoor Ahamed (2):
  am33xx: add ELM support
  omap_gpmc: BCH8 support (ELM based)

 arch/arm/cpu/armv7/am33xx/Makefile           |    2 +
 arch/arm/cpu/armv7/am33xx/board.c            |    1 +
 arch/arm/cpu/armv7/am33xx/clock.c            |   10 +
 arch/arm/cpu/armv7/am33xx/elm.c              |  212 ++++++++++++++
 arch/arm/cpu/armv7/am33xx/mem.c              |  101 +++++++
 arch/arm/cpu/armv7/omap-common/boot-common.c |    1 +
 arch/arm/include/asm/arch-am33xx/cpu.h       |   53 ++++
 arch/arm/include/asm/arch-am33xx/elm.h       |   93 ++++++
 arch/arm/include/asm/arch-am33xx/hardware.h  |    3 +
 arch/arm/include/asm/arch-am33xx/mem.h       |   83 ++++++
 arch/arm/include/asm/arch-am33xx/omap_gpmc.h |  120 ++++++++
 arch/arm/include/asm/arch-am33xx/sys_proto.h |    3 +
 board/ti/am335x/board.c                      |    2 +
 board/ti/am335x/mux.c                        |   22 ++
 drivers/mtd/nand/Makefile                    |    1 +
 drivers/mtd/nand/am335x_spl_bch.c            |  238 +++++++++++++++
 drivers/mtd/nand/omap_gpmc.c                 |  403 +++++++++++++++++++++++++-
 include/configs/am335x_evm.h                 |   46 +++
 18 files changed, 1393 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/armv7/am33xx/elm.c
 create mode 100644 arch/arm/cpu/armv7/am33xx/mem.c
 create mode 100644 arch/arm/include/asm/arch-am33xx/elm.h
 create mode 100644 arch/arm/include/asm/arch-am33xx/mem.h
 create mode 100644 arch/arm/include/asm/arch-am33xx/omap_gpmc.h
 create mode 100644 drivers/mtd/nand/am335x_spl_bch.c

-- 
1.7.10.2 (Apple Git-33)

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 1/8] OMAP: include sys_proto.h from boot-common
  2012-11-06 23:06 [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Ilya Yanok
@ 2012-11-06 23:06 ` Ilya Yanok
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 2/8] am335x_evm: add nand pinmux definition Ilya Yanok
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Ilya Yanok @ 2012-11-06 23:06 UTC (permalink / raw)
  To: u-boot

Include asm/arch/sys_proto.h for gpmc_init prototype.
Without this we get a warning while building for AM335x.

Signed-off-by: Ilya Yanok <ilya.yanok@cogentembedded.com>
---

 arch/arm/cpu/armv7/omap-common/boot-common.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c
index 0f19141..2b584e0 100644
--- a/arch/arm/cpu/armv7/omap-common/boot-common.c
+++ b/arch/arm/cpu/armv7/omap-common/boot-common.c
@@ -21,6 +21,7 @@
 #include <asm/omap_common.h>
 #include <asm/arch/omap.h>
 #include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
 
 /*
  * This is used to verify if the configuration header
-- 
1.7.10.2 (Apple Git-33)

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 2/8] am335x_evm: add nand pinmux definition
  2012-11-06 23:06 [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Ilya Yanok
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 1/8] OMAP: include sys_proto.h from boot-common Ilya Yanok
@ 2012-11-06 23:06 ` Ilya Yanok
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 3/8] am33xx: NAND support Ilya Yanok
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Ilya Yanok @ 2012-11-06 23:06 UTC (permalink / raw)
  To: u-boot

Add NAND pins mux settings for AM335X devices. Enable NAND pins
for AM335X EVM board.

Signed-off-by: Ilya Yanok <ilya.yanok@cogentembedded.com>

---
Changes in v2:
 -fix nand mux settings (profiles 2&3 don't have NAND)

 board/ti/am335x/mux.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/board/ti/am335x/mux.c b/board/ti/am335x/mux.c
index 8437ef5..0283708 100644
--- a/board/ti/am335x/mux.c
+++ b/board/ti/am335x/mux.c
@@ -171,6 +171,25 @@ static struct module_pin_mux mii1_pin_mux[] = {
 	{-1},
 };
 
+static struct module_pin_mux nand_pin_mux[] = {
+	{OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD0 */
+	{OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD1 */
+	{OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD2 */
+	{OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD3 */
+	{OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD4 */
+	{OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD5 */
+	{OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD6 */
+	{OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD7 */
+	{OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */
+	{OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)},	/* NAND_WPN */
+	{OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)},	/* NAND_CS0 */
+	{OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */
+	{OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)},	/* NAND_OE */
+	{OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)},	/* NAND_WEN */
+	{OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)},	/* NAND_BE_CLE */
+	{-1},
+};
+
 void enable_uart0_pin_mux(void)
 {
 	configure_module_pin_mux(uart0_pin_mux);
@@ -257,6 +276,9 @@ void enable_board_pin_mux(struct am335x_baseboard_id *header)
 		/* In profile #2 i2c1 and spi0 conflict. */
 		if (profile & ~PROFILE_2)
 			configure_module_pin_mux(i2c1_pin_mux);
+		/* Profiles 2 & 3 don't have NAND */
+		if (profile & ~(PROFILE_2 | PROFILE_3))
+			configure_module_pin_mux(nand_pin_mux);
 		else if (profile == PROFILE_2) {
 			configure_module_pin_mux(mmc1_pin_mux);
 			configure_module_pin_mux(spi0_pin_mux);
-- 
1.7.10.2 (Apple Git-33)

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 3/8] am33xx: NAND support
  2012-11-06 23:06 [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Ilya Yanok
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 1/8] OMAP: include sys_proto.h from boot-common Ilya Yanok
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 2/8] am335x_evm: add nand pinmux definition Ilya Yanok
@ 2012-11-06 23:06 ` Ilya Yanok
  2012-11-08  9:33   ` Peter Korsgaard
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 4/8] am335x_evm: enable " Ilya Yanok
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Ilya Yanok @ 2012-11-06 23:06 UTC (permalink / raw)
  To: u-boot

TI AM33XX has the same GPMC controller as OMAP3 so we could just use the
existing omap_gpmc driver. This patch adds adds required
definitions/intialization.

Signed-off-by: Ilya Yanok <ilya.yanok@cogentembedded.com>

---
Changes in v2:
 - rebased on current master
 - clean up mem.c (remove unused stuff that was copied from OMAP3)
 - nand headers: remove unneeded stuff

 arch/arm/cpu/armv7/am33xx/Makefile           |    1 +
 arch/arm/cpu/armv7/am33xx/board.c            |    1 +
 arch/arm/cpu/armv7/am33xx/clock.c            |    5 ++
 arch/arm/cpu/armv7/am33xx/mem.c              |  101 ++++++++++++++++++++++
 arch/arm/include/asm/arch-am33xx/cpu.h       |   53 ++++++++++++
 arch/arm/include/asm/arch-am33xx/hardware.h  |    3 +
 arch/arm/include/asm/arch-am33xx/mem.h       |   83 ++++++++++++++++++
 arch/arm/include/asm/arch-am33xx/omap_gpmc.h |  120 ++++++++++++++++++++++++++
 arch/arm/include/asm/arch-am33xx/sys_proto.h |    3 +
 9 files changed, 370 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/am33xx/mem.c
 create mode 100644 arch/arm/include/asm/arch-am33xx/mem.h
 create mode 100644 arch/arm/include/asm/arch-am33xx/omap_gpmc.h

diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile
index 74875b3..f565357 100644
--- a/arch/arm/cpu/armv7/am33xx/Makefile
+++ b/arch/arm/cpu/armv7/am33xx/Makefile
@@ -18,6 +18,7 @@ LIB	= $(obj)lib$(SOC).o
 
 COBJS	+= clock.o
 COBJS	+= sys_info.o
+COBJS	+= mem.o
 COBJS	+= ddr.o
 COBJS	+= emif4.o
 COBJS	+= board.o
diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c
index e4c123c..c756c09 100644
--- a/arch/arm/cpu/armv7/am33xx/board.c
+++ b/arch/arm/cpu/armv7/am33xx/board.c
@@ -25,6 +25,7 @@
 #include <asm/arch/ddr_defs.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/gpio.h>
+#include <asm/arch/mem.h>
 #include <asm/arch/mmc_host_def.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/io.h>
diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c
index bc2abb6..6eb7d9f 100644
--- a/arch/arm/cpu/armv7/am33xx/clock.c
+++ b/arch/arm/cpu/armv7/am33xx/clock.c
@@ -150,6 +150,11 @@ static void enable_per_clocks(void)
 		;
 #endif /* CONFIG_SERIAL6 */
 
+	/* GPMC */
+	writel(PRCM_MOD_EN, &cmper->gpmcclkctrl);
+	while (readl(&cmper->gpmcclkctrl) != PRCM_MOD_EN)
+		;
+
 	/* MMC0*/
 	writel(PRCM_MOD_EN, &cmper->mmc0clkctrl);
 	while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN)
diff --git a/arch/arm/cpu/armv7/am33xx/mem.c b/arch/arm/cpu/armv7/am33xx/mem.c
new file mode 100644
index 0000000..b8f54ab
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/mem.c
@@ -0,0 +1,101 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *     Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * Initial Code from:
+ *     Manikandan Pillai <mani.pillai@ti.com>
+ *     Richard Woodruff <r-woodruff2@ti.com>
+ *     Syed Mohammed Khasim <khasim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/sys_proto.h>
+#include <command.h>
+
+struct gpmc *gpmc_cfg;
+
+#if defined(CONFIG_CMD_NAND)
+static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
+	M_NAND_GPMC_CONFIG1,
+	M_NAND_GPMC_CONFIG2,
+	M_NAND_GPMC_CONFIG3,
+	M_NAND_GPMC_CONFIG4,
+	M_NAND_GPMC_CONFIG5,
+	M_NAND_GPMC_CONFIG6, 0
+};
+#endif
+
+
+void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
+			u32 size)
+{
+	writel(0, &cs->config7);
+	sdelay(1000);
+	/* Delay for settling */
+	writel(gpmc_config[0], &cs->config1);
+	writel(gpmc_config[1], &cs->config2);
+	writel(gpmc_config[2], &cs->config3);
+	writel(gpmc_config[3], &cs->config4);
+	writel(gpmc_config[4], &cs->config5);
+	writel(gpmc_config[5], &cs->config6);
+	/* Enable the config */
+	writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) |
+		(1 << 6)), &cs->config7);
+	sdelay(2000);
+}
+
+/*****************************************************
+ * gpmc_init(): init gpmc bus
+ * Init GPMC for x16, MuxMode (SDRAM in x32).
+ * This code can only be executed from SRAM or SDRAM.
+ *****************************************************/
+void gpmc_init(void)
+{
+	/* putting a blanket check on GPMC based on ZeBu for now */
+	gpmc_cfg = (struct gpmc *)GPMC_BASE;
+
+#ifdef CONFIG_CMD_NAND
+	const u32 *gpmc_config = NULL;
+	u32 base = 0;
+	u32 size = 0;
+#endif
+	/* global settings */
+	writel(0x00000008, &gpmc_cfg->sysconfig);
+	writel(0x00000100, &gpmc_cfg->irqstatus);
+	writel(0x00000200, &gpmc_cfg->irqenable);
+	writel(0x00000012, &gpmc_cfg->config);
+	/*
+	 * Disable the GPMC0 config set by ROM code
+	 */
+	writel(0, &gpmc_cfg->cs[0].config7);
+	sdelay(1000);
+
+#ifdef CONFIG_CMD_NAND
+	gpmc_config = gpmc_m_nand;
+
+	base = PISMO1_NAND_BASE;
+	size = PISMO1_NAND_SIZE;
+	enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
+#endif
+}
diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h
index 819fd2f..b91441f 100644
--- a/arch/arm/include/asm/arch-am33xx/cpu.h
+++ b/arch/arm/include/asm/arch-am33xx/cpu.h
@@ -60,6 +60,59 @@
 
 #ifndef __KERNEL_STRICT_NAMES
 #ifndef __ASSEMBLY__
+struct gpmc_cs {
+	u32 config1;		/* 0x00 */
+	u32 config2;		/* 0x04 */
+	u32 config3;		/* 0x08 */
+	u32 config4;		/* 0x0C */
+	u32 config5;		/* 0x10 */
+	u32 config6;		/* 0x14 */
+	u32 config7;		/* 0x18 */
+	u32 nand_cmd;		/* 0x1C */
+	u32 nand_adr;		/* 0x20 */
+	u32 nand_dat;		/* 0x24 */
+	u8 res[8];		/* blow up to 0x30 byte */
+};
+
+struct bch_res_0_3 {
+	u32 bch_result_x[4];
+};
+
+struct gpmc {
+	u8 res1[0x10];
+	u32 sysconfig;		/* 0x10 */
+	u8 res2[0x4];
+	u32 irqstatus;		/* 0x18 */
+	u32 irqenable;		/* 0x1C */
+	u8 res3[0x20];
+	u32 timeout_control;	/* 0x40 */
+	u8 res4[0xC];
+	u32 config;		/* 0x50 */
+	u32 status;		/* 0x54 */
+	u8 res5[0x8];		/* 0x58 */
+	struct gpmc_cs cs[8];	/* 0x60, 0x90, .. */
+	u8 res6[0x14];		/* 0x1E0 */
+	u32 ecc_config;		/* 0x1F4 */
+	u32 ecc_control;	/* 0x1F8 */
+	u32 ecc_size_config;	/* 0x1FC */
+	u32 ecc1_result;	/* 0x200 */
+	u32 ecc2_result;	/* 0x204 */
+	u32 ecc3_result;	/* 0x208 */
+	u32 ecc4_result;	/* 0x20C */
+	u32 ecc5_result;	/* 0x210 */
+	u32 ecc6_result;	/* 0x214 */
+	u32 ecc7_result;	/* 0x218 */
+	u32 ecc8_result;	/* 0x21C */
+	u32 ecc9_result;	/* 0x220 */
+	u8 res7[12];		/* 0x224 */
+	u32 testmomde_ctrl;	/* 0x230 */
+	u8 res8[12];		/* 0x234 */
+	struct bch_res_0_3 bch_result_0_3[2];	/* 0x240 */
+};
+
+/* Used for board specific gpmc initialization */
+extern struct gpmc *gpmc_cfg;
+
 /* Encapsulating core pll registers */
 struct cm_wkuppll {
 	unsigned int wkclkstctrl;	/* offset 0x00 */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware.h b/arch/arm/include/asm/arch-am33xx/hardware.h
index 5bd4bc8..b3922d9 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware.h
@@ -80,6 +80,9 @@
 #define DDRPHY_0_CONFIG_BASE		(CTRL_BASE + 0x1400)
 #define DDRPHY_CONFIG_BASE		DDRPHY_0_CONFIG_BASE
 
+/* GPMC Base address */
+#define GPMC_BASE			0x50000000
+
 /* CPSW Config space */
 #define AM335X_CPSW_BASE		0x4A100000
 #define AM335X_CPSW_MDIO_BASE		0x4A101000
diff --git a/arch/arm/include/asm/arch-am33xx/mem.h b/arch/arm/include/asm/arch-am33xx/mem.h
new file mode 100644
index 0000000..c3bf74e
--- /dev/null
+++ b/arch/arm/include/asm/arch-am33xx/mem.h
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2006-2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author
+ *		Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * Initial Code from:
+ *		Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MEM_H_
+#define _MEM_H_
+
+/*
+ * GPMC settings -
+ * Definitions is as per the following format
+ * #define <PART>_GPMC_CONFIG<x> <value>
+ * Where:
+ * PART is the part name e.g. STNOR - Intel Strata Flash
+ * x is GPMC config registers from 1 to 6 (there will be 6 macros)
+ * Value is corresponding value
+ *
+ * For every valid PRCM configuration there should be only one definition of
+ * the same. if values are independent of the board, this definition will be
+ * present in this file if values are dependent on the board, then this should
+ * go into corresponding mem-boardName.h file
+ *
+ * Currently valid part Names are (PART):
+ * M_NAND - Micron NAND
+ */
+#define GPMC_SIZE_256M		0x0
+#define GPMC_SIZE_128M		0x8
+#define GPMC_SIZE_64M		0xC
+#define GPMC_SIZE_32M		0xE
+#define GPMC_SIZE_16M		0xF
+
+#define M_NAND_GPMC_CONFIG1	0x00000800
+#define M_NAND_GPMC_CONFIG2	0x001e1e00
+#define M_NAND_GPMC_CONFIG3	0x001e1e00
+#define M_NAND_GPMC_CONFIG4	0x16051807
+#define M_NAND_GPMC_CONFIG5	0x00151e1e
+#define M_NAND_GPMC_CONFIG6	0x16000f80
+#define M_NAND_GPMC_CONFIG7	0x00000008
+
+/* max number of GPMC Chip Selects */
+#define GPMC_MAX_CS		8
+/* max number of GPMC regs */
+#define GPMC_MAX_REG		7
+
+#define PISMO1_NOR		1
+#define PISMO1_NAND		2
+#define PISMO2_CS0		3
+#define PISMO2_CS1		4
+#define PISMO1_ONENAND		5
+#define DBG_MPDB		6
+#define PISMO2_NAND_CS0		7
+#define PISMO2_NAND_CS1		8
+
+/* make it readable for the gpmc_init */
+#define PISMO1_NOR_BASE	FLASH_BASE
+#define PISMO1_NAND_BASE	CONFIG_SYS_NAND_BASE
+#define PISMO1_NAND_SIZE	GPMC_SIZE_256M
+
+#endif /* endif _MEM_H_ */
diff --git a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
new file mode 100644
index 0000000..572f9d0
--- /dev/null
+++ b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
@@ -0,0 +1,120 @@
+/*
+ * (C) Copyright 2004-2008 Texas Instruments, <www.ti.com>
+ * Rohit Choraria <rohitkc@ti.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_ARCH_OMAP_GPMC_H
+#define __ASM_ARCH_OMAP_GPMC_H
+
+#define GPMC_BUF_EMPTY	0
+#define GPMC_BUF_FULL	1
+
+#define ECCCLEAR	(0x1 << 8)
+#define ECCRESULTREG1	(0x1 << 0)
+#define ECCSIZE512BYTE	0xFF
+#define ECCSIZE1	(ECCSIZE512BYTE << 22)
+#define ECCSIZE0	(ECCSIZE512BYTE << 12)
+#define ECCSIZE0SEL	(0x000 << 0)
+
+/* Generic ECC Layouts */
+/* Large Page x8 NAND device Layout */
+#ifdef GPMC_NAND_ECC_LP_x8_LAYOUT
+#define GPMC_NAND_HW_ECC_LAYOUT {\
+	.eccbytes = 12,\
+	.eccpos = {1, 2, 3, 4, 5, 6, 7, 8,\
+		9, 10, 11, 12},\
+	.oobfree = {\
+		{.offset = 13,\
+		 .length = 51 } } \
+}
+#endif
+
+/* Large Page x16 NAND device Layout */
+#ifdef GPMC_NAND_ECC_LP_x16_LAYOUT
+#define GPMC_NAND_HW_ECC_LAYOUT {\
+	.eccbytes = 12,\
+	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9,\
+		10, 11, 12, 13},\
+	.oobfree = {\
+		{.offset = 14,\
+		 .length = 50 } } \
+}
+#endif
+
+/* Small Page x8 NAND device Layout */
+#ifdef GPMC_NAND_ECC_SP_x8_LAYOUT
+#define GPMC_NAND_HW_ECC_LAYOUT {\
+	.eccbytes = 3,\
+	.eccpos = {1, 2, 3},\
+	.oobfree = {\
+		{.offset = 4,\
+		 .length = 12 } } \
+}
+#endif
+
+/* Small Page x16 NAND device Layout */
+#ifdef GPMC_NAND_ECC_SP_x16_LAYOUT
+#define GPMC_NAND_HW_ECC_LAYOUT {\
+	.eccbytes = 3,\
+	.eccpos = {2, 3, 4},\
+	.oobfree = {\
+		{.offset = 5,\
+		 .length = 11 } } \
+}
+#endif
+
+#define GPMC_NAND_HW_BCH4_ECC_LAYOUT {\
+	.eccbytes = 32,\
+	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
+				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
+				28, 29, 30, 31, 32, 33},\
+	.oobfree = {\
+		{.offset = 34,\
+		 .length = 30 } } \
+}
+
+#define GPMC_NAND_HW_BCH8_ECC_LAYOUT {\
+	.eccbytes = 56,\
+	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
+				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
+				28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
+				40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
+				52, 53, 54, 55, 56, 57},\
+	.oobfree = {\
+		{.offset = 58,\
+		 .length = 6 } } \
+}
+
+#define GPMC_NAND_HW_BCH16_ECC_LAYOUT {\
+	.eccbytes = 104,\
+	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
+				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
+				28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
+				40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
+				52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\
+				64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,\
+				76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,\
+				88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\
+				100, 101, 102, 103, 104, 105},\
+	.oobfree = {\
+		{.offset = 106,\
+		 .length = 8 } } \
+}
+#endif /* __ASM_ARCH_OMAP_GPMC_H */
diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h b/arch/arm/include/asm/arch-am33xx/sys_proto.h
index 9cf35e0..588d8de 100644
--- a/arch/arm/include/asm/arch-am33xx/sys_proto.h
+++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h
@@ -33,4 +33,7 @@ u32 get_device_type(void);
 void setup_clocks_for_console(void);
 void ddr_pll_config(unsigned int ddrpll_M);
 
+void sdelay(unsigned long);
+void gpmc_init(void);
+void omap_nand_switch_ecc(int);
 #endif
-- 
1.7.10.2 (Apple Git-33)

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 4/8] am335x_evm: enable NAND support
  2012-11-06 23:06 [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Ilya Yanok
                   ` (2 preceding siblings ...)
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 3/8] am33xx: NAND support Ilya Yanok
@ 2012-11-06 23:06 ` Ilya Yanok
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 5/8] am33xx: add ELM support Ilya Yanok
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Ilya Yanok @ 2012-11-06 23:06 UTC (permalink / raw)
  To: u-boot

Enable NAND support for AM335X boards.

Signed-off-by: Ilya Yanok <ilya.yanok@cogentembedded.com>

---
Changes in v2:
 - rebased onto master
 - minor config style fix (wrt nand)

 board/ti/am335x/board.c      |    2 ++
 include/configs/am335x_evm.h |   12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index b56a801..6908378 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -318,6 +318,8 @@ int board_init(void)
 
 	gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
 
+	gpmc_init();
+
 	return 0;
 }
 
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index b6e48f8..ded1cab 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -274,4 +274,16 @@
 #define CONFIG_PHYLIB
 #define CONFIG_PHY_SMSC
 
+#define CONFIG_NAND
+/* NAND support */
+#ifdef CONFIG_NAND
+#define CONFIG_CMD_NAND
+#define CONFIG_NAND_OMAP_GPMC
+#define GPMC_NAND_ECC_LP_x16_LAYOUT	1
+#define CONFIG_SYS_NAND_BASE		(0x08000000)	/* physical address */
+							/* to access nand at */
+							/* CS0 */
+#define CONFIG_SYS_MAX_NAND_DEVICE	1		/* Max number of NAND */
+#endif							/* devices */
+
 #endif	/* ! __CONFIG_AM335X_EVM_H */
-- 
1.7.10.2 (Apple Git-33)

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 5/8] am33xx: add ELM support
  2012-11-06 23:06 [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Ilya Yanok
                   ` (3 preceding siblings ...)
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 4/8] am335x_evm: enable " Ilya Yanok
@ 2012-11-06 23:06 ` Ilya Yanok
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based) Ilya Yanok
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 21+ messages in thread
From: Ilya Yanok @ 2012-11-06 23:06 UTC (permalink / raw)
  To: u-boot

From: Mansoor Ahamed <mansoor.ahamed@ti.com>

AM33XX has Error Location Module (ELM) that can be used in conjuction
with GPMC controller to implement BCH codes fully in hardware.
This code is mostly taken from arago tree.

Signed-off-by: Mansoor Ahamed <mansoor.ahamed@ti.com>
Signed-off-by: Ilya Yanok <ilya.yanok@cogentembedded.com>

---
Changes in v2:
 - fix wrong braces in Makefile

 arch/arm/cpu/armv7/am33xx/Makefile     |    1 +
 arch/arm/cpu/armv7/am33xx/clock.c      |    5 +
 arch/arm/cpu/armv7/am33xx/elm.c        |  212 ++++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-am33xx/elm.h |   93 ++++++++++++++
 4 files changed, 311 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/am33xx/elm.c
 create mode 100644 arch/arm/include/asm/arch-am33xx/elm.h

diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile
index f565357..70c443e 100644
--- a/arch/arm/cpu/armv7/am33xx/Makefile
+++ b/arch/arm/cpu/armv7/am33xx/Makefile
@@ -23,6 +23,7 @@ COBJS	+= ddr.o
 COBJS	+= emif4.o
 COBJS	+= board.o
 COBJS	+= mux.o
+COBJS-$(CONFIG_NAND_OMAP_GPMC)	+= elm.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c
index 6eb7d9f..2b7c910 100644
--- a/arch/arm/cpu/armv7/am33xx/clock.c
+++ b/arch/arm/cpu/armv7/am33xx/clock.c
@@ -155,6 +155,11 @@ static void enable_per_clocks(void)
 	while (readl(&cmper->gpmcclkctrl) != PRCM_MOD_EN)
 		;
 
+	/* ELM */
+	writel(PRCM_MOD_EN, &cmper->elmclkctrl);
+	while (readl(&cmper->elmclkctrl) != PRCM_MOD_EN)
+		;
+
 	/* MMC0*/
 	writel(PRCM_MOD_EN, &cmper->mmc0clkctrl);
 	while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN)
diff --git a/arch/arm/cpu/armv7/am33xx/elm.c b/arch/arm/cpu/armv7/am33xx/elm.c
new file mode 100644
index 0000000..9eed23d
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/elm.c
@@ -0,0 +1,212 @@
+/*
+ * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
+ * Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * BCH Error Location Module (ELM) support.
+ *
+ * NOTE:
+ * 1. Supports only continuous mode. Dont see need for page mode in uboot
+ * 2. Supports only syndrome polynomial 0. i.e. poly local variable is
+ *    always set to ELM_DEFAULT_POLY. Dont see need for other polynomial
+ *    sets in uboot
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/omap_gpmc.h>
+#include <asm/arch/elm.h>
+
+#define ELM_DEFAULT_POLY (0)
+
+struct elm *elm_cfg;
+
+/**
+ * elm_load_syndromes - Load BCH syndromes based on nibble selection
+ * @syndrome: BCH syndrome
+ * @nibbles:
+ * @poly: Syndrome Polynomial set to use
+ *
+ * Load BCH syndromes based on nibble selection
+ */
+static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
+{
+	u32 *ptr;
+	u32 val;
+
+	/* reg 0 */
+	ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[0];
+	val = syndrome[0] | (syndrome[1] << 8) | (syndrome[2] << 16) |
+				(syndrome[3] << 24);
+	writel(val, ptr);
+	/* reg 1 */
+	ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[1];
+	val = syndrome[4] | (syndrome[5] << 8) | (syndrome[6] << 16) |
+				(syndrome[7] << 24);
+	writel(val, ptr);
+
+	/* BCH 8-bit with 26 nibbles (4*8=32) */
+	if (nibbles > 13) {
+		/* reg 2 */
+		ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2];
+		val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) |
+				(syndrome[11] << 24);
+		writel(val, ptr);
+		/* reg 3 */
+		ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[3];
+		val = syndrome[12] | (syndrome[13] << 8) |
+			(syndrome[14] << 16) | (syndrome[15] << 24);
+		writel(val, ptr);
+	}
+
+	/* BCH 16-bit with 52 nibbles (7*8=56) */
+	if (nibbles > 26) {
+		/* reg 4 */
+		ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4];
+		val = syndrome[16] | (syndrome[17] << 8) |
+			(syndrome[18] << 16) | (syndrome[19] << 24);
+		writel(val, ptr);
+
+		/* reg 5 */
+		ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[5];
+		val = syndrome[20] | (syndrome[21] << 8) |
+			(syndrome[22] << 16) | (syndrome[23] << 24);
+		writel(val, ptr);
+
+		/* reg 6 */
+		ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6];
+		val = syndrome[24] | (syndrome[25] << 8) |
+			(syndrome[26] << 16) | (syndrome[27] << 24);
+		writel(val, ptr);
+	}
+}
+
+/**
+ * elm_check_errors - Check for BCH errors and return error locations
+ * @syndrome: BCH syndrome
+ * @nibbles:
+ * @error_count: Returns number of errrors in the syndrome
+ * @error_locations: Returns error locations (in decimal) in this array
+ *
+ * Check the provided syndrome for BCH errors and return error count
+ * and locations in the array passed. Returns -1 if error is not correctable,
+ * else returns 0
+ */
+int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
+		u32 *error_locations)
+{
+	u8 poly = ELM_DEFAULT_POLY;
+	s8 i;
+	u32 location_status;
+
+	elm_load_syndromes(syndrome, nibbles, poly);
+
+	/* start processing */
+	writel((readl(&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6])
+				| ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID),
+		&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]);
+
+	/* wait for processing to complete */
+	while ((readl(&elm_cfg->irqstatus) & (0x1 << poly)) != 0x1)
+		;
+	/* clear status */
+	writel((readl(&elm_cfg->irqstatus) | (0x1 << poly)),
+			&elm_cfg->irqstatus);
+
+	/* check if correctable */
+	location_status = readl(&elm_cfg->error_location[poly].location_status);
+	if (!(location_status & ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK))
+		return -1;
+
+	/* get error count */
+	*error_count = readl(&elm_cfg->error_location[poly].location_status) &
+					ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK;
+
+	for (i = 0; i < *error_count; i++) {
+		error_locations[i] =
+			readl(&elm_cfg->error_location[poly].error_location_x[i]);
+	}
+
+	return 0;
+}
+
+
+/**
+ * elm_config - Configure ELM module
+ * @level: 4 / 8 / 16 bit BCH
+ *
+ * Configure ELM module based on BCH level.
+ * Set mode as continuous mode.
+ * Currently we are using only syndrome 0 and syndromes 1 to 6 are not used.
+ * Also, the mode is set only for syndrome 0
+ */
+int elm_config(enum bch_level level)
+{
+	u32 val;
+	u8 poly = ELM_DEFAULT_POLY;
+	u32 buffer_size = 0x7FF;
+
+	/* config size and level */
+	val = (u32)(level) & ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK;
+	val |= ((buffer_size << ELM_LOCATION_CONFIG_ECC_SIZE_POS) &
+				ELM_LOCATION_CONFIG_ECC_SIZE_MASK);
+	writel(val, &elm_cfg->location_config);
+
+	/* config continous mode */
+	/* enable interrupt generation for syndrome polynomial set */
+	writel((readl(&elm_cfg->irqenable) | (0x1 << poly)),
+			&elm_cfg->irqenable);
+	/* set continuous mode for the syndrome polynomial set */
+	writel((readl(&elm_cfg->page_ctrl) & ~(0x1 << poly)),
+			&elm_cfg->page_ctrl);
+
+	return 0;
+}
+
+/**
+ * elm_reset - Do a soft reset of ELM
+ *
+ * Perform a soft reset of ELM and return after reset is done.
+ */
+void elm_reset(void)
+{
+	/* initiate reset */
+	writel((readl(&elm_cfg->sysconfig) | ELM_SYSCONFIG_SOFTRESET),
+				&elm_cfg->sysconfig);
+
+	/* wait for reset complete and normal operation */
+	while ((readl(&elm_cfg->sysstatus) & ELM_SYSSTATUS_RESETDONE) !=
+		ELM_SYSSTATUS_RESETDONE)
+		;
+}
+
+/**
+ * elm_init - Initialize ELM module
+ *
+ * Initialize ELM support. Currently it does only base address init
+ * and ELM reset.
+ */
+void elm_init(void)
+{
+	elm_cfg = (struct elm *)ELM_BASE;
+	elm_reset();
+}
diff --git a/arch/arm/include/asm/arch-am33xx/elm.h b/arch/arm/include/asm/arch-am33xx/elm.h
new file mode 100644
index 0000000..e80f7d4
--- /dev/null
+++ b/arch/arm/include/asm/arch-am33xx/elm.h
@@ -0,0 +1,93 @@
+/*
+ * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
+ * Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * Derived from work done by Rohit Choraria <rohitkc@ti.com> for omap3
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef __ASM_ARCH_ELM_H
+#define __ASM_ARCH_ELM_H
+/*
+ * ELM Module Registers
+ */
+
+/* ELM registers bit fields */
+#define ELM_SYSCONFIG_SOFTRESET_MASK			(0x2)
+#define ELM_SYSCONFIG_SOFTRESET			(0x2)
+#define ELM_SYSSTATUS_RESETDONE_MASK			(0x1)
+#define ELM_SYSSTATUS_RESETDONE			(0x1)
+#define ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK		(0x3)
+#define ELM_LOCATION_CONFIG_ECC_SIZE_MASK		(0x7FF0000)
+#define ELM_LOCATION_CONFIG_ECC_SIZE_POS		(16)
+#define ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID		(0x00010000)
+#define ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK	(0x100)
+#define ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK		(0x1F)
+
+#ifndef __ASSEMBLY__
+
+enum bch_level {
+	BCH_4_BIT = 0,
+	BCH_8_BIT,
+	BCH_16_BIT
+};
+
+
+/* BCH syndrome registers */
+struct syndrome {
+	u32 syndrome_fragment_x[7];	/* 0x400, 0x404.... 0x418 */
+	u8 res1[36];			/* 0x41c */
+};
+
+/* BCH error status & location register */
+struct location {
+	u32 location_status;		/* 0x800 */
+	u8 res1[124];			/* 0x804 */
+	u32 error_location_x[16];	/* 0x880.... */
+	u8 res2[64];			/* 0x8c0 */
+};
+
+/* BCH ELM register map - do not try to allocate memmory for this structure.
+ * We have used plenty of reserved variables to fill the slots in the ELM
+ * register memory map.
+ * Directly initialize the struct pointer to ELM base address.
+ */
+struct elm {
+	u32 rev;				/* 0x000 */
+	u8 res1[12];				/* 0x004 */
+	u32 sysconfig;				/* 0x010 */
+	u32 sysstatus;				/* 0x014 */
+	u32 irqstatus;				/* 0x018 */
+	u32 irqenable;				/* 0x01c */
+	u32 location_config;			/* 0x020 */
+	u8 res2[92];				/* 0x024 */
+	u32 page_ctrl;				/* 0x080 */
+	u8 res3[892];				/* 0x084 */
+	struct  syndrome syndrome_fragments[8]; /* 0x400 */
+	u8 res4[512];				/* 0x600 */
+	struct location  error_location[8];	/* 0x800 */
+};
+
+int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
+		u32 *error_locations);
+int elm_config(enum bch_level level);
+void elm_reset(void);
+void elm_init(void);
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_ELM_H */
-- 
1.7.10.2 (Apple Git-33)

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based)
  2012-11-06 23:06 [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Ilya Yanok
                   ` (4 preceding siblings ...)
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 5/8] am33xx: add ELM support Ilya Yanok
@ 2012-11-06 23:06 ` Ilya Yanok
  2012-11-15 13:25   ` Andreas Bießmann
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 7/8] am33xx_spl_bch: simple SPL nand loader for AM33XX Ilya Yanok
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Ilya Yanok @ 2012-11-06 23:06 UTC (permalink / raw)
  To: u-boot

From: Mansoor Ahamed <mansoor.ahamed@ti.com>

This patch adds support for BCH8 error correction code to omap_gpmc
driver. We use GPMC to generate codes/syndromes but we need ELM to find
error locations from given syndrome.

Signed-off-by: Mansoor Ahamed <mansoor.ahamed@ti.com>
[ilya: merge it with omap_gpmc driver, some fixes and cleanup]
Signed-off-by: Ilya Yanok <ilya.yanok@cogentembedded.com>
---

 drivers/mtd/nand/omap_gpmc.c |  403 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 402 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index f1469d1..cee394e 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -29,6 +29,9 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/compiler.h>
 #include <nand.h>
+#ifdef CONFIG_AM33XX
+#include <asm/arch/elm.h>
+#endif
 
 static uint8_t cs;
 static __maybe_unused struct nand_ecclayout hw_nand_oob =
@@ -234,6 +237,370 @@ static void __maybe_unused omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
 	}
 }
 
+/*
+ * BCH8 support (needs ELM and thus AM33xx-only)
+ */
+#ifdef CONFIG_AM33XX
+struct nand_bch_priv {
+	uint8_t mode;
+	uint8_t type;
+	uint8_t nibbles;
+};
+
+/* bch types */
+#define ECC_BCH4	0
+#define ECC_BCH8	1
+#define ECC_BCH16	2
+
+/* BCH nibbles for diff bch levels */
+#define NAND_ECC_HW_BCH ((uint8_t)(NAND_ECC_HW_OOB_FIRST) + 1)
+#define ECC_BCH4_NIBBLES	13
+#define ECC_BCH8_NIBBLES	26
+#define ECC_BCH16_NIBBLES	52
+
+static struct nand_ecclayout hw_bch8_nand_oob = GPMC_NAND_HW_BCH8_ECC_LAYOUT;
+
+static struct nand_bch_priv bch_priv = {
+	.mode = NAND_ECC_HW_BCH,
+	.type = ECC_BCH8,
+	.nibbles = ECC_BCH8_NIBBLES
+};
+
+/*
+ * omap_read_bch8_result - Read BCH result for BCH8 level
+ *
+ * @mtd:	MTD device structure
+ * @big_endian:	When set read register 3 first
+ * @ecc_code:	Read syndrome from BCH result registers
+ */
+static void omap_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian,
+				uint8_t *ecc_code)
+{
+	uint32_t *ptr;
+	int8_t i = 0, j;
+
+	if (big_endian) {
+		ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
+		ecc_code[i++] = readl(ptr) & 0xFF;
+		ptr--;
+		for (j = 0; j < 3; j++) {
+			ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
+			ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
+			ecc_code[i++] = (readl(ptr) >>  8) & 0xFF;
+			ecc_code[i++] = readl(ptr) & 0xFF;
+			ptr--;
+		}
+	} else {
+		ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[0];
+		for (j = 0; j < 3; j++) {
+			ecc_code[i++] = readl(ptr) & 0xFF;
+			ecc_code[i++] = (readl(ptr) >>  8) & 0xFF;
+			ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
+			ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
+			ptr++;
+		}
+		ecc_code[i++] = readl(ptr) & 0xFF;
+		ecc_code[i++] = 0;	/* 14th byte is always zero */
+	}
+}
+
+/*
+ * omap_ecc_disable - Disable H/W ECC calculation
+ *
+ * @mtd:	MTD device structure
+ *
+ */
+static void omap_ecc_disable(struct mtd_info *mtd)
+{
+	writel((readl(&gpmc_cfg->ecc_config) & ~0x1),
+		&gpmc_cfg->ecc_config);
+}
+
+/*
+ * omap_rotate_ecc_bch - Rotate the syndrome bytes
+ *
+ * @mtd:	MTD device structure
+ * @calc_ecc:	ECC read from ECC registers
+ * @syndrome:	Rotated syndrome will be retuned in this array
+ *
+ */
+static void omap_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc,
+		uint8_t *syndrome)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct nand_bch_priv *bch = chip->priv;
+	uint8_t n_bytes = 0;
+	int8_t i, j;
+
+	switch (bch->type) {
+	case ECC_BCH4:
+		n_bytes = 8;
+		break;
+
+	case ECC_BCH16:
+		n_bytes = 28;
+		break;
+
+	case ECC_BCH8:
+	default:
+		n_bytes = 13;
+		break;
+	}
+
+	for (i = 0, j = (n_bytes-1); i < n_bytes; i++, j--)
+		syndrome[i] =  calc_ecc[j];
+}
+
+/*
+ *  omap_calculate_ecc_bch - Read BCH ECC result
+ *
+ *  @mtd:	MTD structure
+ *  @dat:	unused
+ *  @ecc_code:	ecc_code buffer
+ */
+static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
+				uint8_t *ecc_code)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct nand_bch_priv *bch = chip->priv;
+	uint8_t big_endian = 1;
+	int8_t ret = 0;
+
+	if (bch->type == ECC_BCH8)
+		omap_read_bch8_result(mtd, big_endian, ecc_code);
+	else /* BCH4 and BCH16 currently not supported */
+		ret = -1;
+
+	/*
+	 * Stop reading anymore ECC vals and clear old results
+	 * enable will be called if more reads are required
+	 */
+	omap_ecc_disable(mtd);
+
+	return ret;
+}
+
+/*
+ * omap_fix_errors_bch - Correct bch error in the data
+ *
+ * @mtd:	MTD device structure
+ * @data:	Data read from flash
+ * @error_count:Number of errors in data
+ * @error_loc:	Locations of errors in the data
+ *
+ */
+static void omap_fix_errors_bch(struct mtd_info *mtd, uint8_t *data,
+		uint32_t error_count, uint32_t *error_loc)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct nand_bch_priv *bch = chip->priv;
+	uint8_t count = 0;
+	uint32_t error_byte_pos;
+	uint32_t error_bit_mask;
+	uint32_t last_bit = (bch->nibbles * 4) - 1;
+
+	/* Flip all bits as specified by the error location array. */
+	/* FOR( each found error location flip the bit ) */
+	for (count = 0; count < error_count; count++) {
+		if (error_loc[count] > last_bit) {
+			/* Remove the ECC spare bits from correction. */
+			error_loc[count] -= (last_bit + 1);
+			/* Offset bit in data region */
+			error_byte_pos = ((512 * 8) -
+					(error_loc[count]) - 1) / 8;
+			/* Error Bit mask */
+			error_bit_mask = 0x1 << (error_loc[count] % 8);
+			/* Toggle the error bit to make the correction. */
+			data[error_byte_pos] ^= error_bit_mask;
+		}
+	}
+}
+
+/*
+ * omap_correct_data_bch - Compares the ecc read from nand spare area
+ * with ECC registers values and corrects one bit error if it has occured
+ *
+ * @mtd:	MTD device structure
+ * @dat:	page data
+ * @read_ecc:	ecc read from nand flash (ignored)
+ * @calc_ecc:	ecc read from ECC registers
+ *
+ * @return 0 if data is OK or corrected, else returns -1
+ */
+static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
+				uint8_t *read_ecc, uint8_t *calc_ecc)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct nand_bch_priv *bch = chip->priv;
+	uint8_t syndrome[28];
+	uint32_t error_count = 0;
+	uint32_t error_loc[8];
+	uint32_t i, ecc_flag;
+
+	ecc_flag = 0;
+	for (i = 0; i < chip->ecc.bytes; i++)
+		if (read_ecc[i] != 0xff)
+			ecc_flag = 1;
+
+	if (!ecc_flag)
+		return 0;
+
+	elm_reset();
+	elm_config((enum bch_level)(bch->type));
+
+	/*
+	 * while reading ECC result we read it in big endian.
+	 * Hence while loading to ELM we have rotate to get the right endian.
+	 */
+	omap_rotate_ecc_bch(mtd, calc_ecc, syndrome);
+
+	/* use elm module to check for errors */
+	if (elm_check_error(syndrome, bch->nibbles, &error_count,
+				error_loc) != 0) {
+		printf("ECC: uncorrectable.\n");
+		return -1;
+	}
+
+	/* correct bch error */
+	if (error_count > 0)
+		omap_fix_errors_bch(mtd, dat, error_count, error_loc);
+
+	return 0;
+}
+/*
+ * omap_hwecc_init_bch - Initialize the BCH Hardware ECC for NAND flash in
+ *				GPMC controller
+ * @mtd:       MTD device structure
+ * @mode:	Read/Write mode
+ */
+static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
+{
+	uint32_t val, dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
+	uint32_t unused_length = 0;
+	struct nand_bch_priv *bch = chip->priv;
+
+	switch (bch->nibbles) {
+	case ECC_BCH4_NIBBLES:
+		unused_length = 3;
+		break;
+	case ECC_BCH8_NIBBLES:
+		unused_length = 2;
+		break;
+	case ECC_BCH16_NIBBLES:
+		unused_length = 0;
+		break;
+	}
+
+	/* Clear the ecc result registers, select ecc reg as 1 */
+	writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
+
+	switch (mode) {
+	case NAND_ECC_WRITE:
+		/* eccsize1 config */
+		val = ((unused_length + bch->nibbles) << 22);
+		break;
+
+	case NAND_ECC_READ:
+	default:
+		/* by default eccsize0 selected for ecc1resultsize */
+		/* eccsize0 config */
+		val  = (bch->nibbles << 12);
+		/* eccsize1 config */
+		val |= (unused_length << 22);
+		break;
+	}
+	/* ecc size configuration */
+	writel(val, &gpmc_cfg->ecc_size_config);
+	/* by default 512bytes sector page is selected */
+	/* set bch mode */
+	val  = (1 << 16);
+	/* bch4 / bch8 / bch16 */
+	val |= (bch->type << 12);
+	/* set wrap mode to 1 */
+	val |= (1 << 8);
+	val |= (dev_width << 7);
+	val |= (cs << 1);
+	writel(val, &gpmc_cfg->ecc_config);
+}
+
+/*
+ * omap_enable_ecc_bch- This function enables the bch h/w ecc functionality
+ * @mtd:        MTD device structure
+ * @mode:       Read/Write mode
+ *
+ */
+static void omap_enable_ecc_bch(struct mtd_info *mtd, int32_t mode)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	omap_hwecc_init_bch(chip, mode);
+	/* enable ecc */
+	writel((readl(&gpmc_cfg->ecc_config) | 0x1), &gpmc_cfg->ecc_config);
+}
+
+/**
+ * omap_read_page_bch - hardware ecc based page read function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ *
+ */
+static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
+				uint8_t *buf, int page)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *p = buf;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	uint8_t *oob = chip->oob_poi;
+	uint32_t data_pos;
+	uint32_t oob_pos;
+
+	data_pos = 0;
+	/* oob area start */
+	oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
+	oob += chip->ecc.layout->eccpos[0];
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
+				oob += eccbytes) {
+		chip->ecc.hwctl(mtd, NAND_ECC_READ);
+		/* read data */
+		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, page);
+		chip->read_buf(mtd, p, eccsize);
+
+		/* read respective ecc from oob area */
+		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, page);
+		chip->read_buf(mtd, oob, eccbytes);
+		/* read syndrome */
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+		data_pos += eccsize;
+		oob_pos += eccbytes;
+	}
+
+	for (i = 0; i < chip->ecc.total; i++)
+		ecc_code[i] = chip->oob_poi[eccpos[i]];
+
+	eccsteps = chip->ecc.steps;
+	p = buf;
+
+	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		int stat;
+
+		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+	return 0;
+}
+#endif /* CONFIG_AM33XX */
+
 #ifndef CONFIG_SPL_BUILD
 /*
  * omap_nand_switch_ecc - switch the ECC operation b/w h/w ecc and s/w ecc.
@@ -269,7 +636,7 @@ void omap_nand_switch_ecc(int32_t hardware)
 	nand->ecc.calculate = NULL;
 
 	/* Setup the ecc configurations again */
-	if (hardware) {
+	if (hardware == 1) {
 		nand->ecc.mode = NAND_ECC_HW;
 		nand->ecc.layout = &hw_nand_oob;
 		nand->ecc.size = 512;
@@ -279,6 +646,19 @@ void omap_nand_switch_ecc(int32_t hardware)
 		nand->ecc.calculate = omap_calculate_ecc;
 		omap_hwecc_init(nand);
 		printf("HW ECC selected\n");
+#ifdef CONFIG_AM33XX
+	} else if (hardware == 2) {
+		nand->ecc.mode = NAND_ECC_HW;
+		nand->ecc.layout = &hw_bch8_nand_oob;
+		nand->ecc.size = 512;
+		nand->ecc.bytes = 14;
+		nand->ecc.read_page = omap_read_page_bch;
+		nand->ecc.hwctl = omap_enable_ecc_bch;
+		nand->ecc.correct = omap_correct_data_bch;
+		nand->ecc.calculate = omap_calculate_ecc_bch;
+		omap_hwecc_init_bch(nand, NAND_ECC_READ);
+		printf("HW BCH8 selected\n");
+#endif
 	} else {
 		nand->ecc.mode = NAND_ECC_SOFT;
 		/* Use mtd default settings */
@@ -350,7 +730,27 @@ int board_nand_init(struct nand_chip *nand)
 		nand->options |= NAND_BUSWIDTH_16;
 
 	nand->chip_delay = 100;
+
+#ifdef CONFIG_AM33XX
+	/* required in case of BCH */
+	elm_init();
+
+	/* BCH info that will be correct for SPL or overridden otherwise. */
+	nand->priv = &bch_priv;
+#endif
+
 	/* Default ECC mode */
+#ifdef CONFIG_AM33XX
+	nand->ecc.mode = NAND_ECC_HW;
+	nand->ecc.layout = &hw_bch8_nand_oob;
+	nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
+	nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
+	nand->ecc.hwctl = omap_enable_ecc_bch;
+	nand->ecc.correct = omap_correct_data_bch;
+	nand->ecc.calculate = omap_calculate_ecc_bch;
+	nand->ecc.read_page = omap_read_page_bch;
+	omap_hwecc_init_bch(nand, NAND_ECC_READ);
+#else
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_NAND_SOFTECC)
 	nand->ecc.mode = NAND_ECC_SOFT;
 #else
@@ -363,6 +763,7 @@ int board_nand_init(struct nand_chip *nand)
 	nand->ecc.calculate = omap_calculate_ecc;
 	omap_hwecc_init(nand);
 #endif
+#endif
 
 #ifdef CONFIG_SPL_BUILD
 	if (nand->options & NAND_BUSWIDTH_16)
-- 
1.7.10.2 (Apple Git-33)

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 7/8] am33xx_spl_bch: simple SPL nand loader for AM33XX
  2012-11-06 23:06 [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Ilya Yanok
                   ` (5 preceding siblings ...)
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based) Ilya Yanok
@ 2012-11-06 23:06 ` Ilya Yanok
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 8/8] am335x_evm: enable SPL NAND support Ilya Yanok
  2012-12-10 20:18 ` [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Tom Rini
  8 siblings, 0 replies; 21+ messages in thread
From: Ilya Yanok @ 2012-11-06 23:06 UTC (permalink / raw)
  To: u-boot

AM33XX with BCH8 can't work with nand_spl_simple correctly
because custom read_page implementation is required for proper
syndrome generation.

This simple driver mostly duplicates nand_spl_simple but has
nand_read_page changed to suit our needs.

Signed-off-by: Ilya Yanok <ilya.yanok@cogentembedded.com>
---

 drivers/mtd/nand/Makefile         |    1 +
 drivers/mtd/nand/am335x_spl_bch.c |  238 +++++++++++++++++++++++++++++++++++++
 2 files changed, 239 insertions(+)
 create mode 100644 drivers/mtd/nand/am335x_spl_bch.c

diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index beb99ca..5322f3a 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -30,6 +30,7 @@ ifdef CONFIG_SPL_BUILD
 ifdef CONFIG_SPL_NAND_SIMPLE
 COBJS-y += nand_spl_simple.o
 endif
+COBJS-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
 ifdef CONFIG_SPL_NAND_LOAD
 COBJS-y	+= nand_spl_load.o
 endif
diff --git a/drivers/mtd/nand/am335x_spl_bch.c b/drivers/mtd/nand/am335x_spl_bch.c
new file mode 100644
index 0000000..b84528b
--- /dev/null
+++ b/drivers/mtd/nand/am335x_spl_bch.c
@@ -0,0 +1,238 @@
+/*
+ * (C) Copyright 2012
+ * Konstantin Kozhevnikov, Cogent Embedded
+ *
+ * based on nand_spl_simple code
+ *
+ * (C) Copyright 2006-2008
+ * Stefan Roese, DENX Software Engineering, sr at denx.de.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <common.h>
+#include <nand.h>
+#include <asm/io.h>
+#include <linux/mtd/nand_ecc.h>
+
+static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
+static nand_info_t mtd;
+static struct nand_chip nand_chip;
+
+#define ECCSTEPS	(CONFIG_SYS_NAND_PAGE_SIZE / \
+					CONFIG_SYS_NAND_ECCSIZE)
+#define ECCTOTAL	(ECCSTEPS * CONFIG_SYS_NAND_ECCBYTES)
+
+
+/*
+ * NAND command for large page NAND devices (2k)
+ */
+static int nand_command(int block, int page, uint32_t offs,
+	u8 cmd)
+{
+	struct nand_chip *this = mtd.priv;
+	int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
+	void (*hwctrl)(struct mtd_info *mtd, int cmd,
+			unsigned int ctrl) = this->cmd_ctrl;
+
+	while (!this->dev_ready(&mtd))
+		;
+
+	/* Emulate NAND_CMD_READOOB */
+	if (cmd == NAND_CMD_READOOB) {
+		offs += CONFIG_SYS_NAND_PAGE_SIZE;
+		cmd = NAND_CMD_READ0;
+	}
+
+	/* Begin command latch cycle */
+	hwctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
+
+	if (cmd == NAND_CMD_RESET) {
+		hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+		while (!this->dev_ready(&mtd))
+			;
+		return 0;
+	}
+
+	/* Shift the offset from byte addressing to word addressing. */
+	if (this->options & NAND_BUSWIDTH_16)
+		offs >>= 1;
+
+	/* Set ALE and clear CLE to start address cycle */
+	/* Column address */
+	hwctrl(&mtd, offs & 0xff,
+		       NAND_CTRL_ALE | NAND_CTRL_CHANGE); /* A[7:0] */
+	hwctrl(&mtd, (offs >> 8) & 0xff, NAND_CTRL_ALE); /* A[11:9] */
+	/* Row address */
+	hwctrl(&mtd, (page_addr & 0xff), NAND_CTRL_ALE); /* A[19:12] */
+	hwctrl(&mtd, ((page_addr >> 8) & 0xff),
+		       NAND_CTRL_ALE); /* A[27:20] */
+#ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE
+	/* One more address cycle for devices > 128MiB */
+	hwctrl(&mtd, (page_addr >> 16) & 0x0f,
+		       NAND_CTRL_ALE); /* A[31:28] */
+#endif
+	hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+
+	if (cmd == NAND_CMD_READ0) {
+		/* Latch in address */
+		hwctrl(&mtd, NAND_CMD_READSTART,
+			   NAND_CTRL_CLE | NAND_CTRL_CHANGE);
+		hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+
+		/*
+		 * Wait a while for the data to be ready
+		 */
+		while (!this->dev_ready(&mtd))
+			;
+	} else if (cmd == NAND_CMD_RNDOUT) {
+		hwctrl(&mtd, NAND_CMD_RNDOUTSTART, NAND_CTRL_CLE |
+					NAND_CTRL_CHANGE);
+		hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+	}
+
+	return 0;
+}
+
+static int nand_is_bad_block(int block)
+{
+	struct nand_chip *this = mtd.priv;
+
+	nand_command(block, 0, CONFIG_SYS_NAND_BAD_BLOCK_POS,
+		NAND_CMD_READOOB);
+
+	/*
+	 * Read one byte (or two if it's a 16 bit chip).
+	 */
+	if (this->options & NAND_BUSWIDTH_16) {
+		if (readw(this->IO_ADDR_R) != 0xffff)
+			return 1;
+	} else {
+		if (readb(this->IO_ADDR_R) != 0xff)
+			return 1;
+	}
+
+	return 0;
+}
+
+static int nand_read_page(int block, int page, void *dst)
+{
+	struct nand_chip *this = mtd.priv;
+	u_char ecc_calc[ECCTOTAL];
+	u_char ecc_code[ECCTOTAL];
+	u_char oob_data[CONFIG_SYS_NAND_OOBSIZE];
+	int i;
+	int eccsize = CONFIG_SYS_NAND_ECCSIZE;
+	int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
+	int eccsteps = ECCSTEPS;
+	uint8_t *p = dst;
+	uint32_t data_pos = 0;
+	uint8_t *oob = &oob_data[0] + nand_ecc_pos[0];
+	uint32_t oob_pos = eccsize * eccsteps + nand_ecc_pos[0];
+
+	nand_command(block, page, 0, NAND_CMD_READ0);
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		this->ecc.hwctl(&mtd, NAND_ECC_READ);
+		nand_command(block, page, data_pos, NAND_CMD_RNDOUT);
+
+		this->read_buf(&mtd, p, eccsize);
+
+		nand_command(block, page, oob_pos, NAND_CMD_RNDOUT);
+
+		this->read_buf(&mtd, oob, eccbytes);
+		this->ecc.calculate(&mtd, p, &ecc_calc[i]);
+
+		data_pos += eccsize;
+		oob_pos += eccbytes;
+		oob += eccbytes;
+	}
+
+	/* Pick the ECC bytes out of the oob data */
+	for (i = 0; i < ECCTOTAL; i++)
+		ecc_code[i] = oob_data[nand_ecc_pos[i]];
+
+	eccsteps = ECCSTEPS;
+	p = dst;
+
+	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		/* No chance to do something with the possible error message
+		 * from correct_data(). We just hope that all possible errors
+		 * are corrected by this routine.
+		 */
+		this->ecc.correct(&mtd, p, &ecc_code[i], &ecc_calc[i]);
+	}
+
+	return 0;
+}
+
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
+{
+	unsigned int block, lastblock;
+	unsigned int page;
+
+	/*
+	 * offs has to be aligned to a page address!
+	 */
+	block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
+	lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
+	page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
+
+	while (block <= lastblock) {
+		if (!nand_is_bad_block(block)) {
+			/*
+			 * Skip bad blocks
+			 */
+			while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
+				nand_read_page(block, page, dst);
+				dst += CONFIG_SYS_NAND_PAGE_SIZE;
+				page++;
+			}
+
+			page = 0;
+		} else {
+			lastblock++;
+		}
+
+		block++;
+	}
+
+	return 0;
+}
+
+/* nand_init() - initialize data to make nand usable by SPL */
+void nand_init(void)
+{
+	/*
+	 * Init board specific nand support
+	 */
+	mtd.priv = &nand_chip;
+	nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W =
+		(void  __iomem *)CONFIG_SYS_NAND_BASE;
+	board_nand_init(&nand_chip);
+
+	if (nand_chip.select_chip)
+		nand_chip.select_chip(&mtd, 0);
+
+	/* NAND chip may require reset after power-on */
+	nand_command(0, 0, 0, NAND_CMD_RESET);
+}
+
+/* Unselect after operation */
+void nand_deselect(void)
+{
+	if (nand_chip.select_chip)
+		nand_chip.select_chip(&mtd, -1);
+}
-- 
1.7.10.2 (Apple Git-33)

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 8/8] am335x_evm: enable SPL NAND support
  2012-11-06 23:06 [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Ilya Yanok
                   ` (6 preceding siblings ...)
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 7/8] am33xx_spl_bch: simple SPL nand loader for AM33XX Ilya Yanok
@ 2012-11-06 23:06 ` Ilya Yanok
  2012-12-10 20:18 ` [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Tom Rini
  8 siblings, 0 replies; 21+ messages in thread
From: Ilya Yanok @ 2012-11-06 23:06 UTC (permalink / raw)
  To: u-boot

Enable booting from NAND support from AM335x boards as well as
environment in NAND.

Signed-off-by: Ilya Yanok <ilya.yanok@cogentembedded.com>

---

 include/configs/am335x_evm.h |   38 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index ded1cab..6abe544 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -240,6 +240,35 @@
 #define CONFIG_SYS_SPI_U_BOOT_SIZE	0x40000
 #define CONFIG_SPL_LDSCRIPT		"$(CPUDIR)/omap-common/u-boot-spl.lds"
 
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_NAND_AM33XX_BCH
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_SYS_NAND_PAGE_COUNT	(CONFIG_SYS_NAND_BLOCK_SIZE / \
+					 CONFIG_SYS_NAND_PAGE_SIZE)
+#define CONFIG_SYS_NAND_PAGE_SIZE	2048
+#define CONFIG_SYS_NAND_OOBSIZE		64
+#define CONFIG_SYS_NAND_BLOCK_SIZE	(128*1024)
+#define CONFIG_SYS_NAND_BAD_BLOCK_POS	NAND_LARGE_BADBLOCK_POS
+#define CONFIG_SYS_NAND_ECCPOS		{ 2, 3, 4, 5, 6, 7, 8, 9, \
+					 10, 11, 12, 13, 14, 15, 16, 17, \
+					 18, 19, 20, 21, 22, 23, 24, 25, \
+					 26, 27, 28, 29, 30, 31, 32, 33, \
+					 34, 35, 36, 37, 38, 39, 40, 41, \
+					 42, 43, 44, 45, 46, 47, 48, 49, \
+					 50, 51, 52, 53, 54, 55, 56, 57, }
+
+#define CONFIG_SYS_NAND_ECCSIZE		512
+#define CONFIG_SYS_NAND_ECCBYTES	14
+
+#define CONFIG_SYS_NAND_ECCSTEPS	4
+#define	CONFIG_SYS_NAND_ECCTOTAL	(CONFIG_SYS_NAND_ECCBYTES * \
+						CONFIG_SYS_NAND_ECCSTEPS)
+
+#define	CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000
+
 /*
  * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
  * 64 bytes before this address should be set aside for u-boot.img's
@@ -283,7 +312,12 @@
 #define CONFIG_SYS_NAND_BASE		(0x08000000)	/* physical address */
 							/* to access nand at */
 							/* CS0 */
-#define CONFIG_SYS_MAX_NAND_DEVICE	1		/* Max number of NAND */
-#endif							/* devices */
+#define CONFIG_SYS_MAX_NAND_DEVICE	1		/* Max number of NAND
+							   devices */
+#undef CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET		0x260000 /* environment starts here */
+#define CONFIG_SYS_ENV_SECT_SIZE	(128 << 10)	/* 128 KiB */
+#endif
 
 #endif	/* ! __CONFIG_AM335X_EVM_H */
-- 
1.7.10.2 (Apple Git-33)

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 3/8] am33xx: NAND support
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 3/8] am33xx: NAND support Ilya Yanok
@ 2012-11-08  9:33   ` Peter Korsgaard
  2012-11-15 20:21     ` Ilya Yanok
  0 siblings, 1 reply; 21+ messages in thread
From: Peter Korsgaard @ 2012-11-08  9:33 UTC (permalink / raw)
  To: u-boot

>>>>> "Ilya" == Ilya Yanok <ilya.yanok@cogentembedded.com> writes:

 Ilya> TI AM33XX has the same GPMC controller as OMAP3 so we could just use the
 Ilya> existing omap_gpmc driver. This patch adds adds required
 Ilya> definitions/intialization.

 Ilya> Signed-off-by: Ilya Yanok <ilya.yanok@cogentembedded.com>

..

 Ilya> +void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
 Ilya> +			u32 size)
 Ilya> +{
 Ilya> +	writel(0, &cs->config7);
 Ilya> +	sdelay(1000);
 Ilya> +	/* Delay for settling */

That comment should go above the delay.


 Ilya> +	writel(gpmc_config[0], &cs->config1);
 Ilya> +	writel(gpmc_config[1], &cs->config2);
 Ilya> +	writel(gpmc_config[2], &cs->config3);
 Ilya> +	writel(gpmc_config[3], &cs->config4);
 Ilya> +	writel(gpmc_config[4], &cs->config5);
 Ilya> +	writel(gpmc_config[5], &cs->config6);
 Ilya> +	/* Enable the config */
 Ilya> +	writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) |
 Ilya> +		(1 << 6)), &cs->config7);
 Ilya> +	sdelay(2000);

Any reason you now wait double as long?


 Ilya> +}
 Ilya> +
 Ilya> +/*****************************************************
 Ilya> + * gpmc_init(): init gpmc bus
 Ilya> + * Init GPMC for x16, MuxMode (SDRAM in x32).
 Ilya> + * This code can only be executed from SRAM or SDRAM.
 Ilya> + *****************************************************/
 Ilya> +void gpmc_init(void)
 Ilya> +{
 Ilya> +	/* putting a blanket check on GPMC based on ZeBu for now */
 Ilya> +	gpmc_cfg = (struct gpmc *)GPMC_BASE;
 Ilya> +
 Ilya> +#ifdef CONFIG_CMD_NAND
 Ilya> +	const u32 *gpmc_config = NULL;
 Ilya> +	u32 base = 0;
 Ilya> +	u32 size = 0;
 Ilya> +#endif
 Ilya> +	/* global settings */
 Ilya> +	writel(0x00000008, &gpmc_cfg->sysconfig);
 Ilya> +	writel(0x00000100, &gpmc_cfg->irqstatus);
 Ilya> +	writel(0x00000200, &gpmc_cfg->irqenable);
 Ilya> +	writel(0x00000012, &gpmc_cfg->config);
 Ilya> +	/*
 Ilya> +	 * Disable the GPMC0 config set by ROM code
 Ilya> +	 */
 Ilya> +	writel(0, &gpmc_cfg->cs[0].config7);
 Ilya> +	sdelay(1000);

Why? You already do this in enable_gpmc_cs_config().


 Ilya> +
 Ilya> +#ifdef CONFIG_CMD_NAND
 Ilya> +	gpmc_config = gpmc_m_nand;
 Ilya> +
 Ilya> +	base = PISMO1_NAND_BASE;
 Ilya> +	size = PISMO1_NAND_SIZE;
 Ilya> +	enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
 Ilya> +#endif
 Ilya> +}

 Ilya> +++ b/arch/arm/include/asm/arch-am33xx/mem.h
 Ilya> @@ -0,0 +1,83 @@
 Ilya> +/*
 Ilya> + * (C) Copyright 2006-2008
 Ilya> + * Texas Instruments, <www.ti.com>
 Ilya> + *
 Ilya> + * Author
 Ilya> + *		Mansoor Ahamed <mansoor.ahamed@ti.com>
 Ilya> + *
 Ilya> + * Initial Code from:
 Ilya> + *		Richard Woodruff <r-woodruff2@ti.com>
 Ilya> + *
 Ilya> + * See file CREDITS for list of people who contributed to this
 Ilya> + * project.
 Ilya> + *
 Ilya> + * This program is free software; you can redistribute it and/or
 Ilya> + * modify it under the terms of the GNU General Public License as
 Ilya> + * published by the Free Software Foundation; either version 2 of
 Ilya> + * the License, or (at your option) any later version.
 Ilya> + *
 Ilya> + * This program is distributed in the hope that it will be useful,
 Ilya> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 Ilya> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 Ilya> + * GNU General Public License for more details.
 Ilya> + *
 Ilya> + * You should have received a copy of the GNU General Public License
 Ilya> + * along with this program; if not, write to the Free Software
 Ilya> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 Ilya> + * MA 02111-1307 USA
 Ilya> + */
 Ilya> +
 Ilya> +#ifndef _MEM_H_
 Ilya> +#define _MEM_H_
 Ilya> +
 Ilya> +/*
 Ilya> + * GPMC settings -
 Ilya> + * Definitions is as per the following format
 Ilya> + * #define <PART>_GPMC_CONFIG<x> <value>
 Ilya> + * Where:
 Ilya> + * PART is the part name e.g. STNOR - Intel Strata Flash
 Ilya> + * x is GPMC config registers from 1 to 6 (there will be 6 macros)
 Ilya> + * Value is corresponding value
 Ilya> + *
 Ilya> + * For every valid PRCM configuration there should be only one definition of
 Ilya> + * the same. if values are independent of the board, this definition will be
 Ilya> + * present in this file if values are dependent on the board, then this should
 Ilya> + * go into corresponding mem-boardName.h file
 Ilya> + *
 Ilya> + * Currently valid part Names are (PART):
 Ilya> + * M_NAND - Micron NAND
 Ilya> + */
 Ilya> +#define GPMC_SIZE_256M		0x0
 Ilya> +#define GPMC_SIZE_128M		0x8
 Ilya> +#define GPMC_SIZE_64M		0xC
 Ilya> +#define GPMC_SIZE_32M		0xE
 Ilya> +#define GPMC_SIZE_16M		0xF
 Ilya> +
 Ilya> +#define M_NAND_GPMC_CONFIG1	0x00000800
 Ilya> +#define M_NAND_GPMC_CONFIG2	0x001e1e00
 Ilya> +#define M_NAND_GPMC_CONFIG3	0x001e1e00
 Ilya> +#define M_NAND_GPMC_CONFIG4	0x16051807
 Ilya> +#define M_NAND_GPMC_CONFIG5	0x00151e1e
 Ilya> +#define M_NAND_GPMC_CONFIG6	0x16000f80
 Ilya> +#define M_NAND_GPMC_CONFIG7	0x00000008

For what Micron part is this exactly? How about using the actual part
number in the define like we recently did for the DDR configuration?


 Ilya> +++ b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
 Ilya> @@ -0,0 +1,120 @@
 Ilya> +/*
 Ilya> + * (C) Copyright 2004-2008 Texas Instruments, <www.ti.com>
 Ilya> + * Rohit Choraria <rohitkc@ti.com>
 Ilya> + *
 Ilya> + * See file CREDITS for list of people who contributed to this
 Ilya> + * project.
 Ilya> + *
 Ilya> + * This program is free software; you can redistribute it and/or
 Ilya> + * modify it under the terms of the GNU General Public License as
 Ilya> + * published by the Free Software Foundation; either version 2 of
 Ilya> + * the License, or (at your option) any later version.
 Ilya> + *
 Ilya> + * This program is distributed in the hope that it will be useful,
 Ilya> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 Ilya> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 Ilya> + * GNU General Public License for more details.
 Ilya> + *
 Ilya> + * You should have received a copy of the GNU General Public License
 Ilya> + * along with this program; if not, write to the Free Software
 Ilya> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 Ilya> + * MA 02111-1307 USA
 Ilya> + */
 Ilya> +#ifndef __ASM_ARCH_OMAP_GPMC_H
 Ilya> +#define __ASM_ARCH_OMAP_GPMC_H
 Ilya> +
 Ilya> +#define GPMC_BUF_EMPTY	0
 Ilya> +#define GPMC_BUF_FULL	1
 Ilya> +
 Ilya> +#define ECCCLEAR	(0x1 << 8)
 Ilya> +#define ECCRESULTREG1	(0x1 << 0)
 Ilya> +#define ECCSIZE512BYTE	0xFF
 Ilya> +#define ECCSIZE1	(ECCSIZE512BYTE << 22)
 Ilya> +#define ECCSIZE0	(ECCSIZE512BYTE << 12)
 Ilya> +#define ECCSIZE0SEL	(0x000 << 0)
 Ilya> +
 Ilya> +/* Generic ECC Layouts */
 Ilya> +/* Large Page x8 NAND device Layout */
 Ilya> +#ifdef GPMC_NAND_ECC_LP_x8_LAYOUT
 Ilya> +#define GPMC_NAND_HW_ECC_LAYOUT {\
 Ilya> +	.eccbytes = 12,\
 Ilya> +	.eccpos = {1, 2, 3, 4, 5, 6, 7, 8,\
 Ilya> +		9, 10, 11, 12},\
 Ilya> +	.oobfree = {\
 Ilya> +		{.offset = 13,\
 Ilya> +		 .length = 51 } } \
 Ilya> +}
 Ilya> +#endif
 Ilya> +
 Ilya> +/* Large Page x16 NAND device Layout */
 Ilya> +#ifdef GPMC_NAND_ECC_LP_x16_LAYOUT
 Ilya> +#define GPMC_NAND_HW_ECC_LAYOUT {\
 Ilya> +	.eccbytes = 12,\
 Ilya> +	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9,\
 Ilya> +		10, 11, 12, 13},\
 Ilya> +	.oobfree = {\
 Ilya> +		{.offset = 14,\
 Ilya> +		 .length = 50 } } \
 Ilya> +}
 Ilya> +#endif
 Ilya> +
 Ilya> +/* Small Page x8 NAND device Layout */
 Ilya> +#ifdef GPMC_NAND_ECC_SP_x8_LAYOUT
 Ilya> +#define GPMC_NAND_HW_ECC_LAYOUT {\
 Ilya> +	.eccbytes = 3,\
 Ilya> +	.eccpos = {1, 2, 3},\
 Ilya> +	.oobfree = {\
 Ilya> +		{.offset = 4,\
 Ilya> +		 .length = 12 } } \
 Ilya> +}
 Ilya> +#endif
 Ilya> +
 Ilya> +/* Small Page x16 NAND device Layout */
 Ilya> +#ifdef GPMC_NAND_ECC_SP_x16_LAYOUT
 Ilya> +#define GPMC_NAND_HW_ECC_LAYOUT {\
 Ilya> +	.eccbytes = 3,\
 Ilya> +	.eccpos = {2, 3, 4},\
 Ilya> +	.oobfree = {\
 Ilya> +		{.offset = 5,\
 Ilya> +		 .length = 11 } } \
 Ilya> +}
 Ilya> +#endif
 Ilya> +
 Ilya> +#define GPMC_NAND_HW_BCH4_ECC_LAYOUT {\
 Ilya> +	.eccbytes = 32,\
 Ilya> +	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
 Ilya> +				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
 Ilya> +				28, 29, 30, 31, 32, 33},\
 Ilya> +	.oobfree = {\
 Ilya> +		{.offset = 34,\
 Ilya> +		 .length = 30 } } \
 Ilya> +}
 Ilya> +
 Ilya> +#define GPMC_NAND_HW_BCH8_ECC_LAYOUT {\
 Ilya> +	.eccbytes = 56,\
 Ilya> +	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
 Ilya> +				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
 Ilya> +				28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
 Ilya> +				40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
 Ilya> +				52, 53, 54, 55, 56, 57},\
 Ilya> +	.oobfree = {\
 Ilya> +		{.offset = 58,\
 Ilya> +		 .length = 6 } } \
 Ilya> +}
 Ilya> +
 Ilya> +#define GPMC_NAND_HW_BCH16_ECC_LAYOUT {\
 Ilya> +	.eccbytes = 104,\
 Ilya> +	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
 Ilya> +				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
 Ilya> +				28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
 Ilya> +				40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
 Ilya> +				52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\
 Ilya> +				64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,\
 Ilya> +				76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,\
 Ilya> +				88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\
 Ilya> +				100, 101, 102, 103, 104, 105},\
 Ilya> +	.oobfree = {\
 Ilya> +		{.offset = 106,\
 Ilya> +		 .length = 8 } } \
 Ilya> +}
 Ilya> +#endif /* __ASM_ARCH_OMAP_GPMC_H */


Do the non-BCH layouts make sense for am33xx? I've noticed that the TRM
shows the BCH8 format as 13 bytes/256 tightly packed instead of 14, but
that's wrong. I'll report it to the doc people.

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based)
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based) Ilya Yanok
@ 2012-11-15 13:25   ` Andreas Bießmann
       [not found]     ` <CAA3CPjX0pHtU6y6kAtzVmdZq-akGAXhKcpkq92BwBJtb0HbRgw@mail.gmail.com>
  2012-11-21 17:04     ` Tom Rini
  0 siblings, 2 replies; 21+ messages in thread
From: Andreas Bießmann @ 2012-11-15 13:25 UTC (permalink / raw)
  To: u-boot

Dear Ilya Yanok,

On 07.11.2012 00:06, Ilya Yanok wrote:
> From: Mansoor Ahamed <mansoor.ahamed@ti.com>
> 
> This patch adds support for BCH8 error correction code to omap_gpmc
> driver. We use GPMC to generate codes/syndromes but we need ELM to find
> error locations from given syndrome.
> 

first of all, I wonder why this is so different than the kernel
implementation for BCH. I mean the API (and content) of this and commit
8d602cf50d3bba864bc1438f486b626df69c87b3 mainline linux seems to differ.
The main question coming to mind is: Is the resulting OOB layout
compatible then?

Best regards

Andreas Bie?mann

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 3/8] am33xx: NAND support
  2012-11-08  9:33   ` Peter Korsgaard
@ 2012-11-15 20:21     ` Ilya Yanok
  2012-11-15 22:26       ` Peter Korsgaard
  0 siblings, 1 reply; 21+ messages in thread
From: Ilya Yanok @ 2012-11-15 20:21 UTC (permalink / raw)
  To: u-boot

Hi Peter,

On Thu, Nov 8, 2012 at 10:33 AM, Peter Korsgaard <jacmet@sunsite.dk> wrote:

>  Ilya> +void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs
> *cs, u32 base,
>  Ilya> +                        u32 size)
>  Ilya> +{
>  Ilya> +        writel(0, &cs->config7);
>  Ilya> +        sdelay(1000);
>  Ilya> +        /* Delay for settling */
>
> That comment should go above the delay.
>

Ok, will fix.


>   Ilya> +        writel(gpmc_config[0], &cs->config1);
>  Ilya> +        writel(gpmc_config[1], &cs->config2);
>  Ilya> +        writel(gpmc_config[2], &cs->config3);
>  Ilya> +        writel(gpmc_config[3], &cs->config4);
>  Ilya> +        writel(gpmc_config[4], &cs->config5);
>  Ilya> +        writel(gpmc_config[5], &cs->config6);
>  Ilya> +        /* Enable the config */
>  Ilya> +        writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) |
>  Ilya> +                (1 << 6)), &cs->config7);
>  Ilya> +        sdelay(2000);
>
> Any reason you now wait double as long?
>

No idea ;) To tell the truth I've taken all this code from omap3 as is.


>  Ilya> +}
>  Ilya> +
>  Ilya> +/*****************************************************
>  Ilya> + * gpmc_init(): init gpmc bus
>  Ilya> + * Init GPMC for x16, MuxMode (SDRAM in x32).
>  Ilya> + * This code can only be executed from SRAM or SDRAM.
>  Ilya> + *****************************************************/
>  Ilya> +void gpmc_init(void)
>  Ilya> +{
>  Ilya> +        /* putting a blanket check on GPMC based on ZeBu for now */
>  Ilya> +        gpmc_cfg = (struct gpmc *)GPMC_BASE;
>  Ilya> +
>  Ilya> +#ifdef CONFIG_CMD_NAND
>  Ilya> +        const u32 *gpmc_config = NULL;
>  Ilya> +        u32 base = 0;
>  Ilya> +        u32 size = 0;
>  Ilya> +#endif
>  Ilya> +        /* global settings */
>  Ilya> +        writel(0x00000008, &gpmc_cfg->sysconfig);
>  Ilya> +        writel(0x00000100, &gpmc_cfg->irqstatus);
>  Ilya> +        writel(0x00000200, &gpmc_cfg->irqenable);
>  Ilya> +        writel(0x00000012, &gpmc_cfg->config);
>  Ilya> +        /*
>  Ilya> +         * Disable the GPMC0 config set by ROM code
>  Ilya> +         */
>  Ilya> +        writel(0, &gpmc_cfg->cs[0].config7);
>  Ilya> +        sdelay(1000);
>
> Why? You already do this in enable_gpmc_cs_config().
>

Hm... Again, I'm not the one who written this code, I just stole it ;)
but probably the idea was to disable the config even in case of
CONFIG_CMD_NAND undefined...


>  Ilya> +
>  Ilya> +#ifdef CONFIG_CMD_NAND
>  Ilya> +        gpmc_config = gpmc_m_nand;
>  Ilya> +
>  Ilya> +        base = PISMO1_NAND_BASE;
>  Ilya> +        size = PISMO1_NAND_SIZE;
>  Ilya> +        enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base,
> size);
>  Ilya> +#endif
>  Ilya> +}
>
>  Ilya> +#define M_NAND_GPMC_CONFIG1     0x00000800
>  Ilya> +#define M_NAND_GPMC_CONFIG2     0x001e1e00
>  Ilya> +#define M_NAND_GPMC_CONFIG3     0x001e1e00
>  Ilya> +#define M_NAND_GPMC_CONFIG4     0x16051807
>  Ilya> +#define M_NAND_GPMC_CONFIG5     0x00151e1e
>  Ilya> +#define M_NAND_GPMC_CONFIG6     0x16000f80
>  Ilya> +#define M_NAND_GPMC_CONFIG7     0x00000008
>
> For what Micron part is this exactly? How about using the actual part
> number in the define like we recently did for the DDR configuration?
>

Ok, I'll try to figure that out from schematics.

Do the non-BCH layouts make sense for am33xx? I've noticed that the TRM
> shows the BCH8 format as 13 bytes/256 tightly packed instead of 14, but
> that's wrong. I'll report it to the doc people.
>

Hm. Non-BCH layouts was here because I initially planned to support nandecc
command to switch between supported ECC schemas... But as Tom requested to
remove it I guess we don't need these layouts any more...
Well, my idea was to make separate patches (one to just support existing
omap_gpmc driver on AM33xx and one to add BCH8 support) and this kinda
needs non-BCH layouts too... but I guess I should just squash the patches
into one.

Thanks for the review.

Regards, Ilya.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 3/8] am33xx: NAND support
  2012-11-15 20:21     ` Ilya Yanok
@ 2012-11-15 22:26       ` Peter Korsgaard
  2012-11-21 16:59         ` Tom Rini
  0 siblings, 1 reply; 21+ messages in thread
From: Peter Korsgaard @ 2012-11-15 22:26 UTC (permalink / raw)
  To: u-boot

>>>>> "Ilya" == Ilya Yanok <ilya.yanok@cogentembedded.com> writes:

Hi,

 Peter>     Why? You already do this in enable_gpmc_cs_config().

 Ilya> Hm... Again, I'm not the one who written this code, I just stole
 Ilya> it ;) but probably the idea was to disable the config even in
 Ilya> case of CONFIG_CMD_NAND undefined...

Why would you want to do that? I don't see a reason for touching the
GPMC if you're not going to use it.


 Ilya>     ?Ilya> +#define M_NAND_GPMC_CONFIG1 ? ? 0x00000800
 Ilya>     ?Ilya> +#define M_NAND_GPMC_CONFIG2 ? ? 0x001e1e00
 Ilya>     ?Ilya> +#define M_NAND_GPMC_CONFIG3 ? ? 0x001e1e00
 Ilya>     ?Ilya> +#define M_NAND_GPMC_CONFIG4 ? ? 0x16051807
 Ilya>     ?Ilya> +#define M_NAND_GPMC_CONFIG5 ? ? 0x00151e1e
 Ilya>     ?Ilya> +#define M_NAND_GPMC_CONFIG6 ? ? 0x16000f80
 Ilya>     ?Ilya> +#define M_NAND_GPMC_CONFIG7 ? ? 0x00000008

 Peter>    For what Micron part is this exactly? How about using the actual part
 Peter>    number in the define like we recently did for the DDR configuration?


 Ilya> Ok, I'll try to figure that out from schematics.

Great, thanks. The choice of GPMC configuration values should also be
moved to board code, similar to how I did it for DDR.


 Peter>   Do the non-BCH layouts make sense for am33xx? I've noticed
 Peter>   that the TRM shows the BCH8 format as 13 bytes/256 tightly
 Peter>   packed instead of 14, but that's wrong. I'll report it to the
 Peter>   doc people.


 Ilya> Hm. Non-BCH layouts was here because I initially planned to
 Ilya> support nandecc command to switch between supported ECC
 Ilya> schemas... But as Tom requested to remove it I guess we don't
 Ilya> need these layouts any more...  Well, my idea was to make
 Ilya> separate patches (one to just support existing omap_gpmc driver
 Ilya> on AM33xx and one to add BCH8 support) and this kinda needs
 Ilya> non-BCH layouts too... but I guess I should just squash the
 Ilya> patches into one.

I don't think non-BCH makes much sense on am33xx considering the ROM
uses/requires BCH8.

 Ilya> Thanks for the review.

You're welcome.

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based)
       [not found]     ` <CAA3CPjX0pHtU6y6kAtzVmdZq-akGAXhKcpkq92BwBJtb0HbRgw@mail.gmail.com>
@ 2012-11-16 10:24       ` Andreas Bießmann
  2012-11-16 15:59         ` Peter Korsgaard
  0 siblings, 1 reply; 21+ messages in thread
From: Andreas Bießmann @ 2012-11-16 10:24 UTC (permalink / raw)
  To: u-boot

Dear Ilya Yanok,

On 15.11.2012 21:08, Ilya Yanok wrote:
> Dear Andreas,
> 
> On Thu, Nov 15, 2012 at 2:25 PM, Andreas Bie?mann
> <andreas.devel at googlemail.com <mailto:andreas.devel@googlemail.com>> wrote:
> 
>     Dear Ilya Yanok,
> 
>     On 07.11.2012 00:06, Ilya Yanok wrote:
>     > From: Mansoor Ahamed <mansoor.ahamed@ti.com
>     <mailto:mansoor.ahamed@ti.com>>
>     >
>     > This patch adds support for BCH8 error correction code to omap_gpmc
>     > driver. We use GPMC to generate codes/syndromes but we need ELM to
>     find
>     > error locations from given syndrome.
>     >
> 
>     first of all, I wonder why this is so different than the kernel
>     implementation for BCH. I mean the API (and content) of this and commit
>     8d602cf50d3bba864bc1438f486b626df69c87b3 mainline linux seems to differ.
>     The main question coming to mind is: Is the resulting OOB layout
>     compatible then?
> 
> 
> Please note that these patches are AM33XX-specific (as we are using ELM
> that, I think, just isn't available on OMAP3) so we use OOB layout that
> is compatible with AM33xx ROM boot code. 

You are right, ELM is not available in OMAP3 devices. It seems the ROM
loader of these devices only support the 1-Bit Hamming, but is also
different to the OOB layout used for the SW 1-bit hamming provided by
the Kernel.
So we get here a lot of different OOB layouts ... I wonder if we can
stick to e.g. the generic SW BCH layout (of linux kernel) for all but
the ROM partition (where the SPL is placed). So the SPL need to know
just one mechanism but software modifying that place needs to know about
the 'special' ROM layout.

> It's likely that this layout
> doesn't match with the current kernel layout as RBL uses strange 14th
> byte for BCH8 while only 13 bytes are needed. 

Sorry, what does RBL mean in that context?

> There are some patches for
> the kernel that make it use the same layout too but I don't if they are
> going to be accepted soon.

Ok, that would be required to write the SPL to flash.

> Actually, the only assumption the code does about the OOB layout is that
> ECC code occupies continuous area in the OOB.

Well, but you have defined that for example it is written in big endian.

I'm currently working on a omap3 enabled device that requires 4-bit ECC
for all but the first block. And I'm searching for a clean solution that
would be accepted mainline.
I think it would be best to have the same OOB layout for the whole
device but the SPL space (cause that needs to be read by ROM). The
layout should be chosen at compile time of the SPL.
What do you think about?

Best regards

Andreas Bie?mann

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based)
  2012-11-16 10:24       ` Andreas Bießmann
@ 2012-11-16 15:59         ` Peter Korsgaard
  2012-11-17 14:10           ` Andreas Bießmann
  0 siblings, 1 reply; 21+ messages in thread
From: Peter Korsgaard @ 2012-11-16 15:59 UTC (permalink / raw)
  To: u-boot

>>>>> "Andreas" == Andreas Bie?mann <andreas.devel@googlemail.com> writes:

Hi,

 >> Please note that these patches are AM33XX-specific (as we are using
 >> ELM that, I think, just isn't available on OMAP3) so we use OOB
 >> layout that is compatible with AM33xx ROM boot code.

 Andreas> You are right, ELM is not available in OMAP3 devices. It seems
 Andreas> the ROM loader of these devices only support the 1-Bit
 Andreas> Hamming, but is also different to the OOB layout used for the
 Andreas> SW 1-bit hamming provided by the Kernel.  So we get here a lot
 Andreas> of different OOB layouts ... I wonder if we can stick to
 Andreas> e.g. the generic SW BCH layout (of linux kernel) for all but
 Andreas> the ROM partition (where the SPL is placed). So the SPL need
 Andreas> to know just one mechanism but software modifying that place
 Andreas> needs to know about the 'special' ROM layout.

No, please not. Having more than 1 OOB layout on the same NAND device
leads to all kind of complications. There has also been kernel patches
posted for the ELM, so IMHO the only sane option for am33xx is BCH8
everywhere (with the ROM layout).


 >> It's likely that this layout
 >> doesn't match with the current kernel layout as RBL uses strange 14th
 >> byte for BCH8 while only 13 bytes are needed. 

 Andreas> Sorry, what does RBL mean in that context?

The ROM boot loader, E.G. the part loading the spl.


 >> Actually, the only assumption the code does about the OOB layout is that
 >> ECC code occupies continuous area in the OOB.

 Andreas> Well, but you have defined that for example it is written in
 Andreas> big endian.

 Andreas> I'm currently working on a omap3 enabled device that requires
 Andreas> 4-bit ECC for all but the first block. And I'm searching for a
 Andreas> clean solution that would be accepted mainline.  I think it
 Andreas> would be best to have the same OOB layout for the whole device
 Andreas> but the SPL space (cause that needs to be read by ROM). The
 Andreas> layout should be chosen at compile time of the SPL.  What do
 Andreas> you think about?

So the only reason to not have the same OOB layout everywhere is because
of ROM restrictions and that 1bit ECC isn't good enough anymore?
E.G. you actually would have prefered to use the ROM layout if it would
have used something better like the am33xx ROM does.

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based)
  2012-11-16 15:59         ` Peter Korsgaard
@ 2012-11-17 14:10           ` Andreas Bießmann
  2012-11-17 19:13             ` Peter Korsgaard
  0 siblings, 1 reply; 21+ messages in thread
From: Andreas Bießmann @ 2012-11-17 14:10 UTC (permalink / raw)
  To: u-boot

Dear Peter Korsgaard,

On 16.11.12 16:59, Peter Korsgaard wrote:
>>>>>> "Andreas" == Andreas Bie?mann <andreas.devel@googlemail.com> writes:
> 
> Hi,
> 
>  >> Please note that these patches are AM33XX-specific (as we are using
>  >> ELM that, I think, just isn't available on OMAP3) so we use OOB
>  >> layout that is compatible with AM33xx ROM boot code.
> 
>  Andreas> You are right, ELM is not available in OMAP3 devices. It seems
>  Andreas> the ROM loader of these devices only support the 1-Bit
>  Andreas> Hamming, but is also different to the OOB layout used for the
>  Andreas> SW 1-bit hamming provided by the Kernel.  So we get here a lot
>  Andreas> of different OOB layouts ... I wonder if we can stick to
>  Andreas> e.g. the generic SW BCH layout (of linux kernel) for all but
>  Andreas> the ROM partition (where the SPL is placed). So the SPL need
>  Andreas> to know just one mechanism but software modifying that place
>  Andreas> needs to know about the 'special' ROM layout.
> 
> No, please not. Having more than 1 OOB layout on the same NAND device
> leads to all kind of complications. There has also been kernel patches
> posted for the ELM, so IMHO the only sane option for am33xx is BCH8
> everywhere (with the ROM layout).

Ok, I understand your point here. But there are device combinations out
there that do not match!
We have an AM37xx with some micron NAND that requires 1bit ECC for the
first page (if less than 1000 erase cycle). But 4bit ECC for the rest of
the device. With the 1bit for first page it does fit to the ROM
requirements of that SoC but unfortunately we can not use the same OOB
layout on the whole device, cause the ROM can only do the 1bit hamming ECC.
I think there are other boards out there facing the same problem. I have
to recheck for example the devkit8000 which is a mainlined development
device some users based their products on (as we do).

>  >> Actually, the only assumption the code does about the OOB layout is that
>  >> ECC code occupies continuous area in the OOB.
> 
>  Andreas> Well, but you have defined that for example it is written in
>  Andreas> big endian.
> 
>  Andreas> I'm currently working on a omap3 enabled device that requires
>  Andreas> 4-bit ECC for all but the first block. And I'm searching for a
>  Andreas> clean solution that would be accepted mainline.  I think it
>  Andreas> would be best to have the same OOB layout for the whole device
>  Andreas> but the SPL space (cause that needs to be read by ROM). The
>  Andreas> layout should be chosen at compile time of the SPL.  What do
>  Andreas> you think about?
> 
> So the only reason to not have the same OOB layout everywhere is because
> of ROM restrictions and that 1bit ECC isn't good enough anymore?

That's my point.

> E.G. you actually would have prefered to use the ROM layout if it would
> have used something better like the am33xx ROM does.

You are right.

Best regards

Andreas Bie?mann

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based)
  2012-11-17 14:10           ` Andreas Bießmann
@ 2012-11-17 19:13             ` Peter Korsgaard
  0 siblings, 0 replies; 21+ messages in thread
From: Peter Korsgaard @ 2012-11-17 19:13 UTC (permalink / raw)
  To: u-boot

>>>>> "Andreas" == Andreas Bie?mann <andreas.devel@googlemail.com> writes:

Hi,

 >> No, please not. Having more than 1 OOB layout on the same NAND device
 >> leads to all kind of complications. There has also been kernel patches
 >> posted for the ELM, so IMHO the only sane option for am33xx is BCH8
 >> everywhere (with the ROM layout).

 Andreas> Ok, I understand your point here. But there are device
 Andreas> combinations out there that do not match!  We have an AM37xx
 Andreas> with some micron NAND that requires 1bit ECC for the first
 Andreas> page (if less than 1000 erase cycle). But 4bit ECC for the
 Andreas> rest of the device. With the 1bit for first page it does fit
 Andreas> to the ROM requirements of that SoC but unfortunately we can
 Andreas> not use the same OOB layout on the whole device, cause the ROM
 Andreas> can only do the 1bit hamming ECC.  I think there are other
 Andreas> boards out there facing the same problem. I have to recheck
 Andreas> for example the devkit8000 which is a mainlined development
 Andreas> device some users based their products on (as we do).

Sure, reality tends to be more complicated than that. The different
SoCs, Nand devices and projects have different requirements. Notice that
this patch is specifically about the Error Location Module present on
E.G. am33xx and omap4, where the ROM also uses BCH encoding.

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 3/8] am33xx: NAND support
  2012-11-15 22:26       ` Peter Korsgaard
@ 2012-11-21 16:59         ` Tom Rini
  0 siblings, 0 replies; 21+ messages in thread
From: Tom Rini @ 2012-11-21 16:59 UTC (permalink / raw)
  To: u-boot

On Thu, Nov 15, 2012 at 11:26:59PM +0100, Peter Korsgaard wrote:
>  Ilya> Hm. Non-BCH layouts was here because I initially planned to
>  Ilya> support nandecc command to switch between supported ECC
>  Ilya> schemas... But as Tom requested to remove it I guess we don't
>  Ilya> need these layouts any more...  Well, my idea was to make
>  Ilya> separate patches (one to just support existing omap_gpmc driver
>  Ilya> on AM33xx and one to add BCH8 support) and this kinda needs
>  Ilya> non-BCH layouts too... but I guess I should just squash the
>  Ilya> patches into one.
> 
> I don't think non-BCH makes much sense on am33xx considering the ROM
> uses/requires BCH8.

Long term (not today tho) we need to support BCH16 as well since the ROM
requires BCH16 on some parts and BCH8 on others.  We can cross that
bridge when we come to it, however.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20121121/981a5e28/attachment.pgp>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based)
  2012-11-15 13:25   ` Andreas Bießmann
       [not found]     ` <CAA3CPjX0pHtU6y6kAtzVmdZq-akGAXhKcpkq92BwBJtb0HbRgw@mail.gmail.com>
@ 2012-11-21 17:04     ` Tom Rini
  2012-11-21 20:51       ` Andreas Bießmann
  1 sibling, 1 reply; 21+ messages in thread
From: Tom Rini @ 2012-11-21 17:04 UTC (permalink / raw)
  To: u-boot

On Thu, Nov 15, 2012 at 02:25:23PM +0100, Andreas Bie?mann wrote:
> Dear Ilya Yanok,
> 
> On 07.11.2012 00:06, Ilya Yanok wrote:
> > From: Mansoor Ahamed <mansoor.ahamed@ti.com>
> > 
> > This patch adds support for BCH8 error correction code to omap_gpmc
> > driver. We use GPMC to generate codes/syndromes but we need ELM to find
> > error locations from given syndrome.
> > 
> 
> first of all, I wonder why this is so different than the kernel
> implementation for BCH. I mean the API (and content) of this and commit
> 8d602cf50d3bba864bc1438f486b626df69c87b3 mainline linux seems to differ.
> The main question coming to mind is: Is the resulting OOB layout
> compatible then?

I think this has been mostly addressed now, but for clarity:
- We do NOT want to have > 1 layout used per NAND chip unless we must
  (historically we did because we had ROM that couldn't use >1bit ECC).
- We DO want to utilize the HW as this is the only easy way to get a
  match with the BCH constants the ROM uses.
- There are corresponding kernel patches already posted and working
  their way along.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20121121/2929d2b4/attachment.pgp>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based)
  2012-11-21 17:04     ` Tom Rini
@ 2012-11-21 20:51       ` Andreas Bießmann
  0 siblings, 0 replies; 21+ messages in thread
From: Andreas Bießmann @ 2012-11-21 20:51 UTC (permalink / raw)
  To: u-boot

On 21.11.12 18:04, Tom Rini wrote:
> On Thu, Nov 15, 2012 at 02:25:23PM +0100, Andreas Bie?mann wrote:
>> Dear Ilya Yanok,
>>
>> On 07.11.2012 00:06, Ilya Yanok wrote:
>>> From: Mansoor Ahamed <mansoor.ahamed@ti.com>
>>>
>>> This patch adds support for BCH8 error correction code to omap_gpmc
>>> driver. We use GPMC to generate codes/syndromes but we need ELM to find
>>> error locations from given syndrome.
>>>
>>
>> first of all, I wonder why this is so different than the kernel
>> implementation for BCH. I mean the API (and content) of this and commit
>> 8d602cf50d3bba864bc1438f486b626df69c87b3 mainline linux seems to differ.
>> The main question coming to mind is: Is the resulting OOB layout
>> compatible then?
> 
> I think this has been mostly addressed now, but for clarity:
> - We do NOT want to have > 1 layout used per NAND chip unless we must
>   (historically we did because we had ROM that couldn't use >1bit ECC).
> - We DO want to utilize the HW as this is the only easy way to get a
>   match with the BCH constants the ROM uses.
> - There are corresponding kernel patches already posted and working
>   their way along.

I'm fine with all these three points. My question came up when I looked
into this deeply the very first time cause BCH4/8 support was missing
for OMAP35xx/AM37xx devices.
I do have now working support for these (hw assisted BCH but sw
correction) like the kernel does. It needs some final polishing however
I will send it these days as RFC, would be great to get some feedback.

Best regards

Andreas Bie?mann

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [U-Boot] [PATCH v2 0/8] NAND support for AM33XX
  2012-11-06 23:06 [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Ilya Yanok
                   ` (7 preceding siblings ...)
  2012-11-06 23:06 ` [U-Boot] [PATCH v2 8/8] am335x_evm: enable SPL NAND support Ilya Yanok
@ 2012-12-10 20:18 ` Tom Rini
  8 siblings, 0 replies; 21+ messages in thread
From: Tom Rini @ 2012-12-10 20:18 UTC (permalink / raw)
  To: u-boot

On Wed, Nov 07, 2012 at 12:06:27AM +0100, Ilya Yanok wrote:

> These series add support for NAND on AM33XX. AM33XX has the same GPMC
> controller as OMAP3 so the first part of the series just add required
> defines/initialization to enable the existing omap_gpmc driver to work
> on AM33XX. The rest of the series adds support for BCH8 error correction
> code. We use GPMC to generate codes/syndromes and ELM to find the
> errors.
> 
> Changes in v2:
>  -fix nand mux settings (profiles 2&3 don't have NAND)
>  - rebased on current master
>  - clean up mem.c (remove unused stuff that was copied from OMAP3)
>  - nand headers: remove unneeded stuff
>  - rebased onto master
>  - minor config style fix (wrt nand)
>  - fix wrong braces in Makefile
> 
> Ilya Yanok (6):
>   OMAP: include sys_proto.h from boot-common
>   am335x_evm: add nand pinmux definition
>   am33xx: NAND support
>   am335x_evm: enable NAND support
>   am33xx_spl_bch: simple SPL nand loader for AM33XX
>   am335x_evm: enable SPL NAND support
> 
> Mansoor Ahamed (2):
>   am33xx: add ELM support
>   omap_gpmc: BCH8 support (ELM based)
> 
>  arch/arm/cpu/armv7/am33xx/Makefile           |    2 +
>  arch/arm/cpu/armv7/am33xx/board.c            |    1 +
>  arch/arm/cpu/armv7/am33xx/clock.c            |   10 +
>  arch/arm/cpu/armv7/am33xx/elm.c              |  212 ++++++++++++++
>  arch/arm/cpu/armv7/am33xx/mem.c              |  101 +++++++
>  arch/arm/cpu/armv7/omap-common/boot-common.c |    1 +
>  arch/arm/include/asm/arch-am33xx/cpu.h       |   53 ++++
>  arch/arm/include/asm/arch-am33xx/elm.h       |   93 ++++++
>  arch/arm/include/asm/arch-am33xx/hardware.h  |    3 +
>  arch/arm/include/asm/arch-am33xx/mem.h       |   83 ++++++
>  arch/arm/include/asm/arch-am33xx/omap_gpmc.h |  120 ++++++++
>  arch/arm/include/asm/arch-am33xx/sys_proto.h |    3 +
>  board/ti/am335x/board.c                      |    2 +
>  board/ti/am335x/mux.c                        |   22 ++
>  drivers/mtd/nand/Makefile                    |    1 +
>  drivers/mtd/nand/am335x_spl_bch.c            |  238 +++++++++++++++
>  drivers/mtd/nand/omap_gpmc.c                 |  403 +++++++++++++++++++++++++-
>  include/configs/am335x_evm.h                 |   46 +++
>  18 files changed, 1393 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/cpu/armv7/am33xx/elm.c
>  create mode 100644 arch/arm/cpu/armv7/am33xx/mem.c
>  create mode 100644 arch/arm/include/asm/arch-am33xx/elm.h
>  create mode 100644 arch/arm/include/asm/arch-am33xx/mem.h
>  create mode 100644 arch/arm/include/asm/arch-am33xx/omap_gpmc.h
>  create mode 100644 drivers/mtd/nand/am335x_spl_bch.c

For the series, applied to u-boot-ti/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20121210/45f4f960/attachment.pgp>

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2012-12-10 20:18 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-06 23:06 [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Ilya Yanok
2012-11-06 23:06 ` [U-Boot] [PATCH v2 1/8] OMAP: include sys_proto.h from boot-common Ilya Yanok
2012-11-06 23:06 ` [U-Boot] [PATCH v2 2/8] am335x_evm: add nand pinmux definition Ilya Yanok
2012-11-06 23:06 ` [U-Boot] [PATCH v2 3/8] am33xx: NAND support Ilya Yanok
2012-11-08  9:33   ` Peter Korsgaard
2012-11-15 20:21     ` Ilya Yanok
2012-11-15 22:26       ` Peter Korsgaard
2012-11-21 16:59         ` Tom Rini
2012-11-06 23:06 ` [U-Boot] [PATCH v2 4/8] am335x_evm: enable " Ilya Yanok
2012-11-06 23:06 ` [U-Boot] [PATCH v2 5/8] am33xx: add ELM support Ilya Yanok
2012-11-06 23:06 ` [U-Boot] [PATCH v2 6/8] omap_gpmc: BCH8 support (ELM based) Ilya Yanok
2012-11-15 13:25   ` Andreas Bießmann
     [not found]     ` <CAA3CPjX0pHtU6y6kAtzVmdZq-akGAXhKcpkq92BwBJtb0HbRgw@mail.gmail.com>
2012-11-16 10:24       ` Andreas Bießmann
2012-11-16 15:59         ` Peter Korsgaard
2012-11-17 14:10           ` Andreas Bießmann
2012-11-17 19:13             ` Peter Korsgaard
2012-11-21 17:04     ` Tom Rini
2012-11-21 20:51       ` Andreas Bießmann
2012-11-06 23:06 ` [U-Boot] [PATCH v2 7/8] am33xx_spl_bch: simple SPL nand loader for AM33XX Ilya Yanok
2012-11-06 23:06 ` [U-Boot] [PATCH v2 8/8] am335x_evm: enable SPL NAND support Ilya Yanok
2012-12-10 20:18 ` [U-Boot] [PATCH v2 0/8] NAND support for AM33XX Tom Rini

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.