Index: firmware/export/sd.h
===================================================================
--- firmware/export/sd.h (revision 22843)
+++ firmware/export/sd.h (working copy)
@@ -97,6 +97,7 @@
#define SD_ERASE 38
#define SD_APP_OP_COND 41
#define SD_LOCK_UNLOCK 42
+#define SD_SET_CLR_CARD_DETECT 42 /* acmd42 */
#define SD_SEND_SCR 51 /* acmd51 */
#define SD_APP_CMD 55

Index: firmware/target/arm/as3525/pcm-as3525.c
===================================================================
--- firmware/target/arm/as3525/pcm-as3525.c (revision 22843)
+++ firmware/target/arm/as3525/pcm-as3525.c (working copy)
@@ -71,8 +71,9 @@
CGU_AUDIO |= (1<<11);

clean_dcache_range((void*)addr, size); /* force write back */
+ /* OF use transfers of 4 * 32 bits words on memory, i2sin, i2sout */
dma_enable_channel(1, (void*)addr, (void*)I2SOUT_DATA, DMA_PERI_I2SOUT,
- DMAC_FLOWCTRL_DMAC_MEM_TO_PERI, true, false, size >> 2, DMA_S1,
+ DMAC_FLOWCTRL_DMAC_MEM_TO_PERI, true, false, size >> 2, DMA_S4,
dma_callback);
}

Index: firmware/target/arm/as3525/system-as3525.c
===================================================================
--- firmware/target/arm/as3525/system-as3525.c (revision 22843)
+++ firmware/target/arm/as3525/system-as3525.c (working copy)
@@ -257,8 +257,8 @@
CCU_SRL = CCU_SRL_MAGIC_NUMBER;
CCU_SRC = CCU_SRL = 0;

- CCU_SCON = 1; /* AHB master's priority configuration :
- TIC (Test Interface Controller) > DMA > USB > IDE > ARM */
+ // CCU_SCON = 1; /* AHB master's priority configuration :
+ // TIC (Test Interface Controller) > DMA > USB > IDE > ARM */

CGU_PROC = 0; /* fclk 24 MHz */
CGU_PERI &= ~0x7f; /* pclk 24 MHz */
Index: firmware/target/arm/as3525/ata_sd_as3525.c
===================================================================
--- firmware/target/arm/as3525/ata_sd_as3525.c (revision 22843)
+++ firmware/target/arm/as3525/ata_sd_as3525.c (working copy)
@@ -95,6 +95,7 @@
#endif
};

+static int sd_wait_for_state(const int drive, unsigned int state);
static int sd_select_bank(signed char bank);
static int sd_init_card(const int drive);
static void init_pl180_controller(const int drive);
@@ -245,6 +246,7 @@
unsigned long response;
long init_timeout;
bool sdhc;
+ bool hscard = false;
unsigned long temp_reg[4];
int i;

@@ -308,21 +310,14 @@
if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL))
return -9;

- if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_ARG, NULL))
- return -10;
+ /* Check card for HS capable and if so switch to HS */
+ if(card_info[drive].speed > 125000)
+ {
+ hscard = true;
+ if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_ARG, NULL))
+ return -90;
+ }

- if(!send_cmd(drive, SD_SET_BUS_WIDTH, card_info[drive].rca | 2, MCI_ARG, NULL))
- return -11;
-
- if(!send_cmd(drive, SD_SET_BLOCKLEN, card_info[drive].blocksize, MCI_ARG,
- NULL))
- return -12;
-
- card_info[drive].initialized = 1;
-
- MCI_CLOCK(drive) |= MCI_CLOCK_BYPASS; /* full speed for controller clock */
- mci_delay();
-
/*
* enable bank switching
* without issuing this command, we only have access to 1/4 of the blocks
@@ -336,6 +331,32 @@
return ret - 13;
}

+ card_info[drive].initialized = 1;
+
+ if(drive)
+ {
+ if(sd_wait_for_state(drive, SD_TRAN) < 0)
+ return -120;
+
+ if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_ARG, NULL))
+ return -10;
+
+ if(!send_cmd(drive, SD_SET_BUS_WIDTH, 2, MCI_ARG, NULL))
+ return -11;
+
+ if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_ARG, NULL))
+ return -100;
+
+ if(!send_cmd(drive, SD_SET_CLR_CARD_DETECT, 0, MCI_ARG, NULL))
+ return -110;
+
+ MCI_CLOCK(drive) |= MCI_CLOCK_WIDEBUS; //(drive? MCI_CLOCK_WIDEBUS: 0); /* full speed for controller clock */
+ mci_delay();
+ }
+
+
+
+
return 0;
}

@@ -464,7 +485,7 @@

MCI_SELECT(drive) = 0;

- MCI_CLOCK(drive) = MCI_CLOCK_ENABLE | AS3525_SD_IDENT_DIV;
+ MCI_CLOCK(drive) = MCI_CLOCK_ENABLE | MCI_CLOCK_BYPASS;
mci_delay();
}

