diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 31 |
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 */ |