Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Kyungmin Park and committed by
Thomas Gleixner
52b0eea7 cd5f6346

+123 -6
+6
drivers/mtd/onenand/Kconfig
··· 29 29 help 30 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 38 endmenu
+64 -2
drivers/mtd/onenand/omap-onenand.c
··· 25 25 #include <asm/arch/hardware.h> 26 26 #include <asm/arch/tc.h> 27 27 #include <asm/sizes.h> 28 + #include <asm/mach-types.h> 28 29 29 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 33 * MTD structure for OMAP board 33 34 */ ··· 69 68 }, 70 69 }; 71 70 72 - const char *part_probes[] = { "cmdlinepart", NULL, }; 71 + static const char *part_probes[] = { "cmdlinepart", NULL, }; 73 72 74 73 #endif 74 + 75 + #ifdef CONFIG_MTD_ONENAND_SYNC_READ 76 + static unsigned int omap_emifs_cs; 77 + 78 + static void omap_find_emifs_cs(unsigned int addr) 79 + { 80 + /* Check CS3 */ 81 + if (OMAP_EMIFS_CONFIG_REG & OMAP_EMIFS_CONFIG_BM && addr == 0x0) { 82 + omap_emifs_cs = 3; 83 + } else { 84 + omap_emifs_cs = (addr >> 26); 85 + } 86 + } 87 + 88 + /** 89 + * omap_onenand_mmcontrol - Control OMAP EMIFS 90 + */ 91 + static void omap_onenand_mmcontrol(struct mtd_info *mtd, int sync_read) 92 + { 93 + struct onenand_chip *this = mtd->priv; 94 + static unsigned long omap_emifs_ccs, omap_emifs_acs; 95 + static unsigned long onenand_sys_cfg1; 96 + int config, emifs_ccs, emifs_acs; 97 + 98 + if (sync_read) { 99 + /* 100 + * Note: BRL and RDWST is equal 101 + */ 102 + omap_emifs_ccs = EMIFS_CCS(omap_emifs_cs); 103 + omap_emifs_acs = EMIFS_ACS(omap_emifs_cs); 104 + 105 + emifs_ccs = 0x41141; 106 + emifs_acs = 0x1; 107 + 108 + /* OneNAND System Configuration 1 */ 109 + onenand_sys_cfg1 = this->read_word(this->base + ONENAND_REG_SYS_CFG1); 110 + config = (onenand_sys_cfg1 111 + & ~(0x3f << ONENAND_SYS_CFG1_BL_SHIFT)) 112 + | ONENAND_SYS_CFG1_SYNC_READ 113 + | ONENAND_SYS_CFG1_BRL_4 114 + | ONENAND_SYS_CFG1_BL_8; 115 + } else { 116 + emifs_ccs = omap_emifs_ccs; 117 + emifs_acs = omap_emifs_acs; 118 + config = onenand_sys_cfg1; 119 + } 120 + 121 + this->write_word(config, this->base + ONENAND_REG_SYS_CFG1); 122 + EMIFS_CCS(omap_emifs_cs) = emifs_ccs; 123 + EMIFS_ACS(omap_emifs_cs) = emifs_acs; 124 + } 125 + #else 126 + #define omap_find_emifs_cs(x) do { } while (0) 127 + #define omap_onenand_mmcontrol NULL 128 + #endif 129 + 75 130 76 131 /* Scan to find existance of the device at base. 77 132 This also allocates oob and data internal buffers */ ··· 159 102 160 103 /* Link the private data with the MTD structure */ 161 104 omap_onenand_mtd->priv = this; 105 + this->mmcontrol = omap_onenand_mmcontrol; 162 106 163 107 /* try the first address */ 164 108 this->base = ioremap(OMAP_ONENAND_FLASH_START1, SZ_128K); 109 + omap_find_emifs_cs(OMAP_ONENAND_FLASH_START1); 110 + 165 111 omap_onenand_mtd->name = onenand_name; 166 112 if (onenand_scan(omap_onenand_mtd, 1)){ 167 113 /* try the second address */ 168 114 iounmap(this->base); 169 115 this->base = ioremap(OMAP_ONENAND_FLASH_START2, SZ_128K); 116 + omap_find_emifs_cs(OMAP_ONENAND_FLASH_START2); 117 + 170 118 if (onenand_scan(omap_onenand_mtd, 1)) { 171 119 iounmap(this->base); 172 120 err = -ENXIO;
+37 -2
drivers/mtd/onenand/onenand_base.c
··· 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 411 * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area 383 412 * @param mtd MTD data structure 384 413 * @param area BufferRAM area ··· 1302 1273 break; 1303 1274 } 1304 1275 1305 - printk(KERN_DEBUG "OneNAND Manufacturer: %s\n", 1306 - onenand_manuf_ids[i].name); 1276 + printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", 1277 + onenand_manuf_ids[i].name, manuf); 1307 1278 1308 1279 return (i != ONENAND_MFR_UNKNOWN); 1309 1280 } ··· 1413 1384 1414 1385 if (onenand_probe(mtd)) 1415 1386 return -ENXIO; 1387 + 1388 + /* Set Sync. Burst Read after probing */ 1389 + if (this->mmcontrol) { 1390 + printk(KERN_INFO "OneNAND Sync. Burst Read support\n"); 1391 + this->read_bufferram = onenand_sync_read_bufferram; 1392 + } 1416 1393 1417 1394 this->state = FL_READY; 1418 1395 init_waitqueue_head(&this->wq);
+1
include/linux/mtd/onenand.h
··· 95 95 const unsigned char *buffer, int offset, size_t count); 96 96 unsigned short (*read_word)(void __iomem *addr); 97 97 void (*write_word)(unsigned short value, void __iomem *addr); 98 + void (*mmcontrol)(struct mtd_info *mtd, int sync_read); 98 99 99 100 spinlock_t chip_lock; 100 101 wait_queue_head_t wq;
+15 -2
include/linux/mtd/onenand_regs.h
··· 121 121 * System Configuration 1 Register F221h (R, R/W) 122 122 */ 123 123 #define ONENAND_SYS_CFG1_SYNC_READ (1 << 15) 124 - #define ONENAND_SYS_CFG1_BRL (1 << 12) 125 - #define ONENAND_SYS_CFG1_BL (1 << 9) 124 + #define ONENAND_SYS_CFG1_BRL_7 (7 << 12) 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 139 #define ONENAND_SYS_CFG1_NO_ECC (1 << 8) 127 140 #define ONENAND_SYS_CFG1_RDY (1 << 7) 128 141 #define ONENAND_SYS_CFG1_INT (1 << 6)