Hi all,

I found a chunk of code that was used by both the nand_[write|read]_page_raw
and I thought it might be helpful to NAND devices that implement the
read_page function.  In my case, I don't want to copy the work like the
davinci driver does :P.  Let me know if this is good for committing.

// Dean Glazeski
From 0512447d983a6bf27db711148e30c3480683b5b0 Mon Sep 17 00:00:00 2001
From: Dean Glazeski <[email protected]>
Date: Fri, 20 Nov 2009 00:19:39 -0600
Subject: [PATCH] NAND page command refactoring.

Created a new function that handles sending a command and the address
information for pages to a NAND device.
---
 src/flash/nand.c |   91 +++++++++++++++++++----------------------------------
 src/flash/nand.h |    3 ++
 2 files changed, 36 insertions(+), 58 deletions(-)

diff --git a/src/flash/nand.c b/src/flash/nand.c
index cac26d0..db2f314 100644
--- a/src/flash/nand.c
+++ b/src/flash/nand.c
@@ -839,20 +839,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)
 {
-	uint32_t i;
-
 	if (!nand->device)
 		return ERROR_NAND_DEVICE_NOT_PROBED;
 
-	if (nand->page_size <= 512)
-	{
+	if (oob && NAND_CMD_READ0 && 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);
@@ -868,20 +867,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)
 			nand->controller->address(nand, 0x8);
+		else
+			nand->controller->address(nand, 0x0);
 
 		/* row */
 		nand->controller->address(nand, page & 0xff);
@@ -891,8 +887,10 @@ 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);
+		if (NAND_CMD_READ0 == cmd) {
+			/* large page devices need a start command if reading */
+			nand->controller->command(nand, NAND_CMD_READSTART);
+		}
 	}
 
 	if (nand->controller->nand_ready) {
@@ -902,6 +900,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;
+	uint8_t command = NAND_CMD_READ0;
+	int retval;
+
+	retval = nand_page_command(nand, page, command, !data);
+	if (ERROR_OK != retval) {
+		return retval;
+	}
+
 	if (data)
 	{
 		if (nand->controller->read_block_data != NULL)
@@ -959,46 +971,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 f23dd19..103332f 100644
--- a/src/flash/nand.h
+++ b/src/flash/nand.h
@@ -268,6 +268,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);
+
 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,
-- 
1.6.2.5

_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to