summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8700/ipodnano2g
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2009-10-11 10:10:49 +0000
committerMichael Sparmann <theseven@rockbox.org>2009-10-11 10:10:49 +0000
commite6c8a185e53337353e2f182b4625edf2d20542f7 (patch)
treec963036a9e72dd6b72ea37309bbd4d6280994d5c /firmware/target/arm/s5l8700/ipodnano2g
parent0260b0ad5ad0dba0adaaab0626d135f3a40cab74 (diff)
downloadrockbox-e6c8a185e53337353e2f182b4625edf2d20542f7.tar.gz
rockbox-e6c8a185e53337353e2f182b4625edf2d20542f7.zip
Implement NAND power management for iPod Nano 2G
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23099 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/s5l8700/ipodnano2g')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c51
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-target.h8
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];
84uint8_t nand_tunk2[4]; 85uint8_t nand_tunk2[4];
85uint8_t nand_tunk3[4]; 86uint8_t nand_tunk3[4];
86uint32_t nand_type[4]; 87uint32_t nand_type[4];
88int nand_powered = 0;
87 89
88static struct mutex nand_mtx; 90static struct mutex nand_mtx;
89static struct wakeup nand_wakeup; 91static struct wakeup nand_wakeup;
@@ -126,6 +128,45 @@ uint32_t nand_timeout(long timeout)
126 } 128 }
127} 129}
128 130
131void 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
151void 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
129uint32_t nand_wait_rbbdone(void) 170uint32_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,
383uint32_t nand_block_erase(uint32_t bank, uint32_t page) 426uint32_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);
49const struct nand_device_info_type* nand_get_device_type(uint32_t bank); 49const struct nand_device_info_type* nand_get_device_type(uint32_t bank);
50uint32_t nand_reset(uint32_t bank); 50uint32_t nand_reset(uint32_t bank);
51uint32_t nand_device_init(void); 51uint32_t nand_device_init(void);
52void nand_power_up(void);
53void nand_power_down(void);
52 54
53 55
54#endif 56#endif