diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | 26 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/avic-imx31.h | 4 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c | 32 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-imx31.c | 14 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-target.h | 14 |
5 files changed, 61 insertions, 29 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c index fa74d3bb9f..b04b22911a 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | |||
@@ -84,18 +84,24 @@ void __attribute__((naked)) fiq_handler(void) | |||
84 | 84 | ||
85 | void avic_init(void) | 85 | void avic_init(void) |
86 | { | 86 | { |
87 | int i; | ||
88 | |||
87 | /* Disable all interrupts and set to unhandled */ | 89 | /* Disable all interrupts and set to unhandled */ |
88 | avic_disable_int(ALL); | 90 | avic_disable_int(ALL); |
89 | 91 | ||
92 | /* Reset AVIC control */ | ||
93 | INTCNTL = 0; | ||
94 | |||
90 | /* Init all interrupts to type IRQ */ | 95 | /* Init all interrupts to type IRQ */ |
91 | avic_set_int_type(ALL, IRQ); | 96 | avic_set_int_type(ALL, IRQ); |
92 | 97 | ||
98 | /* Set all normal to lowest priority */ | ||
99 | for (i = 0; i < 8; i++) | ||
100 | NIPRIORITY(i) = 0; | ||
101 | |||
93 | /* Set NM bit to enable VIC */ | 102 | /* Set NM bit to enable VIC */ |
94 | INTCNTL |= INTCNTL_NM; | 103 | INTCNTL |= INTCNTL_NM; |
95 | 104 | ||
96 | /* Enable IRQ/FIQ in imx31 INTCNTL reg */ | ||
97 | INTCNTL &= ~(INTCNTL_ABFEN | INTCNTL_NIDIS | INTCNTL_FIDIS); | ||
98 | |||
99 | /* Enable VE bit in CP15 Control reg to enable VIC */ | 105 | /* Enable VE bit in CP15 Control reg to enable VIC */ |
100 | asm volatile ( | 106 | asm volatile ( |
101 | "mrc p15, 0, r0, c1, c0, 0 \n" | 107 | "mrc p15, 0, r0, c1, c0, 0 \n" |
@@ -104,11 +110,20 @@ void avic_init(void) | |||
104 | : : : "r0"); | 110 | : : : "r0"); |
105 | 111 | ||
106 | /* Enable normal interrupts at all priorities */ | 112 | /* Enable normal interrupts at all priorities */ |
107 | NIMASK = 16; | 113 | NIMASK = 0x1f; |
114 | } | ||
115 | |||
116 | void avic_set_int_priority(enum IMX31_INT_LIST ints, | ||
117 | unsigned long ni_priority) | ||
118 | { | ||
119 | volatile unsigned long *reg = &NIPRIORITY((63 - ints) / 8); | ||
120 | unsigned int shift = 4*(ints % 8); | ||
121 | unsigned long mask = 0xful << shift; | ||
122 | *reg = (*reg & ~mask) | ((ni_priority << shift) & mask); | ||
108 | } | 123 | } |
109 | 124 | ||
110 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | 125 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, |
111 | void (*handler)(void)) | 126 | unsigned long ni_priority, void (*handler)(void)) |
112 | { | 127 | { |
113 | int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, | 128 | int oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, |
114 | IRQ_FIQ_STATUS); | 129 | IRQ_FIQ_STATUS); |
@@ -118,6 +133,7 @@ void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | |||
118 | avic_set_int_type(ints, intstype); | 133 | avic_set_int_type(ints, intstype); |
119 | VECTOR(ints) = (long)handler; | 134 | VECTOR(ints) = (long)handler; |
120 | INTENNUM = ints; | 135 | INTENNUM = ints; |
136 | avic_set_int_priority(ints, ni_priority); | ||
121 | } | 137 | } |
122 | 138 | ||
123 | set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); | 139 | set_interrupt_status(oldstatus, IRQ_FIQ_STATUS); |
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h index 29a3ec8dd0..7bb7c09da7 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h | |||
@@ -49,7 +49,9 @@ enum IMX31_INT_LIST | |||
49 | 49 | ||
50 | void avic_init(void); | 50 | void avic_init(void); |
51 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | 51 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, |
52 | void (*handler)(void)); | 52 | unsigned long ni_priority, void (*handler)(void)); |
53 | void avic_set_int_priority(enum IMX31_INT_LIST ints, | ||
54 | unsigned long ni_priority); | ||
53 | void avic_disable_int(enum IMX31_INT_LIST ints); | 55 | void avic_disable_int(enum IMX31_INT_LIST ints); |
54 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); | 56 | void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); |
55 | #endif | 57 | #endif |
diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c index 3c44a156b0..c2fddc40a7 100644 --- a/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c | |||
@@ -7,7 +7,6 @@ | |||
7 | 7 | ||
8 | extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); | 8 | extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); |
9 | 9 | ||
10 | #ifndef BOOTLOADER | ||
11 | static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) | 10 | static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) |
12 | { | 11 | { |
13 | int i; | 12 | int i; |
@@ -23,14 +22,11 @@ static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) | |||
23 | 22 | ||
24 | current_tick++; | 23 | current_tick++; |
25 | } | 24 | } |
26 | #endif | ||
27 | 25 | ||
28 | void tick_start(unsigned int interval_in_ms) | 26 | void tick_start(unsigned int interval_in_ms) |
29 | { | 27 | { |
30 | EPITCR1 &= ~(1 << 0); /* Disable the counter */ | 28 | CLKCTL_CGR0 |= (3 << 6); /* EPIT1 module clock ON - before writing regs! */ |
31 | EPITCR1 |= (1 << 16); /* Reset */ | 29 | EPITCR1 &= ~((1 << 2) | (1 << 0)); /* Disable the counter */ |
32 | |||
33 | CLKCTL_CGR0 |= (0x3 << 6); /* Clock ON */ | ||
34 | CLKCTL_WIMR0 &= ~(1 << 23); /* Clear wakeup mask */ | 30 | CLKCTL_WIMR0 &= ~(1 << 23); /* Clear wakeup mask */ |
35 | 31 | ||
36 | /* NOTE: This isn't really accurate yet but it's close enough to work | 32 | /* NOTE: This isn't really accurate yet but it's close enough to work |
@@ -39,17 +35,21 @@ void tick_start(unsigned int interval_in_ms) | |||
39 | /* CLKSRC=32KHz, EPIT Output Disconnected, Enabled | 35 | /* CLKSRC=32KHz, EPIT Output Disconnected, Enabled |
40 | * prescale 1/32, Reload from modulus register, Compare interrupt enabled, | 36 | * prescale 1/32, Reload from modulus register, Compare interrupt enabled, |
41 | * Count from load value */ | 37 | * Count from load value */ |
42 | EPITCR1 = (0x3 << 24) | (1 << 19) | (32 << 4) | | 38 | EPITCR1 = (3 << 24) | (1 << 19) | (32 << 4) | |
43 | (1 << 3) | (1 << 2) | (1 << 1); | 39 | (1 << 3) | (1 << 2) | (1 << 1); |
44 | #ifndef BOOTLOADER | ||
45 | EPITLR1 = interval_in_ms; | ||
46 | EPITCMPR1 = 0; /* Event when counter reaches 0 */ | ||
47 | avic_enable_int(EPIT1, IRQ, EPIT1_HANDLER); | ||
48 | #else | ||
49 | (void)interval_in_ms; | ||
50 | #endif | ||
51 | EPITSR1 = 1; /* Clear any pending interrupt after | ||
52 | enabling the vector */ | ||
53 | 40 | ||
41 | EPITLR1 = interval_in_ms; /* Count down from interval */ | ||
42 | EPITCMPR1 = 0; /* Event when counter reaches 0 */ | ||
43 | EPITSR1 = 1; /* Clear any pending interrupt */ | ||
44 | avic_enable_int(EPIT1, IRQ, 7, EPIT1_HANDLER); | ||
54 | EPITCR1 |= (1 << 0); /* Enable the counter */ | 45 | EPITCR1 |= (1 << 0); /* Enable the counter */ |
55 | } | 46 | } |
47 | |||
48 | #ifdef BOOTLOADER | ||
49 | void tick_stop(void) | ||
50 | { | ||
51 | avic_disable_int(EPIT1); /* Disable insterrupt */ | ||
52 | EPITCR1 &= ~((1 << 2) | (1 << 0)); /* Disable counter */ | ||
53 | CLKCTL_CGR0 &= ~(3 << 6); /* EPIT1 module clock OFF */ | ||
54 | } | ||
55 | #endif | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c index ed5a26cd6e..c77c923d60 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "kernel.h" | 1 | #include "kernel.h" |
2 | #include "system.h" | 2 | #include "system.h" |
3 | #include "panic.h" | 3 | #include "panic.h" |
4 | #include "avic-imx31.h" | ||
4 | #include "mmu-imx31.h" | 5 | #include "mmu-imx31.h" |
5 | #include "system-target.h" | 6 | #include "system-target.h" |
6 | #include "lcd.h" | 7 | #include "lcd.h" |
@@ -19,11 +20,20 @@ void system_reboot(void) | |||
19 | 20 | ||
20 | void system_init(void) | 21 | void system_init(void) |
21 | { | 22 | { |
22 | #ifndef BOOTLOADER | 23 | /* MCR WFI enables wait mode */ |
24 | CLKCTL_CCMR &= ~(3 << 14); | ||
23 | avic_init(); | 25 | avic_init(); |
24 | #endif | ||
25 | } | 26 | } |
26 | 27 | ||
28 | #ifdef BOOTLOADER | ||
29 | void system_prepare_fw_start(void) | ||
30 | { | ||
31 | set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS); | ||
32 | avic_disable_int(ALL); | ||
33 | tick_stop(); | ||
34 | } | ||
35 | #endif | ||
36 | |||
27 | inline void dumpregs(void) | 37 | inline void dumpregs(void) |
28 | { | 38 | { |
29 | asm volatile ("mov %0,r0\n\t" | 39 | asm volatile ("mov %0,r0\n\t" |
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h index 1f7a2475af..327d72b7bc 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h | |||
@@ -33,24 +33,28 @@ static inline void udelay(unsigned int usecs) | |||
33 | #define __dbg_hw_info(...) 0 | 33 | #define __dbg_hw_info(...) 0 |
34 | #define __dbg_ports(...) 0 | 34 | #define __dbg_ports(...) 0 |
35 | 35 | ||
36 | void system_prepare_fw_start(void); | ||
37 | void tick_stop(void); | ||
38 | |||
36 | #define HAVE_INVALIDATE_ICACHE | 39 | #define HAVE_INVALIDATE_ICACHE |
37 | static inline void invalidate_icache(void) | 40 | static inline void invalidate_icache(void) |
38 | { | 41 | { |
39 | long rd = 0; | ||
40 | asm volatile( | 42 | asm volatile( |
41 | "mcr p15, 0, %0, c7, c10, 0 \n" | 43 | /* Clean and invalidate entire data cache */ |
44 | "mcr p15, 0, %0, c7, c14, 0 \n" | ||
45 | /* Invalidate entire instruction cache */ | ||
42 | "mcr p15, 0, %0, c7, c5, 0 \n" | 46 | "mcr p15, 0, %0, c7, c5, 0 \n" |
43 | : : "r"(rd) | 47 | : : "r"(0) |
44 | ); | 48 | ); |
45 | } | 49 | } |
46 | 50 | ||
47 | #define HAVE_FLUSH_ICACHE | 51 | #define HAVE_FLUSH_ICACHE |
48 | static inline void flush_icache(void) | 52 | static inline void flush_icache(void) |
49 | { | 53 | { |
50 | long rd = 0; | ||
51 | asm volatile ( | 54 | asm volatile ( |
55 | /* Clean entire data cache */ | ||
52 | "mcr p15, 0, %0, c7, c10, 0 \n" | 56 | "mcr p15, 0, %0, c7, c10, 0 \n" |
53 | : : "r"(rd) | 57 | : : "r"(0) |
54 | ); | 58 | ); |
55 | } | 59 | } |
56 | 60 | ||