Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-at91/at91sam9261.c
10817 views
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/cpu.h>
20
#include <mach/at91sam9261.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
28
static struct map_desc at91sam9261_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
37
static struct map_desc at91sam9261_sram_desc[] __initdata = {
38
{
39
.virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE,
40
.pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE),
41
.length = AT91SAM9261_SRAM_SIZE,
42
.type = MT_DEVICE,
43
},
44
};
45
46
static struct map_desc at91sam9g10_sram_desc[] __initdata = {
47
{
48
.virtual = AT91_IO_VIRT_BASE - AT91SAM9G10_SRAM_SIZE,
49
.pfn = __phys_to_pfn(AT91SAM9G10_SRAM_BASE),
50
.length = AT91SAM9G10_SRAM_SIZE,
51
.type = MT_DEVICE,
52
},
53
};
54
55
/* --------------------------------------------------------------------
56
* Clocks
57
* -------------------------------------------------------------------- */
58
59
/*
60
* The peripheral clocks.
61
*/
62
static struct clk pioA_clk = {
63
.name = "pioA_clk",
64
.pmc_mask = 1 << AT91SAM9261_ID_PIOA,
65
.type = CLK_TYPE_PERIPHERAL,
66
};
67
static struct clk pioB_clk = {
68
.name = "pioB_clk",
69
.pmc_mask = 1 << AT91SAM9261_ID_PIOB,
70
.type = CLK_TYPE_PERIPHERAL,
71
};
72
static struct clk pioC_clk = {
73
.name = "pioC_clk",
74
.pmc_mask = 1 << AT91SAM9261_ID_PIOC,
75
.type = CLK_TYPE_PERIPHERAL,
76
};
77
static struct clk usart0_clk = {
78
.name = "usart0_clk",
79
.pmc_mask = 1 << AT91SAM9261_ID_US0,
80
.type = CLK_TYPE_PERIPHERAL,
81
};
82
static struct clk usart1_clk = {
83
.name = "usart1_clk",
84
.pmc_mask = 1 << AT91SAM9261_ID_US1,
85
.type = CLK_TYPE_PERIPHERAL,
86
};
87
static struct clk usart2_clk = {
88
.name = "usart2_clk",
89
.pmc_mask = 1 << AT91SAM9261_ID_US2,
90
.type = CLK_TYPE_PERIPHERAL,
91
};
92
static struct clk mmc_clk = {
93
.name = "mci_clk",
94
.pmc_mask = 1 << AT91SAM9261_ID_MCI,
95
.type = CLK_TYPE_PERIPHERAL,
96
};
97
static struct clk udc_clk = {
98
.name = "udc_clk",
99
.pmc_mask = 1 << AT91SAM9261_ID_UDP,
100
.type = CLK_TYPE_PERIPHERAL,
101
};
102
static struct clk twi_clk = {
103
.name = "twi_clk",
104
.pmc_mask = 1 << AT91SAM9261_ID_TWI,
105
.type = CLK_TYPE_PERIPHERAL,
106
};
107
static struct clk spi0_clk = {
108
.name = "spi0_clk",
109
.pmc_mask = 1 << AT91SAM9261_ID_SPI0,
110
.type = CLK_TYPE_PERIPHERAL,
111
};
112
static struct clk spi1_clk = {
113
.name = "spi1_clk",
114
.pmc_mask = 1 << AT91SAM9261_ID_SPI1,
115
.type = CLK_TYPE_PERIPHERAL,
116
};
117
static struct clk ssc0_clk = {
118
.name = "ssc0_clk",
119
.pmc_mask = 1 << AT91SAM9261_ID_SSC0,
120
.type = CLK_TYPE_PERIPHERAL,
121
};
122
static struct clk ssc1_clk = {
123
.name = "ssc1_clk",
124
.pmc_mask = 1 << AT91SAM9261_ID_SSC1,
125
.type = CLK_TYPE_PERIPHERAL,
126
};
127
static struct clk ssc2_clk = {
128
.name = "ssc2_clk",
129
.pmc_mask = 1 << AT91SAM9261_ID_SSC2,
130
.type = CLK_TYPE_PERIPHERAL,
131
};
132
static struct clk tc0_clk = {
133
.name = "tc0_clk",
134
.pmc_mask = 1 << AT91SAM9261_ID_TC0,
135
.type = CLK_TYPE_PERIPHERAL,
136
};
137
static struct clk tc1_clk = {
138
.name = "tc1_clk",
139
.pmc_mask = 1 << AT91SAM9261_ID_TC1,
140
.type = CLK_TYPE_PERIPHERAL,
141
};
142
static struct clk tc2_clk = {
143
.name = "tc2_clk",
144
.pmc_mask = 1 << AT91SAM9261_ID_TC2,
145
.type = CLK_TYPE_PERIPHERAL,
146
};
147
static struct clk ohci_clk = {
148
.name = "ohci_clk",
149
.pmc_mask = 1 << AT91SAM9261_ID_UHP,
150
.type = CLK_TYPE_PERIPHERAL,
151
};
152
static struct clk lcdc_clk = {
153
.name = "lcdc_clk",
154
.pmc_mask = 1 << AT91SAM9261_ID_LCDC,
155
.type = CLK_TYPE_PERIPHERAL,
156
};
157
158
static struct clk *periph_clocks[] __initdata = {
159
&pioA_clk,
160
&pioB_clk,
161
&pioC_clk,
162
&usart0_clk,
163
&usart1_clk,
164
&usart2_clk,
165
&mmc_clk,
166
&udc_clk,
167
&twi_clk,
168
&spi0_clk,
169
&spi1_clk,
170
&ssc0_clk,
171
&ssc1_clk,
172
&ssc2_clk,
173
&tc0_clk,
174
&tc1_clk,
175
&tc2_clk,
176
&ohci_clk,
177
&lcdc_clk,
178
// irq0 .. irq2
179
};
180
181
static struct clk_lookup periph_clocks_lookups[] = {
182
CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
183
CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
184
CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
185
CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
186
CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc1_clk),
187
CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
188
CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
189
CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
190
};
191
192
static struct clk_lookup usart_clocks_lookups[] = {
193
CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
194
CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
195
CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
196
CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
197
};
198
199
/*
200
* The four programmable clocks.
201
* You must configure pin multiplexing to bring these signals out.
202
*/
203
static struct clk pck0 = {
204
.name = "pck0",
205
.pmc_mask = AT91_PMC_PCK0,
206
.type = CLK_TYPE_PROGRAMMABLE,
207
.id = 0,
208
};
209
static struct clk pck1 = {
210
.name = "pck1",
211
.pmc_mask = AT91_PMC_PCK1,
212
.type = CLK_TYPE_PROGRAMMABLE,
213
.id = 1,
214
};
215
static struct clk pck2 = {
216
.name = "pck2",
217
.pmc_mask = AT91_PMC_PCK2,
218
.type = CLK_TYPE_PROGRAMMABLE,
219
.id = 2,
220
};
221
static struct clk pck3 = {
222
.name = "pck3",
223
.pmc_mask = AT91_PMC_PCK3,
224
.type = CLK_TYPE_PROGRAMMABLE,
225
.id = 3,
226
};
227
228
/* HClocks */
229
static struct clk hck0 = {
230
.name = "hck0",
231
.pmc_mask = AT91_PMC_HCK0,
232
.type = CLK_TYPE_SYSTEM,
233
.id = 0,
234
};
235
static struct clk hck1 = {
236
.name = "hck1",
237
.pmc_mask = AT91_PMC_HCK1,
238
.type = CLK_TYPE_SYSTEM,
239
.id = 1,
240
};
241
242
static void __init at91sam9261_register_clocks(void)
243
{
244
int i;
245
246
for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
247
clk_register(periph_clocks[i]);
248
249
clkdev_add_table(periph_clocks_lookups,
250
ARRAY_SIZE(periph_clocks_lookups));
251
clkdev_add_table(usart_clocks_lookups,
252
ARRAY_SIZE(usart_clocks_lookups));
253
254
clk_register(&pck0);
255
clk_register(&pck1);
256
clk_register(&pck2);
257
clk_register(&pck3);
258
259
clk_register(&hck0);
260
clk_register(&hck1);
261
}
262
263
static struct clk_lookup console_clock_lookup;
264
265
void __init at91sam9261_set_console_clock(int id)
266
{
267
if (id >= ARRAY_SIZE(usart_clocks_lookups))
268
return;
269
270
console_clock_lookup.con_id = "usart";
271
console_clock_lookup.clk = usart_clocks_lookups[id].clk;
272
clkdev_add(&console_clock_lookup);
273
}
274
275
/* --------------------------------------------------------------------
276
* GPIO
277
* -------------------------------------------------------------------- */
278
279
static struct at91_gpio_bank at91sam9261_gpio[] = {
280
{
281
.id = AT91SAM9261_ID_PIOA,
282
.offset = AT91_PIOA,
283
.clock = &pioA_clk,
284
}, {
285
.id = AT91SAM9261_ID_PIOB,
286
.offset = AT91_PIOB,
287
.clock = &pioB_clk,
288
}, {
289
.id = AT91SAM9261_ID_PIOC,
290
.offset = AT91_PIOC,
291
.clock = &pioC_clk,
292
}
293
};
294
295
static void at91sam9261_poweroff(void)
296
{
297
at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
298
}
299
300
301
/* --------------------------------------------------------------------
302
* AT91SAM9261 processor initialization
303
* -------------------------------------------------------------------- */
304
305
void __init at91sam9261_map_io(void)
306
{
307
/* Map peripherals */
308
iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc));
309
310
if (cpu_is_at91sam9g10())
311
iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc));
312
else
313
iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc));
314
}
315
316
void __init at91sam9261_initialize(unsigned long main_clock)
317
{
318
at91_arch_reset = at91sam9_alt_reset;
319
pm_power_off = at91sam9261_poweroff;
320
at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
321
| (1 << AT91SAM9261_ID_IRQ2);
322
323
/* Init clock subsystem */
324
at91_clock_init(main_clock);
325
326
/* Register the processor-specific clocks */
327
at91sam9261_register_clocks();
328
329
/* Register GPIO subsystem */
330
at91_gpio_init(at91sam9261_gpio, 3);
331
}
332
333
/* --------------------------------------------------------------------
334
* Interrupt initialization
335
* -------------------------------------------------------------------- */
336
337
/*
338
* The default interrupt priority levels (0 = lowest, 7 = highest).
339
*/
340
static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
341
7, /* Advanced Interrupt Controller */
342
7, /* System Peripherals */
343
1, /* Parallel IO Controller A */
344
1, /* Parallel IO Controller B */
345
1, /* Parallel IO Controller C */
346
0,
347
5, /* USART 0 */
348
5, /* USART 1 */
349
5, /* USART 2 */
350
0, /* Multimedia Card Interface */
351
2, /* USB Device Port */
352
6, /* Two-Wire Interface */
353
5, /* Serial Peripheral Interface 0 */
354
5, /* Serial Peripheral Interface 1 */
355
4, /* Serial Synchronous Controller 0 */
356
4, /* Serial Synchronous Controller 1 */
357
4, /* Serial Synchronous Controller 2 */
358
0, /* Timer Counter 0 */
359
0, /* Timer Counter 1 */
360
0, /* Timer Counter 2 */
361
2, /* USB Host port */
362
3, /* LCD Controller */
363
0,
364
0,
365
0,
366
0,
367
0,
368
0,
369
0,
370
0, /* Advanced Interrupt Controller */
371
0, /* Advanced Interrupt Controller */
372
0, /* Advanced Interrupt Controller */
373
};
374
375
void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS])
376
{
377
if (!priority)
378
priority = at91sam9261_default_irq_priority;
379
380
/* Initialize the AIC interrupt controller */
381
at91_aic_init(priority);
382
383
/* Enable GPIO interrupts */
384
at91_gpio_irq_setup();
385
}
386
387