@@ -712,7 +733,7 @@
ret -= 3*20;
goto sd_transfer_error;
}
-
+ /* OF uses transfers of 8 * 32 bits words on SD */
if(write)
dma_enable_channel(0, dma_buf, MCI_FIFO(drive),
(drive == INTERNAL_AS3525) ? DMA_PERI_SD : DMA_PERI_SD_SLOT,
@@ -737,9 +758,10 @@
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);

/* Higher speed class cards need a write delay here for some reason */
+
if((drive == SD_SLOT_AS3525) && write)
{
- int delay = 3500;
+ int delay = 0x3500;
while(delay--) asm volatile ("nop\n");
}

Index: firmware/target/arm/as3525/dma-pl081.c
===================================================================
--- firmware/target/arm/as3525/dma-pl081.c (revision 22843)
+++ firmware/target/arm/as3525/dma-pl081.c (working copy)
@@ -33,28 +33,30 @@
if(++dma_used == 1)
{
CGU_PERI |= CGU_DMA_CLOCK_ENABLE;
- DMAC_CONFIGURATION |= (1<<0);
- }
+ DMAC_CONFIGURATION |= (1<<0); /* SMDMAC enable */
+ }
}

void dma_release(void)
{
if(--dma_used == 0)
{
- DMAC_CONFIGURATION &= ~(1<<0);
+ DMAC_CONFIGURATION &= ~(1<<0); /* SMDMAC disable (save power) */
CGU_PERI &= ~CGU_DMA_CLOCK_ENABLE;
}
}

void dma_init(void)
{
- DMAC_SYNC = 0xffff; /* disable synchronisation logic */
+// DMAC_SYNC = 0xffff; /* disable synchronisation logic */
VIC_INT_ENABLE |= INTERRUPT_DMAC;
}

inline void dma_disable_channel(int channel)
{
- DMAC_CH_CONFIGURATION(channel) &= ~(1<<0);
+ DMAC_CH_CONFIGURATION(channel) |= (1<<19); /* Set Halt Bit */
+ while(DMAC_CH_CONFIGURATION(channel) & (1<<18)); /* Poll Active Bit */
+ DMAC_CH_CONFIGURATION(channel) &= ~(1<<0); /* Clear Enable Bit*/
}

void dma_enable_channel(int channel, void *src, void *dst, int peri,
@@ -63,37 +65,45 @@
{
dma_callback[channel] = callback;

- int control = 0;
+ /* clear any pending interrupts leftover from previous operations */
+ DMAC_INT_TC_CLEAR = (1<<channel);
+ DMAC_INT_ERR_CLEAR = (1<<channel);

DMAC_CH_SRC_ADDR(channel) = (int)src;
DMAC_CH_DST_ADDR(channel) = (int)dst;

DMAC_CH_LLI(channel) = 0; /* we use contigous memory, so don't use the LLI */

- /* specify address increment */
- if(src_inc)
- control |= (1<<26);
-
- if(dst_inc)
- control |= (1<<27);
-
+ /** Channel Control Register */
/* OF use transfers of 4 * 32 bits words on memory, i2sin, i2sout */
/* OF use transfers of 8 * 32 bits words on SD */
+ DMAC_CH_CONTROL(channel) = (
+ (1<<31) /* current LLI triggers terminal count interrupt */
+ /* Protection bits */
+ | (0<<30) /* cacheable = 1, non = 0 */
+ | (1<<29) /* bufferable = 1, non = 0 */
+ | (1<<28) /* privileged = 1, user = 0 */
+ | (dst_inc? (1<<27): 0) /* specify address increment */
+ | (src_inc? (1<<26): 0) /* specify address increment */
+ /* [25:24] */ /* undefined */
+ | (2<<21) /* dst width = word, 32bit */
+ | (2<<18) /* src width = word, 32bit */
+ | (nwords<<15) /* dst size */
+ | (nwords<<12) /* src size */
+ | ((size & 0x7ff)<<0) /* transfer size */
+ );

- control |= (2<<21) | (2<<18); /* dst/src width = word, 32bit */
- control |= (nwords<<15) | (nwords<<12); /* dst/src size */
- control |= (size & 0x7ff); /* transfer size */
-
- control |= (1<<31); /* current LLI is expected to trigger terminal count interrupt */
-
- DMAC_CH_CONTROL(channel) = control;
-
+ /** Channel Config Register */
/* we set the same peripheral as source and destination because we always
* use memory-to-peripheral or peripheral-to-memory transfers */
DMAC_CH_CONFIGURATION(channel) =
- (flow_controller<<11) /* flow controller is peripheral */
+ /* [31:19] */ /* Read undefined. Write as zero */
+ (0<<18) /* Halt Bit */
+ | (0<<17) /* Active Bit */
+ | (0<<16) /* Lock Bit */
| (1<<15) /* terminal count interrupt mask */
| (1<<14) /* interrupt error mask */
+ | (flow_controller<<11) /* flow controller is peripheral */
| (peri<<6) /* dst peripheral */
| (peri<<1) /* src peripheral */
| (1<<0) /* enable channel */