summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/sd-as3525.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/as3525/sd-as3525.c')
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index 0dc29c8aa5..6f11145ee6 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -116,9 +116,8 @@ static void init_pl180_controller(const int drive);
116static tCardInfo card_info[NUM_DRIVES]; 116static tCardInfo card_info[NUM_DRIVES];
117 117
118/* maximum timeouts recommanded in the SD Specification v2.00 */ 118/* maximum timeouts recommanded in the SD Specification v2.00 */
119#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */ 119#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ*(cpu_frequency==CPUFREQ_MAX?2:1)) / 1000 * 100) /* 100 ms */
120#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */ 120#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ*(cpu_frequency==CPUFREQ_MAX?2:1)) / 1000 * 250) /* 250 ms */
121
122/* for compatibility */ 121/* for compatibility */
123static long last_disk_activity = -1; 122static long last_disk_activity = -1;
124 123
@@ -140,6 +139,8 @@ static struct wakeup transfer_completion_signal;
140static volatile unsigned int transfer_error[NUM_VOLUMES]; 139static volatile unsigned int transfer_error[NUM_VOLUMES];
141#define PL180_MAX_TRANSFER_ERRORS 10 140#define PL180_MAX_TRANSFER_ERRORS 10
142 141
142extern long cpu_frequency;
143
143#define UNALIGNED_NUM_SECTORS 10 144#define UNALIGNED_NUM_SECTORS 10
144static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SD_BLOCK_SIZE] __attribute__((aligned(32))); /* align on cache line size */ 145static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SD_BLOCK_SIZE] __attribute__((aligned(32))); /* align on cache line size */
145static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0]); 146static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0]);
@@ -283,7 +284,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
283#define MCI_HALFSPEED (MCI_CLOCK_ENABLE) /* MCLK/2 */ 284#define MCI_HALFSPEED (MCI_CLOCK_ENABLE) /* MCLK/2 */
284#define MCI_QUARTERSPEED (MCI_CLOCK_ENABLE | 1) /* MCLK/4 */ 285#define MCI_QUARTERSPEED (MCI_CLOCK_ENABLE | 1) /* MCLK/4 */
285#define MCI_IDENTSPEED (MCI_CLOCK_ENABLE | AS3525_SD_IDENT_DIV) /* IDENT */ 286#define MCI_IDENTSPEED (MCI_CLOCK_ENABLE | AS3525_SD_IDENT_DIV) /* IDENT */
286 287#define MCI_IDENTSPEED_BOOSTED (MCI_CLOCK_ENABLE | AS3525_SD_IDENT_DIV_BOOSTED)
287static int sd_init_card(const int drive) 288static int sd_init_card(const int drive)
288{ 289{
289 unsigned long response; 290 unsigned long response;
@@ -293,7 +294,10 @@ static int sd_init_card(const int drive)
293 card_info[drive].rca = 0; 294 card_info[drive].rca = 0;
294 295
295 /* MCLCK on and set to 400kHz ident frequency */ 296 /* MCLCK on and set to 400kHz ident frequency */
296 MCI_CLOCK(drive) = MCI_IDENTSPEED; 297 if (cpu_frequency == CPUFREQ_MAX)
298 MCI_CLOCK(drive) = MCI_IDENTSPEED_BOOSTED;
299 else
300 MCI_CLOCK(drive) = MCI_IDENTSPEED;
297 301
298 /* 100 - 400kHz clock required for Identification Mode */ 302 /* 100 - 400kHz clock required for Identification Mode */
299 /* Start of Card Identification Mode ************************************/ 303 /* Start of Card Identification Mode ************************************/
@@ -375,8 +379,12 @@ static int sd_init_card(const int drive)
375 MCI_CLOCK(drive) = MCI_HALFSPEED; /* MCICLK = IDE_CLK/2 = 25 MHz */ 379 MCI_CLOCK(drive) = MCI_HALFSPEED; /* MCICLK = IDE_CLK/2 = 25 MHz */
376#if defined(HAVE_MULTIDRIVE) 380#if defined(HAVE_MULTIDRIVE)
377 else 381 else
378 /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/ 382 { /* PCLK = 31Mhz (62 boosted) MCI = 31Mhz(hs) or 15.5 */
379 MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED); 383 if (cpu_frequency == CPUFREQ_MAX )
384 MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED);
385 else
386 MCI_CLOCK(drive) = (hs_card ? MCI_FULLSPEED : MCI_HALFSPEED);
387 }
380#endif 388#endif
381 389
382 /* CMD7 w/rca: Select card to put it in TRAN state */ 390 /* CMD7 w/rca: Select card to put it in TRAN state */
@@ -523,6 +531,26 @@ static void sd_thread(void)
523 } 531 }
524} 532}
525 533
534#ifdef HAVE_MULTIDRIVE
535void sd_set_boosted_divider(void)
536{
537 if ( !sd_enabled )
538 return;
539 /* 62Mhz/2 - 62/4 */
540 MCI_CLOCK(SD_SLOT_AS3525) = (hs_card ?
541 MCI_HALFSPEED : MCI_QUARTERSPEED);
542}
543
544void sd_set_unboosted_divider(void)
545{
546 if ( !sd_enabled )
547 return;
548 /* 31Mhz/1 - 31/2 */
549 MCI_CLOCK(SD_SLOT_AS3525) = (hs_card ?
550 MCI_FULLSPEED : MCI_HALFSPEED);
551}
552#endif
553
526static void init_pl180_controller(const int drive) 554static void init_pl180_controller(const int drive)
527{ 555{
528 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0; 556 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0;