summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Halpin <jack.halpin@gmail.com>2009-12-08 20:26:31 +0000
committerJack Halpin <jack.halpin@gmail.com>2009-12-08 20:26:31 +0000
commitf37fe2563825723f9619ea799f97ff25b8e97d74 (patch)
tree9b36a78b2a294f1f063343f137a255a32153fac3
parent40cbaa5d6cb0e25153b86df9f215b522b58f9120 (diff)
downloadrockbox-f37fe2563825723f9619ea799f97ff25b8e97d74.tar.gz
rockbox-f37fe2563825723f9619ea799f97ff25b8e97d74.zip
Sansa AMS: Run all SD cards within SD Specification frequencies.
Addition of a small write delay avoids data crc failures at lower MCICLK frequencies. Check the actual speed value from the card's CSD register to determine HS status. HS cards can run at twice the speed of standard speed SD cards. Internal cards & standard speed uSD now run at PCLK/4 = 15.5 MHz. HS uSD cards run at PCLK/2 = 31 MHz. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23901 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c
index 43c1a37670..d59777a57d 100644
--- a/firmware/target/arm/as3525/ata_sd_as3525.c
+++ b/firmware/target/arm/as3525/ata_sd_as3525.c
@@ -336,9 +336,6 @@ static int sd_init_card(const int drive)
336 } 336 }
337#endif /* HAVE_MULTIDRIVE */ 337#endif /* HAVE_MULTIDRIVE */
338 338
339 /* Boost MCICLK to operating speed */ /*FIXME: v1 at 31 MHz still too high*/
340 MCI_CLOCK(drive) = (sd_v2 ? MCI_HALFSPEED : MCI_HALFSPEED);
341
342 /* CMD9 send CSD */ 339 /* CMD9 send CSD */
343 if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, 340 if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca,
344 MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg)) 341 MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg))
@@ -349,6 +346,14 @@ static int sd_init_card(const int drive)
349 346
350 sd_parse_csd(&card_info[drive]); 347 sd_parse_csd(&card_info[drive]);
351 348
349 /* Boost MCICLK to operating speed */
350 if(drive == INTERNAL_AS3525)
351 MCI_CLOCK(drive) = MCI_QUARTERSPEED; /* MCICLK = PCLK/4 = 15.5MHz */
352 else
353 /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/
354 MCI_CLOCK(drive) = ((card_info[drive].speed == 50000000) ?
355 MCI_HALFSPEED : MCI_QUARTERSPEED);
356
352 /* CMD7 w/rca: Select card to put it in TRAN state */ 357 /* CMD7 w/rca: Select card to put it in TRAN state */
353 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) 358 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL))
354 return -10; 359 return -10;
@@ -619,6 +624,7 @@ static int sd_select_bank(signed char bank)
619 (1<<3) /* DMA */ | 624 (1<<3) /* DMA */ |
620 (9<<4) /* 2^9 = 512 */ ; 625 (9<<4) /* 2^9 = 512 */ ;
621 626
627 /* Wakeup signal comes from NAND/MCIO isr on MCI_ERROR | MCI_DATA_END */
622 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 628 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
623 629
624 /* Wait for FIFO to empty, card may still be in PRG state */ 630 /* Wait for FIFO to empty, card may still be in PRG state */
@@ -697,16 +703,17 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
697 transfer = BLOCKS_PER_BANK - bank_start; 703 transfer = BLOCKS_PER_BANK - bank_start;
698 } 704 }
699 705
706 /* Set bank_start to the correct unit (blocks or bytes) */
707 if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */
708 bank_start *= SD_BLOCK_SIZE;
709
700 dma_buf = aligned_buffer; 710 dma_buf = aligned_buffer;
701 if(transfer > UNALIGNED_NUM_SECTORS) 711 if(transfer > UNALIGNED_NUM_SECTORS)
702 transfer = UNALIGNED_NUM_SECTORS; 712 transfer = UNALIGNED_NUM_SECTORS;
713
703 if(write) 714 if(write)
704 memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); 715 memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE);
705 716
706 /* Set bank_start to the correct unit (blocks or bytes) */
707 if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */
708 bank_start *= SD_BLOCK_SIZE;
709
710 ret = sd_wait_for_state(drive, SD_TRAN); 717 ret = sd_wait_for_state(drive, SD_TRAN);
711 if (ret < 0) 718 if (ret < 0)
712 { 719 {
@@ -721,17 +728,20 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
721 } 728 }
722 729
723 if(write) 730 if(write)
731 {
724 dma_enable_channel(0, dma_buf, MCI_FIFO(drive), 732 dma_enable_channel(0, dma_buf, MCI_FIFO(drive),
725 (drive == INTERNAL_AS3525) ? DMA_PERI_SD : DMA_PERI_SD_SLOT, 733 (drive == INTERNAL_AS3525) ? DMA_PERI_SD : DMA_PERI_SD_SLOT,
726 DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL); 734 DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL);
735
736 /*Small delay for writes prevents data crc failures at lower freqs*/
737 int write_delay = 125;
738 while(write_delay--);
739 }
727 else 740 else
728 dma_enable_channel(0, MCI_FIFO(drive), dma_buf, 741 dma_enable_channel(0, MCI_FIFO(drive), dma_buf,
729 (drive == INTERNAL_AS3525) ? DMA_PERI_SD : DMA_PERI_SD_SLOT, 742 (drive == INTERNAL_AS3525) ? DMA_PERI_SD : DMA_PERI_SD_SLOT,
730 DMAC_FLOWCTRL_PERI_PERI_TO_MEM, false, true, 0, DMA_S8, NULL); 743 DMAC_FLOWCTRL_PERI_PERI_TO_MEM, false, true, 0, DMA_S8, NULL);
731 744
732 /* FIXME : we should check if the timeouts calculated from the card's
733 * CSD are lower, and use them if it is the case
734 * Note : the OF doesn't seem to use them anyway */
735 MCI_DATA_TIMER(drive) = write ? 745 MCI_DATA_TIMER(drive) = write ?
736 SD_MAX_WRITE_TIMEOUT : SD_MAX_READ_TIMEOUT; 746 SD_MAX_WRITE_TIMEOUT : SD_MAX_READ_TIMEOUT;
737 MCI_DATA_LENGTH(drive) = transfer * SD_BLOCK_SIZE; 747 MCI_DATA_LENGTH(drive) = transfer * SD_BLOCK_SIZE;
@@ -740,6 +750,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
740 (1<<3) /* DMA */ | 750 (1<<3) /* DMA */ |
741 (9<<4) /* 2^9 = 512 */ ; 751 (9<<4) /* 2^9 = 512 */ ;
742 752
753 /* Wakeup signal comes from NAND/MCIO isr on MCI_ERROR | MCI_DATA_END */
743 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 754 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
744 755
745 /* Wait for FIFO to empty, card may still be in PRG state for writes */ 756 /* Wait for FIFO to empty, card may still be in PRG state for writes */