From 9a51b8b0e3d0b629915a8248e2c112a01ffc93dc Mon Sep 17 00:00:00 2001 From: Dean Glazeski 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 --- src/flash/nand.c | 91 ++++++++++++++++++++------------------------------------ src/flash/nand.h | 3 ++ 2 files changed, 35 insertions(+), 59 deletions(-) (limited to 'src/flash') 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