pandora: defconfig: update
[pandora-kernel.git] / arch / mips / alchemy / common / platform.c
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/au1000.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
28 static 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
60 static 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
87 static struct platform_device au1xx0_uart_device = {
88         .name                   = "serial8250",
89         .id                     = PLAT8250_DEV_AU1X00,
90 };
91
92 static 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
115 /* The dmamask must be set for OHCI/EHCI to work */
116 static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32);
117 static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32);
118
119 static unsigned long alchemy_ohci_data[][2] __initdata = {
120         [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT },
121         [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT },
122         [ALCHEMY_CPU_AU1100] = { AU1000_USB_OHCI_PHYS_ADDR, AU1100_USB_HOST_INT },
123         [ALCHEMY_CPU_AU1550] = { AU1550_USB_OHCI_PHYS_ADDR, AU1550_USB_HOST_INT },
124         [ALCHEMY_CPU_AU1200] = { AU1200_USB_OHCI_PHYS_ADDR, AU1200_USB_INT },
125 };
126
127 static unsigned long alchemy_ehci_data[][2] __initdata = {
128         [ALCHEMY_CPU_AU1200] = { AU1200_USB_EHCI_PHYS_ADDR, AU1200_USB_INT },
129 };
130
131 static int __init _new_usbres(struct resource **r, struct platform_device **d)
132 {
133         *r = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
134         if (!*r)
135                 return -ENOMEM;
136         *d = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
137         if (!*d) {
138                 kfree(*r);
139                 return -ENOMEM;
140         }
141
142         (*d)->dev.coherent_dma_mask = DMA_BIT_MASK(32);
143         (*d)->num_resources = 2;
144         (*d)->resource = *r;
145
146         return 0;
147 }
148
149 static void __init alchemy_setup_usb(int ctype)
150 {
151         struct resource *res;
152         struct platform_device *pdev;
153
154         /* setup OHCI0.  Every variant has one */
155         if (_new_usbres(&res, &pdev))
156                 return;
157
158         res[0].start = alchemy_ohci_data[ctype][0];
159         res[0].end = res[0].start + 0x100 - 1;
160         res[0].flags = IORESOURCE_MEM;
161         res[1].start = alchemy_ohci_data[ctype][1];
162         res[1].end = res[1].start;
163         res[1].flags = IORESOURCE_IRQ;
164         pdev->name = "au1xxx-ohci";
165         pdev->id = 0;
166         pdev->dev.dma_mask = &alchemy_ohci_dmamask;
167
168         if (platform_device_register(pdev))
169                 printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n");
170
171
172         /* setup EHCI0: Au1200 */
173         if (ctype == ALCHEMY_CPU_AU1200) {
174                 if (_new_usbres(&res, &pdev))
175                         return;
176
177                 res[0].start = alchemy_ehci_data[ctype][0];
178                 res[0].end = res[0].start + 0x100 - 1;
179                 res[0].flags = IORESOURCE_MEM;
180                 res[1].start = alchemy_ehci_data[ctype][1];
181                 res[1].end = res[1].start;
182                 res[1].flags = IORESOURCE_IRQ;
183                 pdev->name = "au1xxx-ehci";
184                 pdev->id = 0;
185                 pdev->dev.dma_mask = &alchemy_ehci_dmamask;
186
187                 if (platform_device_register(pdev))
188                         printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
189         }
190 }
191
192 /* Macro to help defining the Ethernet MAC resources */
193 #define MAC_RES_COUNT   4       /* MAC regs, MAC en, MAC INT, MACDMA regs */
194 #define MAC_RES(_base, _enable, _irq, _macdma)          \
195         {                                               \
196                 .start  = _base,                        \
197                 .end    = _base + 0xffff,               \
198                 .flags  = IORESOURCE_MEM,               \
199         },                                              \
200         {                                               \
201                 .start  = _enable,                      \
202                 .end    = _enable + 0x3,                \
203                 .flags  = IORESOURCE_MEM,               \
204         },                                              \
205         {                                               \
206                 .start  = _irq,                         \
207                 .end    = _irq,                         \
208                 .flags  = IORESOURCE_IRQ                \
209         },                                              \
210         {                                               \
211                 .start  = _macdma,                      \
212                 .end    = _macdma + 0x1ff,              \
213                 .flags  = IORESOURCE_MEM,               \
214         }
215
216 static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = {
217         [ALCHEMY_CPU_AU1000] = {
218                 MAC_RES(AU1000_MAC0_PHYS_ADDR,
219                         AU1000_MACEN_PHYS_ADDR,
220                         AU1000_MAC0_DMA_INT,
221                         AU1000_MACDMA0_PHYS_ADDR)
222         },
223         [ALCHEMY_CPU_AU1500] = {
224                 MAC_RES(AU1500_MAC0_PHYS_ADDR,
225                         AU1500_MACEN_PHYS_ADDR,
226                         AU1500_MAC0_DMA_INT,
227                         AU1000_MACDMA0_PHYS_ADDR)
228         },
229         [ALCHEMY_CPU_AU1100] = {
230                 MAC_RES(AU1000_MAC0_PHYS_ADDR,
231                         AU1000_MACEN_PHYS_ADDR,
232                         AU1100_MAC0_DMA_INT,
233                         AU1000_MACDMA0_PHYS_ADDR)
234         },
235         [ALCHEMY_CPU_AU1550] = {
236                 MAC_RES(AU1000_MAC0_PHYS_ADDR,
237                         AU1000_MACEN_PHYS_ADDR,
238                         AU1550_MAC0_DMA_INT,
239                         AU1000_MACDMA0_PHYS_ADDR)
240         },
241 };
242
243 static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
244         .phy1_search_mac0 = 1,
245 };
246
247 static struct platform_device au1xxx_eth0_device = {
248         .name           = "au1000-eth",
249         .id             = 0,
250         .num_resources  = MAC_RES_COUNT,
251         .dev.platform_data = &au1xxx_eth0_platform_data,
252 };
253
254 static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = {
255         [ALCHEMY_CPU_AU1000] = {
256                 MAC_RES(AU1000_MAC1_PHYS_ADDR,
257                         AU1000_MACEN_PHYS_ADDR + 4,
258                         AU1000_MAC1_DMA_INT,
259                         AU1000_MACDMA1_PHYS_ADDR)
260         },
261         [ALCHEMY_CPU_AU1500] = {
262                 MAC_RES(AU1500_MAC1_PHYS_ADDR,
263                         AU1500_MACEN_PHYS_ADDR + 4,
264                         AU1500_MAC1_DMA_INT,
265                         AU1000_MACDMA1_PHYS_ADDR)
266         },
267         [ALCHEMY_CPU_AU1550] = {
268                 MAC_RES(AU1000_MAC1_PHYS_ADDR,
269                         AU1000_MACEN_PHYS_ADDR + 4,
270                         AU1550_MAC1_DMA_INT,
271                         AU1000_MACDMA1_PHYS_ADDR)
272         },
273 };
274
275 static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
276         .phy1_search_mac0 = 1,
277 };
278
279 static struct platform_device au1xxx_eth1_device = {
280         .name           = "au1000-eth",
281         .id             = 1,
282         .num_resources  = MAC_RES_COUNT,
283         .dev.platform_data = &au1xxx_eth1_platform_data,
284 };
285
286 void __init au1xxx_override_eth_cfg(unsigned int port,
287                         struct au1000_eth_platform_data *eth_data)
288 {
289         if (!eth_data || port > 1)
290                 return;
291
292         if (port == 0)
293                 memcpy(&au1xxx_eth0_platform_data, eth_data,
294                         sizeof(struct au1000_eth_platform_data));
295         else
296                 memcpy(&au1xxx_eth1_platform_data, eth_data,
297                         sizeof(struct au1000_eth_platform_data));
298 }
299
300 static void __init alchemy_setup_macs(int ctype)
301 {
302         int ret, i;
303         unsigned char ethaddr[6];
304         struct resource *macres;
305
306         /* Handle 1st MAC */
307         if (alchemy_get_macs(ctype) < 1)
308                 return;
309
310         macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
311         if (!macres) {
312                 printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
313                 return;
314         }
315         memcpy(macres, au1xxx_eth0_resources[ctype],
316                sizeof(struct resource) * MAC_RES_COUNT);
317         au1xxx_eth0_device.resource = macres;
318
319         i = prom_get_ethernet_addr(ethaddr);
320         if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
321                 memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
322
323         ret = platform_device_register(&au1xxx_eth0_device);
324         if (ret)
325                 printk(KERN_INFO "Alchemy: failed to register MAC0\n");
326
327
328         /* Handle 2nd MAC */
329         if (alchemy_get_macs(ctype) < 2)
330                 return;
331
332         macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
333         if (!macres) {
334                 printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
335                 return;
336         }
337         memcpy(macres, au1xxx_eth1_resources[ctype],
338                sizeof(struct resource) * MAC_RES_COUNT);
339         au1xxx_eth1_device.resource = macres;
340
341         ethaddr[5] += 1;        /* next addr for 2nd MAC */
342         if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
343                 memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
344
345         /* Register second MAC if enabled in pinfunc */
346         if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) {
347                 ret = platform_device_register(&au1xxx_eth1_device);
348                 if (ret)
349                         printk(KERN_INFO "Alchemy: failed to register MAC1\n");
350         }
351 }
352
353 static int __init au1xxx_platform_init(void)
354 {
355         int ctype = alchemy_get_cputype();
356
357         alchemy_setup_uarts(ctype);
358         alchemy_setup_macs(ctype);
359         alchemy_setup_usb(ctype);
360
361         return 0;
362 }
363
364 arch_initcall(au1xxx_platform_init);