diff options
Diffstat (limited to 'firmware/target/arm/s5l8700/ipodnano2g')
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | 51 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/nand-target.h | 8 |
2 files changed, 50 insertions, 9 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c index 795e489258..fe59fc5d2d 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "cpu.h" | 26 | #include "cpu.h" |
27 | #include "inttypes.h" | 27 | #include "inttypes.h" |
28 | #include "nand-target.h" | 28 | #include "nand-target.h" |
29 | #include <pmu-target.h> | ||
29 | #include <string.h> | 30 | #include <string.h> |
30 | 31 | ||
31 | 32 | ||
@@ -84,6 +85,7 @@ uint8_t nand_twp[4]; | |||
84 | uint8_t nand_tunk2[4]; | 85 | uint8_t nand_tunk2[4]; |
85 | uint8_t nand_tunk3[4]; | 86 | uint8_t nand_tunk3[4]; |
86 | uint32_t nand_type[4]; | 87 | uint32_t nand_type[4]; |
88 | int nand_powered = 0; | ||
87 | 89 | ||
88 | static struct mutex nand_mtx; | 90 | static struct mutex nand_mtx; |
89 | static struct wakeup nand_wakeup; | 91 | static struct wakeup nand_wakeup; |
@@ -126,6 +128,45 @@ uint32_t nand_timeout(long timeout) | |||
126 | } | 128 | } |
127 | } | 129 | } |
128 | 130 | ||
131 | void nand_power_up(void) | ||
132 | { | ||
133 | unsigned char powerup[2] = {0x15, 1}; | ||
134 | mutex_lock(&ecc_mtx); | ||
135 | PWRCONEXT &= ~0x40; | ||
136 | PWRCON &= ~0x100000; | ||
137 | PCON2 = 0x33333333; | ||
138 | PDAT2 = 0; | ||
139 | PCON3 = 0x11113333; | ||
140 | PDAT3 = 0; | ||
141 | PCON4 = 0x33333333; | ||
142 | PDAT4 = 0; | ||
143 | PCON5 = (PCON5 & ~0xF) | 3; | ||
144 | PUNK5 = 1; | ||
145 | pmu_write_multiple(0x35, 2, powerup); | ||
146 | sleep(HZ / 50); | ||
147 | nand_powered = 1; | ||
148 | mutex_unlock(&ecc_mtx); | ||
149 | } | ||
150 | |||
151 | void nand_power_down(void) | ||
152 | { | ||
153 | unsigned char powerdown[2] = {0x15, 0}; | ||
154 | mutex_lock(&ecc_mtx); | ||
155 | pmu_write_multiple(0x35, 2, powerdown); | ||
156 | PCON2 = 0x11111111; | ||
157 | PDAT2 = 0; | ||
158 | PCON3 = 0x11111111; | ||
159 | PDAT3 = 0; | ||
160 | PCON4 = 0x11111111; | ||
161 | PDAT4 = 0; | ||
162 | PCON5 = (PCON5 & ~0xF) | 1; | ||
163 | PUNK5 = 1; | ||
164 | PWRCONEXT |= 0x40; | ||
165 | PWRCON |= 0x100000; | ||
166 | nand_powered = 0; | ||
167 | mutex_unlock(&ecc_mtx); | ||
168 | } | ||
169 | |||
129 | uint32_t nand_wait_rbbdone(void) | 170 | uint32_t nand_wait_rbbdone(void) |
130 | { | 171 | { |
131 | long timeout = current_tick + HZ / 50; | 172 | long timeout = current_tick + HZ / 50; |
@@ -302,6 +343,7 @@ uint32_t nand_read_page(uint32_t bank, uint32_t page, void* databuffer, | |||
302 | uint32_t checkempty) | 343 | uint32_t checkempty) |
303 | { | 344 | { |
304 | mutex_lock(&nand_mtx); | 345 | mutex_lock(&nand_mtx); |
346 | if (!nand_powered) nand_power_up(); | ||
305 | uint32_t rc, eccresult; | 347 | uint32_t rc, eccresult; |
306 | nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA); | 348 | nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA); |
307 | if (nand_send_cmd(NAND_CMD_READ) != 0) return nand_unlock(1); | 349 | if (nand_send_cmd(NAND_CMD_READ) != 0) return nand_unlock(1); |
@@ -351,6 +393,7 @@ uint32_t nand_write_page(uint32_t bank, uint32_t page, void* databuffer, | |||
351 | void* sparebuffer, uint32_t doecc) | 393 | void* sparebuffer, uint32_t doecc) |
352 | { | 394 | { |
353 | mutex_lock(&nand_mtx); | 395 | mutex_lock(&nand_mtx); |
396 | if (!nand_powered) nand_power_up(); | ||
354 | if (sparebuffer != 0) memcpy(nand_uncached_spare, sparebuffer, 0x40); | 397 | if (sparebuffer != 0) memcpy(nand_uncached_spare, sparebuffer, 0x40); |
355 | else memset(nand_uncached_spare, 0xFF, 0x40); | 398 | else memset(nand_uncached_spare, 0xFF, 0x40); |
356 | if (doecc != 0) | 399 | if (doecc != 0) |
@@ -383,6 +426,7 @@ uint32_t nand_write_page(uint32_t bank, uint32_t page, void* databuffer, | |||
383 | uint32_t nand_block_erase(uint32_t bank, uint32_t page) | 426 | uint32_t nand_block_erase(uint32_t bank, uint32_t page) |
384 | { | 427 | { |
385 | mutex_lock(&nand_mtx); | 428 | mutex_lock(&nand_mtx); |
429 | if (!nand_powered) nand_power_up(); | ||
386 | nand_set_fmctrl0(bank, 0); | 430 | nand_set_fmctrl0(bank, 0); |
387 | if (nand_send_cmd(NAND_CMD_BLOCKERASE) != 0) return nand_unlock(1); | 431 | if (nand_send_cmd(NAND_CMD_BLOCKERASE) != 0) return nand_unlock(1); |
388 | FMANUM = 2; | 432 | FMANUM = 2; |
@@ -410,12 +454,7 @@ uint32_t nand_device_init(void) | |||
410 | 454 | ||
411 | uint32_t type; | 455 | uint32_t type; |
412 | uint32_t i, j; | 456 | uint32_t i, j; |
413 | PCON2 = 0x33333333; | 457 | if (!nand_powered) nand_power_up(); |
414 | PDAT2 = 0; | ||
415 | PCON3 = 0x11113333; | ||
416 | PDAT3 = 0; | ||
417 | PCON4 = 0x33333333; | ||
418 | PDAT4 = 0; | ||
419 | for (i = 0; i < 4; i++) | 458 | for (i = 0; i < 4; i++) |
420 | { | 459 | { |
421 | nand_tunk1[i] = 7; | 460 | nand_tunk1[i] = 7; |
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-target.h b/firmware/target/arm/s5l8700/ipodnano2g/nand-target.h index bed94ee243..a1559e936c 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/nand-target.h +++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-target.h | |||
@@ -19,8 +19,8 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #ifndef __NAND_H__ | 22 | #ifndef __NAND_TARGET_H__ |
23 | #define __NAND_H__ | 23 | #define __NAND_TARGET_H__ |
24 | 24 | ||
25 | #include "config.h" | 25 | #include "config.h" |
26 | #include "inttypes.h" | 26 | #include "inttypes.h" |
@@ -30,7 +30,7 @@ struct nand_device_info_type | |||
30 | { | 30 | { |
31 | uint32_t id; | 31 | uint32_t id; |
32 | uint16_t blocks; | 32 | uint16_t blocks; |
33 | uint32_t userblocks; | 33 | uint16_t userblocks; |
34 | uint16_t pagesperblock; | 34 | uint16_t pagesperblock; |
35 | uint8_t blocksizeexponent; | 35 | uint8_t blocksizeexponent; |
36 | uint8_t tunk1; | 36 | uint8_t tunk1; |
@@ -49,6 +49,8 @@ uint32_t nand_block_erase(uint32_t bank, uint32_t page); | |||
49 | const struct nand_device_info_type* nand_get_device_type(uint32_t bank); | 49 | const struct nand_device_info_type* nand_get_device_type(uint32_t bank); |
50 | uint32_t nand_reset(uint32_t bank); | 50 | uint32_t nand_reset(uint32_t bank); |
51 | uint32_t nand_device_init(void); | 51 | uint32_t nand_device_init(void); |
52 | void nand_power_up(void); | ||
53 | void nand_power_down(void); | ||
52 | 54 | ||
53 | 55 | ||
54 | #endif | 56 | #endif |