Linux Audio

Check our new training course

Loading...
v3.1
  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/init.h>
 17#include <linux/platform_device.h>
 18#include <linux/serial_8250.h>
 19#include <linux/slab.h>
 
 
 20
 21#include <asm/mach-au1x00/au1xxx.h>
 22#include <asm/mach-au1x00/au1xxx_dbdma.h>
 23#include <asm/mach-au1x00/au1100_mmc.h>
 24#include <asm/mach-au1x00/au1xxx_eth.h>
 25
 26#include <prom.h>
 27
 28static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
 29			    unsigned int old_state)
 30{
 31#ifdef CONFIG_SERIAL_8250
 32	switch (state) {
 33	case 0:
 34		alchemy_uart_enable(CPHYSADDR(port->membase));
 35		serial8250_do_pm(port, state, old_state);
 36		break;
 37	case 3:		/* power off */
 38		serial8250_do_pm(port, state, old_state);
 39		alchemy_uart_disable(CPHYSADDR(port->membase));
 40		break;
 41	default:
 42		serial8250_do_pm(port, state, old_state);
 43		break;
 44	}
 45#endif
 46}
 47
 48#define PORT(_base, _irq)					\
 49	{							\
 50		.mapbase	= _base,			\
 51		.irq		= _irq,				\
 52		.regshift	= 2,				\
 53		.iotype		= UPIO_AU,			\
 54		.flags		= UPF_SKIP_TEST | UPF_IOREMAP |	\
 55				  UPF_FIXED_TYPE,		\
 56		.type		= PORT_16550A,			\
 57		.pm		= alchemy_8250_pm,		\
 58	}
 59
 60static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = {
 61	[ALCHEMY_CPU_AU1000] = {
 62		PORT(AU1000_UART0_PHYS_ADDR, AU1000_UART0_INT),
 63		PORT(AU1000_UART1_PHYS_ADDR, AU1000_UART1_INT),
 64		PORT(AU1000_UART2_PHYS_ADDR, AU1000_UART2_INT),
 65		PORT(AU1000_UART3_PHYS_ADDR, AU1000_UART3_INT),
 66	},
 67	[ALCHEMY_CPU_AU1500] = {
 68		PORT(AU1000_UART0_PHYS_ADDR, AU1500_UART0_INT),
 69		PORT(AU1000_UART3_PHYS_ADDR, AU1500_UART3_INT),
 70	},
 71	[ALCHEMY_CPU_AU1100] = {
 72		PORT(AU1000_UART0_PHYS_ADDR, AU1100_UART0_INT),
 73		PORT(AU1000_UART1_PHYS_ADDR, AU1100_UART1_INT),
 74		PORT(AU1000_UART3_PHYS_ADDR, AU1100_UART3_INT),
 75	},
 76	[ALCHEMY_CPU_AU1550] = {
 77		PORT(AU1000_UART0_PHYS_ADDR, AU1550_UART0_INT),
 78		PORT(AU1000_UART1_PHYS_ADDR, AU1550_UART1_INT),
 79		PORT(AU1000_UART3_PHYS_ADDR, AU1550_UART3_INT),
 80	},
 81	[ALCHEMY_CPU_AU1200] = {
 82		PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT),
 83		PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT),
 84	},
 
 
 
 
 
 
 85};
 86
 87static struct platform_device au1xx0_uart_device = {
 88	.name			= "serial8250",
 89	.id			= PLAT8250_DEV_AU1X00,
 90};
 91
 92static void __init alchemy_setup_uarts(int ctype)
 93{
 94	unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
 95	int s = sizeof(struct plat_serial8250_port);
 96	int c = alchemy_get_uarts(ctype);
 97	struct plat_serial8250_port *ports;
 
 
 
 
 
 
 
 
 
 
 98
 99	ports = kzalloc(s * (c + 1), GFP_KERNEL);
100	if (!ports) {
101		printk(KERN_INFO "Alchemy: no memory for UART data\n");
102		return;
103	}
104	memcpy(ports, au1x00_uart_data[ctype], s * c);
105	au1xx0_uart_device.dev.platform_data = ports;
106
107	/* Fill up uartclk. */
108	for (s = 0; s < c; s++)
109		ports[s].uartclk = uartclk;
110	if (platform_device_register(&au1xx0_uart_device))
111		printk(KERN_INFO "Alchemy: failed to register UARTs\n");
112}
113
114/* OHCI (USB full speed host controller) */
115static struct resource au1xxx_usb_ohci_resources[] = {
116	[0] = {
117		.start		= USB_OHCI_BASE,
118		.end		= USB_OHCI_BASE + USB_OHCI_LEN - 1,
119		.flags		= IORESOURCE_MEM,
120	},
121	[1] = {
122		.start		= FOR_PLATFORM_C_USB_HOST_INT,
123		.end		= FOR_PLATFORM_C_USB_HOST_INT,
124		.flags		= IORESOURCE_IRQ,
125	},
126};
127
128/* The dmamask must be set for OHCI to work */
129static u64 ohci_dmamask = DMA_BIT_MASK(32);
130
131static struct platform_device au1xxx_usb_ohci_device = {
132	.name		= "au1xxx-ohci",
133	.id		= 0,
134	.dev = {
135		.dma_mask		= &ohci_dmamask,
136		.coherent_dma_mask	= DMA_BIT_MASK(32),
137	},
138	.num_resources	= ARRAY_SIZE(au1xxx_usb_ohci_resources),
139	.resource	= au1xxx_usb_ohci_resources,
140};
141
142/*** AU1100 LCD controller ***/
 
 
 
 
143
144#ifdef CONFIG_FB_AU1100
145static struct resource au1100_lcd_resources[] = {
146	[0] = {
147		.start          = LCD_PHYS_ADDR,
148		.end            = LCD_PHYS_ADDR + 0x800 - 1,
149		.flags          = IORESOURCE_MEM,
150	},
151	[1] = {
152		.start          = AU1100_LCD_INT,
153		.end            = AU1100_LCD_INT,
154		.flags          = IORESOURCE_IRQ,
155	}
156};
157
158static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
159
160static struct platform_device au1100_lcd_device = {
161	.name           = "au1100-lcd",
162	.id             = 0,
163	.dev = {
164		.dma_mask               = &au1100_lcd_dmamask,
165		.coherent_dma_mask      = DMA_BIT_MASK(32),
166	},
167	.num_resources  = ARRAY_SIZE(au1100_lcd_resources),
168	.resource       = au1100_lcd_resources,
169};
170#endif
171
172#ifdef CONFIG_SOC_AU1200
173/* EHCI (USB high speed host controller) */
174static struct resource au1xxx_usb_ehci_resources[] = {
175	[0] = {
176		.start		= USB_EHCI_BASE,
177		.end		= USB_EHCI_BASE + USB_EHCI_LEN - 1,
178		.flags		= IORESOURCE_MEM,
179	},
180	[1] = {
181		.start		= AU1200_USB_INT,
182		.end		= AU1200_USB_INT,
183		.flags		= IORESOURCE_IRQ,
184	},
185};
186
187static u64 ehci_dmamask = DMA_BIT_MASK(32);
 
