]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/arm/mach-stmp37xx/stmp37xx.c
[ARM] 5465/1: Freescale STMP platform support [7/10]
[mv-sheeva.git] / arch / arm / mach-stmp37xx / stmp37xx.c
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  */
45 static 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
57 static void stmp37xx_mask_irq(unsigned int irq)
58 {
59         /* IRQ disable */
60         HW_ICOLL_PRIORITYn_CLR(irq / 4, 0x04 << ((irq % 4) * 8));
61 }
62
63 static void stmp37xx_unmask_irq(unsigned int irq)
64 {
65         /* IRQ enable */
66         HW_ICOLL_PRIORITYn_SET(irq / 4, 0x04 << ((irq % 4) * 8));
67 }
68
69 static struct irq_chip stmp37xx_chip = {
70         .ack    = stmp37xx_ack_irq,
71         .mask   = stmp37xx_mask_irq,
72         .unmask = stmp37xx_unmask_irq,
73 };
74
75 void __init stmp37xx_init_irq(void)
76 {
77         stmp3xxx_init_irq(&stmp37xx_chip);
78 }
79
80 /*
81  * DMA interrupt handling
82  */
83 void 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 }
97 EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt);
98
99 void 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 }
113 EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt);
114
115 int 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 }
132 EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt);
133
134 void 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 }
157 EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel);
158
159 void 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 }
173 EXPORT_SYMBOL(stmp3xxx_arch_dma_freeze);
174
175 void 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 }
189 EXPORT_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  */
199 static 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
214 void __init stmp37xx_map_io(void)
215 {
216         iotable_init(stmp37xx_io_desc, ARRAY_SIZE(stmp37xx_io_desc));
217 }