aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-stmp37xx/stmp37xx.c
diff options
context:
space:
mode:
authordmitry pervushin <dpervushin@embeddedalley.com>2009-04-22 18:57:05 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-04-27 05:28:08 -0400
commit45d9108011b9dfb4fccd6c258290d2185145709b (patch)
treec416842cd6f2a3444fc87b4b03009d0346312a55 /arch/arm/mach-stmp37xx/stmp37xx.c
parent5cccd37ea15970846a93b4b01fafd6e043bafe8e (diff)
[ARM] 5465/1: Freescale STMP platform support [7/10]
Sources: support for 37xx boards Signed-off-by: dmitry pervushin <dpervushin@embeddedalley.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-stmp37xx/stmp37xx.c')
-rw-r--r--arch/arm/mach-stmp37xx/stmp37xx.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/arch/arm/mach-stmp37xx/stmp37xx.c b/arch/arm/mach-stmp37xx/stmp37xx.c
new file mode 100644
index 00000000000..83a41c90c25
--- /dev/null
+++ b/arch/arm/mach-stmp37xx/stmp37xx.c
@@ -0,0 +1,217 @@
1/*
2 * Freescale STMP37XX platform support
3 *
4 * Embedded Alley Solutions, Inc <source@embeddedalley.com>
5 *
6 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
7 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
8 */
9
10/*
11 * The code contained herein is licensed under the GNU General Public
12 * License. You may obtain a copy of the GNU General Public License
13 * Version 2 or later at the following locations:
14 *
15 * http://www.opensource.org/licenses/gpl-license.html
16 * http://www.gnu.org/copyleft/gpl.html
17 */
18#include <linux/types.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/device.h>
22#include <linux/platform_device.h>
23#include <linux/irq.h>
24#include <linux/io.h>
25
26#include <asm/setup.h>
27#include <asm/mach-types.h>
28
29#include <asm/mach/arch.h>
30#include <asm/mach/irq.h>
31#include <asm/mach/map.h>
32#include <asm/mach/time.h>
33
34#include <mach/stmp3xxx.h>
35#include <mach/dma.h>
36
37#include <mach/regs-icoll.h>
38#include <mach/regs-apbh.h>
39#include <mach/regs-apbx.h>
40#include "stmp37xx.h"
41
42/*
43 * IRQ handling
44 */
45static void stmp37xx_ack_irq(unsigned int irq)
46{
47 /* Disable IRQ */
48 HW_ICOLL_PRIORITYn_CLR(irq / 4, 0x04 << ((irq % 4) * 8));
49
50 /* ACK current interrupt */
51 HW_ICOLL_LEVELACK_WR(1);
52
53 /* Barrier */
54 (void) HW_ICOLL_STAT_RD();
55}
56
57static void stmp37xx_mask_irq(unsigned int irq)
58{
59 /* IRQ disable */
60 HW_ICOLL_PRIORITYn_CLR(irq / 4, 0x04 << ((irq % 4) * 8));
61}
62
63static void stmp37xx_unmask_irq(unsigned int irq)
64{
65 /* IRQ enable */
66 HW_ICOLL_PRIORITYn_SET(irq / 4, 0x04 << ((irq % 4) * 8));
67}
68
69static struct irq_chip stmp37xx_chip = {
70 .ack = stmp37xx_ack_irq,
71 .mask = stmp37xx_mask_irq,
72 .unmask = stmp37xx_unmask_irq,
73};
74
75void __init stmp37xx_init_irq(void)
76{
77 stmp3xxx_init_irq(&stmp37xx_chip);
78}
79
80/*
81 * DMA interrupt handling
82 */
83void stmp3xxx_arch_dma_enable_interrupt(int channel)
84{
85 int dmabus = channel / 16;
86
87 switch (dmabus) {
88 case STMP3XXX_BUS_APBH:
89 HW_APBH_CTRL1_SET(1 << (8 + (channel % 16)));
90 break;
91
92 case STMP3XXX_BUS_APBX:
93 HW_APBX_CTRL1_SET(1 << (8 + (channel % 16)));
94 break;
95 }
96}
97EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt);
98
99void stmp3xxx_arch_dma_clear_interrupt(int channel)
100{
101 int dmabus = channel / 16;
102
103 switch (dmabus) {
104 case STMP3XXX_BUS_APBH:
105 HW_APBH_CTRL1_CLR(1 << (channel % 16));
106 break;
107
108 case STMP3XXX_BUS_APBX:
109 HW_APBX_CTRL1_CLR(1 << (channel % 16));
110 break;
111 }
112}
113EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt);
114
115int stmp3xxx_arch_dma_is_interrupt(int channel)
116{
117 int r = 0;
118
119 int dmabus = channel / 16;
120
121 switch (dmabus) {
122 case STMP3XXX_BUS_APBH:
123 r = HW_APBH_CTRL1_RD() & (1 << (channel % 16));
124 break;
125
126 case STMP3XXX_BUS_APBX:
127 r = HW_APBX_CTRL1_RD() & (1 << (channel % 16));
128 break;
129 }
130 return r;
131}
132EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt);
133
134void stmp3xxx_arch_dma_reset_channel(int channel)
135{
136 int dmabus = channel / 16;
137 unsigned chbit = 1 << (channel % 16);
138
139 switch (dmabus) {
140 case STMP3XXX_BUS_APBH:
141 /* Reset channel and wait for it to complete */
142 HW_APBH_CTRL0_SET(chbit << BP_APBH_CTRL0_RESET_CHANNEL);
143 while (HW_APBH_CTRL0_RD() &
144 (chbit << BP_APBH_CTRL0_RESET_CHANNEL))
145 continue;
146 break;
147
148 case STMP3XXX_BUS_APBX:
149 /* Reset channel and wait for it to complete */
150 HW_APBX_CTRL0_SET(chbit << BP_APBX_CTRL0_RESET_CHANNEL);
151 while (HW_APBX_CTRL0_RD() &
152 (chbit << BP_APBX_CTRL0_RESET_CHANNEL))
153 continue;
154 break;
155 }
156}
157EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel);
158
159void stmp3xxx_arch_dma_freeze(int channel)
160{
161 int dmabus = channel / 16;
162 unsigned chbit = 1 << (channel % 16);
163
164 switch (dmabus) {
165 case STMP3XXX_BUS_APBH:
166 HW_APBH_CTRL0_SET(1<<chbit);
167 break;
168 case STMP3XXX_BUS_APBX:
169 HW_APBX_CTRL0_SET(1<<chbit);
170 break;
171 }
172}
173EXPORT_SYMBOL(stmp3xxx_arch_dma_freeze);
174
175void stmp3xxx_arch_dma_unfreeze(int channel)
176{
177 int dmabus = channel / 16;
178 unsigned chbit = 1 << (channel % 16);
179
180 switch (dmabus) {
181 case STMP3XXX_BUS_APBH:
182 HW_APBH_CTRL0_CLR(1<<chbit);
183 break;
184 case STMP3XXX_BUS_APBX:
185 HW_APBX_CTRL0_CLR(1<<chbit);
186 break;
187 }
188}
189EXPORT_SYMBOL(stmp3xxx_arch_dma_unfreeze);
190
191/*
192 * The registers are all very closely mapped, so we might as well map them all
193 * with a single mapping
194 *
195 * Logical Physical
196 * f0000000 80000000 On-chip registers
197 * f1000000 00000000 256k on-chip SRAM
198 */
199static struct map_desc stmp37xx_io_desc[] __initdata = {
200 {
201 .virtual = (u32)STMP3XXX_REGS_BASE,
202 .pfn = __phys_to_pfn(STMP3XXX_REGS_PHBASE),
203 .length = SZ_1M,
204 .type = MT_DEVICE
205 },
206 {
207 .virtual = (u32)STMP3XXX_OCRAM_BASE,
208 .pfn = __phys_to_pfn(STMP3XXX_OCRAM_PHBASE),
209 .length = STMP3XXX_OCRAM_SIZE,
210 .type = MT_DEVICE,
211 },
212};
213
214void __init stmp37xx_map_io(void)
215{
216 iotable_init(stmp37xx_io_desc, ARRAY_SIZE(stmp37xx_io_desc));
217}