mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 21:25:19 -05:00
emBIOS backports part three: Make the NAND flash driver return more useful error codes if initialization fails.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27782 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
6b389305f6
commit
b4d6d1e643
2 changed files with 22 additions and 24 deletions
|
|
@ -45,8 +45,6 @@
|
||||||
|
|
||||||
#define NAND_STATUS_READY 0x40
|
#define NAND_STATUS_READY 0x40
|
||||||
|
|
||||||
#define NAND_DEVICEINFOTABLE_ENTRIES 33
|
|
||||||
|
|
||||||
static const struct nand_device_info_type nand_deviceinfotable[] =
|
static const struct nand_device_info_type nand_deviceinfotable[] =
|
||||||
{
|
{
|
||||||
{0x1580F1EC, 1024, 968, 0x40, 6, 2, 1, 2, 1},
|
{0x1580F1EC, 1024, 968, 0x40, 6, 2, 1, 2, 1},
|
||||||
|
|
@ -88,7 +86,7 @@ static uint8_t nand_tunk1[4];
|
||||||
static uint8_t nand_twp[4];
|
static uint8_t nand_twp[4];
|
||||||
static uint8_t nand_tunk2[4];
|
static uint8_t nand_tunk2[4];
|
||||||
static uint8_t nand_tunk3[4];
|
static uint8_t nand_tunk3[4];
|
||||||
static uint32_t nand_type[4];
|
static int nand_type[4];
|
||||||
static int nand_powered = 0;
|
static int nand_powered = 0;
|
||||||
static int nand_interleaved = 0;
|
static int nand_interleaved = 0;
|
||||||
static int nand_cached = 0;
|
static int nand_cached = 0;
|
||||||
|
|
@ -307,15 +305,15 @@ static uint32_t nand_get_chip_type(uint32_t bank)
|
||||||
{
|
{
|
||||||
mutex_lock(&nand_mtx);
|
mutex_lock(&nand_mtx);
|
||||||
uint32_t result;
|
uint32_t result;
|
||||||
if (nand_reset(bank)) return nand_unlock(0xFFFFFFFF);
|
if (nand_reset(bank)) return nand_unlock(0xFFFFFFFE);
|
||||||
if (nand_send_cmd(0x90)) return nand_unlock(0xFFFFFFFF);
|
if (nand_send_cmd(0x90)) return nand_unlock(0xFFFFFFFD);
|
||||||
FMANUM = 0;
|
FMANUM = 0;
|
||||||
FMADDR0 = 0;
|
FMADDR0 = 0;
|
||||||
FMCTRL1 = FMCTRL1_DOTRANSADDR;
|
FMCTRL1 = FMCTRL1_DOTRANSADDR;
|
||||||
if (nand_wait_cmddone()) return nand_unlock(0xFFFFFFFF);
|
if (nand_wait_cmddone()) return nand_unlock(0xFFFFFFFC);
|
||||||
FMDNUM = 4;
|
FMDNUM = 4;
|
||||||
FMCTRL1 = FMCTRL1_DOREADDATA;
|
FMCTRL1 = FMCTRL1_DOREADDATA;
|
||||||
if (nand_wait_addrdone()) return nand_unlock(0xFFFFFFFF);
|
if (nand_wait_addrdone()) return nand_unlock(0xFFFFFFFB);
|
||||||
result = FMFIFO;
|
result = FMFIFO;
|
||||||
FMCTRL1 = FMCTRL1_CLEARRFIFO;
|
FMCTRL1 = FMCTRL1_CLEARRFIFO;
|
||||||
return nand_unlock(result);
|
return nand_unlock(result);
|
||||||
|
|
@ -351,13 +349,9 @@ void nand_power_up(void)
|
||||||
sleep(HZ / 20);
|
sleep(HZ / 20);
|
||||||
nand_last_activity_value = current_tick;
|
nand_last_activity_value = current_tick;
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
if (nand_type[i] >= 0)
|
||||||
if(nand_type[i] != 0xFFFFFFFF)
|
|
||||||
{
|
|
||||||
if (nand_reset(i))
|
if (nand_reset(i))
|
||||||
panicf("nand_power_up: nand_reset(bank=%d) failed.",(unsigned int)i);
|
panicf("nand_power_up: nand_reset(bank=%d) failed.",(unsigned int)i);
|
||||||
}
|
|
||||||
}
|
|
||||||
nand_powered = 1;
|
nand_powered = 1;
|
||||||
nand_last_activity_value = current_tick;
|
nand_last_activity_value = current_tick;
|
||||||
mutex_unlock(&nand_mtx);
|
mutex_unlock(&nand_mtx);
|
||||||
|
|
@ -516,7 +510,7 @@ uint32_t nand_read_page_fast(uint32_t page, void* databuffer,
|
||||||
{
|
{
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
if (nand_type[i] == 0xFFFFFFFF) continue;
|
if (nand_type[i] < 0) continue;
|
||||||
void* databuf = (void*)0;
|
void* databuf = (void*)0;
|
||||||
void* sparebuf = (void*)0;
|
void* sparebuf = (void*)0;
|
||||||
if (databuffer) databuf = (void*)((uint32_t)databuffer + 0x800 * i);
|
if (databuffer) databuf = (void*)((uint32_t)databuffer + 0x800 * i);
|
||||||
|
|
@ -534,7 +528,7 @@ uint32_t nand_read_page_fast(uint32_t page, void* databuffer,
|
||||||
led(true);
|
led(true);
|
||||||
if (!nand_powered) nand_power_up();
|
if (!nand_powered) nand_power_up();
|
||||||
uint8_t status[4];
|
uint8_t status[4];
|
||||||
for (i = 0; i < 4; i++) status[i] = (nand_type[i] == 0xFFFFFFFF);
|
for (i = 0; i < 4; i++) status[i] = (nand_type[i] < 0);
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
if (!status[i])
|
if (!status[i])
|
||||||
|
|
@ -628,7 +622,7 @@ uint32_t nand_read_page_fast(uint32_t page, void* databuffer,
|
||||||
+ 0x40 * (i - 1))) << 1;
|
+ 0x40 * (i - 1))) << 1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
if (nand_type[i] != 0xFFFFFFFF)
|
if (nand_type[i] < 0)
|
||||||
rc |= status[i] << (i << 2);
|
rc |= status[i] << (i << 2);
|
||||||
return nand_unlock(rc);
|
return nand_unlock(rc);
|
||||||
}
|
}
|
||||||
|
|
@ -686,7 +680,7 @@ static uint32_t nand_block_erase_fast(uint32_t page)
|
||||||
if (!nand_powered) nand_power_up();
|
if (!nand_powered) nand_power_up();
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
if (nand_type[i] == 0xFFFFFFFF) continue;
|
if (nand_type[i] < 0) continue;
|
||||||
nand_set_fmctrl0(i, 0);
|
nand_set_fmctrl0(i, 0);
|
||||||
if (nand_send_cmd(NAND_CMD_BLOCKERASE))
|
if (nand_send_cmd(NAND_CMD_BLOCKERASE))
|
||||||
{
|
{
|
||||||
|
|
@ -705,7 +699,7 @@ static uint32_t nand_block_erase_fast(uint32_t page)
|
||||||
}
|
}
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
if (nand_type[i] == 0xFFFFFFFF) continue;
|
if (nand_type[i] < 0) continue;
|
||||||
if (rc & (1 << i)) continue;
|
if (rc & (1 << i)) continue;
|
||||||
if (nand_wait_status_ready(i)) rc |= 1 << i;
|
if (nand_wait_status_ready(i)) rc |= 1 << i;
|
||||||
}
|
}
|
||||||
|
|
@ -715,7 +709,7 @@ static uint32_t nand_block_erase_fast(uint32_t page)
|
||||||
|
|
||||||
const struct nand_device_info_type* nand_get_device_type(uint32_t bank)
|
const struct nand_device_info_type* nand_get_device_type(uint32_t bank)
|
||||||
{
|
{
|
||||||
if (nand_type[bank] == 0xFFFFFFFF)
|
if (nand_type[bank] < 0)
|
||||||
return (struct nand_device_info_type*)0;
|
return (struct nand_device_info_type*)0;
|
||||||
return &nand_deviceinfotable[nand_type[bank]];
|
return &nand_deviceinfotable[nand_type[bank]];
|
||||||
}
|
}
|
||||||
|
|
@ -734,7 +728,7 @@ static void nand_thread(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t nand_device_init(void)
|
int nand_device_init(void)
|
||||||
{
|
{
|
||||||
mutex_init(&nand_mtx);
|
mutex_init(&nand_mtx);
|
||||||
wakeup_init(&nand_wakeup);
|
wakeup_init(&nand_wakeup);
|
||||||
|
|
@ -746,7 +740,7 @@ uint32_t nand_device_init(void)
|
||||||
|
|
||||||
/* Assume there are 0 banks, to prevent
|
/* Assume there are 0 banks, to prevent
|
||||||
nand_power_up from talking with them yet. */
|
nand_power_up from talking with them yet. */
|
||||||
for(i = 0; i < 4; i++) nand_type[i] = 0xFFFFFFFF;
|
for (i = 0; i < 4; i++) nand_type[i] = -1;
|
||||||
nand_power_up();
|
nand_power_up();
|
||||||
|
|
||||||
/* Now that the flash is powered on, detect how
|
/* Now that the flash is powered on, detect how
|
||||||
|
|
@ -758,7 +752,11 @@ uint32_t nand_device_init(void)
|
||||||
nand_tunk2[i] = 7;
|
nand_tunk2[i] = 7;
|
||||||
nand_tunk3[i] = 7;
|
nand_tunk3[i] = 7;
|
||||||
type = nand_get_chip_type(i);
|
type = nand_get_chip_type(i);
|
||||||
if (type == 0xFFFFFFFF) continue;
|
if (type >= 0xFFFFFFF0)
|
||||||
|
{
|
||||||
|
nand_type[i] = (int)type;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (j = 0; ; j++)
|
for (j = 0; ; j++)
|
||||||
{
|
{
|
||||||
if (j == ARRAYLEN(nand_deviceinfotable)) break;
|
if (j == ARRAYLEN(nand_deviceinfotable)) break;
|
||||||
|
|
@ -773,7 +771,7 @@ uint32_t nand_device_init(void)
|
||||||
nand_tunk2[i] = nand_deviceinfotable[nand_type[i]].tunk2;
|
nand_tunk2[i] = nand_deviceinfotable[nand_type[i]].tunk2;
|
||||||
nand_tunk3[i] = nand_deviceinfotable[nand_type[i]].tunk3;
|
nand_tunk3[i] = nand_deviceinfotable[nand_type[i]].tunk3;
|
||||||
}
|
}
|
||||||
if (nand_type[0] == 0xFFFFFFFF) return 1;
|
if (nand_type[0] < 0) return nand_type[0];
|
||||||
nand_interleaved = ((nand_type[0] >> 22) & 1);
|
nand_interleaved = ((nand_type[0] >> 22) & 1);
|
||||||
nand_cached = ((nand_type[0] >> 23) & 1);
|
nand_cached = ((nand_type[0] >> 23) & 1);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ uint32_t nand_write_page_collect(uint32_t bank);
|
||||||
|
|
||||||
const struct nand_device_info_type* nand_get_device_type(uint32_t bank);
|
const struct nand_device_info_type* nand_get_device_type(uint32_t bank);
|
||||||
uint32_t nand_reset(uint32_t bank);
|
uint32_t nand_reset(uint32_t bank);
|
||||||
uint32_t nand_device_init(void);
|
int nand_device_init(void);
|
||||||
void nand_set_active(void);
|
void nand_set_active(void);
|
||||||
long nand_last_activity(void);
|
long nand_last_activity(void);
|
||||||
void nand_power_up(void);
|
void nand_power_up(void);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue