From 10edfff05a2fc8c3ae161a7684482d001f6b576a Mon Sep 17 00:00:00 2001
From: oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Sun, 1 Mar 2009 20:57:34 +0000
Subject: Nicolas Pitre nico at cam.org  support for NAND controllers without
 explicit busy signal

git-svn-id: svn://svn.berlios.de/openocd/trunk@1387 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/flash/nand.c | 42 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 36 insertions(+), 6 deletions(-)

(limited to 'src/flash')

diff --git a/src/flash/nand.c b/src/flash/nand.c
index 8708ef3c..1d0766d6 100644
--- a/src/flash/nand.c
+++ b/src/flash/nand.c
@@ -372,6 +372,27 @@ int nand_read_status(struct nand_device_s *device, u8 *status)
 	return ERROR_OK;
 }
 
+int nand_poll_ready(struct nand_device_s *device, int timeout)
+{
+	u8 status;
+
+	device->controller->command(device, NAND_CMD_STATUS);
+	do {
+		if (device->device->options & NAND_BUSWIDTH_16) {
+			u16 data;
+			device->controller->read_data(device, &data);
+			status = data & 0xff;
+		} else {
+			device->controller->read_data(device, &status);
+		}
+		if (status & NAND_STATUS_READY)
+			break;
+		alive_sleep(1);
+	} while (timeout--);
+
+	return (status & NAND_STATUS_READY) != 0;
+}
+
 int nand_probe(struct nand_device_s *device)
 {
 	u8 manufacturer_id, device_id;
@@ -648,9 +669,11 @@ int nand_erase(struct nand_device_s *device, int first_block, int last_block)
 		
 		/* Send erase confirm command */
 		device->controller->command(device, NAND_CMD_ERASE2);
-		
-		if (!device->controller->nand_ready(device, 1000))
-		{
+
+		retval = device->controller->nand_ready ?
+				device->controller->nand_ready(device, 1000) :
+				nand_poll_ready(device, 1000);
+		if (!retval) {
 			LOG_ERROR("timeout waiting for NAND flash block erase to complete");
 			return ERROR_NAND_OPERATION_TIMEOUT;
 		}
@@ -823,8 +846,12 @@ int nand_read_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 dat
 		device->controller->command(device, NAND_CMD_READSTART);
 	}
 	
-	if (!device->controller->nand_ready(device, 100))
-		return ERROR_NAND_OPERATION_TIMEOUT;
+	if (device->controller->nand_ready) {
+		if (!device->controller->nand_ready(device, 100))
+			return ERROR_NAND_OPERATION_TIMEOUT;
+	} else {
+		alive_sleep(1);
+	}
 	
 	if (data)
 	{
@@ -977,7 +1004,10 @@ int nand_write_page_raw(struct nand_device_s *device, u32 page, u8 *data, u32 da
 	
 	device->controller->command(device, NAND_CMD_PAGEPROG);
 	
-	if (!device->controller->nand_ready(device, 100))
+	retval = device->controller->nand_ready ?
+			device->controller->nand_ready(device, 100) :
+			nand_poll_ready(device, 100);
+	if (!retval)
 		return ERROR_NAND_OPERATION_TIMEOUT;
 	
 	if ((retval = nand_read_status(device, &status)) != ERROR_OK)
-- 
cgit v1.2.3