• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/arm/mach-at91/
1/*
2 * arch/arm/mach-at91/at91rm9200.c
3 *
4 *  Copyright (C) 2005 SAN People
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14
15#include <asm/irq.h>
16#include <asm/mach/arch.h>
17#include <asm/mach/map.h>
18#include <mach/at91rm9200.h>
19#include <mach/at91_pmc.h>
20#include <mach/at91_st.h>
21
22#include "generic.h"
23#include "clock.h"
24
25static struct map_desc at91rm9200_io_desc[] __initdata = {
26	{
27		.virtual	= AT91_VA_BASE_SYS,
28		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
29		.length		= SZ_4K,
30		.type		= MT_DEVICE,
31	}, {
32		.virtual	= AT91_VA_BASE_EMAC,
33		.pfn		= __phys_to_pfn(AT91RM9200_BASE_EMAC),
34		.length		= SZ_16K,
35		.type		= MT_DEVICE,
36	}, {
37		.virtual	= AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE,
38		.pfn		= __phys_to_pfn(AT91RM9200_SRAM_BASE),
39		.length		= AT91RM9200_SRAM_SIZE,
40		.type		= MT_DEVICE,
41	},
42};
43
44/* --------------------------------------------------------------------
45 *  Clocks
46 * -------------------------------------------------------------------- */
47
48/*
49 * The peripheral clocks.
50 */
51static struct clk udc_clk = {
52	.name		= "udc_clk",
53	.pmc_mask	= 1 << AT91RM9200_ID_UDP,
54	.type		= CLK_TYPE_PERIPHERAL,
55};
56static struct clk ohci_clk = {
57	.name		= "ohci_clk",
58	.pmc_mask	= 1 << AT91RM9200_ID_UHP,
59	.type		= CLK_TYPE_PERIPHERAL,
60};
61static struct clk ether_clk = {
62	.name		= "ether_clk",
63	.pmc_mask	= 1 << AT91RM9200_ID_EMAC,
64	.type		= CLK_TYPE_PERIPHERAL,
65};
66static struct clk mmc_clk = {
67	.name		= "mci_clk",
68	.pmc_mask	= 1 << AT91RM9200_ID_MCI,
69	.type		= CLK_TYPE_PERIPHERAL,
70};
71static struct clk twi_clk = {
72	.name		= "twi_clk",
73	.pmc_mask	= 1 << AT91RM9200_ID_TWI,
74	.type		= CLK_TYPE_PERIPHERAL,
75};
76static struct clk usart0_clk = {
77	.name		= "usart0_clk",
78	.pmc_mask	= 1 << AT91RM9200_ID_US0,
79	.type		= CLK_TYPE_PERIPHERAL,
80};
81static struct clk usart1_clk = {
82	.name		= "usart1_clk",
83	.pmc_mask	= 1 << AT91RM9200_ID_US1,
84	.type		= CLK_TYPE_PERIPHERAL,
85};
86static struct clk usart2_clk = {
87	.name		= "usart2_clk",
88	.pmc_mask	= 1 << AT91RM9200_ID_US2,
89	.type		= CLK_TYPE_PERIPHERAL,
90};
91static struct clk usart3_clk = {
92	.name		= "usart3_clk",
93	.pmc_mask	= 1 << AT91RM9200_ID_US3,
94	.type		= CLK_TYPE_PERIPHERAL,
95};
96static struct clk spi_clk = {
97	.name		= "spi_clk",
98	.pmc_mask	= 1 << AT91RM9200_ID_SPI,
99	.type		= CLK_TYPE_PERIPHERAL,
100};
101static struct clk pioA_clk = {
102	.name		= "pioA_clk",
103	.pmc_mask	= 1 << AT91RM9200_ID_PIOA,
104	.type		= CLK_TYPE_PERIPHERAL,
105};
106static struct clk pioB_clk = {
107	.name		= "pioB_clk",
108	.pmc_mask	= 1 << AT91RM9200_ID_PIOB,
109	.type		= CLK_TYPE_PERIPHERAL,
110};
111static struct clk pioC_clk = {
112	.name		= "pioC_clk",
113	.pmc_mask	= 1 << AT91RM9200_ID_PIOC,
114	.type		= CLK_TYPE_PERIPHERAL,
115};
116static struct clk pioD_clk = {
117	.name		= "pioD_clk",
118	.pmc_mask	= 1 << AT91RM9200_ID_PIOD,
119	.type		= CLK_TYPE_PERIPHERAL,
120};
121static struct clk ssc0_clk = {
122	.name		= "ssc0_clk",
123	.pmc_mask	= 1 << AT91RM9200_ID_SSC0,
124	.type		= CLK_TYPE_PERIPHERAL,
125};
126static struct clk ssc1_clk = {
127	.name		= "ssc1_clk",
128	.pmc_mask	= 1 << AT91RM9200_ID_SSC1,
129	.type		= CLK_TYPE_PERIPHERAL,
130};
131static struct clk ssc2_clk = {
132	.name		= "ssc2_clk",
133	.pmc_mask	= 1 << AT91RM9200_ID_SSC2,
134	.type		= CLK_TYPE_PERIPHERAL,
135};
136static struct clk tc0_clk = {
137	.name		= "tc0_clk",
138	.pmc_mask	= 1 << AT91RM9200_ID_TC0,
139	.type		= CLK_TYPE_PERIPHERAL,
140};
141static struct clk tc1_clk = {
142	.name		= "tc1_clk",
143	.pmc_mask	= 1 << AT91RM9200_ID_TC1,
144	.type		= CLK_TYPE_PERIPHERAL,
145};
146static struct clk tc2_clk = {
147	.name		= "tc2_clk",
148	.pmc_mask	= 1 << AT91RM9200_ID_TC2,
149	.type		= CLK_TYPE_PERIPHERAL,
150};
151static struct clk tc3_clk = {
152	.name		= "tc3_clk",
153	.pmc_mask	= 1 << AT91RM9200_ID_TC3,
154	.type		= CLK_TYPE_PERIPHERAL,
155};
156static struct clk tc4_clk = {
157	.name		= "tc4_clk",
158	.pmc_mask	= 1 << AT91RM9200_ID_TC4,
159	.type		= CLK_TYPE_PERIPHERAL,
160};
161static struct clk tc5_clk = {
162	.name		= "tc5_clk",
163	.pmc_mask	= 1 << AT91RM9200_ID_TC5,
164	.type		= CLK_TYPE_PERIPHERAL,
165};
166
167static struct clk *periph_clocks[] __initdata = {
168	&pioA_clk,
169	&pioB_clk,
170	&pioC_clk,
171	&pioD_clk,
172	&usart0_clk,
173	&usart1_clk,
174	&usart2_clk,
175	&usart3_clk,
176	&mmc_clk,
177	&udc_clk,
178	&twi_clk,
179	&spi_clk,
180	&ssc0_clk,
181	&ssc1_clk,
182	&ssc2_clk,
183	&tc0_clk,
184	&tc1_clk,
185	&tc2_clk,
186	&tc3_clk,
187	&tc4_clk,
188	&tc5_clk,
189	&ohci_clk,
190	&ether_clk,
191	// irq0 .. irq6
192};
193
194/*
195 * The four programmable clocks.
196 * You must configure pin multiplexing to bring these signals out.
197 */
198static struct clk pck0 = {
199	.name		= "pck0",
200	.pmc_mask	= AT91_PMC_PCK0,
201	.type		= CLK_TYPE_PROGRAMMABLE,
202	.id		= 0,
203};
204static struct clk pck1 = {
205	.name		= "pck1",
206	.pmc_mask	= AT91_PMC_PCK1,
207	.type		= CLK_TYPE_PROGRAMMABLE,
208	.id		= 1,
209};
210static struct clk pck2 = {
211	.name		= "pck2",
212	.pmc_mask	= AT91_PMC_PCK2,
213	.type		= CLK_TYPE_PROGRAMMABLE,
214	.id		= 2,
215};
216static struct clk pck3 = {
217	.name		= "pck3",
218	.pmc_mask	= AT91_PMC_PCK3,
219	.type		= CLK_TYPE_PROGRAMMABLE,
220	.id		= 3,
221};
222
223static void __init at91rm9200_register_clocks(void)
224{
225	int i;
226
227	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
228		clk_register(periph_clocks[i]);
229
230	clk_register(&pck0);
231	clk_register(&pck1);
232	clk_register(&pck2);
233	clk_register(&pck3);
234}
235
236/* --------------------------------------------------------------------
237 *  GPIO
238 * -------------------------------------------------------------------- */
239
240static struct at91_gpio_bank at91rm9200_gpio[] = {
241	{
242		.id		= AT91RM9200_ID_PIOA,
243		.offset		= AT91_PIOA,
244		.clock		= &pioA_clk,
245	}, {
246		.id		= AT91RM9200_ID_PIOB,
247		.offset		= AT91_PIOB,
248		.clock		= &pioB_clk,
249	}, {
250		.id		= AT91RM9200_ID_PIOC,
251		.offset		= AT91_PIOC,
252		.clock		= &pioC_clk,
253	}, {
254		.id		= AT91RM9200_ID_PIOD,
255		.offset		= AT91_PIOD,
256		.clock		= &pioD_clk,
257	}
258};
259
260static void at91rm9200_reset(void)
261{
262	/*
263	 * Perform a hardware reset with the use of the Watchdog timer.
264	 */
265	at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
266	at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
267}
268
269
270/* --------------------------------------------------------------------
271 *  AT91RM9200 processor initialization
272 * -------------------------------------------------------------------- */
273void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks)
274{
275	/* Map peripherals */
276	iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
277
278	at91_arch_reset = at91rm9200_reset;
279	at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1)
280			| (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3)
281			| (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5)
282			| (1 << AT91RM9200_ID_IRQ6);
283
284	/* Init clock subsystem */
285	at91_clock_init(main_clock);
286
287	/* Register the processor-specific clocks */
288	at91rm9200_register_clocks();
289
290	/* Initialize GPIO subsystem */
291	at91_gpio_init(at91rm9200_gpio, banks);
292}
293
294
295/* --------------------------------------------------------------------
296 *  Interrupt initialization
297 * -------------------------------------------------------------------- */
298
299/*
300 * The default interrupt priority levels (0 = lowest, 7 = highest).
301 */
302static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
303	7,	/* Advanced Interrupt Controller (FIQ) */
304	7,	/* System Peripherals */
305	1,	/* Parallel IO Controller A */
306	1,	/* Parallel IO Controller B */
307	1,	/* Parallel IO Controller C */
308	1,	/* Parallel IO Controller D */
309	5,	/* USART 0 */
310	5,	/* USART 1 */
311	5,	/* USART 2 */
312	5,	/* USART 3 */
313	0,	/* Multimedia Card Interface */
314	2,	/* USB Device Port */
315	6,	/* Two-Wire Interface */
316	5,	/* Serial Peripheral Interface */
317	4,	/* Serial Synchronous Controller 0 */
318	4,	/* Serial Synchronous Controller 1 */
319	4,	/* Serial Synchronous Controller 2 */
320	0,	/* Timer Counter 0 */
321	0,	/* Timer Counter 1 */
322	0,	/* Timer Counter 2 */
323	0,	/* Timer Counter 3 */
324	0,	/* Timer Counter 4 */
325	0,	/* Timer Counter 5 */
326	2,	/* USB Host port */
327	3,	/* Ethernet MAC */
328	0,	/* Advanced Interrupt Controller (IRQ0) */
329	0,	/* Advanced Interrupt Controller (IRQ1) */
330	0,	/* Advanced Interrupt Controller (IRQ2) */
331	0,	/* Advanced Interrupt Controller (IRQ3) */
332	0,	/* Advanced Interrupt Controller (IRQ4) */
333	0,	/* Advanced Interrupt Controller (IRQ5) */
334	0	/* Advanced Interrupt Controller (IRQ6) */
335};
336
337void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS])
338{
339	if (!priority)
340		priority = at91rm9200_default_irq_priority;
341
342	/* Initialize the AIC interrupt controller */
343	at91_aic_init(priority);
344
345	/* Enable GPIO interrupts */
346	at91_gpio_irq_setup();
347}
348