Commit 8048525d authored by Teerth Reddy's avatar Teerth Reddy Committed by Tony Lindgren

OMAP3 NAND: Add NAND support on OMAP3430

This patch adds NAND support on 3430sdp board

[VS: updated for NAND_BLOCK_SIZE macros]
Signed-off-by: default avatarTeerth Reddy <teerth@ti.com>
Signed-off-by: default avatarVimal Singh <vimal.singh@ti.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 3ed75505
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <mach/onenand.h> #include <mach/onenand.h>
#include <mach/board.h> #include <mach/board.h>
#include <mach/gpmc.h> #include <mach/gpmc.h>
#include <mach/nand.h>
static struct mtd_partition sdp_nor_partitions[] = { static struct mtd_partition sdp_nor_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */ /* bootloader (U-Boot, etc) in first sector */
...@@ -137,6 +138,61 @@ static int sdp_onenand_setup(void __iomem *onenand_base, int freq) ...@@ -137,6 +138,61 @@ static int sdp_onenand_setup(void __iomem *onenand_base, int freq)
/* Onenand setup does nothing at present */ /* Onenand setup does nothing at present */
return 0; return 0;
} }
static struct mtd_partition sdp_nand_partitions[] = {
/* All the partition sizes are listed in terms of NAND block size */
{
.name = "X-Loader-NAND",
.offset = 0,
.size = 4 * NAND_BLOCK_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "U-Boot-NAND",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
.size = 4 * NAND_BLOCK_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
{
.name = "Boot Env-NAND",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x100000 */
.size = 2 * NAND_BLOCK_SIZE,
},
{
.name = "Kernel-NAND",
.offset = MTDPART_OFS_APPEND, /* Offset = 0x140000 */
.size = 32 * NAND_BLOCK_SIZE,
},
{
.name = "File System - NAND",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND, /* Offset = 0x540000 */
},
};
static struct omap_nand_platform_data sdp_nand_data = {
.parts = sdp_nand_partitions,
.nr_parts = ARRAY_SIZE(sdp_nand_partitions),
.nand_setup = NULL,
.dma_channel = -1, /* disable DMA in OMAP NAND driver */
.dev_ready = NULL,
};
static struct resource sdp_nand_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device sdp_nand_device = {
.name = "omap2-nand",
.id = 0,
.dev = {
.platform_data = &sdp_nand_data,
},
.num_resources = 1,
.resource = &sdp_nand_resource,
};
/** /**
* sdp3430_flash_init - Identify devices connected to GPMC and register. * sdp3430_flash_init - Identify devices connected to GPMC and register.
* *
...@@ -145,7 +201,11 @@ static int sdp_onenand_setup(void __iomem *onenand_base, int freq) ...@@ -145,7 +201,11 @@ static int sdp_onenand_setup(void __iomem *onenand_base, int freq)
void __init sdp3430_flash_init(void) void __init sdp3430_flash_init(void)
{ {
u8 cs = 0; u8 cs = 0;
u8 nandcs = GPMC_CS_NUM + 1;
u8 onenandcs = GPMC_CS_NUM + 1; u8 onenandcs = GPMC_CS_NUM + 1;
unsigned long gpmc_base_add;
gpmc_base_add = OMAP34XX_GPMC_VIRT;
/* Configure start address and size of NOR device */ /* Configure start address and size of NOR device */
if (system_rev > OMAP3430_REV_ES1_0) { if (system_rev > OMAP3430_REV_ES1_0) {
...@@ -163,25 +223,42 @@ void __init sdp3430_flash_init(void) ...@@ -163,25 +223,42 @@ void __init sdp3430_flash_init(void)
while (cs < GPMC_CS_NUM) { while (cs < GPMC_CS_NUM) {
u32 ret = 0; u32 ret = 0;
ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
/* /*
* xloader/Uboot would have programmed the oneNAND * xloader/Uboot would have programmed the NAND/oneNAND
* base address for us This is a ugly hack. The proper * base address for us This is a ugly hack. The proper
* way of doing this is to pass the setup of u-boot up * way of doing this is to pass the setup of u-boot up
* to kernel using kernel params - something on the * to kernel using kernel params - something on the
* lines of machineID. Check if oneNAND is configured * lines of machineID. Check if oneNAND is configured
*/ */
if ((ret & 0x3F) == (ONENAND_MAP >> 24)) if ((ret & 0xC00) == 0x800) {
/* Found it!! */
if (nandcs > GPMC_CS_NUM)
nandcs = cs;
} else {
ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
if ((ret & 0x3F) == (ONENAND_MAP >> 24))
onenandcs = cs; onenandcs = cs;
}
cs++; cs++;
} }
if (onenandcs > GPMC_CS_NUM) { if ((nandcs > GPMC_CS_NUM) && (onenandcs > GPMC_CS_NUM)) {
printk(KERN_INFO "OneNAND: Unable to find configuration " printk(KERN_INFO "NAND/OneNAND: Unable to find configuration "
" in GPMC\n "); " in GPMC\n ");
return; return;
} }
if (nandcs < GPMC_CS_NUM) {
sdp_nand_data.cs = nandcs;
sdp_nand_data.gpmc_cs_baseaddr = (void *)(gpmc_base_add +
GPMC_CS0_BASE + nandcs*GPMC_CS_SIZE);
sdp_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
if (platform_device_register(&sdp_nand_device) < 0)
printk(KERN_ERR "Unable to register NAND device\n");
}
if (onenandcs < GPMC_CS_NUM) { if (onenandcs < GPMC_CS_NUM) {
sdp_onenand_data.cs = onenandcs; sdp_onenand_data.cs = onenandcs;
if (platform_device_register(&sdp_onenand_device) < 0) if (platform_device_register(&sdp_onenand_device) < 0)
......
...@@ -25,8 +25,18 @@ ...@@ -25,8 +25,18 @@
#define GPMC_CS_NAND_ADDRESS 0x20 #define GPMC_CS_NAND_ADDRESS 0x20
#define GPMC_CS_NAND_DATA 0x24 #define GPMC_CS_NAND_DATA 0x24
/*
* The following gpmc registers are being used by
* nand driver and hence is defined here.
* TBD: Move them to gpmc.c by providing appropriate
* methods to read and write into these registers
*/
#define GPMC_IRQSTATUS 0x18
#define GPMC_CONFIG 0x50 #define GPMC_CONFIG 0x50
#define GPMC_STATUS 0x54 #define GPMC_STATUS 0x54
#define GPMC_CS0_BASE 0x60
#define GPMC_CS_SIZE 0x30
#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31) #define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31)
#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30) #define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30)
......
...@@ -45,7 +45,7 @@ extern void nand_wait_ready(struct mtd_info *mtd); ...@@ -45,7 +45,7 @@ extern void nand_wait_ready(struct mtd_info *mtd);
*/ */
#define NAND_MAX_OOBSIZE 64 #define NAND_MAX_OOBSIZE 64
#define NAND_MAX_PAGESIZE 2048 #define NAND_MAX_PAGESIZE 2048
#define NAND_BLOCK_SIZE SZ_128K
/* /*
* Constants for hardware specific CLE/ALE/NCE function * Constants for hardware specific CLE/ALE/NCE function
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment