summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/avic-imx31.c26
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/avic-imx31.h4
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/kernel-imx31.c32
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-imx31.c14
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-target.h14
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
85void avic_init(void) 85void 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
116void 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
110void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, 125void 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
50void avic_init(void); 50void avic_init(void);
51void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, 51void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
52 void (*handler)(void)); 52 unsigned long ni_priority, void (*handler)(void));
53void avic_set_int_priority(enum IMX31_INT_LIST ints,
54 unsigned long ni_priority);
53void avic_disable_int(enum IMX31_INT_LIST ints); 55void avic_disable_int(enum IMX31_INT_LIST ints);
54void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype); 56void 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
8extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void); 8extern void (*tick_funcs[MAX_NUM_TICK_TASKS])(void);
9 9
10#ifndef BOOTLOADER
11static __attribute__((interrupt("IRQ"))) void EPIT1_HANDLER(void) 10static __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
28void tick_start(unsigned int interval_in_ms) 26void 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
49void 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
20void system_init(void) 21void 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
29void 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
27inline void dumpregs(void) 37inline 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
36void system_prepare_fw_start(void);
37void tick_stop(void);
38
36#define HAVE_INVALIDATE_ICACHE 39#define HAVE_INVALIDATE_ICACHE
37static inline void invalidate_icache(void) 40static 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
48static inline void flush_icache(void) 52static 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