188
189static struct platform_device au1xxx_usb_ehci_device = {
190	.name		= "au1xxx-ehci",
191	.id		= 0,
192	.dev = {
193		.dma_mask		= &ehci_dmamask,
194		.coherent_dma_mask	= DMA_BIT_MASK(32),
195	},
196	.num_resources	= ARRAY_SIZE(au1xxx_usb_ehci_resources),
197	.resource	= au1xxx_usb_ehci_resources,
198};
199
200/* Au1200 UDC (USB gadget controller) */
201static struct resource au1xxx_usb_gdt_resources[] = {
202	[0] = {
203		.start		= USB_UDC_BASE,
204		.end		= USB_UDC_BASE + USB_UDC_LEN - 1,
205		.flags		= IORESOURCE_MEM,
206	},
207	[1] = {
208		.start		= AU1200_USB_INT,
209		.end		= AU1200_USB_INT,
210		.flags		= IORESOURCE_IRQ,
211	},
212};
213
214static u64 udc_dmamask = DMA_BIT_MASK(32);
 
215
216static struct platform_device au1xxx_usb_gdt_device = {
217	.name		= "au1xxx-udc",
218	.id		= 0,
219	.dev = {
220		.dma_mask		= &udc_dmamask,
221		.coherent_dma_mask	= DMA_BIT_MASK(32),
222	},
223	.num_resources	= ARRAY_SIZE(au1xxx_usb_gdt_resources),
224	.resource	= au1xxx_usb_gdt_resources,
225};
226
227/* Au1200 UOC (USB OTG controller) */
228static struct resource au1xxx_usb_otg_resources[] = {
229	[0] = {
230		.start		= USB_UOC_BASE,
231		.end		= USB_UOC_BASE + USB_UOC_LEN - 1,
232		.flags		= IORESOURCE_MEM,
233	},
234	[1] = {
235		.start		= AU1200_USB_INT,
236		.end		= AU1200_USB_INT,
237		.flags		= IORESOURCE_IRQ,
238	},
239};
240
241static u64 uoc_dmamask = DMA_BIT_MASK(32);
242
243static struct platform_device au1xxx_usb_otg_device = {
244	.name		= "au1xxx-uoc",
245	.id		= 0,
246	.dev = {
247		.dma_mask		= &uoc_dmamask,
248		.coherent_dma_mask	= DMA_BIT_MASK(32),
249	},
250	.num_resources	= ARRAY_SIZE(au1xxx_usb_otg_resources),
251	.resource	= au1xxx_usb_otg_resources,
252};
253
254static struct resource au1200_lcd_resources[] = {
255	[0] = {
256		.start          = LCD_PHYS_ADDR,
257		.end            = LCD_PHYS_ADDR + 0x800 - 1,
258		.flags          = IORESOURCE_MEM,
259	},
260	[1] = {
261		.start          = AU1200_LCD_INT,
262		.end            = AU1200_LCD_INT,
263		.flags          = IORESOURCE_IRQ,
264	}
265};
266
267static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
268
269static struct platform_device au1200_lcd_device = {
270	.name           = "au1200-lcd",
271	.id             = 0,
272	.dev = {
273		.dma_mask               = &au1200_lcd_dmamask,
274		.coherent_dma_mask      = DMA_BIT_MASK(32),
275	},
276	.num_resources  = ARRAY_SIZE(au1200_lcd_resources),
277	.resource       = au1200_lcd_resources,
278};
279
280static u64 au1xxx_mmc_dmamask =  DMA_BIT_MASK(32);
 
