diff options
author | Ladislav Michl <ladis@linux-mips.org> | 2017-06-20 11:44:29 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-06-23 10:38:07 -0400 |
commit | b51ced8e2aec9cc4f5a600b09d09f1b54be19d04 (patch) | |
tree | 3ca19d062a35f74b744d521543e3a56e6ad0161e /drivers/mtd | |
parent | 0da008ef8d0441d582619c279212e65f9f0bd2fa (diff) |
onenand_spl_simple: Add DDP OneNAND support
Current implementation is unable to access second half of
DDP OneNAND flash (reads first half mirrored). Use block
and bufferram address calculations from onenand_base to
fix this.
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/onenand/onenand_spl.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/mtd/onenand/onenand_spl.c b/drivers/mtd/onenand/onenand_spl.c index 6fad34aa1d..0b78067a23 100644 --- a/drivers/mtd/onenand/onenand_spl.c +++ b/drivers/mtd/onenand/onenand_spl.c @@ -23,11 +23,29 @@ enum onenand_spl_pagesize { PAGE_4K = 4096, }; +static unsigned int density_mask; + #define ONENAND_PAGES_PER_BLOCK 64 -#define onenand_block_address(block) (block) #define onenand_sector_address(page) (page << 2) #define onenand_buffer_address() ((1 << 3) << 8) -#define onenand_bufferram_address(block) (0) + +static inline int onenand_block_address(int block) +{ + /* Device Flash Core select, NAND Flash Block Address */ + if (block & density_mask) + return ONENAND_DDP_CHIP1 | (block ^ density_mask); + + return block; +} + +static inline int onenand_bufferram_address(int block) +{ + /* Device BufferRAM Select */ + if (block & density_mask) + return ONENAND_DDP_CHIP1; + + return ONENAND_DDP_CHIP0; +} static inline uint16_t onenand_readw(uint32_t addr) { @@ -41,7 +59,7 @@ static inline void onenand_writew(uint16_t value, uint32_t addr) static enum onenand_spl_pagesize onenand_spl_get_geometry(void) { - uint32_t dev_id, density; + unsigned int dev_id, density, size; if (!onenand_readw(ONENAND_REG_TECHNOLOGY)) { dev_id = onenand_readw(ONENAND_REG_DEVICE_ID); @@ -51,8 +69,11 @@ static enum onenand_spl_pagesize onenand_spl_get_geometry(void) if (density < ONENAND_DEVICE_DENSITY_4Gb) return PAGE_2K; - if (dev_id & ONENAND_DEVICE_IS_DDP) + if (dev_id & ONENAND_DEVICE_IS_DDP) { + size = onenand_readw(ONENAND_REG_DATA_BUFFER_SIZE); + density_mask = 1 << (18 + density - ffs(size)); return PAGE_2K; + } } return PAGE_4K; |