diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2010-06-19 04:55:10 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2010-06-19 04:55:10 +0000 |
commit | ffc7323ec3599d09bd3452658c154ad6cd857230 (patch) | |
tree | c65741e699cb7239d11286fc16b18cc026dfe576 /firmware/target/arm/as3525/sd-as3525v2.c | |
parent | 9e3f473492353852d07ce359c10540c6f1fbd14a (diff) | |
download | rockbox-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-as3525v2.c')
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525v2.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c index 386b76e758..d268bc779c 100644 --- a/firmware/target/arm/as3525/sd-as3525v2.c +++ b/firmware/target/arm/as3525/sd-as3525v2.c | |||
@@ -789,6 +789,8 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
789 | #ifndef HAVE_MULTIDRIVE | 789 | #ifndef HAVE_MULTIDRIVE |
790 | const int drive = 0; | 790 | const int drive = 0; |
791 | #endif | 791 | #endif |
792 | bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); | ||
793 | |||
792 | 794 | ||
793 | mutex_lock(&sd_mtx); | 795 | mutex_lock(&sd_mtx); |
794 | #ifndef BOOTLOADER | 796 | #ifndef BOOTLOADER |
@@ -828,17 +830,34 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
828 | last_disk_activity = current_tick; | 830 | last_disk_activity = current_tick; |
829 | dma_retain(); | 831 | dma_retain(); |
830 | 832 | ||
833 | if(aligned) | ||
834 | { | ||
835 | if(write) | ||
836 | clean_dcache_range(buf, count * SECTOR_SIZE); | ||
837 | else | ||
838 | dump_dcache_range(buf, count * SECTOR_SIZE); | ||
839 | } | ||
840 | |||
831 | const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; | 841 | const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; |
832 | 842 | ||
833 | do | 843 | do |
834 | { | 844 | { |
835 | void *dma_buf = aligned_buffer; | 845 | void *dma_buf; |
836 | unsigned int transfer = count; | 846 | unsigned int transfer = count; |
837 | if(transfer > UNALIGNED_NUM_SECTORS) | ||
838 | transfer = UNALIGNED_NUM_SECTORS; | ||
839 | 847 | ||
840 | if(write) | 848 | if(aligned) |
841 | memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); | 849 | { |
850 | dma_buf = buf; | ||
851 | } | ||
852 | else | ||
853 | { | ||
854 | dma_buf = aligned_buffer; | ||
855 | if(transfer > UNALIGNED_NUM_SECTORS) | ||
856 | transfer = UNALIGNED_NUM_SECTORS; | ||
857 | |||
858 | if(write) | ||
859 | memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); | ||
860 | } | ||
842 | 861 | ||
843 | /* Interrupt handler might set this to true during transfer */ | 862 | /* Interrupt handler might set this to true during transfer */ |
844 | retry = false; | 863 | retry = false; |
@@ -893,7 +912,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
893 | 912 | ||
894 | if(!retry) | 913 | if(!retry) |
895 | { | 914 | { |
896 | if(!write) | 915 | if(!write && !aligned) |
897 | memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); | 916 | memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); |
898 | buf += transfer * SD_BLOCK_SIZE; | 917 | buf += transfer * SD_BLOCK_SIZE; |
899 | start += transfer; | 918 | start += transfer; |