mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
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
This commit is contained in:
parent
02c4ec294c
commit
2d6ddd0c5b
3 changed files with 12 additions and 11 deletions
|
@ -46,9 +46,9 @@
|
||||||
#define NAND_FREG_PROTECTION_BRWD 0x80
|
#define NAND_FREG_PROTECTION_BRWD 0x80
|
||||||
#define NAND_FREG_PROTECTION_BP2 0x20
|
#define NAND_FREG_PROTECTION_BP2 0x20
|
||||||
#define NAND_FREG_PROTECTION_BP1 0x10
|
#define NAND_FREG_PROTECTION_BP1 0x10
|
||||||
#define NAND_FREG_PROTECTION_BP0 0x80
|
#define NAND_FREG_PROTECTION_BP0 0x08
|
||||||
/* Mask of BP bits 0-2 */
|
/* Mask of BP bits 0-2 */
|
||||||
#define NAND_FREG_PROTECTION_ALLBP (0x38)
|
#define NAND_FREG_PROTECTION_ALLBP 0x38
|
||||||
|
|
||||||
/* Feature register bits */
|
/* Feature register bits */
|
||||||
#define NAND_FREG_FEATURE_QE 0x01
|
#define NAND_FREG_FEATURE_QE 0x01
|
||||||
|
@ -129,6 +129,7 @@ int nand_open(void)
|
||||||
sfc_set_dev_conf(chip_data->dev_conf);
|
sfc_set_dev_conf(chip_data->dev_conf);
|
||||||
sfc_set_clock(chip_data->clock_freq);
|
sfc_set_clock(chip_data->clock_freq);
|
||||||
|
|
||||||
|
sfc_unlock();
|
||||||
return NAND_SUCCESS;
|
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 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 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))
|
if(addr & (block_size - 1))
|
||||||
return NAND_ERR_UNALIGNED;
|
return NAND_ERR_UNALIGNED;
|
||||||
|
@ -333,13 +334,13 @@ static int nandop_set_write_protect(bool en)
|
||||||
return val;
|
return val;
|
||||||
|
|
||||||
if(en) {
|
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;
|
val |= NAND_FREG_PROTECTION_ALLBP;
|
||||||
if(nand_drv.chip_data->flags & NANDCHIP_FLAG_USE_BRWD)
|
if(nand_drv.chip_data->flags & NANDCHIP_FLAG_USE_BRWD)
|
||||||
val |= NAND_FREG_PROTECTION_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
|
/* 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};
|
sfc_op op = {0};
|
||||||
op.command = NAND_CMD_SET_FEATURE;
|
op.command = NAND_CMD_SET_FEATURE;
|
||||||
op.flags = SFC_FLAG_READ;
|
op.flags = SFC_FLAG_WRITE;
|
||||||
op.addr_bytes = 1;
|
op.addr_bytes = 1;
|
||||||
op.addr_lo = reg;
|
op.addr_lo = reg;
|
||||||
op.data_bytes = 1;
|
op.data_bytes = 1;
|
||||||
|
|
|
@ -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_read(uint32_t addr, uint32_t size, uint8_t* buf);
|
||||||
extern int nand_write(uint32_t addr, uint32_t size, const 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.
|
* 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. */
|
* If not, no blocks are erased and an error code is returned. */
|
||||||
extern int nand_erase(uint32_t addr, uint32_t size);
|
extern int nand_erase(uint32_t addr, uint32_t size);
|
||||||
|
|
|
@ -166,7 +166,7 @@ void SFC(void)
|
||||||
* so please do NOT try to rearrange the code without testing it first!
|
* 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;
|
int data_words = (data_bytes + 3) / 4;
|
||||||
while(data_words > 0) {
|
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;
|
int data_words = (data_bytes + 3) / 4;
|
||||||
while(data_words > 0) {
|
while(data_words > 0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue