summaryrefslogtreecommitdiff
path: root/firmware
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
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')
-rw-r--r--firmware/export/s5l8700.h1
-rw-r--r--firmware/target/arm/s5l8700/ata-nand-s5l8700.c4
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c51
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-target.h8
-rw-r--r--firmware/target/arm/s5l8700/usb-s5l8700.c31
5 files changed, 66 insertions, 29 deletions
diff --git a/firmware/export/s5l8700.h b/firmware/export/s5l8700.h
index f9e015baff..e649b92c14 100644
--- a/firmware/export/s5l8700.h
+++ b/firmware/export/s5l8700.h
@@ -545,6 +545,7 @@
545#define PDAT4 (*(REG32_PTR_T)(0x3CF00044)) /* The data register for port 4 */ 545#define PDAT4 (*(REG32_PTR_T)(0x3CF00044)) /* The data register for port 4 */
546#define PCON5 (*(REG32_PTR_T)(0x3CF00050)) /* Configures the pins of port 5 */ 546#define PCON5 (*(REG32_PTR_T)(0x3CF00050)) /* Configures the pins of port 5 */
547#define PDAT5 (*(REG32_PTR_T)(0x3CF00054)) /* The data register for port 5 */ 547#define PDAT5 (*(REG32_PTR_T)(0x3CF00054)) /* The data register for port 5 */
548#define PUNK5 (*(REG32_PTR_T)(0x3CF0005C)) /* Unknown thing for port 5 */
548#define PCON6 (*(REG32_PTR_T)(0x3CF00060)) /* Configures the pins of port 6 */ 549#define PCON6 (*(REG32_PTR_T)(0x3CF00060)) /* Configures the pins of port 6 */
549#define PDAT6 (*(REG32_PTR_T)(0x3CF00064)) /* The data register for port 6 */ 550#define PDAT6 (*(REG32_PTR_T)(0x3CF00064)) /* The data register for port 6 */
550#define PCON7 (*(REG32_PTR_T)(0x3CF00070)) /* Configures the pins of port 7 */ 551#define PCON7 (*(REG32_PTR_T)(0x3CF00070)) /* Configures the pins of port 7 */
diff --git a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
index 883c167c78..308f0a5e61 100644
--- a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
+++ b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
@@ -29,6 +29,7 @@
29#include "panic.h" 29#include "panic.h"
30#include "usb.h" 30#include "usb.h"
31#include "ftl-target.h" 31#include "ftl-target.h"
32#include "nand-target.h"
32 33
33/* for compatibility */ 34/* for compatibility */
34long last_disk_activity = -1; 35long last_disk_activity = -1;
@@ -62,14 +63,17 @@ void nand_spindown(int seconds)
62 63
63void nand_sleep(void) 64void nand_sleep(void)
64{ 65{
66 nand_power_down();
65} 67}
66 68
67void nand_sleepnow(void) 69void nand_sleepnow(void)
68{ 70{
71 nand_power_down();
69} 72}
70 73
71void nand_spin(void) 74void nand_spin(void)
72{ 75{
76 nand_power_up();
73} 77}
74 78
75void nand_enable(bool on) 79void nand_enable(bool on)
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
diff --git a/firmware/target/arm/s5l8700/usb-s5l8700.c b/firmware/target/arm/s5l8700/usb-s5l8700.c
index c0bf7a951b..6ad4dcea95 100644
--- a/firmware/target/arm/s5l8700/usb-s5l8700.c
+++ b/firmware/target/arm/s5l8700/usb-s5l8700.c
@@ -20,9 +20,6 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "config.h" 21#include "config.h"
22#include "usb.h" 22#include "usb.h"
23#include "cpu.h"
24#include "system.h"
25#include "string.h"
26 23
27void usb_init_device(void) 24void usb_init_device(void)
28{ 25{
@@ -30,27 +27,21 @@ void usb_init_device(void)
30 27
31void usb_enable(bool on) 28void usb_enable(bool on)
32{ 29{
33 /* This device specific code will eventually give way to proper USB 30 (void)on;
34 handling, which should be the same for all S5L870x targets. */ 31}
35 if (on)
36 {
37#ifdef IPOD_ARCH
38 /* For iPod, we can only do one thing with USB mode atm - reboot
39 into the flash-based disk-mode. This does not return. */
40 32
41 memcpy((void *)0x0002bf00, "diskmodehotstuff\1\0\0\0", 20); 33void usb_attach(void)
34{
42 35
43 system_reboot(); /* Reboot */
44#endif
45 }
46} 36}
47 37
48int usb_detect(void) 38static bool usb_pin_state(void)
49{ 39{
50#if defined(IPOD_NANO2G) 40 return false;
51 if ((PDAT14 & 0x8) == 0x0) 41}
52 return USB_INSERTED;
53#endif
54 42
55 return USB_EXTRACTED; 43/* detect host or charger (INSERTED or EXTRACTED) */
44int usb_detect(void)
45{
46 return usb_pin_state() ? USB_INSERTED : USB_EXTRACTED;
56} 47}