281
282extern struct au1xmmc_platform_data au1xmmc_platdata[2];
 
 
 
283
284static struct resource au1200_mmc0_resources[] = {
285	[0] = {
286		.start          = AU1100_SD0_PHYS_ADDR,
287		.end            = AU1100_SD0_PHYS_ADDR + 0xfff,
288		.flags          = IORESOURCE_MEM,
289	},
290	[1] = {
291		.start		= AU1200_SD_INT,
292		.end		= AU1200_SD_INT,
293		.flags		= IORESOURCE_IRQ,
294	},
295	[2] = {
296		.start		= DSCR_CMD0_SDMS_TX0,
297		.end		= DSCR_CMD0_SDMS_TX0,
298		.flags		= IORESOURCE_DMA,
299	},
300	[3] = {
301		.start          = DSCR_CMD0_SDMS_RX0,
302		.end		= DSCR_CMD0_SDMS_RX0,
303		.flags          = IORESOURCE_DMA,
304	}
305};
306
307static struct platform_device au1200_mmc0_device = {
308	.name = "au1xxx-mmc",
309	.id = 0,
310	.dev = {
311		.dma_mask		= &au1xxx_mmc_dmamask,
312		.coherent_dma_mask	= DMA_BIT_MASK(32),
313		.platform_data		= &au1xmmc_platdata[0],
314	},
315	.num_resources	= ARRAY_SIZE(au1200_mmc0_resources),
316	.resource	= au1200_mmc0_resources,
317};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
319#ifndef CONFIG_MIPS_DB1200
320static struct resource au1200_mmc1_resources[] = {
321	[0] = {
322		.start          = AU1100_SD1_PHYS_ADDR,
323		.end            = AU1100_SD1_PHYS_ADDR + 0xfff,
324		.flags          = IORESOURCE_MEM,
325	},
326	[1] = {
327		.start		= AU1200_SD_INT,
328		.end		= AU1200_SD_INT,
329		.flags		= IORESOURCE_IRQ,
330	},
331	[2] = {
332		.start		= DSCR_CMD0_SDMS_TX1,
333		.end		= DSCR_CMD0_SDMS_TX1,
334		.flags		= IORESOURCE_DMA,
335	},
336	[3] = {
337		.start          = DSCR_CMD0_SDMS_RX1,
338		.end		= DSCR_CMD0_SDMS_RX1,
339		.flags          = IORESOURCE_DMA,
340	}
341};
342
343static struct platform_device au1200_mmc1_device = {
344	.name = "au1xxx-mmc",
345	.id = 1,
346	.dev = {
347		.dma_mask		= &au1xxx_mmc_dmamask,
348		.coherent_dma_mask	= DMA_BIT_MASK(32),
349		.platform_data		= &au1xmmc_platdata[1],
350	},
351	.num_resources	= ARRAY_SIZE(au1200_mmc1_resources),
352	.resource	= au1200_mmc1_resources,
353};
354#endif /* #ifndef CONFIG_MIPS_DB1200 */
355#endif /* #ifdef CONFIG_SOC_AU1200 */
356
357/* All Alchemy demoboards with I2C have this #define in their headers */
358#ifdef SMBUS_PSC_BASE
359static struct resource pbdb_smbus_resources[] = {
360	{
361		.start	= CPHYSADDR(SMBUS_PSC_BASE),
362		.end	= CPHYSADDR(SMBUS_PSC_BASE + 0xfffff),
363		.flags	= IORESOURCE_MEM,
364	},
365};
366
367static struct platform_device pbdb_smbus_device = {
368	.name		= "au1xpsc_smbus",
369	.id		= 0,	/* bus number */
370	.num_resources	= ARRAY_SIZE(pbdb_smbus_resources),
371	.resource	= pbdb_smbus_resources,
372};
373#endif
374
375/* Macro to help defining the Ethernet MAC resources */
376#define MAC_RES_COUNT	3	/* MAC regs base, MAC enable reg, MAC INT */
377#define MAC_RES(_base, _enable, _irq)			\
378	{						\
379		.start	= _base,			\
380		.end	= _base + 0xffff,		\
381		.flags	= IORESOURCE_MEM,		\
382	},						\
383	{						\
384		.start	= _enable,			\
385		.end	= _enable + 0x3,		\
386		.flags	= IORESOURCE_MEM,		\
387	},						\
388	{						\
389		.start	= _irq,				\
390		.end	= _irq,				\
391		.flags	= IORESOURCE_IRQ		\
 
 
 
 
 
392	}
393
394static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = {
395	[ALCHEMY_CPU_AU1000] = {
396		MAC_RES(AU1000_MAC0_PHYS_ADDR,
397			AU1000_MACEN_PHYS_ADDR,
398			AU1000_MAC0_DMA_INT)
 
399	},
400	[ALCHEMY_CPU_AU1500] = {
401		MAC_RES(AU1500_MAC0_PHYS_ADDR,
402			AU1500_MACEN_PHYS_ADDR,
403			AU1500_MAC0_DMA_INT)
 
404	},
405	[ALCHEMY_CPU_AU1100] = {
406		MAC_RES(AU1000_MAC0_PHYS_ADDR,
407			AU1000_MACEN_PHYS_ADDR,
408			AU1100_MAC0_DMA_INT)
 
409	},
410	[ALCHEMY_CPU_AU1550] = {
411		MAC_RES(AU1000_MAC0_PHYS_ADDR,
412			AU1000_MACEN_PHYS_ADDR,
413			AU1550_MAC0_DMA_INT)
 
414	},
415};
416
417static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
418	.phy1_search_mac0 = 1,
419};
420
421static struct platform_device au1xxx_eth0_device = {
422	.name		= "au1000-eth",
423	.id		= 0,
424	.num_resources	= MAC_RES_COUNT,
425	.dev.platform_data = &au1xxx_eth0_platform_data,
 
 
 
 
426};
427
428static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = {
429	[ALCHEMY_CPU_AU1000] = {
430		MAC_RES(AU1000_MAC1_PHYS_ADDR,
431			AU1000_MACEN_PHYS_ADDR + 4,
432			AU1000_MAC1_DMA_INT)
 
433	},
434	[ALCHEMY_CPU_AU1500] = {
435		MAC_RES(AU1500_MAC1_PHYS_ADDR,
436			AU1500_MACEN_PHYS_ADDR + 4,
437			AU1500_MAC1_DMA_INT)
 
438	},
439	[ALCHEMY_CPU_AU1550] = {
440		MAC_RES(AU1000_MAC1_PHYS_ADDR,
441			AU1000_MACEN_PHYS_ADDR + 4,
442			AU1550_MAC1_DMA_INT)
 
443	},
444};
445
446static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
447	.phy1_search_mac0 = 1,
448};
449
450static struct platform_device au1xxx_eth1_device = {
451	.name		= "au1000-eth",
452	.id		= 1,
453	.num_resources	= MAC_RES_COUNT,
454	.dev.platform_data = &au1xxx_eth1_platform_data,
 
 
 
 
455};
456
457void __init au1xxx_override_eth_cfg(unsigned int port,
458			struct au1000_eth_platform_data *eth_data)
459{
460	if (!eth_data || port > 1)
461		return;
462
463	if (port == 0)
464		memcpy(&au1xxx_eth0_platform_data, eth_data,
465			sizeof(struct au1000_eth_platform_data));
466	else
467		memcpy(&au1xxx_eth1_platform_data, eth_data,
468			sizeof(struct au1000_eth_platform_data));
469}
470
471static void __init alchemy_setup_macs(int ctype)
472{
473	int ret, i;
474	unsigned char ethaddr[6];
475	struct resource *macres;
476
477	/* Handle 1st MAC */
478	if (alchemy_get_macs(ctype) < 1)
479		return;
480
481	macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
 
482	if (!macres) {
483		printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
484		return;
485	}
486	memcpy(macres, au1xxx_eth0_resources[ctype],
487	       sizeof(struct resource) * MAC_RES_COUNT);
488	au1xxx_eth0_device.resource = macres;
489
490	i = prom_get_ethernet_addr(ethaddr);
491	if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
492		memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
493
494	ret = platform_device_register(&au1xxx_eth0_device);
495	if (ret)
496		printk(KERN_INFO "Alchemy: failed to register MAC0\n");
497
498
499	/* Handle 2nd MAC */
500	if (alchemy_get_macs(ctype) < 2)
501		return;
502
503	macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
 
504	if (!macres) {
505		printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
506		return;
507	}
508	memcpy(macres, au1xxx_eth1_resources[ctype],
509	       sizeof(struct resource) * MAC_RES_COUNT);
510	au1xxx_eth1_device.resource = macres;
511
512	ethaddr[5] += 1;	/* next addr for 2nd MAC */
513	if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
514		memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
515
516	/* Register second MAC if enabled in pinfunc */
517	if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) {
518		ret = platform_device_register(&au1xxx_eth1_device);
519		if (ret)
520			printk(KERN_INFO "Alchemy: failed to register MAC1\n");
521	}
522}
523
524static struct platform_device *au1xxx_platform_devices[] __initdata = {
525	&au1xxx_usb_ohci_device,
526#ifdef CONFIG_FB_AU1100
527	&au1100_lcd_device,
528#endif
529#ifdef CONFIG_SOC_AU1200
530	&au1xxx_usb_ehci_device,
531	&au1xxx_usb_gdt_device,
532	&au1xxx_usb_otg_device,
533	&au1200_lcd_device,
534	&au1200_mmc0_device,
535#ifndef CONFIG_MIPS_DB1200
536	&au1200_mmc1_device,
537#endif
538#endif
539#ifdef SMBUS_PSC_BASE
540	&pbdb_smbus_device,
541#endif
542};
543
544static int __init au1xxx_platform_init(void)
545{
546	int err, ctype = alchemy_get_cputype();
547
548	alchemy_setup_uarts(ctype);
549	alchemy_setup_macs(ctype);
 
550
551	err = platform_add_devices(au1xxx_platform_devices,
552				   ARRAY_SIZE(au1xxx_platform_devices));
553	return err;
554}
555
556arch_initcall(au1xxx_platform_init);
v5.14.15
  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/clk.h>
 15#include <linux/dma-mapping.h>
 16#include <linux/etherdevice.h>
 17#include <linux/init.h>
 18#include <linux/platform_device.h>
 19#include <linux/serial_8250.h>
 20#include <linux/slab.h>
 21#include <linux/usb/ehci_pdriver.h>
 22#include <linux/usb/ohci_pdriver.h>
 23
 24#include <asm/mach-au1x00/au1000.h>
 25#include <asm/mach-au1x00/au1xxx_dbdma.h>
 26#include <asm/mach-au1x00/au1100_mmc.h>
 27#include <asm/mach-au1x00/au1xxx_eth.h>
 28
 29#include <prom.h>
 30
 31static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
 32			    unsigned int old_state)
 33{
 34#ifdef CONFIG_SERIAL_8250
 35	switch (state) {
 36	case 0:
 37		alchemy_uart_enable(CPHYSADDR(port->membase));
 38		serial8250_do_pm(port, state, old_state);
 39		break;
 40	case 3:		/* power off */
 41		serial8250_do_pm(port, state, old_state);
 42		alchemy_uart_disable(CPHYSADDR(port->membase));
 43		break;
 44	default:
 45		serial8250_do_pm(port, state, old_state);
 46		break;
 47	}
 48#endif
 49}
 50
 51#define PORT(_base, _irq)					\
 52	{							\
 53		.mapbase	= _base,			\
 54		.irq		= _irq,				\
 55		.regshift	= 2,				\
 56		.iotype		= UPIO_AU,			\
 57		.flags		= UPF_SKIP_TEST | UPF_IOREMAP | \
 58				  UPF_FIXED_TYPE,		\
 59		.type		= PORT_16550A,			\
 60		.pm		= alchemy_8250_pm,		\
 61	}
 62
 63static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = {
 64	[ALCHEMY_CPU_AU1000] = {
 65		PORT(AU1000_UART0_PHYS_ADDR, AU1000_UART0_INT),
 66		PORT(AU1000_UART1_PHYS_ADDR, AU1000_UART1_INT),
 67		PORT(AU1000_UART2_PHYS_ADDR, AU1000_UART2_INT),
 68		PORT(AU1000_UART3_PHYS_ADDR, AU1000_UART3_INT),
 69	},
 70	[ALCHEMY_CPU_AU1500] = {
 71		PORT(AU1000_UART0_PHYS_ADDR, AU1500_UART0_INT),
 72		PORT(AU1000_UART3_PHYS_ADDR, AU1500_UART3_INT),
 73	},
 74	[ALCHEMY_CPU_AU1100] = {
 75		PORT(AU1000_UART0_PHYS_ADDR, AU1100_UART0_INT),
 76		PORT(AU1000_UART1_PHYS_ADDR, AU1100_UART1_INT),
 77		PORT(AU1000_UART3_PHYS_ADDR, AU1100_UART3_INT),
 78	},
 79	[ALCHEMY_CPU_AU1550] = {
 80		PORT(AU1000_UART0_PHYS_ADDR, AU1550_UART0_INT),
 81		PORT(AU1000_UART1_PHYS_ADDR, AU1550_UART1_INT),
 82		PORT(AU1000_UART3_PHYS_ADDR, AU1550_UART3_INT),
 83	},
 84	[ALCHEMY_CPU_AU1200] = {
 85		PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT),
 86		PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT),
 87	},
 88	[ALCHEMY_CPU_AU1300] = {
 89		PORT(AU1300_UART0_PHYS_ADDR, AU1300_UART0_INT),
 90		PORT(AU1300_UART1_PHYS_ADDR, AU1300_UART1_INT),
 91		PORT(AU1300_UART2_PHYS_ADDR, AU1300_UART2_INT),
 92		PORT(AU1300_UART3_PHYS_ADDR, AU1300_UART3_INT),
 93	},
 94};
 95
 96static struct platform_device au1xx0_uart_device = {
 97	.name			= "serial8250",
 98	.id			= PLAT8250_DEV_AU1X00,
 99};
