1
0
Fork 0
forked from len0rd/rockbox

Implement NAND power management for iPod Nano 2G

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23099 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sparmann 2009-10-11 10:10:49 +00:00
parent 0260b0ad5a
commit e6c8a185e5
5 changed files with 68 additions and 31 deletions

View file

@ -545,6 +545,7 @@
#define PDAT4 (*(REG32_PTR_T)(0x3CF00044)) /* The data register for port 4 */
#define PCON5 (*(REG32_PTR_T)(0x3CF00050)) /* Configures the pins of port 5 */
#define PDAT5 (*(REG32_PTR_T)(0x3CF00054)) /* The data register for port 5 */
#define PUNK5 (*(REG32_PTR_T)(0x3CF0005C)) /* Unknown thing for port 5 */
#define PCON6 (*(REG32_PTR_T)(0x3CF00060)) /* Configures the pins of port 6 */
#define PDAT6 (*(REG32_PTR_T)(0x3CF00064)) /* The data register for port 6 */
#define PCON7 (*(REG32_PTR_T)(0x3CF00070)) /* Configures the pins of port 7 */

View file

@ -29,6 +29,7 @@
#include "panic.h"
#include "usb.h"
#include "ftl-target.h"
#include "nand-target.h"
/* for compatibility */
long last_disk_activity = -1;
@ -62,14 +63,17 @@ void nand_spindown(int seconds)
void nand_sleep(void)
{
nand_power_down();
}
void nand_sleepnow(void)
{
nand_power_down();
}
void nand_spin(void)
{
nand_power_up();
}
void nand_enable(bool on)

View file

@ -26,6 +26,7 @@
#include "cpu.h"
#include "inttypes.h"
#include "nand-target.h"
#include <pmu-target.h>
#include <string.h>
@ -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;

View file

@ -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

View file

@ -20,9 +20,6 @@
****************************************************************************/
#include "config.h"
#include "usb.h"
#include "cpu.h"
#include "system.h"
#include "string.h"
void usb_init_device(void)
{
@ -30,27 +27,21 @@ void usb_init_device(void)
void usb_enable(bool on)
{
/* This device specific code will eventually give way to proper USB
handling, which should be the same for all S5L870x targets. */
if (on)
{
#ifdef IPOD_ARCH
/* For iPod, we can only do one thing with USB mode atm - reboot
into the flash-based disk-mode. This does not return. */
memcpy((void *)0x0002bf00, "diskmodehotstuff\1\0\0\0", 20);
system_reboot(); /* Reboot */
#endif
}
(void)on;
}
void usb_attach(void)
{
}
static bool usb_pin_state(void)
{
return false;
}
/* detect host or charger (INSERTED or EXTRACTED) */
int usb_detect(void)
{
#if defined(IPOD_NANO2G)
if ((PDAT14 & 0x8) == 0x0)
return USB_INSERTED;
#endif
return USB_EXTRACTED;
return usb_pin_state() ? USB_INSERTED : USB_EXTRACTED;
}