summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2009-06-08 23:05:33 +0000
committerRafaël Carré <rafael.carre@gmail.com>2009-06-08 23:05:33 +0000
commitf5041538574c039b07c4db8d261bd33ec0f3bab0 (patch)
treed4fc2f48c7209e3303b5c48abc211e3a961a7dac
parent20a78a36f36967651032ab10b4ee31412e37b69d (diff)
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
-rw-r--r--bootloader/sansa_as3525.c2
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/export/as3525.h12
-rw-r--r--firmware/target/arm/as3525/app.lds14
-rw-r--r--firmware/target/arm/as3525/ata_sd_as3525.c25
-rw-r--r--firmware/target/arm/as3525/boot.lds6
-rw-r--r--firmware/target/arm/as3525/pcm-as3525.c11
-rw-r--r--firmware/target/arm/as3525/sansa-clip/button-clip.c5
-rw-r--r--firmware/target/arm/as3525/sansa-fuze/button-fuze.c2
-rw-r--r--firmware/target/arm/as3525/system-as3525.c30
-rw-r--r--firmware/target/arm/as3525/system-target.h6
-rw-r--r--firmware/target/arm/crt0.S12
-rwxr-xr-xtools/configure12
13 files changed, 84 insertions, 54 deletions
diff --git a/bootloader/sansa_as3525.c b/bootloader/sansa_as3525.c
index dbe6218d48..48f21bc196 100644
--- a/bootloader/sansa_as3525.c
+++ b/bootloader/sansa_as3525.c
@@ -36,6 +36,8 @@
#include "power.h"
int show_logo(void);
+
+void main(void) __attribute__((naked, noreturn));
void main(void)
{
unsigned char* loadbuffer;
diff --git a/firmware/SOURCES b/firmware/SOURCES
index f4705d9694..da85a7123a 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -374,6 +374,7 @@ target/arm/as3525/usb-as3525.c
target/arm/as3525/dma-pl081.c
target/arm/as3525/ascodec-as3525.c
#ifndef BOOTLOADER
+target/arm/mmu-arm.S
drivers/generic_i2c.c
target/arm/adc-as3514.c
target/arm/as3525/audio-as3525.c
diff --git a/firmware/export/as3525.h b/firmware/export/as3525.h
index 21bf2bdc48..31bbeedc1e 100644
--- a/firmware/export/as3525.h
+++ b/firmware/export/as3525.h
@@ -27,9 +27,11 @@
/* we put the codec buffer in IRAM */
#define AMS_LOWMEM
#endif
-/* these addresses are valid after mapping through the MMU */
+
+/* Virtual addresses */
+/* Do not apply to the bootloader, which uses physical addresses (no MMU) */
#define DRAM_ORIG 0x30000000
-#define IRAM_ORIG 0x0
+#define IRAM_ORIG (DRAM_ORIG + DRAM_SIZE) /* IRAM is mapped just next to DRAM */
#define DRAM_SIZE (MEMORYSIZE * 0x100000)
#define IRAM_SIZE 0x50000
@@ -40,8 +42,7 @@
#define ECCBYTES 3
/* AS352X MMU Page Table Entries */
-/* to be implemented */
-#define TTB_SIZE 0x0
+#define TTB_SIZE 0x4000
#define TTB_BASE_ADDR (DRAM_ORIG + DRAM_SIZE - TTB_SIZE)
@@ -493,4 +494,7 @@ interface */
#define I2SOUT_CLEAR (*(volatile unsigned char*)(I2SOUT_BASE+0x10))
#define I2SOUT_DATA (volatile unsigned long*)(I2SOUT_BASE+0x14)
+/* PCM addresses for obtaining buffers will be what DMA is using (physical) */
+#define HAVE_PCM_DMA_ADDRESS
+
#endif /*__AS3525_H__*/
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 */
diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S
index 35d0aecccb..4bd01e4952 100644
--- a/firmware/target/arm/crt0.S
+++ b/firmware/target/arm/crt0.S
@@ -58,16 +58,8 @@ newstart:
msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
#if CONFIG_CPU==AS3525 && !defined(BOOTLOADER)
-
- /* relocate vectors */
- mov r1, #0 @ destination
- ldr r2, =_vectorscopy @ source
- ldr r3, =_vectorsend @ end
-
-1: ldr r0, [r2], #4
- str r0, [r1], #4
- cmp r1, r3
- bne 1b
+ /* Setup MMU : has to be done before accessing IRAM ! */
+ bl memory_init
/* Zero out IBSS */
ldr r2, =_iedata
diff --git a/tools/configure b/tools/configure
index a58e8c6e1c..f081b8ba72 100755
--- a/tools/configure
+++ b/tools/configure
@@ -259,7 +259,7 @@ arm7tdmicc () {
arm9tdmicc () {
prefixtools arm-elf-
GCCOPTS="$CCOPTS -mcpu=arm9tdmi"
- if test "$modelname" != "gigabeatf"; then
+ if test "$modelname" != "gigabeatf" -a "$t_manufacturer" != "as3525"; then
GCCOPTS="$GCCOPTS -mlong-calls"
fi
GCCOPTIMIZE="-fomit-frame-pointer"
@@ -1734,7 +1734,6 @@ fi
modelname="clip"
target="-DSANSA_CLIP"
memory=2
- arm9tdmicc
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$bmp2rb_mono"
tool="$rootdir/tools/scramble -add=clip"
@@ -1747,6 +1746,7 @@ fi
t_cpu="arm"
t_manufacturer="as3525"
t_model="sansa-clip"
+ arm9tdmicc
;;
@@ -1755,7 +1755,6 @@ fi
modelname="e200v2"
target="-DSANSA_E200V2"
memory=8
- arm9tdmicc
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
tool="$rootdir/tools/scramble -add=e2v2"
@@ -1768,6 +1767,7 @@ fi
t_cpu="arm"
t_manufacturer="as3525"
t_model="sansa-e200v2"
+ arm9tdmicc
;;
@@ -1776,7 +1776,6 @@ fi
modelname="m200v4"
target="-DSANSA_M200V4"
memory=2
- arm9tdmicc
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$bmp2rb_mono"
tool="$rootdir/tools/scramble -add=m2v4"
@@ -1789,6 +1788,7 @@ fi
t_cpu="arm"
t_manufacturer="as3525"
t_model="sansa-m200v4"
+ arm9tdmicc
;;
@@ -1797,7 +1797,6 @@ fi
modelname="fuze"
target="-DSANSA_FUZE"
memory=8
- arm9tdmicc
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
tool="$rootdir/tools/scramble -add=fuze"
@@ -1810,6 +1809,7 @@ fi
t_cpu="arm"
t_manufacturer="as3525"
t_model="sansa-fuze"
+ arm9tdmicc
;;
@@ -1818,7 +1818,6 @@ fi
modelname="c200v2"
target="-DSANSA_C200V2"
memory=2 # as per OF diagnosis mode
- arm9tdmicc
bmp2rb_mono="$rootdir/tools/bmp2rb -f 0"
bmp2rb_native="$rootdir/tools/bmp2rb -f 4"
tool="$rootdir/tools/scramble -add=c2v2"
@@ -1834,6 +1833,7 @@ fi
t_cpu="arm"
t_manufacturer="as3525"
t_model="sansa-c200v2"
+ arm9tdmicc
;;
60|Clipv2|clipv2)