100
101static void __init alchemy_setup_uarts(int ctype)
102{
103	long uartclk;
104	int s = sizeof(struct plat_serial8250_port);
105	int c = alchemy_get_uarts(ctype);
106	struct plat_serial8250_port *ports;
107	struct clk *clk = clk_get(NULL, ALCHEMY_PERIPH_CLK);
108
109	if (IS_ERR(clk))
110		return;
111	if (clk_prepare_enable(clk)) {
112		clk_put(clk);
113		return;
114	}
115	uartclk = clk_get_rate(clk);
116	clk_put(clk);
117
118	ports = kcalloc(s, (c + 1), GFP_KERNEL);
119	if (!ports) {
120		printk(KERN_INFO "Alchemy: no memory for UART data\n");
121		return;
122	}
123	memcpy(ports, au1x00_uart_data[ctype], s * c);
124	au1xx0_uart_device.dev.platform_data = ports;
125
126	/* Fill up uartclk. */
127	for (s = 0; s < c; s++)
128		ports[s].uartclk = uartclk;
129	if (platform_device_register(&au1xx0_uart_device))
130		printk(KERN_INFO "Alchemy: failed to register UARTs\n");
131}
132
 
 
 
 
 
 
 
 
 
 
 
 
 
133
134static u64 alchemy_all_dmamask = DMA_BIT_MASK(32);
 
