summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Halpin <jack.halpin@gmail.com>2009-12-13 20:37:55 +0000
committerJack Halpin <jack.halpin@gmail.com>2009-12-13 20:37:55 +0000
commit87770d24393be04bf3f9687fef9a595bbc186998 (patch)
treee3c1c655a1a4627cb156b1f155c0c52b86bcf36d
parentcfe82de67094ede675442fd90f8e7612911afcd7 (diff)
downloadrockbox-87770d24393be04bf3f9687fef9a595bbc186998.zip
rockbox-87770d24393be04bf3f9687fef9a595bbc186998.tar.gz
rockbox-87770d24393be04bf3f9687fef9a595bbc186998.tar.bz2
rockbox-87770d24393be04bf3f9687fef9a595bbc186998.tar.xz
Sansa AMS: Implement 4 bit widebus mode for SD cards.
Both the internal and uSD cards are now put into 4 bit widebus mode during initialization except for bootloader. Add MCI_START_BIT_ERR to MCI_ERROR list and change name to MCI_DATA_ERROR for clarity. Make appropriate changes to SD error codes. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23977 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index ab247c8..754b1ec 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -79,8 +79,12 @@
#define MCI_SELECT(i) (*(volatile unsigned long *) (pl180_base[i]+0x44))
#define MCI_FIFO_CNT(i) (*(volatile unsigned long *) (pl180_base[i]+0x48))
-#define MCI_ERROR \
- (MCI_DATA_CRC_FAIL | MCI_DATA_TIMEOUT | MCI_RX_OVERRUN | MCI_TX_UNDERRUN)
+#define MCI_DATA_ERROR \
+ ( MCI_DATA_CRC_FAIL \
+ | MCI_DATA_TIMEOUT \
+ | MCI_TX_UNDERRUN \
+ | MCI_RX_OVERRUN \
+ | MCI_START_BIT_ERR)
#define MCI_FIFO(i) ((unsigned long *) (pl180_base[i]+0x80))
/* volumes */
@@ -181,7 +185,7 @@ void INT_NAND(void)
{
const int status = MCI_STATUS(INTERNAL_AS3525);
- transfer_error[INTERNAL_AS3525] = status & MCI_ERROR;
+ transfer_error[INTERNAL_AS3525] = status & MCI_DATA_ERROR;
wakeup_signal(&transfer_completion_signal);
MCI_CLEAR(INTERNAL_AS3525) = status;
@@ -192,7 +196,7 @@ void INT_MCI0(void)
{
const int status = MCI_STATUS(SD_SLOT_AS3525);
- transfer_error[SD_SLOT_AS3525] = status & MCI_ERROR;
+ transfer_error[SD_SLOT_AS3525] = status & MCI_DATA_ERROR;
wakeup_signal(&transfer_completion_signal);
MCI_CLEAR(SD_SLOT_AS3525) = status;
@@ -275,7 +279,6 @@ static int sd_init_card(const int drive)
/* CMD0 Go Idle */
if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_FLAGS, NULL))
return -1;
-
mci_delay();
/* CMD8 Check for v2 sd card. Must be sent before using ACMD41
@@ -367,6 +370,32 @@ static int sd_init_card(const int drive)
/* CMD7 w/rca: Select card to put it in TRAN state */
if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL))
return -10;
+ mci_delay();
+
+#ifndef BOOTLOADER
+ /* Switch to to 4 bit widebus mode */
+ if(sd_wait_for_state(drive, SD_TRAN) < 0)
+ return -11;
+ mci_delay();
+ /* CMD55 */
+ if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_ARG, NULL))
+ return -12;
+ mci_delay();
+ /* ACMD6 */
+ if(!send_cmd(drive, SD_SET_BUS_WIDTH, 2, MCI_ARG, NULL))
+ return -13;
+ mci_delay();
+ /* CMD55 */
+ if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_ARG, NULL))
+ return -14;
+ mci_delay();
+ /* ACMD42 */
+ if(!send_cmd(drive, SD_SET_CLR_CARD_DETECT, 0, MCI_ARG, NULL))
+ return -15;
+ mci_delay();
+ /* Now that card is widebus make controller widebus also */
+ MCI_CLOCK(drive) |= MCI_CLOCK_WIDEBUS;
+#endif
/*
* enable bank switching
@@ -378,7 +407,7 @@ static int sd_init_card(const int drive)
{
const int ret = sd_select_bank(-1);
if(ret < 0)
- return ret - 11;
+ return ret -16;
}
card_info[drive].initialized = 1;
@@ -481,7 +510,7 @@ static void init_pl180_controller(const int drive)
MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0;
MCI_CLEAR(drive) = 0x7ff;
- MCI_MASK0(drive) = MCI_ERROR | MCI_DATA_END;
+ MCI_MASK0(drive) = MCI_DATA_ERROR | MCI_DATA_END;
MCI_MASK1(drive) = 0;
#ifdef HAVE_MULTIDRIVE
VIC_INT_ENABLE =
@@ -634,7 +663,7 @@ static int sd_select_bank(signed char bank)
(1<<3) /* DMA */ |
(9<<4) /* 2^9 = 512 */ ;
- /* Wakeup signal comes from NAND/MCIO isr on MCI_ERROR | MCI_DATA_END */
+ /* Wakeup signal from NAND/MCIO isr on MCI_DATA_ERROR | MCI_DATA_END */
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
/* Wait for FIFO to empty, card may still be in PRG state */
@@ -764,7 +793,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
(1<<3) /* DMA */ |
(9<<4) /* 2^9 = 512 */ ;
- /* Wakeup signal comes from NAND/MCIO isr on MCI_ERROR | MCI_DATA_END */
+ /* Wakeup signal from NAND/MCIO isr on MCI_DATA_ERROR | MCI_DATA_END */
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
/* Wait for FIFO to empty, card may still be in PRG state for writes */