summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-07-12 08:22:03 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2010-07-12 08:22:03 +0200
commit6ffe2ec8cd37e432fdfc08f71cb9a46767ef1e39 (patch)
tree4ef60a59d5ca2ab0bb4391da3175fd868bffebbc
parenta2f567095ba3831a3198aa2e1cacda2f5dcbf820 (diff)
parent0be6fd0bf642541dbe999dbead7c3ae7e9c9db16 (diff)
downloadbarebox-6ffe2ec8cd37e432fdfc08f71cb9a46767ef1e39.tar.gz
barebox-6ffe2ec8cd37e432fdfc08f71cb9a46767ef1e39.tar.xz
Merge remote branch 'origin/omap' into next
-rw-r--r--arch/arm/mach-omap/Kconfig14
-rw-r--r--arch/arm/mach-omap/include/mach/gpmc_nand.h45
-rw-r--r--board/omap/Kconfig69
-rw-r--r--board/omap/Makefile2
-rw-r--r--board/omap/board-beagle.c242
-rw-r--r--board/omap/config.h5
-rw-r--r--board/omap/devices-gpmc-nand.c63
-rw-r--r--drivers/mtd/nand/Kconfig8
-rw-r--r--drivers/mtd/nand/nand_omap_gpmc.c103
9 files changed, 225 insertions, 326 deletions
diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig
index 99b9f9d973..e5230802ec 100644
--- a/arch/arm/mach-omap/Kconfig
+++ b/arch/arm/mach-omap/Kconfig
@@ -39,20 +39,6 @@ config ARCH_OMAP3
endchoice
-config OMAP_CONFIG_STACKSIZE
- prompt "STACKSIZE"
- hex
- default 0x00020000
- help
- Select the Stack Size when defaults are used
-
-config OMAP_MALLOC_LEN
- prompt "MALLOC LENGTH"
- hex
- default 0x00001000
- help
- Select the Malloc Length when defaults are used
-
### Generic Clock configurations to be enabled by Mach - invisible to enable.
config OMAP_CLOCK_UART
bool
diff --git a/arch/arm/mach-omap/include/mach/gpmc_nand.h b/arch/arm/mach-omap/include/mach/gpmc_nand.h
index c6c51d5d52..e23faabcac 100644
--- a/arch/arm/mach-omap/include/mach/gpmc_nand.h
+++ b/arch/arm/mach-omap/include/mach/gpmc_nand.h
@@ -68,54 +68,11 @@ struct gpmc_nand_platform_data {
#define NAND_WAITPOL_HIGH (1 << 0)
#define NAND_WAITPOL_MASK (1 << 0)
-#ifdef CONFIG_NAND_OMAP_GPMC_HWECC
/** plat_options: hw ecc enabled */
#define NAND_HWECC_ENABLE (1 << 1)
-#endif
/** plat_options: hw ecc disabled */
-#define NAND_HWECC_DISABLE (0 << 1)
#define NAND_HWECC_MASK (1 << 1)
-/* Typical BOOTROM oob layouts-requires hwecc **/
-#ifdef CONFIG_NAND_OMAP_GPMC_HWECC
-/** Large Page x8 NAND device Layout */
-#define GPMC_NAND_ECC_LP_x8_LAYOUT {\
- .eccbytes = 12,\
- .eccpos = {1, 2, 3, 4, 5, 6, 7, 8,\
- 9, 10, 11, 12},\
- .oobfree = {\
- {.offset = 60,\
- .length = 2 } } \
-}
-
-/** Large Page x16 NAND device Layout */
-#define GPMC_NAND_ECC_LP_x16_LAYOUT {\
- .eccbytes = 12,\
- .eccpos = {2, 3, 4, 5, 6, 7, 8, 9,\
- 10, 11, 12, 13},\
- .oobfree = {\
- {.offset = 60,\
- .length = 2 } } \
-}
-
-/** Small Page x8 NAND device Layout */
-#define GPMC_NAND_ECC_SP_x8_LAYOUT {\
- .eccbytes = 3,\
- .eccpos = {1, 2, 3},\
- .oobfree = {\
- {.offset = 14,\
- .length = 2 } } \
-}
-
-/** Small Page x16 NAND device Layout */
-#define GPMC_NAND_ECC_SP_x16_LAYOUT {\
- .eccbytes = 3,\
- .eccpos = {2, 3, 4},\
- .oobfree = {\
- {.offset = 14,\
- .length = 2 } } \
-}
-
-#endif /* CONFIG_NAND_OMAP_GPMC_HWECC */
+int gpmc_generic_nand_devices_init(int cs, int width, int hwecc);
#endif /* __ASM_OMAP_NAND_GPMC_H */
diff --git a/board/omap/Kconfig b/board/omap/Kconfig
index 361bed436f..d612064710 100644
--- a/board/omap/Kconfig
+++ b/board/omap/Kconfig
@@ -90,73 +90,4 @@ config MACH_OMAP_ADVANCED_MUX
config HAS_OMAP_NAND
bool
-
-menuconfig MACH_OMAP_GPMC_NAND
- tristate "Enable NAND device support for GPMC"
- depends on HAS_OMAP_NAND
- default n
- help
- Say Y here if you would like to have NAND device support
-
-if MACH_OMAP_GPMC_NAND
-# Single definition used to club all generic definitions together
-config MACH_OMAP_GPMC_GENERICNAND
- bool
-
-choice
- prompt "Select NAND Device"
-
-config MACH_OMAP_GPMC_GENERICNAND_LP_X8
- tristate "Enable 8 bit Large page nand"
- depends on MACH_OMAP_GPMC_NAND
- select MACH_OMAP_GPMC_GENERICNAND
- help
- Say Y here if you would support for 8 bit NAND
- with large page
- NOTE: The timing parameter are the most relaxed
- If you need optimized timing, selec appropriate
- supported NAND flash
-
-config MACH_OMAP_GPMC_GENERICNAND_LP_X16
- tristate "Enable 16 bit Large page nand"
- depends on MACH_OMAP_GPMC_NAND
- select MACH_OMAP_GPMC_GENERICNAND
- help
- Say Y here if you would support for 16 bit NAND
- with large page
- NOTE: The timing parameter are the most relaxed
- If you need optimized timing, selec appropriate
- supported NAND flash
-
-config MACH_OMAP_GPMC_GENERICNAND_SP_X8
- tristate "Enable 8 bit Small page nand"
- depends on MACH_OMAP_GPMC_NAND
- select MACH_OMAP_GPMC_GENERICNAND
- help
- Say Y here if you would support for 8 bit NAND
- with small page
- NOTE: The timing parameter are the most relaxed
- If you need optimized timing, selec appropriate
- supported NAND flash
-
-config MACH_OMAP_GPMC_GENERICNAND_SP_X16
- tristate "Enable 16 bit Small page nand"
- depends on MACH_OMAP_GPMC_NAND
- select MACH_OMAP_GPMC_GENERICNAND
- help
- Say Y here if you would support for 16 bit NAND
- with small page
- NOTE: The timing parameter are the most relaxed
- If you need optimized timing, selec appropriate
- supported NAND flash
-endchoice
-
-config MACH_OMAP_CS
- hex "NAND CS"
- depends on MACH_OMAP_GPMC_NAND
- default 0x0
- help
- Provide the Chip select of the NAND flash
-endif
-
endmenu
diff --git a/board/omap/Makefile b/board/omap/Makefile
index b4bb3e1d05..1e74e241b4 100644
--- a/board/omap/Makefile
+++ b/board/omap/Makefile
@@ -24,5 +24,5 @@ obj-$(CONFIG_MACH_DO_LOWLEVEL_INIT) += platform.o
obj-$(CONFIG_MACH_OMAP343xSDP) += board-sdp343x.o
obj-$(CONFIG_MACH_BEAGLE) += board-beagle.o
obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o
-obj-$(CONFIG_MACH_OMAP_GPMC_GENERICNAND) += devices-gpmc-nand.o
+obj-y += devices-gpmc-nand.o
diff --git a/board/omap/board-beagle.c b/board/omap/board-beagle.c
index 866d8325e5..78c0ef9728 100644
--- a/board/omap/board-beagle.c
+++ b/board/omap/board-beagle.c
@@ -77,51 +77,51 @@
*/
static void sdrc_init(void)
{
- /* SDRAM software reset */
- /* No idle ack and RESET enable */
- writel(0x1A, SDRC_REG(SYSCONFIG));
- sdelay(100);
- /* No idle ack and RESET disable */
- writel(0x18, SDRC_REG(SYSCONFIG));
-
- /* SDRC Sharing register */
- /* 32-bit SDRAM on data lane [31:0] - CS0 */
- /* pin tri-stated = 1 */
- writel(0x00000100, SDRC_REG(SHARING));
-
- /* ----- SDRC Registers Configuration --------- */
- /* SDRC_MCFG0 register */
- writel(0x02584099, SDRC_REG(MCFG_0));
-
- /* SDRC_RFR_CTRL0 register */
- writel(0x54601, SDRC_REG(RFR_CTRL_0));
-
- /* SDRC_ACTIM_CTRLA0 register */
- writel(0xA29DB4C6, SDRC_REG(ACTIM_CTRLA_0));
-
- /* SDRC_ACTIM_CTRLB0 register */
- writel(0x12214, SDRC_REG(ACTIM_CTRLB_0));
-
- /* Disble Power Down of CKE due to 1 CKE on combo part */
- writel(0x00000081, SDRC_REG(POWER));
-
- /* SDRC_MANUAL command register */
- /* NOP command */
- writel(0x00000000, SDRC_REG(MANUAL_0));
- /* Precharge command */
- writel(0x00000001, SDRC_REG(MANUAL_0));
- /* Auto-refresh command */
- writel(0x00000002, SDRC_REG(MANUAL_0));
- /* Auto-refresh command */
- writel(0x00000002, SDRC_REG(MANUAL_0));
-
- /* SDRC MR0 register Burst length=4 */
- writel(0x00000032, SDRC_REG(MR_0));
-
- /* SDRC DLLA control register */
- writel(0x0000000A, SDRC_REG(DLLA_CTRL));
-
- return;
+ /* SDRAM software reset */
+ /* No idle ack and RESET enable */
+ writel(0x1A, SDRC_REG(SYSCONFIG));
+ sdelay(100);
+ /* No idle ack and RESET disable */
+ writel(0x18, SDRC_REG(SYSCONFIG));
+
+ /* SDRC Sharing register */
+ /* 32-bit SDRAM on data lane [31:0] - CS0 */
+ /* pin tri-stated = 1 */
+ writel(0x00000100, SDRC_REG(SHARING));
+
+ /* ----- SDRC Registers Configuration --------- */
+ /* SDRC_MCFG0 register */
+ writel(0x02584099, SDRC_REG(MCFG_0));
+
+ /* SDRC_RFR_CTRL0 register */
+ writel(0x54601, SDRC_REG(RFR_CTRL_0));
+
+ /* SDRC_ACTIM_CTRLA0 register */
+ writel(0xA29DB4C6, SDRC_REG(ACTIM_CTRLA_0));
+
+ /* SDRC_ACTIM_CTRLB0 register */
+ writel(0x12214, SDRC_REG(ACTIM_CTRLB_0));
+
+ /* Disble Power Down of CKE due to 1 CKE on combo part */
+ writel(0x00000081, SDRC_REG(POWER));
+
+ /* SDRC_MANUAL command register */
+ /* NOP command */
+ writel(0x00000000, SDRC_REG(MANUAL_0));
+ /* Precharge command */
+ writel(0x00000001, SDRC_REG(MANUAL_0));
+ /* Auto-refresh command */
+ writel(0x00000002, SDRC_REG(MANUAL_0));
+ /* Auto-refresh command */
+ writel(0x00000002, SDRC_REG(MANUAL_0));
+
+ /* SDRC MR0 register Burst length=4 */
+ writel(0x00000032, SDRC_REG(MR_0));
+
+ /* SDRC DLLA control register */
+ writel(0x0000000A, SDRC_REG(DLLA_CTRL));
+
+ return;
}
/**
@@ -135,60 +135,59 @@ static void sdrc_init(void)
*/
static void mux_config(void)
{
+ /* SDRC_D0 - SDRC_D31 default mux mode is mode0 */
+
+ /* GPMC */
+ MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0));
+
+ /* D0-D7 default mux mode is mode0 */
+ MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0));
+ /* GPMC_NADV_ALE default mux mode is mode0 */
+ /* GPMC_NOE default mux mode is mode0 */
+ /* GPMC_NWE default mux mode is mode0 */
+ /* GPMC_NBE0_CLE default mux mode is mode0 */
+ MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_NBE1), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0));
+ /* GPMC_WAIT0 default mux mode is mode0 */
+ MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0));
- /* SDRC_D0 - SDRC_D31 default mux mode is mode0 */
-
- /* GPMC */
- MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0));
-
- /* D0-D7 default mux mode is mode0 */
- MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0));
- /* GPMC_NADV_ALE default mux mode is mode0 */
- /* GPMC_NOE default mux mode is mode0 */
- /* GPMC_NWE default mux mode is mode0 */
- /* GPMC_NBE0_CLE default mux mode is mode0 */
- MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_NBE1), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0));
- /* GPMC_WAIT0 default mux mode is mode0 */
- MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0));
-
- /* SERIAL INTERFACE */
- MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTD | EN | M0));
- MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_CLK), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_STP), (IDIS | PTU | EN | M0));
- MUX_VAL(CP(HSUSB0_DIR), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_NXT), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_DATA0), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_DATA1), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_DATA2), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_DATA3), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_DATA4), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_DATA6), (IEN | PTD | DIS | M0));
- MUX_VAL(CP(HSUSB0_DATA7), (IEN | PTD | DIS | M0));
- /* I2C1_SCL default mux mode is mode0 */
- /* I2C1_SDA default mux mode is mode0 */
+ /* SERIAL INTERFACE */
+ MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTD | EN | M0));
+ MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_CLK), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_STP), (IDIS | PTU | EN | M0));
+ MUX_VAL(CP(HSUSB0_DIR), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_NXT), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_DATA0), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_DATA1), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_DATA2), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_DATA3), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_DATA4), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_DATA6), (IEN | PTD | DIS | M0));
+ MUX_VAL(CP(HSUSB0_DATA7), (IEN | PTD | DIS | M0));
+ /* I2C1_SCL default mux mode is mode0 */
+ /* I2C1_SDA default mux mode is mode0 */
}
/**
@@ -202,11 +201,12 @@ static void mux_config(void)
*/
void board_init(void)
{
- int in_sdram = running_in_sdram();
- mux_config();
- /* Dont reconfigure SDRAM while running in SDRAM! */
- if (!in_sdram)
- sdrc_init();
+ int in_sdram = running_in_sdram();
+
+ mux_config();
+ /* Dont reconfigure SDRAM while running in SDRAM! */
+ if (!in_sdram)
+ sdrc_init();
}
/******************** Board Run Time *******************/
@@ -214,17 +214,17 @@ void board_init(void)
#ifdef CONFIG_DRIVER_SERIAL_NS16550
static struct NS16550_plat serial_plat = {
- .clock = 48000000, /* 48MHz (APLL96/2) */
- .f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR,
- .reg_read = omap_uart_read,
- .reg_write = omap_uart_write,
+ .clock = 48000000, /* 48MHz (APLL96/2) */
+ .f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR,
+ .reg_read = omap_uart_read,
+ .reg_write = omap_uart_write,
};
static struct device_d beagle_serial_device = {
- .name = "serial_ns16550",
- .map_base = OMAP_UART3_BASE,
- .size = 1024,
- .platform_data = (void *)&serial_plat,
+ .name = "serial_ns16550",
+ .map_base = OMAP_UART3_BASE,
+ .size = 1024,
+ .platform_data = (void *)&serial_plat,
};
/**
@@ -235,8 +235,8 @@ static struct device_d beagle_serial_device = {
*/
static int beagle_console_init(void)
{
- /* Register the serial port */
- return register_device(&beagle_serial_device);
+ /* Register the serial port */
+ return register_device(&beagle_serial_device);
}
console_initcall(beagle_console_init);
#endif /* CONFIG_DRIVER_SERIAL_NS16550 */
@@ -255,16 +255,20 @@ static struct device_d sdram_dev = {
static int beagle_devices_init(void)
{
- int ret;
- ret = register_device(&sdram_dev);
- if (ret)
- goto failed;
+ int ret;
+
+ ret = register_device(&sdram_dev);
+ if (ret)
+ goto failed;
+
#ifdef CONFIG_GPMC
/* WP is made high and WAIT1 active Low */
gpmc_generic_init(0x10);
#endif
- armlinux_add_dram(&sdram_dev);
+ gpmc_generic_nand_devices_init(0, 16, 1);
+
+ armlinux_add_dram(&sdram_dev);
failed:
- return ret;
+ return ret;
}
device_initcall(beagle_devices_init);
diff --git a/board/omap/config.h b/board/omap/config.h
index 28b62730e4..707b3c4343 100644
--- a/board/omap/config.h
+++ b/board/omap/config.h
@@ -30,9 +30,4 @@
#ifndef __MACH_OMAP_CONFIG_H
#define __MACH_OMAP_CONFIG_H
-/** define CFG_MALLOC_LEN from Kconfig define */
-#define CFG_MALLOC_LEN CONFIG_OMAP_MALLOC_LEN
-/** define CONFIG_STACKSIZE from Kconfig define */
-#define CONFIG_STACKSIZE CONFIG_OMAP_CONFIG_STACKSIZE
-
#endif /* __MACH_OMAP_CONFIG_H */
diff --git a/board/omap/devices-gpmc-nand.c b/board/omap/devices-gpmc-nand.c
index bbcceafe88..e8b34caf4d 100644
--- a/board/omap/devices-gpmc-nand.c
+++ b/board/omap/devices-gpmc-nand.c
@@ -37,47 +37,14 @@
#include <mach/gpmc.h>
#include <mach/gpmc_nand.h>
-#ifdef CONFIG_MACH_OMAP_GPMC_GENERICNAND
-
#define GPMC_CONF1_VALx8 0x00000800
#define GPMC_CONF1_VALx16 0x00001800
/* Set up the generic params */
-#ifdef CONFIG_MACH_OMAP_GPMC_GENERICNAND_LP_X8
-#define GPMC_NAND_ECC_LAYOUT GPMC_NAND_ECC_LP_x8_LAYOUT
-#define GPMC_CONF1_VAL GPMC_CONF1_VALx8
-#define GPMC_NAND_DEV_WIDTH 8
-#endif
-
-#ifdef CONFIG_MACH_OMAP_GPMC_GENERICNAND_LP_X16
-#define GPMC_NAND_ECC_LAYOUT GPMC_NAND_ECC_LP_x16_LAYOUT
-#define GPMC_CONF1_VAL GPMC_CONF1_VALx16
-#define GPMC_NAND_DEV_WIDTH 16
-#endif
-
-#ifdef CONFIG_MACH_OMAP_GPMC_GENERICNAND_SP_X8
-#define GPMC_NAND_ECC_LAYOUT GPMC_NAND_ECC_SP_x8_LAYOUT
-#define GPMC_CONF1_VAL GPMC_CONF1_VALx8
-#define GPMC_NAND_DEV_WIDTH 8
-#endif
-
-#ifdef CONFIG_MACH_OMAP_GPMC_GENERICNAND_SP_X16
-#define GPMC_NAND_ECC_LAYOUT GPMC_NAND_ECC_SP_x16_LAYOUT
-#define GPMC_CONF1_VAL GPMC_CONF1_VALx16
-#define GPMC_NAND_DEV_WIDTH 16
-#endif
-
-#ifdef CONFIG_NAND_OMAP_GPMC_HWECC
-/**
- * The following is the organization of ECC as expected by BootROM.
- * Based on the type of device, this can vary. select the config accordingly
- */
-static struct nand_ecclayout boot_rom_ecc = GPMC_NAND_ECC_LAYOUT;
-#endif
/** GPMC timing for our nand device */
static struct gpmc_config nand_cfg = {
.cfg = {
- GPMC_CONF1_VAL, /*CONF1 */
+ 0, /*CONF1 */
0x00141400, /*CONF2 */
0x00141400, /*CONF3 */
0x0F010F01, /*CONF4 */
@@ -97,16 +64,9 @@ static struct gpmc_config nand_cfg = {
/** NAND platform specific settings settings */
static struct gpmc_nand_platform_data nand_plat = {
- .cs = CONFIG_MACH_OMAP_CS,
- .device_width = GPMC_NAND_DEV_WIDTH,
+ .cs = 0,
.max_timeout = MSECOND,
.wait_mon_pin = 0,
-#ifdef CONFIG_NAND_OMAP_GPMC_HWECC
- .plat_options = NAND_HWECC_ENABLE,
- .oob = &boot_rom_ecc,
-#else
- .plat_options = NAND_HWECC_DISABLE,
-#endif
.priv = (void *)&nand_cfg,
};
@@ -123,16 +83,19 @@ static struct device_d gpmc_generic_nand_nand_device = {
*
* @return success/fail based on device funtion
*/
-static int gpmc_generic_nand_devices_init(void)
+int gpmc_generic_nand_devices_init(int cs, int width, int hwecc)
{
+ nand_plat.cs = cs;
+
+ if (width == 16)
+ nand_cfg.cfg[0] = GPMC_CONF1_VALx16;
+ else
+ nand_cfg.cfg[0] = GPMC_CONF1_VALx8;
+
+ nand_plat.device_width = width;
+ nand_plat.plat_options = hwecc ? NAND_HWECC_ENABLE : 0;
+
/* Configure GPMC CS before register */
gpmc_cs_config(nand_plat.cs, &nand_cfg);
return register_device(&gpmc_generic_nand_nand_device);
}
-
-device_initcall(gpmc_generic_nand_devices_init);
-
-#endif /* CONFIG_MACH_OMAP_GPMC_GENERICNAND */
-
-/* All specific optimized nand configurations for GPMC NAND comes here */
-
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index e0d9d0d3b6..ddc0c34e7d 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -25,14 +25,6 @@ config NAND_OMAP_GPMC
Support for NAND flash using GPMC. GPMC is a common memory
interface found on Texas Instrument's OMAP platforms
-config NAND_OMAP_GPMC_HWECC
- bool "The Hardware ECC support"
- depends on NAND && NAND_OMAP_GPMC
- default n
- help
- The ECC compuatation for the data to be written/read can be either by
- software or omap has Hw ecc engine which calculates it.
-
config NAND_ATMEL
bool
prompt "Atmel (AT91SAM9xxx) NAND driver"
diff --git a/drivers/mtd/nand/nand_omap_gpmc.c b/drivers/mtd/nand/nand_omap_gpmc.c
index c6647e56ed..1363808ce0 100644
--- a/drivers/mtd/nand/nand_omap_gpmc.c
+++ b/drivers/mtd/nand/nand_omap_gpmc.c
@@ -102,10 +102,57 @@ struct gpmc_nand_info {
uint64_t timeout;
unsigned inuse:1;
unsigned wait_pol:1;
-#ifdef CONFIG_NAND_OMAP_GPMC_HWECC
unsigned char ecc_parity_pairs;
unsigned int ecc_config;
-#endif
+};
+
+/* Typical BOOTROM oob layouts-requires hwecc **/
+
+/** Large Page x8 NAND device Layout */
+static struct nand_ecclayout ecc_lp_x8 = {
+ .eccbytes = 12,
+ .eccpos = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
+ .oobfree = {
+ {
+ .offset = 60,
+ .length = 2,
+ }
+ }
+};
+
+/** Large Page x16 NAND device Layout */
+static struct nand_ecclayout ecc_lp_x16 = {
+ .eccbytes = 12,
+ .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13},
+ .oobfree = {
+ {
+ .offset = 60,
+ .length = 2,
+ }
+ }
+};
+
+/** Small Page x8 NAND device Layout */
+static struct nand_ecclayout ecc_sp_x8 = {
+ .eccbytes = 3,
+ .eccpos = {1, 2, 3},
+ .oobfree = {
+ {
+ .offset = 14,
+ .length = 2,
+ }
+ }
+};
+
+/** Small Page x16 NAND device Layout */
+static struct nand_ecclayout ecc_sp_x16 = {
+ .eccbytes = 3,
+ .eccpos = {2, 3, 4},
+ .oobfree = {
+ {
+ .offset = 14,
+ .length = 2 }
+ }
};
/**
@@ -203,8 +250,6 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
return;
}
-#ifdef CONFIG_NAND_OMAP_GPMC_HWECC
-
/**
* @brief This function will generate true ECC value, which can be used
* when correcting data read from NAND flash memory core
@@ -345,7 +390,6 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode)
break;
}
}
-#endif /* CONFIG_NAND_OMAP_GPMC_HWECC */
/**
* @brief nand device probe.
@@ -362,6 +406,7 @@ static int gpmc_nand_probe(struct device_d *pdev)
struct mtd_info *minfo;
unsigned long cs_base;
int err;
+ struct nand_ecclayout *layout, *lsp, *llp;
gpmcnand_dbg("pdev=%x", (unsigned int)pdev);
pdata = (struct gpmc_nand_platform_data *)pdev->platform_data;
@@ -453,11 +498,6 @@ static int gpmc_nand_probe(struct device_d *pdev)
/* State my controller */
nand->controller = &oinfo->controller;
- /* if a different placement scheme is requested */
- if (pdata->oob)
- nand->ecc.layout = pdata->oob;
-
-#ifdef CONFIG_NAND_OMAP_GPMC_HWECC
if (pdata->plat_options & NAND_HWECC_ENABLE) {
/* Program how many columns we expect+
* enable the cs we want and enable the engine
@@ -474,7 +514,6 @@ static int gpmc_nand_probe(struct device_d *pdev)
nand->ecc.steps = nand->ecc.layout->eccbytes / nand->ecc.bytes;
oinfo->ecc_parity_pairs = 12;
} else
-#endif
nand->ecc.mode = NAND_ECC_SOFT;
/* All information is ready.. now lets call setup, if present */
@@ -495,15 +534,47 @@ static int gpmc_nand_probe(struct device_d *pdev)
writeb(NAND_CMD_RESET, oinfo->gpmc_command);
mdelay(1);
- /* In normal mode, we scan to get just the device
- * presence and then to get the device geometry
- */
- if (nand_scan(minfo, 1)) {
- gpmcnand_err("device scan failed\n");
+ /* first scan to find the device and get the page size */
+ if (nand_scan_ident(minfo, 1)) {
+ err = -ENXIO;
+ goto out_release_mem;
+ }
+
+ switch (pdata->device_width) {
+ case 8:
+ lsp = &ecc_sp_x8;
+ llp = &ecc_lp_x8;
+ break;
+ case 16:
+ lsp = &ecc_sp_x16;
+ llp = &ecc_lp_x16;
+ break;
+ default:
+ err = -EINVAL;
+ goto out_release_mem;
+ }
+
+ switch (minfo->writesize) {
+ case 512:
+ layout = lsp;
+ break;
+ case 2048:
+ layout = llp;
+ break;
+ default:
+ err = -EINVAL;
+ goto out_release_mem;
+ }
+
+ /* second phase scan */
+ if (nand_scan_tail(minfo)) {
err = -ENXIO;
goto out_release_mem;
}
+ if (pdata->plat_options & NAND_HWECC_ENABLE)
+ nand->ecc.layout = layout;
+
/* We are all set to register with the system now! */
err = add_mtd_device(minfo);
if (err) {