diff options
| author | Kyungmin Park <kyungmin.park@samsung.com> | 2005-09-03 02:07:19 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-11-06 15:19:37 -0500 |
| commit | 52b0eea73de05df33c51ca652e288a3ba1bba03b (patch) | |
| tree | 6ddb928b70458a0137481e434cea416e41ca4bb8 | |
| parent | cd5f6346bc28a41375412b49b290d22ee4e4bbe8 (diff) | |
[PATCH] OneNAND: Sync. Burst Read support
Add OneNAND Sync. Burst Read support
Tested with OMAP platform
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
| -rw-r--r-- | drivers/mtd/onenand/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/mtd/onenand/omap-onenand.c | 66 | ||||
| -rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 39 | ||||
| -rw-r--r-- | include/linux/mtd/onenand.h | 1 | ||||
| -rw-r--r-- | include/linux/mtd/onenand_regs.h | 17 |
5 files changed, 123 insertions, 6 deletions
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig index 7d76ede984d8..186ea9dc0942 100644 --- a/drivers/mtd/onenand/Kconfig +++ b/drivers/mtd/onenand/Kconfig | |||
| @@ -29,4 +29,10 @@ config MTD_ONENAND_OMAP | |||
| 29 | help | 29 | help |
| 30 | Support for OneNAND flash on TI OMAP board. | 30 | Support for OneNAND flash on TI OMAP board. |
| 31 | 31 | ||
| 32 | config MTD_ONENAND_SYNC_READ | ||
| 33 | bool "OneNAND Sync. Burst Read Support" | ||
| 34 | depends on ARCH_OMAP | ||
| 35 | help | ||
| 36 | This enables support for Sync. Burst Read. | ||
| 37 | |||
| 32 | endmenu | 38 | endmenu |
diff --git a/drivers/mtd/onenand/omap-onenand.c b/drivers/mtd/onenand/omap-onenand.c index 56e1aec6b835..7c89549f7f58 100644 --- a/drivers/mtd/onenand/omap-onenand.c +++ b/drivers/mtd/onenand/omap-onenand.c | |||
| @@ -25,9 +25,10 @@ | |||
| 25 | #include <asm/arch/hardware.h> | 25 | #include <asm/arch/hardware.h> |
| 26 | #include <asm/arch/tc.h> | 26 | #include <asm/arch/tc.h> |
| 27 | #include <asm/sizes.h> | 27 | #include <asm/sizes.h> |
| 28 | #include <asm/mach-types.h> | ||
| 28 | 29 | ||
| 29 | #define OMAP_ONENAND_FLASH_START1 OMAP_CS2A_PHYS | 30 | #define OMAP_ONENAND_FLASH_START1 OMAP_CS2A_PHYS |
| 30 | #define OMAP_ONENAND_FLASH_START2 OMAP_CS0_PHYS | 31 | #define OMAP_ONENAND_FLASH_START2 omap_cs3_phys() |
| 31 | /* | 32 | /* |
| 32 | * MTD structure for OMAP board | 33 | * MTD structure for OMAP board |
| 33 | */ | 34 | */ |
| @@ -68,10 +69,66 @@ static struct mtd_partition static_partition[] = { | |||
| 68 | }, | 69 | }, |
| 69 | }; | 70 | }; |
| 70 | 71 | ||
| 71 | const char *part_probes[] = { "cmdlinepart", NULL, }; | 72 | static const char *part_probes[] = { "cmdlinepart", NULL, }; |
| 72 | 73 | ||
| 73 | #endif | 74 | #endif |
| 74 | 75 | ||
| 76 | #ifdef CONFIG_MTD_ONENAND_SYNC_READ | ||
| 77 | static unsigned int omap_emifs_cs; | ||
| 78 | |||
| 79 | static void omap_find_emifs_cs(unsigned int addr) | ||
| 80 | { | ||
| 81 | /* Check CS3 */ | ||
| 82 | if (OMAP_EMIFS_CONFIG_REG & OMAP_EMIFS_CONFIG_BM && addr == 0x0) { | ||
| 83 | omap_emifs_cs = 3; | ||
| 84 | } else { | ||
| 85 | omap_emifs_cs = (addr >> 26); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | /** | ||
| 90 | * omap_onenand_mmcontrol - Control OMAP EMIFS | ||
| 91 | */ | ||
| 92 | static void omap_onenand_mmcontrol(struct mtd_info *mtd, int sync_read) | ||
| 93 | { | ||
| 94 | struct onenand_chip *this = mtd->priv; | ||
| 95 | static unsigned long omap_emifs_ccs, omap_emifs_acs; | ||
| 96 | static unsigned long onenand_sys_cfg1; | ||
| 97 | int config, emifs_ccs, emifs_acs; | ||
| 98 | |||
| 99 | if (sync_read) { | ||
| 100 | /* | ||
| 101 | * Note: BRL and RDWST is equal | ||
| 102 | */ | ||
| 103 | omap_emifs_ccs = EMIFS_CCS(omap_emifs_cs); | ||
| 104 | omap_emifs_acs = EMIFS_ACS(omap_emifs_cs); | ||
| 105 | |||
| 106 | emifs_ccs = 0x41141; | ||
| 107 | emifs_acs = 0x1; | ||
| 108 | |||
| 109 | /* OneNAND System Configuration 1 */ | ||
| 110 | onenand_sys_cfg1 = this->read_word(this->base + ONENAND_REG_SYS_CFG1); | ||
| 111 | config = (onenand_sys_cfg1 | ||
| 112 | & ~(0x3f << ONENAND_SYS_CFG1_BL_SHIFT)) | ||
| 113 | | ONENAND_SYS_CFG1_SYNC_READ | ||
| 114 | | ONENAND_SYS_CFG1_BRL_4 | ||
| 115 | | ONENAND_SYS_CFG1_BL_8; | ||
| 116 | } else { | ||
| 117 | emifs_ccs = omap_emifs_ccs; | ||
| 118 | emifs_acs = omap_emifs_acs; | ||
| 119 | config = onenand_sys_cfg1; | ||
| 120 | } | ||
| 121 | |||
| 122 | this->write_word(config, this->base + ONENAND_REG_SYS_CFG1); | ||
| 123 | EMIFS_CCS(omap_emifs_cs) = emifs_ccs; | ||
| 124 | EMIFS_ACS(omap_emifs_cs) = emifs_acs; | ||
| 125 | } | ||
| 126 | #else | ||
| 127 | #define omap_find_emifs_cs(x) do { } while (0) | ||
| 128 | #define omap_onenand_mmcontrol NULL | ||
| 129 | #endif | ||
| 130 | |||
| 131 | |||
| 75 | /* Scan to find existance of the device at base. | 132 | /* Scan to find existance of the device at base. |
| 76 | This also allocates oob and data internal buffers */ | 133 | This also allocates oob and data internal buffers */ |
| 77 | static char onenand_name[] = "onenand"; | 134 | static char onenand_name[] = "onenand"; |
| @@ -102,14 +159,19 @@ static int __init omap_onenand_init (void) | |||
| 102 | 159 | ||
| 103 | /* Link the private data with the MTD structure */ | 160 | /* Link the private data with the MTD structure */ |
| 104 | omap_onenand_mtd->priv = this; | 161 | omap_onenand_mtd->priv = this; |
| 162 | this->mmcontrol = omap_onenand_mmcontrol; | ||
| 105 | 163 | ||
| 106 | /* try the first address */ | 164 | /* try the first address */ |
| 107 | this->base = ioremap(OMAP_ONENAND_FLASH_START1, SZ_128K); | 165 | this->base = ioremap(OMAP_ONENAND_FLASH_START1, SZ_128K); |
| 166 | omap_find_emifs_cs(OMAP_ONENAND_FLASH_START1); | ||
| 167 | |||
| 108 | omap_onenand_mtd->name = onenand_name; | 168 | omap_onenand_mtd->name = onenand_name; |
| 109 | if (onenand_scan(omap_onenand_mtd, 1)){ | 169 | if (onenand_scan(omap_onenand_mtd, 1)){ |
| 110 | /* try the second address */ | 170 | /* try the second address */ |
| 111 | iounmap(this->base); | 171 | iounmap(this->base); |
| 112 | this->base = ioremap(OMAP_ONENAND_FLASH_START2, SZ_128K); | 172 | this->base = ioremap(OMAP_ONENAND_FLASH_START2, SZ_128K); |
| 173 | omap_find_emifs_cs(OMAP_ONENAND_FLASH_START2); | ||
| 174 | |||
| 113 | if (onenand_scan(omap_onenand_mtd, 1)) { | 175 | if (onenand_scan(omap_onenand_mtd, 1)) { |
| 114 | iounmap(this->base); | 176 | iounmap(this->base); |
| 115 | err = -ENXIO; | 177 | err = -ENXIO; |
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index bcce22ae3cb1..e87489505772 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
| @@ -379,6 +379,35 @@ static int onenand_read_bufferram(struct mtd_info *mtd, int area, | |||
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | /** | 381 | /** |
| 382 | * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode | ||
| 383 | * @param mtd MTD data structure | ||
| 384 | * @param area BufferRAM area | ||
| 385 | * @param buffer the databuffer to put/get data | ||
| 386 | * @param offset offset to read from or write to | ||
| 387 | * @param count number of bytes to read/write | ||
| 388 | * | ||
| 389 | * Read the BufferRAM area with Sync. Burst Mode | ||
| 390 | */ | ||
| 391 | static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area, | ||
| 392 | unsigned char *buffer, int offset, size_t count) | ||
| 393 | { | ||
| 394 | struct onenand_chip *this = mtd->priv; | ||
| 395 | void __iomem *bufferram; | ||
| 396 | |||
| 397 | bufferram = this->base + area; | ||
| 398 | |||
| 399 | bufferram += onenand_bufferram_offset(mtd, area); | ||
| 400 | |||
| 401 | this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ); | ||
| 402 | |||
| 403 | memcpy(buffer, bufferram + offset, count); | ||
| 404 | |||
| 405 | this->mmcontrol(mtd, 0); | ||
| 406 | |||
| 407 | return 0; | ||
| 408 | } | ||
| 409 | |||
| 410 | /** | ||
| 382 | * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area | 411 | * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area |
| 383 | * @param mtd MTD data structure | 412 | * @param mtd MTD data structure |
| 384 | * @param area BufferRAM area | 413 | * @param area BufferRAM area |
| @@ -1273,8 +1302,8 @@ static int onenand_check_maf(int manuf) | |||
| 1273 | break; | 1302 | break; |
| 1274 | } | 1303 | } |
| 1275 | 1304 | ||
| 1276 | printk(KERN_DEBUG "OneNAND Manufacturer: %s\n", | 1305 | printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", |
| 1277 | onenand_manuf_ids[i].name); | 1306 | onenand_manuf_ids[i].name, manuf); |
| 1278 | 1307 | ||
| 1279 | return (i != ONENAND_MFR_UNKNOWN); | 1308 | return (i != ONENAND_MFR_UNKNOWN); |
| 1280 | } | 1309 | } |
| @@ -1385,6 +1414,12 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) | |||
