Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
platform.c
Go to the documentation of this file.
1 /*
2  * Platform device support for Au1x00 SoCs.
3  *
4  * Copyright 2004, Matt Porter <[email protected]>
5  *
6  * (C) Copyright Embedded Alley Solutions, Inc 2005
7  * Author: Pantelis Antoniou <[email protected]>
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>
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] = {
66  },
67  [ALCHEMY_CPU_AU1500] = {
70  },
71  [ALCHEMY_CPU_AU1100] = {
75  },
76  [ALCHEMY_CPU_AU1550] = {
80  },
81  [ALCHEMY_CPU_AU1200] = {
84  },
85  [ALCHEMY_CPU_AU1300] = {
90  },
91 };
92 
93 static struct platform_device au1xx0_uart_device = {
94  .name = "serial8250",
95  .id = PLAT8250_DEV_AU1X00,
96 };
97 
98 static void __init alchemy_setup_uarts(int ctype)
99 {
100  unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
101  int s = sizeof(struct plat_serial8250_port);
102  int c = alchemy_get_uarts(ctype);
103  struct plat_serial8250_port *ports;
104 
105  ports = kzalloc(s * (c + 1), GFP_KERNEL);
106  if (!ports) {
107  printk(KERN_INFO "Alchemy: no memory for UART data\n");
108  return;
109  }
110  memcpy(ports, au1x00_uart_data[ctype], s * c);
111  au1xx0_uart_device.dev.platform_data = ports;
112 
113  /* Fill up uartclk. */
114  for (s = 0; s < c; s++)
115  ports[s].uartclk = uartclk;
116  if (platform_device_register(&au1xx0_uart_device))
117  printk(KERN_INFO "Alchemy: failed to register UARTs\n");
118 }
119 
120 
121 /* The dmamask must be set for OHCI/EHCI to work */
122 static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32);
123 static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32);
124 
125 static unsigned long alchemy_ohci_data[][2] __initdata = {
132 };
133 
134 static unsigned long alchemy_ehci_data[][2] __initdata = {
137 };
138 
139 static int __init _new_usbres(struct resource **r, struct platform_device **d)
140 {
141  *r = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
142  if (!*r)
143  return -ENOMEM;
144  *d = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
145  if (!*d) {
146  kfree(*r);
147  return -ENOMEM;
148  }
149 
150  (*d)->dev.coherent_dma_mask = DMA_BIT_MASK(32);
151  (*d)->num_resources = 2;
152  (*d)->resource = *r;
153 
154  return 0;
155 }
156 
157 static void __init alchemy_setup_usb(int ctype)
158 {
159  struct resource *res;
160  struct platform_device *pdev;
161 
162  /* setup OHCI0. Every variant has one */
163  if (_new_usbres(&res, &pdev))
164  return;
165 
166  res[0].start = alchemy_ohci_data[ctype][0];
167  res[0].end = res[0].start + 0x100 - 1;
168  res[0].flags = IORESOURCE_MEM;
169  res[1].start = alchemy_ohci_data[ctype][1];
170  res[1].end = res[1].start;
171  res[1].flags = IORESOURCE_IRQ;
172  pdev->name = "au1xxx-ohci";
173  pdev->id = 0;
174  pdev->dev.dma_mask = &alchemy_ohci_dmamask;
175 
176  if (platform_device_register(pdev))
177  printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n");
178 
179 
180  /* setup EHCI0: Au1200/Au1300 */
181  if ((ctype == ALCHEMY_CPU_AU1200) || (ctype == ALCHEMY_CPU_AU1300)) {
182  if (_new_usbres(&res, &pdev))
183  return;
184 
185  res[0].start = alchemy_ehci_data[ctype][0];
186  res[0].end = res[0].start + 0x100 - 1;
187  res[0].flags = IORESOURCE_MEM;
188  res[1].start = alchemy_ehci_data[ctype][1];
189  res[1].end = res[1].start;
190  res[1].flags = IORESOURCE_IRQ;
191  pdev->name = "au1xxx-ehci";
192  pdev->id = 0;
193  pdev->dev.dma_mask = &alchemy_ehci_dmamask;
194 
195  if (platform_device_register(pdev))
196  printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
197  }
198 
199  /* Au1300: OHCI1 */
200  if (ctype == ALCHEMY_CPU_AU1300) {
201  if (_new_usbres(&res, &pdev))
202  return;
203 
205  res[0].end = res[0].start + 0x100 - 1;
206  res[0].flags = IORESOURCE_MEM;
207  res[1].start = AU1300_USB_INT;
208  res[1].end = res[1].start;
209  res[1].flags = IORESOURCE_IRQ;
210  pdev->name = "au1xxx-ohci";
211  pdev->id = 1;
212  pdev->dev.dma_mask = &alchemy_ohci_dmamask;
213 
214  if (platform_device_register(pdev))
215  printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n");
216  }
217 }
218 
219 /* Macro to help defining the Ethernet MAC resources */
220 #define MAC_RES_COUNT 4 /* MAC regs, MAC en, MAC INT, MACDMA regs */
221 #define MAC_RES(_base, _enable, _irq, _macdma) \
222  { \
223  .start = _base, \
224  .end = _base + 0xffff, \
225  .flags = IORESOURCE_MEM, \
226  }, \
227  { \
228  .start = _enable, \
229  .end = _enable + 0x3, \
230  .flags = IORESOURCE_MEM, \
231  }, \
232  { \
233  .start = _irq, \
234  .end = _irq, \
235  .flags = IORESOURCE_IRQ \
236  }, \
237  { \
238  .start = _macdma, \
239  .end = _macdma + 0x1ff, \
240  .flags = IORESOURCE_MEM, \
241  }
242 
243 static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = {
244  [ALCHEMY_CPU_AU1000] = {
249  },
250  [ALCHEMY_CPU_AU1500] = {
255  },
256  [ALCHEMY_CPU_AU1100] = {
261  },
262  [ALCHEMY_CPU_AU1550] = {
267  },
268 };
269 
270 static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
271  .phy1_search_mac0 = 1,
272 };
273 
274 static struct platform_device au1xxx_eth0_device = {
275  .name = "au1000-eth",
276  .id = 0,
277  .num_resources = MAC_RES_COUNT,
278  .dev.platform_data = &au1xxx_eth0_platform_data,
279 };
280 
281 static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = {
282  [ALCHEMY_CPU_AU1000] = {
287  },
288  [ALCHEMY_CPU_AU1500] = {
293  },
294  [ALCHEMY_CPU_AU1550] = {
299  },
300 };
301 
302 static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
303  .phy1_search_mac0 = 1,
304 };
305 
306 static struct platform_device au1xxx_eth1_device = {
307  .name = "au1000-eth",
308  .id = 1,
309  .num_resources = MAC_RES_COUNT,
310  .dev.platform_data = &au1xxx_eth1_platform_data,
311 };
312 
313 void __init au1xxx_override_eth_cfg(unsigned int port,
314  struct au1000_eth_platform_data *eth_data)
315 {
316  if (!eth_data || port > 1)
317  return;
318 
319  if (port == 0)
320  memcpy(&au1xxx_eth0_platform_data, eth_data,
321  sizeof(struct au1000_eth_platform_data));
322  else
323  memcpy(&au1xxx_eth1_platform_data, eth_data,
324  sizeof(struct au1000_eth_platform_data));
325 }
326 
327 static void __init alchemy_setup_macs(int ctype)
328 {
329  int ret, i;
330  unsigned char ethaddr[6];
331  struct resource *macres;
332 
333  /* Handle 1st MAC */
334  if (alchemy_get_macs(ctype) < 1)
335  return;
336 
337  macres = kmemdup(au1xxx_eth0_resources[ctype],
338  sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
339  if (!macres) {
340  printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
341  return;
342  }
343  au1xxx_eth0_device.resource = macres;
344 
345  i = prom_get_ethernet_addr(ethaddr);
346  if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
347  memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
348 
349  ret = platform_device_register(&au1xxx_eth0_device);
350  if (ret)
351  printk(KERN_INFO "Alchemy: failed to register MAC0\n");
352 
353 
354  /* Handle 2nd MAC */
355  if (alchemy_get_macs(ctype) < 2)
356  return;
357 
358  macres = kmemdup(au1xxx_eth1_resources[ctype],
359  sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
360  if (!macres) {
361  printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
362  return;
363  }
364  au1xxx_eth1_device.resource = macres;
365 
366  ethaddr[5] += 1; /* next addr for 2nd MAC */
367  if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
368  memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
369 
370  /* Register second MAC if enabled in pinfunc */
371  if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) {
372  ret = platform_device_register(&au1xxx_eth1_device);
373  if (ret)
374  printk(KERN_INFO "Alchemy: failed to register MAC1\n");
375  }
376 }
377 
378 static int __init au1xxx_platform_init(void)
379 {
380  int ctype = alchemy_get_cputype();
381 
382  alchemy_setup_uarts(ctype);
383  alchemy_setup_macs(ctype);
384  alchemy_setup_usb(ctype);
385 
386  return 0;
387 }
388 
389 arch_initcall(au1xxx_platform_init);