diff mbox

[U-Boot,2/2] onenand_spl_simple: Add DDP OneNAND support

Message ID 20170620094429.lnrjgfiq7qz5tran@lenoch
State Accepted
Commit b51ced8e2aec9cc4f5a600b09d09f1b54be19d04
Delegated to: Tom Rini
Headers show

Commit Message

Ladislav Michl June 20, 2017, 9:44 a.m. UTC
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>
---
 drivers/mtd/onenand/onenand_spl.c | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

Comments

Tom Rini June 24, 2017, 10:17 p.m. UTC | #1
On Tue, Jun 20, 2017 at 11:44:29AM +0200, Ladislav Michl wrote:

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

Applied to u-boot/master, thanks!
diff mbox

Patch

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;