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.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index 7e61fa509f..423181ab7a 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -686,6 +686,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
686#endif 686#endif
687 int ret = 0; 687 int ret = 0;
688 unsigned loops = 0; 688 unsigned loops = 0;
689 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1));
689 690
690 mutex_lock(&sd_mtx); 691 mutex_lock(&sd_mtx);
691 sd_enable(true); 692 sd_enable(true);
@@ -717,6 +718,14 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
717 718
718 dma_retain(); 719 dma_retain();
719 720
721 if(aligned)
722 {
723 if(write)
724 clean_dcache_range(buf, count * SECTOR_SIZE);
725 else
726 dump_dcache_range(buf, count * SECTOR_SIZE);
727 }
728
720 while(count) 729 while(count)
721 { 730 {
722 /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH 731 /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH
@@ -758,12 +767,19 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
758 if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ 767 if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */
759 bank_start *= SD_BLOCK_SIZE; 768 bank_start *= SD_BLOCK_SIZE;
760 769
761 dma_buf = aligned_buffer; 770 if(aligned)
762 if(transfer > UNALIGNED_NUM_SECTORS) 771 {
763 transfer = UNALIGNED_NUM_SECTORS; 772 dma_buf = AS3525_PHYSICAL_ADDR(buf);
773 }
774 else
775 {
776 dma_buf = aligned_buffer;
777 if(transfer > UNALIGNED_NUM_SECTORS)
778 transfer = UNALIGNED_NUM_SECTORS;
764 779
765 if(write) 780 if(write)
766 memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); 781 memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE);
782 }
767 783
768 ret = sd_wait_for_tran_state(drive); 784 ret = sd_wait_for_tran_state(drive);
769 if (ret < 0) 785 if (ret < 0)
@@ -822,7 +838,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
822 838
823 if(!transfer_error[drive]) 839 if(!transfer_error[drive])
824 { 840 {
825 if(!write) 841 if(!write && !aligned)
826 memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); 842 memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE);
827 buf += transfer * SD_BLOCK_SIZE; 843 buf += transfer * SD_BLOCK_SIZE;
828 start += transfer; 844 start += transfer;