From f5041538574c039b07c4db8d261bd33ec0f3bab0 Mon Sep 17 00:00:00 2001 From: Rafaël Carré Date: Mon, 8 Jun 2009 23:05:33 +0000 Subject: FS#10048 : enable MMU and data cache on Sansa AMS to give a major speed up - cache IRAM and DRAM - map IRAM just next to DRAM to remove the need for -mlong-calls and reduce binsize - tweak delays in Fuze button code - tweak delays in Clip button code (down button sometimes doesn't respond anyway : an alternate driver is being worked on) Before reporting any problem, please check your filesystem or format your player from the OF git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21228 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/as3525/app.lds | 14 +++++----- firmware/target/arm/as3525/ata_sd_as3525.c | 25 ++++++++---------- firmware/target/arm/as3525/boot.lds | 6 ----- firmware/target/arm/as3525/pcm-as3525.c | 11 ++++++++ .../target/arm/as3525/sansa-clip/button-clip.c | 5 +++- .../target/arm/as3525/sansa-fuze/button-fuze.c | 2 +- firmware/target/arm/as3525/system-as3525.c | 30 +++++++++++++++++++--- firmware/target/arm/as3525/system-target.h | 6 +++++ 8 files changed, 65 insertions(+), 34 deletions(-) (limited to 'firmware/target/arm/as3525') diff --git a/firmware/target/arm/as3525/app.lds b/firmware/target/arm/as3525/app.lds index 45ae30f9f3..eb5b28f852 100644 --- a/firmware/target/arm/as3525/app.lds +++ b/firmware/target/arm/as3525/app.lds @@ -55,6 +55,12 @@ SECTIONS { loadaddress = DRAM_ORIG; + .vectors : + { + _vectors_start = .; + *(.init.text) + } > DRAM + .text : { _loadaddress = .; @@ -83,14 +89,6 @@ SECTIONS *(.eh_frame) } - .vectors IRAMORIG: - { - _vectors_start = .; - *(.init.text) - } > IRAM AT > DRAM - - _vectorscopy = LOADADDR(.vectors); - .iram : { _iramstart = .; diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index b3ab31b293..91d65235ef 100644 --- a/firmware/target/arm/as3525/ata_sd_as3525.c +++ b/firmware/target/arm/as3525/ata_sd_as3525.c @@ -595,7 +595,7 @@ static int sd_select_bank(signed char bank) dma_enable_channel(0, card_data, MCI_FIFO(INTERNAL_AS3525), DMA_PERI_SD, DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL); - MCI_DATA_TIMER(INTERNAL_AS3525) = 0x1000000; /* FIXME: arbitrary */ + MCI_DATA_TIMER(INTERNAL_AS3525) = 0xffffffff;/* FIXME: arbitrary */ MCI_DATA_LENGTH(INTERNAL_AS3525) = 512; MCI_DATA_CTRL(INTERNAL_AS3525) = (1<<0) /* enable */ | (0<<1) /* transfer direction */ | @@ -618,7 +618,8 @@ static int sd_select_bank(signed char bank) } #define UNALIGNED_NUM_SECTORS 10 -static int32_t aligned_buffer[UNALIGNED_NUM_SECTORS* (SECTOR_SIZE / 4)]; +static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SECTOR_SIZE] __attribute__((aligned(32))); /* align on cache line size */ +static unsigned char *uncached_buffer = UNCACHED_ADDR(aligned_buffer); static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, int count, void* buf, const bool write) @@ -627,7 +628,6 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, const int drive = 0; #endif int ret = 0; - bool unaligned_transfer = (int)buf & 3; /* skip SanDisk OF */ if (drive == INTERNAL_AS3525) @@ -693,16 +693,11 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, transfer = BLOCKS_PER_BANK - bank_start; } - if(unaligned_transfer) - { - dma_buf = aligned_buffer; - if(transfer > UNALIGNED_NUM_SECTORS) - transfer = UNALIGNED_NUM_SECTORS; - if(write) - memcpy(aligned_buffer, buf, transfer * SECTOR_SIZE); - } - else /* Aligned transfers are faster : no memcpy */ - dma_buf = buf; + dma_buf = aligned_buffer; + if(transfer > UNALIGNED_NUM_SECTORS) + transfer = UNALIGNED_NUM_SECTORS; + if(write) + memcpy(uncached_buffer, buf, transfer * SECTOR_SIZE); /* Set bank_start to the correct unit (blocks or bytes) */ if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ @@ -734,8 +729,8 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); if(!retry) { - if(unaligned_transfer && !write) - memcpy(buf, aligned_buffer, transfer * SECTOR_SIZE); + if(!write) + memcpy(buf, uncached_buffer, transfer * SECTOR_SIZE); buf += transfer * SECTOR_SIZE; start += transfer; count -= transfer; diff --git a/firmware/target/arm/as3525/boot.lds b/firmware/target/arm/as3525/boot.lds index a98763e8f6..9c6d6faf11 100644 --- a/firmware/target/arm/as3525/boot.lds +++ b/firmware/target/arm/as3525/boot.lds @@ -6,17 +6,11 @@ OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) STARTUP(target/arm/crt0.o) -/* -No need for DRAM in our bootloader -#define DRAMSIZE (MEMORYSIZE * 0x100000) - TTB_SIZE -#define DRAMORIG 0x30000000 -*/ #define IRAMORIG 0x81000000 #define IRAMSIZE 0x50000 MEMORY { - /*DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE*/ IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE } diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c index 5074941f4a..4f9e18523d 100644 --- a/firmware/target/arm/as3525/pcm-as3525.c +++ b/firmware/target/arm/as3525/pcm-as3525.c @@ -28,6 +28,7 @@ #include "panic.h" #include "as3514.h" #include "audiohw.h" +#include "mmu-arm.h" #define MAX_TRANSFER (4*((1<<11)-1)) /* maximum data we can transfer via DMA * i.e. 32 bits at once (size of I2SO_DATA) @@ -69,6 +70,7 @@ static void play_start_pcm(void) CGU_PERI |= CGU_I2SOUT_APB_CLOCK_ENABLE; CGU_AUDIO |= (1<<11); + clean_dcache_range((void*)addr, size); /* force write back */ dma_enable_channel(1, (void*)addr, (void*)I2SOUT_DATA, DMA_PERI_I2SOUT, DMAC_FLOWCTRL_DMAC_MEM_TO_PERI, true, false, size >> 2, DMA_S1, dma_callback); @@ -164,6 +166,15 @@ const void * pcm_play_dma_get_peak_buffer(int *count) return (const void*)dma_start_addr; } +#ifdef HAVE_PCM_DMA_ADDRESS +void * pcm_dma_addr(void *addr) +{ + if (addr != NULL) + addr = UNCACHED_ADDR(addr); + return addr; +} +#endif + /**************************************************************************** ** Recording DMA transfer diff --git a/firmware/target/arm/as3525/sansa-clip/button-clip.c b/firmware/target/arm/as3525/sansa-clip/button-clip.c index b6da130d2f..2d2a3a661e 100644 --- a/firmware/target/arm/as3525/sansa-clip/button-clip.c +++ b/firmware/target/arm/as3525/sansa-clip/button-clip.c @@ -46,8 +46,9 @@ int button_read_device(void) /* This is a keypad using C4-C6 as columns and B0-B2 as rows */ GPIOC_PIN(4) = (1<<4); + asm volatile("nop\nnop\nnop\nnop\nnop\n"); /* small delay */ - /* C4B0 is unused */ + (void)GPIOB_PIN(0); /* C4B0 is unused */ if (GPIOB_PIN(1)) result |= BUTTON_VOL_UP; @@ -58,6 +59,7 @@ int button_read_device(void) GPIOC_PIN(4) = 0x00; GPIOC_PIN(5) = (1<<5); + asm volatile("nop\nnop\nnop\nnop\nnop\n"); /* small delay */ if (GPIOB_PIN(0)) result |= BUTTON_LEFT; @@ -71,6 +73,7 @@ int button_read_device(void) GPIOC_PIN(5) = 0x00; GPIOC_PIN(6) = (1<<6); + asm volatile("nop\nnop\nnop\nnop\nnop\n"); /* small delay */ if (GPIOB_PIN(0)) result |= BUTTON_DOWN; diff --git a/firmware/target/arm/as3525/sansa-fuze/button-fuze.c b/firmware/target/arm/as3525/sansa-fuze/button-fuze.c index f8c489c4dd..266ca79deb 100644 --- a/firmware/target/arm/as3525/sansa-fuze/button-fuze.c +++ b/firmware/target/arm/as3525/sansa-fuze/button-fuze.c @@ -150,7 +150,7 @@ bool button_hold(void) static void button_delay(void) { - int i = 24; + int i = 50; while(i--) asm volatile ("nop\n"); } diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index 2f320e91ab..60fe7032e6 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c @@ -28,6 +28,9 @@ #include "clock-target.h" #include "fmradio_i2c.h" #include "button-target.h" +#ifndef BOOTLOADER +#include "mmu-arm.h" +#endif #define default_interrupt(name) \ extern __attribute__((weak,alias("UIRQ"))) void name (void) @@ -214,6 +217,26 @@ static void sdram_init(void) MPMC_DYNAMIC_CONFIG_0 |= (1<<19); /* buffer enable */ } +#else +void memory_init(void) +{ + ttb_init(); + /* map every region to itself, uncached */ + map_section(0, 0, 4096, CACHE_NONE); + + /* IRAM */ + map_section(0, IRAM_ORIG, 1, CACHE_ALL); + map_section(0, UNCACHED_ADDR(IRAM_ORIG), 1, CACHE_NONE); + + /* DRAM */ + map_section(0x30000000, DRAM_ORIG, MEMORYSIZE, CACHE_ALL); + map_section(0x30000000, UNCACHED_ADDR(DRAM_ORIG), MEMORYSIZE, CACHE_NONE); + + /* map 1st mbyte of DRAM at 0x0 to have exception vectors available */ + map_section(0x30000000, 0, 1, CACHE_ALL); + + enable_mmu(); +} #endif void system_init(void) @@ -226,6 +249,9 @@ void system_init(void) CCU_SRL = CCU_SRL_MAGIC_NUMBER; CCU_SRC = CCU_SRL = 0; + CCU_SCON = 1; /* AHB master's priority configuration : + TIC (Test Interface Controller) > DMA > USB > IDE > ARM */ + CGU_PROC = 0; /* fclk 24 MHz */ CGU_PERI &= ~0x7f; /* pclk 24 MHz */ @@ -244,10 +270,8 @@ void system_init(void) asm volatile( "mov r0, #0 \n" - "mcr p15, 0, r0, c7, c7 \n" /* invalidate icache & dcache */ "mrc p15, 0, r0, c1, c0 \n" /* control register */ - "bic r0, r0, #3<<30 \n" /* clears bus bits & sets fastbus */ - "orr r0, r0, #1<<12 \n" /* enable icache */ + "bic r0, r0, #3<<30 \n" /* clears bus bits : sets fastbus */ "mcr p15, 0, r0, c1, c0 \n" : : : "r0" ); diff --git a/firmware/target/arm/as3525/system-target.h b/firmware/target/arm/as3525/system-target.h index 713e96c4b8..daea180a64 100644 --- a/firmware/target/arm/as3525/system-target.h +++ b/firmware/target/arm/as3525/system-target.h @@ -25,4 +25,10 @@ #include "clock-target.h" /* CPUFREQ_* are defined here */ +#ifdef BOOTLOADER +#define UNCACHED_ADDR(a) (a) +#else +#define UNCACHED_ADDR(a) (a + 0x10000000) +#endif + #endif /* SYSTEM_TARGET_H */ -- cgit v1.2.3