diff options
Diffstat (limited to 'arch/arm/mach-at91')
32 files changed, 8786 insertions, 0 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig new file mode 100644 index 000000000000..bf0d96272e3a --- /dev/null +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -0,0 +1,175 @@ | |||
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 or AT91SAM9XE" | ||
13 | |||
14 | config ARCH_AT91SAM9261 | ||
15 | bool "AT91SAM9261" | ||
16 | |||
17 | config ARCH_AT91SAM9263 | ||
18 | bool "AT91SAM9263" | ||
19 | |||
20 | endchoice | ||
21 | |||
22 | # ---------------------------------------------------------- | ||
23 | |||
24 | if ARCH_AT91RM9200 | ||
25 | |||
26 | comment "AT91RM9200 Board Type" | ||
27 | |||
28 | config MACH_ONEARM | ||
29 | bool "Ajeco 1ARM Single Board Computer" | ||
30 | depends on ARCH_AT91RM9200 | ||
31 | help | ||
32 | Select this if you are using Ajeco's 1ARM Single Board Computer. | ||
33 | <http://www.ajeco.fi/products.htm> | ||
34 | |||
35 | config ARCH_AT91RM9200DK | ||
36 | bool "Atmel AT91RM9200-DK Development board" | ||
37 | depends on ARCH_AT91RM9200 | ||
38 | help | ||
39 | Select this if you are using Atmel's AT91RM9200-DK Development board. | ||
40 | (Discontinued) | ||
41 | |||
42 | config MACH_AT91RM9200EK | ||
43 | bool "Atmel AT91RM9200-EK Evaluation Kit" | ||
44 | depends on ARCH_AT91RM9200 | ||
45 | help | ||
46 | Select this if you are using Atmel's AT91RM9200-EK Evaluation Kit. | ||
47 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3507> | ||
48 | |||
49 | config MACH_CSB337 | ||
50 | bool "Cogent CSB337" | ||
51 | depends on ARCH_AT91RM9200 | ||
52 | help | ||
53 | Select this if you are using Cogent's CSB337 board. | ||
54 | <http://www.cogcomp.com/csb_csb337.htm> | ||
55 | |||
56 | config MACH_CSB637 | ||
57 | bool "Cogent CSB637" | ||
58 | depends on ARCH_AT91RM9200 | ||
59 | help | ||
60 | Select this if you are using Cogent's CSB637 board. | ||
61 | <http://www.cogcomp.com/csb_csb637.htm> | ||
62 | |||
63 | config MACH_CARMEVA | ||
64 | bool "Conitec ARM&EVA" | ||
65 | depends on ARCH_AT91RM9200 | ||
66 | help | ||
67 | Select this if you are using Conitec's AT91RM9200-MCU-Module. | ||
68 | <http://www.conitec.net/english/linuxboard.htm> | ||
69 | |||
70 | config MACH_ATEB9200 | ||
71 | bool "Embest ATEB9200" | ||
72 | depends on ARCH_AT91RM9200 | ||
73 | help | ||
74 | Select this if you are using Embest's ATEB9200 board. | ||
75 | <http://www.embedinfo.com/english/product/ATEB9200.asp> | ||
76 | |||
77 | config MACH_KB9200 | ||
78 | bool "KwikByte KB920x" | ||
79 | depends on ARCH_AT91RM9200 | ||
80 | help | ||
81 | Select this if you are using KwikByte's KB920x board. | ||
82 | <http://kwikbyte.com/KB9202_description_new.htm> | ||
83 | |||
84 | config MACH_KAFA | ||
85 | bool "Sperry-Sun KAFA board" | ||
86 | depends on ARCH_AT91RM9200 | ||
87 | help | ||
88 | Select this if you are using Sperry-Sun's KAFA board. | ||
89 | |||
90 | endif | ||
91 | |||
92 | # ---------------------------------------------------------- | ||
93 | |||
94 | if ARCH_AT91SAM9260 | ||
95 | |||
96 | comment "AT91SAM9260 Variants" | ||
97 | |||
98 | config ARCH_AT91SAM9260_SAM9XE | ||
99 | bool "AT91SAM9XE" | ||
100 | depends on ARCH_AT91SAM9260 | ||
101 | help | ||
102 | Select this if you are using Atmel's AT91SAM9XE System-on-Chip. | ||
103 | They are basicaly AT91SAM9260s with various sizes of embedded Flash. | ||
104 | |||
105 | comment "AT91SAM9260 / AT91SAM9XE Board Type" | ||
106 | |||
107 | config MACH_AT91SAM9260EK | ||
108 | bool "Atmel AT91SAM9260-EK / AT91SAM9XE Evaluation Kit" | ||
109 | depends on ARCH_AT91SAM9260 | ||
110 | help | ||
111 | Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit | ||
112 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933> | ||
113 | |||
114 | endif | ||
115 | |||
116 | # ---------------------------------------------------------- | ||
117 | |||
118 | if ARCH_AT91SAM9261 | ||
119 | |||
120 | comment "AT91SAM9261 Board Type" | ||
121 | |||
122 | config MACH_AT91SAM9261EK | ||
123 | bool "Atmel AT91SAM9261-EK Evaluation Kit" | ||
124 | depends on ARCH_AT91SAM9261 | ||
125 | help | ||
126 | Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit. | ||
127 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3820> | ||
128 | |||
129 | endif | ||
130 | |||
131 | # ---------------------------------------------------------- | ||
132 | |||
133 | if ARCH_AT91SAM9263 | ||
134 | |||
135 | comment "AT91SAM9263 Board Type" | ||
136 | |||
137 | config MACH_AT91SAM9263EK | ||
138 | bool "Atmel AT91SAM9263-EK Evaluation Kit" | ||
139 | depends on ARCH_AT91SAM9263 | ||
140 | help | ||
141 | Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit. | ||
142 | <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057> | ||
143 | |||
144 | endif | ||
145 | |||
146 | # ---------------------------------------------------------- | ||
147 | |||
148 | comment "AT91 Board Options" | ||
149 | |||
150 | config MTD_AT91_DATAFLASH_CARD | ||
151 | bool "Enable DataFlash Card support" | ||
152 | depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK) | ||
153 | help | ||
154 | Enable support for the DataFlash card. | ||
155 | |||
156 | config MTD_NAND_AT91_BUSWIDTH_16 | ||
157 | bool "Enable 16-bit data bus interface to NAND flash" | ||
158 | depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK) | ||
159 | help | ||
160 | On AT91SAM926x boards both types of NAND flash can be present | ||
161 | (8 and 16 bit data bus width). | ||
162 | |||
163 | # ---------------------------------------------------------- | ||
164 | |||
165 | comment "AT91 Feature Selections" | ||
166 | |||
167 | config AT91_PROGRAMMABLE_CLOCKS | ||
168 | bool "Programmable Clocks" | ||
169 | help | ||
170 | Select this if you need to program one or more of the PCK0..PCK3 | ||
171 | programmable clock outputs. | ||
172 | |||
173 | endmenu | ||
174 | |||
175 | endif | ||
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile new file mode 100644 index 000000000000..05de6cdc88f1 --- /dev/null +++ b/arch/arm/mach-at91/Makefile | |||
@@ -0,0 +1,53 @@ | |||
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 | obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o | ||
17 | |||
18 | # AT91RM9200 board-specific support | ||
19 | obj-$(CONFIG_MACH_ONEARM) += board-1arm.o | ||
20 | obj-$(CONFIG_ARCH_AT91RM9200DK) += board-dk.o | ||
21 | obj-$(CONFIG_MACH_AT91RM9200EK) += board-ek.o | ||
22 | obj-$(CONFIG_MACH_CSB337) += board-csb337.o | ||
23 | obj-$(CONFIG_MACH_CSB637) += board-csb637.o | ||
24 | obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o | ||
25 | obj-$(CONFIG_MACH_KB9200) += board-kb9202.o | ||
26 | obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o | ||
27 | obj-$(CONFIG_MACH_KAFA) += board-kafa.o | ||
28 | |||
29 | # AT91SAM9260 board-specific support | ||
30 | obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o | ||
31 | |||
32 | # AT91SAM9261 board-specific support | ||
33 | obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o | ||
34 | |||
35 | # AT91SAM9263 board-specific support | ||
36 | obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o | ||
37 | |||
38 | # LEDs support | ||
39 | led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o | ||
40 | led-$(CONFIG_MACH_AT91RM9200EK) += leds.o | ||
41 | led-$(CONFIG_MACH_CSB337) += leds.o | ||
42 | led-$(CONFIG_MACH_CSB637) += leds.o | ||
43 | led-$(CONFIG_MACH_KB9200) += leds.o | ||
44 | led-$(CONFIG_MACH_KAFA) += leds.o | ||
45 | obj-$(CONFIG_LEDS) += $(led-y) | ||
46 | |||
47 | # VGA support | ||
48 | #obj-$(CONFIG_FB_S1D13XXX) += ics1523.o | ||
49 | |||
50 | |||
51 | ifeq ($(CONFIG_PM_DEBUG),y) | ||
52 | CFLAGS_pm.o += -DDEBUG | ||
53 | 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..2ddcdd69df7d --- /dev/null +++ b/arch/arm/mach-at91/at91rm9200.c | |||
@@ -0,0 +1,329 @@ | |||
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 | static struct clk tc0_clk = { | ||
121 | .name = "tc0_clk", | ||
122 | .pmc_mask = 1 << AT91RM9200_ID_TC0, | ||
123 | .type = CLK_TYPE_PERIPHERAL, | ||
124 | }; | ||
125 | static struct clk tc1_clk = { | ||
126 | .name = "tc1_clk", | ||
127 | .pmc_mask = 1 << AT91RM9200_ID_TC1, | ||
128 | .type = CLK_TYPE_PERIPHERAL, | ||
129 | }; | ||
130 | static struct clk tc2_clk = { | ||
131 | .name = "tc2_clk", | ||
132 | .pmc_mask = 1 << AT91RM9200_ID_TC2, | ||
133 | .type = CLK_TYPE_PERIPHERAL, | ||
134 | }; | ||
135 | static struct clk tc3_clk = { | ||
136 | .name = "tc3_clk", | ||
137 | .pmc_mask = 1 << AT91RM9200_ID_TC3, | ||
138 | .type = CLK_TYPE_PERIPHERAL, | ||
139 | }; | ||
140 | static struct clk tc4_clk = { | ||
141 | .name = "tc4_clk", | ||
142 | .pmc_mask = 1 << AT91RM9200_ID_TC4, | ||
143 | .type = CLK_TYPE_PERIPHERAL, | ||
144 | }; | ||
145 | static struct clk tc5_clk = { | ||
146 | .name = "tc5_clk", | ||
147 | .pmc_mask = 1 << AT91RM9200_ID_TC5, | ||
148 | .type = CLK_TYPE_PERIPHERAL, | ||
149 | }; | ||
150 | |||
151 | static struct clk *periph_clocks[] __initdata = { | ||
152 | &pioA_clk, | ||
153 | &pioB_clk, | ||
154 | &pioC_clk, | ||
155 | &pioD_clk, | ||
156 | &usart0_clk, | ||
157 | &usart1_clk, | ||
158 | &usart2_clk, | ||
159 | &usart3_clk, | ||
160 | &mmc_clk, | ||
161 | &udc_clk, | ||
162 | &twi_clk, | ||
163 | &spi_clk, | ||
164 | // ssc 0 .. ssc2 | ||
165 | &tc0_clk, | ||
166 | &tc1_clk, | ||
167 | &tc2_clk, | ||
168 | &tc3_clk, | ||
169 | &tc4_clk, | ||
170 | &tc5_clk, | ||
171 | &ohci_clk, | ||
172 | ðer_clk, | ||
173 | // irq0 .. irq6 | ||
174 | }; | ||
175 | |||
176 | /* | ||
177 | * The four programmable clocks. | ||
178 | * You must configure pin multiplexing to bring these signals out. | ||
179 | */ | ||
180 | static struct clk pck0 = { | ||
181 | .name = "pck0", | ||
182 | .pmc_mask = AT91_PMC_PCK0, | ||
183 | .type = CLK_TYPE_PROGRAMMABLE, | ||
184 | .id = 0, | ||
185 | }; | ||
186 | static struct clk pck1 = { | ||
187 | .name = "pck1", | ||
188 | .pmc_mask = AT91_PMC_PCK1, | ||
189 | .type = CLK_TYPE_PROGRAMMABLE, | ||
190 | .id = 1, | ||
191 | }; | ||
192 | static struct clk pck2 = { | ||
193 | .name = "pck2", | ||
194 | .pmc_mask = AT91_PMC_PCK2, | ||
195 | .type = CLK_TYPE_PROGRAMMABLE, | ||
196 | .id = 2, | ||
197 | }; | ||
198 | static struct clk pck3 = { | ||
199 | .name = "pck3", | ||
200 | .pmc_mask = AT91_PMC_PCK3, | ||
201 | .type = CLK_TYPE_PROGRAMMABLE, | ||
202 | .id = 3, | ||
203 | }; | ||
204 | |||
205 | static void __init at91rm9200_register_clocks(void) | ||
206 | { | ||
207 | int i; | ||
208 | |||
209 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
210 | clk_register(periph_clocks[i]); | ||
211 | |||
212 | clk_register(&pck0); | ||
213 | clk_register(&pck1); | ||
214 | clk_register(&pck2); | ||
215 | clk_register(&pck3); | ||
216 | } | ||
217 | |||
218 | /* -------------------------------------------------------------------- | ||
219 | * GPIO | ||
220 | * -------------------------------------------------------------------- */ | ||
221 | |||
222 | static struct at91_gpio_bank at91rm9200_gpio[] = { | ||
223 | { | ||
224 | .id = AT91RM9200_ID_PIOA, | ||
225 | .offset = AT91_PIOA, | ||
226 | .clock = &pioA_clk, | ||
227 | }, { | ||
228 | .id = AT91RM9200_ID_PIOB, | ||
229 | .offset = AT91_PIOB, | ||
230 | .clock = &pioB_clk, | ||
231 | }, { | ||
232 | .id = AT91RM9200_ID_PIOC, | ||
233 | .offset = AT91_PIOC, | ||
234 | .clock = &pioC_clk, | ||
235 | }, { | ||
236 | .id = AT91RM9200_ID_PIOD, | ||
237 | .offset = AT91_PIOD, | ||
238 | .clock = &pioD_clk, | ||
239 | } | ||
240 | }; | ||
241 | |||
242 | static void at91rm9200_reset(void) | ||
243 | { | ||
244 | /* | ||
245 | * Perform a hardware reset with the use of the Watchdog timer. | ||
246 | */ | ||
247 | at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); | ||
248 | at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); | ||
249 | } | ||
250 | |||
251 | |||
252 | /* -------------------------------------------------------------------- | ||
253 | * AT91RM9200 processor initialization | ||
254 | * -------------------------------------------------------------------- */ | ||
255 | void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks) | ||
256 | { | ||
257 | /* Map peripherals */ | ||
258 | iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); | ||
259 | |||
260 | at91_arch_reset = at91rm9200_reset; | ||
261 | at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) | ||
262 | | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) | ||
263 | | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5) | ||
264 | | (1 << AT91RM9200_ID_IRQ6); | ||
265 | |||
266 | /* Init clock subsystem */ | ||
267 | at91_clock_init(main_clock); | ||
268 | |||
269 | /* Register the processor-specific clocks */ | ||
270 | at91rm9200_register_clocks(); | ||
271 | |||
272 | /* Initialize GPIO subsystem */ | ||
273 | at91_gpio_init(at91rm9200_gpio, banks); | ||
274 | } | ||
275 | |||
276 | |||
277 | /* -------------------------------------------------------------------- | ||
278 | * Interrupt initialization | ||
279 | * -------------------------------------------------------------------- */ | ||
280 | |||
281 | /* | ||
282 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
283 | */ | ||
284 | static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
285 | 7, /* Advanced Interrupt Controller (FIQ) */ | ||
286 | 7, /* System Peripherals */ | ||
287 | 0, /* Parallel IO Controller A */ | ||
288 | 0, /* Parallel IO Controller B */ | ||
289 | 0, /* Parallel IO Controller C */ | ||
290 | 0, /* Parallel IO Controller D */ | ||
291 | 6, /* USART 0 */ | ||
292 | 6, /* USART 1 */ | ||
293 | 6, /* USART 2 */ | ||
294 | 6, /* USART 3 */ | ||
295 | 0, /* Multimedia Card Interface */ | ||
296 | 4, /* USB Device Port */ | ||
297 | 0, /* Two-Wire Interface */ | ||
298 | 6, /* Serial Peripheral Interface */ | ||
299 | 5, /* Serial Synchronous Controller 0 */ | ||
300 | 5, /* Serial Synchronous Controller 1 */ | ||
301 | 5, /* Serial Synchronous Controller 2 */ | ||
302 | 0, /* Timer Counter 0 */ | ||
303 | 0, /* Timer Counter 1 */ | ||
304 | 0, /* Timer Counter 2 */ | ||
305 | 0, /* Timer Counter 3 */ | ||
306 | 0, /* Timer Counter 4 */ | ||
307 | 0, /* Timer Counter 5 */ | ||
308 | 3, /* USB Host port */ | ||
309 | 3, /* Ethernet MAC */ | ||
310 | 0, /* Advanced Interrupt Controller (IRQ0) */ | ||
311 | 0, /* Advanced Interrupt Controller (IRQ1) */ | ||
312 | 0, /* Advanced Interrupt Controller (IRQ2) */ | ||
313 | 0, /* Advanced Interrupt Controller (IRQ3) */ | ||
314 | 0, /* Advanced Interrupt Controller (IRQ4) */ | ||
315 | 0, /* Advanced Interrupt Controller (IRQ5) */ | ||
316 | 0 /* Advanced Interrupt Controller (IRQ6) */ | ||
317 | }; | ||
318 | |||
319 | void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | ||
320 | { | ||
321 | if (!priority) | ||
322 | priority = at91rm9200_default_irq_priority; | ||
323 | |||
324 | /* Initialize the AIC interrupt controller */ | ||
325 | at91_aic_init(priority); | ||
326 | |||
327 | /* Enable GPIO interrupts */ | ||
328 | at91_gpio_irq_setup(); | ||
329 | } | ||
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c new file mode 100644 index 000000000000..2624a4f22d61 --- /dev/null +++ b/arch/arm/mach-at91/at91rm9200_devices.c | |||
@@ -0,0 +1,879 @@ | |||
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(short mmc_id, 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(short mmc_id, 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 | /* Enable GPIO to access the LEDs */ | ||
598 | at91_set_gpio_output(cpu_led, 1); | ||
599 | at91_set_gpio_output(timer_led, 1); | ||
600 | |||
601 | at91_leds_cpu = cpu_led; | ||
602 | at91_leds_timer = timer_led; | ||
603 | } | ||
604 | #else | ||
605 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | ||
606 | #endif | ||
607 | |||
608 | |||
609 | /* -------------------------------------------------------------------- | ||
610 | * UART | ||
611 | * -------------------------------------------------------------------- */ | ||
612 | |||
613 | #if defined(CONFIG_SERIAL_ATMEL) | ||
614 | static struct resource dbgu_resources[] = { | ||
615 | [0] = { | ||
616 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | ||
617 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | ||
618 | .flags = IORESOURCE_MEM, | ||
619 | }, | ||
620 | [1] = { | ||
621 | .start = AT91_ID_SYS, | ||
622 | .end = AT91_ID_SYS, | ||
623 | .flags = IORESOURCE_IRQ, | ||
624 | }, | ||
625 | }; | ||
626 | |||
627 | static struct atmel_uart_data dbgu_data = { | ||
628 | .use_dma_tx = 0, | ||
629 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | ||
630 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | ||
631 | }; | ||
632 | |||
633 | static struct platform_device at91rm9200_dbgu_device = { | ||
634 | .name = "atmel_usart", | ||
635 | .id = 0, | ||
636 | .dev = { | ||
637 | .platform_data = &dbgu_data, | ||
638 | .coherent_dma_mask = 0xffffffff, | ||
639 | }, | ||
640 | .resource = dbgu_resources, | ||
641 | .num_resources = ARRAY_SIZE(dbgu_resources), | ||
642 | }; | ||
643 | |||
644 | static inline void configure_dbgu_pins(void) | ||
645 | { | ||
646 | at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */ | ||
647 | at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */ | ||
648 | } | ||
649 | |||
650 | static struct resource uart0_resources[] = { | ||
651 | [0] = { | ||
652 | .start = AT91RM9200_BASE_US0, | ||
653 | .end = AT91RM9200_BASE_US0 + SZ_16K - 1, | ||
654 | .flags = IORESOURCE_MEM, | ||
655 | }, | ||
656 | [1] = { | ||
657 | .start = AT91RM9200_ID_US0, | ||
658 | .end = AT91RM9200_ID_US0, | ||
659 | .flags = IORESOURCE_IRQ, | ||
660 | }, | ||
661 | }; | ||
662 | |||
663 | static struct atmel_uart_data uart0_data = { | ||
664 | .use_dma_tx = 1, | ||
665 | .use_dma_rx = 1, | ||
666 | }; | ||
667 | |||
668 | static struct platform_device at91rm9200_uart0_device = { | ||
669 | .name = "atmel_usart", | ||
670 | .id = 1, | ||
671 | .dev = { | ||
672 | .platform_data = &uart0_data, | ||
673 | .coherent_dma_mask = 0xffffffff, | ||
674 | }, | ||
675 | .resource = uart0_resources, | ||
676 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
677 | }; | ||
678 | |||
679 | static inline void configure_usart0_pins(void) | ||
680 | { | ||
681 | at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ | ||
682 | at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ | ||
683 | at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ | ||
684 | |||
685 | /* | ||
686 | * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. | ||
687 | * We need to drive the pin manually. Default is off (RTS is active low). | ||
688 | */ | ||
689 | at91_set_gpio_output(AT91_PIN_PA21, 1); | ||
690 | } | ||
691 | |||
692 | static struct resource uart1_resources[] = { | ||
693 | [0] = { | ||
694 | .start = AT91RM9200_BASE_US1, | ||
695 | .end = AT91RM9200_BASE_US1 + SZ_16K - 1, | ||
696 | .flags = IORESOURCE_MEM, | ||
697 | }, | ||
698 | [1] = { | ||
699 | .start = AT91RM9200_ID_US1, | ||
700 | .end = AT91RM9200_ID_US1, | ||
701 | .flags = IORESOURCE_IRQ, | ||
702 | }, | ||
703 | }; | ||
704 | |||
705 | static struct atmel_uart_data uart1_data = { | ||
706 | .use_dma_tx = 1, | ||
707 | .use_dma_rx = 1, | ||
708 | }; | ||
709 | |||
710 | static struct platform_device at91rm9200_uart1_device = { | ||
711 | .name = "atmel_usart", | ||
712 | .id = 2, | ||
713 | .dev = { | ||
714 | .platform_data = &uart1_data, | ||
715 | .coherent_dma_mask = 0xffffffff, | ||
716 | }, | ||
717 | .resource = uart1_resources, | ||
718 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
719 | }; | ||
720 | |||
721 | static inline void configure_usart1_pins(void) | ||
722 | { | ||
723 | at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ | ||
724 | at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ | ||
725 | at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ | ||
726 | at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ | ||
727 | at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ | ||
728 | at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ | ||
729 | at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ | ||
730 | at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ | ||
731 | } | ||
732 | |||
733 | static struct resource uart2_resources[] = { | ||
734 | [0] = { | ||
735 | .start = AT91RM9200_BASE_US2, | ||
736 | .end = AT91RM9200_BASE_US2 + SZ_16K - 1, | ||
737 | .flags = IORESOURCE_MEM, | ||
738 | }, | ||
739 | [1] = { | ||
740 | .start = AT91RM9200_ID_US2, | ||
741 | .end = AT91RM9200_ID_US2, | ||
742 | .flags = IORESOURCE_IRQ, | ||
743 | }, | ||
744 | }; | ||
745 | |||
746 | static struct atmel_uart_data uart2_data = { | ||
747 | .use_dma_tx = 1, | ||
748 | .use_dma_rx = 1, | ||
749 | }; | ||
750 | |||
751 | static struct platform_device at91rm9200_uart2_device = { | ||
752 | .name = "atmel_usart", | ||
753 | .id = 3, | ||
754 | .dev = { | ||
755 | .platform_data = &uart2_data, | ||
756 | .coherent_dma_mask = 0xffffffff, | ||
757 | }, | ||
758 | .resource = uart2_resources, | ||
759 | .num_resources = ARRAY_SIZE(uart2_resources), | ||
760 | }; | ||
761 | |||
762 | static inline void configure_usart2_pins(void) | ||
763 | { | ||
764 | at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ | ||
765 | at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ | ||
766 | } | ||
767 | |||
768 | static struct resource uart3_resources[] = { | ||
769 | [0] = { | ||
770 | .start = AT91RM9200_BASE_US3, | ||
771 | .end = AT91RM9200_BASE_US3 + SZ_16K - 1, | ||
772 | .flags = IORESOURCE_MEM, | ||
773 | }, | ||
774 | [1] = { | ||
775 | .start = AT91RM9200_ID_US3, | ||
776 | .end = AT91RM9200_ID_US3, | ||
777 | .flags = IORESOURCE_IRQ, | ||
778 | }, | ||
779 | }; | ||
780 | |||
781 | static struct atmel_uart_data uart3_data = { | ||
782 | .use_dma_tx = 1, | ||
783 | .use_dma_rx = 1, | ||
784 | }; | ||
785 | |||
786 | static struct platform_device at91rm9200_uart3_device = { | ||
787 | .name = "atmel_usart", | ||
788 | .id = 4, | ||
789 | .dev = { | ||
790 | .platform_data = &uart3_data, | ||
791 | .coherent_dma_mask = 0xffffffff, | ||
792 | }, | ||
793 | .resource = uart3_resources, | ||
794 | .num_resources = ARRAY_SIZE(uart3_resources), | ||
795 | }; | ||
796 | |||
797 | static inline void configure_usart3_pins(void) | ||
798 | { | ||
799 | at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ | ||
800 | at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ | ||
801 | } | ||
802 | |||
803 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | ||
804 | struct platform_device *atmel_default_console_device; /* the serial console device */ | ||
805 | |||
806 | void __init at91_init_serial(struct at91_uart_config *config) | ||
807 | { | ||
808 | int i; | ||
809 | |||
810 | /* Fill in list of supported UARTs */ | ||
811 | for (i = 0; i < config->nr_tty; i++) { | ||
812 | switch (config->tty_map[i]) { | ||
813 | case 0: | ||
814 | configure_usart0_pins(); | ||
815 | at91_uarts[i] = &at91rm9200_uart0_device; | ||
816 | at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart"); | ||
817 | break; | ||
818 | case 1: | ||
819 | configure_usart1_pins(); | ||
820 | at91_uarts[i] = &at91rm9200_uart1_device; | ||
821 | at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart"); | ||
822 | break; | ||
823 | case 2: | ||
824 | configure_usart2_pins(); | ||
825 | at91_uarts[i] = &at91rm9200_uart2_device; | ||
826 | at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart"); | ||
827 | break; | ||
828 | case 3: | ||
829 | configure_usart3_pins(); | ||
830 | at91_uarts[i] = &at91rm9200_uart3_device; | ||
831 | at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart"); | ||
832 | break; | ||
833 | case 4: | ||
834 | configure_dbgu_pins(); | ||
835 | at91_uarts[i] = &at91rm9200_dbgu_device; | ||
836 | at91_clock_associate("mck", &at91rm9200_dbgu_device.dev, "usart"); | ||
837 | break; | ||
838 | default: | ||
839 | continue; | ||
840 | } | ||
841 | at91_uarts[i]->id = i; /* update ID number to mapped ID */ | ||
842 | } | ||
843 | |||
844 | /* Set serial console device */ | ||
845 | if (config->console_tty < ATMEL_MAX_UART) | ||
846 | atmel_default_console_device = at91_uarts[config->console_tty]; | ||
847 | if (!atmel_default_console_device) | ||
848 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
849 | } | ||
850 | |||
851 | void __init at91_add_device_serial(void) | ||
852 | { | ||
853 | int i; | ||
854 | |||
855 | for (i = 0; i < ATMEL_MAX_UART; i++) { | ||
856 | if (at91_uarts[i]) | ||
857 | platform_device_register(at91_uarts[i]); | ||
858 | } | ||
859 | } | ||
860 | #else | ||
861 | void __init at91_init_serial(struct at91_uart_config *config) {} | ||
862 | void __init at91_add_device_serial(void) {} | ||
863 | #endif | ||
864 | |||
865 | |||
866 | /* -------------------------------------------------------------------- */ | ||
867 | |||
868 | /* | ||
869 | * These devices are always present and don't need any board-specific | ||
870 | * setup. | ||
871 | */ | ||
872 | static int __init at91_add_standard_devices(void) | ||
873 | { | ||
874 | at91_add_device_rtc(); | ||
875 | at91_add_device_watchdog(); | ||
876 | return 0; | ||
877 | } | ||
878 | |||
879 | 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..6ea41d8266cb --- /dev/null +++ b/arch/arm/mach-at91/at91sam9260.c | |||
@@ -0,0 +1,367 @@ | |||
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/cpu.h> | ||
18 | #include <asm/arch/at91sam9260.h> | ||
19 | #include <asm/arch/at91_pmc.h> | ||
20 | #include <asm/arch/at91_rstc.h> | ||
21 | |||
22 | #include "generic.h" | ||
23 | #include "clock.h" | ||
24 | |||
25 | static struct map_desc at91sam9260_io_desc[] __initdata = { | ||
26 | { | ||
27 | .virtual = AT91_VA_BASE_SYS, | ||
28 | .pfn = __phys_to_pfn(AT91_BASE_SYS), | ||
29 | .length = SZ_16K, | ||
30 | .type = MT_DEVICE, | ||
31 | } | ||
32 | }; | ||
33 | |||
34 | static struct map_desc at91sam9260_sram_desc[] __initdata = { | ||
35 | { | ||
36 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE, | ||
37 | .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE), | ||
38 | .length = AT91SAM9260_SRAM0_SIZE, | ||
39 | .type = MT_DEVICE, | ||
40 | }, { | ||
41 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE - AT91SAM9260_SRAM1_SIZE, | ||
42 | .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE), | ||
43 | .length = AT91SAM9260_SRAM1_SIZE, | ||
44 | .type = MT_DEVICE, | ||
45 | } | ||
46 | }; | ||
47 | |||
48 | static struct map_desc at91sam9xe_sram_desc[] __initdata = { | ||
49 | { | ||
50 | .pfn = __phys_to_pfn(AT91SAM9XE_SRAM_BASE), | ||
51 | .type = MT_DEVICE, | ||
52 | } | ||
53 | }; | ||
54 | |||
55 | /* -------------------------------------------------------------------- | ||
56 | * Clocks | ||
57 | * -------------------------------------------------------------------- */ | ||
58 | |||
59 | /* | ||
60 | * The peripheral clocks. | ||
61 | */ | ||
62 | static struct clk pioA_clk = { | ||
63 | .name = "pioA_clk", | ||
64 | .pmc_mask = 1 << AT91SAM9260_ID_PIOA, | ||
65 | .type = CLK_TYPE_PERIPHERAL, | ||
66 | }; | ||
67 | static struct clk pioB_clk = { | ||
68 | .name = "pioB_clk", | ||
69 | .pmc_mask = 1 << AT91SAM9260_ID_PIOB, | ||
70 | .type = CLK_TYPE_PERIPHERAL, | ||
71 | }; | ||
72 | static struct clk pioC_clk = { | ||
73 | .name = "pioC_clk", | ||
74 | .pmc_mask = 1 << AT91SAM9260_ID_PIOC, | ||
75 | .type = CLK_TYPE_PERIPHERAL, | ||
76 | }; | ||
77 | static struct clk adc_clk = { | ||
78 | .name = "adc_clk", | ||
79 | .pmc_mask = 1 << AT91SAM9260_ID_ADC, | ||
80 | .type = CLK_TYPE_PERIPHERAL, | ||
81 | }; | ||
82 | static struct clk usart0_clk = { | ||
83 | .name = "usart0_clk", | ||
84 | .pmc_mask = 1 << AT91SAM9260_ID_US0, | ||
85 | .type = CLK_TYPE_PERIPHERAL, | ||
86 | }; | ||
87 | static struct clk usart1_clk = { | ||
88 | .name = "usart1_clk", | ||
89 | .pmc_mask = 1 << AT91SAM9260_ID_US1, | ||
90 | .type = CLK_TYPE_PERIPHERAL, | ||
91 | }; | ||
92 | static struct clk usart2_clk = { | ||
93 | .name = "usart2_clk", | ||
94 | .pmc_mask = 1 << AT91SAM9260_ID_US2, | ||
95 | .type = CLK_TYPE_PERIPHERAL, | ||
96 | }; | ||
97 | static struct clk mmc_clk = { | ||
98 | .name = "mci_clk", | ||
99 | .pmc_mask = 1 << AT91SAM9260_ID_MCI, | ||
100 | .type = CLK_TYPE_PERIPHERAL, | ||
101 | }; | ||
102 | static struct clk udc_clk = { | ||
103 | .name = "udc_clk", | ||
104 | .pmc_mask = 1 << AT91SAM9260_ID_UDP, | ||
105 | .type = CLK_TYPE_PERIPHERAL, | ||
106 | }; | ||
107 | static struct clk twi_clk = { | ||
108 | .name = "twi_clk", | ||
109 | .pmc_mask = 1 << AT91SAM9260_ID_TWI, | ||
110 | .type = CLK_TYPE_PERIPHERAL, | ||
111 | }; | ||
112 | static struct clk spi0_clk = { | ||
113 | .name = "spi0_clk", | ||
114 | .pmc_mask = 1 << AT91SAM9260_ID_SPI0, | ||
115 | .type = CLK_TYPE_PERIPHERAL, | ||
116 | }; | ||
117 | static struct clk spi1_clk = { | ||
118 | .name = "spi1_clk", | ||
119 | .pmc_mask = 1 << AT91SAM9260_ID_SPI1, | ||
120 | .type = CLK_TYPE_PERIPHERAL, | ||
121 | }; | ||
122 | static struct clk tc0_clk = { | ||
123 | .name = "tc0_clk", | ||
124 | .pmc_mask = 1 << AT91SAM9260_ID_TC0, | ||
125 | .type = CLK_TYPE_PERIPHERAL, | ||
126 | }; | ||
127 | static struct clk tc1_clk = { | ||
128 | .name = "tc1_clk", | ||
129 | .pmc_mask = 1 << AT91SAM9260_ID_TC1, | ||
130 | .type = CLK_TYPE_PERIPHERAL, | ||
131 | }; | ||
132 | static struct clk tc2_clk = { | ||
133 | .name = "tc2_clk", | ||
134 | .pmc_mask = 1 << AT91SAM9260_ID_TC2, | ||
135 | .type = CLK_TYPE_PERIPHERAL, | ||
136 | }; | ||
137 | static struct clk ohci_clk = { | ||
138 | .name = "ohci_clk", | ||
139 | .pmc_mask = 1 << AT91SAM9260_ID_UHP, | ||
140 | .type = CLK_TYPE_PERIPHERAL, | ||
141 | }; | ||
142 | static struct clk macb_clk = { | ||
143 | .name = "macb_clk", | ||
144 | .pmc_mask = 1 << AT91SAM9260_ID_EMAC, | ||
145 | .type = CLK_TYPE_PERIPHERAL, | ||
146 | }; | ||
147 | static struct clk isi_clk = { | ||
148 | .name = "isi_clk", | ||
149 | .pmc_mask = 1 << AT91SAM9260_ID_ISI, | ||
150 | .type = CLK_TYPE_PERIPHERAL, | ||
151 | }; | ||
152 | static struct clk usart3_clk = { | ||
153 | .name = "usart3_clk", | ||
154 | .pmc_mask = 1 << AT91SAM9260_ID_US3, | ||
155 | .type = CLK_TYPE_PERIPHERAL, | ||
156 | }; | ||
157 | static struct clk usart4_clk = { | ||
158 | .name = "usart4_clk", | ||
159 | .pmc_mask = 1 << AT91SAM9260_ID_US4, | ||
160 | .type = CLK_TYPE_PERIPHERAL, | ||
161 | }; | ||
162 | static struct clk usart5_clk = { | ||
163 | .name = "usart5_clk", | ||
164 | .pmc_mask = 1 << AT91SAM9260_ID_US5, | ||
165 | .type = CLK_TYPE_PERIPHERAL, | ||
166 | }; | ||
167 | static struct clk tc3_clk = { | ||
168 | .name = "tc3_clk", | ||
169 | .pmc_mask = 1 << AT91SAM9260_ID_TC3, | ||
170 | .type = CLK_TYPE_PERIPHERAL, | ||
171 | }; | ||
172 | static struct clk tc4_clk = { | ||
173 | .name = "tc4_clk", | ||
174 | .pmc_mask = 1 << AT91SAM9260_ID_TC4, | ||
175 | .type = CLK_TYPE_PERIPHERAL, | ||
176 | }; | ||
177 | static struct clk tc5_clk = { | ||
178 | .name = "tc5_clk", | ||
179 | .pmc_mask = 1 << AT91SAM9260_ID_TC5, | ||
180 | .type = CLK_TYPE_PERIPHERAL, | ||
181 | }; | ||
182 | |||
183 | static struct clk *periph_clocks[] __initdata = { | ||
184 | &pioA_clk, | ||
185 | &pioB_clk, | ||
186 | &pioC_clk, | ||
187 | &adc_clk, | ||
188 | &usart0_clk, | ||
189 | &usart1_clk, | ||
190 | &usart2_clk, | ||
191 | &mmc_clk, | ||
192 | &udc_clk, | ||
193 | &twi_clk, | ||
194 | &spi0_clk, | ||
195 | &spi1_clk, | ||
196 | // ssc | ||
197 | &tc0_clk, | ||
198 | &tc1_clk, | ||
199 | &tc2_clk, | ||
200 | &ohci_clk, | ||
201 | &macb_clk, | ||
202 | &isi_clk, | ||
203 | &usart3_clk, | ||
204 | &usart4_clk, | ||
205 | &usart5_clk, | ||
206 | &tc3_clk, | ||
207 | &tc4_clk, | ||
208 | &tc5_clk, | ||
209 | // irq0 .. irq2 | ||
210 | }; | ||
211 | |||
212 | /* | ||
213 | * The two programmable clocks. | ||
214 | * You must configure pin multiplexing to bring these signals out. | ||
215 | */ | ||
216 | static struct clk pck0 = { | ||
217 | .name = "pck0", | ||
218 | .pmc_mask = AT91_PMC_PCK0, | ||
219 | .type = CLK_TYPE_PROGRAMMABLE, | ||
220 | .id = 0, | ||
221 | }; | ||
222 | static struct clk pck1 = { | ||
223 | .name = "pck1", | ||
224 | .pmc_mask = AT91_PMC_PCK1, | ||
225 | .type = CLK_TYPE_PROGRAMMABLE, | ||
226 | .id = 1, | ||
227 | }; | ||
228 | |||
229 | static void __init at91sam9260_register_clocks(void) | ||
230 | { | ||
231 | int i; | ||
232 | |||
233 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
234 | clk_register(periph_clocks[i]); | ||
235 | |||
236 | clk_register(&pck0); | ||
237 | clk_register(&pck1); | ||
238 | } | ||
239 | |||
240 | /* -------------------------------------------------------------------- | ||
241 | * GPIO | ||
242 | * -------------------------------------------------------------------- */ | ||
243 | |||
244 | static struct at91_gpio_bank at91sam9260_gpio[] = { | ||
245 | { | ||
246 | .id = AT91SAM9260_ID_PIOA, | ||
247 | .offset = AT91_PIOA, | ||
248 | .clock = &pioA_clk, | ||
249 | }, { | ||
250 | .id = AT91SAM9260_ID_PIOB, | ||
251 | .offset = AT91_PIOB, | ||
252 | .clock = &pioB_clk, | ||
253 | }, { | ||
254 | .id = AT91SAM9260_ID_PIOC, | ||
255 | .offset = AT91_PIOC, | ||
256 | .clock = &pioC_clk, | ||
257 | } | ||
258 | }; | ||
259 | |||
260 | static void at91sam9260_reset(void) | ||
261 | { | ||
262 | at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); | ||
263 | } | ||
264 | |||
265 | |||
266 | /* -------------------------------------------------------------------- | ||
267 | * AT91SAM9260 processor initialization | ||
268 | * -------------------------------------------------------------------- */ | ||
269 | |||
270 | static void __init at91sam9xe_initialize(void) | ||
271 | { | ||
272 | unsigned long cidr, sram_size; | ||
273 | |||
274 | cidr = at91_sys_read(AT91_DBGU_CIDR); | ||
275 | |||
276 | switch (cidr & AT91_CIDR_SRAMSIZ) { | ||
277 | case AT91_CIDR_SRAMSIZ_32K: | ||
278 | sram_size = 2 * SZ_16K; | ||
279 | break; | ||
280 | case AT91_CIDR_SRAMSIZ_16K: | ||
281 | default: | ||
282 | sram_size = SZ_16K; | ||
283 | } | ||
284 | |||
285 | at91sam9xe_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size; | ||
286 | at91sam9xe_sram_desc->length = sram_size; | ||
287 | |||
288 | iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc)); | ||
289 | } | ||
290 | |||
291 | void __init at91sam9260_initialize(unsigned long main_clock) | ||
292 | { | ||
293 | /* Map peripherals */ | ||
294 | iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); | ||
295 | |||
296 | if (cpu_is_at91sam9xe()) | ||
297 | at91sam9xe_initialize(); | ||
298 | else | ||
299 | iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc)); | ||
300 | |||
301 | at91_arch_reset = at91sam9260_reset; | ||
302 | at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) | ||
303 | | (1 << AT91SAM9260_ID_IRQ2); | ||
304 | |||
305 | /* Init clock subsystem */ | ||
306 | at91_clock_init(main_clock); | ||
307 | |||
308 | /* Register the processor-specific clocks */ | ||
309 | at91sam9260_register_clocks(); | ||
310 | |||
311 | /* Register GPIO subsystem */ | ||
312 | at91_gpio_init(at91sam9260_gpio, 3); | ||
313 | } | ||
314 | |||
315 | /* -------------------------------------------------------------------- | ||
316 | * Interrupt initialization | ||
317 | * -------------------------------------------------------------------- */ | ||
318 | |||
319 | /* | ||
320 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
321 | */ | ||
322 | static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
323 | 7, /* Advanced Interrupt Controller */ | ||
324 | 7, /* System Peripherals */ | ||
325 | 0, /* Parallel IO Controller A */ | ||
326 | 0, /* Parallel IO Controller B */ | ||
327 | 0, /* Parallel IO Controller C */ | ||
328 | 0, /* Analog-to-Digital Converter */ | ||
329 | 6, /* USART 0 */ | ||
330 | 6, /* USART 1 */ | ||
331 | 6, /* USART 2 */ | ||
332 | 0, /* Multimedia Card Interface */ | ||
333 | 4, /* USB Device Port */ | ||
334 | 0, /* Two-Wire Interface */ | ||
335 | 6, /* Serial Peripheral Interface 0 */ | ||
336 | 6, /* Serial Peripheral Interface 1 */ | ||
337 | 5, /* Serial Synchronous Controller */ | ||
338 | 0, | ||
339 | 0, | ||
340 | 0, /* Timer Counter 0 */ | ||
341 | 0, /* Timer Counter 1 */ | ||
342 | 0, /* Timer Counter 2 */ | ||
343 | 3, /* USB Host port */ | ||
344 | 3, /* Ethernet */ | ||
345 | 0, /* Image Sensor Interface */ | ||
346 | 6, /* USART 3 */ | ||
347 | 6, /* USART 4 */ | ||
348 | 6, /* USART 5 */ | ||
349 | 0, /* Timer Counter 3 */ | ||
350 | 0, /* Timer Counter 4 */ | ||
351 | 0, /* Timer Counter 5 */ | ||
352 | 0, /* Advanced Interrupt Controller */ | ||
353 | 0, /* Advanced Interrupt Controller */ | ||
354 | 0, /* Advanced Interrupt Controller */ | ||
355 | }; | ||
356 | |||
357 | void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | ||
358 | { | ||
359 | if (!priority) | ||
360 | priority = at91sam9260_default_irq_priority; | ||
361 | |||
362 | /* Initialize the AIC interrupt controller */ | ||
363 | at91_aic_init(priority); | ||
364 | |||
365 | /* Enable GPIO interrupts */ | ||
366 | at91_gpio_irq_setup(); | ||
367 | } | ||
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c new file mode 100644 index 000000000000..f7d342ccbebf --- /dev/null +++ b/arch/arm/mach-at91/at91sam9260_devices.c | |||
@@ -0,0 +1,871 @@ | |||
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(short mmc_id, 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(short mmc_id, 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 | /* Enable GPIO to access the LEDs */ | ||
519 | at91_set_gpio_output(cpu_led, 1); | ||
520 | at91_set_gpio_output(timer_led, 1); | ||
521 | |||
522 | at91_leds_cpu = cpu_led; | ||
523 | at91_leds_timer = timer_led; | ||
524 | } | ||
525 | #else | ||
526 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | ||
527 | #endif | ||
528 | |||
529 | |||
530 | /* -------------------------------------------------------------------- | ||
531 | * UART | ||
532 | * -------------------------------------------------------------------- */ | ||
533 | #if defined(CONFIG_SERIAL_ATMEL) | ||
534 | static struct resource dbgu_resources[] = { | ||
535 | [0] = { | ||
536 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | ||
537 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | ||
538 | .flags = IORESOURCE_MEM, | ||
539 | }, | ||
540 | [1] = { | ||
541 | .start = AT91_ID_SYS, | ||
542 | .end = AT91_ID_SYS, | ||
543 | .flags = IORESOURCE_IRQ, | ||
544 | }, | ||
545 | }; | ||
546 | |||
547 | static struct atmel_uart_data dbgu_data = { | ||
548 | .use_dma_tx = 0, | ||
549 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | ||
550 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | ||
551 | }; | ||
552 | |||
553 | static struct platform_device at91sam9260_dbgu_device = { | ||
554 | .name = "atmel_usart", | ||
555 | .id = 0, | ||
556 | .dev = { | ||
557 | .platform_data = &dbgu_data, | ||
558 | .coherent_dma_mask = 0xffffffff, | ||
559 | }, | ||
560 | .resource = dbgu_resources, | ||
561 | .num_resources = ARRAY_SIZE(dbgu_resources), | ||
562 | }; | ||
563 | |||
564 | static inline void configure_dbgu_pins(void) | ||
565 | { | ||
566 | at91_set_A_periph(AT91_PIN_PB14, 0); /* DRXD */ | ||
567 | at91_set_A_periph(AT91_PIN_PB15, 1); /* DTXD */ | ||
568 | } | ||
569 | |||
570 | static struct resource uart0_resources[] = { | ||
571 | [0] = { | ||
572 | .start = AT91SAM9260_BASE_US0, | ||
573 | .end = AT91SAM9260_BASE_US0 + SZ_16K - 1, | ||
574 | .flags = IORESOURCE_MEM, | ||
575 | }, | ||
576 | [1] = { | ||
577 | .start = AT91SAM9260_ID_US0, | ||
578 | .end = AT91SAM9260_ID_US0, | ||
579 | .flags = IORESOURCE_IRQ, | ||
580 | }, | ||
581 | }; | ||
582 | |||
583 | static struct atmel_uart_data uart0_data = { | ||
584 | .use_dma_tx = 1, | ||
585 | .use_dma_rx = 1, | ||
586 | }; | ||
587 | |||
588 | static struct platform_device at91sam9260_uart0_device = { | ||
589 | .name = "atmel_usart", | ||
590 | .id = 1, | ||
591 | .dev = { | ||
592 | .platform_data = &uart0_data, | ||
593 | .coherent_dma_mask = 0xffffffff, | ||
594 | }, | ||
595 | .resource = uart0_resources, | ||
596 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
597 | }; | ||
598 | |||
599 | static inline void configure_usart0_pins(void) | ||
600 | { | ||
601 | at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */ | ||
602 | at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */ | ||
603 | at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */ | ||
604 | at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */ | ||
605 | at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */ | ||
606 | at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */ | ||
607 | at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */ | ||
608 | at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */ | ||
609 | } | ||
610 | |||
611 | static struct resource uart1_resources[] = { | ||
612 | [0] = { | ||
613 | .start = AT91SAM9260_BASE_US1, | ||
614 | .end = AT91SAM9260_BASE_US1 + SZ_16K - 1, | ||
615 | .flags = IORESOURCE_MEM, | ||
616 | }, | ||
617 | [1] = { | ||
618 | .start = AT91SAM9260_ID_US1, | ||
619 | .end = AT91SAM9260_ID_US1, | ||
620 | .flags = IORESOURCE_IRQ, | ||
621 | }, | ||
622 | }; | ||
623 | |||
624 | static struct atmel_uart_data uart1_data = { | ||
625 | .use_dma_tx = 1, | ||
626 | .use_dma_rx = 1, | ||
627 | }; | ||
628 | |||
629 | static struct platform_device at91sam9260_uart1_device = { | ||
630 | .name = "atmel_usart", | ||
631 | .id = 2, | ||
632 | .dev = { | ||
633 | .platform_data = &uart1_data, | ||
634 | .coherent_dma_mask = 0xffffffff, | ||
635 | }, | ||
636 | .resource = uart1_resources, | ||
637 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
638 | }; | ||
639 | |||
640 | static inline void configure_usart1_pins(void) | ||
641 | { | ||
642 | at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */ | ||
643 | at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */ | ||
644 | at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */ | ||
645 | at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */ | ||
646 | } | ||
647 | |||
648 | static struct resource uart2_resources[] = { | ||
649 | [0] = { | ||
650 | .start = AT91SAM9260_BASE_US2, | ||
651 | .end = AT91SAM9260_BASE_US2 + SZ_16K - 1, | ||
652 | .flags = IORESOURCE_MEM, | ||
653 | }, | ||
654 | [1] = { | ||
655 | .start = AT91SAM9260_ID_US2, | ||
656 | .end = AT91SAM9260_ID_US2, | ||
657 | .flags = IORESOURCE_IRQ, | ||
658 | }, | ||
659 | }; | ||
660 | |||
661 | static struct atmel_uart_data uart2_data = { | ||
662 | .use_dma_tx = 1, | ||
663 | .use_dma_rx = 1, | ||
664 | }; | ||
665 | |||
666 | static struct platform_device at91sam9260_uart2_device = { | ||
667 | .name = "atmel_usart", | ||
668 | .id = 3, | ||
669 | .dev = { | ||
670 | .platform_data = &uart2_data, | ||
671 | .coherent_dma_mask = 0xffffffff, | ||
672 | }, | ||
673 | .resource = uart2_resources, | ||
674 | .num_resources = ARRAY_SIZE(uart2_resources), | ||
675 | }; | ||
676 | |||
677 | static inline void configure_usart2_pins(void) | ||
678 | { | ||
679 | at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */ | ||
680 | at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */ | ||
681 | } | ||
682 | |||
683 | static struct resource uart3_resources[] = { | ||
684 | [0] = { | ||
685 | .start = AT91SAM9260_BASE_US3, | ||
686 | .end = AT91SAM9260_BASE_US3 + SZ_16K - 1, | ||
687 | .flags = IORESOURCE_MEM, | ||
688 | }, | ||
689 | [1] = { | ||
690 | .start = AT91SAM9260_ID_US3, | ||
691 | .end = AT91SAM9260_ID_US3, | ||
692 | .flags = IORESOURCE_IRQ, | ||
693 | }, | ||
694 | }; | ||
695 | |||
696 | static struct atmel_uart_data uart3_data = { | ||
697 | .use_dma_tx = 1, | ||
698 | .use_dma_rx = 1, | ||
699 | }; | ||
700 | |||
701 | static struct platform_device at91sam9260_uart3_device = { | ||
702 | .name = "atmel_usart", | ||
703 | .id = 4, | ||
704 | .dev = { | ||
705 | .platform_data = &uart3_data, | ||
706 | .coherent_dma_mask = 0xffffffff, | ||
707 | }, | ||
708 | .resource = uart3_resources, | ||
709 | .num_resources = ARRAY_SIZE(uart3_resources), | ||
710 | }; | ||
711 | |||
712 | static inline void configure_usart3_pins(void) | ||
713 | { | ||
714 | at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */ | ||
715 | at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */ | ||
716 | } | ||
717 | |||
718 | static struct resource uart4_resources[] = { | ||
719 | [0] = { | ||
720 | .start = AT91SAM9260_BASE_US4, | ||
721 | .end = AT91SAM9260_BASE_US4 + SZ_16K - 1, | ||
722 | .flags = IORESOURCE_MEM, | ||
723 | }, | ||
724 | [1] = { | ||
725 | .start = AT91SAM9260_ID_US4, | ||
726 | .end = AT91SAM9260_ID_US4, | ||
727 | .flags = IORESOURCE_IRQ, | ||
728 | }, | ||
729 | }; | ||
730 | |||
731 | static struct atmel_uart_data uart4_data = { | ||
732 | .use_dma_tx = 1, | ||
733 | .use_dma_rx = 1, | ||
734 | }; | ||
735 | |||
736 | static struct platform_device at91sam9260_uart4_device = { | ||
737 | .name = "atmel_usart", | ||
738 | .id = 5, | ||
739 | .dev = { | ||
740 | .platform_data = &uart4_data, | ||
741 | .coherent_dma_mask = 0xffffffff, | ||
742 | }, | ||
743 | .resource = uart4_resources, | ||
744 | .num_resources = ARRAY_SIZE(uart4_resources), | ||
745 | }; | ||
746 | |||
747 | static inline void configure_usart4_pins(void) | ||
748 | { | ||
749 | at91_set_B_periph(AT91_PIN_PA31, 1); /* TXD4 */ | ||
750 | at91_set_B_periph(AT91_PIN_PA30, 0); /* RXD4 */ | ||
751 | } | ||
752 | |||
753 | static struct resource uart5_resources[] = { | ||
754 | [0] = { | ||
755 | .start = AT91SAM9260_BASE_US5, | ||
756 | .end = AT91SAM9260_BASE_US5 + SZ_16K - 1, | ||
757 | .flags = IORESOURCE_MEM, | ||
758 | }, | ||
759 | [1] = { | ||
760 | .start = AT91SAM9260_ID_US5, | ||
761 | .end = AT91SAM9260_ID_US5, | ||
762 | .flags = IORESOURCE_IRQ, | ||
763 | }, | ||
764 | }; | ||
765 | |||
766 | static struct atmel_uart_data uart5_data = { | ||
767 | .use_dma_tx = 1, | ||
768 | .use_dma_rx = 1, | ||
769 | }; | ||
770 | |||
771 | static struct platform_device at91sam9260_uart5_device = { | ||
772 | .name = "atmel_usart", | ||
773 | .id = 6, | ||
774 | .dev = { | ||
775 | .platform_data = &uart5_data, | ||
776 | .coherent_dma_mask = 0xffffffff, | ||
777 | }, | ||
778 | .resource = uart5_resources, | ||
779 | .num_resources = ARRAY_SIZE(uart5_resources), | ||
780 | }; | ||
781 | |||
782 | static inline void configure_usart5_pins(void) | ||
783 | { | ||
784 | at91_set_A_periph(AT91_PIN_PB12, 1); /* TXD5 */ | ||
785 | at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */ | ||
786 | } | ||
787 | |||
788 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | ||
789 | struct platform_device *atmel_default_console_device; /* the serial console device */ | ||
790 | |||
791 | void __init at91_init_serial(struct at91_uart_config *config) | ||
792 | { | ||
793 | int i; | ||
794 | |||
795 | /* Fill in list of supported UARTs */ | ||
796 | for (i = 0; i < config->nr_tty; i++) { | ||
797 | switch (config->tty_map[i]) { | ||
798 | case 0: | ||
799 | configure_usart0_pins(); | ||
800 | at91_uarts[i] = &at91sam9260_uart0_device; | ||
801 | at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart"); | ||
802 | break; | ||
803 | case 1: | ||
804 | configure_usart1_pins(); | ||
805 | at91_uarts[i] = &at91sam9260_uart1_device; | ||
806 | at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart"); | ||
807 | break; | ||
808 | case 2: | ||
809 | configure_usart2_pins(); | ||
810 | at91_uarts[i] = &at91sam9260_uart2_device; | ||
811 | at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart"); | ||
812 | break; | ||
813 | case 3: | ||
814 | configure_usart3_pins(); | ||
815 | at91_uarts[i] = &at91sam9260_uart3_device; | ||
816 | at91_clock_associate("usart3_clk", &at91sam9260_uart3_device.dev, "usart"); | ||
817 | break; | ||
818 | case 4: | ||
819 | configure_usart4_pins(); | ||
820 | at91_uarts[i] = &at91sam9260_uart4_device; | ||
821 | at91_clock_associate("usart4_clk", &at91sam9260_uart4_device.dev, "usart"); | ||
822 | break; | ||
823 | case 5: | ||
824 | configure_usart5_pins(); | ||
825 | at91_uarts[i] = &at91sam9260_uart5_device; | ||
826 | at91_clock_associate("usart5_clk", &at91sam9260_uart5_device.dev, "usart"); | ||
827 | break; | ||
828 | case 6: | ||
829 | configure_dbgu_pins(); | ||
830 | at91_uarts[i] = &at91sam9260_dbgu_device; | ||
831 | at91_clock_associate("mck", &at91sam9260_dbgu_device.dev, "usart"); | ||
832 | break; | ||
833 | default: | ||
834 | continue; | ||
835 | } | ||
836 | at91_uarts[i]->id = i; /* update ID number to mapped ID */ | ||
837 | } | ||
838 | |||
839 | /* Set serial console device */ | ||
840 | if (config->console_tty < ATMEL_MAX_UART) | ||
841 | atmel_default_console_device = at91_uarts[config->console_tty]; | ||
842 | if (!atmel_default_console_device) | ||
843 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
844 | } | ||
845 | |||
846 | void __init at91_add_device_serial(void) | ||
847 | { | ||
848 | int i; | ||
849 | |||
850 | for (i = 0; i < ATMEL_MAX_UART; i++) { | ||
851 | if (at91_uarts[i]) | ||
852 | platform_device_register(at91_uarts[i]); | ||
853 | } | ||
854 | } | ||
855 | #else | ||
856 | void __init at91_init_serial(struct at91_uart_config *config) {} | ||
857 | void __init at91_add_device_serial(void) {} | ||
858 | #endif | ||
859 | |||
860 | |||
861 | /* -------------------------------------------------------------------- */ | ||
862 | /* | ||
863 | * These devices are always present and don't need any board-specific | ||
864 | * setup. | ||
865 | */ | ||
866 | static int __init at91_add_standard_devices(void) | ||
867 | { | ||
868 | return 0; | ||
869 | } | ||
870 | |||
871 | 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..784d1e682d6d --- /dev/null +++ b/arch/arm/mach-at91/at91sam9261.c | |||
@@ -0,0 +1,307 @@ | |||
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 tc0_clk = { | ||
101 | .name = "tc0_clk", | ||
102 | .pmc_mask = 1 << AT91SAM9261_ID_TC0, | ||
103 | .type = CLK_TYPE_PERIPHERAL, | ||
104 | }; | ||
105 | static struct clk tc1_clk = { | ||
106 | .name = "tc1_clk", | ||
107 | .pmc_mask = 1 << AT91SAM9261_ID_TC1, | ||
108 | .type = CLK_TYPE_PERIPHERAL, | ||
109 | }; | ||
110 | static struct clk tc2_clk = { | ||
111 | .name = "tc2_clk", | ||
112 | .pmc_mask = 1 << AT91SAM9261_ID_TC2, | ||
113 | .type = CLK_TYPE_PERIPHERAL, | ||
114 | }; | ||
115 | static struct clk ohci_clk = { | ||
116 | .name = "ohci_clk", | ||
117 | .pmc_mask = 1 << AT91SAM9261_ID_UHP, | ||
118 | .type = CLK_TYPE_PERIPHERAL, | ||
119 | }; | ||
120 | static struct clk lcdc_clk = { | ||
121 | .name = "lcdc_clk", | ||
122 | .pmc_mask = 1 << AT91SAM9261_ID_LCDC, | ||
123 | .type = CLK_TYPE_PERIPHERAL, | ||
124 | }; | ||
125 | |||
126 | static struct clk *periph_clocks[] __initdata = { | ||
127 | &pioA_clk, | ||
128 | &pioB_clk, | ||
129 | &pioC_clk, | ||
130 | &usart0_clk, | ||
131 | &usart1_clk, | ||
132 | &usart2_clk, | ||
133 | &mmc_clk, | ||
134 | &udc_clk, | ||
135 | &twi_clk, | ||
136 | &spi0_clk, | ||
137 | &spi1_clk, | ||
138 | // ssc 0 .. ssc2 | ||
139 | &tc0_clk, | ||
140 | &tc1_clk, | ||
141 | &tc2_clk, | ||
142 | &ohci_clk, | ||
143 | &lcdc_clk, | ||
144 | // irq0 .. irq2 | ||
145 | }; | ||
146 | |||
147 | /* | ||
148 | * The four programmable clocks. | ||
149 | * You must configure pin multiplexing to bring these signals out. | ||
150 | */ | ||
151 | static struct clk pck0 = { | ||
152 | .name = "pck0", | ||
153 | .pmc_mask = AT91_PMC_PCK0, | ||
154 | .type = CLK_TYPE_PROGRAMMABLE, | ||
155 | .id = 0, | ||
156 | }; | ||
157 | static struct clk pck1 = { | ||
158 | .name = "pck1", | ||
159 | .pmc_mask = AT91_PMC_PCK1, | ||
160 | .type = CLK_TYPE_PROGRAMMABLE, | ||
161 | .id = 1, | ||
162 | }; | ||
163 | static struct clk pck2 = { | ||
164 | .name = "pck2", | ||
165 | .pmc_mask = AT91_PMC_PCK2, | ||
166 | .type = CLK_TYPE_PROGRAMMABLE, | ||
167 | .id = 2, | ||
168 | }; | ||
169 | static struct clk pck3 = { | ||
170 | .name = "pck3", | ||
171 | .pmc_mask = AT91_PMC_PCK3, | ||
172 | .type = CLK_TYPE_PROGRAMMABLE, | ||
173 | .id = 3, | ||
174 | }; | ||
175 | |||
176 | /* HClocks */ | ||
177 | static struct clk hck0 = { | ||
178 | .name = "hck0", | ||
179 | .pmc_mask = AT91_PMC_HCK0, | ||
180 | .type = CLK_TYPE_SYSTEM, | ||
181 | .id = 0, | ||
182 | }; | ||
183 | static struct clk hck1 = { | ||
184 | .name = "hck1", | ||
185 | .pmc_mask = AT91_PMC_HCK1, | ||
186 | .type = CLK_TYPE_SYSTEM, | ||
187 | .id = 1, | ||
188 | }; | ||
189 | |||
190 | static void __init at91sam9261_register_clocks(void) | ||
191 | { | ||
192 | int i; | ||
193 | |||
194 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
195 | clk_register(periph_clocks[i]); | ||
196 | |||
197 | clk_register(&pck0); | ||
198 | clk_register(&pck1); | ||
199 | clk_register(&pck2); | ||
200 | clk_register(&pck3); | ||
201 | |||
202 | clk_register(&hck0); | ||
203 | clk_register(&hck1); | ||
204 | } | ||
205 | |||
206 | /* -------------------------------------------------------------------- | ||
207 | * GPIO | ||
208 | * -------------------------------------------------------------------- */ | ||
209 | |||
210 | static struct at91_gpio_bank at91sam9261_gpio[] = { | ||
211 | { | ||
212 | .id = AT91SAM9261_ID_PIOA, | ||
213 | .offset = AT91_PIOA, | ||
214 | .clock = &pioA_clk, | ||
215 | }, { | ||
216 | .id = AT91SAM9261_ID_PIOB, | ||
217 | .offset = AT91_PIOB, | ||
218 | .clock = &pioB_clk, | ||
219 | }, { | ||
220 | .id = AT91SAM9261_ID_PIOC, | ||
221 | .offset = AT91_PIOC, | ||
222 | .clock = &pioC_clk, | ||
223 | } | ||
224 | }; | ||
225 | |||
226 | static void at91sam9261_reset(void) | ||
227 | { | ||
228 | at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); | ||
229 | } | ||
230 | |||
231 | |||
232 | /* -------------------------------------------------------------------- | ||
233 | * AT91SAM9261 processor initialization | ||
234 | * -------------------------------------------------------------------- */ | ||
235 | |||
236 | void __init at91sam9261_initialize(unsigned long main_clock) | ||
237 | { | ||
238 | /* Map peripherals */ | ||
239 | iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); | ||
240 | |||
241 | at91_arch_reset = at91sam9261_reset; | ||
242 | at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) | ||
243 | | (1 << AT91SAM9261_ID_IRQ2); | ||
244 | |||
245 | /* Init clock subsystem */ | ||
246 | at91_clock_init(main_clock); | ||
247 | |||
248 | /* Register the processor-specific clocks */ | ||
249 | at91sam9261_register_clocks(); | ||
250 | |||
251 | /* Register GPIO subsystem */ | ||
252 | at91_gpio_init(at91sam9261_gpio, 3); | ||
253 | } | ||
254 | |||
255 | /* -------------------------------------------------------------------- | ||
256 | * Interrupt initialization | ||
257 | * -------------------------------------------------------------------- */ | ||
258 | |||
259 | /* | ||
260 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
261 | */ | ||
262 | static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
263 | 7, /* Advanced Interrupt Controller */ | ||
264 | 7, /* System Peripherals */ | ||
265 | 0, /* Parallel IO Controller A */ | ||
266 | 0, /* Parallel IO Controller B */ | ||
267 | 0, /* Parallel IO Controller C */ | ||
268 | 0, | ||
269 | 6, /* USART 0 */ | ||
270 | 6, /* USART 1 */ | ||
271 | 6, /* USART 2 */ | ||
272 | 0, /* Multimedia Card Interface */ | ||
273 | 4, /* USB Device Port */ | ||
274 | 0, /* Two-Wire Interface */ | ||
275 | 6, /* Serial Peripheral Interface 0 */ | ||
276 | 6, /* Serial Peripheral Interface 1 */ | ||
277 | 5, /* Serial Synchronous Controller 0 */ | ||
278 | 5, /* Serial Synchronous Controller 1 */ | ||
279 | 5, /* Serial Synchronous Controller 2 */ | ||
280 | 0, /* Timer Counter 0 */ | ||
281 | 0, /* Timer Counter 1 */ | ||
282 | 0, /* Timer Counter 2 */ | ||
283 | 3, /* USB Host port */ | ||
284 | 3, /* LCD Controller */ | ||
285 | 0, | ||
286 | 0, | ||
287 | 0, | ||
288 | 0, | ||
289 | 0, | ||
290 | 0, | ||
291 | 0, | ||
292 | 0, /* Advanced Interrupt Controller */ | ||
293 | 0, /* Advanced Interrupt Controller */ | ||
294 | 0, /* Advanced Interrupt Controller */ | ||
295 | }; | ||
296 | |||
297 | void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | ||
298 | { | ||
299 | if (!priority) | ||
300 | priority = at91sam9261_default_irq_priority; | ||
301 | |||
302 | /* Initialize the AIC interrupt controller */ | ||
303 | at91_aic_init(priority); | ||
304 | |||
305 | /* Enable GPIO interrupts */ | ||
306 | at91_gpio_irq_setup(); | ||
307 | } | ||
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c new file mode 100644 index 000000000000..e1504766fd64 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9261_devices.c | |||
@@ -0,0 +1,745 @@ | |||
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(short mmc_id, 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(short mmc_id, 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 | /* Enable GPIO to access the LEDs */ | ||
517 | at91_set_gpio_output(cpu_led, 1); | ||
518 | at91_set_gpio_output(timer_led, 1); | ||
519 | |||
520 | at91_leds_cpu = cpu_led; | ||
521 | at91_leds_timer = timer_led; | ||
522 | } | ||
523 | #else | ||
524 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | ||
525 | #endif | ||
526 | |||
527 | |||
528 | /* -------------------------------------------------------------------- | ||
529 | * UART | ||
530 | * -------------------------------------------------------------------- */ | ||
531 | |||
532 | #if defined(CONFIG_SERIAL_ATMEL) | ||
533 | static struct resource dbgu_resources[] = { | ||
534 | [0] = { | ||
535 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | ||
536 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | ||
537 | .flags = IORESOURCE_MEM, | ||
538 | }, | ||
539 | [1] = { | ||
540 | .start = AT91_ID_SYS, | ||
541 | .end = AT91_ID_SYS, | ||
542 | .flags = IORESOURCE_IRQ, | ||
543 | }, | ||
544 | }; | ||
545 | |||
546 | static struct atmel_uart_data dbgu_data = { | ||
547 | .use_dma_tx = 0, | ||
548 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | ||
549 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | ||
550 | }; | ||
551 | |||
552 | static struct platform_device at91sam9261_dbgu_device = { | ||
553 | .name = "atmel_usart", | ||
554 | .id = 0, | ||
555 | .dev = { | ||
556 | .platform_data = &dbgu_data, | ||
557 | .coherent_dma_mask = 0xffffffff, | ||
558 | }, | ||
559 | .resource = dbgu_resources, | ||
560 | .num_resources = ARRAY_SIZE(dbgu_resources), | ||
561 | }; | ||
562 | |||
563 | static inline void configure_dbgu_pins(void) | ||
564 | { | ||
565 | at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ | ||
566 | at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */ | ||
567 | } | ||
568 | |||
569 | static struct resource uart0_resources[] = { | ||
570 | [0] = { | ||
571 | .start = AT91SAM9261_BASE_US0, | ||
572 | .end = AT91SAM9261_BASE_US0 + SZ_16K - 1, | ||
573 | .flags = IORESOURCE_MEM, | ||
574 | }, | ||
575 | [1] = { | ||
576 | .start = AT91SAM9261_ID_US0, | ||
577 | .end = AT91SAM9261_ID_US0, | ||
578 | .flags = IORESOURCE_IRQ, | ||
579 | }, | ||
580 | }; | ||
581 | |||
582 | static struct atmel_uart_data uart0_data = { | ||
583 | .use_dma_tx = 1, | ||
584 | .use_dma_rx = 1, | ||
585 | }; | ||
586 | |||
587 | static struct platform_device at91sam9261_uart0_device = { | ||
588 | .name = "atmel_usart", | ||
589 | .id = 1, | ||
590 | .dev = { | ||
591 | .platform_data = &uart0_data, | ||
592 | .coherent_dma_mask = 0xffffffff, | ||
593 | }, | ||
594 | .resource = uart0_resources, | ||
595 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
596 | }; | ||
597 | |||
598 | static inline void configure_usart0_pins(void) | ||
599 | { | ||
600 | at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ | ||
601 | at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ | ||
602 | at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */ | ||
603 | at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */ | ||
604 | } | ||
605 | |||
606 | static struct resource uart1_resources[] = { | ||
607 | [0] = { | ||
608 | .start = AT91SAM9261_BASE_US1, | ||
609 | .end = AT91SAM9261_BASE_US1 + SZ_16K - 1, | ||
610 | .flags = IORESOURCE_MEM, | ||
611 | }, | ||
612 | [1] = { | ||
613 | .start = AT91SAM9261_ID_US1, | ||
614 | .end = AT91SAM9261_ID_US1, | ||
615 | .flags = IORESOURCE_IRQ, | ||
616 | }, | ||
617 | }; | ||
618 | |||
619 | static struct atmel_uart_data uart1_data = { | ||
620 | .use_dma_tx = 1, | ||
621 | .use_dma_rx = 1, | ||
622 | }; | ||
623 | |||
624 | static struct platform_device at91sam9261_uart1_device = { | ||
625 | .name = "atmel_usart", | ||
626 | .id = 2, | ||
627 | .dev = { | ||
628 | .platform_data = &uart1_data, | ||
629 | .coherent_dma_mask = 0xffffffff, | ||
630 | }, | ||
631 | .resource = uart1_resources, | ||
632 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
633 | }; | ||
634 | |||
635 | static inline void configure_usart1_pins(void) | ||
636 | { | ||
637 | at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ | ||
638 | at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ | ||
639 | } | ||
640 | |||
641 | static struct resource uart2_resources[] = { | ||
642 | [0] = { | ||
643 | .start = AT91SAM9261_BASE_US2, | ||
644 | .end = AT91SAM9261_BASE_US2 + SZ_16K - 1, | ||
645 | .flags = IORESOURCE_MEM, | ||
646 | }, | ||
647 | [1] = { | ||
648 | .start = AT91SAM9261_ID_US2, | ||
649 | .end = AT91SAM9261_ID_US2, | ||
650 | .flags = IORESOURCE_IRQ, | ||
651 | }, | ||
652 | }; | ||
653 | |||
654 | static struct atmel_uart_data uart2_data = { | ||
655 | .use_dma_tx = 1, | ||
656 | .use_dma_rx = 1, | ||
657 | }; | ||
658 | |||
659 | static struct platform_device at91sam9261_uart2_device = { | ||
660 | .name = "atmel_usart", | ||
661 | .id = 3, | ||
662 | .dev = { | ||
663 | .platform_data = &uart2_data, | ||
664 | .coherent_dma_mask = 0xffffffff, | ||
665 | }, | ||
666 | .resource = uart2_resources, | ||
667 | .num_resources = ARRAY_SIZE(uart2_resources), | ||
668 | }; | ||
669 | |||
670 | static inline void configure_usart2_pins(void) | ||
671 | { | ||
672 | at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ | ||
673 | at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ | ||
674 | } | ||
675 | |||
676 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | ||
677 | struct platform_device *atmel_default_console_device; /* the serial console device */ | ||
678 | |||
679 | void __init at91_init_serial(struct at91_uart_config *config) | ||
680 | { | ||
681 | int i; | ||
682 | |||
683 | /* Fill in list of supported UARTs */ | ||
684 | for (i = 0; i < config->nr_tty; i++) { | ||
685 | switch (config->tty_map[i]) { | ||
686 | case 0: | ||
687 | configure_usart0_pins(); | ||
688 | at91_uarts[i] = &at91sam9261_uart0_device; | ||
689 | at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart"); | ||
690 | break; | ||
691 | case 1: | ||
692 | configure_usart1_pins(); | ||
693 | at91_uarts[i] = &at91sam9261_uart1_device; | ||
694 | at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart"); | ||
695 | break; | ||
696 | case 2: | ||
697 | configure_usart2_pins(); | ||
698 | at91_uarts[i] = &at91sam9261_uart2_device; | ||
699 | at91_clock_associate("usart2_clk", &at91sam9261_uart2_device.dev, "usart"); | ||
700 | break; | ||
701 | case 3: | ||
702 | configure_dbgu_pins(); | ||
703 | at91_uarts[i] = &at91sam9261_dbgu_device; | ||
704 | at91_clock_associate("mck", &at91sam9261_dbgu_device.dev, "usart"); | ||
705 | break; | ||
706 | default: | ||
707 | continue; | ||
708 | } | ||
709 | at91_uarts[i]->id = i; /* update ID number to mapped ID */ | ||
710 | } | ||
711 | |||
712 | /* Set serial console device */ | ||
713 | if (config->console_tty < ATMEL_MAX_UART) | ||
714 | atmel_default_console_device = at91_uarts[config->console_tty]; | ||
715 | if (!atmel_default_console_device) | ||
716 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
717 | } | ||
718 | |||
719 | void __init at91_add_device_serial(void) | ||
720 | { | ||
721 | int i; | ||
722 | |||
723 | for (i = 0; i < ATMEL_MAX_UART; i++) { | ||
724 | if (at91_uarts[i]) | ||
725 | platform_device_register(at91_uarts[i]); | ||
726 | } | ||
727 | } | ||
728 | #else | ||
729 | void __init at91_init_serial(struct at91_uart_config *config) {} | ||
730 | void __init at91_add_device_serial(void) {} | ||
731 | #endif | ||
732 | |||
733 | |||
734 | /* -------------------------------------------------------------------- */ | ||
735 | |||
736 | /* | ||
737 | * These devices are always present and don't need any board-specific | ||
738 | * setup. | ||
739 | */ | ||
740 | static int __init at91_add_standard_devices(void) | ||
741 | { | ||
742 | return 0; | ||
743 | } | ||
744 | |||
745 | arch_initcall(at91_add_standard_devices); | ||
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c new file mode 100644 index 000000000000..6aa342e8f1b1 --- /dev/null +++ b/arch/arm/mach-at91/at91sam9263.c | |||
@@ -0,0 +1,313 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/at91sam9263.c | ||
3 | * | ||
4 | * Copyright (C) 2007 Atmel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | |||
15 | #include <asm/mach/arch.h> | ||
16 | #include <asm/mach/map.h> | ||
17 | #include <asm/arch/at91sam9263.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 at91sam9263_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 - AT91SAM9263_SRAM0_SIZE, | ||
32 | .pfn = __phys_to_pfn(AT91SAM9263_SRAM0_BASE), | ||
33 | .length = AT91SAM9263_SRAM0_SIZE, | ||
34 | .type = MT_DEVICE, | ||
35 | }, { | ||
36 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE - AT91SAM9263_SRAM1_SIZE, | ||
37 | .pfn = __phys_to_pfn(AT91SAM9263_SRAM1_BASE), | ||
38 | .length = AT91SAM9263_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 << AT91SAM9263_ID_PIOA, | ||
53 | .type = CLK_TYPE_PERIPHERAL, | ||
54 | }; | ||
55 | static struct clk pioB_clk = { | ||
56 | .name = "pioB_clk", | ||
57 | .pmc_mask = 1 << AT91SAM9263_ID_PIOB, | ||
58 | .type = CLK_TYPE_PERIPHERAL, | ||
59 | }; | ||
60 | static struct clk pioCDE_clk = { | ||
61 | .name = "pioCDE_clk", | ||
62 | .pmc_mask = 1 << AT91SAM9263_ID_PIOCDE, | ||
63 | .type = CLK_TYPE_PERIPHERAL, | ||
64 | }; | ||
65 | static struct clk usart0_clk = { | ||
66 | .name = "usart0_clk", | ||
67 | .pmc_mask = 1 << AT91SAM9263_ID_US0, | ||
68 | .type = CLK_TYPE_PERIPHERAL, | ||
69 | }; | ||
70 | static struct clk usart1_clk = { | ||
71 | .name = "usart1_clk", | ||
72 | .pmc_mask = 1 << AT91SAM9263_ID_US1, | ||
73 | .type = CLK_TYPE_PERIPHERAL, | ||
74 | }; | ||
75 | static struct clk usart2_clk = { | ||
76 | .name = "usart2_clk", | ||
77 | .pmc_mask = 1 << AT91SAM9263_ID_US2, | ||
78 | .type = CLK_TYPE_PERIPHERAL, | ||
79 | }; | ||
80 | static struct clk mmc0_clk = { | ||
81 | .name = "mci0_clk", | ||
82 | .pmc_mask = 1 << AT91SAM9263_ID_MCI0, | ||
83 | .type = CLK_TYPE_PERIPHERAL, | ||
84 | }; | ||
85 | static struct clk mmc1_clk = { | ||
86 | .name = "mci1_clk", | ||
87 | .pmc_mask = 1 << AT91SAM9263_ID_MCI1, | ||
88 | .type = CLK_TYPE_PERIPHERAL, | ||
89 | }; | ||
90 | static struct clk twi_clk = { | ||
91 | .name = "twi_clk", | ||
92 | .pmc_mask = 1 << AT91SAM9263_ID_TWI, | ||
93 | .type = CLK_TYPE_PERIPHERAL, | ||
94 | }; | ||
95 | static struct clk spi0_clk = { | ||
96 | .name = "spi0_clk", | ||
97 | .pmc_mask = 1 << AT91SAM9263_ID_SPI0, | ||
98 | .type = CLK_TYPE_PERIPHERAL, | ||
99 | }; | ||
100 | static struct clk spi1_clk = { | ||
101 | .name = "spi1_clk", | ||
102 | .pmc_mask = 1 << AT91SAM9263_ID_SPI1, | ||
103 | .type = CLK_TYPE_PERIPHERAL, | ||
104 | }; | ||
105 | static struct clk tcb_clk = { | ||
106 | .name = "tcb_clk", | ||
107 | .pmc_mask = 1 << AT91SAM9263_ID_TCB, | ||
108 | .type = CLK_TYPE_PERIPHERAL, | ||
109 | }; | ||
110 | static struct clk macb_clk = { | ||
111 | .name = "macb_clk", | ||
112 | .pmc_mask = 1 << AT91SAM9263_ID_EMAC, | ||
113 | .type = CLK_TYPE_PERIPHERAL, | ||
114 | }; | ||
115 | static struct clk udc_clk = { | ||
116 | .name = "udc_clk", | ||
117 | .pmc_mask = 1 << AT91SAM9263_ID_UDP, | ||
118 | .type = CLK_TYPE_PERIPHERAL, | ||
119 | }; | ||
120 | static struct clk isi_clk = { | ||
121 | .name = "isi_clk", | ||
122 | .pmc_mask = 1 << AT91SAM9263_ID_ISI, | ||
123 | .type = CLK_TYPE_PERIPHERAL, | ||
124 | }; | ||
125 | static struct clk lcdc_clk = { | ||
126 | .name = "lcdc_clk", | ||
127 | .pmc_mask = 1 << AT91SAM9263_ID_ISI, | ||
128 | .type = CLK_TYPE_PERIPHERAL, | ||
129 | }; | ||
130 | static struct clk ohci_clk = { | ||
131 | .name = "ohci_clk", | ||
132 | .pmc_mask = 1 << AT91SAM9263_ID_UHP, | ||
133 | .type = CLK_TYPE_PERIPHERAL, | ||
134 | }; | ||
135 | |||
136 | static struct clk *periph_clocks[] __initdata = { | ||
137 | &pioA_clk, | ||
138 | &pioB_clk, | ||
139 | &pioCDE_clk, | ||
140 | &usart0_clk, | ||
141 | &usart1_clk, | ||
142 | &usart2_clk, | ||
143 | &mmc0_clk, | ||
144 | &mmc1_clk, | ||
145 | // can | ||
146 | &twi_clk, | ||
147 | &spi0_clk, | ||
148 | &spi1_clk, | ||
149 | // ssc0 .. ssc1 | ||
150 | // ac97 | ||
151 | &tcb_clk, | ||
152 | // pwmc | ||
153 | &macb_clk, | ||
154 | // 2dge | ||
155 | &udc_clk, | ||
156 | &isi_clk, | ||
157 | &lcdc_clk, | ||
158 | // dma | ||
159 | &ohci_clk, | ||
160 | // irq0 .. irq1 | ||
161 | }; | ||
162 | |||
163 | /* | ||
164 | * The four programmable clocks. | ||
165 | * You must configure pin multiplexing to bring these signals out. | ||
166 | */ | ||
167 | static struct clk pck0 = { | ||
168 | .name = "pck0", | ||
169 | .pmc_mask = AT91_PMC_PCK0, | ||
170 | .type = CLK_TYPE_PROGRAMMABLE, | ||
171 | .id = 0, | ||
172 | }; | ||
173 | static struct clk pck1 = { | ||
174 | .name = "pck1", | ||
175 | .pmc_mask = AT91_PMC_PCK1, | ||
176 | .type = CLK_TYPE_PROGRAMMABLE, | ||
177 | .id = 1, | ||
178 | }; | ||
179 | static struct clk pck2 = { | ||
180 | .name = "pck2", | ||
181 | .pmc_mask = AT91_PMC_PCK2, | ||
182 | .type = CLK_TYPE_PROGRAMMABLE, | ||
183 | .id = 2, | ||
184 | }; | ||
185 | static struct clk pck3 = { | ||
186 | .name = "pck3", | ||
187 | .pmc_mask = AT91_PMC_PCK3, | ||
188 | .type = CLK_TYPE_PROGRAMMABLE, | ||
189 | .id = 3, | ||
190 | }; | ||
191 | |||
192 | static void __init at91sam9263_register_clocks(void) | ||
193 | { | ||
194 | int i; | ||
195 | |||
196 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
197 | clk_register(periph_clocks[i]); | ||
198 | |||
199 | clk_register(&pck0); | ||
200 | clk_register(&pck1); | ||
201 | clk_register(&pck2); | ||
202 | clk_register(&pck3); | ||
203 | } | ||
204 | |||
205 | /* -------------------------------------------------------------------- | ||
206 | * GPIO | ||
207 | * -------------------------------------------------------------------- */ | ||
208 | |||
209 | static struct at91_gpio_bank at91sam9263_gpio[] = { | ||
210 | { | ||
211 | .id = AT91SAM9263_ID_PIOA, | ||
212 | .offset = AT91_PIOA, | ||
213 | .clock = &pioA_clk, | ||
214 | }, { | ||
215 | .id = AT91SAM9263_ID_PIOB, | ||
216 | .offset = AT91_PIOB, | ||
217 | .clock = &pioB_clk, | ||
218 | }, { | ||
219 | .id = AT91SAM9263_ID_PIOCDE, | ||
220 | .offset = AT91_PIOC, | ||
221 | .clock = &pioCDE_clk, | ||
222 | }, { | ||
223 | .id = AT91SAM9263_ID_PIOCDE, | ||
224 | .offset = AT91_PIOD, | ||
225 | .clock = &pioCDE_clk, | ||
226 | }, { | ||
227 | .id = AT91SAM9263_ID_PIOCDE, | ||
228 | .offset = AT91_PIOE, | ||
229 | .clock = &pioCDE_clk, | ||
230 | } | ||
231 | }; | ||
232 | |||
233 | static void at91sam9263_reset(void) | ||
234 | { | ||
235 | at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); | ||
236 | } | ||
237 | |||
238 | |||
239 | /* -------------------------------------------------------------------- | ||
240 | * AT91SAM9263 processor initialization | ||
241 | * -------------------------------------------------------------------- */ | ||
242 | |||
243 | void __init at91sam9263_initialize(unsigned long main_clock) | ||
244 | { | ||
245 | /* Map peripherals */ | ||
246 | iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc)); | ||
247 | |||
248 | at91_arch_reset = at91sam9263_reset; | ||
249 | at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); | ||
250 | |||
251 | /* Init clock subsystem */ | ||
252 | at91_clock_init(main_clock); | ||
253 | |||
254 | /* Register the processor-specific clocks */ | ||
255 | at91sam9263_register_clocks(); | ||
256 | |||
257 | /* Register GPIO subsystem */ | ||
258 | at91_gpio_init(at91sam9263_gpio, 5); | ||
259 | } | ||
260 | |||
261 | /* -------------------------------------------------------------------- | ||
262 | * Interrupt initialization | ||
263 | * -------------------------------------------------------------------- */ | ||
264 | |||
265 | /* | ||
266 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
267 | */ | ||
268 | static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
269 | 7, /* Advanced Interrupt Controller (FIQ) */ | ||
270 | 7, /* System Peripherals */ | ||
271 | 0, /* Parallel IO Controller A */ | ||
272 | 0, /* Parallel IO Controller B */ | ||
273 | 0, /* Parallel IO Controller C, D and E */ | ||
274 | 0, | ||
275 | 0, | ||
276 | 6, /* USART 0 */ | ||
277 | 6, /* USART 1 */ | ||
278 | 6, /* USART 2 */ | ||
279 | 0, /* Multimedia Card Interface 0 */ | ||
280 | 0, /* Multimedia Card Interface 1 */ | ||
281 | 4, /* CAN */ | ||
282 | 0, /* Two-Wire Interface */ | ||
283 | 6, /* Serial Peripheral Interface 0 */ | ||
284 | 6, /* Serial Peripheral Interface 1 */ | ||
285 | 5, /* Serial Synchronous Controller 0 */ | ||
286 | 5, /* Serial Synchronous Controller 1 */ | ||
287 | 6, /* AC97 Controller */ | ||
288 | 0, /* Timer Counter 0, 1 and 2 */ | ||
289 | 0, /* Pulse Width Modulation Controller */ | ||
290 | 3, /* Ethernet */ | ||
291 | 0, | ||
292 | 0, /* 2D Graphic Engine */ | ||
293 | 3, /* USB Device Port */ | ||
294 | 0, /* Image Sensor Interface */ | ||
295 | 3, /* LDC Controller */ | ||
296 | 0, /* DMA Controller */ | ||
297 | 0, | ||
298 | 3, /* USB Host port */ | ||
299 | 0, /* Advanced Interrupt Controller (IRQ0) */ | ||
300 | 0, /* Advanced Interrupt Controller (IRQ1) */ | ||
301 | }; | ||
302 | |||
303 | void __init at91sam9263_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | ||
304 | { | ||
305 | if (!priority) | ||
306 | priority = at91sam9263_default_irq_priority; | ||
307 | |||
308 | /* Initialize the AIC interrupt controller */ | ||
309 | at91_aic_init(priority); | ||
310 | |||
311 | /* Enable GPIO interrupts */ | ||
312 | at91_gpio_irq_setup(); | ||
313 | } | ||
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c new file mode 100644 index 000000000000..d9af7ca58bce --- /dev/null +++ b/arch/arm/mach-at91/at91sam9263_devices.c | |||
@@ -0,0 +1,818 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-at91/at91sam9263_devices.c | ||
3 | * | ||
4 | * Copyright (C) 2007 Atmel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | */ | ||
12 | #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/at91sam9263.h> | ||
20 | #include <asm/arch/at91sam926x_mc.h> | ||
21 | #include <asm/arch/at91sam9263_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 = AT91SAM9263_UHP_BASE, | ||
40 | .end = AT91SAM9263_UHP_BASE + SZ_1M - 1, | ||
41 | .flags = IORESOURCE_MEM, | ||
42 | }, | ||
43 | [1] = { | ||
44 | .start = AT91SAM9263_ID_UHP, | ||
45 | .end = AT91SAM9263_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 | int i; | ||
65 | |||
66 | if (!data) | ||
67 | return; | ||
68 | |||
69 | /* Enable VBus control for UHP ports */ | ||
70 | for (i = 0; i < data->ports; i++) { | ||
71 | if (data->vbus_pin[i]) | ||
72 | at91_set_gpio_output(data->vbus_pin[i], 0); | ||
73 | } | ||
74 | |||
75 | usbh_data = *data; | ||
76 | platform_device_register(&at91_usbh_device); | ||
77 | } | ||
78 | #else | ||
79 | void __init at91_add_device_usbh(struct at91_usbh_data *data) {} | ||
80 | #endif | ||
81 | |||
82 | |||
83 | /* -------------------------------------------------------------------- | ||
84 | * USB Device (Gadget) | ||
85 | * -------------------------------------------------------------------- */ | ||
86 | |||
87 | #ifdef CONFIG_USB_GADGET_AT91 | ||
88 | static struct at91_udc_data udc_data; | ||
89 | |||
90 | static struct resource udc_resources[] = { | ||
91 | [0] = { | ||
92 | .start = AT91SAM9263_BASE_UDP, | ||
93 | .end = AT91SAM9263_BASE_UDP + SZ_16K - 1, | ||
94 | .flags = IORESOURCE_MEM, | ||
95 | }, | ||
96 | [1] = { | ||
97 | .start = AT91SAM9263_ID_UDP, | ||
98 | .end = AT91SAM9263_ID_UDP, | ||
99 | .flags = IORESOURCE_IRQ, | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | static struct platform_device at91_udc_device = { | ||
104 | .name = "at91_udc", | ||
105 | .id = -1, | ||
106 | .dev = { | ||
107 | .platform_data = &udc_data, | ||
108 | }, | ||
109 | .resource = udc_resources, | ||
110 | .num_resources = ARRAY_SIZE(udc_resources), | ||
111 | }; | ||
112 | |||
113 | void __init at91_add_device_udc(struct at91_udc_data *data) | ||
114 | { | ||
115 | if (!data) | ||
116 | return; | ||
117 | |||
118 | if (data->vbus_pin) { | ||
119 | at91_set_gpio_input(data->vbus_pin, 0); | ||
120 | at91_set_deglitch(data->vbus_pin, 1); | ||
121 | } | ||
122 | |||
123 | /* Pullup pin is handled internally by USB device peripheral */ | ||
124 | |||
125 | udc_data = *data; | ||
126 | platform_device_register(&at91_udc_device); | ||
127 | } | ||
128 | #else | ||
129 | void __init at91_add_device_udc(struct at91_udc_data *data) {} | ||
130 | #endif | ||
131 | |||
132 | |||
133 | /* -------------------------------------------------------------------- | ||
134 | * Ethernet | ||
135 | * -------------------------------------------------------------------- */ | ||
136 | |||
137 | #if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) | ||
138 | static u64 eth_dmamask = 0xffffffffUL; | ||
139 | static struct at91_eth_data eth_data; | ||
140 | |||
141 | static struct resource eth_resources[] = { | ||
142 | [0] = { | ||
143 | .start = AT91SAM9263_BASE_EMAC, | ||
144 | .end = AT91SAM9263_BASE_EMAC + SZ_16K - 1, | ||
145 | .flags = IORESOURCE_MEM, | ||
146 | }, | ||
147 | [1] = { | ||
148 | .start = AT91SAM9263_ID_EMAC, | ||
149 | .end = AT91SAM9263_ID_EMAC, | ||
150 | .flags = IORESOURCE_IRQ, | ||
151 | }, | ||
152 | }; | ||
153 | |||
154 | static struct platform_device at91sam9263_eth_device = { | ||
155 | .name = "macb", | ||
156 | .id = -1, | ||
157 | .dev = { | ||
158 | .dma_mask = ð_dmamask, | ||
159 | .coherent_dma_mask = 0xffffffff, | ||
160 | .platform_data = ð_data, | ||
161 | }, | ||
162 | .resource = eth_resources, | ||
163 | .num_resources = ARRAY_SIZE(eth_resources), | ||
164 | }; | ||
165 | |||
166 | void __init at91_add_device_eth(struct at91_eth_data *data) | ||
167 | { | ||
168 | if (!data) | ||
169 | return; | ||
170 | |||
171 | if (data->phy_irq_pin) { | ||
172 | at91_set_gpio_input(data->phy_irq_pin, 0); | ||
173 | at91_set_deglitch(data->phy_irq_pin, 1); | ||
174 | } | ||
175 | |||
176 | /* Pins used for MII and RMII */ | ||
177 | at91_set_A_periph(AT91_PIN_PE21, 0); /* ETXCK_EREFCK */ | ||
178 | at91_set_B_periph(AT91_PIN_PC25, 0); /* ERXDV */ | ||
179 | at91_set_A_periph(AT91_PIN_PE25, 0); /* ERX0 */ | ||
180 | at91_set_A_periph(AT91_PIN_PE26, 0); /* ERX1 */ | ||
181 | at91_set_A_periph(AT91_PIN_PE27, 0); /* ERXER */ | ||
182 | at91_set_A_periph(AT91_PIN_PE28, 0); /* ETXEN */ | ||
183 | at91_set_A_periph(AT91_PIN_PE23, 0); /* ETX0 */ | ||
184 | at91_set_A_periph(AT91_PIN_PE24, 0); /* ETX1 */ | ||
185 | at91_set_A_periph(AT91_PIN_PE30, 0); /* EMDIO */ | ||
186 | at91_set_A_periph(AT91_PIN_PE29, 0); /* EMDC */ | ||
187 | |||
188 | if (!data->is_rmii) { | ||
189 | at91_set_A_periph(AT91_PIN_PE22, 0); /* ECRS */ | ||
190 | at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */ | ||
191 | at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */ | ||
192 | at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */ | ||
193 | at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */ | ||
194 | at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */ | ||
195 | at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */ | ||
196 | at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */ | ||
197 | } | ||
198 | |||
199 | eth_data = *data; | ||
200 | platform_device_register(&at91sam9263_eth_device); | ||
201 | } | ||
202 | #else | ||
203 | void __init at91_add_device_eth(struct at91_eth_data *data) {} | ||
204 | #endif | ||
205 | |||
206 | |||
207 | /* -------------------------------------------------------------------- | ||
208 | * MMC / SD | ||
209 | * -------------------------------------------------------------------- */ | ||
210 | |||
211 | #if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) | ||
212 | static u64 mmc_dmamask = 0xffffffffUL; | ||
213 | static struct at91_mmc_data mmc0_data, mmc1_data; | ||
214 | |||
215 | static struct resource mmc0_resources[] = { | ||
216 | [0] = { | ||
217 | .start = AT91SAM9263_BASE_MCI0, | ||
218 | .end = AT91SAM9263_BASE_MCI0 + SZ_16K - 1, | ||
219 | .flags = IORESOURCE_MEM, | ||
220 | }, | ||
221 | [1] = { | ||
222 | .start = AT91SAM9263_ID_MCI0, | ||
223 | .end = AT91SAM9263_ID_MCI0, | ||
224 | .flags = IORESOURCE_IRQ, | ||
225 | }, | ||
226 | }; | ||
227 | |||
228 | static struct platform_device at91sam9263_mmc0_device = { | ||
229 | .name = "at91_mci", | ||
230 | .id = 0, | ||
231 | .dev = { | ||
232 | .dma_mask = &mmc_dmamask, | ||
233 | .coherent_dma_mask = 0xffffffff, | ||
234 | .platform_data = &mmc0_data, | ||
235 | }, | ||
236 | .resource = mmc0_resources, | ||
237 | .num_resources = ARRAY_SIZE(mmc0_resources), | ||
238 | }; | ||
239 | |||
240 | static struct resource mmc1_resources[] = { | ||
241 | [0] = { | ||
242 | .start = AT91SAM9263_BASE_MCI1, | ||
243 | .end = AT91SAM9263_BASE_MCI1 + SZ_16K - 1, | ||
244 | .flags = IORESOURCE_MEM, | ||
245 | }, | ||
246 | [1] = { | ||
247 | .start = AT91SAM9263_ID_MCI1, | ||
248 | .end = AT91SAM9263_ID_MCI1, | ||
249 | .flags = IORESOURCE_IRQ, | ||
250 | }, | ||
251 | }; | ||
252 | |||
253 | static struct platform_device at91sam9263_mmc1_device = { | ||
254 | .name = "at91_mci", | ||
255 | .id = 1, | ||
256 | .dev = { | ||
257 | .dma_mask = &mmc_dmamask, | ||
258 | .coherent_dma_mask = 0xffffffff, | ||
259 | .platform_data = &mmc1_data, | ||
260 | }, | ||
261 | .resource = mmc1_resources, | ||
262 | .num_resources = ARRAY_SIZE(mmc1_resources), | ||
263 | }; | ||
264 | |||
265 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) | ||
266 | { | ||
267 | if (!data) | ||
268 | return; | ||
269 | |||
270 | /* input/irq */ | ||
271 | if (data->det_pin) { | ||
272 | at91_set_gpio_input(data->det_pin, 1); | ||
273 | at91_set_deglitch(data->det_pin, 1); | ||
274 | } | ||
275 | if (data->wp_pin) | ||
276 | at91_set_gpio_input(data->wp_pin, 1); | ||
277 | if (data->vcc_pin) | ||
278 | at91_set_gpio_output(data->vcc_pin, 0); | ||
279 | |||
280 | if (mmc_id == 0) { /* MCI0 */ | ||
281 | /* CLK */ | ||
282 | at91_set_A_periph(AT91_PIN_PA12, 0); | ||
283 | |||
284 | if (data->slot_b) { | ||
285 | /* CMD */ | ||
286 | at91_set_A_periph(AT91_PIN_PA16, 1); | ||
287 | |||
288 | /* DAT0, maybe DAT1..DAT3 */ | ||
289 | at91_set_A_periph(AT91_PIN_PA17, 1); | ||
290 | if (data->wire4) { | ||
291 | at91_set_A_periph(AT91_PIN_PA18, 1); | ||
292 | at91_set_A_periph(AT91_PIN_PA19, 1); | ||
293 | at91_set_A_periph(AT91_PIN_PA20, 1); | ||
294 | } | ||
295 | } else { | ||
296 | /* CMD */ | ||
297 | at91_set_A_periph(AT91_PIN_PA1, 1); | ||
298 | |||
299 | /* DAT0, maybe DAT1..DAT3 */ | ||
300 | at91_set_A_periph(AT91_PIN_PA0, 1); | ||
301 | if (data->wire4) { | ||
302 | at91_set_A_periph(AT91_PIN_PA3, 1); | ||
303 | at91_set_A_periph(AT91_PIN_PA4, 1); | ||
304 | at91_set_A_periph(AT91_PIN_PA5, 1); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | mmc0_data = *data; | ||
309 | at91_clock_associate("mci0_clk", &at91sam9263_mmc1_device.dev, "mci_clk"); | ||
310 | platform_device_register(&at91sam9263_mmc0_device); | ||
311 | } else { /* MCI1 */ | ||
312 | /* CLK */ | ||
313 | at91_set_A_periph(AT91_PIN_PA6, 0); | ||
314 | |||
315 | if (data->slot_b) { | ||
316 | /* CMD */ | ||
317 | at91_set_A_periph(AT91_PIN_PA21, 1); | ||
318 | |||
319 | /* DAT0, maybe DAT1..DAT3 */ | ||
320 | at91_set_A_periph(AT91_PIN_PA22, 1); | ||
321 | if (data->wire4) { | ||
322 | at91_set_A_periph(AT91_PIN_PA23, 1); | ||
323 | at91_set_A_periph(AT91_PIN_PA24, 1); | ||
324 | at91_set_A_periph(AT91_PIN_PA25, 1); | ||
325 | } | ||
326 | } else { | ||
327 | /* CMD */ | ||
328 | at91_set_A_periph(AT91_PIN_PA7, 1); | ||
329 | |||
330 | /* DAT0, maybe DAT1..DAT3 */ | ||
331 | at91_set_A_periph(AT91_PIN_PA8, 1); | ||
332 | if (data->wire4) { | ||
333 | at91_set_A_periph(AT91_PIN_PA9, 1); | ||
334 | at91_set_A_periph(AT91_PIN_PA10, 1); | ||
335 | at91_set_A_periph(AT91_PIN_PA11, 1); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | mmc1_data = *data; | ||
340 | at91_clock_associate("mci1_clk", &at91sam9263_mmc1_device.dev, "mci_clk"); | ||
341 | platform_device_register(&at91sam9263_mmc1_device); | ||
342 | } | ||
343 | } | ||
344 | #else | ||
345 | void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} | ||
346 | #endif | ||
347 | |||
348 | |||
349 | /* -------------------------------------------------------------------- | ||
350 | * NAND / SmartMedia | ||
351 | * -------------------------------------------------------------------- */ | ||
352 | |||
353 | #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) | ||
354 | static struct at91_nand_data nand_data; | ||
355 | |||
356 | #define NAND_BASE AT91_CHIPSELECT_3 | ||
357 | |||
358 | static struct resource nand_resources[] = { | ||
359 | { | ||
360 | .start = NAND_BASE, | ||
361 | .end = NAND_BASE + SZ_256M - 1, | ||
362 | .flags = IORESOURCE_MEM, | ||
363 | } | ||
364 | }; | ||
365 | |||
366 | static struct platform_device at91sam9263_nand_device = { | ||
367 | .name = "at91_nand", | ||
368 | .id = -1, | ||
369 | .dev = { | ||
370 | .platform_data = &nand_data, | ||
371 | }, | ||
372 | .resource = nand_resources, | ||
373 | .num_resources = ARRAY_SIZE(nand_resources), | ||
374 | }; | ||
375 | |||
376 | void __init at91_add_device_nand(struct at91_nand_data *data) | ||
377 | { | ||
378 | unsigned long csa, mode; | ||
379 | |||
380 | if (!data) | ||
381 | return; | ||
382 | |||
383 | csa = at91_sys_read(AT91_MATRIX_EBI0CSA); | ||
384 | at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC); | ||
385 | |||
386 | /* set the bus interface characteristics */ | ||
387 | at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) | ||
388 | | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); | ||
389 | |||
390 | at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) | ||
391 | | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3)); | ||
392 | |||
393 | at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5)); | ||
394 | |||
395 | if (data->bus_width_16) | ||
396 | mode = AT91_SMC_DBW_16; | ||
397 | else | ||
398 | mode = AT91_SMC_DBW_8; | ||
399 | at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2)); | ||
400 | |||
401 | /* enable pin */ | ||
402 | if (data->enable_pin) | ||
403 | at91_set_gpio_output(data->enable_pin, 1); | ||
404 | |||
405 | /* ready/busy pin */ | ||
406 | if (data->rdy_pin) | ||
407 | at91_set_gpio_input(data->rdy_pin, 1); | ||
408 | |||
409 | /* card detect pin */ | ||
410 | if (data->det_pin) | ||
411 | at91_set_gpio_input(data->det_pin, 1); | ||
412 | |||
413 | nand_data = *data; | ||
414 | platform_device_register(&at91sam9263_nand_device); | ||
415 | } | ||
416 | #else | ||
417 | void __init at91_add_device_nand(struct at91_nand_data *data) {} | ||
418 | #endif | ||
419 | |||
420 | |||
421 | /* -------------------------------------------------------------------- | ||
422 | * TWI (i2c) | ||
423 | * -------------------------------------------------------------------- */ | ||
424 | |||
425 | #if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) | ||
426 | |||
427 | static struct resource twi_resources[] = { | ||
428 | [0] = { | ||
429 | .start = AT91SAM9263_BASE_TWI, | ||
430 | .end = AT91SAM9263_BASE_TWI + SZ_16K - 1, | ||
431 | .flags = IORESOURCE_MEM, | ||
432 | }, | ||
433 | [1] = { | ||
434 | .start = AT91SAM9263_ID_TWI, | ||
435 | .end = AT91SAM9263_ID_TWI, | ||
436 | .flags = IORESOURCE_IRQ, | ||
437 | }, | ||
438 | }; | ||
439 | |||
440 | static struct platform_device at91sam9263_twi_device = { | ||
441 | .name = "at91_i2c", | ||
442 | .id = -1, | ||
443 | .resource = twi_resources, | ||
444 | .num_resources = ARRAY_SIZE(twi_resources), | ||
445 | }; | ||
446 | |||
447 | void __init at91_add_device_i2c(void) | ||
448 | { | ||
449 | /* pins used for TWI interface */ | ||
450 | at91_set_A_periph(AT91_PIN_PB4, 0); /* TWD */ | ||
451 | at91_set_multi_drive(AT91_PIN_PB4, 1); | ||
452 | |||
453 | at91_set_A_periph(AT91_PIN_PB5, 0); /* TWCK */ | ||
454 | at91_set_multi_drive(AT91_PIN_PB5, 1); | ||
455 | |||
456 | platform_device_register(&at91sam9263_twi_device); | ||
457 | } | ||
458 | #else | ||
459 | void __init at91_add_device_i2c(void) {} | ||
460 | #endif | ||
461 | |||
462 | |||
463 | /* -------------------------------------------------------------------- | ||
464 | * SPI | ||
465 | * -------------------------------------------------------------------- */ | ||
466 | |||
467 | #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) | ||
468 | static u64 spi_dmamask = 0xffffffffUL; | ||
469 | |||
470 | static struct resource spi0_resources[] = { | ||
471 | [0] = { | ||
472 | .start = AT91SAM9263_BASE_SPI0, | ||
473 | .end = AT91SAM9263_BASE_SPI0 + SZ_16K - 1, | ||
474 | .flags = IORESOURCE_MEM, | ||
475 | }, | ||
476 | [1] = { | ||
477 | .start = AT91SAM9263_ID_SPI0, | ||
478 | .end = AT91SAM9263_ID_SPI0, | ||
479 | .flags = IORESOURCE_IRQ, | ||
480 | }, | ||
481 | }; | ||
482 | |||
483 | static struct platform_device at91sam9263_spi0_device = { | ||
484 | .name = "atmel_spi", | ||
485 | .id = 0, | ||
486 | .dev = { | ||
487 | .dma_mask = &spi_dmamask, | ||
488 | .coherent_dma_mask = 0xffffffff, | ||
489 | }, | ||
490 | .resource = spi0_resources, | ||
491 | .num_resources = ARRAY_SIZE(spi0_resources), | ||
492 | }; | ||
493 | |||
494 | static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PB11 }; | ||
495 | |||
496 | static struct resource spi1_resources[] = { | ||
497 | [0] = { | ||
498 | .start = AT91SAM9263_BASE_SPI1, | ||
499 | .end = AT91SAM9263_BASE_SPI1 + SZ_16K - 1, | ||
500 | .flags = IORESOURCE_MEM, | ||
501 | }, | ||
502 | [1] = { | ||
503 | .start = AT91SAM9263_ID_SPI1, | ||
504 | .end = AT91SAM9263_ID_SPI1, | ||
505 | .flags = IORESOURCE_IRQ, | ||
506 | }, | ||
507 | }; | ||
508 | |||
509 | static struct platform_device at91sam9263_spi1_device = { | ||
510 | .name = "atmel_spi", | ||
511 | .id = 1, | ||
512 | .dev = { | ||
513 | .dma_mask = &spi_dmamask, | ||
514 | .coherent_dma_mask = 0xffffffff, | ||
515 | }, | ||
516 | .resource = spi1_resources, | ||
517 | .num_resources = ARRAY_SIZE(spi1_resources), | ||
518 | }; | ||
519 | |||
520 | static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 }; | ||
521 | |||
522 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) | ||
523 | { | ||
524 | int i; | ||
525 | unsigned long cs_pin; | ||
526 | short enable_spi0 = 0; | ||
527 | short enable_spi1 = 0; | ||
528 | |||
529 | /* Choose SPI chip-selects */ | ||
530 | for (i = 0; i < nr_devices; i++) { | ||
531 | if (devices[i].controller_data) | ||
532 | cs_pin = (unsigned long) devices[i].controller_data; | ||
533 | else if (devices[i].bus_num == 0) | ||
534 | cs_pin = spi0_standard_cs[devices[i].chip_select]; | ||
535 | else | ||
536 | cs_pin = spi1_standard_cs[devices[i].chip_select]; | ||
537 | |||
538 | if (devices[i].bus_num == 0) | ||
539 | enable_spi0 = 1; | ||
540 | else | ||
541 | enable_spi1 = 1; | ||
542 | |||
543 | /* enable chip-select pin */ | ||
544 | at91_set_gpio_output(cs_pin, 1); | ||
545 | |||
546 | /* pass chip-select pin to driver */ | ||
547 | devices[i].controller_data = (void *) cs_pin; | ||
548 | } | ||
549 | |||
550 | spi_register_board_info(devices, nr_devices); | ||
551 | |||
552 | /* Configure SPI bus(es) */ | ||
553 | if (enable_spi0) { | ||
554 | at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ | ||
555 | at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ | ||
556 | at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI1_SPCK */ | ||
557 | |||
558 | at91_clock_associate("spi0_clk", &at91sam9263_spi0_device.dev, "spi_clk"); | ||
559 | platform_device_register(&at91sam9263_spi0_device); | ||
560 | } | ||
561 | if (enable_spi1) { | ||
562 | at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */ | ||
563 | at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */ | ||
564 | at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */ | ||
565 | |||
566 | at91_clock_associate("spi1_clk", &at91sam9263_spi1_device.dev, "spi_clk"); | ||
567 | platform_device_register(&at91sam9263_spi1_device); | ||
568 | } | ||
569 | } | ||
570 | #else | ||
571 | void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} | ||
572 | #endif | ||
573 | |||
574 | |||
575 | /* -------------------------------------------------------------------- | ||
576 | * LEDs | ||
577 | * -------------------------------------------------------------------- */ | ||
578 | |||
579 | #if defined(CONFIG_LEDS) | ||
580 | u8 at91_leds_cpu; | ||
581 | u8 at91_leds_timer; | ||
582 | |||
583 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) | ||
584 | { | ||
585 | /* Enable GPIO to access the LEDs */ | ||
586 | at91_set_gpio_output(cpu_led, 1); | ||
587 | at91_set_gpio_output(timer_led, 1); | ||
588 | |||
589 | at91_leds_cpu = cpu_led; | ||
590 | at91_leds_timer = timer_led; | ||
591 | } | ||
592 | #else | ||
593 | void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} | ||
594 | #endif | ||
595 | |||
596 | |||
597 | /* -------------------------------------------------------------------- | ||
598 | * UART | ||
599 | * -------------------------------------------------------------------- */ | ||
600 | |||
601 | #if defined(CONFIG_SERIAL_ATMEL) | ||
602 | |||
603 | static struct resource dbgu_resources[] = { | ||
604 | [0] = { | ||
605 | .start = AT91_VA_BASE_SYS + AT91_DBGU, | ||
606 | .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, | ||
607 | .flags = IORESOURCE_MEM, | ||
608 | }, | ||
609 | [1] = { | ||
610 | .start = AT91_ID_SYS, | ||
611 | .end = AT91_ID_SYS, | ||
612 | .flags = IORESOURCE_IRQ, | ||
613 | }, | ||
614 | }; | ||
615 | |||
616 | static struct atmel_uart_data dbgu_data = { | ||
617 | .use_dma_tx = 0, | ||
618 | .use_dma_rx = 0, /* DBGU not capable of receive DMA */ | ||
619 | .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), | ||
620 | }; | ||
621 | |||
622 | static struct platform_device at91sam9263_dbgu_device = { | ||
623 | .name = "atmel_usart", | ||
624 | .id = 0, | ||
625 | .dev = { | ||
626 | .platform_data = &dbgu_data, | ||
627 | .coherent_dma_mask = 0xffffffff, | ||
628 | }, | ||
629 | .resource = dbgu_resources, | ||
630 | .num_resources = ARRAY_SIZE(dbgu_resources), | ||
631 | }; | ||
632 | |||
633 | static inline void configure_dbgu_pins(void) | ||
634 | { | ||
635 | at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */ | ||
636 | at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */ | ||
637 | } | ||
638 | |||
639 | static struct resource uart0_resources[] = { | ||
640 | [0] = { | ||
641 | .start = AT91SAM9263_BASE_US0, | ||
642 | .end = AT91SAM9263_BASE_US0 + SZ_16K - 1, | ||
643 | .flags = IORESOURCE_MEM, | ||
644 | }, | ||
645 | [1] = { | ||
646 | .start = AT91SAM9263_ID_US0, | ||
647 | .end = AT91SAM9263_ID_US0, | ||
648 | .flags = IORESOURCE_IRQ, | ||
649 | }, | ||
650 | }; | ||
651 | |||
652 | static struct atmel_uart_data uart0_data = { | ||
653 | .use_dma_tx = 1, | ||
654 | .use_dma_rx = 1, | ||
655 | }; | ||
656 | |||
657 | static struct platform_device at91sam9263_uart0_device = { | ||
658 | .name = "atmel_usart", | ||
659 | .id = 1, | ||
660 | .dev = { | ||
661 | .platform_data = &uart0_data, | ||
662 | .coherent_dma_mask = 0xffffffff, | ||
663 | }, | ||
664 | .resource = uart0_resources, | ||
665 | .num_resources = ARRAY_SIZE(uart0_resources), | ||
666 | }; | ||
667 | |||
668 | static inline void configure_usart0_pins(void) | ||
669 | { | ||
670 | at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */ | ||
671 | at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */ | ||
672 | at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */ | ||
673 | at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */ | ||
674 | } | ||
675 | |||
676 | static struct resource uart1_resources[] = { | ||
677 | [0] = { | ||
678 | .start = AT91SAM9263_BASE_US1, | ||
679 | .end = AT91SAM9263_BASE_US1 + SZ_16K - 1, | ||
680 | .flags = IORESOURCE_MEM, | ||
681 | }, | ||
682 | [1] = { | ||
683 | .start = AT91SAM9263_ID_US1, | ||
684 | .end = AT91SAM9263_ID_US1, | ||
685 | .flags = IORESOURCE_IRQ, | ||
686 | }, | ||
687 | }; | ||
688 | |||
689 | static struct atmel_uart_data uart1_data = { | ||
690 | .use_dma_tx = 1, | ||
691 | .use_dma_rx = 1, | ||
692 | }; | ||
693 | |||
694 | static struct platform_device at91sam9263_uart1_device = { | ||
695 | .name = "atmel_usart", | ||
696 | .id = 2, | ||
697 | .dev = { | ||
698 | .platform_data = &uart1_data, | ||
699 | .coherent_dma_mask = 0xffffffff, | ||
700 | }, | ||
701 | .resource = uart1_resources, | ||
702 | .num_resources = ARRAY_SIZE(uart1_resources), | ||
703 | }; | ||
704 | |||
705 | static inline void configure_usart1_pins(void) | ||
706 | { | ||
707 | at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */ | ||
708 | at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */ | ||
709 | at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */ | ||
710 | at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */ | ||
711 | } | ||
712 | |||
713 | static struct resource uart2_resources[] = { | ||
714 | [0] = { | ||
715 | .start = AT91SAM9263_BASE_US2, | ||
716 | .end = AT91SAM9263_BASE_US2 + SZ_16K - 1, | ||
717 | .flags = IORESOURCE_MEM, | ||
718 | }, | ||
719 | [1] = { | ||
720 | .start = AT91SAM9263_ID_US2, | ||
721 | .end = AT91SAM9263_ID_US2, | ||
722 | .flags = IORESOURCE_IRQ, | ||
723 | }, | ||
724 | }; | ||
725 | |||
726 | static struct atmel_uart_data uart2_data = { | ||
727 | .use_dma_tx = 1, | ||
728 | .use_dma_rx = 1, | ||
729 | }; | ||
730 | |||
731 | static struct platform_device at91sam9263_uart2_device = { | ||
732 | .name = "atmel_usart", | ||
733 | .id = 3, | ||
734 | .dev = { | ||
735 | .platform_data = &uart2_data, | ||
736 | .coherent_dma_mask = 0xffffffff, | ||
737 | }, | ||
738 | .resource = uart2_resources, | ||
739 | .num_resources = ARRAY_SIZE(uart2_resources), | ||
740 | }; | ||
741 | |||
742 | static inline void configure_usart2_pins(void) | ||
743 | { | ||
744 | at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */ | ||
745 | at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */ | ||
746 | at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */ | ||
747 | at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */ | ||
748 | } | ||
749 | |||
750 | struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ | ||
751 | struct platform_device *atmel_default_console_device; /* the serial console device */ | ||
752 | |||
753 | void __init at91_init_serial(struct at91_uart_config *config) | ||
754 | { | ||
755 | int i; | ||
756 | |||
757 | /* Fill in list of supported UARTs */ | ||
758 | for (i = 0; i < config->nr_tty; i++) { | ||
759 | switch (config->tty_map[i]) { | ||
760 | case 0: | ||
761 | configure_usart0_pins(); | ||
762 | at91_uarts[i] = &at91sam9263_uart0_device; | ||
763 | at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart"); | ||
764 | break; | ||
765 | case 1: | ||
766 | configure_usart1_pins(); | ||
767 | at91_uarts[i] = &at91sam9263_uart1_device; | ||
768 | at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart"); | ||
769 | break; | ||
770 | case 2: | ||
771 | configure_usart2_pins(); | ||
772 | at91_uarts[i] = &at91sam9263_uart2_device; | ||
773 | at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart"); | ||
774 | break; | ||
775 | case 3: | ||
776 | configure_dbgu_pins(); | ||
777 | at91_uarts[i] = &at91sam9263_dbgu_device; | ||
778 | at91_clock_associate("mck", &at91sam9263_dbgu_device.dev, "usart"); | ||
779 | break; | ||
780 | default: | ||
781 | continue; | ||
782 | } | ||
783 | at91_uarts[i]->id = i; /* update ID number to mapped ID */ | ||
784 | } | ||
785 | |||
786 | /* Set serial console device */ | ||
787 | if (config->console_tty < ATMEL_MAX_UART) | ||
788 | atmel_default_console_device = at91_uarts[config->console_tty]; | ||
789 | if (!atmel_default_console_device) | ||
790 | printk(KERN_INFO "AT91: No default serial console defined.\n"); | ||
791 | } | ||
792 | |||
793 | void __init at91_add_device_serial(void) | ||
794 | { | ||
795 | int i; | ||
796 | |||
797 | for (i = 0; i < ATMEL_MAX_UART; i++) { | ||
798 | if (at91_uarts[i]) | ||
799 | platform_device_register(at91_uarts[i]); | ||
800 | } | ||
801 | } | ||
802 | #else | ||
803 | void __init at91_init_serial(struct at91_uart_config *config) {} | ||
804 | void __init at91_add_device_serial(void) {} | ||
805 | #endif | ||
806 | |||
807 | |||
808 | /* -------------------------------------------------------------------- */ | ||
809 | /* | ||
810 | * These devices are always present and don't need any board-specific | ||
811 | * setup. | ||
812 | */ | ||
813 | static int __init at91_add_standard_devices(void) | ||
814 | { | ||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | 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..a4dded27fa16 --- /dev/null +++ b/arch/arm/mach-at91/at91sam926x_time.c | |||
@@ -0,0 +1,113 @@ | |||
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 | */ | ||
34 | static unsigned long at91sam926x_gettimeoffset(void) | ||
35 | { | ||
36 | unsigned long elapsed; | ||
37 | unsigned long t = at91_sys_read(AT91_PIT_PIIR); | ||
38 | |||
39 | elapsed = (PIT_PICNT(t) * LATCH) + PIT_CPIV(t); /* hardware clock cycles */ | ||
40 | |||
41 | return (unsigned long)(elapsed * jiffies_to_usecs(1)) / LATCH; | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * IRQ handler for the timer. | ||
46 | */ | ||
47 | static irqreturn_t at91sam926x_timer_interrupt(int irq, void *dev_id) | ||
48 | { | ||
49 | volatile long nr_ticks; | ||
50 | |||
51 | if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) { /* This is a shared interrupt */ | ||
52 | write_seqlock(&xtime_lock); | ||
53 | |||
54 | /* Get number to ticks performed before interrupt and clear PIT interrupt */ | ||
55 | nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); | ||
56 | do { | ||
57 | timer_tick(); | ||
58 | nr_ticks--; | ||
59 | } while (nr_ticks); | ||
60 | |||
61 | write_sequnlock(&xtime_lock); | ||
62 | return IRQ_HANDLED; | ||
63 | } else | ||
64 | return IRQ_NONE; /* not handled */ | ||
65 | } | ||
66 | |||
67 | static struct irqaction at91sam926x_timer_irq = { | ||
68 | .name = "at91_tick", | ||
69 | .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER, | ||
70 | .handler = at91sam926x_timer_interrupt | ||
71 | }; | ||
72 | |||
73 | void at91sam926x_timer_reset(void) | ||
74 | { | ||
75 | /* Disable timer */ | ||
76 | at91_sys_write(AT91_PIT_MR, 0); | ||
77 | |||
78 | /* Clear any pending interrupts */ | ||
79 | (void) at91_sys_read(AT91_PIT_PIVR); | ||
80 | |||
81 | /* Set Period Interval timer and enable its interrupt */ | ||
82 | at91_sys_write(AT91_PIT_MR, (LATCH & AT91_PIT_PIV) | AT91_PIT_PITIEN | AT91_PIT_PITEN); | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * Set up timer interrupt. | ||
87 | */ | ||
88 | void __init at91sam926x_timer_init(void) | ||
89 | { | ||
90 | /* Initialize and enable the timer */ | ||
91 | at91sam926x_timer_reset(); | ||
92 | |||
93 | /* Make IRQs happen for the system timer. */ | ||
94 | setup_irq(AT91_ID_SYS, &at91sam926x_timer_irq); | ||
95 | } | ||
96 | |||
97 | #ifdef CONFIG_PM | ||
98 | static void at91sam926x_timer_suspend(void) | ||
99 | { | ||
100 | /* Disable timer */ | ||
101 | at91_sys_write(AT91_PIT_MR, 0); | ||
102 | } | ||
103 | #else | ||
104 | #define at91sam926x_timer_suspend NULL | ||
105 | #endif | ||
106 | |||
107 | struct sys_timer at91sam926x_timer = { | ||
108 | .init = at91sam926x_timer_init, | ||
109 | .offset = at91sam926x_gettimeoffset, | ||
110 | .suspend = at91sam926x_timer_suspend, | ||
111 | .resume = at91sam926x_timer_reset, | ||
112 | }; | ||
113 | |||
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..b4518619063a --- /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(0, &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..e18a41e61f0c --- /dev/null +++ b/arch/arm/mach-at91/board-csb337.c | |||
@@ -0,0 +1,184 @@ | |||
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 | #include <linux/mtd/physmap.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 | |||
41 | #include "generic.h" | ||
42 | |||
43 | |||
44 | /* | ||
45 | * Serial port configuration. | ||
46 | * 0 .. 3 = USART0 .. USART3 | ||
47 | * 4 = DBGU | ||
48 | */ | ||
49 | static struct at91_uart_config __initdata csb337_uart_config = { | ||
50 | .console_tty = 0, /* ttyS0 */ | ||
51 | .nr_tty = 2, | ||
52 | .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */ | ||
53 | }; | ||
54 | |||
55 | static void __init csb337_map_io(void) | ||
56 | { | ||
57 | /* Initialize processor: 3.6864 MHz crystal */ | ||
58 | at91rm9200_initialize(3686400, AT91RM9200_BGA); | ||
59 | |||
60 | /* Setup the LEDs */ | ||
61 | at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); | ||
62 | |||
63 | /* Setup the serial ports and console */ | ||
64 | at91_init_serial(&csb337_uart_config); | ||
65 | } | ||
66 | |||
67 | static void __init csb337_init_irq(void) | ||
68 | { | ||
69 | at91rm9200_init_interrupts(NULL); | ||
70 | } | ||
71 | |||
72 | static struct at91_eth_data __initdata csb337_eth_data = { | ||
73 | .phy_irq_pin = AT91_PIN_PC2, | ||
74 | .is_rmii = 0, | ||
75 | }; | ||
76 | |||
77 | static struct at91_usbh_data __initdata csb337_usbh_data = { | ||
78 | .ports = 2, | ||
79 | }; | ||
80 | |||
81 | static struct at91_udc_data __initdata csb337_udc_data = { | ||
82 | // this has no VBUS sensing pin | ||
83 | .pullup_pin = AT91_PIN_PA24, | ||
84 | }; | ||
85 | |||
86 | static struct at91_cf_data __initdata csb337_cf_data = { | ||
87 | /* | ||
88 | * connector P4 on the CSB 337 mates to | ||
89 | * connector P8 on the CSB 300CF | ||
90 | */ | ||
91 | |||
92 | /* CSB337 specific */ | ||
93 | .det_pin = AT91_PIN_PC3, | ||
94 | |||
95 | /* CSB300CF specific */ | ||
96 | .irq_pin = AT91_PIN_PA19, | ||
97 | .vcc_pin = AT91_PIN_PD0, | ||
98 | .rst_pin = AT91_PIN_PD2, | ||
99 | }; | ||
100 | |||
101 | static struct at91_mmc_data __initdata csb337_mmc_data = { | ||
102 | .det_pin = AT91_PIN_PD5, | ||
103 | .slot_b = 0, | ||
104 | .wire4 = 1, | ||
105 | .wp_pin = AT91_PIN_PD6, | ||
106 | }; | ||
107 | |||
108 | static struct spi_board_info csb337_spi_devices[] = { | ||
109 | { /* CAN controller */ | ||
110 | .modalias = "sak82c900", | ||
111 | .chip_select = 0, | ||
112 | .max_speed_hz = 6 * 1000 * 1000, | ||
113 | }, | ||
114 | }; | ||
115 | |||
116 | #define CSB_FLASH_BASE AT91_CHIPSELECT_0 | ||
117 | #define CSB_FLASH_SIZE 0x800000 | ||
118 | |||
119 | static struct mtd_partition csb_flash_partitions[] = { | ||
120 | { | ||
121 | .name = "uMON flash", | ||
122 | .offset = 0, | ||
123 | .size = MTDPART_SIZ_FULL, | ||
124 | .mask_flags = MTD_WRITEABLE, /* read only */ | ||
125 | } | ||
126 | }; | ||
127 | |||
128 | static struct physmap_flash_data csb_flash_data = { | ||
129 | .width = 2, | ||
130 | .parts = csb_flash_partitions, | ||
131 | .nr_parts = ARRAY_SIZE(csb_flash_partitions), | ||
132 | }; | ||
133 | |||
134 | static struct resource csb_flash_resources[] = { | ||
135 | { | ||
136 | .start = CSB_FLASH_BASE, | ||
137 | .end = CSB_FLASH_BASE + CSB_FLASH_SIZE - 1, | ||
138 | .flags = IORESOURCE_MEM, | ||
139 | } | ||
140 | }; | ||
141 | |||
142 | static struct platform_device csb_flash = { | ||
143 | .name = "physmap-flash", | ||
144 | .id = 0, | ||
145 | .dev = { | ||
146 | .platform_data = &csb_flash_data, | ||
147 | }, | ||
148 | .resource = csb_flash_resources, | ||
149 | .num_resources = ARRAY_SIZE(csb_flash_resources), | ||
150 | }; | ||
151 | |||
152 | static void __init csb337_board_init(void) | ||
153 | { | ||
154 | /* Serial */ | ||
155 | at91_add_device_serial(); | ||
156 | /* Ethernet */ | ||
157 | at91_add_device_eth(&csb337_eth_data); | ||
158 | /* USB Host */ | ||
159 | at91_add_device_usbh(&csb337_usbh_data); | ||
160 | /* USB Device */ | ||
161 | at91_add_device_udc(&csb337_udc_data); | ||
162 | /* I2C */ | ||
163 | at91_add_device_i2c(); | ||
164 | /* Compact Flash */ | ||
165 | at91_set_gpio_input(AT91_PIN_PB22, 1); /* IOIS16 */ | ||
166 | at91_add_device_cf(&csb337_cf_data); | ||
167 | /* SPI */ | ||
168 | at91_add_device_spi(csb337_spi_devices, ARRAY_SIZE(csb337_spi_devices)); | ||
169 | /* MMC */ | ||
170 | at91_add_device_mmc(0, &csb337_mmc_data); | ||
171 | /* NOR flash */ | ||
172 | platform_device_register(&csb_flash); | ||
173 | } | ||
174 | |||
175 | MACHINE_START(CSB337, "Cogent CSB337") | ||
176 | /* Maintainer: Bill Gatliff */ | ||
177 | .phys_io = AT91_BASE_SYS, | ||
178 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
179 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
180 | .timer = &at91rm9200_timer, | ||
181 | .map_io = csb337_map_io, | ||
182 | .init_irq = csb337_init_irq, | ||
183 | .init_machine = csb337_board_init, | ||
184 | 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..77f04b935b3a --- /dev/null +++ b/arch/arm/mach-at91/board-csb637.c | |||
@@ -0,0 +1,148 @@ | |||
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 | #include <linux/mtd/physmap.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 csb637_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 csb637_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_PB2, AT91_PIN_PB2); | ||
61 | |||
62 | /* Setup the serial ports and console */ | ||
63 | at91_init_serial(&csb637_uart_config); | ||
64 | } | ||
65 | |||
66 | static void __init csb637_init_irq(void) | ||
67 | { | ||
68 | at91rm9200_init_interrupts(NULL); | ||
69 | } | ||
70 | |||
71 | static struct at91_eth_data __initdata csb637_eth_data = { | ||
72 | .phy_irq_pin = AT91_PIN_PC0, | ||
73 | .is_rmii = 0, | ||
74 | }; | ||
75 | |||
76 | static struct at91_usbh_data __initdata csb637_usbh_data = { | ||
77 | .ports = 2, | ||
78 | }; | ||
79 | |||
80 | static struct at91_udc_data __initdata csb637_udc_data = { | ||
81 | .vbus_pin = AT91_PIN_PB28, | ||
82 | .pullup_pin = AT91_PIN_PB1, | ||
83 | }; | ||
84 | |||
85 | #define CSB_FLASH_BASE AT91_CHIPSELECT_0 | ||
86 | #define CSB_FLASH_SIZE 0x1000000 | ||
87 | |||
88 | static struct mtd_partition csb_flash_partitions[] = { | ||
89 | { | ||
90 | .name = "uMON flash", | ||
91 | .offset = 0, | ||
92 | .size = MTDPART_SIZ_FULL, | ||
93 | .mask_flags = MTD_WRITEABLE, /* read only */ | ||
94 | } | ||
95 | }; | ||
96 | |||
97 | static struct physmap_flash_data csb_flash_data = { | ||
98 | .width = 2, | ||
99 | .parts = csb_flash_partitions, | ||
100 | .nr_parts = ARRAY_SIZE(csb_flash_partitions), | ||
101 | }; | ||
102 | |||
103 | static struct resource csb_flash_resources[] = { | ||
104 | { | ||
105 | .start = CSB_FLASH_BASE, | ||
106 | .end = CSB_FLASH_BASE + CSB_FLASH_SIZE - 1, | ||
107 | .flags = IORESOURCE_MEM, | ||
108 | } | ||
109 | }; | ||
110 | |||
111 | static struct platform_device csb_flash = { | ||
112 | .name = "physmap-flash", | ||
113 | .id = 0, | ||
114 | .dev = { | ||
115 | .platform_data = &csb_flash_data, | ||
116 | }, | ||
117 | .resource = csb_flash_resources, | ||
118 | .num_resources = ARRAY_SIZE(csb_flash_resources), | ||
119 | }; | ||
120 | |||
121 | static void __init csb637_board_init(void) | ||
122 | { | ||
123 | /* Serial */ | ||
124 | at91_add_device_serial(); | ||
125 | /* Ethernet */ | ||
126 | at91_add_device_eth(&csb637_eth_data); | ||
127 | /* USB Host */ | ||
128 | at91_add_device_usbh(&csb637_usbh_data); | ||
129 | /* USB Device */ | ||
130 | at91_add_device_udc(&csb637_udc_data); | ||
131 | /* I2C */ | ||
132 | at91_add_device_i2c(); | ||
133 | /* SPI */ | ||
134 | at91_add_device_spi(NULL, 0); | ||
135 | /* NOR flash */ | ||
136 | platform_device_register(&csb_flash); | ||
137 | } | ||
138 | |||
139 | MACHINE_START(CSB637, "Cogent CSB637") | ||
140 | /* Maintainer: Bill Gatliff */ | ||
141 | .phys_io = AT91_BASE_SYS, | ||
142 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
143 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
144 | .timer = &at91rm9200_timer, | ||
145 | .map_io = csb637_map_io, | ||
146 | .init_irq = csb637_init_irq, | ||
147 | .init_machine = csb637_board_init, | ||
148 | 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..6043c38c0a9e --- /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(0, &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..20458b5548f0 --- /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(0, &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..322fdd75a1e4 --- /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(0, &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..76f6e1e553ea --- /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(0, &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..57fb4499d969 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9260ek.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-sam9260ek.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(0, &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..b7e772467cf6 --- /dev/null +++ b/arch/arm/mach-at91/board-sam9261ek.c | |||
@@ -0,0 +1,259 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-sam9261ek.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(0, &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/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c new file mode 100644 index 000000000000..8fdce11a880c --- /dev/null +++ b/arch/arm/mach-at91/board-sam9263ek.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-sam9263ek.c | ||
3 | * | ||
4 | * Copyright (C) 2005 SAN People | ||
5 | * Copyright (C) 2007 Atmel Corporation. | ||
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 .. 2 = USART0 .. USART2 | ||
48 | * 3 = DBGU | ||
49 | */ | ||
50 | static struct at91_uart_config __initdata ek_uart_config = { | ||
51 | .console_tty = 0, /* ttyS0 */ | ||
52 | .nr_tty = 2, | ||
53 | .tty_map = { 3, 0, -1, -1, } /* ttyS0, ..., ttyS3 */ | ||
54 | }; | ||
55 | |||
56 | static void __init ek_map_io(void) | ||
57 | { | ||
58 | /* Initialize processor: 16.367 MHz crystal */ | ||
59 | at91sam9263_initialize(16367660); | ||
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 | at91sam9263_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 | .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, | ||
77 | }; | ||
78 | |||
79 | /* | ||
80 | * USB Device port | ||
81 | */ | ||
82 | static struct at91_udc_data __initdata ek_udc_data = { | ||
83 | .vbus_pin = AT91_PIN_PA25, | ||
84 | .pullup_pin = 0, /* pull-up driven by UDC */ | ||
85 | }; | ||
86 | |||
87 | |||
88 | /* | ||
89 | * SPI devices. | ||
90 | */ | ||
91 | static struct spi_board_info ek_spi_devices[] = { | ||
92 | #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) | ||
93 | { /* DataFlash card */ | ||
94 | .modalias = "mtd_dataflash", | ||
95 | .chip_select = 0, | ||
96 | .max_speed_hz = 15 * 1000 * 1000, | ||
97 | .bus_num = 0, | ||
98 | }, | ||
99 | #endif | ||
100 | }; | ||
101 | |||
102 | |||
103 | /* | ||
104 | * MCI (SD/MMC) | ||
105 | */ | ||
106 | static struct at91_mmc_data __initdata ek_mmc_data = { | ||
107 | .wire4 = 1, | ||
108 | .det_pin = AT91_PIN_PE18, | ||
109 | .wp_pin = AT91_PIN_PE19, | ||
110 | // .vcc_pin = ... not connected | ||
111 | }; | ||
112 | |||
113 | |||
114 | /* | ||
115 | * NAND flash | ||
116 | */ | ||
117 | static struct mtd_partition __initdata ek_nand_partition[] = { | ||
118 | { | ||
119 | .name = "Partition 1", | ||
120 | .offset = 0, | ||
121 | .size = 64 * 1024 * 1024, | ||
122 | }, | ||
123 | { | ||
124 | .name = "Partition 2", | ||
125 | .offset = 64 * 1024 * 1024, | ||
126 | .size = MTDPART_SIZ_FULL, | ||
127 | }, | ||
128 | }; | ||
129 | |||
130 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | ||
131 | { | ||
132 | *num_partitions = ARRAY_SIZE(ek_nand_partition); | ||
133 | return ek_nand_partition; | ||
134 | } | ||
135 | |||
136 | static struct at91_nand_data __initdata ek_nand_data = { | ||
137 | .ale = 21, | ||
138 | .cle = 22, | ||
139 | // .det_pin = ... not connected | ||
140 | .rdy_pin = AT91_PIN_PA22, | ||
141 | .enable_pin = AT91_PIN_PD15, | ||
142 | .partition_info = nand_partitions, | ||
143 | #if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) | ||
144 | .bus_width_16 = 1, | ||
145 | #else | ||
146 | .bus_width_16 = 0, | ||
147 | #endif | ||
148 | }; | ||
149 | |||
150 | |||
151 | static void __init ek_board_init(void) | ||
152 | { | ||
153 | /* Serial */ | ||
154 | at91_add_device_serial(); | ||
155 | /* USB Host */ | ||
156 | at91_add_device_usbh(&ek_usbh_data); | ||
157 | /* USB Device */ | ||
158 | at91_add_device_udc(&ek_udc_data); | ||
159 | /* SPI */ | ||
160 | at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); | ||
161 | /* MMC */ | ||
162 | at91_add_device_mmc(1, &ek_mmc_data); | ||
163 | /* NAND */ | ||
164 | at91_add_device_nand(&ek_nand_data); | ||
165 | } | ||
166 | |||
167 | MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") | ||
168 | /* Maintainer: Atmel */ | ||
169 | .phys_io = AT91_BASE_SYS, | ||
170 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
171 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
172 | .timer = &at91sam926x_timer, | ||
173 | .map_io = ek_map_io, | ||
174 | .init_irq = ek_init_irq, | ||
175 | .init_machine = ek_board_init, | ||
176 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c new file mode 100644 index 000000000000..06c9a0507d0d --- /dev/null +++ b/arch/arm/mach-at91/clock.c | |||
@@ -0,0 +1,640 @@ | |||
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 const 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 | static struct clk *const standard_pmc_clocks[] __initdata = { | ||
529 | /* four primary clocks */ | ||
530 | &clk32k, | ||
531 | &main_clk, | ||
532 | &plla, | ||
533 | &pllb, | ||
534 | |||
535 | /* PLLB children (USB) */ | ||
536 | &udpck, | ||
537 | &uhpck, | ||
538 | |||
539 | /* MCK */ | ||
540 | &mck | ||
541 | }; | ||
542 | |||
543 | int __init at91_clock_init(unsigned long main_clock) | ||
544 | { | ||
545 | unsigned tmp, freq, mckr; | ||
546 | int i; | ||
547 | |||
548 | /* | ||
549 | * When the bootloader initialized the main oscillator correctly, | ||
550 | * there's no problem using the cycle counter. But if it didn't, | ||
551 | * or when using oscillator bypass mode, we must be told the speed | ||
552 | * of the main clock. | ||
553 | */ | ||
554 | if (!main_clock) { | ||
555 | do { | ||
556 | tmp = at91_sys_read(AT91_CKGR_MCFR); | ||
557 | } while (!(tmp & AT91_PMC_MAINRDY)); | ||
558 | main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16); | ||
559 | } | ||
560 | main_clk.rate_hz = main_clock; | ||
561 | |||
562 | /* report if PLLA is more than mildly overclocked */ | ||
563 | plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); | ||
564 | if (plla.rate_hz > 209000000) | ||
565 | pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); | ||
566 | |||
567 | /* | ||
568 | * USB clock init: choose 48 MHz PLLB value, | ||
569 | * disable 48MHz clock during usb peripheral suspend. | ||
570 | * | ||
571 | * REVISIT: assumes MCK doesn't derive from PLLB! | ||
572 | */ | ||
573 | at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; | ||
574 | pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); | ||
575 | if (cpu_is_at91rm9200()) { | ||
576 | uhpck.pmc_mask = AT91RM9200_PMC_UHP; | ||
577 | udpck.pmc_mask = AT91RM9200_PMC_UDP; | ||
578 | at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); | ||
579 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { | ||
580 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; | ||
581 | udpck.pmc_mask = AT91SAM926x_PMC_UDP; | ||
582 | } | ||
583 | at91_sys_write(AT91_CKGR_PLLBR, 0); | ||
584 | |||
585 | udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); | ||
586 | uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); | ||
587 | |||
588 | /* | ||
589 | * MCK and CPU derive from one of those primary clocks. | ||
590 | * For now, assume this parentage won't change. | ||
591 | */ | ||
592 | mckr = at91_sys_read(AT91_PMC_MCKR); | ||
593 | mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); | ||
594 | freq = mck.parent->rate_hz; | ||
595 | freq /= (1 << ((mckr >> 2) & 3)); /* prescale */ | ||
596 | mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */ | ||
597 | |||
598 | /* Register the PMC's standard clocks */ | ||
599 | for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) | ||
600 | list_add_tail(&standard_pmc_clocks[i]->node, &clocks); | ||
601 | |||
602 | /* MCK and CPU clock are "always on" */ | ||
603 | clk_enable(&mck); | ||
604 | |||
605 | printk("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n", | ||
606 | freq / 1000000, (unsigned) mck.rate_hz / 1000000, | ||
607 | (unsigned) main_clock / 1000000, | ||
608 | ((unsigned) main_clock % 1000000) / 1000); | ||
609 | |||
610 | return 0; | ||
611 | } | ||
612 | |||
613 | /* | ||
614 | * Several unused clocks may be active. Turn them off. | ||
615 | */ | ||
616 | static int __init at91_clock_reset(void) | ||
617 | { | ||
618 | unsigned long pcdr = 0; | ||
619 | unsigned long scdr = 0; | ||
620 | struct clk *clk; | ||
621 | |||
622 | list_for_each_entry(clk, &clocks, node) { | ||
623 | if (clk->users > 0) | ||
624 | continue; | ||
625 | |||
626 | if (clk->mode == pmc_periph_mode) | ||
627 | pcdr |= clk->pmc_mask; | ||
628 | |||
629 | if (clk->mode == pmc_sys_mode) | ||
630 | scdr |= clk->pmc_mask; | ||
631 | |||
632 | pr_debug("Clocks: disable unused %s\n", clk->name); | ||
633 | } | ||
634 | |||
635 | at91_sys_write(AT91_PMC_PCDR, pcdr); | ||
636 | at91_sys_write(AT91_PMC_SCDR, scdr); | ||
637 | |||
638 | return 0; | ||
639 | } | ||
640 | late_initcall(at91_clock_reset); | ||
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..bda26221c522 --- /dev/null +++ b/arch/arm/mach-at91/generic.h | |||
@@ -0,0 +1,51 @@ | |||
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 | extern void __init at91sam9263_initialize(unsigned long main_clock); | ||
16 | |||
17 | /* Interrupts */ | ||
18 | extern void __init at91rm9200_init_interrupts(unsigned int priority[]); | ||
19 | extern void __init at91sam9260_init_interrupts(unsigned int priority[]); | ||
20 | extern void __init at91sam9261_init_interrupts(unsigned int priority[]); | ||
21 | extern void __init at91sam9263_init_interrupts(unsigned int priority[]); | ||
22 | extern void __init at91_aic_init(unsigned int priority[]); | ||
23 | |||
24 | /* Timer */ | ||
25 | struct sys_timer; | ||
26 | extern struct sys_timer at91rm9200_timer; | ||
27 | extern struct sys_timer at91sam926x_timer; | ||
28 | |||
29 | /* Clocks */ | ||
30 | extern int __init at91_clock_init(unsigned long main_clock); | ||
31 | struct device; | ||
32 | extern void __init at91_clock_associate(const char *id, struct device *dev, const char *func); | ||
33 | |||
34 | /* Power Management */ | ||
35 | extern void at91_irq_suspend(void); | ||
36 | extern void at91_irq_resume(void); | ||
37 | |||
38 | /* GPIO */ | ||
39 | #define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ | ||
40 | #define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ | ||
41 | |||
42 | struct at91_gpio_bank { | ||
43 | unsigned short id; /* peripheral ID */ | ||
44 | unsigned long offset; /* offset from system peripheral base */ | ||
45 | struct clk *clock; /* associated clock */ | ||
46 | }; | ||
47 | extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); | ||
48 | extern void __init at91_gpio_irq_setup(void); | ||
49 | |||
50 | extern void (*at91_arch_reset)(void); | ||
51 | 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..7b87f3f101b7 --- /dev/null +++ b/arch/arm/mach-at91/gpio.c | |||
@@ -0,0 +1,462 @@ | |||
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 "GPIO" peripheral role. | ||
69 | */ | ||
70 | int __init_or_module at91_set_GPIO_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 | __raw_writel(mask, pio + PIO_IDR); | ||
78 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | ||
79 | __raw_writel(mask, pio + PIO_PER); | ||
80 | return 0; | ||
81 | } | ||
82 | EXPORT_SYMBOL(at91_set_GPIO_periph); | ||
83 | |||
84 | |||
85 | /* | ||
86 | * mux the pin to the "A" internal peripheral role. | ||
87 | */ | ||
88 | int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup) | ||
89 | { | ||
90 | void __iomem *pio = pin_to_controller(pin); | ||
91 | unsigned mask = pin_to_mask(pin); | ||
92 | |||
93 | if (!pio) | ||
94 | return -EINVAL; | ||
95 | |||
96 | __raw_writel(mask, pio + PIO_IDR); | ||
97 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | ||
98 | __raw_writel(mask, pio + PIO_ASR); | ||
99 | __raw_writel(mask, pio + PIO_PDR); | ||
100 | return 0; | ||
101 | } | ||
102 | EXPORT_SYMBOL(at91_set_A_periph); | ||
103 | |||
104 | |||
105 | /* | ||
106 | * mux the pin to the "B" internal peripheral role. | ||
107 | */ | ||
108 | int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup) | ||
109 | { | ||
110 | void __iomem *pio = pin_to_controller(pin); | ||
111 | unsigned mask = pin_to_mask(pin); | ||
112 | |||
113 | if (!pio) | ||
114 | return -EINVAL; | ||
115 | |||
116 | __raw_writel(mask, pio + PIO_IDR); | ||
117 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | ||
118 | __raw_writel(mask, pio + PIO_BSR); | ||
119 | __raw_writel(mask, pio + PIO_PDR); | ||
120 | return 0; | ||
121 | } | ||
122 | EXPORT_SYMBOL(at91_set_B_periph); | ||
123 | |||
124 | |||
125 | /* | ||
126 | * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and | ||
127 | * configure it for an input. | ||
128 | */ | ||
129 | int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup) | ||
130 | { | ||
131 | void __iomem *pio = pin_to_controller(pin); | ||
132 | unsigned mask = pin_to_mask(pin); | ||
133 | |||
134 | if (!pio) | ||
135 | return -EINVAL; | ||
136 | |||
137 | __raw_writel(mask, pio + PIO_IDR); | ||
138 | __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); | ||
139 | __raw_writel(mask, pio + PIO_ODR); | ||
140 | __raw_writel(mask, pio + PIO_PER); | ||
141 | return 0; | ||
142 | } | ||
143 | EXPORT_SYMBOL(at91_set_gpio_input); | ||
144 | |||
145 | |||
146 | /* | ||
147 | * mux the pin to the gpio controller (instead of "A" or "B" peripheral), | ||
148 | * and configure it for an output. | ||
149 | */ | ||
150 | int __init_or_module at91_set_gpio_output(unsigned pin, int value) | ||
151 | { | ||
152 | void __iomem *pio = pin_to_controller(pin); | ||
153 | unsigned mask = pin_to_mask(pin); | ||
154 | |||
155 | if (!pio) | ||
156 | return -EINVAL; | ||
157 | |||
158 | __raw_writel(mask, pio + PIO_IDR); | ||
159 | __raw_writel(mask, pio + PIO_PUDR); | ||
160 | __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); | ||
161 | __raw_writel(mask, pio + PIO_OER); | ||
162 | __raw_writel(mask, pio + PIO_PER); | ||
163 | return 0; | ||
164 | } | ||
165 | EXPORT_SYMBOL(at91_set_gpio_output); | ||
166 | |||
167 | |||
168 | /* | ||
169 | * enable/disable the glitch filter; mostly used with IRQ handling. | ||
170 | */ | ||
171 | int __init_or_module at91_set_deglitch(unsigned pin, int is_on) | ||
172 | { | ||
173 | void __iomem *pio = pin_to_controller(pin); | ||
174 | unsigned mask = pin_to_mask(pin); | ||
175 | |||
176 | if (!pio) | ||
177 | return -EINVAL; | ||
178 | __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); | ||
179 | return 0; | ||
180 | } | ||
181 | EXPORT_SYMBOL(at91_set_deglitch); | ||
182 | |||
183 | /* | ||
184 | * enable/disable the multi-driver; This is only valid for output and | ||
185 | * allows the output pin to run as an open collector output. | ||
186 | */ | ||
187 | int __init_or_module at91_set_multi_drive(unsigned pin, int is_on) | ||
188 | { | ||
189 | void __iomem *pio = pin_to_controller(pin); | ||
190 | unsigned mask = pin_to_mask(pin); | ||
191 | |||
192 | if (!pio) | ||
193 | return -EINVAL; | ||
194 | |||
195 | __raw_writel(mask, pio + (is_on ? PIO_MDER : PIO_MDDR)); | ||
196 | return 0; | ||
197 | } | ||
198 | EXPORT_SYMBOL(at91_set_multi_drive); | ||
199 | |||
200 | /*--------------------------------------------------------------------------*/ | ||
201 | |||
202 | /* new-style GPIO calls; these expect at91_set_GPIO_periph to have been | ||
203 | * called, and maybe at91_set_multi_drive() for putout pins. | ||
204 | */ | ||
205 | |||
206 | int gpio_direction_input(unsigned pin) | ||
207 | { | ||
208 | void __iomem *pio = pin_to_controller(pin); | ||
209 | unsigned mask = pin_to_mask(pin); | ||
210 | |||
211 | if (!pio || !(__raw_readl(pio + PIO_PSR) & mask)) | ||
212 | return -EINVAL; | ||
213 | __raw_writel(mask, pio + PIO_OER); | ||
214 | return 0; | ||
215 | } | ||
216 | EXPORT_SYMBOL(gpio_direction_input); | ||
217 | |||
218 | int gpio_direction_output(unsigned pin) | ||
219 | { | ||
220 | void __iomem *pio = pin_to_controller(pin); | ||
221 | unsigned mask = pin_to_mask(pin); | ||
222 | |||
223 | if (!pio || !(__raw_readl(pio + PIO_PSR) & mask)) | ||
224 | return -EINVAL; | ||
225 | __raw_writel(mask, pio + PIO_OER); | ||
226 | return 0; | ||
227 | } | ||
228 | EXPORT_SYMBOL(gpio_direction_output); | ||
229 | |||
230 | /*--------------------------------------------------------------------------*/ | ||
231 | |||
232 | /* | ||
233 | * assuming the pin is muxed as a gpio output, set its value. | ||
234 | */ | ||
235 | int at91_set_gpio_value(unsigned pin, int value) | ||
236 | { | ||
237 | void __iomem *pio = pin_to_controller(pin); | ||
238 | unsigned mask = pin_to_mask(pin); | ||
239 | |||
240 | if (!pio) | ||
241 | return -EINVAL; | ||
242 | __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); | ||
243 | return 0; | ||
244 | } | ||
245 | EXPORT_SYMBOL(at91_set_gpio_value); | ||
246 | |||
247 | |||
248 | /* | ||
249 | * read the pin's value (works even if it's not muxed as a gpio). | ||
250 | */ | ||
251 | int at91_get_gpio_value(unsigned pin) | ||
252 | { | ||
253 | void __iomem *pio = pin_to_controller(pin); | ||
254 | unsigned mask = pin_to_mask(pin); | ||
255 | u32 pdsr; | ||
256 | |||
257 | if (!pio) | ||
258 | return -EINVAL; | ||
259 | pdsr = __raw_readl(pio + PIO_PDSR); | ||
260 | return (pdsr & mask) != 0; | ||
261 | } | ||
262 | EXPORT_SYMBOL(at91_get_gpio_value); | ||
263 | |||
264 | /*--------------------------------------------------------------------------*/ | ||
265 | |||
266 | #ifdef CONFIG_PM | ||
267 | |||
268 | static u32 wakeups[MAX_GPIO_BANKS]; | ||
269 | static u32 backups[MAX_GPIO_BANKS]; | ||
270 | |||
271 | static int gpio_irq_set_wake(unsigned pin, unsigned state) | ||
272 | { | ||
273 | unsigned mask = pin_to_mask(pin); | ||
274 | unsigned bank = (pin - PIN_BASE) / 32; | ||
275 | |||
276 | if (unlikely(bank >= MAX_GPIO_BANKS)) | ||
277 | return -EINVAL; | ||
278 | |||
279 | if (state) | ||
280 | wakeups[bank] |= mask; | ||
281 | else | ||
282 | wakeups[bank] &= ~mask; | ||
283 | |||
284 | set_irq_wake(gpio[bank].id, state); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | void at91_gpio_suspend(void) | ||
290 | { | ||
291 | int i; | ||
292 | |||
293 | for (i = 0; i < gpio_banks; i++) { | ||
294 | u32 pio = gpio[i].offset; | ||
295 | |||
296 | backups[i] = at91_sys_read(pio + PIO_IMR); | ||
297 | at91_sys_write(pio + PIO_IDR, backups[i]); | ||
298 | at91_sys_write(pio + PIO_IER, wakeups[i]); | ||
299 | |||
300 | if (!wakeups[i]) | ||
301 | clk_disable(gpio[i].clock); | ||
302 | else { | ||
303 | #ifdef CONFIG_PM_DEBUG | ||
304 | printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); | ||
305 | #endif | ||
306 | } | ||
307 | } | ||
308 | } | ||
309 | |||
310 | void at91_gpio_resume(void) | ||
311 | { | ||
312 | int i; | ||
313 | |||
314 | for (i = 0; i < gpio_banks; i++) { | ||
315 | u32 pio = gpio[i].offset; | ||
316 | |||
317 | if (!wakeups[i]) | ||
318 | clk_enable(gpio[i].clock); | ||
319 | |||
320 | at91_sys_write(pio + PIO_IDR, wakeups[i]); | ||
321 | at91_sys_write(pio + PIO_IER, backups[i]); | ||
322 | } | ||
323 | } | ||
324 | |||
325 | #else | ||
326 | #define gpio_irq_set_wake NULL | ||
327 | #endif | ||
328 | |||
329 | |||
330 | /* Several AIC controller irqs are dispatched through this GPIO handler. | ||
331 | * To use any AT91_PIN_* as an externally triggered IRQ, first call | ||
332 | * at91_set_gpio_input() then maybe enable its glitch filter. | ||
333 | * Then just request_irq() with the pin ID; it works like any ARM IRQ | ||
334 | * handler, though it always triggers on rising and falling edges. | ||
335 | * | ||
336 | * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after | ||
337 | * configuring them with at91_set_a_periph() or at91_set_b_periph(). | ||
338 | * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering. | ||
339 | */ | ||
340 | |||
341 | static void gpio_irq_mask(unsigned pin) | ||
342 | { | ||
343 | void __iomem *pio = pin_to_controller(pin); | ||
344 | unsigned mask = pin_to_mask(pin); | ||
345 | |||
346 | if (pio) | ||
347 | __raw_writel(mask, pio + PIO_IDR); | ||
348 | } | ||
349 | |||
350 | static void gpio_irq_unmask(unsigned pin) | ||
351 | { | ||
352 | void __iomem *pio = pin_to_controller(pin); | ||
353 | unsigned mask = pin_to_mask(pin); | ||
354 | |||
355 | if (pio) | ||
356 | __raw_writel(mask, pio + PIO_IER); | ||
357 | } | ||
358 | |||
359 | static int gpio_irq_type(unsigned pin, unsigned type) | ||
360 | { | ||
361 | return (type == IRQT_BOTHEDGE) ? 0 : -EINVAL; | ||
362 | } | ||
363 | |||
364 | static struct irq_chip gpio_irqchip = { | ||
365 | .name = "GPIO", | ||
366 | .mask = gpio_irq_mask, | ||
367 | .unmask = gpio_irq_unmask, | ||
368 | .set_type = gpio_irq_type, | ||
369 | .set_wake = gpio_irq_set_wake, | ||
370 | }; | ||
371 | |||
372 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
373 | { | ||
374 | unsigned pin; | ||
375 | struct irq_desc *gpio; | ||
376 | void __iomem *pio; | ||
377 | u32 isr; | ||
378 | |||
379 | pio = get_irq_chip_data(irq); | ||
380 | |||
381 | /* temporarily mask (level sensitive) parent IRQ */ | ||
382 | desc->chip->ack(irq); | ||
383 | for (;;) { | ||
384 | /* reading ISR acks the pending (edge triggered) GPIO interrupt */ | ||
385 | isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR); | ||
386 | if (!isr) | ||
387 | break; | ||
388 | |||
389 | pin = (unsigned) get_irq_data(irq); | ||
390 | gpio = &irq_desc[pin]; | ||
391 | |||
392 | while (isr) { | ||
393 | if (isr & 1) { | ||
394 | if (unlikely(gpio->depth)) { | ||
395 | /* | ||
396 | * The core ARM interrupt handler lazily disables IRQs so | ||
397 | * another IRQ must be generated before it actually gets | ||
398 | * here to be disabled on the GPIO controller. | ||
399 | */ | ||
400 | gpio_irq_mask(pin); | ||
401 | } | ||
402 | else | ||
403 | desc_handle_irq(pin, gpio); | ||
404 | } | ||
405 | pin++; | ||
406 | gpio++; | ||
407 | isr >>= 1; | ||
408 | } | ||
409 | } | ||
410 | desc->chip->unmask(irq); | ||
411 | /* now it may re-trigger */ | ||
412 | } | ||
413 | |||
414 | /*--------------------------------------------------------------------------*/ | ||
415 | |||
416 | /* | ||
417 | * Called from the processor-specific init to enable GPIO interrupt support. | ||
418 | */ | ||
419 | void __init at91_gpio_irq_setup(void) | ||
420 | { | ||
421 | unsigned pioc, pin; | ||
422 | |||
423 | for (pioc = 0, pin = PIN_BASE; | ||
424 | pioc < gpio_banks; | ||
425 | pioc++) { | ||
426 | void __iomem *controller; | ||
427 | unsigned id = gpio[pioc].id; | ||
428 | unsigned i; | ||
429 | |||
430 | clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */ | ||
431 | |||
432 | controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset; | ||
433 | __raw_writel(~0, controller + PIO_IDR); | ||
434 | |||
435 | set_irq_data(id, (void *) pin); | ||
436 | set_irq_chip_data(id, controller); | ||
437 | |||
438 | for (i = 0; i < 32; i++, pin++) { | ||
439 | /* | ||
440 | * Can use the "simple" and not "edge" handler since it's | ||
441 | * shorter, and the AIC handles interupts sanely. | ||
442 | */ | ||
443 | set_irq_chip(pin, &gpio_irqchip); | ||
444 | set_irq_handler(pin, handle_simple_irq); | ||
445 | set_irq_flags(pin, IRQF_VALID); | ||
446 | } | ||
447 | |||
448 | set_irq_chained_handler(id, gpio_irq_handler); | ||
449 | } | ||
450 | pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); | ||
451 | } | ||
452 | |||
453 | /* | ||
454 | * Called from the processor-specific init to enable GPIO pin support. | ||
455 | */ | ||
456 | void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) | ||
457 | { | ||
458 | BUG_ON(nr_banks > MAX_GPIO_BANKS); | ||
459 | |||
460 | gpio = data; | ||
461 | gpio_banks = nr_banks; | ||
462 | } | ||
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..0d5144973988 --- /dev/null +++ b/arch/arm/mach-at91/leds.c | |||
@@ -0,0 +1,95 @@ | |||
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 | leds_event = at91_leds_event; | ||
90 | |||
91 | leds_event(led_start); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | __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..b49bfda53d7f --- /dev/null +++ b/arch/arm/mach-at91/pm.c | |||
@@ -0,0 +1,229 @@ | |||
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 | } else if (cpu_is_at91sam9263()) { | ||
84 | #warning "Check SAM9263 USB clocks" | ||
85 | } | ||
86 | |||
87 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | ||
88 | /* PCK0..PCK3 must be disabled, or configured to use clk32k */ | ||
89 | for (i = 0; i < 4; i++) { | ||
90 | u32 css; | ||
91 | |||
92 | if ((scsr & (AT91_PMC_PCK0 << i)) == 0) | ||
93 | continue; | ||
94 | |||
95 | css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; | ||
96 | if (css != AT91_PMC_CSS_SLOW) { | ||
97 | pr_debug("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); | ||
98 | return 0; | ||
99 | } | ||
100 | } | ||
101 | #endif | ||
102 | |||
103 | return 1; | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * Call this from platform driver suspend() to see how deeply to suspend. | ||
108 | * For example, some controllers (like OHCI) need one of the PLL clocks | ||
109 | * in order to act as a wakeup source, and those are not available when | ||
110 | * going into slow clock mode. | ||
111 | * | ||
112 | * REVISIT: generalize as clk_will_be_available(clk)? Other platforms have | ||
113 | * the very same problem (but not using at91 main_clk), and it'd be better | ||
114 | * to add one generic API rather than lots of platform-specific ones. | ||
115 | */ | ||
116 | int at91_suspend_entering_slow_clock(void) | ||
117 | { | ||
118 | return (target_state == PM_SUSPEND_MEM); | ||
119 | } | ||
120 | EXPORT_SYMBOL(at91_suspend_entering_slow_clock); | ||
121 | |||
122 | |||
123 | static void (*slow_clock)(void); | ||
124 | |||
125 | |||
126 | static int at91_pm_enter(suspend_state_t state) | ||
127 | { | ||
128 | at91_gpio_suspend(); | ||
129 | at91_irq_suspend(); | ||
130 | |||
131 | pr_debug("AT91: PM - wake mask %08x, pm state %d\n", | ||
132 | /* remember all the always-wake irqs */ | ||
133 | (at91_sys_read(AT91_PMC_PCSR) | ||
134 | | (1 << AT91_ID_FIQ) | ||
135 | | (1 << AT91_ID_SYS) | ||
136 | | (at91_extern_irq)) | ||
137 | & at91_sys_read(AT91_AIC_IMR), | ||
138 | state); | ||
139 | |||
140 | switch (state) { | ||
141 | /* | ||
142 | * Suspend-to-RAM is like STANDBY plus slow clock mode, so | ||
143 | * drivers must suspend more deeply: only the master clock | ||
144 | * controller may be using the main oscillator. | ||
145 | */ | ||
146 | case PM_SUSPEND_MEM: | ||
147 | /* | ||
148 | * Ensure that clocks are in a valid state. | ||
149 | */ | ||
150 | if (!at91_pm_verify_clocks()) | ||
151 | goto error; | ||
152 | |||
153 | /* | ||
154 | * Enter slow clock mode by switching over to clk32k and | ||
155 | * turning off the main oscillator; reverse on wakeup. | ||
156 | */ | ||
157 | if (slow_clock) { | ||
158 | slow_clock(); | ||
159 | break; | ||
160 | } else { | ||
161 | /* DEVELOPMENT ONLY */ | ||
162 | pr_info("AT91: PM - no slow clock mode yet ...\n"); | ||
163 | /* FALLTHROUGH leaving master clock alone */ | ||
164 | } | ||
165 | |||
166 | /* | ||
167 | * STANDBY mode has *all* drivers suspended; ignores irqs not | ||
168 | * marked as 'wakeup' event sources; and reduces DRAM power. | ||
169 | * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and | ||
170 | * nothing fancy done with main or cpu clocks. | ||
171 | */ | ||
172 | case PM_SUSPEND_STANDBY: | ||
173 | /* | ||
174 | * NOTE: the Wait-for-Interrupt instruction needs to be | ||
175 | * in icache so the SDRAM stays in self-refresh mode until | ||
176 | * the wakeup IRQ occurs. | ||
177 | */ | ||
178 | asm("b 1f; .align 5; 1:"); | ||
179 | asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ | ||
180 | at91_sys_write(AT91_SDRAMC_SRR, 1); /* self-refresh mode */ | ||
181 | /* fall though to next state */ | ||
182 | |||
183 | case PM_SUSPEND_ON: | ||
184 | asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */ | ||
185 | break; | ||
186 | |||
187 | default: | ||
188 | pr_debug("AT91: PM - bogus suspend state %d\n", state); | ||
189 | goto error; | ||
190 | } | ||
191 | |||
192 | pr_debug("AT91: PM - wakeup %08x\n", | ||
193 | at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); | ||
194 | |||
195 | error: | ||
196 | target_state = PM_SUSPEND_ON; | ||
197 | at91_irq_resume(); | ||
198 | at91_gpio_resume(); | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | |||
203 | static struct pm_ops at91_pm_ops ={ | ||
204 | .pm_disk_mode = 0, | ||
205 | .valid = at91_pm_valid_state, | ||
206 | .prepare = at91_pm_prepare, | ||
207 | .enter = at91_pm_enter, | ||
208 | }; | ||
209 | |||
210 | static int __init at91_pm_init(void) | ||
211 | { | ||
212 | printk("AT91: Power Management\n"); | ||
213 | |||
214 | #ifdef CONFIG_AT91_PM_SLOW_CLOCK | ||
215 | /* REVISIT allocations of SRAM should be dynamically managed. | ||
216 | * FIQ handlers and other components will want SRAM/TCM too... | ||
217 | */ | ||
218 | slow_clock = (void *) (AT91_VA_BASE_SRAM + (3 * SZ_4K)); | ||
219 | memcpy(slow_clock, at91rm9200_slow_clock, at91rm9200_slow_clock_sz); | ||
220 | #endif | ||
221 | |||
222 | /* Disable SDRAM low-power mode. Cannot be used with self-refresh. */ | ||
223 | at91_sys_write(AT91_SDRAMC_LPR, 0); | ||
224 | |||
225 | pm_set_ops(&at91_pm_ops); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | arch_initcall(at91_pm_init); | ||