summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2010-04-09 01:21:53 +0000
committerMichael Sevakis <jethead71@rockbox.org>2010-04-09 01:21:53 +0000
commit7abf2b53a462612808d46d6d77a7f35261a0e5a3 (patch)
tree241304f7cd2b5d1c2a9e091fe56a33d2d2f8e816 /firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
parent43304b87b0662d1619ac60e5297a1694aa580310 (diff)
downloadrockbox-7abf2b53a462612808d46d6d77a7f35261a0e5a3.tar.gz
rockbox-7abf2b53a462612808d46d6d77a7f35261a0e5a3.zip
Gigabeat S/i.MX31: Sort files in the /target tree into things that are SoC-generic (into /imx31) and player-specific (into /gigabeat-s, based upon current appearances). Move i2s clock init into the appropriate file. Housekeeping only-- no functional changes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25547 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/avic-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/avic-imx31.c212
1 files changed, 0 insertions, 212 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c b/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
deleted file mode 100644
index 4ba7da4be0..0000000000
--- a/firmware/target/arm/imx31/gigabeat-s/avic-imx31.c
+++ /dev/null
@@ -1,212 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by James Espinoza
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include "system.h"
23#include "imx31l.h"
24#include "avic-imx31.h"
25#include "panic.h"
26#include "debug.h"
27
28static const char * avic_int_names[64] =
29{
30 "RESERVED0", "RESERVED1", "RESERVED2", "I2C3",
31 "I2C2", "MPEG4_ENCODER", "RTIC", "FIR",
32 "MMC/SDHC2", "MMC/SDHC1", "I2C1", "SSI2",
33 "SSI1", "CSPI2", "CSPI1", "ATA",
34 "MBX", "CSPI3", "UART3", "IIM",
35 "SIM1", "SIM2", "RNGA", "EVTMON",
36 "KPP", "RTC", "PWN", "EPIT2",
37 "EPIT1", "GPT", "PWR_FAIL", "CCM_DVFS",
38 "UART2", "NANDFC", "SDMA", "USB_HOST1",
39 "USB_HOST2", "USB_OTG", "RESERVED3", "MSHC1",
40 "MSHC2", "IPU_ERR", "IPU", "RESERVED4",
41 "RESERVED5", "UART1", "UART4", "UART5",
42 "ETC_IRQ", "SCC_SCM", "SCC_SMN", "GPIO2",
43 "GPIO1", "CCM_CLK", "PCMCIA", "WDOG",
44 "GPIO3", "RESERVED6", "EXT_PWMG", "EXT_TEMP",
45 "EXT_SENS1", "EXT_SENS2", "EXT_WDOG", "EXT_TV"
46};
47
48void UIE_VECTOR(void)
49{
50 int mode;
51 int offset;
52
53 asm volatile (
54 "mrs %0, cpsr \n" /* Mask core IRQ/FIQ */
55 "orr %0, %0, #0xc0 \n"
56 "msr cpsr_c, %0 \n"
57 "and %0, %0, #0x1f \n" /* Get mode bits */
58 : "=&r"(mode)
59 );
60
61 offset = mode == 0x11 ?
62 (int32_t)AVIC_FIVECSR : ((int32_t)AVIC_NIVECSR >> 16);
63
64 panicf("Unhandled %s %d: %s",
65 mode == 0x11 ? "FIQ" : "IRQ", offset,
66 offset >= 0 ? avic_int_names[offset] : "<Unknown>");
67}
68
69/* We use the AVIC */
70void __attribute__((interrupt("IRQ"))) irq_handler(void)
71{
72 const int offset = (int32_t)AVIC_NIVECSR >> 16;
73
74 if (offset == -1)
75 {
76 /* This is called occasionally for some unknown reason even with the
77 * avic enabled but returning normally appears to cause no harm. The
78 * KPP and ATA seem to have a part in it (common but multiplexed pins
79 * that can interfere). It will be investigated more thoroughly but
80 * for now it is simply an occasional irritant. */
81 return;
82 }
83
84 disable_interrupt(IRQ_FIQ_STATUS);
85 panicf("Unhandled IRQ %d in irq_handler: %s", offset,
86 offset >= 0 ? avic_int_names[offset] : "<Unknown>");
87}
88
89/* Accoring to section 9.3.5 of the UM, the AVIC doesn't accelerate
90 * fast interrupts and they must be dispatched */
91void __attribute__((naked)) fiq_handler(void)
92{
93 asm volatile (
94 "mov r10, #0x68000000 \n" /* load AVIC base address */
95 "ldr r9, [r10, #0x44] \n" /* read FIVECSR of AVIC */
96 "add r10, r10, #0x100 \n" /* move pointer to base of VECTOR table */
97 "ldr r8, [r10, r9, lsl #2] \n" /* read FIQ vector from VECTOR table */
98 "bx r8 \n" /* jump to FIQ service routine */
99 );
100}
101
102void avic_init(void)
103{
104 struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
105 int i;
106
107 /* Disable all interrupts and set to unhandled */
108 avic_disable_int(INT_ALL);
109
110 /* Reset AVIC control */
111 avic->intcntl = 0;
112
113 /* Init all interrupts to type IRQ */
114 avic_set_int_type(INT_ALL, INT_TYPE_IRQ);
115
116 /* Set all normal to lowest priority */
117 for (i = 0; i < 8; i++)
118 avic->nipriority[i] = 0;
119
120 /* Set NM bit to enable VIC */
121 avic->intcntl |= AVIC_INTCNTL_NM;
122
123 /* Enable VE bit in CP15 Control reg to enable VIC */
124 asm volatile (
125 "mrc p15, 0, r0, c1, c0, 0 \n"
126 "orr r0, r0, #(1 << 24) \n"
127 "mcr p15, 0, r0, c1, c0, 0 \n"
128 : : : "r0");
129
130 /* Enable normal interrupts at all priorities */
131 avic->nimask = 0x1f;
132}
133
134void avic_set_int_priority(enum IMX31_INT_LIST ints,
135 unsigned long ni_priority)
136{
137 struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
138 volatile uint32_t *reg = &avic->nipriority[7 - (ints >> 3)];
139 unsigned int shift = (ints & 0x7) << 2;
140 uint32_t mask = 0xful << shift;
141 *reg = (*reg & ~mask) | ((ni_priority << shift) & mask);
142}
143
144void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
145 unsigned long ni_priority, void (*handler)(void))
146{
147 struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
148 int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
149
150 if (ints != INT_ALL) /* No mass-enable allowed */
151 {
152 avic_set_int_type(ints, intstype);
153 avic->vector[ints] = (long)handler;
154 avic->intennum = ints;
155 avic_set_int_priority(ints, ni_priority);
156 }
157
158 restore_interrupt(oldstatus);
159}
160
161void avic_disable_int(enum IMX31_INT_LIST ints)
162{
163 struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
164 uint32_t i;
165
166 if (ints == INT_ALL)
167 {
168 for (i = 0; i < 64; i++)
169 {
170 avic->intdisnum = i;
171 avic->vector[i] = (long)UIE_VECTOR;
172 }
173 }
174 else
175 {
176 avic->intdisnum = ints;
177 avic->vector[ints] = (long)UIE_VECTOR;
178 }
179}
180
181static void set_int_type(int i, enum INT_TYPE intstype)
182{
183 /* INTTYPEH: vectors 63-32, INTTYPEL: vectors 31-0 */
184 struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
185 volatile uint32_t *reg = &avic->inttype[1 - (i >> 5)];
186 uint32_t val = 1L << (i & 0x1f);
187
188 if (intstype == INT_TYPE_IRQ)
189 val = *reg & ~val;
190 else
191 val = *reg | val;
192
193 *reg = val;
194}
195
196void avic_set_int_type(enum IMX31_INT_LIST ints, enum INT_TYPE intstype)
197{
198 int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
199
200 if (ints == INT_ALL)
201 {
202 int i;
203 for (i = 0; i < 64; i++)
204 set_int_type(i, intstype);
205 }
206 else
207 {
208 set_int_type(ints, intstype);
209 }
210
211 restore_interrupt(oldstatus);
212}