Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dev-usb.c
Go to the documentation of this file.
1 /*
2  * Atheros AR7XXX/AR9XXX USB Host Controller device
3  *
4  * Copyright (C) 2008-2011 Gabor Juhos <[email protected]>
5  * Copyright (C) 2008 Imre Kaloz <[email protected]>
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/irq.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/platform_device.h>
20 #include <linux/usb/ehci_pdriver.h>
21 #include <linux/usb/ohci_pdriver.h>
22 
23 #include <asm/mach-ath79/ath79.h>
25 #include "common.h"
26 #include "dev-usb.h"
27 
28 static struct resource ath79_ohci_resources[2];
29 
30 static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32);
31 
32 static struct usb_ohci_pdata ath79_ohci_pdata = {
33 };
34 
35 static struct platform_device ath79_ohci_device = {
36  .name = "ohci-platform",
37  .id = -1,
38  .resource = ath79_ohci_resources,
39  .num_resources = ARRAY_SIZE(ath79_ohci_resources),
40  .dev = {
41  .dma_mask = &ath79_ohci_dmamask,
42  .coherent_dma_mask = DMA_BIT_MASK(32),
43  .platform_data = &ath79_ohci_pdata,
44  },
45 };
46 
47 static struct resource ath79_ehci_resources[2];
48 
49 static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
50 
51 static struct usb_ehci_pdata ath79_ehci_pdata_v1 = {
52  .has_synopsys_hc_bug = 1,
53  .port_power_off = 1,
54 };
55 
56 static struct usb_ehci_pdata ath79_ehci_pdata_v2 = {
57  .caps_offset = 0x100,
58  .has_tt = 1,
59  .port_power_off = 1,
60 };
61 
62 static struct platform_device ath79_ehci_device = {
63  .name = "ehci-platform",
64  .id = -1,
65  .resource = ath79_ehci_resources,
66  .num_resources = ARRAY_SIZE(ath79_ehci_resources),
67  .dev = {
68  .dma_mask = &ath79_ehci_dmamask,
69  .coherent_dma_mask = DMA_BIT_MASK(32),
70  },
71 };
72 
73 static void __init ath79_usb_init_resource(struct resource res[2],
74  unsigned long base,
75  unsigned long size,
76  int irq)
77 {
78  res[0].flags = IORESOURCE_MEM;
79  res[0].start = base;
80  res[0].end = base + size - 1;
81 
82  res[1].flags = IORESOURCE_IRQ;
83  res[1].start = irq;
84  res[1].end = irq;
85 }
86 
87 #define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \
88  AR71XX_RESET_USB_PHY | \
89  AR71XX_RESET_USB_OHCI_DLL)
90 
91 static void __init ath79_usb_setup(void)
92 {
93  void __iomem *usb_ctrl_base;
94 
96  mdelay(1000);
98 
100 
101  /* Turning on the Buff and Desc swap bits */
102  __raw_writel(0xf0000, usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG);
103 
104  /* WAR for HW bug. Here it adjusts the duration between two SOFS */
105  __raw_writel(0x20c00, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
106 
107  iounmap(usb_ctrl_base);
108 
109  mdelay(900);
110 
111  ath79_usb_init_resource(ath79_ohci_resources, AR71XX_OHCI_BASE,
113  platform_device_register(&ath79_ohci_device);
114 
115  ath79_usb_init_resource(ath79_ehci_resources, AR71XX_EHCI_BASE,
117  ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1;
118  platform_device_register(&ath79_ehci_device);
119 }
120 
121 static void __init ar7240_usb_setup(void)
122 {
123  void __iomem *usb_ctrl_base;
124 
127 
128  mdelay(1000);
129 
132 
134 
135  /* WAR for HW bug. Here it adjusts the duration between two SOFS */
136  __raw_writel(0x3, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
137 
138  iounmap(usb_ctrl_base);
139 
140  ath79_usb_init_resource(ath79_ohci_resources, AR7240_OHCI_BASE,
142  platform_device_register(&ath79_ohci_device);
143 }
144 
145 static void __init ar724x_usb_setup(void)
146 {
148  mdelay(10);
149 
151  mdelay(10);
152 
154  mdelay(10);
155 
156  ath79_usb_init_resource(ath79_ehci_resources, AR724X_EHCI_BASE,
158  ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
159  platform_device_register(&ath79_ehci_device);
160 }
161 
162 static void __init ar913x_usb_setup(void)
163 {
165  mdelay(10);
166 
168  mdelay(10);
169 
171  mdelay(10);
172 
173  ath79_usb_init_resource(ath79_ehci_resources, AR913X_EHCI_BASE,
175  ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
176  platform_device_register(&ath79_ehci_device);
177 }
178 
179 static void __init ar933x_usb_setup(void)
180 {
182  mdelay(10);
183 
185  mdelay(10);
186 
188  mdelay(10);
189 
190  ath79_usb_init_resource(ath79_ehci_resources, AR933X_EHCI_BASE,
192  ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
193  platform_device_register(&ath79_ehci_device);
194 }
195 
196 static void __init ar934x_usb_setup(void)
197 {
198  u32 bootstrap;
199 
200  bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
201  if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE)
202  return;
203 
205  udelay(1000);
206 
208  udelay(1000);
209 
211  udelay(1000);
212 
214  udelay(1000);
215 
216  ath79_usb_init_resource(ath79_ehci_resources, AR934X_EHCI_BASE,
218  ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
219  platform_device_register(&ath79_ehci_device);
220 }
221 
223 {
224  if (soc_is_ar71xx())
225  ath79_usb_setup();
226  else if (soc_is_ar7240())
227  ar7240_usb_setup();
228  else if (soc_is_ar7241() || soc_is_ar7242())
229  ar724x_usb_setup();
230  else if (soc_is_ar913x())
231  ar913x_usb_setup();
232  else if (soc_is_ar933x())
233  ar933x_usb_setup();
234  else if (soc_is_ar934x())
235  ar934x_usb_setup();
236  else
237  BUG();
238 }