From 2d6ddd0c5be78678ec2a349b9a912cc1999c1c68 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Sat, 12 Jun 2021 00:22:48 +0100 Subject: x1000: NAND driver bugfixes - Missing mutex unlock in nand_open() - SET_FEATURE command incorrectly issued as a read operation - Inverted protection bits, not sure how that happened... - Block erase skipped ahead by a wrong amount, causing erases spanning multiple blocks to erase the wrong blocks This code was buggy as hell... it's in need of a major overhaul. It's not very flexible or reliable, and access to the flash is useful during development of a new port, even if not useful once the port is complete. Change-Id: Ib85ee7453beab9657e3d19798ebaa09174b3649e --- firmware/target/mips/ingenic_x1000/nand-x1000.c | 17 +++++++++-------- firmware/target/mips/ingenic_x1000/nand-x1000.h | 2 +- firmware/target/mips/ingenic_x1000/sfc-x1000.c | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) (limited to 'firmware/target/mips/ingenic_x1000') diff --git a/firmware/target/mips/ingenic_x1000/nand-x1000.c b/firmware/target/mips/ingenic_x1000/nand-x1000.c index fbac824789..5a21b1f8c2 100644 --- a/firmware/target/mips/ingenic_x1000/nand-x1000.c +++ b/firmware/target/mips/ingenic_x1000/nand-x1000.c @@ -46,9 +46,9 @@ #define NAND_FREG_PROTECTION_BRWD 0x80 #define NAND_FREG_PROTECTION_BP2 0x20 #define NAND_FREG_PROTECTION_BP1 0x10 -#define NAND_FREG_PROTECTION_BP0 0x80 +#define NAND_FREG_PROTECTION_BP0 0x08 /* Mask of BP bits 0-2 */ -#define NAND_FREG_PROTECTION_ALLBP (0x38) +#define NAND_FREG_PROTECTION_ALLBP 0x38 /* Feature register bits */ #define NAND_FREG_FEATURE_QE 0x01 @@ -129,6 +129,7 @@ int nand_open(void) sfc_set_dev_conf(chip_data->dev_conf); sfc_set_clock(chip_data->clock_freq); + sfc_unlock(); return NAND_SUCCESS; } @@ -237,7 +238,7 @@ int nand_erase(uint32_t addr, uint32_t size) { const uint32_t page_size = 1 << nand_drv.chip_data->log2_page_size; const uint32_t block_size = page_size << nand_drv.chip_data->log2_block_size; - const uint32_t pages_per_block = 1 << nand_drv.chip_data->log2_page_size; + const uint32_t pages_per_block = 1 << nand_drv.chip_data->log2_block_size; if(addr & (block_size - 1)) return NAND_ERR_UNALIGNED; @@ -333,13 +334,13 @@ static int nandop_set_write_protect(bool en) return val; if(en) { - val &= ~NAND_FREG_PROTECTION_ALLBP; - if(nand_drv.chip_data->flags & NANDCHIP_FLAG_USE_BRWD) - val &= ~NAND_FREG_PROTECTION_BRWD; - } else { val |= NAND_FREG_PROTECTION_ALLBP; if(nand_drv.chip_data->flags & NANDCHIP_FLAG_USE_BRWD) val |= NAND_FREG_PROTECTION_BRWD; + } else { + val &= ~NAND_FREG_PROTECTION_ALLBP; + if(nand_drv.chip_data->flags & NANDCHIP_FLAG_USE_BRWD) + val &= ~NAND_FREG_PROTECTION_BRWD; } /* NOTE: The WP pin typically only protects changes to the protection @@ -406,7 +407,7 @@ static int nandcmd_set_feature(uint8_t reg, uint8_t val) { sfc_op op = {0}; op.command = NAND_CMD_SET_FEATURE; - op.flags = SFC_FLAG_READ; + op.flags = SFC_FLAG_WRITE; op.addr_bytes = 1; op.addr_lo = reg; op.data_bytes = 1; diff --git a/firmware/target/mips/ingenic_x1000/nand-x1000.h b/firmware/target/mips/ingenic_x1000/nand-x1000.h index f5db0bbfa5..cc56b836f8 100644 --- a/firmware/target/mips/ingenic_x1000/nand-x1000.h +++ b/firmware/target/mips/ingenic_x1000/nand-x1000.h @@ -99,7 +99,7 @@ extern int nand_enable_writes(bool en); extern int nand_read(uint32_t addr, uint32_t size, uint8_t* buf); extern int nand_write(uint32_t addr, uint32_t size, const uint8_t* buf); -/* Ereas eoperates on whole blocks. Like the page read/write operations, +/* Erase operates on whole blocks. Like the page read/write operations, * the address and size must be aligned to a multiple of the block size. * If not, no blocks are erased and an error code is returned. */ extern int nand_erase(uint32_t addr, uint32_t size); diff --git a/firmware/target/mips/ingenic_x1000/sfc-x1000.c b/firmware/target/mips/ingenic_x1000/sfc-x1000.c index c1ffb6a5e1..c1fde89b70 100644 --- a/firmware/target/mips/ingenic_x1000/sfc-x1000.c +++ b/firmware/target/mips/ingenic_x1000/sfc-x1000.c @@ -166,7 +166,7 @@ void SFC(void) * so please do NOT try to rearrange the code without testing it first! */ -void sfc_fifo_read(unsigned* buffer, int data_bytes) +static void sfc_fifo_read(unsigned* buffer, int data_bytes) { int data_words = (data_bytes + 3) / 4; while(data_words > 0) { @@ -183,7 +183,7 @@ void sfc_fifo_read(unsigned* buffer, int data_bytes) } } -void sfc_fifo_write(const unsigned* buffer, int data_bytes) +static void sfc_fifo_write(const unsigned* buffer, int data_bytes) { int data_words = (data_bytes + 3) / 4; while(data_words > 0) { -- cgit v1.2.3