diff options
Diffstat (limited to 'arch/mips/alchemy/common/platform.c')
-rw-r--r-- | arch/mips/alchemy/common/platform.c | 370 |
1 files changed, 89 insertions, 281 deletions
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index f72c48d4804c..c8e5d72a5826 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c @@ -18,7 +18,7 @@ #include <linux/serial_8250.h> #include <linux/slab.h> -#include <asm/mach-au1x00/au1xxx.h> +#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1xxx_dbdma.h> #include <asm/mach-au1x00/au1100_mmc.h> #include <asm/mach-au1x00/au1xxx_eth.h> @@ -111,270 +111,87 @@ static void __init alchemy_setup_uarts(int ctype) printk(KERN_INFO "Alchemy: failed to register UARTs\n"); } -/* OHCI (USB full speed host controller) */ -static struct resource au1xxx_usb_ohci_resources[] = { - [0] = { - .start = USB_OHCI_BASE, - .end = USB_OHCI_BASE + USB_OHCI_LEN - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = FOR_PLATFORM_C_USB_HOST_INT, - .end = FOR_PLATFORM_C_USB_HOST_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -/* The dmamask must be set for OHCI to work */ -static u64 ohci_dmamask = DMA_BIT_MASK(32); - -static struct platform_device au1xxx_usb_ohci_device = { - .name = "au1xxx-ohci", - .id = 0, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(au1xxx_usb_ohci_resources), - .resource = au1xxx_usb_ohci_resources, -}; - -/*** AU1100 LCD controller ***/ - -#ifdef CONFIG_FB_AU1100 -static struct resource au1100_lcd_resources[] = { - [0] = { - .start = LCD_PHYS_ADDR, - .end = LCD_PHYS_ADDR + 0x800 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AU1100_LCD_INT, - .end = AU1100_LCD_INT, - .flags = IORESOURCE_IRQ, - } -}; - -static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32); - -static struct platform_device au1100_lcd_device = { - .name = "au1100-lcd", - .id = 0, - .dev = { - .dma_mask = &au1100_lcd_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(au1100_lcd_resources), - .resource = au1100_lcd_resources, -}; -#endif - -#ifdef CONFIG_SOC_AU1200 -/* EHCI (USB high speed host controller) */ -static struct resource au1xxx_usb_ehci_resources[] = { - [0] = { - .start = USB_EHCI_BASE, - .end = USB_EHCI_BASE + USB_EHCI_LEN - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AU1200_USB_INT, - .end = AU1200_USB_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 ehci_dmamask = DMA_BIT_MASK(32); - -static struct platform_device au1xxx_usb_ehci_device = { - .name = "au1xxx-ehci", - .id = 0, - .dev = { - .dma_mask = &ehci_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources), - .resource = au1xxx_usb_ehci_resources, -}; - -/* Au1200 UDC (USB gadget controller) */ -static struct resource au1xxx_usb_gdt_resources[] = { - [0] = { - .start = USB_UDC_BASE, - .end = USB_UDC_BASE + USB_UDC_LEN - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AU1200_USB_INT, - .end = AU1200_USB_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 udc_dmamask = DMA_BIT_MASK(32); -static struct platform_device au1xxx_usb_gdt_device = { - .name = "au1xxx-udc", - .id = 0, - .dev = { - .dma_mask = &udc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources), - .resource = au1xxx_usb_gdt_resources, -}; +/* The dmamask must be set for OHCI/EHCI to work */ +static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32); +static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32); -/* Au1200 UOC (USB OTG controller) */ -static struct resource au1xxx_usb_otg_resources[] = { - [0] = { - .start = USB_UOC_BASE, - .end = USB_UOC_BASE + USB_UOC_LEN - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AU1200_USB_INT, - .end = AU1200_USB_INT, - .flags = IORESOURCE_IRQ, - }, +static unsigned long alchemy_ohci_data[][2] __initdata = { + [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT }, + [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT }, + [ALCHEMY_CPU_AU1100] = { AU1000_USB_OHCI_PHYS_ADDR, AU1100_USB_HOST_INT }, + [ALCHEMY_CPU_AU1550] = { AU1550_USB_OHCI_PHYS_ADDR, AU1550_USB_HOST_INT }, + [ALCHEMY_CPU_AU1200] = { AU1200_USB_OHCI_PHYS_ADDR, AU1200_USB_INT }, }; -static u64 uoc_dmamask = DMA_BIT_MASK(32); - -static struct platform_device au1xxx_usb_otg_device = { - .name = "au1xxx-uoc", - .id = 0, - .dev = { - .dma_mask = &uoc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources), - .resource = au1xxx_usb_otg_resources, +static unsigned long alchemy_ehci_data[][2] __initdata = { + [ALCHEMY_CPU_AU1200] = { AU1200_USB_EHCI_PHYS_ADDR, AU1200_USB_INT }, }; -static struct resource au1200_lcd_resources[] = { - [0] = { - .start = LCD_PHYS_ADDR, - .end = LCD_PHYS_ADDR + 0x800 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AU1200_LCD_INT, - .end = AU1200_LCD_INT, - .flags = IORESOURCE_IRQ, +static int __init _new_usbres(struct resource **r, struct platform_device **d) +{ + *r = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!*r) + return -ENOMEM; + *d = kzalloc(sizeof(struct platform_device), GFP_KERNEL); + if (!*d) { + kfree(*r); + return -ENOMEM; } -}; - -static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32); - -static struct platform_device au1200_lcd_device = { - .name = "au1200-lcd", - .id = 0, - .dev = { - .dma_mask = &au1200_lcd_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = ARRAY_SIZE(au1200_lcd_resources), - .resource = au1200_lcd_resources, -}; -static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32); + (*d)->dev.coherent_dma_mask = DMA_BIT_MASK(32); + (*d)->num_resources = 2; + (*d)->resource = *r; -extern struct au1xmmc_platform_data au1xmmc_platdata[2]; + return 0; +} -static struct resource au1200_mmc0_resources[] = { - [0] = { - .start = AU1100_SD0_PHYS_ADDR, - .end = AU1100_SD0_PHYS_ADDR + 0xfff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AU1200_SD_INT, - .end = AU1200_SD_INT, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = DSCR_CMD0_SDMS_TX0, - .end = DSCR_CMD0_SDMS_TX0, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = DSCR_CMD0_SDMS_RX0, - .end = DSCR_CMD0_SDMS_RX0, - .flags = IORESOURCE_DMA, - } -}; +static void __init alchemy_setup_usb(int ctype) +{ + struct resource *res; + struct platform_device *pdev; -static struct platform_device au1200_mmc0_device = { - .name = "au1xxx-mmc", - .id = 0, - .dev = { - .dma_mask = &au1xxx_mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &au1xmmc_platdata[0], - }, - .num_resources = ARRAY_SIZE(au1200_mmc0_resources), - .resource = au1200_mmc0_resources, -}; + /* setup OHCI0. Every variant has one */ + if (_new_usbres(&res, &pdev)) + return; -#ifndef CONFIG_MIPS_DB1200 -static struct resource au1200_mmc1_resources[] = { - [0] = { - .start = AU1100_SD1_PHYS_ADDR, - .end = AU1100_SD1_PHYS_ADDR + 0xfff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AU1200_SD_INT, - .end = AU1200_SD_INT, - .flags = IORESOURCE_IRQ, - }, - [2] = { - .start = DSCR_CMD0_SDMS_TX1, - .end = DSCR_CMD0_SDMS_TX1, - .flags = IORESOURCE_DMA, - }, - [3] = { - .start = DSCR_CMD0_SDMS_RX1, - .end = DSCR_CMD0_SDMS_RX1, - .flags = IORESOURCE_DMA, + res[0].start = alchemy_ohci_data[ctype][0]; + res[0].end = res[0].start + 0x100 - 1; + res[0].flags = IORESOURCE_MEM; + res[1].start = alchemy_ohci_data[ctype][1]; + res[1].end = res[1].start; + res[1].flags = IORESOURCE_IRQ; + pdev->name = "au1xxx-ohci"; + pdev->id = 0; + pdev->dev.dma_mask = &alchemy_ohci_dmamask; + + if (platform_device_register(pdev)) + printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n"); + + + /* setup EHCI0: Au1200 */ + if (ctype == ALCHEMY_CPU_AU1200) { + if (_new_usbres(&res, &pdev)) + return; + + res[0].start = alchemy_ehci_data[ctype][0]; + res[0].end = res[0].start + 0x100 - 1; + res[0].flags = IORESOURCE_MEM; + res[1].start = alchemy_ehci_data[ctype][1]; + res[1].end = res[1].start; + res[1].flags = IORESOURCE_IRQ; + pdev->name = "au1xxx-ehci"; + pdev->id = 0; + pdev->dev.dma_mask = &alchemy_ehci_dmamask; + + if (platform_device_register(pdev)) + printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n"); } -}; - -static struct platform_device au1200_mmc1_device = { - .name = "au1xxx-mmc", - .id = 1, - .dev = { - .dma_mask = &au1xxx_mmc_dmamask, - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &au1xmmc_platdata[1], - }, - .num_resources = ARRAY_SIZE(au1200_mmc1_resources), - .resource = au1200_mmc1_resources, -}; -#endif /* #ifndef CONFIG_MIPS_DB1200 */ -#endif /* #ifdef CONFIG_SOC_AU1200 */ - -/* All Alchemy demoboards with I2C have this #define in their headers */ -#ifdef SMBUS_PSC_BASE -static struct resource pbdb_smbus_resources[] = { - { - .start = CPHYSADDR(SMBUS_PSC_BASE), - .end = CPHYSADDR(SMBUS_PSC_BASE + 0xfffff), - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device pbdb_smbus_device = { - .name = "au1xpsc_smbus", - .id = 0, /* bus number */ - .num_resources = ARRAY_SIZE(pbdb_smbus_resources), - .resource = pbdb_smbus_resources, -}; -#endif +} /* Macro to help defining the Ethernet MAC resources */ -#define MAC_RES_COUNT 3 /* MAC regs base, MAC enable reg, MAC INT */ -#define MAC_RES(_base, _enable, _irq) \ +#define MAC_RES_COUNT 4 /* MAC regs, MAC en, MAC INT, MACDMA regs */ +#define MAC_RES(_base, _enable, _irq, _macdma) \ { \ .start = _base, \ .end = _base + 0xffff, \ @@ -389,28 +206,37 @@ static struct platform_device pbdb_smbus_device = { .start = _irq, \ .end = _irq, \ .flags = IORESOURCE_IRQ \ + }, \ + { \ + .start = _macdma, \ + .end = _macdma + 0x1ff, \ + .flags = IORESOURCE_MEM, \ } static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = { [ALCHEMY_CPU_AU1000] = { MAC_RES(AU1000_MAC0_PHYS_ADDR, AU1000_MACEN_PHYS_ADDR, - AU1000_MAC0_DMA_INT) + AU1000_MAC0_DMA_INT, + AU1000_MACDMA0_PHYS_ADDR) }, [ALCHEMY_CPU_AU1500] = { MAC_RES(AU1500_MAC0_PHYS_ADDR, AU1500_MACEN_PHYS_ADDR, - AU1500_MAC0_DMA_INT) + AU1500_MAC0_DMA_INT, + AU1000_MACDMA0_PHYS_ADDR) }, [ALCHEMY_CPU_AU1100] = { MAC_RES(AU1000_MAC0_PHYS_ADDR, AU1000_MACEN_PHYS_ADDR, - AU1100_MAC0_DMA_INT) + AU1100_MAC0_DMA_INT, + AU1000_MACDMA0_PHYS_ADDR) }, [ALCHEMY_CPU_AU1550] = { MAC_RES(AU1000_MAC0_PHYS_ADDR, AU1000_MACEN_PHYS_ADDR, - AU1550_MAC0_DMA_INT) + AU1550_MAC0_DMA_INT, + AU1000_MACDMA0_PHYS_ADDR) }, }; @@ -429,17 +255,20 @@ static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = { [ALCHEMY_CPU_AU1000] = { MAC_RES(AU1000_MAC1_PHYS_ADDR, AU1000_MACEN_PHYS_ADDR + 4, - AU1000_MAC1_DMA_INT) + AU1000_MAC1_DMA_INT, + AU1000_MACDMA1_PHYS_ADDR) }, [ALCHEMY_CPU_AU1500] = { MAC_RES(AU1500_MAC1_PHYS_ADDR, AU1500_MACEN_PHYS_ADDR + 4, - AU1500_MAC1_DMA_INT) + AU1500_MAC1_DMA_INT, + AU1000_MACDMA1_PHYS_ADDR) }, [ALCHEMY_CPU_AU1550] = { MAC_RES(AU1000_MAC1_PHYS_ADDR, AU1000_MACEN_PHYS_ADDR + 4, - AU1550_MAC1_DMA_INT) + AU1550_MAC1_DMA_INT, + AU1000_MACDMA1_PHYS_ADDR) }, }; @@ -521,36 +350,15 @@ static void __init alchemy_setup_macs(int ctype) } } -static struct platform_device *au1xxx_platform_devices[] __initdata = { - &au1xxx_usb_ohci_device, -#ifdef CONFIG_FB_AU1100 - &au1100_lcd_device, -#endif -#ifdef CONFIG_SOC_AU1200 - &au1xxx_usb_ehci_device, - &au1xxx_usb_gdt_device, - &au1xxx_usb_otg_device, - &au1200_lcd_device, - &au1200_mmc0_device, -#ifndef CONFIG_MIPS_DB1200 - &au1200_mmc1_device, -#endif -#endif -#ifdef SMBUS_PSC_BASE - &pbdb_smbus_device, -#endif -}; - static int __init au1xxx_platform_init(void) { - int err, ctype = alchemy_get_cputype(); + int ctype = alchemy_get_cputype(); alchemy_setup_uarts(ctype); alchemy_setup_macs(ctype); + alchemy_setup_usb(ctype); - err = platform_add_devices(au1xxx_platform_devices, - ARRAY_SIZE(au1xxx_platform_devices)); - return err; + return 0; } arch_initcall(au1xxx_platform_init); |