From 9a51b8b0e3d0b629915a8248e2c112a01ffc93dc Mon Sep 17 00:00:00 2001
From: Dean Glazeski <dnglaze@gmail.com>
Date: Fri, 20 Nov 2009 00:19:39 -0600
Subject: NAND page command refactoring.

Created a new function that handles sending a command and the address
information for pages to a NAND device.

[dbrownell@users.sourceforge.net: tweaked line lengths, name 'oob_only']

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
---
 src/flash/nand.c | 91 ++++++++++++++++++++------------------------------------
 src/flash/nand.h |  3 ++
 2 files changed, 35 insertions(+), 59 deletions(-)

(limited to 'src')

diff --git a/src/flash/nand.c b/src/flash/nand.c
index 5bcbea47..2f0f503f 100644
--- a/src/flash/nand.c
+++ b/src/flash/nand.c
@@ -863,20 +863,19 @@ static int nand_read_page(struct nand_device *nand, uint32_t page, uint8_t *data
 		return nand->controller->read_page(nand, page, data, data_size, oob, oob_size);
 }
 
-int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)
+int nand_page_command(struct nand_device *nand, uint32_t page,
+		uint8_t cmd, bool oob_only)
 {
-	uint32_t i;
-
 	if (!nand->device)
 		return ERROR_NAND_DEVICE_NOT_PROBED;
 
-	if (nand->page_size <= 512)
-	{
+	if (oob_only && NAND_CMD_READ0 == cmd && nand->page_size <= 512)
+		cmd = NAND_CMD_READOOB;
+
+	nand->controller->command(nand, cmd);
+
+	if (nand->page_size <= 512) {
 		/* small page device */
-		if (data)
-			nand->controller->command(nand, NAND_CMD_READ0);
-		else
-			nand->controller->command(nand, NAND_CMD_READOOB);
 
 		/* column (always 0, we start at the beginning of a page/OOB area) */
 		nand->controller->address(nand, 0x0);
@@ -892,20 +891,17 @@ int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, u
 		/* 5th cycle only on devices with more than 8 GiB */
 		if (nand->address_cycles >= 5)
 			nand->controller->address(nand, (page >> 24) & 0xff);
-	}
-	else
-	{
+	} else {
 		/* large page device */
-		nand->controller->command(nand, NAND_CMD_READ0);
 
 		/* column (0 when we start at the beginning of a page,
 		 * or 2048 for the beginning of OOB area)
 		 */
 		nand->controller->address(nand, 0x0);
-		if (data)
-			nand->controller->address(nand, 0x0);
-		else
+		if (oob_only)
 			nand->controller->address(nand, 0x8);
+		else
+			nand->controller->address(nand, 0x0);
 
 		/* row */
 		nand->controller->address(nand, page & 0xff);
@@ -915,8 +911,9 @@ int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, u
 		if (nand->address_cycles >= 5)
 			nand->controller->address(nand, (page >> 16) & 0xff);
 
-		/* large page devices need a start command */
-		nand->controller->command(nand, NAND_CMD_READSTART);
+		/* large page devices need a start command if reading */
+		if (NAND_CMD_READ0 == cmd)
+			nand->controller->command(nand, NAND_CMD_READSTART);
 	}
 
 	if (nand->controller->nand_ready) {
@@ -926,6 +923,20 @@ int nand_read_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data, u
 		alive_sleep(1);
 	}
 
+	return ERROR_OK;
+}
+
+int nand_read_page_raw(struct nand_device *nand, uint32_t page,
+		uint8_t *data, uint32_t data_size,
+		uint8_t *oob, uint32_t oob_size)
+{
+	uint32_t i;
+	int retval;
+
+	retval = nand_page_command(nand, page, NAND_CMD_READ0, !data);
+	if (ERROR_OK != retval)
+		return retval;
+
 	if (data)
 	{
 		if (nand->controller->read_block_data != NULL)
@@ -983,47 +994,9 @@ int nand_write_page_raw(struct nand_device *nand, uint32_t page, uint8_t *data,
 	int retval;
 	uint8_t status;
 
-	if (!nand->device)
-		return ERROR_NAND_DEVICE_NOT_PROBED;
-
-	nand->controller->command(nand, NAND_CMD_SEQIN);
-
-	if (nand->page_size <= 512)
-	{
-		/* column (always 0, we start at the beginning of a page/OOB area) */
-		nand->controller->address(nand, 0x0);
-
-		/* row */
-		nand->controller->address(nand, page & 0xff);
-		nand->controller->address(nand, (page >> 8) & 0xff);
-
-		/* 4th cycle only on devices with more than 32 MiB */
-		if (nand->address_cycles >= 4)
-			nand->controller->address(nand, (page >> 16) & 0xff);
-
-		/* 5th cycle only on devices with more than 8 GiB */
-		if (nand->address_cycles >= 5)
-			nand->controller->address(nand, (page >> 24) & 0xff);
-	}
-	else
-	{
-		/* column (0 when we start at the beginning of a page,
-		 * or 2048 for the beginning of OOB area)
-		 */
-		nand->controller->address(nand, 0x0);
-		if (data)
-			nand->controller->address(nand, 0x0);
-		else
-			nand->controller->address(nand, 0x8);
-
-		/* row */
-		nand->controller->address(nand, page & 0xff);
-		nand->controller->address(nand, (page >> 8) & 0xff);
-
-		/* 5th cycle only on devices with more than 128 MiB */
-		if (nand->address_cycles >= 5)
-			nand->controller->address(nand, (page >> 16) & 0xff);
-	}
+	retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);
+	if (ERROR_OK != retval)
+		return retval;
 
 	if (data)
 	{
diff --git a/src/flash/nand.h b/src/flash/nand.h
index d73aee14..230cf508 100644
--- a/src/flash/nand.h
+++ b/src/flash/nand.h
@@ -270,6 +270,9 @@ struct nand_device *get_nand_device_by_name(const char *name);
 
 struct nand_device *get_nand_device_by_num(int num);
 
+int nand_page_command(struct nand_device *nand, uint32_t page,
+		uint8_t cmd, bool oob_only);
+
 int nand_read_page_raw(struct nand_device *nand, uint32_t page,
 		uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);
 int nand_write_page_raw(struct nand_device *nand, uint32_t page,
-- 
cgit v1.2.3