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
