summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-06-12 00:22:48 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-06-14 20:45:14 +0100
commit2d6ddd0c5be78678ec2a349b9a912cc1999c1c68 (patch)
tree415a787eef027217196f372161d41e57d1fc2eaf
parent02c4ec294c19115c5d9749971eebedf1769e81ba (diff)
downloadrockbox-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
-rw-r--r--firmware/target/mips/ingenic_x1000/nand-x1000.c17
-rw-r--r--firmware/target/mips/ingenic_x1000/nand-x1000.h2
-rw-r--r--firmware/target/mips/ingenic_x1000/sfc-x1000.c4
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);
99extern int nand_read(uint32_t addr, uint32_t size, uint8_t* buf); 99extern int nand_read(uint32_t addr, uint32_t size, uint8_t* buf);
100extern int nand_write(uint32_t addr, uint32_t size, const uint8_t* buf); 100extern 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. */
105extern int nand_erase(uint32_t addr, uint32_t size); 105extern 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
169void sfc_fifo_read(unsigned* buffer, int data_bytes) 169static 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
186void sfc_fifo_write(const unsigned* buffer, int data_bytes) 186static 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) {