• 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/at91sam9260.c
3 *
4 *  Copyright (C) 2006 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#include <linux/pm.h>
15
16#include <asm/irq.h>
17#include <asm/mach/arch.h>
18#include <asm/mach/map.h>
19#include <mach/cpu.h>
20#include <mach/at91sam9260.h>
21#include <mach/at91_pmc.h>
22#include <mach/at91_rstc.h>
23#include <mach/at91_shdwc.h>
24
25#include "generic.h"
26#include "clock.h"
27
28static struct map_desc at91sam9260_io_desc[] __initdata = {
29	{
30		.virtual	= AT91_VA_BASE_SYS,
31		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
32		.length		= SZ_16K,
33		.type		= MT_DEVICE,
34	}
35};
36
37static struct map_desc at91sam9260_sram_desc[] __initdata = {
38	{
39		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE,
40		.pfn		= __phys_to_pfn(AT91SAM9260_SRAM0_BASE),
41		.length		= AT91SAM9260_SRAM0_SIZE,
42		.type		= MT_DEVICE,
43	}, {
44		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE - AT91SAM9260_SRAM1_SIZE,
45		.pfn		= __phys_to_pfn(AT91SAM9260_SRAM1_BASE),
46		.length		= AT91SAM9260_SRAM1_SIZE,
47		.type		= MT_DEVICE,
48	}
49};
50
51static struct map_desc at91sam9g20_sram_desc[] __initdata = {
52	{
53		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE,
54		.pfn		= __phys_to_pfn(AT91SAM9G20_SRAM0_BASE),
55		.length		= AT91SAM9G20_SRAM0_SIZE,
56		.type		= MT_DEVICE,
57	}, {
58		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE - AT91SAM9G20_SRAM1_SIZE,
59		.pfn		= __phys_to_pfn(AT91SAM9G20_SRAM1_BASE),
60		.length		= AT91SAM9G20_SRAM1_SIZE,
61		.type		= MT_DEVICE,
62	}
63};
64
65static struct map_desc at91sam9xe_sram_desc[] __initdata = {
66	{
67		.pfn		= __phys_to_pfn(AT91SAM9XE_SRAM_BASE),
68		.type		= MT_DEVICE,
69	}
70};
71
72/* --------------------------------------------------------------------
73 *  Clocks
74 * -------------------------------------------------------------------- */
75
76/*
77 * The peripheral clocks.
78 */
79static struct clk pioA_clk = {
80	.name		= "pioA_clk",
81	.pmc_mask	= 1 << AT91SAM9260_ID_PIOA,
82	.type		= CLK_TYPE_PERIPHERAL,
83};
84static struct clk pioB_clk = {
85	.name		= "pioB_clk",
86	.pmc_mask	= 1 << AT91SAM9260_ID_PIOB,
87	.type		= CLK_TYPE_PERIPHERAL,
88};
89static struct clk pioC_clk = {
90	.name		= "pioC_clk",
91	.pmc_mask	= 1 << AT91SAM9260_ID_PIOC,
92	.type		= CLK_TYPE_PERIPHERAL,
93};
94static struct clk adc_clk = {
95	.name		= "adc_clk",
96	.pmc_mask	= 1 << AT91SAM9260_ID_ADC,
97	.type		= CLK_TYPE_PERIPHERAL,
98};
99static struct clk usart0_clk = {
100	.name		= "usart0_clk",
101	.pmc_mask	= 1 << AT91SAM9260_ID_US0,
102	.type		= CLK_TYPE_PERIPHERAL,
103};
104static struct clk usart1_clk = {
105	.name		= "usart1_clk",
106	.pmc_mask	= 1 << AT91SAM9260_ID_US1,
107	.type		= CLK_TYPE_PERIPHERAL,
108};
109static struct clk usart2_clk = {
110	.name		= "usart2_clk",
111	.pmc_mask	= 1 << AT91SAM9260_ID_US2,
112	.type		= CLK_TYPE_PERIPHERAL,
113};
114static struct clk mmc_clk = {
115	.name		= "mci_clk",
116	.pmc_mask	= 1 << AT91SAM9260_ID_MCI,
117	.type		= CLK_TYPE_PERIPHERAL,
118};
119static struct clk udc_clk = {
120	.name		= "udc_clk",
121	.pmc_mask	= 1 << AT91SAM9260_ID_UDP,
122	.type		= CLK_TYPE_PERIPHERAL,
123};
124static struct clk twi_clk = {
125	.name		= "twi_clk",
126	.pmc_mask	= 1 << AT91SAM9260_ID_TWI,
127	.type		= CLK_TYPE_PERIPHERAL,
128};
129static struct clk spi0_clk = {
130	.name		= "spi0_clk",
131	.pmc_mask	= 1 << AT91SAM9260_ID_SPI0,
132	.type		= CLK_TYPE_PERIPHERAL,
133};
134static struct clk spi1_clk = {
135	.name		= "spi1_clk",
136	.pmc_mask	= 1 << AT91SAM9260_ID_SPI1,
137	.type		= CLK_TYPE_PERIPHERAL,
138};
139static struct clk ssc_clk = {
140	.name		= "ssc_clk",
141	.pmc_mask	= 1 << AT91SAM9260_ID_SSC,
142	.type		= CLK_TYPE_PERIPHERAL,
143};
144static struct clk tc0_clk = {
145	.name		= "tc0_clk",
146	.pmc_mask	= 1 << AT91SAM9260_ID_TC0,
147	.type		= CLK_TYPE_PERIPHERAL,
148};
149static struct clk tc1_clk = {
150	.name		= "tc1_clk",
151	.pmc_mask	= 1 << AT91SAM9260_ID_TC1,
152	.type		= CLK_TYPE_PERIPHERAL,
153};
154static struct clk tc2_clk = {
155	.name		= "tc2_clk",
156	.pmc_mask	= 1 << AT91SAM9260_ID_TC2,
157	.type		= CLK_TYPE_PERIPHERAL,
158};
159static struct clk ohci_clk = {
160	.name		= "ohci_clk",
161	.pmc_mask	= 1 << AT91SAM9260_ID_UHP,
162	.type		= CLK_TYPE_PERIPHERAL,
163};
164static struct clk macb_clk = {
165	.name		= "macb_clk",
166	.pmc_mask	= 1 << AT91SAM9260_ID_EMAC,
167	.type		= CLK_TYPE_PERIPHERAL,
168};
169static struct clk isi_clk = {
170	.name		= "isi_clk",
171	.pmc_mask	= 1 << AT91SAM9260_ID_ISI,
172	.type		= CLK_TYPE_PERIPHERAL,
173};
174static struct clk usart3_clk = {
175	.name		= "usart3_clk",
176	.pmc_mask	= 1 << AT91SAM9260_ID_US3,
177	.type		= CLK_TYPE_PERIPHERAL,
178};
179static struct clk usart4_clk = {
180	.name		= "usart4_clk",
181	.pmc_mask	= 1 << AT91SAM9260_ID_US4,
182	.type		= CLK_TYPE_PERIPHERAL,
183};
184static struct clk usart5_clk = {
185	.name		= "usart5_clk",
186	.pmc_mask	= 1 << AT91SAM9260_ID_US5,
187	.type		= CLK_TYPE_PERIPHERAL,
188};
189static struct clk tc3_clk = {
190	.name		= "tc3_clk",
191	.pmc_mask	= 1 << AT91SAM9260_ID_TC3,
192	.type		= CLK_TYPE_PERIPHERAL,
193};
194static struct clk tc4_clk = {
195	.name		= "tc4_clk",
196	.pmc_mask	= 1 << AT91SAM9260_ID_TC4,
197	.type		= CLK_TYPE_PERIPHERAL,
198};
199static struct clk tc5_clk = {
200	.name		= "tc5_clk",
201	.pmc_mask	= 1 << AT91SAM9260_ID_TC5,
202	.type		= CLK_TYPE_PERIPHERAL,
203};
204
205static struct clk *periph_clocks[] __initdata = {
206	&pioA_clk,
207	&pioB_clk,
208	&pioC_clk,
209	&adc_clk,
210	&usart0_clk,
211	&usart1_clk,
212	&usart2_clk,
213	&mmc_clk,
214	&udc_clk,
215	&twi_clk,
216	&spi0_clk,
217	&spi1_clk,
218	&ssc_clk,
219	&tc0_clk,
220	&tc1_clk,
221	&tc2_clk,
222	&ohci_clk,
223	&macb_clk,
224	&isi_clk,
225	&usart3_clk,
226	&usart4_clk,
227	&usart5_clk,
228	&tc3_clk,
229	&tc4_clk,
230	&tc5_clk,
231	// irq0 .. irq2
232};
233
234/*
235 * The two programmable clocks.
236 * You must configure pin multiplexing to bring these signals out.
237 */
238static struct clk pck0 = {
239	.name		= "pck0",
240	.pmc_mask	= AT91_PMC_PCK0,
241	.type		= CLK_TYPE_PROGRAMMABLE,
242	.id		= 0,
243};
244static struct clk pck1 = {
245	.name		= "pck1",
246	.pmc_mask	= AT91_PMC_PCK1,
247	.type		= CLK_TYPE_PROGRAMMABLE,
248	.id		= 1,
249};
250
251static void __init at91sam9260_register_clocks(void)
252{
253	int i;
254
255	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
256		clk_register(periph_clocks[i]);
257
258	clk_register(&pck0);
259	clk_register(&pck1);
260}
261
262/* --------------------------------------------------------------------
263 *  GPIO
264 * -------------------------------------------------------------------- */
265
266static struct at91_gpio_bank at91sam9260_gpio[] = {
267	{
268		.id		= AT91SAM9260_ID_PIOA,
269		.offset		= AT91_PIOA,
270		.clock		= &pioA_clk,
271	}, {
272		.id		= AT91SAM9260_ID_PIOB,
273		.offset		= AT91_PIOB,
274		.clock		= &pioB_clk,
275	}, {
276		.id		= AT91SAM9260_ID_PIOC,
277		.offset		= AT91_PIOC,
278		.clock		= &pioC_clk,
279	}
280};
281
282static void at91sam9260_reset(void)
283{
284	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
285}
286
287static void at91sam9260_poweroff(void)
288{
289	at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
290}
291
292
293/* --------------------------------------------------------------------
294 *  AT91SAM9260 processor initialization
295 * -------------------------------------------------------------------- */
296
297static void __init at91sam9xe_initialize(void)
298{
299	unsigned long cidr, sram_size;
300
301	cidr = at91_sys_read(AT91_DBGU_CIDR);
302
303	switch (cidr & AT91_CIDR_SRAMSIZ) {
304		case AT91_CIDR_SRAMSIZ_32K:
305			sram_size = 2 * SZ_16K;
306			break;
307		case AT91_CIDR_SRAMSIZ_16K:
308		default:
309			sram_size = SZ_16K;
310	}
311
312	at91sam9xe_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size;
313	at91sam9xe_sram_desc->length = sram_size;
314
315	iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc));
316}
317
318void __init at91sam9260_initialize(unsigned long main_clock)
319{
320	/* Map peripherals */
321	iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc));
322
323	if (cpu_is_at91sam9xe())
324		at91sam9xe_initialize();
325	else if (cpu_is_at91sam9g20())
326		iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc));
327	else
328		iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc));
329
330	at91_arch_reset = at91sam9260_reset;
331	pm_power_off = at91sam9260_poweroff;
332	at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
333			| (1 << AT91SAM9260_ID_IRQ2);
334
335	/* Init clock subsystem */
336	at91_clock_init(main_clock);
337
338	/* Register the processor-specific clocks */
339	at91sam9260_register_clocks();
340
341	/* Register GPIO subsystem */
342	at91_gpio_init(at91sam9260_gpio, 3);
343}
344
345/* --------------------------------------------------------------------
346 *  Interrupt initialization
347 * -------------------------------------------------------------------- */
348
349/*
350 * The default interrupt priority levels (0 = lowest, 7 = highest).
351 */
352static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
353	7,	/* Advanced Interrupt Controller */
354	7,	/* System Peripherals */
355	1,	/* Parallel IO Controller A */
356	1,	/* Parallel IO Controller B */
357	1,	/* Parallel IO Controller C */
358	0,	/* Analog-to-Digital Converter */
359	5,	/* USART 0 */
360	5,	/* USART 1 */
361	5,	/* USART 2 */
362	0,	/* Multimedia Card Interface */
363	2,	/* USB Device Port */
364	6,	/* Two-Wire Interface */
365	5,	/* Serial Peripheral Interface 0 */
366	5,	/* Serial Peripheral Interface 1 */
367	5,	/* Serial Synchronous Controller */
368	0,
369	0,
370	0,	/* Timer Counter 0 */
371	0,	/* Timer Counter 1 */
372	0,	/* Timer Counter 2 */
373	2,	/* USB Host port */
374	3,	/* Ethernet */
375	0,	/* Image Sensor Interface */
376	5,	/* USART 3 */
377	5,	/* USART 4 */
378	5,	/* USART 5 */
379	0,	/* Timer Counter 3 */
380	0,	/* Timer Counter 4 */
381	0,	/* Timer Counter 5 */
382	0,	/* Advanced Interrupt Controller */
383	0,	/* Advanced Interrupt Controller */
384	0,	/* Advanced Interrupt Controller */
385};
386
387void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS])
388{
389	if (!priority)
390		priority = at91sam9260_default_irq_priority;
391
392	/* Initialize the AIC interrupt controller */
393	at91_aic_init(priority);
394
395	/* Enable GPIO interrupts */
396	at91_gpio_irq_setup();
397}
398