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-as3525.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-as3525.c')
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525.c | 28 |
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; |