mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 13:12:37 -05:00
Sansa AS3525V1 Sd Interface implement powersave mode
This patch cleans up the sd driver for the V1 sansas powersave implemented for the sd interface Change-Id: I3d864f7aa304cf792cc65fa4ff06c1e52fbed329
This commit is contained in:
parent
f45db552f3
commit
9f336217c2
1 changed files with 65 additions and 30 deletions
|
|
@ -89,6 +89,8 @@
|
|||
| MCI_CMD_CRC_FAIL)
|
||||
|
||||
#define MCI_FIFO(i) ((unsigned long *) (pl180_base[i]+0x80))
|
||||
|
||||
#define IDE_INTERFACE_CLK (1<<6) /* non AHB interface */
|
||||
/* volumes */
|
||||
#define INTERNAL_AS3525 0 /* embedded SD card */
|
||||
#define SD_SLOT_AS3525 1 /* SD slot if present */
|
||||
|
|
@ -109,7 +111,8 @@ static void init_pl180_controller(const int drive);
|
|||
|
||||
static tCardInfo card_info[NUM_DRIVES];
|
||||
|
||||
/* maximum timeouts recommanded in the SD Specification v2.00 */
|
||||
/* maximum timeouts recommended in the SD Specification v2.00 */
|
||||
/* MCI_DATA_TIMER register data timeout in card bus clock periods */
|
||||
#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */
|
||||
#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */
|
||||
|
||||
|
|
@ -143,7 +146,17 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
|
|||
|
||||
static inline void mci_delay(void) { udelay(1000) ; }
|
||||
|
||||
static void enable_controller(bool on)
|
||||
static inline bool card_detect_target(void)
|
||||
{
|
||||
#if defined(HAVE_MULTIDRIVE)
|
||||
return !(GPIOA_PIN(2));
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(HAVE_MULTIDRIVE) || defined(HAVE_HOTSWAP)
|
||||
static void enable_controller_mci(bool on)
|
||||
{
|
||||
|
||||
#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
|
||||
|
|
@ -197,17 +210,33 @@ static void enable_controller(bool on)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* defined(HAVE_MULTIDRIVE) || defined(HAVE_HOTSWAP) */
|
||||
|
||||
static inline bool card_detect_target(void)
|
||||
/* AMS v1 have two different drive interfaces MCI_SD(XPD) and GGU_IDE */
|
||||
static void enable_controller(bool on, const int drive)
|
||||
{
|
||||
#if defined(HAVE_MULTIDRIVE)
|
||||
return !(GPIOA_PIN(2));
|
||||
#else
|
||||
return false;
|
||||
|
||||
if (drive == INTERNAL_AS3525)
|
||||
{
|
||||
#ifndef BOOTLOADER
|
||||
if (on)
|
||||
{
|
||||
bitset32(&CGU_PERI, CGU_NAF_CLOCK_ENABLE);
|
||||
CGU_IDE |= IDE_INTERFACE_CLK; /* interface enable */
|
||||
}
|
||||
else
|
||||
{
|
||||
CGU_IDE &= ~(IDE_INTERFACE_CLK); /* interface disable */
|
||||
bitclr32(&CGU_PERI, CGU_NAF_CLOCK_ENABLE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if defined(HAVE_MULTIDRIVE) || defined(HAVE_HOTSWAP)
|
||||
else
|
||||
enable_controller_mci(on);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_HOTSWAP
|
||||
static int sd1_oneshot_callback(struct timeout *tmo)
|
||||
{
|
||||
|
|
@ -326,6 +355,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* MCI_CLOCK = MCLK / 2x(ClkDiv[bits 7:0]+1) */
|
||||
#define MCI_FULLSPEED (MCI_CLOCK_ENABLE | MCI_CLOCK_BYPASS) /* MCLK */
|
||||
#define MCI_HALFSPEED (MCI_CLOCK_ENABLE) /* MCLK/2 */
|
||||
#define MCI_QUARTERSPEED (MCI_CLOCK_ENABLE | 1) /* MCLK/4 */
|
||||
|
|
@ -345,7 +375,7 @@ static int sd_init_card(const int drive)
|
|||
/* 100 - 400kHz clock required for Identification Mode */
|
||||
/* Start of Card Identification Mode ************************************/
|
||||
|
||||
/* CMD0 Go Idle */
|
||||
/* CMD0 Go Idle -- all card functions switch back to default */
|
||||
if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL))
|
||||
return -1;
|
||||
mci_delay();
|
||||
|
|
@ -393,10 +423,10 @@ static int sd_init_card(const int drive)
|
|||
|
||||
if(sd_wait_for_tran_state(drive))
|
||||
return -6;
|
||||
/* CMD6 */
|
||||
/* CMD6 0xf indicates no influence, [3:0],0x1 - HS Access*/
|
||||
if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_NO_RESP, NULL))
|
||||
return -7;
|
||||
sleep(HZ/10);
|
||||
sleep(HZ/10);/* need to wait at least 8 clock periods */
|
||||
|
||||
/* go back to STBY state so we can read csd */
|
||||
/* CMD7 w/rca=0: Deselect card to put it in STBY state */
|
||||
|
|
@ -423,7 +453,8 @@ static int sd_init_card(const int drive)
|
|||
#if defined(HAVE_MULTIDRIVE)
|
||||
else
|
||||
/* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/
|
||||
MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED);
|
||||
MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED) |
|
||||
MCI_CLOCK_POWERSAVE; /* SD supports powersave */
|
||||
#endif
|
||||
|
||||
/* CMD7 w/rca: Select card to put it in TRAN state */
|
||||
|
|
@ -517,7 +548,7 @@ static void init_pl180_controller(const int drive)
|
|||
int sd_init(void)
|
||||
{
|
||||
int ret;
|
||||
CGU_IDE = (1<<6) /* enable non AHB interface*/
|
||||
CGU_IDE = IDE_INTERFACE_CLK /* enable interface */
|
||||
| (AS3525_IDE_DIV << 2)
|
||||
| AS3525_CLK_PLLA; /* clock source = PLLA */
|
||||
|
||||
|
|
@ -540,7 +571,9 @@ int sd_init(void)
|
|||
/* init mutex */
|
||||
mutex_init(&sd_mtx);
|
||||
|
||||
enable_controller(false);
|
||||
for (int i = 0; i < NUM_DRIVES ; i++)
|
||||
enable_controller(false, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -656,7 +689,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
|
|||
unsigned long response;
|
||||
bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1));
|
||||
|
||||
enable_controller(true);
|
||||
enable_controller(true, drive);
|
||||
led(true);
|
||||
|
||||
if (card_info[drive].initialized <= 0)
|
||||
|
|
@ -692,17 +725,15 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
|
|||
else
|
||||
discard_dcache_range(buf, count * SECTOR_SIZE);
|
||||
}
|
||||
|
||||
while(count)
|
||||
const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
|
||||
while(count > 0)
|
||||
{
|
||||
/* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH
|
||||
* register, so we have to transfer maximum 127 sectors at a time. */
|
||||
unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */
|
||||
void *dma_buf;
|
||||
const int cmd =
|
||||
write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
|
||||
|
||||
unsigned long bank_start = start;
|
||||
unsigned long status;
|
||||
|
||||
/* Only switch banks for internal storage */
|
||||
if(drive == INTERNAL_AS3525)
|
||||
|
|
@ -770,10 +801,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
|
|||
/*Small delay for writes prevents data crc failures at lower freqs*/
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
if((drive == SD_SLOT_AS3525) && !hs_card)
|
||||
{
|
||||
int write_delay = 125;
|
||||
while(write_delay--);
|
||||
}
|
||||
udelay(4);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
@ -804,7 +832,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
|
|||
|
||||
last_disk_activity = current_tick;
|
||||
|
||||
if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP, &status))
|
||||
if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP, &response))
|
||||
{
|
||||
ret = -4*20;
|
||||
goto sd_transfer_error;
|
||||
|
|
@ -831,7 +859,7 @@ sd_transfer_error:
|
|||
sd_transfer_error_nodma:
|
||||
|
||||
led(false);
|
||||
enable_controller(false);
|
||||
enable_controller(false, drive);
|
||||
|
||||
if (ret) /* error */
|
||||
card_info[drive].initialized = 0;
|
||||
|
|
@ -922,12 +950,18 @@ void ams_sd_get_debug_info(struct ams_sd_debug_info *info)
|
|||
#define MCI_SD *((volatile unsigned long *)(SD_MCI_BASE + 0x04))
|
||||
|
||||
mutex_lock(&sd_mtx);
|
||||
enable_controller(true); /* must be on to read regs */
|
||||
|
||||
for (int i = 0; i < NUM_DRIVES ; i++)
|
||||
enable_controller(true, i); /* must be on to read regs */
|
||||
|
||||
info->mci_nand = MCI_NAND;
|
||||
#ifdef HAVE_MULTIDRIVE
|
||||
info->mci_sd = MCI_SD;
|
||||
#endif
|
||||
enable_controller(false);
|
||||
|
||||
for (int i = 0; i < NUM_DRIVES ; i++)
|
||||
enable_controller(false, i);
|
||||
|
||||
mutex_unlock(&sd_mtx);
|
||||
}
|
||||
|
||||
|
|
@ -948,10 +982,10 @@ int sd_event(long id, intptr_t data)
|
|||
|
||||
if (id == SYS_HOTSWAP_INSERTED)
|
||||
{
|
||||
enable_controller(true);
|
||||
enable_controller(true, data);
|
||||
init_pl180_controller(data);
|
||||
rc = sd_init_card(data);
|
||||
enable_controller(false);
|
||||
enable_controller(false, data);
|
||||
}
|
||||
|
||||
mutex_unlock(&sd_mtx);
|
||||
|
|
@ -968,3 +1002,4 @@ int sd_event(long id, intptr_t data)
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue