2 * Infineon/ADMTek 8668 (WildPass) platform devices support
4 * Copyright (C) 2010 Scott Nicholas <neutronscott@scottn.us>
5 * Copyright (C) 2012 Florian Fainelli <florian@openwrt.org>
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/platform_device.h>
15 #include <linux/platform_data/tulip.h>
16 #include <linux/usb/ehci_pdriver.h>
17 #include <linux/mtd/physmap.h>
18 #include <linux/mtd/partitions.h>
19 #include <linux/pci.h>
20 #include <linux/slab.h>
21 #include <linux/ioport.h>
22 #include <linux/amba/bus.h>
23 #include <linux/amba/serial.h>
25 #include <asm/reboot.h>
27 #include <asm/addrspace.h>
28 #include <asm/bootinfo.h>
32 #define ADM8868_UBOOT_ENV 0x20000
33 #define ADM8868_UBOOT_WAN_MAC 0x5ac
34 #define ADM8868_UBOOT_LAN_MAC 0x404
36 static void adm8668_uart_set_mctrl(struct amba_device
*dev
,
42 static struct amba_pl010_data adm8668_uart0_data
= {
43 .set_mctrl
= adm8668_uart_set_mctrl
,
46 static struct amba_device adm8668_uart0_device
= {
48 .init_name
= "apb:uart0",
49 .platform_data
= &adm8668_uart0_data
,
52 .start
= ADM8668_UART0_BASE
,
53 .end
= ADM8668_UART0_BASE
+ 0xF,
54 .flags
= IORESOURCE_MEM
,
60 .periphid
= 0x0041010,
63 static struct resource eth0_resources
[] = {
65 .start
= ADM8668_LAN_BASE
,
66 .end
= ADM8668_LAN_BASE
+ 256,
67 .flags
= IORESOURCE_MEM
,
70 .start
= ADM8668_LAN_IRQ
,
71 .flags
= IORESOURCE_IRQ
,
75 static struct tulip_platform_data eth0_pdata
= {
79 static struct platform_device adm8668_eth0_device
= {
82 .resource
= eth0_resources
,
83 .num_resources
= ARRAY_SIZE(eth0_resources
),
84 .dev
.platform_data
= ð0_pdata
,
87 static struct resource eth1_resources
[] = {
89 .start
= ADM8668_WAN_BASE
,
90 .end
= ADM8668_WAN_BASE
+ 256,
91 .flags
= IORESOURCE_MEM
,
94 .start
= ADM8668_WAN_IRQ
,
95 .flags
= IORESOURCE_IRQ
,
99 static struct tulip_platform_data eth1_pdata
= {
103 static struct platform_device adm8668_eth1_device
= {
106 .resource
= eth1_resources
,
107 .num_resources
= ARRAY_SIZE(eth1_resources
),
108 .dev
.platform_data
= ð1_pdata
,
111 static const char *nor_probe_types
[] = { "adm8668part", NULL
};
113 static struct physmap_flash_data nor_flash_data
= {
115 .part_probe_types
= nor_probe_types
,
118 static struct resource nor_resources
[] = {
120 .start
= ADM8668_SMEM1_BASE
,
121 .end
= ADM8668_SMEM1_BASE
+ 0x800000 - 1,
122 .flags
= IORESOURCE_MEM
,
126 static struct platform_device adm8668_nor_device
= {
127 .name
= "physmap-flash",
129 .resource
= nor_resources
,
130 .num_resources
= ARRAY_SIZE(nor_resources
),
131 .dev
.platform_data
= &nor_flash_data
,
134 static struct resource usb_resources
[] = {
136 .start
= ADM8668_USB_BASE
,
137 .end
= ADM8668_USB_BASE
+ 0x1FFFFF,
138 .flags
= IORESOURCE_MEM
,
141 .start
= ADM8668_USB_IRQ
,
142 .end
= ADM8668_USB_IRQ
,
143 .flags
= IORESOURCE_IRQ
,
147 static struct usb_ehci_pdata usb_pdata
= {
148 .caps_offset
= 0x100,
153 static struct platform_device adm8668_usb_device
= {
154 .name
= "ehci-platform",
156 .resource
= usb_resources
,
157 .num_resources
= ARRAY_SIZE(usb_resources
),
158 .dev
.platform_data
= &usb_pdata
,
161 static struct platform_device
*adm8668_devs
[] = {
162 &adm8668_eth0_device
,
163 &adm8668_eth1_device
,
168 static void adm8668_fetch_mac(int unit
)
172 struct tulip_platform_data
*pdata
;
177 offset
= ADM8868_UBOOT_LAN_MAC
;
181 offset
= ADM8868_UBOOT_WAN_MAC
;
185 pr_err("unsupported ethernet unit: %d\n", unit
);
189 mac
= (u8
*)(KSEG1ADDR(ADM8668_SMEM1_BASE
) + ADM8868_UBOOT_ENV
+ offset
);
191 memcpy(pdata
->mac
, mac
, sizeof(pdata
->mac
));
194 static void adm8668_ehci_workaround(void)
198 chipid
= ADM8668_CONFIG_REG(ADM8668_CR0
);
199 ADM8668_CONFIG_REG(ADM8668_CR66
) = 0x0C1600D9;
201 if (chipid
== 0x86880001)
204 ADM8668_CONFIG_REG(ADM8668_CR66
) &= ~(3 << 20);
205 ADM8668_CONFIG_REG(ADM8668_CR66
) |= (1 << 20);
206 pr_info("ADM8668: applied USB workaround\n");
210 int __devinit
adm8668_devs_register(void)
214 ret
= amba_device_register(&adm8668_uart0_device
, &iomem_resource
);
216 panic("failed to register AMBA UART");
218 adm8668_fetch_mac(0);
219 adm8668_fetch_mac(1);
220 adm8668_ehci_workaround();
222 return platform_add_devices(adm8668_devs
, ARRAY_SIZE(adm8668_devs
));
224 arch_initcall(adm8668_devs_register
);