diff options
Diffstat (limited to 'firmware/target/arm')
32 files changed, 2607 insertions, 4 deletions
diff --git a/firmware/target/arm/crt0.S b/firmware/target/arm/crt0.S index 56876ca9b1..d734f82df8 100644 --- a/firmware/target/arm/crt0.S +++ b/firmware/target/arm/crt0.S | |||
@@ -23,6 +23,9 @@ | |||
23 | 23 | ||
24 | .global start | 24 | .global start |
25 | start: | 25 | start: |
26 | b newstart | ||
27 | .space 4*16 | ||
28 | |||
26 | 29 | ||
27 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader | 30 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader |
28 | * | 31 | * |
@@ -31,7 +34,13 @@ start: | |||
31 | * | 34 | * |
32 | */ | 35 | */ |
33 | 36 | ||
34 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */ | 37 | newstart: |
38 | #if CONFIG_CPU == IMX31L | ||
39 | mov r0,#0xD3 | ||
40 | msr cpsr, r0 | ||
41 | #else | ||
42 | msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ */ | ||
43 | #endif | ||
35 | 44 | ||
36 | #if !defined(BOOTLOADER) || (CONFIG_CPU == DM320) | 45 | #if !defined(BOOTLOADER) || (CONFIG_CPU == DM320) |
37 | #if !defined(DEBUG) | 46 | #if !defined(DEBUG) |
@@ -95,7 +104,7 @@ start: | |||
95 | cmp r3, r2 | 104 | cmp r3, r2 |
96 | strhi r4, [r2], #4 | 105 | strhi r4, [r2], #4 |
97 | bhi 1b | 106 | bhi 1b |
98 | 107 | ||
99 | #ifdef BOOTLOADER | 108 | #ifdef BOOTLOADER |
100 | /* Code for ARM bootloader targets other than iPod go here */ | 109 | /* Code for ARM bootloader targets other than iPod go here */ |
101 | 110 | ||
@@ -274,6 +283,151 @@ start: | |||
274 | start_loc: | 283 | start_loc: |
275 | bl main | 284 | bl main |
276 | 285 | ||
286 | #elif CONFIG_CPU == IMX31L | ||
287 | |||
288 | mov r0, #0 | ||
289 | mcr 15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */ | ||
290 | mcr 15, 0, r0, c8, c7, 0 /* invalidate TLBs */ | ||
291 | mcr 15, 0, r0, c7, c10, 4 /* Drain the write buffer */ | ||
292 | |||
293 | /* Also setup the Peripheral Port Remap register inside the core */ | ||
294 | ldr r0, =0x40000015 /* start from AIPS 2GB region */ | ||
295 | mcr p15, 0, r0, c15, c2, 4 | ||
296 | |||
297 | /*** L2 Cache setup/invalidation/disable ***/ | ||
298 | /* Disable L2 cache first */ | ||
299 | ldr r0, =L2CC_BASE_ADDR | ||
300 | ldr r2, [r0, #L2_CACHE_CTL_REG] | ||
301 | bic r2, r2, #0x1 | ||
302 | str r2, [r0, #L2_CACHE_CTL_REG] | ||
303 | |||
304 | |||
305 | /* | ||
306 | * Configure L2 Cache: | ||
307 | * - 128k size(16k way) | ||
308 | * - 8-way associativity | ||
309 | * - 0 ws TAG/VALID/DIRTY | ||
310 | * - 4 ws DATA R/W | ||
311 | */ | ||
312 | ldr r1, [r0, #L2_CACHE_AUX_CTL_REG] | ||
313 | and r1, r1, #0xFE000000 | ||
314 | ldr r2, =0x00030024 | ||
315 | orr r1, r1, r2 | ||
316 | str r1, [r0, #L2_CACHE_AUX_CTL_REG] | ||
317 | |||
318 | /* Invalidate L2 */ | ||
319 | ldr r1, =0x000000FF | ||
320 | str r1, [r0, #L2_CACHE_INV_WAY_REG] | ||
321 | L2_loop: | ||
322 | /* Poll Invalidate By Way register */ | ||
323 | ldr r2, [r0, #L2_CACHE_INV_WAY_REG] | ||
324 | cmp r2, #0 | ||
325 | bne L2_loop | ||
326 | /*** End of L2 operations ***/ | ||
327 | /* Set up stack for IRQ mode */ | ||
328 | mov r0,#0xd2 | ||
329 | msr cpsr, r0 | ||
330 | ldr sp, =irq_stack | ||
331 | /* Set up stack for FIQ mode */ | ||
332 | mov r0,#0xd1 | ||
333 | msr cpsr, r0 | ||
334 | ldr sp, =fiq_stack | ||
335 | |||
336 | /* Let abort and undefined modes use IRQ stack */ | ||
337 | mov r0,#0xd7 | ||
338 | msr cpsr, r0 | ||
339 | ldr sp, =irq_stack | ||
340 | mov r0,#0xdb | ||
341 | msr cpsr, r0 | ||
342 | ldr sp, =irq_stack | ||
343 | /* Switch to supervisor mode */ | ||
344 | mov r0,#0xd3 | ||
345 | msr cpsr, r0 | ||
346 | ldr sp, =stackend | ||
347 | |||
348 | /*remap memory as well as exception vectors*/ | ||
349 | /*for now this will be done in bootloader, especially | ||
350 | if usb will be needed within the bootloader to load the | ||
351 | main firmware file. Interrupts will be needed for this | ||
352 | (whether they be swi or irq)*/ | ||
353 | bl memory_init | ||
354 | mov r0,#0 | ||
355 | ldr r1,=_vectorstart | ||
356 | mov r2,#0 | ||
357 | |||
358 | lp: ldr r3,[r1] | ||
359 | add r1,r1,#4 | ||
360 | str r3,[r0] | ||
361 | add r0,r0,#4 | ||
362 | add r2,r2,#1 | ||
363 | cmp r2,#16 | ||
364 | bne lp | ||
365 | bl main | ||
366 | |||
367 | .section .vectors,"aw" | ||
368 | _vectorstart: | ||
369 | ldr pc, [pc, #24] | ||
370 | ldr pc, [pc, #24] | ||
371 | ldr pc, [pc, #24] | ||
372 | ldr pc, [pc, #24] | ||
373 | ldr pc, [pc, #24] | ||
374 | ldr pc, [pc, #24] | ||
375 | ldr pc, [pc, #24] | ||
376 | ldr pc, [pc, #24] | ||
377 | |||
378 | /* Exception vectors */ | ||
379 | .global vectors | ||
380 | vectors: | ||
381 | .word start | ||
382 | .word undef_instr_handler | ||
383 | .word software_int_handler | ||
384 | .word prefetch_abort_handler | ||
385 | .word data_abort_handler | ||
386 | .word reserved_handler | ||
387 | .word irqz | ||
388 | .word fiqz | ||
389 | |||
390 | .text | ||
391 | .global irq | ||
392 | .global fiq | ||
393 | .global UIE | ||
394 | |||
395 | undef_instr_handler: | ||
396 | mov r0, lr | ||
397 | mov r1, #0 | ||
398 | b UIE | ||
399 | |||
400 | software_int_handler: | ||
401 | reserved_handler: | ||
402 | bl irq_handler | ||
403 | movs pc, lr | ||
404 | |||
405 | prefetch_abort_handler: | ||
406 | sub r0, lr, #4 | ||
407 | mov r1, #1 | ||
408 | b UIE | ||
409 | |||
410 | data_abort_handler: | ||
411 | sub r0, lr, #8 | ||
412 | mov r1, #2 | ||
413 | b UIE | ||
414 | |||
415 | /*not working....if we get here, let someone | ||
416 | know....*/ | ||
417 | irqz: bl irq_handler | ||
418 | fiqz: bl fiq_handler | ||
419 | |||
420 | UIE: | ||
421 | b UIE | ||
422 | |||
423 | /* 256 words of IRQ stack */ | ||
424 | .space 256*4 | ||
425 | irq_stack: | ||
426 | |||
427 | /* 256 words of FIQ stack */ | ||
428 | .space 256*4 | ||
429 | fiq_stack: | ||
430 | |||
277 | #else | 431 | #else |
278 | /* get the high part of our execute address */ | 432 | /* get the high part of our execute address */ |
279 | ldr r2, =0xffffff00 | 433 | ldr r2, =0xffffff00 |
@@ -295,11 +449,15 @@ start_loc: | |||
295 | 449 | ||
296 | start_loc: | 450 | start_loc: |
297 | bl main | 451 | bl main |
452 | |||
298 | #endif | 453 | #endif |
299 | 454 | ||
300 | #else /* BOOTLOADER */ | 455 | #else /* BOOTLOADER */ |
301 | 456 | ||
302 | /* Set up stack for IRQ mode */ | 457 | |
458 | |||
459 | |||
460 | /* Set up stack for IRQ mode */ | ||
303 | msr cpsr_c, #0xd2 | 461 | msr cpsr_c, #0xd2 |
304 | ldr sp, =irq_stack | 462 | ldr sp, =irq_stack |
305 | /* Set up stack for FIQ mode */ | 463 | /* Set up stack for FIQ mode */ |
@@ -316,8 +474,11 @@ start_loc: | |||
316 | ldr sp, =stackend | 474 | ldr sp, =stackend |
317 | bl main | 475 | bl main |
318 | /* main() should never return */ | 476 | /* main() should never return */ |
319 | 477 | ||
320 | /* Exception handlers. Will be copied to address 0 after memory remapping */ | 478 | /* Exception handlers. Will be copied to address 0 after memory remapping */ |
479 | #if CONFIG_CPU == IMX31L | ||
480 | _vectorstart: | ||
481 | #endif | ||
321 | .section .vectors,"aw" | 482 | .section .vectors,"aw" |
322 | ldr pc, [pc, #24] | 483 | ldr pc, [pc, #24] |
323 | ldr pc, [pc, #24] | 484 | ldr pc, [pc, #24] |
diff --git a/firmware/target/arm/imx31/gigabeat-s/adc-imx31.c b/firmware/target/arm/imx31/gigabeat-s/adc-imx31.c new file mode 100644 index 0000000000..1fd2247ef1 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/adc-imx31.c | |||
@@ -0,0 +1,52 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Wade Brown | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "cpu.h" | ||
20 | #include "adc-target.h" | ||
21 | #include "kernel.h" | ||
22 | |||
23 | /* prototypes */ | ||
24 | static unsigned short __adc_read(int channel); | ||
25 | static void adc_tick(void); | ||
26 | |||
27 | void adc_init(void) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | /* Called to get the recent ADC reading */ | ||
32 | inline unsigned short adc_read(int channel) | ||
33 | { | ||
34 | (void)channel; | ||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | /** | ||
39 | * Read the ADC by polling | ||
40 | * @param channel The ADC channel to read | ||
41 | * @return 10bit reading from ADC channel or ADC_READ_ERROR if timeout | ||
42 | */ | ||
43 | static unsigned short __adc_read(int channel) | ||
44 | { | ||
45 | (void)channel; | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | /* add this to the tick so that the ADC converts are done in the background */ | ||
50 | static void adc_tick(void) | ||
51 | { | ||
52 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/adc-target.h b/firmware/target/arm/imx31/gigabeat-s/adc-target.h new file mode 100644 index 0000000000..8d2beaf320 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/adc-target.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Barry Wardell | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef _ADC_TARGET_H_ | ||
20 | #define _ADC_TARGET_H_ | ||
21 | |||
22 | /* only two channels used by the Gigabeat */ | ||
23 | #define NUM_ADC_CHANNELS 2 | ||
24 | |||
25 | #define ADC_BATTERY 0 | ||
26 | #define ADC_HPREMOTE 1 | ||
27 | #define ADC_UNKNOWN_3 2 | ||
28 | #define ADC_UNKNOWN_4 3 | ||
29 | #define ADC_UNKNOWN_5 4 | ||
30 | #define ADC_UNKNOWN_6 5 | ||
31 | #define ADC_UNKNOWN_7 6 | ||
32 | #define ADC_UNKNOWN_8 7 | ||
33 | |||
34 | #define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */ | ||
35 | #define ADC_READ_ERROR 0xFFFF | ||
36 | |||
37 | #endif | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c b/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c new file mode 100644 index 0000000000..58659c7d53 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Will Robertson | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "cpu.h" | ||
21 | #include "kernel.h" | ||
22 | #include "thread.h" | ||
23 | #include "system.h" | ||
24 | #include "power.h" | ||
25 | #include "panic.h" | ||
26 | #include "pcf50606.h" | ||
27 | #include "ata-target.h" | ||
28 | #include "mmu-imx31.h" | ||
29 | #include "backlight-target.h" | ||
30 | |||
31 | #define ATA_RST (1 << 6) | ||
32 | |||
33 | void ata_reset(void) | ||
34 | { | ||
35 | ATA_CONTROL &= ~ATA_RST; | ||
36 | sleep(1); | ||
37 | ATA_CONTROL |= ATA_RST; | ||
38 | sleep(1); | ||
39 | } | ||
40 | |||
41 | /* This function is called before enabling the USB bus */ | ||
42 | void ata_enable(bool on) | ||
43 | { | ||
44 | (void)on; | ||
45 | } | ||
46 | |||
47 | bool ata_is_coldstart(void) | ||
48 | { | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | unsigned long get_pll(bool serial) { | ||
53 | unsigned long mfi, mfn, mfd, pdf, ref_clk; | ||
54 | unsigned long reg = 0, ccmr; | ||
55 | unsigned long long temp; | ||
56 | unsigned int prcs; | ||
57 | |||
58 | ccmr = CLKCTL_CCMR; | ||
59 | prcs = (ccmr & 0x6) >> 1; | ||
60 | if(prcs == 0x1) { | ||
61 | ref_clk = 32768 * 1024; | ||
62 | } else { | ||
63 | ref_clk = 27000000; | ||
64 | } | ||
65 | |||
66 | if(serial) { | ||
67 | reg = CLKCTL_SPCTL; | ||
68 | } else { | ||
69 | if((ccmr & 0x8) == 0) | ||
70 | return ref_clk; | ||
71 | if((ccmr & 0x80) != 0) | ||
72 | return ref_clk; | ||
73 | reg = CLKCTL_MPCTL; | ||
74 | } | ||
75 | pdf = (reg & (0x7 << 26)) >> 26; | ||
76 | mfd = (reg & (0x3FF << 16)) >> 16; | ||
77 | mfi = (reg & (0xF << 10)) >> 10; | ||
78 | mfi = (mfi <= 5) ? 5 : mfi; | ||
79 | mfn = (reg & 0x3FF); | ||
80 | |||
81 | if(mfn < 0x200) { | ||
82 | temp = (unsigned long long)2 *ref_clk * mfn; | ||
83 | temp /= (mfd + 1); | ||
84 | temp = (unsigned long long)2 *ref_clk * mfi + temp; | ||
85 | temp /= (pdf + 1); | ||
86 | } else { | ||
87 | temp = (unsigned long long)2 *ref_clk * (0x400 - mfn); | ||
88 | temp /= (mfd + 1); | ||
89 | temp = (unsigned long long)2 *ref_clk * mfi - temp; | ||
90 | temp /= (pdf + 1); | ||
91 | |||
92 | } | ||
93 | return (unsigned long)temp; | ||
94 | } | ||
95 | |||
96 | unsigned long get_ata_clock(void) { | ||
97 | unsigned long pll, ret_val, hclk, max_pdf, ipg_pdf, mcu_pdf; | ||
98 | |||
99 | max_pdf = (CLKCTL_PDR0 & (0x7 << 3)) >> 3; | ||
100 | ipg_pdf = (CLKCTL_PDR0 & (0x3 << 6)) >> 6; | ||
101 | mcu_pdf = (CLKCTL_PDR0 & 0x7); | ||
102 | if((CLKCTL_PMCR0 & 0xC0000000 ) == 0) { | ||
103 | pll = get_pll(true); | ||
104 | } else { | ||
105 | pll = get_pll(false); | ||
106 | } | ||
107 | hclk = pll/(max_pdf + 1); | ||
108 | ret_val = hclk / (ipg_pdf + 1); | ||
109 | |||
110 | return ret_val; | ||
111 | } | ||
112 | |||
113 | void ata_device_init(void) | ||
114 | { | ||
115 | ATA_CONTROL |= ATA_RST; /* Make sure we're not in reset mode */ | ||
116 | |||
117 | /* Setup the timing for PIO mode */ | ||
118 | int T = 1000 * 1000 * 1000 / get_ata_clock(); | ||
119 | TIME_OFF = 3; | ||
120 | TIME_ON = 3; | ||
121 | |||
122 | TIME_1 = (T + 70)/T; | ||
123 | TIME_2W = (T + 290)/T; | ||
124 | TIME_2R = (T + 290)/T; | ||
125 | TIME_AX = (T + 50)/T; | ||
126 | TIME_PIO_RDX = 1; | ||
127 | TIME_4 = (T + 30)/T; | ||
128 | TIME_9 = (T + 20)/T; | ||
129 | } | ||
130 | |||
131 | #if !defined(BOOTLOADER) | ||
132 | void copy_read_sectors(unsigned char* buf, int wordcount) | ||
133 | { | ||
134 | (void)buf; | ||
135 | (void)wordcount; | ||
136 | } | ||
137 | #endif | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/ata-target.h b/firmware/target/arm/imx31/gigabeat-s/ata-target.h new file mode 100644 index 0000000000..6dd6da9134 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/ata-target.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef ATA_TARGET_H | ||
20 | #define ATA_TARGET_H | ||
21 | |||
22 | /* Plain C read & write loops */ | ||
23 | #define PREFER_C_READING | ||
24 | #define PREFER_C_WRITING | ||
25 | #if !defined(BOOTLOADER) | ||
26 | #define ATA_OPTIMIZED_READING | ||
27 | void copy_read_sectors(unsigned char* buf, int wordcount); | ||
28 | #endif | ||
29 | |||
30 | #define ATA_IOBASE 0x43F8C000 | ||
31 | #define ATA_DATA (*((volatile unsigned short*)(ATA_IOBASE + 0xA0))) | ||
32 | #define ATA_ERROR (*((volatile unsigned char*)(ATA_IOBASE + 0xA4))) | ||
33 | #define ATA_NSECTOR (*((volatile unsigned char*)(ATA_IOBASE + 0xA8))) | ||
34 | #define ATA_SECTOR (*((volatile unsigned char*)(ATA_IOBASE + 0xAC))) | ||
35 | #define ATA_LCYL (*((volatile unsigned char*)(ATA_IOBASE + 0xB0))) | ||
36 | #define ATA_HCYL (*((volatile unsigned char*)(ATA_IOBASE + 0xB4))) | ||
37 | #define ATA_SELECT (*((volatile unsigned char*)(ATA_IOBASE + 0xB8))) | ||
38 | #define ATA_COMMAND (*((volatile unsigned char*)(ATA_IOBASE + 0xBC))) | ||
39 | #define ATA_CONTROL (*((volatile unsigned char*)(ATA_IOBASE + 0xD8))) | ||
40 | |||
41 | #define STATUS_BSY 0x80 | ||
42 | #define STATUS_RDY 0x40 | ||
43 | #define STATUS_DF 0x20 | ||
44 | #define STATUS_DRQ 0x08 | ||
45 | #define STATUS_ERR 0x01 | ||
46 | #define ERROR_ABRT 0x04 | ||
47 | |||
48 | #define WRITE_PATTERN1 0xa5 | ||
49 | #define WRITE_PATTERN2 0x5a | ||
50 | #define WRITE_PATTERN3 0xaa | ||
51 | #define WRITE_PATTERN4 0x55 | ||
52 | |||
53 | #define READ_PATTERN1 0xa5 | ||
54 | #define READ_PATTERN2 0x5a | ||
55 | #define READ_PATTERN3 0xaa | ||
56 | #define READ_PATTERN4 0x55 | ||
57 | |||
58 | #define READ_PATTERN1_MASK 0xff | ||
59 | #define READ_PATTERN2_MASK 0xff | ||
60 | #define READ_PATTERN3_MASK 0xff | ||
61 | #define READ_PATTERN4_MASK 0xff | ||
62 | |||
63 | #define SET_REG(reg,val) reg = (val) | ||
64 | #define SET_16BITREG(reg,val) reg = (val) | ||
65 | |||
66 | void ata_reset(void); | ||
67 | void ata_device_init(void); | ||
68 | bool ata_is_coldstart(void); | ||
69 | |||
70 | #endif | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c new file mode 100644 index 0000000000..8236a38014 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | |||
@@ -0,0 +1,223 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by James Espinoza | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include <stdio.h> | ||
20 | #include "system.h" | ||
21 | #include "imx31l.h" | ||
22 | #include "avic-imx31.h" | ||
23 | #include "debug.h" | ||
24 | |||
25 | void avic_init(void) | ||
26 | { | ||
27 | /*following the steps in the AVIC setup in imx31 man*/ | ||
28 | |||
29 | /*Initialize interrupt structures*/ | ||
30 | int i,avicstart; | ||
31 | /*get start of avic_init section for address calculation*/ | ||
32 | __asm__ ("ldr %0,=_avicstart\n\t" | ||
33 | :"=r"(avicstart):); | ||
34 | |||
35 | for(i=0; i < 64;i++) | ||
36 | { | ||
37 | imx31_int[i].name = (char *)&imx31_int_names[i]; | ||
38 | imx31_int[i].int_type=IRQ; | ||
39 | /*integer i MUST be multiplied by 8 b/c gnu as | ||
40 | generates 2 instructions for each vector instruction | ||
41 | in vector_init(). Hence the value of 8 byte intervals | ||
42 | between each vector start address*/ | ||
43 | imx31_int[i].addr=(avicstart+(i*8)); | ||
44 | imx31_int[i].priority=0; | ||
45 | imx31_int[i].pInt_Handler=Unhandled_Int; | ||
46 | } | ||
47 | |||
48 | /*enable all Interrupts*/ | ||
49 | avic_enable_int(ALL,IRQ,0); | ||
50 | |||
51 | /*Setup all interrupt type IRQ*/ | ||
52 | avic_set_int_type(ALL,IRQ); | ||
53 | |||
54 | /*Set NM bit to enable VIC*/ | ||
55 | INTCNTL |= (1 << 18); | ||
56 | |||
57 | /*Setup Registers Vector0-Vector63 for interrupt handler functions*/ | ||
58 | for(i=0; i < 64;i++) | ||
59 | writel(imx31_int[i].addr,(VECTOR_BASE_ADDR+(i*8))); | ||
60 | |||
61 | /*disable FIQ for now until the interrupt handlers are more mature...*/ | ||
62 | disable_fiq(); | ||
63 | /*enable_fiq();*/ | ||
64 | |||
65 | /*enable IRQ in imx31 INTCNTL reg*/ | ||
66 | INTCNTL &= ~(NIDIS); | ||
67 | /*disable FIQ in imx31 INTCNTL reg*/ | ||
68 | INTCNTL |= FIDIS; | ||
69 | |||
70 | /*enable IRQ in ARM11 core, enable VE bit in CP15 Control reg to enable VIC*/ | ||
71 | __asm__ ("mrs r0,cpsr\t\n" | ||
72 | "bic r0,r0,#0x80\t\n" | ||
73 | "msr cpsr,r0\t\n" | ||
74 | "mrc p15,0,r0,c1,c0,0\n\t" | ||
75 | "orr r0,r0,#0x1000000\n\t" | ||
76 | "mcr p15,0,r0,c1,c0,0\n\t"::: | ||
77 | "r0"); | ||
78 | } | ||
79 | |||
80 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | ||
81 | void (*pInt_Handler) (void)) | ||
82 | { | ||
83 | int i; | ||
84 | |||
85 | if(ints == ALL) | ||
86 | { | ||
87 | avic_set_int_type(ALL,intstype); | ||
88 | for(i=0;i<64;i++) | ||
89 | INTENNUM= (long)i; | ||
90 | if(!(*pInt_Handler)) | ||
91 | pInt_Handler=Unhandled_Int; | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | imx31_int[ints].int_type=intstype; | ||
96 | imx31_int[ints].pInt_Handler=pInt_Handler; | ||
97 | avic_set_int_type(ints,intstype); | ||
98 | INTENNUM=(long)ints; | ||
99 | } | ||
100 | |||
101 | void avic_disable_int(enum IMX31_INT_LIST ints) | ||
102 | { | ||
103 | int i; | ||
104 | |||
105 | if(ints == ALL) | ||
106 | { | ||
107 | for(i=0;i<64;i++) | ||
108 | INTDISNUM=(long)i; | ||
109 | imx31_int[ints].pInt_Handler=Unhandled_Int; | ||
110 | return; | ||
111 | } | ||
112 | |||
113 | INTDISNUM=(long)ints; | ||
114 | } | ||
115 | |||
116 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype) | ||
117 | { | ||
118 | int i; | ||
119 | if(ints == ALL) | ||
120 | { | ||
121 | imx31_int[ints].int_type=intstype; | ||
122 | for(i=0;i<64;i++) | ||
123 | { | ||
124 | if(intstype > CCM_DVFS) | ||
125 | INTTYPEH=(long)(intstype-32); | ||
126 | else INTTYPEL=(long)intstype; | ||
127 | } | ||
128 | return; | ||
129 | } | ||
130 | |||
131 | imx31_int[ints].int_type=intstype; | ||
132 | if(intstype > CCM_DVFS) | ||
133 | INTTYPEH=(long)(intstype-32); | ||
134 | else INTTYPEL=(long)intstype; | ||
135 | } | ||
136 | |||
137 | void Unhandled_Int(void) | ||
138 | { | ||
139 | enum IMX31_INT_LIST ints = 0; | ||
140 | DEBUGF("Unhandled Interrupt:\n"); | ||
141 | DEBUGF("Name : %s\n",imx31_int[ints].name); | ||
142 | DEBUGF("Interrupt Type : "); | ||
143 | if(imx31_int[ints].int_type==IRQ) | ||
144 | DEBUGF("IRQ\n"); | ||
145 | else DEBUGF("FIQ\n"); | ||
146 | DEBUGF("Handler Address : 0x%x\n",imx31_int[ints].addr); | ||
147 | DEBUGF("Priority : %d",imx31_int[ints].priority); | ||
148 | } | ||
149 | |||
150 | void vector_init(void) | ||
151 | { | ||
152 | |||
153 | /*64 branch instructions, one for every vector in avic | ||
154 | A better idea would to calculate the shellcode for each of these | ||
155 | instructions...*/ | ||
156 | |||
157 | |||
158 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED0].pInt_Handler)); | ||
159 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED1].pInt_Handler)); | ||
160 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED2].pInt_Handler)); | ||
161 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C3].pInt_Handler)); | ||
162 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C2].pInt_Handler)); | ||
163 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MPEG4_ENCODER].pInt_Handler)); | ||
164 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RTIC].pInt_Handler)); | ||
165 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[FIR].pInt_Handler)); | ||
166 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MMC_SDHC2].pInt_Handler)); | ||
167 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MMC_SDHC1].pInt_Handler)); | ||
168 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[I2C1].pInt_Handler)); | ||
169 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SSI2].pInt_Handler)); | ||
170 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SSI1].pInt_Handler)); | ||
171 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI2].pInt_Handler)); | ||
172 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI1].pInt_Handler)); | ||
173 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[ATA].pInt_Handler)); | ||
174 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MBX].pInt_Handler)); | ||
175 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CSPI3].pInt_Handler)); | ||
176 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART3].pInt_Handler)); | ||
177 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IIM].pInt_Handler)); | ||
178 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SIM1].pInt_Handler)); | ||
179 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SIM2].pInt_Handler)); | ||
180 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RNGA].pInt_Handler)); | ||
181 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EVTMON].pInt_Handler)); | ||
182 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[KPP].pInt_Handler)); | ||
183 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RTC].pInt_Handler)); | ||
184 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PWN].pInt_Handler)); | ||
185 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EPIT2].pInt_Handler)); | ||
186 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EPIT1].pInt_Handler)); | ||
187 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPT].pInt_Handler)); | ||
188 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PWR_FAIL].pInt_Handler)); | ||
189 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CCM_DVFS].pInt_Handler)); | ||
190 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART2].pInt_Handler)); | ||
191 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[NANDFC].pInt_Handler)); | ||
192 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SDMA].pInt_Handler)); | ||
193 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_HOST1].pInt_Handler)); | ||
194 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_HOST2].pInt_Handler)); | ||
195 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[USB_OTG].pInt_Handler)); | ||
196 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED3].pInt_Handler)); | ||
197 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MSHC1].pInt_Handler)); | ||
198 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[MSHC2].pInt_Handler)); | ||
199 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IPU_ERR].pInt_Handler)); | ||
200 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[IPU].pInt_Handler)); | ||
201 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED4].pInt_Handler)); | ||
202 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED5].pInt_Handler)); | ||
203 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART1].pInt_Handler)); | ||
204 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART4].pInt_Handler)); | ||
205 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[UART5].pInt_Handler)); | ||
206 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[ETC_IRQ].pInt_Handler)); | ||
207 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SCC_SCM].pInt_Handler)); | ||
208 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[SCC_SMN].pInt_Handler)); | ||
209 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO2].pInt_Handler)); | ||
210 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO1].pInt_Handler)); | ||
211 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[CCM_CLK].pInt_Handler)); | ||
212 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[PCMCIA].pInt_Handler)); | ||
213 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[WDOG].pInt_Handler)); | ||
214 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[GPIO3].pInt_Handler)); | ||
215 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[RESERVED6].pInt_Handler)); | ||
216 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_PWMG].pInt_Handler)); | ||
217 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_TEMP].pInt_Handler)); | ||
218 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_SENS1].pInt_Handler)); | ||
219 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_SENS2].pInt_Handler)); | ||
220 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_WDOG].pInt_Handler)); | ||
221 | __asm__("ldr pc, %0\n\t"::"g"(imx31_int[EXT_TV].pInt_Handler)); | ||
222 | |||
223 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h new file mode 100644 index 0000000000..53a37b353b --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h | |||
@@ -0,0 +1,125 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by James Espinoza | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef AVIC_IMX31_H | ||
20 | #define AVIC_IMX31_H | ||
21 | |||
22 | |||
23 | enum INT_TYPE {IRQ=0,FIQ}; | ||
24 | |||
25 | struct int_names { | ||
26 | char name[16]; | ||
27 | }; | ||
28 | |||
29 | static const struct int_names imx31_int_names[64] = | ||
30 | { {"RESERVED0"}, | ||
31 | {"RESERVED1"}, | ||
32 | {"RESERVED2"}, | ||
33 | {"I2C3"}, | ||
34 | {"I2C2"}, | ||
35 | {"MPEG4_ENCODER"}, | ||
36 | {"RTIC"}, | ||
37 | {"FIR"}, | ||
38 | {"MMC/SDHC2"}, | ||
39 | {"MMC/SDHC1"}, | ||
40 | {"I2C1"}, | ||
41 | {"SSI2"}, | ||
42 | {"SSI1"}, | ||
43 | {"CSPI2"}, | ||
44 | {"CSPI1"}, | ||
45 | {"ATA"}, | ||
46 | {"MBX"}, | ||
47 | {"CSPI3"}, | ||
48 | {"UART3"}, | ||
49 | {"IIM"}, | ||
50 | {"SIM1"}, | ||
51 | {"SIM2"}, | ||
52 | {"RNGA"}, | ||
53 | {"EVTMON"}, | ||
54 | {"KPP"}, | ||
55 | {"RTC"}, | ||
56 | {"PWN"}, | ||
57 | {"EPIT2"}, | ||
58 | {"EPIT1"}, | ||
59 | {"GPT"}, | ||
60 | {"PWR_FAIL"}, | ||
61 | {"CCM_DVFS"}, | ||
62 | {"UART2"}, | ||
63 | {"NANDFC"}, | ||
64 | {"SDMA"}, | ||
65 | {"USB_HOST1"}, | ||
66 | {"USB_HOST2"}, | ||
67 | {"USB_OTG"}, | ||
68 | {"RESERVED3"}, | ||
69 | {"MSHC1"}, | ||
70 | {"MSHC2"}, | ||
71 | {"IPU_ERR"}, | ||
72 | {"IPU"}, | ||
73 | {"RESERVED4"}, | ||
74 | {"RESERVED5"}, | ||
75 | {"UART1"}, | ||
76 | {"UART4"}, | ||
77 | {"UART5"}, | ||
78 | {"ETC_IRQ"}, | ||
79 | {"SCC_SCM"}, | ||
80 | {"SCC_SMN"}, | ||
81 | {"GPIO2"}, | ||
82 | {"GPIO1"}, | ||
83 | {"CCM_CLK"}, | ||
84 | {"PCMCIA"}, | ||
85 | {"WDOG"}, | ||
86 | {"GPIO3"}, | ||
87 | {"RESERVED6"}, | ||
88 | {"EXT_PWMG"}, | ||
89 | {"EXT_TEMP"}, | ||
90 | {"EXT_SENS1"}, | ||
91 | {"EXT_SENS2"}, | ||
92 | {"EXT_WDOG"}, | ||
93 | {"EXT_TV"} }; | ||
94 | |||
95 | enum IMX31_INT_LIST { | ||
96 | RESERVED0 = 0,RESERVED1,RESERVED2,I2C3, | ||
97 | I2C2,MPEG4_ENCODER,RTIC,FIR,MMC_SDHC2, | ||
98 | MMC_SDHC1,I2C1,SSI2,SSI1,CSPI2,CSPI1, | ||
99 | ATA,MBX,CSPI3,UART3,IIM,SIM1,SIM2, | ||
100 | RNGA,EVTMON,KPP,RTC,PWN,EPIT2,EPIT1, | ||
101 | GPT,PWR_FAIL,CCM_DVFS,UART2,NANDFC, | ||
102 | SDMA,USB_HOST1,USB_HOST2,USB_OTG, | ||
103 | RESERVED3,MSHC1,MSHC2,IPU_ERR,IPU, | ||
104 | RESERVED4,RESERVED5,UART1,UART4,UART5, | ||
105 | ETC_IRQ,SCC_SCM,SCC_SMN,GPIO2,GPIO1, | ||
106 | CCM_CLK,PCMCIA,WDOG,GPIO3,RESERVED6, | ||
107 | EXT_PWMG,EXT_TEMP,EXT_SENS1,EXT_SENS2, | ||
108 | EXT_WDOG,EXT_TV,ALL }; | ||
109 | |||
110 | static struct avic_int { | ||
111 | char * name; | ||
112 | enum INT_TYPE int_type; | ||
113 | unsigned int addr; | ||
114 | unsigned int priority; | ||
115 | void (*pInt_Handler) (void); | ||
116 | } imx31_int[64]; | ||
117 | |||
118 | void avic_init(void); | ||
119 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | ||
120 | void (*pInt_Handler) (void)); | ||
121 | void avic_disable_int(enum IMX31_INT_LIST ints) ; | ||
122 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); | ||
123 | void Unhandled_Int(void); | ||
124 | void vector_init(void) __attribute__ ((section(".avic_int"),naked)); | ||
125 | #endif | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c b/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c new file mode 100644 index 0000000000..37cf086a0e --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "cpu.h" | ||
21 | #include "system.h" | ||
22 | #include "backlight-target.h" | ||
23 | #include "backlight.h" | ||
24 | #include "lcd.h" | ||
25 | #include "power.h" | ||
26 | #include "spi-imx31.h" | ||
27 | #include "debug.h" | ||
28 | |||
29 | bool __backlight_init(void) | ||
30 | { | ||
31 | return true; | ||
32 | } | ||
33 | |||
34 | void __backlight_on(void) | ||
35 | { | ||
36 | // This relies on the SPI interface being initialised already | ||
37 | spi_send(51, 1); | ||
38 | } | ||
39 | |||
40 | void __backlight_off(void) | ||
41 | { | ||
42 | // This relies on the SPI interface being initialised already | ||
43 | spi_send(51, 0); | ||
44 | } | ||
45 | |||
46 | /* Assumes that the backlight has been initialized */ | ||
47 | void __backlight_set_brightness(int brightness) | ||
48 | { | ||
49 | (void)brightness; | ||
50 | } | ||
51 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/backlight-target.h b/firmware/target/arm/imx31/gigabeat-s/backlight-target.h new file mode 100644 index 0000000000..8f14c76138 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/backlight-target.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef BACKLIGHT_TARGET_H | ||
20 | #define BACKLIGHT_TARGET_H | ||
21 | |||
22 | bool __backlight_init(void); | ||
23 | void __backlight_on(void); | ||
24 | void __backlight_off(void); | ||
25 | void __backlight_set_brightness(int brightness); | ||
26 | |||
27 | /* true: backlight fades off - false: backlight fades on */ | ||
28 | void __backlight_dim(bool dim); | ||
29 | #endif | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/button-imx31.c b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c new file mode 100644 index 0000000000..32d2a63c49 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/button-imx31.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "cpu.h" | ||
22 | #include "system.h" | ||
23 | #include "button.h" | ||
24 | #include "kernel.h" | ||
25 | #include "backlight.h" | ||
26 | #include "adc.h" | ||
27 | #include "system.h" | ||
28 | #include "backlight-target.h" | ||
29 | #include "debug.h" | ||
30 | #include "stdio.h" | ||
31 | |||
32 | /* Most code in here is taken from the Linux BSP provided by Freescale | ||
33 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. */ | ||
34 | |||
35 | void button_init_device(void) | ||
36 | { | ||
37 | unsigned int reg_val; | ||
38 | /* Enable keypad clock */ | ||
39 | //mxc_clks_enable(KPP_CLK); | ||
40 | |||
41 | /* Enable number of rows in keypad (KPCR[7:0]) | ||
42 | * Configure keypad columns as open-drain (KPCR[15:8]) | ||
43 | * | ||
44 | * Configure the rows/cols in KPP | ||
45 | * LSB nibble in KPP is for 8 rows | ||
46 | * MSB nibble in KPP is for 8 cols | ||
47 | */ | ||
48 | reg_val = KPP_KPCR; | ||
49 | reg_val |= (1 << 8) - 1; /* LSB */ | ||
50 | reg_val |= ((1 << 8) - 1) << 8; /* MSB */ | ||
51 | KPP_KPCR = reg_val; | ||
52 | |||
53 | /* Write 0's to KPDR[15:8] */ | ||
54 | reg_val = KPP_KPDR; | ||
55 | reg_val &= 0x00ff; | ||
56 | KPP_KPDR = reg_val; | ||
57 | |||
58 | /* Configure columns as output, rows as input (KDDR[15:0]) */ | ||
59 | KPP_KDDR = 0xff00; | ||
60 | |||
61 | reg_val = 0xD; | ||
62 | reg_val |= (1 << 8); | ||
63 | KPP_KPSR = reg_val; | ||
64 | } | ||
65 | |||
66 | inline bool button_hold(void) | ||
67 | { | ||
68 | return GPIO3_DR & 0x10; | ||
69 | } | ||
70 | |||
71 | int button_read_device(void) | ||
72 | { | ||
73 | unsigned short reg_val; | ||
74 | int col, row; | ||
75 | int button = BUTTON_NONE; | ||
76 | |||
77 | if(!button_hold()) { | ||
78 | for (col = 0; col < 3; col++) { /* Col */ | ||
79 | /* 1. Write 1s to KPDR[15:8] setting column data to 1s */ | ||
80 | reg_val = KPP_KPDR; | ||
81 | reg_val |= 0xff00; | ||
82 | KPP_KPDR = reg_val; | ||
83 | |||
84 | /* | ||
85 | * 2. Configure columns as totem pole outputs(for quick | ||
86 | * discharging of keypad capacitance) | ||
87 | */ | ||
88 | reg_val = KPP_KPCR; | ||
89 | reg_val &= 0x00ff; | ||
90 | KPP_KPCR = reg_val; | ||
91 | |||
92 | /* Give the columns time to discharge */ | ||
93 | udelay(2); | ||
94 | |||
95 | /* 3. Configure columns as open-drain */ | ||
96 | reg_val = KPP_KPCR; | ||
97 | reg_val |= ((1 << 8) - 1) << 8; | ||
98 | KPP_KPCR = reg_val; | ||
99 | |||
100 | /* 4. Write a single column to 0, others to 1. | ||
101 | * 5. Sample row inputs and save data. Multiple key presses | ||
102 | * can be detected on a single column. | ||
103 | * 6. Repeat steps 1 - 5 for remaining columns. | ||
104 | */ | ||
105 | |||
106 | /* Col bit starts at 8th bit in KPDR */ | ||
107 | reg_val = KPP_KPDR; | ||
108 | reg_val &= ~(1 << (8 + col)); | ||
109 | KPP_KPDR = reg_val; | ||
110 | |||
111 | /* Delay added to avoid propagating the 0 from column to row | ||
112 | * when scanning. */ | ||
113 | udelay(2); | ||
114 | |||
115 | /* Read row input */ | ||
116 | reg_val = KPP_KPDR; | ||
117 | for (row = 0; row < 5; row++) { /* sample row */ | ||
118 | if (!(reg_val & (1 << row))) { | ||
119 | if(row == 0) { | ||
120 | if(col == 0) { | ||
121 | button |= BUTTON_LEFT; | ||
122 | } | ||
123 | if(col == 1) { | ||
124 | button |= BUTTON_BACK; | ||
125 | } | ||
126 | if(col == 2) { | ||
127 | button |= BUTTON_VOL_UP; | ||
128 | } | ||
129 | } else if(row == 1) { | ||
130 | if(col == 0) { | ||
131 | button |= BUTTON_UP; | ||
132 | } | ||
133 | if(col == 1) { | ||
134 | button |= BUTTON_MENU; | ||
135 | } | ||
136 | if(col == 2) { | ||
137 | button |= BUTTON_VOL_DOWN; | ||
138 | } | ||
139 | } else if(row == 2) { | ||
140 | if(col == 0) { | ||
141 | button |= BUTTON_DOWN; | ||
142 | } | ||
143 | if(col == 2) { | ||
144 | button |= BUTTON_PREV; | ||
145 | } | ||
146 | } else if(row == 3) { | ||
147 | if(col == 0) { | ||
148 | button |= BUTTON_RIGHT; | ||
149 | } | ||
150 | if(col == 2) { | ||
151 | button |= BUTTON_PLAY; | ||
152 | } | ||
153 | } else if(row == 4) { | ||
154 | if(col == 0) { | ||
155 | button |= BUTTON_SELECT; | ||
156 | } | ||
157 | if(col == 2) { | ||
158 | button |= BUTTON_NEXT; | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * 7. Return all columns to 0 in preparation for standby mode. | ||
167 | * 8. Clear KPKD and KPKR status bit(s) by writing to a .1., | ||
168 | * set the KPKR synchronizer chain by writing "1" to KRSS register, | ||
169 | * clear the KPKD synchronizer chain by writing "1" to KDSC register | ||
170 | */ | ||
171 | reg_val = 0x00; | ||
172 | KPP_KPDR = reg_val; | ||
173 | reg_val = KPP_KPDR; | ||
174 | reg_val = KPP_KPSR; | ||
175 | reg_val |= 0xF; | ||
176 | KPP_KPSR = reg_val; | ||
177 | } | ||
178 | |||
179 | return button; | ||
180 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/button-target.h b/firmware/target/arm/imx31/gigabeat-s/button-target.h new file mode 100644 index 0000000000..33f018e0bf --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/button-target.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef _BUTTON_TARGET_H_ | ||
20 | #define _BUTTON_TARGET_H_ | ||
21 | |||
22 | #include <stdbool.h> | ||
23 | #include "config.h" | ||
24 | |||
25 | #define HAS_BUTTON_HOLD | ||
26 | |||
27 | bool button_hold(void); | ||
28 | void button_init_device(void); | ||
29 | int button_read_device(void); | ||
30 | |||
31 | /* Toshiba Gigabeat specific button codes */ | ||
32 | |||
33 | #define BUTTON_BACK (1 << 0) | ||
34 | #define BUTTON_MENU (1 << 1) | ||
35 | |||
36 | #define BUTTON_LEFT (1 << 2) | ||
37 | #define BUTTON_RIGHT (1 << 3) | ||
38 | #define BUTTON_UP (1 << 4) | ||
39 | #define BUTTON_DOWN (1 << 5) | ||
40 | #define BUTTON_SELECT (1 << 6) | ||
41 | |||
42 | #define BUTTON_POWER (1 << 7) | ||
43 | #define BUTTON_VOL_UP (1 << 8) | ||
44 | #define BUTTON_VOL_DOWN (1 << 9) | ||
45 | #define BUTTON_NEXT (1 << 10) | ||
46 | #define BUTTON_PREV (1 << 11) | ||
47 | #define BUTTON_PLAY (1 << 12) | ||
48 | |||
49 | #define BUTTON_MAIN (BUTTON_BACK|BUTTON_MENU|BUTTON_LEFT|BUTTON_RIGHT \ | ||
50 | |BUTTON_UP|BUTTON_DOWN|BUTTON_SELECT|BUTTON_POWER \ | ||
51 | |BUTTON_VOL_UP|BUTTON_VOL_DOWN|BUTTON_NEXT|BUTTON_PREV \ | ||
52 | |BUTTON_PLAY) | ||
53 | |||
54 | #define BUTTON_REMOTE 0 | ||
55 | |||
56 | #define POWEROFF_BUTTON BUTTON_POWER | ||
57 | #define POWEROFF_COUNT 10 | ||
58 | |||
59 | #endif /* _BUTTON_TARGET_H_ */ | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/dma_start.c b/firmware/target/arm/imx31/gigabeat-s/dma_start.c new file mode 100644 index 0000000000..c1ab6c15cb --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/dma_start.c | |||
@@ -0,0 +1,8 @@ | |||
1 | #include <sys/types.h> | ||
2 | |||
3 | void dma_start(const void* addr, size_t size) { | ||
4 | (void) addr; | ||
5 | (void) size; | ||
6 | //TODO: | ||
7 | } | ||
8 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/i2c-imx31.c b/firmware/target/arm/imx31/gigabeat-s/i2c-imx31.c new file mode 100644 index 0000000000..7c608c172d --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/i2c-imx31.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Michael Sevakis | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "system.h" | ||
20 | #include "i2c-imx31.h" | ||
21 | |||
22 | static int i2c_getack(void) | ||
23 | { | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | static int i2c_start(void) | ||
28 | { | ||
29 | return 0; | ||
30 | } | ||
31 | |||
32 | static void i2c_stop(void) | ||
33 | { | ||
34 | } | ||
35 | |||
36 | static int i2c_outb(unsigned char byte) | ||
37 | { | ||
38 | (void)byte; | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | void i2c_write(int addr, const unsigned char *buf, int count) | ||
43 | { | ||
44 | (void)addr; | ||
45 | (void)*buf; | ||
46 | (void)count; | ||
47 | } | ||
48 | |||
49 | void i2c_init(void) | ||
50 | { | ||
51 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/i2c-imx31.h b/firmware/target/arm/imx31/gigabeat-s/i2c-imx31.h new file mode 100644 index 0000000000..c708ebbfb4 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/i2c-imx31.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Michael Sevakis | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | void i2c_init(void); | ||
21 | void i2c_write(int addr, const unsigned char *data, int count); | ||
22 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/i2s-imx31.c b/firmware/target/arm/imx31/gigabeat-s/i2s-imx31.c new file mode 100644 index 0000000000..a8607babae --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/i2s-imx31.c | |||
@@ -0,0 +1,22 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Michael Sevakis | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | void i2s_reset(void) | ||
21 | { | ||
22 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c new file mode 100644 index 0000000000..9df90a2344 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c | |||
@@ -0,0 +1,25 @@ | |||
1 | #include "kernel.h" | ||
2 | #include "thread.h" | ||
3 | |||
4 | #include <stdio.h> | ||
5 | #include "lcd.h" | ||
6 | |||
7 | extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); | ||
8 | |||
9 | void timer4(void) { | ||
10 | int i; | ||
11 | /* Run through the list of tick tasks */ | ||
12 | for(i = 0; i < MAX_NUM_TICK_TASKS; i++) | ||
13 | { | ||
14 | if(tick_funcs[i]) | ||
15 | { | ||
16 | tick_funcs[i](); | ||
17 | } | ||
18 | } | ||
19 | |||
20 | current_tick++; | ||
21 | |||
22 | /* following needs to be fixed. */ | ||
23 | /*wake_up_thread();*/ | ||
24 | } | ||
25 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S b/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S new file mode 100644 index 0000000000..d431c95f29 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/lcd-as-imx31.S | |||
@@ -0,0 +1,222 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Michael Sevakis | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "config.h" | ||
21 | #include "cpu.h" | ||
22 | |||
23 | /**************************************************************************** | ||
24 | * void lcd_write_yuv_420_lines(fb_data *dst, | ||
25 | * unsigned char chroma_buf[LCD_HEIGHT/2*3], | ||
26 | unsigned char const * const src[3], | ||
27 | * int width, | ||
28 | * int stride); | ||
29 | * | ||
30 | * |R| |1.000000 -0.000001 1.402000| |Y'| | ||
31 | * |G| = |1.000000 -0.334136 -0.714136| |Pb| | ||
32 | * |B| |1.000000 1.772000 0.000000| |Pr| | ||
33 | * Scaled, normalized, rounded and tweaked to yield RGB 565: | ||
34 | * |R| |74 0 101| |Y' - 16| >> 9 | ||
35 | * |G| = |74 -24 -51| |Cb - 128| >> 8 | ||
36 | * |B| |74 128 0| |Cr - 128| >> 9 | ||
37 | */ | ||
38 | .section .icode, "ax", %progbits | ||
39 | .align 2 | ||
40 | .global lcd_write_yuv420_lines | ||
41 | .type lcd_write_yuv420_lines, %function | ||
42 | lcd_write_yuv420_lines: | ||
43 | @ r0 = dst | ||
44 | @ r1 = chroma_buf | ||
45 | @ r2 = yuv_src | ||
46 | @ r3 = width | ||
47 | @ [sp] = stride | ||
48 | stmdb sp!, { r4-r12, lr } @ save non-scratch | ||
49 | stmdb sp!, { r0, r3 } @ save dst and width | ||
50 | mov r14, #74 @ r14 = Y factor | ||
51 | ldmia r2, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p | ||
52 | @ r5 = yuv_src[1] = Cb_p | ||
53 | @ r6 = yuv_src[2] = Cr_p | ||
54 | 10: @ loop line 1 @ | ||
55 | ldrb r2, [r4], #1 @ r2 = *Y'_p++; | ||
56 | ldrb r8, [r5], #1 @ r8 = *Cb_p++; | ||
57 | ldrb r11, [r6], #1 @ r11 = *Cr_p++; | ||
58 | @ | ||
59 | @ compute Y | ||
60 | sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74 | ||
61 | mul r7, r2, r14 @ | ||
62 | @ | ||
63 | sub r8, r8, #128 @ Cb -= 128 | ||
64 | sub r11, r11, #128 @ Cr -= 128 | ||
65 | @ | ||
66 | mvn r2, #24 @ compute guv | ||
67 | mul r10, r2, r8 @ r10 = Cb*-24 | ||
68 | mvn r2, #51 @ | ||
69 | mla r10, r2, r11, r10 @ r10 = r10 + Cr*-51 | ||
70 | @ | ||
71 | mov r2, #101 @ compute rv | ||
72 | mul r9, r11, r2 @ r9 = rv = Cr*101 | ||
73 | @ | ||
74 | @ store chromas in line buffer | ||
75 | add r8, r8, #2 @ bu = (Cb + 2) >> 2 | ||
76 | mov r8, r8, asr #2 @ | ||
77 | strb r8, [r1], #1 @ | ||
78 | add r9, r9, #256 @ rv = (Cr + 256) >> 9 | ||
79 | mov r9, r9, asr #9 @ | ||
80 | strb r9, [r1], #1 @ | ||
81 | mov r10, r10, asr #8 @ guv >>= 8 | ||
82 | strb r10, [r1], #1 @ | ||
83 | @ compute R, G, and B | ||
84 | add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu | ||
85 | add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv | ||
86 | add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv | ||
87 | @ | ||
88 | orr r12, r2, r11 @ check if clamping is needed... | ||
89 | orr r12, r12, r7, asr #1 @ ...at all | ||
90 | cmp r12, #31 @ | ||
91 | bls 15f @ no clamp @ | ||
92 | mov r12, #31 @ | ||
93 | cmp r12, r2 @ clamp b | ||
94 | andlo r2, r12, r2, asr #31 @ | ||
95 | eorlo r2, r2, r12 @ | ||
96 | cmp r12, r11 @ clamp r | ||
97 | andlo r11, r12, r11, asr #31 @ | ||
98 | eorlo r11, r11, r12 @ | ||
99 | cmp r12, r7, asr #1 @ clamp g | ||
100 | andlo r7, r12, r7, asr #31 @ | ||
101 | eorlo r7, r7, r12 @ | ||
102 | orrlo r7, r7, r7, asl #1 @ | ||
103 | 15: @ no clamp @ | ||
104 | @ | ||
105 | orr r12, r2, r7, lsl #5 @ r4 |= (g << 5) | ||
106 | ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++ | ||
107 | orr r12, r12, r11, lsl #11 @ r4 = b | (r << 11) | ||
108 | strh r12, [r0], #240 @ store pixel | ||
109 | @ | ||
110 | sub r2, r2, #16 @ r7 = Y = (Y' - 16)*74 | ||
111 | mul r7, r2, r14 @ next Y | ||
112 | @ compute R, G, and B | ||
113 | add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu | ||
114 | add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv | ||
115 | add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv | ||
116 | @ | ||
117 | orr r12, r2, r11 @ check if clamping is needed... | ||
118 | orr r12, r12, r7, asr #1 @ ...at all | ||
119 | cmp r12, #31 @ | ||
120 | bls 15f @ no clamp @ | ||
121 | mov r12, #31 @ | ||
122 | cmp r12, r2 @ clamp b | ||
123 | andlo r2, r12, r2, asr #31 @ | ||
124 | eorlo r2, r2, r12 @ | ||
125 | cmp r12, r11 @ clamp r | ||
126 | andlo r11, r12, r11, asr #31 @ | ||
127 | eorlo r11, r11, r12 @ | ||
128 | cmp r12, r7, asr #1 @ clamp g | ||
129 | andlo r7, r12, r7, asr #31 @ | ||
130 | eorlo r7, r7, r12 @ | ||
131 | orrlo r7, r7, r7, asl #1 @ | ||
132 | 15: @ no clamp @ | ||
133 | @ | ||
134 | orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) | ||
135 | orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) | ||
136 | strh r12, [r0, #240]! @ store pixel | ||
137 | add r0, r0, #2*240 @ | ||
138 | @ | ||
139 | subs r3, r3, #2 @ | ||
140 | bgt 10b @ loop line 1 @ | ||
141 | @ do second line | ||
142 | @ | ||
143 | ldmia sp!, { r0, r3 } @ pop dst and width | ||
144 | sub r0, r0, #2 @ set dst to start of next line | ||
145 | sub r1, r1, r3, asl #1 @ rewind chroma pointer... | ||
146 | ldr r2, [sp, #40] @ r2 = stride | ||
147 | add r1, r1, r3, asr #1 @ ... (r1 -= width/2*3) | ||
148 | @ move sources to start of next line | ||
149 | sub r2, r2, r3 @ r2 = skip = stride - width | ||
150 | add r4, r4, r2 @ r4 = Y'_p + skip | ||
151 | @ | ||
152 | 20: @ loop line 2 @ | ||
153 | ldrb r2, [r4], #1 @ r7 = Y' = *Y'_p++ | ||
154 | ldrsb r8, [r1], #1 @ reload saved chromas | ||
155 | ldrsb r9, [r1], #1 @ | ||
156 | ldrsb r10, [r1], #1 @ | ||
157 | @ | ||
158 | sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74 | ||
159 | mul r7, r2, r14 @ | ||
160 | @ compute R, G, and B | ||
161 | add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu | ||
162 | add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv | ||
163 | add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv | ||
164 | @ | ||
165 | orr r12, r2, r11 @ check if clamping is needed... | ||
166 | orr r12, r12, r7, asr #1 @ ...at all | ||
167 | cmp r12, #31 @ | ||
168 | bls 25f @ no clamp @ | ||
169 | mov r12, #31 @ | ||
170 | cmp r12, r2 @ clamp b | ||
171 | andlo r2, r12, r2, asr #31 @ | ||
172 | eorlo r2, r2, r12 @ | ||
173 | cmp r12, r11 @ clamp r | ||
174 | andlo r11, r12, r11, asr #31 @ | ||
175 | eorlo r11, r11, r12 @ | ||
176 | cmp r12, r7, asr #1 @ clamp g | ||
177 | andlo r7, r12, r7, asr #31 @ | ||
178 | eorlo r7, r7, r12 @ | ||
179 | orrlo r7, r7, r7, asl #1 @ | ||
180 | 25: @ no clamp @ | ||
181 | @ | ||
182 | orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) | ||
183 | ldrb r2, [r4], #1 @ r2 = Y' = *Y'_p++ | ||
184 | orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) | ||
185 | strh r12, [r0], #240 @ store pixel | ||
186 | @ | ||
187 | @ do second pixel | ||
188 | @ | ||
189 | sub r2, r2, #16 @ r2 = Y = (Y' - 16)*74 | ||
190 | mul r7, r2, r14 @ | ||
191 | @ compute R, G, and B | ||
192 | add r2, r8, r7, asr #9 @ r2 = b = (Y >> 9) + bu | ||
193 | add r11, r9, r7, asr #9 @ r11 = r = (Y >> 9) + rv | ||
194 | add r7, r10, r7, asr #8 @ r7 = g = (Y >> 8) + guv | ||
195 | @ | ||
196 | orr r12, r2, r11 @ check if clamping is needed... | ||
197 | orr r12, r12, r7, asr #1 @ ...at all | ||
198 | cmp r12, #31 @ | ||
199 | bls 25f @ no clamp @ | ||
200 | mov r12, #31 @ | ||
201 | cmp r12, r2 @ clamp b | ||
202 | andlo r2, r12, r2, asr #31 @ | ||
203 | eorlo r2, r2, r12 @ | ||
204 | cmp r12, r11 @ clamp r | ||
205 | andlo r11, r12, r11, asr #31 @ | ||
206 | eorlo r11, r11, r12 @ | ||
207 | cmp r12, r7, asr #1 @ clamp g | ||
208 | andlo r7, r12, r7, asr #31 @ | ||
209 | eorlo r7, r7, r12 @ | ||
210 | orrlo r7, r7, r7, asl #1 @ | ||
211 | 25: @ no clamp @ | ||
212 | @ | ||
213 | orr r12, r2, r11, lsl #11 @ r4 = b | (r << 11) | ||
214 | orr r12, r12, r7, lsl #5 @ r4 |= (g << 5) | ||
215 | strh r12, [r0, #240]! @ store pixel | ||
216 | add r0, r0, #2*240 @ | ||
217 | @ | ||
218 | subs r3, r3, #2 @ | ||
219 | bgt 20b @ loop line 2 @ | ||
220 | @ | ||
221 | ldmia sp!, { r4-r12, pc } @ restore registers and return | ||
222 | .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c b/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c new file mode 100644 index 0000000000..c9cce6d653 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/lcd-imx31.c | |||
@@ -0,0 +1,230 @@ | |||
1 | #include "config.h" | ||
2 | #include "cpu.h" | ||
3 | #include "string.h" | ||
4 | #include "lcd.h" | ||
5 | #include "kernel.h" | ||
6 | #include "lcd-target.h" | ||
7 | |||
8 | #define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) | ||
9 | |||
10 | static volatile bool lcd_on = true; | ||
11 | volatile bool lcd_poweroff = false; | ||
12 | /* | ||
13 | ** These are imported from lcd-16bit.c | ||
14 | */ | ||
15 | extern unsigned fg_pattern; | ||
16 | extern unsigned bg_pattern; | ||
17 | |||
18 | #if 0 | ||
19 | bool lcd_enabled() | ||
20 | { | ||
21 | return lcd_on; | ||
22 | } | ||
23 | #endif | ||
24 | |||
25 | void printscreen(unsigned int colour) { | ||
26 | int i; | ||
27 | int base = 0x84100000; | ||
28 | for(i=0;i<(320*240*2);i++) { | ||
29 | writel(colour,base); | ||
30 | base++; | ||
31 | } | ||
32 | } | ||
33 | |||
34 | unsigned int LCDBANK(unsigned int address) | ||
35 | { | ||
36 | return ((address >> 22) & 0xff); | ||
37 | } | ||
38 | |||
39 | unsigned int LCDBASEU(unsigned int address) | ||
40 | { | ||
41 | return (address & ((1 << 22)-1)) >> 1; | ||
42 | } | ||
43 | |||
44 | unsigned int LCDBASEL(unsigned int address) | ||
45 | { | ||
46 | address += 320*240*2; | ||
47 | return (address & ((1 << 22)-1)) >> 1; | ||
48 | } | ||
49 | |||
50 | |||
51 | /* LCD init */ | ||
52 | void lcd_init_device(void) | ||
53 | { | ||
54 | int i; | ||
55 | #ifdef BOOTLOADER | ||
56 | /* When the Rockbox bootloader starts, we are changing framebuffer address, | ||
57 | but we don't want what's shown on the LCD to change until we do an | ||
58 | lcd_update(), so copy the data from the old framebuffer to the new one */ | ||
59 | unsigned short *buf = (unsigned short*)FRAME1; | ||
60 | |||
61 | memcpy(FRAME1, (short *)((LCDSADDR1)<<1), 320*240*2); | ||
62 | |||
63 | /* The Rockbox bootloader is transitioning from RGB555I to RGB565 mode | ||
64 | so convert the frambuffer data accordingly */ | ||
65 | for(i=0; i< 320*240; i++){ | ||
66 | *buf = ((*buf>>1) & 0x1F) | (*buf & 0xffc0); | ||
67 | buf++; | ||
68 | } | ||
69 | return; | ||
70 | #endif | ||
71 | } | ||
72 | |||
73 | /* Update a fraction of the display. */ | ||
74 | void lcd_update_rect(int x, int y, int width, int height) | ||
75 | { | ||
76 | (void)x; | ||
77 | (void)width; | ||
78 | (void)y; | ||
79 | (void)height; | ||
80 | |||
81 | if(!lcd_on) | ||
82 | { | ||
83 | sleep(200); | ||
84 | return; | ||
85 | } | ||
86 | memcpy(((char*)FRAME2) + (y * sizeof(fb_data) * LCD_WIDTH), ((char *)&lcd_framebuffer) + (y * sizeof(fb_data) * LCD_WIDTH), ((height * sizeof(fb_data) * LCD_WIDTH))); | ||
87 | } | ||
88 | |||
89 | void lcd_enable(bool state) | ||
90 | { | ||
91 | (void)state; | ||
92 | } | ||
93 | |||
94 | bool lcd_enabled(void) | ||
95 | { | ||
96 | return true; | ||
97 | } | ||
98 | |||
99 | /* Update the display. | ||
100 | This must be called after all other LCD functions that change the display. */ | ||
101 | void lcd_update(void) | ||
102 | { | ||
103 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | ||
104 | } | ||
105 | |||
106 | void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | ||
107 | int stride, int x, int y, int width, | ||
108 | int height) | ||
109 | { | ||
110 | fb_data *dst, *dst_end; | ||
111 | unsigned int transcolor; | ||
112 | |||
113 | /* nothing to draw? */ | ||
114 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
115 | || (x + width <= 0) || (y + height <= 0)) | ||
116 | return; | ||
117 | |||
118 | /* clipping */ | ||
119 | if (x < 0) | ||
120 | { | ||
121 | width += x; | ||
122 | src_x -= x; | ||
123 | x = 0; | ||
124 | } | ||
125 | if (y < 0) | ||
126 | { | ||
127 | height += y; | ||
128 | src_y -= y; | ||
129 | y = 0; | ||
130 | } | ||
131 | if (x + width > LCD_WIDTH) | ||
132 | width = LCD_WIDTH - x; | ||
133 | if (y + height > LCD_HEIGHT) | ||
134 | height = LCD_HEIGHT - y; | ||
135 | |||
136 | src += stride * src_y + src_x; /* move starting point */ | ||
137 | dst = &lcd_framebuffer[(y)][(x)]; | ||
138 | dst_end = dst + height * LCD_WIDTH; | ||
139 | width *= 2; | ||
140 | stride *= 2; | ||
141 | transcolor = TRANSPARENT_COLOR; | ||
142 | asm volatile( | ||
143 | "rowstart: \n" | ||
144 | "mov r0, #0 \n" | ||
145 | "nextpixel: \n" | ||
146 | "ldrh r1, [%0, r0] \n" /* Load word src+r0 */ | ||
147 | "cmp r1, %5 \n" /* Compare to transparent color */ | ||
148 | "strneh r1, [%1, r0] \n" /* Store dst+r0 if not transparent */ | ||
149 | "add r0, r0, #2 \n" | ||
150 | "cmp r0, %2 \n" /* r0 == width? */ | ||
151 | "bne nextpixel \n" /* More in this row? */ | ||
152 | "add %0, %0, %4 \n" /* src += stride */ | ||
153 | "add %1, %1, #480 \n" /* dst += LCD_WIDTH (x2) */ | ||
154 | "cmp %1, %3 \n" | ||
155 | "bne rowstart \n" /* if(dst != dst_end), keep going */ | ||
156 | : : "r" (src), "r" (dst), "r" (width), "r" (dst_end), "r" (stride), "r" (transcolor) : "r0", "r1" ); | ||
157 | } | ||
158 | |||
159 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
160 | extern void lcd_write_yuv420_lines(fb_data *dst, | ||
161 | unsigned char chroma_buf[LCD_HEIGHT/2*3], | ||
162 | unsigned char const * const src[3], | ||
163 | int width, | ||
164 | int stride); | ||
165 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
166 | /* For the Gigabeat - show it rotated */ | ||
167 | /* So the LCD_WIDTH is now the height */ | ||
168 | void lcd_yuv_blit(unsigned char * const src[3], | ||
169 | int src_x, int src_y, int stride, | ||
170 | int x, int y, int width, int height) | ||
171 | { | ||
172 | /* Caches for chroma data so it only need be recaculated every other | ||
173 | line */ | ||
174 | unsigned char chroma_buf[LCD_HEIGHT/2*3]; /* 480 bytes */ | ||
175 | unsigned char const * yuv_src[3]; | ||
176 | off_t z; | ||
177 | |||
178 | if (!lcd_on) | ||
179 | return; | ||
180 | |||
181 | /* Sorry, but width and height must be >= 2 or else */ | ||
182 | width &= ~1; | ||
183 | height >>= 1; | ||
184 | |||
185 | fb_data *dst = (fb_data*)FRAME1 + x * LCD_WIDTH + (LCD_WIDTH - y) - 1; | ||
186 | |||
187 | z = stride*src_y; | ||
188 | yuv_src[0] = src[0] + z + src_x; | ||
189 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
190 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
191 | |||
192 | do | ||
193 | { | ||
194 | lcd_write_yuv420_lines(dst, chroma_buf, yuv_src, width, | ||
195 | stride); | ||
196 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
197 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
198 | yuv_src[2] += stride >> 1; | ||
199 | dst -= 2; | ||
200 | } | ||
201 | while (--height > 0); | ||
202 | } | ||
203 | |||
204 | void lcd_set_contrast(int val) { | ||
205 | (void) val; | ||
206 | // TODO: | ||
207 | } | ||
208 | |||
209 | void lcd_set_invert_display(bool yesno) { | ||
210 | (void) yesno; | ||
211 | // TODO: | ||
212 | } | ||
213 | |||
214 | void lcd_blit(const fb_data* data, int bx, int y, int bwidth, | ||
215 | int height, int stride) | ||
216 | { | ||
217 | (void) data; | ||
218 | (void) bx; | ||
219 | (void) y; | ||
220 | (void) bwidth; | ||
221 | (void) height; | ||
222 | (void) stride; | ||
223 | //TODO: | ||
224 | } | ||
225 | |||
226 | void lcd_set_flip(bool yesno) { | ||
227 | (void) yesno; | ||
228 | // TODO: | ||
229 | } | ||
230 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-target.h b/firmware/target/arm/imx31/gigabeat-s/lcd-target.h new file mode 100644 index 0000000000..48e304752c --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/lcd-target.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id $ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Greg White | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | //extern void lcd_enable(bool state); | ||
21 | void printscreen(unsigned int colour); | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c b/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c new file mode 100644 index 0000000000..ee86ccc95c --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.c | |||
@@ -0,0 +1,237 @@ | |||
1 | #include <string.h> | ||
2 | #include "mmu-imx31.h" | ||
3 | #include "cpu.h" | ||
4 | |||
5 | static void enable_mmu(void); | ||
6 | static void set_ttb(void); | ||
7 | static void set_page_tables(void); | ||
8 | static void map_section(unsigned int pa, unsigned int va, int mb, int cache_flags); | ||
9 | |||
10 | #define SECTION_ADDRESS_MASK (-1 << 20) | ||
11 | #define CACHE_ALL (1 << 3 | 1 << 2 ) | ||
12 | #define CACHE_NONE 0 | ||
13 | #define BUFFERED (1 << 2) | ||
14 | #define MB (1 << 20) | ||
15 | |||
16 | void memory_init(void) { | ||
17 | set_ttb(); | ||
18 | set_page_tables(); | ||
19 | enable_mmu(); | ||
20 | } | ||
21 | |||
22 | unsigned int* ttb_base = (unsigned int *) TTB_BASE; | ||
23 | const int ttb_size = 4096; | ||
24 | |||
25 | void set_ttb() { | ||
26 | int i; | ||
27 | int* ttbPtr; | ||
28 | int domain_access; | ||
29 | |||
30 | /* must be 16Kb (0x4000) aligned */ | ||
31 | ttb_base = (int*) TTB_BASE; | ||
32 | for (i=0; i<ttb_size; i++,ttbPtr++) | ||
33 | ttbPtr = 0; | ||
34 | asm volatile("mcr p15, 0, %0, c2, c0, 0" : : "r" (ttb_base)); | ||
35 | |||
36 | /* set domain D0 to "client" permission access */ | ||
37 | |||
38 | domain_access = 3; | ||
39 | asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (domain_access)); | ||
40 | |||
41 | } | ||
42 | |||
43 | void set_page_tables() { | ||
44 | |||
45 | map_section(0, 0, 0x1000, CACHE_NONE); /* map every memory region to itself */ | ||
46 | /*This pa *might* change*/ | ||
47 | map_section(0x80000000, 0, 64, CACHE_ALL); /* map RAM to 0 and enable caching for it */ | ||
48 | map_section((int)FRAME1, (int)FRAME1, 1, BUFFERED); /* enable buffered writing for the framebuffer */ | ||
49 | map_section((int)FRAME2, (int)FRAME2, 1, BUFFERED); | ||
50 | } | ||
51 | |||
52 | void map_section(unsigned int pa, unsigned int va, int mb, int cache_flags) { | ||
53 | unsigned int* ttbPtr; | ||
54 | int i; | ||
55 | int section_no; | ||
56 | |||
57 | section_no = va >> 20; /* sections are 1Mb size */ | ||
58 | ttbPtr = ttb_base + section_no; | ||
59 | pa &= SECTION_ADDRESS_MASK; /* align to 1Mb */ | ||
60 | for(i=0; i<mb; i++, pa += MB) { | ||
61 | *(ttbPtr + i) = | ||
62 | pa | | ||
63 | 1 << 10 | /* superuser - r/w, user - no access */ | ||
64 | 0 << 5 | /* domain 0th */ | ||
65 | 1 << 4 | /* should be "1" */ | ||
66 | cache_flags | | ||
67 | 1 << 1; /* Section signature */ | ||
68 | } | ||
69 | } | ||
70 | |||
71 | static void enable_mmu(void) { | ||
72 | int regread; | ||
73 | |||
74 | asm volatile( | ||
75 | "MRC p15, 0, %r0, c1, c0, 0\n" /* Read reg1, control register */ | ||
76 | : /* outputs */ | ||
77 | "=r"(regread) | ||
78 | : /* inputs */ | ||
79 | : /* clobbers */ | ||
80 | "r0" | ||
81 | ); | ||
82 | |||
83 | if ( !(regread & 0x04) || !(regread & 0x00001000) ) /* Was the ICache or DCache Enabled? */ | ||
84 | clean_dcache(); /* If so we need to clean the DCache before invalidating below */ | ||
85 | |||
86 | asm volatile("mov r0, #0\n" | ||
87 | "mcr p15, 0, r0, c8, c7, 0\n" /* invalidate TLB */ | ||
88 | |||
89 | "mcr p15, 0, r0, c7, c7,0\n" /* invalidate both icache and dcache */ | ||
90 | |||
91 | "mrc p15, 0, r0, c1, c0, 0\n" | ||
92 | "orr r0, r0, #1<<0\n" /* enable mmu bit, icache and dcache */ | ||
93 | "orr r0, r0, #1<<2\n" /* enable dcache */ | ||
94 | "orr r0, r0, #1<<12\n" /* enable icache */ | ||
95 | "mcr p15, 0, r0, c1, c0, 0" : : : "r0"); | ||
96 | asm volatile("nop \n nop \n nop \n nop"); | ||
97 | } | ||
98 | |||
99 | /* Invalidate DCache for this range */ | ||
100 | /* Will do write back */ | ||
101 | void invalidate_dcache_range(const void *base, unsigned int size) { | ||
102 | unsigned int addr = (((int) base) & ~31); /* Align start to cache line*/ | ||
103 | unsigned int end = ((addr+size) & ~31)+64; /* Align end to cache line, pad */ | ||
104 | asm volatile( | ||
105 | "inv_start: \n" | ||
106 | "mcr p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ | ||
107 | "add %0, %0, #32 \n" | ||
108 | "cmp %0, %1 \n" | ||
109 | "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ | ||
110 | "addne %0, %0, #32 \n" | ||
111 | "cmpne %0, %1 \n" | ||
112 | "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ | ||
113 | "addne %0, %0, #32 \n" | ||
114 | "cmpne %0, %1 \n" | ||
115 | "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ | ||
116 | "addne %0, %0, #32 \n" | ||
117 | "cmpne %0, %1 \n" | ||
118 | "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ | ||
119 | "addne %0, %0, #32 \n" | ||
120 | "cmpne %0, %1 \n" | ||
121 | "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ | ||
122 | "addne %0, %0, #32 \n" | ||
123 | "cmpne %0, %1 \n" | ||
124 | "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ | ||
125 | "addne %0, %0, #32 \n" | ||
126 | "cmpne %0, %1 \n" | ||
127 | "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */ | ||
128 | "addne %0, %0, #32 \n" | ||
129 | "cmpne %0, %1 \n" | ||
130 | "bne inv_start \n" | ||
131 | "mov %0, #0\n" | ||
132 | "mcr p15,0,%0,c7,c10,4\n" /* Drain write buffer */ | ||
133 | : : "r" (addr), "r" (end)); | ||
134 | } | ||
135 | |||
136 | /* clean DCache for this range */ | ||
137 | /* forces DCache writeback for the specified range */ | ||
138 | void clean_dcache_range(const void *base, unsigned int size) { | ||
139 | unsigned int addr = (int) base; | ||
140 | unsigned int end = addr+size+32; | ||
141 | asm volatile( | ||
142 | "bic %0, %0, #31 \n" | ||
143 | "clean_start: \n" | ||
144 | "mcr p15, 0, %0, c7, c10, 1 \n" /* Clean this line */ | ||
145 | "add %0, %0, #32 \n" | ||
146 | "cmp %0, %1 \n" | ||
147 | "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */ | ||
148 | "addlo %0, %0, #32 \n" | ||
149 | "cmplo %0, %1 \n" | ||
150 | "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */ | ||
151 | "addlo %0, %0, #32 \n" | ||
152 | "cmplo %0, %1 \n" | ||
153 | "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */ | ||
154 | "addlo %0, %0, #32 \n" | ||
155 | "cmplo %0, %1 \n" | ||
156 | "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */ | ||
157 | "addlo %0, %0, #32 \n" | ||
158 | "cmplo %0, %1 \n" | ||
159 | "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */ | ||
160 | "addlo %0, %0, #32 \n" | ||
161 | "cmplo %0, %1 \n" | ||
162 | "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */ | ||
163 | "addlo %0, %0, #32 \n" | ||
164 | "cmplo %0, %1 \n" | ||
165 | "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */ | ||
166 | "addlo %0, %0, #32 \n" | ||
167 | "cmplo %0, %1 \n" | ||
168 | "blo clean_start \n" | ||
169 | "mov %0, #0\n" | ||
170 | "mcr p15,0,%0,c7,c10,4 \n" /* Drain write buffer */ | ||
171 | : : "r" (addr), "r" (end)); | ||
172 | } | ||
173 | |||
174 | /* Dump DCache for this range */ | ||
175 | /* Will *NOT* do write back */ | ||
176 | void dump_dcache_range(const void *base, unsigned int size) { | ||
177 | unsigned int addr = (int) base; | ||
178 | unsigned int end = addr+size; | ||
179 | asm volatile( | ||
180 | "tst %0, #31 \n" /* Check to see if low five bits are set */ | ||
181 | "bic %0, %0, #31 \n" /* Clear them */ | ||
182 | "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line, if those bits were set */ | ||
183 | "add %0, %0, #32 \n" /* Move to the next cache line */ | ||
184 | "tst %1, #31 \n" /* Check last line for bits set */ | ||
185 | "bic %1, %1, #31 \n" /* Clear those bits */ | ||
186 | "mcrne p15, 0, %1, c7, c14, 1 \n" /* Clean and invalidate this line, if not cache aligned */ | ||
187 | "dump_start: \n" | ||
188 | "mcr p15, 0, %0, c7, c6, 1 \n" /* Invalidate this line */ | ||
189 | "add %0, %0, #32 \n" /* Next cache line */ | ||
190 | "cmp %0, %1 \n" | ||
191 | "bne dump_start \n" | ||
192 | "dump_end: \n" | ||
193 | "mcr p15,0,%0,c7,c10,4 \n" /* Drain write buffer */ | ||
194 | : : "r" (addr), "r" (end)); | ||
195 | } | ||
196 | /* Cleans entire DCache */ | ||
197 | void clean_dcache(void) | ||
198 | { | ||
199 | unsigned int index, addr; | ||
200 | |||
201 | for(index = 0; index <= 63; index++) { | ||
202 | addr = (0 << 5) | (index << 26); | ||
203 | asm volatile( | ||
204 | "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ | ||
205 | : : "r" (addr)); | ||
206 | addr = (1 << 5) | (index << 26); | ||
207 | asm volatile( | ||
208 | "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ | ||
209 | : : "r" (addr)); | ||
210 | addr = (2 << 5) | (index << 26); | ||
211 | asm volatile( | ||
212 | "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ | ||
213 | : : "r" (addr)); | ||
214 | addr = (3 << 5) | (index << 26); | ||
215 | asm volatile( | ||
216 | "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ | ||
217 | : : "r" (addr)); | ||
218 | addr = (4 << 5) | (index << 26); | ||
219 | asm volatile( | ||
220 | "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ | ||
221 | : : "r" (addr)); | ||
222 | addr = (5 << 5) | (index << 26); | ||
223 | asm volatile( | ||
224 | "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ | ||
225 | : : "r" (addr)); | ||
226 | addr = (6 << 5) | (index << 26); | ||
227 | asm volatile( | ||
228 | "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ | ||
229 | : : "r" (addr)); | ||
230 | addr = (7 << 5) | (index << 26); | ||
231 | asm volatile( | ||
232 | "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */ | ||
233 | : : "r" (addr)); | ||
234 | } | ||
235 | } | ||
236 | |||
237 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.h b/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.h new file mode 100644 index 0000000000..524978852d --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/mmu-imx31.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006,2007 by Greg White | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | /* Invalidate DCache for this range */ | ||
21 | /* Will do write back */ | ||
22 | void invalidate_dcache_range(const void *base, unsigned int size); | ||
23 | |||
24 | /* clean DCache for this range */ | ||
25 | /* forces DCache writeback for the specified range */ | ||
26 | void clean_dcache_range(const void *base, unsigned int size); | ||
27 | |||
28 | /* Dump DCache for this range */ | ||
29 | /* Will *NOT* do write back */ | ||
30 | void dump_dcache_range(const void *base, unsigned int size); | ||
31 | |||
32 | /* Cleans entire DCache */ | ||
33 | void clean_dcache(void); | ||
34 | |||
35 | void memory_init(void); | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c new file mode 100644 index 0000000000..73bd9fef14 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Michael Sevakis | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include <stdlib.h> | ||
20 | #include "system.h" | ||
21 | #include "kernel.h" | ||
22 | #include "logf.h" | ||
23 | #include "audio.h" | ||
24 | #include "sound.h" | ||
25 | #include "file.h" | ||
26 | #include "mmu-imx31.h" | ||
27 | |||
28 | void fiq_handler(void) __attribute__((naked)); | ||
29 | |||
30 | static void _pcm_apply_settings(void) | ||
31 | { | ||
32 | } | ||
33 | |||
34 | void pcm_apply_settings(void) | ||
35 | { | ||
36 | } | ||
37 | |||
38 | void pcm_init(void) | ||
39 | { | ||
40 | } | ||
41 | |||
42 | void pcm_postinit(void) | ||
43 | { | ||
44 | } | ||
45 | |||
46 | void pcm_play_dma_start(const void *addr, size_t size) | ||
47 | { | ||
48 | (void)addr; | ||
49 | (void)size; | ||
50 | } | ||
51 | |||
52 | static void pcm_play_dma_stop_fiq(void) | ||
53 | { | ||
54 | } | ||
55 | |||
56 | void fiq_handler(void) | ||
57 | { | ||
58 | } | ||
59 | |||
60 | /* Disconnect the DMA and wait for the FIFO to clear */ | ||
61 | void pcm_play_dma_stop(void) | ||
62 | { | ||
63 | } | ||
64 | |||
65 | void pcm_play_pause_pause(void) | ||
66 | { | ||
67 | } | ||
68 | |||
69 | void pcm_play_pause_unpause(void) | ||
70 | { | ||
71 | } | ||
72 | |||
73 | void pcm_set_frequency(unsigned int frequency) | ||
74 | { | ||
75 | (void)frequency; | ||
76 | } | ||
77 | |||
78 | size_t pcm_get_bytes_waiting(void) | ||
79 | { | ||
80 | } | ||
81 | |||
82 | void pcm_mute(bool mute) | ||
83 | { | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * Return playback peaks - Peaks ahead in the DMA buffer based upon the | ||
88 | * calling period to attempt to compensate for | ||
89 | * delay. | ||
90 | */ | ||
91 | void pcm_calculate_peaks(int *left, int *right) | ||
92 | { | ||
93 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/power-imx31.c b/firmware/target/arm/imx31/gigabeat-s/power-imx31.c new file mode 100644 index 0000000000..c739a19cba --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/power-imx31.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "cpu.h" | ||
21 | #include <stdbool.h> | ||
22 | #include "kernel.h" | ||
23 | #include "system.h" | ||
24 | #include "power.h" | ||
25 | #include "pcf50606.h" | ||
26 | #include "backlight.h" | ||
27 | #include "backlight-target.h" | ||
28 | |||
29 | #ifndef SIMULATOR | ||
30 | |||
31 | void power_init(void) | ||
32 | { | ||
33 | } | ||
34 | |||
35 | bool charger_inserted(void) | ||
36 | { | ||
37 | return false; | ||
38 | } | ||
39 | |||
40 | /* Returns true if the unit is charging the batteries. */ | ||
41 | bool charging_state(void) { | ||
42 | return false; | ||
43 | } | ||
44 | |||
45 | void ide_power_enable(bool on) | ||
46 | { | ||
47 | (void)on; | ||
48 | } | ||
49 | |||
50 | bool ide_powered(void) | ||
51 | { | ||
52 | return true; | ||
53 | } | ||
54 | |||
55 | void power_off(void) | ||
56 | { | ||
57 | } | ||
58 | |||
59 | #else /* SIMULATOR */ | ||
60 | |||
61 | bool charger_inserted(void) | ||
62 | { | ||
63 | return false; | ||
64 | } | ||
65 | |||
66 | void charger_enable(bool on) | ||
67 | { | ||
68 | (void)on; | ||
69 | } | ||
70 | |||
71 | void power_off(void) | ||
72 | { | ||
73 | } | ||
74 | |||
75 | void ide_power_enable(bool on) | ||
76 | { | ||
77 | (void)on; | ||
78 | } | ||
79 | |||
80 | #endif /* SIMULATOR */ | ||
81 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c b/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c new file mode 100644 index 0000000000..7441100a7d --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese | ||
11 | * Revisions copyright (C) 2005 by Gerald Van Baren | ||
12 | * | ||
13 | * All files in this archive are subject to the GNU General Public License. | ||
14 | * See the file COPYING in the source tree root for full license agreement. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ****************************************************************************/ | ||
20 | |||
21 | /* FIXME: This is just the Gigabeat F/X file with a different name... */ | ||
22 | |||
23 | #include "config.h" | ||
24 | #include "adc.h" | ||
25 | #include "powermgmt.h" | ||
26 | |||
27 | const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = | ||
28 | { | ||
29 | 3450 | ||
30 | }; | ||
31 | |||
32 | const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = | ||
33 | { | ||
34 | 3400 | ||
35 | }; | ||
36 | |||
37 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ | ||
38 | const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = | ||
39 | { | ||
40 | /* Toshiba Gigabeat Li Ion 830mAH figured from discharge curve */ | ||
41 | { 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 }, | ||
42 | }; | ||
43 | |||
44 | /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ | ||
45 | const unsigned short percent_to_volt_charge[11] = | ||
46 | { | ||
47 | /* Toshiba Gigabeat Li Ion 830mAH */ | ||
48 | 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 | ||
49 | }; | ||
50 | |||
51 | /* ADC[0] is (530) at discharge and 625 at full charge */ | ||
52 | #define BATTERY_SCALE_FACTOR 6605 | ||
53 | /* full-scale ADC readout (2^10) in millivolt */ | ||
54 | |||
55 | /* Returns battery voltage from ADC [millivolts] */ | ||
56 | unsigned int battery_adc_voltage(void) | ||
57 | { | ||
58 | return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10; | ||
59 | } | ||
60 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/serial-imx31.h b/firmware/target/arm/imx31/gigabeat-s/serial-imx31.h new file mode 100644 index 0000000000..62babe0abf --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/serial-imx31.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef SERIAL_IMX31_H | ||
2 | #define SERIAL_IMX31_H | ||
3 | |||
4 | #include <stdarg.h> | ||
5 | #include <stdio.h> | ||
6 | |||
7 | int Tx_Rdy(void); | ||
8 | void Tx_Writec(const char c); | ||
9 | void dprintf(const char * str, ... ); | ||
10 | |||
11 | #endif | ||
12 | |||
diff --git a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c new file mode 100644 index 0000000000..7d6e8efd22 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (c) 2007 Will Robertson | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "cpu.h" | ||
20 | #include "spi-imx31.h" | ||
21 | #include "debug.h" | ||
22 | #include "kernel.h" | ||
23 | |||
24 | /* This is all based on communicating with the MC13783 PMU which is on | ||
25 | * CSPI2 with the chip select at 0. The LCD controller resides on | ||
26 | * CSPI3 cs1, but we have no idea how to communicate to it */ | ||
27 | |||
28 | void spi_init(void) { | ||
29 | CSPI_CONREG2 |= (2 << 20); // Burst will be triggered at SPI_RDY low | ||
30 | CSPI_CONREG2 |= (2 << 16); // Clock = IPG_CLK/16 - we want about 20mhz | ||
31 | CSPI_CONREG2 |= (31 << 8); // All 32 bits are to be transferred | ||
32 | CSPI_CONREG2 |= (1 << 3); // Start burst on TXFIFO write. | ||
33 | CSPI_CONREG2 |= (1 << 1); // Master mode. | ||
34 | CSPI_CONREG2 |= 1; // Enable CSPI2; | ||
35 | } | ||
36 | |||
37 | static int spi_transfer(int address, long data, long* buffer, bool read) { | ||
38 | unsigned long packet = 0; | ||
39 | if(!read) { | ||
40 | /* Set the appropriate bit in the packet to indicate a write */ | ||
41 | packet |= (1<<31); | ||
42 | } | ||
43 | /* Set the address of the packet */ | ||
44 | packet |= (address << 25); | ||
45 | |||
46 | /* Ensure data only occupies 24 bits, then mash the data into the packet */ | ||
47 | data &= ~(DATAMASK); | ||
48 | packet |= data; | ||
49 | |||
50 | /* Wait for some room in TXFIFO */ | ||
51 | while(CSPI_STATREG2 & (1<<2)); | ||
52 | |||
53 | /* Send the packet */ | ||
54 | CSPI_TXDATA2 = packet; | ||
55 | |||
56 | /* Poll the XCH bit to wait for the end of the transfer, with | ||
57 | * a one second timeout */ | ||
58 | int newtick = current_tick + HZ; | ||
59 | while((CSPI_CONREG2 & (1<<2)) && (current_tick < newtick)); | ||
60 | |||
61 | if(newtick > current_tick) { | ||
62 | *buffer = CSPI_RXDATA2; | ||
63 | return 0; | ||
64 | } else { | ||
65 | /* Indicate the fact that the transfer timed out */ | ||
66 | return -1; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | void spi_send(int address, unsigned long data) { | ||
71 | long dummy; | ||
72 | if(spi_transfer(address, data, &dummy, false)) { | ||
73 | DEBUGF("SPI Send timed out"); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | void spi_read(int address, unsigned long* buffer) { | ||
78 | if(spi_transfer(address, 0, buffer, true)) { | ||
79 | DEBUGF("SPI read timed out"); | ||
80 | } | ||
81 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h new file mode 100644 index 0000000000..5f6cfc984f --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (c) 2007 Will Robertson | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #define DATAMASK 0xFF000000 | ||
20 | |||
21 | void spi_init(void); | ||
22 | void spi_send(int address, unsigned long data); | ||
23 | void spi_read(int address, unsigned long* buffer); | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c new file mode 100644 index 0000000000..544ae3afe6 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c | |||
@@ -0,0 +1,93 @@ | |||
1 | #include "kernel.h" | ||
2 | #include "system.h" | ||
3 | #include "panic.h" | ||
4 | #include "mmu-imx31.h" | ||
5 | #include "system-target.h" | ||
6 | #include "lcd.h" | ||
7 | #include "serial-imx31.h" | ||
8 | #include "debug.h" | ||
9 | |||
10 | int system_memory_guard(int newmode) | ||
11 | { | ||
12 | (void)newmode; | ||
13 | return 0; | ||
14 | } | ||
15 | |||
16 | extern void timer4(void); | ||
17 | extern void dma0(void); /* free */ | ||
18 | extern void dma1(void); | ||
19 | extern void dma3(void); | ||
20 | |||
21 | void irq_handler(void) | ||
22 | { | ||
23 | } | ||
24 | |||
25 | #ifdef BOOTLOADER | ||
26 | void fiq_handler(void) | ||
27 | { | ||
28 | } | ||
29 | #endif | ||
30 | |||
31 | void system_reboot(void) | ||
32 | { | ||
33 | } | ||
34 | |||
35 | void system_init(void) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | inline void dumpregs(void) | ||
40 | { | ||
41 | asm volatile ("mov %0,r0\n\t" | ||
42 | "mov %1,r1\n\t" | ||
43 | "mov %2,r2\n\t" | ||
44 | "mov %3,r3": | ||
45 | "=r"(regs.r0),"=r"(regs.r1), | ||
46 | "=r"(regs.r2),"=r"(regs.r3):); | ||
47 | |||
48 | asm volatile ("mov %0,r4\n\t" | ||
49 | "mov %1,r5\n\t" | ||
50 | "mov %2,r6\n\t" | ||
51 | "mov %3,r7": | ||
52 | "=r"(regs.r4),"=r"(regs.r5), | ||
53 | "=r"(regs.r6),"=r"(regs.r7):); | ||
54 | |||
55 | asm volatile ("mov %0,r8\n\t" | ||
56 | "mov %1,r9\n\t" | ||
57 | "mov %2,r10\n\t" | ||
58 | "mov %3,r12": | ||
59 | "=r"(regs.r8),"=r"(regs.r9), | ||
60 | "=r"(regs.r10),"=r"(regs.r11):); | ||
61 | |||
62 | asm volatile ("mov %0,r12\n\t" | ||
63 | "mov %1,sp\n\t" | ||
64 | "mov %2,lr\n\t" | ||
65 | "mov %3,pc\n" | ||
66 | "sub %3,%3,#8": | ||
67 | "=r"(regs.r12),"=r"(regs.sp), | ||
68 | "=r"(regs.lr),"=r"(regs.pc):); | ||
69 | #ifdef HAVE_SERIAL | ||
70 | dprintf("Register Dump :\n"); | ||
71 | dprintf("R0=0x%x\tR1=0x%x\tR2=0x%x\tR3=0x%x\n",regs.r0,regs.r1,regs.r2,regs.r3); | ||
72 | dprintf("R4=0x%x\tR5=0x%x\tR6=0x%x\tR7=0x%x\n",regs.r4,regs.r5,regs.r6,regs.r7); | ||
73 | dprintf("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs.r8,regs.r9,regs.r10,regs.r11); | ||
74 | dprintf("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs.r12,regs.sp,regs.lr,regs.pc); | ||
75 | //dprintf("CPSR=0x%x\t\n",regs.cpsr); | ||
76 | #endif | ||
77 | DEBUGF("Register Dump :\n"); | ||
78 | DEBUGF("R0=0x%x\tR1=0x%x\tR2=0x%x\tR3=0x%x\n",regs.r0,regs.r1,regs.r2,regs.r3); | ||
79 | DEBUGF("R4=0x%x\tR5=0x%x\tR6=0x%x\tR7=0x%x\n",regs.r4,regs.r5,regs.r6,regs.r7); | ||
80 | DEBUGF("R8=0x%x\tR9=0x%x\tR10=0x%x\tR11=0x%x\n",regs.r8,regs.r9,regs.r10,regs.r11); | ||
81 | DEBUGF("R12=0x%x\tSP=0x%x\tLR=0x%x\tPC=0x%x\n",regs.r12,regs.sp,regs.lr,regs.pc); | ||
82 | //DEBUGF("CPSR=0x%x\t\n",regs.cpsr); | ||
83 | |||
84 | } | ||
85 | |||
86 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | ||
87 | |||
88 | void set_cpu_frequency(long frequency) | ||
89 | { | ||
90 | (void)freqency; | ||
91 | } | ||
92 | |||
93 | #endif | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h new file mode 100644 index 0000000000..b1803d01cb --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Greg White | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef SYSTEM_TARGET_H | ||
20 | #define SYSTEM_TARGET_H | ||
21 | |||
22 | #include "mmu-imx31.h" | ||
23 | #include "system-arm.h" | ||
24 | |||
25 | #define CPUFREQ_NORMAL 532000000 | ||
26 | |||
27 | static inline void udelay(unsigned int usecs) | ||
28 | { | ||
29 | volatile signed int stop = EPITCNT1 - usecs; | ||
30 | while (EPITCNT1 > stop); | ||
31 | } | ||
32 | |||
33 | |||
34 | #define HAVE_INVALIDATE_ICACHE | ||
35 | static inline void invalidate_icache(void) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | struct ARM_REGS { | ||
40 | int r0; | ||
41 | int r1; | ||
42 | int r2; | ||
43 | int r3; | ||
44 | int r4; | ||
45 | int r5; | ||
46 | int r6; | ||
47 | int r7; | ||
48 | int r8; | ||
49 | int r9; | ||
50 | int r10; | ||
51 | int r11; | ||
52 | int r12; | ||
53 | int sp; | ||
54 | int lr; | ||
55 | int pc; | ||
56 | int cpsr; | ||
57 | } regs; | ||
58 | |||
59 | inline void dumpregs(void); | ||
60 | |||
61 | #endif /* SYSTEM_TARGET_H */ | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c b/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c new file mode 100644 index 0000000000..94b5c82791 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "cpu.h" | ||
21 | #include "system.h" | ||
22 | #include "kernel.h" | ||
23 | #include "ata.h" | ||
24 | |||
25 | inline int usb_detect(void) | ||
26 | { | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | void usb_init_device(void) | ||
31 | { | ||
32 | } | ||
33 | |||
34 | void usb_enable(bool on) | ||
35 | { | ||
36 | (void)on; | ||
37 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/usb-target.h b/firmware/target/arm/imx31/gigabeat-s/usb-target.h new file mode 100644 index 0000000000..de5bdac52b --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/usb-target.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef USB_TARGET_H | ||
20 | #define USB_TARGET_H | ||
21 | |||
22 | bool usb_init_device(void); | ||
23 | int usb_detect(void); | ||
24 | void usb_enable(bool on); | ||
25 | |||
26 | #endif | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c b/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c new file mode 100644 index 0000000000..238ee3aeb2 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c | |||
@@ -0,0 +1,39 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Gigabeat specific code for the Wolfson codec | ||
11 | * | ||
12 | * Based on code from the ipodlinux project - http://ipodlinux.org/ | ||
13 | * Adapted for Rockbox in December 2005 | ||
14 | * | ||
15 | * Original file: linux/arch/armnommu/mach-ipod/audio.c | ||
16 | * | ||
17 | * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org) | ||
18 | * | ||
19 | * All files in this archive are subject to the GNU General Public License. | ||
20 | * See the file COPYING in the source tree root for full license agreement. | ||
21 | * | ||
22 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
23 | * KIND, either express or implied. | ||
24 | * | ||
25 | ****************************************************************************/ | ||
26 | #include "cpu.h" | ||
27 | #include "kernel.h" | ||
28 | #include "sound.h" | ||
29 | #include "i2c-imx31.h" | ||
30 | |||
31 | void audiohw_init(void) | ||
32 | { | ||
33 | } | ||
34 | |||
35 | void wmcodec_write(int reg, int data) | ||
36 | { | ||
37 | (void)reg; | ||
38 | (void)data; | ||
39 | } | ||