2 * Freescale STMP37XX 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/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>
26 #include <asm/setup.h>
27 #include <asm/mach-types.h>
29 #include <asm/mach/arch.h>
30 #include <asm/mach/irq.h>
31 #include <asm/mach/map.h>
32 #include <asm/mach/time.h>
34 #include <mach/stmp3xxx.h>
37 #include <mach/regs-icoll.h>
38 #include <mach/regs-apbh.h>
39 #include <mach/regs-apbx.h>
45 static void stmp37xx_ack_irq(unsigned int irq)
48 HW_ICOLL_PRIORITYn_CLR(irq / 4, 0x04 << ((irq % 4) * 8));
50 /* ACK current interrupt */
51 HW_ICOLL_LEVELACK_WR(1);
54 (void) HW_ICOLL_STAT_RD();
57 static void stmp37xx_mask_irq(unsigned int irq)
60 HW_ICOLL_PRIORITYn_CLR(irq / 4, 0x04 << ((irq % 4) * 8));
63 static void stmp37xx_unmask_irq(unsigned int irq)
66 HW_ICOLL_PRIORITYn_SET(irq / 4, 0x04 << ((irq % 4) * 8));
69 static struct irq_chip stmp37xx_chip = {
70 .ack = stmp37xx_ack_irq,
71 .mask = stmp37xx_mask_irq,
72 .unmask = stmp37xx_unmask_irq,
75 void __init stmp37xx_init_irq(void)
77 stmp3xxx_init_irq(&stmp37xx_chip);
81 * DMA interrupt handling
83 void stmp3xxx_arch_dma_enable_interrupt(int channel)
85 int dmabus = channel / 16;
88 case STMP3XXX_BUS_APBH:
89 HW_APBH_CTRL1_SET(1 << (8 + (channel % 16)));
92 case STMP3XXX_BUS_APBX:
93 HW_APBX_CTRL1_SET(1 << (8 + (channel % 16)));
97 EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt);
99 void stmp3xxx_arch_dma_clear_interrupt(int channel)
101 int dmabus = channel / 16;
104 case STMP3XXX_BUS_APBH:
105 HW_APBH_CTRL1_CLR(1 << (channel % 16));
108 case STMP3XXX_BUS_APBX:
109 HW_APBX_CTRL1_CLR(1 << (channel % 16));
113 EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt);
115 int stmp3xxx_arch_dma_is_interrupt(int channel)
119 int dmabus = channel / 16;
122 case STMP3XXX_BUS_APBH:
123 r = HW_APBH_CTRL1_RD() & (1 << (channel % 16));
126 case STMP3XXX_BUS_APBX:
127 r = HW_APBX_CTRL1_RD() & (1 << (channel % 16));
132 EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt);
134 void stmp3xxx_arch_dma_reset_channel(int channel)
136 int dmabus = channel / 16;
137 unsigned chbit = 1 << (channel % 16);
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))
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))
157 EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel);
159 void stmp3xxx_arch_dma_freeze(int channel)
161 int dmabus = channel / 16;
162 unsigned chbit = 1 << (channel % 16);
165 case STMP3XXX_BUS_APBH:
166 HW_APBH_CTRL0_SET(1<<chbit);
168 case STMP3XXX_BUS_APBX:
169 HW_APBX_CTRL0_SET(1<<chbit);
173 EXPORT_SYMBOL(stmp3xxx_arch_dma_freeze);
175 void stmp3xxx_arch_dma_unfreeze(int channel)
177 int dmabus = channel / 16;
178 unsigned chbit = 1 << (channel % 16);
181 case STMP3XXX_BUS_APBH:
182 HW_APBH_CTRL0_CLR(1<<chbit);
184 case STMP3XXX_BUS_APBX:
185 HW_APBX_CTRL0_CLR(1<<chbit);
189 EXPORT_SYMBOL(stmp3xxx_arch_dma_unfreeze);
192 * The registers are all very closely mapped, so we might as well map them all
193 * with a single mapping
196 * f0000000 80000000 On-chip registers
197 * f1000000 00000000 256k on-chip SRAM
199 static struct map_desc stmp37xx_io_desc[] __initdata = {
201 .virtual = (u32)STMP3XXX_REGS_BASE,
202 .pfn = __phys_to_pfn(STMP3XXX_REGS_PHBASE),
207 .virtual = (u32)STMP3XXX_OCRAM_BASE,
208 .pfn = __phys_to_pfn(STMP3XXX_OCRAM_PHBASE),
209 .length = STMP3XXX_OCRAM_SIZE,
214 void __init stmp37xx_map_io(void)
216 iotable_init(stmp37xx_io_desc, ARRAY_SIZE(stmp37xx_io_desc));