From e6c8a185e53337353e2f182b4625edf2d20542f7 Mon Sep 17 00:00:00 2001 From: Michael Sparmann Date: Sun, 11 Oct 2009 10:10:49 +0000 Subject: Implement NAND power management for iPod Nano 2G git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23099 a1c6a512-1295-4272-9138-f99709370657 --- .../target/arm/s5l8700/ipodnano2g/nand-nano2g.c | 51 +++++++++++++++++++--- .../target/arm/s5l8700/ipodnano2g/nand-target.h | 8 ++-- 2 files changed, 50 insertions(+), 9 deletions(-) (limited to 'firmware/target/arm/s5l8700/ipodnano2g') 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 @@ #include "cpu.h" #include "inttypes.h" #include "nand-target.h" +#include #include @@ -84,6 +85,7 @@ uint8_t nand_twp[4]; uint8_t nand_tunk2[4]; uint8_t nand_tunk3[4]; uint32_t nand_type[4]; +int nand_powered = 0; static struct mutex nand_mtx; static struct wakeup nand_wakeup; @@ -126,6 +128,45 @@ uint32_t nand_timeout(long timeout) } } +void nand_power_up(void) +{ + unsigned char powerup[2] = {0x15, 1}; + mutex_lock(&ecc_mtx); + PWRCONEXT &= ~0x40; + PWRCON &= ~0x100000; + PCON2 = 0x33333333; + PDAT2 = 0; + PCON3 = 0x11113333; + PDAT3 = 0; + PCON4 = 0x33333333; + PDAT4 = 0; + PCON5 = (PCON5 & ~0xF) | 3; + PUNK5 = 1; + pmu_write_multiple(0x35, 2, powerup); + sleep(HZ / 50); + nand_powered = 1; + mutex_unlock(&ecc_mtx); +} + +void nand_power_down(void) +{ + unsigned char powerdown[2] = {0x15, 0}; + mutex_lock(&ecc_mtx); + pmu_write_multiple(0x35, 2, powerdown); + PCON2 = 0x11111111; + PDAT2 = 0; + PCON3 = 0x11111111; + PDAT3 = 0; + PCON4 = 0x11111111; + PDAT4 = 0; + PCON5 = (PCON5 & ~0xF) | 1; + PUNK5 = 1; + PWRCONEXT |= 0x40; + PWRCON |= 0x100000; + nand_powered = 0; + mutex_unlock(&ecc_mtx); +} + uint32_t nand_wait_rbbdone(void) { long timeout = current_tick + HZ / 50; @@ -302,6 +343,7 @@ uint32_t nand_read_page(uint32_t bank, uint32_t page, void* databuffer, uint32_t checkempty) { mutex_lock(&nand_mtx); + if (!nand_powered) nand_power_up(); uint32_t rc, eccresult; nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA); 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, void* sparebuffer, uint32_t doecc) { mutex_lock(&nand_mtx); + if (!nand_powered) nand_power_up(); if (sparebuffer != 0) memcpy(nand_uncached_spare, sparebuffer, 0x40); else memset(nand_uncached_spare, 0xFF, 0x40); if (doecc != 0) @@ -383,6 +426,7 @@ uint32_t nand_write_page(uint32_t bank, uint32_t page, void* databuffer, uint32_t nand_block_erase(uint32_t bank, uint32_t page) { mutex_lock(&nand_mtx); + if (!nand_powered) nand_power_up(); nand_set_fmctrl0(bank, 0); if (nand_send_cmd(NAND_CMD_BLOCKERASE) != 0) return nand_unlock(1); FMANUM = 2; @@ -410,12 +454,7 @@ uint32_t nand_device_init(void) uint32_t type; uint32_t i, j; - PCON2 = 0x33333333; - PDAT2 = 0; - PCON3 = 0x11113333; - PDAT3 = 0; - PCON4 = 0x33333333; - PDAT4 = 0; + if (!nand_powered) nand_power_up(); for (i = 0; i < 4; i++) { 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 @@ * ****************************************************************************/ -#ifndef __NAND_H__ -#define __NAND_H__ +#ifndef __NAND_TARGET_H__ +#define __NAND_TARGET_H__ #include "config.h" #include "inttypes.h" @@ -30,7 +30,7 @@ struct nand_device_info_type { uint32_t id; uint16_t blocks; - uint32_t userblocks; + uint16_t userblocks; uint16_t pagesperblock; uint8_t blocksizeexponent; uint8_t tunk1; @@ -49,6 +49,8 @@ uint32_t nand_block_erase(uint32_t bank, uint32_t page); const struct nand_device_info_type* nand_get_device_type(uint32_t bank); uint32_t nand_reset(uint32_t bank); uint32_t nand_device_init(void); +void nand_power_up(void); +void nand_power_down(void); #endif -- cgit v1.2.3