2 * Freescale STMP378X platform support
4 * Embedded Alley Solutions, Inc <source@embeddedalley.com>
6 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
7 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
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:
15 * http://www.opensource.org/licenses/gpl-license.html
16 * http://www.gnu.org/copyleft/gpl.html
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/platform_device.h>
21 #include <linux/irq.h>
24 #include <asm/setup.h>
25 #include <asm/mach-types.h>
27 #include <asm/mach/arch.h>
28 #include <asm/mach/irq.h>
29 #include <asm/mach/map.h>
30 #include <asm/mach/time.h>
32 #include <mach/pins.h>
33 #include <mach/pinmux.h>
35 #include <mach/hardware.h>
36 #include <mach/system.h>
37 #include <mach/platform.h>
38 #include <mach/stmp3xxx.h>
39 #include <mach/regs-icoll.h>
40 #include <mach/regs-apbh.h>
41 #include <mach/regs-apbx.h>
47 static void stmp378x_ack_irq(unsigned int irq
)
49 /* Tell ICOLL to release IRQ line */
50 __raw_writel(0, REGS_ICOLL_BASE
+ HW_ICOLL_VECTOR
);
52 /* ACK current interrupt */
53 __raw_writel(0x01 /* BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 */,
54 REGS_ICOLL_BASE
+ HW_ICOLL_LEVELACK
);
57 (void)__raw_readl(REGS_ICOLL_BASE
+ HW_ICOLL_STAT
);
60 static void stmp378x_mask_irq(unsigned int irq
)
63 stmp3xxx_clearl(BM_ICOLL_INTERRUPTn_ENABLE
,
64 REGS_ICOLL_BASE
+ HW_ICOLL_INTERRUPTn
+ irq
* 0x10);
67 static void stmp378x_unmask_irq(unsigned int irq
)
70 stmp3xxx_setl(BM_ICOLL_INTERRUPTn_ENABLE
,
71 REGS_ICOLL_BASE
+ HW_ICOLL_INTERRUPTn
+ irq
* 0x10);
74 static struct irq_chip stmp378x_chip
= {
75 .ack
= stmp378x_ack_irq
,
76 .mask
= stmp378x_mask_irq
,
77 .unmask
= stmp378x_unmask_irq
,
80 void __init
stmp378x_init_irq(void)
82 stmp3xxx_init_irq(&stmp378x_chip
);
86 * DMA interrupt handling
88 void stmp3xxx_arch_dma_enable_interrupt(int channel
)
90 void __iomem
*c1
, *c2
;
92 switch (STMP3XXX_DMA_BUS(channel
)) {
93 case STMP3XXX_BUS_APBH
:
94 c1
= REGS_APBH_BASE
+ HW_APBH_CTRL1
;
95 c2
= REGS_APBH_BASE
+ HW_APBH_CTRL2
;
98 case STMP3XXX_BUS_APBX
:
99 c1
= REGS_APBX_BASE
+ HW_APBX_CTRL1
;
100 c2
= REGS_APBX_BASE
+ HW_APBX_CTRL2
;
106 stmp3xxx_setl(1 << (16 + STMP3XXX_DMA_CHANNEL(channel
)), c1
);
107 stmp3xxx_setl(1 << (16 + STMP3XXX_DMA_CHANNEL(channel
)), c2
);
109 EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt
);
111 void stmp3xxx_arch_dma_clear_interrupt(int channel
)
113 void __iomem
*c1
, *c2
;
115 switch (STMP3XXX_DMA_BUS(channel
)) {
116 case STMP3XXX_BUS_APBH
:
117 c1
= REGS_APBH_BASE
+ HW_APBH_CTRL1
;
118 c2
= REGS_APBH_BASE
+ HW_APBH_CTRL2
;
121 case STMP3XXX_BUS_APBX
:
122 c1
= REGS_APBX_BASE
+ HW_APBX_CTRL1
;
123 c2
= REGS_APBX_BASE
+ HW_APBX_CTRL2
;
129 stmp3xxx_clearl(1 << STMP3XXX_DMA_CHANNEL(channel
), c1
);
130 stmp3xxx_clearl(1 << STMP3XXX_DMA_CHANNEL(channel
), c2
);
132 EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt
);
134 int stmp3xxx_arch_dma_is_interrupt(int channel
)
138 switch (STMP3XXX_DMA_BUS(channel
)) {
139 case STMP3XXX_BUS_APBH
:
140 r
= __raw_readl(REGS_APBH_BASE
+ HW_APBH_CTRL1
) &
141 (1 << STMP3XXX_DMA_CHANNEL(channel
));
144 case STMP3XXX_BUS_APBX
:
145 r
= __raw_readl(REGS_APBX_BASE
+ HW_APBX_CTRL1
) &
146 (1 << STMP3XXX_DMA_CHANNEL(channel
));
151 EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt
);
153 void stmp3xxx_arch_dma_reset_channel(int channel
)
155 unsigned chbit
= 1 << STMP3XXX_DMA_CHANNEL(channel
);
159 switch (STMP3XXX_DMA_BUS(channel
)) {
160 case STMP3XXX_BUS_APBH
:
161 c0
= REGS_APBH_BASE
+ HW_APBH_CTRL0
;
162 mask
= chbit
<< BP_APBH_CTRL0_RESET_CHANNEL
;
164 case STMP3XXX_BUS_APBX
:
165 c0
= REGS_APBX_BASE
+ HW_APBX_CHANNEL_CTRL
;
166 mask
= chbit
<< BP_APBX_CHANNEL_CTRL_RESET_CHANNEL
;
172 /* Reset channel and wait for it to complete */
173 stmp3xxx_setl(mask
, c0
);
174 while (__raw_readl(c0
) & mask
)
177 EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel
);
179 void stmp3xxx_arch_dma_freeze(int channel
)
181 unsigned chbit
= 1 << STMP3XXX_DMA_CHANNEL(channel
);
182 u32 mask
= 1 << chbit
;
184 switch (STMP3XXX_DMA_BUS(channel
)) {
185 case STMP3XXX_BUS_APBH
:
186 stmp3xxx_setl(mask
, REGS_APBH_BASE
+ HW_APBH_CTRL0
);
188 case STMP3XXX_BUS_APBX
:
189 stmp3xxx_setl(mask
, REGS_APBX_BASE
+ HW_APBX_CHANNEL_CTRL
);
193 EXPORT_SYMBOL(stmp3xxx_arch_dma_freeze
);
195 void stmp3xxx_arch_dma_unfreeze(int channel
)
197 unsigned chbit
= 1 << STMP3XXX_DMA_CHANNEL(channel
);
198 u32 mask
= 1 << chbit
;
200 switch (STMP3XXX_DMA_BUS(channel
)) {
201 case STMP3XXX_BUS_APBH
:
202 stmp3xxx_clearl(mask
, REGS_APBH_BASE
+ HW_APBH_CTRL0
);
204 case STMP3XXX_BUS_APBX
:
205 stmp3xxx_clearl(mask
, REGS_APBX_BASE
+ HW_APBX_CHANNEL_CTRL
);
209 EXPORT_SYMBOL(stmp3xxx_arch_dma_unfreeze
);
212 * The registers are all very closely mapped, so we might as well map them all
213 * with a single mapping
216 * f0000000 80000000 On-chip registers
217 * f1000000 00000000 32k on-chip SRAM
220 static struct map_desc stmp378x_io_desc
[] __initdata
= {
222 .virtual = (u32
)STMP3XXX_REGS_BASE
,
223 .pfn
= __phys_to_pfn(STMP3XXX_REGS_PHBASE
),
224 .length
= STMP3XXX_REGS_SIZE
,
228 .virtual = (u32
)STMP3XXX_OCRAM_BASE
,
229 .pfn
= __phys_to_pfn(STMP3XXX_OCRAM_PHBASE
),
230 .length
= STMP3XXX_OCRAM_SIZE
,
235 void __init
stmp378x_map_io(void)
237 iotable_init(stmp378x_io_desc
, ARRAY_SIZE(stmp378x_io_desc
));