aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/onenand/Kconfig6
-rw-r--r--drivers/mtd/onenand/omap-onenand.c66
-rw-r--r--drivers/mtd/onenand/onenand_base.c39
-rw-r--r--include/linux/mtd/onenand.h1
-rw-r--r--include/linux/mtd/onenand_regs.h17
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
32config 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
32endmenu 38endmenu
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
71const char *part_probes[] = { "cmdlinepart", NULL, }; 72static const char *part_probes[] = { "cmdlinepart", NULL, };
72 73
73#endif 74#endif
74 75
76#ifdef CONFIG_MTD_ONENAND_SYNC_READ
77static unsigned int omap_emifs_cs;
78
79static 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 */
92static 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 */
77static char onenand_name[] = "onenand"; 134static 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 */
391static 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)
1385 if (onenand_probe(mtd)) 1414 if (onenand_probe(mtd))
1386 return -ENXIO; 1415 return -ENXIO;
1387 1416
1417 /* Set Sync. Burst Read after probing */
1418 if (this->mmcontrol) {
1419 printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
1420 this->read_bufferram = onenand_sync_read_bufferram;
1421 }
1422
1388 this->state = FL_READY; 1423 this->state = FL_READY;
1389 init_waitqueue_head(&this->wq); 1424 init_waitqueue_head(&this->wq);
1390 spin_lock_init(&this->chip_lock); 1425 spin_lock_init(&this->chip_lock);
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index b9a64117d646..c557caa24a6c 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -95,6 +95,7 @@ struct onenand_chip {
95 const unsigned char *buffer, int offset, size_t count); 95 const unsigned char *buffer, int offset, size_t count);
96 unsigned short (*read_word)(void __iomem *addr); 96 unsigned short (*read_word)(void __iomem *addr);
97 void (*write_word)(unsigned short value, void __iomem *addr); 97 void (*write_word)(unsigned short value, void __iomem *addr);
98 void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
98 99
99 spinlock_t chip_lock; 100 spinlock_t chip_lock;
100 wait_queue_head_t wq; 101 wait_queue_head_t wq;
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index 4a2daad7d738..d7832ef8ed63 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -121,8 +121,21 @@
121 * System Configuration 1 Register F221h (R, R/W) 121 * System Configuration 1 Register F221h (R, R/W)
122 */ 122 */
123#define ONENAND_SYS_CFG1_SYNC_READ (1 << 15) 123#define ONENAND_SYS_CFG1_SYNC_READ (1 << 15)
124#define ONENAND_SYS_CFG1_BRL (1 << 12) 124#define ONENAND_SYS_CFG1_BRL_7 (7 << 12)
125#define ONENAND_SYS_CFG1_BL (1 << 9) 125#define ONENAND_SYS_CFG1_BRL_6 (6 << 12)
126#define ONENAND_SYS_CFG1_BRL_5 (5 << 12)
127#define ONENAND_SYS_CFG1_BRL_4 (4 << 12)
128#define ONENAND_SYS_CFG1_BRL_3 (3 << 12)
129#define ONENAND_SYS_CFG1_BRL_10 (2 << 12)
130#define ONENAND_SYS_CFG1_BRL_9 (1 << 12)
131#define ONENAND_SYS_CFG1_BRL_8 (0 << 12)
132#define ONENAND_SYS_CFG1_BRL_SHIFT (12)
133#define ONENAND_SYS_CFG1_BL_32 (4 << 9)
134#define ONENAND_SYS_CFG1_BL_16 (3 << 9)
135#define ONENAND_SYS_CFG1_BL_8 (2 << 9)
136#define ONENAND_SYS_CFG1_BL_4 (1 << 9)
137#define ONENAND_SYS_CFG1_BL_CONT (0 << 9)
138#define ONENAND_SYS_CFG1_BL_SHIFT (9)
126#define ONENAND_SYS_CFG1_NO_ECC (1 << 8) 139#define ONENAND_SYS_CFG1_NO_ECC (1 << 8)
127#define ONENAND_SYS_CFG1_RDY (1 << 7) 140#define ONENAND_SYS_CFG1_RDY (1 << 7)
128#define ONENAND_SYS_CFG1_INT (1 << 6) 141#define ONENAND_SYS_CFG1_INT (1 << 6)