• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * arch/arm/mach-at91/at91sam9261.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 #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/at91sam9261.h>
20 #include <mach/at91_pmc.h>
21 #include <mach/at91_rstc.h>
22 #include <mach/at91_shdwc.h>
23 
24 #include "generic.h"
25 #include "clock.h"
26 
27 static struct map_desc at91sam9261_io_desc[] __initdata = {
28 	{
29 		.virtual	= AT91_VA_BASE_SYS,
30 		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
31 		.length		= SZ_16K,
32 		.type		= MT_DEVICE,
33 	}, {
34 		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE,
35 		.pfn		= __phys_to_pfn(AT91SAM9261_SRAM_BASE),
36 		.length		= AT91SAM9261_SRAM_SIZE,
37 		.type		= MT_DEVICE,
38 	},
39 };
40 
41 /* --------------------------------------------------------------------
42  *  Clocks
43  * -------------------------------------------------------------------- */
44 
45 /*
46  * The peripheral clocks.
47  */
48 static struct clk pioA_clk = {
49 	.name		= "pioA_clk",
50 	.pmc_mask	= 1 << AT91SAM9261_ID_PIOA,
51 	.type		= CLK_TYPE_PERIPHERAL,
52 };
53 static struct clk pioB_clk = {
54 	.name		= "pioB_clk",
55 	.pmc_mask	= 1 << AT91SAM9261_ID_PIOB,
56 	.type		= CLK_TYPE_PERIPHERAL,
57 };
58 static struct clk pioC_clk = {
59 	.name		= "pioC_clk",
60 	.pmc_mask	= 1 << AT91SAM9261_ID_PIOC,
61 	.type		= CLK_TYPE_PERIPHERAL,
62 };
63 static struct clk usart0_clk = {
64 	.name		= "usart0_clk",
65 	.pmc_mask	= 1 << AT91SAM9261_ID_US0,
66 	.type		= CLK_TYPE_PERIPHERAL,
67 };
68 static struct clk usart1_clk = {
69 	.name		= "usart1_clk",
70 	.pmc_mask	= 1 << AT91SAM9261_ID_US1,
71 	.type		= CLK_TYPE_PERIPHERAL,
72 };
73 static struct clk usart2_clk = {
74 	.name		= "usart2_clk",
75 	.pmc_mask	= 1 << AT91SAM9261_ID_US2,
76 	.type		= CLK_TYPE_PERIPHERAL,
77 };
78 static struct clk mmc_clk = {
79 	.name		= "mci_clk",
80 	.pmc_mask	= 1 << AT91SAM9261_ID_MCI,
81 	.type		= CLK_TYPE_PERIPHERAL,
82 };
83 static struct clk udc_clk = {
84 	.name		= "udc_clk",
85 	.pmc_mask	= 1 << AT91SAM9261_ID_UDP,
86 	.type		= CLK_TYPE_PERIPHERAL,
87 };
88 static struct clk twi_clk = {
89 	.name		= "twi_clk",
90 	.pmc_mask	= 1 << AT91SAM9261_ID_TWI,
91 	.type		= CLK_TYPE_PERIPHERAL,
92 };
93 static struct clk spi0_clk = {
94 	.name		= "spi0_clk",
95 	.pmc_mask	= 1 << AT91SAM9261_ID_SPI0,
96 	.type		= CLK_TYPE_PERIPHERAL,
97 };
98 static struct clk spi1_clk = {
99 	.name		= "spi1_clk",
100 	.pmc_mask	= 1 << AT91SAM9261_ID_SPI1,
101 	.type		= CLK_TYPE_PERIPHERAL,
102 };
103 static struct clk ssc0_clk = {
104 	.name		= "ssc0_clk",
105 	.pmc_mask	= 1 << AT91SAM9261_ID_SSC0,
106 	.type		= CLK_TYPE_PERIPHERAL,
107 };
108 static struct clk ssc1_clk = {
109 	.name		= "ssc1_clk",
110 	.pmc_mask	= 1 << AT91SAM9261_ID_SSC1,
111 	.type		= CLK_TYPE_PERIPHERAL,
112 };
113 static struct clk ssc2_clk = {
114 	.name		= "ssc2_clk",
115 	.pmc_mask	= 1 << AT91SAM9261_ID_SSC2,
116 	.type		= CLK_TYPE_PERIPHERAL,
117 };
118 static struct clk tc0_clk = {
119 	.name		= "tc0_clk",
120 	.pmc_mask	= 1 << AT91SAM9261_ID_TC0,
121 	.type		= CLK_TYPE_PERIPHERAL,
122 };
123 static struct clk tc1_clk = {
124 	.name		= "tc1_clk",
125 	.pmc_mask	= 1 << AT91SAM9261_ID_TC1,
126 	.type		= CLK_TYPE_PERIPHERAL,
127 };
128 static struct clk tc2_clk = {
129 	.name		= "tc2_clk",
130 	.pmc_mask	= 1 << AT91SAM9261_ID_TC2,
131 	.type		= CLK_TYPE_PERIPHERAL,
132 };
133 static struct clk ohci_clk = {
134 	.name		= "ohci_clk",
135 	.pmc_mask	= 1 << AT91SAM9261_ID_UHP,
136 	.type		= CLK_TYPE_PERIPHERAL,
137 };
138 static struct clk lcdc_clk = {
139 	.name		= "lcdc_clk",
140 	.pmc_mask	= 1 << AT91SAM9261_ID_LCDC,
141 	.type		= CLK_TYPE_PERIPHERAL,
142 };
143 
144 static struct clk *periph_clocks[] __initdata = {
145 	&pioA_clk,
146 	&pioB_clk,
147 	&pioC_clk,
148 	&usart0_clk,
149 	&usart1_clk,
150 	&usart2_clk,
151 	&mmc_clk,
152 	&udc_clk,
153 	&twi_clk,
154 	&spi0_clk,
155 	&spi1_clk,
156 	&ssc0_clk,
157 	&ssc1_clk,
158 	&ssc2_clk,
159 	&tc0_clk,
160 	&tc1_clk,
161 	&tc2_clk,
162 	&ohci_clk,
163 	&lcdc_clk,
164 	// irq0 .. irq2
165 };
166 
167 /*
168  * The four programmable clocks.
169  * You must configure pin multiplexing to bring these signals out.
170  */
171 static struct clk pck0 = {
172 	.name		= "pck0",
173 	.pmc_mask	= AT91_PMC_PCK0,
174 	.type		= CLK_TYPE_PROGRAMMABLE,
175 	.id		= 0,
176 };
177 static struct clk pck1 = {
178 	.name		= "pck1",
179 	.pmc_mask	= AT91_PMC_PCK1,
180 	.type		= CLK_TYPE_PROGRAMMABLE,
181 	.id		= 1,
182 };
183 static struct clk pck2 = {
184 	.name		= "pck2",
185 	.pmc_mask	= AT91_PMC_PCK2,
186 	.type		= CLK_TYPE_PROGRAMMABLE,
187 	.id		= 2,
188 };
189 static struct clk pck3 = {
190 	.name		= "pck3",
191 	.pmc_mask	= AT91_PMC_PCK3,
192 	.type		= CLK_TYPE_PROGRAMMABLE,
193 	.id		= 3,
194 };
195 
196 /* HClocks */
197 static struct clk hck0 = {
198 	.name		= "hck0",
199 	.pmc_mask	= AT91_PMC_HCK0,
200 	.type		= CLK_TYPE_SYSTEM,
201 	.id		= 0,
202 };
203 static struct clk hck1 = {
204 	.name		= "hck1",
205 	.pmc_mask	= AT91_PMC_HCK1,
206 	.type		= CLK_TYPE_SYSTEM,
207 	.id		= 1,
208 };
209 
at91sam9261_register_clocks(void)210 static void __init at91sam9261_register_clocks(void)
211 {
212 	int i;
213 
214 	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
215 		clk_register(periph_clocks[i]);
216 
217 	clk_register(&pck0);
218 	clk_register(&pck1);
219 	clk_register(&pck2);
220 	clk_register(&pck3);
221 
222 	clk_register(&hck0);
223 	clk_register(&hck1);
224 }
225 
226 /* --------------------------------------------------------------------
227  *  GPIO
228  * -------------------------------------------------------------------- */
229 
230 static struct at91_gpio_bank at91sam9261_gpio[] = {
231 	{
232 		.id		= AT91SAM9261_ID_PIOA,
233 		.offset		= AT91_PIOA,
234 		.clock		= &pioA_clk,
235 	}, {
236 		.id		= AT91SAM9261_ID_PIOB,
237 		.offset		= AT91_PIOB,
238 		.clock		= &pioB_clk,
239 	}, {
240 		.id		= AT91SAM9261_ID_PIOC,
241 		.offset		= AT91_PIOC,
242 		.clock		= &pioC_clk,
243 	}
244 };
245 
at91sam9261_reset(void)246 static void at91sam9261_reset(void)
247 {
248 	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
249 }
250 
at91sam9261_poweroff(void)251 static void at91sam9261_poweroff(void)
252 {
253 	at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
254 }
255 
256 
257 /* --------------------------------------------------------------------
258  *  AT91SAM9261 processor initialization
259  * -------------------------------------------------------------------- */
260 
at91sam9261_initialize(unsigned long main_clock)261 void __init at91sam9261_initialize(unsigned long main_clock)
262 {
263 	/* Map peripherals */
264 	iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc));
265 
266 	at91_arch_reset = at91sam9261_reset;
267 	pm_power_off = at91sam9261_poweroff;
268 	at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
269 			| (1 << AT91SAM9261_ID_IRQ2);
270 
271 	/* Init clock subsystem */
272 	at91_clock_init(main_clock);
273 
274 	/* Register the processor-specific clocks */
275 	at91sam9261_register_clocks();
276 
277 	/* Register GPIO subsystem */
278 	at91_gpio_init(at91sam9261_gpio, 3);
279 }
280 
281 /* --------------------------------------------------------------------
282  *  Interrupt initialization
283  * -------------------------------------------------------------------- */
284 
285 /*
286  * The default interrupt priority levels (0 = lowest, 7 = highest).
287  */
288 static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
289 	7,	/* Advanced Interrupt Controller */
290 	7,	/* System Peripherals */
291 	1,	/* Parallel IO Controller A */
292 	1,	/* Parallel IO Controller B */
293 	1,	/* Parallel IO Controller C */
294 	0,
295 	5,	/* USART 0 */
296 	5,	/* USART 1 */
297 	5,	/* USART 2 */
298 	0,	/* Multimedia Card Interface */
299 	2,	/* USB Device Port */
300 	6,	/* Two-Wire Interface */
301 	5,	/* Serial Peripheral Interface 0 */
302 	5,	/* Serial Peripheral Interface 1 */
303 	4,	/* Serial Synchronous Controller 0 */
304 	4,	/* Serial Synchronous Controller 1 */
305 	4,	/* Serial Synchronous Controller 2 */
306 	0,	/* Timer Counter 0 */
307 	0,	/* Timer Counter 1 */
308 	0,	/* Timer Counter 2 */
309 	2,	/* USB Host port */
310 	3,	/* LCD Controller */
311 	0,
312 	0,
313 	0,
314 	0,
315 	0,
316 	0,
317 	0,
318 	0,	/* Advanced Interrupt Controller */
319 	0,	/* Advanced Interrupt Controller */
320 	0,	/* Advanced Interrupt Controller */
321 };
322 
at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS])323 void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS])
324 {
325 	if (!priority)
326 		priority = at91sam9261_default_irq_priority;
327 
328 	/* Initialize the AIC interrupt controller */
329 	at91_aic_init(priority);
330 
331 	/* Enable GPIO interrupts */
332 	at91_gpio_irq_setup();
333 }
334