surprise :p
[openwrt.git] / target / linux / ar71xx / files / arch / mips / ar71xx / platform.c
1 /*
2  *  Atheros AR71xx SoC platform devices
3  *
4  *  Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
5  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6  *
7  *  Parts of this file are based on Atheros' 2.6.15 BSP
8  *
9  *  This program is free software; you can redistribute it and/or modify it
10  *  under the terms of the GNU General Public License version 2 as published
11  *  by the Free Software Foundation.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/delay.h>
17 #include <linux/dma-mapping.h>
18 #include <linux/platform_device.h>
19 #include <linux/serial_8250.h>
20
21 #include <asm/mips_machine.h>
22 #include <asm/mach-ar71xx/ar71xx.h>
23 #include <asm/mach-ar71xx/platform.h>
24
25 /*
26  * OHCI (USB full speed host controller)
27  */
28 static struct resource ar71xx_usb_ohci_resources[] = {
29         [0] = {
30                 .start  = AR71XX_OHCI_BASE,
31                 .end    = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
32                 .flags  = IORESOURCE_MEM,
33         },
34         [1] = {
35                 .start  = AR71XX_MISC_IRQ_OHCI,
36                 .end    = AR71XX_MISC_IRQ_OHCI,
37                 .flags  = IORESOURCE_IRQ,
38         },
39 };
40
41 static u64 ar71xx_ohci_dmamask = DMA_BIT_MASK(32);
42 static struct platform_device ar71xx_usb_ohci_device = {
43         .name           = "ar71xx-ohci",
44         .id             = 0,
45         .resource       = ar71xx_usb_ohci_resources,
46         .num_resources  = ARRAY_SIZE(ar71xx_usb_ohci_resources),
47         .dev = {
48                 .dma_mask               = &ar71xx_ohci_dmamask,
49                 .coherent_dma_mask      = DMA_BIT_MASK(32),
50         },
51 };
52
53 /*
54  * EHCI (USB full speed host controller)
55  */
56 static struct resource ar71xx_usb_ehci_resources[] = {
57         [0] = {
58                 .start  = AR71XX_EHCI_BASE,
59                 .end    = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
60                 .flags  = IORESOURCE_MEM,
61         },
62         [1] = {
63                 .start  = AR71XX_CPU_IRQ_USB,
64                 .end    = AR71XX_CPU_IRQ_USB,
65                 .flags  = IORESOURCE_IRQ,
66         },
67 };
68
69 static u64 ar71xx_ehci_dmamask = DMA_BIT_MASK(32);
70 static struct platform_device ar71xx_usb_ehci_device = {
71         .name           = "ar71xx-ehci",
72         .id             = 0,
73         .resource       = ar71xx_usb_ehci_resources,
74         .num_resources  = ARRAY_SIZE(ar71xx_usb_ehci_resources),
75         .dev = {
76                 .dma_mask               = &ar71xx_ehci_dmamask,
77                 .coherent_dma_mask      = DMA_BIT_MASK(32),
78         },
79 };
80
81 #define AR71XX_USB_RESET_MASK \
82         (RESET_MODULE_USB_HOST | RESET_MODULE_USB_PHY \
83         | RESET_MODULE_USB_OHCI_DLL)
84
85 void __init ar71xx_add_device_usb(void)
86 {
87         ar71xx_device_stop(AR71XX_USB_RESET_MASK);
88         mdelay(1000);
89         ar71xx_device_start(AR71XX_USB_RESET_MASK);
90
91         /* Turning on the Buff and Desc swap bits */
92         ar71xx_usb_ctrl_wr(USB_CTRL_REG_CONFIG, 0xf0000);
93
94         /* WAR for HW bug. Here it adjusts the duration between two SOFS */
95         ar71xx_usb_ctrl_wr(USB_CTRL_REG_FLADJ, 0x20c00);
96
97         mdelay(900);
98
99         platform_device_register(&ar71xx_usb_ohci_device);
100         platform_device_register(&ar71xx_usb_ehci_device);
101 }
102
103 #ifdef CONFIG_AR71XX_EARLY_SERIAL
104 static void __init ar71xx_add_device_uart(void) {};
105 #else
106 static struct resource ar71xx_uart_resources[] = {
107         {
108                 .start  = AR71XX_UART_BASE,
109                 .end    = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
110                 .flags  = IORESOURCE_MEM,
111         },
112 };
113
114 #define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
115 static struct plat_serial8250_port ar71xx_uart_data[] = {
116         {
117                 .mapbase        = AR71XX_UART_BASE,
118                 .irq            = AR71XX_MISC_IRQ_UART,
119                 .flags          = AR71XX_UART_FLAGS,
120                 .iotype         = UPIO_MEM32,
121                 .regshift       = 2,
122         }, {
123                 /* terminating entry */
124         }
125 };
126
127 static struct platform_device ar71xx_uart_device = {
128         .name           = "serial8250",
129         .id             = PLAT8250_DEV_PLATFORM,
130         .resource       = ar71xx_uart_resources,
131         .num_resources  = ARRAY_SIZE(ar71xx_uart_resources),
132         .dev = {
133                 .platform_data  = ar71xx_uart_data
134         },
135 };
136
137 static void __init ar71xx_add_device_uart(void)
138 {
139         ar71xx_uart_data[0].uartclk = ar71xx_ahb_freq;
140         platform_device_register(&ar71xx_uart_device);
141 }
142 #endif /* CONFIG_AR71XX_EARLY_SERIAL */
143
144 static struct resource ar71xx_eth0_resources[] = {
145         {
146                 .name   = "mac_base",
147                 .flags  = IORESOURCE_MEM,
148                 .start  = AR71XX_GE0_BASE,
149                 .end    = AR71XX_GE0_BASE + AR71XX_GE0_SIZE - 1,
150         }, {
151                 .name   = "mii_ctrl",
152                 .flags  = IORESOURCE_MEM,
153                 .start  = AR71XX_MII_BASE + MII_REG_MII0_CTRL,
154                 .end    = AR71XX_MII_BASE + MII_REG_MII0_CTRL + 3,
155         }, {
156                 .name   = "mac_irq",
157                 .flags  = IORESOURCE_IRQ,
158                 .start  = AR71XX_CPU_IRQ_GE0,
159                 .end    = AR71XX_CPU_IRQ_GE0,
160         },
161 };
162
163 static struct ag71xx_platform_data ar71xx_eth0_data = {
164         .reset_bit      = RESET_MODULE_GE0_MAC,
165         .flush_reg      = DDR_REG_FLUSH_GE0,
166 };
167
168 static struct platform_device ar71xx_eth0_device = {
169         .name           = "ag71xx",
170         .id             = 0,
171         .resource       = ar71xx_eth0_resources,
172         .num_resources  = ARRAY_SIZE(ar71xx_eth0_resources),
173         .dev = {
174                 .platform_data = &ar71xx_eth0_data,
175         },
176 };
177
178 static struct resource ar71xx_eth1_resources[] = {
179         {
180                 .name   = "mac_base",
181                 .flags  = IORESOURCE_MEM,
182                 .start  = AR71XX_GE1_BASE,
183                 .end    = AR71XX_GE1_BASE + AR71XX_GE1_SIZE - 1,
184         }, {
185                 .name   = "mii_ctrl",
186                 .flags  = IORESOURCE_MEM,
187                 .start  = AR71XX_MII_BASE + MII_REG_MII1_CTRL,
188                 .end    = AR71XX_MII_BASE + MII_REG_MII1_CTRL + 3,
189         }, {
190                 .name   = "mac_irq",
191                 .flags  = IORESOURCE_IRQ,
192                 .start  = AR71XX_CPU_IRQ_GE1,
193                 .end    = AR71XX_CPU_IRQ_GE1,
194         },
195 };
196
197 static struct ag71xx_platform_data ar71xx_eth1_data = {
198         .reset_bit      = RESET_MODULE_GE1_MAC,
199         .flush_reg      = DDR_REG_FLUSH_GE1,
200 };
201
202 static struct platform_device ar71xx_eth1_device = {
203         .name           = "ag71xx",
204         .id             = 1,
205         .resource       = ar71xx_eth1_resources,
206         .num_resources  = ARRAY_SIZE(ar71xx_eth1_resources),
207         .dev = {
208                 .platform_data = &ar71xx_eth1_data,
209         },
210 };
211
212 void __init ar71xx_add_device_eth(unsigned int id, phy_interface_t phy_if_mode,
213                                 u32 phy_mask)
214 {
215         struct platform_device *pdev;
216
217         switch (id) {
218         case 0:
219                 switch (phy_if_mode) {
220                 case PHY_INTERFACE_MODE_MII:
221                         ar71xx_eth0_data.mii_if = MII0_CTRL_IF_MII;
222                         break;
223                 case PHY_INTERFACE_MODE_GMII:
224                         ar71xx_eth0_data.mii_if = MII0_CTRL_IF_GMII;
225                         break;
226                 case PHY_INTERFACE_MODE_RGMII:
227                         ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RGMII;
228                         break;
229                 case PHY_INTERFACE_MODE_RMII:
230                         ar71xx_eth0_data.mii_if = MII0_CTRL_IF_RMII;
231                         break;
232                 default:
233                         BUG();
234                 }
235                 ar71xx_eth0_data.phy_if_mode = phy_if_mode;
236                 ar71xx_eth0_data.phy_mask = phy_mask;
237                 pdev = &ar71xx_eth0_device;
238                 break;
239         case 1:
240                 switch (phy_if_mode) {
241                 case PHY_INTERFACE_MODE_RMII:
242                         ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RMII;
243                         break;
244                 case PHY_INTERFACE_MODE_RGMII:
245                         ar71xx_eth1_data.mii_if = MII1_CTRL_IF_RGMII;
246                         break;
247                 default:
248                         BUG();
249                 }
250                 ar71xx_eth1_data.phy_if_mode = phy_if_mode;
251                 ar71xx_eth1_data.phy_mask = phy_mask;
252                 pdev = &ar71xx_eth1_device;
253                 break;
254         default:
255                 pdev = NULL;
256                 break;
257         }
258
259         if (pdev)
260                 platform_device_register(pdev);
261 }
262
263 static struct resource ar71xx_spi_resources[] = {
264         [0] = {
265                 .start  = AR71XX_SPI_BASE,
266                 .end    = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
267                 .flags  = IORESOURCE_MEM,
268         },
269 };
270
271 static struct platform_device ar71xx_spi_device = {
272         .name           = "ar71xx-spi",
273         .id             = -1,
274         .resource       = ar71xx_spi_resources,
275         .num_resources  = ARRAY_SIZE(ar71xx_spi_resources),
276 };
277
278 void __init ar71xx_add_device_spi(struct ar71xx_spi_platform_data *pdata,
279                                 struct spi_board_info const *info,
280                                 unsigned n)
281 {
282         ar71xx_gpio_function_enable(GPIO_FUNC_SPI_EN);
283
284         spi_register_board_info(info, n);
285         ar71xx_spi_device.dev.platform_data = pdata;
286         platform_device_register(&ar71xx_spi_device);
287 }
288
289 static int __init ar71xx_machine_setup(void)
290 {
291         ar71xx_print_cmdline();
292
293         ar71xx_gpio_init();
294
295         ar71xx_add_device_uart();
296
297         mips_machine_setup();
298         return 0;
299 }
300
301 arch_initcall(ar71xx_machine_setup);