diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2008-04-27 21:32:10 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2008-04-27 21:32:10 +0000 |
commit | 88451d59c41251794b59dc31d9dfaa1c7e1881eb (patch) | |
tree | 83fe76c94b609508d5f8f0ce6a0f6cde36a9c99c /firmware/target/arm | |
parent | e23ea5d2a9af537c904011b7b81d90a1b1541e2e (diff) | |
download | rockbox-88451d59c41251794b59dc31d9dfaa1c7e1881eb.tar.gz rockbox-88451d59c41251794b59dc31d9dfaa1c7e1881eb.zip |
IMX31: Use template structures to access modules' registers from a base address (as for i2c) which makes drivers look nicer and makes array accesses of registers simpler. Throw in minor fix to fiq_handler dispatcher, otherwise no functional changes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17270 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | 53 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/avic-imx31.h | 151 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/gpio-imx31.c | 38 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/gpio-imx31.h | 11 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/spi-imx31.c | 67 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/spi-imx31.h | 13 |
6 files changed, 252 insertions, 81 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c index 6b64bfad77..ce2932a13f 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c | |||
@@ -74,9 +74,9 @@ void __attribute__((naked)) irq_handler(void) | |||
74 | void __attribute__((naked)) fiq_handler(void) | 74 | void __attribute__((naked)) fiq_handler(void) |
75 | { | 75 | { |
76 | asm volatile ( | 76 | asm volatile ( |
77 | "mov r10, #0x6c000000 \n" /* load AVIC base address */ | 77 | "mov r10, #0x68000000 \n" /* load AVIC base address */ |
78 | "ldr r9, [r10, #0x44] \n" /* read FIVECSR of AVIC */ | 78 | "ldr r9, [r10, #0x44] \n" /* read FIVECSR of AVIC */ |
79 | "add r10, r10, #100 \n" /* move pointer to base of VECTOR table */ | 79 | "add r10, r10, #0x100 \n" /* move pointer to base of VECTOR table */ |
80 | "ldr r8, [r10, r9, lsl #2] \n" /* read FIQ vector from VECTOR table */ | 80 | "ldr r8, [r10, r9, lsl #2] \n" /* read FIQ vector from VECTOR table */ |
81 | "bx r8 \n" /* jump to FIQ service routine */ | 81 | "bx r8 \n" /* jump to FIQ service routine */ |
82 | ); | 82 | ); |
@@ -84,23 +84,24 @@ void __attribute__((naked)) fiq_handler(void) | |||
84 | 84 | ||
85 | void avic_init(void) | 85 | void avic_init(void) |
86 | { | 86 | { |
87 | struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; | ||
87 | int i; | 88 | int i; |
88 | 89 | ||
89 | /* Disable all interrupts and set to unhandled */ | 90 | /* Disable all interrupts and set to unhandled */ |
90 | avic_disable_int(ALL); | 91 | avic_disable_int(ALL); |
91 | 92 | ||
92 | /* Reset AVIC control */ | 93 | /* Reset AVIC control */ |
93 | INTCNTL = 0; | 94 | avic->intcntl = 0; |
94 | 95 | ||
95 | /* Init all interrupts to type IRQ */ | 96 | /* Init all interrupts to type IRQ */ |
96 | avic_set_int_type(ALL, IRQ); | 97 | avic_set_int_type(ALL, IRQ); |
97 | 98 | ||
98 | /* Set all normal to lowest priority */ | 99 | /* Set all normal to lowest priority */ |
99 | for (i = 0; i < 8; i++) | 100 | for (i = 0; i < 8; i++) |
100 | NIPRIORITY(i) = 0; | 101 | avic->nipriority[i] = 0; |
101 | 102 | ||
102 | /* Set NM bit to enable VIC */ | 103 | /* Set NM bit to enable VIC */ |
103 | INTCNTL |= INTCNTL_NM; | 104 | avic->intcntl |= INTCNTL_NM; |
104 | 105 | ||
105 | /* Enable VE bit in CP15 Control reg to enable VIC */ | 106 | /* Enable VE bit in CP15 Control reg to enable VIC */ |
106 | asm volatile ( | 107 | asm volatile ( |
@@ -110,28 +111,30 @@ void avic_init(void) | |||
110 | : : : "r0"); | 111 | : : : "r0"); |
111 | 112 | ||
112 | /* Enable normal interrupts at all priorities */ | 113 | /* Enable normal interrupts at all priorities */ |
113 | NIMASK = 0x1f; | 114 | avic->nimask = 0x1f; |
114 | } | 115 | } |
115 | 116 | ||
116 | void avic_set_int_priority(enum IMX31_INT_LIST ints, | 117 | void avic_set_int_priority(enum IMX31_INT_LIST ints, |
117 | unsigned long ni_priority) | 118 | unsigned long ni_priority) |
118 | { | 119 | { |
119 | volatile unsigned long *reg = &NIPRIORITY((63 - ints) / 8); | 120 | struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; |
120 | unsigned int shift = 4*(ints % 8); | 121 | volatile uint32_t *reg = &avic->nipriority[7 - (ints >> 3)]; |
121 | unsigned long mask = 0xful << shift; | 122 | unsigned int shift = (ints & 0x7) << 2; |
123 | uint32_t mask = 0xful << shift; | ||
122 | *reg = (*reg & ~mask) | ((ni_priority << shift) & mask); | 124 | *reg = (*reg & ~mask) | ((ni_priority << shift) & mask); |
123 | } | 125 | } |
124 | 126 | ||
125 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | 127 | void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, |
126 | unsigned long ni_priority, void (*handler)(void)) | 128 | unsigned long ni_priority, void (*handler)(void)) |
127 | { | 129 | { |
130 | struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; | ||
128 | int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); | 131 | int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); |
129 | 132 | ||
130 | if (ints != ALL) /* No mass-enable allowed */ | 133 | if (ints != ALL) /* No mass-enable allowed */ |
131 | { | 134 | { |
132 | avic_set_int_type(ints, intstype); | 135 | avic_set_int_type(ints, intstype); |
133 | VECTOR(ints) = (long)handler; | 136 | avic->vector[ints] = (long)handler; |
134 | INTENNUM = ints; | 137 | avic->intennum = ints; |
135 | avic_set_int_priority(ints, ni_priority); | 138 | avic_set_int_priority(ints, ni_priority); |
136 | } | 139 | } |
137 | 140 | ||
@@ -140,38 +143,30 @@ void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype, | |||
140 | 143 | ||
141 | void avic_disable_int(enum IMX31_INT_LIST ints) | 144 | void avic_disable_int(enum IMX31_INT_LIST ints) |
142 | { | 145 | { |
143 | long i; | 146 | struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; |
147 | uint32_t i; | ||
144 | 148 | ||
145 | if (ints == ALL) | 149 | if (ints == ALL) |
146 | { | 150 | { |
147 | for (i = 0; i < 64; i++) | 151 | for (i = 0; i < 64; i++) |
148 | { | 152 | { |
149 | INTDISNUM = i; | 153 | avic->intdisnum = i; |
150 | VECTOR(i) = (long)UIE_VECTOR; | 154 | avic->vector[i] = (long)UIE_VECTOR; |
151 | } | 155 | } |
152 | } | 156 | } |
153 | else | 157 | else |
154 | { | 158 | { |
155 | INTDISNUM = ints; | 159 | avic->intdisnum = ints; |
156 | VECTOR(ints) = (long)UIE_VECTOR; | 160 | avic->vector[ints] = (long)UIE_VECTOR; |
157 | } | 161 | } |
158 | } | 162 | } |
159 | 163 | ||
160 | static void set_int_type(int i, enum INT_TYPE intstype) | 164 | static void set_int_type(int i, enum INT_TYPE intstype) |
161 | { | 165 | { |
162 | volatile unsigned long *reg; | 166 | /* INTTYPEH: vectors 63-32, INTTYPEL: vectors 31-0 */ |
163 | long val; | 167 | struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR; |
164 | 168 | volatile uint32_t *reg = &avic->inttype[1 - (i >> 5)]; | |
165 | if (i >= 32) | 169 | uint32_t val = 1L << (i & 0x1f); |
166 | { | ||
167 | reg = &INTTYPEH; | ||
168 | val = 1L << (i - 32); | ||
169 | } | ||
170 | else | ||
171 | { | ||
172 | reg = &INTTYPEL; | ||
173 | val = 1L << i; | ||
174 | } | ||
175 | 170 | ||
176 | if (intstype == IRQ) | 171 | if (intstype == IRQ) |
177 | val = *reg & ~val; | 172 | val = *reg & ~val; |
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h index 7bb7c09da7..a2e1b3496d 100644 --- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h +++ b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.h | |||
@@ -19,6 +19,157 @@ | |||
19 | #ifndef AVIC_IMX31_H | 19 | #ifndef AVIC_IMX31_H |
20 | #define AVIC_IMX31_H | 20 | #define AVIC_IMX31_H |
21 | 21 | ||
22 | struct avic_map | ||
23 | { | ||
24 | volatile uint32_t intcntl; /* 00h */ | ||
25 | volatile uint32_t nimask; /* 04h */ | ||
26 | volatile uint32_t intennum; /* 08h */ | ||
27 | volatile uint32_t intdisnum; /* 0Ch */ | ||
28 | union /* 10h */ | ||
29 | { | ||
30 | struct | ||
31 | { | ||
32 | volatile uint32_t intenableh; /* 10h */ | ||
33 | volatile uint32_t intenablel; /* 14h */ | ||
34 | }; | ||
35 | volatile uint32_t intenable[2]; /* H,L */ | ||
36 | }; | ||
37 | union | ||
38 | { | ||
39 | struct | ||
40 | { | ||
41 | volatile uint32_t inttypeh; /* 18h */ | ||
42 | volatile uint32_t inttypel; /* 1Ch */ | ||
43 | }; | ||
44 | volatile uint32_t inttype[2]; /* H,L */ | ||
45 | }; | ||
46 | union | ||
47 | { | ||
48 | struct | ||
49 | { | ||
50 | volatile uint32_t nipriority7; /* 20h */ | ||
51 | volatile uint32_t nipriority6; /* 24h */ | ||
52 | volatile uint32_t nipriority5; /* 28h */ | ||
53 | volatile uint32_t nipriority4; /* 2Ch */ | ||
54 | volatile uint32_t nipriority3; /* 30h */ | ||
55 | volatile uint32_t nipriority2; /* 34h */ | ||
56 | volatile uint32_t nipriority1; /* 38h */ | ||
57 | volatile uint32_t nipriority0; /* 3Ch */ | ||
58 | }; | ||
59 | volatile uint32_t nipriority[8]; /* 7-0 */ | ||
60 | }; | ||
61 | volatile uint32_t nivecsr; /* 40h */ | ||
62 | volatile uint32_t fivecsr; /* 44h */ | ||
63 | union | ||
64 | { | ||
65 | struct | ||
66 | { | ||
67 | volatile uint32_t intsrch; /* 48h */ | ||
68 | volatile uint32_t intsrcl; /* 4Ch */ | ||
69 | }; | ||
70 | volatile uint32_t intsrc[2]; /* H,L */ | ||
71 | }; | ||
72 | union | ||
73 | { | ||
74 | struct | ||
75 | { | ||
76 | volatile uint32_t intfrch; /* 50h */ | ||
77 | volatile uint32_t intfrcl; /* 54h */ | ||
78 | }; | ||
79 | volatile uint32_t intfrc[2]; /* H,L */ | ||
80 | }; | ||
81 | union | ||
82 | { | ||
83 | struct | ||
84 | { | ||
85 | volatile uint32_t nipndh; /* 58h */ | ||
86 | volatile uint32_t nipndl; /* 5Ch */ | ||
87 | }; | ||
88 | volatile uint32_t nipnd[2]; /* H,L */ | ||
89 | }; | ||
90 | union | ||
91 | { | ||
92 | struct | ||
93 | { | ||
94 | volatile uint32_t fipndh; /* 60h */ | ||
95 | volatile uint32_t fipndl; /* 64h */ | ||
96 | }; | ||
97 | volatile uint32_t fipnd[2]; /* H,L */ | ||
98 | }; | ||
99 | volatile uint32_t skip1[0x26]; /* 68h */ | ||
100 | union /* 100h */ | ||
101 | { | ||
102 | struct | ||
103 | { | ||
104 | volatile uint32_t reserved0; | ||
105 | volatile uint32_t reserved1; | ||
106 | volatile uint32_t reserved2; | ||
107 | volatile uint32_t i2c3; | ||
108 | volatile uint32_t i2c2; | ||
109 | volatile uint32_t mpeg4encoder; | ||
110 | volatile uint32_t rtic; | ||
111 | volatile uint32_t fir; | ||
112 | volatile uint32_t mmc_sdhc2; | ||
113 | volatile uint32_t mmc_sdhc1; | ||
114 | volatile uint32_t i2c1; | ||
115 | volatile uint32_t ssi2; | ||
116 | volatile uint32_t ssi1; | ||
117 | volatile uint32_t cspi2; | ||
118 | volatile uint32_t cspi1; | ||
119 | volatile uint32_t ata; | ||
120 | volatile uint32_t mbx; | ||
121 | volatile uint32_t cspi3; | ||
122 | volatile uint32_t uart3; | ||
123 | volatile uint32_t iim; | ||
124 | volatile uint32_t sim1; | ||
125 | volatile uint32_t sim2; | ||
126 | volatile uint32_t rnga; | ||
127 | volatile uint32_t evtmon; | ||
128 | volatile uint32_t kpp; | ||
129 | volatile uint32_t rtc; | ||
130 | volatile uint32_t pwn; | ||
131 | volatile uint32_t epit2; | ||
132 | volatile uint32_t epit1; | ||
133 | volatile uint32_t gpt; | ||
134 | volatile uint32_t pwr_fail; | ||
135 | volatile uint32_t ccm_dvfs; | ||
136 | volatile uint32_t uart2; | ||
137 | volatile uint32_t nandfc; | ||
138 | volatile uint32_t sdma; | ||
139 | volatile uint32_t usb_host1; | ||
140 | volatile uint32_t usb_host2; | ||
141 | volatile uint32_t usb_otg; | ||
142 | volatile uint32_t reserved3; | ||
143 | volatile uint32_t mshc1; | ||
144 | volatile uint32_t mshc2; | ||
145 | volatile uint32_t ipu_err; | ||
146 | volatile uint32_t ipu; | ||
147 | volatile uint32_t reserved4; | ||
148 | volatile uint32_t reserved5; | ||
149 | volatile uint32_t uart1; | ||
150 | volatile uint32_t uart4; | ||
151 | volatile uint32_t uart5; | ||
152 | volatile uint32_t etc_irq; | ||
153 | volatile uint32_t scc_scm; | ||
154 | volatile uint32_t scc_smn; | ||
155 | volatile uint32_t gpio2; | ||
156 | volatile uint32_t gpio1; | ||
157 | volatile uint32_t ccm_clk; | ||
158 | volatile uint32_t pcmcia; | ||
159 | volatile uint32_t wdog; | ||
160 | volatile uint32_t gpio3; | ||
161 | volatile uint32_t reserved6; | ||
162 | volatile uint32_t ext_pwmg; | ||
163 | volatile uint32_t ext_temp; | ||
164 | volatile uint32_t ext_sense1; | ||
165 | volatile uint32_t ext_sense2; | ||
166 | volatile uint32_t ext_wdog; | ||
167 | volatile uint32_t ext_tv; | ||
168 | }; | ||
169 | volatile uint32_t vector[0x40]; /* 100h */ | ||
170 | }; | ||
171 | }; | ||
172 | |||
22 | enum INT_TYPE | 173 | enum INT_TYPE |
23 | { | 174 | { |
24 | IRQ = 0, | 175 | IRQ = 0, |
diff --git a/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.c b/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.c index a7427f16c0..0b76b84d36 100644 --- a/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.c | |||
@@ -44,7 +44,7 @@ extern const struct gpio_event_list gpio3_event_list; | |||
44 | 44 | ||
45 | static struct gpio_module_descriptor | 45 | static struct gpio_module_descriptor |
46 | { | 46 | { |
47 | volatile unsigned long *base; /* Module base address */ | 47 | struct gpio_map * const base; /* Module base address */ |
48 | enum IMX31_INT_LIST ints; /* AVIC int number */ | 48 | enum IMX31_INT_LIST ints; /* AVIC int number */ |
49 | void (*handler)(void); /* Interrupt function */ | 49 | void (*handler)(void); /* Interrupt function */ |
50 | const struct gpio_event_list *list; /* Event handler list */ | 50 | const struct gpio_event_list *list; /* Event handler list */ |
@@ -52,21 +52,21 @@ static struct gpio_module_descriptor | |||
52 | { | 52 | { |
53 | #if (GPIO_EVENT_MASK & USE_GPIO1_EVENTS) | 53 | #if (GPIO_EVENT_MASK & USE_GPIO1_EVENTS) |
54 | { | 54 | { |
55 | .base = (unsigned long *)GPIO1_BASE_ADDR, | 55 | .base = (struct gpio_map *)GPIO1_BASE_ADDR, |
56 | .ints = GPIO1, | 56 | .ints = GPIO1, |
57 | .handler = GPIO1_HANDLER, | 57 | .handler = GPIO1_HANDLER, |
58 | }, | 58 | }, |
59 | #endif | 59 | #endif |
60 | #if (GPIO_EVENT_MASK & USE_GPIO2_EVENTS) | 60 | #if (GPIO_EVENT_MASK & USE_GPIO2_EVENTS) |
61 | { | 61 | { |
62 | .base = (unsigned long *)GPIO2_BASE_ADDR, | 62 | .base = (struct gpio_map *)GPIO2_BASE_ADDR, |
63 | .ints = GPIO2, | 63 | .ints = GPIO2, |
64 | .handler = GPIO2_HANDLER, | 64 | .handler = GPIO2_HANDLER, |
65 | }, | 65 | }, |
66 | #endif | 66 | #endif |
67 | #if (GPIO_EVENT_MASK & USE_GPIO3_EVENTS) | 67 | #if (GPIO_EVENT_MASK & USE_GPIO3_EVENTS) |
68 | { | 68 | { |
69 | .base = (unsigned long *)GPIO3_BASE_ADDR, | 69 | .base = (struct gpio_map *)GPIO3_BASE_ADDR, |
70 | .ints = GPIO3, | 70 | .ints = GPIO3, |
71 | .handler = GPIO3_HANDLER, | 71 | .handler = GPIO3_HANDLER, |
72 | }, | 72 | }, |
@@ -77,17 +77,17 @@ static void gpio_call_events(enum gpio_module_number gpio) | |||
77 | { | 77 | { |
78 | const struct gpio_module_descriptor * const desc = &gpio_descs[gpio]; | 78 | const struct gpio_module_descriptor * const desc = &gpio_descs[gpio]; |
79 | const struct gpio_event_list * const list = desc->list; | 79 | const struct gpio_event_list * const list = desc->list; |
80 | volatile unsigned long * const base = desc->base; | 80 | struct gpio_map * const base = desc->base; |
81 | unsigned i; | 81 | unsigned i; |
82 | 82 | ||
83 | /* Intersect pending and unmasked bits */ | 83 | /* Intersect pending and unmasked bits */ |
84 | unsigned long pending = base[GPIO_ISR_I] & base[GPIO_IMR_I]; | 84 | uint32_t pending = base->isr & base->imr; |
85 | 85 | ||
86 | /* Call each event handler in order */ | 86 | /* Call each event handler in order */ |
87 | for (i = 0; i < list->count; i++) | 87 | for (i = 0; i < list->count; i++) |
88 | { | 88 | { |
89 | const struct gpio_event * const event = &list->events[i]; | 89 | const struct gpio_event * const event = &list->events[i]; |
90 | unsigned long bit = 1ul << event->line; | 90 | uint32_t bit = 1ul << event->line; |
91 | 91 | ||
92 | if ((pending & bit) && event->callback()) | 92 | if ((pending & bit) && event->callback()) |
93 | pending &= ~bit; | 93 | pending &= ~bit; |
@@ -144,10 +144,10 @@ bool gpio_enable_event(enum gpio_module_number gpio, unsigned id) | |||
144 | { | 144 | { |
145 | const struct gpio_module_descriptor * const desc = &gpio_descs[gpio]; | 145 | const struct gpio_module_descriptor * const desc = &gpio_descs[gpio]; |
146 | const struct gpio_event * const event = &desc->list->events[id]; | 146 | const struct gpio_event * const event = &desc->list->events[id]; |
147 | volatile unsigned long * const base = desc->base; | 147 | struct gpio_map * const base = desc->base; |
148 | volatile unsigned long * icr; | 148 | volatile uint32_t *icr; |
149 | unsigned long mask; | 149 | uint32_t mask; |
150 | unsigned long imr; | 150 | uint32_t imr; |
151 | int shift; | 151 | int shift; |
152 | 152 | ||
153 | if (id >= desc->list->count) | 153 | if (id >= desc->list->count) |
@@ -155,7 +155,7 @@ bool gpio_enable_event(enum gpio_module_number gpio, unsigned id) | |||
155 | 155 | ||
156 | int oldlevel = disable_irq_save(); | 156 | int oldlevel = disable_irq_save(); |
157 | 157 | ||
158 | imr = base[GPIO_IMR_I]; | 158 | imr = base->imr; |
159 | 159 | ||
160 | if (imr == 0) | 160 | if (imr == 0) |
161 | { | 161 | { |
@@ -165,14 +165,14 @@ bool gpio_enable_event(enum gpio_module_number gpio, unsigned id) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | /* Set the line sense */ | 167 | /* Set the line sense */ |
168 | icr = &base[GPIO_ICR1_I] + event->line / 16; | 168 | icr = &base->icr[event->line >> 4]; |
169 | shift = 2*(event->line % 16); | 169 | shift = (event->line & 15) << 1; |
170 | mask = GPIO_SENSE_CONFIG_MASK << shift; | 170 | mask = GPIO_SENSE_CONFIG_MASK << shift; |
171 | 171 | ||
172 | *icr = (*icr & ~mask) | ((event->sense << shift) & mask); | 172 | *icr = (*icr & ~mask) | ((event->sense << shift) & mask); |
173 | 173 | ||
174 | /* Unmask the line */ | 174 | /* Unmask the line */ |
175 | base[GPIO_IMR_I] = imr | (1ul << event->line); | 175 | base->imr = imr | (1ul << event->line); |
176 | 176 | ||
177 | restore_irq(oldlevel); | 177 | restore_irq(oldlevel); |
178 | 178 | ||
@@ -183,8 +183,8 @@ void gpio_disable_event(enum gpio_module_number gpio, unsigned id) | |||
183 | { | 183 | { |
184 | const struct gpio_module_descriptor * const desc = &gpio_descs[gpio]; | 184 | const struct gpio_module_descriptor * const desc = &gpio_descs[gpio]; |
185 | const struct gpio_event * const event = &desc->list->events[id]; | 185 | const struct gpio_event * const event = &desc->list->events[id]; |
186 | volatile unsigned long * const base = desc->base; | 186 | struct gpio_map * const base = desc->base; |
187 | unsigned long imr; | 187 | uint32_t imr; |
188 | 188 | ||
189 | if (id >= desc->list->count) | 189 | if (id >= desc->list->count) |
190 | return; | 190 | return; |
@@ -192,10 +192,10 @@ void gpio_disable_event(enum gpio_module_number gpio, unsigned id) | |||
192 | int oldlevel = disable_irq_save(); | 192 | int oldlevel = disable_irq_save(); |
193 | 193 | ||
194 | /* Remove bit from mask */ | 194 | /* Remove bit from mask */ |
195 | imr = base[GPIO_IMR_I] & ~(1ul << event->line); | 195 | imr = base->imr & ~(1ul << event->line); |
196 | 196 | ||
197 | /* Mask the line */ | 197 | /* Mask the line */ |
198 | base[GPIO_IMR_I] = imr; | 198 | base->imr = imr; |
199 | 199 | ||
200 | if (imr == 0) | 200 | if (imr == 0) |
201 | { | 201 | { |
diff --git a/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.h b/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.h index a197558ad4..f6e07309e5 100644 --- a/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.h +++ b/firmware/target/arm/imx31/gigabeat-s/gpio-imx31.h | |||
@@ -51,6 +51,17 @@ enum gpio_int_sense_enum | |||
51 | 51 | ||
52 | #define GPIO_SENSE_CONFIG_MASK 0x3 | 52 | #define GPIO_SENSE_CONFIG_MASK 0x3 |
53 | 53 | ||
54 | /* Register map for each module */ | ||
55 | struct gpio_map | ||
56 | { | ||
57 | volatile uint32_t dr; /* 00h */ | ||
58 | volatile uint32_t gdir; /* 04h */ | ||
59 | volatile uint32_t psr; /* 08h */ | ||
60 | volatile uint32_t icr[2]; /* 0Ch */ | ||
61 | volatile uint32_t imr; /* 14h */ | ||
62 | volatile uint32_t isr; /* 18h */ | ||
63 | }; | ||
64 | |||
54 | /* Pending events will be called in array order */ | 65 | /* Pending events will be called in array order */ |
55 | 66 | ||
56 | /* Describes a single event for a pin */ | 67 | /* Describes a single event for a pin */ |
diff --git a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c index bcbe85a76b..415511e7c7 100644 --- a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.c | |||
@@ -16,7 +16,8 @@ | |||
16 | * KIND, either express or implied. | 16 | * KIND, either express or implied. |
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | #include "cpu.h" | 19 | #include "config.h" |
20 | #include "system.h" | ||
20 | #include "spi-imx31.h" | 21 | #include "spi-imx31.h" |
21 | #include "avic-imx31.h" | 22 | #include "avic-imx31.h" |
22 | #include "clkctl-imx31.h" | 23 | #include "clkctl-imx31.h" |
@@ -37,7 +38,7 @@ static __attribute__((interrupt("IRQ"))) void CSPI3_HANDLER(void); | |||
37 | /* State data associatated with each CSPI module */ | 38 | /* State data associatated with each CSPI module */ |
38 | static struct spi_module_descriptor | 39 | static struct spi_module_descriptor |
39 | { | 40 | { |
40 | volatile unsigned long *base; | 41 | struct cspi_map * const base; |
41 | int enab; | 42 | int enab; |
42 | struct spi_node *last; | 43 | struct spi_node *last; |
43 | enum IMX31_CG_LIST cg; | 44 | enum IMX31_CG_LIST cg; |
@@ -53,7 +54,7 @@ static struct spi_module_descriptor | |||
53 | { | 54 | { |
54 | #if (SPI_MODULE_MASK & USE_CSPI1_MODULE) | 55 | #if (SPI_MODULE_MASK & USE_CSPI1_MODULE) |
55 | { | 56 | { |
56 | .base = (unsigned long *)CSPI1_BASE_ADDR, | 57 | .base = (struct cspi_map *)CSPI1_BASE_ADDR, |
57 | .cg = CG_CSPI1, | 58 | .cg = CG_CSPI1, |
58 | .ints = CSPI1, | 59 | .ints = CSPI1, |
59 | .handler = CSPI1_HANDLER, | 60 | .handler = CSPI1_HANDLER, |
@@ -61,7 +62,7 @@ static struct spi_module_descriptor | |||
61 | #endif | 62 | #endif |
62 | #if (SPI_MODULE_MASK & USE_CSPI2_MODULE) | 63 | #if (SPI_MODULE_MASK & USE_CSPI2_MODULE) |
63 | { | 64 | { |
64 | .base = (unsigned long *)CSPI2_BASE_ADDR, | 65 | .base = (struct cspi_map *)CSPI2_BASE_ADDR, |
65 | .cg = CG_CSPI2, | 66 | .cg = CG_CSPI2, |
66 | .ints = CSPI2, | 67 | .ints = CSPI2, |
67 | .handler = CSPI2_HANDLER, | 68 | .handler = CSPI2_HANDLER, |
@@ -69,7 +70,7 @@ static struct spi_module_descriptor | |||
69 | #endif | 70 | #endif |
70 | #if (SPI_MODULE_MASK & USE_CSPI3_MODULE) | 71 | #if (SPI_MODULE_MASK & USE_CSPI3_MODULE) |
71 | { | 72 | { |
72 | .base = (unsigned long *)CSPI3_BASE_ADDR, | 73 | .base = (struct cspi_map *)CSPI3_BASE_ADDR, |
73 | .cg = CG_CSPI3, | 74 | .cg = CG_CSPI3, |
74 | .ints = CSPI3, | 75 | .ints = CSPI3, |
75 | .handler = CSPI3_HANDLER, | 76 | .handler = CSPI3_HANDLER, |
@@ -81,16 +82,16 @@ static struct spi_module_descriptor | |||
81 | static void spi_interrupt(enum spi_module_number spi) | 82 | static void spi_interrupt(enum spi_module_number spi) |
82 | { | 83 | { |
83 | struct spi_module_descriptor *desc = &spi_descs[spi]; | 84 | struct spi_module_descriptor *desc = &spi_descs[spi]; |
84 | volatile unsigned long * const base = desc->base; | 85 | struct cspi_map * const base = desc->base; |
85 | struct spi_transfer *trans = desc->trans; | 86 | struct spi_transfer *trans = desc->trans; |
86 | int inc = desc->byte_size + 1; | 87 | int inc = desc->byte_size + 1; |
87 | 88 | ||
88 | if (desc->rxcount > 0) | 89 | if (desc->rxcount > 0) |
89 | { | 90 | { |
90 | /* Data received - empty out RXFIFO */ | 91 | /* Data received - empty out RXFIFO */ |
91 | while ((base[CSPI_STATREG_I] & CSPI_STATREG_RR) != 0) | 92 | while ((base->statreg & CSPI_STATREG_RR) != 0) |
92 | { | 93 | { |
93 | uint32_t word = base[CSPI_RXDATA_I]; | 94 | uint32_t word = base->rxdata; |
94 | 95 | ||
95 | switch (desc->byte_size & 3) | 96 | switch (desc->byte_size & 3) |
96 | { | 97 | { |
@@ -108,20 +109,20 @@ static void spi_interrupt(enum spi_module_number spi) | |||
108 | 109 | ||
109 | if (--desc->rxcount < 4) | 110 | if (--desc->rxcount < 4) |
110 | { | 111 | { |
111 | unsigned long intreg = base[CSPI_INTREG_I]; | 112 | unsigned long intreg = base->intreg; |
112 | 113 | ||
113 | if (desc->rxcount <= 0) | 114 | if (desc->rxcount <= 0) |
114 | { | 115 | { |
115 | /* No more to receive - stop RX interrupts */ | 116 | /* No more to receive - stop RX interrupts */ |
116 | intreg &= ~(CSPI_INTREG_RHEN | CSPI_INTREG_RREN); | 117 | intreg &= ~(CSPI_INTREG_RHEN | CSPI_INTREG_RREN); |
117 | base[CSPI_INTREG_I] = intreg; | 118 | base->intreg = intreg; |
118 | break; | 119 | break; |
119 | } | 120 | } |
120 | else if (!(intreg & CSPI_INTREG_RREN)) | 121 | else if (!(intreg & CSPI_INTREG_RREN)) |
121 | { | 122 | { |
122 | /* < 4 words expected - switch to RX ready */ | 123 | /* < 4 words expected - switch to RX ready */ |
123 | intreg &= ~CSPI_INTREG_RHEN; | 124 | intreg &= ~CSPI_INTREG_RHEN; |
124 | base[CSPI_INTREG_I] = intreg | CSPI_INTREG_RREN; | 125 | base->intreg = intreg | CSPI_INTREG_RREN; |
125 | } | 126 | } |
126 | } | 127 | } |
127 | } | 128 | } |
@@ -130,7 +131,7 @@ static void spi_interrupt(enum spi_module_number spi) | |||
130 | if (trans->count > 0) | 131 | if (trans->count > 0) |
131 | { | 132 | { |
132 | /* Data to transmit - fill TXFIFO or write until exhausted */ | 133 | /* Data to transmit - fill TXFIFO or write until exhausted */ |
133 | while ((base[CSPI_STATREG_I] & CSPI_STATREG_TF) == 0) | 134 | while ((base->statreg & CSPI_STATREG_TF) == 0) |
134 | { | 135 | { |
135 | uint32_t word = 0; | 136 | uint32_t word = 0; |
136 | 137 | ||
@@ -148,21 +149,21 @@ static void spi_interrupt(enum spi_module_number spi) | |||
148 | 149 | ||
149 | trans->txbuf += inc; | 150 | trans->txbuf += inc; |
150 | 151 | ||
151 | base[CSPI_TXDATA_I] = word; | 152 | base->txdata = word; |
152 | 153 | ||
153 | if (--trans->count <= 0) | 154 | if (--trans->count <= 0) |
154 | { | 155 | { |
155 | /* Out of data - stop TX interrupts */ | 156 | /* Out of data - stop TX interrupts */ |
156 | base[CSPI_INTREG_I] &= ~CSPI_INTREG_THEN; | 157 | base->intreg &= ~CSPI_INTREG_THEN; |
157 | break; | 158 | break; |
158 | } | 159 | } |
159 | } | 160 | } |
160 | } | 161 | } |
161 | 162 | ||
162 | /* If all interrupts have been remasked - we're done */ | 163 | /* If all interrupts have been remasked - we're done */ |
163 | if (base[CSPI_INTREG_I] == 0) | 164 | if (base->intreg == 0) |
164 | { | 165 | { |
165 | base[CSPI_STATREG_I] = CSPI_STATREG_TC | CSPI_STATREG_BO; | 166 | base->statreg = CSPI_STATREG_TC | CSPI_STATREG_BO; |
166 | wakeup_signal(&desc->w); | 167 | wakeup_signal(&desc->w); |
167 | } | 168 | } |
168 | } | 169 | } |
@@ -193,9 +194,9 @@ static __attribute__((interrupt("IRQ"))) void CSPI3_HANDLER(void) | |||
193 | static bool spi_set_context(struct spi_node *node, | 194 | static bool spi_set_context(struct spi_node *node, |
194 | struct spi_module_descriptor *desc) | 195 | struct spi_module_descriptor *desc) |
195 | { | 196 | { |
196 | volatile unsigned long * const base = desc->base; | 197 | struct cspi_map * const base = desc->base; |
197 | 198 | ||
198 | if ((base[CSPI_CONREG_I] & CSPI_CONREG_EN) == 0) | 199 | if ((base->conreg & CSPI_CONREG_EN) == 0) |
199 | return false; | 200 | return false; |
200 | 201 | ||
201 | if (node != desc->last) | 202 | if (node != desc->last) |
@@ -205,13 +206,13 @@ static bool spi_set_context(struct spi_node *node, | |||
205 | desc->byte_size = (((node->conreg >> 8) & 0x1f) + 1 + 7) / 8 - 1; | 206 | desc->byte_size = (((node->conreg >> 8) & 0x1f) + 1 + 7) / 8 - 1; |
206 | 207 | ||
207 | /* Keep reserved and start bits cleared. Keep enabled bit. */ | 208 | /* Keep reserved and start bits cleared. Keep enabled bit. */ |
208 | base[CSPI_CONREG_I] = | 209 | base->conreg = |
209 | (node->conreg & ~(0xfcc8e000 | CSPI_CONREG_XCH | CSPI_CONREG_SMC)) | 210 | (node->conreg & ~(0xfcc8e000 | CSPI_CONREG_XCH | CSPI_CONREG_SMC)) |
210 | | CSPI_CONREG_EN; | 211 | | CSPI_CONREG_EN; |
211 | /* Set the wait-states */ | 212 | /* Set the wait-states */ |
212 | base[CSPI_PERIODREG_I] = node->periodreg & 0xffff; | 213 | base->periodreg = node->periodreg & 0xffff; |
213 | /* Clear out any spuriously-pending interrupts */ | 214 | /* Clear out any spuriously-pending interrupts */ |
214 | base[CSPI_STATREG_I] = CSPI_STATREG_TC | CSPI_STATREG_BO; | 215 | base->statreg = CSPI_STATREG_TC | CSPI_STATREG_BO; |
215 | } | 216 | } |
216 | 217 | ||
217 | return true; | 218 | return true; |
@@ -252,16 +253,16 @@ void spi_enable_module(struct spi_node *node) | |||
252 | if (++desc->enab == 1) | 253 | if (++desc->enab == 1) |
253 | { | 254 | { |
254 | /* First enable for this module */ | 255 | /* First enable for this module */ |
255 | volatile unsigned long * const base = desc->base; | 256 | struct cspi_map * const base = desc->base; |
256 | 257 | ||
257 | /* Enable clock-gating register */ | 258 | /* Enable clock-gating register */ |
258 | imx31_clkctl_module_clock_gating(desc->cg, CGM_ON_ALL); | 259 | imx31_clkctl_module_clock_gating(desc->cg, CGM_ON_ALL); |
259 | 260 | ||
260 | /* Reset */ | 261 | /* Reset */ |
261 | base[CSPI_CONREG_I] &= ~CSPI_CONREG_EN; | 262 | base->conreg &= ~CSPI_CONREG_EN; |
262 | base[CSPI_CONREG_I] |= CSPI_CONREG_EN; | 263 | base->conreg |= CSPI_CONREG_EN; |
263 | base[CSPI_INTREG_I] = 0; | 264 | base->intreg = 0; |
264 | base[CSPI_STATREG_I] = CSPI_STATREG_TC | CSPI_STATREG_BO; | 265 | base->statreg = CSPI_STATREG_TC | CSPI_STATREG_BO; |
265 | 266 | ||
266 | /* Enable interrupt at controller level */ | 267 | /* Enable interrupt at controller level */ |
267 | avic_enable_int(desc->ints, IRQ, 6, desc->handler); | 268 | avic_enable_int(desc->ints, IRQ, 6, desc->handler); |
@@ -280,13 +281,13 @@ void spi_disable_module(struct spi_node *node) | |||
280 | if (desc->enab > 0 && --desc->enab == 0) | 281 | if (desc->enab > 0 && --desc->enab == 0) |
281 | { | 282 | { |
282 | /* Last enable for this module */ | 283 | /* Last enable for this module */ |
283 | volatile unsigned long * const base = desc->base; | 284 | struct cspi_map * const base = desc->base; |
284 | 285 | ||
285 | /* Disable interrupt at controller level */ | 286 | /* Disable interrupt at controller level */ |
286 | avic_disable_int(desc->ints); | 287 | avic_disable_int(desc->ints); |
287 | 288 | ||
288 | /* Disable interface */ | 289 | /* Disable interface */ |
289 | base[CSPI_CONREG_I] &= ~CSPI_CONREG_EN; | 290 | base->conreg &= ~CSPI_CONREG_EN; |
290 | 291 | ||
291 | /* Disable interface clock */ | 292 | /* Disable interface clock */ |
292 | imx31_clkctl_module_clock_gating(desc->cg, CGM_OFF); | 293 | imx31_clkctl_module_clock_gating(desc->cg, CGM_OFF); |
@@ -310,7 +311,7 @@ int spi_transfer(struct spi_node *node, struct spi_transfer *trans) | |||
310 | 311 | ||
311 | if (retval) | 312 | if (retval) |
312 | { | 313 | { |
313 | volatile unsigned long * const base = desc->base; | 314 | struct cspi_map * const base = desc->base; |
314 | unsigned long intreg; | 315 | unsigned long intreg; |
315 | 316 | ||
316 | desc->trans = trans; | 317 | desc->trans = trans; |
@@ -323,15 +324,15 @@ int spi_transfer(struct spi_node *node, struct spi_transfer *trans) | |||
323 | CSPI_INTREG_RREN : /* Must grab data on every word */ | 324 | CSPI_INTREG_RREN : /* Must grab data on every word */ |
324 | CSPI_INTREG_RHEN; /* Enough data to wait for half-full */ | 325 | CSPI_INTREG_RHEN; /* Enough data to wait for half-full */ |
325 | 326 | ||
326 | base[CSPI_INTREG_I] = intreg; | 327 | base->intreg = intreg; |
327 | 328 | ||
328 | /* Start transfer */ | 329 | /* Start transfer */ |
329 | base[CSPI_CONREG_I] |= CSPI_CONREG_XCH; | 330 | base->conreg |= CSPI_CONREG_XCH; |
330 | 331 | ||
331 | if (wakeup_wait(&desc->w, HZ) != OBJ_WAIT_SUCCEEDED) | 332 | if (wakeup_wait(&desc->w, HZ) != OBJ_WAIT_SUCCEEDED) |
332 | { | 333 | { |
333 | base[CSPI_INTREG_I] = 0; | 334 | base->intreg = 0; |
334 | base[CSPI_CONREG_I] &= ~CSPI_CONREG_XCH; | 335 | base->conreg &= ~CSPI_CONREG_XCH; |
335 | retval = false; | 336 | retval = false; |
336 | } | 337 | } |
337 | } | 338 | } |
diff --git a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h index 07084832ad..2e104595f6 100644 --- a/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h +++ b/firmware/target/arm/imx31/gigabeat-s/spi-imx31.h | |||
@@ -39,6 +39,19 @@ enum spi_module_number | |||
39 | SPI_NUM_CSPI, | 39 | SPI_NUM_CSPI, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct cspi_map | ||
43 | { | ||
44 | volatile uint32_t rxdata; /* 00h */ | ||
45 | volatile uint32_t txdata; /* 04h */ | ||
46 | volatile uint32_t conreg; /* 08h */ | ||
47 | volatile uint32_t intreg; /* 0Ch */ | ||
48 | volatile uint32_t dmareg; /* 10h */ | ||
49 | volatile uint32_t statreg; /* 14h */ | ||
50 | volatile uint32_t periodreg; /* 18h */ | ||
51 | volatile uint32_t skip1[0x69]; /* 1Ch */ | ||
52 | volatile uint32_t testreg; /* 1C0h */ | ||
53 | }; | ||
54 | |||
42 | struct spi_node | 55 | struct spi_node |
43 | { | 56 | { |
44 | enum spi_module_number num; /* Module number (CSPIx_NUM) */ | 57 | enum spi_module_number num; /* Module number (CSPIx_NUM) */ |