diff options
Diffstat (limited to 'src')
32 files changed, 2085 insertions, 2380 deletions
diff --git a/src/flash/nand/arm_io.c b/src/flash/nand/arm_io.c index 431ac90..cf49476 100644 --- a/src/flash/nand/arm_io.c +++ b/src/flash/nand/arm_io.c @@ -30,7 +30,6 @@ #include <target/arm.h> #include <target/algorithm.h> - /** * Copies code to a working area. This will allocate room for the code plus the * additional amount requested if the working area pointer is null. @@ -44,8 +43,8 @@ * @return Success or failure of the operation */ static int arm_code_to_working_area(struct target *target, - const uint32_t *code, unsigned code_size, - unsigned additional, struct working_area **area) + const uint32_t *code, unsigned code_size, + unsigned additional, struct working_area **area) { uint8_t code_buf[code_size]; unsigned i; @@ -61,7 +60,7 @@ static int arm_code_to_working_area(struct target *target, if (NULL == *area) { retval = target_alloc_working_area(target, size, area); if (retval != ERROR_OK) { - LOG_DEBUG("%s: no %d byte buffer", __FUNCTION__, (int) size); + LOG_DEBUG("%s: no %d byte buffer", __func__, (int) size); return ERROR_NAND_NO_BUFFER; } } @@ -95,13 +94,13 @@ static int arm_code_to_working_area(struct target *target, */ int arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size) { - struct target *target = nand->target; - struct arm_algorithm algo; - struct arm *arm = target->arch_info; - struct reg_param reg_params[3]; - uint32_t target_buf; - uint32_t exit_var = 0; - int retval; + struct target *target = nand->target; + struct arm_algorithm algo; + struct arm *arm = target->arch_info; + struct reg_param reg_params[3]; + uint32_t target_buf; + uint32_t exit_var = 0; + int retval; /* Inputs: * r0 NAND data address (byte wide) @@ -121,9 +120,8 @@ int arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size) if (nand->op != ARM_NAND_WRITE || !nand->copy_area) { retval = arm_code_to_working_area(target, code, sizeof(code), nand->chunk_size, &nand->copy_area); - if (retval != ERROR_OK) { + if (retval != ERROR_OK) return retval; - } } nand->op = ARM_NAND_WRITE; @@ -206,9 +204,8 @@ int arm_nandread(struct arm_nand_data *nand, uint8_t *data, uint32_t size) if (nand->op != ARM_NAND_READ || !nand->copy_area) { retval = arm_code_to_working_area(target, code, sizeof(code), nand->chunk_size, &nand->copy_area); - if (retval != ERROR_OK) { + if (retval != ERROR_OK) return retval; - } } nand->op = ARM_NAND_READ; @@ -246,4 +243,3 @@ int arm_nandread(struct arm_nand_data *nand, uint8_t *data, uint32_t size) return retval; } - diff --git a/src/flash/nand/arm_io.h b/src/flash/nand/arm_io.h index 2e825bf..a8a4396 100644 --- a/src/flash/nand/arm_io.h +++ b/src/flash/nand/arm_io.h @@ -23,9 +23,9 @@ * Available operational states the arm_nand_data struct can be in. */ enum arm_nand_op { - ARM_NAND_NONE, /**< No operation performed. */ - ARM_NAND_READ, /**< Read operation performed. */ - ARM_NAND_WRITE, /**< Write operation performed. */ + ARM_NAND_NONE, /**< No operation performed. */ + ARM_NAND_READ, /**< Read operation performed. */ + ARM_NAND_WRITE, /**< Write operation performed. */ }; /** @@ -37,7 +37,7 @@ struct arm_nand_data { struct target *target; /** The copy area holds code loop and data for I/O operations. */ - struct working_area *copy_area; + struct working_area *copy_area; /** The chunk size is the page size or ECC chunk. */ unsigned chunk_size; @@ -54,4 +54,4 @@ struct arm_nand_data { int arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size); int arm_nandread(struct arm_nand_data *nand, uint8_t *data, uint32_t size); -#endif /* __ARM_NANDIO_H */ +#endif /* __ARM_NANDIO_H */ diff --git a/src/flash/nand/at91sam9.c b/src/flash/nand/at91sam9.c index 42924c9..4f0f647 100644 --- a/src/flash/nand/at91sam9.c +++ b/src/flash/nand/at91sam9.c @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -26,13 +27,13 @@ #include "imp.h" #include "arm_io.h" -#define AT91C_PIOx_SODR (0x30) /**< Offset to PIO SODR. */ -#define AT91C_PIOx_CODR (0x34) /**< Offset to PIO CODR. */ -#define AT91C_PIOx_PDSR (0x3C) /**< Offset to PIO PDSR. */ -#define AT91C_ECCx_CR (0x00) /**< Offset to ECC CR. */ -#define AT91C_ECCx_SR (0x08) /**< Offset to ECC SR. */ -#define AT91C_ECCx_PR (0x0C) /**< Offset to ECC PR. */ -#define AT91C_ECCx_NPR (0x10) /**< Offset to ECC NPR. */ +#define AT91C_PIOx_SODR (0x30) /**< Offset to PIO SODR. */ +#define AT91C_PIOx_CODR (0x34) /**< Offset to PIO CODR. */ +#define AT91C_PIOx_PDSR (0x3C) /**< Offset to PIO PDSR. */ +#define AT91C_ECCx_CR (0x00) /**< Offset to ECC CR. */ +#define AT91C_ECCx_SR (0x08) /**< Offset to ECC SR. */ +#define AT91C_ECCx_PR (0x0C) /**< Offset to ECC PR. */ +#define AT91C_ECCx_NPR (0x10) /**< Offset to ECC NPR. */ /** * Representation of a pin on an AT91SAM9 chip. @@ -97,9 +98,8 @@ static int at91sam9_init(struct nand_device *nand) { struct target *target = nand->target; - if (!at91sam9_halted(target, "init")) { + if (!at91sam9_halted(target, "init")) return ERROR_NAND_OPERATION_FAILED; - } return ERROR_OK; } @@ -144,9 +144,8 @@ static int at91sam9_command(struct nand_device *nand, uint8_t command) struct at91sam9_nand *info = nand->controller_priv; struct target *target = nand->target; - if (!at91sam9_halted(target, "command")) { + if (!at91sam9_halted(target, "command")) return ERROR_NAND_OPERATION_FAILED; - } at91sam9_enable(nand); @@ -161,9 +160,8 @@ static int at91sam9_command(struct nand_device *nand, uint8_t command) */ static int at91sam9_reset(struct nand_device *nand) { - if (!at91sam9_halted(nand->target, "reset")) { + if (!at91sam9_halted(nand->target, "reset")) return ERROR_NAND_OPERATION_FAILED; - } return at91sam9_disable(nand); } @@ -180,9 +178,8 @@ static int at91sam9_address(struct nand_device *nand, uint8_t address) struct at91sam9_nand *info = nand->controller_priv; struct target *target = nand->target; - if (!at91sam9_halted(nand->target, "address")) { + if (!at91sam9_halted(nand->target, "address")) return ERROR_NAND_OPERATION_FAILED; - } return target_write_u8(target, info->addr, address); } @@ -200,9 +197,8 @@ static int at91sam9_read_data(struct nand_device *nand, void *data) struct at91sam9_nand *info = nand->controller_priv; struct target *target = nand->target; - if (!at91sam9_halted(nand->target, "read data")) { + if (!at91sam9_halted(nand->target, "read data")) return ERROR_NAND_OPERATION_FAILED; - } return target_read_u8(target, info->data, data); } @@ -220,9 +216,8 @@ static int at91sam9_write_data(struct nand_device *nand, uint16_t data) struct at91sam9_nand *info = nand->controller_priv; struct target *target = nand->target; - if (!at91sam9_halted(target, "write data")) { + if (!at91sam9_halted(target, "write data")) return ERROR_NAND_OPERATION_FAILED; - } return target_write_u8(target, info->data, data); } @@ -240,16 +235,14 @@ static int at91sam9_nand_ready(struct nand_device *nand, int timeout) struct target *target = nand->target; uint32_t status; - if (!at91sam9_halted(target, "nand ready")) { + if (!at91sam9_halted(target, "nand ready")) return 0; - } do { target_read_u32(target, info->busy.pioc + AT91C_PIOx_PDSR, &status); - if (status & (1 << info->busy.num)) { + if (status & (1 << info->busy.num)) return 1; - } alive_sleep(1); } while (timeout-- > 0); @@ -272,9 +265,8 @@ static int at91sam9_read_block_data(struct nand_device *nand, uint8_t *data, int struct arm_nand_data *io = &info->io; int status; - if (!at91sam9_halted(nand->target, "read block")) { + if (!at91sam9_halted(nand->target, "read block")) return ERROR_NAND_OPERATION_FAILED; - } io->chunk_size = nand->page_size; status = arm_nandread(io, data, size); @@ -297,9 +289,8 @@ static int at91sam9_write_block_data(struct nand_device *nand, uint8_t *data, in struct arm_nand_data *io = &info->io; int status; - if (!at91sam9_halted(nand->target, "write block")) { + if (!at91sam9_halted(nand->target, "write block")) return ERROR_NAND_OPERATION_FAILED; - } io->chunk_size = nand->page_size; status = arm_nandwrite(io, data, size); @@ -321,7 +312,7 @@ static int at91sam9_ecc_init(struct target *target, struct at91sam9_nand *info) return ERROR_NAND_OPERATION_FAILED; } - // reset ECC parity registers + /* reset ECC parity registers */ return target_write_u32(target, info->ecc + AT91C_ECCx_CR, 1); } @@ -335,15 +326,14 @@ static int at91sam9_ecc_init(struct target *target, struct at91sam9_nand *info) * @param size Size of the OOB. * @return Pointer to an area to store OOB data. */ -static uint8_t * at91sam9_oob_init(struct nand_device *nand, uint8_t *oob, uint32_t *size) +static uint8_t *at91sam9_oob_init(struct nand_device *nand, uint8_t *oob, uint32_t *size) { if (!oob) { - // user doesn't want OOB, allocate it - if (nand->page_size == 512) { + /* user doesn't want OOB, allocate it */ + if (nand->page_size == 512) *size = 16; - } else if (nand->page_size == 2048) { + else if (nand->page_size == 2048) *size = 64; - } oob = malloc(*size); if (!oob) { @@ -371,7 +361,7 @@ static uint8_t * at91sam9_oob_init(struct nand_device *nand, uint8_t *oob, uint3 * @return Success or failure of reading the NAND page. */ static int at91sam9_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) { int retval; struct at91sam9_nand *info = nand->controller_priv; @@ -380,20 +370,17 @@ static int at91sam9_read_page(struct nand_device *nand, uint32_t page, uint32_t status; retval = at91sam9_ecc_init(target, info); - if (ERROR_OK != retval) { + if (ERROR_OK != retval) return retval; - } retval = nand_page_command(nand, page, NAND_CMD_READ0, !data); - if (ERROR_OK != retval) { + if (ERROR_OK != retval) return retval; - } if (data) { retval = nand_read_data_page(nand, data, data_size); - if (ERROR_OK != retval) { + if (ERROR_OK != retval) return retval; - } } oob_data = at91sam9_oob_init(nand, oob, &oob_size); @@ -402,33 +389,33 @@ static int at91sam9_read_page(struct nand_device *nand, uint32_t page, target_read_u32(target, info->ecc + AT91C_ECCx_SR, &status); if (status & 1) { LOG_ERROR("Error detected!"); - if (status & 4) { + if (status & 4) LOG_ERROR("Multiple errors encountered; unrecoverable!"); - } else { - // attempt recovery + else { + /* attempt recovery */ uint32_t parity; target_read_u32(target, - info->ecc + AT91C_ECCx_PR, - &parity); + info->ecc + AT91C_ECCx_PR, + &parity); uint32_t word = (parity & 0x0000FFF0) >> 4; uint32_t bit = parity & 0x0F; data[word] ^= (0x1) << bit; LOG_INFO("Data word %d, bit %d corrected.", - (unsigned) word, - (unsigned) bit); + (unsigned) word, + (unsigned) bit); } } if (status & 2) { - // we could write back correct ECC data + /* we could write back correct ECC data */ LOG_ERROR("Error in ECC bytes detected"); } } if (!oob) { - // if it wasn't asked for, free it + /* if it wasn't asked for, free it */ free(oob_data); } @@ -449,7 +436,7 @@ static int at91sam9_read_page(struct nand_device *nand, uint32_t page, * @return Success or failure of the page write. */ static int at91sam9_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) { struct at91sam9_nand *info = nand->controller_priv; struct target *target = nand->target; @@ -458,14 +445,12 @@ static int at91sam9_write_page(struct nand_device *nand, uint32_t page, uint32_t parity, nparity; retval = at91sam9_ecc_init(target, info); - if (ERROR_OK != retval) { + if (ERROR_OK != retval) return retval; - } retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data); - if (ERROR_OK != retval) { + if (ERROR_OK != retval) return retval; - } if (data) { retval = nand_write_data_page(nand, data, data_size); @@ -478,7 +463,7 @@ static int at91sam9_write_page(struct nand_device *nand, uint32_t page, oob_data = at91sam9_oob_init(nand, oob, &oob_size); if (!oob) { - // no OOB given, so read in the ECC parity from the ECC controller + /* no OOB given, so read in the ECC parity from the ECC controller */ target_read_u32(target, info->ecc + AT91C_ECCx_PR, &parity); target_read_u32(target, info->ecc + AT91C_ECCx_NPR, &nparity); @@ -490,9 +475,8 @@ static int at91sam9_write_page(struct nand_device *nand, uint32_t page, retval = nand_write_data_page(nand, oob_data, oob_size); - if (!oob) { + if (!oob) free(oob_data); - } if (ERROR_OK != retval) { LOG_ERROR("Unable to write OOB data to NAND"); @@ -594,9 +578,8 @@ COMMAND_HANDLER(handle_at91sam9_ale_command) struct at91sam9_nand *info = NULL; unsigned num, address_line; - if (CMD_ARGC != 2) { + if (CMD_ARGC != 2) return ERROR_COMMAND_SYNTAX_ERROR; - } COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); nand = get_nand_device_by_num(num); @@ -623,9 +606,8 @@ COMMAND_HANDLER(handle_at91sam9_rdy_busy_command) struct at91sam9_nand *info = NULL; unsigned num, base_pioc, pin_num; - if (CMD_ARGC != 3) { + if (CMD_ARGC != 3) return ERROR_COMMAND_SYNTAX_ERROR; - } COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); nand = get_nand_device_by_num(num); @@ -655,9 +637,8 @@ COMMAND_HANDLER(handle_at91sam9_ce_command) struct at91sam9_nand *info = NULL; unsigned num, base_pioc, pin_num; - if (CMD_ARGC != 3) { + if (CMD_ARGC != 3) return ERROR_COMMAND_SYNTAX_ERROR; - } COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); nand = get_nand_device_by_num(num); diff --git a/src/flash/nand/core.c b/src/flash/nand/core.c index 777b2fd..d1a7763 100644 --- a/src/flash/nand/core.c +++ b/src/flash/nand/core.c @@ -20,6 +20,7 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -27,13 +28,14 @@ #include "imp.h" /* configured NAND devices and NAND Flash command handler */ -struct nand_device *nand_devices = NULL; +struct nand_device *nand_devices; void nand_device_add(struct nand_device *c) { if (nand_devices) { struct nand_device *p = nand_devices; - while (p && p->next) p = p->next; + while (p && p->next) + p = p->next; p->next = c; } else nand_devices = c; @@ -50,94 +52,94 @@ void nand_device_add(struct nand_device *c) * 256 256 Byte page size * 512 512 Byte page size */ -static struct nand_info nand_flash_ids[] = -{ +static struct nand_info nand_flash_ids[] = { /* Vendor Specific Entries */ - { NAND_MFR_SAMSUNG, 0xD5, 8192, 2048, 0x100000, LP_OPTIONS, "K9GAG08 2GB NAND 3.3V x8 MLC 2b/cell"}, - { NAND_MFR_SAMSUNG, 0xD7, 8192, 4096, 0x100000, LP_OPTIONS, "K9LBG08 4GB NAND 3.3V x8 MLC 2b/cell"}, + { NAND_MFR_SAMSUNG, 0xD5, 8192, 2048, 0x100000, LP_OPTIONS, + "K9GAG08 2GB NAND 3.3V x8 MLC 2b/cell"}, + { NAND_MFR_SAMSUNG, 0xD7, 8192, 4096, 0x100000, LP_OPTIONS, + "K9LBG08 4GB NAND 3.3V x8 MLC 2b/cell"}, /* start "museum" IDs */ - { 0x0, 0x6e, 256, 1, 0x1000, 0, "NAND 1MiB 5V 8-bit"}, - { 0x0, 0x64, 256, 2, 0x1000, 0, "NAND 2MiB 5V 8-bit"}, - { 0x0, 0x6b, 512, 4, 0x2000, 0, "NAND 4MiB 5V 8-bit"}, - { 0x0, 0xe8, 256, 1, 0x1000, 0, "NAND 1MiB 3.3V 8-bit"}, - { 0x0, 0xec, 256, 1, 0x1000, 0, "NAND 1MiB 3.3V 8-bit"}, - { 0x0, 0xea, 256, 2, 0x1000, 0, "NAND 2MiB 3.3V 8-bit"}, - { 0x0, 0xd5, 512, 4, 0x2000, 0, "NAND 4MiB 3.3V 8-bit"}, - { 0x0, 0xe3, 512, 4, 0x2000, 0, "NAND 4MiB 3.3V 8-bit"}, - { 0x0, 0xe5, 512, 4, 0x2000, 0, "NAND 4MiB 3.3V 8-bit"}, - { 0x0, 0xd6, 512, 8, 0x2000, 0, "NAND 8MiB 3.3V 8-bit"}, - - { 0x0, 0x39, 512, 8, 0x2000, 0, "NAND 8MiB 1.8V 8-bit"}, - { 0x0, 0xe6, 512, 8, 0x2000, 0, "NAND 8MiB 3.3V 8-bit"}, - { 0x0, 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16, "NAND 8MiB 1.8V 16-bit"}, - { 0x0, 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16, "NAND 8MiB 3.3V 16-bit"}, + { 0x0, 0x6e, 256, 1, 0x1000, 0, "NAND 1MiB 5V 8-bit"}, + { 0x0, 0x64, 256, 2, 0x1000, 0, "NAND 2MiB 5V 8-bit"}, + { 0x0, 0x6b, 512, 4, 0x2000, 0, "NAND 4MiB 5V 8-bit"}, + { 0x0, 0xe8, 256, 1, 0x1000, 0, "NAND 1MiB 3.3V 8-bit"}, + { 0x0, 0xec, 256, 1, 0x1000, 0, "NAND 1MiB 3.3V 8-bit"}, + { 0x0, 0xea, 256, 2, 0x1000, 0, "NAND 2MiB 3.3V 8-bit"}, + { 0x0, 0xd5, 512, 4, 0x2000, 0, "NAND 4MiB 3.3V 8-bit"}, + { 0x0, 0xe3, 512, 4, 0x2000, 0, "NAND 4MiB 3.3V 8-bit"}, + { 0x0, 0xe5, 512, 4, 0x2000, 0, "NAND 4MiB 3.3V 8-bit"}, + { 0x0, 0xd6, 512, 8, 0x2000, 0, "NAND 8MiB 3.3V 8-bit"}, + + { 0x0, 0x39, 512, 8, 0x2000, 0, "NAND 8MiB 1.8V 8-bit"}, + { 0x0, 0xe6, 512, 8, 0x2000, 0, "NAND 8MiB 3.3V 8-bit"}, + { 0x0, 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16, "NAND 8MiB 1.8V 16-bit"}, + { 0x0, 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16, "NAND 8MiB 3.3V 16-bit"}, /* end "museum" IDs */ - { 0x0, 0x33, 512, 16, 0x4000, 0, "NAND 16MiB 1.8V 8-bit"}, - { 0x0, 0x73, 512, 16, 0x4000, 0, "NAND 16MiB 3.3V 8-bit"}, - { 0x0, 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16,"NAND 16MiB 1.8V 16-bit"}, - { 0x0, 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16,"NAND 16MiB 3.3V 16-bit"}, - - { 0x0, 0x35, 512, 32, 0x4000, 0, "NAND 32MiB 1.8V 8-bit"}, - { 0x0, 0x75, 512, 32, 0x4000, 0, "NAND 32MiB 3.3V 8-bit"}, - { 0x0, 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16,"NAND 32MiB 1.8V 16-bit"}, - { 0x0, 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16,"NAND 32MiB 3.3V 16-bit"}, - - { 0x0, 0x36, 512, 64, 0x4000, 0, "NAND 64MiB 1.8V 8-bit"}, - { 0x0, 0x76, 512, 64, 0x4000, 0, "NAND 64MiB 3.3V 8-bit"}, - { 0x0, 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16,"NAND 64MiB 1.8V 16-bit"}, - { 0x0, 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16,"NAND 64MiB 3.3V 16-bit"}, - - { 0x0, 0x78, 512, 128, 0x4000, 0, "NAND 128MiB 1.8V 8-bit"}, - { 0x0, 0x39, 512, 128, 0x4000, 0, "NAND 128MiB 1.8V 8-bit"}, - { 0x0, 0x79, 512, 128, 0x4000, 0, "NAND 128MiB 3.3V 8-bit"}, - { 0x0, 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16,"NAND 128MiB 1.8V 16-bit"}, - { 0x0, 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16,"NAND 128MiB 1.8V 16-bit"}, - { 0x0, 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16,"NAND 128MiB 3.3V 16-bit"}, - { 0x0, 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16,"NAND 128MiB 3.3V 16-bit"}, - - { 0x0, 0x71, 512, 256, 0x4000, 0, "NAND 256MiB 3.3V 8-bit"}, - - { 0x0, 0xA2, 0, 64, 0, LP_OPTIONS, "NAND 64MiB 1.8V 8-bit"}, - { 0x0, 0xF2, 0, 64, 0, LP_OPTIONS, "NAND 64MiB 3.3V 8-bit"}, - { 0x0, 0xB2, 0, 64, 0, LP_OPTIONS16, "NAND 64MiB 1.8V 16-bit"}, - { 0x0, 0xC2, 0, 64, 0, LP_OPTIONS16, "NAND 64MiB 3.3V 16-bit"}, - - { 0x0, 0xA1, 0, 128, 0, LP_OPTIONS, "NAND 128MiB 1.8V 8-bit"}, - { 0x0, 0xF1, 0, 128, 0, LP_OPTIONS, "NAND 128MiB 3.3V 8-bit"}, - { 0x0, 0xB1, 0, 128, 0, LP_OPTIONS16, "NAND 128MiB 1.8V 16-bit"}, - { 0x0, 0xC1, 0, 128, 0, LP_OPTIONS16, "NAND 128MiB 3.3V 16-bit"}, - - { 0x0, 0xAA, 0, 256, 0, LP_OPTIONS, "NAND 256MiB 1.8V 8-bit"}, - { 0x0, 0xDA, 0, 256, 0, LP_OPTIONS, "NAND 256MiB 3.3V 8-bit"}, - { 0x0, 0xBA, 0, 256, 0, LP_OPTIONS16, "NAND 256MiB 1.8V 16-bit"}, - { 0x0, 0xCA, 0, 256, 0, LP_OPTIONS16, "NAND 256MiB 3.3V 16-bit"}, - - { 0x0, 0xAC, 0, 512, 0, LP_OPTIONS, "NAND 512MiB 1.8V 8-bit"}, - { 0x0, 0xDC, 0, 512, 0, LP_OPTIONS, "NAND 512MiB 3.3V 8-bit"}, - { 0x0, 0xBC, 0, 512, 0, LP_OPTIONS16, "NAND 512MiB 1.8V 16-bit"}, - { 0x0, 0xCC, 0, 512, 0, LP_OPTIONS16, "NAND 512MiB 3.3V 16-bit"}, - - { 0x0, 0xA3, 0, 1024, 0, LP_OPTIONS, "NAND 1GiB 1.8V 8-bit"}, - { 0x0, 0xD3, 0, 1024, 0, LP_OPTIONS, "NAND 1GiB 3.3V 8-bit"}, - { 0x0, 0xB3, 0, 1024, 0, LP_OPTIONS16, "NAND 1GiB 1.8V 16-bit"}, - { 0x0, 0xC3, 0, 1024, 0, LP_OPTIONS16, "NAND 1GiB 3.3V 16-bit"}, - - { 0x0, 0xA5, 0, 2048, 0, LP_OPTIONS, "NAND 2GiB 1.8V 8-bit"}, - { 0x0, 0xD5, 0, 8192, 0, LP_OPTIONS, "NAND 2GiB 3.3V 8-bit"}, - { 0x0, 0xB5, 0, 2048, 0, LP_OPTIONS16, "NAND 2GiB 1.8V 16-bit"}, - { 0x0, 0xC5, 0, 2048, 0, LP_OPTIONS16, "NAND 2GiB 3.3V 16-bit"}, - - { 0x0, 0x48, 0, 2048, 0, LP_OPTIONS, "NAND 2GiB 3.3V 8-bit"}, + { 0x0, 0x33, 512, 16, 0x4000, 0, "NAND 16MiB 1.8V 8-bit"}, + { 0x0, 0x73, 512, 16, 0x4000, 0, "NAND 16MiB 3.3V 8-bit"}, + { 0x0, 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16, "NAND 16MiB 1.8V 16-bit"}, + { 0x0, 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16, "NAND 16MiB 3.3V 16-bit"}, + + { 0x0, 0x35, 512, 32, 0x4000, 0, "NAND 32MiB 1.8V 8-bit"}, + { 0x0, 0x75, 512, 32, 0x4000, 0, "NAND 32MiB 3.3V 8-bit"}, + { 0x0, 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16, "NAND 32MiB 1.8V 16-bit"}, + { 0x0, 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16, "NAND 32MiB 3.3V 16-bit"}, + + { 0x0, 0x36, 512, 64, 0x4000, 0, "NAND 64MiB 1.8V 8-bit"}, + { 0x0, 0x76, 512, 64, 0x4000, 0, "NAND 64MiB 3.3V 8-bit"}, + { 0x0, 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16, "NAND 64MiB 1.8V 16-bit"}, + { 0x0, 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16, "NAND 64MiB 3.3V 16-bit"}, + + { 0x0, 0x78, 512, 128, 0x4000, 0, "NAND 128MiB 1.8V 8-bit"}, + { 0x0, 0x39, 512, 128, 0x4000, 0, "NAND 128MiB 1.8V 8-bit"}, + { 0x0, 0x79, 512, 128, 0x4000, 0, "NAND 128MiB 3.3V 8-bit"}, + { 0x0, 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16, "NAND 128MiB 1.8V 16-bit"}, + { 0x0, 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16, "NAND 128MiB 1.8V 16-bit"}, + { 0x0, 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16, "NAND 128MiB 3.3V 16-bit"}, + { 0x0, 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16, "NAND 128MiB 3.3V 16-bit"}, + + { 0x0, 0x71, 512, 256, 0x4000, 0, "NAND 256MiB 3.3V 8-bit"}, + + { 0x0, 0xA2, 0, 64, 0, LP_OPTIONS, "NAND 64MiB 1.8V 8-bit"}, + { 0x0, 0xF2, 0, 64, 0, LP_OPTIONS, "NAND 64MiB 3.3V 8-bit"}, + { 0x0, 0xB2, 0, 64, 0, LP_OPTIONS16, "NAND 64MiB 1.8V 16-bit"}, + { 0x0, 0xC2, 0, 64, 0, LP_OPTIONS16, "NAND 64MiB 3.3V 16-bit"}, + + { 0x0, 0xA1, 0, 128, 0, LP_OPTIONS, "NAND 128MiB 1.8V 8-bit"}, + { 0x0, 0xF1, 0, 128, 0, LP_OPTIONS, "NAND 128MiB 3.3V 8-bit"}, + { 0x0, 0xB1, 0, 128, 0, LP_OPTIONS16, "NAND 128MiB 1.8V 16-bit"}, + { 0x0, 0xC1, 0, 128, 0, LP_OPTIONS16, "NAND 128MiB 3.3V 16-bit"}, + + { 0x0, 0xAA, 0, 256, 0, LP_OPTIONS, "NAND 256MiB 1.8V 8-bit"}, + { 0x0, 0xDA, 0, 256, 0, LP_OPTIONS, "NAND 256MiB 3.3V 8-bit"}, + { 0x0, 0xBA, 0, 256, 0, LP_OPTIONS16, "NAND 256MiB 1.8V 16-bit"}, + { 0x0, 0xCA, 0, 256, 0, LP_OPTIONS16, "NAND 256MiB 3.3V 16-bit"}, + + { 0x0, 0xAC, 0, 512, 0, LP_OPTIONS, "NAND 512MiB 1.8V 8-bit"}, + { 0x0, 0xDC, 0, 512, 0, LP_OPTIONS, "NAND 512MiB 3.3V 8-bit"}, + { 0x0, 0xBC, 0, 512, 0, LP_OPTIONS16, "NAND 512MiB 1.8V 16-bit"}, + { 0x0, 0xCC, 0, 512, 0, LP_OPTIONS16, "NAND 512MiB 3.3V 16-bit"}, + + { 0x0, 0xA3, 0, 1024, 0, LP_OPTIONS, "NAND 1GiB 1.8V 8-bit"}, + { 0x0, 0xD3, 0, 1024, 0, LP_OPTIONS, "NAND 1GiB 3.3V 8-bit"}, + { 0x0, 0xB3, 0, 1024, 0, LP_OPTIONS16, "NAND 1GiB 1.8V 16-bit"}, + { 0x0, 0xC3, 0, 1024, 0, LP_OPTIONS16, "NAND 1GiB 3.3V 16-bit"}, + + { 0x0, 0xA5, 0, 2048, 0, LP_OPTIONS, "NAND 2GiB 1.8V 8-bit"}, + { 0x0, 0xD5, 0, 8192, 0, LP_OPTIONS, "NAND 2GiB 3.3V 8-bit"}, + { 0x0, 0xB5, 0, 2048, 0, LP_OPTIONS16, "NAND 2GiB 1.8V 16-bit"}, + { 0x0, 0xC5, 0, 2048, 0, LP_OPTIONS16, "NAND 2GiB 3.3V 16-bit"}, + + { 0x0, 0x48, 0, 2048, 0, LP_OPTIONS, "NAND 2GiB 3.3V 8-bit"}, {0, 0, 0, 0, 0, 0, NULL} }; /* Manufacturer ID list */ -static struct nand_manufacturer nand_manuf_ids[] = -{ +static struct nand_manufacturer nand_manuf_ids[] = { {0x0, "unknown"}, {NAND_MFR_TOSHIBA, "Toshiba"}, {NAND_MFR_SAMSUNG, "Samsung"}, @@ -162,7 +164,8 @@ static struct nand_ecclayout nand_oob_8 = { {.offset = 3, .length = 2}, {.offset = 6, - .length = 2}} + .length = 2} + } }; #endif @@ -179,8 +182,7 @@ static struct nand_device *get_nand_device_by_name(const char *name) unsigned found = 0; struct nand_device *nand; - for (nand = nand_devices; NULL != nand; nand = nand->next) - { + for (nand = nand_devices; NULL != nand; nand = nand->next) { if (strcmp(nand->name, name) == 0) return nand; if (!flash_driver_name_matches(nand->controller->name, name)) @@ -197,19 +199,16 @@ struct nand_device *get_nand_device_by_num(int num) struct nand_device *p; int i = 0; - for (p = nand_devices; p; p = p->next) - { + for (p = nand_devices; p; p = p->next) { if (i++ == num) - { return p; - } } return NULL; } COMMAND_HELPER(nand_command_get_device, unsigned name_index, - struct nand_device **nand) + struct nand_device **nand) { const char *str = CMD_ARGV[name_index]; *nand = get_nand_device_by_name(str); @@ -241,23 +240,18 @@ int nand_build_bbt(struct nand_device *nand, int first, int last) last = nand->num_blocks - 1; page = first * pages_per_block; - for (i = first; i <= last; i++) - { + for (i = first; i <= last; i++) { ret = nand_read_page(nand, page, NULL, 0, oob, 6); if (ret != ERROR_OK) return ret; if (((nand->device->options & NAND_BUSWIDTH_16) && ((oob[0] & oob[1]) != 0xff)) - || (((nand->page_size == 512) && (oob[5] != 0xff)) || - ((nand->page_size == 2048) && (oob[0] != 0xff)))) - { + || (((nand->page_size == 512) && (oob[5] != 0xff)) || + ((nand->page_size == 2048) && (oob[0] != 0xff)))) { LOG_WARNING("bad block: %i", i); nand->blocks[i].is_bad = 1; - } - else - { + } else nand->blocks[i].is_bad = 0; - } page += pages_per_block; } @@ -276,16 +270,12 @@ int nand_read_status(struct nand_device *nand, uint8_t *status) alive_sleep(1); /* read status */ - if (nand->device->options & NAND_BUSWIDTH_16) - { + if (nand->device->options & NAND_BUSWIDTH_16) { uint16_t data; nand->controller->read_data(nand, &data); *status = data & 0xff; - } - else - { + } else nand->controller->read_data(nand, status); - } return ERROR_OK; } @@ -300,9 +290,8 @@ static int nand_poll_ready(struct nand_device *nand, int timeout) uint16_t data; nand->controller->read_data(nand, &data); status = data & 0xff; - } else { + } else nand->controller->read_data(nand, &status); - } if (status & NAND_STATUS_READY) break; alive_sleep(1); @@ -329,15 +318,15 @@ int nand_probe(struct nand_device *nand) nand->erase_size = 0; /* initialize controller (device parameters are zero, use controller default) */ - if ((retval = nand->controller->init(nand) != ERROR_OK)) - { - switch (retval) - { + retval = nand->controller->init(nand); + if (retval != ERROR_OK) { + switch (retval) { case ERROR_NAND_OPERATION_FAILED: LOG_DEBUG("controller initialization failed"); return ERROR_NAND_OPERATION_FAILED; case ERROR_NAND_OPERATION_NOT_SUPPORTED: - LOG_ERROR("BUG: controller reported that it doesn't support default parameters"); + LOG_ERROR( + "BUG: controller reported that it doesn't support default parameters"); return ERROR_NAND_OPERATION_FAILED; default: LOG_ERROR("BUG: unknown controller initialization failure"); @@ -351,13 +340,10 @@ int nand_probe(struct nand_device *nand) nand->controller->command(nand, NAND_CMD_READID); nand->controller->address(nand, 0x0); - if (nand->bus_width == 8) - { + if (nand->bus_width == 8) { nand->controller->read_data(nand, &manufacturer_id); nand->controller->read_data(nand, &device_id); - } - else - { + } else { uint16_t data_buf; nand->controller->read_data(nand, &data_buf); manufacturer_id = data_buf & 0xff; @@ -365,36 +351,32 @@ int nand_probe(struct nand_device *nand) device_id = data_buf & 0xff; } - for (i = 0; nand_flash_ids[i].name; i++) - { + for (i = 0; nand_flash_ids[i].name; i++) { if (nand_flash_ids[i].id == device_id && - (nand_flash_ids[i].mfr_id == manufacturer_id || - nand_flash_ids[i].mfr_id == 0 )) - { + (nand_flash_ids[i].mfr_id == manufacturer_id || + nand_flash_ids[i].mfr_id == 0)) { nand->device = &nand_flash_ids[i]; break; } } - for (i = 0; nand_manuf_ids[i].name; i++) - { - if (nand_manuf_ids[i].id == manufacturer_id) - { + for (i = 0; nand_manuf_ids[i].name; i++) { + if (nand_manuf_ids[i].id == manufacturer_id) { nand->manufacturer = &nand_manuf_ids[i]; break; } } - if (!nand->manufacturer) - { + if (!nand->manufacturer) { nand->manufacturer = &nand_manuf_ids[0]; nand->manufacturer->id = manufacturer_id; } - if (!nand->device) - { - LOG_ERROR("unknown NAND flash device found, manufacturer id: 0x%2.2x device id: 0x%2.2x", - manufacturer_id, device_id); + if (!nand->device) { + LOG_ERROR( + "unknown NAND flash device found, manufacturer id: 0x%2.2x device id: 0x%2.2x", + manufacturer_id, + device_id); return ERROR_NAND_OPERATION_FAILED; } @@ -410,16 +392,12 @@ int nand_probe(struct nand_device *nand) /* Do we need extended device probe information? */ if (nand->device->page_size == 0 || - nand->device->erase_size == 0) - { - if (nand->bus_width == 8) - { + nand->device->erase_size == 0) { + if (nand->bus_width == 8) { nand->controller->read_data(nand, id_buff + 3); nand->controller->read_data(nand, id_buff + 4); nand->controller->read_data(nand, id_buff + 5); - } - else - { + } else { uint16_t data_buf; nand->controller->read_data(nand, &data_buf); @@ -435,81 +413,68 @@ int nand_probe(struct nand_device *nand) /* page size */ if (nand->device->page_size == 0) - { nand->page_size = 1 << (10 + (id_buff[4] & 3)); - } - else if (nand->device->page_size == 256) - { + else if (nand->device->page_size == 256) { LOG_ERROR("NAND flashes with 256 byte pagesize are not supported"); return ERROR_NAND_OPERATION_FAILED; - } - else - { + } else nand->page_size = nand->device->page_size; - } /* number of address cycles */ - if (nand->page_size <= 512) - { + if (nand->page_size <= 512) { /* small page devices */ if (nand->device->chip_size <= 32) nand->address_cycles = 3; else if (nand->device->chip_size <= 8*1024) nand->address_cycles = 4; - else - { + else { LOG_ERROR("BUG: small page NAND device with more than 8 GiB encountered"); nand->address_cycles = 5; } - } - else - { + } else { /* large page devices */ if (nand->device->chip_size <= 128) nand->address_cycles = 4; else if (nand->device->chip_size <= 32*1024) nand->address_cycles = 5; - else - { + else { LOG_ERROR("BUG: large page NAND device with more than 32 GiB encountered"); nand->address_cycles = 6; } } /* erase size */ - if (nand->device->erase_size == 0) - { + if (nand->device->erase_size == 0) { switch ((id_buff[4] >> 4) & 3) { - case 0: - nand->erase_size = 64 << 10; - break; - case 1: - nand->erase_size = 128 << 10; - break; - case 2: - nand->erase_size = 256 << 10; - break; - case 3: - nand->erase_size =512 << 10; - break; + case 0: + nand->erase_size = 64 << 10; + break; + case 1: + nand->erase_size = 128 << 10; + break; + case 2: + nand->erase_size = 256 << 10; + break; + case 3: + nand->erase_size = 512 << 10; + break; } - } - else - { + } else nand->erase_size = nand->device->erase_size; - } /* initialize controller, but leave parameters at the controllers default */ - if ((retval = nand->controller->init(nand) != ERROR_OK)) - { - switch (retval) - { + retval = nand->controller->init(nand); + if (retval != ERROR_OK) { + switch (retval) { case ERROR_NAND_OPERATION_FAILED: LOG_DEBUG("controller initialization failed"); return ERROR_NAND_OPERATION_FAILED; case ERROR_NAND_OPERATION_NOT_SUPPORTED: - LOG_ERROR("controller doesn't support requested parameters (buswidth: %i, address cycles: %i, page size: %i)", - nand->bus_width, nand->address_cycles, nand->page_size); + LOG_ERROR( + "controller doesn't support requested parameters (buswidth: %i, address cycles: %i, page size: %i)", + nand->bus_width, + nand->address_cycles, + nand->page_size); return ERROR_NAND_OPERATION_FAILED; default: LOG_ERROR("BUG: unknown controller initialization failure"); @@ -520,8 +485,7 @@ int nand_probe(struct nand_device *nand) nand->num_blocks = (nand->device->chip_size * 1024) / (nand->erase_size / 1024); nand->blocks = malloc(sizeof(struct nand_block) * nand->num_blocks); - for (i = 0; i < nand->num_blocks; i++) - { + for (i = 0; i < nand->num_blocks; i++) { nand->blocks[i].size = nand->erase_size; nand->blocks[i].offset = i * nand->erase_size; nand->blocks[i].is_erased = -1; @@ -545,25 +509,21 @@ int nand_erase(struct nand_device *nand, int first_block, int last_block) return ERROR_COMMAND_SYNTAX_ERROR; /* make sure we know if a block is bad before erasing it */ - for (i = first_block; i <= last_block; i++) - { - if (nand->blocks[i].is_bad == -1) - { + for (i = first_block; i <= last_block; i++) { + if (nand->blocks[i].is_bad == -1) { nand_build_bbt(nand, i, last_block); break; } } - for (i = first_block; i <= last_block; i++) - { + for (i = first_block; i <= last_block; i++) { /* Send erase setup command */ nand->controller->command(nand, NAND_CMD_ERASE1); page = i * (nand->erase_size / nand->page_size); /* Send page address */ - if (nand->page_size <= 512) - { + if (nand->page_size <= 512) { /* row */ nand->controller->address(nand, page & 0xff); nand->controller->address(nand, (page >> 8) & 0xff); @@ -575,9 +535,7 @@ int nand_erase(struct nand_device *nand, int first_block, int last_block) /* 4th cycle only on devices with more than 8 GiB */ if (nand->address_cycles >= 5) nand->controller->address(nand, (page >> 24) & 0xff); - } - else - { + } else { /* row */ nand->controller->address(nand, page & 0xff); nand->controller->address(nand, (page >> 8) & 0xff); @@ -591,26 +549,24 @@ int nand_erase(struct nand_device *nand, int first_block, int last_block) nand->controller->command(nand, NAND_CMD_ERASE2); retval = nand->controller->nand_ready ? - nand->controller->nand_ready(nand, 1000) : - nand_poll_ready(nand, 1000); + nand->controller->nand_ready(nand, 1000) : + nand_poll_ready(nand, 1000); if (!retval) { LOG_ERROR("timeout waiting for NAND flash block erase to complete"); return ERROR_NAND_OPERATION_TIMEOUT; } retval = nand_read_status(nand, &status); - if (retval != ERROR_OK) - { + if (retval != ERROR_OK) { LOG_ERROR("couldn't read status"); return ERROR_NAND_OPERATION_FAILED; } - if (status & 0x1) - { + if (status & 0x1) { LOG_ERROR("didn't erase %sblock %d; status: 0x%2.2x", - (nand->blocks[i].is_bad == 1) - ? "bad " : "", - i, status); + (nand->blocks[i].is_bad == 1) + ? "bad " : "", + i, status); /* continue; other blocks might still be erasable */ } @@ -621,23 +577,24 @@ int nand_erase(struct nand_device *nand, int first_block, int last_block) } #if 0 -static int nand_read_plain(struct nand_device *nand, uint32_t address, uint8_t *data, uint32_t data_size) +static int nand_read_plain(struct nand_device *nand, + uint32_t address, + uint8_t *data, + uint32_t data_size) { uint8_t *page; if (!nand->device) return ERROR_NAND_DEVICE_NOT_PROBED; - if (address % nand->page_size) - { + if (address % nand->page_size) { LOG_ERROR("reads need to be page aligned"); return ERROR_NAND_OPERATION_FAILED; } page = malloc(nand->page_size); - while (data_size > 0) - { + while (data_size > 0) { uint32_t thisrun_size = (data_size > nand->page_size) ? nand->page_size : data_size; uint32_t page_address; @@ -658,23 +615,24 @@ static int nand_read_plain(struct nand_device *nand, uint32_t address, uint8_t * return ERROR_OK; } -static int nand_write_plain(struct nand_device *nand, uint32_t address, uint8_t *data, uint32_t data_size) +static int nand_write_plain(struct nand_device *nand, + uint32_t address, + uint8_t *data, + uint32_t data_size) { uint8_t *page; if (!nand->device) return ERROR_NAND_DEVICE_NOT_PROBED; - if (address % nand->page_size) - { + if (address % nand->page_size) { LOG_ERROR("writes need to be page aligned"); return ERROR_NAND_OPERATION_FAILED; } page = malloc(nand->page_size); - while (data_size > 0) - { + while (data_size > 0) { uint32_t thisrun_size = (data_size > nand->page_size) ? nand->page_size : data_size; uint32_t page_address; @@ -697,8 +655,8 @@ static int nand_write_plain(struct nand_device *nand, uint32_t address, uint8_t #endif int nand_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size) { uint32_t block; @@ -716,8 +674,8 @@ int nand_write_page(struct nand_device *nand, uint32_t page, } int nand_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size) { if (!nand->device) return ERROR_NAND_DEVICE_NOT_PROBED; @@ -729,7 +687,7 @@ int nand_read_page(struct nand_device *nand, uint32_t page, } int nand_page_command(struct nand_device *nand, uint32_t page, - uint8_t cmd, bool oob_only) + uint8_t cmd, bool oob_only) { if (!nand->device) return ERROR_NAND_DEVICE_NOT_PROBED; @@ -814,8 +772,8 @@ int nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t 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) + uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size) { int retval; @@ -870,8 +828,8 @@ int nand_write_finish(struct nand_device *nand) nand->controller->command(nand, NAND_CMD_PAGEPROG); retval = nand->controller->nand_ready ? - nand->controller->nand_ready(nand, 100) : - nand_poll_ready(nand, 100); + nand->controller->nand_ready(nand, 100) : + nand_poll_ready(nand, 100); if (!retval) return ERROR_NAND_OPERATION_TIMEOUT; @@ -883,7 +841,7 @@ int nand_write_finish(struct nand_device *nand) if (status & NAND_STATUS_FAIL) { LOG_ERROR("write operation didn't pass, status: 0x%2.2x", - status); + status); return ERROR_NAND_OPERATION_FAILED; } @@ -891,8 +849,8 @@ int nand_write_finish(struct nand_device *nand) } int nand_write_page_raw(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size) { int retval; @@ -918,4 +876,3 @@ int nand_write_page_raw(struct nand_device *nand, uint32_t page, return nand_write_finish(nand); } - diff --git a/src/flash/nand/core.h b/src/flash/nand/core.h index 8a76d48..0451084 100644 --- a/src/flash/nand/core.h +++ b/src/flash/nand/core.h @@ -22,6 +22,7 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifndef FLASH_NAND_CORE_H #define FLASH_NAND_CORE_H @@ -30,8 +31,7 @@ /** * Representation of a single NAND block in a NAND device. */ -struct nand_block -{ +struct nand_block { /** Offset to the block. */ uint32_t offset; @@ -57,8 +57,7 @@ struct nand_ecclayout { struct nand_oobfree oobfree[2]; }; -struct nand_device -{ +struct nand_device { const char *name; struct target *target; struct nand_flash_controller *controller; @@ -77,8 +76,7 @@ struct nand_device /* NAND Flash Manufacturer ID Codes */ -enum -{ +enum { NAND_MFR_TOSHIBA = 0x98, NAND_MFR_SAMSUNG = 0xec, NAND_MFR_FUJITSU = 0x04, @@ -89,14 +87,12 @@ enum NAND_MFR_MICRON = 0x2c, }; -struct nand_manufacturer -{ +struct nand_manufacturer { int id; const char *name; }; -struct nand_info -{ +struct nand_info { int mfr_id; int id; int page_size; @@ -152,8 +148,7 @@ enum { LP_OPTIONS16 = (LP_OPTIONS | NAND_BUSWIDTH_16), }; -enum -{ +enum { /* Standard NAND flash commands */ NAND_CMD_READ0 = 0x0, NAND_CMD_READ1 = 0x1, @@ -161,7 +156,7 @@ enum NAND_CMD_PAGEPROG = 0x10, NAND_CMD_READOOB = 0x50, NAND_CMD_ERASE1 = 0x60, - NAND_CMD_STATUS = 0x70, + NAND_CMD_STATUS = 0x70, NAND_CMD_STATUS_MULTI = 0x71, NAND_CMD_SEQIN = 0x80, NAND_CMD_RNDIN = 0x85, @@ -176,8 +171,7 @@ enum }; /* Status bits */ -enum -{ +enum { NAND_STATUS_FAIL = 0x01, NAND_STATUS_FAIL_N1 = 0x02, NAND_STATUS_TRUE_READY = 0x20, @@ -186,14 +180,14 @@ enum }; /* OOB (spare) data formats */ -enum oob_formats -{ +enum oob_formats { NAND_OOB_NONE = 0x0, /* no OOB data at all */ - NAND_OOB_RAW = 0x1, /* raw OOB data (16 bytes for 512b page sizes, 64 bytes for 2048b page sizes) */ + NAND_OOB_RAW = 0x1, /* raw OOB data (16 bytes for 512b page sizes, 64 bytes for + *2048b page sizes) */ NAND_OOB_ONLY = 0x2, /* only OOB data */ NAND_OOB_SW_ECC = 0x10, /* when writing, use SW ECC (as opposed to no ECC) */ - NAND_OOB_HW_ECC = 0x20, /* when writing, use HW ECC (as opposed to no ECC) */ - NAND_OOB_SW_ECC_KW = 0x40, /* when writing, use Marvell's Kirkwood bootrom format */ + NAND_OOB_HW_ECC = 0x20, /* when writing, use HW ECC (as opposed to no ECC) */ + NAND_OOB_SW_ECC_KW = 0x40, /* when writing, use Marvell's Kirkwood bootrom format */ NAND_OOB_JFFS2 = 0x100, /* when writing, use JFFS2 OOB layout */ NAND_OOB_YAFFS2 = 0x100,/* when writing, use YAFFS2 OOB layout */ }; @@ -202,40 +196,39 @@ enum oob_formats 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); + uint8_t cmd, bool oob_only); int nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t size); int nand_write_data_page(struct nand_device *nand, - uint8_t *data, uint32_t size); + uint8_t *data, uint32_t size); int nand_write_finish(struct nand_device *nand); 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); + 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, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); int nand_read_status(struct nand_device *nand, uint8_t *status); int nand_calculate_ecc(struct nand_device *nand, - const uint8_t *dat, uint8_t *ecc_code); + const uint8_t *dat, uint8_t *ecc_code); int nand_calculate_ecc_kw(struct nand_device *nand, - const uint8_t *dat, uint8_t *ecc_code); + const uint8_t *dat, uint8_t *ecc_code); int nand_register_commands(struct command_context *cmd_ctx); -/// helper for parsing a nand device command argument string +/* / helper for parsing a nand device command argument string */ COMMAND_HELPER(nand_command_get_device, unsigned name_index, - struct nand_device **nand); - + struct nand_device **nand); -#define ERROR_NAND_DEVICE_INVALID (-1100) -#define ERROR_NAND_OPERATION_FAILED (-1101) -#define ERROR_NAND_OPERATION_TIMEOUT (-1102) -#define ERROR_NAND_OPERATION_NOT_SUPPORTED (-1103) -#define ERROR_NAND_DEVICE_NOT_PROBED (-1104) -#define ERROR_NAND_ERROR_CORRECTION_FAILED (-1105) -#define ERROR_NAND_NO_BUFFER (-1106) -#endif // FLASH_NAND_CORE_H +#define ERROR_NAND_DEVICE_INVALID (-1100) +#define ERROR_NAND_OPERATION_FAILED (-1101) +#define ERROR_NAND_OPERATION_TIMEOUT (-1102) +#define ERROR_NAND_OPERATION_NOT_SUPPORTED (-1103) +#define ERROR_NAND_DEVICE_NOT_PROBED (-1104) +#define ERROR_NAND_ERROR_CORRECTION_FAILED (-1105) +#define ERROR_NAND_NO_BUFFER (-1106) +#endif /* FLASH_NAND_CORE_H */ diff --git a/src/flash/nand/davinci.c b/src/flash/nand/davinci.c index e12fc46..cd9d9ab 100644 --- a/src/flash/nand/davinci.c +++ b/src/flash/nand/davinci.c @@ -39,34 +39,34 @@ enum ecc { }; struct davinci_nand { - uint8_t chipsel; /* chipselect 0..3 == CS2..CS5 */ - uint8_t eccmode; + uint8_t chipsel; /* chipselect 0..3 == CS2..CS5 */ + uint8_t eccmode; /* Async EMIF controller base */ - uint32_t aemif; + uint32_t aemif; /* NAND chip addresses */ - uint32_t data; /* without CLE or ALE */ - uint32_t cmd; /* with CLE */ - uint32_t addr; /* with ALE */ + uint32_t data; /* without CLE or ALE */ + uint32_t cmd; /* with CLE */ + uint32_t addr; /* with ALE */ /* write acceleration */ - struct arm_nand_data io; + struct arm_nand_data io; /* page i/o for the relevant flavor of hardware ECC */ int (*read_page)(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); int (*write_page)(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); }; -#define NANDFCR 0x60 /* flash control register */ -#define NANDFSR 0x64 /* flash status register */ -#define NANDFECC 0x70 /* 1-bit ECC data, CS0, 1st of 4 */ -#define NAND4BITECCLOAD 0xbc /* 4-bit ECC, load saved values */ -#define NAND4BITECC 0xc0 /* 4-bit ECC data, 1st of 4 */ -#define NANDERRADDR 0xd0 /* 4-bit ECC err addr, 1st of 2 */ -#define NANDERRVAL 0xd8 /* 4-bit ECC err value, 1st of 2 */ +#define NANDFCR 0x60 /* flash control register */ +#define NANDFSR 0x64 /* flash status register */ +#define NANDFECC 0x70 /* 1-bit ECC data, CS0, 1st of 4 */ +#define NAND4BITECCLOAD 0xbc /* 4-bit ECC, load saved values */ +#define NAND4BITECC 0xc0 /* 4-bit ECC data, 1st of 4 */ +#define NANDERRADDR 0xd0 /* 4-bit ECC err addr, 1st of 2 */ +#define NANDERRVAL 0xd8 /* 4-bit ECC err value, 1st of 2 */ static int halted(struct target *target, const char *label) { @@ -181,7 +181,7 @@ static int davinci_read_data(struct nand_device *nand, void *data) /* REVISIT a bit of native code should let block reads be MUCH faster */ static int davinci_read_block_data(struct nand_device *nand, - uint8_t *data, int data_size) + uint8_t *data, int data_size) { struct davinci_nand *info = nand->controller_priv; struct target *target = nand->target; @@ -214,7 +214,7 @@ static int davinci_read_block_data(struct nand_device *nand, } static int davinci_write_block_data(struct nand_device *nand, - uint8_t *data, int data_size) + uint8_t *data, int data_size) { struct davinci_nand *info = nand->controller_priv; struct target *target = nand->target; @@ -250,7 +250,7 @@ static int davinci_write_block_data(struct nand_device *nand, } static int davinci_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) { struct davinci_nand *info = nand->controller_priv; uint8_t *ooballoc = NULL; @@ -269,17 +269,17 @@ static int davinci_write_page(struct nand_device *nand, uint32_t page, /* If we're not given OOB, write 0xff where we don't write ECC codes. */ switch (nand->page_size) { - case 512: - oob_size = 16; - break; - case 2048: - oob_size = 64; - break; - case 4096: - oob_size = 128; - break; - default: - return ERROR_NAND_OPERATION_FAILED; + case 512: + oob_size = 16; + break; + case 2048: + oob_size = 64; + break; + case 4096: + oob_size = 128; + break; + default: + return ERROR_NAND_OPERATION_FAILED; } if (!oob) { ooballoc = malloc(oob_size); @@ -301,7 +301,7 @@ static int davinci_write_page(struct nand_device *nand, uint32_t page, } static int davinci_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) { struct davinci_nand *info = nand->controller_priv; @@ -358,7 +358,7 @@ static int davinci_seek_column(struct nand_device *nand, uint16_t column) } static int davinci_writepage_tail(struct nand_device *nand, - uint8_t *oob, uint32_t oob_size) + uint8_t *oob, uint32_t oob_size) { struct davinci_nand *info = nand->controller_priv; struct target *target = nand->target; @@ -390,7 +390,7 @@ static int davinci_writepage_tail(struct nand_device *nand, * All DaVinci family chips support 1-bit ECC on a per-chipselect basis. */ static int davinci_write_page_ecc1(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) { unsigned oob_offset; struct davinci_nand *info = nand->controller_priv; @@ -404,15 +404,15 @@ static int davinci_write_page_ecc1(struct nand_device *nand, uint32_t page, * for 16-bit OOB, those extra bytes are discontiguous. */ switch (nand->page_size) { - case 512: - oob_offset = 0; - break; - case 2048: - oob_offset = 40; - break; - default: - oob_offset = 80; - break; + case 512: + oob_offset = 0; + break; + case 2048: + oob_offset = 40; + break; + default: + oob_offset = 80; + break; } davinci_write_pagecmd(nand, NAND_CMD_SEQIN, page); @@ -457,10 +457,10 @@ static int davinci_write_page_ecc1(struct nand_device *nand, uint32_t page, * manufacturer bad block markers are safe. Contrast: old "infix" style. */ static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) { static const uint8_t ecc512[] = { - 0, 1, 2, 3, 4, /* 5== mfr badblock */ + 0, 1, 2, 3, 4, /* 5== mfr badblock */ 6, 7, /* 8..12 for BBT or JFFS2 */ 13, 14, 15, }; static const uint8_t ecc2048[] = { @@ -470,12 +470,12 @@ static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, }; static const uint8_t ecc4096[] = { - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, }; @@ -495,15 +495,15 @@ static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page, * the standard ECC logic can't handle. */ switch (nand->page_size) { - case 512: - l = ecc512; - break; - case 2048: - l = ecc2048; - break; - default: - l = ecc4096; - break; + case 512: + l = ecc512; + break; + case 2048: + l = ecc2048; + break; + default: + l = ecc4096; + break; } davinci_write_pagecmd(nand, NAND_CMD_SEQIN, page); @@ -533,11 +533,11 @@ static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page, raw_ecc[i] &= 0x03ff03ff; } for (i = 0, p = raw_ecc; i < 2; i++, p += 2) { - oob[*l++] = p[0] & 0xff; + oob[*l++] = p[0] & 0xff; oob[*l++] = ((p[0] >> 8) & 0x03) | ((p[0] >> 14) & 0xfc); oob[*l++] = ((p[0] >> 22) & 0x0f) | ((p[1] << 4) & 0xf0); oob[*l++] = ((p[1] >> 4) & 0x3f) | ((p[1] >> 10) & 0xc0); - oob[*l++] = (p[1] >> 18) & 0xff; + oob[*l++] = (p[1] >> 18) & 0xff; } } while (data_size); @@ -559,7 +559,7 @@ static int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page, * (MVL 4.x/5.x kernels, filesystems, etc) may need it more generally. */ static int davinci_write_page_ecc4infix(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) { struct davinci_nand *info = nand->controller_priv; struct target *target = nand->target; @@ -597,11 +597,11 @@ static int davinci_write_page_ecc4infix(struct nand_device *nand, uint32_t page, /* skip 6 bytes of prepad, then pack 10 packed ecc bytes */ for (i = 0, l = oob + 6, p = raw_ecc; i < 2; i++, p += 2) { - *l++ = p[0] & 0xff; + *l++ = p[0] & 0xff; *l++ = ((p[0] >> 8) & 0x03) | ((p[0] >> 14) & 0xfc); *l++ = ((p[0] >> 22) & 0x0f) | ((p[1] << 4) & 0xf0); *l++ = ((p[1] >> 4) & 0x3f) | ((p[1] >> 10) & 0xc0); - *l++ = (p[1] >> 18) & 0xff; + *l++ = (p[1] >> 18) & 0xff; } /* write this "out-of-band" data -- infix */ @@ -616,7 +616,7 @@ static int davinci_write_page_ecc4infix(struct nand_device *nand, uint32_t page, } static int davinci_read_page_ecc4infix(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) { int read_size; int want_col, at_col; @@ -688,9 +688,8 @@ NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command) * - aemif address * Plus someday, optionally, ALE and CLE masks. */ - if (CMD_ARGC < 5) { + if (CMD_ARGC < 5) return ERROR_COMMAND_SYNTAX_ERROR; - } COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], chip); if (chip == 0) { @@ -720,9 +719,9 @@ NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command) * AEMIF controller address. */ if (aemif == 0x01e00000 /* dm6446, dm357 */ - || aemif == 0x01e10000 /* dm335, dm355 */ - || aemif == 0x01d10000 /* dm365 */ - ) { + || aemif == 0x01e10000 /* dm335, dm355 */ + || aemif == 0x01d10000 /* dm365 */ + ) { if (chip < 0x02000000 || chip >= 0x0a000000) { LOG_ERROR("NAND address %08lx out of range?", chip); goto fail; @@ -757,19 +756,19 @@ NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command) info->read_page = nand_read_page_raw; switch (eccmode) { - case HWECC1: - /* ECC_HW, 1-bit corrections, 3 bytes ECC per 512 data bytes */ - info->write_page = davinci_write_page_ecc1; - break; - case HWECC4: - /* ECC_HW, 4-bit corrections, 10 bytes ECC per 512 data bytes */ - info->write_page = davinci_write_page_ecc4; - break; - case HWECC4_INFIX: - /* Same 4-bit ECC HW, with problematic page/ecc layout */ - info->read_page = davinci_read_page_ecc4infix; - info->write_page = davinci_write_page_ecc4infix; - break; + case HWECC1: + /* ECC_HW, 1-bit corrections, 3 bytes ECC per 512 data bytes */ + info->write_page = davinci_write_page_ecc1; + break; + case HWECC4: + /* ECC_HW, 4-bit corrections, 10 bytes ECC per 512 data bytes */ + info->write_page = davinci_write_page_ecc4; + break; + case HWECC4_INFIX: + /* Same 4-bit ECC HW, with problematic page/ecc layout */ + info->read_page = davinci_read_page_ecc4infix; + info->write_page = davinci_write_page_ecc4infix; + break; } return ERROR_OK; @@ -779,18 +778,18 @@ fail: } struct nand_flash_controller davinci_nand_controller = { - .name = "davinci", - .usage = "chip_addr hwecc_mode aemif_addr", - .nand_device_command = davinci_nand_device_command, - .init = davinci_init, - .reset = davinci_reset, - .command = davinci_command, - .address = davinci_address, - .write_data = davinci_write_data, - .read_data = davinci_read_data, - .write_page = davinci_write_page, - .read_page = davinci_read_page, - .write_block_data = davinci_write_block_data, - .read_block_data = davinci_read_block_data, - .nand_ready = davinci_nand_ready, + .name = "davinci", + .usage = "chip_addr hwecc_mode aemif_addr", + .nand_device_command = davinci_nand_device_command, + .init = davinci_init, + .reset = davinci_reset, + .command = davinci_command, + .address = davinci_address, + .write_data = davinci_write_data, + .read_data = davinci_read_data, + .write_page = davinci_write_page, + .read_page = davinci_read_page, + .write_block_data = davinci_write_block_data, + .read_block_data = davinci_read_block_data, + .nand_ready = davinci_nand_ready, }; diff --git a/src/flash/nand/driver.c b/src/flash/nand/driver.c index ae35b64..2ba3e1e 100644 --- a/src/flash/nand/driver.c +++ b/src/flash/nand/driver.c @@ -45,8 +45,7 @@ extern struct nand_flash_controller nuc910_nand_controller; /* extern struct nand_flash_controller boundary_scan_nand_controller; */ -static struct nand_flash_controller *nand_flash_controllers[] = -{ +static struct nand_flash_controller *nand_flash_controllers[] = { &nonce_nand_controller, &davinci_nand_controller, &lpc3180_nand_controller, @@ -67,8 +66,7 @@ static struct nand_flash_controller *nand_flash_controllers[] = struct nand_flash_controller *nand_driver_find_by_name(const char *name) { - for (unsigned i = 0; nand_flash_controllers[i]; i++) - { + for (unsigned i = 0; nand_flash_controllers[i]; i++) { struct nand_flash_controller *controller = nand_flash_controllers[i]; if (strcmp(name, controller->name) == 0) return controller; @@ -77,13 +75,10 @@ struct nand_flash_controller *nand_driver_find_by_name(const char *name) } int nand_driver_walk(nand_driver_walker_t f, void *x) { - for (unsigned i = 0; nand_flash_controllers[i]; i++) - { + for (unsigned i = 0; nand_flash_controllers[i]; i++) { int retval = (*f)(nand_flash_controllers[i], x); if (ERROR_OK != retval) return retval; } return ERROR_OK; } - - diff --git a/src/flash/nand/driver.h b/src/flash/nand/driver.h index 04ec64f..caf3219 100644 --- a/src/flash/nand/driver.h +++ b/src/flash/nand/driver.h @@ -19,28 +19,28 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifndef FLASH_NAND_DRIVER_H #define FLASH_NAND_DRIVER_H struct nand_device; #define __NAND_DEVICE_COMMAND(name) \ - COMMAND_HELPER(name, struct nand_device *nand) + COMMAND_HELPER(name, struct nand_device *nand) /** * Interface for NAND flash controllers. Not all of these functions are * required for full functionality of the NAND driver, but better performance * can be achieved by implementing each function. */ -struct nand_flash_controller -{ +struct nand_flash_controller { /** Driver name that is used to select it from configuration files. */ const char *name; /** Usage of flash command registration. */ const char *usage; - const struct command_registration *commands; + const struct command_registration *commands; /** NAND device command called when driver is instantiated during configuration. */ __NAND_DEVICE_COMMAND((*nand_device_command)); @@ -70,10 +70,12 @@ struct nand_flash_controller int (*read_block_data)(struct nand_device *nand, uint8_t *data, int size); /** Write a page to the NAND device. */ - int (*write_page)(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); + int (*write_page)(struct nand_device *nand, uint32_t page, uint8_t *data, + uint32_t data_size, uint8_t *oob, uint32_t oob_size); /** Read a page from the NAND device. */ - int (*read_page)(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size); + int (*read_page)(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size); /** Check if the NAND device is ready for more instructions with timeout. */ int (*nand_ready)(struct nand_device *nand, int timeout); @@ -88,8 +90,8 @@ struct nand_flash_controller */ struct nand_flash_controller *nand_driver_find_by_name(const char *name); -/// Signature for callback functions passed to nand_driver_walk -typedef int (*nand_driver_walker_t)(struct nand_flash_controller *c, void*); +/* / Signature for callback functions passed to nand_driver_walk */ +typedef int (*nand_driver_walker_t)(struct nand_flash_controller *c, void *); /** * Walk the list of drivers, encapsulating the data structure type. * Application state/context can be passed through the @c x pointer. @@ -100,4 +102,4 @@ typedef int (*nand_driver_walker_t)(struct nand_flash_controller *c, void*); */ int nand_driver_walk(nand_driver_walker_t f, void *x); -#endif // FLASH_NAND_DRIVER_H +#endif /* FLASH_NAND_DRIVER_H */ diff --git a/src/flash/nand/ecc.c b/src/flash/nand/ecc.c index b3623d4..f3e2551 100644 --- a/src/flash/nand/ecc.c +++ b/src/flash/nand/ecc.c @@ -125,7 +125,7 @@ static inline int countbits(uint32_t b) { int res = 0; - for (;b; b >>= 1) + for (; b; b >>= 1) res += b & 0x01; return res; } @@ -134,7 +134,7 @@ static inline int countbits(uint32_t b) * nand_correct_data - Detect and correct a 1 bit error for 256 byte block */ int nand_correct_data(struct nand_device *nand, u_char *dat, - u_char *read_ecc, u_char *calc_ecc) + u_char *read_ecc, u_char *calc_ecc) { uint8_t s0, s1, s2; @@ -151,9 +151,9 @@ int nand_correct_data(struct nand_device *nand, u_char *dat, return 0; /* Check for a single bit error */ - if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 && - ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 && - ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) { + if (((s0 ^ (s0 >> 1)) & 0x55) == 0x55 && + ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 && + ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) { uint32_t byteoffs, bitnum; @@ -176,7 +176,7 @@ int nand_correct_data(struct nand_device *nand, u_char *dat, return 1; } - if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1) + if (countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 << 16)) == 1) return 1; return -1; diff --git a/src/flash/nand/ecc_kw.c b/src/flash/nand/ecc_kw.c index 1c1a8ea..1c3cc70 100644 --- a/src/flash/nand/ecc_kw.c +++ b/src/flash/nand/ecc_kw.c @@ -28,7 +28,7 @@ * For multiplication, a discrete log/exponent table is used, with * primitive element x (F is a primitive field, so x is primitive). */ -#define MODPOLY 0x409 /* x^10 + x^3 + 1 in binary */ +#define MODPOLY 0x409 /* x^10 + x^3 + 1 in binary */ /* * Maps an integer a [0..1022] to a polynomial b = gf_exp[a] in @@ -102,7 +102,7 @@ int nand_calculate_ecc_kw(struct nand_device *nand, const uint8_t *data, uint8_t { unsigned int r7, r6, r5, r4, r3, r2, r1, r0; int i; - static int tables_initialized = 0; + static int tables_initialized; if (!tables_initialized) { gf_build_log_exp_table(); @@ -121,7 +121,6 @@ int nand_calculate_ecc_kw(struct nand_device *nand, const uint8_t *data, uint8_t r6 = data[510]; r7 = data[511]; - /* * Shift bytes 503..0 (in that order) into r0, followed * by eight zero bytes, while reducing the polynomial by the diff --git a/src/flash/nand/fileio.c b/src/flash/nand/fileio.c index c7515e2..8948247 100644 --- a/src/flash/nand/fileio.c +++ b/src/flash/nand/fileio.c @@ -20,6 +20,7 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -32,18 +33,21 @@ static struct nand_ecclayout nand_oob_16 = { .eccpos = {0, 1, 2, 3, 6, 7}, .oobfree = { {.offset = 8, - . length = 8}} + .length = 8} + } }; static struct nand_ecclayout nand_oob_64 = { .eccbytes = 24, .eccpos = { - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63}, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63 + }, .oobfree = { {.offset = 2, - .length = 38}} + .length = 38} + } }; void nand_fileio_init(struct nand_fileio_state *state) @@ -53,45 +57,37 @@ void nand_fileio_init(struct nand_fileio_state *state) } int nand_fileio_start(struct command_context *cmd_ctx, - struct nand_device *nand, const char *filename, int filemode, - struct nand_fileio_state *state) + struct nand_device *nand, const char *filename, int filemode, + struct nand_fileio_state *state) { - if (state->address % nand->page_size) - { + if (state->address % nand->page_size) { command_print(cmd_ctx, "only page-aligned addresses are supported"); return ERROR_COMMAND_SYNTAX_ERROR; } duration_start(&state->bench); - if (NULL != filename) - { + if (NULL != filename) { int retval = fileio_open(&state->fileio, filename, filemode, FILEIO_BINARY); - if (ERROR_OK != retval) - { + if (ERROR_OK != retval) { const char *msg = (FILEIO_READ == filemode) ? "read" : "write"; command_print(cmd_ctx, "failed to open '%s' for %s access", - filename, msg); + filename, msg); return retval; } state->file_opened = true; } - if (!(state->oob_format & NAND_OOB_ONLY)) - { + if (!(state->oob_format & NAND_OOB_ONLY)) { state->page_size = nand->page_size; state->page = malloc(nand->page_size); } - if (state->oob_format & (NAND_OOB_RAW | NAND_OOB_SW_ECC | NAND_OOB_SW_ECC_KW)) - { - if (nand->page_size == 512) - { + if (state->oob_format & (NAND_OOB_RAW | NAND_OOB_SW_ECC | NAND_OOB_SW_ECC_KW)) { + if (nand->page_size == 512) { state->oob_size = 16; state->eccpos = nand_oob_16.eccpos; - } - else if (nand->page_size == 2048) - { + } else if (nand->page_size == 2048) { state->oob_size = 64; state->eccpos = nand_oob_64.eccpos; } @@ -105,13 +101,11 @@ int nand_fileio_cleanup(struct nand_fileio_state *state) if (state->file_opened) fileio_close(&state->fileio); - if (state->oob) - { + if (state->oob) { free(state->oob); state->oob = NULL; } - if (state->page) - { + if (state->page) { free(state->page); state->page = NULL; } @@ -124,8 +118,8 @@ int nand_fileio_finish(struct nand_fileio_state *state) } COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state, - struct nand_device **dev, enum fileio_access filemode, - bool need_size, bool sw_ecc) + struct nand_device **dev, enum fileio_access filemode, + bool need_size, bool sw_ecc) { nand_fileio_init(state); @@ -138,27 +132,22 @@ COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state, if (ERROR_OK != retval) return retval; - if (NULL == nand->device) - { + if (NULL == nand->device) { command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]); return ERROR_OK; } COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], state->address); - if (need_size) - { - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], state->size); - if (state->size % nand->page_size) - { - command_print(CMD_CTX, "only page-aligned sizes are supported"); - return ERROR_COMMAND_SYNTAX_ERROR; - } + if (need_size) { + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], state->size); + if (state->size % nand->page_size) { + command_print(CMD_CTX, "only page-aligned sizes are supported"); + return ERROR_COMMAND_SYNTAX_ERROR; + } } - if (CMD_ARGC > minargs) - { - for (unsigned i = minargs; i < CMD_ARGC; i++) - { + if (CMD_ARGC > minargs) { + for (unsigned i = minargs; i < CMD_ARGC; i++) { if (!strcmp(CMD_ARGV[i], "oob_raw")) state->oob_format |= NAND_OOB_RAW; else if (!strcmp(CMD_ARGV[i], "oob_only")) @@ -167,8 +156,7 @@ COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state, state->oob_format |= NAND_OOB_SW_ECC; else if (sw_ecc && !strcmp(CMD_ARGV[i], "oob_softecc_kw")) state->oob_format |= NAND_OOB_SW_ECC_KW; - else - { + else { command_print(CMD_CTX, "unknown option: %s", CMD_ARGV[i]); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -179,8 +167,7 @@ COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state, if (ERROR_OK != retval) return retval; - if (!need_size) - { + if (!need_size) { int filesize; retval = fileio_size(&state->fileio, &filesize); if (retval != ERROR_OK) @@ -202,28 +189,23 @@ int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s) size_t total_read = 0; size_t one_read; - if (NULL != s->page) - { + if (NULL != s->page) { fileio_read(&s->fileio, s->page_size, s->page, &one_read); if (one_read < s->page_size) memset(s->page + one_read, 0xff, s->page_size - one_read); total_read += one_read; } - if (s->oob_format & NAND_OOB_SW_ECC) - { + if (s->oob_format & NAND_OOB_SW_ECC) { uint8_t ecc[3]; memset(s->oob, 0xff, s->oob_size); - for (uint32_t i = 0, j = 0; i < s->page_size; i += 256) - { + for (uint32_t i = 0, j = 0; i < s->page_size; i += 256) { nand_calculate_ecc(nand, s->page + i, ecc); s->oob[s->eccpos[j++]] = ecc[0]; s->oob[s->eccpos[j++]] = ecc[1]; s->oob[s->eccpos[j++]] = ecc[2]; } - } - else if (s->oob_format & NAND_OOB_SW_ECC_KW) - { + } else if (s->oob_format & NAND_OOB_SW_ECC_KW) { /* * In this case eccpos is not used as * the ECC data is always stored contigously @@ -232,14 +214,11 @@ int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s) */ uint8_t *ecc = s->oob + s->oob_size - s->page_size / 512 * 10; memset(s->oob, 0xff, s->oob_size); - for (uint32_t i = 0; i < s->page_size; i += 512) - { + for (uint32_t i = 0; i < s->page_size; i += 512) { nand_calculate_ecc_kw(nand, s->page + i, ecc); ecc += 10; } - } - else if (NULL != s->oob) - { + } else if (NULL != s->oob) { fileio_read(&s->fileio, s->oob_size, s->oob, &one_read); if (one_read < s->oob_size) memset(s->oob + one_read, 0xff, s->oob_size - one_read); @@ -247,4 +226,3 @@ int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s) } return total_read; } - diff --git a/src/flash/nand/fileio.h b/src/flash/nand/fileio.h index 7855431..0a5669a 100644 --- a/src/flash/nand/fileio.h +++ b/src/flash/nand/fileio.h @@ -16,6 +16,7 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifndef FLASH_NAND_FILEIO_H #define FLASH_NAND_FILEIO_H @@ -49,9 +50,9 @@ int nand_fileio_cleanup(struct nand_fileio_state *state); int nand_fileio_finish(struct nand_fileio_state *state); COMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state, - struct nand_device **dev, enum fileio_access filemode, - bool need_size, bool sw_ecc); + struct nand_device **dev, enum fileio_access filemode, + bool need_size, bool sw_ecc); int nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s); -#endif // FLASH_NAND_FILEIO_H +#endif /* FLASH_NAND_FILEIO_H */ diff --git a/src/flash/nand/imp.h b/src/flash/nand/imp.h index e6c9c5f..00b14b0 100644 --- a/src/flash/nand/imp.h +++ b/src/flash/nand/imp.h @@ -16,6 +16,7 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifndef FLASH_NAND_IMP_H #define FLASH_NAND_IMP_H @@ -36,4 +37,4 @@ int nand_probe(struct nand_device *nand); int nand_erase(struct nand_device *nand, int first_block, int last_block); int nand_build_bbt(struct nand_device *nand, int first, int last); -#endif // FLASH_NAND_IMP_H +#endif /* FLASH_NAND_IMP_H */ diff --git a/src/flash/nand/lpc3180.c b/src/flash/nand/lpc3180.c index b370e11..1b53067 100644 --- a/src/flash/nand/lpc3180.c +++ b/src/flash/nand/lpc3180.c @@ -20,6 +20,7 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -28,25 +29,20 @@ #include "lpc3180.h" #include <target/target.h> - static int lpc3180_reset(struct nand_device *nand); static int lpc3180_controller_ready(struct nand_device *nand, int timeout); static int lpc3180_tc_ready(struct nand_device *nand, int timeout); - #define ECC_OFFS 0x120 #define SPARE_OFFS 0x140 #define DATA_OFFS 0x200 - /* nand device lpc3180 <target#> <oscillator_frequency> */ NAND_DEVICE_COMMAND_HANDLER(lpc3180_nand_device_command) { if (CMD_ARGC < 3) - { return ERROR_COMMAND_SYNTAX_ERROR; - } uint32_t osc_freq; COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], osc_freq); @@ -58,9 +54,9 @@ NAND_DEVICE_COMMAND_HANDLER(lpc3180_nand_device_command) lpc3180_info->osc_freq = osc_freq; if ((lpc3180_info->osc_freq < 1000) || (lpc3180_info->osc_freq > 20000)) - { - LOG_WARNING("LPC3180 oscillator frequency should be between 1000 and 20000 kHz, was %i", lpc3180_info->osc_freq); - } + LOG_WARNING( + "LPC3180 oscillator frequency should be between 1000 and 20000 kHz, was %i", + lpc3180_info->osc_freq); lpc3180_info->selected_controller = LPC3180_NO_CONTROLLER; lpc3180_info->sw_write_protection = 0; lpc3180_info->sw_wp_lower_bound = 0x0; @@ -120,25 +116,18 @@ static float lpc3180_cycle_time(struct nand_device *nand) /* determine selected HCLK source */ target_read_u32(target, 0x40004044, &pwr_ctrl); - if ((pwr_ctrl & (1 << 2)) == 0) /* DIRECT RUN mode */ - { + if ((pwr_ctrl & (1 << 2)) == 0) /* DIRECT RUN mode */ hclk = sysclk; - } - else - { + else { target_read_u32(target, 0x40004058, &hclkpll_ctrl); hclk_pll = lpc3180_pll(sysclk, hclkpll_ctrl); target_read_u32(target, 0x40004040, &hclkdiv_ctrl); if (pwr_ctrl & (1 << 10)) /* ARM_CLK and HCLK use PERIPH_CLK */ - { hclk = hclk_pll / (((hclkdiv_ctrl & 0x7c) >> 2) + 1); - } else /* HCLK uses HCLK_PLL */ - { hclk = hclk_pll / (1 << (hclkdiv_ctrl & 0x3)); - } } LOG_DEBUG("LPC3180 HCLK currently clocked at %i kHz", hclk); @@ -156,15 +145,13 @@ static int lpc3180_init(struct nand_device *nand) int address_cycles = nand->address_cycles ? : 3; int page_size = nand->page_size ? : 512; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } /* sanitize arguments */ - if ((bus_width != 8) && (bus_width != 16)) - { + if ((bus_width != 8) && (bus_width != 16)) { LOG_ERROR("LPC3180 only supports 8 or 16 bit bus width, not %i", bus_width); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } @@ -173,34 +160,28 @@ static int lpc3180_init(struct nand_device *nand) * would support 16 bit, too, so we just warn about this for now */ if (bus_width == 16) - { LOG_WARNING("LPC3180 only supports 8 bit bus width"); - } /* inform calling code about selected bus width */ nand->bus_width = bus_width; - if ((address_cycles != 3) && (address_cycles != 4)) - { + if ((address_cycles != 3) && (address_cycles != 4)) { LOG_ERROR("LPC3180 only supports 3 or 4 address cycles, not %i", address_cycles); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } - if ((page_size != 512) && (page_size != 2048)) - { + if ((page_size != 512) && (page_size != 2048)) { LOG_ERROR("LPC3180 only supports 512 or 2048 byte pages, not %i", page_size); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } /* select MLC controller if none is currently selected */ - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) - { + if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { LOG_DEBUG("no LPC3180 NAND flash controller selected, using default 'mlc'"); lpc3180_info->selected_controller = LPC3180_MLC_CONTROLLER; } - if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - { + if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { uint32_t mlc_icr_value = 0x0; float cycle; int twp, twh, trp, treh, trhz, trbwb, tcea; @@ -245,9 +226,7 @@ static int lpc3180_init(struct nand_device *nand) ((trbwb & 0x1f) << 19) | ((tcea & 0x3) << 24)); lpc3180_reset(nand); - } - else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { float cycle; int r_setup, r_hold, r_width, r_rdy; int w_setup, w_hold, w_width, w_rdy; @@ -258,18 +237,19 @@ static int lpc3180_init(struct nand_device *nand) /* after reset set other registers of SLC so reset calling is here at the begining*/ lpc3180_reset(nand); - /* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst enabled, DMA read from SLC, WIDTH = bus_width) */ + /* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst enabled, + *DMA read from SLC, WIDTH = bus_width) */ target_write_u32(target, 0x20020014, 0x3e | (bus_width == 16) ? 1 : 0); /* SLC_IEN = 3 (INT_RDY_EN = 1) ,(INT_TC_STAT = 1) */ target_write_u32(target, 0x20020020, 0x03); - /* DMA configuration */ - /* DMACLK_CTRL = 0x01 (enable clock for DMA controller) */ + /* DMA configuration + * DMACLK_CTRL = 0x01 (enable clock for DMA controller) */ target_write_u32(target, 0x400040e8, 0x01); /* DMACConfig = DMA enabled*/ target_write_u32(target, 0x31000030, 0x01); - + /* calculate NAND controller timings */ cycle = lpc3180_cycle_time(nand); @@ -295,35 +275,27 @@ static int lpc3180_reset(struct nand_device *nand) struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) - { + if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); return ERROR_NAND_OPERATION_FAILED; - } - else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { /* MLC_CMD = 0xff (reset controller and NAND device) */ target_write_u32(target, 0x200b8000, 0xff); - if (!lpc3180_controller_ready(nand, 100)) - { + if (!lpc3180_controller_ready(nand, 100)) { LOG_ERROR("LPC3180 NAND controller timed out after reset"); return ERROR_NAND_OPERATION_TIMEOUT; } - } - else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { /* SLC_CTRL = 0x6 (ECC_CLEAR, SW_RESET) */ target_write_u32(target, 0x20020010, 0x6); - if (!lpc3180_controller_ready(nand, 100)) - { + if (!lpc3180_controller_ready(nand, 100)) { LOG_ERROR("LPC3180 NAND controller timed out after reset"); return ERROR_NAND_OPERATION_TIMEOUT; } @@ -337,24 +309,18 @@ static int lpc3180_command(struct nand_device *nand, uint8_t command) struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) - { + if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); return ERROR_NAND_OPERATION_FAILED; - } - else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { /* MLC_CMD = command */ target_write_u32(target, 0x200b8000, command); - } - else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { /* SLC_CMD = command */ target_write_u32(target, 0x20020008, command); } @@ -367,24 +333,18 @@ static int lpc3180_address(struct nand_device *nand, uint8_t address) struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) - { + if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); return ERROR_NAND_OPERATION_FAILED; - } - else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { /* MLC_ADDR = address */ target_write_u32(target, 0x200b8004, address); - } - else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { /* SLC_ADDR = address */ target_write_u32(target, 0x20020004, address); } @@ -397,24 +357,18 @@ static int lpc3180_write_data(struct nand_device *nand, uint16_t data) struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) - { + if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); return ERROR_NAND_OPERATION_FAILED; - } - else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { /* MLC_DATA = data */ target_write_u32(target, 0x200b0000, data); - } - else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { /* SLC_DATA = data */ target_write_u32(target, 0x20020000, data); } @@ -427,55 +381,39 @@ static int lpc3180_read_data(struct nand_device *nand, void *data) struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) - { + if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); return ERROR_NAND_OPERATION_FAILED; - } - else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { /* data = MLC_DATA, use sized access */ - if (nand->bus_width == 8) - { + if (nand->bus_width == 8) { uint8_t *data8 = data; target_read_u8(target, 0x200b0000, data8); - } - else if (nand->bus_width == 16) - { + } else if (nand->bus_width == 16) { uint16_t *data16 = data; target_read_u16(target, 0x200b0000, data16); - } - else - { + } else { LOG_ERROR("BUG: bus_width neither 8 nor 16 bit"); return ERROR_NAND_OPERATION_FAILED; } - } - else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { uint32_t data32; /* data = SLC_DATA, must use 32-bit access */ target_read_u32(target, 0x20020000, &data32); - if (nand->bus_width == 8) - { + if (nand->bus_width == 8) { uint8_t *data8 = data; *data8 = data32 & 0xff; - } - else if (nand->bus_width == 16) - { + } else if (nand->bus_width == 16) { uint16_t *data16 = data; *data16 = data32 & 0xffff; - } - else - { + } else { LOG_ERROR("BUG: bus_width neither 8 nor 16 bit"); return ERROR_NAND_OPERATION_FAILED; } @@ -484,7 +422,12 @@ static int lpc3180_read_data(struct nand_device *nand, void *data) return ERROR_OK; } -static int lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) +static int lpc3180_write_page(struct nand_device *nand, + uint32_t page, + uint8_t *data, + uint32_t data_size, + uint8_t *oob, + uint32_t oob_size) { struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; @@ -492,37 +435,30 @@ static int lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t * uint8_t status; uint8_t *page_buffer; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) - { + if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); return ERROR_NAND_OPERATION_FAILED; - } - else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { uint8_t *oob_buffer; int quarter, num_quarters; - if (!data && oob) - { + if (!data && oob) { LOG_ERROR("LPC3180 MLC controller can't write OOB data only"); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } - if (oob && (oob_size > 24)) - { + if (oob && (oob_size > 24)) { LOG_ERROR("LPC3180 MLC controller can't write more " "than 6 bytes for each quarter's OOB data"); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } - if (data_size > (uint32_t)nand->page_size) - { + if (data_size > (uint32_t)nand->page_size) { LOG_ERROR("data size exceeds page size"); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } @@ -533,8 +469,7 @@ static int lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t * page_buffer = malloc(512); oob_buffer = malloc(6); - if (nand->page_size == 512) - { + if (nand->page_size == 512) { /* MLC_ADDR = 0x0 (one column cycle) */ target_write_u32(target, 0x200b8004, 0x0); @@ -544,9 +479,7 @@ static int lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t * if (nand->address_cycles == 4) target_write_u32(target, 0x200b8004, (page >> 16) & 0xff); - } - else - { + } else { /* MLC_ADDR = 0x0 (two column cycles) */ target_write_u32(target, 0x200b8004, 0x0); target_write_u32(target, 0x200b8004, 0x0); @@ -561,22 +494,19 @@ static int lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t * */ num_quarters = (nand->page_size == 2048) ? 4 : 1; - for (quarter = 0; quarter < num_quarters; quarter++) - { + for (quarter = 0; quarter < num_quarters; quarter++) { int thisrun_data_size = (data_size > 512) ? 512 : data_size; int thisrun_oob_size = (oob_size > 6) ? 6 : oob_size; memset(page_buffer, 0xff, 512); - if (data) - { + if (data) { memcpy(page_buffer, data, thisrun_data_size); data_size -= thisrun_data_size; data += thisrun_data_size; } memset(oob_buffer, 0xff, 6); - if (oob) - { + if (oob) { memcpy(oob_buffer, oob, thisrun_oob_size); oob_size -= thisrun_oob_size; oob += thisrun_oob_size; @@ -586,16 +516,16 @@ static int lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t * target_write_u32(target, 0x200b8008, 0x0); target_write_memory(target, 0x200a8000, - 4, 128, page_buffer); + 4, 128, page_buffer); target_write_memory(target, 0x200a8000, - 1, 6, oob_buffer); + 1, 6, oob_buffer); /* write MLC_ECC_AUTO_ENC_REG to start auto encode */ target_write_u32(target, 0x200b8010, 0x0); - if (!lpc3180_controller_ready(nand, 1000)) - { - LOG_ERROR("timeout while waiting for completion of auto encode cycle"); + if (!lpc3180_controller_ready(nand, 1000)) { + LOG_ERROR( + "timeout while waiting for completion of auto encode cycle"); return ERROR_NAND_OPERATION_FAILED; } } @@ -603,291 +533,334 @@ static int lpc3180_write_page(struct nand_device *nand, uint32_t page, uint8_t * /* MLC_CMD = auto program command */ target_write_u32(target, 0x200b8000, NAND_CMD_PAGEPROG); - if ((retval = nand_read_status(nand, &status)) != ERROR_OK) - { + retval = nand_read_status(nand, &status); + if (retval != ERROR_OK) { LOG_ERROR("couldn't read status"); return ERROR_NAND_OPERATION_FAILED; } - if (status & NAND_STATUS_FAIL) - { + if (status & NAND_STATUS_FAIL) { LOG_ERROR("write operation didn't pass, status: 0x%2.2x", status); return ERROR_NAND_OPERATION_FAILED; } free(page_buffer); free(oob_buffer); - } - else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { - - /********************************************************************** - * Write both SLC NAND flash page main area and spare area. - * Small page - - * ------------------------------------------ - * | 512 bytes main | 16 bytes spare | - * ------------------------------------------ - * Large page - - * ------------------------------------------ - * | 2048 bytes main | 64 bytes spare | - * ------------------------------------------ - * If DMA & ECC enabled, then the ECC generated for the 1st 256-byte - * data is written to the 3rd word of the spare area. The ECC - * generated for the 2nd 256-byte data is written to the 4th word - * of the spare area. The ECC generated for the 3rd 256-byte data is - * written to the 7th word of the spare area. The ECC generated - * for the 4th 256-byte data is written to the 8th word of the - * spare area and so on. - * - **********************************************************************/ - - int i=0,target_mem_base; - uint8_t *ecc_flash_buffer; - struct working_area *pworking_area; - - - if(lpc3180_info->is_bulk){ - - if (!data && oob){ - /*if oob only mode is active original method is used as SLC controller hangs during DMA interworking. Anyway the code supports the oob only mode below. */ - return nand_write_page_raw(nand, page, data, data_size, oob, oob_size); - } - retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data); - if (ERROR_OK != retval) - return retval; - - /* allocate a working area */ - if (target->working_area_size < (uint32_t) nand->page_size + 0x200){ - LOG_ERROR("Reserve at least 0x%x physical target working area",nand->page_size + 0x200); - return ERROR_FLASH_OPERATION_FAILED; - } - if (target->working_area_phys%4){ - LOG_ERROR("Reserve the physical target working area at word boundary"); - return ERROR_FLASH_OPERATION_FAILED; - } - if (target_alloc_working_area(target, target->working_area_size, &pworking_area) != ERROR_OK) - { - LOG_ERROR("no working area specified, can't read LPC internal flash"); - return ERROR_FLASH_OPERATION_FAILED; - } - target_mem_base = target->working_area_phys; - - - if (nand->page_size == 2048) - { - page_buffer = malloc(2048); - } - else - { - page_buffer = malloc(512); - } - - ecc_flash_buffer = malloc(64); - - /* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst enabled, DMA write to SLC, WIDTH = bus_width) */ - target_write_u32(target, 0x20020014, 0x3c); - - if( data && !oob){ - /* set DMA LLI-s in target memory and in DMA*/ - for(i=0;i<nand->page_size/0x100;i++){ - - int tmp; - /* -------LLI for 256 byte block---------*/ - /* DMACC0SrcAddr = SRAM */ - target_write_u32(target,target_mem_base+0+i*32,target_mem_base+DATA_OFFS+i*256 ); - if(i==0) target_write_u32(target,0x31000100,target_mem_base+DATA_OFFS ); - /* DMACCxDestAddr = SLC_DMA_DATA */ - target_write_u32(target,target_mem_base+4+i*32,0x20020038 ); - if(i==0) target_write_u32(target,0x31000104,0x20020038 ); - /* DMACCxLLI = next element */ - tmp = (target_mem_base+(1+i*2)*16)&0xfffffffc; - target_write_u32(target,target_mem_base+8+i*32, tmp ); - if(i==0) target_write_u32(target,0x31000108, tmp ); - /* DMACCxControl = TransferSize =64, Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit, - Destination transfer width = 32 bit, Source AHB master select = M0, Destination AHB master select = M0, Source increment = 1, - Destination increment = 0, Terminal count interrupt enable bit = 0*/ - target_write_u32(target,target_mem_base+12+i*32,0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | 0<<27| 0<<31); - if(i==0) target_write_u32(target,0x3100010c,0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | 0<<27| 0<<31); - - /* -------LLI for 3 byte ECC---------*/ - /* DMACC0SrcAddr = SLC_ECC*/ - target_write_u32(target,target_mem_base+16+i*32,0x20020034 ); - /* DMACCxDestAddr = SRAM */ - target_write_u32(target,target_mem_base+20+i*32,target_mem_base+SPARE_OFFS+8+16*(i>>1)+(i%2)*4 ); - /* DMACCxLLI = next element */ - tmp = (target_mem_base+(2+i*2)*16)&0xfffffffc; - target_write_u32(target,target_mem_base+24+i*32, tmp ); - /* DMACCxControl = TransferSize =1, Source burst size =4, Destination burst size = 4, Source transfer width = 32 bit, - Destination transfer width = 32 bit, Source AHB master select = M0, Destination AHB master select = M0, Source increment = 0, - Destination increment = 1, Terminal count interrupt enable bit = 0*/ - target_write_u32(target,target_mem_base+28+i*32,0x01 | 1<<12 | 1<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27| 0<<31); - } - } - else if (data && oob){ - /* -------LLI for 512 or 2048 bytes page---------*/ - /* DMACC0SrcAddr = SRAM */ - target_write_u32(target,target_mem_base,target_mem_base+DATA_OFFS ); - target_write_u32(target,0x31000100,target_mem_base+DATA_OFFS ); - /* DMACCxDestAddr = SLC_DMA_DATA */ - target_write_u32(target,target_mem_base+4,0x20020038 ); - target_write_u32(target,0x31000104,0x20020038 ); - /* DMACCxLLI = next element */ - target_write_u32(target,target_mem_base+8, (target_mem_base+32)&0xfffffffc ); - target_write_u32(target,0x31000108, (target_mem_base+32)&0xfffffffc ); - /* DMACCxControl = TransferSize =512 or 128, Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit, - Destination transfer width = 32 bit, Source AHB master select = M0, Destination AHB master select = M0, Source increment = 1, - Destination increment = 0, Terminal count interrupt enable bit = 0*/ - target_write_u32(target,target_mem_base+12,(nand->page_size==2048?512:128) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | 0<<27| 0<<31); - target_write_u32(target,0x3100010c,(nand->page_size==2048?512:128) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | 0<<27| 0<<31); - i = 1; - } - else if (!data && oob){ - i = 0; - } - - /* -------LLI for spare area---------*/ - /* DMACC0SrcAddr = SRAM*/ - target_write_u32(target,target_mem_base+0+i*32,target_mem_base+SPARE_OFFS ); - if(i==0) target_write_u32(target,0x31000100,target_mem_base+SPARE_OFFS ); - /* DMACCxDestAddr = SLC_DMA_DATA */ - target_write_u32(target,target_mem_base+4+i*32,0x20020038 ); - if(i==0) target_write_u32(target,0x31000104,0x20020038 ); - /* DMACCxLLI = next element = NULL */ - target_write_u32(target,target_mem_base+8+i*32, 0 ); - if(i==0) target_write_u32(target,0x31000108,0 ); - /* DMACCxControl = TransferSize =16 for large page or 4 for small page, Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit, - Destination transfer width = 32 bit, Source AHB master select = M0, Destination AHB master select = M0, Source increment = 1, - Destination increment = 0, Terminal count interrupt enable bit = 0*/ - target_write_u32(target,target_mem_base+12+i*32, (nand->page_size==2048?0x10:0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | 0<<27| 0<<31); - if(i==0) target_write_u32(target,0x3100010c,(nand->page_size==2048?0x10:0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | 0<<27| 0<<31 ); - - - - memset(ecc_flash_buffer, 0xff, 64); - if( oob ){ - memcpy(ecc_flash_buffer,oob, oob_size); - } - target_write_memory(target, target_mem_base+SPARE_OFFS, 4, 16, ecc_flash_buffer); - - if (data){ - memset(page_buffer, 0xff, nand->page_size == 2048?2048:512); - memcpy(page_buffer,data, data_size); - target_write_memory(target, target_mem_base+DATA_OFFS, 4, nand->page_size == 2048?512:128, page_buffer); - } - - free(page_buffer); - free(ecc_flash_buffer); - - /* Enable DMA after channel set up ! - LLI only works when DMA is the flow controller! - */ - /* DMACCxConfig= E=1, SrcPeripheral = 1 (SLC), DestPeripheral = 1 (SLC), FlowCntrl = 2 (Pher -> Mem, DMA), IE = 0, ITC = 0, L= 0, H=0*/ - target_write_u32(target,0x31000110, 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 | 0<<15 | 0<<16 | 0<<18); - - - - /* SLC_CTRL = 3 (START DMA), ECC_CLEAR */ - target_write_u32(target, 0x20020010, 0x3); - - /* SLC_ICR = 2, INT_TC_CLR, clear pending TC*/ - target_write_u32(target, 0x20020028, 2); - - /* SLC_TC */ - if (!data && oob) - target_write_u32(target, 0x20020030, (nand->page_size==2048?0x10:0x04)); - else - target_write_u32(target, 0x20020030, (nand->page_size==2048?0x840:0x210)); - - nand_write_finish(nand); - - - if (!lpc3180_tc_ready(nand, 1000)) - { - LOG_ERROR("timeout while waiting for completion of DMA"); - return ERROR_NAND_OPERATION_FAILED; - } - - target_free_working_area(target,pworking_area); - - LOG_INFO("Page = 0x%" PRIx32 " was written.",page); - - } - else - return nand_write_page_raw(nand, page, data, data_size, oob, oob_size); - } + } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { + + /********************************************************************** + * Write both SLC NAND flash page main area and spare area. + * Small page - + * ------------------------------------------ + * | 512 bytes main | 16 bytes spare | + * ------------------------------------------ + * Large page - + * ------------------------------------------ + * | 2048 bytes main | 64 bytes spare | + * ------------------------------------------ + * If DMA & ECC enabled, then the ECC generated for the 1st 256-byte + * data is written to the 3rd word of the spare area. The ECC + * generated for the 2nd 256-byte data is written to the 4th word + * of the spare area. The ECC generated for the 3rd 256-byte data is + * written to the 7th word of the spare area. The ECC generated + * for the 4th 256-byte data is written to the 8th word of the + * spare area and so on. + * + **********************************************************************/ + + int i = 0, target_mem_base; + uint8_t *ecc_flash_buffer; + struct working_area *pworking_area; + + if (lpc3180_info->is_bulk) { + + if (!data && oob) { + /*if oob only mode is active original method is used as SLC + *controller hangs during DMA interworking. Anyway the code supports + *the oob only mode below. */ + return nand_write_page_raw(nand, + page, + data, + data_size, + oob, + oob_size); + } + retval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data); + if (ERROR_OK != retval) + return retval; + + /* allocate a working area */ + if (target->working_area_size < (uint32_t) nand->page_size + 0x200) { + LOG_ERROR("Reserve at least 0x%x physical target working area", + nand->page_size + 0x200); + return ERROR_FLASH_OPERATION_FAILED; + } + if (target->working_area_phys%4) { + LOG_ERROR( + "Reserve the physical target working area at word boundary"); + return ERROR_FLASH_OPERATION_FAILED; + } + if (target_alloc_working_area(target, target->working_area_size, + &pworking_area) != ERROR_OK) { + LOG_ERROR("no working area specified, can't read LPC internal flash"); + return ERROR_FLASH_OPERATION_FAILED; + } + target_mem_base = target->working_area_phys; + + if (nand->page_size == 2048) + page_buffer = malloc(2048); + else + page_buffer = malloc(512); + + ecc_flash_buffer = malloc(64); + + /* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst + *enabled, DMA write to SLC, WIDTH = bus_width) */ + target_write_u32(target, 0x20020014, 0x3c); + + if (data && !oob) { + /* set DMA LLI-s in target memory and in DMA*/ + for (i = 0; i < nand->page_size/0x100; i++) { + + int tmp; + /* -------LLI for 256 byte block--------- + * DMACC0SrcAddr = SRAM */ + target_write_u32(target, + target_mem_base+0+i*32, + target_mem_base+DATA_OFFS+i*256); + if (i == 0) + target_write_u32(target, + 0x31000100, + target_mem_base+DATA_OFFS); + /* DMACCxDestAddr = SLC_DMA_DATA */ + target_write_u32(target, target_mem_base+4+i*32, 0x20020038); + if (i == 0) + target_write_u32(target, 0x31000104, 0x20020038); + /* DMACCxLLI = next element */ + tmp = (target_mem_base+(1+i*2)*16)&0xfffffffc; + target_write_u32(target, target_mem_base+8+i*32, tmp); + if (i == 0) + target_write_u32(target, 0x31000108, tmp); + /* DMACCxControl = TransferSize =64, Source burst size =16, + * Destination burst size = 16, Source transfer width = 32 bit, + * Destination transfer width = 32 bit, Source AHB master select = M0, + * Destination AHB master select = M0, Source increment = 1, + * Destination increment = 0, Terminal count interrupt enable bit = 0*/ + target_write_u32(target, + target_mem_base+12+i*32, + 0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | + 0<<27 | 0<<31); + if (i == 0) + target_write_u32(target, + 0x3100010c, + 0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | + 0<<27 | 0<<31); + + /* -------LLI for 3 byte ECC--------- + * DMACC0SrcAddr = SLC_ECC*/ + target_write_u32(target, target_mem_base+16+i*32, 0x20020034); + /* DMACCxDestAddr = SRAM */ + target_write_u32(target, + target_mem_base+20+i*32, + target_mem_base+SPARE_OFFS+8+16*(i>>1)+(i%2)*4); + /* DMACCxLLI = next element */ + tmp = (target_mem_base+(2+i*2)*16)&0xfffffffc; + target_write_u32(target, target_mem_base+24+i*32, tmp); + /* DMACCxControl = TransferSize =1, Source burst size =4, + * Destination burst size = 4, Source transfer width = 32 bit, + * Destination transfer width = 32 bit, Source AHB master select = M0, + * Destination AHB master select = M0, Source increment = 0, + * Destination increment = 1, Terminal count interrupt enable bit = 0*/ + target_write_u32(target, + target_mem_base+28+i*32, + 0x01 | 1<<12 | 1<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<< + 31); + } + } else if (data && oob) { + /* -------LLI for 512 or 2048 bytes page--------- + * DMACC0SrcAddr = SRAM */ + target_write_u32(target, target_mem_base, target_mem_base+DATA_OFFS); + target_write_u32(target, 0x31000100, target_mem_base+DATA_OFFS); + /* DMACCxDestAddr = SLC_DMA_DATA */ + target_write_u32(target, target_mem_base+4, 0x20020038); + target_write_u32(target, 0x31000104, 0x20020038); + /* DMACCxLLI = next element */ + target_write_u32(target, + target_mem_base+8, + (target_mem_base+32)&0xfffffffc); + target_write_u32(target, 0x31000108, + (target_mem_base+32)&0xfffffffc); + /* DMACCxControl = TransferSize =512 or 128, Source burst size =16, + * Destination burst size = 16, Source transfer width = 32 bit, + * Destination transfer width = 32 bit, Source AHB master select = M0, + * Destination AHB master select = M0, Source increment = 1, + * Destination increment = 0, Terminal count interrupt enable bit = 0*/ + target_write_u32(target, + target_mem_base+12, + (nand->page_size == + 2048 ? 512 : 128) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | + 1<<26 | 0<<27 | 0<<31); + target_write_u32(target, + 0x3100010c, + (nand->page_size == + 2048 ? 512 : 128) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | + 1<<26 | 0<<27 | 0<<31); + i = 1; + } else if (!data && oob) + i = 0; + + /* -------LLI for spare area--------- + * DMACC0SrcAddr = SRAM*/ + target_write_u32(target, target_mem_base+0+i*32, target_mem_base+SPARE_OFFS); + if (i == 0) + target_write_u32(target, 0x31000100, target_mem_base+SPARE_OFFS); + /* DMACCxDestAddr = SLC_DMA_DATA */ + target_write_u32(target, target_mem_base+4+i*32, 0x20020038); + if (i == 0) + target_write_u32(target, 0x31000104, 0x20020038); + /* DMACCxLLI = next element = NULL */ + target_write_u32(target, target_mem_base+8+i*32, 0); + if (i == 0) + target_write_u32(target, 0x31000108, 0); + /* DMACCxControl = TransferSize =16 for large page or 4 for small page, + * Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit, + * Destination transfer width = 32 bit, Source AHB master select = M0, + * Destination AHB master select = M0, Source increment = 1, + * Destination increment = 0, Terminal count interrupt enable bit = 0*/ + target_write_u32(target, + target_mem_base+12+i*32, + (nand->page_size == + 2048 ? 0x10 : 0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 | + 0<<27 | 0<<31); + if (i == 0) + target_write_u32(target, 0x3100010c, + (nand->page_size == 2048 ? + 0x10 : 0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | + 0<<25 | 1<<26 | 0<<27 | 0<<31); + + memset(ecc_flash_buffer, 0xff, 64); + if (oob) + memcpy(ecc_flash_buffer, oob, oob_size); + target_write_memory(target, + target_mem_base+SPARE_OFFS, + 4, + 16, + ecc_flash_buffer); + + if (data) { + memset(page_buffer, 0xff, nand->page_size == 2048 ? 2048 : 512); + memcpy(page_buffer, data, data_size); + target_write_memory(target, + target_mem_base+DATA_OFFS, + 4, + nand->page_size == 2048 ? 512 : 128, + page_buffer); + } + + free(page_buffer); + free(ecc_flash_buffer); + + /* Enable DMA after channel set up ! + LLI only works when DMA is the flow controller! + */ + /* DMACCxConfig= E=1, SrcPeripheral = 1 (SLC), DestPeripheral = 1 (SLC), + *FlowCntrl = 2 (Pher -> Mem, DMA), IE = 0, ITC = 0, L= 0, H=0*/ + target_write_u32(target, + 0x31000110, + 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 | 0<<15 | 0<<16 | 0<<18); + /* SLC_CTRL = 3 (START DMA), ECC_CLEAR */ + target_write_u32(target, 0x20020010, 0x3); + + /* SLC_ICR = 2, INT_TC_CLR, clear pending TC*/ + target_write_u32(target, 0x20020028, 2); + + /* SLC_TC */ + if (!data && oob) + target_write_u32(target, 0x20020030, + (nand->page_size == 2048 ? 0x10 : 0x04)); + else + target_write_u32(target, 0x20020030, + (nand->page_size == 2048 ? 0x840 : 0x210)); + + nand_write_finish(nand); + + if (!lpc3180_tc_ready(nand, 1000)) { + LOG_ERROR("timeout while waiting for completion of DMA"); + return ERROR_NAND_OPERATION_FAILED; + } + + target_free_working_area(target, pworking_area); + + LOG_INFO("Page = 0x%" PRIx32 " was written.", page); + + } else + return nand_write_page_raw(nand, page, data, data_size, oob, oob_size); + } return ERROR_OK; } -static int lpc3180_read_page(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size) +static int lpc3180_read_page(struct nand_device *nand, + uint32_t page, + uint8_t *data, + uint32_t data_size, + uint8_t *oob, + uint32_t oob_size) { struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; uint8_t *page_buffer; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } - if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) - { + if (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) { LOG_ERROR("BUG: no LPC3180 NAND flash controller selected"); return ERROR_NAND_OPERATION_FAILED; - } - else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { uint8_t *oob_buffer; uint32_t page_bytes_done = 0; uint32_t oob_bytes_done = 0; uint32_t mlc_isr; #if 0 - if (oob && (oob_size > 6)) - { + if (oob && (oob_size > 6)) { LOG_ERROR("LPC3180 MLC controller can't read more than 6 bytes of OOB data"); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } #endif - if (data_size > (uint32_t)nand->page_size) - { + if (data_size > (uint32_t)nand->page_size) { LOG_ERROR("data size exceeds page size"); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } - if (nand->page_size == 2048) - { + if (nand->page_size == 2048) { page_buffer = malloc(2048); oob_buffer = malloc(64); - } - else - { + } else { page_buffer = malloc(512); oob_buffer = malloc(16); } - if (!data && oob) - { + if (!data && oob) { /* MLC_CMD = Read OOB * we can use the READOOB command on both small and large page devices, * as the controller translates the 0x50 command to a 0x0 with appropriate * positioning of the serial buffer read pointer */ target_write_u32(target, 0x200b8000, NAND_CMD_READOOB); - } - else - { + } else { /* MLC_CMD = Read0 */ target_write_u32(target, 0x200b8000, NAND_CMD_READ0); } - if (nand->page_size == 512) - { - /* small page device */ - /* MLC_ADDR = 0x0 (one column cycle) */ + if (nand->page_size == 512) { + /* small page device + * MLC_ADDR = 0x0 (one column cycle) */ target_write_u32(target, 0x200b8004, 0x0); /* MLC_ADDR = row */ @@ -896,11 +869,9 @@ static int lpc3180_read_page(struct nand_device *nand, uint32_t page, uint8_t *d if (nand->address_cycles == 4) target_write_u32(target, 0x200b8004, (page >> 16) & 0xff); - } - else - { - /* large page device */ - /* MLC_ADDR = 0x0 (two column cycles) */ + } else { + /* large page device + * MLC_ADDR = 0x0 (two column cycles) */ target_write_u32(target, 0x200b8004, 0x0); target_write_u32(target, 0x200b8004, 0x0); @@ -912,39 +883,42 @@ static int lpc3180_read_page(struct nand_device *nand, uint32_t page, uint8_t *d target_write_u32(target, 0x200b8000, NAND_CMD_READSTART); } - while (page_bytes_done < (uint32_t)nand->page_size) - { + while (page_bytes_done < (uint32_t)nand->page_size) { /* MLC_ECC_AUTO_DEC_REG = dummy */ target_write_u32(target, 0x200b8014, 0xaa55aa55); - if (!lpc3180_controller_ready(nand, 1000)) - { - LOG_ERROR("timeout while waiting for completion of auto decode cycle"); + if (!lpc3180_controller_ready(nand, 1000)) { + LOG_ERROR( + "timeout while waiting for completion of auto decode cycle"); return ERROR_NAND_OPERATION_FAILED; } target_read_u32(target, 0x200b8048, &mlc_isr); - if (mlc_isr & 0x8) - { - if (mlc_isr & 0x40) - { - LOG_ERROR("uncorrectable error detected: 0x%2.2x", (unsigned)mlc_isr); + if (mlc_isr & 0x8) { + if (mlc_isr & 0x40) { + LOG_ERROR("uncorrectable error detected: 0x%2.2x", + (unsigned)mlc_isr); return ERROR_NAND_OPERATION_FAILED; } - LOG_WARNING("%i symbol error detected and corrected", ((int)(((mlc_isr & 0x30) >> 4) + 1))); + LOG_WARNING("%i symbol error detected and corrected", + ((int)(((mlc_isr & 0x30) >> 4) + 1))); } if (data) - { - target_read_memory(target, 0x200a8000, 4, 128, page_buffer + page_bytes_done); - } + target_read_memory(target, + 0x200a8000, + 4, + 128, + page_buffer + page_bytes_done); if (oob) - { - target_read_memory(target, 0x200a8000, 4, 4, oob_buffer + oob_bytes_done); - } + target_read_memory(target, + 0x200a8000, + 4, + 4, + oob_buffer + oob_bytes_done); page_bytes_done += 512; oob_bytes_done += 16; @@ -958,178 +932,221 @@ static int lpc3180_read_page(struct nand_device *nand, uint32_t page, uint8_t *d free(page_buffer); free(oob_buffer); - } - else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { + + /********************************************************************** + * Read both SLC NAND flash page main area and spare area. + * Small page - + * ------------------------------------------ + * | 512 bytes main | 16 bytes spare | + * ------------------------------------------ + * Large page - + * ------------------------------------------ + * | 2048 bytes main | 64 bytes spare | + * ------------------------------------------ + * If DMA & ECC enabled, then the ECC generated for the 1st 256-byte + * data is compared with the 3rd word of the spare area. The ECC + * generated for the 2nd 256-byte data is compared with the 4th word + * of the spare area. The ECC generated for the 3rd 256-byte data is + * compared with the 7th word of the spare area. The ECC generated + * for the 4th 256-byte data is compared with the 8th word of the + * spare area and so on. + * + **********************************************************************/ + + int retval, i, target_mem_base; + uint8_t *ecc_hw_buffer; + uint8_t *ecc_flash_buffer; + struct working_area *pworking_area; + + if (lpc3180_info->is_bulk) { + + /* read always the data and also oob areas*/ + + retval = nand_page_command(nand, page, NAND_CMD_READ0, 0); + if (ERROR_OK != retval) + return retval; + + /* allocate a working area */ + if (target->working_area_size < (uint32_t) nand->page_size + 0x200) { + LOG_ERROR("Reserve at least 0x%x physical target working area", + nand->page_size + 0x200); + return ERROR_FLASH_OPERATION_FAILED; + } + if (target->working_area_phys%4) { + LOG_ERROR( + "Reserve the physical target working area at word boundary"); + return ERROR_FLASH_OPERATION_FAILED; + } + if (target_alloc_working_area(target, target->working_area_size, + &pworking_area) != ERROR_OK) { + LOG_ERROR("no working area specified, can't read LPC internal flash"); + return ERROR_FLASH_OPERATION_FAILED; + } + target_mem_base = target->working_area_phys; + + if (nand->page_size == 2048) + page_buffer = malloc(2048); + else + page_buffer = malloc(512); + + ecc_hw_buffer = malloc(32); + ecc_flash_buffer = malloc(64); + + /* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst + *enabled, DMA read from SLC, WIDTH = bus_width) */ + target_write_u32(target, 0x20020014, 0x3e); + + /* set DMA LLI-s in target memory and in DMA*/ + for (i = 0; i < nand->page_size/0x100; i++) { + int tmp; + /* -------LLI for 256 byte block--------- + * DMACC0SrcAddr = SLC_DMA_DATA*/ + target_write_u32(target, target_mem_base+0+i*32, 0x20020038); + if (i == 0) + target_write_u32(target, 0x31000100, 0x20020038); + /* DMACCxDestAddr = SRAM */ + target_write_u32(target, + target_mem_base+4+i*32, + target_mem_base+DATA_OFFS+i*256); + if (i == 0) + target_write_u32(target, + 0x31000104, + target_mem_base+DATA_OFFS); + /* DMACCxLLI = next element */ + tmp = (target_mem_base+(1+i*2)*16)&0xfffffffc; + target_write_u32(target, target_mem_base+8+i*32, tmp); + if (i == 0) + target_write_u32(target, 0x31000108, tmp); + /* DMACCxControl = TransferSize =64, Source burst size =16, + * Destination burst size = 16, Source transfer width = 32 bit, + * Destination transfer width = 32 bit, Source AHB master select = M0, + * Destination AHB master select = M0, Source increment = 0, + * Destination increment = 1, Terminal count interrupt enable bit = 0*/ + target_write_u32(target, + target_mem_base+12+i*32, + 0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<< + 31); + if (i == 0) + target_write_u32(target, + 0x3100010c, + 0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<< + 31); + + /* -------LLI for 3 byte ECC--------- + * DMACC0SrcAddr = SLC_ECC*/ + target_write_u32(target, target_mem_base+16+i*32, 0x20020034); + /* DMACCxDestAddr = SRAM */ + target_write_u32(target, + target_mem_base+20+i*32, + target_mem_base+ECC_OFFS+i*4); + /* DMACCxLLI = next element */ + tmp = (target_mem_base+(2+i*2)*16)&0xfffffffc; + target_write_u32(target, target_mem_base+24+i*32, tmp); + /* DMACCxControl = TransferSize =1, Source burst size =4, + * Destination burst size = 4, Source transfer width = 32 bit, + * Destination transfer width = 32 bit, Source AHB master select = M0, + * Destination AHB master select = M0, Source increment = 0, + * Destination increment = 1, Terminal count interrupt enable bit = 0*/ + target_write_u32(target, + target_mem_base+28+i*32, + 0x01 | 1<<12 | 1<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<< + 31); + } + + /* -------LLI for spare area--------- + * DMACC0SrcAddr = SLC_DMA_DATA*/ + target_write_u32(target, target_mem_base+0+i*32, 0x20020038); + /* DMACCxDestAddr = SRAM */ + target_write_u32(target, target_mem_base+4+i*32, target_mem_base+SPARE_OFFS); + /* DMACCxLLI = next element = NULL */ + target_write_u32(target, target_mem_base+8+i*32, 0); + /* DMACCxControl = TransferSize =16 for large page or 4 for small page, + * Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit, + * Destination transfer width = 32 bit, Source AHB master select = M0, + * Destination AHB master select = M0, Source increment = 0, + * Destination increment = 1, Terminal count interrupt enable bit = 0*/ + target_write_u32(target, + target_mem_base + 12 + i * 32, + (nand->page_size == 2048 ? 0x10 : 0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | + 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<<31); + + /* Enable DMA after channel set up ! + LLI only works when DMA is the flow controller! + */ + /* DMACCxConfig= E=1, SrcPeripheral = 1 (SLC), DestPeripheral = 1 (SLC), + *FlowCntrl = 2 (Pher-> Mem, DMA), IE = 0, ITC = 0, L= 0, H=0*/ + target_write_u32(target, + 0x31000110, + 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 | 0<<15 | 0<<16 | 0<<18); + + /* SLC_CTRL = 3 (START DMA), ECC_CLEAR */ + target_write_u32(target, 0x20020010, 0x3); + + /* SLC_ICR = 2, INT_TC_CLR, clear pending TC*/ + target_write_u32(target, 0x20020028, 2); + + /* SLC_TC */ + target_write_u32(target, 0x20020030, + (nand->page_size == 2048 ? 0x840 : 0x210)); + + if (!lpc3180_tc_ready(nand, 1000)) { + LOG_ERROR("timeout while waiting for completion of DMA"); + free(page_buffer); + free(ecc_hw_buffer); + free(ecc_flash_buffer); + target_free_working_area(target, pworking_area); + return ERROR_NAND_OPERATION_FAILED; + } + + if (data) { + target_read_memory(target, + target_mem_base+DATA_OFFS, + 4, + nand->page_size == 2048 ? 512 : 128, + page_buffer); + memcpy(data, page_buffer, data_size); + + LOG_INFO("Page = 0x%" PRIx32 " was read.", page); + + /* check hw generated ECC for each 256 bytes block with the saved + *ECC in flash spare area*/ + int idx = nand->page_size/0x200; + target_read_memory(target, + target_mem_base+SPARE_OFFS, + 4, + 16, + ecc_flash_buffer); + target_read_memory(target, + target_mem_base+ECC_OFFS, + 4, + 8, + ecc_hw_buffer); + for (i = 0; i < idx; i++) { + if ((0x00ffffff & *(uint32_t *)(void *)(ecc_hw_buffer+i*8)) != + (0x00ffffff & *(uint32_t *)(void *)(ecc_flash_buffer+8+i*16))) + LOG_WARNING( + "ECC mismatch at 256 bytes size block= %d at page= 0x%" PRIx32, + i * 2 + 1, page); + if ((0x00ffffff & *(uint32_t *)(void *)(ecc_hw_buffer+4+i*8)) != + (0x00ffffff & *(uint32_t *)(void *)(ecc_flash_buffer+12+i*16))) + LOG_WARNING( + "ECC mismatch at 256 bytes size block= %d at page= 0x%" PRIx32, + i * 2 + 2, page); + } + } + + if (oob) + memcpy(oob, ecc_flash_buffer, oob_size); - /********************************************************************** - * Read both SLC NAND flash page main area and spare area. - * Small page - - * ------------------------------------------ - * | 512 bytes main | 16 bytes spare | - * ------------------------------------------ - * Large page - - * ------------------------------------------ - * | 2048 bytes main | 64 bytes spare | - * ------------------------------------------ - * If DMA & ECC enabled, then the ECC generated for the 1st 256-byte - * data is compared with the 3rd word of the spare area. The ECC - * generated for the 2nd 256-byte data is compared with the 4th word - * of the spare area. The ECC generated for the 3rd 256-byte data is - * compared with the 7th word of the spare area. The ECC generated - * for the 4th 256-byte data is compared with the 8th word of the - * spare area and so on. - * - **********************************************************************/ - - int retval,i,target_mem_base; - uint8_t *ecc_hw_buffer; - uint8_t *ecc_flash_buffer; - struct working_area *pworking_area; - - if(lpc3180_info->is_bulk){ - - /* read always the data and also oob areas*/ - - retval = nand_page_command(nand, page, NAND_CMD_READ0, 0); - if (ERROR_OK != retval) - return retval; - - /* allocate a working area */ - if (target->working_area_size < (uint32_t) nand->page_size + 0x200){ - LOG_ERROR("Reserve at least 0x%x physical target working area",nand->page_size + 0x200); - return ERROR_FLASH_OPERATION_FAILED; - } - if (target->working_area_phys%4){ - LOG_ERROR("Reserve the physical target working area at word boundary"); - return ERROR_FLASH_OPERATION_FAILED; - } - if (target_alloc_working_area(target, target->working_area_size, &pworking_area) != ERROR_OK) - { - LOG_ERROR("no working area specified, can't read LPC internal flash"); - return ERROR_FLASH_OPERATION_FAILED; - } - target_mem_base = target->working_area_phys; - - if (nand->page_size == 2048) - { - page_buffer = malloc(2048); - } - else - { - page_buffer = malloc(512); - } - - ecc_hw_buffer = malloc(32); - ecc_flash_buffer = malloc(64); - - /* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst enabled, DMA read from SLC, WIDTH = bus_width) */ - target_write_u32(target, 0x20020014, 0x3e); - - /* set DMA LLI-s in target memory and in DMA*/ - for(i=0;i<nand->page_size/0x100;i++){ - int tmp; - /* -------LLI for 256 byte block---------*/ - /* DMACC0SrcAddr = SLC_DMA_DATA*/ - target_write_u32(target,target_mem_base+0+i*32,0x20020038 ); - if(i==0) target_write_u32(target,0x31000100,0x20020038 ); - /* DMACCxDestAddr = SRAM */ - target_write_u32(target,target_mem_base+4+i*32,target_mem_base+DATA_OFFS+i*256 ); - if(i==0) target_write_u32(target,0x31000104,target_mem_base+DATA_OFFS ); - /* DMACCxLLI = next element */ - tmp = (target_mem_base+(1+i*2)*16)&0xfffffffc; - target_write_u32(target,target_mem_base+8+i*32, tmp ); - if(i==0) target_write_u32(target,0x31000108, tmp ); - /* DMACCxControl = TransferSize =64, Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit, - Destination transfer width = 32 bit, Source AHB master select = M0, Destination AHB master select = M0, Source increment = 0, - Destination increment = 1, Terminal count interrupt enable bit = 0*/ - target_write_u32(target,target_mem_base+12+i*32,0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27| 0<<31); - if(i==0) target_write_u32(target,0x3100010c,0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27| 0<<31); - - /* -------LLI for 3 byte ECC---------*/ - /* DMACC0SrcAddr = SLC_ECC*/ - target_write_u32(target,target_mem_base+16+i*32,0x20020034 ); - /* DMACCxDestAddr = SRAM */ - target_write_u32(target,target_mem_base+20+i*32,target_mem_base+ECC_OFFS+i*4 ); - /* DMACCxLLI = next element */ - tmp = (target_mem_base+(2+i*2)*16)&0xfffffffc; - target_write_u32(target,target_mem_base+24+i*32, tmp ); - /* DMACCxControl = TransferSize =1, Source burst size =4, Destination burst size = 4, Source transfer width = 32 bit, - Destination transfer width = 32 bit, Source AHB master select = M0, Destination AHB master select = M0, Source increment = 0, - Destination increment = 1, Terminal count interrupt enable bit = 0*/ - target_write_u32(target,target_mem_base+28+i*32,0x01 | 1<<12 | 1<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27| 0<<31); - - - } - - /* -------LLI for spare area---------*/ - /* DMACC0SrcAddr = SLC_DMA_DATA*/ - target_write_u32(target,target_mem_base+0+i*32,0x20020038 ); - /* DMACCxDestAddr = SRAM */ - target_write_u32(target,target_mem_base+4+i*32,target_mem_base+SPARE_OFFS ); - /* DMACCxLLI = next element = NULL */ - target_write_u32(target,target_mem_base+8+i*32, 0 ); - /* DMACCxControl = TransferSize =16 for large page or 4 for small page, Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit, - Destination transfer width = 32 bit, Source AHB master select = M0, Destination AHB master select = M0, Source increment = 0, - Destination increment = 1, Terminal count interrupt enable bit = 0*/ - target_write_u32(target,target_mem_base+12+i*32, (nand->page_size==2048?0x10:0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27| 0<<31); - - /* Enable DMA after channel set up ! - LLI only works when DMA is the flow controller! - */ - /* DMACCxConfig= E=1, SrcPeripheral = 1 (SLC), DestPeripheral = 1 (SLC), FlowCntrl = 2 (Pher-> Mem, DMA), IE = 0, ITC = 0, L= 0, H=0*/ - target_write_u32(target,0x31000110, 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 | 0<<15 | 0<<16 | 0<<18); - - - /* SLC_CTRL = 3 (START DMA), ECC_CLEAR */ - target_write_u32(target, 0x20020010, 0x3); - - /* SLC_ICR = 2, INT_TC_CLR, clear pending TC*/ - target_write_u32(target, 0x20020028, 2); - - /* SLC_TC */ - target_write_u32(target, 0x20020030, (nand->page_size==2048?0x840:0x210)); - - if (!lpc3180_tc_ready(nand, 1000)) - { - LOG_ERROR("timeout while waiting for completion of DMA"); - free(page_buffer); - free(ecc_hw_buffer); - free(ecc_flash_buffer); - target_free_working_area(target,pworking_area); - return ERROR_NAND_OPERATION_FAILED; - } - - if (data){ - target_read_memory(target, target_mem_base+DATA_OFFS, 4, nand->page_size == 2048?512:128, page_buffer); - memcpy(data, page_buffer, data_size); - - LOG_INFO("Page = 0x%" PRIx32 " was read.",page); - - /* check hw generated ECC for each 256 bytes block with the saved ECC in flash spare area*/ - int idx = nand->page_size/0x200 ; - target_read_memory(target, target_mem_base+SPARE_OFFS, 4, 16, ecc_flash_buffer); - target_read_memory(target, target_mem_base+ECC_OFFS, 4, 8, ecc_hw_buffer); - for(i=0;i<idx;i++){ - if( (0x00ffffff&*(uint32_t *)(void *)(ecc_hw_buffer+i*8)) != (0x00ffffff&*(uint32_t *)(void *)(ecc_flash_buffer+8+i*16)) ) - LOG_WARNING("ECC mismatch at 256 bytes size block= %d at page= 0x%" PRIx32,i*2+1,page); - if( (0x00ffffff&*(uint32_t *)(void *)(ecc_hw_buffer+4+i*8)) != (0x00ffffff&*(uint32_t *)(void *)(ecc_flash_buffer+12+i*16)) ) - LOG_WARNING("ECC mismatch at 256 bytes size block= %d at page= 0x%" PRIx32,i*2+2,page); - } - } - - if (oob) - memcpy(oob, ecc_flash_buffer, oob_size); - - free(page_buffer); - free(ecc_hw_buffer); - free(ecc_flash_buffer); - - target_free_working_area(target,pworking_area); - - } - else - return nand_read_page_raw(nand, page, data, data_size, oob, oob_size); + free(page_buffer); + free(ecc_hw_buffer); + free(ecc_flash_buffer); + + target_free_working_area(target, pworking_area); + + } else + return nand_read_page_raw(nand, page, data, data_size, oob, oob_size); } return ERROR_OK; @@ -1140,18 +1157,15 @@ static int lpc3180_controller_ready(struct nand_device *nand, int timeout) struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } LOG_DEBUG("lpc3180_controller_ready count start=%d", timeout); - do - { - if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - { + do { + if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { uint8_t status; /* Read MLC_ISR, wait for controller to become ready */ @@ -1159,12 +1173,10 @@ static int lpc3180_controller_ready(struct nand_device *nand, int timeout) if (status & 2) { LOG_DEBUG("lpc3180_controller_ready count=%d", - timeout); + timeout); return 1; } - } - else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { uint32_t status; /* Read SLC_STAT and check READY bit */ @@ -1172,7 +1184,7 @@ static int lpc3180_controller_ready(struct nand_device *nand, int timeout) if (status & 1) { LOG_DEBUG("lpc3180_controller_ready count=%d", - timeout); + timeout); return 1; } } @@ -1188,18 +1200,15 @@ static int lpc3180_nand_ready(struct nand_device *nand, int timeout) struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } LOG_DEBUG("lpc3180_nand_ready count start=%d", timeout); - do - { - if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - { + do { + if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) { uint8_t status = 0x0; /* Read MLC_ISR, wait for NAND flash device to become ready */ @@ -1207,12 +1216,10 @@ static int lpc3180_nand_ready(struct nand_device *nand, int timeout) if (status & 1) { LOG_DEBUG("lpc3180_nand_ready count end=%d", - timeout); + timeout); return 1; } - } - else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { + } else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { uint32_t status = 0x0; /* Read SLC_STAT and check READY bit */ @@ -1220,7 +1227,7 @@ static int lpc3180_nand_ready(struct nand_device *nand, int timeout) if (status & 1) { LOG_DEBUG("lpc3180_nand_ready count end=%d", - timeout); + timeout); return 1; } } @@ -1236,28 +1243,25 @@ static int lpc3180_tc_ready(struct nand_device *nand, int timeout) struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; - if (target->state != TARGET_HALTED) - { + if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } - LOG_DEBUG("lpc3180_tc_ready count start=%d", - timeout); + LOG_DEBUG("lpc3180_tc_ready count start=%d", + timeout); - do - { - if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) - { - uint32_t status = 0x0; + do { + if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) { + uint32_t status = 0x0; /* Read SLC_INT_STAT and check INT_TC_STAT bit */ target_read_u32(target, 0x2002001c, &status); - if (status & 2){ - LOG_DEBUG("lpc3180_tc_ready count=%d", - timeout); - return 1; - } + if (status & 2) { + LOG_DEBUG("lpc3180_tc_ready count=%d", + timeout); + return 1; + } } alive_sleep(1); @@ -1266,59 +1270,47 @@ static int lpc3180_tc_ready(struct nand_device *nand, int timeout) return 0; } - COMMAND_HANDLER(handle_lpc3180_select_command) { struct lpc3180_nand_controller *lpc3180_info = NULL; - char *selected[] = - { + char *selected[] = { "no", "mlc", "slc" }; if ((CMD_ARGC < 1) || (CMD_ARGC > 3)) - { return ERROR_COMMAND_SYNTAX_ERROR; - } unsigned num; COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); struct nand_device *nand = get_nand_device_by_num(num); - if (!nand) - { + if (!nand) { command_print(CMD_CTX, "nand device '#%s' is out of bounds", CMD_ARGV[0]); return ERROR_OK; } lpc3180_info = nand->controller_priv; - if (CMD_ARGC >= 2) - { + if (CMD_ARGC >= 2) { if (strcmp(CMD_ARGV[1], "mlc") == 0) - { lpc3180_info->selected_controller = LPC3180_MLC_CONTROLLER; - } - else if (strcmp(CMD_ARGV[1], "slc") == 0) - { + else if (strcmp(CMD_ARGV[1], "slc") == 0) { lpc3180_info->selected_controller = LPC3180_SLC_CONTROLLER; - if (CMD_ARGC == 3 && strcmp(CMD_ARGV[2], "bulk") == 0){ - lpc3180_info->is_bulk = 1; - } - else{ - lpc3180_info->is_bulk = 0; - } - } - else - { + if (CMD_ARGC == 3 && strcmp(CMD_ARGV[2], "bulk") == 0) + lpc3180_info->is_bulk = 1; + else + lpc3180_info->is_bulk = 0; + } else return ERROR_COMMAND_SYNTAX_ERROR; - } } - if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) - command_print(CMD_CTX, "%s controller selected", selected[lpc3180_info->selected_controller]); - else{ - command_print(CMD_CTX, lpc3180_info->is_bulk?"%s controller selected bulk mode is available":"%s controller selected bulk mode is not available", selected[lpc3180_info->selected_controller]); - } - + if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) + command_print(CMD_CTX, "%s controller selected", + selected[lpc3180_info->selected_controller]); + else + command_print(CMD_CTX, + lpc3180_info->is_bulk ? "%s controller selected bulk mode is available" : + "%s controller selected bulk mode is not available", + selected[lpc3180_info->selected_controller]); return ERROR_OK; } @@ -1328,7 +1320,8 @@ static const struct command_registration lpc3180_exec_command_handlers[] = { .name = "select", .handler = handle_lpc3180_select_command, .mode = COMMAND_EXEC, - .help = "select MLC or SLC controller (default is MLC), SLC can be set to bulk mode", + .help = + "select MLC or SLC controller (default is MLC), SLC can be set to bulk mode", .usage = "bank_id ['mlc'|'slc' ['bulk'] ]", }, COMMAND_REGISTRATION_DONE diff --git a/src/flash/nand/lpc3180.h b/src/flash/nand/lpc3180.h index d524cfe..8c07de6 100644 --- a/src/flash/nand/lpc3180.h +++ b/src/flash/nand/lpc3180.h @@ -17,18 +17,17 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifndef LPC3180_NAND_CONTROLLER_H #define LPC3180_NAND_CONTROLLER_H -enum lpc3180_selected_controller -{ +enum lpc3180_selected_controller { LPC3180_NO_CONTROLLER, LPC3180_MLC_CONTROLLER, LPC3180_SLC_CONTROLLER, }; -struct lpc3180_nand_controller -{ +struct lpc3180_nand_controller { int osc_freq; enum lpc3180_selected_controller selected_controller; int is_bulk; @@ -37,4 +36,4 @@ struct lpc3180_nand_controller uint32_t sw_wp_upper_bound; }; -#endif /*LPC3180_NAND_CONTROLLER_H */ +#endif /*LPC3180_NAND_CONTROLLER_H */ diff --git a/src/flash/nand/lpc32xx.c b/src/flash/nand/lpc32xx.c index f6ac8ff..932a0d5 100644 --- a/src/flash/nand/lpc32xx.c +++ b/src/flash/nand/lpc32xx.c @@ -25,6 +25,7 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -37,7 +38,7 @@ static int lpc32xx_reset(struct nand_device *nand); static int lpc32xx_controller_ready(struct nand_device *nand, int timeout); static int lpc32xx_tc_ready(struct nand_device *nand, int timeout); extern int nand_correct_data(struct nand_device *nand, u_char *dat, - u_char *read_ecc, u_char *calc_ecc); + u_char *read_ecc, u_char *calc_ecc); /* These are offset with the working area in IRAM when using DMA to * read/write data to the SLC controller. @@ -74,9 +75,8 @@ static dmac_ll_t dmalist[(2048/256) * 2 + 1]; */ NAND_DEVICE_COMMAND_HANDLER(lpc32xx_nand_device_command) { - if (CMD_ARGC < 3) { + if (CMD_ARGC < 3) return ERROR_COMMAND_SYNTAX_ERROR; - } uint32_t osc_freq; COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], osc_freq); @@ -89,8 +89,8 @@ NAND_DEVICE_COMMAND_HANDLER(lpc32xx_nand_device_command) if ((lpc32xx_info->osc_freq < 1000) || (lpc32xx_info->osc_freq > 20000)) LOG_WARNING("LPC32xx oscillator frequency should be between " - "1000 and 20000 kHz, was %i", - lpc32xx_info->osc_freq); + "1000 and 20000 kHz, was %i", + lpc32xx_info->osc_freq); lpc32xx_info->selected_controller = LPC32xx_NO_CONTROLLER; lpc32xx_info->sw_write_protection = 0; @@ -113,18 +113,18 @@ static int lpc32xx_pll(int fclkin, uint32_t pll_ctrl) if (!lock) LOG_WARNING("PLL is not locked"); - if (!bypass && direct) /* direct mode */ + if (!bypass && direct) /* direct mode */ return (m * fclkin) / n; - if (bypass && !direct) /* bypass mode */ + if (bypass && !direct) /* bypass mode */ return fclkin / (2 * p); - if (bypass & direct) /* direct bypass mode */ + if (bypass & direct) /* direct bypass mode */ return fclkin; - if (feedback) /* integer mode */ + if (feedback) /* integer mode */ return m * (fclkin / n); - else /* non-integer mode */ + else /* non-integer mode */ return (m / (2 * p)) * (fclkin / n); } @@ -160,9 +160,9 @@ static float lpc32xx_cycle_time(struct nand_device *nand) return ERROR_NAND_OPERATION_FAILED; } - if ((pwr_ctrl & (1 << 2)) == 0) { /* DIRECT RUN mode */ + if ((pwr_ctrl & (1 << 2)) == 0) /* DIRECT RUN mode */ hclk = sysclk; - } else { + else { retval = target_read_u32(target, 0x40004058, &hclkpll_ctrl); if (ERROR_OK != retval) { LOG_ERROR("could not read HCLKPLL_CTRL"); @@ -176,9 +176,9 @@ static float lpc32xx_cycle_time(struct nand_device *nand) return ERROR_NAND_OPERATION_FAILED; } - if (pwr_ctrl & (1 << 10)) /* ARM_CLK and HCLK use PERIPH_CLK */ + if (pwr_ctrl & (1 << 10)) /* ARM_CLK and HCLK use PERIPH_CLK */ hclk = hclk_pll / (((hclkdiv_ctrl & 0x7c) >> 2) + 1); - else /* HCLK uses HCLK_PLL */ + else /* HCLK uses HCLK_PLL */ hclk = hclk_pll / (1 << (hclkdiv_ctrl & 0x3)); } @@ -200,7 +200,7 @@ static int lpc32xx_init(struct nand_device *nand) if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); + "NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } @@ -226,7 +226,7 @@ static int lpc32xx_init(struct nand_device *nand) /* select MLC controller if none is currently selected */ if (lpc32xx_info->selected_controller == LPC32xx_NO_CONTROLLER) { LOG_DEBUG("no LPC32xx NAND flash controller selected, " - "using default 'slc'"); + "using default 'slc'"); lpc32xx_info->selected_controller = LPC32xx_SLC_CONTROLLER; } @@ -291,13 +291,13 @@ static int lpc32xx_init(struct nand_device *nand) /* MLC_TIME_REG */ retval = target_write_u32(target, 0x200b8034, - (twp & 0xf) - | ((twh & 0xf) << 4) - | ((trp & 0xf) << 8) - | ((treh & 0xf) << 12) - | ((trhz & 0x7) << 16) - | ((trbwb & 0x1f) << 19) - | ((tcea & 0x3) << 24)); + (twp & 0xf) + | ((twh & 0xf) << 4) + | ((trp & 0xf) << 8) + | ((treh & 0xf) << 12) + | ((trhz & 0x7) << 16) + | ((trbwb & 0x1f) << 19) + | ((tcea & 0x3) << 24)); if (ERROR_OK != retval) { LOG_ERROR("could not set MLC_TIME_REG"); return ERROR_NAND_OPERATION_FAILED; @@ -334,7 +334,7 @@ static int lpc32xx_init(struct nand_device *nand) WIDTH = bus_width) */ retval = target_write_u32(target, 0x20020014, - 0x3e | (bus_width == 16) ? 1 : 0); + 0x3e | (bus_width == 16) ? 1 : 0); if (ERROR_OK != retval) { LOG_ERROR("could not set SLC_CFG"); return ERROR_NAND_OPERATION_FAILED; @@ -374,14 +374,14 @@ static int lpc32xx_init(struct nand_device *nand) /* SLC_TAC: SLC timing arcs register */ retval = target_write_u32(target, 0x2002002c, - (r_setup & 0xf) - | ((r_hold & 0xf) << 4) - | ((r_width & 0xf) << 8) - | ((r_rdy & 0xf) << 12) - | ((w_setup & 0xf) << 16) - | ((w_hold & 0xf) << 20) - | ((w_width & 0xf) << 24) - | ((w_rdy & 0xf) << 28)); + (r_setup & 0xf) + | ((r_hold & 0xf) << 4) + | ((r_width & 0xf) << 8) + | ((r_rdy & 0xf) << 12) + | ((w_setup & 0xf) << 16) + | ((w_hold & 0xf) << 20) + | ((w_width & 0xf) << 24) + | ((w_rdy & 0xf) << 28)); if (ERROR_OK != retval) { LOG_ERROR("could not set SLC_TAC"); return ERROR_NAND_OPERATION_FAILED; @@ -399,7 +399,7 @@ static int lpc32xx_reset(struct nand_device *nand) if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use " - "LPC32xx NAND flash controller"); + "LPC32xx NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } @@ -416,7 +416,7 @@ static int lpc32xx_reset(struct nand_device *nand) if (!lpc32xx_controller_ready(nand, 100)) { LOG_ERROR("LPC32xx MLC NAND controller timed out " - "after reset"); + "after reset"); return ERROR_NAND_OPERATION_TIMEOUT; } } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { @@ -427,10 +427,9 @@ static int lpc32xx_reset(struct nand_device *nand) return ERROR_NAND_OPERATION_FAILED; } - if (!lpc32xx_controller_ready(nand, 100)) - { + if (!lpc32xx_controller_ready(nand, 100)) { LOG_ERROR("LPC32xx SLC NAND controller timed out " - "after reset"); + "after reset"); return ERROR_NAND_OPERATION_TIMEOUT; } } @@ -446,7 +445,7 @@ static int lpc32xx_command(struct nand_device *nand, uint8_t command) if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use " - "LPC32xx NAND flash controller"); + "LPC32xx NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } @@ -480,7 +479,7 @@ static int lpc32xx_address(struct nand_device *nand, uint8_t address) if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use " - "LPC32xx NAND flash controller"); + "LPC32xx NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } @@ -514,7 +513,7 @@ static int lpc32xx_write_data(struct nand_device *nand, uint16_t data) if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use " - "LPC32xx NAND flash controller"); + "LPC32xx NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } @@ -548,7 +547,7 @@ static int lpc32xx_read_data(struct nand_device *nand, void *data) if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); + "NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } @@ -591,8 +590,8 @@ static int lpc32xx_read_data(struct nand_device *nand, void *data) } static int lpc32xx_write_page_mlc(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size) { struct target *target = nand->target; int retval; @@ -623,7 +622,7 @@ static int lpc32xx_write_page_mlc(struct nand_device *nand, uint32_t page, return ERROR_NAND_OPERATION_FAILED; } retval = target_write_u32(target, 0x200b8004, - (page >> 8) & 0xff); + (page >> 8) & 0xff); if (ERROR_OK != retval) { LOG_ERROR("could not set MLC_ADDR"); return ERROR_NAND_OPERATION_FAILED; @@ -631,7 +630,7 @@ static int lpc32xx_write_page_mlc(struct nand_device *nand, uint32_t page, if (nand->address_cycles == 4) { retval = target_write_u32(target, 0x200b8004, - (page >> 16) & 0xff); + (page >> 16) & 0xff); if (ERROR_OK != retval) { LOG_ERROR("could not set MLC_ADDR"); return ERROR_NAND_OPERATION_FAILED; @@ -657,7 +656,7 @@ static int lpc32xx_write_page_mlc(struct nand_device *nand, uint32_t page, return ERROR_NAND_OPERATION_FAILED; } retval = target_write_u32(target, 0x200b8004, - (page >> 8) & 0xff); + (page >> 8) & 0xff); if (ERROR_OK != retval) { LOG_ERROR("could not set MLC_ADDR"); return ERROR_NAND_OPERATION_FAILED; @@ -717,7 +716,7 @@ static int lpc32xx_write_page_mlc(struct nand_device *nand, uint32_t page, if (!lpc32xx_controller_ready(nand, 1000)) { LOG_ERROR("timeout while waiting for " - "completion of auto encode cycle"); + "completion of auto encode cycle"); return ERROR_NAND_OPERATION_FAILED; } } @@ -729,14 +728,15 @@ static int lpc32xx_write_page_mlc(struct nand_device *nand, uint32_t page, return ERROR_NAND_OPERATION_FAILED; } - if ((retval = nand_read_status(nand, &status)) != ERROR_OK) { + retval = nand_read_status(nand, &status); + if (retval != ERROR_OK) { LOG_ERROR("couldn't read status"); return ERROR_NAND_OPERATION_FAILED; } if (status & NAND_STATUS_FAIL) { LOG_ERROR("write operation didn't pass, status: 0x%2.2x", - status); + status); return ERROR_NAND_OPERATION_FAILED; } @@ -749,7 +749,7 @@ static int lpc32xx_write_page_mlc(struct nand_device *nand, uint32_t page, * target. */ static int lpc32xx_make_dma_list(uint32_t target_mem_base, uint32_t page_size, - int do_read) + int do_read) { uint32_t i, dmasrc, ctrl, ecc_ctrl, oob_ctrl, dmadst; @@ -794,7 +794,7 @@ static int lpc32xx_make_dma_list(uint32_t target_mem_base, uint32_t page_size, */ ctrl = (0x40 | 3 << 12 | 3 << 15 | 2 << 18 | 2 << 21 | 0 << 24 - | 0 << 25 | 0 << 26 | 0 << 27 | 0 << 31); + | 0 << 25 | 0 << 26 | 0 << 27 | 0 << 31); /* DMACCxControl = TransferSize =1, @@ -809,7 +809,7 @@ static int lpc32xx_make_dma_list(uint32_t target_mem_base, uint32_t page_size, Terminal count interrupt enable bit = 0 */ ecc_ctrl = 0x01 | 1 << 12 | 1 << 15 | 2 << 18 | 2 << 21 | 0 << 24 - | 0 << 25 | 0 << 26 | 1 << 27 | 0 << 31; + | 0 << 25 | 0 << 26 | 1 << 27 | 0 << 31; /* DMACCxControl = TransferSize =16 for lp or 4 for sp, @@ -824,18 +824,18 @@ static int lpc32xx_make_dma_list(uint32_t target_mem_base, uint32_t page_size, Terminal count interrupt enable bit = 1 // set on last */ oob_ctrl = (page_size == 2048 ? 0x10 : 0x04) - | 3 << 12 | 3 << 15 | 2 << 18 | 2 << 21 | 0 << 24 - | 0 << 25 | 0 << 26 | 0 << 27 | 1 << 31; + | 3 << 12 | 3 << 15 | 2 << 18 | 2 << 21 | 0 << 24 + | 0 << 25 | 0 << 26 | 0 << 27 | 1 << 31; if (do_read) { - ctrl |= 1 << 27; /* Destination increment = 1 */ - oob_ctrl |= 1 << 27; /* Destination increment = 1 */ - dmasrc = 0x20020038; /* SLC_DMA_DATA */ + ctrl |= 1 << 27;/* Destination increment = 1 */ + oob_ctrl |= 1 << 27; /* Destination increment = 1 */ + dmasrc = 0x20020038; /* SLC_DMA_DATA */ dmadst = target_mem_base + DATA_OFFS; } else { - ctrl |= 1 << 26; /* Source increment = 1 */ - oob_ctrl |= 1 << 26; /* Source increment = 1 */ + ctrl |= 1 << 26;/* Source increment = 1 */ + oob_ctrl |= 1 << 26; /* Source increment = 1 */ dmasrc = target_mem_base + DATA_OFFS; - dmadst = 0x20020038; /* SLC_DMA_DATA */ + dmadst = 0x20020038; /* SLC_DMA_DATA */ } /* * Write Operation Sequence for Small Block NAND @@ -865,40 +865,38 @@ static int lpc32xx_make_dma_list(uint32_t target_mem_base, uint32_t page_size, * data & 32 bytes of ECC data. * 2. X'fer 64 bytes of Spare area from Flash to Memory. */ - for (i = 0; i < page_size/0x100; i++) - { + for (i = 0; i < page_size/0x100; i++) { dmalist[i*2].dma_src = (do_read ? dmasrc : (dmasrc + i * 256)); dmalist[i*2].dma_dest = (do_read ? (dmadst + i * 256) : dmadst); dmalist[i*2].next_lli = target_mem_base + (i*2 + 1) * sizeof(dmac_ll_t); dmalist[i*2].next_ctrl = ctrl; - dmalist[(i*2) + 1].dma_src = 0x20020034; /* SLC_ECC */ + dmalist[(i*2) + 1].dma_src = 0x20020034;/* SLC_ECC */ dmalist[(i*2) + 1].dma_dest = target_mem_base + ECC_OFFS + i * 4; dmalist[(i*2) + 1].next_lli = - target_mem_base + (i*2 + 2) * sizeof(dmac_ll_t); + target_mem_base + (i*2 + 2) * sizeof(dmac_ll_t); dmalist[(i*2) + 1].next_ctrl = ecc_ctrl; } if (do_read) - { dmadst = target_mem_base + SPARE_OFFS; - } else { + else { dmasrc = target_mem_base + SPARE_OFFS; - dmalist[(i*2) - 1].next_lli = 0; /* last link = null on write */ - dmalist[(i*2) - 1].next_ctrl |= (1 << 31); /* Set TC enable */ + dmalist[(i*2) - 1].next_lli = 0;/* last link = null on write */ + dmalist[(i*2) - 1].next_ctrl |= (1 << 31); /* Set TC enable */ } dmalist[i*2].dma_src = dmasrc; dmalist[i*2].dma_dest = dmadst; dmalist[i*2].next_lli = 0; dmalist[i*2].next_ctrl = oob_ctrl; - return (i*2 + 1); /* Number of descriptors */ + return i * 2 + 1; /* Number of descriptors */ } static int lpc32xx_start_slc_dma(struct nand_device *nand, uint32_t count, - int do_wait) + int do_wait) { struct target *target = nand->target; int retval; @@ -909,14 +907,14 @@ static int lpc32xx_start_slc_dma(struct nand_device *nand, uint32_t count, LOG_ERROR("Could not set DMACIntTCClear"); return retval; } - + /* DMACIntErrClear = ch0 */ retval = target_write_u32(target, 0x31000010, 1); if (ERROR_OK != retval) { LOG_ERROR("Could not set DMACIntErrClear"); return retval; } - + /* DMACCxConfig= E=1, SrcPeripheral = 1 (SLC), @@ -928,8 +926,8 @@ static int lpc32xx_start_slc_dma(struct nand_device *nand, uint32_t count, H=0 */ retval = target_write_u32(target, 0x31000110, - 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 - | 0<<15 | 0<<16 | 0<<18); + 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 + | 0<<15 | 0<<16 | 0<<18); if (ERROR_OK != retval) { LOG_ERROR("Could not set DMACC0Config"); return retval; @@ -990,14 +988,13 @@ static int lpc32xx_dma_ready(struct nand_device *nand, int timeout) } if ((tc_stat | err_stat) & 1) { LOG_DEBUG("lpc32xx_dma_ready count=%d", - timeout); + timeout); if (err_stat & 1) { LOG_ERROR("lpc32xx_dma_ready " - "DMA error, aborted"); + "DMA error, aborted"); return 0; - } else { + } else return 1; - } } alive_sleep(1); @@ -1006,8 +1003,8 @@ static int lpc32xx_dma_ready(struct nand_device *nand, int timeout) return 0; } -static uint32_t slc_ecc_copy_to_buffer(uint8_t * spare, - const uint32_t * ecc, int count) +static uint32_t slc_ecc_copy_to_buffer(uint8_t *spare, + const uint32_t *ecc, int count) { int i; for (i = 0; i < (count * 3); i += 3) { @@ -1025,30 +1022,30 @@ static void lpc32xx_dump_oob(uint8_t *oob, uint32_t oob_size) int addr = 0; while (oob_size > 0) { LOG_DEBUG("%02x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, - oob[0], oob[1], oob[2], oob[3], - oob[4], oob[5], oob[6], oob[7]); + oob[0], oob[1], oob[2], oob[3], + oob[4], oob[5], oob[6], oob[7]); oob += 8; addr += 8; oob_size -= 8; - } + } } static int lpc32xx_write_page_slc(struct nand_device *nand, - struct working_area *pworking_area, - uint32_t page, uint8_t *data, - uint32_t data_size, uint8_t *oob, - uint32_t oob_size) + struct working_area *pworking_area, + uint32_t page, uint8_t *data, + uint32_t data_size, uint8_t *oob, + uint32_t oob_size) { struct target *target = nand->target; int retval; uint32_t target_mem_base; LOG_DEBUG("SLC write page %x data=%d, oob=%d, " - "data_size=%d, oob_size=%d", - page, data != 0, oob != 0, data_size, oob_size); + "data_size=%d, oob_size=%d", + page, data != 0, oob != 0, data_size, oob_size); target_mem_base = pworking_area->address; - /* + /* * Skip writting page which has all 0xFF data as this will * generate 0x0 value. */ @@ -1060,7 +1057,7 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, break; } if (all_ff) - return ERROR_OK; + return ERROR_OK; } /* Make the dma descriptors in local memory */ int nll = lpc32xx_make_dma_list(target_mem_base, nand->page_size, 0); @@ -1068,8 +1065,8 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, XXX: Assumes host and target have same byte sex. */ retval = target_write_memory(target, target_mem_base, 4, - nll * sizeof(dmac_ll_t) / 4, - (uint8_t *)dmalist); + nll * sizeof(dmac_ll_t) / 4, + (uint8_t *)dmalist); if (ERROR_OK != retval) { LOG_ERROR("Could not write DMA descriptors to IRAM"); return retval; @@ -1081,13 +1078,13 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, return retval; } - /* SLC_CFG = - Force nCE assert, - DMA ECC enabled, - ECC enabled, - DMA burst enabled, - DMA write to SLC, - WIDTH = bus_width + /* SLC_CFG = + Force nCE assert, + DMA ECC enabled, + ECC enabled, + DMA burst enabled, + DMA write to SLC, + WIDTH = bus_width */ retval = target_write_u32(target, 0x20020014, 0x3c); if (ERROR_OK != retval) { @@ -1100,8 +1097,8 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, memset(fdata, 0xFF, nand->page_size); memcpy(fdata, data, data_size); retval = target_write_memory(target, - target_mem_base + DATA_OFFS, - 4, nand->page_size/4, fdata); + target_mem_base + DATA_OFFS, + 4, nand->page_size/4, fdata); if (ERROR_OK != retval) { LOG_ERROR("Could not write data to IRAM"); return retval; @@ -1109,8 +1106,8 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, /* Write first decriptor to DMA controller */ retval = target_write_memory(target, 0x31000100, 4, - sizeof(dmac_ll_t) / 4, - (uint8_t *)dmalist); + sizeof(dmac_ll_t) / 4, + (uint8_t *)dmalist); if (ERROR_OK != retval) { LOG_ERROR("Could not write DMA descriptor to DMAC"); return retval; @@ -1124,26 +1121,26 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, LOG_ERROR("DMA failed"); return retval; } - + /* Wait for DMA to finish. SLC is not finished at this stage */ if (!lpc32xx_dma_ready(nand, 100)) { LOG_ERROR("Data DMA failed during write"); return ERROR_FLASH_OPERATION_FAILED; } - } /* data xfer */ + } /* data xfer */ /* Copy OOB to iram */ static uint8_t foob[64]; int foob_size = nand->page_size == 2048 ? 64 : 16; memset(foob, 0xFF, foob_size); - if (oob) { /* Raw mode */ + if (oob) /* Raw mode */ memcpy(foob, oob, oob_size); - } else { + else { /* Get HW generated ECC, made while writing data */ int ecc_count = nand->page_size == 2048 ? 8 : 2; static uint32_t hw_ecc[8]; retval = target_read_memory(target, target_mem_base + ECC_OFFS, - 4, ecc_count, (uint8_t *)hw_ecc); + 4, ecc_count, (uint8_t *)hw_ecc); if (ERROR_OK != retval) { LOG_ERROR("Reading hw generated ECC from IRAM failed"); return retval; @@ -1158,7 +1155,7 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, lpc32xx_dump_oob(foob, foob_size); } retval = target_write_memory(target, target_mem_base + SPARE_OFFS, 4, - foob_size / 4, foob); + foob_size / 4, foob); if (ERROR_OK != retval) { LOG_ERROR("Writing OOB to IRAM failed"); return retval; @@ -1166,8 +1163,8 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, /* Write OOB decriptor to DMA controller */ retval = target_write_memory(target, 0x31000100, 4, - sizeof(dmac_ll_t) / 4, - (uint8_t *)(&dmalist[nll-1])); + sizeof(dmac_ll_t) / 4, + (uint8_t *)(&dmalist[nll-1])); if (ERROR_OK != retval) { LOG_ERROR("Could not write OOB DMA descriptor to DMAC"); return retval; @@ -1183,18 +1180,18 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, return retval; } /* DMACCxConfig= - E=1, - SrcPeripheral = 1 (SLC), - DestPeripheral = 1 (SLC), - FlowCntrl = 2 (Pher -> Mem, DMA), - IE = 0, - ITC = 0, - L= 0, - H=0 + * E=1, + * SrcPeripheral = 1 (SLC), + * DestPeripheral = 1 (SLC), + * FlowCntrl = 2 (Pher -> Mem, DMA), + * IE = 0, + * ITC = 0, + * L= 0, + * H=0 */ retval = target_write_u32(target, 0x31000110, - 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 - | 0<<15 | 0<<16 | 0<<18); + 1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 + | 0<<15 | 0<<16 | 0<<18); if (ERROR_OK != retval) { LOG_ERROR("Could not set DMACC0Config"); return retval; @@ -1202,7 +1199,7 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, /* Wait finish */ if (!lpc32xx_tc_ready(nand, 100)) { LOG_ERROR("timeout while waiting for " - "completion of DMA"); + "completion of DMA"); return ERROR_NAND_OPERATION_FAILED; } } else { @@ -1225,8 +1222,8 @@ static int lpc32xx_write_page_slc(struct nand_device *nand, } static int lpc32xx_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size) { struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; struct target *target = nand->target; @@ -1234,7 +1231,7 @@ static int lpc32xx_write_page(struct nand_device *nand, uint32_t page, if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); + "NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } @@ -1244,13 +1241,13 @@ static int lpc32xx_write_page(struct nand_device *nand, uint32_t page, } else if (lpc32xx_info->selected_controller == LPC32xx_MLC_CONTROLLER) { if (!data && oob) { LOG_ERROR("LPC32xx MLC controller can't write " - "OOB data only"); + "OOB data only"); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } if (oob && (oob_size > 24)) { LOG_ERROR("LPC32xx MLC controller can't write more " - "than 6 bytes for each quarter's OOB data"); + "than 6 bytes for each quarter's OOB data"); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } @@ -1260,7 +1257,7 @@ static int lpc32xx_write_page(struct nand_device *nand, uint32_t page, } retval = lpc32xx_write_page_mlc(nand, page, data, data_size, - oob, oob_size); + oob, oob_size); } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { struct working_area *pworking_area; if (!data && oob) { @@ -1270,18 +1267,18 @@ static int lpc32xx_write_page(struct nand_device *nand, uint32_t page, * Anyway the code supports the oob only mode below. */ return nand_write_page_raw(nand, page, data, - data_size, oob, oob_size); + data_size, oob, oob_size); } retval = target_alloc_working_area(target, - nand->page_size + DATA_OFFS, - &pworking_area); + nand->page_size + DATA_OFFS, + &pworking_area); if (retval != ERROR_OK) { LOG_ERROR("Can't allocate working area in " - "LPC internal RAM"); + "LPC internal RAM"); return ERROR_FLASH_OPERATION_FAILED; } retval = lpc32xx_write_page_slc(nand, pworking_area, page, - data, data_size, oob, oob_size); + data, data_size, oob, oob_size); target_free_working_area(target, pworking_area); } @@ -1289,8 +1286,8 @@ static int lpc32xx_write_page(struct nand_device *nand, uint32_t page, } static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size) { struct target *target = nand->target; static uint8_t page_buffer[2048]; @@ -1317,8 +1314,8 @@ static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, return ERROR_NAND_OPERATION_FAILED; } if (nand->page_size == 512) { - /* small page device */ - /* MLC_ADDR = 0x0 (one column cycle) */ + /* small page device + * MLC_ADDR = 0x0 (one column cycle) */ retval = target_write_u32(target, 0x200b8004, 0x0); if (ERROR_OK != retval) { LOG_ERROR("could not set MLC_ADDR"); @@ -1332,7 +1329,7 @@ static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, return ERROR_NAND_OPERATION_FAILED; } retval = target_write_u32(target, 0x200b8004, - (page >> 8) & 0xff); + (page >> 8) & 0xff); if (ERROR_OK != retval) { LOG_ERROR("could not set MLC_ADDR"); return ERROR_NAND_OPERATION_FAILED; @@ -1340,15 +1337,15 @@ static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, if (nand->address_cycles == 4) { retval = target_write_u32(target, 0x200b8004, - (page >> 16) & 0xff); + (page >> 16) & 0xff); if (ERROR_OK != retval) { LOG_ERROR("could not set MLC_ADDR"); return ERROR_NAND_OPERATION_FAILED; } } } else { - /* large page device */ - /* MLC_ADDR = 0x0 (two column cycles) */ + /* large page device + * MLC_ADDR = 0x0 (two column cycles) */ retval = target_write_u32(target, 0x200b8004, 0x0); if (ERROR_OK != retval) { LOG_ERROR("could not set MLC_ADDR"); @@ -1367,7 +1364,7 @@ static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, return ERROR_NAND_OPERATION_FAILED; } retval = target_write_u32(target, 0x200b8004, - (page >> 8) & 0xff); + (page >> 8) & 0xff); if (ERROR_OK != retval) { LOG_ERROR("could not set MLC_ADDR"); return ERROR_NAND_OPERATION_FAILED; @@ -1375,7 +1372,7 @@ static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, /* MLC_CMD = Read Start */ retval = target_write_u32(target, 0x200b8000, - NAND_CMD_READSTART); + NAND_CMD_READSTART); if (ERROR_OK != retval) { LOG_ERROR("could not set MLC_CMD"); return ERROR_NAND_OPERATION_FAILED; @@ -1392,7 +1389,7 @@ static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, if (!lpc32xx_controller_ready(nand, 1000)) { LOG_ERROR("timeout while waiting for " - "completion of auto decode cycle"); + "completion of auto decode cycle"); return ERROR_NAND_OPERATION_FAILED; } @@ -1405,17 +1402,17 @@ static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, if (mlc_isr & 0x8) { if (mlc_isr & 0x40) { LOG_ERROR("uncorrectable error detected: " - "0x%2.2x", (unsigned)mlc_isr); + "0x%2.2x", (unsigned)mlc_isr); return ERROR_NAND_OPERATION_FAILED; } LOG_WARNING("%i symbol error detected and corrected", - ((int)(((mlc_isr & 0x30) >> 4) + 1))); + ((int)(((mlc_isr & 0x30) >> 4) + 1))); } if (data) { retval = target_read_memory(target, 0x200a8000, 4, 128, - page_buffer + page_bytes_done); + page_buffer + page_bytes_done); if (ERROR_OK != retval) { LOG_ERROR("could not read MLC_BUF (data)"); return ERROR_NAND_OPERATION_FAILED; @@ -1424,7 +1421,7 @@ static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, if (oob) { retval = target_read_memory(target, 0x200a8000, 4, 4, - oob_buffer + oob_bytes_done); + oob_buffer + oob_bytes_done); if (ERROR_OK != retval) { LOG_ERROR("could not read MLC_BUF (oob)"); return ERROR_NAND_OPERATION_FAILED; @@ -1445,17 +1442,17 @@ static int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page, } static int lpc32xx_read_page_slc(struct nand_device *nand, - struct working_area *pworking_area, - uint32_t page, uint8_t *data, - uint32_t data_size, uint8_t *oob, - uint32_t oob_size) + struct working_area *pworking_area, + uint32_t page, uint8_t *data, + uint32_t data_size, uint8_t *oob, + uint32_t oob_size) { struct target *target = nand->target; int retval; uint32_t target_mem_base; LOG_DEBUG("SLC read page %x data=%d, oob=%d", - page, data_size, oob_size); + page, data_size, oob_size); target_mem_base = pworking_area->address; @@ -1465,8 +1462,8 @@ static int lpc32xx_read_page_slc(struct nand_device *nand, XXX: Assumes host and target have same byte sex. */ retval = target_write_memory(target, target_mem_base, 4, - nll * sizeof(dmac_ll_t) / 4, - (uint8_t *)dmalist); + nll * sizeof(dmac_ll_t) / 4, + (uint8_t *)dmalist); if (ERROR_OK != retval) { LOG_ERROR("Could not write DMA descriptors to IRAM"); return retval; @@ -1478,13 +1475,13 @@ static int lpc32xx_read_page_slc(struct nand_device *nand, return retval; } - /* SLC_CFG = - Force nCE assert, - DMA ECC enabled, - ECC enabled, - DMA burst enabled, - DMA read from SLC, - WIDTH = bus_width + /* SLC_CFG = + Force nCE assert, + DMA ECC enabled, + ECC enabled, + DMA burst enabled, + DMA read from SLC, + WIDTH = bus_width */ retval = target_write_u32(target, 0x20020014, 0x3e); if (ERROR_OK != retval) { @@ -1494,7 +1491,7 @@ static int lpc32xx_read_page_slc(struct nand_device *nand, /* Write first decriptor to DMA controller */ retval = target_write_memory(target, 0x31000100, 4, - sizeof(dmac_ll_t) / 4, (uint8_t *)dmalist); + sizeof(dmac_ll_t) / 4, (uint8_t *)dmalist); if (ERROR_OK != retval) { LOG_ERROR("Could not write DMA descriptor to DMAC"); return retval; @@ -1512,7 +1509,7 @@ static int lpc32xx_read_page_slc(struct nand_device *nand, /* Copy data from iram */ if (data) { retval = target_read_memory(target, target_mem_base + DATA_OFFS, - 4, data_size/4, data); + 4, data_size/4, data); if (ERROR_OK != retval) { LOG_ERROR("Could not read data from IRAM"); return retval; @@ -1521,8 +1518,8 @@ static int lpc32xx_read_page_slc(struct nand_device *nand, if (oob) { /* No error correction, just return data as read from flash */ retval = target_read_memory(target, - target_mem_base + SPARE_OFFS, 4, - oob_size/4, oob); + target_mem_base + SPARE_OFFS, 4, + oob_size/4, oob); if (ERROR_OK != retval) { LOG_ERROR("Could not read OOB from IRAM"); return retval; @@ -1533,7 +1530,7 @@ static int lpc32xx_read_page_slc(struct nand_device *nand, /* Copy OOB from flash, stored in IRAM */ static uint8_t foob[64]; retval = target_read_memory(target, target_mem_base + SPARE_OFFS, - 4, nand->page_size == 2048 ? 16 : 4, foob); + 4, nand->page_size == 2048 ? 16 : 4, foob); lpc32xx_dump_oob(foob, nand->page_size == 2048 ? 64 : 16); if (ERROR_OK != retval) { LOG_ERROR("Could not read OOB from IRAM"); @@ -1541,9 +1538,9 @@ static int lpc32xx_read_page_slc(struct nand_device *nand, } /* Copy ECC from HW, generated while reading */ int ecc_count = nand->page_size == 2048 ? 8 : 2; - static uint32_t hw_ecc[8]; /* max size */ + static uint32_t hw_ecc[8]; /* max size */ retval = target_read_memory(target, target_mem_base + ECC_OFFS, 4, - ecc_count, (uint8_t *)hw_ecc); + ecc_count, (uint8_t *)hw_ecc); if (ERROR_OK != retval) { LOG_ERROR("Could not read hw generated ECC from IRAM"); return retval; @@ -1551,7 +1548,7 @@ static int lpc32xx_read_page_slc(struct nand_device *nand, static uint8_t ecc[24]; slc_ecc_copy_to_buffer(ecc, hw_ecc, ecc_count); /* Copy ECC from flash using correct layout */ - static uint8_t fecc[24]; /* max size */ + static uint8_t fecc[24];/* max size */ int *layout = nand->page_size == 2048 ? lp_ooblayout : sp_ooblayout; int i; for (i = 0; i < ecc_count * 3; i++) @@ -1559,10 +1556,10 @@ static int lpc32xx_read_page_slc(struct nand_device *nand, /* Compare ECC and possibly correct data */ for (i = 0; i < ecc_count; i++) { retval = nand_correct_data(nand, data + 256*i, &fecc[i * 3], - &ecc[i * 3]); + &ecc[i * 3]); if (retval > 0) LOG_WARNING("error detected and corrected: %d/%d", - page, i); + page, i); if (retval < 0) break; } @@ -1576,8 +1573,8 @@ static int lpc32xx_read_page_slc(struct nand_device *nand, } static int lpc32xx_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size) { struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; struct target *target = nand->target; @@ -1585,7 +1582,7 @@ static int lpc32xx_read_page(struct nand_device *nand, uint32_t page, if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); + "NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } @@ -1598,21 +1595,21 @@ static int lpc32xx_read_page(struct nand_device *nand, uint32_t page, return ERROR_NAND_OPERATION_NOT_SUPPORTED; } retval = lpc32xx_read_page_mlc(nand, page, data, data_size, - oob, oob_size); + oob, oob_size); } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { struct working_area *pworking_area; - retval = target_alloc_working_area(target, - nand->page_size + 0x200, - &pworking_area); + retval = target_alloc_working_area(target, + nand->page_size + 0x200, + &pworking_area); if (retval != ERROR_OK) { LOG_ERROR("Can't allocate working area in " - "LPC internal RAM"); + "LPC internal RAM"); return ERROR_FLASH_OPERATION_FAILED; } retval = lpc32xx_read_page_slc(nand, pworking_area, page, - data, data_size, oob, oob_size); - target_free_working_area(target, pworking_area); + data, data_size, oob, oob_size); + target_free_working_area(target, pworking_area); } return retval; @@ -1626,7 +1623,7 @@ static int lpc32xx_controller_ready(struct nand_device *nand, int timeout) if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); + "NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } @@ -1645,7 +1642,7 @@ static int lpc32xx_controller_ready(struct nand_device *nand, int timeout) if (status & 2) { LOG_DEBUG("lpc32xx_controller_ready count=%d", - timeout); + timeout); return 1; } } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { @@ -1660,7 +1657,7 @@ static int lpc32xx_controller_ready(struct nand_device *nand, int timeout) if (status & 1) { LOG_DEBUG("lpc32xx_controller_ready count=%d", - timeout); + timeout); return 1; } } @@ -1679,7 +1676,7 @@ static int lpc32xx_nand_ready(struct nand_device *nand, int timeout) if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC32xx " - "NAND flash controller"); + "NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } @@ -1699,7 +1696,7 @@ static int lpc32xx_nand_ready(struct nand_device *nand, int timeout) if (status & 1) { LOG_DEBUG("lpc32xx_nand_ready count end=%d", - timeout); + timeout); return 1; } } else if (lpc32xx_info->selected_controller == LPC32xx_SLC_CONTROLLER) { @@ -1714,7 +1711,7 @@ static int lpc32xx_nand_ready(struct nand_device *nand, int timeout) if (status & 1) { LOG_DEBUG("lpc32xx_nand_ready count end=%d", - timeout); + timeout); return 1; } } @@ -1740,7 +1737,7 @@ static int lpc32xx_tc_ready(struct nand_device *nand, int timeout) LOG_ERROR("Could not read SLC_INT_STAT"); return 0; } - if (status & 2){ + if (status & 2) { LOG_DEBUG("lpc32xx_tc_ready count=%d", timeout); return 1; } @@ -1758,16 +1755,15 @@ COMMAND_HANDLER(handle_lpc32xx_select_command) "no", "mlc", "slc" }; - if ((CMD_ARGC < 1) || (CMD_ARGC > 3)) { + if ((CMD_ARGC < 1) || (CMD_ARGC > 3)) return ERROR_COMMAND_SYNTAX_ERROR; - } unsigned num; COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num); struct nand_device *nand = get_nand_device_by_num(num); if (!nand) { command_print(CMD_CTX, "nand device '#%s' is out of bounds", - CMD_ARGV[0]); + CMD_ARGV[0]); return ERROR_OK; } @@ -1780,13 +1776,12 @@ COMMAND_HANDLER(handle_lpc32xx_select_command) } else if (strcmp(CMD_ARGV[1], "slc") == 0) { lpc32xx_info->selected_controller = LPC32xx_SLC_CONTROLLER; - } else { + } else return ERROR_COMMAND_SYNTAX_ERROR; - } } command_print(CMD_CTX, "%s controller selected", - selected[lpc32xx_info->selected_controller]); + selected[lpc32xx_info->selected_controller]); return ERROR_OK; } diff --git a/src/flash/nand/lpc32xx.h b/src/flash/nand/lpc32xx.h index fd87245..0cac27c 100644 --- a/src/flash/nand/lpc32xx.h +++ b/src/flash/nand/lpc32xx.h @@ -17,18 +17,17 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifndef LPC32xx_NAND_CONTROLLER_H #define LPC32xx_NAND_CONTROLLER_H -enum lpc32xx_selected_controller -{ +enum lpc32xx_selected_controller { LPC32xx_NO_CONTROLLER, LPC32xx_MLC_CONTROLLER, LPC32xx_SLC_CONTROLLER, }; -struct lpc32xx_nand_controller -{ +struct lpc32xx_nand_controller { int osc_freq; enum lpc32xx_selected_controller selected_controller; int sw_write_protection; @@ -36,4 +35,4 @@ struct lpc32xx_nand_controller uint32_t sw_wp_upper_bound; }; -#endif /*LPC32xx_NAND_CONTROLLER_H */ +#endif /*LPC32xx_NAND_CONTROLLER_H */ diff --git a/src/flash/nand/mx3.c b/src/flash/nand/mx3.c index 54ba1f9..23e6033 100644 --- a/src/flash/nand/mx3.c +++ b/src/flash/nand/mx3.c @@ -40,647 +40,541 @@ get_next_halfword_from_sram_buffer() not tested #include <target/target.h> static const char target_not_halted_err_msg[] = - "target must be halted to use mx3 NAND flash controller"; + "target must be halted to use mx3 NAND flash controller"; static const char data_block_size_err_msg[] = - "minimal granularity is one half-word, %" PRId32 " is incorrect"; + "minimal granularity is one half-word, %" PRId32 " is incorrect"; static const char sram_buffer_bounds_err_msg[] = - "trying to access out of SRAM buffer bound (addr=0x%" PRIx32 ")"; + "trying to access out of SRAM buffer bound (addr=0x%" PRIx32 ")"; static const char get_status_register_err_msg[] = "can't get NAND status"; static uint32_t in_sram_address; static unsigned char sign_of_sequental_byte_read; -static int test_iomux_settings (struct target * target, uint32_t value, - uint32_t mask, const char *text); -static int initialize_nf_controller (struct nand_device *nand); -static int get_next_byte_from_sram_buffer (struct target * target, uint8_t * value); -static int get_next_halfword_from_sram_buffer (struct target * target, - uint16_t * value); -static int poll_for_complete_op (struct target * target, const char *text); -static int validate_target_state (struct nand_device *nand); -static int do_data_output (struct nand_device *nand); +static int test_iomux_settings(struct target *target, uint32_t value, + uint32_t mask, const char *text); +static int initialize_nf_controller(struct nand_device *nand); +static int get_next_byte_from_sram_buffer(struct target *target, uint8_t *value); +static int get_next_halfword_from_sram_buffer(struct target *target, + uint16_t *value); +static int poll_for_complete_op(struct target *target, const char *text); +static int validate_target_state(struct nand_device *nand); +static int do_data_output(struct nand_device *nand); -static int imx31_command (struct nand_device *nand, uint8_t command); -static int imx31_address (struct nand_device *nand, uint8_t address); +static int imx31_command(struct nand_device *nand, uint8_t command); +static int imx31_address(struct nand_device *nand, uint8_t address); NAND_DEVICE_COMMAND_HANDLER(imx31_nand_device_command) { struct mx3_nf_controller *mx3_nf_info; - mx3_nf_info = malloc (sizeof (struct mx3_nf_controller)); - if (mx3_nf_info == NULL) - { - LOG_ERROR ("no memory for nand controller"); - return ERROR_FAIL; + mx3_nf_info = malloc(sizeof(struct mx3_nf_controller)); + if (mx3_nf_info == NULL) { + LOG_ERROR("no memory for nand controller"); + return ERROR_FAIL; } nand->controller_priv = mx3_nf_info; if (CMD_ARGC < 3) - { - return ERROR_COMMAND_SYNTAX_ERROR; - } + return ERROR_COMMAND_SYNTAX_ERROR; /* * check hwecc requirements */ { - int hwecc_needed; - hwecc_needed = strcmp (CMD_ARGV[2], "hwecc"); - if (hwecc_needed == 0) - { - mx3_nf_info->flags.hw_ecc_enabled = 1; - } - else - { - mx3_nf_info->flags.hw_ecc_enabled = 0; - } + int hwecc_needed; + hwecc_needed = strcmp(CMD_ARGV[2], "hwecc"); + if (hwecc_needed == 0) + mx3_nf_info->flags.hw_ecc_enabled = 1; + else + mx3_nf_info->flags.hw_ecc_enabled = 0; } mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE; mx3_nf_info->fin = MX3_NF_FIN_NONE; mx3_nf_info->flags.target_little_endian = - (nand->target->endianness == TARGET_LITTLE_ENDIAN); + (nand->target->endianness == TARGET_LITTLE_ENDIAN); /* * testing host endianness */ { - int x = 1; - if (*(char *) &x == 1) - { - mx3_nf_info->flags.host_little_endian = 1; - } - else - { - mx3_nf_info->flags.host_little_endian = 0; - } + int x = 1; + if (*(char *) &x == 1) + mx3_nf_info->flags.host_little_endian = 1; + else + mx3_nf_info->flags.host_little_endian = 0; } return ERROR_OK; } -static int imx31_init (struct nand_device *nand) +static int imx31_init(struct nand_device *nand) { struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; struct target *target = nand->target; { - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state(nand); - if (validate_target_result != ERROR_OK) - { - return validate_target_result; - } + /* + * validate target state + */ + int validate_target_result; + validate_target_result = validate_target_state(nand); + if (validate_target_result != ERROR_OK) + return validate_target_result; } { - uint16_t buffsize_register_content; - target_read_u16 (target, MX3_NF_BUFSIZ, &buffsize_register_content); - mx3_nf_info->flags.one_kb_sram = !(buffsize_register_content & 0x000f); + uint16_t buffsize_register_content; + target_read_u16(target, MX3_NF_BUFSIZ, &buffsize_register_content); + mx3_nf_info->flags.one_kb_sram = !(buffsize_register_content & 0x000f); } { - uint32_t pcsr_register_content; - target_read_u32 (target, MX3_PCSR, &pcsr_register_content); - if (!nand->bus_width) - { - nand->bus_width = - (pcsr_register_content & 0x80000000) ? 16 : 8; - } - else - { - pcsr_register_content |= - ((nand->bus_width == 16) ? 0x80000000 : 0x00000000); - target_write_u32 (target, MX3_PCSR, pcsr_register_content); - } - - if (!nand->page_size) - { - nand->page_size = - (pcsr_register_content & 0x40000000) ? 2048 : 512; - } - else - { - pcsr_register_content |= - ((nand->page_size == 2048) ? 0x40000000 : 0x00000000); - target_write_u32 (target, MX3_PCSR, pcsr_register_content); - } - if (mx3_nf_info->flags.one_kb_sram && (nand->page_size == 2048)) - { - LOG_ERROR - ("NAND controller have only 1 kb SRAM, so pagesize 2048 is incompatible with it"); - } + uint32_t pcsr_register_content; + target_read_u32(target, MX3_PCSR, &pcsr_register_content); + if (!nand->bus_width) { + nand->bus_width = (pcsr_register_content & 0x80000000) ? 16 : 8; + } else { + pcsr_register_content |= ((nand->bus_width == 16) ? 0x80000000 : 0x00000000); + target_write_u32(target, MX3_PCSR, pcsr_register_content); + } + + if (!nand->page_size) { + nand->page_size = (pcsr_register_content & 0x40000000) ? 2048 : 512; + } else { + pcsr_register_content |= ((nand->page_size == 2048) ? 0x40000000 : 0x00000000); + target_write_u32(target, MX3_PCSR, pcsr_register_content); + } + if (mx3_nf_info->flags.one_kb_sram && (nand->page_size == 2048)) { + LOG_ERROR("NAND controller have only 1 kb SRAM, " + "so pagesize 2048 is incompatible with it"); + } } { - uint32_t cgr_register_content; - target_read_u32 (target, MX3_CCM_CGR2, &cgr_register_content); - if (!(cgr_register_content & 0x00000300)) - { - LOG_ERROR ("clock gating to EMI disabled"); - return ERROR_FAIL; - } + uint32_t cgr_register_content; + target_read_u32(target, MX3_CCM_CGR2, &cgr_register_content); + if (!(cgr_register_content & 0x00000300)) { + LOG_ERROR("clock gating to EMI disabled"); + return ERROR_FAIL; + } } { - uint32_t gpr_register_content; - target_read_u32 (target, MX3_GPR, &gpr_register_content); - if (gpr_register_content & 0x00000060) - { - LOG_ERROR ("pins mode overrided by GPR"); - return ERROR_FAIL; - } + uint32_t gpr_register_content; + target_read_u32(target, MX3_GPR, &gpr_register_content); + if (gpr_register_content & 0x00000060) { + LOG_ERROR("pins mode overrided by GPR"); + return ERROR_FAIL; + } } { - /* - * testing IOMUX settings; must be in "functional-mode output and - * functional-mode input" mode - */ - int test_iomux; - test_iomux = ERROR_OK; - test_iomux |= - test_iomux_settings (target, 0x43fac0c0, 0x7f7f7f00, "d0,d1,d2"); - test_iomux |= - test_iomux_settings (target, 0x43fac0c4, 0x7f7f7f7f, "d3,d4,d5,d6"); - test_iomux |= - test_iomux_settings (target, 0x43fac0c8, 0x0000007f, "d7"); - if (nand->bus_width == 16) - { - test_iomux |= - test_iomux_settings (target, 0x43fac0c8, 0x7f7f7f00, - "d8,d9,d10"); - test_iomux |= - test_iomux_settings (target, 0x43fac0cc, 0x7f7f7f7f, - "d11,d12,d13,d14"); - test_iomux |= - test_iomux_settings (target, 0x43fac0d0, 0x0000007f, "d15"); - } - test_iomux |= - test_iomux_settings (target, 0x43fac0d0, 0x7f7f7f00, - "nfwp,nfce,nfrb"); - test_iomux |= - test_iomux_settings (target, 0x43fac0d4, 0x7f7f7f7f, - "nfwe,nfre,nfale,nfcle"); - if (test_iomux != ERROR_OK) - { - return ERROR_FAIL; - } + /* + * testing IOMUX settings; must be in "functional-mode output and + * functional-mode input" mode + */ + int test_iomux; + test_iomux = ERROR_OK; + test_iomux |= test_iomux_settings(target, 0x43fac0c0, 0x7f7f7f00, "d0,d1,d2"); + test_iomux |= test_iomux_settings(target, 0x43fac0c4, 0x7f7f7f7f, "d3,d4,d5,d6"); + test_iomux |= test_iomux_settings(target, 0x43fac0c8, 0x0000007f, "d7"); + if (nand->bus_width == 16) { + test_iomux |= test_iomux_settings(target, 0x43fac0c8, 0x7f7f7f00, "d8,d9,d10"); + test_iomux |= test_iomux_settings(target, 0x43fac0cc, 0x7f7f7f7f, "d11,d12,d13,d14"); + test_iomux |= test_iomux_settings(target, 0x43fac0d0, 0x0000007f, "d15"); + } + test_iomux |= test_iomux_settings(target, 0x43fac0d0, 0x7f7f7f00, "nfwp,nfce,nfrb"); + test_iomux |= test_iomux_settings(target, 0x43fac0d4, 0x7f7f7f7f, + "nfwe,nfre,nfale,nfcle"); + if (test_iomux != ERROR_OK) + return ERROR_FAIL; } - initialize_nf_controller (nand); + initialize_nf_controller(nand); { - int retval; - uint16_t nand_status_content; - retval = ERROR_OK; - retval |= imx31_command (nand, NAND_CMD_STATUS); - retval |= imx31_address (nand, 0x00); - retval |= do_data_output (nand); - if (retval != ERROR_OK) - { - LOG_ERROR (get_status_register_err_msg); - return ERROR_FAIL; - } - target_read_u16 (target, MX3_NF_MAIN_BUFFER0, &nand_status_content); - if (!(nand_status_content & 0x0080)) - { - /* - * is host-big-endian correctly ?? - */ - LOG_INFO ("NAND read-only"); - mx3_nf_info->flags.nand_readonly = 1; - } - else - { - mx3_nf_info->flags.nand_readonly = 0; - } + int retval; + uint16_t nand_status_content; + retval = ERROR_OK; + retval |= imx31_command(nand, NAND_CMD_STATUS); + retval |= imx31_address(nand, 0x00); + retval |= do_data_output(nand); + if (retval != ERROR_OK) { + LOG_ERROR(get_status_register_err_msg); + return ERROR_FAIL; + } + target_read_u16(target, MX3_NF_MAIN_BUFFER0, &nand_status_content); + if (!(nand_status_content & 0x0080)) { + /* + * is host-big-endian correctly ?? + */ + LOG_INFO("NAND read-only"); + mx3_nf_info->flags.nand_readonly = 1; + } else + mx3_nf_info->flags.nand_readonly = 0; } return ERROR_OK; } -static int imx31_read_data (struct nand_device *nand, void *data) +static int imx31_read_data(struct nand_device *nand, void *data) { struct target *target = nand->target; { - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state (nand); - if (validate_target_result != ERROR_OK) - { - return validate_target_result; - } + /* + * validate target state + */ + int validate_target_result; + validate_target_result = validate_target_state(nand); + if (validate_target_result != ERROR_OK) + return validate_target_result; } { - /* - * get data from nand chip - */ - int try_data_output_from_nand_chip; - try_data_output_from_nand_chip = do_data_output (nand); - if (try_data_output_from_nand_chip != ERROR_OK) - { - return try_data_output_from_nand_chip; - } + /* + * get data from nand chip + */ + int try_data_output_from_nand_chip; + try_data_output_from_nand_chip = do_data_output(nand); + if (try_data_output_from_nand_chip != ERROR_OK) + return try_data_output_from_nand_chip; } if (nand->bus_width == 16) - { - get_next_halfword_from_sram_buffer (target, data); - } + get_next_halfword_from_sram_buffer(target, data); else - { - get_next_byte_from_sram_buffer (target, data); - } + get_next_byte_from_sram_buffer(target, data); return ERROR_OK; } -static int imx31_write_data (struct nand_device *nand, uint16_t data) +static int imx31_write_data(struct nand_device *nand, uint16_t data) { - LOG_ERROR ("write_data() not implemented"); + LOG_ERROR("write_data() not implemented"); return ERROR_NAND_OPERATION_FAILED; } -static int imx31_reset (struct nand_device *nand) +static int imx31_reset(struct nand_device *nand) { /* * validate target state */ int validate_target_result; - validate_target_result = validate_target_state (nand); + validate_target_result = validate_target_state(nand); if (validate_target_result != ERROR_OK) - { - return validate_target_result; - } - initialize_nf_controller (nand); + return validate_target_result; + initialize_nf_controller(nand); return ERROR_OK; } -static int imx31_command (struct nand_device *nand, uint8_t command) +static int imx31_command(struct nand_device *nand, uint8_t command) { struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; struct target *target = nand->target; { - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state (nand); - if (validate_target_result != ERROR_OK) - { - return validate_target_result; - } - } - - switch (command) - { - case NAND_CMD_READOOB: - command = NAND_CMD_READ0; - in_sram_address = MX3_NF_SPARE_BUFFER0; /* set read point for - * data_read() and - * read_block_data() to - * spare area in SRAM - * buffer */ - break; - case NAND_CMD_READ1: - command = NAND_CMD_READ0; /* - * offset == one half of page size + * validate target state */ - in_sram_address = - MX3_NF_MAIN_BUFFER0 + (nand->page_size >> 1); - default: - in_sram_address = MX3_NF_MAIN_BUFFER0; + int validate_target_result; + validate_target_result = validate_target_state(nand); + if (validate_target_result != ERROR_OK) + return validate_target_result; + } + + switch (command) { + case NAND_CMD_READOOB: + command = NAND_CMD_READ0; + in_sram_address = MX3_NF_SPARE_BUFFER0; /* set read point for + * data_read() and + * read_block_data() to + * spare area in SRAM + * buffer */ + break; + case NAND_CMD_READ1: + command = NAND_CMD_READ0; + /* + * offset == one half of page size + */ + in_sram_address = MX3_NF_MAIN_BUFFER0 + (nand->page_size >> 1); + default: + in_sram_address = MX3_NF_MAIN_BUFFER0; } - target_write_u16 (target, MX3_NF_FCMD, command); + target_write_u16(target, MX3_NF_FCMD, command); /* * start command input operation (set MX3_NF_BIT_OP_DONE==0) */ - target_write_u16 (target, MX3_NF_CFG2, MX3_NF_BIT_OP_FCI); + target_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FCI); { - int poll_result; - poll_result = poll_for_complete_op (target, "command"); - if (poll_result != ERROR_OK) - { - return poll_result; - } + int poll_result; + poll_result = poll_for_complete_op(target, "command"); + if (poll_result != ERROR_OK) + return poll_result; } /* * reset cursor to begin of the buffer */ sign_of_sequental_byte_read = 0; - switch (command) - { - case NAND_CMD_READID: - mx3_nf_info->optype = MX3_NF_DATAOUT_NANDID; - mx3_nf_info->fin = MX3_NF_FIN_DATAOUT; - break; - case NAND_CMD_STATUS: - mx3_nf_info->optype = MX3_NF_DATAOUT_NANDSTATUS; - mx3_nf_info->fin = MX3_NF_FIN_DATAOUT; - break; - case NAND_CMD_READ0: - mx3_nf_info->fin = MX3_NF_FIN_DATAOUT; - mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE; - break; - default: - mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE; + switch (command) { + case NAND_CMD_READID: + mx3_nf_info->optype = MX3_NF_DATAOUT_NANDID; + mx3_nf_info->fin = MX3_NF_FIN_DATAOUT; + break; + case NAND_CMD_STATUS: + mx3_nf_info->optype = MX3_NF_DATAOUT_NANDSTATUS; + mx3_nf_info->fin = MX3_NF_FIN_DATAOUT; + break; + case NAND_CMD_READ0: + mx3_nf_info->fin = MX3_NF_FIN_DATAOUT; + mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE; + break; + default: + mx3_nf_info->optype = MX3_NF_DATAOUT_PAGE; } return ERROR_OK; } -static int imx31_address (struct nand_device *nand, uint8_t address) +static int imx31_address(struct nand_device *nand, uint8_t address) { struct target *target = nand->target; { - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state (nand); - if (validate_target_result != ERROR_OK) - { - return validate_target_result; - } + /* + * validate target state + */ + int validate_target_result; + validate_target_result = validate_target_state(nand); + if (validate_target_result != ERROR_OK) + return validate_target_result; } - target_write_u16 (target, MX3_NF_FADDR, address); + target_write_u16(target, MX3_NF_FADDR, address); /* * start address input operation (set MX3_NF_BIT_OP_DONE==0) */ - target_write_u16 (target, MX3_NF_CFG2, MX3_NF_BIT_OP_FAI); + target_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FAI); { - int poll_result; - poll_result = poll_for_complete_op (target, "address"); - if (poll_result != ERROR_OK) - { - return poll_result; - } + int poll_result; + poll_result = poll_for_complete_op(target, "address"); + if (poll_result != ERROR_OK) + return poll_result; } return ERROR_OK; } -static int imx31_nand_ready (struct nand_device *nand, int tout) +static int imx31_nand_ready(struct nand_device *nand, int tout) { uint16_t poll_complete_status; struct target *target = nand->target; { - /* - * validate target state - */ - int validate_target_result; - validate_target_result = validate_target_state (nand); - if (validate_target_result != ERROR_OK) - { - return validate_target_result; - } - } - - do - { - target_read_u16 (target, MX3_NF_CFG2, &poll_complete_status); - if (poll_complete_status & MX3_NF_BIT_OP_DONE) - { - return tout; - } - alive_sleep (1); - } - while (tout-- > 0); + /* + * validate target state + */ + int validate_target_result; + validate_target_result = validate_target_state(nand); + if (validate_target_result != ERROR_OK) + return validate_target_result; + } + + do { + target_read_u16(target, MX3_NF_CFG2, &poll_complete_status); + if (poll_complete_status & MX3_NF_BIT_OP_DONE) + return tout; + alive_sleep(1); + } while (tout-- > 0); return tout; } -static int imx31_write_page (struct nand_device *nand, uint32_t page, - uint8_t * data, uint32_t data_size, uint8_t * oob, - uint32_t oob_size) +static int imx31_write_page(struct nand_device *nand, uint32_t page, + uint8_t *data, uint32_t data_size, uint8_t *oob, + uint32_t oob_size) { struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; struct target *target = nand->target; - if (data_size % 2) - { - LOG_ERROR (data_block_size_err_msg, data_size); - return ERROR_NAND_OPERATION_FAILED; + if (data_size % 2) { + LOG_ERROR(data_block_size_err_msg, data_size); + return ERROR_NAND_OPERATION_FAILED; } - if (oob_size % 2) - { - LOG_ERROR (data_block_size_err_msg, oob_size); - return ERROR_NAND_OPERATION_FAILED; - } - if (!data) - { - LOG_ERROR ("nothing to program"); - return ERROR_NAND_OPERATION_FAILED; + if (oob_size % 2) { + LOG_ERROR(data_block_size_err_msg, oob_size); + return ERROR_NAND_OPERATION_FAILED; } - { - /* - * validate target state - */ - int retval; - retval = validate_target_state (nand); - if (retval != ERROR_OK) - { - return retval; - } + if (!data) { + LOG_ERROR("nothing to program"); + return ERROR_NAND_OPERATION_FAILED; } { - int retval = ERROR_OK; - retval |= imx31_command(nand, NAND_CMD_SEQIN); - retval |= imx31_address(nand, 0x00); - retval |= imx31_address(nand, page & 0xff); - retval |= imx31_address(nand, (page >> 8) & 0xff); - if (nand->address_cycles >= 4) - { - retval |= imx31_address (nand, (page >> 16) & 0xff); - if (nand->address_cycles >= 5) - { - retval |= imx31_address (nand, (page >> 24) & 0xff); - } - } - target_write_buffer (target, MX3_NF_MAIN_BUFFER0, data_size, data); - if (oob) - { - if (mx3_nf_info->flags.hw_ecc_enabled) - { - /* - * part of spare block will be overrided by hardware - * ECC generator - */ - LOG_DEBUG - ("part of spare block will be overrided by hardware ECC generator"); - } - target_write_buffer (target, MX3_NF_SPARE_BUFFER0, oob_size, - oob); - } - /* - * start data input operation (set MX3_NF_BIT_OP_DONE==0) - */ - target_write_u16 (target, MX3_NF_CFG2, MX3_NF_BIT_OP_FDI); - { - int poll_result; - poll_result = poll_for_complete_op (target, "data input"); - if (poll_result != ERROR_OK) - { - return poll_result; + /* + * validate target state + */ + int retval; + retval = validate_target_state(nand); + if (retval != ERROR_OK) + return retval; + } + { + int retval = ERROR_OK; + retval |= imx31_command(nand, NAND_CMD_SEQIN); + retval |= imx31_address(nand, 0x00); + retval |= imx31_address(nand, page & 0xff); + retval |= imx31_address(nand, (page >> 8) & 0xff); + if (nand->address_cycles >= 4) { + retval |= imx31_address(nand, (page >> 16) & 0xff); + if (nand->address_cycles >= 5) + retval |= imx31_address(nand, (page >> 24) & 0xff); } - } - retval |= imx31_command (nand, NAND_CMD_PAGEPROG); - if (retval != ERROR_OK) - { - return retval; - } - - /* - * check status register - */ - { - uint16_t nand_status_content; - retval = ERROR_OK; - retval |= imx31_command(nand, NAND_CMD_STATUS); - retval |= imx31_address(nand, 0x00); - retval |= do_data_output(nand); - if (retval != ERROR_OK) + target_write_buffer(target, MX3_NF_MAIN_BUFFER0, data_size, data); + if (oob) { + if (mx3_nf_info->flags.hw_ecc_enabled) { + /* + * part of spare block will be overrided by hardware + * ECC generator + */ + LOG_DEBUG("part of spare block will be overrided by hardware ECC generator"); + } + target_write_buffer(target, MX3_NF_SPARE_BUFFER0, oob_size, oob); + } + /* + * start data input operation (set MX3_NF_BIT_OP_DONE==0) + */ + target_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FDI); { - LOG_ERROR (get_status_register_err_msg); - return retval; + int poll_result; + poll_result = poll_for_complete_op(target, "data input"); + if (poll_result != ERROR_OK) + return poll_result; } - target_read_u16 (target, MX3_NF_MAIN_BUFFER0, &nand_status_content); - if (nand_status_content & 0x0001) + retval |= imx31_command(nand, NAND_CMD_PAGEPROG); + if (retval != ERROR_OK) + return retval; + + /* + * check status register + */ { - /* - * is host-big-endian correctly ?? - */ - return ERROR_NAND_OPERATION_FAILED; + uint16_t nand_status_content; + retval = ERROR_OK; + retval |= imx31_command(nand, NAND_CMD_STATUS); + retval |= imx31_address(nand, 0x00); + retval |= do_data_output(nand); + if (retval != ERROR_OK) { + LOG_ERROR(get_status_register_err_msg); + return retval; + } + target_read_u16(target, MX3_NF_MAIN_BUFFER0, &nand_status_content); + if (nand_status_content & 0x0001) { + /* + * is host-big-endian correctly ?? + */ + return ERROR_NAND_OPERATION_FAILED; + } } } - } return ERROR_OK; } -static int imx31_read_page (struct nand_device *nand, uint32_t page, - uint8_t * data, uint32_t data_size, uint8_t * oob, - uint32_t oob_size) +static int imx31_read_page(struct nand_device *nand, uint32_t page, + uint8_t *data, uint32_t data_size, uint8_t *oob, + uint32_t oob_size) { struct target *target = nand->target; - if (data_size % 2) - { - LOG_ERROR (data_block_size_err_msg, data_size); - return ERROR_NAND_OPERATION_FAILED; + if (data_size % 2) { + LOG_ERROR(data_block_size_err_msg, data_size); + return ERROR_NAND_OPERATION_FAILED; } - if (oob_size % 2) - { - LOG_ERROR (data_block_size_err_msg, oob_size); - return ERROR_NAND_OPERATION_FAILED; + if (oob_size % 2) { + LOG_ERROR(data_block_size_err_msg, oob_size); + return ERROR_NAND_OPERATION_FAILED; } { - /* - * validate target state - */ - int retval; - retval = validate_target_state(nand); - if (retval != ERROR_OK) - { - return retval; - } - } - { - int retval = ERROR_OK; - retval |= imx31_command(nand, NAND_CMD_READ0); - retval |= imx31_address(nand, 0x00); - retval |= imx31_address(nand, page & 0xff); - retval |= imx31_address(nand, (page >> 8) & 0xff); - if (nand->address_cycles >= 4) - { - retval |= imx31_address(nand, (page >> 16) & 0xff); - if (nand->address_cycles >= 5) - { - retval |= imx31_address(nand, (page >> 24) & 0xff); - retval |= imx31_command(nand, NAND_CMD_READSTART); - } - } - retval |= do_data_output (nand); - if (retval != ERROR_OK) - { - return retval; - } - - if (data) - { - target_read_buffer (target, MX3_NF_MAIN_BUFFER0, data_size, - data); - } - if (oob) - { - target_read_buffer (target, MX3_NF_SPARE_BUFFER0, oob_size, - oob); - } + /* + * validate target state + */ + int retval; + retval = validate_target_state(nand); + if (retval != ERROR_OK) + return retval; + } + { + int retval = ERROR_OK; + retval |= imx31_command(nand, NAND_CMD_READ0); + retval |= imx31_address(nand, 0x00); + retval |= imx31_address(nand, page & 0xff); + retval |= imx31_address(nand, (page >> 8) & 0xff); + if (nand->address_cycles >= 4) { + retval |= imx31_address(nand, (page >> 16) & 0xff); + if (nand->address_cycles >= 5) { + retval |= imx31_address(nand, (page >> 24) & 0xff); + retval |= imx31_command(nand, NAND_CMD_READSTART); + } + } + retval |= do_data_output(nand); + if (retval != ERROR_OK) + return retval; + + if (data) { + target_read_buffer(target, MX3_NF_MAIN_BUFFER0, data_size, + data); + } + if (oob) { + target_read_buffer(target, MX3_NF_SPARE_BUFFER0, oob_size, + oob); + } } return ERROR_OK; } -static int test_iomux_settings (struct target * target, uint32_t address, - uint32_t mask, const char *text) +static int test_iomux_settings(struct target *target, uint32_t address, + uint32_t mask, const char *text) { uint32_t register_content; - target_read_u32 (target, address, ®ister_content); - if ((register_content & mask) != (0x12121212 & mask)) - { - LOG_ERROR ("IOMUX for {%s} is bad", text); - return ERROR_FAIL; + target_read_u32(target, address, ®ister_content); + if ((register_content & mask) != (0x12121212 & mask)) { + LOG_ERROR("IOMUX for {%s} is bad", text); + return ERROR_FAIL; } return ERROR_OK; } -static int initialize_nf_controller (struct nand_device *nand) +static int initialize_nf_controller(struct nand_device *nand) { struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; struct target *target = nand->target; /* * resets NAND flash controller in zero time ? I dont know. */ - target_write_u16 (target, MX3_NF_CFG1, MX3_NF_BIT_RESET_EN); + target_write_u16(target, MX3_NF_CFG1, MX3_NF_BIT_RESET_EN); { - uint16_t work_mode; - work_mode = MX3_NF_BIT_INT_DIS; /* disable interrupt */ - if (target->endianness == TARGET_BIG_ENDIAN) - { - work_mode |= MX3_NF_BIT_BE_EN; - } - if (mx3_nf_info->flags.hw_ecc_enabled) - { - work_mode |= MX3_NF_BIT_ECC_EN; - } - target_write_u16 (target, MX3_NF_CFG1, work_mode); + uint16_t work_mode; + work_mode = MX3_NF_BIT_INT_DIS; /* disable interrupt */ + if (target->endianness == TARGET_BIG_ENDIAN) + work_mode |= MX3_NF_BIT_BE_EN; + if (mx3_nf_info->flags.hw_ecc_enabled) + work_mode |= MX3_NF_BIT_ECC_EN; + target_write_u16(target, MX3_NF_CFG1, work_mode); } /* * unlock SRAM buffer for write; 2 mean "Unlock", other values means "Lock" */ - target_write_u16 (target, MX3_NF_BUFCFG, 2); + target_write_u16(target, MX3_NF_BUFCFG, 2); { - uint16_t temp; - target_read_u16 (target, MX3_NF_FWP, &temp); - if ((temp & 0x0007) == 1) - { - LOG_ERROR ("NAND flash is tight-locked, reset needed"); - return ERROR_FAIL; - } + uint16_t temp; + target_read_u16(target, MX3_NF_FWP, &temp); + if ((temp & 0x0007) == 1) { + LOG_ERROR("NAND flash is tight-locked, reset needed"); + return ERROR_FAIL; + } } /* * unlock NAND flash for write */ - target_write_u16 (target, MX3_NF_FWP, 4); - target_write_u16 (target, MX3_NF_LOCKSTART, 0x0000); - target_write_u16 (target, MX3_NF_LOCKEND, 0xFFFF); + target_write_u16(target, MX3_NF_FWP, 4); + target_write_u16(target, MX3_NF_LOCKSTART, 0x0000); + target_write_u16(target, MX3_NF_LOCKEND, 0xFFFF); /* * 0x0000 means that first SRAM buffer @0xB800_0000 will be used */ - target_write_u16 (target, MX3_NF_BUFADDR, 0x0000); + target_write_u16(target, MX3_NF_BUFADDR, 0x0000); /* * address of SRAM buffer */ @@ -689,176 +583,148 @@ static int initialize_nf_controller (struct nand_device *nand) return ERROR_OK; } -static int get_next_byte_from_sram_buffer (struct target * target, uint8_t * value) +static int get_next_byte_from_sram_buffer(struct target *target, uint8_t *value) { - static uint8_t even_byte = 0; + static uint8_t even_byte; /* * host-big_endian ?? */ if (sign_of_sequental_byte_read == 0) - { - even_byte = 0; - } - if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR) - { - LOG_ERROR (sram_buffer_bounds_err_msg, in_sram_address); - *value = 0; - sign_of_sequental_byte_read = 0; - even_byte = 0; - return ERROR_NAND_OPERATION_FAILED; - } - else - { - uint16_t temp; - target_read_u16 (target, in_sram_address, &temp); - if (even_byte) - { - *value = temp >> 8; - even_byte = 0; - in_sram_address += 2; - } - else - { - *value = temp & 0xff; - even_byte = 1; + even_byte = 0; + if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR) { + LOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address); + *value = 0; + sign_of_sequental_byte_read = 0; + even_byte = 0; + return ERROR_NAND_OPERATION_FAILED; + } else { + uint16_t temp; + target_read_u16(target, in_sram_address, &temp); + if (even_byte) { + *value = temp >> 8; + even_byte = 0; + in_sram_address += 2; + } else { + *value = temp & 0xff; + even_byte = 1; } } sign_of_sequental_byte_read = 1; return ERROR_OK; } -static int get_next_halfword_from_sram_buffer (struct target * target, - uint16_t * value) +static int get_next_halfword_from_sram_buffer(struct target *target, + uint16_t *value) { - if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR) - { - LOG_ERROR (sram_buffer_bounds_err_msg, in_sram_address); - *value = 0; - return ERROR_NAND_OPERATION_FAILED; - } - else - { - target_read_u16 (target, in_sram_address, value); - in_sram_address += 2; + if (in_sram_address > MX3_NF_LAST_BUFFER_ADDR) { + LOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address); + *value = 0; + return ERROR_NAND_OPERATION_FAILED; + } else { + target_read_u16(target, in_sram_address, value); + in_sram_address += 2; } return ERROR_OK; } -static int poll_for_complete_op (struct target * target, const char *text) +static int poll_for_complete_op(struct target *target, const char *text) { uint16_t poll_complete_status; - for (int poll_cycle_count = 0; poll_cycle_count < 100; poll_cycle_count++) - { - usleep (25); - target_read_u16 (target, MX3_NF_CFG2, &poll_complete_status); - if (poll_complete_status & MX3_NF_BIT_OP_DONE) - { - break; - } + for (int poll_cycle_count = 0; poll_cycle_count < 100; poll_cycle_count++) { + usleep(25); + target_read_u16(target, MX3_NF_CFG2, &poll_complete_status); + if (poll_complete_status & MX3_NF_BIT_OP_DONE) + break; } - if (!(poll_complete_status & MX3_NF_BIT_OP_DONE)) - { - LOG_ERROR ("%s sending timeout", text); - return ERROR_NAND_OPERATION_FAILED; + if (!(poll_complete_status & MX3_NF_BIT_OP_DONE)) { + LOG_ERROR("%s sending timeout", text); + return ERROR_NAND_OPERATION_FAILED; } return ERROR_OK; } -static int validate_target_state (struct nand_device *nand) +static int validate_target_state(struct nand_device *nand) { struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; struct target *target = nand->target; - if (target->state != TARGET_HALTED) - { - LOG_ERROR (target_not_halted_err_msg); - return ERROR_NAND_OPERATION_FAILED; + if (target->state != TARGET_HALTED) { + LOG_ERROR(target_not_halted_err_msg); + return ERROR_NAND_OPERATION_FAILED; } if (mx3_nf_info->flags.target_little_endian != - (target->endianness == TARGET_LITTLE_ENDIAN)) - { - /* - * endianness changed after NAND controller probed - */ - return ERROR_NAND_OPERATION_FAILED; + (target->endianness == TARGET_LITTLE_ENDIAN)) { + /* + * endianness changed after NAND controller probed + */ + return ERROR_NAND_OPERATION_FAILED; } return ERROR_OK; } -static int do_data_output (struct nand_device *nand) +static int do_data_output(struct nand_device *nand) { struct mx3_nf_controller *mx3_nf_info = nand->controller_priv; struct target *target = nand->target; - switch (mx3_nf_info->fin) - { - case MX3_NF_FIN_DATAOUT: - /* - * start data output operation (set MX3_NF_BIT_OP_DONE==0) - */ - target_write_u16 (target, MX3_NF_CFG2, - MX3_NF_BIT_DATAOUT_TYPE (mx3_nf_info-> - optype)); - { - int poll_result; - poll_result = poll_for_complete_op (target, "data output"); - if (poll_result != ERROR_OK) + switch (mx3_nf_info->fin) { + case MX3_NF_FIN_DATAOUT: + /* + * start data output operation (set MX3_NF_BIT_OP_DONE==0) + */ + target_write_u16 (target, MX3_NF_CFG2, + MX3_NF_BIT_DATAOUT_TYPE(mx3_nf_info->optype)); { - return poll_result; + int poll_result; + poll_result = poll_for_complete_op(target, "data output"); + if (poll_result != ERROR_OK) + return poll_result; } - } - mx3_nf_info->fin = MX3_NF_FIN_NONE; - /* - * ECC stuff - */ - if ((mx3_nf_info->optype == MX3_NF_DATAOUT_PAGE) - && mx3_nf_info->flags.hw_ecc_enabled) - { - uint16_t ecc_status; - target_read_u16 (target, MX3_NF_ECCSTATUS, &ecc_status); - switch (ecc_status & 0x000c) - { + mx3_nf_info->fin = MX3_NF_FIN_NONE; + /* + * ECC stuff + */ + if ((mx3_nf_info->optype == MX3_NF_DATAOUT_PAGE) + && mx3_nf_info->flags.hw_ecc_enabled) { + uint16_t ecc_status; + target_read_u16 (target, MX3_NF_ECCSTATUS, &ecc_status); + switch (ecc_status & 0x000c) { case 1 << 2: - LOG_DEBUG - ("main area readed with 1 (correctable) error"); - break; + LOG_DEBUG("main area readed with 1 (correctable) error"); + break; case 2 << 2: - LOG_DEBUG - ("main area readed with more than 1 (incorrectable) error"); - return ERROR_NAND_OPERATION_FAILED; - break; - } - switch (ecc_status & 0x0003) - { + LOG_DEBUG("main area readed with more than 1 (incorrectable) error"); + return ERROR_NAND_OPERATION_FAILED; + break; + } + switch (ecc_status & 0x0003) { case 1: - LOG_DEBUG - ("spare area readed with 1 (correctable) error"); - break; + LOG_DEBUG("spare area readed with 1 (correctable) error"); + break; case 2: - LOG_DEBUG - ("main area readed with more than 1 (incorrectable) error"); - return ERROR_NAND_OPERATION_FAILED; - break; - } - } - break; - case MX3_NF_FIN_NONE: - break; + LOG_DEBUG("main area readed with more than 1 (incorrectable) error"); + return ERROR_NAND_OPERATION_FAILED; + break; + } + } + break; + case MX3_NF_FIN_NONE: + break; } return ERROR_OK; } struct nand_flash_controller imx31_nand_flash_controller = { - .name = "imx31", - .usage = "nand device imx31 target noecc|hwecc", - .nand_device_command = &imx31_nand_device_command, - .init = &imx31_init, - .reset = &imx31_reset, - .command = &imx31_command, - .address = &imx31_address, - .write_data = &imx31_write_data, - .read_data = &imx31_read_data, - .write_page = &imx31_write_page, - .read_page = &imx31_read_page, - .nand_ready = &imx31_nand_ready, - }; + .name = "imx31", + .usage = "nand device imx31 target noecc|hwecc", + .nand_device_command = &imx31_nand_device_command, + .init = &imx31_init, + .reset = &imx31_reset, + .command = &imx31_command, + .address = &imx31_address, + .write_data = &imx31_write_data, + .read_data = &imx31_read_data, + .write_page = &imx31_write_page, + .read_page = &imx31_read_page, + .nand_ready = &imx31_nand_ready, +}; diff --git a/src/flash/nand/mx3.h b/src/flash/nand/mx3.h index c0a6184..1738ff7 100644 --- a/src/flash/nand/mx3.h +++ b/src/flash/nand/mx3.h @@ -1,4 +1,3 @@ - /*************************************************************************** * Copyright (C) 2009 by Alexei Babich * * Rezonans plc., Chelyabinsk, Russia * @@ -26,80 +25,77 @@ * Many thanks to Ben Dooks for writing s3c24xx driver. */ -#define MX3_NF_BASE_ADDR 0xb8000000 -#define MX3_NF_BUFSIZ (MX3_NF_BASE_ADDR + 0xe00) -#define MX3_NF_BUFADDR (MX3_NF_BASE_ADDR + 0xe04) -#define MX3_NF_FADDR (MX3_NF_BASE_ADDR + 0xe06) -#define MX3_NF_FCMD (MX3_NF_BASE_ADDR + 0xe08) -#define MX3_NF_BUFCFG (MX3_NF_BASE_ADDR + 0xe0a) -#define MX3_NF_ECCSTATUS (MX3_NF_BASE_ADDR + 0xe0c) -#define MX3_NF_ECCMAINPOS (MX3_NF_BASE_ADDR + 0xe0e) -#define MX3_NF_ECCSPAREPOS (MX3_NF_BASE_ADDR + 0xe10) -#define MX3_NF_FWP (MX3_NF_BASE_ADDR + 0xe12) -#define MX3_NF_LOCKSTART (MX3_NF_BASE_ADDR + 0xe14) -#define MX3_NF_LOCKEND (MX3_NF_BASE_ADDR + 0xe16) -#define MX3_NF_FWPSTATUS (MX3_NF_BASE_ADDR + 0xe18) - /* - * all bits not marked as self-clearing bit - */ -#define MX3_NF_CFG1 (MX3_NF_BASE_ADDR + 0xe1a) -#define MX3_NF_CFG2 (MX3_NF_BASE_ADDR + 0xe1c) +#define MX3_NF_BASE_ADDR 0xb8000000 +#define MX3_NF_BUFSIZ (MX3_NF_BASE_ADDR + 0xe00) +#define MX3_NF_BUFADDR (MX3_NF_BASE_ADDR + 0xe04) +#define MX3_NF_FADDR (MX3_NF_BASE_ADDR + 0xe06) +#define MX3_NF_FCMD (MX3_NF_BASE_ADDR + 0xe08) +#define MX3_NF_BUFCFG (MX3_NF_BASE_ADDR + 0xe0a) +#define MX3_NF_ECCSTATUS (MX3_NF_BASE_ADDR + 0xe0c) +#define MX3_NF_ECCMAINPOS (MX3_NF_BASE_ADDR + 0xe0e) +#define MX3_NF_ECCSPAREPOS (MX3_NF_BASE_ADDR + 0xe10) +#define MX3_NF_FWP (MX3_NF_BASE_ADDR + 0xe12) +#define MX3_NF_LOCKSTART (MX3_NF_BASE_ADDR + 0xe14) +#define MX3_NF_LOCKEND (MX3_NF_BASE_ADDR + 0xe16) +#define MX3_NF_FWPSTATUS (MX3_NF_BASE_ADDR + 0xe18) +/* + * all bits not marked as self-clearing bit + */ +#define MX3_NF_CFG1 (MX3_NF_BASE_ADDR + 0xe1a) +#define MX3_NF_CFG2 (MX3_NF_BASE_ADDR + 0xe1c) -#define MX3_NF_MAIN_BUFFER0 (MX3_NF_BASE_ADDR + 0x0000) -#define MX3_NF_MAIN_BUFFER1 (MX3_NF_BASE_ADDR + 0x0200) -#define MX3_NF_MAIN_BUFFER2 (MX3_NF_BASE_ADDR + 0x0400) -#define MX3_NF_MAIN_BUFFER3 (MX3_NF_BASE_ADDR + 0x0600) -#define MX3_NF_SPARE_BUFFER0 (MX3_NF_BASE_ADDR + 0x0800) -#define MX3_NF_SPARE_BUFFER1 (MX3_NF_BASE_ADDR + 0x0810) -#define MX3_NF_SPARE_BUFFER2 (MX3_NF_BASE_ADDR + 0x0820) -#define MX3_NF_SPARE_BUFFER3 (MX3_NF_BASE_ADDR + 0x0830) -#define MX3_NF_MAIN_BUFFER_LEN 512 -#define MX3_NF_SPARE_BUFFER_LEN 16 -#define MX3_NF_LAST_BUFFER_ADDR ((MX3_NF_SPARE_BUFFER3) + MX3_NF_SPARE_BUFFER_LEN - 2) +#define MX3_NF_MAIN_BUFFER0 (MX3_NF_BASE_ADDR + 0x0000) +#define MX3_NF_MAIN_BUFFER1 (MX3_NF_BASE_ADDR + 0x0200) +#define MX3_NF_MAIN_BUFFER2 (MX3_NF_BASE_ADDR + 0x0400) +#define MX3_NF_MAIN_BUFFER3 (MX3_NF_BASE_ADDR + 0x0600) +#define MX3_NF_SPARE_BUFFER0 (MX3_NF_BASE_ADDR + 0x0800) +#define MX3_NF_SPARE_BUFFER1 (MX3_NF_BASE_ADDR + 0x0810) +#define MX3_NF_SPARE_BUFFER2 (MX3_NF_BASE_ADDR + 0x0820) +#define MX3_NF_SPARE_BUFFER3 (MX3_NF_BASE_ADDR + 0x0830) +#define MX3_NF_MAIN_BUFFER_LEN 512 +#define MX3_NF_SPARE_BUFFER_LEN 16 +#define MX3_NF_LAST_BUFFER_ADDR ((MX3_NF_SPARE_BUFFER3) + MX3_NF_SPARE_BUFFER_LEN - 2) /* bits in MX3_NF_CFG1 register */ -#define MX3_NF_BIT_SPARE_ONLY_EN (1<<2) -#define MX3_NF_BIT_ECC_EN (1<<3) -#define MX3_NF_BIT_INT_DIS (1<<4) -#define MX3_NF_BIT_BE_EN (1<<5) -#define MX3_NF_BIT_RESET_EN (1<<6) -#define MX3_NF_BIT_FORCE_CE (1<<7) +#define MX3_NF_BIT_SPARE_ONLY_EN (1<<2) +#define MX3_NF_BIT_ECC_EN (1<<3) +#define MX3_NF_BIT_INT_DIS (1<<4) +#define MX3_NF_BIT_BE_EN (1<<5) +#define MX3_NF_BIT_RESET_EN (1<<6) +#define MX3_NF_BIT_FORCE_CE (1<<7) /* bits in MX3_NF_CFG2 register */ /*Flash Command Input*/ -#define MX3_NF_BIT_OP_FCI (1<<0) - /* - * Flash Address Input - */ -#define MX3_NF_BIT_OP_FAI (1<<1) - /* - * Flash Data Input - */ -#define MX3_NF_BIT_OP_FDI (1<<2) +#define MX3_NF_BIT_OP_FCI (1<<0) +/* + * Flash Address Input + */ +#define MX3_NF_BIT_OP_FAI (1<<1) +/* + * Flash Data Input + */ +#define MX3_NF_BIT_OP_FDI (1<<2) /* see "enum mx_dataout_type" below */ -#define MX3_NF_BIT_DATAOUT_TYPE(x) ((x)<<3) -#define MX3_NF_BIT_OP_DONE (1<<15) +#define MX3_NF_BIT_DATAOUT_TYPE(x) ((x)<<3) +#define MX3_NF_BIT_OP_DONE (1<<15) -#define MX3_CCM_CGR2 0x53f80028 -#define MX3_GPR 0x43fac008 -#define MX3_PCSR 0x53f8000c +#define MX3_CCM_CGR2 0x53f80028 +#define MX3_GPR 0x43fac008 +#define MX3_PCSR 0x53f8000c -enum mx_dataout_type -{ +enum mx_dataout_type { MX3_NF_DATAOUT_PAGE = 1, MX3_NF_DATAOUT_NANDID = 2, MX3_NF_DATAOUT_NANDSTATUS = 4, }; -enum mx_nf_finalize_action -{ +enum mx_nf_finalize_action { MX3_NF_FIN_NONE, MX3_NF_FIN_DATAOUT, }; -struct mx3_nf_flags -{ +struct mx3_nf_flags { unsigned host_little_endian:1; unsigned target_little_endian:1; unsigned nand_readonly:1; @@ -107,8 +103,7 @@ struct mx3_nf_flags unsigned hw_ecc_enabled:1; }; -struct mx3_nf_controller -{ +struct mx3_nf_controller { enum mx_dataout_type optype; enum mx_nf_finalize_action fin; struct mx3_nf_flags flags; diff --git a/src/flash/nand/mxc.c b/src/flash/nand/mxc.c index 3017019..dd6d6c7 100644 --- a/src/flash/nand/mxc.c +++ b/src/flash/nand/mxc.c @@ -49,12 +49,12 @@ #include "mxc.h" #include <target/target.h> -#define OOB_SIZE 64 +#define OOB_SIZE 64 #define nfc_is_v1() (mxc_nf_info->mxc_version == MXC_VERSION_MX27 || \ - mxc_nf_info->mxc_version == MXC_VERSION_MX31) + mxc_nf_info->mxc_version == MXC_VERSION_MX31) #define nfc_is_v2() (mxc_nf_info->mxc_version == MXC_VERSION_MX25 || \ - mxc_nf_info->mxc_version == MXC_VERSION_MX35) + mxc_nf_info->mxc_version == MXC_VERSION_MX35) /* This permits to print (in LOG_INFO) how much bytes * has been written after a page read or write. @@ -136,7 +136,7 @@ NAND_DEVICE_COMMAND_HANDLER(mxc_nand_device_command) mxc_nf_info->optype = MXC_NF_DATAOUT_PAGE; mxc_nf_info->fin = MXC_NF_FIN_NONE; mxc_nf_info->flags.target_little_endian = - (nand->target->endianness == TARGET_LITTLE_ENDIAN); + (nand->target->endianness == TARGET_LITTLE_ENDIAN); /* * should factory bad block indicator be swaped @@ -190,9 +190,9 @@ COMMAND_HANDLER(handle_mxc_biswap_command) static const struct command_registration mxc_sub_command_handlers[] = { { .name = "biswap", - .handler = handle_mxc_biswap_command , + .handler = handle_mxc_biswap_command, .help = "Turns on/off bad block information swaping from main area, " - "without parameter query status.", + "without parameter query status.", .usage = "bank_id ['enable'|'disable']", }, COMMAND_REGISTRATION_DONE @@ -262,18 +262,17 @@ static int mxc_init(struct nand_device *nand) else LOG_DEBUG("MXC_NF : bus is 8-bit width"); - if (!nand->page_size) { + if (!nand->page_size) nand->page_size = (sreg_content & SEL_FMS) ? 2048 : 512; - } else { + else { sreg_content |= ((nand->page_size == 2048) ? SEL_FMS : 0x00000000); target_write_u32(target, SREG, sreg_content); } if (mxc_nf_info->flags.one_kb_sram && (nand->page_size == 2048)) { LOG_ERROR("NAND controller have only 1 kb SRAM, so " - "pagesize 2048 is incompatible with it"); - } else { + "pagesize 2048 is incompatible with it"); + } else LOG_DEBUG("MXC_NF : NAND controller can handle pagesize of 2048"); - } if (nfc_is_v2() && sreg_content & MX35_RCSR_NF_4K) LOG_ERROR("MXC driver does not have support for 4k pagesize."); @@ -292,9 +291,8 @@ static int mxc_init(struct nand_device *nand) if (!(nand_status_content & 0x0080)) { LOG_INFO("NAND read-only"); mxc_nf_info->flags.nand_readonly = 1; - } else { + } else mxc_nf_info->flags.nand_readonly = 0; - } return ERROR_OK; } @@ -315,7 +313,7 @@ static int mxc_read_data(struct nand_device *nand, void *data) try_data_output_from_nand_chip = do_data_output(nand); if (try_data_output_from_nand_chip != ERROR_OK) { LOG_ERROR("mxc_read_data : read data failed : '%x'", - try_data_output_from_nand_chip); + try_data_output_from_nand_chip); return try_data_output_from_nand_chip; } @@ -360,26 +358,26 @@ static int mxc_command(struct nand_device *nand, uint8_t command) return validate_target_result; switch (command) { - case NAND_CMD_READOOB: - command = NAND_CMD_READ0; - /* set read point for data_read() and read_block_data() to - * spare area in SRAM buffer - */ - if (nfc_is_v1()) - in_sram_address = MXC_NF_V1_SPARE_BUFFER0; - else - in_sram_address = MXC_NF_V2_SPARE_BUFFER0; - break; - case NAND_CMD_READ1: - command = NAND_CMD_READ0; - /* - * offset == one half of page size - */ - in_sram_address = MXC_NF_MAIN_BUFFER0 + (nand->page_size >> 1); - break; - default: - in_sram_address = MXC_NF_MAIN_BUFFER0; - break; + case NAND_CMD_READOOB: + command = NAND_CMD_READ0; + /* set read point for data_read() and read_block_data() to + * spare area in SRAM buffer + */ + if (nfc_is_v1()) + in_sram_address = MXC_NF_V1_SPARE_BUFFER0; + else + in_sram_address = MXC_NF_V2_SPARE_BUFFER0; + break; + case NAND_CMD_READ1: + command = NAND_CMD_READ0; + /* + * offset == one half of page size + */ + in_sram_address = MXC_NF_MAIN_BUFFER0 + (nand->page_size >> 1); + break; + default: + in_sram_address = MXC_NF_MAIN_BUFFER0; + break; } target_write_u16(target, MXC_NF_FCMD, command); @@ -396,24 +394,24 @@ static int mxc_command(struct nand_device *nand, uint8_t command) sign_of_sequental_byte_read = 0; /* Handle special read command and adjust NF_CFG2(FDO) */ switch (command) { - case NAND_CMD_READID: - mxc_nf_info->optype = MXC_NF_DATAOUT_NANDID; - mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; - break; - case NAND_CMD_STATUS: - mxc_nf_info->optype = MXC_NF_DATAOUT_NANDSTATUS; - mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; - target_write_u16 (target, MXC_NF_BUFADDR, 0); - in_sram_address = 0; - break; - case NAND_CMD_READ0: - mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; - mxc_nf_info->optype = MXC_NF_DATAOUT_PAGE; - break; - default: - /* Ohter command use the default 'One page data out' FDO */ - mxc_nf_info->optype = MXC_NF_DATAOUT_PAGE; - break; + case NAND_CMD_READID: + mxc_nf_info->optype = MXC_NF_DATAOUT_NANDID; + mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; + break; + case NAND_CMD_STATUS: + mxc_nf_info->optype = MXC_NF_DATAOUT_NANDSTATUS; + mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; + target_write_u16 (target, MXC_NF_BUFADDR, 0); + in_sram_address = 0; + break; + case NAND_CMD_READ0: + mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; + mxc_nf_info->optype = MXC_NF_DATAOUT_PAGE; + break; + default: + /* Ohter command use the default 'One page data out' FDO */ + mxc_nf_info->optype = MXC_NF_DATAOUT_PAGE; + break; } return ERROR_OK; } @@ -463,14 +461,13 @@ static int mxc_nand_ready(struct nand_device *nand, int tout) return tout; alive_sleep(1); - } - while (tout-- > 0); + } while (tout-- > 0); return tout; } static int mxc_write_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size) { struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; struct target *target = nand->target; @@ -504,11 +501,11 @@ static int mxc_write_page(struct nand_device *nand, uint32_t page, sign_of_sequental_byte_read = 0; retval = ERROR_OK; retval |= mxc_command(nand, NAND_CMD_SEQIN); - retval |= mxc_address(nand, 0); /* col */ - retval |= mxc_address(nand, 0); /* col */ - retval |= mxc_address(nand, page & 0xff); /* page address */ - retval |= mxc_address(nand, (page >> 8) & 0xff); /* page address */ - retval |= mxc_address(nand, (page >> 16) & 0xff); /* page address */ + retval |= mxc_address(nand, 0); /* col */ + retval |= mxc_address(nand, 0); /* col */ + retval |= mxc_address(nand, page & 0xff); /* page address */ + retval |= mxc_address(nand, (page >> 8) & 0xff);/* page address */ + retval |= mxc_address(nand, (page >> 16) & 0xff); /* page address */ target_write_buffer(target, MXC_NF_MAIN_BUFFER0, data_size, data); if (oob) { @@ -518,7 +515,7 @@ static int mxc_write_page(struct nand_device *nand, uint32_t page, * ECC generator */ LOG_DEBUG("part of spare block will be overrided " - "by hardware ECC generator"); + "by hardware ECC generator"); } if (nfc_is_v1()) target_write_buffer(target, MXC_NF_V1_SPARE_BUFFER0, oob_size, oob); @@ -541,7 +538,7 @@ static int mxc_write_page(struct nand_device *nand, uint32_t page, LOG_ERROR("Due to NFC Bug, oob is not correctly implemented in mxc driver"); return ERROR_NAND_OPERATION_FAILED; } - swap2 = 0xffff; /* Spare buffer unused forced to 0xffff */ + swap2 = 0xffff; /* Spare buffer unused forced to 0xffff */ new_swap1 = (swap1 & 0xFF00) | (swap2 >> 8); swap2 = (swap1 << 8) | (swap2 & 0xFF); target_write_u16(target, MXC_NF_MAIN_BUFFER3 + 464, new_swap1); @@ -559,7 +556,7 @@ static int mxc_write_page(struct nand_device *nand, uint32_t page, else bufs = 1; - for (uint8_t i = 0 ; i < bufs ; ++i) { + for (uint8_t i = 0; i < bufs; ++i) { target_write_u16(target, MXC_NF_BUFADDR, i); target_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_OP_FDI); poll_result = poll_for_complete_op(nand, "data input"); @@ -598,8 +595,8 @@ static int mxc_write_page(struct nand_device *nand, uint32_t page, } static int mxc_read_page(struct nand_device *nand, uint32_t page, - uint8_t *data, uint32_t data_size, - uint8_t *oob, uint32_t oob_size) + uint8_t *data, uint32_t data_size, + uint8_t *oob, uint32_t oob_size) { struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; struct target *target = nand->target; @@ -620,31 +617,37 @@ static int mxc_read_page(struct nand_device *nand, uint32_t page, * validate target state */ retval = validate_target_state(nand); - if (retval != ERROR_OK) { + if (retval != ERROR_OK) return retval; - } - /* Reset address_cycles before mxc_command ?? */ + /* Reset address_cycles before mxc_command ?? */ retval = mxc_command(nand, NAND_CMD_READ0); - if (retval != ERROR_OK) return retval; - retval = mxc_address(nand, 0); /* col */ - if (retval != ERROR_OK) return retval; - retval = mxc_address(nand, 0); /* col */ - if (retval != ERROR_OK) return retval; - retval = mxc_address(nand, page & 0xff); /* page address */ - if (retval != ERROR_OK) return retval; - retval = mxc_address(nand, (page >> 8) & 0xff); /* page address */ - if (retval != ERROR_OK) return retval; - retval = mxc_address(nand, (page >> 16) & 0xff); /* page address */ - if (retval != ERROR_OK) return retval; + if (retval != ERROR_OK) + return retval; + retval = mxc_address(nand, 0); /* col */ + if (retval != ERROR_OK) + return retval; + retval = mxc_address(nand, 0); /* col */ + if (retval != ERROR_OK) + return retval; + retval = mxc_address(nand, page & 0xff);/* page address */ + if (retval != ERROR_OK) + return retval; + retval = mxc_address(nand, (page >> 8) & 0xff); /* page address */ + if (retval != ERROR_OK) + return retval; + retval = mxc_address(nand, (page >> 16) & 0xff);/* page address */ + if (retval != ERROR_OK) + return retval; retval = mxc_command(nand, NAND_CMD_READSTART); - if (retval != ERROR_OK) return retval; + if (retval != ERROR_OK) + return retval; if (nfc_is_v1() && nand->page_size > 512) bufs = 4; else bufs = 1; - for (uint8_t i = 0 ; i < bufs ; ++i) { + for (uint8_t i = 0; i < bufs; ++i) { target_write_u16(target, MXC_NF_BUFADDR, i); mxc_nf_info->fin = MXC_NF_FIN_DATAOUT; retval = do_data_output(nand); @@ -702,9 +705,9 @@ static uint32_t align_address_v2(struct nand_device *nand, uint32_t addr) struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; uint32_t ret = addr; if (addr > MXC_NF_V2_SPARE_BUFFER0 && - (addr & 0x1F) == MXC_NF_SPARE_BUFFER_LEN) { + (addr & 0x1F) == MXC_NF_SPARE_BUFFER_LEN) ret += MXC_NF_SPARE_BUFFER_MAX - MXC_NF_SPARE_BUFFER_LEN; - } else if (addr >= (mxc_nf_info->mxc_base_addr + (uint32_t)nand->page_size)) + else if (addr >= (mxc_nf_info->mxc_base_addr + (uint32_t)nand->page_size)) ret = MXC_NF_V2_SPARE_BUFFER0; return ret; } @@ -725,15 +728,13 @@ static int initialize_nf_controller(struct nand_device *nand) if (target->endianness == TARGET_BIG_ENDIAN) { LOG_DEBUG("MXC_NF : work in Big Endian mode"); work_mode |= MXC_NF_BIT_BE_EN; - } else { + } else LOG_DEBUG("MXC_NF : work in Little Endian mode"); - } if (mxc_nf_info->flags.hw_ecc_enabled) { LOG_DEBUG("MXC_NF : work with ECC mode"); work_mode |= MXC_NF_BIT_ECC_EN; - } else { + } else LOG_DEBUG("MXC_NF : work without ECC mode"); - } if (nfc_is_v2()) { target_write_u16(target, MXC_NF_V2_SPAS, OOB_SIZE / 2); if (nand->page_size) { @@ -788,7 +789,7 @@ static int get_next_byte_from_sram_buffer(struct nand_device *nand, uint8_t *val { struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; struct target *target = nand->target; - static uint8_t even_byte = 0; + static uint8_t even_byte; uint16_t temp; /* * host-big_endian ?? @@ -796,8 +797,7 @@ static int get_next_byte_from_sram_buffer(struct nand_device *nand, uint8_t *val if (sign_of_sequental_byte_read == 0) even_byte = 0; - if (in_sram_address > - (nfc_is_v1() ? MXC_NF_V1_LAST_BUFFADDR : MXC_NF_V2_LAST_BUFFADDR)) { + if (in_sram_address > (nfc_is_v1() ? MXC_NF_V1_LAST_BUFFADDR : MXC_NF_V2_LAST_BUFFADDR)) { LOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address); *value = 0; sign_of_sequental_byte_read = 0; @@ -826,8 +826,7 @@ static int get_next_halfword_from_sram_buffer(struct nand_device *nand, uint16_t struct mxc_nf_controller *mxc_nf_info = nand->controller_priv; struct target *target = nand->target; - if (in_sram_address > - (nfc_is_v1() ? MXC_NF_V1_LAST_BUFFADDR : MXC_NF_V2_LAST_BUFFADDR)) { + if (in_sram_address > (nfc_is_v1() ? MXC_NF_V1_LAST_BUFFADDR : MXC_NF_V2_LAST_BUFFADDR)) { LOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address); *value = 0; return ERROR_NAND_OPERATION_FAILED; @@ -861,7 +860,7 @@ static int validate_target_state(struct nand_device *nand) } if (mxc_nf_info->flags.target_little_endian != - (target->endianness == TARGET_LITTLE_ENDIAN)) { + (target->endianness == TARGET_LITTLE_ENDIAN)) { /* * endianness changed after NAND controller probed */ @@ -878,22 +877,22 @@ int ecc_status_v1(struct nand_device *nand) target_read_u16(target, MXC_NF_ECCSTATUS, &ecc_status); switch (ecc_status & 0x000c) { - case 1 << 2: - LOG_INFO("main area read with 1 (correctable) error"); - break; - case 2 << 2: - LOG_INFO("main area read with more than 1 (incorrectable) error"); - return ERROR_NAND_OPERATION_FAILED; - break; + case 1 << 2: + LOG_INFO("main area read with 1 (correctable) error"); + break; + case 2 << 2: + LOG_INFO("main area read with more than 1 (incorrectable) error"); + return ERROR_NAND_OPERATION_FAILED; + break; } switch (ecc_status & 0x0003) { - case 1: - LOG_INFO("spare area read with 1 (correctable) error"); - break; - case 2: - LOG_INFO("main area read with more than 1 (incorrectable) error"); - return ERROR_NAND_OPERATION_FAILED; - break; + case 1: + LOG_INFO("spare area read with 1 (correctable) error"); + break; + case 2: + LOG_INFO("main area read with more than 1 (incorrectable) error"); + return ERROR_NAND_OPERATION_FAILED; + break; } return ERROR_OK; } @@ -927,47 +926,46 @@ static int do_data_output(struct nand_device *nand) struct target *target = nand->target; int poll_result; switch (mxc_nf_info->fin) { - case MXC_NF_FIN_DATAOUT: - /* - * start data output operation (set MXC_NF_BIT_OP_DONE==0) - */ - target_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_DATAOUT_TYPE(mxc_nf_info->optype)); - poll_result = poll_for_complete_op(nand, "data output"); - if (poll_result != ERROR_OK) - return poll_result; + case MXC_NF_FIN_DATAOUT: + /* + * start data output operation (set MXC_NF_BIT_OP_DONE==0) + */ + target_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_DATAOUT_TYPE(mxc_nf_info->optype)); + poll_result = poll_for_complete_op(nand, "data output"); + if (poll_result != ERROR_OK) + return poll_result; - mxc_nf_info->fin = MXC_NF_FIN_NONE; - /* - * ECC stuff - */ - if (mxc_nf_info->optype == MXC_NF_DATAOUT_PAGE && - mxc_nf_info->flags.hw_ecc_enabled) { - int ecc_status; - if (nfc_is_v1()) - ecc_status = ecc_status_v1(nand); - else - ecc_status = ecc_status_v2(nand); - if (ecc_status != ERROR_OK) - return ecc_status; - } - break; - case MXC_NF_FIN_NONE: - break; + mxc_nf_info->fin = MXC_NF_FIN_NONE; + /* + * ECC stuff + */ + if (mxc_nf_info->optype == MXC_NF_DATAOUT_PAGE && mxc_nf_info->flags.hw_ecc_enabled) { + int ecc_status; + if (nfc_is_v1()) + ecc_status = ecc_status_v1(nand); + else + ecc_status = ecc_status_v2(nand); + if (ecc_status != ERROR_OK) + return ecc_status; + } + break; + case MXC_NF_FIN_NONE: + break; } return ERROR_OK; } struct nand_flash_controller mxc_nand_flash_controller = { - .name = "mxc", - .nand_device_command = &mxc_nand_device_command, - .commands = mxc_nand_command_handler, - .init = &mxc_init, - .reset = &mxc_reset, - .command = &mxc_command, - .address = &mxc_address, - .write_data = &mxc_write_data, - .read_data = &mxc_read_data, - .write_page = &mxc_write_page, - .read_page = &mxc_read_page, - .nand_ready = &mxc_nand_ready, + .name = "mxc", + .nand_device_command = &mxc_nand_device_command, + .commands = mxc_nand_command_handler, + .init = &mxc_init, + .reset = &mxc_reset, + .command = &mxc_command, + .address = &mxc_address, + .write_data = &mxc_write_data, + .read_data = &mxc_read_data, + .write_page = &mxc_write_page, + .read_page = &mxc_read_page, + .nand_ready = &mxc_nand_ready, }; diff --git a/src/flash/nand/nonce.c b/src/flash/nand/nonce.c index 565ad72..76ed526 100644 --- a/src/flash/nand/nonce.c +++ b/src/flash/nand/nonce.c @@ -24,7 +24,6 @@ #include "imp.h" #include "hello.h" - static int nonce_nand_command(struct nand_device *nand, uint8_t command) { return ERROR_OK; @@ -62,16 +61,15 @@ static int nonce_nand_init(struct nand_device *nand) return ERROR_OK; } -struct nand_flash_controller nonce_nand_controller = -{ - .name = "nonce", - .commands = hello_command_handlers, - .nand_device_command = &nonce_nand_device_command, - .init = &nonce_nand_init, - .reset = &nonce_nand_reset, - .command = &nonce_nand_command, - .address = &nonce_nand_address, - .read_data = &nonce_nand_read, - .write_data = &nonce_nand_write, - .write_block_data = &nonce_nand_fast_block_write, +struct nand_flash_controller nonce_nand_controller = { + .name = "nonce", + .commands = hello_command_handlers, + .nand_device_command = &nonce_nand_device_command, + .init = &nonce_nand_init, + .reset = &nonce_nand_reset, + .command = &nonce_nand_command, + .address = &nonce_nand_address, + .read_data = &nonce_nand_read, + .write_data = &nonce_nand_write, + .write_block_data = &nonce_nand_fast_block_write, }; diff --git a/src/flash/nand/nuc910.c b/src/flash/nand/nuc910.c index 7b598d2..d8ef67b 100644 --- a/src/flash/nand/nuc910.c +++ b/src/flash/nand/nuc910.c @@ -31,8 +31,7 @@ #include "arm_io.h" #include <target/arm.h> -struct nuc910_nand_controller -{ +struct nuc910_nand_controller { struct arm_nand_data io; }; @@ -53,7 +52,8 @@ static int nuc910_nand_command(struct nand_device *nand, uint8_t command) struct target *target = nand->target; int result; - if ((result = validate_target_state(nand)) != ERROR_OK) + result = validate_target_state(nand); + if (result != ERROR_OK) return result; target_write_u8(target, NUC910_SMCMD, command); @@ -65,7 +65,8 @@ static int nuc910_nand_address(struct nand_device *nand, uint8_t address) struct target *target = nand->target; int result; - if ((result = validate_target_state(nand)) != ERROR_OK) + result = validate_target_state(nand); + if (result != ERROR_OK) return result; target_write_u32(target, NUC910_SMADDR, ((address & 0xff) | NUC910_SMADDR_EOA)); @@ -77,7 +78,8 @@ static int nuc910_nand_read(struct nand_device *nand, void *data) struct target *target = nand->target; int result; - if ((result = validate_target_state(nand)) != ERROR_OK) + result = validate_target_state(nand); + if (result != ERROR_OK) return result; target_read_u8(target, NUC910_SMDATA, data); @@ -89,7 +91,8 @@ static int nuc910_nand_write(struct nand_device *nand, uint16_t data) struct target *target = nand->target; int result; - if ((result = validate_target_state(nand)) != ERROR_OK) + result = validate_target_state(nand); + if (result != ERROR_OK) return result; target_write_u8(target, NUC910_SMDATA, data); @@ -102,7 +105,8 @@ static int nuc910_nand_read_block_data(struct nand_device *nand, struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; int result; - if ((result = validate_target_state(nand)) != ERROR_OK) + result = validate_target_state(nand); + if (result != ERROR_OK) return result; nuc910_nand->io.chunk_size = nand->page_size; @@ -125,7 +129,8 @@ static int nuc910_nand_write_block_data(struct nand_device *nand, struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; int result; - if ((result = validate_target_state(nand)) != ERROR_OK) + result = validate_target_state(nand); + if (result != ERROR_OK) return result; nuc910_nand->io.chunk_size = nand->page_size; @@ -154,9 +159,8 @@ static int nuc910_nand_ready(struct nand_device *nand, int timeout) do { target_read_u32(target, NUC910_SMISR, &status); - if (status & NUC910_SMISR_RB_) { + if (status & NUC910_SMISR_RB_) return 1; - } alive_sleep(1); } while (timeout-- > 0); @@ -184,12 +188,12 @@ static int nuc910_nand_init(struct nand_device *nand) int bus_width = nand->bus_width ? : 8; int result; - if ((result = validate_target_state(nand)) != ERROR_OK) + result = validate_target_state(nand); + if (result != ERROR_OK) return result; /* nuc910 only supports 8bit */ - if (bus_width != 8) - { + if (bus_width != 8) { LOG_ERROR("nuc910 only supports 8 bit bus width, not %i", bus_width); return ERROR_NAND_OPERATION_NOT_SUPPORTED; } @@ -210,8 +214,7 @@ static int nuc910_nand_init(struct nand_device *nand) return ERROR_OK; } -struct nand_flash_controller nuc910_nand_controller = -{ +struct nand_flash_controller nuc910_nand_controller = { .name = "nuc910", .command = nuc910_nand_command, .address = nuc910_nand_address, diff --git a/src/flash/nand/orion.c b/src/flash/nand/orion.c index e6a33eb..52c5a5d 100644 --- a/src/flash/nand/orion.c +++ b/src/flash/nand/orion.c @@ -30,9 +30,7 @@ #include "arm_io.h" #include <target/arm.h> - -struct orion_nand_controller -{ +struct orion_nand_controller { struct arm_nand_data io; uint32_t cmd; @@ -120,9 +118,8 @@ NAND_DEVICE_COMMAND_HANDLER(orion_nand_device_command) uint32_t base; uint8_t ale, cle; - if (CMD_ARGC != 3) { + if (CMD_ARGC != 3) return ERROR_COMMAND_SYNTAX_ERROR; - } hw = calloc(1, sizeof(*hw)); if (!hw) { @@ -152,17 +149,15 @@ static int orion_nand_init(struct nand_device *nand) return ERROR_OK; } -struct nand_flash_controller orion_nand_controller = -{ - .name = "orion", - .usage = "<target_id> <NAND_address>", - .command = orion_nand_command, - .address = orion_nand_address, - .read_data = orion_nand_read, - .write_data = orion_nand_write, - .write_block_data = orion_nand_fast_block_write, - .reset = orion_nand_reset, - .nand_device_command = orion_nand_device_command, - .init = orion_nand_init, +struct nand_flash_controller orion_nand_controller = { + .name = "orion", + .usage = "<target_id> <NAND_address>", + .command = orion_nand_command, + .address = orion_nand_address, + .read_data = orion_nand_read, + .write_data = orion_nand_write, + .write_block_data = orion_nand_fast_block_write, + .reset = orion_nand_reset, + .nand_device_command = orion_nand_device_command, + .init = orion_nand_init, }; - diff --git a/src/flash/nand/s3c2410.c b/src/flash/nand/s3c2410.c index e998f65..4cda857 100644 --- a/src/flash/nand/s3c2410.c +++ b/src/flash/nand/s3c2410.c @@ -104,15 +104,15 @@ static int s3c2410_nand_ready(struct nand_device *nand, int timeout) } struct nand_flash_controller s3c2410_nand_controller = { - .name = "s3c2410", - .nand_device_command = &s3c2410_nand_device_command, - .init = &s3c2410_init, - .reset = &s3c24xx_reset, - .command = &s3c24xx_command, - .address = &s3c24xx_address, - .write_data = &s3c2410_write_data, - .read_data = &s3c2410_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .nand_ready = &s3c2410_nand_ready, - }; + .name = "s3c2410", + .nand_device_command = &s3c2410_nand_device_command, + .init = &s3c2410_init, + .reset = &s3c24xx_reset, + .command = &s3c24xx_command, + .address = &s3c24xx_address, + .write_data = &s3c2410_write_data, + .read_data = &s3c2410_read_data, + .write_page = s3c24xx_write_page, + .read_page = s3c24xx_read_page, + .nand_ready = &s3c2410_nand_ready, +}; diff --git a/src/flash/nand/s3c2412.c b/src/flash/nand/s3c2412.c index 7f4357e..c0203bd 100644 --- a/src/flash/nand/s3c2412.c +++ b/src/flash/nand/s3c2412.c @@ -61,17 +61,17 @@ static int s3c2412_init(struct nand_device *nand) } struct nand_flash_controller s3c2412_nand_controller = { - .name = "s3c2412", - .nand_device_command = &s3c2412_nand_device_command, - .init = &s3c2412_init, - .reset = &s3c24xx_reset, - .command = &s3c24xx_command, - .address = &s3c24xx_address, - .write_data = &s3c24xx_write_data, - .read_data = &s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = &s3c2440_write_block_data, - .read_block_data = &s3c2440_read_block_data, - .nand_ready = &s3c2440_nand_ready, - }; + .name = "s3c2412", + .nand_device_command = &s3c2412_nand_device_command, + .init = &s3c2412_init, + .reset = &s3c24xx_reset, + .command = &s3c24xx_command, + .address = &s3c24xx_address, + .write_data = &s3c24xx_write_data, + .read_data = &s3c24xx_read_data, + .write_page = s3c24xx_write_page, + .read_page = s3c24xx_read_page, + .write_block_data = &s3c2440_write_block_data, + .read_block_data = &s3c2440_read_block_data, + .nand_ready = &s3c2440_nand_ready, +}; diff --git a/src/flash/nand/s3c2440.c b/src/flash/nand/s3c2440.c index 072683a..440993c 100644 --- a/src/flash/nand/s3c2440.c +++ b/src/flash/nand/s3c2440.c @@ -30,7 +30,6 @@ #include "s3c24xx.h" - NAND_DEVICE_COMMAND_HANDLER(s3c2440_nand_device_command) { struct s3c24xx_nand_controller *info; @@ -153,17 +152,17 @@ int s3c2440_write_block_data(struct nand_device *nand, uint8_t *data, int data_s } struct nand_flash_controller s3c2440_nand_controller = { - .name = "s3c2440", - .nand_device_command = &s3c2440_nand_device_command, - .init = &s3c2440_init, - .reset = &s3c24xx_reset, - .command = &s3c24xx_command, - .address = &s3c24xx_address, - .write_data = &s3c24xx_write_data, - .read_data = &s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = &s3c2440_write_block_data, - .read_block_data = &s3c2440_read_block_data, - .nand_ready = &s3c2440_nand_ready, - }; + .name = "s3c2440", + .nand_device_command = &s3c2440_nand_device_command, + .init = &s3c2440_init, + .reset = &s3c24xx_reset, + .command = &s3c24xx_command, + .address = &s3c24xx_address, + .write_data = &s3c24xx_write_data, + .read_data = &s3c24xx_read_data, + .write_page = s3c24xx_write_page, + .read_page = s3c24xx_read_page, + .write_block_data = &s3c2440_write_block_data, + .read_block_data = &s3c2440_read_block_data, + .nand_ready = &s3c2440_nand_ready, +}; diff --git a/src/flash/nand/s3c2443.c b/src/flash/nand/s3c2443.c index 8ad044c..2212bd3 100644 --- a/src/flash/nand/s3c2443.c +++ b/src/flash/nand/s3c2443.c @@ -30,7 +30,6 @@ #include "s3c24xx.h" - NAND_DEVICE_COMMAND_HANDLER(s3c2443_nand_device_command) { struct s3c24xx_nand_controller *info; @@ -62,17 +61,17 @@ static int s3c2443_init(struct nand_device *nand) } struct nand_flash_controller s3c2443_nand_controller = { - .name = "s3c2443", - .nand_device_command = &s3c2443_nand_device_command, - .init = &s3c2443_init, - .reset = &s3c24xx_reset, - .command = &s3c24xx_command, - .address = &s3c24xx_address, - .write_data = &s3c24xx_write_data, - .read_data = &s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = &s3c2440_write_block_data, - .read_block_data = &s3c2440_read_block_data, - .nand_ready = &s3c2440_nand_ready, - }; + .name = "s3c2443", + .nand_device_command = &s3c2443_nand_device_command, + .init = &s3c2443_init, + .reset = &s3c24xx_reset, + .command = &s3c24xx_command, + .address = &s3c24xx_address, + .write_data = &s3c24xx_write_data, + .read_data = &s3c24xx_read_data, + .write_page = s3c24xx_write_page, + .read_page = s3c24xx_read_page, + .write_block_data = &s3c2440_write_block_data, + .read_block_data = &s3c2440_read_block_data, + .nand_ready = &s3c2440_nand_ready, +}; diff --git a/src/flash/nand/s3c24xx.c b/src/flash/nand/s3c24xx.c index 2fa18de..bdeee4f 100644 --- a/src/flash/nand/s3c24xx.c +++ b/src/flash/nand/s3c24xx.c @@ -30,7 +30,6 @@ #include "s3c24xx.h" - S3C24XX_DEVICE_COMMAND() { *info = NULL; @@ -77,7 +76,6 @@ int s3c24xx_command(struct nand_device *nand, uint8_t command) return ERROR_OK; } - int s3c24xx_address(struct nand_device *nand, uint8_t address) { struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; diff --git a/src/flash/nand/s3c24xx.h b/src/flash/nand/s3c24xx.h index 1535dec..97440bf 100644 --- a/src/flash/nand/s3c24xx.h +++ b/src/flash/nand/s3c24xx.h @@ -31,8 +31,7 @@ #include "s3c24xx_regs.h" #include <target/target.h> -struct s3c24xx_nand_controller -{ +struct s3c24xx_nand_controller { /* register addresses */ uint32_t cmd; uint32_t addr; @@ -78,4 +77,4 @@ int s3c2440_read_block_data(struct nand_device *nand, int s3c2440_write_block_data(struct nand_device *nand, uint8_t *data, int data_size); -#endif // S3C24xx_NAND_H +#endif /* S3C24xx_NAND_H */ diff --git a/src/flash/nand/s3c24xx_regs.h b/src/flash/nand/s3c24xx_regs.h index c8cbe78..51cb26d 100644 --- a/src/flash/nand/s3c24xx_regs.h +++ b/src/flash/nand/s3c24xx_regs.h @@ -23,7 +23,7 @@ */ #ifndef __ASM_ARM_REGS_NAND -#define __ASM_ARM_REGS_NAND "$Id: nand.h,v 1.3 2003/12/09 11:36:29 ben Exp $" +#define __ASM_ARM_REGS_NAND #define S3C2410_NFREG(x) (x) diff --git a/src/flash/nand/s3c6400.c b/src/flash/nand/s3c6400.c index a6f8043..6aa9c33 100644 --- a/src/flash/nand/s3c6400.c +++ b/src/flash/nand/s3c6400.c @@ -58,17 +58,17 @@ static int s3c6400_init(struct nand_device *nand) } struct nand_flash_controller s3c6400_nand_controller = { - .name = "s3c6400", - .nand_device_command = &s3c6400_nand_device_command, - .init = &s3c6400_init, - .reset = &s3c24xx_reset, - .command = &s3c24xx_command, - .address = &s3c24xx_address, - .write_data = &s3c24xx_write_data, - .read_data = &s3c24xx_read_data, - .write_page = s3c24xx_write_page, - .read_page = s3c24xx_read_page, - .write_block_data = &s3c2440_write_block_data, - .read_block_data = &s3c2440_read_block_data, - .nand_ready = &s3c2440_nand_ready, - }; + .name = "s3c6400", + .nand_device_command = &s3c6400_nand_device_command, + .init = &s3c6400_init, + .reset = &s3c24xx_reset, + .command = &s3c24xx_command, + .address = &s3c24xx_address, + .write_data = &s3c24xx_write_data, + .read_data = &s3c24xx_read_data, + .write_page = s3c24xx_write_page, + .read_page = s3c24xx_read_page, + .write_block_data = &s3c2440_write_block_data, + .read_block_data = &s3c2440_read_block_data, + .nand_ready = &s3c2440_nand_ready, +}; diff --git a/src/flash/nand/tcl.c b/src/flash/nand/tcl.c index c52c347..6f942d2 100644 --- a/src/flash/nand/tcl.c +++ b/src/flash/nand/tcl.c @@ -20,6 +20,7 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -29,7 +30,7 @@ #include "fileio.h" #include <target/target.h> -// to be removed +/* to be removed */ extern struct nand_device *nand_devices; COMMAND_HANDLER(handle_nand_list_command) @@ -37,14 +38,12 @@ COMMAND_HANDLER(handle_nand_list_command) struct nand_device *p; int i; - if (!nand_devices) - { + if (!nand_devices) { command_print(CMD_CTX, "no NAND flash devices configured"); return ERROR_OK; } - for (p = nand_devices, i = 0; p; p = p->next, i++) - { + for (p = nand_devices, i = 0; p; p = p->next, i++) { if (p->device) command_print(CMD_CTX, "#%i: %s (%s) " "pagesize: %i, buswidth: %i,\n\t" @@ -67,21 +66,21 @@ COMMAND_HANDLER(handle_nand_info_command) int last = -1; switch (CMD_ARGC) { - default: - return ERROR_COMMAND_SYNTAX_ERROR; - case 1: - first = 0; - last = INT32_MAX; - break; - case 2: - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], i); - first = last = i; - i = 0; - break; - case 3: - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first); - COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last); - break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; + case 1: + first = 0; + last = INT32_MAX; + break; + case 2: + COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], i); + first = last = i; + i = 0; + break; + case 3: + COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first); + COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last); + break; } struct nand_device *p; @@ -89,8 +88,7 @@ COMMAND_HANDLER(handle_nand_info_command) if (ERROR_OK != retval) return retval; - if (NULL == p->device) - { + if (NULL == p->device) { command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]); return ERROR_OK; } @@ -101,11 +99,16 @@ COMMAND_HANDLER(handle_nand_info_command) if (last >= p->num_blocks) last = p->num_blocks - 1; - command_print(CMD_CTX, "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i", - i++, p->device->name, p->manufacturer->name, p->page_size, p->bus_width, p->erase_size); + command_print(CMD_CTX, + "#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i", + i++, + p->device->name, + p->manufacturer->name, + p->page_size, + p->bus_width, + p->erase_size); - for (j = first; j <= last; j++) - { + for (j = first; j <= last; j++) { char *erase_state, *bad_state; if (p->blocks[j].is_erased == 0) @@ -123,12 +126,12 @@ COMMAND_HANDLER(handle_nand_info_command) bad_state = " (block condition unknown)"; command_print(CMD_CTX, - "\t#%i: 0x%8.8" PRIx32 " (%" PRId32 "kB) %s%s", - j, - p->blocks[j].offset, - p->blocks[j].size / 1024, - erase_state, - bad_state); + "\t#%i: 0x%8.8" PRIx32 " (%" PRId32 "kB) %s%s", + j, + p->blocks[j].offset, + p->blocks[j].size / 1024, + erase_state, + bad_state); } return ERROR_OK; @@ -137,19 +140,17 @@ COMMAND_HANDLER(handle_nand_info_command) COMMAND_HANDLER(handle_nand_probe_command) { if (CMD_ARGC != 1) - { return ERROR_COMMAND_SYNTAX_ERROR; - } struct nand_device *p; int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p); if (ERROR_OK != retval) return retval; - if ((retval = nand_probe(p)) == ERROR_OK) - { + retval = nand_probe(p); + if (retval == ERROR_OK) { command_print(CMD_CTX, "NAND flash device '%s (%s)' found", - p->device->name, p->manufacturer->name); + p->device->name, p->manufacturer->name); } return retval; @@ -158,11 +159,8 @@ COMMAND_HANDLER(handle_nand_probe_command) COMMAND_HANDLER(handle_nand_erase_command) { if (CMD_ARGC != 1 && CMD_ARGC != 3) - { return ERROR_COMMAND_SYNTAX_ERROR; - } - struct nand_device *p; int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p); if (ERROR_OK != retval) @@ -181,7 +179,7 @@ COMMAND_HANDLER(handle_nand_erase_command) COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length); if ((length == 0) || (length % p->erase_size) != 0 - || (length + offset) > size) + || (length + offset) > size) return ERROR_COMMAND_SYNTAX_ERROR; offset /= p->erase_size; @@ -192,12 +190,11 @@ COMMAND_HANDLER(handle_nand_erase_command) } retval = nand_erase(p, offset, offset + length - 1); - if (retval == ERROR_OK) - { + if (retval == ERROR_OK) { command_print(CMD_CTX, "erased blocks %lu to %lu " - "on NAND flash device #%s '%s'", - offset, offset + length - 1, - CMD_ARGV[0], p->device->name); + "on NAND flash device #%s '%s'", + offset, offset + length - 1, + CMD_ARGV[0], p->device->name); } return retval; @@ -209,18 +206,14 @@ COMMAND_HANDLER(handle_nand_check_bad_blocks_command) int last = -1; if ((CMD_ARGC < 1) || (CMD_ARGC > 3) || (CMD_ARGC == 2)) - { return ERROR_COMMAND_SYNTAX_ERROR; - } - struct nand_device *p; int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p); if (ERROR_OK != retval) return retval; - if (CMD_ARGC == 3) - { + if (CMD_ARGC == 3) { unsigned long offset; unsigned long length; @@ -241,10 +234,9 @@ COMMAND_HANDLER(handle_nand_check_bad_blocks_command) } retval = nand_build_bbt(p, first, last); - if (retval == ERROR_OK) - { + if (retval == ERROR_OK) { command_print(CMD_CTX, "checked NAND flash device for bad blocks, " - "use \"nand info\" command to list blocks"); + "use \"nand info\" command to list blocks"); } return retval; @@ -260,11 +252,9 @@ COMMAND_HANDLER(handle_nand_write_command) return retval; uint32_t total_bytes = s.size; - while (s.size > 0) - { + while (s.size > 0) { int bytes_read = nand_fileio_read(nand, &s); - if (bytes_read <= 0) - { + if (bytes_read <= 0) { command_print(CMD_CTX, "error while reading file"); return nand_fileio_cleanup(&s); } @@ -272,8 +262,7 @@ COMMAND_HANDLER(handle_nand_write_command) retval = nand_write_page(nand, s.address / nand->page_size, s.page, s.page_size, s.oob, s.oob_size); - if (ERROR_OK != retval) - { + if (ERROR_OK != retval) { command_print(CMD_CTX, "failed writing file %s " "to NAND flash %s at offset 0x%8.8" PRIx32, CMD_ARGV[1], CMD_ARGV[0], s.address); @@ -282,12 +271,11 @@ COMMAND_HANDLER(handle_nand_write_command) s.address += s.page_size; } - if (nand_fileio_finish(&s)) - { + if (nand_fileio_finish(&s)) { command_print(CMD_CTX, "wrote file %s to NAND flash %s up to " - "offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)", - CMD_ARGV[1], CMD_ARGV[0], s.address, duration_elapsed(&s.bench), - duration_kbps(&s.bench, total_bytes)); + "offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)", + CMD_ARGV[1], CMD_ARGV[0], s.address, duration_elapsed(&s.bench), + duration_kbps(&s.bench, total_bytes)); } return ERROR_OK; } @@ -310,12 +298,10 @@ COMMAND_HANDLER(handle_nand_verify_command) if (ERROR_OK != retval) return retval; - while (file.size > 0) - { + while (file.size > 0) { retval = nand_read_page(nand, dev.address / dev.page_size, dev.page, dev.page_size, dev.oob, dev.oob_size); - if (ERROR_OK != retval) - { + if (ERROR_OK != retval) { command_print(CMD_CTX, "reading NAND flash page failed"); nand_fileio_cleanup(&dev); nand_fileio_cleanup(&file); @@ -323,8 +309,7 @@ COMMAND_HANDLER(handle_nand_verify_command) } int bytes_read = nand_fileio_read(nand, &file); - if (bytes_read <= 0) - { + if (bytes_read <= 0) { command_print(CMD_CTX, "error while reading file"); nand_fileio_cleanup(&dev); nand_fileio_cleanup(&file); @@ -332,10 +317,9 @@ COMMAND_HANDLER(handle_nand_verify_command) } if ((dev.page && memcmp(dev.page, file.page, dev.page_size)) || - (dev.oob && memcmp(dev.oob, file.oob, dev.oob_size)) ) - { + (dev.oob && memcmp(dev.oob, file.oob, dev.oob_size))) { command_print(CMD_CTX, "NAND flash contents differ " - "at 0x%8.8" PRIx32, dev.address); + "at 0x%8.8" PRIx32, dev.address); nand_fileio_cleanup(&dev); nand_fileio_cleanup(&file); return ERROR_FAIL; @@ -345,12 +329,11 @@ COMMAND_HANDLER(handle_nand_verify_command) dev.address += nand->page_size; } - if (nand_fileio_finish(&file) == ERROR_OK) - { + if (nand_fileio_finish(&file) == ERROR_OK) { command_print(CMD_CTX, "verified file %s in NAND flash %s " - "up to offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)", - CMD_ARGV[1], CMD_ARGV[0], dev.address, duration_elapsed(&file.bench), - duration_kbps(&file.bench, dev.size)); + "up to offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)", + CMD_ARGV[1], CMD_ARGV[0], dev.address, duration_elapsed(&file.bench), + duration_kbps(&file.bench, dev.size)); } return nand_fileio_cleanup(&dev); @@ -366,13 +349,11 @@ COMMAND_HANDLER(handle_nand_dump_command) if (ERROR_OK != retval) return retval; - while (s.size > 0) - { + while (s.size > 0) { size_t size_written; retval = nand_read_page(nand, s.address / nand->page_size, s.page, s.page_size, s.oob, s.oob_size); - if (ERROR_OK != retval) - { + if (ERROR_OK != retval) { command_print(CMD_CTX, "reading NAND flash page failed"); nand_fileio_cleanup(&s); return retval; @@ -392,11 +373,10 @@ COMMAND_HANDLER(handle_nand_dump_command) if (retval != ERROR_OK) return retval; - if (nand_fileio_finish(&s) == ERROR_OK) - { + if (nand_fileio_finish(&s) == ERROR_OK) { command_print(CMD_CTX, "dumped %ld bytes in %fs (%0.3f KiB/s)", - (long)filesize, duration_elapsed(&s.bench), - duration_kbps(&s.bench, filesize)); + (long)filesize, duration_elapsed(&s.bench), + duration_kbps(&s.bench, filesize)); } return ERROR_OK; } @@ -404,17 +384,14 @@ COMMAND_HANDLER(handle_nand_dump_command) COMMAND_HANDLER(handle_nand_raw_access_command) { if ((CMD_ARGC < 1) || (CMD_ARGC > 2)) - { return ERROR_COMMAND_SYNTAX_ERROR; - } struct nand_device *p; int retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p); if (ERROR_OK != retval) return retval; - if (NULL == p->device) - { + if (NULL == p->device) { command_print(CMD_CTX, "#%s: not probed", CMD_ARGV[0]); return ERROR_OK; } @@ -510,9 +487,8 @@ COMMAND_HANDLER(handle_nand_init_command) if (CMD_ARGC != 0) return ERROR_COMMAND_SYNTAX_ERROR; - static bool nand_initialized = false; - if (nand_initialized) - { + static bool nand_initialized; + if (nand_initialized) { LOG_INFO("'nand init' has already been called"); return ERROR_OK; } @@ -536,32 +512,28 @@ COMMAND_HANDLER(handle_nand_list_drivers) } static COMMAND_HELPER(create_nand_device, const char *bank_name, - struct nand_flash_controller *controller) + struct nand_flash_controller *controller) { struct nand_device *c; struct target *target; int retval; if (CMD_ARGC < 2) - { return ERROR_COMMAND_SYNTAX_ERROR; - } target = get_target(CMD_ARGV[1]); if (!target) { LOG_ERROR("invalid target %s", CMD_ARGV[1]); return ERROR_COMMAND_ARGUMENT_INVALID; } - if (NULL != controller->commands) - { + if (NULL != controller->commands) { retval = register_commands(CMD_CTX, NULL, controller->commands); if (ERROR_OK != retval) return retval; } c = malloc(sizeof(struct nand_device)); - if (c == NULL) - { + if (c == NULL) { LOG_ERROR("End of memory"); return ERROR_FAIL; } @@ -579,8 +551,7 @@ static COMMAND_HELPER(create_nand_device, const char *bank_name, c->next = NULL; retval = CALL_COMMAND_HANDLER(controller->nand_device_command, c); - if (ERROR_OK != retval) - { + if (ERROR_OK != retval) { LOG_ERROR("'%s' driver rejected nand flash. Usage: %s", controller->name, controller->usage); @@ -599,19 +570,16 @@ static COMMAND_HELPER(create_nand_device, const char *bank_name, COMMAND_HANDLER(handle_nand_device_command) { if (CMD_ARGC < 2) - { return ERROR_COMMAND_SYNTAX_ERROR; - } - // save name and increment (for compatibility) with drivers + /* save name and increment (for compatibility) with drivers */ const char *bank_name = *CMD_ARGV++; CMD_ARGC--; const char *driver_name = CMD_ARGV[0]; struct nand_flash_controller *controller; controller = nand_driver_find_by_name(CMD_ARGV[0]); - if (NULL == controller) - { + if (NULL == controller) { LOG_ERROR("No valid NAND flash driver found (%s)", driver_name); return CALL_COMMAND_HANDLER(handle_nand_list_drivers); } @@ -642,6 +610,7 @@ static const struct command_registration nand_config_command_handlers[] = { }, COMMAND_REGISTRATION_DONE }; + static const struct command_registration nand_command_handlers[] = { { .name = "nand", @@ -657,5 +626,3 @@ int nand_register_commands(struct command_context *cmd_ctx) { return register_commands(cmd_ctx, NULL, nand_command_handlers); } - - |