diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2021-06-12 00:22:48 +0100 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2021-06-14 20:45:14 +0100 |
commit | 2d6ddd0c5be78678ec2a349b9a912cc1999c1c68 (patch) | |
tree | 415a787eef027217196f372161d41e57d1fc2eaf /firmware/target | |
parent | 02c4ec294c19115c5d9749971eebedf1769e81ba (diff) | |
download | rockbox-2d6ddd0c5be78678ec2a349b9a912cc1999c1c68.tar.gz rockbox-2d6ddd0c5be78678ec2a349b9a912cc1999c1c68.zip |
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
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/mips/ingenic_x1000/nand-x1000.c | 17 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_x1000/nand-x1000.h | 2 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_x1000/sfc-x1000.c | 4 |
3 files changed, 12 insertions, 11 deletions
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 @@ | |||
46 | #define NAND_FREG_PROTECTION_BRWD 0x80 | 46 | #define NAND_FREG_PROTECTION_BRWD 0x80 |
47 | #define NAND_FREG_PROTECTION_BP2 0x20 | 47 | #define NAND_FREG_PROTECTION_BP2 0x20 |
48 | #define NAND_FREG_PROTECTION_BP1 0x10 | 48 | #define NAND_FREG_PROTECTION_BP1 0x10 |
49 | #define NAND_FREG_PROTECTION_BP0 0x80 | 49 | #define NAND_FREG_PROTECTION_BP0 0x08 |
50 | /* Mask of BP bits 0-2 */ | 50 | /* Mask of BP bits 0-2 */ |
51 | #define NAND_FREG_PROTECTION_ALLBP (0x38) | 51 | #define NAND_FREG_PROTECTION_ALLBP 0x38 |
52 | 52 | ||
53 | /* Feature register bits */ | 53 | /* Feature register bits */ |
54 | #define NAND_FREG_FEATURE_QE 0x01 | 54 | #define NAND_FREG_FEATURE_QE 0x01 |
@@ -129,6 +129,7 @@ int nand_open(void) | |||
129 | sfc_set_dev_conf(chip_data->dev_conf); | 129 | sfc_set_dev_conf(chip_data->dev_conf); |
130 | sfc_set_clock(chip_data->clock_freq); | 130 | sfc_set_clock(chip_data->clock_freq); |
131 | 131 | ||
132 | sfc_unlock(); | ||
132 | return NAND_SUCCESS; | 133 | return NAND_SUCCESS; |
133 | } | 134 | } |
134 | 135 | ||
@@ -237,7 +238,7 @@ int nand_erase(uint32_t addr, uint32_t size) | |||
237 | { | 238 | { |
238 | const uint32_t page_size = 1 << nand_drv.chip_data->log2_page_size; | 239 | const uint32_t page_size = 1 << nand_drv.chip_data->log2_page_size; |
239 | const uint32_t block_size = page_size << nand_drv.chip_data->log2_block_size; | 240 | const uint32_t block_size = page_size << nand_drv.chip_data->log2_block_size; |
240 | const uint32_t pages_per_block = 1 << nand_drv.chip_data->log2_page_size; | 241 | const uint32_t pages_per_block = 1 << nand_drv.chip_data->log2_block_size; |
241 | 242 | ||
242 | if(addr & (block_size - 1)) | 243 | if(addr & (block_size - 1)) |
243 | return NAND_ERR_UNALIGNED; | 244 | return NAND_ERR_UNALIGNED; |
@@ -333,13 +334,13 @@ static int nandop_set_write_protect(bool en) | |||
333 | return val; | 334 | return val; |
334 | 335 | ||
335 | if(en) { | 336 | if(en) { |
336 | val &= ~NAND_FREG_PROTECTION_ALLBP; | ||
337 | if(nand_drv.chip_data->flags & NANDCHIP_FLAG_USE_BRWD) | ||
338 | val &= ~NAND_FREG_PROTECTION_BRWD; | ||
339 | } else { | ||
340 | val |= NAND_FREG_PROTECTION_ALLBP; | 337 | val |= NAND_FREG_PROTECTION_ALLBP; |
341 | if(nand_drv.chip_data->flags & NANDCHIP_FLAG_USE_BRWD) | 338 | if(nand_drv.chip_data->flags & NANDCHIP_FLAG_USE_BRWD) |
342 | val |= NAND_FREG_PROTECTION_BRWD; | 339 | val |= NAND_FREG_PROTECTION_BRWD; |
340 | } else { | ||
341 | val &= ~NAND_FREG_PROTECTION_ALLBP; | ||
342 | if(nand_drv.chip_data->flags & NANDCHIP_FLAG_USE_BRWD) | ||
343 | val &= ~NAND_FREG_PROTECTION_BRWD; | ||
343 | } | 344 | } |
344 | 345 | ||
345 | /* NOTE: The WP pin typically only protects changes to the protection | 346 | /* 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) | |||
406 | { | 407 | { |
407 | sfc_op op = {0}; | 408 | sfc_op op = {0}; |
408 | op.command = NAND_CMD_SET_FEATURE; | 409 | op.command = NAND_CMD_SET_FEATURE; |
409 | op.flags = SFC_FLAG_READ; | 410 | op.flags = SFC_FLAG_WRITE; |
410 | op.addr_bytes = 1; | 411 | op.addr_bytes = 1; |
411 | op.addr_lo = reg; | 412 | op.addr_lo = reg; |
412 | op.data_bytes = 1; | 413 | 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); | |||
99 | extern int nand_read(uint32_t addr, uint32_t size, uint8_t* buf); | 99 | extern int nand_read(uint32_t addr, uint32_t size, uint8_t* buf); |
100 | extern int nand_write(uint32_t addr, uint32_t size, const uint8_t* buf); | 100 | extern int nand_write(uint32_t addr, uint32_t size, const uint8_t* buf); |
101 | 101 | ||
102 | /* Ereas eoperates on whole blocks. Like the page read/write operations, | 102 | /* Erase operates on whole blocks. Like the page read/write operations, |
103 | * the address and size must be aligned to a multiple of the block size. | 103 | * the address and size must be aligned to a multiple of the block size. |
104 | * If not, no blocks are erased and an error code is returned. */ | 104 | * If not, no blocks are erased and an error code is returned. */ |
105 | extern int nand_erase(uint32_t addr, uint32_t size); | 105 | 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) | |||
166 | * so please do NOT try to rearrange the code without testing it first! | 166 | * so please do NOT try to rearrange the code without testing it first! |
167 | */ | 167 | */ |
168 | 168 | ||
169 | void sfc_fifo_read(unsigned* buffer, int data_bytes) | 169 | static void sfc_fifo_read(unsigned* buffer, int data_bytes) |
170 | { | 170 | { |
171 | int data_words = (data_bytes + 3) / 4; | 171 | int data_words = (data_bytes + 3) / 4; |
172 | while(data_words > 0) { | 172 | while(data_words > 0) { |
@@ -183,7 +183,7 @@ void sfc_fifo_read(unsigned* buffer, int data_bytes) | |||
183 | } | 183 | } |
184 | } | 184 | } |
185 | 185 | ||
186 | void sfc_fifo_write(const unsigned* buffer, int data_bytes) | 186 | static void sfc_fifo_write(const unsigned* buffer, int data_bytes) |
187 | { | 187 | { |
188 | int data_words = (data_bytes + 3) / 4; | 188 | int data_words = (data_bytes + 3) / 4; |
189 | while(data_words > 0) { | 189 | while(data_words > 0) { |