From 28bcc17ddef4cfad2d1a669869f2f81f0724acb9 Mon Sep 17 00:00:00 2001 From: Rafaël Carré Date: Wed, 23 Jun 2010 04:34:23 +0000 Subject: revert r27044 (which was a revert of r26953 & r26954) The bug was in playback.c and was fixed in previous commit git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27074 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/as3525/sd-as3525.c | 28 +++++++++++++++++++++------ firmware/target/arm/as3525/sd-as3525v2.c | 31 ++++++++++++++++++++++++------ firmware/target/arm/as3525/system-target.h | 6 ++++++ 3 files changed, 53 insertions(+), 12 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, #endif int ret = 0; unsigned loops = 0; + bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); mutex_lock(&sd_mtx); sd_enable(true); @@ -717,6 +718,14 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, dma_retain(); + if(aligned) + { + if(write) + clean_dcache_range(buf, count * SECTOR_SIZE); + else + dump_dcache_range(buf, count * SECTOR_SIZE); + } + while(count) { /* 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, if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ bank_start *= SD_BLOCK_SIZE; - dma_buf = aligned_buffer; - if(transfer > UNALIGNED_NUM_SECTORS) - transfer = UNALIGNED_NUM_SECTORS; + if(aligned) + { + dma_buf = AS3525_PHYSICAL_ADDR(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); + if(write) + memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); + } ret = sd_wait_for_tran_state(drive); if (ret < 0) @@ -822,7 +838,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, if(!transfer_error[drive]) { - if(!write) + if(!write && !aligned) memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); buf += transfer * SD_BLOCK_SIZE; start += transfer; diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c index 386b76e758..238cd7a5eb 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 = AS3525_PHYSICAL_ADDR(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; diff --git a/firmware/target/arm/as3525/system-target.h b/firmware/target/arm/as3525/system-target.h index f7dc1ac312..b3b9001a45 100644 --- a/firmware/target/arm/as3525/system-target.h +++ b/firmware/target/arm/as3525/system-target.h @@ -27,6 +27,8 @@ #include "clock-target.h" /* CPUFREQ_* are defined here */ +#define STORAGE_WANTS_ALIGN + /* We can use a interrupt-based mechanism on the fuzev2 */ #define INCREASED_SCROLLWHEEL_POLLING \ (defined(HAVE_SCROLLWHEEL) && (CONFIG_CPU == AS3525)) @@ -39,6 +41,10 @@ #endif #define AS3525_UNCACHED_ADDR(a) ((typeof(a)) ((uintptr_t)(a) + 0x10000000)) +#define AS3525_PHYSICAL_ADDR(a) \ + ((typeof(a)) ((((uintptr_t)(a)) & (MEM*0x100000)) \ + ? (((uintptr_t)(a)) - IRAM_ORIG) \ + : ((uintptr_t)(a)))) #ifdef SANSA_C200V2 /* 0: Backlight on A5, 1: Backlight on A7 */ -- cgit v1.2.3