2 * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us>
3 * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org>
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file "COPYING" in the main directory of this archive
10 #include <linux/init.h>
11 #include <linux/kernel.h>
12 #include <linux/platform_device.h>
13 #include <linux/platform_data/tulip.h>
14 #include <linux/usb/ehci_pdriver.h>
15 #include <linux/mtd/physmap.h>
16 #include <linux/pci.h>
17 #include <linux/slab.h>
18 #include <linux/ioport.h>
19 #include <linux/amba/bus.h>
20 #include <linux/amba/serial.h>
22 #include <asm/reboot.h>
24 #include <asm/addrspace.h>
25 #include <asm/bootinfo.h>
29 #define ADM8868_UBOOT_ENV 0x20000
30 #define ADM8868_UBOOT_WAN_MAC 0x5ac
31 #define ADM8868_UBOOT_LAN_MAC 0x404
33 static void adm8668_uart_set_mctrl(struct amba_device *dev,
39 static struct amba_pl010_data adm8668_uart0_data = {
40 .set_mctrl = adm8668_uart_set_mctrl,
43 static struct amba_device adm8668_uart0_device = {
45 .init_name = "apb:uart0",
46 .platform_data = &adm8668_uart0_data,
49 .start = ADM8668_UART0_BASE,
50 .end = ADM8668_UART0_BASE + 0xF,
51 .flags = IORESOURCE_MEM,
57 .periphid = 0x0041010,
60 static struct resource eth0_resources[] = {
62 .start = ADM8668_LAN_BASE,
63 .end = ADM8668_LAN_BASE + 256,
64 .flags = IORESOURCE_MEM,
67 .start = ADM8668_LAN_IRQ,
68 .flags = IORESOURCE_IRQ,
72 static struct tulip_platform_data eth0_pdata = {
76 static struct platform_device adm8668_eth0_device = {
79 .resource = eth0_resources,
80 .num_resources = ARRAY_SIZE(eth0_resources),
81 .dev.platform_data = ð0_pdata,
84 static struct resource eth1_resources[] = {
86 .start = ADM8668_WAN_BASE,
87 .end = ADM8668_WAN_BASE + 256,
88 .flags = IORESOURCE_MEM,
91 .start = ADM8668_WAN_IRQ,
92 .flags = IORESOURCE_IRQ,
96 static struct tulip_platform_data eth1_pdata = {
100 static struct platform_device adm8668_eth1_device = {
103 .resource = eth1_resources,
104 .num_resources = ARRAY_SIZE(eth1_resources),
105 .dev.platform_data = ð1_pdata,
108 static struct resource usb_resources[] = {
110 .start = ADM8668_USB_BASE,
111 .end = ADM8668_USB_BASE + 0x1FFFFF,
112 .flags = IORESOURCE_MEM,
115 .start = ADM8668_USB_IRQ,
116 .end = ADM8668_USB_IRQ,
117 .flags = IORESOURCE_IRQ,
121 static struct usb_ehci_pdata usb_pdata = {
122 .caps_offset = 0x100,
127 static struct platform_device adm8668_usb_device = {
128 .name = "ehci-platform",
130 .resource = usb_resources,
131 .num_resources = ARRAY_SIZE(usb_resources),
132 .dev.platform_data = &usb_pdata,
135 static struct platform_device *adm8668_devs[] = {
136 &adm8668_eth0_device,
137 &adm8668_eth1_device,
141 static void adm8668_fetch_mac(int unit)
145 struct tulip_platform_data *pdata;
150 offset = ADM8868_UBOOT_LAN_MAC;
154 offset = ADM8868_UBOOT_WAN_MAC;
158 pr_err("unsupported ethernet unit: %d\n", unit);
162 mac = (u8 *)(KSEG1ADDR(ADM8668_SMEM1_BASE) + ADM8868_UBOOT_ENV + offset);
164 memcpy(pdata->mac, mac, sizeof(pdata->mac));
167 static void adm8668_ehci_workaround(void)
171 chipid = ADM8668_CONFIG_REG(ADM8668_CR0);
172 ADM8668_CONFIG_REG(ADM8668_CR66) = 0x0C1600D9;
174 if (chipid == 0x86880001)
177 ADM8668_CONFIG_REG(ADM8668_CR66) &= ~(3 << 20);
178 ADM8668_CONFIG_REG(ADM8668_CR66) |= (1 << 20);
179 pr_info("ADM8668: applied USB workaround\n");
183 int __devinit adm8668_devs_register(void)
187 ret = amba_device_register(&adm8668_uart0_device, &iomem_resource);
189 panic("failed to register AMBA UART");
191 adm8668_fetch_mac(0);
192 adm8668_fetch_mac(1);
193 adm8668_ehci_workaround();
195 return platform_add_devices(adm8668_devs, ARRAY_SIZE(adm8668_devs));
197 arch_initcall(adm8668_devs_register);