• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/mips/alchemy/common/
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/etherdevice.h>
16#include <linux/platform_device.h>
17#include <linux/serial_8250.h>
18#include <linux/init.h>
19
20#include <asm/mach-au1x00/au1xxx.h>
21#include <asm/mach-au1x00/au1xxx_dbdma.h>
22#include <asm/mach-au1x00/au1100_mmc.h>
23#include <asm/mach-au1x00/au1xxx_eth.h>
24
25#include <prom.h>
26
27#define PORT(_base, _irq)					\
28	{							\
29		.mapbase	= _base,			\
30		.irq		= _irq,				\
31		.regshift	= 2,				\
32		.iotype		= UPIO_AU,			\
33		.flags		= UPF_SKIP_TEST | UPF_IOREMAP |	\
34				  UPF_FIXED_TYPE,		\
35		.type		= PORT_16550A,			\
36	}
37
38static struct plat_serial8250_port au1x00_uart_data[] = {
39#if defined(CONFIG_SOC_AU1000)
40	PORT(UART0_PHYS_ADDR, AU1000_UART0_INT),
41	PORT(UART1_PHYS_ADDR, AU1000_UART1_INT),
42	PORT(UART2_PHYS_ADDR, AU1000_UART2_INT),
43	PORT(UART3_PHYS_ADDR, AU1000_UART3_INT),
44#elif defined(CONFIG_SOC_AU1500)
45	PORT(UART0_PHYS_ADDR, AU1500_UART0_INT),
46	PORT(UART3_PHYS_ADDR, AU1500_UART3_INT),
47#elif defined(CONFIG_SOC_AU1100)
48	PORT(UART0_PHYS_ADDR, AU1100_UART0_INT),
49	PORT(UART1_PHYS_ADDR, AU1100_UART1_INT),
50	PORT(UART3_PHYS_ADDR, AU1100_UART3_INT),
51#elif defined(CONFIG_SOC_AU1550)
52	PORT(UART0_PHYS_ADDR, AU1550_UART0_INT),
53	PORT(UART1_PHYS_ADDR, AU1550_UART1_INT),
54	PORT(UART3_PHYS_ADDR, AU1550_UART3_INT),
55#elif defined(CONFIG_SOC_AU1200)
56	PORT(UART0_PHYS_ADDR, AU1200_UART0_INT),
57	PORT(UART1_PHYS_ADDR, AU1200_UART1_INT),
58#endif
59	{ },
60};
61
62static struct platform_device au1xx0_uart_device = {
63	.name			= "serial8250",
64	.id			= PLAT8250_DEV_AU1X00,
65	.dev			= {
66		.platform_data	= au1x00_uart_data,
67	},
68};
69
70/* OHCI (USB full speed host controller) */
71static struct resource au1xxx_usb_ohci_resources[] = {
72	[0] = {
73		.start		= USB_OHCI_BASE,
74		.end		= USB_OHCI_BASE + USB_OHCI_LEN - 1,
75		.flags		= IORESOURCE_MEM,
76	},
77	[1] = {
78		.start		= FOR_PLATFORM_C_USB_HOST_INT,
79		.end		= FOR_PLATFORM_C_USB_HOST_INT,
80		.flags		= IORESOURCE_IRQ,
81	},
82};
83
84/* The dmamask must be set for OHCI to work */
85static u64 ohci_dmamask = DMA_BIT_MASK(32);
86
87static struct platform_device au1xxx_usb_ohci_device = {
88	.name		= "au1xxx-ohci",
89	.id		= 0,
90	.dev = {
91		.dma_mask		= &ohci_dmamask,
92		.coherent_dma_mask	= DMA_BIT_MASK(32),
93	},
94	.num_resources	= ARRAY_SIZE(au1xxx_usb_ohci_resources),
95	.resource	= au1xxx_usb_ohci_resources,
96};
97
98/*** AU1100 LCD controller ***/
99
100#ifdef CONFIG_FB_AU1100
101static struct resource au1100_lcd_resources[] = {
102	[0] = {
103		.start          = LCD_PHYS_ADDR,
104		.end            = LCD_PHYS_ADDR + 0x800 - 1,
105		.flags          = IORESOURCE_MEM,
106	},
107	[1] = {
108		.start          = AU1100_LCD_INT,
109		.end            = AU1100_LCD_INT,
110		.flags          = IORESOURCE_IRQ,
111	}
112};
113
114static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
115
116static struct platform_device au1100_lcd_device = {
117	.name           = "au1100-lcd",
118	.id             = 0,
119	.dev = {
120		.dma_mask               = &au1100_lcd_dmamask,
121		.coherent_dma_mask      = DMA_BIT_MASK(32),
122	},
123	.num_resources  = ARRAY_SIZE(au1100_lcd_resources),
124	.resource       = au1100_lcd_resources,
125};
126#endif
127
128#ifdef CONFIG_SOC_AU1200
129/* EHCI (USB high speed host controller) */
130static struct resource au1xxx_usb_ehci_resources[] = {
131	[0] = {
132		.start		= USB_EHCI_BASE,
133		.end		= USB_EHCI_BASE + USB_EHCI_LEN - 1,
134		.flags		= IORESOURCE_MEM,
135	},
136	[1] = {
137		.start		= AU1200_USB_INT,
138		.end		= AU1200_USB_INT,
139		.flags		= IORESOURCE_IRQ,
140	},
141};
142
143static u64 ehci_dmamask = DMA_BIT_MASK(32);
144
145static struct platform_device au1xxx_usb_ehci_device = {
146	.name		= "au1xxx-ehci",
147	.id		= 0,
148	.dev = {
149		.dma_mask		= &ehci_dmamask,
150		.coherent_dma_mask	= DMA_BIT_MASK(32),
151	},
152	.num_resources	= ARRAY_SIZE(au1xxx_usb_ehci_resources),
153	.resource	= au1xxx_usb_ehci_resources,
154};
155
156/* Au1200 UDC (USB gadget controller) */
157static struct resource au1xxx_usb_gdt_resources[] = {
158	[0] = {
159		.start		= USB_UDC_BASE,
160		.end		= USB_UDC_BASE + USB_UDC_LEN - 1,
161		.flags		= IORESOURCE_MEM,
162	},
163	[1] = {
164		.start		= AU1200_USB_INT,
165		.end		= AU1200_USB_INT,
166		.flags		= IORESOURCE_IRQ,
167	},
168};
169
170static u64 udc_dmamask = DMA_BIT_MASK(32);
171
172static struct platform_device au1xxx_usb_gdt_device = {
173	.name		= "au1xxx-udc",
174	.id		= 0,
175	.dev = {
176		.dma_mask		= &udc_dmamask,
177		.coherent_dma_mask	= DMA_BIT_MASK(32),
178	},
179	.num_resources	= ARRAY_SIZE(au1xxx_usb_gdt_resources),
180	.resource	= au1xxx_usb_gdt_resources,
181};
182
183/* Au1200 UOC (USB OTG controller) */
184static struct resource au1xxx_usb_otg_resources[] = {
185	[0] = {
186		.start		= USB_UOC_BASE,
187		.end		= USB_UOC_BASE + USB_UOC_LEN - 1,
188		.flags		= IORESOURCE_MEM,
189	},
190	[1] = {
191		.start		= AU1200_USB_INT,
192		.end		= AU1200_USB_INT,
193		.flags		= IORESOURCE_IRQ,
194	},
195};
196
197static u64 uoc_dmamask = DMA_BIT_MASK(32);
198
199static struct platform_device au1xxx_usb_otg_device = {
200	.name		= "au1xxx-uoc",
201	.id		= 0,
202	.dev = {
203		.dma_mask		= &uoc_dmamask,
204		.coherent_dma_mask	= DMA_BIT_MASK(32),
205	},
206	.num_resources	= ARRAY_SIZE(au1xxx_usb_otg_resources),
207	.resource	= au1xxx_usb_otg_resources,
208};
209
210static struct resource au1200_lcd_resources[] = {
211	[0] = {
212		.start          = LCD_PHYS_ADDR,
213		.end            = LCD_PHYS_ADDR + 0x800 - 1,
214		.flags          = IORESOURCE_MEM,
215	},
216	[1] = {
217		.start          = AU1200_LCD_INT,
218		.end            = AU1200_LCD_INT,
219		.flags          = IORESOURCE_IRQ,
220	}
221};
222
223static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
224
225static struct platform_device au1200_lcd_device = {
226	.name           = "au1200-lcd",
227	.id             = 0,
228	.dev = {
229		.dma_mask               = &au1200_lcd_dmamask,
230		.coherent_dma_mask      = DMA_BIT_MASK(32),
231	},
232	.num_resources  = ARRAY_SIZE(au1200_lcd_resources),
233	.resource       = au1200_lcd_resources,
234};
235
236static u64 au1xxx_mmc_dmamask =  DMA_BIT_MASK(32);
237
238extern struct au1xmmc_platform_data au1xmmc_platdata[2];
239
240static struct resource au1200_mmc0_resources[] = {
241	[0] = {
242		.start          = SD0_PHYS_ADDR,
243		.end            = SD0_PHYS_ADDR + 0x7ffff,
244		.flags          = IORESOURCE_MEM,
245	},
246	[1] = {
247		.start		= AU1200_SD_INT,
248		.end		= AU1200_SD_INT,
249		.flags		= IORESOURCE_IRQ,
250	},
251	[2] = {
252		.start		= DSCR_CMD0_SDMS_TX0,
253		.end		= DSCR_CMD0_SDMS_TX0,
254		.flags		= IORESOURCE_DMA,
255	},
256	[3] = {
257		.start          = DSCR_CMD0_SDMS_RX0,
258		.end		= DSCR_CMD0_SDMS_RX0,
259		.flags          = IORESOURCE_DMA,
260	}
261};
262
263static struct platform_device au1200_mmc0_device = {
264	.name = "au1xxx-mmc",
265	.id = 0,
266	.dev = {
267		.dma_mask		= &au1xxx_mmc_dmamask,
268		.coherent_dma_mask	= DMA_BIT_MASK(32),
269		.platform_data		= &au1xmmc_platdata[0],
270	},
271	.num_resources	= ARRAY_SIZE(au1200_mmc0_resources),
272	.resource	= au1200_mmc0_resources,
273};
274
275#ifndef CONFIG_MIPS_DB1200
276static struct resource au1200_mmc1_resources[] = {
277	[0] = {
278		.start          = SD1_PHYS_ADDR,
279		.end            = SD1_PHYS_ADDR + 0x7ffff,
280		.flags          = IORESOURCE_MEM,
281	},
282	[1] = {
283		.start		= AU1200_SD_INT,
284		.end		= AU1200_SD_INT,
285		.flags		= IORESOURCE_IRQ,
286	},
287	[2] = {
288		.start		= DSCR_CMD0_SDMS_TX1,
289		.end		= DSCR_CMD0_SDMS_TX1,
290		.flags		= IORESOURCE_DMA,
291	},
292	[3] = {
293		.start          = DSCR_CMD0_SDMS_RX1,
294		.end		= DSCR_CMD0_SDMS_RX1,
295		.flags          = IORESOURCE_DMA,
296	}
297};
298
299static struct platform_device au1200_mmc1_device = {
300	.name = "au1xxx-mmc",
301	.id = 1,
302	.dev = {
303		.dma_mask		= &au1xxx_mmc_dmamask,
304		.coherent_dma_mask	= DMA_BIT_MASK(32),
305		.platform_data		= &au1xmmc_platdata[1],
306	},
307	.num_resources	= ARRAY_SIZE(au1200_mmc1_resources),
308	.resource	= au1200_mmc1_resources,
309};
310#endif /* #ifndef CONFIG_MIPS_DB1200 */
311#endif /* #ifdef CONFIG_SOC_AU1200 */
312
313/* All Alchemy demoboards with I2C have this #define in their headers */
314#ifdef SMBUS_PSC_BASE
315static struct resource pbdb_smbus_resources[] = {
316	{
317		.start	= CPHYSADDR(SMBUS_PSC_BASE),
318		.end	= CPHYSADDR(SMBUS_PSC_BASE + 0xfffff),
319		.flags	= IORESOURCE_MEM,
320	},
321};
322
323static struct platform_device pbdb_smbus_device = {
324	.name		= "au1xpsc_smbus",
325	.id		= 0,	/* bus number */
326	.num_resources	= ARRAY_SIZE(pbdb_smbus_resources),
327	.resource	= pbdb_smbus_resources,
328};
329#endif
330
331/* Macro to help defining the Ethernet MAC resources */
332#define MAC_RES(_base, _enable, _irq)			\
333	{						\
334		.start	= CPHYSADDR(_base),		\
335		.end	= CPHYSADDR(_base + 0xffff),	\
336		.flags	= IORESOURCE_MEM,		\
337	},						\
338	{						\
339		.start	= CPHYSADDR(_enable),		\
340		.end	= CPHYSADDR(_enable + 0x3),	\
341		.flags	= IORESOURCE_MEM,		\
342	},						\
343	{						\
344		.start	= _irq,				\
345		.end	= _irq,				\
346		.flags	= IORESOURCE_IRQ		\
347	}
348
349static struct resource au1xxx_eth0_resources[] = {
350#if defined(CONFIG_SOC_AU1000)
351	MAC_RES(AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT),
352#elif defined(CONFIG_SOC_AU1100)
353	MAC_RES(AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT),
354#elif defined(CONFIG_SOC_AU1550)
355	MAC_RES(AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT),
356#elif defined(CONFIG_SOC_AU1500)
357	MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT),
358#endif
359};
360
361
362static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
363	.phy1_search_mac0 = 1,
364};
365
366static struct platform_device au1xxx_eth0_device = {
367	.name		= "au1000-eth",
368	.id		= 0,
369	.num_resources	= ARRAY_SIZE(au1xxx_eth0_resources),
370	.resource	= au1xxx_eth0_resources,
371	.dev.platform_data = &au1xxx_eth0_platform_data,
372};
373
374#ifndef CONFIG_SOC_AU1100
375static struct resource au1xxx_eth1_resources[] = {
376#if defined(CONFIG_SOC_AU1000)
377	MAC_RES(AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT),
378#elif defined(CONFIG_SOC_AU1550)
379	MAC_RES(AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT),
380#elif defined(CONFIG_SOC_AU1500)
381	MAC_RES(AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT),
382#endif
383};
384
385static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
386	.phy1_search_mac0 = 1,
387};
388
389static struct platform_device au1xxx_eth1_device = {
390	.name		= "au1000-eth",
391	.id		= 1,
392	.num_resources	= ARRAY_SIZE(au1xxx_eth1_resources),
393	.resource	= au1xxx_eth1_resources,
394	.dev.platform_data = &au1xxx_eth1_platform_data,
395};
396#endif
397
398void __init au1xxx_override_eth_cfg(unsigned int port,
399			struct au1000_eth_platform_data *eth_data)
400{
401	if (!eth_data || port > 1)
402		return;
403
404	if (port == 0)
405		memcpy(&au1xxx_eth0_platform_data, eth_data,
406			sizeof(struct au1000_eth_platform_data));
407#ifndef CONFIG_SOC_AU1100
408	else
409		memcpy(&au1xxx_eth1_platform_data, eth_data,
410			sizeof(struct au1000_eth_platform_data));
411#endif
412}
413
414static struct platform_device *au1xxx_platform_devices[] __initdata = {
415	&au1xx0_uart_device,
416	&au1xxx_usb_ohci_device,
417#ifdef CONFIG_FB_AU1100
418	&au1100_lcd_device,
419#endif
420#ifdef CONFIG_SOC_AU1200
421	&au1xxx_usb_ehci_device,
422	&au1xxx_usb_gdt_device,
423	&au1xxx_usb_otg_device,
424	&au1200_lcd_device,
425	&au1200_mmc0_device,
426#ifndef CONFIG_MIPS_DB1200
427	&au1200_mmc1_device,
428#endif
429#endif
430#ifdef SMBUS_PSC_BASE
431	&pbdb_smbus_device,
432#endif
433	&au1xxx_eth0_device,
434};
435
436static int __init au1xxx_platform_init(void)
437{
438	unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
439	int err, i;
440	unsigned char ethaddr[6];
441
442	/* Fill up uartclk. */
443	for (i = 0; au1x00_uart_data[i].flags; i++)
444		au1x00_uart_data[i].uartclk = uartclk;
445
446	/* use firmware-provided mac addr if available and necessary */
447	i = prom_get_ethernet_addr(ethaddr);
448	if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
449		memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
450
451	err = platform_add_devices(au1xxx_platform_devices,
452				   ARRAY_SIZE(au1xxx_platform_devices));
453#ifndef CONFIG_SOC_AU1100
454	ethaddr[5] += 1;	/* next addr for 2nd MAC */
455	if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
456		memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
457
458	/* Register second MAC if enabled in pinfunc */
459	if (!err && !(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2))
460		err = platform_device_register(&au1xxx_eth1_device);
461#endif
462
463	return err;
464}
465
466arch_initcall(au1xxx_platform_init);
467