summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/sd-as3525.c
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2010-06-19 04:55:10 +0000
committerRafaël Carré <rafael.carre@gmail.com>2010-06-19 04:55:10 +0000
commitffc7323ec3599d09bd3452658c154ad6cd857230 (patch)
treec65741e699cb7239d11286fc16b18cc026dfe576 /firmware/target/arm/as3525/sd-as3525.c
parent9e3f473492353852d07ce359c10540c6f1fbd14a (diff)
downloadrockbox-ffc7323ec3599d09bd3452658c154ad6cd857230.tar.gz
rockbox-ffc7323ec3599d09bd3452658c154ad6cd857230.zip
sd-as3525*: handle aligned transfers without memcpy()
test_disk shows 1MB transfers are up to 3 times faster not much difference for 1 or 8 sectors at a time define STORAGE_WANTS_ALIGN to use the fast path when possible git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26953 a1c6a512-1295-4272-9138-f99709370657
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 9e55c16be6..52bf6932ec 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -669,6 +669,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
669#endif 669#endif
670 int ret = 0; 670 int ret = 0;
671 unsigned loops = 0; 671 unsigned loops = 0;
672 bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1));
672 673
673 mutex_lock(&sd_mtx); 674 mutex_lock(&sd_mtx);
674 sd_enable(true); 675 sd_enable(true);
@@ -700,6 +701,14 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
700 701
701 dma_retain(); 702 dma_retain();
702 703
704 if(aligned)
705 {
706 if(write)
707 clean_dcache_range(buf, count * SECTOR_SIZE);
708 else
709 dump_dcache_range(buf, count * SECTOR_SIZE);
710 }
711
703 while(count) 712 while(count)
704 { 713 {
705 /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH 714 /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH
@@ -740,12 +749,19 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
740 if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ 749 if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */
741 bank_start *= SD_BLOCK_SIZE; 750 bank_start *= SD_BLOCK_SIZE;
742 751
743 dma_buf = aligned_buffer; 752 if(aligned)
744 if(transfer > UNALIGNED_NUM_SECTORS) 753 {
745 transfer = UNALIGNED_NUM_SECTORS; 754 dma_buf = buf;
755 }
756 else
757 {
758 dma_buf = aligned_buffer;
759 if(transfer > UNALIGNED_NUM_SECTORS)
760 transfer = UNALIGNED_NUM_SECTORS;
746 761
747 if(write) 762 if(write)
748 memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); 763 memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE);
764 }
749 765
750 ret = sd_wait_for_tran_state(drive); 766 ret = sd_wait_for_tran_state(drive);
751 if (ret < 0) 767 if (ret < 0)
@@ -804,7 +820,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
804 820
805 if(!transfer_error[drive]) 821 if(!transfer_error[drive])
806 { 822 {
807 if(!write) 823 if(!write && !aligned)
808 memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); 824 memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE);
809 buf += transfer * SD_BLOCK_SIZE; 825 buf += transfer * SD_BLOCK_SIZE;
810 start += transfer; 826 start += transfer;