diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/as3525/app.lds | 14 | ||||
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 25 | ||||
-rw-r--r-- | firmware/target/arm/as3525/boot.lds | 6 | ||||
-rw-r--r-- | firmware/target/arm/as3525/pcm-as3525.c | 11 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sansa-clip/button-clip.c | 5 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sansa-fuze/button-fuze.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/as3525/system-as3525.c | 30 | ||||
-rw-r--r-- | firmware/target/arm/as3525/system-target.h | 6 | ||||
-rw-r--r-- | firmware/target/arm/crt0.S | 12 |
9 files changed, 67 insertions, 44 deletions
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 | |||
55 | { | 55 | { |
56 | loadaddress = DRAM_ORIG; | 56 | loadaddress = DRAM_ORIG; |
57 | 57 | ||
58 | .vectors : | ||
59 | { | ||
60 | _vectors_start = .; | ||
61 | *(.init.text) | ||
62 | } > DRAM | ||
63 | |||
58 | .text : | 64 | .text : |
59 | { | 65 | { |
60 | _loadaddress = .; | 66 | _loadaddress = .; |
@@ -83,14 +89,6 @@ SECTIONS | |||
83 | *(.eh_frame) | 89 | *(.eh_frame) |
84 | } | 90 | } |
85 | 91 | ||
86 | .vectors IRAMORIG: | ||
87 | { | ||
88 | _vectors_start = .; | ||
89 | *(.init.text) | ||
90 | } > IRAM AT > DRAM | ||
91 | |||
92 | _vectorscopy = LOADADDR(.vectors); | ||
93 | |||
94 | .iram : | 92 | .iram : |
95 | { | 93 | { |
96 | _iramstart = .; | 94 | _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) | |||
595 | dma_enable_channel(0, card_data, MCI_FIFO(INTERNAL_AS3525), DMA_PERI_SD, | 595 | dma_enable_channel(0, card_data, MCI_FIFO(INTERNAL_AS3525), DMA_PERI_SD, |
596 | DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL); | 596 | DMAC_FLOWCTRL_PERI_MEM_TO_PERI, true, false, 0, DMA_S8, NULL); |
597 | 597 | ||
598 | MCI_DATA_TIMER(INTERNAL_AS3525) = 0x1000000; /* FIXME: arbitrary */ | 598 | MCI_DATA_TIMER(INTERNAL_AS3525) = 0xffffffff;/* FIXME: arbitrary */ |
599 | MCI_DATA_LENGTH(INTERNAL_AS3525) = 512; | 599 | MCI_DATA_LENGTH(INTERNAL_AS3525) = 512; |
600 | MCI_DATA_CTRL(INTERNAL_AS3525) = (1<<0) /* enable */ | | 600 | MCI_DATA_CTRL(INTERNAL_AS3525) = (1<<0) /* enable */ | |
601 | (0<<1) /* transfer direction */ | | 601 | (0<<1) /* transfer direction */ | |
@@ -618,7 +618,8 @@ static int sd_select_bank(signed char bank) | |||
618 | } | 618 | } |
619 | 619 | ||
620 | #define UNALIGNED_NUM_SECTORS 10 | 620 | #define UNALIGNED_NUM_SECTORS 10 |
621 | static int32_t aligned_buffer[UNALIGNED_NUM_SECTORS* (SECTOR_SIZE / 4)]; | 621 | static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SECTOR_SIZE] __attribute__((aligned(32))); /* align on cache line size */ |
622 | static unsigned char *uncached_buffer = UNCACHED_ADDR(aligned_buffer); | ||
622 | 623 | ||
623 | static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | 624 | static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, |
624 | int count, void* buf, const bool write) | 625 | int count, void* buf, const bool write) |
@@ -627,7 +628,6 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
627 | const int drive = 0; | 628 | const int drive = 0; |
628 | #endif | 629 | #endif |
629 | int ret = 0; | 630 | int ret = 0; |
630 | bool unaligned_transfer = (int)buf & 3; | ||
631 | 631 | ||
632 | /* skip SanDisk OF */ | 632 | /* skip SanDisk OF */ |
633 | if (drive == INTERNAL_AS3525) | 633 | if (drive == INTERNAL_AS3525) |
@@ -693,16 +693,11 @@ static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, | |||
693 | transfer = BLOCKS_PER_BANK - bank_start; | 693 | transfer = BLOCKS_PER_BANK - bank_start; |
694 | } | 694 | } |
695 | 695 | ||
696 | if(unaligned_transfer) | 696 | dma_buf = aligned_buffer; |
697 | { | 697 | if(transfer > UNALIGNED_NUM_SECTORS) |
698 | dma_buf = aligned_buffer; | 698 | transfer = UNALIGNED_NUM_SECTORS; |
699 | if(transfer > UNALIGNED_NUM_SECTORS) | 699 | if(write) |
700 | transfer = UNALIGNED_NUM_SECTORS; | 700 | memcpy(uncached_buffer, buf, transfer * SECTOR_SIZE); |
701 | if(write) | ||
702 | memcpy(aligned_buffer, buf, transfer * SECTOR_SIZE); | ||
703 | } | ||
704 | else /* Aligned transfers are faster : no memcpy */ | ||
705 | dma_buf = buf; | ||
706 | 701 | ||
707 | /* Set bank_start to the correct unit (blocks or bytes) */ | 702 | /* Set bank_start to the correct unit (blocks or bytes) */ |
708 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ | 703 | 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, | |||
734 | wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); | 729 | wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); |
735 | if(!retry) | 730 | if(!retry) |
736 | { | 731 | { |
737 | if(unaligned_transfer && !write) | 732 | if(!write) |
738 | memcpy(buf, aligned_buffer, transfer * SECTOR_SIZE); | 733 | memcpy(buf, uncached_buffer, transfer * SECTOR_SIZE); |
739 | buf += transfer * SECTOR_SIZE; | 734 | buf += transfer * SECTOR_SIZE; |
740 | start += transfer; | 735 | start += transfer; |
741 | count -= transfer; | 736 | 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) | |||
6 | OUTPUT_ARCH(arm) | 6 | OUTPUT_ARCH(arm) |
7 | STARTUP(target/arm/crt0.o) | 7 | STARTUP(target/arm/crt0.o) |
8 | 8 | ||
9 | /* | ||
10 | No need for DRAM in our bootloader | ||
11 | #define DRAMSIZE (MEMORYSIZE * 0x100000) - TTB_SIZE | ||
12 | #define DRAMORIG 0x30000000 | ||
13 | */ | ||
14 | #define IRAMORIG 0x81000000 | 9 | #define IRAMORIG 0x81000000 |
15 | #define IRAMSIZE 0x50000 | 10 | #define IRAMSIZE 0x50000 |
16 | 11 | ||
17 | MEMORY | 12 | MEMORY |
18 | { | 13 | { |
19 | /*DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE*/ | ||
20 | IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE | 14 | IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE |
21 | } | 15 | } |
22 | 16 | ||
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 @@ | |||
28 | #include "panic.h" | 28 | #include "panic.h" |
29 | #include "as3514.h" | 29 | #include "as3514.h" |
30 | #include "audiohw.h" | 30 | #include "audiohw.h" |
31 | #include "mmu-arm.h" | ||
31 | 32 | ||
32 | #define MAX_TRANSFER (4*((1<<11)-1)) /* maximum data we can transfer via DMA | 33 | #define MAX_TRANSFER (4*((1<<11)-1)) /* maximum data we can transfer via DMA |
33 | * i.e. 32 bits at once (size of I2SO_DATA) | 34 | * i.e. 32 bits at once (size of I2SO_DATA) |
@@ -69,6 +70,7 @@ static void play_start_pcm(void) | |||
69 | CGU_PERI |= CGU_I2SOUT_APB_CLOCK_ENABLE; | 70 | CGU_PERI |= CGU_I2SOUT_APB_CLOCK_ENABLE; |
70 | CGU_AUDIO |= (1<<11); | 71 | CGU_AUDIO |= (1<<11); |
71 | 72 | ||
73 | clean_dcache_range((void*)addr, size); /* force write back */ | ||
72 | dma_enable_channel(1, (void*)addr, (void*)I2SOUT_DATA, DMA_PERI_I2SOUT, | 74 | dma_enable_channel(1, (void*)addr, (void*)I2SOUT_DATA, DMA_PERI_I2SOUT, |
73 | DMAC_FLOWCTRL_DMAC_MEM_TO_PERI, true, false, size >> 2, DMA_S1, | 75 | DMAC_FLOWCTRL_DMAC_MEM_TO_PERI, true, false, size >> 2, DMA_S1, |
74 | dma_callback); | 76 | dma_callback); |
@@ -164,6 +166,15 @@ const void * pcm_play_dma_get_peak_buffer(int *count) | |||
164 | return (const void*)dma_start_addr; | 166 | return (const void*)dma_start_addr; |
165 | } | 167 | } |
166 | 168 | ||
169 | #ifdef HAVE_PCM_DMA_ADDRESS | ||
170 | void * pcm_dma_addr(void *addr) | ||
171 | { | ||
172 | if (addr != NULL) | ||
173 | addr = UNCACHED_ADDR(addr); | ||
174 | return addr; | ||
175 | } | ||
176 | #endif | ||
177 | |||
167 | 178 | ||
168 | /**************************************************************************** | 179 | /**************************************************************************** |
169 | ** Recording DMA transfer | 180 | ** 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) | |||
46 | 46 | ||
47 | /* This is a keypad using C4-C6 as columns and B0-B2 as rows */ | 47 | /* This is a keypad using C4-C6 as columns and B0-B2 as rows */ |
48 | GPIOC_PIN(4) = (1<<4); | 48 | GPIOC_PIN(4) = (1<<4); |
49 | asm volatile("nop\nnop\nnop\nnop\nnop\n"); /* small delay */ | ||
49 | 50 | ||
50 | /* C4B0 is unused */ | 51 | (void)GPIOB_PIN(0); /* C4B0 is unused */ |
51 | 52 | ||
52 | if (GPIOB_PIN(1)) | 53 | if (GPIOB_PIN(1)) |
53 | result |= BUTTON_VOL_UP; | 54 | result |= BUTTON_VOL_UP; |
@@ -58,6 +59,7 @@ int button_read_device(void) | |||
58 | GPIOC_PIN(4) = 0x00; | 59 | GPIOC_PIN(4) = 0x00; |
59 | 60 | ||
60 | GPIOC_PIN(5) = (1<<5); | 61 | GPIOC_PIN(5) = (1<<5); |
62 | asm volatile("nop\nnop\nnop\nnop\nnop\n"); /* small delay */ | ||
61 | 63 | ||
62 | if (GPIOB_PIN(0)) | 64 | if (GPIOB_PIN(0)) |
63 | result |= BUTTON_LEFT; | 65 | result |= BUTTON_LEFT; |
@@ -71,6 +73,7 @@ int button_read_device(void) | |||
71 | GPIOC_PIN(5) = 0x00; | 73 | GPIOC_PIN(5) = 0x00; |
72 | 74 | ||
73 | GPIOC_PIN(6) = (1<<6); | 75 | GPIOC_PIN(6) = (1<<6); |
76 | asm volatile("nop\nnop\nnop\nnop\nnop\n"); /* small delay */ | ||
74 | 77 | ||
75 | if (GPIOB_PIN(0)) | 78 | if (GPIOB_PIN(0)) |
76 | result |= BUTTON_DOWN; | 79 | 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) | |||
150 | 150 | ||
151 | static void button_delay(void) | 151 | static void button_delay(void) |
152 | { | 152 | { |
153 | int i = 24; | 153 | int i = 50; |
154 | while(i--) asm volatile ("nop\n"); | 154 | while(i--) asm volatile ("nop\n"); |
155 | } | 155 | } |
156 | 156 | ||
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 @@ | |||
28 | #include "clock-target.h" | 28 | #include "clock-target.h" |
29 | #include "fmradio_i2c.h" | 29 | #include "fmradio_i2c.h" |
30 | #include "button-target.h" | 30 | #include "button-target.h" |
31 | #ifndef BOOTLOADER | ||
32 | #include "mmu-arm.h" | ||
33 | #endif | ||
31 | 34 | ||
32 | #define default_interrupt(name) \ | 35 | #define default_interrupt(name) \ |
33 | extern __attribute__((weak,alias("UIRQ"))) void name (void) | 36 | extern __attribute__((weak,alias("UIRQ"))) void name (void) |
@@ -214,6 +217,26 @@ static void sdram_init(void) | |||
214 | 217 | ||
215 | MPMC_DYNAMIC_CONFIG_0 |= (1<<19); /* buffer enable */ | 218 | MPMC_DYNAMIC_CONFIG_0 |= (1<<19); /* buffer enable */ |
216 | } | 219 | } |
220 | #else | ||
221 | void memory_init(void) | ||
222 | { | ||
223 | ttb_init(); | ||
224 | /* map every region to itself, uncached */ | ||
225 | map_section(0, 0, 4096, CACHE_NONE); | ||
226 | |||
227 | /* IRAM */ | ||
228 | map_section(0, IRAM_ORIG, 1, CACHE_ALL); | ||
229 | map_section(0, UNCACHED_ADDR(IRAM_ORIG), 1, CACHE_NONE); | ||
230 | |||
231 | /* DRAM */ | ||
232 | map_section(0x30000000, DRAM_ORIG, MEMORYSIZE, CACHE_ALL); | ||
233 | map_section(0x30000000, UNCACHED_ADDR(DRAM_ORIG), MEMORYSIZE, CACHE_NONE); | ||
234 | |||
235 | /* map 1st mbyte of DRAM at 0x0 to have exception vectors available */ | ||
236 | map_section(0x30000000, 0, 1, CACHE_ALL); | ||
237 | |||
238 | enable_mmu(); | ||
239 | } | ||
217 | #endif | 240 | #endif |
218 | 241 | ||
219 | void system_init(void) | 242 | void system_init(void) |
@@ -226,6 +249,9 @@ void system_init(void) | |||
226 | CCU_SRL = CCU_SRL_MAGIC_NUMBER; | 249 | CCU_SRL = CCU_SRL_MAGIC_NUMBER; |
227 | CCU_SRC = CCU_SRL = 0; | 250 | CCU_SRC = CCU_SRL = 0; |
228 | 251 | ||
252 | CCU_SCON = 1; /* AHB master's priority configuration : | ||
253 | TIC (Test Interface Controller) > DMA > USB > IDE > ARM */ | ||
254 | |||
229 | CGU_PROC = 0; /* fclk 24 MHz */ | 255 | CGU_PROC = 0; /* fclk 24 MHz */ |
230 | CGU_PERI &= ~0x7f; /* pclk 24 MHz */ | 256 | CGU_PERI &= ~0x7f; /* pclk 24 MHz */ |
231 | 257 | ||
@@ -244,10 +270,8 @@ void system_init(void) | |||
244 | 270 | ||
245 | asm volatile( | 271 | asm volatile( |
246 | "mov r0, #0 \n" | 272 | "mov r0, #0 \n" |
247 | "mcr p15, 0, r0, c7, c7 \n" /* invalidate icache & dcache */ | ||
248 | "mrc p15, 0, r0, c1, c0 \n" /* control register */ | 273 | "mrc p15, 0, r0, c1, c0 \n" /* control register */ |
249 | "bic r0, r0, #3<<30 \n" /* clears bus bits & sets fastbus */ | 274 | "bic r0, r0, #3<<30 \n" /* clears bus bits : sets fastbus */ |
250 | "orr r0, r0, #1<<12 \n" /* enable icache */ | ||
251 | "mcr p15, 0, r0, c1, c0 \n" | 275 | "mcr p15, 0, r0, c1, c0 \n" |
252 | : : : "r0" ); | 276 | : : : "r0" ); |
253 | 277 | ||
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 @@ | |||
25 | 25 | ||
26 | #include "clock-target.h" /* CPUFREQ_* are defined here */ | 26 | #include "clock-target.h" /* CPUFREQ_* are defined here */ |
27 | 27 | ||
28 | #ifdef BOOTLOADER | ||
29 | #define UNCACHED_ADDR(a) (a) | ||
30 | #else | ||
31 | #define UNCACHED_ADDR(a) (a + 0x10000000) | ||
32 | #endif | ||
33 | |||
28 | #endif /* SYSTEM_TARGET_H */ | 34 | #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: | |||
58 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ | 58 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ |
59 | 59 | ||
60 | #if CONFIG_CPU==AS3525 && !defined(BOOTLOADER) | 60 | #if CONFIG_CPU==AS3525 && !defined(BOOTLOADER) |
61 | 61 | /* Setup MMU : has to be done before accessing IRAM ! */ | |
62 | /* relocate vectors */ | 62 | bl memory_init |
63 | mov r1, #0 @ destination | ||
64 | ldr r2, =_vectorscopy @ source | ||
65 | ldr r3, =_vectorsend @ end | ||
66 | |||
67 | 1: ldr r0, [r2], #4 | ||
68 | str r0, [r1], #4 | ||
69 | cmp r1, r3 | ||
70 | bne 1b | ||
71 | 63 | ||
72 | /* Zero out IBSS */ | 64 | /* Zero out IBSS */ |
73 | ldr r2, =_iedata | 65 | ldr r2, =_iedata |