diff options
Diffstat (limited to 'arch/arm/mach-at91')
29 files changed, 7191 insertions, 0 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig new file mode 100644 index 000000000000..9f11db8af233 --- /dev/null +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -0,0 +1,148 @@ | |||
1 | if ARCH_AT91 | ||
2 | |||
3 | menu "Atmel AT91 System-on-Chip" | ||
4 | |||
5 | choice | ||
6 | prompt "Atmel AT91 Processor" | ||
7 | |||
8 | config ARCH_AT91RM9200 | ||
9 | bool "AT91RM9200" | ||
10 | |||
11 | config ARCH_AT91SAM9260 | ||
12 | bool "AT91SAM9260" | ||
13 | |||
14 | config ARCH_AT91SAM9261 | ||
15 | bool "AT91SAM9261" | ||
16 | |||
17 | endchoice | ||
18 | |||
19 | # ---------------------------------------------------------- | ||
20 | |||
21 | if ARCH_AT91RM9200 | ||
22 | |||
23 | comment "AT91RM9200 Board Type" | ||
24 | |||
25 | config MACH_ONEARM | ||
26 | bool "Ajeco 1ARM Single Board Computer" | ||
27 | depends on ARCH_AT91RM9200 | ||
28 | help | ||
29 | Select this if you are using Ajeco's 1ARM Single Board Computer. | ||
30 | <http://www.ajeco.fi/products.htm> | ||
31 | |||
32 | config ARCH_AT91RM9200DK | ||
33 | bool "Atmel AT91RM9200-DK Development board" | ||
34 | depends on ARCH_AT91RM9200 | ||
35 | help | ||
36 | Select this if you are using Atmel's AT91RM9200-DK Development board. | ||
37 | (Discontinued) | ||
38 | |||
39 | config MACH_AT91RM9200EK | ||
40 | bool "Atmel AT91RM9200-EK Evaluation Kit" | ||
41 | depends on ARCH_AT91RM9200 | ||
42 | help | ||
43 | Select this if you are using Atmel's AT91RM9200-EK Evaluation Kit. | ||
44 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3507> | ||
45 | |||
46 | config MACH_CSB337 | ||
47 | bool "Cogent CSB337" | ||
48 | depends on ARCH_AT91RM9200 | ||
49 | help | ||
50 | Select this if you are using Cogent's CSB337 board. | ||
51 | <http://www.cogcomp.com/csb_csb337.htm> | ||
52 | |||
53 | config MACH_CSB637 | ||
54 | bool "Cogent CSB637" | ||
55 | depends on ARCH_AT91RM9200 | ||
56 | help | ||
57 | Select this if you are using Cogent's CSB637 board. | ||
58 | <http://www.cogcomp.com/csb_csb637.htm> | ||
59 | |||
60 | config MACH_CARMEVA | ||
61 | bool "Conitec ARM&EVA" | ||
62 | depends on ARCH_AT91RM9200 | ||
63 | help | ||
64 | Select this if you are using Conitec's AT91RM9200-MCU-Module. | ||
65 | <http://www.conitec.net/english/linuxboard.htm> | ||
66 | |||
67 | config MACH_ATEB9200 | ||
68 | bool "Embest ATEB9200" | ||
69 | depends on ARCH_AT91RM9200 | ||
70 | help | ||
71 | Select this if you are using Embest's ATEB9200 board. | ||
72 | <http://www.embedinfo.com/english/product/ATEB9200.asp> | ||
73 | |||
74 | config MACH_KB9200 | ||
75 | bool "KwikByte KB920x" | ||
76 | depends on ARCH_AT91RM9200 | ||
77 | help | ||
78 | Select this if you are using KwikByte's KB920x board. | ||
79 | <http://kwikbyte.com/KB9202_description_new.htm> | ||
80 | |||
81 | config MACH_KAFA | ||
82 | bool "Sperry-Sun KAFA board" | ||
83 | depends on ARCH_AT91RM9200 | ||
84 | help | ||
85 | Select this if you are using Sperry-Sun's KAFA board. | ||
86 | |||
87 | endif | ||
88 | |||
89 | # ---------------------------------------------------------- | ||
90 | |||
91 | if ARCH_AT91SAM9260 | ||
92 | |||
93 | comment "AT91SAM9260 Board Type" | ||
94 | |||
95 | config MACH_AT91SAM9260EK | ||
96 | bool "Atmel AT91SAM9260-EK Evaluation Kit" | ||
97 | depends on ARCH_AT91SAM9260 | ||
98 | help | ||
99 | Select this if you are using Atmel's AT91SAM9260-EK Evaluation Kit. | ||
100 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933> | ||
101 | |||
102 | endif | ||
103 | |||
104 | # ---------------------------------------------------------- | ||
105 | |||
106 | if ARCH_AT91SAM9261 | ||
107 | |||
108 | comment "AT91SAM9261 Board Type" | ||
109 | |||
110 | config MACH_AT91SAM9261EK | ||
111 | bool "Atmel AT91SAM9261-EK Evaluation Kit" | ||
112 | depends on ARCH_AT91SAM9261 | ||
113 | help | ||
114 | Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit. | ||
115 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3820> | ||
116 | |||
117 | endif | ||
118 | |||
119 | # ---------------------------------------------------------- | ||
120 | |||
121 | comment "AT91 Board Options" | ||
122 | |||
123 | config MTD_AT91_DATAFLASH_CARD | ||
124 | bool "Enable DataFlash Card support" | ||
125 | depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK) | ||
126 | help | ||
127 | Enable support for the DataFlash card. | ||
128 | |||
129 | config MTD_NAND_AT91_BUSWIDTH_16 | ||
130 | bool "Enable 16-bit data bus interface to NAND flash" | ||
131 | depends on (MACH_AT91SAM9261EK || MACH_AT91SAM9260EK) | ||
132 | help | ||
133 | On AT91SAM926x boards both types of NAND flash can be present | ||
134 | (8 and 16 bit data bus width). | ||
135 | |||
136 | # ---------------------------------------------------------- | ||
137 | |||
138 | comment "AT91 Feature Selections" | ||
139 | |||
140 | config AT91_PROGRAMMABLE_CLOCKS | ||
141 | bool "Programmable Clocks" | ||
142 | help | ||
143 | Select this if you need to program one or more of the PCK0..PCK3 | ||
144 | programmable clock outputs. | ||
145 | |||
146 | endmenu | ||
147 | |||
148 | endif | ||
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile new file mode 100644 index 000000000000..cf777007847a --- /dev/null +++ b/arch/arm/mach-at91/Makefile | |||
@@ -0,0 +1,49 @@ | |||
1 | # | ||
2 | # Makefile for the linux kernel. | ||
3 | # | ||
4 | |||
5 | obj-y := clock.o irq.o gpio.o | ||
6 | obj-m := | ||
7 | obj-n := | ||
8 | obj- := | ||
9 | |||
10 | obj-$(CONFIG_PM) += pm.o | ||
11 | |||
12 | # CPU-specific support | ||
13 | obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o | ||
14 | obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o | ||
15 | obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o | ||
16 | |||
17 | # AT91RM9200 board-specific support | ||
18 | obj-$(CONFIG_MACH_ONEARM) += board-1arm.o | ||
19 | obj-$(CONFIG_ARCH_AT91RM9200DK) += board-dk.o | ||
20 | obj-$(CONFIG_MACH_AT91RM9200EK) += board-ek.o | ||
21 | obj-$(CONFIG_MACH_CSB337) += board-csb337.o | ||
22 | obj-$(CONFIG_MACH_CSB637) += board-csb637.o | ||
23 | obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o | ||
24 | obj-$(CONFIG_MACH_KB9200) += board-kb9202.o | ||
25 | obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o | ||
26 | obj-$(CONFIG_MACH_KAFA) += board-kafa.o | ||
27 | |||
28 | # AT91SAM9260 board-specific support | ||
29 | obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o | ||
30 | |||
31 | # AT91SAM9261 board-specific support | ||
32 | obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o | ||
33 | |||
34 | # LEDs support | ||
35 | led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o | ||
36 | led-$(CONFIG_MACH_AT91RM9200EK) += leds.o | ||
37 | led-$(CONFIG_MACH_CSB337) += leds.o | ||
38 | led-$(CONFIG_MACH_CSB637) += leds.o | ||
39 | led-$(CONFIG_MACH_KB9200) += leds.o | ||
40 | led-$(CONFIG_MACH_KAFA) += leds.o | ||
41 | obj-$(CONFIG_LEDS) += $(led-y) | ||
42 | |||
43 | # VGA support | ||
44 | #obj-$(CONFIG_FB_S1D13XXX) += ics1523.o | ||
45 | |||
46 | |||
47 | ifeq ($(CONFIG_PM_DEBUG),y) | ||
48 | CFLAGS_pm.o += -DDEBUG | ||
49 | endif | ||
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot new file mode 100644 index 000000000000..e667dcc7cd34 --- /dev/null +++ b/arch/arm/mach-at91/Makefile.boot | |||
@@ -0,0 +1,9 @@ | |||
1 | # Note: the following conditions must always be true: | ||
2 | # ZRELADDR == virt_to_phys(TEXTADDR) | ||
3 | # PARAMS_PHYS must be within 4MB of ZRELADDR | ||
4 | # INITRD_PHYS must be in RAM | ||
5 | |||
6 | zreladdr-y := 0x20008000 | ||
7 | params_phys-y := 0x20000100 | ||
8 | initrd_phys-y := 0x20410000 | ||
9 | |||
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c new file mode 100644 index 000000000000..870d4a4eb806 --- /dev/null +++ b/arch/arm/mach-at91/at91rm9200.c | |||
@@ -0,0 +1,294 @@ | |||
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/mach/arch.h> | ||
16 | #include <asm/mach/map.h> | ||
17 | #include <asm/arch/at91rm9200.h> | ||
18 | #include <asm/arch/at91_pmc.h> | ||
19 | #include <asm/arch/at91_st.h> | ||
20 | |||
21 | #include "generic.h" | ||
22 | #include "clock.h" | ||
23 | |||
24 | static struct map_desc at91rm9200_io_desc[] __initdata = { | ||
25 | { | ||
26 | .virtual = AT91_VA_BASE_SYS, | ||
27 | .pfn = __phys_to_pfn(AT91_BASE_SYS), | ||
28 | .length = SZ_4K, | ||
29 | .type = MT_DEVICE, | ||
30 | }, { | ||
31 | .virtual = AT91_VA_BASE_EMAC, | ||
32 | .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC), | ||
33 | .length = SZ_16K, | ||
34 | .type = MT_DEVICE, | ||
35 | }, { | ||
36 | .virtual = AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE, | ||
37 | .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE), | ||
38 | .length = AT91RM9200_SRAM_SIZE, | ||
39 | .type = MT_DEVICE, | ||
40 | }, | ||
41 | }; | ||
42 | |||
43 | /* -------------------------------------------------------------------- | ||
44 | * Clocks | ||
45 | * -------------------------------------------------------------------- */ | ||
46 | |||
47 | /* | ||
48 | * The peripheral clocks. | ||
49 | */ | ||
50 | static struct clk udc_clk = { | ||
51 | .name = "udc_clk", | ||
52 | .pmc_mask = 1 << AT91RM9200_ID_UDP, | ||
53 | .type = CLK_TYPE_PERIPHERAL, | ||
54 | }; | ||
55 | static struct clk ohci_clk = { | ||
56 | .name = "ohci_clk", | ||
57 | .pmc_mask = 1 << AT91RM9200_ID_UHP, | ||
58 | .type = CLK_TYPE_PERIPHERAL, | ||
59 | }; | ||
60 | static struct clk ether_clk = { | ||
61 | .name = "ether_clk", | ||
62 | .pmc_mask = 1 << AT91RM9200_ID_EMAC, | ||
63 | .type = CLK_TYPE_PERIPHERAL, | ||
64 | }; | ||
65 | static struct clk mmc_clk = { | ||
66 | .name = "mci_clk", | ||
67 | .pmc_mask = 1 << AT91RM9200_ID_MCI, | ||
68 | .type = CLK_TYPE_PERIPHERAL, | ||
69 | }; | ||
70 | static struct clk twi_clk = { | ||
71 | .name = "twi_clk", | ||
72 | .pmc_mask = 1 << AT91RM9200_ID_TWI, | ||
73 | .type = CLK_TYPE_PERIPHERAL, | ||
74 | }; | ||
75 | static struct clk usart0_clk = { | ||
76 | .name = "usart0_clk", | ||
77 | .pmc_mask = 1 << AT91RM9200_ID_US0, | ||
78 | .type = CLK_TYPE_PERIPHERAL, | ||
79 | }; | ||
80 | static struct clk usart1_clk = { | ||
81 | .name = "usart1_clk", | ||
82 | .pmc_mask = 1 << AT91RM9200_ID_US1, | ||
83 | .type = CLK_TYPE_PERIPHERAL, | ||
84 | }; | ||
85 | static struct clk usart2_clk = { | ||
86 | .name = "usart2_clk", | ||
87 | .pmc_mask = 1 << AT91RM9200_ID_US2, | ||
88 | .type = CLK_TYPE_PERIPHERAL, | ||
89 | }; | ||
90 | static struct clk usart3_clk = { | ||
91 | .name = "usart3_clk", | ||
92 | .pmc_mask = 1 << AT91RM9200_ID_US3, | ||
93 | .type = CLK_TYPE_PERIPHERAL, | ||
94 | }; | ||
95 | static struct clk spi_clk = { | ||
96 | .name = "spi_clk", | ||
97 | .pmc_mask = 1 << AT91RM9200_ID_SPI, | ||
98 | .type = CLK_TYPE_PERIPHERAL, | ||
99 | }; | ||
100 | static struct clk pioA_clk = { | ||
101 | .name = "pioA_clk", | ||
102 | .pmc_mask = 1 << AT91RM9200_ID_PIOA, | ||
103 | .type = CLK_TYPE_PERIPHERAL, | ||
104 | }; | ||
105 | static struct clk pioB_clk = { | ||
106 | .name = "pioB_clk", | ||
107 | .pmc_mask = 1 << AT91RM9200_ID_PIOB, | ||
108 | .type = CLK_TYPE_PERIPHERAL, | ||
109 | }; | ||
110 | static struct clk pioC_clk = { | ||
111 | .name = "pioC_clk", | ||
112 | .pmc_mask = 1 << AT91RM9200_ID_PIOC, | ||
113 | .type = CLK_TYPE_PERIPHERAL, | ||
114 | }; | ||
115 | static struct clk pioD_clk = { | ||
116 | .name = "pioD_clk", | ||
117 | .pmc_mask = 1 << AT91RM9200_ID_PIOD, | ||
118 | .type = CLK_TYPE_PERIPHERAL, | ||
119 | }; | ||
120 | |||
121 | static struct clk *periph_clocks[] __initdata = { | ||
122 | &pioA_clk, | ||
123 | &pioB_clk, | ||
124 | &pioC_clk, | ||
125 | &pioD_clk, | ||
126 | &usart0_clk, | ||
127 | &usart1_clk, | ||
128 | &usart2_clk, | ||
129 | &usart3_clk, | ||
130 | &mmc_clk, | ||
131 | &udc_clk, | ||
132 | &twi_clk, | ||
133 | &spi_clk, | ||
134 | // ssc 0 .. ssc2 | ||
135 | // tc0 .. tc5 | ||
136 | &ohci_clk, | ||
137 | ðer_clk, | ||
138 | // irq0 .. irq6 | ||
139 | }; | ||
140 | |||
141 | /* | ||
142 | * The four programmable clocks. | ||
143 | * You must configure pin multiplexing to bring these signals out. | ||
144 | */ | ||
145 | static struct clk pck0 = { | ||
146 | .name = "pck0", | ||
147 | .pmc_mask = AT91_PMC_PCK0, | ||
148 | .type = CLK_TYPE_PROGRAMMABLE, | ||
149 | .id = 0, | ||
150 | }; | ||
151 | static struct clk pck1 = { | ||
152 | .name = "pck1", | ||
153 | .pmc_mask = AT91_PMC_PCK1, | ||
154 | .type = CLK_TYPE_PROGRAMMABLE, | ||
155 | .id = 1, | ||
156 | }; | ||
157 | static struct clk pck2 = { | ||
158 | .name = "pck2", | ||
159 | .pmc_mask = AT91_PMC_PCK2, | ||
160 | .type = CLK_TYPE_PROGRAMMABLE, | ||
161 | .id = 2, | ||
162 | }; | ||
163 | static struct clk pck3 = { | ||
164 | .name = "pck3", | ||
165 | .pmc_mask = AT91_PMC_PCK3, | ||
166 | .type = CLK_TYPE_PROGRAMMABLE, | ||
167 | .id = 3, | ||
168 | }; | ||
169 | |||
170 | static void __init at91rm9200_register_clocks(void) | ||
171 | { | ||
172 | int i; | ||
173 | |||
174 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
175 | clk_register(periph_clocks[i]); | ||
176 | |||
177 | clk_register(&pck0); | ||
178 | clk_register(&pck1); | ||
179 | clk_register(&pck2); | ||
180 | clk_register(&pck3); | ||
181 | } | ||
182 | |||
183 | /* -------------------------------------------------------------------- | ||
184 | * GPIO | ||
185 | * -------------------------------------------------------------------- */ | ||
186 | |||
187 | static struct at91_gpio_bank at91rm9200_gpio[] = { | ||
188 | { | ||
189 | .id = AT91RM9200_ID_PIOA, | ||
190 | .offset = AT91_PIOA, | ||
191 | .clock = &pioA_clk, | ||
192 | }, { | ||
193 | .id = AT91RM9200_ID_PIOB, | ||
194 | .offset = AT91_PIOB, | ||
195 | .clock = &pioB_clk, | ||
196 | }, { | ||
197 | .id = AT91RM9200_ID_PIOC, | ||
198 | .offset = AT91_PIOC, | ||
199 | .clock = &pioC_clk, | ||
200 | }, { | ||
201 | .id = AT91RM9200_ID_PIOD, | ||
202 | .offset = AT91_PIOD, | ||
203 | .clock = &pioD_clk, | ||
204 | } | ||
205 | }; | ||
206 | |||
207 | static void at91rm9200_reset(void) | ||
208 | { | ||
209 | /* | ||
210 | * Perform a hardware reset with the use of the Watchdog timer. | ||
211 | */ | ||
212 | at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); | ||
213 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); | ||
214 | } | ||
215 | |||
216 | |||
217 | /* -------------------------------------------------------------------- | ||
218 | * AT91RM9200 processor initialization | ||
219 | * -------------------------------------------------------------------- */ | ||
220 | void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks) | ||
221 | { | ||
222 | /* Map peripherals */ | ||
223 | iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); | ||
224 | |||
225 | at91_arch_reset = at91rm9200_reset; | ||
226 | at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) | ||
227 | | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) | ||
228 | | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5) | ||
229 | | (1 << AT91RM9200_ID_IRQ6); | ||
230 | |||
231 | /* Init clock subsystem */ | ||
232 | at91_clock_init(main_clock); | ||
233 | |||
234 | /* Register the processor-specific clocks */ | ||
235 | at91rm9200_register_clocks(); | ||
236 | |||
237 | /* Initialize GPIO subsystem */ | ||
238 | at91_gpio_init(at91rm9200_gpio, banks); | ||
239 | } | ||
240 | |||
241 | |||
242 | /* -------------------------------------------------------------------- | ||
243 | * Interrupt initialization | ||
244 | * -------------------------------------------------------------------- */ | ||
245 | |||
246 | /* | ||
247 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
248 | */ | ||
249 | static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
250 | 7, /* Advanced Interrupt Controller (FIQ) */ | ||
251 | 7, /* System Peripherals */ | ||
252 | 0, /* Parallel IO Controller A */ | ||
253 | 0, /* Parallel IO Controller B */ | ||
254 | 0, /* Parallel IO Controller C */ | ||
255 | 0, /* Parallel IO Controller D */ | ||
256 | 6, /* USART 0 */ | ||
257 | 6, /* USART 1 */ | ||
258 | 6, /* USART 2 */ | ||
259 | 6, /* USART 3 */ | ||
260 | 0, /* Multimedia Card Interface */ | ||
261 | 4, /* USB Device Port */ | ||
262 | 0, /* Two-Wire Interface */ | ||
263 | 6, /* Serial Peripheral Interface */ | ||
264 | 5, /* Serial Synchronous Controller 0 */ | ||
265 | 5, /* Serial Synchronous Controller 1 */ | ||
266 | 5, /* Serial Synchronous Controller 2 */ | ||
267 | 0, /* Timer Counter 0 */ | ||
268 | 0, /* Timer Counter 1 */ | ||
269 | 0, /* Timer Counter 2 */ | ||
270 | 0, /* Timer Counter 3 */ | ||
271 | 0, /* Timer Counter 4 */ | ||
272 | 0, /* Timer Counter 5 */ | ||
273 | 3, /* USB Host port */ | ||
274 | 3, /* Ethernet MAC */ | ||
275 | 0, /* Advanced Interrupt Controller (IRQ0) */ | ||
276 | 0, /* Advanced Interrupt Controller (IRQ1) */ | ||
277 | 0, /* Advanced Interrupt Controller (IRQ2) */ | ||
278 | 0, /* Advanced Interrupt Controller (IRQ3) */ | ||
279 | 0, /* Advanced Interrupt Controller (IRQ4) */ | ||
280 | 0, /* Advanced Interrupt Controller (IRQ5) */ | ||
281 | 0 /* Advanced Interrupt Controller (IRQ6) */ | ||
282 | }; | ||
283 | |||
284 | void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | ||
285 | { | ||
286 | if (!priority) | ||
287 | priority = at91rm9200_default_irq_priority; | ||
288 | |||
289 | /* Initialize the AIC interrupt controller */ | ||
290 | at91_aic_init(priority); | ||
291 | |||
292 | /* Enable GPIO interrupts */ | ||
293 | at91_gpio_irq_setup(); | ||
294 | } | ||
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c new file mode 100644 index 000000000000..a06498ccc826 --- /dev/null +++ b/arch/arm/mach-at91/at91rm9200_devices.c | |||
@@ -0,0 +1,875 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/at91rm9200_devices.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> | ||
5 | * Copyright (C) 2005 David Brownell | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | #include <asm/mach/arch.h> | ||
14 | #include <asm/mach/map.h> | ||
15 | |||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include <asm/arch/board.h> | ||
19 | #include <asm/arch/gpio.h> | ||
20 | #include <asm/arch/at91rm9200.h> | ||
21 | #include <asm/arch/at91rm9200_mc.h> | ||
22 | |||
23 | #include "generic.h" | ||
24 | |||
25 | #define SZ_512 0x00000200 | ||
26 | #define SZ_256 0x00000100 | ||
27 | #define SZ_16 0x00000010 | ||
28 | |||
29 | /* -------------------------------------------------------------------- | ||
30 | * USB Host | ||
31 | * -------------------------------------------------------------------- */ | ||
32 | |||
33 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
34 | static u64 ohci_dmamask = 0xffffffffUL; | ||
35 | static struct at91_usbh_data usbh_data; | ||
36 | |||
37 | static struct resource usbh_resources[] = { | ||
38 | [0] = { | ||
39 | .start = AT91RM9200_UHP_BASE, | ||
40 | .end = AT91RM9200_UHP_BASE + SZ_1M - 1, | ||
41 | .flags = IORESOURCE_MEM, | ||
42 | }, | ||
43 | [1] = { | ||
44 | .start = AT91RM9200_ID_UHP, | ||
45 | .end = AT91RM9200_ID_UHP, | ||
46 | .flags = IORESOURCE_IRQ, | ||
47 | }, | ||
48 | }; | ||
49 | |||
50 | static struct platform_device at91rm9200_usbh_device = { | ||
51 | .name = "at91_ohci", | ||
52 | .id = -1, | ||
53 | .dev = { | ||
54 | .dma_mask = &ohci_dmamask, | ||
55 | .coherent_dma_mask = 0xffffffff, | ||
56 | .platform_data = &usbh_data, | ||
57 | }, | ||
58 | .resource = usbh_resources, | ||
59 | .num_resources = ARRAY_SIZE(usbh_resources), | ||
60 | }; | ||
61 | |||
62 | void __init at91_add_device_usbh(struct at91_usbh_data *data) | ||
63 | { | ||
64 | if (!data) | ||
65 | return; | ||
66 | |||
67 | usbh_data = *data; | ||
68 | platform_device_register(&at91rm9200_usbh_device); | ||
69 | } | ||
70 | #else | ||
71 | void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | ||
72 | #endif | ||
73 | |||
74 | |||
75 | /* -------------------------------------------------------------------- | ||
76 | * USB Device (Gadget) | ||
77 | * -------------------------------------------------------------------- */ | ||
78 | |||
79 | #ifdef CONFIG_USB_GADGET_AT91 | ||
80 | static struct at91_udc_data udc_data; | ||
81 | |||
82 | static struct resource udc_resources[] = { | ||
83 | [0] = { | ||
84 | .start = AT91RM9200_BASE_UDP, | ||
85 | .end = AT91RM9200_BASE_UDP + SZ_16K - 1, | ||
86 | .flags = IORESOURCE_MEM, | ||
87 | }, | ||
88 | [1] = { | ||
89 | .start = AT91RM9200_ID_UDP, | ||
90 | .end = AT91RM9200_ID_UDP, | ||
91 | .flags = IORESOURCE_IRQ, | ||
92 | }, | ||
93 | }; | ||
94 | |||
95 | static struct platform_device at91rm9200_udc_device = { | ||
96 | .name = "at91_udc", | ||
97 | .id = -1, | ||
98 | .dev = { | ||
99 | .platform_data = &udc_data, | ||
100 | }, | ||
101 | .resource = udc_resources, | ||
102 | .num_resources = ARRAY_SIZE(udc_resources), | ||
103 | }; | ||
104 | |||
105 | void __init at91_add_device_udc(struct at91_udc_data *data) | ||
106 | { | ||
107 | if (!data) | ||
108 | return; | ||
109 | |||
110 | if (data->vbus_pin) { | ||
111 | at91_set_gpio_input(data->vbus_pin, 0); | ||
112 | at91_set_deglitch(data->vbus_pin, 1); | ||
113 | } | ||
114 | if (data->pullup_pin) | ||
115 | at91_set_gpio_output(data->pullup_pin, 0); | ||
116 | |||
117 | udc_data = *data; | ||
118 | platform_device_register(&at91rm9200_udc_device); | ||
119 | } | ||
120 | #else | ||
121 | void __init at91_add_device_udc(struct at91_udc_data *data) {} | ||
122 | #endif | ||
123 | |||
124 | |||
125 | /* -------------------------------------------------------------------- | ||
126 | * Ethernet | ||
127 | * -------------------------------------------------------------------- */ | ||
128 | |||
129 | #if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) | ||
130 | static u64 eth_dmamask = 0xffffffffUL; | ||
131 | static struct at91_eth_data eth_data; | ||
132 | |||
133 | static struct resource eth_resources[] = { | ||
134 | [0] = { | ||
135 | .start = AT91_VA_BASE_EMAC, | ||
136 | .end = AT91_VA_BASE_EMAC + SZ_16K - 1, | ||
137 | .flags = IORESOURCE_MEM, | ||
138 | }, | ||
139 | [1] = { | ||
140 | .start = AT91RM9200_ID_EMAC, | ||
141 | .end = AT91RM9200_ID_EMAC, | ||
142 | .flags = IORESOURCE_IRQ, | ||
143 | }, | ||
144 | }; | ||
145 | |||
146 | static struct platform_device at91rm9200_eth_device = { | ||
147 | .name = "at91_ether", | ||
148 | .id = -1, | ||
149 | .dev = { | ||
150 | .dma_mask = ð_dmamask, | ||
151 | .coherent_dma_mask = 0xffffffff, | ||
152 | .platform_data = ð_data, | ||
153 | }, | ||
154 | .resource = eth_resources, | ||
155 | .num_resources = ARRAY_SIZE(eth_resources), | ||
156 | }; | ||
157 | |||
158 | void __init at91_add_device_eth(struct at91_eth_data *data) | ||
159 | { | ||
160 | if (!data) | ||
161 | return; | ||
162 | |||
163 | if (data->phy_irq_pin) { | ||
164 | at91_set_gpio_input(data->phy_irq_pin, 0); | ||
165 | at91_set_deglitch(data->phy_irq_pin, 1); | ||
166 | } | ||
167 | |||
168 | /* Pins used for MII and RMII */ | ||
169 | at91_set_A_periph(AT91_PIN_PA16, 0); /* EMDIO */ | ||
170 | at91_set_A_periph(AT91_PIN_PA15, 0); /* EMDC */ | ||
171 | at91_set_A_periph(AT91_PIN_PA14, 0); /* ERXER */ | ||
172 | at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ | ||
173 | at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ | ||
174 | at91_set_A_periph(AT91_PIN_PA11, 0); /* ECRS_ECRSDV */ | ||
175 | at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX1 */ | ||
176 | at91_set_A_periph(AT91_PIN_PA9, 0); /* ETX0 */ | ||
177 | at91_set_A_periph(AT91_PIN_PA8, 0); /* ETXEN */ | ||
178 | at91_set_A_periph(AT91_PIN_PA7, 0); /* ETXCK_EREFCK */ | ||
179 | |||
180 | if (!data->is_rmii) { | ||
181 | at91_set_B_periph(AT91_PIN_PB19, 0); /* ERXCK */ | ||
182 | at91_set_B_periph(AT91_PIN_PB18, 0); /* ECOL */ | ||
183 | at91_set_B_periph(AT91_PIN_PB17, 0); /* ERXDV */ | ||
184 | at91_set_B_periph(AT91_PIN_PB16, 0); /* ERX3 */ | ||
185 | at91_set_B_periph(AT91_PIN_PB15, 0); /* ERX2 */ | ||
186 | at91_set_B_periph(AT91_PIN_PB14, 0); /* ETXER */ | ||
187 | at91_set_B_periph(AT91_PIN_PB13, 0); /* ETX3 */ | ||
188 | at91_set_B_periph(AT91_PIN_PB12, 0); /* ETX2 */ | ||
189 | } | ||
190 | |||
191 | eth_data = *data; | ||
192 | platform_device_register(&at91rm9200_eth_device); | ||
193 | } | ||
194 | #else | ||
195 | void __init at91_add_device_eth(struct at91_eth_data *data) {} | ||
196 | #endif | ||
197 | |||
198 | |||
199 | /* -------------------------------------------------------------------- | ||
200 | * Compact Flash / PCMCIA | ||
201 | * -------------------------------------------------------------------- */ | ||
202 | |||
203 | #if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) | ||
204 | static struct at91_cf_data cf_data; | ||
205 | |||
206 | #define CF_BASE AT91_CHIPSELECT_4 | ||
207 | |||
208 | static struct resource cf_resources[] = { | ||
209 | [0] = { | ||
210 | .start = CF_BASE, | ||
211 | /* ties up CS4, CS5 and CS6 */ | ||
212 | .end = CF_BASE + (0x30000000 - 1), | ||
213 | .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, | ||
214 | }, | ||
215 | }; | ||
216 | |||
217 | static struct platform_device at91rm9200_cf_device = { | ||
218 | .name = "at91_cf", | ||
219 | .id = -1, | ||
220 | .dev = { | ||
221 | .platform_data = &cf_data, | ||
222 | }, | ||
223 | .resource = cf_resources, | ||
224 | .num_resources = ARRAY_SIZE(cf_resources), | ||
225 | }; | ||
226 | |||
227 | void __init at91_add_device_cf(struct at91_cf_data *data) | ||
228 | { | ||
229 | unsigned int csa; | ||
230 | |||
231 | if (!data) | ||
232 | return; | ||
233 | |||
234 | data->chipselect = 4; /* can only use EBI ChipSelect 4 */ | ||
235 | |||
236 | /* CF takes over CS4, CS5, CS6 */ | ||
237 | csa = at91_sys_read(AT91_EBI_CSA); | ||
238 | at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); | ||
239 | |||
240 | /* | ||
241 | * Static memory controller timing adjustments. | ||
242 | * REVISIT: these timings are in terms of MCK cycles, so | ||
243 | * when MCK changes (cpufreq etc) so must these values... | ||
244 | */ | ||
245 | at91_sys_write(AT91_SMC_CSR(4), | ||
246 | AT91_SMC_ACSS_STD | ||
247 | | AT91_SMC_DBW_16 | ||
248 | | AT91_SMC_BAT | ||
249 | | AT91_SMC_WSEN | ||
250 | | AT91_SMC_NWS_(32) /* wait states */ | ||
251 | | AT91_SMC_RWSETUP_(6) /* setup time */ | ||
252 | | AT91_SMC_RWHOLD_(4) /* hold time */ | ||
253 | ); | ||
254 | |||
255 | /* input/irq */ | ||
256 | if (data->irq_pin) { | ||
257 | at91_set_gpio_input(data->irq_pin, 1); | ||
258 | at91_set_deglitch(data->irq_pin, 1); | ||
259 | } | ||
260 | at91_set_gpio_input(data->det_pin, 1); | ||
261 | at91_set_deglitch(data->det_pin, 1); | ||
262 | |||
263 | /* outputs, initially off */ | ||
264 | if (data->vcc_pin) | ||
265 | at91_set_gpio_output(data->vcc_pin, 0); | ||
266 | at91_set_gpio_output(data->rst_pin, 0); | ||
267 | |||
268 | /* force poweron defaults for these pins ... */ | ||
269 | at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ | ||
270 | at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ | ||
271 | at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ | ||
272 | at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ | ||
273 | |||
274 | /* nWAIT is _not_ a default setting */ | ||
275 | at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ | ||
276 | |||
277 | cf_data = *data; | ||
278 | platform_device_register(&at91rm9200_cf_device); | ||
279 | } | ||
280 | #else | ||
281 | void __init at91_add_device_cf(struct at91_cf_data *data) {} | ||
282 | #endif | ||
283 | |||
284 | |||
285 | /* -------------------------------------------------------------------- | ||
286 | * MMC / SD | ||
287 | * -------------------------------------------------------------------- */ | ||
288 | |||
289 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | ||
290 | static u64 mmc_dmamask = 0xffffffffUL; | ||
291 | static struct at91_mmc_data mmc_data; | ||
292 | |||
293 | static struct resource mmc_resources[] = { | ||
294 | [0] = { | ||
295 | .start = AT91RM9200_BASE_MCI, | ||
296 | .end = AT91RM9200_BASE_MCI + SZ_16K - 1, | ||
297 | .flags = IORESOURCE_MEM, | ||
298 | }, | ||
299 | [1] = { | ||
300 | .start = AT91RM9200_ID_MCI, | ||
301 | .end = AT91RM9200_ID_MCI, | ||
302 | .flags = IORESOURCE_IRQ, | ||
303 | }, | ||
304 | }; | ||
305 | |||
306 | static struct platform_device at91rm9200_mmc_device = { | ||
307 | .name = "at91_mci", | ||
308 | .id = -1, | ||
309 | .dev = { | ||
310 | .dma_mask = &mmc_dmamask, | ||
311 | .coherent_dma_mask = 0xffffffff, | ||
312 | .platform_data = &mmc_data, | ||
313 | }, | ||
314 | .resource = mmc_resources, | ||
315 | .num_resources = ARRAY_SIZE(mmc_resources), | ||
316 | }; | ||
317 | |||
318 | void __init at91_add_device_mmc(struct at91_mmc_data *data) | ||
319 | { | ||
320 | if (!data) | ||
321 | return; | ||
322 | |||
323 | /* input/irq */ | ||
324 | if (data->det_pin) { | ||
325 | at91_set_gpio_input(data->det_pin, 1); | ||
326 | at91_set_deglitch(data->det_pin, 1); | ||
327 | } | ||
328 | if (data->wp_pin) | ||
329 | at91_set_gpio_input(data->wp_pin, 1); | ||
330 | if (data->vcc_pin) | ||
331 | at91_set_gpio_output(data->vcc_pin, 0); | ||
332 | |||
333 | /* CLK */ | ||
334 | at91_set_A_periph(AT91_PIN_PA27, 0); | ||
335 | |||
336 | if (data->slot_b) { | ||
337 | /* CMD */ | ||
338 | at91_set_B_periph(AT91_PIN_PA8, 1); | ||
339 | |||
340 | /* DAT0, maybe DAT1..DAT3 */ | ||
341 | at91_set_B_periph(AT91_PIN_PA9, 1); | ||
342 | if (data->wire4) { | ||
343 | at91_set_B_periph(AT91_PIN_PA10, 1); | ||
344 | at91_set_B_periph(AT91_PIN_PA11, 1); | ||
345 | at91_set_B_periph(AT91_PIN_PA12, 1); | ||
346 | } | ||
347 | } else { | ||
348 | /* CMD */ | ||
349 | at91_set_A_periph(AT91_PIN_PA28, 1); | ||
350 | |||
351 | /* DAT0, maybe DAT1..DAT3 */ | ||
352 | at91_set_A_periph(AT91_PIN_PA29, 1); | ||
353 | if (data->wire4) { | ||
354 | at91_set_B_periph(AT91_PIN_PB3, 1); | ||
355 | at91_set_B_periph(AT91_PIN_PB4, 1); | ||
356 | at91_set_B_periph(AT91_PIN_PB5, 1); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | mmc_data = *data; | ||
361 | platform_device_register(&at91rm9200_mmc_device); | ||
362 | } | ||
363 | #else | ||
364 | void __init at91_add_device_mmc(struct at91_mmc_data *data) {} | ||
365 | #endif | ||
366 | |||
367 | |||
368 | /* -------------------------------------------------------------------- | ||
369 | * NAND / SmartMedia | ||
370 | * -------------------------------------------------------------------- */ | ||
371 | |||
372 | #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) | ||
373 | static struct at91_nand_data nand_data; | ||
374 | |||
375 | #define NAND_BASE AT91_CHIPSELECT_3 | ||
376 | |||
377 | static struct resource nand_resources[] = { | ||
378 | { | ||
379 | .start = NAND_BASE, | ||
380 | .end = NAND_BASE + SZ_8M - 1, | ||
381 | .flags = IORESOURCE_MEM, | ||
382 | } | ||
383 | }; | ||
384 | |||
385 | static struct platform_device at91rm9200_nand_device = { | ||
386 | .name = "at91_nand", | ||
387 | .id = -1, | ||
388 | .dev = { | ||
389 | .platform_data = &nand_data, | ||
390 | }, | ||
391 | .resource = nand_resources, | ||
392 | .num_resources = ARRAY_SIZE(nand_resources), | ||
393 | }; | ||
394 | |||
395 | void __init at91_add_device_nand(struct at91_nand_data *data) | ||
396 | { | ||
397 | unsigned int csa; | ||
398 | |||
399 | if (!data) | ||
400 | return; | ||
401 | |||
402 | /* enable the address range of CS3 */ | ||
403 | csa = at91_sys_read(AT91_EBI_CSA); | ||
404 | at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA); | ||
405 | |||
406 | /* set the bus interface characteristics */ | ||
407 | at91_sys_write(AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN | ||
408 | | AT91_SMC_NWS_(5) | ||
409 | | AT91_SMC_TDF_(1) | ||
410 | | AT91_SMC_RWSETUP_(0) /* tDS Data Set up Time 30 - ns */ | ||
411 | | AT91_SMC_RWHOLD_(1) /* tDH Data Hold Time 20 - ns */ | ||
412 | ); | ||
413 | |||
414 | /* enable pin */ | ||
415 | if (data->enable_pin) | ||
416 | at91_set_gpio_output(data->enable_pin, 1); | ||
417 | |||
418 | /* ready/busy pin */ | ||
419 | if (data->rdy_pin) | ||
420 | at91_set_gpio_input(data->rdy_pin, 1); | ||
421 | |||
422 | /* card detect pin */ | ||
423 | if (data->det_pin) | ||
424 | at91_set_gpio_input(data->det_pin, 1); | ||
425 | |||
426 | at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ | ||
427 | at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ | ||
428 | |||
429 | nand_data = *data; | ||
430 | platform_device_register(&at91rm9200_nand_device); | ||
431 | } | ||
432 | #else | ||
433 | void __init at91_add_device_nand(struct at91_nand_data *data) {} | ||
434 | #endif | ||
435 | |||
436 | |||
437 | /* -------------------------------------------------------------------- | ||
438 | * TWI (i2c) | ||
439 | * -------------------------------------------------------------------- */ | ||
440 | |||
441 | #if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | ||
442 | |||
443 | static struct resource twi_resources[] = { | ||
444 | [0] = { | ||
445 | .start = AT91RM9200_BASE_TWI, | ||
446 | .end = AT91RM9200_BASE_TWI + SZ_16K - 1, | ||
447 | .flags = IORESOURCE_MEM, | ||
448 | }, | ||
449 | [1] = { | ||
450 | .start = AT91RM9200_ID_TWI, | ||
451 | .end = AT91RM9200_ID_TWI, | ||
452 | .flags = IORESOURCE_IRQ, | ||
453 | }, | ||
454 | }; | ||
455 | |||
456 | static struct platform_device at91rm9200_twi_device = { | ||
457 | .name = "at91_i2c", | ||
458 | .id = -1, | ||
459 | .resource = twi_resources, | ||
460 | .num_resources = ARRAY_SIZE(twi_resources), | ||
461 | }; | ||
462 | |||
463 | void __init at91_add_device_i2c(void) | ||
464 | { | ||
465 | /* pins used for TWI interface */ | ||
466 | at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */ | ||
467 | at91_set_multi_drive(AT91_PIN_PA25, 1); | ||
468 | |||
469 | at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */ | ||
470 | at91_set_multi_drive(AT91_PIN_PA26, 1); | ||
471 | |||
472 | platform_device_register(&at91rm9200_twi_device); | ||
473 | } | ||
474 | #else | ||
475 | void __init at91_add_device_i2c(void) {} | ||
476 | #endif | ||
477 | |||
478 | |||
479 | /* -------------------------------------------------------------------- | ||
480 | * SPI | ||
481 | * -------------------------------------------------------------------- */ | ||
482 | |||
483 | #if defined(CONFIG_SPI_AT91) || defined(CONFIG_SPI_AT91_MODULE) || defined(CONFIG_AT91_SPI) || defined(CONFIG_AT91_SPI_MODULE) | ||
484 | static u64 spi_dmamask = 0xffffffffUL; | ||
485 | |||
486 | static struct resource spi_resources[] = { | ||
487 | [0] = { | ||
488 | .start = AT91RM9200_BASE_SPI, | ||
489 | .end = AT91RM9200_BASE_SPI + SZ_16K - 1, | ||
490 | .flags = IORESOURCE_MEM, | ||
491 | }, | ||
492 | [1] = { | ||
493 | .start = AT91RM9200_ID_SPI, | ||
494 | .end = AT91RM9200_ID_SPI, | ||
495 | .flags = IORESOURCE_IRQ, | ||
496 | }, | ||
497 | }; | ||
498 | |||
499 | static struct platform_device at91rm9200_spi_device = { | ||
500 | .name = "at91_spi", | ||
501 | .id = 0, | ||
502 | .dev = { | ||
503 | .dma_mask = &spi_dmamask, | ||
504 | .coherent_dma_mask = 0xffffffff, | ||
505 | }, | ||
506 | .resource = spi_resources, | ||
507 | .num_resources = ARRAY_SIZE(spi_resources), | ||
508 | }; | ||
509 | |||
510 | static const unsigned spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; | ||
511 | |||
512 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | ||
513 | { | ||
514 | int i; | ||
515 | unsigned long cs_pin; | ||
516 | |||
517 | at91_set_A_periph(AT91_PIN_PA0, 0); /* MISO */ | ||
518 | at91_set_A_periph(AT91_PIN_PA1, 0); /* MOSI */ | ||
519 | at91_set_A_periph(AT91_PIN_PA2, 0); /* SPCK */ | ||
520 | |||
521 | /* Enable SPI chip-selects */ | ||
522 | for (i = 0; i < nr_devices; i++) { | ||
523 | if (devices[i].controller_data) | ||
524 | cs_pin = (unsigned long) devices[i].controller_data; | ||
525 | else | ||
526 | cs_pin = spi_standard_cs[devices[i].chip_select]; | ||
527 | |||
528 | #ifdef CONFIG_SPI_AT91_MANUAL_CS | ||
529 | at91_set_gpio_output(cs_pin, 1); | ||
530 | #else | ||
531 | at91_set_A_periph(cs_pin, 0); | ||
532 | #endif | ||
533 | |||
534 | /* pass chip-select pin to driver */ | ||
535 | devices[i].controller_data = (void *) cs_pin; | ||
536 | } | ||
537 | |||
538 | spi_register_board_info(devices, nr_devices); | ||
539 | at91_clock_associate("spi_clk", &at91rm9200_spi_device.dev, "spi"); | ||
540 | platform_device_register(&at91rm9200_spi_device); | ||
541 | } | ||
542 | #else | ||
543 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} | ||
544 | #endif | ||
545 | |||
546 | |||
547 | /* -------------------------------------------------------------------- | ||
548 | * RTC | ||
549 | * -------------------------------------------------------------------- */ | ||
550 | |||
551 | #if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) | ||
552 | static struct platform_device at91rm9200_rtc_device = { | ||
553 | .name = "at91_rtc", | ||
554 | .id = -1, | ||
555 | .num_resources = 0, | ||
556 | }; | ||
557 | |||
558 | static void __init at91_add_device_rtc(void) | ||
559 | { | ||
560 | platform_device_register(&at91rm9200_rtc_device); | ||
561 | } | ||
562 | #else | ||
563 | static void __init at91_add_device_rtc(void) {} | ||
564 | #endif | ||
565 | |||
566 | |||
567 | /* -------------------------------------------------------------------- | ||
568 | * Watchdog | ||
569 | * -------------------------------------------------------------------- */ | ||
570 | |||
571 | #if defined(CONFIG_AT91RM9200_WATCHDOG) || defined(CONFIG_AT91RM9200_WATCHDOG_MODULE) | ||
572 | static struct platform_device at91rm9200_wdt_device = { | ||
573 | .name = "at91_wdt", | ||
574 | .id = -1, | ||
575 | .num_resources = 0, | ||
576 | }; | ||
577 | |||
578 | static void __init at91_add_device_watchdog(void) | ||
579 | { | ||
580 | platform_device_register(&at91rm9200_wdt_device); | ||
581 | } | ||
582 | #else | ||
583 | static void __init at91_add_device_watchdog(void) {} | ||
584 | #endif | ||
585 | |||
586 | |||
587 | /* -------------------------------------------------------------------- | ||
588 | * LEDs | ||
589 | * -------------------------------------------------------------------- */ | ||
590 | |||
591 | #if defined(CONFIG_LEDS) | ||
592 | u8 at91_leds_cpu; | ||
593 | u8 at91_leds_timer; | ||
594 | |||
595 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | ||
596 | { | ||
597 | at91_leds_cpu = cpu_led; | ||
598 | at91_leds_timer = timer_led; | ||
599 | } | ||
600 | #else | ||
601 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | ||
602 | #endif | ||
603 | |||
604 | |||
605 | /* -------------------------------------------------------------------- | ||
606 | * UART | ||
607 | * -------------------------------------------------------------------- */ | ||
608 | |||
609 | #if defined(CONFIG_SERIAL_ATMEL) | ||
610 | static struct resource dbgu_resources[] = { | ||
611 | [0] = { | ||
612 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | ||
613 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | ||
614 | .flags = IORESOURCE_MEM, | ||
615 | }, | ||
616 | [1] = { | ||
617 | .start = AT91_ID_SYS, | ||
618 | .end = AT91_ID_SYS, | ||
619 | .flags = IORESOURCE_IRQ, | ||
620 | }, | ||
621 | }; | ||
622 | |||
623 | static struct atmel_uart_data dbgu_data = { | ||
624 | .use_dma_tx = 0, | ||
625 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | ||
626 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | ||
627 | }; | ||
628 | |||
629 | static struct platform_device at91rm9200_dbgu_device = { | ||
630 | .name = "atmel_usart", | ||
631 | .id = 0, | ||
632 | .dev = { | ||
633 | .platform_data = &dbgu_data, | ||
634 | .coherent_dma_mask = 0xffffffff, | ||
635 | }, | ||
636 | .resource = dbgu_resources, | ||
637 | .num_resources = ARRAY_SIZE(dbgu_resources), | ||
638 | }; | ||
639 | |||
640 | static inline void configure_dbgu_pins(void) | ||
641 | { | ||
642 | at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */ | ||
643 | at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */ | ||
644 | } | ||
645 | |||
646 | static struct resource uart0_resources[] = { | ||
647 | [0] = { | ||
648 | .start = AT91RM9200_BASE_US0, | ||
649 | .end = AT91RM9200_BASE_US0 + SZ_16K - 1, | ||
650 | .flags = IORESOURCE_MEM, | ||
651 | }, | ||
652 | [1] = { | ||
653 | .start = AT91RM9200_ID_US0, | ||
654 | .end = AT91RM9200_ID_US0, | ||
655 | .flags = IORESOURCE_IRQ, | ||
656 | }, | ||
657 | }; | ||
658 | |||
659 | static struct atmel_uart_data uart0_data = { | ||
660 | .use_dma_tx = 1, | ||
661 | .use_dma_rx = 1, | ||
662 | }; | ||
663 | |||
664 | static struct platform_device at91rm9200_uart0_device = { | ||
665 | .name = "atmel_usart", | ||
666 | .id = 1, | ||
667 | .dev = { | ||
668 | .platform_data = &uart0_data, | ||
669 | .coherent_dma_mask = 0xffffffff, | ||
670 | }, | ||
671 | .resource = uart0_resources, | ||
672 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
673 | }; | ||
674 | |||
675 | static inline void configure_usart0_pins(void) | ||
676 | { | ||
677 | at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ | ||
678 | at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ | ||
679 | at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ | ||
680 | |||
681 | /* | ||
682 | * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. | ||
683 | * We need to drive the pin manually. Default is off (RTS is active low). | ||
684 | */ | ||
685 | at91_set_gpio_output(AT91_PIN_PA21, 1); | ||
686 | } | ||
687 | |||
688 | static struct resource uart1_resources[] = { | ||
689 | [0] = { | ||
690 | .start = AT91RM9200_BASE_US1, | ||
691 | .end = AT91RM9200_BASE_US1 + SZ_16K - 1, | ||
692 | .flags = IORESOURCE_MEM, | ||
693 | }, | ||
694 | [1] = { | ||
695 | .start = AT91RM9200_ID_US1, | ||
696 | .end = AT91RM9200_ID_US1, | ||
697 | .flags = IORESOURCE_IRQ, | ||
698 | }, | ||
699 | }; | ||
700 | |||
701 | static struct atmel_uart_data uart1_data = { | ||
702 | .use_dma_tx = 1, | ||
703 | .use_dma_rx = 1, | ||
704 | }; | ||
705 | |||
706 | static struct platform_device at91rm9200_uart1_device = { | ||
707 | .name = "atmel_usart", | ||
708 | .id = 2, | ||
709 | .dev = { | ||
710 | .platform_data = &uart1_data, | ||
711 | .coherent_dma_mask = 0xffffffff, | ||
712 | }, | ||
713 | .resource = uart1_resources, | ||
714 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
715 | }; | ||
716 | |||
717 | static inline void configure_usart1_pins(void) | ||
718 | { | ||
719 | at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ | ||
720 | at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ | ||
721 | at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ | ||
722 | at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ | ||
723 | at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ | ||
724 | at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ | ||
725 | at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ | ||
726 | at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ | ||
727 | } | ||
728 | |||
729 | static struct resource uart2_resources[] = { | ||
730 | [0] = { | ||
731 | .start = AT91RM9200_BASE_US2, | ||
732 | .end = AT91RM9200_BASE_US2 + SZ_16K - 1, | ||
733 | .flags = IORESOURCE_MEM, | ||
734 | }, | ||
735 | [1] = { | ||
736 | .start = AT91RM9200_ID_US2, | ||
737 | .end = AT91RM9200_ID_US2, | ||
738 | .flags = IORESOURCE_IRQ, | ||
739 | }, | ||
740 | }; | ||
741 | |||
742 | static struct atmel_uart_data uart2_data = { | ||
743 | .use_dma_tx = 1, | ||
744 | .use_dma_rx = 1, | ||
745 | }; | ||
746 | |||
747 | static struct platform_device at91rm9200_uart2_device = { | ||
748 | .name = "atmel_usart", | ||
749 | .id = 3, | ||
750 | .dev = { | ||
751 | .platform_data = &uart2_data, | ||
752 | .coherent_dma_mask = 0xffffffff, | ||
753 | }, | ||
754 | .resource = uart2_resources, | ||
755 | .num_resources = ARRAY_SIZE(uart2_resources), | ||
756 | }; | ||
757 | |||
758 | static inline void configure_usart2_pins(void) | ||
759 | { | ||
760 | at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ | ||
761 | at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ | ||
762 | } | ||
763 | |||
764 | static struct resource uart3_resources[] = { | ||
765 | [0] = { | ||
766 | .start = AT91RM9200_BASE_US3, | ||
767 | .end = AT91RM9200_BASE_US3 + SZ_16K - 1, | ||
768 | .flags = IORESOURCE_MEM, | ||
769 | }, | ||
770 | [1] = { | ||
771 | .start = AT91RM9200_ID_US3, | ||
772 | .end = AT91RM9200_ID_US3, | ||
773 | .flags = IORESOURCE_IRQ, | ||
774 | }, | ||
775 | }; | ||
776 | |||
777 | static struct atmel_uart_data uart3_data = { | ||
778 | .use_dma_tx = 1, | ||
779 | .use_dma_rx = 1, | ||
780 | }; | ||
781 | |||
782 | static struct platform_device at91rm9200_uart3_device = { | ||
783 | .name = "atmel_usart", | ||
784 | .id = 4, | ||
785 | .dev = { | ||
786 | .platform_data = &uart3_data, | ||
787 | .coherent_dma_mask = 0xffffffff, | ||
788 | }, | ||
789 | .resource = uart3_resources, | ||
790 | .num_resources = ARRAY_SIZE(uart3_resources), | ||
791 | }; | ||
792 | |||
793 | static inline void configure_usart3_pins(void) | ||
794 | { | ||
795 | at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ | ||
796 | at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ | ||
797 | } | ||
798 | |||
799 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | ||
800 | struct platform_device *atmel_default_console_device; /* the serial console device */ | ||
801 | |||
802 | void __init at91_init_serial(struct at91_uart_config *config) | ||
803 | { | ||
804 | int i; | ||
805 | |||
806 | /* Fill in list of supported UARTs */ | ||
807 | for (i = 0; i < config->nr_tty; i++) { | ||
808 | switch (config->tty_map[i]) { | ||
809 | case 0: | ||
810 | configure_usart0_pins(); | ||
811 | at91_uarts[i] = &at91rm9200_uart0_device; | ||
812 | at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart"); | ||
813 | break; | ||
814 | case 1: | ||
815 | configure_usart1_pins(); | ||
816 | at91_uarts[i] = &at91rm9200_uart1_device; | ||
817 | at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart"); | ||
818 | break; | ||
819 | case 2: | ||
820 | configure_usart2_pins(); | ||
821 | at91_uarts[i] = &at91rm9200_uart2_device; | ||
822 | at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart"); | ||
823 | break; | ||
824 | case 3: | ||
825 | configure_usart3_pins(); | ||
826 | at91_uarts[i] = &at91rm9200_uart3_device; | ||
827 | at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart"); | ||
828 | break; | ||
829 | case 4: | ||
830 | configure_dbgu_pins(); | ||
831 | at91_uarts[i] = &at91rm9200_dbgu_device; | ||
832 | at91_clock_associate("mck", &at91rm9200_dbgu_device.dev, "usart"); | ||
833 | break; | ||
834 | default: | ||
835 | continue; | ||
836 | } | ||
837 | at91_uarts[i]->id = i; /* update ID number to mapped ID */ | ||
838 | } | ||
839 | |||
840 | /* Set serial console device */ | ||
841 | if (config->console_tty < ATMEL_MAX_UART) | ||
842 | atmel_default_console_device = at91_uarts[config->console_tty]; | ||
843 | if (!atmel_default_console_device) | ||
844 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
845 | } | ||
846 | |||
847 | void __init at91_add_device_serial(void) | ||
848 | { | ||
849 | int i; | ||
850 | |||
851 | for (i = 0; i < ATMEL_MAX_UART; i++) { | ||
852 | if (at91_uarts[i]) | ||
853 | platform_device_register(at91_uarts[i]); | ||
854 | } | ||
855 | } | ||
856 | #else | ||
857 | void __init at91_init_serial(struct at91_uart_config *config) {} | ||
858 | void __init at91_add_device_serial(void) {} | ||
859 | #endif | ||
860 | |||
861 | |||
862 | /* -------------------------------------------------------------------- */ | ||
863 | |||
864 | /* | ||
865 | * These devices are always present and don't need any board-specific | ||
866 | * setup. | ||
867 | */ | ||
868 | static int __init at91_add_standard_devices(void) | ||
869 | { | ||
870 | at91_add_device_rtc(); | ||
871 | at91_add_device_watchdog(); | ||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | arch_initcall(at91_add_standard_devices); | ||
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c new file mode 100644 index 000000000000..949199a244c7 --- /dev/null +++ b/arch/arm/mach-at91/at91rm9200_time.c | |||
@@ -0,0 +1,146 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/at91rm9200_time.c | ||
3 | * | ||
4 | * Copyright (C) 2003 SAN People | ||
5 | * Copyright (C) 2003 ATMEL | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/irq.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/time.h> | ||
28 | |||
29 | #include <asm/hardware.h> | ||
30 | #include <asm/io.h> | ||
31 | #include <asm/mach/time.h> | ||
32 | |||
33 | #include <asm/arch/at91_st.h> | ||
34 | |||
35 | static unsigned long last_crtr; | ||
36 | |||
37 | /* | ||
38 | * The ST_CRTR is updated asynchronously to the master clock. It is therefore | ||
39 | * necessary to read it twice (with the same value) to ensure accuracy. | ||
40 | */ | ||
41 | static inline unsigned long read_CRTR(void) { | ||
42 | unsigned long x1, x2; | ||
43 | |||
44 | do { | ||
45 | x1 = at91_sys_read(AT91_ST_CRTR); | ||
46 | x2 = at91_sys_read(AT91_ST_CRTR); | ||
47 | } while (x1 != x2); | ||
48 | |||
49 | return x1; | ||
50 | } | ||
51 | |||
52 | /* | ||
53 | * Returns number of microseconds since last timer interrupt. Note that interrupts | ||
54 | * will have been disabled by do_gettimeofday() | ||
55 | * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy. | ||
56 | * 'tick' is usecs per jiffy (linux/timex.h). | ||
57 | */ | ||
58 | static unsigned long at91rm9200_gettimeoffset(void) | ||
59 | { | ||
60 | unsigned long elapsed; | ||
61 | |||
62 | elapsed = (read_CRTR() - last_crtr) & AT91_ST_ALMV; | ||
63 | |||
64 | return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH; | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * IRQ handler for the timer. | ||
69 | */ | ||
70 | static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) | ||
71 | { | ||
72 | if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) { /* This is a shared interrupt */ | ||
73 | write_seqlock(&xtime_lock); | ||
74 | |||
75 | while (((read_CRTR() - last_crtr) & AT91_ST_ALMV) >= LATCH) { | ||
76 | timer_tick(); | ||
77 | last_crtr = (last_crtr + LATCH) & AT91_ST_ALMV; | ||
78 | } | ||
79 | |||
80 | write_sequnlock(&xtime_lock); | ||
81 | |||
82 | return IRQ_HANDLED; | ||
83 | } | ||
84 | else | ||
85 | return IRQ_NONE; /* not handled */ | ||
86 | } | ||
87 | |||
88 | static struct irqaction at91rm9200_timer_irq = { | ||
89 | .name = "at91_tick", | ||
90 | .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER, | ||
91 | .handler = at91rm9200_timer_interrupt | ||
92 | }; | ||
93 | |||
94 | void at91rm9200_timer_reset(void) | ||
95 | { | ||
96 | last_crtr = 0; | ||
97 | |||
98 | /* Real time counter incremented every 30.51758 microseconds */ | ||
99 | at91_sys_write(AT91_ST_RTMR, 1); | ||
100 | |||
101 | /* Set Period Interval timer */ | ||
102 | at91_sys_write(AT91_ST_PIMR, LATCH); | ||
103 | |||
104 | /* Clear any pending interrupts */ | ||
105 | (void) at91_sys_read(AT91_ST_SR); | ||
106 | |||
107 | /* Enable Period Interval Timer interrupt */ | ||
108 | at91_sys_write(AT91_ST_IER, AT91_ST_PITS); | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * Set up timer interrupt. | ||
113 | */ | ||
114 | void __init at91rm9200_timer_init(void) | ||
115 | { | ||
116 | /* Disable all timer interrupts */ | ||
117 | at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); | ||
118 | (void) at91_sys_read(AT91_ST_SR); /* Clear any pending interrupts */ | ||
119 | |||
120 | /* Make IRQs happen for the system timer */ | ||
121 | setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq); | ||
122 | |||
123 | /* Change the kernel's 'tick' value to 10009 usec. (the default is 10000) */ | ||
124 | tick_usec = (LATCH * 1000000) / CLOCK_TICK_RATE; | ||
125 | |||
126 | /* Initialize and enable the timer interrupt */ | ||
127 | at91rm9200_timer_reset(); | ||
128 | } | ||
129 | |||
130 | #ifdef CONFIG_PM | ||
131 | static void at91rm9200_timer_suspend(void) | ||
132 | { | ||
133 | /* disable Period Interval Timer interrupt */ | ||
134 | at91_sys_write(AT91_ST_IDR, AT91_ST_PITS); | ||
135 | } | ||
136 | #else | ||
137 | #define at91rm9200_timer_suspend NULL | ||
138 | #endif | ||
139 | |||
140 | struct sys_timer at91rm9200_timer = { | ||
141 | .init = at91rm9200_timer_init, | ||
142 | .offset = at91rm9200_gettimeoffset, | ||
143 | .suspend = at91rm9200_timer_suspend, | ||
144 | .resume = at91rm9200_timer_reset, | ||
145 | }; | ||
146 | |||
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c new file mode 100644 index 000000000000..ffc4c0944740 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9260.c | |||
@@ -0,0 +1,295 @@ | |||
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 | |||
15 | #include <asm/mach/arch.h> | ||
16 | #include <asm/mach/map.h> | ||
17 | #include <asm/arch/at91sam9260.h> | ||
18 | #include <asm/arch/at91_pmc.h> | ||
19 | #include <asm/arch/at91_rstc.h> | ||
20 | |||
21 | #include "generic.h" | ||
22 | #include "clock.h" | ||
23 | |||
24 | static struct map_desc at91sam9260_io_desc[] __initdata = { | ||
25 | { | ||
26 | .virtual = AT91_VA_BASE_SYS, | ||
27 | .pfn = __phys_to_pfn(AT91_BASE_SYS), | ||
28 | .length = SZ_16K, | ||
29 | .type = MT_DEVICE, | ||
30 | }, { | ||
31 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE, | ||
32 | .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE), | ||
33 | .length = AT91SAM9260_SRAM0_SIZE, | ||
34 | .type = MT_DEVICE, | ||
35 | }, { | ||
36 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE - AT91SAM9260_SRAM1_SIZE, | ||
37 | .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE), | ||
38 | .length = AT91SAM9260_SRAM1_SIZE, | ||
39 | .type = MT_DEVICE, | ||
40 | }, | ||
41 | }; | ||
42 | |||
43 | /* -------------------------------------------------------------------- | ||
44 | * Clocks | ||
45 | * -------------------------------------------------------------------- */ | ||
46 | |||
47 | /* | ||
48 | * The peripheral clocks. | ||
49 | */ | ||
50 | static struct clk pioA_clk = { | ||
51 | .name = "pioA_clk", | ||
52 | .pmc_mask = 1 << AT91SAM9260_ID_PIOA, | ||
53 | .type = CLK_TYPE_PERIPHERAL, | ||
54 | }; | ||
55 | static struct clk pioB_clk = { | ||
56 | .name = "pioB_clk", | ||
57 | .pmc_mask = 1 << AT91SAM9260_ID_PIOB, | ||
58 | .type = CLK_TYPE_PERIPHERAL, | ||
59 | }; | ||
60 | static struct clk pioC_clk = { | ||
61 | .name = "pioC_clk", | ||
62 | .pmc_mask = 1 << AT91SAM9260_ID_PIOC, | ||
63 | .type = CLK_TYPE_PERIPHERAL, | ||
64 | }; | ||
65 | static struct clk adc_clk = { | ||
66 | .name = "adc_clk", | ||
67 | .pmc_mask = 1 << AT91SAM9260_ID_ADC, | ||
68 | .type = CLK_TYPE_PERIPHERAL, | ||
69 | }; | ||
70 | static struct clk usart0_clk = { | ||
71 | .name = "usart0_clk", | ||
72 | .pmc_mask = 1 << AT91SAM9260_ID_US0, | ||
73 | .type = CLK_TYPE_PERIPHERAL, | ||
74 | }; | ||
75 | static struct clk usart1_clk = { | ||
76 | .name = "usart1_clk", | ||
77 | .pmc_mask = 1 << AT91SAM9260_ID_US1, | ||
78 | .type = CLK_TYPE_PERIPHERAL, | ||
79 | }; | ||
80 | static struct clk usart2_clk = { | ||
81 | .name = "usart2_clk", | ||
82 | .pmc_mask = 1 << AT91SAM9260_ID_US2, | ||
83 | .type = CLK_TYPE_PERIPHERAL, | ||
84 | }; | ||
85 | static struct clk mmc_clk = { | ||
86 | .name = "mci_clk", | ||
87 | .pmc_mask = 1 << AT91SAM9260_ID_MCI, | ||
88 | .type = CLK_TYPE_PERIPHERAL, | ||
89 | }; | ||
90 | static struct clk udc_clk = { | ||
91 | .name = "udc_clk", | ||
92 | .pmc_mask = 1 << AT91SAM9260_ID_UDP, | ||
93 | .type = CLK_TYPE_PERIPHERAL, | ||
94 | }; | ||
95 | static struct clk twi_clk = { | ||
96 | .name = "twi_clk", | ||
97 | .pmc_mask = 1 << AT91SAM9260_ID_TWI, | ||
98 | .type = CLK_TYPE_PERIPHERAL, | ||
99 | }; | ||
100 | static struct clk spi0_clk = { | ||
101 | .name = "spi0_clk", | ||
102 | .pmc_mask = 1 << AT91SAM9260_ID_SPI0, | ||
103 | .type = CLK_TYPE_PERIPHERAL, | ||
104 | }; | ||
105 | static struct clk spi1_clk = { | ||
106 | .name = "spi1_clk", | ||
107 | .pmc_mask = 1 << AT91SAM9260_ID_SPI1, | ||
108 | .type = CLK_TYPE_PERIPHERAL, | ||
109 | }; | ||
110 | static struct clk ohci_clk = { | ||
111 | .name = "ohci_clk", | ||
112 | .pmc_mask = 1 << AT91SAM9260_ID_UHP, | ||
113 | .type = CLK_TYPE_PERIPHERAL, | ||
114 | }; | ||
115 | static struct clk ether_clk = { | ||
116 | .name = "ether_clk", | ||
117 | .pmc_mask = 1 << AT91SAM9260_ID_EMAC, | ||
118 | .type = CLK_TYPE_PERIPHERAL, | ||
119 | }; | ||
120 | static struct clk isi_clk = { | ||
121 | .name = "isi_clk", | ||
122 | .pmc_mask = 1 << AT91SAM9260_ID_ISI, | ||
123 | .type = CLK_TYPE_PERIPHERAL, | ||
124 | }; | ||
125 | static struct clk usart3_clk = { | ||
126 | .name = "usart3_clk", | ||
127 | .pmc_mask = 1 << AT91SAM9260_ID_US3, | ||
128 | .type = CLK_TYPE_PERIPHERAL, | ||
129 | }; | ||
130 | static struct clk usart4_clk = { | ||
131 | .name = "usart4_clk", | ||
132 | .pmc_mask = 1 << AT91SAM9260_ID_US4, | ||
133 | .type = CLK_TYPE_PERIPHERAL, | ||
134 | }; | ||
135 | static struct clk usart5_clk = { | ||
136 | .name = "usart5_clk", | ||
137 | .pmc_mask = 1 << AT91SAM9260_ID_US5, | ||
138 | .type = CLK_TYPE_PERIPHERAL, | ||
139 | }; | ||
140 | |||
141 | static struct clk *periph_clocks[] __initdata = { | ||
142 | &pioA_clk, | ||
143 | &pioB_clk, | ||
144 | &pioC_clk, | ||
145 | &adc_clk, | ||
146 | &usart0_clk, | ||
147 | &usart1_clk, | ||
148 | &usart2_clk, | ||
149 | &mmc_clk, | ||
150 | &udc_clk, | ||
151 | &twi_clk, | ||
152 | &spi0_clk, | ||
153 | &spi1_clk, | ||
154 | // ssc | ||
155 | // tc0 .. tc2 | ||
156 | &ohci_clk, | ||
157 | ðer_clk, | ||
158 | &isi_clk, | ||
159 | &usart3_clk, | ||
160 | &usart4_clk, | ||
161 | &usart5_clk, | ||
162 | // tc3 .. tc5 | ||
163 | // irq0 .. irq2 | ||
164 | }; | ||
165 | |||
166 | /* | ||
167 | * The two programmable clocks. | ||
168 | * You must configure pin multiplexing to bring these signals out. | ||
169 | */ | ||
170 | static struct clk pck0 = { | ||
171 | .name = "pck0", | ||
172 | .pmc_mask = AT91_PMC_PCK0, | ||
173 | .type = CLK_TYPE_PROGRAMMABLE, | ||
174 | .id = 0, | ||
175 | }; | ||
176 | static struct clk pck1 = { | ||
177 | .name = "pck1", | ||
178 | .pmc_mask = AT91_PMC_PCK1, | ||
179 | .type = CLK_TYPE_PROGRAMMABLE, | ||
180 | .id = 1, | ||
181 | }; | ||
182 | |||
183 | static void __init at91sam9260_register_clocks(void) | ||
184 | { | ||
185 | int i; | ||
186 | |||
187 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
188 | clk_register(periph_clocks[i]); | ||
189 | |||
190 | clk_register(&pck0); | ||
191 | clk_register(&pck1); | ||
192 | } | ||
193 | |||
194 | /* -------------------------------------------------------------------- | ||
195 | * GPIO | ||
196 | * -------------------------------------------------------------------- */ | ||
197 | |||
198 | static struct at91_gpio_bank at91sam9260_gpio[] = { | ||
199 | { | ||
200 | .id = AT91SAM9260_ID_PIOA, | ||
201 | .offset = AT91_PIOA, | ||
202 | .clock = &pioA_clk, | ||
203 | }, { | ||
204 | .id = AT91SAM9260_ID_PIOB, | ||
205 | .offset = AT91_PIOB, | ||
206 | .clock = &pioB_clk, | ||
207 | }, { | ||
208 | .id = AT91SAM9260_ID_PIOC, | ||
209 | .offset = AT91_PIOC, | ||
210 | .clock = &pioC_clk, | ||
211 | } | ||
212 | }; | ||
213 | |||
214 | static void at91sam9260_reset(void) | ||
215 | { | ||
216 | at91_sys_write(AT91_RSTC_CR, (0xA5 << 24) | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); | ||
217 | } | ||
218 | |||
219 | |||
220 | /* -------------------------------------------------------------------- | ||
221 | * AT91SAM9260 processor initialization | ||
222 | * -------------------------------------------------------------------- */ | ||
223 | |||
224 | void __init at91sam9260_initialize(unsigned long main_clock) | ||
225 | { | ||
226 | /* Map peripherals */ | ||
227 | iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); | ||
228 | |||
229 | at91_arch_reset = at91sam9260_reset; | ||
230 | at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) | ||
231 | | (1 << AT91SAM9260_ID_IRQ2); | ||
232 | |||
233 | /* Init clock subsystem */ | ||
234 | at91_clock_init(main_clock); | ||
235 | |||
236 | /* Register the processor-specific clocks */ | ||
237 | at91sam9260_register_clocks(); | ||
238 | |||
239 | /* Register GPIO subsystem */ | ||
240 | at91_gpio_init(at91sam9260_gpio, 3); | ||
241 | } | ||
242 | |||
243 | /* -------------------------------------------------------------------- | ||
244 | * Interrupt initialization | ||
245 | * -------------------------------------------------------------------- */ | ||
246 | |||
247 | /* | ||
248 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
249 | */ | ||
250 | static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
251 | 7, /* Advanced Interrupt Controller */ | ||
252 | 7, /* System Peripherals */ | ||
253 | 0, /* Parallel IO Controller A */ | ||
254 | 0, /* Parallel IO Controller B */ | ||
255 | 0, /* Parallel IO Controller C */ | ||
256 | 0, /* Analog-to-Digital Converter */ | ||
257 | 6, /* USART 0 */ | ||
258 | 6, /* USART 1 */ | ||
259 | 6, /* USART 2 */ | ||
260 | 0, /* Multimedia Card Interface */ | ||
261 | 4, /* USB Device Port */ | ||
262 | 0, /* Two-Wire Interface */ | ||
263 | 6, /* Serial Peripheral Interface 0 */ | ||
264 | 6, /* Serial Peripheral Interface 1 */ | ||
265 | 5, /* Serial Synchronous Controller */ | ||
266 | 0, | ||
267 | 0, | ||
268 | 0, /* Timer Counter 0 */ | ||
269 | 0, /* Timer Counter 1 */ | ||
270 | 0, /* Timer Counter 2 */ | ||
271 | 3, /* USB Host port */ | ||
272 | 3, /* Ethernet */ | ||
273 | 0, /* Image Sensor Interface */ | ||
274 | 6, /* USART 3 */ | ||
275 | 6, /* USART 4 */ | ||
276 | 6, /* USART 5 */ | ||
277 | 0, /* Timer Counter 3 */ | ||
278 | 0, /* Timer Counter 4 */ | ||
279 | 0, /* Timer Counter 5 */ | ||
280 | 0, /* Advanced Interrupt Controller */ | ||
281 | 0, /* Advanced Interrupt Controller */ | ||
282 | 0, /* Advanced Interrupt Controller */ | ||
283 | }; | ||
284 | |||
285 | void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | ||
286 | { | ||
287 | if (!priority) | ||
288 | priority = at91sam9260_default_irq_priority; | ||
289 | |||
290 | /* Initialize the AIC interrupt controller */ | ||
291 | at91_aic_init(priority); | ||
292 | |||
293 | /* Enable GPIO interrupts */ | ||
294 | at91_gpio_irq_setup(); | ||
295 | } | ||
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c new file mode 100644 index 000000000000..4adff70b9ba0 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9260_devices.c | |||
@@ -0,0 +1,867 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/at91sam9260_devices.c | ||
3 | * | ||
4 | * Copyright (C) 2006 Atmel | ||
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 | #include <asm/mach/arch.h> | ||
13 | #include <asm/mach/map.h> | ||
14 | |||
15 | #include <linux/platform_device.h> | ||
16 | |||
17 | #include <asm/arch/board.h> | ||
18 | #include <asm/arch/gpio.h> | ||
19 | #include <asm/arch/at91sam9260.h> | ||
20 | #include <asm/arch/at91sam926x_mc.h> | ||
21 | #include <asm/arch/at91sam9260_matrix.h> | ||
22 | |||
23 | #include "generic.h" | ||
24 | |||
25 | #define SZ_512 0x00000200 | ||
26 | #define SZ_256 0x00000100 | ||
27 | #define SZ_16 0x00000010 | ||
28 | |||
29 | /* -------------------------------------------------------------------- | ||
30 | * USB Host | ||
31 | * -------------------------------------------------------------------- */ | ||
32 | |||
33 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
34 | static u64 ohci_dmamask = 0xffffffffUL; | ||
35 | static struct at91_usbh_data usbh_data; | ||
36 | |||
37 | static struct resource usbh_resources[] = { | ||
38 | [0] = { | ||
39 | .start = AT91SAM9260_UHP_BASE, | ||
40 | .end = AT91SAM9260_UHP_BASE + SZ_1M - 1, | ||
41 | .flags = IORESOURCE_MEM, | ||
42 | }, | ||
43 | [1] = { | ||
44 | .start = AT91SAM9260_ID_UHP, | ||
45 | .end = AT91SAM9260_ID_UHP, | ||
46 | .flags = IORESOURCE_IRQ, | ||
47 | }, | ||
48 | }; | ||
49 | |||
50 | static struct platform_device at91_usbh_device = { | ||
51 | .name = "at91_ohci", | ||
52 | .id = -1, | ||
53 | .dev = { | ||
54 | .dma_mask = &ohci_dmamask, | ||
55 | .coherent_dma_mask = 0xffffffff, | ||
56 | .platform_data = &usbh_data, | ||
57 | }, | ||
58 | .resource = usbh_resources, | ||
59 | .num_resources = ARRAY_SIZE(usbh_resources), | ||
60 | }; | ||
61 | |||
62 | void __init at91_add_device_usbh(struct at91_usbh_data *data) | ||
63 | { | ||
64 | if (!data) | ||
65 | return; | ||
66 | |||
67 | usbh_data = *data; | ||
68 | platform_device_register(&at91_usbh_device); | ||
69 | } | ||
70 | #else | ||
71 | void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | ||
72 | #endif | ||
73 | |||
74 | |||
75 | /* -------------------------------------------------------------------- | ||
76 | * USB Device (Gadget) | ||
77 | * -------------------------------------------------------------------- */ | ||
78 | |||
79 | #ifdef CONFIG_USB_GADGET_AT91 | ||
80 | static struct at91_udc_data udc_data; | ||
81 | |||
82 | static struct resource udc_resources[] = { | ||
83 | [0] = { | ||
84 | .start = AT91SAM9260_BASE_UDP, | ||
85 | .end = AT91SAM9260_BASE_UDP + SZ_16K - 1, | ||
86 | .flags = IORESOURCE_MEM, | ||
87 | }, | ||
88 | [1] = { | ||
89 | .start = AT91SAM9260_ID_UDP, | ||
90 | .end = AT91SAM9260_ID_UDP, | ||
91 | .flags = IORESOURCE_IRQ, | ||
92 | }, | ||
93 | }; | ||
94 | |||
95 | static struct platform_device at91_udc_device = { | ||
96 | .name = "at91_udc", | ||
97 | .id = -1, | ||
98 | .dev = { | ||
99 | .platform_data = &udc_data, | ||
100 | }, | ||
101 | .resource = udc_resources, | ||
102 | .num_resources = ARRAY_SIZE(udc_resources), | ||
103 | }; | ||
104 | |||
105 | void __init at91_add_device_udc(struct at91_udc_data *data) | ||
106 | { | ||
107 | if (!data) | ||
108 | return; | ||
109 | |||
110 | if (data->vbus_pin) { | ||
111 | at91_set_gpio_input(data->vbus_pin, 0); | ||
112 | at91_set_deglitch(data->vbus_pin, 1); | ||
113 | } | ||
114 | |||
115 | /* Pullup pin is handled internally by USB device peripheral */ | ||
116 | |||
117 | udc_data = *data; | ||
118 | platform_device_register(&at91_udc_device); | ||
119 | } | ||
120 | #else | ||
121 | void __init at91_add_device_udc(struct at91_udc_data *data) {} | ||
122 | #endif | ||
123 | |||
124 | |||
125 | /* -------------------------------------------------------------------- | ||
126 | * Ethernet | ||
127 | * -------------------------------------------------------------------- */ | ||
128 | |||
129 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) | ||
130 | static u64 eth_dmamask = 0xffffffffUL; | ||
131 | static struct at91_eth_data eth_data; | ||
132 | |||
133 | static struct resource eth_resources[] = { | ||
134 | [0] = { | ||
135 | .start = AT91SAM9260_BASE_EMAC, | ||
136 | .end = AT91SAM9260_BASE_EMAC + SZ_16K - 1, | ||
137 | .flags = IORESOURCE_MEM, | ||
138 | }, | ||
139 | [1] = { | ||
140 | .start = AT91SAM9260_ID_EMAC, | ||
141 | .end = AT91SAM9260_ID_EMAC, | ||
142 | .flags = IORESOURCE_IRQ, | ||
143 | }, | ||
144 | }; | ||
145 | |||
146 | static struct platform_device at91sam9260_eth_device = { | ||
147 | .name = "macb", | ||
148 | .id = -1, | ||
149 | .dev = { | ||
150 | .dma_mask = ð_dmamask, | ||
151 | .coherent_dma_mask = 0xffffffff, | ||
152 | .platform_data = ð_data, | ||
153 | }, | ||
154 | .resource = eth_resources, | ||
155 | .num_resources = ARRAY_SIZE(eth_resources), | ||
156 | }; | ||
157 | |||
158 | void __init at91_add_device_eth(struct at91_eth_data *data) | ||
159 | { | ||
160 | if (!data) | ||
161 | return; | ||
162 | |||
163 | if (data->phy_irq_pin) { | ||
164 | at91_set_gpio_input(data->phy_irq_pin, 0); | ||
165 | at91_set_deglitch(data->phy_irq_pin, 1); | ||
166 | } | ||
167 | |||
168 | /* Pins used for MII and RMII */ | ||
169 | at91_set_A_periph(AT91_PIN_PA19, 0); /* ETXCK_EREFCK */ | ||
170 | at91_set_A_periph(AT91_PIN_PA17, 0); /* ERXDV */ | ||
171 | at91_set_A_periph(AT91_PIN_PA14, 0); /* ERX0 */ | ||
172 | at91_set_A_periph(AT91_PIN_PA15, 0); /* ERX1 */ | ||
173 | at91_set_A_periph(AT91_PIN_PA18, 0); /* ERXER */ | ||
174 | at91_set_A_periph(AT91_PIN_PA16, 0); /* ETXEN */ | ||
175 | at91_set_A_periph(AT91_PIN_PA12, 0); /* ETX0 */ | ||
176 | at91_set_A_periph(AT91_PIN_PA13, 0); /* ETX1 */ | ||
177 | at91_set_A_periph(AT91_PIN_PA21, 0); /* EMDIO */ | ||
178 | at91_set_A_periph(AT91_PIN_PA20, 0); /* EMDC */ | ||
179 | |||
180 | if (!data->is_rmii) { | ||
181 | at91_set_B_periph(AT91_PIN_PA28, 0); /* ECRS */ | ||
182 | at91_set_B_periph(AT91_PIN_PA29, 0); /* ECOL */ | ||
183 | at91_set_B_periph(AT91_PIN_PA25, 0); /* ERX2 */ | ||
184 | at91_set_B_periph(AT91_PIN_PA26, 0); /* ERX3 */ | ||
185 | at91_set_B_periph(AT91_PIN_PA27, 0); /* ERXCK */ | ||
186 | at91_set_B_periph(AT91_PIN_PA23, 0); /* ETX2 */ | ||
187 | at91_set_B_periph(AT91_PIN_PA24, 0); /* ETX3 */ | ||
188 | at91_set_B_periph(AT91_PIN_PA22, 0); /* ETXER */ | ||
189 | } | ||
190 | |||
191 | eth_data = *data; | ||
192 | platform_device_register(&at91sam9260_eth_device); | ||
193 | } | ||
194 | #else | ||
195 | void __init at91_add_device_eth(struct at91_eth_data *data) {} | ||
196 | #endif | ||
197 | |||
198 | |||
199 | /* -------------------------------------------------------------------- | ||
200 | * MMC / SD | ||
201 | * -------------------------------------------------------------------- */ | ||
202 | |||
203 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | ||
204 | static u64 mmc_dmamask = 0xffffffffUL; | ||
205 | static struct at91_mmc_data mmc_data; | ||
206 | |||
207 | static struct resource mmc_resources[] = { | ||
208 | [0] = { | ||
209 | .start = AT91SAM9260_BASE_MCI, | ||
210 | .end = AT91SAM9260_BASE_MCI + SZ_16K - 1, | ||
211 | .flags = IORESOURCE_MEM, | ||
212 | }, | ||
213 | [1] = { | ||
214 | .start = AT91SAM9260_ID_MCI, | ||
215 | .end = AT91SAM9260_ID_MCI, | ||
216 | .flags = IORESOURCE_IRQ, | ||
217 | }, | ||
218 | }; | ||
219 | |||
220 | static struct platform_device at91sam9260_mmc_device = { | ||
221 | .name = "at91_mci", | ||
222 | .id = -1, | ||
223 | .dev = { | ||
224 | .dma_mask = &mmc_dmamask, | ||
225 | .coherent_dma_mask = 0xffffffff, | ||
226 | .platform_data = &mmc_data, | ||
227 | }, | ||
228 | .resource = mmc_resources, | ||
229 | .num_resources = ARRAY_SIZE(mmc_resources), | ||
230 | }; | ||
231 | |||
232 | void __init at91_add_device_mmc(struct at91_mmc_data *data) | ||
233 | { | ||
234 | if (!data) | ||
235 | return; | ||
236 | |||
237 | /* input/irq */ | ||
238 | if (data->det_pin) { | ||
239 | at91_set_gpio_input(data->det_pin, 1); | ||
240 | at91_set_deglitch(data->det_pin, 1); | ||
241 | } | ||
242 | if (data->wp_pin) | ||
243 | at91_set_gpio_input(data->wp_pin, 1); | ||
244 | if (data->vcc_pin) | ||
245 | at91_set_gpio_output(data->vcc_pin, 0); | ||
246 | |||
247 | /* CLK */ | ||
248 | at91_set_A_periph(AT91_PIN_PA8, 0); | ||
249 | |||
250 | if (data->slot_b) { | ||
251 | /* CMD */ | ||
252 | at91_set_B_periph(AT91_PIN_PA1, 1); | ||
253 | |||
254 | /* DAT0, maybe DAT1..DAT3 */ | ||
255 | at91_set_B_periph(AT91_PIN_PA0, 1); | ||
256 | if (data->wire4) { | ||
257 | at91_set_B_periph(AT91_PIN_PA5, 1); | ||
258 | at91_set_B_periph(AT91_PIN_PA4, 1); | ||
259 | at91_set_B_periph(AT91_PIN_PA3, 1); | ||
260 | } | ||
261 | } else { | ||
262 | /* CMD */ | ||
263 | at91_set_A_periph(AT91_PIN_PA7, 1); | ||
264 | |||
265 | /* DAT0, maybe DAT1..DAT3 */ | ||
266 | at91_set_A_periph(AT91_PIN_PA6, 1); | ||
267 | if (data->wire4) { | ||
268 | at91_set_A_periph(AT91_PIN_PA9, 1); | ||
269 | at91_set_A_periph(AT91_PIN_PA10, 1); | ||
270 | at91_set_A_periph(AT91_PIN_PA11, 1); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | mmc_data = *data; | ||
275 | platform_device_register(&at91sam9260_mmc_device); | ||
276 | } | ||
277 | #else | ||
278 | void __init at91_add_device_mmc(struct at91_mmc_data *data) {} | ||
279 | #endif | ||
280 | |||
281 | |||
282 | /* -------------------------------------------------------------------- | ||
283 | * NAND / SmartMedia | ||
284 | * -------------------------------------------------------------------- */ | ||
285 | |||
286 | #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) | ||
287 | static struct at91_nand_data nand_data; | ||
288 | |||
289 | #define NAND_BASE AT91_CHIPSELECT_3 | ||
290 | |||
291 | static struct resource nand_resources[] = { | ||
292 | { | ||
293 | .start = NAND_BASE, | ||
294 | .end = NAND_BASE + SZ_8M - 1, | ||
295 | .flags = IORESOURCE_MEM, | ||
296 | } | ||
297 | }; | ||
298 | |||
299 | static struct platform_device at91sam9260_nand_device = { | ||
300 | .name = "at91_nand", | ||
301 | .id = -1, | ||
302 | .dev = { | ||
303 | .platform_data = &nand_data, | ||
304 | }, | ||
305 | .resource = nand_resources, | ||
306 | .num_resources = ARRAY_SIZE(nand_resources), | ||
307 | }; | ||
308 | |||
309 | void __init at91_add_device_nand(struct at91_nand_data *data) | ||
310 | { | ||
311 | unsigned long csa, mode; | ||
312 | |||
313 | if (!data) | ||
314 | return; | ||
315 | |||
316 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | ||
317 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC); | ||
318 | |||
319 | /* set the bus interface characteristics */ | ||
320 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) | ||
321 | | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); | ||
322 | |||
323 | at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5) | ||
324 | | AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5)); | ||
325 | |||
326 | at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7)); | ||
327 | |||
328 | if (data->bus_width_16) | ||
329 | mode = AT91_SMC_DBW_16; | ||
330 | else | ||
331 | mode = AT91_SMC_DBW_8; | ||
332 | at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1)); | ||
333 | |||
334 | /* enable pin */ | ||
335 | if (data->enable_pin) | ||
336 | at91_set_gpio_output(data->enable_pin, 1); | ||
337 | |||
338 | /* ready/busy pin */ | ||
339 | if (data->rdy_pin) | ||
340 | at91_set_gpio_input(data->rdy_pin, 1); | ||
341 | |||
342 | /* card detect pin */ | ||
343 | if (data->det_pin) | ||
344 | at91_set_gpio_input(data->det_pin, 1); | ||
345 | |||
346 | nand_data = *data; | ||
347 | platform_device_register(&at91sam9260_nand_device); | ||
348 | } | ||
349 | #else | ||
350 | void __init at91_add_device_nand(struct at91_nand_data *data) {} | ||
351 | #endif | ||
352 | |||
353 | |||
354 | /* -------------------------------------------------------------------- | ||
355 | * TWI (i2c) | ||
356 | * -------------------------------------------------------------------- */ | ||
357 | |||
358 | #if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | ||
359 | |||
360 | static struct resource twi_resources[] = { | ||
361 | [0] = { | ||
362 | .start = AT91SAM9260_BASE_TWI, | ||
363 | .end = AT91SAM9260_BASE_TWI + SZ_16K - 1, | ||
364 | .flags = IORESOURCE_MEM, | ||
365 | }, | ||
366 | [1] = { | ||
367 | .start = AT91SAM9260_ID_TWI, | ||
368 | .end = AT91SAM9260_ID_TWI, | ||
369 | .flags = IORESOURCE_IRQ, | ||
370 | }, | ||
371 | }; | ||
372 | |||
373 | static struct platform_device at91sam9260_twi_device = { | ||
374 | .name = "at91_i2c", | ||
375 | .id = -1, | ||
376 | .resource = twi_resources, | ||
377 | .num_resources = ARRAY_SIZE(twi_resources), | ||
378 | }; | ||
379 | |||
380 | void __init at91_add_device_i2c(void) | ||
381 | { | ||
382 | /* pins used for TWI interface */ | ||
383 | at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ | ||
384 | at91_set_multi_drive(AT91_PIN_PA23, 1); | ||
385 | |||
386 | at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */ | ||
387 | at91_set_multi_drive(AT91_PIN_PA24, 1); | ||
388 | |||
389 | platform_device_register(&at91sam9260_twi_device); | ||
390 | } | ||
391 | #else | ||
392 | void __init at91_add_device_i2c(void) {} | ||
393 | #endif | ||
394 | |||
395 | |||
396 | /* -------------------------------------------------------------------- | ||
397 | * SPI | ||
398 | * -------------------------------------------------------------------- */ | ||
399 | |||
400 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | ||
401 | static u64 spi_dmamask = 0xffffffffUL; | ||
402 | |||
403 | static struct resource spi0_resources[] = { | ||
404 | [0] = { | ||
405 | .start = AT91SAM9260_BASE_SPI0, | ||
406 | .end = AT91SAM9260_BASE_SPI0 + SZ_16K - 1, | ||
407 | .flags = IORESOURCE_MEM, | ||
408 | }, | ||
409 | [1] = { | ||
410 | .start = AT91SAM9260_ID_SPI0, | ||
411 | .end = AT91SAM9260_ID_SPI0, | ||
412 | .flags = IORESOURCE_IRQ, | ||
413 | }, | ||
414 | }; | ||
415 | |||
416 | static struct platform_device at91sam9260_spi0_device = { | ||
417 | .name = "atmel_spi", | ||
418 | .id = 0, | ||
419 | .dev = { | ||
420 | .dma_mask = &spi_dmamask, | ||
421 | .coherent_dma_mask = 0xffffffff, | ||
422 | }, | ||
423 | .resource = spi0_resources, | ||
424 | .num_resources = ARRAY_SIZE(spi0_resources), | ||
425 | }; | ||
426 | |||
427 | static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PC11, AT91_PIN_PC16, AT91_PIN_PC17 }; | ||
428 | |||
429 | static struct resource spi1_resources[] = { | ||
430 | [0] = { | ||
431 | .start = AT91SAM9260_BASE_SPI1, | ||
432 | .end = AT91SAM9260_BASE_SPI1 + SZ_16K - 1, | ||
433 | .flags = IORESOURCE_MEM, | ||
434 | }, | ||
435 | [1] = { | ||
436 | .start = AT91SAM9260_ID_SPI1, | ||
437 | .end = AT91SAM9260_ID_SPI1, | ||
438 | .flags = IORESOURCE_IRQ, | ||
439 | }, | ||
440 | }; | ||
441 | |||
442 | static struct platform_device at91sam9260_spi1_device = { | ||
443 | .name = "atmel_spi", | ||
444 | .id = 1, | ||
445 | .dev = { | ||
446 | .dma_mask = &spi_dmamask, | ||
447 | .coherent_dma_mask = 0xffffffff, | ||
448 | }, | ||
449 | .resource = spi1_resources, | ||
450 | .num_resources = ARRAY_SIZE(spi1_resources), | ||
451 | }; | ||
452 | |||
453 | static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PC5, AT91_PIN_PC4, AT91_PIN_PC3 }; | ||
454 | |||
455 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | ||
456 | { | ||
457 | int i; | ||
458 | unsigned long cs_pin; | ||
459 | short enable_spi0 = 0; | ||
460 | short enable_spi1 = 0; | ||
461 | |||
462 | /* Choose SPI chip-selects */ | ||
463 | for (i = 0; i < nr_devices; i++) { | ||
464 | if (devices[i].controller_data) | ||
465 | cs_pin = (unsigned long) devices[i].controller_data; | ||
466 | else if (devices[i].bus_num == 0) | ||
467 | cs_pin = spi0_standard_cs[devices[i].chip_select]; | ||
468 | else | ||
469 | cs_pin = spi1_standard_cs[devices[i].chip_select]; | ||
470 | |||
471 | if (devices[i].bus_num == 0) | ||
472 | enable_spi0 = 1; | ||
473 | else | ||
474 | enable_spi1 = 1; | ||
475 | |||
476 | /* enable chip-select pin */ | ||
477 | at91_set_gpio_output(cs_pin, 1); | ||
478 | |||
479 | /* pass chip-select pin to driver */ | ||
480 | devices[i].controller_data = (void *) cs_pin; | ||
481 | } | ||
482 | |||
483 | spi_register_board_info(devices, nr_devices); | ||
484 | |||
485 | /* Configure SPI bus(es) */ | ||
486 | if (enable_spi0) { | ||
487 | at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ | ||
488 | at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ | ||
489 | at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI1_SPCK */ | ||
490 | |||
491 | at91_clock_associate("spi0_clk", &at91sam9260_spi0_device.dev, "spi_clk"); | ||
492 | platform_device_register(&at91sam9260_spi0_device); | ||
493 | } | ||
494 | if (enable_spi1) { | ||
495 | at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI1_MISO */ | ||
496 | at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI1_MOSI */ | ||
497 | at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI1_SPCK */ | ||
498 | |||
499 | at91_clock_associate("spi1_clk", &at91sam9260_spi1_device.dev, "spi_clk"); | ||
500 | platform_device_register(&at91sam9260_spi1_device); | ||
501 | } | ||
502 | } | ||
503 | #else | ||
504 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} | ||
505 | #endif | ||
506 | |||
507 | |||
508 | /* -------------------------------------------------------------------- | ||
509 | * LEDs | ||
510 | * -------------------------------------------------------------------- */ | ||
511 | |||
512 | #if defined(CONFIG_LEDS) | ||
513 | u8 at91_leds_cpu; | ||
514 | u8 at91_leds_timer; | ||
515 | |||
516 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | ||
517 | { | ||
518 | at91_leds_cpu = cpu_led; | ||
519 | at91_leds_timer = timer_led; | ||
520 | } | ||
521 | #else | ||
522 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | ||
523 | #endif | ||
524 | |||
525 | |||
526 | /* -------------------------------------------------------------------- | ||
527 | * UART | ||
528 | * -------------------------------------------------------------------- */ | ||
529 | #if defined(CONFIG_SERIAL_ATMEL) | ||
530 | static struct resource dbgu_resources[] = { | ||
531 | [0] = { | ||
532 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | ||
533 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | ||
534 | .flags = IORESOURCE_MEM, | ||
535 | }, | ||
536 | [1] = { | ||
537 | .start = AT91_ID_SYS, | ||
538 | .end = AT91_ID_SYS, | ||
539 | .flags = IORESOURCE_IRQ, | ||
540 | }, | ||
541 | }; | ||
542 | |||
543 | static struct atmel_uart_data dbgu_data = { | ||
544 | .use_dma_tx = 0, | ||
545 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | ||
546 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | ||
547 | }; | ||
548 | |||
549 | static struct platform_device at91sam9260_dbgu_device = { | ||
550 | .name = "atmel_usart", | ||
551 | .id = 0, | ||
552 | .dev = { | ||
553 | .platform_data = &dbgu_data, | ||
554 | .coherent_dma_mask = 0xffffffff, | ||
555 | }, | ||
556 | .resource = dbgu_resources, | ||
557 | .num_resources = ARRAY_SIZE(dbgu_resources), | ||
558 | }; | ||
559 | |||
560 | static inline void configure_dbgu_pins(void) | ||
561 | { | ||
562 | at91_set_A_periph(AT91_PIN_PB14, 0); /* DRXD */ | ||
563 | at91_set_A_periph(AT91_PIN_PB15, 1); /* DTXD */ | ||
564 | } | ||
565 | |||
566 | static struct resource uart0_resources[] = { | ||
567 | [0] = { | ||
568 | .start = AT91SAM9260_BASE_US0, | ||
569 | .end = AT91SAM9260_BASE_US0 + SZ_16K - 1, | ||
570 | .flags = IORESOURCE_MEM, | ||
571 | }, | ||
572 | [1] = { | ||
573 | .start = AT91SAM9260_ID_US0, | ||
574 | .end = AT91SAM9260_ID_US0, | ||
575 | .flags = IORESOURCE_IRQ, | ||
576 | }, | ||
577 | }; | ||
578 | |||
579 | static struct atmel_uart_data uart0_data = { | ||
580 | .use_dma_tx = 1, | ||
581 | .use_dma_rx = 1, | ||
582 | }; | ||
583 | |||
584 | static struct platform_device at91sam9260_uart0_device = { | ||
585 | .name = "atmel_usart", | ||
586 | .id = 1, | ||
587 | .dev = { | ||
588 | .platform_data = &uart0_data, | ||
589 | .coherent_dma_mask = 0xffffffff, | ||
590 | }, | ||
591 | .resource = uart0_resources, | ||
592 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
593 | }; | ||
594 | |||
595 | static inline void configure_usart0_pins(void) | ||
596 | { | ||
597 | at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */ | ||
598 | at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */ | ||
599 | at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */ | ||
600 | at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */ | ||
601 | at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */ | ||
602 | at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */ | ||
603 | at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */ | ||
604 | at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */ | ||
605 | } | ||
606 | |||
607 | static struct resource uart1_resources[] = { | ||
608 | [0] = { | ||
609 | .start = AT91SAM9260_BASE_US1, | ||
610 | .end = AT91SAM9260_BASE_US1 + SZ_16K - 1, | ||
611 | .flags = IORESOURCE_MEM, | ||
612 | }, | ||
613 | [1] = { | ||
614 | .start = AT91SAM9260_ID_US1, | ||
615 | .end = AT91SAM9260_ID_US1, | ||
616 | .flags = IORESOURCE_IRQ, | ||
617 | }, | ||
618 | }; | ||
619 | |||
620 | static struct atmel_uart_data uart1_data = { | ||
621 | .use_dma_tx = 1, | ||
622 | .use_dma_rx = 1, | ||
623 | }; | ||
624 | |||
625 | static struct platform_device at91sam9260_uart1_device = { | ||
626 | .name = "atmel_usart", | ||
627 | .id = 2, | ||
628 | .dev = { | ||
629 | .platform_data = &uart1_data, | ||
630 | .coherent_dma_mask = 0xffffffff, | ||
631 | }, | ||
632 | .resource = uart1_resources, | ||
633 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
634 | }; | ||
635 | |||
636 | static inline void configure_usart1_pins(void) | ||
637 | { | ||
638 | at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */ | ||
639 | at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */ | ||
640 | at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */ | ||
641 | at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */ | ||
642 | } | ||
643 | |||
644 | static struct resource uart2_resources[] = { | ||
645 | [0] = { | ||
646 | .start = AT91SAM9260_BASE_US2, | ||
647 | .end = AT91SAM9260_BASE_US2 + SZ_16K - 1, | ||
648 | .flags = IORESOURCE_MEM, | ||
649 | }, | ||
650 | [1] = { | ||
651 | .start = AT91SAM9260_ID_US2, | ||
652 | .end = AT91SAM9260_ID_US2, | ||
653 | .flags = IORESOURCE_IRQ, | ||
654 | }, | ||
655 | }; | ||
656 | |||
657 | static struct atmel_uart_data uart2_data = { | ||
658 | .use_dma_tx = 1, | ||
659 | .use_dma_rx = 1, | ||
660 | }; | ||
661 | |||
662 | static struct platform_device at91sam9260_uart2_device = { | ||
663 | .name = "atmel_usart", | ||
664 | .id = 3, | ||
665 | .dev = { | ||
666 | .platform_data = &uart2_data, | ||
667 | .coherent_dma_mask = 0xffffffff, | ||
668 | }, | ||
669 | .resource = uart2_resources, | ||
670 | .num_resources = ARRAY_SIZE(uart2_resources), | ||
671 | }; | ||
672 | |||
673 | static inline void configure_usart2_pins(void) | ||
674 | { | ||
675 | at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */ | ||
676 | at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */ | ||
677 | } | ||
678 | |||
679 | static struct resource uart3_resources[] = { | ||
680 | [0] = { | ||
681 | .start = AT91SAM9260_BASE_US3, | ||
682 | .end = AT91SAM9260_BASE_US3 + SZ_16K - 1, | ||
683 | .flags = IORESOURCE_MEM, | ||
684 | }, | ||
685 | [1] = { | ||
686 | .start = AT91SAM9260_ID_US3, | ||
687 | .end = AT91SAM9260_ID_US3, | ||
688 | .flags = IORESOURCE_IRQ, | ||
689 | }, | ||
690 | }; | ||
691 | |||
692 | static struct atmel_uart_data uart3_data = { | ||
693 | .use_dma_tx = 1, | ||
694 | .use_dma_rx = 1, | ||
695 | }; | ||
696 | |||
697 | static struct platform_device at91sam9260_uart3_device = { | ||
698 | .name = "atmel_usart", | ||
699 | .id = 4, | ||
700 | .dev = { | ||
701 | .platform_data = &uart3_data, | ||
702 | .coherent_dma_mask = 0xffffffff, | ||
703 | }, | ||
704 | .resource = uart3_resources, | ||
705 | .num_resources = ARRAY_SIZE(uart3_resources), | ||
706 | }; | ||
707 | |||
708 | static inline void configure_usart3_pins(void) | ||
709 | { | ||
710 | at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */ | ||
711 | at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */ | ||
712 | } | ||
713 | |||
714 | static struct resource uart4_resources[] = { | ||
715 | [0] = { | ||
716 | .start = AT91SAM9260_BASE_US4, | ||
717 | .end = AT91SAM9260_BASE_US4 + SZ_16K - 1, | ||
718 | .flags = IORESOURCE_MEM, | ||
719 | }, | ||
720 | [1] = { | ||
721 | .start = AT91SAM9260_ID_US4, | ||
722 | .end = AT91SAM9260_ID_US4, | ||
723 | .flags = IORESOURCE_IRQ, | ||
724 | }, | ||
725 | }; | ||
726 | |||
727 | static struct atmel_uart_data uart4_data = { | ||
728 | .use_dma_tx = 1, | ||
729 | .use_dma_rx = 1, | ||
730 | }; | ||
731 | |||
732 | static struct platform_device at91sam9260_uart4_device = { | ||
733 | .name = "atmel_usart", | ||
734 | .id = 5, | ||
735 | .dev = { | ||
736 | .platform_data = &uart4_data, | ||
737 | .coherent_dma_mask = 0xffffffff, | ||
738 | }, | ||
739 | .resource = uart4_resources, | ||
740 | .num_resources = ARRAY_SIZE(uart4_resources), | ||
741 | }; | ||
742 | |||
743 | static inline void configure_usart4_pins(void) | ||
744 | { | ||
745 | at91_set_B_periph(AT91_PIN_PA31, 1); /* TXD4 */ | ||
746 | at91_set_B_periph(AT91_PIN_PA30, 0); /* RXD4 */ | ||
747 | } | ||
748 | |||
749 | static struct resource uart5_resources[] = { | ||
750 | [0] = { | ||
751 | .start = AT91SAM9260_BASE_US5, | ||
752 | .end = AT91SAM9260_BASE_US5 + SZ_16K - 1, | ||
753 | .flags = IORESOURCE_MEM, | ||
754 | }, | ||
755 | [1] = { | ||
756 | .start = AT91SAM9260_ID_US5, | ||
757 | .end = AT91SAM9260_ID_US5, | ||
758 | .flags = IORESOURCE_IRQ, | ||
759 | }, | ||
760 | }; | ||
761 | |||
762 | static struct atmel_uart_data uart5_data = { | ||
763 | .use_dma_tx = 1, | ||
764 | .use_dma_rx = 1, | ||
765 | }; | ||
766 | |||
767 | static struct platform_device at91sam9260_uart5_device = { | ||
768 | .name = "atmel_usart", | ||
769 | .id = 6, | ||
770 | .dev = { | ||
771 | .platform_data = &uart5_data, | ||
772 | .coherent_dma_mask = 0xffffffff, | ||
773 | }, | ||
774 | .resource = uart5_resources, | ||
775 | .num_resources = ARRAY_SIZE(uart5_resources), | ||
776 | }; | ||
777 | |||
778 | static inline void configure_usart5_pins(void) | ||
779 | { | ||
780 | at91_set_A_periph(AT91_PIN_PB12, 1); /* TXD5 */ | ||
781 | at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */ | ||
782 | } | ||
783 | |||
784 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | ||
785 | struct platform_device *atmel_default_console_device; /* the serial console device */ | ||
786 | |||
787 | void __init at91_init_serial(struct at91_uart_config *config) | ||
788 | { | ||
789 | int i; | ||
790 | |||
791 | /* Fill in list of supported UARTs */ | ||
792 | for (i = 0; i < config->nr_tty; i++) { | ||
793 | switch (config->tty_map[i]) { | ||
794 | case 0: | ||
795 | configure_usart0_pins(); | ||
796 | at91_uarts[i] = &at91sam9260_uart0_device; | ||
797 | at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart"); | ||
798 | break; | ||
799 | case 1: | ||
800 | configure_usart1_pins(); | ||
801 | at91_uarts[i] = &at91sam9260_uart1_device; | ||
802 | at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart"); | ||
803 | break; | ||
804 | case 2: | ||
805 | configure_usart2_pins(); | ||
806 | at91_uarts[i] = &at91sam9260_uart2_device; | ||
807 | at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart"); | ||
808 | break; | ||
809 | case 3: | ||
810 | configure_usart3_pins(); | ||
811 | at91_uarts[i] = &at91sam9260_uart3_device; | ||
812 | at91_clock_associate("usart3_clk", &at91sam9260_uart3_device.dev, "usart"); | ||
813 | break; | ||
814 | case 4: | ||
815 | configure_usart4_pins(); | ||
816 | at91_uarts[i] = &at91sam9260_uart4_device; | ||
817 | at91_clock_associate("usart4_clk", &at91sam9260_uart4_device.dev, "usart"); | ||
818 | break; | ||
819 | case 5: | ||
820 | configure_usart5_pins(); | ||
821 | at91_uarts[i] = &at91sam9260_uart5_device; | ||
822 | at91_clock_associate("usart5_clk", &at91sam9260_uart5_device.dev, "usart"); | ||
823 | break; | ||
824 | case 6: | ||
825 | configure_dbgu_pins(); | ||
826 | at91_uarts[i] = &at91sam9260_dbgu_device; | ||
827 | at91_clock_associate("mck", &at91sam9260_dbgu_device.dev, "usart"); | ||
828 | break; | ||
829 | default: | ||
830 | continue; | ||
831 | } | ||
832 | at91_uarts[i]->id = i; /* update ID number to mapped ID */ | ||
833 | } | ||
834 | |||
835 | /* Set serial console device */ | ||
836 | if (config->console_tty < ATMEL_MAX_UART) | ||
837 | atmel_default_console_device = at91_uarts[config->console_tty]; | ||
838 | if (!atmel_default_console_device) | ||
839 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
840 | } | ||
841 | |||
842 | void __init at91_add_device_serial(void) | ||
843 | { | ||
844 | int i; | ||
845 | |||
846 | for (i = 0; i < ATMEL_MAX_UART; i++) { | ||
847 | if (at91_uarts[i]) | ||
848 | platform_device_register(at91_uarts[i]); | ||
849 | } | ||
850 | } | ||
851 | #else | ||
852 | void __init at91_init_serial(struct at91_uart_config *config) {} | ||
853 | void __init at91_add_device_serial(void) {} | ||
854 | #endif | ||
855 | |||
856 | |||
857 | /* -------------------------------------------------------------------- */ | ||
858 | /* | ||
859 | * These devices are always present and don't need any board-specific | ||
860 | * setup. | ||
861 | */ | ||
862 | static int __init at91_add_standard_devices(void) | ||
863 | { | ||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | arch_initcall(at91_add_standard_devices); | ||
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c new file mode 100644 index 000000000000..47e02ff7e872 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9261.c | |||
@@ -0,0 +1,290 @@ | |||
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 | |||
15 | #include <asm/mach/arch.h> | ||
16 | #include <asm/mach/map.h> | ||
17 | #include <asm/arch/at91sam9261.h> | ||
18 | #include <asm/arch/at91_pmc.h> | ||
19 | #include <asm/arch/at91_rstc.h> | ||
20 | |||
21 | #include "generic.h" | ||
22 | #include "clock.h" | ||
23 | |||
24 | static struct map_desc at91sam9261_io_desc[] __initdata = { | ||
25 | { | ||
26 | .virtual = AT91_VA_BASE_SYS, | ||
27 | .pfn = __phys_to_pfn(AT91_BASE_SYS), | ||
28 | .length = SZ_16K, | ||
29 | .type = MT_DEVICE, | ||
30 | }, { | ||
31 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE, | ||
32 | .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE), | ||
33 | .length = AT91SAM9261_SRAM_SIZE, | ||
34 | .type = MT_DEVICE, | ||
35 | }, | ||
36 | }; | ||
37 | |||
38 | /* -------------------------------------------------------------------- | ||
39 | * Clocks | ||
40 | * -------------------------------------------------------------------- */ | ||
41 | |||
42 | /* | ||
43 | * The peripheral clocks. | ||
44 | */ | ||
45 | static struct clk pioA_clk = { | ||
46 | .name = "pioA_clk", | ||
47 | .pmc_mask = 1 << AT91SAM9261_ID_PIOA, | ||
48 | .type = CLK_TYPE_PERIPHERAL, | ||
49 | }; | ||
50 | static struct clk pioB_clk = { | ||
51 | .name = "pioB_clk", | ||
52 | .pmc_mask = 1 << AT91SAM9261_ID_PIOB, | ||
53 | .type = CLK_TYPE_PERIPHERAL, | ||
54 | }; | ||
55 | static struct clk pioC_clk = { | ||
56 | .name = "pioC_clk", | ||
57 | .pmc_mask = 1 << AT91SAM9261_ID_PIOC, | ||
58 | .type = CLK_TYPE_PERIPHERAL, | ||
59 | }; | ||
60 | static struct clk usart0_clk = { | ||
61 | .name = "usart0_clk", | ||
62 | .pmc_mask = 1 << AT91SAM9261_ID_US0, | ||
63 | .type = CLK_TYPE_PERIPHERAL, | ||
64 | }; | ||
65 | static struct clk usart1_clk = { | ||
66 | .name = "usart1_clk", | ||
67 | .pmc_mask = 1 << AT91SAM9261_ID_US1, | ||
68 | .type = CLK_TYPE_PERIPHERAL, | ||
69 | }; | ||
70 | static struct clk usart2_clk = { | ||
71 | .name = "usart2_clk", | ||
72 | .pmc_mask = 1 << AT91SAM9261_ID_US2, | ||
73 | .type = CLK_TYPE_PERIPHERAL, | ||
74 | }; | ||
75 | static struct clk mmc_clk = { | ||
76 | .name = "mci_clk", | ||
77 | .pmc_mask = 1 << AT91SAM9261_ID_MCI, | ||
78 | .type = CLK_TYPE_PERIPHERAL, | ||
79 | }; | ||
80 | static struct clk udc_clk = { | ||
81 | .name = "udc_clk", | ||
82 | .pmc_mask = 1 << AT91SAM9261_ID_UDP, | ||
83 | .type = CLK_TYPE_PERIPHERAL, | ||
84 | }; | ||
85 | static struct clk twi_clk = { | ||
86 | .name = "twi_clk", | ||
87 | .pmc_mask = 1 << AT91SAM9261_ID_TWI, | ||
88 | .type = CLK_TYPE_PERIPHERAL, | ||
89 | }; | ||
90 | static struct clk spi0_clk = { | ||
91 | .name = "spi0_clk", | ||
92 | .pmc_mask = 1 << AT91SAM9261_ID_SPI0, | ||
93 | .type = CLK_TYPE_PERIPHERAL, | ||
94 | }; | ||
95 | static struct clk spi1_clk = { | ||
96 | .name = "spi1_clk", | ||
97 | .pmc_mask = 1 << AT91SAM9261_ID_SPI1, | ||
98 | .type = CLK_TYPE_PERIPHERAL, | ||
99 | }; | ||
100 | static struct clk ohci_clk = { | ||
101 | .name = "ohci_clk", | ||
102 | .pmc_mask = 1 << AT91SAM9261_ID_UHP, | ||
103 | .type = CLK_TYPE_PERIPHERAL, | ||
104 | }; | ||
105 | static struct clk lcdc_clk = { | ||
106 | .name = "lcdc_clk", | ||
107 | .pmc_mask = 1 << AT91SAM9261_ID_LCDC, | ||
108 | .type = CLK_TYPE_PERIPHERAL, | ||
109 | }; | ||
110 | |||
111 | static struct clk *periph_clocks[] __initdata = { | ||
112 | &pioA_clk, | ||
113 | &pioB_clk, | ||
114 | &pioC_clk, | ||
115 | &usart0_clk, | ||
116 | &usart1_clk, | ||
117 | &usart2_clk, | ||
118 | &mmc_clk, | ||
119 | &udc_clk, | ||
120 | &twi_clk, | ||
121 | &spi0_clk, | ||
122 | &spi1_clk, | ||
123 | // ssc 0 .. ssc2 | ||
124 | // tc0 .. tc2 | ||
125 | &ohci_clk, | ||
126 | &lcdc_clk, | ||
127 | // irq0 .. irq2 | ||
128 | }; | ||
129 | |||
130 | /* | ||
131 | * The four programmable clocks. | ||
132 | * You must configure pin multiplexing to bring these signals out. | ||
133 | */ | ||
134 | static struct clk pck0 = { | ||
135 | .name = "pck0", | ||
136 | .pmc_mask = AT91_PMC_PCK0, | ||
137 | .type = CLK_TYPE_PROGRAMMABLE, | ||
138 | .id = 0, | ||
139 | }; | ||
140 | static struct clk pck1 = { | ||
141 | .name = "pck1", | ||
142 | .pmc_mask = AT91_PMC_PCK1, | ||
143 | .type = CLK_TYPE_PROGRAMMABLE, | ||
144 | .id = 1, | ||
145 | }; | ||
146 | static struct clk pck2 = { | ||
147 | .name = "pck2", | ||
148 | .pmc_mask = AT91_PMC_PCK2, | ||
149 | .type = CLK_TYPE_PROGRAMMABLE, | ||
150 | .id = 2, | ||
151 | }; | ||
152 | static struct clk pck3 = { | ||
153 | .name = "pck3", | ||
154 | .pmc_mask = AT91_PMC_PCK3, | ||
155 | .type = CLK_TYPE_PROGRAMMABLE, | ||
156 | .id = 3, | ||
157 | }; | ||
158 | |||
159 | /* HClocks */ | ||
160 | static struct clk hck0 = { | ||
161 | .name = "hck0", | ||
162 | .pmc_mask = AT91_PMC_HCK0, | ||
163 | .type = CLK_TYPE_SYSTEM, | ||
164 | .id = 0, | ||
165 | }; | ||
166 | static struct clk hck1 = { | ||
167 | .name = "hck1", | ||
168 | .pmc_mask = AT91_PMC_HCK1, | ||
169 | .type = CLK_TYPE_SYSTEM, | ||
170 | .id = 1, | ||
171 | }; | ||
172 | |||
173 | static void __init at91sam9261_register_clocks(void) | ||
174 | { | ||
175 | int i; | ||
176 | |||
177 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
178 | clk_register(periph_clocks[i]); | ||
179 | |||
180 | clk_register(&pck0); | ||
181 | clk_register(&pck1); | ||
182 | clk_register(&pck2); | ||
183 | clk_register(&pck3); | ||
184 | |||
185 | clk_register(&hck0); | ||
186 | clk_register(&hck1); | ||
187 | } | ||
188 | |||
189 | /* -------------------------------------------------------------------- | ||
190 | * GPIO | ||
191 | * -------------------------------------------------------------------- */ | ||
192 | |||
193 | static struct at91_gpio_bank at91sam9261_gpio[] = { | ||
194 | { | ||
195 | .id = AT91SAM9261_ID_PIOA, | ||
196 | .offset = AT91_PIOA, | ||
197 | .clock = &pioA_clk, | ||
198 | }, { | ||
199 | .id = AT91SAM9261_ID_PIOB, | ||
200 | .offset = AT91_PIOB, | ||
201 | .clock = &pioB_clk, | ||
202 | }, { | ||
203 | .id = AT91SAM9261_ID_PIOC, | ||
204 | .offset = AT91_PIOC, | ||
205 | .clock = &pioC_clk, | ||
206 | } | ||
207 | }; | ||
208 | |||
209 | static void at91sam9261_reset(void) | ||
210 | { | ||
211 | at91_sys_write(AT91_RSTC_CR, (0xA5 << 24) | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); | ||
212 | } | ||
213 | |||
214 | |||
215 | /* -------------------------------------------------------------------- | ||
216 | * AT91SAM9261 processor initialization | ||
217 | * -------------------------------------------------------------------- */ | ||
218 | |||
219 | void __init at91sam9261_initialize(unsigned long main_clock) | ||
220 | { | ||
221 | /* Map peripherals */ | ||
222 | iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); | ||
223 | |||
224 | at91_arch_reset = at91sam9261_reset; | ||
225 | at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) | ||
226 | | (1 << AT91SAM9261_ID_IRQ2); | ||
227 | |||
228 | /* Init clock subsystem */ | ||
229 | at91_clock_init(main_clock); | ||
230 | |||
231 | /* Register the processor-specific clocks */ | ||
232 | at91sam9261_register_clocks(); | ||
233 | |||
234 | /* Register GPIO subsystem */ | ||
235 | at91_gpio_init(at91sam9261_gpio, 3); | ||
236 | } | ||
237 | |||
238 | /* -------------------------------------------------------------------- | ||
239 | * Interrupt initialization | ||
240 | * -------------------------------------------------------------------- */ | ||
241 | |||
242 | /* | ||
243 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
244 | */ | ||
245 | static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
246 | 7, /* Advanced Interrupt Controller */ | ||
247 | 7, /* System Peripherals */ | ||
248 | 0, /* Parallel IO Controller A */ | ||
249 | 0, /* Parallel IO Controller B */ | ||
250 | 0, /* Parallel IO Controller C */ | ||
251 | 0, | ||
252 | 6, /* USART 0 */ | ||
253 | 6, /* USART 1 */ | ||
254 | 6, /* USART 2 */ | ||
255 | 0, /* Multimedia Card Interface */ | ||
256 | 4, /* USB Device Port */ | ||
257 | 0, /* Two-Wire Interface */ | ||
258 | 6, /* Serial Peripheral Interface 0 */ | ||
259 | 6, /* Serial Peripheral Interface 1 */ | ||
260 | 5, /* Serial Synchronous Controller 0 */ | ||
261 | 5, /* Serial Synchronous Controller 1 */ | ||
262 | 5, /* Serial Synchronous Controller 2 */ | ||
263 | 0, /* Timer Counter 0 */ | ||
264 | 0, /* Timer Counter 1 */ | ||
265 | 0, /* Timer Counter 2 */ | ||
266 | 3, /* USB Host port */ | ||
267 | 3, /* LCD Controller */ | ||
268 | 0, | ||
269 | 0, | ||
270 | 0, | ||
271 | 0, | ||
272 | 0, | ||
273 | 0, | ||
274 | 0, | ||
275 | 0, /* Advanced Interrupt Controller */ | ||
276 | 0, /* Advanced Interrupt Controller */ | ||
277 | 0, /* Advanced Interrupt Controller */ | ||
278 | }; | ||
279 | |||
280 | void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | ||
281 | { | ||
282 | if (!priority) | ||
283 | priority = at91sam9261_default_irq_priority; | ||
284 | |||
285 | /* Initialize the AIC interrupt controller */ | ||
286 | at91_aic_init(priority); | ||
287 | |||
288 | /* Enable GPIO interrupts */ | ||
289 | at91_gpio_irq_setup(); | ||
290 | } | ||
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c new file mode 100644 index 000000000000..3249de08d1f3 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9261_devices.c | |||
@@ -0,0 +1,741 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/at91sam9261_devices.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> | ||
5 | * Copyright (C) 2005 David Brownell | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | #include <asm/mach/arch.h> | ||
14 | #include <asm/mach/map.h> | ||
15 | |||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include <asm/arch/board.h> | ||
19 | #include <asm/arch/gpio.h> | ||
20 | #include <asm/arch/at91sam9261.h> | ||
21 | #include <asm/arch/at91sam9261_matrix.h> | ||
22 | #include <asm/arch/at91sam926x_mc.h> | ||
23 | |||
24 | #include "generic.h" | ||
25 | |||
26 | #define SZ_512 0x00000200 | ||
27 | #define SZ_256 0x00000100 | ||
28 | #define SZ_16 0x00000010 | ||
29 | |||
30 | /* -------------------------------------------------------------------- | ||
31 | * USB Host | ||
32 | * -------------------------------------------------------------------- */ | ||
33 | |||
34 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | ||
35 | static u64 ohci_dmamask = 0xffffffffUL; | ||
36 | static struct at91_usbh_data usbh_data; | ||
37 | |||
38 | static struct resource usbh_resources[] = { | ||
39 | [0] = { | ||
40 | .start = AT91SAM9261_UHP_BASE, | ||
41 | .end = AT91SAM9261_UHP_BASE + SZ_1M - 1, | ||
42 | .flags = IORESOURCE_MEM, | ||
43 | }, | ||
44 | [1] = { | ||
45 | .start = AT91SAM9261_ID_UHP, | ||
46 | .end = AT91SAM9261_ID_UHP, | ||
47 | .flags = IORESOURCE_IRQ, | ||
48 | }, | ||
49 | }; | ||
50 | |||
51 | static struct platform_device at91sam9261_usbh_device = { | ||
52 | .name = "at91_ohci", | ||
53 | .id = -1, | ||
54 | .dev = { | ||
55 | .dma_mask = &ohci_dmamask, | ||
56 | .coherent_dma_mask = 0xffffffff, | ||
57 | .platform_data = &usbh_data, | ||
58 | }, | ||
59 | .resource = usbh_resources, | ||
60 | .num_resources = ARRAY_SIZE(usbh_resources), | ||
61 | }; | ||
62 | |||
63 | void __init at91_add_device_usbh(struct at91_usbh_data *data) | ||
64 | { | ||
65 | if (!data) | ||
66 | return; | ||
67 | |||
68 | usbh_data = *data; | ||
69 | platform_device_register(&at91sam9261_usbh_device); | ||
70 | } | ||
71 | #else | ||
72 | void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | ||
73 | #endif | ||
74 | |||
75 | |||
76 | /* -------------------------------------------------------------------- | ||
77 | * USB Device (Gadget) | ||
78 | * -------------------------------------------------------------------- */ | ||
79 | |||
80 | #ifdef CONFIG_USB_GADGET_AT91 | ||
81 | static struct at91_udc_data udc_data; | ||
82 | |||
83 | static struct resource udc_resources[] = { | ||
84 | [0] = { | ||
85 | .start = AT91SAM9261_BASE_UDP, | ||
86 | .end = AT91SAM9261_BASE_UDP + SZ_16K - 1, | ||
87 | .flags = IORESOURCE_MEM, | ||
88 | }, | ||
89 | [1] = { | ||
90 | .start = AT91SAM9261_ID_UDP, | ||
91 | .end = AT91SAM9261_ID_UDP, | ||
92 | .flags = IORESOURCE_IRQ, | ||
93 | }, | ||
94 | }; | ||
95 | |||
96 | static struct platform_device at91sam9261_udc_device = { | ||
97 | .name = "at91_udc", | ||
98 | .id = -1, | ||
99 | .dev = { | ||
100 | .platform_data = &udc_data, | ||
101 | }, | ||
102 | .resource = udc_resources, | ||
103 | .num_resources = ARRAY_SIZE(udc_resources), | ||
104 | }; | ||
105 | |||
106 | void __init at91_add_device_udc(struct at91_udc_data *data) | ||
107 | { | ||
108 | unsigned long x; | ||
109 | |||
110 | if (!data) | ||
111 | return; | ||
112 | |||
113 | if (data->vbus_pin) { | ||
114 | at91_set_gpio_input(data->vbus_pin, 0); | ||
115 | at91_set_deglitch(data->vbus_pin, 1); | ||
116 | } | ||
117 | |||
118 | /* Pullup pin is handled internally */ | ||
119 | x = at91_sys_read(AT91_MATRIX_USBPUCR); | ||
120 | at91_sys_write(AT91_MATRIX_USBPUCR, x | AT91_MATRIX_USBPUCR_PUON); | ||
121 | |||
122 | udc_data = *data; | ||
123 | platform_device_register(&at91sam9261_udc_device); | ||
124 | } | ||
125 | #else | ||
126 | void __init at91_add_device_udc(struct at91_udc_data *data) {} | ||
127 | #endif | ||
128 | |||
129 | /* -------------------------------------------------------------------- | ||
130 | * MMC / SD | ||
131 | * -------------------------------------------------------------------- */ | ||
132 | |||
133 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | ||
134 | static u64 mmc_dmamask = 0xffffffffUL; | ||
135 | static struct at91_mmc_data mmc_data; | ||
136 | |||
137 | static struct resource mmc_resources[] = { | ||
138 | [0] = { | ||
139 | .start = AT91SAM9261_BASE_MCI, | ||
140 | .end = AT91SAM9261_BASE_MCI + SZ_16K - 1, | ||
141 | .flags = IORESOURCE_MEM, | ||
142 | }, | ||
143 | [1] = { | ||
144 | .start = AT91SAM9261_ID_MCI, | ||
145 | .end = AT91SAM9261_ID_MCI, | ||
146 | .flags = IORESOURCE_IRQ, | ||
147 | }, | ||
148 | }; | ||
149 | |||
150 | static struct platform_device at91sam9261_mmc_device = { | ||
151 | .name = "at91_mci", | ||
152 | .id = -1, | ||
153 | .dev = { | ||
154 | .dma_mask = &mmc_dmamask, | ||
155 | .coherent_dma_mask = 0xffffffff, | ||
156 | .platform_data = &mmc_data, | ||
157 | }, | ||
158 | .resource = mmc_resources, | ||
159 | .num_resources = ARRAY_SIZE(mmc_resources), | ||
160 | }; | ||
161 | |||
162 | void __init at91_add_device_mmc(struct at91_mmc_data *data) | ||
163 | { | ||
164 | if (!data) | ||
165 | return; | ||
166 | |||
167 | /* input/irq */ | ||
168 | if (data->det_pin) { | ||
169 | at91_set_gpio_input(data->det_pin, 1); | ||
170 | at91_set_deglitch(data->det_pin, 1); | ||
171 | } | ||
172 | if (data->wp_pin) | ||
173 | at91_set_gpio_input(data->wp_pin, 1); | ||
174 | if (data->vcc_pin) | ||
175 | at91_set_gpio_output(data->vcc_pin, 0); | ||
176 | |||
177 | /* CLK */ | ||
178 | at91_set_B_periph(AT91_PIN_PA2, 0); | ||
179 | |||
180 | /* CMD */ | ||
181 | at91_set_B_periph(AT91_PIN_PA1, 1); | ||
182 | |||
183 | /* DAT0, maybe DAT1..DAT3 */ | ||
184 | at91_set_B_periph(AT91_PIN_PA0, 1); | ||
185 | if (data->wire4) { | ||
186 | at91_set_B_periph(AT91_PIN_PA4, 1); | ||
187 | at91_set_B_periph(AT91_PIN_PA5, 1); | ||
188 | at91_set_B_periph(AT91_PIN_PA6, 1); | ||
189 | } | ||
190 | |||
191 | mmc_data = *data; | ||
192 | platform_device_register(&at91sam9261_mmc_device); | ||
193 | } | ||
194 | #else | ||
195 | void __init at91_add_device_mmc(struct at91_mmc_data *data) {} | ||
196 | #endif | ||
197 | |||
198 | |||
199 | /* -------------------------------------------------------------------- | ||
200 | * NAND / SmartMedia | ||
201 | * -------------------------------------------------------------------- */ | ||
202 | |||
203 | #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) | ||
204 | static struct at91_nand_data nand_data; | ||
205 | |||
206 | #define NAND_BASE AT91_CHIPSELECT_3 | ||
207 | |||
208 | static struct resource nand_resources[] = { | ||
209 | { | ||
210 | .start = NAND_BASE, | ||
211 | .end = NAND_BASE + SZ_256M - 1, | ||
212 | .flags = IORESOURCE_MEM, | ||
213 | } | ||
214 | }; | ||
215 | |||
216 | static struct platform_device at91_nand_device = { | ||
217 | .name = "at91_nand", | ||
218 | .id = -1, | ||
219 | .dev = { | ||
220 | .platform_data = &nand_data, | ||
221 | }, | ||
222 | .resource = nand_resources, | ||
223 | .num_resources = ARRAY_SIZE(nand_resources), | ||
224 | }; | ||
225 | |||
226 | void __init at91_add_device_nand(struct at91_nand_data *data) | ||
227 | { | ||
228 | unsigned long csa, mode; | ||
229 | |||
230 | if (!data) | ||
231 | return; | ||
232 | |||
233 | csa = at91_sys_read(AT91_MATRIX_EBICSA); | ||
234 | at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC); | ||
235 | |||
236 | /* set the bus interface characteristics */ | ||
237 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) | ||
238 | | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); | ||
239 | |||
240 | at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5) | ||
241 | | AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5)); | ||
242 | |||
243 | at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7)); | ||
244 | |||
245 | if (data->bus_width_16) | ||
246 | mode = AT91_SMC_DBW_16; | ||
247 | else | ||
248 | mode = AT91_SMC_DBW_8; | ||
249 | at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1)); | ||
250 | |||
251 | /* enable pin */ | ||
252 | if (data->enable_pin) | ||
253 | at91_set_gpio_output(data->enable_pin, 1); | ||
254 | |||
255 | /* ready/busy pin */ | ||
256 | if (data->rdy_pin) | ||
257 | at91_set_gpio_input(data->rdy_pin, 1); | ||
258 | |||
259 | /* card detect pin */ | ||
260 | if (data->det_pin) | ||
261 | at91_set_gpio_input(data->det_pin, 1); | ||
262 | |||
263 | at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */ | ||
264 | at91_set_A_periph(AT91_PIN_PC1, 0); /* NANDWE */ | ||
265 | |||
266 | nand_data = *data; | ||
267 | platform_device_register(&at91_nand_device); | ||
268 | } | ||
269 | |||
270 | #else | ||
271 | void __init at91_add_device_nand(struct at91_nand_data *data) {} | ||
272 | #endif | ||
273 | |||
274 | |||
275 | /* -------------------------------------------------------------------- | ||
276 | * TWI (i2c) | ||
277 | * -------------------------------------------------------------------- */ | ||
278 | |||
279 | #if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | ||
280 | |||
281 | static struct resource twi_resources[] = { | ||
282 | [0] = { | ||
283 | .start = AT91SAM9261_BASE_TWI, | ||
284 | .end = AT91SAM9261_BASE_TWI + SZ_16K - 1, | ||
285 | .flags = IORESOURCE_MEM, | ||
286 | }, | ||
287 | [1] = { | ||
288 | .start = AT91SAM9261_ID_TWI, | ||
289 | .end = AT91SAM9261_ID_TWI, | ||
290 | .flags = IORESOURCE_IRQ, | ||
291 | }, | ||
292 | }; | ||
293 | |||
294 | static struct platform_device at91sam9261_twi_device = { | ||
295 | .name = "at91_i2c", | ||
296 | .id = -1, | ||
297 | .resource = twi_resources, | ||
298 | .num_resources = ARRAY_SIZE(twi_resources), | ||
299 | }; | ||
300 | |||
301 | void __init at91_add_device_i2c(void) | ||
302 | { | ||
303 | /* pins used for TWI interface */ | ||
304 | at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */ | ||
305 | at91_set_multi_drive(AT91_PIN_PA7, 1); | ||
306 | |||
307 | at91_set_A_periph(AT91_PIN_PA8, 0); /* TWCK */ | ||
308 | at91_set_multi_drive(AT91_PIN_PA8, 1); | ||
309 | |||
310 | platform_device_register(&at91sam9261_twi_device); | ||
311 | } | ||
312 | #else | ||
313 | void __init at91_add_device_i2c(void) {} | ||
314 | #endif | ||
315 | |||
316 | |||
317 | /* -------------------------------------------------------------------- | ||
318 | * SPI | ||
319 | * -------------------------------------------------------------------- */ | ||
320 | |||
321 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | ||
322 | static u64 spi_dmamask = 0xffffffffUL; | ||
323 | |||
324 | static struct resource spi0_resources[] = { | ||
325 | [0] = { | ||
326 | .start = AT91SAM9261_BASE_SPI0, | ||
327 | .end = AT91SAM9261_BASE_SPI0 + SZ_16K - 1, | ||
328 | .flags = IORESOURCE_MEM, | ||
329 | }, | ||
330 | [1] = { | ||
331 | .start = AT91SAM9261_ID_SPI0, | ||
332 | .end = AT91SAM9261_ID_SPI0, | ||
333 | .flags = IORESOURCE_IRQ, | ||
334 | }, | ||
335 | }; | ||
336 | |||
337 | static struct platform_device at91sam9261_spi0_device = { | ||
338 | .name = "atmel_spi", | ||
339 | .id = 0, | ||
340 | .dev = { | ||
341 | .dma_mask = &spi_dmamask, | ||
342 | .coherent_dma_mask = 0xffffffff, | ||
343 | }, | ||
344 | .resource = spi0_resources, | ||
345 | .num_resources = ARRAY_SIZE(spi0_resources), | ||
346 | }; | ||
347 | |||
348 | static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; | ||
349 | |||
350 | static struct resource spi1_resources[] = { | ||
351 | [0] = { | ||
352 | .start = AT91SAM9261_BASE_SPI1, | ||
353 | .end = AT91SAM9261_BASE_SPI1 + SZ_16K - 1, | ||
354 | .flags = IORESOURCE_MEM, | ||
355 | }, | ||
356 | [1] = { | ||
357 | .start = AT91SAM9261_ID_SPI1, | ||
358 | .end = AT91SAM9261_ID_SPI1, | ||
359 | .flags = IORESOURCE_IRQ, | ||
360 | }, | ||
361 | }; | ||
362 | |||
363 | static struct platform_device at91sam9261_spi1_device = { | ||
364 | .name = "atmel_spi", | ||
365 | .id = 1, | ||
366 | .dev = { | ||
367 | .dma_mask = &spi_dmamask, | ||
368 | .coherent_dma_mask = 0xffffffff, | ||
369 | }, | ||
370 | .resource = spi1_resources, | ||
371 | .num_resources = ARRAY_SIZE(spi1_resources), | ||
372 | }; | ||
373 | |||
374 | static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB28, AT91_PIN_PA24, AT91_PIN_PA25, AT91_PIN_PA26 }; | ||
375 | |||
376 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | ||
377 | { | ||
378 | int i; | ||
379 | unsigned long cs_pin; | ||
380 | short enable_spi0 = 0; | ||
381 | short enable_spi1 = 0; | ||
382 | |||
383 | /* Choose SPI chip-selects */ | ||
384 | for (i = 0; i < nr_devices; i++) { | ||
385 | if (devices[i].controller_data) | ||
386 | cs_pin = (unsigned long) devices[i].controller_data; | ||
387 | else if (devices[i].bus_num == 0) | ||
388 | cs_pin = spi0_standard_cs[devices[i].chip_select]; | ||
389 | else | ||
390 | cs_pin = spi1_standard_cs[devices[i].chip_select]; | ||
391 | |||
392 | if (devices[i].bus_num == 0) | ||
393 | enable_spi0 = 1; | ||
394 | else | ||
395 | enable_spi1 = 1; | ||
396 | |||
397 | /* enable chip-select pin */ | ||
398 | at91_set_gpio_output(cs_pin, 1); | ||
399 | |||
400 | /* pass chip-select pin to driver */ | ||
401 | devices[i].controller_data = (void *) cs_pin; | ||
402 | } | ||
403 | |||
404 | spi_register_board_info(devices, nr_devices); | ||
405 | |||
406 | /* Configure SPI bus(es) */ | ||
407 | if (enable_spi0) { | ||
408 | at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ | ||
409 | at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ | ||
410 | at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ | ||
411 | |||
412 | at91_clock_associate("spi0_clk", &at91sam9261_spi0_device.dev, "spi_clk"); | ||
413 | platform_device_register(&at91sam9261_spi0_device); | ||
414 | } | ||
415 | if (enable_spi1) { | ||
416 | at91_set_A_periph(AT91_PIN_PB30, 0); /* SPI1_MISO */ | ||
417 | at91_set_A_periph(AT91_PIN_PB31, 0); /* SPI1_MOSI */ | ||
418 | at91_set_A_periph(AT91_PIN_PB29, 0); /* SPI1_SPCK */ | ||
419 | |||
420 | at91_clock_associate("spi1_clk", &at91sam9261_spi1_device.dev, "spi_clk"); | ||
421 | platform_device_register(&at91sam9261_spi1_device); | ||
422 | } | ||
423 | } | ||
424 | #else | ||
425 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} | ||
426 | #endif | ||
427 | |||
428 | |||
429 | /* -------------------------------------------------------------------- | ||
430 | * LCD Controller | ||
431 | * -------------------------------------------------------------------- */ | ||
432 | |||
433 | #if defined(CONFIG_FB_AT91) || defined(CONFIG_FB_AT91_MODULE) | ||
434 | static u64 lcdc_dmamask = 0xffffffffUL; | ||
435 | static struct at91fb_info lcdc_data; | ||
436 | |||
437 | static struct resource lcdc_resources[] = { | ||
438 | [0] = { | ||
439 | .start = AT91SAM9261_LCDC_BASE, | ||
440 | .end = AT91SAM9261_LCDC_BASE + SZ_4K - 1, | ||
441 | .flags = IORESOURCE_MEM, | ||
442 | }, | ||
443 | [1] = { | ||
444 | .start = AT91SAM9261_ID_LCDC, | ||
445 | .end = AT91SAM9261_ID_LCDC, | ||
446 | .flags = IORESOURCE_IRQ, | ||
447 | }, | ||
448 | #if defined(CONFIG_FB_INTSRAM) | ||
449 | [2] = { | ||
450 | .start = AT91SAM9261_SRAM_BASE, | ||
451 | .end = AT91SAM9261_SRAM_BASE + AT91SAM9261_SRAM_SIZE - 1, | ||
452 | .flags = IORESOURCE_MEM, | ||
453 | }, | ||
454 | #endif | ||
455 | }; | ||
456 | |||
457 | static struct platform_device at91_lcdc_device = { | ||
458 | .name = "at91-fb", | ||
459 | .id = 0, | ||
460 | .dev = { | ||
461 | .dma_mask = &lcdc_dmamask, | ||
462 | .coherent_dma_mask = 0xffffffff, | ||
463 | .platform_data = &lcdc_data, | ||
464 | }, | ||
465 | .resource = lcdc_resources, | ||
466 | .num_resources = ARRAY_SIZE(lcdc_resources), | ||
467 | }; | ||
468 | |||
469 | void __init at91_add_device_lcdc(struct at91fb_info *data) | ||
470 | { | ||
471 | if (!data) { | ||
472 | return; | ||
473 | } | ||
474 | |||
475 | at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ | ||
476 | at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ | ||
477 | at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ | ||
478 | at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */ | ||
479 | at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */ | ||
480 | at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */ | ||
481 | at91_set_A_periph(AT91_PIN_PB9, 0); /* LCDD4 */ | ||
482 | at91_set_A_periph(AT91_PIN_PB10, 0); /* LCDD5 */ | ||
483 | at91_set_A_periph(AT91_PIN_PB11, 0); /* LCDD6 */ | ||
484 | at91_set_A_periph(AT91_PIN_PB12, 0); /* LCDD7 */ | ||
485 | at91_set_A_periph(AT91_PIN_PB15, 0); /* LCDD10 */ | ||
486 | at91_set_A_periph(AT91_PIN_PB16, 0); /* LCDD11 */ | ||
487 | at91_set_A_periph(AT91_PIN_PB17, 0); /* LCDD12 */ | ||
488 | at91_set_A_periph(AT91_PIN_PB18, 0); /* LCDD13 */ | ||
489 | at91_set_A_periph(AT91_PIN_PB19, 0); /* LCDD14 */ | ||
490 | at91_set_A_periph(AT91_PIN_PB20, 0); /* LCDD15 */ | ||
491 | at91_set_B_periph(AT91_PIN_PB23, 0); /* LCDD18 */ | ||
492 | at91_set_B_periph(AT91_PIN_PB24, 0); /* LCDD19 */ | ||
493 | at91_set_B_periph(AT91_PIN_PB25, 0); /* LCDD20 */ | ||
494 | at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */ | ||
495 | at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */ | ||
496 | at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */ | ||
497 | |||
498 | lcdc_data = *data; | ||
499 | platform_device_register(&at91_lcdc_device); | ||
500 | } | ||
501 | #else | ||
502 | void __init at91_add_device_lcdc(struct at91fb_info *data) {} | ||
503 | #endif | ||
504 | |||
505 | |||
506 | /* -------------------------------------------------------------------- | ||
507 | * LEDs | ||
508 | * -------------------------------------------------------------------- */ | ||
509 | |||
510 | #if defined(CONFIG_LEDS) | ||
511 | u8 at91_leds_cpu; | ||
512 | u8 at91_leds_timer; | ||
513 | |||
514 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | ||
515 | { | ||
516 | at91_leds_cpu = cpu_led; | ||
517 | at91_leds_timer = timer_led; | ||
518 | } | ||
519 | #else | ||
520 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | ||
521 | #endif | ||
522 | |||
523 | |||
524 | /* -------------------------------------------------------------------- | ||
525 | * UART | ||
526 | * -------------------------------------------------------------------- */ | ||
527 | |||
528 | #if defined(CONFIG_SERIAL_ATMEL) | ||
529 | static struct resource dbgu_resources[] = { | ||
530 | [0] = { | ||
531 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | ||
532 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | ||
533 | .flags = IORESOURCE_MEM, | ||
534 | }, | ||
535 | [1] = { | ||
536 | .start = AT91_ID_SYS, | ||
537 | .end = AT91_ID_SYS, | ||
538 | .flags = IORESOURCE_IRQ, | ||
539 | }, | ||
540 | }; | ||
541 | |||
542 | static struct atmel_uart_data dbgu_data = { | ||
543 | .use_dma_tx = 0, | ||
544 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | ||
545 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | ||
546 | }; | ||
547 | |||
548 | static struct platform_device at91sam9261_dbgu_device = { | ||
549 | .name = "atmel_usart", | ||
550 | .id = 0, | ||
551 | .dev = { | ||
552 | .platform_data = &dbgu_data, | ||
553 | .coherent_dma_mask = 0xffffffff, | ||
554 | }, | ||
555 | .resource = dbgu_resources, | ||
556 | .num_resources = ARRAY_SIZE(dbgu_resources), | ||
557 | }; | ||
558 | |||
559 | static inline void configure_dbgu_pins(void) | ||
560 | { | ||
561 | at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ | ||
562 | at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */ | ||
563 | } | ||
564 | |||
565 | static struct resource uart0_resources[] = { | ||
566 | [0] = { | ||
567 | .start = AT91SAM9261_BASE_US0, | ||
568 | .end = AT91SAM9261_BASE_US0 + SZ_16K - 1, | ||
569 | .flags = IORESOURCE_MEM, | ||
570 | }, | ||
571 | [1] = { | ||
572 | .start = AT91SAM9261_ID_US0, | ||
573 | .end = AT91SAM9261_ID_US0, | ||
574 | .flags = IORESOURCE_IRQ, | ||
575 | }, | ||
576 | }; | ||
577 | |||
578 | static struct atmel_uart_data uart0_data = { | ||
579 | .use_dma_tx = 1, | ||
580 | .use_dma_rx = 1, | ||
581 | }; | ||
582 | |||
583 | static struct platform_device at91sam9261_uart0_device = { | ||
584 | .name = "atmel_usart", | ||
585 | .id = 1, | ||
586 | .dev = { | ||
587 | .platform_data = &uart0_data, | ||
588 | .coherent_dma_mask = 0xffffffff, | ||
589 | }, | ||
590 | .resource = uart0_resources, | ||
591 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
592 | }; | ||
593 | |||
594 | static inline void configure_usart0_pins(void) | ||
595 | { | ||
596 | at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ | ||
597 | at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ | ||
598 | at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */ | ||
599 | at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */ | ||
600 | } | ||
601 | |||
602 | static struct resource uart1_resources[] = { | ||
603 | [0] = { | ||
604 | .start = AT91SAM9261_BASE_US1, | ||
605 | .end = AT91SAM9261_BASE_US1 + SZ_16K - 1, | ||
606 | .flags = IORESOURCE_MEM, | ||
607 | }, | ||
608 | [1] = { | ||
609 | .start = AT91SAM9261_ID_US1, | ||
610 | .end = AT91SAM9261_ID_US1, | ||
611 | .flags = IORESOURCE_IRQ, | ||
612 | }, | ||
613 | }; | ||
614 | |||
615 | static struct atmel_uart_data uart1_data = { | ||
616 | .use_dma_tx = 1, | ||
617 | .use_dma_rx = 1, | ||
618 | }; | ||
619 | |||
620 | static struct platform_device at91sam9261_uart1_device = { | ||
621 | .name = "atmel_usart", | ||
622 | .id = 2, | ||
623 | .dev = { | ||
624 | .platform_data = &uart1_data, | ||
625 | .coherent_dma_mask = 0xffffffff, | ||
626 | }, | ||
627 | .resource = uart1_resources, | ||
628 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
629 | }; | ||
630 | |||
631 | static inline void configure_usart1_pins(void) | ||
632 | { | ||
633 | at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ | ||
634 | at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ | ||
635 | } | ||
636 | |||
637 | static struct resource uart2_resources[] = { | ||
638 | [0] = { | ||
639 | .start = AT91SAM9261_BASE_US2, | ||
640 | .end = AT91SAM9261_BASE_US2 + SZ_16K - 1, | ||
641 | .flags = IORESOURCE_MEM, | ||
642 | }, | ||
643 | [1] = { | ||
644 | .start = AT91SAM9261_ID_US2, | ||
645 | .end = AT91SAM9261_ID_US2, | ||
646 | .flags = IORESOURCE_IRQ, | ||
647 | }, | ||
648 | }; | ||
649 | |||
650 | static struct atmel_uart_data uart2_data = { | ||
651 | .use_dma_tx = 1, | ||
652 | .use_dma_rx = 1, | ||
653 | }; | ||
654 | |||
655 | static struct platform_device at91sam9261_uart2_device = { | ||
656 | .name = "atmel_usart", | ||
657 | .id = 3, | ||
658 | .dev = { | ||
659 | .platform_data = &uart2_data, | ||
660 | .coherent_dma_mask = 0xffffffff, | ||
661 | }, | ||
662 | .resource = uart2_resources, | ||
663 | .num_resources = ARRAY_SIZE(uart2_resources), | ||
664 | }; | ||
665 | |||
666 | static inline void configure_usart2_pins(void) | ||
667 | { | ||
668 | at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ | ||
669 | at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ | ||
670 | } | ||
671 | |||
672 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | ||
673 | struct platform_device *atmel_default_console_device; /* the serial console device */ | ||
674 | |||
675 | void __init at91_init_serial(struct at91_uart_config *config) | ||
676 | { | ||
677 | int i; | ||
678 | |||
679 | /* Fill in list of supported UARTs */ | ||
680 | for (i = 0; i < config->nr_tty; i++) { | ||
681 | switch (config->tty_map[i]) { | ||
682 | case 0: | ||
683 | configure_usart0_pins(); | ||
684 | at91_uarts[i] = &at91sam9261_uart0_device; | ||
685 | at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart"); | ||
686 | break; | ||
687 | case 1: | ||
688 | configure_usart1_pins(); | ||
689 | at91_uarts[i] = &at91sam9261_uart1_device; | ||
690 | at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart"); | ||
691 | break; | ||
692 | case 2: | ||
693 | configure_usart2_pins(); | ||
694 | at91_uarts[i] = &at91sam9261_uart2_device; | ||
695 | at91_clock_associate("usart2_clk", &at91sam9261_uart2_device.dev, "usart"); | ||
696 | break; | ||
697 | case 3: | ||
698 | configure_dbgu_pins(); | ||
699 | at91_uarts[i] = &at91sam9261_dbgu_device; | ||
700 | at91_clock_associate("mck", &at91sam9261_dbgu_device.dev, "usart"); | ||
701 | break; | ||
702 | default: | ||
703 | continue; | ||
704 | } | ||
705 | at91_uarts[i]->id = i; /* update ID number to mapped ID */ | ||
706 | } | ||
707 | |||
708 | /* Set serial console device */ | ||
709 | if (config->console_tty < ATMEL_MAX_UART) | ||
710 | atmel_default_console_device = at91_uarts[config->console_tty]; | ||
711 | if (!atmel_default_console_device) | ||
712 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
713 | } | ||
714 | |||
715 | void __init at91_add_device_serial(void) | ||
716 | { | ||
717 | int i; | ||
718 | |||
719 | for (i = 0; i < ATMEL_MAX_UART; i++) { | ||
720 | if (at91_uarts[i]) | ||
721 | platform_device_register(at91_uarts[i]); | ||
722 | } | ||
723 | } | ||
724 | #else | ||
725 | void __init at91_init_serial(struct at91_uart_config *config) {} | ||
726 | void __init at91_add_device_serial(void) {} | ||
727 | #endif | ||
728 | |||
729 | |||
730 | /* -------------------------------------------------------------------- */ | ||
731 | |||
732 | /* | ||
733 | * These devices are always present and don't need any board-specific | ||
734 | * setup. | ||
735 | */ | ||
736 | static int __init at91_add_standard_devices(void) | ||
737 | { | ||
738 | return 0; | ||
739 | } | ||
740 | |||
741 | arch_initcall(at91_add_standard_devices); | ||
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c new file mode 100644 index 000000000000..59cbbe1e8161 --- /dev/null +++ b/arch/arm/mach-at91/at91sam926x_time.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/at91sam926x_time.c | ||
3 | * | ||
4 | * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France | ||
5 | * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/sched.h> | ||
17 | #include <linux/time.h> | ||
18 | |||
19 | #include <asm/hardware.h> | ||
20 | #include <asm/io.h> | ||
21 | #include <asm/mach/time.h> | ||
22 | |||
23 | #include <asm/arch/at91_pit.h> | ||
24 | |||
25 | |||
26 | #define PIT_CPIV(x) ((x) & AT91_PIT_CPIV) | ||
27 | #define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20) | ||
28 | |||
29 | /* | ||
30 | * Returns number of microseconds since last timer interrupt. Note that interrupts | ||
31 | * will have been disabled by do_gettimeofday() | ||
32 | * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy. | ||
33 | * 'tick' is usecs per jiffy (linux/timex.h). | ||
34 | */ | ||
35 | static unsigned long at91sam926x_gettimeoffset(void) | ||
36 | { | ||
37 | unsigned long elapsed; | ||
38 | unsigned long t = at91_sys_read(AT91_PIT_PIIR); | ||
39 | |||
40 | elapsed = (PIT_PICNT(t) * LATCH) + PIT_CPIV(t); /* hardware clock cycles */ | ||
41 | |||
42 | return (unsigned long)(elapsed * 1000000) / LATCH; | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | * IRQ handler for the timer. | ||
47 | */ | ||
48 | static irqreturn_t at91sam926x_timer_interrupt(int irq, void *dev_id) | ||
49 | { | ||
50 | volatile long nr_ticks; | ||
51 | |||
52 | if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) { /* This is a shared interrupt */ | ||
53 | write_seqlock(&xtime_lock); | ||
54 | |||
55 | /* Get number to ticks performed before interrupt and clear PIT interrupt */ | ||
56 | nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); | ||
57 | do { | ||
58 | timer_tick(); | ||
59 | nr_ticks--; | ||
60 | } while (nr_ticks); | ||
61 | |||
62 | write_sequnlock(&xtime_lock); | ||
63 | return IRQ_HANDLED; | ||
64 | } else | ||
65 | return IRQ_NONE; /* not handled */ | ||
66 | } | ||
67 | |||
68 | static struct irqaction at91sam926x_timer_irq = { | ||
69 | .name = "at91_tick", | ||
70 | .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER, | ||
71 | .handler = at91sam926x_timer_interrupt | ||
72 | }; | ||
73 | |||
74 | void at91sam926x_timer_reset(void) | ||
75 | { | ||
76 | /* Disable timer */ | ||
77 | at91_sys_write(AT91_PIT_MR, 0); | ||
78 | |||
79 | /* Clear any pending interrupts */ | ||
80 | (void) at91_sys_read(AT91_PIT_PIVR); | ||
81 | |||
82 | /* Set Period Interval timer and enable its interrupt */ | ||
83 | at91_sys_write(AT91_PIT_MR, (LATCH & AT91_PIT_PIV) | AT91_PIT_PITIEN | AT91_PIT_PITEN); | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Set up timer interrupt. | ||
88 | */ | ||
89 | void __init at91sam926x_timer_init(void) | ||
90 | { | ||
91 | /* Initialize and enable the timer */ | ||
92 | at91sam926x_timer_reset(); | ||
93 | |||
94 | /* Make IRQs happen for the system timer. */ | ||
95 | setup_irq(AT91_ID_SYS, &at91sam926x_timer_irq); | ||
96 | } | ||
97 | |||
98 | #ifdef CONFIG_PM | ||
99 | static void at91sam926x_timer_suspend(void) | ||
100 | { | ||
101 | /* Disable timer */ | ||
102 | at91_sys_write(AT91_PIT_MR, 0); | ||
103 | } | ||
104 | #else | ||
105 | #define at91sam926x_timer_suspend NULL | ||
106 | #endif | ||
107 | |||
108 | struct sys_timer at91sam926x_timer = { | ||
109 | .init = at91sam926x_timer_init, | ||
110 | .offset = at91sam926x_gettimeoffset, | ||
111 | .suspend = at91sam926x_timer_suspend, | ||
112 | .resume = at91sam926x_timer_reset, | ||
113 | }; | ||
114 | |||
diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c new file mode 100644 index 000000000000..2d3d4b6f7b02 --- /dev/null +++ b/arch/arm/mach-at91/board-1arm.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-1arm.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 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/types.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/mm.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | |||
27 | #include <asm/hardware.h> | ||
28 | #include <asm/setup.h> | ||
29 | #include <asm/mach-types.h> | ||
30 | #include <asm/irq.h> | ||
31 | |||
32 | #include <asm/mach/arch.h> | ||
33 | #include <asm/mach/map.h> | ||
34 | #include <asm/mach/irq.h> | ||
35 | |||
36 | #include <asm/arch/board.h> | ||
37 | #include <asm/arch/gpio.h> | ||
38 | |||
39 | #include "generic.h" | ||
40 | |||
41 | |||
42 | /* | ||
43 | * Serial port configuration. | ||
44 | * 0 .. 3 = USART0 .. USART3 | ||
45 | * 4 = DBGU | ||
46 | */ | ||
47 | static struct at91_uart_config __initdata onearm_uart_config = { | ||
48 | .console_tty = 0, /* ttyS0 */ | ||
49 | .nr_tty = 3, | ||
50 | .tty_map = { 4, 0, 1, -1, -1 }, /* ttyS0, ..., ttyS4 */ | ||
51 | }; | ||
52 | |||
53 | static void __init onearm_map_io(void) | ||
54 | { | ||
55 | /* Initialize processor: 18.432 MHz crystal */ | ||
56 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | ||
57 | |||
58 | /* Setup the serial ports and console */ | ||
59 | at91_init_serial(&onearm_uart_config); | ||
60 | } | ||
61 | |||
62 | static void __init onearm_init_irq(void) | ||
63 | { | ||
64 | at91rm9200_init_interrupts(NULL); | ||
65 | } | ||
66 | |||
67 | static struct at91_eth_data __initdata onearm_eth_data = { | ||
68 | .phy_irq_pin = AT91_PIN_PC4, | ||
69 | .is_rmii = 1, | ||
70 | }; | ||
71 | |||
72 | static struct at91_usbh_data __initdata onearm_usbh_data = { | ||
73 | .ports = 1, | ||
74 | }; | ||
75 | |||
76 | static struct at91_udc_data __initdata onearm_udc_data = { | ||
77 | .vbus_pin = AT91_PIN_PC2, | ||
78 | .pullup_pin = AT91_PIN_PC3, | ||
79 | }; | ||
80 | |||
81 | static void __init onearm_board_init(void) | ||
82 | { | ||
83 | /* Serial */ | ||
84 | at91_add_device_serial(); | ||
85 | /* Ethernet */ | ||
86 | at91_add_device_eth(&onearm_eth_data); | ||
87 | /* USB Host */ | ||
88 | at91_add_device_usbh(&onearm_usbh_data); | ||
89 | /* USB Device */ | ||
90 | at91_add_device_udc(&onearm_udc_data); | ||
91 | } | ||
92 | |||
93 | MACHINE_START(ONEARM, "Ajeco 1ARM single board computer") | ||
94 | /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ | ||
95 | .phys_io = AT91_BASE_SYS, | ||
96 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
97 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
98 | .timer = &at91rm9200_timer, | ||
99 | .map_io = onearm_map_io, | ||
100 | .init_irq = onearm_init_irq, | ||
101 | .init_machine = onearm_board_init, | ||
102 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c new file mode 100644 index 000000000000..a0815322f685 --- /dev/null +++ b/arch/arm/mach-at91/board-carmeva.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-carmeva.c | ||
3 | * | ||
4 | * Copyright (c) 2005 Peer Georgi | ||
5 | * Conitec Datasystems | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | |||
28 | #include <asm/hardware.h> | ||
29 | #include <asm/setup.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/irq.h> | ||
32 | |||
33 | #include <asm/mach/arch.h> | ||
34 | #include <asm/mach/map.h> | ||
35 | #include <asm/mach/irq.h> | ||
36 | |||
37 | #include <asm/arch/board.h> | ||
38 | #include <asm/arch/gpio.h> | ||
39 | |||
40 | #include "generic.h" | ||
41 | |||
42 | |||
43 | /* | ||
44 | * Serial port configuration. | ||
45 | * 0 .. 3 = USART0 .. USART3 | ||
46 | * 4 = DBGU | ||
47 | */ | ||
48 | static struct at91_uart_config __initdata carmeva_uart_config = { | ||
49 | .console_tty = 0, /* ttyS0 */ | ||
50 | .nr_tty = 2, | ||
51 | .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */ | ||
52 | }; | ||
53 | |||
54 | static void __init carmeva_map_io(void) | ||
55 | { | ||
56 | /* Initialize processor: 20.000 MHz crystal */ | ||
57 | at91rm9200_initialize(20000000, AT91RM9200_BGA); | ||
58 | |||
59 | /* Setup the serial ports and console */ | ||
60 | at91_init_serial(&carmeva_uart_config); | ||
61 | } | ||
62 | |||
63 | static void __init carmeva_init_irq(void) | ||
64 | { | ||
65 | at91rm9200_init_interrupts(NULL); | ||
66 | } | ||
67 | |||
68 | static struct at91_eth_data __initdata carmeva_eth_data = { | ||
69 | .phy_irq_pin = AT91_PIN_PC4, | ||
70 | .is_rmii = 1, | ||
71 | }; | ||
72 | |||
73 | static struct at91_usbh_data __initdata carmeva_usbh_data = { | ||
74 | .ports = 2, | ||
75 | }; | ||
76 | |||
77 | static struct at91_udc_data __initdata carmeva_udc_data = { | ||
78 | .vbus_pin = AT91_PIN_PD12, | ||
79 | .pullup_pin = AT91_PIN_PD9, | ||
80 | }; | ||
81 | |||
82 | /* FIXME: user dependend */ | ||
83 | // static struct at91_cf_data __initdata carmeva_cf_data = { | ||
84 | // .det_pin = AT91_PIN_PB0, | ||
85 | // .rst_pin = AT91_PIN_PC5, | ||
86 | // .irq_pin = ... not connected | ||
87 | // .vcc_pin = ... always powered | ||
88 | // }; | ||
89 | |||
90 | static struct at91_mmc_data __initdata carmeva_mmc_data = { | ||
91 | .slot_b = 0, | ||
92 | .wire4 = 1, | ||
93 | .det_pin = AT91_PIN_PB10, | ||
94 | .wp_pin = AT91_PIN_PC14, | ||
95 | }; | ||
96 | |||
97 | static struct spi_board_info carmeva_spi_devices[] = { | ||
98 | { /* DataFlash chip */ | ||
99 | .modalias = "mtd_dataflash", | ||
100 | .chip_select = 0, | ||
101 | .max_speed_hz = 10 * 1000 * 1000, | ||
102 | }, | ||
103 | { /* User accessable spi - cs1 (250KHz) */ | ||
104 | .modalias = "spi-cs1", | ||
105 | .chip_select = 1, | ||
106 | .max_speed_hz = 250 * 1000, | ||
107 | }, | ||
108 | { /* User accessable spi - cs2 (1MHz) */ | ||
109 | .modalias = "spi-cs2", | ||
110 | .chip_select = 2, | ||
111 | .max_speed_hz = 1 * 1000 * 1000, | ||
112 | }, | ||
113 | { /* User accessable spi - cs3 (10MHz) */ | ||
114 | .modalias = "spi-cs3", | ||
115 | .chip_select = 3, | ||
116 | .max_speed_hz = 10 * 1000 * 1000, | ||
117 | }, | ||
118 | }; | ||
119 | |||
120 | static void __init carmeva_board_init(void) | ||
121 | { | ||
122 | /* Serial */ | ||
123 | at91_add_device_serial(); | ||
124 | /* Ethernet */ | ||
125 | at91_add_device_eth(&carmeva_eth_data); | ||
126 | /* USB Host */ | ||
127 | at91_add_device_usbh(&carmeva_usbh_data); | ||
128 | /* USB Device */ | ||
129 | at91_add_device_udc(&carmeva_udc_data); | ||
130 | /* I2C */ | ||
131 | at91_add_device_i2c(); | ||
132 | /* SPI */ | ||
133 | at91_add_device_spi(carmeva_spi_devices, ARRAY_SIZE(carmeva_spi_devices)); | ||
134 | /* Compact Flash */ | ||
135 | // at91_add_device_cf(&carmeva_cf_data); | ||
136 | /* MMC */ | ||
137 | at91_add_device_mmc(&carmeva_mmc_data); | ||
138 | } | ||
139 | |||
140 | MACHINE_START(CARMEVA, "Carmeva") | ||
141 | /* Maintainer: Conitec Datasystems */ | ||
142 | .phys_io = AT91_BASE_SYS, | ||
143 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
144 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
145 | .timer = &at91rm9200_timer, | ||
146 | .map_io = carmeva_map_io, | ||
147 | .init_irq = carmeva_init_irq, | ||
148 | .init_machine = carmeva_board_init, | ||
149 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c new file mode 100644 index 000000000000..45d6d9b8f5e9 --- /dev/null +++ b/arch/arm/mach-at91/board-csb337.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-csb337.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 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/types.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/mm.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/spi/spi.h> | ||
27 | |||
28 | #include <asm/hardware.h> | ||
29 | #include <asm/setup.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/irq.h> | ||
32 | |||
33 | #include <asm/mach/arch.h> | ||
34 | #include <asm/mach/map.h> | ||
35 | #include <asm/mach/irq.h> | ||
36 | |||
37 | #include <asm/arch/board.h> | ||
38 | #include <asm/arch/gpio.h> | ||
39 | |||
40 | #include "generic.h" | ||
41 | |||
42 | |||
43 | /* | ||
44 | * Serial port configuration. | ||
45 | * 0 .. 3 = USART0 .. USART3 | ||
46 | * 4 = DBGU | ||
47 | */ | ||
48 | static struct at91_uart_config __initdata csb337_uart_config = { | ||
49 | .console_tty = 0, /* ttyS0 */ | ||
50 | .nr_tty = 2, | ||
51 | .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */ | ||
52 | }; | ||
53 | |||
54 | static void __init csb337_map_io(void) | ||
55 | { | ||
56 | /* Initialize processor: 3.6864 MHz crystal */ | ||
57 | at91rm9200_initialize(3686400, AT91RM9200_BGA); | ||
58 | |||
59 | /* Setup the LEDs */ | ||
60 | at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); | ||
61 | |||
62 | /* Setup the serial ports and console */ | ||
63 | at91_init_serial(&csb337_uart_config); | ||
64 | } | ||
65 | |||
66 | static void __init csb337_init_irq(void) | ||
67 | { | ||
68 | at91rm9200_init_interrupts(NULL); | ||
69 | } | ||
70 | |||
71 | static struct at91_eth_data __initdata csb337_eth_data = { | ||
72 | .phy_irq_pin = AT91_PIN_PC2, | ||
73 | .is_rmii = 0, | ||
74 | }; | ||
75 | |||
76 | static struct at91_usbh_data __initdata csb337_usbh_data = { | ||
77 | .ports = 2, | ||
78 | }; | ||
79 | |||
80 | static struct at91_udc_data __initdata csb337_udc_data = { | ||
81 | // this has no VBUS sensing pin | ||
82 | .pullup_pin = AT91_PIN_PA24, | ||
83 | }; | ||
84 | |||
85 | static struct at91_cf_data __initdata csb337_cf_data = { | ||
86 | /* | ||
87 | * connector P4 on the CSB 337 mates to | ||
88 | * connector P8 on the CSB 300CF | ||
89 | */ | ||
90 | |||
91 | /* CSB337 specific */ | ||
92 | .det_pin = AT91_PIN_PC3, | ||
93 | |||
94 | /* CSB300CF specific */ | ||
95 | .irq_pin = AT91_PIN_PA19, | ||
96 | .vcc_pin = AT91_PIN_PD0, | ||
97 | .rst_pin = AT91_PIN_PD2, | ||
98 | }; | ||
99 | |||
100 | static struct at91_mmc_data __initdata csb337_mmc_data = { | ||
101 | .det_pin = AT91_PIN_PD5, | ||
102 | .slot_b = 0, | ||
103 | .wire4 = 1, | ||
104 | .wp_pin = AT91_PIN_PD6, | ||
105 | }; | ||
106 | |||
107 | static struct spi_board_info csb337_spi_devices[] = { | ||
108 | { /* CAN controller */ | ||
109 | .modalias = "sak82c900", | ||
110 | .chip_select = 0, | ||
111 | .max_speed_hz = 6 * 1000 * 1000, | ||
112 | }, | ||
113 | }; | ||
114 | |||
115 | static void __init csb337_board_init(void) | ||
116 | { | ||
117 | /* Serial */ | ||
118 | at91_add_device_serial(); | ||
119 | /* Ethernet */ | ||
120 | at91_add_device_eth(&csb337_eth_data); | ||
121 | /* USB Host */ | ||
122 | at91_add_device_usbh(&csb337_usbh_data); | ||
123 | /* USB Device */ | ||
124 | at91_add_device_udc(&csb337_udc_data); | ||
125 | /* I2C */ | ||
126 | at91_add_device_i2c(); | ||
127 | /* Compact Flash */ | ||
128 | at91_set_gpio_input(AT91_PIN_PB22, 1); /* IOIS16 */ | ||
129 | at91_add_device_cf(&csb337_cf_data); | ||
130 | /* SPI */ | ||
131 | at91_add_device_spi(csb337_spi_devices, ARRAY_SIZE(csb337_spi_devices)); | ||
132 | /* MMC */ | ||
133 | at91_add_device_mmc(&csb337_mmc_data); | ||
134 | } | ||
135 | |||
136 | MACHINE_START(CSB337, "Cogent CSB337") | ||
137 | /* Maintainer: Bill Gatliff */ | ||
138 | .phys_io = AT91_BASE_SYS, | ||
139 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
140 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
141 | .timer = &at91rm9200_timer, | ||
142 | .map_io = csb337_map_io, | ||
143 | .init_irq = csb337_init_irq, | ||
144 | .init_machine = csb337_board_init, | ||
145 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c new file mode 100644 index 000000000000..774609479c74 --- /dev/null +++ b/arch/arm/mach-at91/board-csb637.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-csb637.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 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/types.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/mm.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | |||
27 | #include <asm/hardware.h> | ||
28 | #include <asm/setup.h> | ||
29 | #include <asm/mach-types.h> | ||
30 | #include <asm/irq.h> | ||
31 | |||
32 | #include <asm/mach/arch.h> | ||
33 | #include <asm/mach/map.h> | ||
34 | #include <asm/mach/irq.h> | ||
35 | |||
36 | #include <asm/arch/board.h> | ||
37 | #include <asm/arch/gpio.h> | ||
38 | |||
39 | #include "generic.h" | ||
40 | |||
41 | |||
42 | /* | ||
43 | * Serial port configuration. | ||
44 | * 0 .. 3 = USART0 .. USART3 | ||
45 | * 4 = DBGU | ||
46 | */ | ||
47 | static struct at91_uart_config __initdata csb637_uart_config = { | ||
48 | .console_tty = 0, /* ttyS0 */ | ||
49 | .nr_tty = 2, | ||
50 | .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */ | ||
51 | }; | ||
52 | |||
53 | static void __init csb637_map_io(void) | ||
54 | { | ||
55 | /* Initialize processor: 3.6864 MHz crystal */ | ||
56 | at91rm9200_initialize(3686400, AT91RM9200_BGA); | ||
57 | |||
58 | /* Setup the LEDs */ | ||
59 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); | ||
60 | |||
61 | /* Setup the serial ports and console */ | ||
62 | at91_init_serial(&csb637_uart_config); | ||
63 | } | ||
64 | |||
65 | static void __init csb637_init_irq(void) | ||
66 | { | ||
67 | at91rm9200_init_interrupts(NULL); | ||
68 | } | ||
69 | |||
70 | static struct at91_eth_data __initdata csb637_eth_data = { | ||
71 | .phy_irq_pin = AT91_PIN_PC0, | ||
72 | .is_rmii = 0, | ||
73 | }; | ||
74 | |||
75 | static struct at91_usbh_data __initdata csb637_usbh_data = { | ||
76 | .ports = 2, | ||
77 | }; | ||
78 | |||
79 | static struct at91_udc_data __initdata csb637_udc_data = { | ||
80 | .vbus_pin = AT91_PIN_PB28, | ||
81 | .pullup_pin = AT91_PIN_PB1, | ||
82 | }; | ||
83 | |||
84 | static void __init csb637_board_init(void) | ||
85 | { | ||
86 | /* Serial */ | ||
87 | at91_add_device_serial(); | ||
88 | /* Ethernet */ | ||
89 | at91_add_device_eth(&csb637_eth_data); | ||
90 | /* USB Host */ | ||
91 | at91_add_device_usbh(&csb637_usbh_data); | ||
92 | /* USB Device */ | ||
93 | at91_add_device_udc(&csb637_udc_data); | ||
94 | /* I2C */ | ||
95 | at91_add_device_i2c(); | ||
96 | /* SPI */ | ||
97 | at91_add_device_spi(NULL, 0); | ||
98 | } | ||
99 | |||
100 | MACHINE_START(CSB637, "Cogent CSB637") | ||
101 | /* Maintainer: Bill Gatliff */ | ||
102 | .phys_io = AT91_BASE_SYS, | ||
103 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
104 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
105 | .timer = &at91rm9200_timer, | ||
106 | .map_io = csb637_map_io, | ||
107 | .init_irq = csb637_init_irq, | ||
108 | .init_machine = csb637_board_init, | ||
109 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c new file mode 100644 index 000000000000..7401dbe1b474 --- /dev/null +++ b/arch/arm/mach-at91/board-dk.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-dk.c | ||
3 | * | ||
4 | * Copyright (C) 2005 SAN People | ||
5 | * | ||
6 | * Epson S1D framebuffer glue code is: | ||
7 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/types.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/mm.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/spi/spi.h> | ||
30 | #include <linux/mtd/physmap.h> | ||
31 | |||
32 | #include <asm/hardware.h> | ||
33 | #include <asm/setup.h> | ||
34 | #include <asm/mach-types.h> | ||
35 | #include <asm/irq.h> | ||
36 | |||
37 | #include <asm/mach/arch.h> | ||
38 | #include <asm/mach/map.h> | ||
39 | #include <asm/mach/irq.h> | ||
40 | |||
41 | #include <asm/arch/board.h> | ||
42 | #include <asm/arch/gpio.h> | ||
43 | #include <asm/arch/at91rm9200_mc.h> | ||
44 | |||
45 | #include "generic.h" | ||
46 | |||
47 | |||
48 | /* | ||
49 | * Serial port configuration. | ||
50 | * 0 .. 3 = USART0 .. USART3 | ||
51 | * 4 = DBGU | ||
52 | */ | ||
53 | static struct at91_uart_config __initdata dk_uart_config = { | ||
54 | .console_tty = 0, /* ttyS0 */ | ||
55 | .nr_tty = 2, | ||
56 | .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */ | ||
57 | }; | ||
58 | |||
59 | static void __init dk_map_io(void) | ||
60 | { | ||
61 | /* Initialize processor: 18.432 MHz crystal */ | ||
62 | at91rm9200_initialize(18432000, AT91RM9200_BGA); | ||
63 | |||
64 | /* Setup the LEDs */ | ||
65 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); | ||
66 | |||
67 | /* Setup the serial ports and console */ | ||
68 | at91_init_serial(&dk_uart_config); | ||
69 | } | ||
70 | |||
71 | static void __init dk_init_irq(void) | ||
72 | { | ||
73 | at91rm9200_init_interrupts(NULL); | ||
74 | } | ||
75 | |||
76 | static struct at91_eth_data __initdata dk_eth_data = { | ||
77 | .phy_irq_pin = AT91_PIN_PC4, | ||
78 | .is_rmii = 1, | ||
79 | }; | ||
80 | |||
81 | static struct at91_usbh_data __initdata dk_usbh_data = { | ||
82 | .ports = 2, | ||
83 | }; | ||
84 | |||
85 | static struct at91_udc_data __initdata dk_udc_data = { | ||
86 | .vbus_pin = AT91_PIN_PD4, | ||
87 | .pullup_pin = AT91_PIN_PD5, | ||
88 | }; | ||
89 | |||
90 | static struct at91_cf_data __initdata dk_cf_data = { | ||
91 | .det_pin = AT91_PIN_PB0, | ||
92 | .rst_pin = AT91_PIN_PC5, | ||
93 | // .irq_pin = ... not connected | ||
94 | // .vcc_pin = ... always powered | ||
95 | }; | ||
96 | |||
97 | static struct at91_mmc_data __initdata dk_mmc_data = { | ||
98 | .slot_b = 0, | ||
99 | .wire4 = 1, | ||
100 | }; | ||
101 | |||
102 | static struct spi_board_info dk_spi_devices[] = { | ||
103 | { /* DataFlash chip */ | ||
104 | .modalias = "mtd_dataflash", | ||
105 | .chip_select = 0, | ||
106 | .max_speed_hz = 15 * 1000 * 1000, | ||
107 | }, | ||
108 | { /* UR6HCPS2-SP40 PS2-to-SPI adapter */ | ||
109 | .modalias = "ur6hcps2", | ||
110 | .chip_select = 1, | ||
111 | .max_speed_hz = 250 * 1000, | ||
112 | }, | ||
113 | { /* TLV1504 ADC, 4 channels, 10 bits; one is a temp sensor */ | ||
114 | .modalias = "tlv1504", | ||
115 | .chip_select = 2, | ||
116 | .max_speed_hz = 20 * 1000 * 1000, | ||
117 | }, | ||
118 | #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD | ||
119 | { /* DataFlash card */ | ||
120 | .modalias = "mtd_dataflash", | ||
121 | .chip_select = 3, | ||
122 | .max_speed_hz = 15 * 1000 * 1000, | ||
123 | } | ||
124 | #endif | ||
125 | }; | ||
126 | |||
127 | static struct mtd_partition __initdata dk_nand_partition[] = { | ||
128 | { | ||
129 | .name = "NAND Partition 1", | ||
130 | .offset = 0, | ||
131 | .size = MTDPART_SIZ_FULL, | ||
132 | }, | ||
133 | }; | ||
134 | |||
135 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | ||
136 | { | ||
137 | *num_partitions = ARRAY_SIZE(dk_nand_partition); | ||
138 | return dk_nand_partition; | ||
139 | } | ||
140 | |||
141 | static struct at91_nand_data __initdata dk_nand_data = { | ||
142 | .ale = 22, | ||
143 | .cle = 21, | ||
144 | .det_pin = AT91_PIN_PB1, | ||
145 | .rdy_pin = AT91_PIN_PC2, | ||
146 | // .enable_pin = ... not there | ||
147 | .partition_info = nand_partitions, | ||
148 | }; | ||
149 | |||
150 | #define DK_FLASH_BASE AT91_CHIPSELECT_0 | ||
151 | #define DK_FLASH_SIZE 0x200000 | ||
152 | |||
153 | static struct physmap_flash_data dk_flash_data = { | ||
154 | .width = 2, | ||
155 | }; | ||
156 | |||
157 | static struct resource dk_flash_resource = { | ||
158 | .start = DK_FLASH_BASE, | ||
159 | .end = DK_FLASH_BASE + DK_FLASH_SIZE - 1, | ||
160 | .flags = IORESOURCE_MEM, | ||
161 | }; | ||
162 | |||
163 | static struct platform_device dk_flash = { | ||
164 | .name = "physmap-flash", | ||
165 | .id = 0, | ||
166 | .dev = { | ||
167 | .platform_data = &dk_flash_data, | ||
168 | }, | ||
169 | .resource = &dk_flash_resource, | ||
170 | .num_resources = 1, | ||
171 | }; | ||
172 | |||
173 | |||
174 | static void __init dk_board_init(void) | ||
175 | { | ||
176 | /* Serial */ | ||
177 | at91_add_device_serial(); | ||
178 | /* Ethernet */ | ||
179 | at91_add_device_eth(&dk_eth_data); | ||
180 | /* USB Host */ | ||
181 | at91_add_device_usbh(&dk_usbh_data); | ||
182 | /* USB Device */ | ||
183 | at91_add_device_udc(&dk_udc_data); | ||
184 | at91_set_multi_drive(dk_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */ | ||
185 | /* Compact Flash */ | ||
186 | at91_add_device_cf(&dk_cf_data); | ||
187 | /* I2C */ | ||
188 | at91_add_device_i2c(); | ||
189 | /* SPI */ | ||
190 | at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices)); | ||
191 | #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD | ||
192 | /* DataFlash card */ | ||
193 | at91_set_gpio_output(AT91_PIN_PB7, 0); | ||
194 | #else | ||
195 | /* MMC */ | ||
196 | at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ | ||
197 | at91_add_device_mmc(&dk_mmc_data); | ||
198 | #endif | ||
199 | /* NAND */ | ||
200 | at91_add_device_nand(&dk_nand_data); | ||
201 | /* NOR Flash */ | ||
202 | platform_device_register(&dk_flash); | ||
203 | /* VGA */ | ||
204 | // dk_add_device_video(); | ||
205 | } | ||
206 | |||
207 | MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK") | ||
208 | /* Maintainer: SAN People/Atmel */ | ||
209 | .phys_io = AT91_BASE_SYS, | ||
210 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
211 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
212 | .timer = &at91rm9200_timer, | ||
213 | .map_io = dk_map_io, | ||
214 | .init_irq = dk_init_irq, | ||
215 | .init_machine = dk_board_init, | ||
216 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c new file mode 100644 index 000000000000..56d5ef63e04e --- /dev/null +++ b/arch/arm/mach-at91/board-eb9200.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-eb9200.c | ||
3 | * | ||
4 | * Copyright (C) 2005 SAN People, adapted for ATEB9200 from Embest | ||
5 | * by Andrew Patrikalakis | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/device.h> | ||
27 | |||
28 | #include <asm/hardware.h> | ||
29 | #include <asm/setup.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/irq.h> | ||
32 | |||
33 | #include <asm/mach/arch.h> | ||
34 | #include <asm/mach/map.h> | ||
35 | #include <asm/mach/irq.h> | ||
36 | |||
37 | #include <asm/arch/board.h> | ||
38 | #include <asm/arch/gpio.h> | ||
39 | |||
40 | #include "generic.h" | ||
41 | |||
42 | |||
43 | /* | ||
44 | * Serial port configuration. | ||
45 | * 0 .. 3 = USART0 .. USART3 | ||
46 | * 4 = DBGU | ||
47 | */ | ||
48 | static struct at91_uart_config __initdata eb9200_uart_config = { | ||
49 | .console_tty = 0, /* ttyS0 */ | ||
50 | .nr_tty = 2, | ||
51 | .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */ | ||
52 | }; | ||
53 | |||
54 | static void __init eb9200_map_io(void) | ||
55 | { | ||
56 | /* Initialize processor: 18.432 MHz crystal */ | ||
57 | at91rm9200_initialize(18432000, AT91RM9200_BGA); | ||
58 | |||
59 | /* Setup the serial ports and console */ | ||
60 | at91_init_serial(&eb9200_uart_config); | ||
61 | } | ||
62 | |||
63 | static void __init eb9200_init_irq(void) | ||
64 | { | ||
65 | at91rm9200_init_interrupts(NULL); | ||
66 | } | ||
67 | |||
68 | static struct at91_eth_data __initdata eb9200_eth_data = { | ||
69 | .phy_irq_pin = AT91_PIN_PC4, | ||
70 | .is_rmii = 1, | ||
71 | }; | ||
72 | |||
73 | static struct at91_usbh_data __initdata eb9200_usbh_data = { | ||
74 | .ports = 2, | ||
75 | }; | ||
76 | |||
77 | static struct at91_udc_data __initdata eb9200_udc_data = { | ||
78 | .vbus_pin = AT91_PIN_PD4, | ||
79 | .pullup_pin = AT91_PIN_PD5, | ||
80 | }; | ||
81 | |||
82 | static struct at91_cf_data __initdata eb9200_cf_data = { | ||
83 | .det_pin = AT91_PIN_PB0, | ||
84 | .rst_pin = AT91_PIN_PC5, | ||
85 | // .irq_pin = ... not connected | ||
86 | // .vcc_pin = ... always powered | ||
87 | }; | ||
88 | |||
89 | static struct at91_mmc_data __initdata eb9200_mmc_data = { | ||
90 | .slot_b = 0, | ||
91 | .wire4 = 1, | ||
92 | }; | ||
93 | |||
94 | static void __init eb9200_board_init(void) | ||
95 | { | ||
96 | /* Serial */ | ||
97 | at91_add_device_serial(); | ||
98 | /* Ethernet */ | ||
99 | at91_add_device_eth(&eb9200_eth_data); | ||
100 | /* USB Host */ | ||
101 | at91_add_device_usbh(&eb9200_usbh_data); | ||
102 | /* USB Device */ | ||
103 | at91_add_device_udc(&eb9200_udc_data); | ||
104 | /* I2C */ | ||
105 | at91_add_device_i2c(); | ||
106 | /* Compact Flash */ | ||
107 | at91_add_device_cf(&eb9200_cf_data); | ||
108 | /* SPI */ | ||
109 | at91_add_device_spi(NULL, 0); | ||
110 | /* MMC */ | ||
111 | /* only supports 1 or 4 bit interface, not wired through to SPI */ | ||
112 | at91_add_device_mmc(&eb9200_mmc_data); | ||
113 | } | ||
114 | |||
115 | MACHINE_START(ATEB9200, "Embest ATEB9200") | ||
116 | .phys_io = AT91_BASE_SYS, | ||
117 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
118 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
119 | .timer = &at91rm9200_timer, | ||
120 | .map_io = eb9200_map_io, | ||
121 | .init_irq = eb9200_init_irq, | ||
122 | .init_machine = eb9200_board_init, | ||
123 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c new file mode 100644 index 000000000000..0f589dd7d1a9 --- /dev/null +++ b/arch/arm/mach-at91/board-ek.c | |||
@@ -0,0 +1,174 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-ek.c | ||
3 | * | ||
4 | * Copyright (C) 2005 SAN People | ||
5 | * | ||
6 | * Epson S1D framebuffer glue code is: | ||
7 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/types.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/mm.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/spi/spi.h> | ||
30 | #include <linux/mtd/physmap.h> | ||
31 | |||
32 | #include <asm/hardware.h> | ||
33 | #include <asm/setup.h> | ||
34 | #include <asm/mach-types.h> | ||
35 | #include <asm/irq.h> | ||
36 | |||
37 | #include <asm/mach/arch.h> | ||
38 | #include <asm/mach/map.h> | ||
39 | #include <asm/mach/irq.h> | ||
40 | |||
41 | #include <asm/arch/board.h> | ||
42 | #include <asm/arch/gpio.h> | ||
43 | #include <asm/arch/at91rm9200_mc.h> | ||
44 | |||
45 | #include "generic.h" | ||
46 | |||
47 | |||
48 | /* | ||
49 | * Serial port configuration. | ||
50 | * 0 .. 3 = USART0 .. USART3 | ||
51 | * 4 = DBGU | ||
52 | */ | ||
53 | static struct at91_uart_config __initdata ek_uart_config = { | ||
54 | .console_tty = 0, /* ttyS0 */ | ||
55 | .nr_tty = 2, | ||
56 | .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */ | ||
57 | }; | ||
58 | |||
59 | static void __init ek_map_io(void) | ||
60 | { | ||
61 | /* Initialize processor: 18.432 MHz crystal */ | ||
62 | at91rm9200_initialize(18432000, AT91RM9200_BGA); | ||
63 | |||
64 | /* Setup the LEDs */ | ||
65 | at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); | ||
66 | |||
67 | /* Setup the serial ports and console */ | ||
68 | at91_init_serial(&ek_uart_config); | ||
69 | } | ||
70 | |||
71 | static void __init ek_init_irq(void) | ||
72 | { | ||
73 | at91rm9200_init_interrupts(NULL); | ||
74 | } | ||
75 | |||
76 | static struct at91_eth_data __initdata ek_eth_data = { | ||
77 | .phy_irq_pin = AT91_PIN_PC4, | ||
78 | .is_rmii = 1, | ||
79 | }; | ||
80 | |||
81 | static struct at91_usbh_data __initdata ek_usbh_data = { | ||
82 | .ports = 2, | ||
83 | }; | ||
84 | |||
85 | static struct at91_udc_data __initdata ek_udc_data = { | ||
86 | .vbus_pin = AT91_PIN_PD4, | ||
87 | .pullup_pin = AT91_PIN_PD5, | ||
88 | }; | ||
89 | |||
90 | static struct at91_mmc_data __initdata ek_mmc_data = { | ||
91 | .det_pin = AT91_PIN_PB27, | ||
92 | .slot_b = 0, | ||
93 | .wire4 = 1, | ||
94 | .wp_pin = AT91_PIN_PA17, | ||
95 | }; | ||
96 | |||
97 | static struct spi_board_info ek_spi_devices[] = { | ||
98 | { /* DataFlash chip */ | ||
99 | .modalias = "mtd_dataflash", | ||
100 | .chip_select = 0, | ||
101 | .max_speed_hz = 15 * 1000 * 1000, | ||
102 | }, | ||
103 | #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD | ||
104 | { /* DataFlash card */ | ||
105 | .modalias = "mtd_dataflash", | ||
106 | .chip_select = 3, | ||
107 | .max_speed_hz = 15 * 1000 * 1000, | ||
108 | }, | ||
109 | #endif | ||
110 | }; | ||
111 | |||
112 | #define EK_FLASH_BASE AT91_CHIPSELECT_0 | ||
113 | #define EK_FLASH_SIZE 0x200000 | ||
114 | |||
115 | static struct physmap_flash_data ek_flash_data = { | ||
116 | .width = 2, | ||
117 | }; | ||
118 | |||
119 | static struct resource ek_flash_resource = { | ||
120 | .start = EK_FLASH_BASE, | ||
121 | .end = EK_FLASH_BASE + EK_FLASH_SIZE - 1, | ||
122 | .flags = IORESOURCE_MEM, | ||
123 | }; | ||
124 | |||
125 | static struct platform_device ek_flash = { | ||
126 | .name = "physmap-flash", | ||
127 | .id = 0, | ||
128 | .dev = { | ||
129 | .platform_data = &ek_flash_data, | ||
130 | }, | ||
131 | .resource = &ek_flash_resource, | ||
132 | .num_resources = 1, | ||
133 | }; | ||
134 | |||
135 | |||
136 | static void __init ek_board_init(void) | ||
137 | { | ||
138 | /* Serial */ | ||
139 | at91_add_device_serial(); | ||
140 | /* Ethernet */ | ||
141 | at91_add_device_eth(&ek_eth_data); | ||
142 | /* USB Host */ | ||
143 | at91_add_device_usbh(&ek_usbh_data); | ||
144 | /* USB Device */ | ||
145 | at91_add_device_udc(&ek_udc_data); | ||
146 | at91_set_multi_drive(ek_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */ | ||
147 | /* I2C */ | ||
148 | at91_add_device_i2c(); | ||
149 | /* SPI */ | ||
150 | at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); | ||
151 | #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD | ||
152 | /* DataFlash card */ | ||
153 | at91_set_gpio_output(AT91_PIN_PB22, 0); | ||
154 | #else | ||
155 | /* MMC */ | ||
156 | at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ | ||
157 | at91_add_device_mmc(&ek_mmc_data); | ||
158 | #endif | ||
159 | /* NOR Flash */ | ||
160 | platform_device_register(&ek_flash); | ||
161 | /* VGA */ | ||
162 | // ek_add_device_video(); | ||
163 | } | ||
164 | |||
165 | MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK") | ||
166 | /* Maintainer: SAN People/Atmel */ | ||
167 | .phys_io = AT91_BASE_SYS, | ||
168 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
169 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
170 | .timer = &at91rm9200_timer, | ||
171 | .map_io = ek_map_io, | ||
172 | .init_irq = ek_init_irq, | ||
173 | .init_machine = ek_board_init, | ||
174 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c new file mode 100644 index 000000000000..c77d84ce9cae --- /dev/null +++ b/arch/arm/mach-at91/board-kafa.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-kafa.c | ||
3 | * | ||
4 | * Copyright (C) 2006 Sperry-Sun | ||
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 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/types.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/mm.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | |||
27 | #include <asm/hardware.h> | ||
28 | #include <asm/setup.h> | ||
29 | #include <asm/mach-types.h> | ||
30 | #include <asm/irq.h> | ||
31 | |||
32 | #include <asm/mach/arch.h> | ||
33 | #include <asm/mach/map.h> | ||
34 | #include <asm/mach/irq.h> | ||
35 | |||
36 | #include <asm/arch/board.h> | ||
37 | #include <asm/arch/gpio.h> | ||
38 | |||
39 | #include "generic.h" | ||
40 | |||
41 | |||
42 | /* | ||
43 | * Serial port configuration. | ||
44 | * 0 .. 3 = USART0 .. USART3 | ||
45 | * 4 = DBGU | ||
46 | */ | ||
47 | static struct at91_uart_config __initdata kafa_uart_config = { | ||
48 | .console_tty = 0, /* ttyS0 */ | ||
49 | .nr_tty = 2, | ||
50 | .tty_map = { 4, 0, -1, -1, -1 } /* ttyS0, ..., ttyS4 */ | ||
51 | }; | ||
52 | |||
53 | static void __init kafa_map_io(void) | ||
54 | { | ||
55 | /* Initialize processor: 18.432 MHz crystal */ | ||
56 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | ||
57 | |||
58 | /* Set up the LEDs */ | ||
59 | at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); | ||
60 | |||
61 | /* Setup the serial ports and console */ | ||
62 | at91_init_serial(&kafa_uart_config); | ||
63 | } | ||
64 | |||
65 | static void __init kafa_init_irq(void) | ||
66 | { | ||
67 | at91rm9200_init_interrupts(NULL); | ||
68 | } | ||
69 | |||
70 | static struct at91_eth_data __initdata kafa_eth_data = { | ||
71 | .phy_irq_pin = AT91_PIN_PC4, | ||
72 | .is_rmii = 0, | ||
73 | }; | ||
74 | |||
75 | static struct at91_usbh_data __initdata kafa_usbh_data = { | ||
76 | .ports = 1, | ||
77 | }; | ||
78 | |||
79 | static struct at91_udc_data __initdata kafa_udc_data = { | ||
80 | .vbus_pin = AT91_PIN_PB6, | ||
81 | .pullup_pin = AT91_PIN_PB7, | ||
82 | }; | ||
83 | |||
84 | static void __init kafa_board_init(void) | ||
85 | { | ||
86 | /* Serial */ | ||
87 | at91_add_device_serial(); | ||
88 | /* Ethernet */ | ||
89 | at91_add_device_eth(&kafa_eth_data); | ||
90 | /* USB Host */ | ||
91 | at91_add_device_usbh(&kafa_usbh_data); | ||
92 | /* USB Device */ | ||
93 | at91_add_device_udc(&kafa_udc_data); | ||
94 | /* I2C */ | ||
95 | at91_add_device_i2c(); | ||
96 | /* SPI */ | ||
97 | at91_add_device_spi(NULL, 0); | ||
98 | } | ||
99 | |||
100 | MACHINE_START(KAFA, "Sperry-Sun KAFA") | ||
101 | /* Maintainer: Sergei Sharonov */ | ||
102 | .phys_io = AT91_BASE_SYS, | ||
103 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
104 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
105 | .timer = &at91rm9200_timer, | ||
106 | .map_io = kafa_map_io, | ||
107 | .init_irq = kafa_init_irq, | ||
108 | .init_machine = kafa_board_init, | ||
109 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c new file mode 100644 index 000000000000..17e68f5efb13 --- /dev/null +++ b/arch/arm/mach-at91/board-kb9202.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-kb9202.c | ||
3 | * | ||
4 | * Copyright (c) 2005 kb_admin | ||
5 | * KwikByte, Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | |||
28 | #include <asm/hardware.h> | ||
29 | #include <asm/setup.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/irq.h> | ||
32 | |||
33 | #include <asm/mach/arch.h> | ||
34 | #include <asm/mach/map.h> | ||
35 | #include <asm/mach/irq.h> | ||
36 | |||
37 | #include <asm/arch/board.h> | ||
38 | #include <asm/arch/gpio.h> | ||
39 | |||
40 | #include "generic.h" | ||
41 | |||
42 | |||
43 | /* | ||
44 | * Serial port configuration. | ||
45 | * 0 .. 3 = USART0 .. USART3 | ||
46 | * 4 = DBGU | ||
47 | */ | ||
48 | static struct at91_uart_config __initdata kb9202_uart_config = { | ||
49 | .console_tty = 0, /* ttyS0 */ | ||
50 | .nr_tty = 3, | ||
51 | .tty_map = { 4, 0, 1, -1, -1 } /* ttyS0, ..., ttyS4 */ | ||
52 | }; | ||
53 | |||
54 | static void __init kb9202_map_io(void) | ||
55 | { | ||
56 | /* Initialize processor: 10 MHz crystal */ | ||
57 | at91rm9200_initialize(10000000, AT91RM9200_PQFP); | ||
58 | |||
59 | /* Set up the LEDs */ | ||
60 | at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); | ||
61 | |||
62 | /* Setup the serial ports and console */ | ||
63 | at91_init_serial(&kb9202_uart_config); | ||
64 | } | ||
65 | |||
66 | static void __init kb9202_init_irq(void) | ||
67 | { | ||
68 | at91rm9200_init_interrupts(NULL); | ||
69 | } | ||
70 | |||
71 | static struct at91_eth_data __initdata kb9202_eth_data = { | ||
72 | .phy_irq_pin = AT91_PIN_PB29, | ||
73 | .is_rmii = 0, | ||
74 | }; | ||
75 | |||
76 | static struct at91_usbh_data __initdata kb9202_usbh_data = { | ||
77 | .ports = 1, | ||
78 | }; | ||
79 | |||
80 | static struct at91_udc_data __initdata kb9202_udc_data = { | ||
81 | .vbus_pin = AT91_PIN_PB24, | ||
82 | .pullup_pin = AT91_PIN_PB22, | ||
83 | }; | ||
84 | |||
85 | static struct at91_mmc_data __initdata kb9202_mmc_data = { | ||
86 | .det_pin = AT91_PIN_PB2, | ||
87 | .slot_b = 0, | ||
88 | .wire4 = 1, | ||
89 | }; | ||
90 | |||
91 | static struct mtd_partition __initdata kb9202_nand_partition[] = { | ||
92 | { | ||
93 | .name = "nand_fs", | ||
94 | .offset = 0, | ||
95 | .size = MTDPART_SIZ_FULL, | ||
96 | }, | ||
97 | }; | ||
98 | |||
99 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | ||
100 | { | ||
101 | *num_partitions = ARRAY_SIZE(kb9202_nand_partition); | ||
102 | return kb9202_nand_partition; | ||
103 | } | ||
104 | |||
105 | static struct at91_nand_data __initdata kb9202_nand_data = { | ||
106 | .ale = 22, | ||
107 | .cle = 21, | ||
108 | // .det_pin = ... not there | ||
109 | .rdy_pin = AT91_PIN_PC29, | ||
110 | .enable_pin = AT91_PIN_PC28, | ||
111 | .partition_info = nand_partitions, | ||
112 | }; | ||
113 | |||
114 | static void __init kb9202_board_init(void) | ||
115 | { | ||
116 | /* Serial */ | ||
117 | at91_add_device_serial(); | ||
118 | /* Ethernet */ | ||
119 | at91_add_device_eth(&kb9202_eth_data); | ||
120 | /* USB Host */ | ||
121 | at91_add_device_usbh(&kb9202_usbh_data); | ||
122 | /* USB Device */ | ||
123 | at91_add_device_udc(&kb9202_udc_data); | ||
124 | /* MMC */ | ||
125 | at91_add_device_mmc(&kb9202_mmc_data); | ||
126 | /* I2C */ | ||
127 | at91_add_device_i2c(); | ||
128 | /* SPI */ | ||
129 | at91_add_device_spi(NULL, 0); | ||
130 | /* NAND */ | ||
131 | at91_add_device_nand(&kb9202_nand_data); | ||
132 | } | ||
133 | |||
134 | MACHINE_START(KB9200, "KB920x") | ||
135 | /* Maintainer: KwikByte, Inc. */ | ||
136 | .phys_io = AT91_BASE_SYS, | ||
137 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
138 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
139 | .timer = &at91rm9200_timer, | ||
140 | .map_io = kb9202_map_io, | ||
141 | .init_irq = kb9202_init_irq, | ||
142 | .init_machine = kb9202_board_init, | ||
143 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c new file mode 100644 index 000000000000..6ae272d224e5 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9260ek.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-ek.c | ||
3 | * | ||
4 | * Copyright (C) 2005 SAN People | ||
5 | * Copyright (C) 2006 Atmel | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/spi/spi.h> | ||
28 | |||
29 | #include <asm/hardware.h> | ||
30 | #include <asm/setup.h> | ||
31 | #include <asm/mach-types.h> | ||
32 | #include <asm/irq.h> | ||
33 | |||
34 | #include <asm/mach/arch.h> | ||
35 | #include <asm/mach/map.h> | ||
36 | #include <asm/mach/irq.h> | ||
37 | |||
38 | #include <asm/arch/board.h> | ||
39 | #include <asm/arch/gpio.h> | ||
40 | #include <asm/arch/at91sam926x_mc.h> | ||
41 | |||
42 | #include "generic.h" | ||
43 | |||
44 | |||
45 | /* | ||
46 | * Serial port configuration. | ||
47 | * 0 .. 5 = USART0 .. USART5 | ||
48 | * 6 = DBGU | ||
49 | */ | ||
50 | static struct at91_uart_config __initdata ek_uart_config = { | ||
51 | .console_tty = 0, /* ttyS0 */ | ||
52 | .nr_tty = 3, | ||
53 | .tty_map = { 6, 0, 1, -1, -1, -1, -1 } /* ttyS0, ..., ttyS6 */ | ||
54 | }; | ||
55 | |||
56 | static void __init ek_map_io(void) | ||
57 | { | ||
58 | /* Initialize processor: 18.432 MHz crystal */ | ||
59 | at91sam9260_initialize(18432000); | ||
60 | |||
61 | /* Setup the serial ports and console */ | ||
62 | at91_init_serial(&ek_uart_config); | ||
63 | } | ||
64 | |||
65 | static void __init ek_init_irq(void) | ||
66 | { | ||
67 | at91sam9260_init_interrupts(NULL); | ||
68 | } | ||
69 | |||
70 | |||
71 | /* | ||
72 | * USB Host port | ||
73 | */ | ||
74 | static struct at91_usbh_data __initdata ek_usbh_data = { | ||
75 | .ports = 2, | ||
76 | }; | ||
77 | |||
78 | /* | ||
79 | * USB Device port | ||
80 | */ | ||
81 | static struct at91_udc_data __initdata ek_udc_data = { | ||
82 | .vbus_pin = AT91_PIN_PC5, | ||
83 | .pullup_pin = 0, /* pull-up driven by UDC */ | ||
84 | }; | ||
85 | |||
86 | |||
87 | /* | ||
88 | * SPI devices. | ||
89 | */ | ||
90 | static struct spi_board_info ek_spi_devices[] = { | ||
91 | #if !defined(CONFIG_MMC_AT91) | ||
92 | { /* DataFlash chip */ | ||
93 | .modalias = "mtd_dataflash", | ||
94 | .chip_select = 1, | ||
95 | .max_speed_hz = 15 * 1000 * 1000, | ||
96 | .bus_num = 0, | ||
97 | }, | ||
98 | #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) | ||
99 | { /* DataFlash card */ | ||
100 | .modalias = "mtd_dataflash", | ||
101 | .chip_select = 0, | ||
102 | .max_speed_hz = 15 * 1000 * 1000, | ||
103 | .bus_num = 0, | ||
104 | }, | ||
105 | #endif | ||
106 | #endif | ||
107 | #if defined(CONFIG_SND_AT73C213) | ||
108 | { /* AT73C213 DAC */ | ||
109 | .modalias = "snd_at73c213", | ||
110 | .chip_select = 0, | ||
111 | .max_speed_hz = 10 * 1000 * 1000, | ||
112 | .bus_num = 1, | ||
113 | }, | ||
114 | #endif | ||
115 | }; | ||
116 | |||
117 | |||
118 | /* | ||
119 | * MACB Ethernet device | ||
120 | */ | ||
121 | static struct __initdata at91_eth_data ek_macb_data = { | ||
122 | .phy_irq_pin = AT91_PIN_PA7, | ||
123 | .is_rmii = 1, | ||
124 | }; | ||
125 | |||
126 | |||
127 | /* | ||
128 | * NAND flash | ||
129 | */ | ||
130 | static struct mtd_partition __initdata ek_nand_partition[] = { | ||
131 | { | ||
132 | .name = "Partition 1", | ||
133 | .offset = 0, | ||
134 | .size = 256 * 1024, | ||
135 | }, | ||
136 | { | ||
137 | .name = "Partition 2", | ||
138 | .offset = 256 * 1024, | ||
139 | .size = MTDPART_SIZ_FULL, | ||
140 | }, | ||
141 | }; | ||
142 | |||
143 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | ||
144 | { | ||
145 | *num_partitions = ARRAY_SIZE(ek_nand_partition); | ||
146 | return ek_nand_partition; | ||
147 | } | ||
148 | |||
149 | static struct at91_nand_data __initdata ek_nand_data = { | ||
150 | .ale = 21, | ||
151 | .cle = 22, | ||
152 | // .det_pin = ... not connected | ||
153 | .rdy_pin = AT91_PIN_PC13, | ||
154 | .enable_pin = AT91_PIN_PC14, | ||
155 | .partition_info = nand_partitions, | ||
156 | #if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) | ||
157 | .bus_width_16 = 1, | ||
158 | #else | ||
159 | .bus_width_16 = 0, | ||
160 | #endif | ||
161 | }; | ||
162 | |||
163 | |||
164 | /* | ||
165 | * MCI (SD/MMC) | ||
166 | */ | ||
167 | static struct at91_mmc_data __initdata ek_mmc_data = { | ||
168 | .slot_b = 1, | ||
169 | .wire4 = 1, | ||
170 | // .det_pin = ... not connected | ||
171 | // .wp_pin = ... not connected | ||
172 | // .vcc_pin = ... not connected | ||
173 | }; | ||
174 | |||
175 | static void __init ek_board_init(void) | ||
176 | { | ||
177 | /* Serial */ | ||
178 | at91_add_device_serial(); | ||
179 | /* USB Host */ | ||
180 | at91_add_device_usbh(&ek_usbh_data); | ||
181 | /* USB Device */ | ||
182 | at91_add_device_udc(&ek_udc_data); | ||
183 | /* SPI */ | ||
184 | at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); | ||
185 | /* NAND */ | ||
186 | at91_add_device_nand(&ek_nand_data); | ||
187 | /* Ethernet */ | ||
188 | at91_add_device_eth(&ek_macb_data); | ||
189 | /* MMC */ | ||
190 | at91_add_device_mmc(&ek_mmc_data); | ||
191 | } | ||
192 | |||
193 | MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") | ||
194 | /* Maintainer: Atmel */ | ||
195 | .phys_io = AT91_BASE_SYS, | ||
196 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
197 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
198 | .timer = &at91sam926x_timer, | ||
199 | .map_io = ek_map_io, | ||
200 | .init_irq = ek_init_irq, | ||
201 | .init_machine = ek_board_init, | ||
202 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c new file mode 100644 index 000000000000..25d626348e6d --- /dev/null +++ b/arch/arm/mach-at91/board-sam9261ek.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-ek.c | ||
3 | * | ||
4 | * Copyright (C) 2005 SAN People | ||
5 | * Copyright (C) 2006 Atmel | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/spi/spi.h> | ||
28 | #include <linux/dm9000.h> | ||
29 | |||
30 | #include <asm/hardware.h> | ||
31 | #include <asm/setup.h> | ||
32 | #include <asm/mach-types.h> | ||
33 | #include <asm/irq.h> | ||
34 | |||
35 | #include <asm/mach/arch.h> | ||
36 | #include <asm/mach/map.h> | ||
37 | #include <asm/mach/irq.h> | ||
38 | |||
39 | #include <asm/arch/board.h> | ||
40 | #include <asm/arch/gpio.h> | ||
41 | #include <asm/arch/at91sam926x_mc.h> | ||
42 | |||
43 | #include "generic.h" | ||
44 | |||
45 | |||
46 | /* | ||
47 | * Serial port configuration. | ||
48 | * 0 .. 2 = USART0 .. USART2 | ||
49 | * 3 = DBGU | ||
50 | */ | ||
51 | static struct at91_uart_config __initdata ek_uart_config = { | ||
52 | .console_tty = 0, /* ttyS0 */ | ||
53 | .nr_tty = 1, | ||
54 | .tty_map = { 3, -1, -1, -1 } /* ttyS0, ..., ttyS3 */ | ||
55 | }; | ||
56 | |||
57 | static void __init ek_map_io(void) | ||
58 | { | ||
59 | /* Initialize processor: 18.432 MHz crystal */ | ||
60 | at91sam9261_initialize(18432000); | ||
61 | |||
62 | /* Setup the serial ports and console */ | ||
63 | at91_init_serial(&ek_uart_config); | ||
64 | } | ||
65 | |||
66 | static void __init ek_init_irq(void) | ||
67 | { | ||
68 | at91sam9261_init_interrupts(NULL); | ||
69 | } | ||
70 | |||
71 | |||
72 | /* | ||
73 | * DM9000 ethernet device | ||
74 | */ | ||
75 | #if defined(CONFIG_DM9000) | ||
76 | static struct resource at91sam9261_dm9000_resource[] = { | ||
77 | [0] = { | ||
78 | .start = AT91_CHIPSELECT_2, | ||
79 | .end = AT91_CHIPSELECT_2 + 3, | ||
80 | .flags = IORESOURCE_MEM | ||
81 | }, | ||
82 | [1] = { | ||
83 | .start = AT91_CHIPSELECT_2 + 0x44, | ||
84 | .end = AT91_CHIPSELECT_2 + 0xFF, | ||
85 | .flags = IORESOURCE_MEM | ||
86 | }, | ||
87 | [2] = { | ||
88 | .start = AT91_PIN_PC11, | ||
89 | .end = AT91_PIN_PC11, | ||
90 | .flags = IORESOURCE_IRQ | ||
91 | } | ||
92 | }; | ||
93 | |||
94 | static struct dm9000_plat_data dm9000_platdata = { | ||
95 | .flags = DM9000_PLATF_16BITONLY, | ||
96 | }; | ||
97 | |||
98 | static struct platform_device at91sam9261_dm9000_device = { | ||
99 | .name = "dm9000", | ||
100 | .id = 0, | ||
101 | .num_resources = ARRAY_SIZE(at91sam9261_dm9000_resource), | ||
102 | .resource = at91sam9261_dm9000_resource, | ||
103 | .dev = { | ||
104 | .platform_data = &dm9000_platdata, | ||
105 | } | ||
106 | }; | ||
107 | |||
108 | static void __init ek_add_device_dm9000(void) | ||
109 | { | ||
110 | /* | ||
111 | * Configure Chip-Select 2 on SMC for the DM9000. | ||
112 | * Note: These timings were calculated for MASTER_CLOCK = 100000000 | ||
113 | * according to the DM9000 timings. | ||
114 | */ | ||
115 | at91_sys_write(AT91_SMC_SETUP(2), AT91_SMC_NWESETUP_(2) | AT91_SMC_NCS_WRSETUP_(0) | AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(0)); | ||
116 | at91_sys_write(AT91_SMC_PULSE(2), AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(8) | AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(8)); | ||
117 | at91_sys_write(AT91_SMC_CYCLE(2), AT91_SMC_NWECYCLE_(16) | AT91_SMC_NRDCYCLE_(16)); | ||
118 | at91_sys_write(AT91_SMC_MODE(2), AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16 | AT91_SMC_TDF_(1)); | ||
119 | |||
120 | /* Configure Reset signal as output */ | ||
121 | at91_set_gpio_output(AT91_PIN_PC10, 0); | ||
122 | |||
123 | /* Configure Interrupt pin as input, no pull-up */ | ||
124 | at91_set_gpio_input(AT91_PIN_PC11, 0); | ||
125 | |||
126 | platform_device_register(&at91sam9261_dm9000_device); | ||
127 | } | ||
128 | #else | ||
129 | static void __init ek_add_device_dm9000(void) {} | ||
130 | #endif /* CONFIG_DM9000 */ | ||
131 | |||
132 | |||
133 | /* | ||
134 | * USB Host Port | ||
135 | */ | ||
136 | static struct at91_usbh_data __initdata ek_usbh_data = { | ||
137 | .ports = 2, | ||
138 | }; | ||
139 | |||
140 | |||
141 | /* | ||
142 | * USB Device Port | ||
143 | */ | ||
144 | static struct at91_udc_data __initdata ek_udc_data = { | ||
145 | .vbus_pin = AT91_PIN_PB29, | ||
146 | .pullup_pin = 0, /* pull-up driven by UDC */ | ||
147 | }; | ||
148 | |||
149 | |||
150 | /* | ||
151 | * MCI (SD/MMC) | ||
152 | */ | ||
153 | static struct at91_mmc_data __initdata ek_mmc_data = { | ||
154 | .wire4 = 1, | ||
155 | // .det_pin = ... not connected | ||
156 | // .wp_pin = ... not connected | ||
157 | // .vcc_pin = ... not connected | ||
158 | }; | ||
159 | |||
160 | |||
161 | /* | ||
162 | * NAND flash | ||
163 | */ | ||
164 | static struct mtd_partition __initdata ek_nand_partition[] = { | ||
165 | { | ||
166 | .name = "Partition 1", | ||
167 | .offset = 0, | ||
168 | .size = 256 * 1024, | ||
169 | }, | ||
170 | { | ||
171 | .name = "Partition 2", | ||
172 | .offset = 256 * 1024 , | ||
173 | .size = MTDPART_SIZ_FULL, | ||
174 | }, | ||
175 | }; | ||
176 | |||
177 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | ||
178 | { | ||
179 | *num_partitions = ARRAY_SIZE(ek_nand_partition); | ||
180 | return ek_nand_partition; | ||
181 | } | ||
182 | |||
183 | static struct at91_nand_data __initdata ek_nand_data = { | ||
184 | .ale = 22, | ||
185 | .cle = 21, | ||
186 | // .det_pin = ... not connected | ||
187 | .rdy_pin = AT91_PIN_PC15, | ||
188 | .enable_pin = AT91_PIN_PC14, | ||
189 | .partition_info = nand_partitions, | ||
190 | #if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) | ||
191 | .bus_width_16 = 1, | ||
192 | #else | ||
193 | .bus_width_16 = 0, | ||
194 | #endif | ||
195 | }; | ||
196 | |||
197 | /* | ||
198 | * SPI devices | ||
199 | */ | ||
200 | static struct spi_board_info ek_spi_devices[] = { | ||
201 | { /* DataFlash chip */ | ||
202 | .modalias = "mtd_dataflash", | ||
203 | .chip_select = 0, | ||
204 | .max_speed_hz = 15 * 1000 * 1000, | ||
205 | .bus_num = 0, | ||
206 | }, | ||
207 | #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) | ||
208 | { /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */ | ||
209 | .modalias = "mtd_dataflash", | ||
210 | .chip_select = 3, | ||
211 | .max_speed_hz = 15 * 1000 * 1000, | ||
212 | .bus_num = 0, | ||
213 | }, | ||
214 | #elif defined(CONFIG_SND_AT73C213) | ||
215 | { /* AT73C213 DAC */ | ||
216 | .modalias = "snd_at73c213", | ||
217 | .chip_select = 3, | ||
218 | .max_speed_hz = 10 * 1000 * 1000, | ||
219 | .bus_num = 0, | ||
220 | }, | ||
221 | #endif | ||
222 | }; | ||
223 | |||
224 | |||
225 | static void __init ek_board_init(void) | ||
226 | { | ||
227 | /* Serial */ | ||
228 | at91_add_device_serial(); | ||
229 | /* USB Host */ | ||
230 | at91_add_device_usbh(&ek_usbh_data); | ||
231 | /* USB Device */ | ||
232 | at91_add_device_udc(&ek_udc_data); | ||
233 | /* I2C */ | ||
234 | at91_add_device_i2c(); | ||
235 | /* NAND */ | ||
236 | at91_add_device_nand(&ek_nand_data); | ||
237 | /* DM9000 ethernet */ | ||
238 | ek_add_device_dm9000(); | ||
239 | |||
240 | /* spi0 and mmc/sd share the same PIO pins */ | ||
241 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | ||
242 | /* SPI */ | ||
243 | at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); | ||
244 | #else | ||
245 | /* MMC */ | ||
246 | at91_add_device_mmc(&ek_mmc_data); | ||
247 | #endif | ||
248 | } | ||
249 | |||
250 | MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") | ||
251 | /* Maintainer: Atmel */ | ||
252 | .phys_io = AT91_BASE_SYS, | ||
253 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
254 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
255 | .timer = &at91sam926x_timer, | ||
256 | .map_io = ek_map_io, | ||
257 | .init_irq = ek_init_irq, | ||
258 | .init_machine = ek_board_init, | ||
259 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c new file mode 100644 index 000000000000..baab095f6e32 --- /dev/null +++ b/arch/arm/mach-at91/clock.c | |||
@@ -0,0 +1,644 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/clock.c | ||
3 | * | ||
4 | * Copyright (C) 2005 David Brownell | ||
5 | * Copyright (C) 2005 Ivan Kokshaysky | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/fs.h> | ||
17 | #include <linux/debugfs.h> | ||
18 | #include <linux/seq_file.h> | ||
19 | #include <linux/list.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/clk.h> | ||
25 | |||
26 | #include <asm/semaphore.h> | ||
27 | #include <asm/io.h> | ||
28 | #include <asm/mach-types.h> | ||
29 | |||
30 | #include <asm/hardware.h> | ||
31 | #include <asm/arch/at91_pmc.h> | ||
32 | #include <asm/arch/cpu.h> | ||
33 | |||
34 | #include "clock.h" | ||
35 | |||
36 | |||
37 | /* | ||
38 | * There's a lot more which can be done with clocks, including cpufreq | ||
39 | * integration, slow clock mode support (for system suspend), letting | ||
40 | * PLLB be used at other rates (on boards that don't need USB), etc. | ||
41 | */ | ||
42 | |||
43 | #define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) | ||
44 | #define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) | ||
45 | #define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) | ||
46 | #define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM) | ||
47 | |||
48 | |||
49 | static LIST_HEAD(clocks); | ||
50 | static DEFINE_SPINLOCK(clk_lock); | ||
51 | |||
52 | static u32 at91_pllb_usb_init; | ||
53 | |||
54 | /* | ||
55 | * Four primary clock sources: two crystal oscillators (32K, main), and | ||
56 | * two PLLs. PLLA usually runs the master clock; and PLLB must run at | ||
57 | * 48 MHz (unless no USB function clocks are needed). The main clock and | ||
58 | * both PLLs are turned off to run in "slow clock mode" (system suspend). | ||
59 | */ | ||
60 | static struct clk clk32k = { | ||
61 | .name = "clk32k", | ||
62 | .rate_hz = AT91_SLOW_CLOCK, | ||
63 | .users = 1, /* always on */ | ||
64 | .id = 0, | ||
65 | .type = CLK_TYPE_PRIMARY, | ||
66 | }; | ||
67 | static struct clk main_clk = { | ||
68 | .name = "main", | ||
69 | .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ | ||
70 | .id = 1, | ||
71 | .type = CLK_TYPE_PRIMARY, | ||
72 | }; | ||
73 | static struct clk plla = { | ||
74 | .name = "plla", | ||
75 | .parent = &main_clk, | ||
76 | .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ | ||
77 | .id = 2, | ||
78 | .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, | ||
79 | }; | ||
80 | |||
81 | static void pllb_mode(struct clk *clk, int is_on) | ||
82 | { | ||
83 | u32 value; | ||
84 | |||
85 | if (is_on) { | ||
86 | is_on = AT91_PMC_LOCKB; | ||
87 | value = at91_pllb_usb_init; | ||
88 | } else | ||
89 | value = 0; | ||
90 | |||
91 | // REVISIT: Add work-around for AT91RM9200 Errata #26 ? | ||
92 | at91_sys_write(AT91_CKGR_PLLBR, value); | ||
93 | |||
94 | do { | ||
95 | cpu_relax(); | ||
96 | } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on); | ||
97 | } | ||
98 | |||
99 | static struct clk pllb = { | ||
100 | .name = "pllb", | ||
101 | .parent = &main_clk, | ||
102 | .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ | ||
103 | .mode = pllb_mode, | ||
104 | .id = 3, | ||
105 | .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, | ||
106 | }; | ||
107 | |||
108 | static void pmc_sys_mode(struct clk *clk, int is_on) | ||
109 | { | ||
110 | if (is_on) | ||
111 | at91_sys_write(AT91_PMC_SCER, clk->pmc_mask); | ||
112 | else | ||
113 | at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask); | ||
114 | } | ||
115 | |||
116 | /* USB function clocks (PLLB must be 48 MHz) */ | ||
117 | static struct clk udpck = { | ||
118 | .name = "udpck", | ||
119 | .parent = &pllb, | ||
120 | .mode = pmc_sys_mode, | ||
121 | }; | ||
122 | static struct clk uhpck = { | ||
123 | .name = "uhpck", | ||
124 | .parent = &pllb, | ||
125 | .mode = pmc_sys_mode, | ||
126 | }; | ||
127 | |||
128 | |||
129 | /* | ||
130 | * The master clock is divided from the CPU clock (by 1-4). It's used for | ||
131 | * memory, interfaces to on-chip peripherals, the AIC, and sometimes more | ||
132 | * (e.g baud rate generation). It's sourced from one of the primary clocks. | ||
133 | */ | ||
134 | static struct clk mck = { | ||
135 | .name = "mck", | ||
136 | .pmc_mask = AT91_PMC_MCKRDY, /* in PMC_SR */ | ||
137 | }; | ||
138 | |||
139 | static void pmc_periph_mode(struct clk *clk, int is_on) | ||
140 | { | ||
141 | if (is_on) | ||
142 | at91_sys_write(AT91_PMC_PCER, clk->pmc_mask); | ||
143 | else | ||
144 | at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); | ||
145 | } | ||
146 | |||
147 | static struct clk __init *at91_css_to_clk(unsigned long css) | ||
148 | { | ||
149 | switch (css) { | ||
150 | case AT91_PMC_CSS_SLOW: | ||
151 | return &clk32k; | ||
152 | case AT91_PMC_CSS_MAIN: | ||
153 | return &main_clk; | ||
154 | case AT91_PMC_CSS_PLLA: | ||
155 | return &plla; | ||
156 | case AT91_PMC_CSS_PLLB: | ||
157 | return &pllb; | ||
158 | } | ||
159 | |||
160 | return NULL; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * Associate a particular clock with a function (eg, "uart") and device. | ||
165 | * The drivers can then request the same 'function' with several different | ||
166 | * devices and not care about which clock name to use. | ||
167 | */ | ||
168 | void __init at91_clock_associate(const char *id, struct device *dev, const char *func) | ||
169 | { | ||
170 | struct clk *clk = clk_get(NULL, id); | ||
171 | |||
172 | if (!dev || !clk || !IS_ERR(clk_get(dev, func))) | ||
173 | return; | ||
174 | |||
175 | clk->function = func; | ||
176 | clk->dev = dev; | ||
177 | } | ||
178 | |||
179 | /* clocks cannot be de-registered no refcounting necessary */ | ||
180 | struct clk *clk_get(struct device *dev, const char *id) | ||
181 | { | ||
182 | struct clk *clk; | ||
183 | |||
184 | list_for_each_entry(clk, &clocks, node) { | ||
185 | if (strcmp(id, clk->name) == 0) | ||
186 | return clk; | ||
187 | if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0) | ||
188 | return clk; | ||
189 | } | ||
190 | |||
191 | return ERR_PTR(-ENOENT); | ||
192 | } | ||
193 | EXPORT_SYMBOL(clk_get); | ||
194 | |||
195 | void clk_put(struct clk *clk) | ||
196 | { | ||
197 | } | ||
198 | EXPORT_SYMBOL(clk_put); | ||
199 | |||
200 | static void __clk_enable(struct clk *clk) | ||
201 | { | ||
202 | if (clk->parent) | ||
203 | __clk_enable(clk->parent); | ||
204 | if (clk->users++ == 0 && clk->mode) | ||
205 | clk->mode(clk, 1); | ||
206 | } | ||
207 | |||
208 | int clk_enable(struct clk *clk) | ||
209 | { | ||
210 | unsigned long flags; | ||
211 | |||
212 | spin_lock_irqsave(&clk_lock, flags); | ||
213 | __clk_enable(clk); | ||
214 | spin_unlock_irqrestore(&clk_lock, flags); | ||
215 | return 0; | ||
216 | } | ||
217 | EXPORT_SYMBOL(clk_enable); | ||
218 | |||
219 | static void __clk_disable(struct clk *clk) | ||
220 | { | ||
221 | BUG_ON(clk->users == 0); | ||
222 | if (--clk->users == 0 && clk->mode) | ||
223 | clk->mode(clk, 0); | ||
224 | if (clk->parent) | ||
225 | __clk_disable(clk->parent); | ||
226 | } | ||
227 | |||
228 | void clk_disable(struct clk *clk) | ||
229 | { | ||
230 | unsigned long flags; | ||
231 | |||
232 | spin_lock_irqsave(&clk_lock, flags); | ||
233 | __clk_disable(clk); | ||
234 | spin_unlock_irqrestore(&clk_lock, flags); | ||
235 | } | ||
236 | EXPORT_SYMBOL(clk_disable); | ||
237 | |||
238 | unsigned long clk_get_rate(struct clk *clk) | ||
239 | { | ||
240 | unsigned long flags; | ||
241 | unsigned long rate; | ||
242 | |||
243 | spin_lock_irqsave(&clk_lock, flags); | ||
244 | for (;;) { | ||
245 | rate = clk->rate_hz; | ||
246 | if (rate || !clk->parent) | ||
247 | break; | ||
248 | clk = clk->parent; | ||
249 | } | ||
250 | spin_unlock_irqrestore(&clk_lock, flags); | ||
251 | return rate; | ||
252 | } | ||
253 | EXPORT_SYMBOL(clk_get_rate); | ||
254 | |||
255 | /*------------------------------------------------------------------------*/ | ||
256 | |||
257 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | ||
258 | |||
259 | /* | ||
260 | * For now, only the programmable clocks support reparenting (MCK could | ||
261 | * do this too, with care) or rate changing (the PLLs could do this too, | ||
262 | * ditto MCK but that's more for cpufreq). Drivers may reparent to get | ||
263 | * a better rate match; we don't. | ||
264 | */ | ||
265 | |||
266 | long clk_round_rate(struct clk *clk, unsigned long rate) | ||
267 | { | ||
268 | unsigned long flags; | ||
269 | unsigned prescale; | ||
270 | unsigned long actual; | ||
271 | |||
272 | if (!clk_is_programmable(clk)) | ||
273 | return -EINVAL; | ||
274 | spin_lock_irqsave(&clk_lock, flags); | ||
275 | |||
276 | actual = clk->parent->rate_hz; | ||
277 | for (prescale = 0; prescale < 7; prescale++) { | ||
278 | if (actual && actual <= rate) | ||
279 | break; | ||
280 | actual >>= 1; | ||
281 | } | ||
282 | |||
283 | spin_unlock_irqrestore(&clk_lock, flags); | ||
284 | return (prescale < 7) ? actual : -ENOENT; | ||
285 | } | ||
286 | EXPORT_SYMBOL(clk_round_rate); | ||
287 | |||
288 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
289 | { | ||
290 | unsigned long flags; | ||
291 | unsigned prescale; | ||
292 | unsigned long actual; | ||
293 | |||
294 | if (!clk_is_programmable(clk)) | ||
295 | return -EINVAL; | ||
296 | if (clk->users) | ||
297 | return -EBUSY; | ||
298 | spin_lock_irqsave(&clk_lock, flags); | ||
299 | |||
300 | actual = clk->parent->rate_hz; | ||
301 | for (prescale = 0; prescale < 7; prescale++) { | ||
302 | if (actual && actual <= rate) { | ||
303 | u32 pckr; | ||
304 | |||
305 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); | ||
306 | pckr &= AT91_PMC_CSS_PLLB; /* clock selection */ | ||
307 | pckr |= prescale << 2; | ||
308 | at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); | ||
309 | clk->rate_hz = actual; | ||
310 | break; | ||
311 | } | ||
312 | actual >>= 1; | ||
313 | } | ||
314 | |||
315 | spin_unlock_irqrestore(&clk_lock, flags); | ||
316 | return (prescale < 7) ? actual : -ENOENT; | ||
317 | } | ||
318 | EXPORT_SYMBOL(clk_set_rate); | ||
319 | |||
320 | struct clk *clk_get_parent(struct clk *clk) | ||
321 | { | ||
322 | return clk->parent; | ||
323 | } | ||
324 | EXPORT_SYMBOL(clk_get_parent); | ||
325 | |||
326 | int clk_set_parent(struct clk *clk, struct clk *parent) | ||
327 | { | ||
328 | unsigned long flags; | ||
329 | |||
330 | if (clk->users) | ||
331 | return -EBUSY; | ||
332 | if (!clk_is_primary(parent) || !clk_is_programmable(clk)) | ||
333 | return -EINVAL; | ||
334 | spin_lock_irqsave(&clk_lock, flags); | ||
335 | |||
336 | clk->rate_hz = parent->rate_hz; | ||
337 | clk->parent = parent; | ||
338 | at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id); | ||
339 | |||
340 | spin_unlock_irqrestore(&clk_lock, flags); | ||
341 | return 0; | ||
342 | } | ||
343 | EXPORT_SYMBOL(clk_set_parent); | ||
344 | |||
345 | /* establish PCK0..PCK3 parentage and rate */ | ||
346 | static void init_programmable_clock(struct clk *clk) | ||
347 | { | ||
348 | struct clk *parent; | ||
349 | u32 pckr; | ||
350 | |||
351 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); | ||
352 | parent = at91_css_to_clk(pckr & AT91_PMC_CSS); | ||
353 | clk->parent = parent; | ||
354 | clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3)); | ||
355 | } | ||
356 | |||
357 | #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ | ||
358 | |||
359 | /*------------------------------------------------------------------------*/ | ||
360 | |||
361 | #ifdef CONFIG_DEBUG_FS | ||
362 | |||
363 | static int at91_clk_show(struct seq_file *s, void *unused) | ||
364 | { | ||
365 | u32 scsr, pcsr, sr; | ||
366 | struct clk *clk; | ||
367 | unsigned i; | ||
368 | |||
369 | seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); | ||
370 | seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR)); | ||
371 | |||
372 | seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); | ||
373 | seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); | ||
374 | seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); | ||
375 | seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); | ||
376 | |||
377 | seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); | ||
378 | for (i = 0; i < 4; i++) | ||
379 | seq_printf(s, "PCK%d = %8x\n", i, at91_sys_read(AT91_PMC_PCKR(i))); | ||
380 | seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); | ||
381 | |||
382 | seq_printf(s, "\n"); | ||
383 | |||
384 | list_for_each_entry(clk, &clocks, node) { | ||
385 | char *state; | ||
386 | |||
387 | if (clk->mode == pmc_sys_mode) | ||
388 | state = (scsr & clk->pmc_mask) ? "on" : "off"; | ||
389 | else if (clk->mode == pmc_periph_mode) | ||
390 | state = (pcsr & clk->pmc_mask) ? "on" : "off"; | ||
391 | else if (clk->pmc_mask) | ||
392 | state = (sr & clk->pmc_mask) ? "on" : "off"; | ||
393 | else if (clk == &clk32k || clk == &main_clk) | ||
394 | state = "on"; | ||
395 | else | ||
396 | state = ""; | ||
397 | |||
398 | seq_printf(s, "%-10s users=%2d %-3s %9ld Hz %s\n", | ||
399 | clk->name, clk->users, state, clk_get_rate(clk), | ||
400 | clk->parent ? clk->parent->name : ""); | ||
401 | } | ||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int at91_clk_open(struct inode *inode, struct file *file) | ||
406 | { | ||
407 | return single_open(file, at91_clk_show, NULL); | ||
408 | } | ||
409 | |||
410 | static struct file_operations at91_clk_operations = { | ||
411 | .open = at91_clk_open, | ||
412 | .read = seq_read, | ||
413 | .llseek = seq_lseek, | ||
414 | .release = single_release, | ||
415 | }; | ||
416 | |||
417 | static int __init at91_clk_debugfs_init(void) | ||
418 | { | ||
419 | /* /sys/kernel/debug/at91_clk */ | ||
420 | (void) debugfs_create_file("at91_clk", S_IFREG | S_IRUGO, NULL, NULL, &at91_clk_operations); | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | postcore_initcall(at91_clk_debugfs_init); | ||
425 | |||
426 | #endif | ||
427 | |||
428 | /*------------------------------------------------------------------------*/ | ||
429 | |||
430 | /* Register a new clock */ | ||
431 | int __init clk_register(struct clk *clk) | ||
432 | { | ||
433 | if (clk_is_peripheral(clk)) { | ||
434 | clk->parent = &mck; | ||
435 | clk->mode = pmc_periph_mode; | ||
436 | list_add_tail(&clk->node, &clocks); | ||
437 | } | ||
438 | else if (clk_is_sys(clk)) { | ||
439 | clk->parent = &mck; | ||
440 | clk->mode = pmc_sys_mode; | ||
441 | |||
442 | list_add_tail(&clk->node, &clocks); | ||
443 | } | ||
444 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | ||
445 | else if (clk_is_programmable(clk)) { | ||
446 | clk->mode = pmc_sys_mode; | ||
447 | init_programmable_clock(clk); | ||
448 | list_add_tail(&clk->node, &clocks); | ||
449 | } | ||
450 | #endif | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | |||
456 | /*------------------------------------------------------------------------*/ | ||
457 | |||
458 | static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) | ||
459 | { | ||
460 | unsigned mul, div; | ||
461 | |||
462 | div = reg & 0xff; | ||
463 | mul = (reg >> 16) & 0x7ff; | ||
464 | if (div && mul) { | ||
465 | freq /= div; | ||
466 | freq *= mul + 1; | ||
467 | } else | ||
468 | freq = 0; | ||
469 | |||
470 | return freq; | ||
471 | } | ||
472 | |||
473 | static u32 __init at91_usb_rate(struct clk *pll, u32 freq, u32 reg) | ||
474 | { | ||
475 | if (pll == &pllb && (reg & AT91_PMC_USB96M)) | ||
476 | return freq / 2; | ||
477 | else | ||
478 | return freq; | ||
479 | } | ||
480 | |||
481 | static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) | ||
482 | { | ||
483 | unsigned i, div = 0, mul = 0, diff = 1 << 30; | ||
484 | unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; | ||
485 | |||
486 | /* PLL output max 240 MHz (or 180 MHz per errata) */ | ||
487 | if (out_freq > 240000000) | ||
488 | goto fail; | ||
489 | |||
490 | for (i = 1; i < 256; i++) { | ||
491 | int diff1; | ||
492 | unsigned input, mul1; | ||
493 | |||
494 | /* | ||
495 | * PLL input between 1MHz and 32MHz per spec, but lower | ||
496 | * frequences seem necessary in some cases so allow 100K. | ||
497 | */ | ||
498 | input = main_freq / i; | ||
499 | if (input < 100000) | ||
500 | continue; | ||
501 | if (input > 32000000) | ||
502 | continue; | ||
503 | |||
504 | mul1 = out_freq / input; | ||
505 | if (mul1 > 2048) | ||
506 | continue; | ||
507 | if (mul1 < 2) | ||
508 | goto fail; | ||
509 | |||
510 | diff1 = out_freq - input * mul1; | ||
511 | if (diff1 < 0) | ||
512 | diff1 = -diff1; | ||
513 | if (diff > diff1) { | ||
514 | diff = diff1; | ||
515 | div = i; | ||
516 | mul = mul1; | ||
517 | if (diff == 0) | ||
518 | break; | ||
519 | } | ||
520 | } | ||
521 | if (i == 256 && diff > (out_freq >> 5)) | ||
522 | goto fail; | ||
523 | return ret | ((mul - 1) << 16) | div; | ||
524 | fail: | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | /* | ||
529 | * Several unused clocks may be active. Turn them off. | ||
530 | */ | ||
531 | static void __init at91_periphclk_reset(void) | ||
532 | { | ||
533 | unsigned long reg; | ||
534 | struct clk *clk; | ||
535 | |||
536 | reg = at91_sys_read(AT91_PMC_PCSR); | ||
537 | |||
538 | list_for_each_entry(clk, &clocks, node) { | ||
539 | if (clk->mode != pmc_periph_mode) | ||
540 | continue; | ||
541 | |||
542 | if (clk->users > 0) | ||
543 | reg &= ~clk->pmc_mask; | ||
544 | } | ||
545 | |||
546 | at91_sys_write(AT91_PMC_PCDR, reg); | ||
547 | } | ||
548 | |||
549 | static struct clk *const standard_pmc_clocks[] __initdata = { | ||
550 | /* four primary clocks */ | ||
551 | &clk32k, | ||
552 | &main_clk, | ||
553 | &plla, | ||
554 | &pllb, | ||
555 | |||
556 | /* PLLB children (USB) */ | ||
557 | &udpck, | ||
558 | &uhpck, | ||
559 | |||
560 | /* MCK */ | ||
561 | &mck | ||
562 | }; | ||
563 | |||
564 | int __init at91_clock_init(unsigned long main_clock) | ||
565 | { | ||
566 | unsigned tmp, freq, mckr; | ||
567 | int i; | ||
568 | |||
569 | /* | ||
570 | * When the bootloader initialized the main oscillator correctly, | ||
571 | * there's no problem using the cycle counter. But if it didn't, | ||
572 | * or when using oscillator bypass mode, we must be told the speed | ||
573 | * of the main clock. | ||
574 | */ | ||
575 | if (!main_clock) { | ||
576 | do { | ||
577 | tmp = at91_sys_read(AT91_CKGR_MCFR); | ||
578 | } while (!(tmp & AT91_PMC_MAINRDY)); | ||
579 | main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16); | ||
580 | } | ||
581 | main_clk.rate_hz = main_clock; | ||
582 | |||
583 | /* report if PLLA is more than mildly overclocked */ | ||
584 | plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); | ||
585 | if (plla.rate_hz > 209000000) | ||
586 | pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); | ||
587 | |||
588 | /* | ||
589 | * USB clock init: choose 48 MHz PLLB value, turn all clocks off, | ||
590 | * disable 48MHz clock during usb peripheral suspend. | ||
591 | * | ||
592 | * REVISIT: assumes MCK doesn't derive from PLLB! | ||
593 | */ | ||
594 | at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; | ||
595 | pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); | ||
596 | if (cpu_is_at91rm9200()) { | ||
597 | uhpck.pmc_mask = AT91RM9200_PMC_UHP; | ||
598 | udpck.pmc_mask = AT91RM9200_PMC_UDP; | ||
599 | at91_sys_write(AT91_PMC_SCDR, AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP); | ||
600 | at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); | ||
601 | } else if (cpu_is_at91sam9260()) { | ||
602 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; | ||
603 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; | ||
604 | at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP); | ||
605 | } else if (cpu_is_at91sam9261()) { | ||
606 | uhpck.pmc_mask = (AT91SAM926x_PMC_UHP | AT91_PMC_HCK0); | ||
607 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; | ||
608 | at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91_PMC_HCK0 | AT91SAM926x_PMC_UDP); | ||
609 | } | ||
610 | at91_sys_write(AT91_CKGR_PLLBR, 0); | ||
611 | |||
612 | udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); | ||
613 | uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); | ||
614 | |||
615 | /* | ||
616 | * MCK and CPU derive from one of those primary clocks. | ||
617 | * For now, assume this parentage won't change. | ||
618 | */ | ||
619 | mckr = at91_sys_read(AT91_PMC_MCKR); | ||
620 | mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); | ||
621 | freq = mck.parent->rate_hz; | ||
622 | freq /= (1 << ((mckr >> 2) & 3)); /* prescale */ | ||
623 | mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */ | ||
624 | |||
625 | /* Register the PMC's standard clocks */ | ||
626 | for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) | ||
627 | list_add_tail(&standard_pmc_clocks[i]->node, &clocks); | ||
628 | |||
629 | /* MCK and CPU clock are "always on" */ | ||
630 | clk_enable(&mck); | ||
631 | |||
632 | printk("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n", | ||
633 | freq / 1000000, (unsigned) mck.rate_hz / 1000000, | ||
634 | (unsigned) main_clock / 1000000, | ||
635 | ((unsigned) main_clock % 1000000) / 1000); | ||
636 | |||
637 | /* disable all programmable clocks */ | ||
638 | at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3); | ||
639 | |||
640 | /* disable all other unused peripheral clocks */ | ||
641 | at91_periphclk_reset(); | ||
642 | |||
643 | return 0; | ||
644 | } | ||
diff --git a/arch/arm/mach-at91/clock.h b/arch/arm/mach-at91/clock.h new file mode 100644 index 000000000000..1ba3b95ff359 --- /dev/null +++ b/arch/arm/mach-at91/clock.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/clock.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #define CLK_TYPE_PRIMARY 0x1 | ||
10 | #define CLK_TYPE_PLL 0x2 | ||
11 | #define CLK_TYPE_PROGRAMMABLE 0x4 | ||
12 | #define CLK_TYPE_PERIPHERAL 0x8 | ||
13 | #define CLK_TYPE_SYSTEM 0x10 | ||
14 | |||
15 | |||
16 | struct clk { | ||
17 | struct list_head node; | ||
18 | const char *name; /* unique clock name */ | ||
19 | const char *function; /* function of the clock */ | ||
20 | struct device *dev; /* device associated with function */ | ||
21 | unsigned long rate_hz; | ||
22 | struct clk *parent; | ||
23 | u32 pmc_mask; | ||
24 | void (*mode)(struct clk *, int); | ||
25 | unsigned id:2; /* PCK0..3, or 32k/main/a/b */ | ||
26 | unsigned type; /* clock type */ | ||
27 | u16 users; | ||
28 | }; | ||
29 | |||
30 | |||
31 | extern int __init clk_register(struct clk *clk); | ||
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h new file mode 100644 index 000000000000..10ee37bf6d4d --- /dev/null +++ b/arch/arm/mach-at91/generic.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/generic.h | ||
3 | * | ||
4 | * Copyright (C) 2005 David Brownell | ||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | /* Processors */ | ||
12 | extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks); | ||
13 | extern void __init at91sam9260_initialize(unsigned long main_clock); | ||
14 | extern void __init at91sam9261_initialize(unsigned long main_clock); | ||
15 | |||
16 | /* Interrupts */ | ||
17 | extern void __init at91rm9200_init_interrupts(unsigned int priority[]); | ||
18 | extern void __init at91sam9260_init_interrupts(unsigned int priority[]); | ||
19 | extern void __init at91sam9261_init_interrupts(unsigned int priority[]); | ||
20 | extern void __init at91_aic_init(unsigned int priority[]); | ||
21 | |||
22 | /* Timer */ | ||
23 | struct sys_timer; | ||
24 | extern struct sys_timer at91rm9200_timer; | ||
25 | extern struct sys_timer at91sam926x_timer; | ||
26 | |||
27 | /* Clocks */ | ||
28 | extern int __init at91_clock_init(unsigned long main_clock); | ||
29 | struct device; | ||
30 | extern void __init at91_clock_associate(const char *id, struct device *dev, const char *func); | ||
31 | |||
32 | /* Power Management */ | ||
33 | extern void at91_irq_suspend(void); | ||
34 | extern void at91_irq_resume(void); | ||
35 | |||
36 | /* GPIO */ | ||
37 | #define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ | ||
38 | #define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ | ||
39 | |||
40 | struct at91_gpio_bank { | ||
41 | unsigned short id; /* peripheral ID */ | ||
42 | unsigned long offset; /* offset from system peripheral base */ | ||
43 | struct clk *clock; /* associated clock */ | ||
44 | }; | ||
45 | extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); | ||
46 | extern void __init at91_gpio_irq_setup(void); | ||
47 | |||
48 | extern void (*at91_arch_reset)(void); | ||
49 | extern int at91_extern_irq; | ||
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c new file mode 100644 index 000000000000..9b7495cd555d --- /dev/null +++ b/arch/arm/mach-at91/gpio.c | |||
@@ -0,0 +1,414 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/gpio.c | ||
3 | * | ||
4 | * Copyright (C) 2005 HP Labs | ||
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 | #include <linux/clk.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/module.h> | ||
19 | |||
20 | #include <asm/io.h> | ||
21 | #include <asm/hardware.h> | ||
22 | #include <asm/arch/at91_pio.h> | ||
23 | #include <asm/arch/gpio.h> | ||
24 | |||
25 | #include "generic.h" | ||
26 | |||
27 | |||
28 | static struct at91_gpio_bank *gpio; | ||
29 | static int gpio_banks; | ||
30 | |||
31 | |||
32 | static inline void __iomem *pin_to_controller(unsigned pin) | ||
33 | { | ||
34 | void __iomem *sys_base = (void __iomem *) AT91_VA_BASE_SYS; | ||
35 | |||
36 | pin -= PIN_BASE; | ||
37 | pin /= 32; | ||
38 | if (likely(pin < gpio_banks)) | ||
39 | return sys_base + gpio[pin].offset; | ||
40 | |||
41 | return NULL; | ||
42 | } | ||
43 | |||
44 | static inline unsigned pin_to_mask(unsigned pin) | ||
45 | { | ||
46 | pin -= PIN_BASE; | ||
47 | return 1 << (pin % 32); | ||
48 | } | ||
49 | |||
50 | |||
51 | /*--------------------------------------------------------------------------*/ | ||
52 | |||
53 | /* Not all hardware capabilities are exposed through these calls; they | ||
54 | * only encapsulate the most common features and modes. (So if you | ||
55 | * want to change signals in groups, do it directly.) | ||
56 | * | ||
57 | * Bootloaders will usually handle some of the pin multiplexing setup. | ||
58 | * The intent is certainly that by the time Linux is fully booted, all | ||
59 | * pins should have been fully initialized. These setup calls should | ||
60 | * only be used by board setup routines, or possibly in driver probe(). | ||
61 | * | ||
62 | * For bootloaders doing all that setup, these calls could be inlined | ||
63 | * as NOPs so Linux won't duplicate any setup code | ||
64 | */ | ||
65 | |||
66 | |||
67 | /* | ||
68 | * mux the pin to the "A" internal peripheral role. | ||
69 | */ | ||
70 | int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup) | ||
71 | { | ||
72 | void __iomem *pio = pin_to_controller(pin); | ||
73 | unsigned mask = pin_to_mask(pin); | ||
74 | |||
75 | if (!pio) | ||
76 | return -EINVAL; | ||
77 | |||
78 | __raw_writel(mask, pio + PIO_IDR); | ||
79 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | ||
80 | __raw_writel(mask, pio + PIO_ASR); | ||
81 | __raw_writel(mask, pio + PIO_PDR); | ||
82 | return 0; | ||
83 | } | ||
84 | EXPORT_SYMBOL(at91_set_A_periph); | ||
85 | |||
86 | |||
87 | /* | ||
88 | * mux the pin to the "B" internal peripheral role. | ||
89 | */ | ||
90 | int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup) | ||
91 | { | ||
92 | void __iomem *pio = pin_to_controller(pin); | ||
93 | unsigned mask = pin_to_mask(pin); | ||
94 | |||
95 | if (!pio) | ||
96 | return -EINVAL; | ||
97 | |||
98 | __raw_writel(mask, pio + PIO_IDR); | ||
99 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | ||
100 | __raw_writel(mask, pio + PIO_BSR); | ||
101 | __raw_writel(mask, pio + PIO_PDR); | ||
102 | return 0; | ||
103 | } | ||
104 | EXPORT_SYMBOL(at91_set_B_periph); | ||
105 | |||
106 | |||
107 | /* | ||
108 | * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and | ||
109 | * configure it for an input. | ||
110 | */ | ||
111 | int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup) | ||
112 | { | ||
113 | void __iomem *pio = pin_to_controller(pin); | ||
114 | unsigned mask = pin_to_mask(pin); | ||
115 | |||
116 | if (!pio) | ||
117 | return -EINVAL; | ||
118 | |||
119 | __raw_writel(mask, pio + PIO_IDR); | ||
120 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | ||
121 | __raw_writel(mask, pio + PIO_ODR); | ||
122 | __raw_writel(mask, pio + PIO_PER); | ||
123 | return 0; | ||
124 | } | ||
125 | EXPORT_SYMBOL(at91_set_gpio_input); | ||
126 | |||
127 | |||
128 | /* | ||
129 | * mux the pin to the gpio controller (instead of "A" or "B" peripheral), | ||
130 | * and configure it for an output. | ||
131 | */ | ||
132 | int __init_or_module at91_set_gpio_output(unsigned pin, int value) | ||
133 | { | ||
134 | void __iomem *pio = pin_to_controller(pin); | ||
135 | unsigned mask = pin_to_mask(pin); | ||
136 | |||
137 | if (!pio) | ||
138 | return -EINVAL; | ||
139 | |||
140 | __raw_writel(mask, pio + PIO_IDR); | ||
141 | __raw_writel(mask, pio + PIO_PUDR); | ||
142 | __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); | ||
143 | __raw_writel(mask, pio + PIO_OER); | ||
144 | __raw_writel(mask, pio + PIO_PER); | ||
145 | return 0; | ||
146 | } | ||
147 | EXPORT_SYMBOL(at91_set_gpio_output); | ||
148 | |||
149 | |||
150 | /* | ||
151 | * enable/disable the glitch filter; mostly used with IRQ handling. | ||
152 | */ | ||
153 | int __init_or_module at91_set_deglitch(unsigned pin, int is_on) | ||
154 | { | ||
155 | void __iomem *pio = pin_to_controller(pin); | ||
156 | unsigned mask = pin_to_mask(pin); | ||
157 | |||
158 | if (!pio) | ||
159 | return -EINVAL; | ||
160 | __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); | ||
161 | return 0; | ||
162 | } | ||
163 | EXPORT_SYMBOL(at91_set_deglitch); | ||
164 | |||
165 | /* | ||
166 | * enable/disable the multi-driver; This is only valid for output and | ||
167 | * allows the output pin to run as an open collector output. | ||
168 | */ | ||
169 | int __init_or_module at91_set_multi_drive(unsigned pin, int is_on) | ||
170 | { | ||
171 | void __iomem *pio = pin_to_controller(pin); | ||
172 | unsigned mask = pin_to_mask(pin); | ||
173 | |||
174 | if (!pio) | ||
175 | return -EINVAL; | ||
176 | |||
177 | __raw_writel(mask, pio + (is_on ? PIO_MDER : PIO_MDDR)); | ||
178 | return 0; | ||
179 | } | ||
180 | EXPORT_SYMBOL(at91_set_multi_drive); | ||
181 | |||
182 | /*--------------------------------------------------------------------------*/ | ||
183 | |||
184 | /* | ||
185 | * assuming the pin is muxed as a gpio output, set its value. | ||
186 | */ | ||
187 | int at91_set_gpio_value(unsigned pin, int value) | ||
188 | { | ||
189 | void __iomem *pio = pin_to_controller(pin); | ||
190 | unsigned mask = pin_to_mask(pin); | ||
191 | |||
192 | if (!pio) | ||
193 | return -EINVAL; | ||
194 | __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); | ||
195 | return 0; | ||
196 | } | ||
197 | EXPORT_SYMBOL(at91_set_gpio_value); | ||
198 | |||
199 | |||
200 | /* | ||
201 | * read the pin's value (works even if it's not muxed as a gpio). | ||
202 | */ | ||
203 | int at91_get_gpio_value(unsigned pin) | ||
204 | { | ||
205 | void __iomem *pio = pin_to_controller(pin); | ||
206 | unsigned mask = pin_to_mask(pin); | ||
207 | u32 pdsr; | ||
208 | |||
209 | if (!pio) | ||
210 | return -EINVAL; | ||
211 | pdsr = __raw_readl(pio + PIO_PDSR); | ||
212 | return (pdsr & mask) != 0; | ||
213 | } | ||
214 | EXPORT_SYMBOL(at91_get_gpio_value); | ||
215 | |||
216 | /*--------------------------------------------------------------------------*/ | ||
217 | |||
218 | #ifdef CONFIG_PM | ||
219 | |||
220 | static u32 wakeups[MAX_GPIO_BANKS]; | ||
221 | static u32 backups[MAX_GPIO_BANKS]; | ||
222 | |||
223 | static int gpio_irq_set_wake(unsigned pin, unsigned state) | ||
224 | { | ||
225 | unsigned mask = pin_to_mask(pin); | ||
226 | unsigned bank = (pin - PIN_BASE) / 32; | ||
227 | |||
228 | if (unlikely(bank >= MAX_GPIO_BANKS)) | ||
229 | return -EINVAL; | ||
230 | |||
231 | if (state) | ||
232 | wakeups[bank] |= mask; | ||
233 | else | ||
234 | wakeups[bank] &= ~mask; | ||
235 | |||
236 | set_irq_wake(gpio[bank].id, state); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | void at91_gpio_suspend(void) | ||
242 | { | ||
243 | int i; | ||
244 | |||
245 | for (i = 0; i < gpio_banks; i++) { | ||
246 | u32 pio = gpio[i].offset; | ||
247 | |||
248 | backups[i] = at91_sys_read(pio + PIO_IMR); | ||
249 | at91_sys_write(pio + PIO_IDR, backups[i]); | ||
250 | at91_sys_write(pio + PIO_IER, wakeups[i]); | ||
251 | |||
252 | if (!wakeups[i]) | ||
253 | clk_disable(gpio[i].clock); | ||
254 | else { | ||
255 | #ifdef CONFIG_PM_DEBUG | ||
256 | printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); | ||
257 | #endif | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | |||
262 | void at91_gpio_resume(void) | ||
263 | { | ||
264 | int i; | ||
265 | |||
266 | for (i = 0; i < gpio_banks; i++) { | ||
267 | u32 pio = gpio[i].offset; | ||
268 | |||
269 | if (!wakeups[i]) | ||
270 | clk_enable(gpio[i].clock); | ||
271 | |||
272 | at91_sys_write(pio + PIO_IDR, wakeups[i]); | ||
273 | at91_sys_write(pio + PIO_IER, backups[i]); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | #else | ||
278 | #define gpio_irq_set_wake NULL | ||
279 | #endif | ||
280 | |||
281 | |||
282 | /* Several AIC controller irqs are dispatched through this GPIO handler. | ||
283 | * To use any AT91_PIN_* as an externally triggered IRQ, first call | ||
284 | * at91_set_gpio_input() then maybe enable its glitch filter. | ||
285 | * Then just request_irq() with the pin ID; it works like any ARM IRQ | ||
286 | * handler, though it always triggers on rising and falling edges. | ||
287 | * | ||
288 | * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after | ||
289 | * configuring them with at91_set_a_periph() or at91_set_b_periph(). | ||
290 | * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering. | ||
291 | */ | ||
292 | |||
293 | static void gpio_irq_mask(unsigned pin) | ||
294 | { | ||
295 | void __iomem *pio = pin_to_controller(pin); | ||
296 | unsigned mask = pin_to_mask(pin); | ||
297 | |||
298 | if (pio) | ||
299 | __raw_writel(mask, pio + PIO_IDR); | ||
300 | } | ||
301 | |||
302 | static void gpio_irq_unmask(unsigned pin) | ||
303 | { | ||
304 | void __iomem *pio = pin_to_controller(pin); | ||
305 | unsigned mask = pin_to_mask(pin); | ||
306 | |||
307 | if (pio) | ||
308 | __raw_writel(mask, pio + PIO_IER); | ||
309 | } | ||
310 | |||
311 | static int gpio_irq_type(unsigned pin, unsigned type) | ||
312 | { | ||
313 | return (type == IRQT_BOTHEDGE) ? 0 : -EINVAL; | ||
314 | } | ||
315 | |||
316 | static struct irq_chip gpio_irqchip = { | ||
317 | .name = "GPIO", | ||
318 | .mask = gpio_irq_mask, | ||
319 | .unmask = gpio_irq_unmask, | ||
320 | .set_type = gpio_irq_type, | ||
321 | .set_wake = gpio_irq_set_wake, | ||
322 | }; | ||
323 | |||
324 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
325 | { | ||
326 | unsigned pin; | ||
327 | struct irq_desc *gpio; | ||
328 | void __iomem *pio; | ||
329 | u32 isr; | ||
330 | |||
331 | pio = get_irq_chip_data(irq); | ||
332 | |||
333 | /* temporarily mask (level sensitive) parent IRQ */ | ||
334 | desc->chip->ack(irq); | ||
335 | for (;;) { | ||
336 | /* reading ISR acks the pending (edge triggered) GPIO interrupt */ | ||
337 | isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR); | ||
338 | if (!isr) | ||
339 | break; | ||
340 | |||
341 | pin = (unsigned) get_irq_data(irq); | ||
342 | gpio = &irq_desc[pin]; | ||
343 | |||
344 | while (isr) { | ||
345 | if (isr & 1) { | ||
346 | if (unlikely(gpio->depth)) { | ||
347 | /* | ||
348 | * The core ARM interrupt handler lazily disables IRQs so | ||
349 | * another IRQ must be generated before it actually gets | ||
350 | * here to be disabled on the GPIO controller. | ||
351 | */ | ||
352 | gpio_irq_mask(pin); | ||
353 | } | ||
354 | else | ||
355 | desc_handle_irq(pin, gpio); | ||
356 | } | ||
357 | pin++; | ||
358 | gpio++; | ||
359 | isr >>= 1; | ||
360 | } | ||
361 | } | ||
362 | desc->chip->unmask(irq); | ||
363 | /* now it may re-trigger */ | ||
364 | } | ||
365 | |||
366 | /*--------------------------------------------------------------------------*/ | ||
367 | |||
368 | /* | ||
369 | * Called from the processor-specific init to enable GPIO interrupt support. | ||
370 | */ | ||
371 | void __init at91_gpio_irq_setup(void) | ||
372 | { | ||
373 | unsigned pioc, pin; | ||
374 | |||
375 | for (pioc = 0, pin = PIN_BASE; | ||
376 | pioc < gpio_banks; | ||
377 | pioc++) { | ||
378 | void __iomem *controller; | ||
379 | unsigned id = gpio[pioc].id; | ||
380 | unsigned i; | ||
381 | |||
382 | clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */ | ||
383 | |||
384 | controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset; | ||
385 | __raw_writel(~0, controller + PIO_IDR); | ||
386 | |||
387 | set_irq_data(id, (void *) pin); | ||
388 | set_irq_chip_data(id, controller); | ||
389 | |||
390 | for (i = 0; i < 32; i++, pin++) { | ||
391 | /* | ||
392 | * Can use the "simple" and not "edge" handler since it's | ||
393 | * shorter, and the AIC handles interupts sanely. | ||
394 | */ | ||
395 | set_irq_chip(pin, &gpio_irqchip); | ||
396 | set_irq_handler(pin, handle_simple_irq); | ||
397 | set_irq_flags(pin, IRQF_VALID); | ||
398 | } | ||
399 | |||
400 | set_irq_chained_handler(id, gpio_irq_handler); | ||
401 | } | ||
402 | pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * Called from the processor-specific init to enable GPIO pin support. | ||
407 | */ | ||
408 | void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) | ||
409 | { | ||
410 | BUG_ON(nr_banks > MAX_GPIO_BANKS); | ||
411 | |||
412 | gpio = data; | ||
413 | gpio_banks = nr_banks; | ||
414 | } | ||
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c new file mode 100644 index 000000000000..78a5cdb746dc --- /dev/null +++ b/arch/arm/mach-at91/irq.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/irq.c | ||
3 | * | ||
4 | * Copyright (C) 2004 SAN People | ||
5 | * Copyright (C) 2004 ATMEL | ||
6 | * Copyright (C) Rick Bronson | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/init.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/mm.h> | ||
26 | #include <linux/types.h> | ||
27 | |||
28 | #include <asm/hardware.h> | ||
29 | #include <asm/irq.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/setup.h> | ||
32 | |||
33 | #include <asm/mach/arch.h> | ||
34 | #include <asm/mach/irq.h> | ||
35 | #include <asm/mach/map.h> | ||
36 | |||
37 | |||
38 | static void at91_aic_mask_irq(unsigned int irq) | ||
39 | { | ||
40 | /* Disable interrupt on AIC */ | ||
41 | at91_sys_write(AT91_AIC_IDCR, 1 << irq); | ||
42 | } | ||
43 | |||
44 | static void at91_aic_unmask_irq(unsigned int irq) | ||
45 | { | ||
46 | /* Enable interrupt on AIC */ | ||
47 | at91_sys_write(AT91_AIC_IECR, 1 << irq); | ||
48 | } | ||
49 | |||
50 | unsigned int at91_extern_irq; | ||
51 | |||
52 | #define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq) | ||
53 | |||
54 | static int at91_aic_set_type(unsigned irq, unsigned type) | ||
55 | { | ||
56 | unsigned int smr, srctype; | ||
57 | |||
58 | switch (type) { | ||
59 | case IRQT_HIGH: | ||
60 | srctype = AT91_AIC_SRCTYPE_HIGH; | ||
61 | break; | ||
62 | case IRQT_RISING: | ||
63 | srctype = AT91_AIC_SRCTYPE_RISING; | ||
64 | break; | ||
65 | case IRQT_LOW: | ||
66 | if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ | ||
67 | srctype = AT91_AIC_SRCTYPE_LOW; | ||
68 | else | ||
69 | return -EINVAL; | ||
70 | break; | ||
71 | case IRQT_FALLING: | ||
72 | if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ | ||
73 | srctype = AT91_AIC_SRCTYPE_FALLING; | ||
74 | else | ||
75 | return -EINVAL; | ||
76 | break; | ||
77 | default: | ||
78 | return -EINVAL; | ||
79 | } | ||
80 | |||
81 | smr = at91_sys_read(AT91_AIC_SMR(irq)) & ~AT91_AIC_SRCTYPE; | ||
82 | at91_sys_write(AT91_AIC_SMR(irq), smr | srctype); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | #ifdef CONFIG_PM | ||
87 | |||
88 | static u32 wakeups; | ||
89 | static u32 backups; | ||
90 | |||
91 | static int at91_aic_set_wake(unsigned irq, unsigned value) | ||
92 | { | ||
93 | if (unlikely(irq >= 32)) | ||
94 | return -EINVAL; | ||
95 | |||
96 | if (value) | ||
97 | wakeups |= (1 << irq); | ||
98 | else | ||
99 | wakeups &= ~(1 << irq); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | void at91_irq_suspend(void) | ||
105 | { | ||
106 | backups = at91_sys_read(AT91_AIC_IMR); | ||
107 | at91_sys_write(AT91_AIC_IDCR, backups); | ||
108 | at91_sys_write(AT91_AIC_IECR, wakeups); | ||
109 | } | ||
110 | |||
111 | void at91_irq_resume(void) | ||
112 | { | ||
113 | at91_sys_write(AT91_AIC_IDCR, wakeups); | ||
114 | at91_sys_write(AT91_AIC_IECR, backups); | ||
115 | } | ||
116 | |||
117 | #else | ||
118 | #define at91_aic_set_wake NULL | ||
119 | #endif | ||
120 | |||
121 | static struct irq_chip at91_aic_chip = { | ||
122 | .name = "AIC", | ||
123 | .ack = at91_aic_mask_irq, | ||
124 | .mask = at91_aic_mask_irq, | ||
125 | .unmask = at91_aic_unmask_irq, | ||
126 | .set_type = at91_aic_set_type, | ||
127 | .set_wake = at91_aic_set_wake, | ||
128 | }; | ||
129 | |||
130 | /* | ||
131 | * Initialize the AIC interrupt controller. | ||
132 | */ | ||
133 | void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) | ||
134 | { | ||
135 | unsigned int i; | ||
136 | |||
137 | /* | ||
138 | * The IVR is used by macro get_irqnr_and_base to read and verify. | ||
139 | * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. | ||
140 | */ | ||
141 | for (i = 0; i < NR_AIC_IRQS; i++) { | ||
142 | /* Put irq number in Source Vector Register: */ | ||
143 | at91_sys_write(AT91_AIC_SVR(i), i); | ||
144 | /* Active Low interrupt, with the specified priority */ | ||
145 | at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); | ||
146 | |||
147 | set_irq_chip(i, &at91_aic_chip); | ||
148 | set_irq_handler(i, handle_level_irq); | ||
149 | set_irq_flags(i, IRQF_VALID | IRQF_PROBE); | ||
150 | |||
151 | /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ | ||
152 | if (i < 8) | ||
153 | at91_sys_write(AT91_AIC_EOICR, 0); | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS | ||
158 | * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU | ||
159 | */ | ||
160 | at91_sys_write(AT91_AIC_SPU, NR_AIC_IRQS); | ||
161 | |||
162 | /* No debugging in AIC: Debug (Protect) Control Register */ | ||
163 | at91_sys_write(AT91_AIC_DCR, 0); | ||
164 | |||
165 | /* Disable and clear all interrupts initially */ | ||
166 | at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF); | ||
167 | at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF); | ||
168 | } | ||
diff --git a/arch/arm/mach-at91/leds.c b/arch/arm/mach-at91/leds.c new file mode 100644 index 000000000000..1a333730466e --- /dev/null +++ b/arch/arm/mach-at91/leds.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * LED driver for Atmel AT91-based boards. | ||
3 | * | ||
4 | * Copyright (C) SAN People (Pty) Ltd | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | |||
16 | #include <asm/mach-types.h> | ||
17 | #include <asm/leds.h> | ||
18 | #include <asm/arch/board.h> | ||
19 | #include <asm/arch/gpio.h> | ||
20 | |||
21 | |||
22 | static inline void at91_led_on(unsigned int led) | ||
23 | { | ||
24 | at91_set_gpio_value(led, 0); | ||
25 | } | ||
26 | |||
27 | static inline void at91_led_off(unsigned int led) | ||
28 | { | ||
29 | at91_set_gpio_value(led, 1); | ||
30 | } | ||
31 | |||
32 | static inline void at91_led_toggle(unsigned int led) | ||
33 | { | ||
34 | unsigned long is_off = at91_get_gpio_value(led); | ||
35 | if (is_off) | ||
36 | at91_led_on(led); | ||
37 | else | ||
38 | at91_led_off(led); | ||
39 | } | ||
40 | |||
41 | |||
42 | /* | ||
43 | * Handle LED events. | ||
44 | */ | ||
45 | static void at91_leds_event(led_event_t evt) | ||
46 | { | ||
47 | unsigned long flags; | ||
48 | |||
49 | local_irq_save(flags); | ||
50 | |||
51 | switch(evt) { | ||
52 | case led_start: /* System startup */ | ||
53 | at91_led_on(at91_leds_cpu); | ||
54 | break; | ||
55 | |||
56 | case led_stop: /* System stop / suspend */ | ||
57 | at91_led_off(at91_leds_cpu); | ||
58 | break; | ||
59 | |||
60 | #ifdef CONFIG_LEDS_TIMER | ||
61 | case led_timer: /* Every 50 timer ticks */ | ||
62 | at91_led_toggle(at91_leds_timer); | ||
63 | break; | ||
64 | #endif | ||
65 | |||
66 | #ifdef CONFIG_LEDS_CPU | ||
67 | case led_idle_start: /* Entering idle state */ | ||
68 | at91_led_off(at91_leds_cpu); | ||
69 | break; | ||
70 | |||
71 | case led_idle_end: /* Exit idle state */ | ||
72 | at91_led_on(at91_leds_cpu); | ||
73 | break; | ||
74 | #endif | ||
75 | |||
76 | default: | ||
77 | break; | ||
78 | } | ||
79 | |||
80 | local_irq_restore(flags); | ||
81 | } | ||
82 | |||
83 | |||
84 | static int __init leds_init(void) | ||
85 | { | ||
86 | if (!at91_leds_timer || !at91_leds_cpu) | ||
87 | return -ENODEV; | ||
88 | |||
89 | /* Enable PIO to access the LEDs */ | ||
90 | at91_set_gpio_output(at91_leds_timer, 1); | ||
91 | at91_set_gpio_output(at91_leds_cpu, 1); | ||
92 | |||
93 | leds_event = at91_leds_event; | ||
94 | |||
95 | leds_event(led_start); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | __initcall(leds_init); | ||
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c new file mode 100644 index 000000000000..e095b1fe8d8a --- /dev/null +++ b/arch/arm/mach-at91/pm.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/pm.c | ||
3 | * AT91 Power Management | ||
4 | * | ||
5 | * Copyright (C) 2005 David Brownell | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/pm.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/proc_fs.h> | ||
16 | #include <linux/pm.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/sysfs.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | #include <asm/io.h> | ||
23 | #include <asm/irq.h> | ||
24 | #include <asm/atomic.h> | ||
25 | #include <asm/mach/time.h> | ||
26 | #include <asm/mach/irq.h> | ||
27 | #include <asm/mach-types.h> | ||
28 | |||
29 | #include <asm/arch/at91_pmc.h> | ||
30 | #include <asm/arch/at91rm9200_mc.h> | ||
31 | #include <asm/arch/gpio.h> | ||
32 | #include <asm/arch/cpu.h> | ||
33 | |||
34 | #include "generic.h" | ||
35 | |||
36 | |||
37 | static int at91_pm_valid_state(suspend_state_t state) | ||
38 | { | ||
39 | switch (state) { | ||
40 | case PM_SUSPEND_ON: | ||
41 | case PM_SUSPEND_STANDBY: | ||
42 | case PM_SUSPEND_MEM: | ||
43 | return 1; | ||
44 | |||
45 | default: | ||
46 | return 0; | ||
47 | } | ||
48 | } | ||
49 | |||
50 | |||
51 | static suspend_state_t target_state; | ||
52 | |||
53 | /* | ||
54 | * Called after processes are frozen, but before we shutdown devices. | ||
55 | */ | ||
56 | static int at91_pm_prepare(suspend_state_t state) | ||
57 | { | ||
58 | target_state = state; | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * Verify that all the clocks are correct before entering | ||
64 | * slow-clock mode. | ||
65 | */ | ||
66 | static int at91_pm_verify_clocks(void) | ||
67 | { | ||
68 | unsigned long scsr; | ||
69 | int i; | ||
70 | |||
71 | scsr = at91_sys_read(AT91_PMC_SCSR); | ||
72 | |||
73 | /* USB must not be using PLLB */ | ||
74 | if (cpu_is_at91rm9200()) { | ||
75 | if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) { | ||
76 | pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); | ||
77 | return 0; | ||
78 | } | ||
79 | } else if (cpu_is_at91sam9260()) { | ||
80 | #warning "Check SAM9260 USB clocks" | ||
81 | } else if (cpu_is_at91sam9261()) { | ||
82 | #warning "Check SAM9261 USB clocks" | ||
83 | } | ||
84 | |||
85 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | ||
86 | /* PCK0..PCK3 must be disabled, or configured to use clk32k */ | ||
87 | for (i = 0; i < 4; i++) { | ||
88 | u32 css; | ||
89 | |||
90 | if ((scsr & (AT91_PMC_PCK0 << i)) == 0) | ||
91 | continue; | ||
92 | |||
93 | css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; | ||
94 | if (css != AT91_PMC_CSS_SLOW) { | ||
95 | pr_debug("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); | ||
96 | return 0; | ||
97 | } | ||
98 | } | ||
99 | #endif | ||
100 | |||
101 | return 1; | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * Call this from platform driver suspend() to see how deeply to suspend. | ||
106 | * For example, some controllers (like OHCI) need one of the PLL clocks | ||
107 | * in order to act as a wakeup source, and those are not available when | ||
108 | * going into slow clock mode. | ||
109 | * | ||
110 | * REVISIT: generalize as clk_will_be_available(clk)? Other platforms have | ||
111 | * the very same problem (but not using at91 main_clk), and it'd be better | ||
112 | * to add one generic API rather than lots of platform-specific ones. | ||
113 | */ | ||
114 | int at91_suspend_entering_slow_clock(void) | ||
115 | { | ||
116 | return (target_state == PM_SUSPEND_MEM); | ||
117 | } | ||
118 | EXPORT_SYMBOL(at91_suspend_entering_slow_clock); | ||
119 | |||
120 | |||
121 | static void (*slow_clock)(void); | ||
122 | |||
123 | |||
124 | static int at91_pm_enter(suspend_state_t state) | ||
125 | { | ||
126 | at91_gpio_suspend(); | ||
127 | at91_irq_suspend(); | ||
128 | |||
129 | pr_debug("AT91: PM - wake mask %08x, pm state %d\n", | ||
130 | /* remember all the always-wake irqs */ | ||
131 | (at91_sys_read(AT91_PMC_PCSR) | ||
132 | | (1 << AT91_ID_FIQ) | ||
133 | | (1 << AT91_ID_SYS) | ||
134 | | (at91_extern_irq)) | ||
135 | & at91_sys_read(AT91_AIC_IMR), | ||
136 | state); | ||
137 | |||
138 | switch (state) { | ||
139 | /* | ||
140 | * Suspend-to-RAM is like STANDBY plus slow clock mode, so | ||
141 | * drivers must suspend more deeply: only the master clock | ||
142 | * controller may be using the main oscillator. | ||
143 | */ | ||
144 | case PM_SUSPEND_MEM: | ||
145 | /* | ||
146 | * Ensure that clocks are in a valid state. | ||
147 | */ | ||
148 | if (!at91_pm_verify_clocks()) | ||
149 | goto error; | ||
150 | |||
151 | /* | ||
152 | * Enter slow clock mode by switching over to clk32k and | ||
153 | * turning off the main oscillator; reverse on wakeup. | ||
154 | */ | ||
155 | if (slow_clock) { | ||
156 | slow_clock(); | ||
157 | break; | ||
158 | } else { | ||
159 | /* DEVELOPMENT ONLY */ | ||
160 | pr_info("AT91: PM - no slow clock mode yet ...\n"); | ||
161 | /* FALLTHROUGH leaving master clock alone */ | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * STANDBY mode has *all* drivers suspended; ignores irqs not | ||
166 | * marked as 'wakeup' event sources; and reduces DRAM power. | ||
167 | * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and | ||
168 | * nothing fancy done with main or cpu clocks. | ||
169 | */ | ||
170 | case PM_SUSPEND_STANDBY: | ||
171 | /* | ||
172 | * NOTE: the Wait-for-Interrupt instruction needs to be | ||
173 | * in icache so the SDRAM stays in self-refresh mode until | ||
174 | * the wakeup IRQ occurs. | ||
175 | */ | ||
176 | asm("b 1f; .align 5; 1:"); | ||
177 | asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ | ||
178 | at91_sys_write(AT91_SDRAMC_SRR, 1); /* self-refresh mode */ | ||
179 | /* fall though to next state */ | ||
180 | |||
181 | case PM_SUSPEND_ON: | ||
182 | asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */ | ||
183 | break; | ||
184 | |||
185 | default: | ||
186 | pr_debug("AT91: PM - bogus suspend state %d\n", state); | ||
187 | goto error; | ||
188 | } | ||
189 | |||
190 | pr_debug("AT91: PM - wakeup %08x\n", | ||
191 | at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); | ||
192 | |||
193 | error: | ||
194 | target_state = PM_SUSPEND_ON; | ||
195 | at91_irq_resume(); | ||
196 | at91_gpio_resume(); | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | |||
201 | static struct pm_ops at91_pm_ops ={ | ||
202 | .pm_disk_mode = 0, | ||
203 | .valid = at91_pm_valid_state, | ||
204 | .prepare = at91_pm_prepare, | ||
205 | .enter = at91_pm_enter, | ||
206 | }; | ||
207 | |||
208 | static int __init at91_pm_init(void) | ||
209 | { | ||
210 | printk("AT91: Power Management\n"); | ||
211 | |||
212 | #ifdef CONFIG_AT91_PM_SLOW_CLOCK | ||
213 | /* REVISIT allocations of SRAM should be dynamically managed. | ||
214 | * FIQ handlers and other components will want SRAM/TCM too... | ||
215 | */ | ||
216 | slow_clock = (void *) (AT91_VA_BASE_SRAM + (3 * SZ_4K)); | ||
217 | memcpy(slow_clock, at91rm9200_slow_clock, at91rm9200_slow_clock_sz); | ||
218 | #endif | ||
219 | |||
220 | /* Disable SDRAM low-power mode. Cannot be used with self-refresh. */ | ||
221 | at91_sys_write(AT91_SDRAMC_LPR, 0); | ||
222 | |||
223 | pm_set_ops(&at91_pm_ops); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | arch_initcall(at91_pm_init); | ||