Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-at91/at91sam9g45.c
10817 views
1
/*
2
* Chip-specific setup code for the AT91SAM9G45 family
3
*
4
* Copyright (C) 2009 Atmel Corporation.
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/at91sam9g45.h>
20
#include <mach/at91_pmc.h>
21
#include <mach/at91_rstc.h>
22
#include <mach/at91_shdwc.h>
23
#include <mach/cpu.h>
24
25
#include "generic.h"
26
#include "clock.h"
27
28
static struct map_desc at91sam9g45_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
.virtual = AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE,
36
.pfn = __phys_to_pfn(AT91SAM9G45_SRAM_BASE),
37
.length = AT91SAM9G45_SRAM_SIZE,
38
.type = MT_DEVICE,
39
}
40
};
41
42
/* --------------------------------------------------------------------
43
* Clocks
44
* -------------------------------------------------------------------- */
45
46
/*
47
* The peripheral clocks.
48
*/
49
static struct clk pioA_clk = {
50
.name = "pioA_clk",
51
.pmc_mask = 1 << AT91SAM9G45_ID_PIOA,
52
.type = CLK_TYPE_PERIPHERAL,
53
};
54
static struct clk pioB_clk = {
55
.name = "pioB_clk",
56
.pmc_mask = 1 << AT91SAM9G45_ID_PIOB,
57
.type = CLK_TYPE_PERIPHERAL,
58
};
59
static struct clk pioC_clk = {
60
.name = "pioC_clk",
61
.pmc_mask = 1 << AT91SAM9G45_ID_PIOC,
62
.type = CLK_TYPE_PERIPHERAL,
63
};
64
static struct clk pioDE_clk = {
65
.name = "pioDE_clk",
66
.pmc_mask = 1 << AT91SAM9G45_ID_PIODE,
67
.type = CLK_TYPE_PERIPHERAL,
68
};
69
static struct clk usart0_clk = {
70
.name = "usart0_clk",
71
.pmc_mask = 1 << AT91SAM9G45_ID_US0,
72
.type = CLK_TYPE_PERIPHERAL,
73
};
74
static struct clk usart1_clk = {
75
.name = "usart1_clk",
76
.pmc_mask = 1 << AT91SAM9G45_ID_US1,
77
.type = CLK_TYPE_PERIPHERAL,
78
};
79
static struct clk usart2_clk = {
80
.name = "usart2_clk",
81
.pmc_mask = 1 << AT91SAM9G45_ID_US2,
82
.type = CLK_TYPE_PERIPHERAL,
83
};
84
static struct clk usart3_clk = {
85
.name = "usart3_clk",
86
.pmc_mask = 1 << AT91SAM9G45_ID_US3,
87
.type = CLK_TYPE_PERIPHERAL,
88
};
89
static struct clk mmc0_clk = {
90
.name = "mci0_clk",
91
.pmc_mask = 1 << AT91SAM9G45_ID_MCI0,
92
.type = CLK_TYPE_PERIPHERAL,
93
};
94
static struct clk twi0_clk = {
95
.name = "twi0_clk",
96
.pmc_mask = 1 << AT91SAM9G45_ID_TWI0,
97
.type = CLK_TYPE_PERIPHERAL,
98
};
99
static struct clk twi1_clk = {
100
.name = "twi1_clk",
101
.pmc_mask = 1 << AT91SAM9G45_ID_TWI1,
102
.type = CLK_TYPE_PERIPHERAL,
103
};
104
static struct clk spi0_clk = {
105
.name = "spi0_clk",
106
.pmc_mask = 1 << AT91SAM9G45_ID_SPI0,
107
.type = CLK_TYPE_PERIPHERAL,
108
};
109
static struct clk spi1_clk = {
110
.name = "spi1_clk",
111
.pmc_mask = 1 << AT91SAM9G45_ID_SPI1,
112
.type = CLK_TYPE_PERIPHERAL,
113
};
114
static struct clk ssc0_clk = {
115
.name = "ssc0_clk",
116
.pmc_mask = 1 << AT91SAM9G45_ID_SSC0,
117
.type = CLK_TYPE_PERIPHERAL,
118
};
119
static struct clk ssc1_clk = {
120
.name = "ssc1_clk",
121
.pmc_mask = 1 << AT91SAM9G45_ID_SSC1,
122
.type = CLK_TYPE_PERIPHERAL,
123
};
124
static struct clk tcb0_clk = {
125
.name = "tcb0_clk",
126
.pmc_mask = 1 << AT91SAM9G45_ID_TCB,
127
.type = CLK_TYPE_PERIPHERAL,
128
};
129
static struct clk pwm_clk = {
130
.name = "pwm_clk",
131
.pmc_mask = 1 << AT91SAM9G45_ID_PWMC,
132
.type = CLK_TYPE_PERIPHERAL,
133
};
134
static struct clk tsc_clk = {
135
.name = "tsc_clk",
136
.pmc_mask = 1 << AT91SAM9G45_ID_TSC,
137
.type = CLK_TYPE_PERIPHERAL,
138
};
139
static struct clk dma_clk = {
140
.name = "dma_clk",
141
.pmc_mask = 1 << AT91SAM9G45_ID_DMA,
142
.type = CLK_TYPE_PERIPHERAL,
143
};
144
static struct clk uhphs_clk = {
145
.name = "uhphs_clk",
146
.pmc_mask = 1 << AT91SAM9G45_ID_UHPHS,
147
.type = CLK_TYPE_PERIPHERAL,
148
};
149
static struct clk lcdc_clk = {
150
.name = "lcdc_clk",
151
.pmc_mask = 1 << AT91SAM9G45_ID_LCDC,
152
.type = CLK_TYPE_PERIPHERAL,
153
};
154
static struct clk ac97_clk = {
155
.name = "ac97_clk",
156
.pmc_mask = 1 << AT91SAM9G45_ID_AC97C,
157
.type = CLK_TYPE_PERIPHERAL,
158
};
159
static struct clk macb_clk = {
160
.name = "macb_clk",
161
.pmc_mask = 1 << AT91SAM9G45_ID_EMAC,
162
.type = CLK_TYPE_PERIPHERAL,
163
};
164
static struct clk isi_clk = {
165
.name = "isi_clk",
166
.pmc_mask = 1 << AT91SAM9G45_ID_ISI,
167
.type = CLK_TYPE_PERIPHERAL,
168
};
169
static struct clk udphs_clk = {
170
.name = "udphs_clk",
171
.pmc_mask = 1 << AT91SAM9G45_ID_UDPHS,
172
.type = CLK_TYPE_PERIPHERAL,
173
};
174
static struct clk mmc1_clk = {
175
.name = "mci1_clk",
176
.pmc_mask = 1 << AT91SAM9G45_ID_MCI1,
177
.type = CLK_TYPE_PERIPHERAL,
178
};
179
180
/* Video decoder clock - Only for sam9m10/sam9m11 */
181
static struct clk vdec_clk = {
182
.name = "vdec_clk",
183
.pmc_mask = 1 << AT91SAM9G45_ID_VDEC,
184
.type = CLK_TYPE_PERIPHERAL,
185
};
186
187
static struct clk *periph_clocks[] __initdata = {
188
&pioA_clk,
189
&pioB_clk,
190
&pioC_clk,
191
&pioDE_clk,
192
&usart0_clk,
193
&usart1_clk,
194
&usart2_clk,
195
&usart3_clk,
196
&mmc0_clk,
197
&twi0_clk,
198
&twi1_clk,
199
&spi0_clk,
200
&spi1_clk,
201
&ssc0_clk,
202
&ssc1_clk,
203
&tcb0_clk,
204
&pwm_clk,
205
&tsc_clk,
206
&dma_clk,
207
&uhphs_clk,
208
&lcdc_clk,
209
&ac97_clk,
210
&macb_clk,
211
&isi_clk,
212
&udphs_clk,
213
&mmc1_clk,
214
// irq0
215
};
216
217
static struct clk_lookup periph_clocks_lookups[] = {
218
/* One additional fake clock for ohci */
219
CLKDEV_CON_ID("ohci_clk", &uhphs_clk),
220
CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk),
221
CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
222
CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
223
CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk),
224
CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk),
225
CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
226
CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
227
CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk),
228
CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk),
229
CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
230
CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
231
};
232
233
static struct clk_lookup usart_clocks_lookups[] = {
234
CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
235
CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
236
CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
237
CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
238
CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk),
239
};
240
241
/*
242
* The two programmable clocks.
243
* You must configure pin multiplexing to bring these signals out.
244
*/
245
static struct clk pck0 = {
246
.name = "pck0",
247
.pmc_mask = AT91_PMC_PCK0,
248
.type = CLK_TYPE_PROGRAMMABLE,
249
.id = 0,
250
};
251
static struct clk pck1 = {
252
.name = "pck1",
253
.pmc_mask = AT91_PMC_PCK1,
254
.type = CLK_TYPE_PROGRAMMABLE,
255
.id = 1,
256
};
257
258
static void __init at91sam9g45_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
clkdev_add_table(periph_clocks_lookups,
266
ARRAY_SIZE(periph_clocks_lookups));
267
clkdev_add_table(usart_clocks_lookups,
268
ARRAY_SIZE(usart_clocks_lookups));
269
270
if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11())
271
clk_register(&vdec_clk);
272
273
clk_register(&pck0);
274
clk_register(&pck1);
275
}
276
277
static struct clk_lookup console_clock_lookup;
278
279
void __init at91sam9g45_set_console_clock(int id)
280
{
281
if (id >= ARRAY_SIZE(usart_clocks_lookups))
282
return;
283
284
console_clock_lookup.con_id = "usart";
285
console_clock_lookup.clk = usart_clocks_lookups[id].clk;
286
clkdev_add(&console_clock_lookup);
287
}
288
289
/* --------------------------------------------------------------------
290
* GPIO
291
* -------------------------------------------------------------------- */
292
293
static struct at91_gpio_bank at91sam9g45_gpio[] = {
294
{
295
.id = AT91SAM9G45_ID_PIOA,
296
.offset = AT91_PIOA,
297
.clock = &pioA_clk,
298
}, {
299
.id = AT91SAM9G45_ID_PIOB,
300
.offset = AT91_PIOB,
301
.clock = &pioB_clk,
302
}, {
303
.id = AT91SAM9G45_ID_PIOC,
304
.offset = AT91_PIOC,
305
.clock = &pioC_clk,
306
}, {
307
.id = AT91SAM9G45_ID_PIODE,
308
.offset = AT91_PIOD,
309
.clock = &pioDE_clk,
310
}, {
311
.id = AT91SAM9G45_ID_PIODE,
312
.offset = AT91_PIOE,
313
.clock = &pioDE_clk,
314
}
315
};
316
317
static void at91sam9g45_reset(void)
318
{
319
at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
320
}
321
322
static void at91sam9g45_poweroff(void)
323
{
324
at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
325
}
326
327
328
/* --------------------------------------------------------------------
329
* AT91SAM9G45 processor initialization
330
* -------------------------------------------------------------------- */
331
332
void __init at91sam9g45_map_io(void)
333
{
334
/* Map peripherals */
335
iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc));
336
}
337
338
void __init at91sam9g45_initialize(unsigned long main_clock)
339
{
340
at91_arch_reset = at91sam9g45_reset;
341
pm_power_off = at91sam9g45_poweroff;
342
at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
343
344
/* Init clock subsystem */
345
at91_clock_init(main_clock);
346
347
/* Register the processor-specific clocks */
348
at91sam9g45_register_clocks();
349
350
/* Register GPIO subsystem */
351
at91_gpio_init(at91sam9g45_gpio, 5);
352
}
353
354
/* --------------------------------------------------------------------
355
* Interrupt initialization
356
* -------------------------------------------------------------------- */
357
358
/*
359
* The default interrupt priority levels (0 = lowest, 7 = highest).
360
*/
361
static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
362
7, /* Advanced Interrupt Controller (FIQ) */
363
7, /* System Peripherals */
364
1, /* Parallel IO Controller A */
365
1, /* Parallel IO Controller B */
366
1, /* Parallel IO Controller C */
367
1, /* Parallel IO Controller D and E */
368
0,
369
5, /* USART 0 */
370
5, /* USART 1 */
371
5, /* USART 2 */
372
5, /* USART 3 */
373
0, /* Multimedia Card Interface 0 */
374
6, /* Two-Wire Interface 0 */
375
6, /* Two-Wire Interface 1 */
376
5, /* Serial Peripheral Interface 0 */
377
5, /* Serial Peripheral Interface 1 */
378
4, /* Serial Synchronous Controller 0 */
379
4, /* Serial Synchronous Controller 1 */
380
0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */
381
0, /* Pulse Width Modulation Controller */
382
0, /* Touch Screen Controller */
383
0, /* DMA Controller */
384
2, /* USB Host High Speed port */
385
3, /* LDC Controller */
386
5, /* AC97 Controller */
387
3, /* Ethernet */
388
0, /* Image Sensor Interface */
389
2, /* USB Device High speed port */
390
0,
391
0, /* Multimedia Card Interface 1 */
392
0,
393
0, /* Advanced Interrupt Controller (IRQ0) */
394
};
395
396
void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS])
397
{
398
if (!priority)
399
priority = at91sam9g45_default_irq_priority;
400
401
/* Initialize the AIC interrupt controller */
402
at91_aic_init(priority);
403
404
/* Enable GPIO interrupts */
405
at91_gpio_irq_setup();
406
}
407
408