mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-25 08:02:56 +00:00
[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>
This commit is contained in:
parent
cd5f6346bc
commit
52b0eea73d
5 changed files with 123 additions and 6 deletions
|
@ -29,4 +29,10 @@ config MTD_ONENAND_OMAP
|
||||||
help
|
help
|
||||||
Support for OneNAND flash on TI OMAP board.
|
Support for OneNAND flash on TI OMAP board.
|
||||||
|
|
||||||
|
config MTD_ONENAND_SYNC_READ
|
||||||
|
bool "OneNAND Sync. Burst Read Support"
|
||||||
|
depends on ARCH_OMAP
|
||||||
|
help
|
||||||
|
This enables support for Sync. Burst Read.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -25,9 +25,10 @@
|
||||||
#include <asm/arch/hardware.h>
|
#include <asm/arch/hardware.h>
|
||||||
#include <asm/arch/tc.h>
|
#include <asm/arch/tc.h>
|
||||||
#include <asm/sizes.h>
|
#include <asm/sizes.h>
|
||||||
|
#include <asm/mach-types.h>
|
||||||
|
|
||||||
#define OMAP_ONENAND_FLASH_START1 OMAP_CS2A_PHYS
|
#define OMAP_ONENAND_FLASH_START1 OMAP_CS2A_PHYS
|
||||||
#define OMAP_ONENAND_FLASH_START2 OMAP_CS0_PHYS
|
#define OMAP_ONENAND_FLASH_START2 omap_cs3_phys()
|
||||||
/*
|
/*
|
||||||
* MTD structure for OMAP board
|
* MTD structure for OMAP board
|
||||||
*/
|
*/
|
||||||
|
@ -68,10 +69,66 @@ static struct mtd_partition static_partition[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *part_probes[] = { "cmdlinepart", NULL, };
|
static const char *part_probes[] = { "cmdlinepart", NULL, };
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_MTD_ONENAND_SYNC_READ
|
||||||
|
static unsigned int omap_emifs_cs;
|
||||||
|
|
||||||
|
static void omap_find_emifs_cs(unsigned int addr)
|
||||||
|
{
|
||||||
|
/* Check CS3 */
|
||||||
|
if (OMAP_EMIFS_CONFIG_REG & OMAP_EMIFS_CONFIG_BM && addr == 0x0) {
|
||||||
|
omap_emifs_cs = 3;
|
||||||
|
} else {
|
||||||
|
omap_emifs_cs = (addr >> 26);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* omap_onenand_mmcontrol - Control OMAP EMIFS
|
||||||
|
*/
|
||||||
|
static void omap_onenand_mmcontrol(struct mtd_info *mtd, int sync_read)
|
||||||
|
{
|
||||||
|
struct onenand_chip *this = mtd->priv;
|
||||||
|
static unsigned long omap_emifs_ccs, omap_emifs_acs;
|
||||||
|
static unsigned long onenand_sys_cfg1;
|
||||||
|
int config, emifs_ccs, emifs_acs;
|
||||||
|
|
||||||
|
if (sync_read) {
|
||||||
|
/*
|
||||||
|
* Note: BRL and RDWST is equal
|
||||||
|
*/
|
||||||
|
omap_emifs_ccs = EMIFS_CCS(omap_emifs_cs);
|
||||||
|
omap_emifs_acs = EMIFS_ACS(omap_emifs_cs);
|
||||||
|
|
||||||
|
emifs_ccs = 0x41141;
|
||||||
|
emifs_acs = 0x1;
|
||||||
|
|
||||||
|
/* OneNAND System Configuration 1 */
|
||||||
|
onenand_sys_cfg1 = this->read_word(this->base + ONENAND_REG_SYS_CFG1);
|
||||||
|
config = (onenand_sys_cfg1
|
||||||
|
& ~(0x3f << ONENAND_SYS_CFG1_BL_SHIFT))
|
||||||
|
| ONENAND_SYS_CFG1_SYNC_READ
|
||||||
|
| ONENAND_SYS_CFG1_BRL_4
|
||||||
|
| ONENAND_SYS_CFG1_BL_8;
|
||||||
|
} else {
|
||||||
|
emifs_ccs = omap_emifs_ccs;
|
||||||
|
emifs_acs = omap_emifs_acs;
|
||||||
|
config = onenand_sys_cfg1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->write_word(config, this->base + ONENAND_REG_SYS_CFG1);
|
||||||
|
EMIFS_CCS(omap_emifs_cs) = emifs_ccs;
|
||||||
|
EMIFS_ACS(omap_emifs_cs) = emifs_acs;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define omap_find_emifs_cs(x) do { } while (0)
|
||||||
|
#define omap_onenand_mmcontrol NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Scan to find existance of the device at base.
|
/* Scan to find existance of the device at base.
|
||||||
This also allocates oob and data internal buffers */
|
This also allocates oob and data internal buffers */
|
||||||
static char onenand_name[] = "onenand";
|
static char onenand_name[] = "onenand";
|
||||||
|
@ -102,14 +159,19 @@ static int __init omap_onenand_init (void)
|
||||||
|
|
||||||
/* Link the private data with the MTD structure */
|
/* Link the private data with the MTD structure */
|
||||||
omap_onenand_mtd->priv = this;
|
omap_onenand_mtd->priv = this;
|
||||||
|
this->mmcontrol = omap_onenand_mmcontrol;
|
||||||
|
|
||||||
/* try the first address */
|
/* try the first address */
|
||||||
this->base = ioremap(OMAP_ONENAND_FLASH_START1, SZ_128K);
|
this->base = ioremap(OMAP_ONENAND_FLASH_START1, SZ_128K);
|
||||||
|
omap_find_emifs_cs(OMAP_ONENAND_FLASH_START1);
|
||||||
|
|
||||||
omap_onenand_mtd->name = onenand_name;
|
omap_onenand_mtd->name = onenand_name;
|
||||||
if (onenand_scan(omap_onenand_mtd, 1)){
|
if (onenand_scan(omap_onenand_mtd, 1)){
|
||||||
/* try the second address */
|
/* try the second address */
|
||||||
iounmap(this->base);
|
iounmap(this->base);
|
||||||
this->base = ioremap(OMAP_ONENAND_FLASH_START2, SZ_128K);
|
this->base = ioremap(OMAP_ONENAND_FLASH_START2, SZ_128K);
|
||||||
|
omap_find_emifs_cs(OMAP_ONENAND_FLASH_START2);
|
||||||
|
|
||||||
if (onenand_scan(omap_onenand_mtd, 1)) {
|
if (onenand_scan(omap_onenand_mtd, 1)) {
|
||||||
iounmap(this->base);
|
iounmap(this->base);
|
||||||
err = -ENXIO;
|
err = -ENXIO;
|
||||||
|
|
|
@ -378,6 +378,35 @@ static int onenand_read_bufferram(struct mtd_info *mtd, int area,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
|
||||||
|
* @param mtd MTD data structure
|
||||||
|
* @param area BufferRAM area
|
||||||
|
* @param buffer the databuffer to put/get data
|
||||||
|
* @param offset offset to read from or write to
|
||||||
|
* @param count number of bytes to read/write
|
||||||
|
*
|
||||||
|
* Read the BufferRAM area with Sync. Burst Mode
|
||||||
|
*/
|
||||||
|
static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
|
||||||
|
unsigned char *buffer, int offset, size_t count)
|
||||||
|
{
|
||||||
|
struct onenand_chip *this = mtd->priv;
|
||||||
|
void __iomem *bufferram;
|
||||||
|
|
||||||
|
bufferram = this->base + area;
|
||||||
|
|
||||||
|
bufferram += onenand_bufferram_offset(mtd, area);
|
||||||
|
|
||||||
|
this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
|
||||||
|
|
||||||
|
memcpy(buffer, bufferram + offset, count);
|
||||||
|
|
||||||
|
this->mmcontrol(mtd, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
|
* onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
|
||||||
* @param mtd MTD data structure
|
* @param mtd MTD data structure
|
||||||
|
@ -1273,8 +1302,8 @@ static int onenand_check_maf(int manuf)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(KERN_DEBUG "OneNAND Manufacturer: %s\n",
|
printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
|
||||||
onenand_manuf_ids[i].name);
|
onenand_manuf_ids[i].name, manuf);
|
||||||
|
|
||||||
return (i != ONENAND_MFR_UNKNOWN);
|
return (i != ONENAND_MFR_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
@ -1385,6 +1414,12 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
|
||||||
if (onenand_probe(mtd))
|
if (onenand_probe(mtd))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
|
/* Set Sync. Burst Read after probing */
|
||||||
|
if (this->mmcontrol) {
|
||||||
|
printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
|
||||||
|
this->read_bufferram = onenand_sync_read_bufferram;
|
||||||
|
}
|
||||||
|
|
||||||
this->state = FL_READY;
|
this->state = FL_READY;
|
||||||
init_waitqueue_head(&this->wq);
|
init_waitqueue_head(&this->wq);
|
||||||
spin_lock_init(&this->chip_lock);
|
spin_lock_init(&this->chip_lock);
|
||||||
|
|
|
@ -95,6 +95,7 @@ struct onenand_chip {
|
||||||
const unsigned char *buffer, int offset, size_t count);
|
const unsigned char *buffer, int offset, size_t count);
|
||||||
unsigned short (*read_word)(void __iomem *addr);
|
unsigned short (*read_word)(void __iomem *addr);
|
||||||
void (*write_word)(unsigned short value, void __iomem *addr);
|
void (*write_word)(unsigned short value, void __iomem *addr);
|
||||||
|
void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
|
||||||
|
|
||||||
spinlock_t chip_lock;
|
spinlock_t chip_lock;
|
||||||
wait_queue_head_t wq;
|
wait_queue_head_t wq;
|
||||||
|
|
|
@ -121,8 +121,21 @@
|
||||||
* System Configuration 1 Register F221h (R, R/W)
|
* System Configuration 1 Register F221h (R, R/W)
|
||||||
*/
|
*/
|
||||||
#define ONENAND_SYS_CFG1_SYNC_READ (1 << 15)
|
#define ONENAND_SYS_CFG1_SYNC_READ (1 << 15)
|
||||||
#define ONENAND_SYS_CFG1_BRL (1 << 12)
|
#define ONENAND_SYS_CFG1_BRL_7 (7 << 12)
|
||||||
#define ONENAND_SYS_CFG1_BL (1 << 9)
|
#define ONENAND_SYS_CFG1_BRL_6 (6 << 12)
|
||||||
|
#define ONENAND_SYS_CFG1_BRL_5 (5 << 12)
|
||||||
|
#define ONENAND_SYS_CFG1_BRL_4 (4 << 12)
|
||||||
|
#define ONENAND_SYS_CFG1_BRL_3 (3 << 12)
|
||||||
|
#define ONENAND_SYS_CFG1_BRL_10 (2 << 12)
|
||||||
|
#define ONENAND_SYS_CFG1_BRL_9 (1 << 12)
|
||||||
|
#define ONENAND_SYS_CFG1_BRL_8 (0 << 12)
|
||||||
|
#define ONENAND_SYS_CFG1_BRL_SHIFT (12)
|
||||||
|
#define ONENAND_SYS_CFG1_BL_32 (4 << 9)
|
||||||
|
#define ONENAND_SYS_CFG1_BL_16 (3 << 9)
|
||||||
|
#define ONENAND_SYS_CFG1_BL_8 (2 << 9)
|
||||||
|
#define ONENAND_SYS_CFG1_BL_4 (1 << 9)
|
||||||
|
#define ONENAND_SYS_CFG1_BL_CONT (0 << 9)
|
||||||
|
#define ONENAND_SYS_CFG1_BL_SHIFT (9)
|
||||||
#define ONENAND_SYS_CFG1_NO_ECC (1 << 8)
|
#define ONENAND_SYS_CFG1_NO_ECC (1 << 8)
|
||||||
#define ONENAND_SYS_CFG1_RDY (1 << 7)
|
#define ONENAND_SYS_CFG1_RDY (1 << 7)
|
||||||
#define ONENAND_SYS_CFG1_INT (1 << 6)
|
#define ONENAND_SYS_CFG1_INT (1 << 6)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue