diff options
Diffstat (limited to 'arch/mips/alchemy/common/platform.c')
-rw-r--r-- | arch/mips/alchemy/common/platform.c | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c new file mode 100644 index 000000000000..dc8a67efac28 --- /dev/null +++ b/arch/mips/alchemy/common/platform.c | |||
@@ -0,0 +1,319 @@ | |||
1 | /* | ||
2 | * Platform device support for Au1x00 SoCs. | ||
3 | * | ||
4 | * Copyright 2004, Matt Porter <mporter@kernel.crashing.org> | ||
5 | * | ||
6 | * (C) Copyright Embedded Alley Solutions, Inc 2005 | ||
7 | * Author: Pantelis Antoniou <pantelis@embeddedalley.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/dma-mapping.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/serial_8250.h> | ||
17 | #include <linux/init.h> | ||
18 | |||
19 | #include <asm/mach-au1x00/au1xxx.h> | ||
20 | |||
21 | #define PORT(_base, _irq) \ | ||
22 | { \ | ||
23 | .iobase = _base, \ | ||
24 | .membase = (void __iomem *)_base,\ | ||
25 | .mapbase = CPHYSADDR(_base), \ | ||
26 | .irq = _irq, \ | ||
27 | .regshift = 2, \ | ||
28 | .iotype = UPIO_AU, \ | ||
29 | .flags = UPF_SKIP_TEST \ | ||
30 | } | ||
31 | |||
32 | static struct plat_serial8250_port au1x00_uart_data[] = { | ||
33 | #if defined(CONFIG_SERIAL_8250_AU1X00) | ||
34 | #if defined(CONFIG_SOC_AU1000) | ||
35 | PORT(UART0_ADDR, AU1000_UART0_INT), | ||
36 | PORT(UART1_ADDR, AU1000_UART1_INT), | ||
37 | PORT(UART2_ADDR, AU1000_UART2_INT), | ||
38 | PORT(UART3_ADDR, AU1000_UART3_INT), | ||
39 | #elif defined(CONFIG_SOC_AU1500) | ||
40 | PORT(UART0_ADDR, AU1500_UART0_INT), | ||
41 | PORT(UART3_ADDR, AU1500_UART3_INT), | ||
42 | #elif defined(CONFIG_SOC_AU1100) | ||
43 | PORT(UART0_ADDR, AU1100_UART0_INT), | ||
44 | PORT(UART1_ADDR, AU1100_UART1_INT), | ||
45 | PORT(UART3_ADDR, AU1100_UART3_INT), | ||
46 | #elif defined(CONFIG_SOC_AU1550) | ||
47 | PORT(UART0_ADDR, AU1550_UART0_INT), | ||
48 | PORT(UART1_ADDR, AU1550_UART1_INT), | ||
49 | PORT(UART3_ADDR, AU1550_UART3_INT), | ||
50 | #elif defined(CONFIG_SOC_AU1200) | ||
51 | PORT(UART0_ADDR, AU1200_UART0_INT), | ||
52 | PORT(UART1_ADDR, AU1200_UART1_INT), | ||
53 | #endif | ||
54 | #endif /* CONFIG_SERIAL_8250_AU1X00 */ | ||
55 | { }, | ||
56 | }; | ||
57 | |||
58 | static struct platform_device au1xx0_uart_device = { | ||
59 | .name = "serial8250", | ||
60 | .id = PLAT8250_DEV_AU1X00, | ||
61 | .dev = { | ||
62 | .platform_data = au1x00_uart_data, | ||
63 | }, | ||
64 | }; | ||
65 | |||
66 | /* OHCI (USB full speed host controller) */ | ||
67 | static struct resource au1xxx_usb_ohci_resources[] = { | ||
68 | [0] = { | ||
69 | .start = USB_OHCI_BASE, | ||
70 | .end = USB_OHCI_BASE + USB_OHCI_LEN - 1, | ||
71 | .flags = IORESOURCE_MEM, | ||
72 | }, | ||
73 | [1] = { | ||
74 | .start = AU1000_USB_HOST_INT, | ||
75 | .end = AU1000_USB_HOST_INT, | ||
76 | .flags = IORESOURCE_IRQ, | ||
77 | }, | ||
78 | }; | ||
79 | |||
80 | /* The dmamask must be set for OHCI to work */ | ||
81 | static u64 ohci_dmamask = DMA_32BIT_MASK; | ||
82 | |||
83 | static struct platform_device au1xxx_usb_ohci_device = { | ||
84 | .name = "au1xxx-ohci", | ||
85 | .id = 0, | ||
86 | .dev = { | ||
87 | .dma_mask = &ohci_dmamask, | ||
88 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
89 | }, | ||
90 | .num_resources = ARRAY_SIZE(au1xxx_usb_ohci_resources), | ||
91 | .resource = au1xxx_usb_ohci_resources, | ||
92 | }; | ||
93 | |||
94 | /*** AU1100 LCD controller ***/ | ||
95 | |||
96 | #ifdef CONFIG_FB_AU1100 | ||
97 | static struct resource au1100_lcd_resources[] = { | ||
98 | [0] = { | ||
99 | .start = LCD_PHYS_ADDR, | ||
100 | .end = LCD_PHYS_ADDR + 0x800 - 1, | ||
101 | .flags = IORESOURCE_MEM, | ||
102 | }, | ||
103 | [1] = { | ||
104 | .start = AU1100_LCD_INT, | ||
105 | .end = AU1100_LCD_INT, | ||
106 | .flags = IORESOURCE_IRQ, | ||
107 | } | ||
108 | }; | ||
109 | |||
110 | static u64 au1100_lcd_dmamask = DMA_32BIT_MASK; | ||
111 | |||
112 | static struct platform_device au1100_lcd_device = { | ||
113 | .name = "au1100-lcd", | ||
114 | .id = 0, | ||
115 | .dev = { | ||
116 | .dma_mask = &au1100_lcd_dmamask, | ||
117 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
118 | }, | ||
119 | .num_resources = ARRAY_SIZE(au1100_lcd_resources), | ||
120 | .resource = au1100_lcd_resources, | ||
121 | }; | ||
122 | #endif | ||
123 | |||
124 | #ifdef CONFIG_SOC_AU1200 | ||
125 | /* EHCI (USB high speed host controller) */ | ||
126 | static struct resource au1xxx_usb_ehci_resources[] = { | ||
127 | [0] = { | ||
128 | .start = USB_EHCI_BASE, | ||
129 | .end = USB_EHCI_BASE + USB_EHCI_LEN - 1, | ||
130 | .flags = IORESOURCE_MEM, | ||
131 | }, | ||
132 | [1] = { | ||
133 | .start = AU1000_USB_HOST_INT, | ||
134 | .end = AU1000_USB_HOST_INT, | ||
135 | .flags = IORESOURCE_IRQ, | ||
136 | }, | ||
137 | }; | ||
138 | |||
139 | static u64 ehci_dmamask = DMA_32BIT_MASK; | ||
140 | |||
141 | static struct platform_device au1xxx_usb_ehci_device = { | ||
142 | .name = "au1xxx-ehci", | ||
143 | .id = 0, | ||
144 | .dev = { | ||
145 | .dma_mask = &ehci_dmamask, | ||
146 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
147 | }, | ||
148 | .num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources), | ||
149 | .resource = au1xxx_usb_ehci_resources, | ||
150 | }; | ||
151 | |||
152 | /* Au1200 UDC (USB gadget controller) */ | ||
153 | static struct resource au1xxx_usb_gdt_resources[] = { | ||
154 | [0] = { | ||
155 | .start = USB_UDC_BASE, | ||
156 | .end = USB_UDC_BASE + USB_UDC_LEN - 1, | ||
157 | .flags = IORESOURCE_MEM, | ||
158 | }, | ||
159 | [1] = { | ||
160 | .start = AU1200_USB_INT, | ||
161 | .end = AU1200_USB_INT, | ||
162 | .flags = IORESOURCE_IRQ, | ||
163 | }, | ||
164 | }; | ||
165 | |||
166 | static struct resource au1xxx_mmc_resources[] = { | ||
167 | [0] = { | ||
168 | .start = SD0_PHYS_ADDR, | ||
169 | .end = SD0_PHYS_ADDR + 0x7ffff, | ||
170 | .flags = IORESOURCE_MEM, | ||
171 | }, | ||
172 | [1] = { | ||
173 | .start = SD1_PHYS_ADDR, | ||
174 | .end = SD1_PHYS_ADDR + 0x7ffff, | ||
175 | .flags = IORESOURCE_MEM, | ||
176 | }, | ||
177 | [2] = { | ||
178 | .start = AU1200_SD_INT, | ||
179 | .end = AU1200_SD_INT, | ||
180 | .flags = IORESOURCE_IRQ, | ||
181 | } | ||
182 | }; | ||
183 | |||
184 | static u64 udc_dmamask = DMA_32BIT_MASK; | ||
185 | |||
186 | static struct platform_device au1xxx_usb_gdt_device = { | ||
187 | .name = "au1xxx-udc", | ||
188 | .id = 0, | ||
189 | .dev = { | ||
190 | .dma_mask = &udc_dmamask, | ||
191 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
192 | }, | ||
193 | .num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources), | ||
194 | .resource = au1xxx_usb_gdt_resources, | ||
195 | }; | ||
196 | |||
197 | /* Au1200 UOC (USB OTG controller) */ | ||
198 | static struct resource au1xxx_usb_otg_resources[] = { | ||
199 | [0] = { | ||
200 | .start = USB_UOC_BASE, | ||
201 | .end = USB_UOC_BASE + USB_UOC_LEN - 1, | ||
202 | .flags = IORESOURCE_MEM, | ||
203 | }, | ||
204 | [1] = { | ||
205 | .start = AU1200_USB_INT, | ||
206 | .end = AU1200_USB_INT, | ||
207 | .flags = IORESOURCE_IRQ, | ||
208 | }, | ||
209 | }; | ||
210 | |||
211 | static u64 uoc_dmamask = DMA_32BIT_MASK; | ||
212 | |||
213 | static struct platform_device au1xxx_usb_otg_device = { | ||
214 | .name = "au1xxx-uoc", | ||
215 | .id = 0, | ||
216 | .dev = { | ||
217 | .dma_mask = &uoc_dmamask, | ||
218 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
219 | }, | ||
220 | .num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources), | ||
221 | .resource = au1xxx_usb_otg_resources, | ||
222 | }; | ||
223 | |||
224 | static struct resource au1200_lcd_resources[] = { | ||
225 | [0] = { | ||
226 | .start = LCD_PHYS_ADDR, | ||
227 | .end = LCD_PHYS_ADDR + 0x800 - 1, | ||
228 | .flags = IORESOURCE_MEM, | ||
229 | }, | ||
230 | [1] = { | ||
231 | .start = AU1200_LCD_INT, | ||
232 | .end = AU1200_LCD_INT, | ||
233 | .flags = IORESOURCE_IRQ, | ||
234 | } | ||
235 | }; | ||
236 | |||
237 | static u64 au1200_lcd_dmamask = DMA_32BIT_MASK; | ||
238 | |||
239 | static struct platform_device au1200_lcd_device = { | ||
240 | .name = "au1200-lcd", | ||
241 | .id = 0, | ||
242 | .dev = { | ||
243 | .dma_mask = &au1200_lcd_dmamask, | ||
244 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
245 | }, | ||
246 | .num_resources = ARRAY_SIZE(au1200_lcd_resources), | ||
247 | .resource = au1200_lcd_resources, | ||
248 | }; | ||
249 | |||
250 | static u64 au1xxx_mmc_dmamask = DMA_32BIT_MASK; | ||
251 | |||
252 | static struct platform_device au1xxx_mmc_device = { | ||
253 | .name = "au1xxx-mmc", | ||
254 | .id = 0, | ||
255 | .dev = { | ||
256 | .dma_mask = &au1xxx_mmc_dmamask, | ||
257 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
258 | }, | ||
259 | .num_resources = ARRAY_SIZE(au1xxx_mmc_resources), | ||
260 | .resource = au1xxx_mmc_resources, | ||
261 | }; | ||
262 | #endif /* #ifdef CONFIG_SOC_AU1200 */ | ||
263 | |||
264 | static struct platform_device au1x00_pcmcia_device = { | ||
265 | .name = "au1x00-pcmcia", | ||
266 | .id = 0, | ||
267 | }; | ||
268 | |||
269 | /* All Alchemy demoboards with I2C have this #define in their headers */ | ||
270 | #ifdef SMBUS_PSC_BASE | ||
271 | static struct resource pbdb_smbus_resources[] = { | ||
272 | { | ||
273 | .start = CPHYSADDR(SMBUS_PSC_BASE), | ||
274 | .end = CPHYSADDR(SMBUS_PSC_BASE + 0xfffff), | ||
275 | .flags = IORESOURCE_MEM, | ||
276 | }, | ||
277 | }; | ||
278 | |||
279 | static struct platform_device pbdb_smbus_device = { | ||
280 | .name = "au1xpsc_smbus", | ||
281 | .id = 0, /* bus number */ | ||
282 | .num_resources = ARRAY_SIZE(pbdb_smbus_resources), | ||
283 | .resource = pbdb_smbus_resources, | ||
284 | }; | ||
285 | #endif | ||
286 | |||
287 | static struct platform_device *au1xxx_platform_devices[] __initdata = { | ||
288 | &au1xx0_uart_device, | ||
289 | &au1xxx_usb_ohci_device, | ||
290 | &au1x00_pcmcia_device, | ||
291 | #ifdef CONFIG_FB_AU1100 | ||
292 | &au1100_lcd_device, | ||
293 | #endif | ||
294 | #ifdef CONFIG_SOC_AU1200 | ||
295 | &au1xxx_usb_ehci_device, | ||
296 | &au1xxx_usb_gdt_device, | ||
297 | &au1xxx_usb_otg_device, | ||
298 | &au1200_lcd_device, | ||
299 | &au1xxx_mmc_device, | ||
300 | #endif | ||
301 | #ifdef SMBUS_PSC_BASE | ||
302 | &pbdb_smbus_device, | ||
303 | #endif | ||
304 | }; | ||
305 | |||
306 | static int __init au1xxx_platform_init(void) | ||
307 | { | ||
308 | unsigned int uartclk = get_au1x00_uart_baud_base() * 16; | ||
309 | int i; | ||
310 | |||
311 | /* Fill up uartclk. */ | ||
312 | for (i = 0; au1x00_uart_data[i].flags; i++) | ||
313 | au1x00_uart_data[i].uartclk = uartclk; | ||
314 | |||
315 | return platform_add_devices(au1xxx_platform_devices, | ||
316 | ARRAY_SIZE(au1xxx_platform_devices)); | ||
317 | } | ||
318 | |||
319 | arch_initcall(au1xxx_platform_init); | ||