135
136/* Power on callback for the ehci platform driver */
137static int alchemy_ehci_power_on(struct platform_device *pdev)
138{
139	return alchemy_usb_control(ALCHEMY_USB_EHCI0, 1);
140}
 
 
 
 
 
141
142/* Power off/suspend callback for the ehci platform driver */
143static void alchemy_ehci_power_off(struct platform_device *pdev)
144{
145	alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
146}
147
148static struct usb_ehci_pdata alchemy_ehci_pdata = {
149	.no_io_watchdog = 1,
150	.power_on	= alchemy_ehci_power_on,
151	.power_off	= alchemy_ehci_power_off,
152	.power_suspend	= alchemy_ehci_power_off,
 
 
 
 
 
 
 
153};
154
155/* Power on callback for the ohci platform driver */
156static int alchemy_ohci_power_on(struct platform_device *pdev)
157{
158	int unit;
 
 
 
 
 
 
 
 
 
159
160	unit = (pdev->id == 1) ?
161		ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
 
 
 
 
 
 
 
 
 
 
 
 
162
163	return alchemy_usb_control(unit, 1);
164}
165
166/* Power off/suspend callback for the ohci platform driver */
167static void alchemy_ohci_power_off(struct platform_device *pdev)
168{
169	int unit;
 
 
 
 
 
 
170
171	unit = (pdev->id == 1) ?
172		ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
 
 
 
 
 
 
 
 
 
 
 
173
174	alchemy_usb_control(unit, 0);
175}
176
177static struct usb_ohci_pdata alchemy_ohci_pdata = {
178	.power_on		= alchemy_ohci_power_on,
179	.power_off		= alchemy_ohci_power_off,
180	.power_suspend		= alchemy_ohci_power_off,
 
 
 
 
 
181};
182
183static unsigned long alchemy_ohci_data[][2] __initdata = {
184	[ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT },
185	[ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT },
186	[ALCHEMY_CPU_AU1100] = { AU1000_USB_OHCI_PHYS_ADDR, AU1100_USB_HOST_INT },
187	[ALCHEMY_CPU_AU1550] = { AU1550_USB_OHCI_PHYS_ADDR, AU1550_USB_HOST_INT },
188	[ALCHEMY_CPU_AU1200] = { AU1200_USB_OHCI_PHYS_ADDR, AU1200_USB_INT },
189	[ALCHEMY_CPU_AU1300] = { AU1300_USB_OHCI0_PHYS_ADDR, AU1300_USB_INT },
 
 
 
 
 
190};
191
192static unsigned long alchemy_ehci_data[][2] __initdata = {
193	[ALCHEMY_CPU_AU1200] = { AU1200_USB_EHCI_PHYS_ADDR, AU1200_USB_INT },
194	[ALCHEMY_CPU_AU1300] = { AU1300_USB_EHCI_PHYS_ADDR, AU1300_USB_INT },
 
 
 
 
 
 
 
 
195};
196
197static int __init _new_usbres(struct resource **r, struct platform_device **d)
198{
199	*r = kcalloc(2, sizeof(struct resource), GFP_KERNEL);
200	if (!*r)
201		return -ENOMEM;
202	*d = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
203	if (!*d) {
204		kfree(*r);
205		return -ENOMEM;
 
206	}
 
207
208	(*d)->dev.coherent_dma_mask = DMA_BIT_MASK(32);
209	(*d)->num_resources = 2;
210	(*d)->resource = *r;
 
 
 
 
 
 
 
 
 
211
212	return 0;
213}
214
215static void __init alchemy_setup_usb(int ctype)
216{
217	struct resource *res;
218	struct platform_device *pdev;
219
220	/* setup OHCI0.  Every variant has one */
221	if (_new_usbres(&res, &pdev))
222		return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
224	res[0].start = alchemy_ohci_data[ctype][0];
225	res[0].end = res[0].start + 0x100 - 1;
226	res[0].flags = IORESOURCE_MEM;
227	res[1].start = alchemy_ohci_data[ctype][1];
228	res[1].end = res[1].start;
229	res[1].flags = IORESOURCE_IRQ;
230	pdev->name = "ohci-platform";
231	pdev->id = 0;
232	pdev->dev.dma_mask = &alchemy_all_dmamask;
233	pdev->dev.platform_data = &alchemy_ohci_pdata;
234
235	if (platform_device_register(pdev))
236		printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n");
237
238
239	/* setup EHCI0: Au1200/Au1300 */
240	if ((ctype == ALCHEMY_CPU_AU1200) || (ctype == ALCHEMY_CPU_AU1300)) {
241		if (_new_usbres(&res, &pdev))
242			return;
243
244		res[0].start = alchemy_ehci_data[ctype][0];
245		res[0].end = res[0].start + 0x100 - 1;
246		res[0].flags = IORESOURCE_MEM;
247		res[1].start = alchemy_ehci_data[ctype][1];
248		res[1].end = res[1].start;
249		res[1].flags = IORESOURCE_IRQ;
250		pdev->name = "ehci-platform";
251		pdev->id = 0;
252		pdev->dev.dma_mask = &alchemy_all_dmamask;
253		pdev->dev.platform_data = &alchemy_ehci_pdata;
254
255		if (platform_device_register(pdev))
256			printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
257	}
258
259	/* Au1300: OHCI1 */
260	if (ctype == ALCHEMY_CPU_AU1300) {
261		if (_new_usbres(&res, &pdev))
262			return;
263
264		res[0].start = AU1300_USB_OHCI1_PHYS_ADDR;
265		res[0].end = res[0].start + 0x100 - 1;
266		res[0].flags = IORESOURCE_MEM;
267		res[1].start = AU1300_USB_INT;
268		res[1].end = res[1].start;
269		res[1].flags = IORESOURCE_IRQ;
270		pdev->name = "ohci-platform";
271		pdev->id = 1;
272		pdev->dev.dma_mask = &alchemy_all_dmamask;
273		pdev->dev.platform_data = &alchemy_ohci_pdata;
274
275		if (platform_device_register(pdev))
276			printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277	}
278}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
280/* Macro to help defining the Ethernet MAC resources */
281#define MAC_RES_COUNT	4	/* MAC regs, MAC en, MAC INT, MACDMA regs */
282#define MAC_RES(_base, _enable, _irq, _macdma)		\
283	{						\
284		.start	= _base,			\
285		.end	= _base + 0xffff,		\
286		.flags	= IORESOURCE_MEM,		\
287	},						\
288	{						\
289		.start	= _enable,			\
290		.end	= _enable + 0x3,		\
291		.flags	= IORESOURCE_MEM,		\
292	},						\
293	{						\
294		.start	= _irq,				\
295		.end	= _irq,				\
296		.flags	= IORESOURCE_IRQ		\
297	},						\
298	{						\
299		.start	= _macdma,			\
300		.end	= _macdma + 0x1ff,		\
301		.flags	= IORESOURCE_MEM,		\
302	}
303
304static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = {
305	[ALCHEMY_CPU_AU1000] = {
306		MAC_RES(AU1000_MAC0_PHYS_ADDR,
307			AU1000_MACEN_PHYS_ADDR,
308			AU1000_MAC0_DMA_INT,
309			AU1000_MACDMA0_PHYS_ADDR)
310	},
311	[ALCHEMY_CPU_AU1500] = {
312		MAC_RES(AU1500_MAC0_PHYS_ADDR,
313			AU1500_MACEN_PHYS_ADDR,
314			AU1500_MAC0_DMA_INT,
315			AU1000_MACDMA0_PHYS_ADDR)
316	},
317	[ALCHEMY_CPU_AU1100] = {
318		MAC_RES(AU1000_MAC0_PHYS_ADDR,
319			AU1000_MACEN_PHYS_ADDR,
320			AU1100_MAC0_DMA_INT,
321			AU1000_MACDMA0_PHYS_ADDR)
322	},
323	[ALCHEMY_CPU_AU1550] = {
324		MAC_RES(AU1000_MAC0_PHYS_ADDR,
325			AU1000_MACEN_PHYS_ADDR,
326			AU1550_MAC0_DMA_INT,
327			AU1000_MACDMA0_PHYS_ADDR)
328	},
329};
330
331static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
332	.phy1_search_mac0 = 1,
333};
334
335static struct platform_device au1xxx_eth0_device = {
336	.name		= "au1000-eth",
337	.id		= 0,
338	.num_resources	= MAC_RES_COUNT,
339	.dev = {
340		.dma_mask               = &alchemy_all_dmamask,
341		.coherent_dma_mask      = DMA_BIT_MASK(32),
342		.platform_data          = &au1xxx_eth0_platform_data,
343	},
344};
345
346static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = {
347	[ALCHEMY_CPU_AU1000] = {
348		MAC_RES(AU1000_MAC1_PHYS_ADDR,
349			AU1000_MACEN_PHYS_ADDR + 4,
350			AU1000_MAC1_DMA_INT,
351			AU1000_MACDMA1_PHYS_ADDR)
352	},
353	[ALCHEMY_CPU_AU1500] = {
354		MAC_RES(AU1500_MAC1_PHYS_ADDR,
355			AU1500_MACEN_PHYS_ADDR + 4,
356			AU1500_MAC1_DMA_INT,
357			AU1000_MACDMA1_PHYS_ADDR)
358	},
359	[ALCHEMY_CPU_AU1550] = {
360		MAC_RES(AU1000_MAC1_PHYS_ADDR,
361			AU1000_MACEN_PHYS_ADDR + 4,
362			AU1550_MAC1_DMA_INT,
363			AU1000_MACDMA1_PHYS_ADDR)
364	},
365};
366
367static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
368	.phy1_search_mac0 = 1,
369};
370
371static struct platform_device au1xxx_eth1_device = {
372	.name		= "au1000-eth",
373	.id		= 1,
374	.num_resources	= MAC_RES_COUNT,
375	.dev = {
376		.dma_mask               = &alchemy_all_dmamask,
377		.coherent_dma_mask      = DMA_BIT_MASK(32),
378		.platform_data          = &au1xxx_eth1_platform_data,
379	},
380};
381
382void __init au1xxx_override_eth_cfg(unsigned int port,
383			struct au1000_eth_platform_data *eth_data)
384{
385	if (!eth_data || port > 1)
386		return;
387
388	if (port == 0)
389		memcpy(&au1xxx_eth0_platform_data, eth_data,
390			sizeof(struct au1000_eth_platform_data));
391	else
392		memcpy(&au1xxx_eth1_platform_data, eth_data,
393			sizeof(struct au1000_eth_platform_data));
394}
395
396static void __init alchemy_setup_macs(int ctype)
397{
398	int ret, i;
399	unsigned char ethaddr[6];
400	struct resource *macres;
401
402	/* Handle 1st MAC */
403	if (alchemy_get_macs(ctype) < 1)
404		return;
405
406	macres = kmemdup(au1xxx_eth0_resources[ctype],
407			 sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
408	if (!macres) {
409		printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
410		return;
411	}
 
 
412	au1xxx_eth0_device.resource = macres;
413
414	i = prom_get_ethernet_addr(ethaddr);
415	if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
416		memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
417
418	ret = platform_device_register(&au1xxx_eth0_device);
419	if (ret)
420		printk(KERN_INFO "Alchemy: failed to register MAC0\n");
421
422
423	/* Handle 2nd MAC */
424	if (alchemy_get_macs(ctype) < 2)
425		return;
426
427	macres = kmemdup(au1xxx_eth1_resources[ctype],
428			 sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
429	if (!macres) {
430		printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
431		return;
432	}
 
 
433	au1xxx_eth1_device.resource = macres;
434
435	ethaddr[5] += 1;	/* next addr for 2nd MAC */
436	if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
437		memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
438
439	/* Register second MAC if enabled in pinfunc */
440	if (!(alchemy_rdsys(AU1000_SYS_PINFUNC) & SYS_PF_NI2)) {
441		ret = platform_device_register(&au1xxx_eth1_device);
442		if (ret)
443			printk(KERN_INFO "Alchemy: failed to register MAC1\n");
444	}
445}
446
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447static int __init au1xxx_platform_init(void)
448{
449	int ctype = alchemy_get_cputype();
450
451	alchemy_setup_uarts(ctype);
452	alchemy_setup_macs(ctype);
453	alchemy_setup_usb(ctype);
454
455	return 0;
 
 
456}
457
458arch_initcall(au1xxx_platform_init);