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);
320