summaryrefslogtreecommitdiff
path: root/src/flash/nand
diff options
context:
space:
mode:
authorrichard vegh <vegh.ricsi@gmail.com>2010-01-16 12:27:45 -0800
committerDavid Brownell <dbrownell@users.sourceforge.net>2010-01-16 12:27:45 -0800
commitdaa1ff3535c2dc1f6ae6da2b740cdf23f4f5f7a6 (patch)
treea4116c06b3f1c638f76cceb04762bd4d69685f90 /src/flash/nand
parent183765707fb4d819b790b9431b83a9bf637fadc5 (diff)
downloadopenocd+libswd-daa1ff3535c2dc1f6ae6da2b740cdf23f4f5f7a6.tar.gz
openocd+libswd-daa1ff3535c2dc1f6ae6da2b740cdf23f4f5f7a6.tar.bz2
openocd+libswd-daa1ff3535c2dc1f6ae6da2b740cdf23f4f5f7a6.tar.xz
openocd+libswd-daa1ff3535c2dc1f6ae6da2b740cdf23f4f5f7a6.zip
NAND: lpc3180 crashes on LPC3250
The LPC3180 NAND driver was crashing on some large page chips. Fix: - Crash and related functionality (don't memset too much OOB data) - Some debug messages - Command handling now works [dbrownell@users.sourceforge.net: whitespace/linelength/message cleanup] Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Diffstat (limited to 'src/flash/nand')
-rw-r--r--src/flash/nand/lpc3180.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/src/flash/nand/lpc3180.c b/src/flash/nand/lpc3180.c
index 51ab34bc..acb5f586 100644
--- a/src/flash/nand/lpc3180.c
+++ b/src/flash/nand/lpc3180.c
@@ -500,9 +500,10 @@ static int lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t *
return ERROR_NAND_OPERATION_NOT_SUPPORTED;
}
- if (oob && (oob_size > 6))
+ if (oob && (oob_size > 24))
{
- LOG_ERROR("LPC3180 MLC controller can't write more than 6 bytes of OOB data");
+ LOG_ERROR("LPC3180 MLC controller can't write more "
+ "than 6 bytes for each quarter's OOB data");
return ERROR_NAND_OPERATION_NOT_SUPPORTED;
}
@@ -559,10 +560,10 @@ static int lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t *
data += thisrun_data_size;
}
- memset(oob_buffer, 0xff, (nand->page_size == 512) ? 6 : 24);
+ memset(oob_buffer, 0xff, 6);
if (oob)
{
- memcpy(page_buffer, oob, thisrun_oob_size);
+ memcpy(oob_buffer, oob, thisrun_oob_size);
oob_size -= thisrun_oob_size;
oob += thisrun_oob_size;
}
@@ -570,8 +571,10 @@ static int lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t *
/* write MLC_ECC_ENC_REG to start encode cycle */
target_write_u32(target, 0x200b8008, 0x0);
- target_write_memory(target, 0x200a8000, 4, 128, page_buffer + (quarter * 512));
- target_write_memory(target, 0x200a8000, 1, 6, oob_buffer + (quarter * 6));
+ target_write_memory(target, 0x200a8000,
+ 4, 128, page_buffer);
+ target_write_memory(target, 0x200a8000,
+ 1, 6, oob_buffer);
/* write MLC_ECC_AUTO_ENC_REG to start auto encode */
target_write_u32(target, 0x200b8010, 0x0);
@@ -760,7 +763,6 @@ static int lpc3180_controller_ready(struct nand_device *nand, int timeout)
{
struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;
struct target *target = lpc3180_info->target;
- uint8_t status = 0x0;
if (target->state != TARGET_HALTED)
{
@@ -768,20 +770,35 @@ static int lpc3180_controller_ready(struct nand_device *nand, int timeout)
return ERROR_NAND_OPERATION_FAILED;
}
+ LOG_DEBUG("lpc3180_controller_ready count start=%d", timeout);
+
do
{
if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
{
+ uint8_t status;
+
/* Read MLC_ISR, wait for controller to become ready */
target_read_u8(target, 0x200b8048, &status);
- if (status & 2)
+ if (status & 2) {
+ LOG_DEBUG("lpc3180_controller_ready count=%d",
+ timeout);
return 1;
+ }
}
else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
{
- /* we pretend that the SLC controller is always ready */
- return 1;
+ uint32_t status;
+
+ /* Read SLC_STAT and check READY bit */
+ target_read_u32(target, 0x20020018, &status);
+
+ if (status & 1) {
+ LOG_DEBUG("lpc3180_controller_ready count=%d",
+ timeout);
+ return 1;
+ }
}
alive_sleep(1);
@@ -801,6 +818,8 @@ static int lpc3180_nand_ready(struct nand_device *nand, int timeout)
return ERROR_NAND_OPERATION_FAILED;
}
+ LOG_DEBUG("lpc3180_nand_ready count start=%d", timeout);
+
do
{
if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)
@@ -810,8 +829,11 @@ static int lpc3180_nand_ready(struct nand_device *nand, int timeout)
/* Read MLC_ISR, wait for NAND flash device to become ready */
target_read_u8(target, 0x200b8048, &status);
- if (status & 1)
+ if (status & 1) {
+ LOG_DEBUG("lpc3180_nand_ready count end=%d",
+ timeout);
return 1;
+ }
}
else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER)
{
@@ -820,8 +842,11 @@ static int lpc3180_nand_ready(struct nand_device *nand, int timeout)
/* Read SLC_STAT and check READY bit */
target_read_u32(target, 0x20020018, &status);
- if (status & 1)
+ if (status & 1) {
+ LOG_DEBUG("lpc3180_nand_ready count end=%d",
+ timeout);
return 1;
+ }
}
alive_sleep(1);
@@ -844,7 +869,7 @@ COMMAND_HANDLER(handle_lpc3180_select_command)
}
unsigned num;
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], num);
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);
struct nand_device *nand = get_nand_device_by_num(num);
if (!nand)
{