summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm')
-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
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
621static int32_t aligned_buffer[UNALIGNED_NUM_SECTORS* (SECTOR_SIZE / 4)]; 621static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SECTOR_SIZE] __attribute__((aligned(32))); /* align on cache line size */
622static unsigned char *uncached_buffer = UNCACHED_ADDR(aligned_buffer);
622 623
623static int sd_transfer_sectors(IF_MV2(int drive,) unsigned long start, 624static 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)
6OUTPUT_ARCH(arm) 6OUTPUT_ARCH(arm)
7STARTUP(target/arm/crt0.o) 7STARTUP(target/arm/crt0.o)
8 8
9/*
10No 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
17MEMORY 12MEMORY
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
170void * 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
151static void button_delay(void) 151static 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
221void 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
219void system_init(void) 242void 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
671: 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