From ffc7323ec3599d09bd3452658c154ad6cd857230 Mon Sep 17 00:00:00 2001 From: Rafaël Carré Date: Sat, 19 Jun 2010 04:55:10 +0000 Subject: 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 --- firmware/target/arm/as3525/sd-as3525v2.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'firmware/target/arm/as3525/sd-as3525v2.c') 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, #ifndef HAVE_MULTIDRIVE const int drive = 0; #endif + bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); + mutex_lock(&sd_mtx); #ifndef BOOTLOADER @@ -828,17 +830,34 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, last_disk_activity = current_tick; dma_retain(); + if(aligned) + { + if(write) + clean_dcache_range(buf, count * SECTOR_SIZE); + else + dump_dcache_range(buf, count * SECTOR_SIZE); + } + const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; do { - void *dma_buf = aligned_buffer; + void *dma_buf; unsigned int transfer = count; - if(transfer > UNALIGNED_NUM_SECTORS) - transfer = UNALIGNED_NUM_SECTORS; - if(write) - memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); + if(aligned) + { + dma_buf = buf; + } + else + { + dma_buf = aligned_buffer; + if(transfer > UNALIGNED_NUM_SECTORS) + transfer = UNALIGNED_NUM_SECTORS; + + if(write) + memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); + } /* Interrupt handler might set this to true during transfer */ retry = false; @@ -893,7 +912,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, if(!retry) { - if(!write) + if(!write && !aligned) memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); buf += transfer * SD_BLOCK_SIZE; start += transfer; -- cgit v1.2.3