Merge branch 'xen/xenbus' into upstream/xen
[pandora-kernel.git] / arch / arm / mach-at91 / at572d940hf.c
1 /*
2  * arch/arm/mach-at91/at572d940hf.c
3  *
4  * Antonio R. Costa <costa.antonior@gmail.com>
5  * Copyright (C) 2008 Atmel
6  *
7  * Copyright (C) 2005 SAN People
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24
25 #include <linux/module.h>
26
27 #include <asm/mach/irq.h>
28 #include <asm/mach/arch.h>
29 #include <asm/mach/map.h>
30 #include <mach/at572d940hf.h>
31 #include <mach/at91_pmc.h>
32 #include <mach/at91_rstc.h>
33
34 #include "generic.h"
35 #include "clock.h"
36
37 static struct map_desc at572d940hf_io_desc[] __initdata = {
38         {
39                 .virtual        = AT91_VA_BASE_SYS,
40                 .pfn            = __phys_to_pfn(AT91_BASE_SYS),
41                 .length         = SZ_16K,
42                 .type           = MT_DEVICE,
43         }, {
44                 .virtual        = AT91_IO_VIRT_BASE - AT572D940HF_SRAM_SIZE,
45                 .pfn            = __phys_to_pfn(AT572D940HF_SRAM_BASE),
46                 .length         = AT572D940HF_SRAM_SIZE,
47                 .type           = MT_DEVICE,
48         },
49 };
50
51 /* --------------------------------------------------------------------
52  *  Clocks
53  * -------------------------------------------------------------------- */
54
55 /*
56  * The peripheral clocks.
57  */
58 static struct clk pioA_clk = {
59         .name           = "pioA_clk",
60         .pmc_mask       = 1 << AT572D940HF_ID_PIOA,
61         .type           = CLK_TYPE_PERIPHERAL,
62 };
63 static struct clk pioB_clk = {
64         .name           = "pioB_clk",
65         .pmc_mask       = 1 << AT572D940HF_ID_PIOB,
66         .type           = CLK_TYPE_PERIPHERAL,
67 };
68 static struct clk pioC_clk = {
69         .name           = "pioC_clk",
70         .pmc_mask       = 1 << AT572D940HF_ID_PIOC,
71         .type           = CLK_TYPE_PERIPHERAL,
72 };
73 static struct clk macb_clk = {
74         .name           = "macb_clk",
75         .pmc_mask       = 1 << AT572D940HF_ID_EMAC,
76         .type           = CLK_TYPE_PERIPHERAL,
77 };
78 static struct clk usart0_clk = {
79         .name           = "usart0_clk",
80         .pmc_mask       = 1 << AT572D940HF_ID_US0,
81         .type           = CLK_TYPE_PERIPHERAL,
82 };
83 static struct clk usart1_clk = {
84         .name           = "usart1_clk",
85         .pmc_mask       = 1 << AT572D940HF_ID_US1,
86         .type           = CLK_TYPE_PERIPHERAL,
87 };
88 static struct clk usart2_clk = {
89         .name           = "usart2_clk",
90         .pmc_mask       = 1 << AT572D940HF_ID_US2,
91         .type           = CLK_TYPE_PERIPHERAL,
92 };
93 static struct clk mmc_clk = {
94         .name           = "mci_clk",
95         .pmc_mask       = 1 << AT572D940HF_ID_MCI,
96         .type           = CLK_TYPE_PERIPHERAL,
97 };
98 static struct clk udc_clk = {
99         .name           = "udc_clk",
100         .pmc_mask       = 1 << AT572D940HF_ID_UDP,
101         .type           = CLK_TYPE_PERIPHERAL,
102 };
103 static struct clk twi0_clk = {
104         .name           = "twi0_clk",
105         .pmc_mask       = 1 << AT572D940HF_ID_TWI0,
106         .type           = CLK_TYPE_PERIPHERAL,
107 };
108 static struct clk spi0_clk = {
109         .name           = "spi0_clk",
110         .pmc_mask       = 1 << AT572D940HF_ID_SPI0,
111         .type           = CLK_TYPE_PERIPHERAL,
112 };
113 static struct clk spi1_clk = {
114         .name           = "spi1_clk",
115         .pmc_mask       = 1 << AT572D940HF_ID_SPI1,
116         .type           = CLK_TYPE_PERIPHERAL,
117 };
118 static struct clk ssc0_clk = {
119         .name           = "ssc0_clk",
120         .pmc_mask       = 1 << AT572D940HF_ID_SSC0,
121         .type           = CLK_TYPE_PERIPHERAL,
122 };
123 static struct clk ssc1_clk = {
124         .name           = "ssc1_clk",
125         .pmc_mask       = 1 << AT572D940HF_ID_SSC1,
126         .type           = CLK_TYPE_PERIPHERAL,
127 };
128 static struct clk ssc2_clk = {
129         .name           = "ssc2_clk",
130         .pmc_mask       = 1 << AT572D940HF_ID_SSC2,
131         .type           = CLK_TYPE_PERIPHERAL,
132 };
133 static struct clk tc0_clk = {
134         .name           = "tc0_clk",
135         .pmc_mask       = 1 << AT572D940HF_ID_TC0,
136         .type           = CLK_TYPE_PERIPHERAL,
137 };
138 static struct clk tc1_clk = {
139         .name           = "tc1_clk",
140         .pmc_mask       = 1 << AT572D940HF_ID_TC1,
141         .type           = CLK_TYPE_PERIPHERAL,
142 };
143 static struct clk tc2_clk = {
144         .name           = "tc2_clk",
145         .pmc_mask       = 1 << AT572D940HF_ID_TC2,
146         .type           = CLK_TYPE_PERIPHERAL,
147 };
148 static struct clk ohci_clk = {
149         .name           = "ohci_clk",
150         .pmc_mask       = 1 << AT572D940HF_ID_UHP,
151         .type           = CLK_TYPE_PERIPHERAL,
152 };
153 static struct clk ssc3_clk = {
154         .name           = "ssc3_clk",
155         .pmc_mask       = 1 << AT572D940HF_ID_SSC3,
156         .type           = CLK_TYPE_PERIPHERAL,
157 };
158 static struct clk twi1_clk = {
159         .name           = "twi1_clk",
160         .pmc_mask       = 1 << AT572D940HF_ID_TWI1,
161         .type           = CLK_TYPE_PERIPHERAL,
162 };
163 static struct clk can0_clk = {
164         .name           = "can0_clk",
165         .pmc_mask       = 1 << AT572D940HF_ID_CAN0,
166         .type           = CLK_TYPE_PERIPHERAL,
167 };
168 static struct clk can1_clk = {
169         .name           = "can1_clk",
170         .pmc_mask       = 1 << AT572D940HF_ID_CAN1,
171         .type           = CLK_TYPE_PERIPHERAL,
172 };
173 static struct clk mAgicV_clk = {
174         .name           = "mAgicV_clk",
175         .pmc_mask       = 1 << AT572D940HF_ID_MSIRQ0,
176         .type           = CLK_TYPE_PERIPHERAL,
177 };
178
179
180 static struct clk *periph_clocks[] __initdata = {
181         &pioA_clk,
182         &pioB_clk,
183         &pioC_clk,
184         &macb_clk,
185         &usart0_clk,
186         &usart1_clk,
187         &usart2_clk,
188         &mmc_clk,
189         &udc_clk,
190         &twi0_clk,
191         &spi0_clk,
192         &spi1_clk,
193         &ssc0_clk,
194         &ssc1_clk,
195         &ssc2_clk,
196         &tc0_clk,
197         &tc1_clk,
198         &tc2_clk,
199         &ohci_clk,
200         &ssc3_clk,
201         &twi1_clk,
202         &can0_clk,
203         &can1_clk,
204         &mAgicV_clk,
205         /* irq0 .. irq2 */
206 };
207
208 /*
209  * The five programmable clocks.
210  * You must configure pin multiplexing to bring these signals out.
211  */
212 static struct clk pck0 = {
213         .name           = "pck0",
214         .pmc_mask       = AT91_PMC_PCK0,
215         .type           = CLK_TYPE_PROGRAMMABLE,
216         .id             = 0,
217 };
218 static struct clk pck1 = {
219         .name           = "pck1",
220         .pmc_mask       = AT91_PMC_PCK1,
221         .type           = CLK_TYPE_PROGRAMMABLE,
222         .id             = 1,
223 };
224 static struct clk pck2 = {
225         .name           = "pck2",
226         .pmc_mask       = AT91_PMC_PCK2,
227         .type           = CLK_TYPE_PROGRAMMABLE,
228         .id             = 2,
229 };
230 static struct clk pck3 = {
231         .name           = "pck3",
232         .pmc_mask       = AT91_PMC_PCK3,
233         .type           = CLK_TYPE_PROGRAMMABLE,
234         .id             = 3,
235 };
236
237 static struct clk mAgicV_mem_clk = {
238         .name           = "mAgicV_mem_clk",
239         .pmc_mask       = AT91_PMC_PCK4,
240         .type           = CLK_TYPE_PROGRAMMABLE,
241         .id             = 4,
242 };
243
244 /* HClocks */
245 static struct clk hck0 = {
246         .name           = "hck0",
247         .pmc_mask       = AT91_PMC_HCK0,
248         .type           = CLK_TYPE_SYSTEM,
249         .id             = 0,
250 };
251 static struct clk hck1 = {
252         .name           = "hck1",
253         .pmc_mask       = AT91_PMC_HCK1,
254         .type           = CLK_TYPE_SYSTEM,
255         .id             = 1,
256 };
257
258 static void __init at572d940hf_register_clocks(void)
259 {
260         int i;
261
262         for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
263                 clk_register(periph_clocks[i]);
264
265         clk_register(&pck0);
266         clk_register(&pck1);
267         clk_register(&pck2);
268         clk_register(&pck3);
269         clk_register(&mAgicV_mem_clk);
270
271         clk_register(&hck0);
272         clk_register(&hck1);
273 }
274
275 /* --------------------------------------------------------------------
276  *  GPIO
277  * -------------------------------------------------------------------- */
278
279 static struct at91_gpio_bank at572d940hf_gpio[] = {
280         {
281                 .id             = AT572D940HF_ID_PIOA,
282                 .offset         = AT91_PIOA,
283                 .clock          = &pioA_clk,
284         }, {
285                 .id             = AT572D940HF_ID_PIOB,
286                 .offset         = AT91_PIOB,
287                 .clock          = &pioB_clk,
288         }, {
289                 .id             = AT572D940HF_ID_PIOC,
290                 .offset         = AT91_PIOC,
291                 .clock          = &pioC_clk,
292         }
293 };
294
295 static void at572d940hf_reset(void)
296 {
297         at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
298 }
299
300
301 /* --------------------------------------------------------------------
302  *  AT572D940HF processor initialization
303  * -------------------------------------------------------------------- */
304
305 void __init at572d940hf_initialize(unsigned long main_clock)
306 {
307         /* Map peripherals */
308         iotable_init(at572d940hf_io_desc, ARRAY_SIZE(at572d940hf_io_desc));
309
310         at91_arch_reset = at572d940hf_reset;
311         at91_extern_irq = (1 << AT572D940HF_ID_IRQ0) | (1 << AT572D940HF_ID_IRQ1)
312                         | (1 << AT572D940HF_ID_IRQ2);
313
314         /* Init clock subsystem */
315         at91_clock_init(main_clock);
316
317         /* Register the processor-specific clocks */
318         at572d940hf_register_clocks();
319
320         /* Register GPIO subsystem */
321         at91_gpio_init(at572d940hf_gpio, 3);
322 }
323
324 /* --------------------------------------------------------------------
325  *  Interrupt initialization
326  * -------------------------------------------------------------------- */
327
328 /*
329  * The default interrupt priority levels (0 = lowest, 7 = highest).
330  */
331 static unsigned int at572d940hf_default_irq_priority[NR_AIC_IRQS] __initdata = {
332         7,      /* Advanced Interrupt Controller */
333         7,      /* System Peripherals */
334         0,      /* Parallel IO Controller A */
335         0,      /* Parallel IO Controller B */
336         0,      /* Parallel IO Controller C */
337         3,      /* Ethernet */
338         6,      /* USART 0 */
339         6,      /* USART 1 */
340         6,      /* USART 2 */
341         0,      /* Multimedia Card Interface */
342         4,      /* USB Device Port */
343         0,      /* Two-Wire Interface 0 */
344         6,      /* Serial Peripheral Interface 0 */
345         6,      /* Serial Peripheral Interface 1 */
346         5,      /* Serial Synchronous Controller 0 */
347         5,      /* Serial Synchronous Controller 1 */
348         5,      /* Serial Synchronous Controller 2 */
349         0,      /* Timer Counter 0 */
350         0,      /* Timer Counter 1 */
351         0,      /* Timer Counter 2 */
352         3,      /* USB Host port */
353         3,      /* Serial Synchronous Controller 3 */
354         0,      /* Two-Wire Interface 1 */
355         0,      /* CAN Controller 0 */
356         0,      /* CAN Controller 1 */
357         0,      /* mAgicV HALT line */
358         0,      /* mAgicV SIRQ0 line */
359         0,      /* mAgicV exception line */
360         0,      /* mAgicV end of DMA line */
361         0,      /* Advanced Interrupt Controller */
362         0,      /* Advanced Interrupt Controller */
363         0,      /* Advanced Interrupt Controller */
364 };
365
366 void __init at572d940hf_init_interrupts(unsigned int priority[NR_AIC_IRQS])
367 {
368         if (!priority)
369                 priority = at572d940hf_default_irq_priority;
370
371         /* Initialize the AIC interrupt controller */
372         at91_aic_init(priority);
373
374         /* Enable GPIO interrupts */
375         at91_gpio_irq_setup();
376 }
377