Index: firmware/target/arm/as3525/ata_sd_as3525.c =================================================================== --- firmware/target/arm/as3525/ata_sd_as3525.c (revision 22249) +++ firmware/target/arm/as3525/ata_sd_as3525.c (working copy) @@ -104,8 +104,9 @@ static tCardInfo card_info[NUM_DRIVES]; /* maximum timeouts recommanded in the SD Specification v2.00 */ -#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */ -#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */ +#define SD_MCICLK_FREQ (MCI_CLOCK(drive) & MCI_CLOCK_BYPASS)? AS3525_PCLK_FREQ: ((AS3525_PCLK_FREQ) / (2*((MCI_CLOCK(drive) & 0xff) + 1))) +#define SD_MAX_READ_TIMEOUT ((SD_MCICLK_FREQ) / 1000 * 100) /* 100 ms */ +#define SD_MAX_WRITE_TIMEOUT ((SD_MCICLK_FREQ) / 1000 * 250) /* 250 ms */ /* for compatibility */ static long last_disk_activity = -1; @@ -245,6 +246,7 @@ unsigned long response; long init_timeout; bool sdhc; + bool hscard = false; unsigned long temp_reg[4]; int i; @@ -295,6 +297,9 @@ &card_info[drive].rca)) return -6; + /* Change to pushpull bus mode for higher frequencies */ + MCI_POWER(drive) &= ~MCI_POWER_OPEN_DRAIN; + /* send CSD */ if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg)) @@ -305,24 +310,29 @@ sd_parse_csd(&card_info[drive]); + card_info[drive].initialized = 1; + if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) - return -9; + return -8; - 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 -9; + } - 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(); + if(drive) /* Drop freq for uSD Card to spec ( < 50MHz) */ + { + /* MCICLK == PCLK/2 for HS, PCLK/4 for std*/ + MCI_CLOCK(drive) = (MCI_CLOCK(drive) & 0xff00) | (hscard ? 0: 1); + mci_delay(); + } + /* * enable bank switching * without issuing this command, we only have access to 1/4 of the blocks @@ -603,7 +613,7 @@ DMA_PERI_SD, DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL); - MCI_DATA_TIMER(INTERNAL_AS3525) = SD_MAX_WRITE_TIMEOUT; + MCI_DATA_TIMER(INTERNAL_AS3525) = ((AS3525_PCLK_FREQ) / 1000 * 250); /*Max Write Timeout 250 ms */ MCI_DATA_LENGTH(INTERNAL_AS3525) = 512; MCI_DATA_CTRL(INTERNAL_AS3525) = (1<<0) /* enable */ | (0<<1) /* transfer direction */ |