diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2009-02-02 02:38:21 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2009-02-02 02:38:21 +0000 |
commit | 1a00056f1f225ee0d1643d3e4e603de171f7ab9a (patch) | |
tree | a73a7d2124305c5578982f1fec872f640bca6b13 /firmware/target/arm/imx31/gigabeat-s/system-imx31.c | |
parent | 304aefe80256429e8c1cbdbb5afd1693d90041aa (diff) | |
download | rockbox-1a00056f1f225ee0d1643d3e4e603de171f7ab9a.tar.gz rockbox-1a00056f1f225ee0d1643d3e4e603de171f7ab9a.zip |
i.MX31: Make SPI more tolerant by resetting and forcing a reconfigure of the interface if an error ever happens. Better handle PMIC GPIO interrupt; it definitely doesn't low-pulse PRIINT (remains high if sources become active again or stay active while acking) so needed rising edge may never happen in such a case-- use high-level detection rather than rising edge. Optimize the reg/clr/set/mod functions a bit since they get more regular use now.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19903 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/system-imx31.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-imx31.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c index 7454806d07..cb265af0a3 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c | |||
@@ -172,24 +172,46 @@ void system_init(void) | |||
172 | gpio_init(); | 172 | gpio_init(); |
173 | } | 173 | } |
174 | 174 | ||
175 | void imx31_regmod32(volatile uint32_t *reg_p, uint32_t value, uint32_t mask) | 175 | void __attribute__((naked)) imx31_regmod32(volatile uint32_t *reg_p, |
176 | uint32_t value, | ||
177 | uint32_t mask) | ||
176 | { | 178 | { |
177 | value &= mask; | 179 | asm volatile("and r1, r1, r2 \n" |
178 | mask = ~mask; | 180 | "mrs ip, cpsr \n" |
179 | 181 | "cpsid if \n" | |
180 | int oldlevel = disable_interrupt_save(IRQ_FIQ_STATUS); | 182 | "ldr r3, [r0] \n" |
181 | *reg_p = (*reg_p & mask) | value; | 183 | "bic r3, r3, r2 \n" |
182 | restore_interrupt(oldlevel); | 184 | "orr r3, r3, r1 \n" |
185 | "str r3, [r0] \n" | ||
186 | "msr cpsr_c, ip \n" | ||
187 | "bx lr \n"); | ||
188 | (void)reg_p; (void)value; (void)mask; | ||
183 | } | 189 | } |
184 | 190 | ||
185 | void imx31_regset32(volatile uint32_t *reg_p, uint32_t mask) | 191 | void __attribute__((naked)) imx31_regset32(volatile uint32_t *reg_p, |
192 | uint32_t mask) | ||
186 | { | 193 | { |
187 | imx31_regmod32(reg_p, mask, mask); | 194 | asm volatile("mrs r3, cpsr \n" |
195 | "cpsid if \n" | ||
196 | "ldr r2, [r0] \n" | ||
197 | "orr r2, r2, r1 \n" | ||
198 | "str r2, [r0] \n" | ||
199 | "msr cpsr_c, r3 \n" | ||
200 | "bx lr \n"); | ||
201 | (void)reg_p; (void)mask; | ||
188 | } | 202 | } |
189 | 203 | ||
190 | void imx31_regclr32(volatile uint32_t *reg_p, uint32_t mask) | 204 | void __attribute__((naked)) imx31_regclr32(volatile uint32_t *reg_p, |
205 | uint32_t mask) | ||
191 | { | 206 | { |
192 | imx31_regmod32(reg_p, 0, mask); | 207 | asm volatile("mrs r3, cpsr \n" |
208 | "cpsid if \n" | ||
209 | "ldr r2, [r0] \n" | ||
210 | "bic r2, r2, r1 \n" | ||
211 | "str r2, [r0] \n" | ||
212 | "msr cpsr_c, r3 \n" | ||
213 | "bx lr \n"); | ||
214 | (void)reg_p; (void)mask; | ||
193 | } | 215 | } |
194 | 216 | ||
195 | #ifdef BOOTLOADER | 217 | #ifdef BOOTLOADER |