blob: 286b2f4acdc2c57e6839c5ddeb3288a8f96c87f5 [file] [log] [blame]
Matt Porter7ff71d62005-09-22 22:31:15 -07001/*
2 * EHCI HCD (Host Controller Driver) PCI Bus Glue.
3 *
4 * Copyright (c) 2000-2004 by David Brownell
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef CONFIG_PCI
22#error "This file is PCI bus glue. CONFIG_PCI must be defined."
23#endif
24
25/*-------------------------------------------------------------------------*/
26
David Brownell18807522005-11-23 15:45:37 -080027/* called after powerup, by probe or system-pm "wakeup" */
28static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
29{
30 u32 temp;
31 int retval;
32 unsigned count = 256/4;
33
34 /* optional debug port, normally in the first BAR */
35 temp = pci_find_capability(pdev, 0x0a);
36 if (temp) {
37 pci_read_config_dword(pdev, temp, &temp);
38 temp >>= 16;
39 if ((temp & (3 << 13)) == (1 << 13)) {
40 temp &= 0x1fff;
41 ehci->debug = ehci_to_hcd(ehci)->regs + temp;
42 temp = readl(&ehci->debug->control);
43 ehci_info(ehci, "debug port %d%s\n",
44 HCS_DEBUG_PORT(ehci->hcs_params),
45 (temp & DBGP_ENABLED)
46 ? " IN USE"
47 : "");
48 if (!(temp & DBGP_ENABLED))
49 ehci->debug = NULL;
50 }
51 }
52
David Brownell401feaf2006-01-24 07:15:30 -080053 /* we expect static quirk code to handle the "extended capabilities"
54 * (currently just BIOS handoff) allowed starting with EHCI 0.96
55 */
David Brownell18807522005-11-23 15:45:37 -080056
57 /* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */
58 retval = pci_set_mwi(pdev);
59 if (!retval)
60 ehci_dbg(ehci, "MWI active\n");
61
62 ehci_port_power(ehci, 0);
63
64 return 0;
65}
66
David Brownell8926bfa2005-11-28 08:40:38 -080067/* called during probe() after chip reset completes */
68static int ehci_pci_setup(struct usb_hcd *hcd)
Matt Porter7ff71d62005-09-22 22:31:15 -070069{
David Brownellabcc9442005-11-23 15:45:32 -080070 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
71 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
Matt Porter7ff71d62005-09-22 22:31:15 -070072 u32 temp;
David Brownell18807522005-11-23 15:45:37 -080073 int retval;
Matt Porter7ff71d62005-09-22 22:31:15 -070074
75 ehci->caps = hcd->regs;
David Brownellabcc9442005-11-23 15:45:32 -080076 ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
77 dbg_hcs_params(ehci, "reset");
78 dbg_hcc_params(ehci, "reset");
Matt Porter7ff71d62005-09-22 22:31:15 -070079
80 /* cache this readonly data; minimize chip reads */
David Brownellabcc9442005-11-23 15:45:32 -080081 ehci->hcs_params = readl(&ehci->caps->hcs_params);
Matt Porter7ff71d62005-09-22 22:31:15 -070082
David Brownell18807522005-11-23 15:45:37 -080083 retval = ehci_halt(ehci);
84 if (retval)
85 return retval;
86
David Brownell8926bfa2005-11-28 08:40:38 -080087 /* data structure init */
88 retval = ehci_init(hcd);
89 if (retval)
90 return retval;
91
David Brownellabcc9442005-11-23 15:45:32 -080092 /* NOTE: only the parts below this line are PCI-specific */
Matt Porter7ff71d62005-09-22 22:31:15 -070093
David Brownellabcc9442005-11-23 15:45:32 -080094 switch (pdev->vendor) {
95 case PCI_VENDOR_ID_TDI:
96 if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
97 ehci->is_tdi_rh_tt = 1;
98 tdi_reset(ehci);
99 }
100 break;
101 case PCI_VENDOR_ID_AMD:
102 /* AMD8111 EHCI doesn't work, according to AMD errata */
103 if (pdev->device == 0x7463) {
104 ehci_info(ehci, "ignoring AMD8111 (errata)\n");
David Brownell8926bfa2005-11-28 08:40:38 -0800105 retval = -EIO;
106 goto done;
David Brownellabcc9442005-11-23 15:45:32 -0800107 }
108 break;
109 case PCI_VENDOR_ID_NVIDIA:
110 /* NVidia reports that certain chips don't handle
111 * QH, ITD, or SITD addresses above 2GB. (But TD,
112 * data buffer, and periodic schedule are normal.)
113 */
114 switch (pdev->device) {
115 case 0x003c: /* MCP04 */
116 case 0x005b: /* CK804 */
117 case 0x00d8: /* CK8 */
118 case 0x00e8: /* CK8S */
119 if (pci_set_consistent_dma_mask(pdev,
120 DMA_31BIT_MASK) < 0)
121 ehci_warn(ehci, "can't enable NVidia "
122 "workaround for >2GB RAM\n");
Matt Porter7ff71d62005-09-22 22:31:15 -0700123 break;
124 }
David Brownellabcc9442005-11-23 15:45:32 -0800125 break;
126 }
Matt Porter7ff71d62005-09-22 22:31:15 -0700127
Matt Porter7ff71d62005-09-22 22:31:15 -0700128 if (ehci_is_TDI(ehci))
David Brownellabcc9442005-11-23 15:45:32 -0800129 ehci_reset(ehci);
Matt Porter7ff71d62005-09-22 22:31:15 -0700130
Matt Porter7ff71d62005-09-22 22:31:15 -0700131 /* at least the Genesys GL880S needs fixup here */
132 temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
133 temp &= 0x0f;
134 if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
David Brownellabcc9442005-11-23 15:45:32 -0800135 ehci_dbg(ehci, "bogus port configuration: "
Matt Porter7ff71d62005-09-22 22:31:15 -0700136 "cc=%d x pcc=%d < ports=%d\n",
137 HCS_N_CC(ehci->hcs_params),
138 HCS_N_PCC(ehci->hcs_params),
139 HCS_N_PORTS(ehci->hcs_params));
140
David Brownellabcc9442005-11-23 15:45:32 -0800141 switch (pdev->vendor) {
142 case 0x17a0: /* GENESYS */
143 /* GL880S: should be PORTS=2 */
144 temp |= (ehci->hcs_params & ~0xf);
145 ehci->hcs_params = temp;
146 break;
147 case PCI_VENDOR_ID_NVIDIA:
148 /* NF4: should be PCC=10 */
149 break;
Matt Porter7ff71d62005-09-22 22:31:15 -0700150 }
151 }
152
David Brownellabcc9442005-11-23 15:45:32 -0800153 /* Serial Bus Release Number is at PCI 0x60 offset */
154 pci_read_config_byte(pdev, 0x60, &ehci->sbrn);
Matt Porter7ff71d62005-09-22 22:31:15 -0700155
David Brownell2c1c3c42005-11-07 15:24:46 -0800156 /* Workaround current PCI init glitch: wakeup bits aren't
157 * being set from PCI PM capability.
158 */
159 if (!device_can_wakeup(&pdev->dev)) {
160 u16 port_wake;
161
162 pci_read_config_word(pdev, 0x62, &port_wake);
163 if (port_wake & 0x0001)
164 device_init_wakeup(&pdev->dev, 1);
165 }
Matt Porter7ff71d62005-09-22 22:31:15 -0700166
David Brownell18807522005-11-23 15:45:37 -0800167 retval = ehci_pci_reinit(ehci, pdev);
David Brownell8926bfa2005-11-28 08:40:38 -0800168done:
169 return retval;
Matt Porter7ff71d62005-09-22 22:31:15 -0700170}
171
172/*-------------------------------------------------------------------------*/
173
174#ifdef CONFIG_PM
175
176/* suspend/resume, section 4.3 */
177
David Brownellf03c17f2005-11-23 15:45:28 -0800178/* These routines rely on the PCI bus glue
Matt Porter7ff71d62005-09-22 22:31:15 -0700179 * to handle powerdown and wakeup, and currently also on
180 * transceivers that don't need any software attention to set up
181 * the right sort of wakeup.
David Brownellf03c17f2005-11-23 15:45:28 -0800182 * Also they depend on separate root hub suspend/resume.
Matt Porter7ff71d62005-09-22 22:31:15 -0700183 */
184
David Brownellabcc9442005-11-23 15:45:32 -0800185static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
Matt Porter7ff71d62005-09-22 22:31:15 -0700186{
David Brownellabcc9442005-11-23 15:45:32 -0800187 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
Benjamin Herrenschmidt8de98402005-11-25 09:59:46 +1100188 unsigned long flags;
189 int rc = 0;
Matt Porter7ff71d62005-09-22 22:31:15 -0700190
David Brownellabcc9442005-11-23 15:45:32 -0800191 if (time_before(jiffies, ehci->next_statechange))
192 msleep(10);
Matt Porter7ff71d62005-09-22 22:31:15 -0700193
Benjamin Herrenschmidt8de98402005-11-25 09:59:46 +1100194 /* Root hub was already suspended. Disable irq emission and
195 * mark HW unaccessible, bail out if RH has been resumed. Use
196 * the spinlock to properly synchronize with possible pending
197 * RH suspend or resume activity.
198 *
199 * This is still racy as hcd->state is manipulated outside of
200 * any locks =P But that will be a different fix.
201 */
202 spin_lock_irqsave (&ehci->lock, flags);
203 if (hcd->state != HC_STATE_SUSPENDED) {
204 rc = -EINVAL;
205 goto bail;
206 }
207 writel (0, &ehci->regs->intr_enable);
208 (void)readl(&ehci->regs->intr_enable);
209
210 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
211 bail:
212 spin_unlock_irqrestore (&ehci->lock, flags);
213
David Brownellf03c17f2005-11-23 15:45:28 -0800214 // could save FLADJ in case of Vaux power loss
Matt Porter7ff71d62005-09-22 22:31:15 -0700215 // ... we'd only use it to handle clock skew
216
Benjamin Herrenschmidt8de98402005-11-25 09:59:46 +1100217 return rc;
Matt Porter7ff71d62005-09-22 22:31:15 -0700218}
219
David Brownellabcc9442005-11-23 15:45:32 -0800220static int ehci_pci_resume(struct usb_hcd *hcd)
Matt Porter7ff71d62005-09-22 22:31:15 -0700221{
David Brownellabcc9442005-11-23 15:45:32 -0800222 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
Matt Porter7ff71d62005-09-22 22:31:15 -0700223 unsigned port;
David Brownell18807522005-11-23 15:45:37 -0800224 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
Matt Porter7ff71d62005-09-22 22:31:15 -0700225 int retval = -EINVAL;
226
David Brownellf03c17f2005-11-23 15:45:28 -0800227 // maybe restore FLADJ
Matt Porter7ff71d62005-09-22 22:31:15 -0700228
David Brownellabcc9442005-11-23 15:45:32 -0800229 if (time_before(jiffies, ehci->next_statechange))
230 msleep(100);
Matt Porter7ff71d62005-09-22 22:31:15 -0700231
Benjamin Herrenschmidt8de98402005-11-25 09:59:46 +1100232 /* Mark hardware accessible again as we are out of D3 state by now */
233 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
234
David Brownellf03c17f2005-11-23 15:45:28 -0800235 /* If CF is clear, we lost PCI Vaux power and need to restart. */
David Brownell18807522005-11-23 15:45:37 -0800236 if (readl(&ehci->regs->configured_flag) != FLAG_CF)
David Brownellf03c17f2005-11-23 15:45:28 -0800237 goto restart;
238
Matt Porter7ff71d62005-09-22 22:31:15 -0700239 /* If any port is suspended (or owned by the companion),
240 * we know we can/must resume the HC (and mustn't reset it).
David Brownellf03c17f2005-11-23 15:45:28 -0800241 * We just defer that to the root hub code.
Matt Porter7ff71d62005-09-22 22:31:15 -0700242 */
David Brownellabcc9442005-11-23 15:45:32 -0800243 for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) {
Matt Porter7ff71d62005-09-22 22:31:15 -0700244 u32 status;
245 port--;
David Brownellabcc9442005-11-23 15:45:32 -0800246 status = readl(&ehci->regs->port_status [port]);
Matt Porter7ff71d62005-09-22 22:31:15 -0700247 if (!(status & PORT_POWER))
248 continue;
David Brownellf03c17f2005-11-23 15:45:28 -0800249 if (status & (PORT_SUSPEND | PORT_RESUME | PORT_OWNER)) {
250 usb_hcd_resume_root_hub(hcd);
251 return 0;
Matt Porter7ff71d62005-09-22 22:31:15 -0700252 }
David Brownellf03c17f2005-11-23 15:45:28 -0800253 }
254
255restart:
256 ehci_dbg(ehci, "lost power, restarting\n");
Alan Stern1c50c312005-11-14 11:45:38 -0500257 usb_root_hub_lost_power(hcd->self.root_hub);
Matt Porter7ff71d62005-09-22 22:31:15 -0700258
259 /* Else reset, to cope with power loss or flush-to-storage
David Brownellf03c17f2005-11-23 15:45:28 -0800260 * style "resume" having let BIOS kick in during reboot.
Matt Porter7ff71d62005-09-22 22:31:15 -0700261 */
David Brownellabcc9442005-11-23 15:45:32 -0800262 (void) ehci_halt(ehci);
263 (void) ehci_reset(ehci);
David Brownell18807522005-11-23 15:45:37 -0800264 (void) ehci_pci_reinit(ehci, pdev);
Matt Porter7ff71d62005-09-22 22:31:15 -0700265
David Brownellf03c17f2005-11-23 15:45:28 -0800266 /* emptying the schedule aborts any urbs */
David Brownellabcc9442005-11-23 15:45:32 -0800267 spin_lock_irq(&ehci->lock);
David Brownellf03c17f2005-11-23 15:45:28 -0800268 if (ehci->reclaim)
269 ehci->reclaim_ready = 1;
David Brownellabcc9442005-11-23 15:45:32 -0800270 ehci_work(ehci, NULL);
271 spin_unlock_irq(&ehci->lock);
Matt Porter7ff71d62005-09-22 22:31:15 -0700272
David Brownellf03c17f2005-11-23 15:45:28 -0800273 /* restart; khubd will disconnect devices */
David Brownellabcc9442005-11-23 15:45:32 -0800274 retval = ehci_run(hcd);
Matt Porter7ff71d62005-09-22 22:31:15 -0700275
David Brownell18807522005-11-23 15:45:37 -0800276 /* here we "know" root ports should always stay powered */
David Brownellabcc9442005-11-23 15:45:32 -0800277 ehci_port_power(ehci, 1);
Matt Porter7ff71d62005-09-22 22:31:15 -0700278
279 return retval;
280}
281#endif
282
283static const struct hc_driver ehci_pci_hc_driver = {
284 .description = hcd_name,
285 .product_desc = "EHCI Host Controller",
286 .hcd_priv_size = sizeof(struct ehci_hcd),
287
288 /*
289 * generic hardware linkage
290 */
291 .irq = ehci_irq,
292 .flags = HCD_MEMORY | HCD_USB2,
293
294 /*
295 * basic lifecycle operations
296 */
David Brownell8926bfa2005-11-28 08:40:38 -0800297 .reset = ehci_pci_setup,
David Brownell18807522005-11-23 15:45:37 -0800298 .start = ehci_run,
Matt Porter7ff71d62005-09-22 22:31:15 -0700299#ifdef CONFIG_PM
300 .suspend = ehci_pci_suspend,
301 .resume = ehci_pci_resume,
302#endif
David Brownell18807522005-11-23 15:45:37 -0800303 .stop = ehci_stop,
Matt Porter7ff71d62005-09-22 22:31:15 -0700304
305 /*
306 * managing i/o requests and associated device resources
307 */
308 .urb_enqueue = ehci_urb_enqueue,
309 .urb_dequeue = ehci_urb_dequeue,
310 .endpoint_disable = ehci_endpoint_disable,
311
312 /*
313 * scheduling support
314 */
315 .get_frame_number = ehci_get_frame,
316
317 /*
318 * root hub support
319 */
320 .hub_status_data = ehci_hub_status_data,
321 .hub_control = ehci_hub_control,
Alan Stern0c0382e2005-10-13 17:08:02 -0400322 .bus_suspend = ehci_bus_suspend,
323 .bus_resume = ehci_bus_resume,
Matt Porter7ff71d62005-09-22 22:31:15 -0700324};
325
326/*-------------------------------------------------------------------------*/
327
328/* PCI driver selection metadata; PCI hotplugging uses this */
329static const struct pci_device_id pci_ids [] = { {
330 /* handle any USB 2.0 EHCI controller */
331 PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0),
332 .driver_data = (unsigned long) &ehci_pci_hc_driver,
333 },
334 { /* end: all zeroes */ }
335};
David Brownellabcc9442005-11-23 15:45:32 -0800336MODULE_DEVICE_TABLE(pci, pci_ids);
Matt Porter7ff71d62005-09-22 22:31:15 -0700337
338/* pci driver glue; this is a "new style" PCI driver module */
339static struct pci_driver ehci_pci_driver = {
340 .name = (char *) hcd_name,
341 .id_table = pci_ids,
Matt Porter7ff71d62005-09-22 22:31:15 -0700342
343 .probe = usb_hcd_pci_probe,
344 .remove = usb_hcd_pci_remove,
345
346#ifdef CONFIG_PM
347 .suspend = usb_hcd_pci_suspend,
348 .resume = usb_hcd_pci_resume,
349#endif
350};
351
David Brownellabcc9442005-11-23 15:45:32 -0800352static int __init ehci_hcd_pci_init(void)
Matt Porter7ff71d62005-09-22 22:31:15 -0700353{
354 if (usb_disabled())
355 return -ENODEV;
356
David Brownellabcc9442005-11-23 15:45:32 -0800357 pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
Matt Porter7ff71d62005-09-22 22:31:15 -0700358 hcd_name,
David Brownellabcc9442005-11-23 15:45:32 -0800359 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
360 sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
Matt Porter7ff71d62005-09-22 22:31:15 -0700361
David Brownellabcc9442005-11-23 15:45:32 -0800362 return pci_register_driver(&ehci_pci_driver);
Matt Porter7ff71d62005-09-22 22:31:15 -0700363}
David Brownellabcc9442005-11-23 15:45:32 -0800364module_init(ehci_hcd_pci_init);
Matt Porter7ff71d62005-09-22 22:31:15 -0700365
David Brownellabcc9442005-11-23 15:45:32 -0800366static void __exit ehci_hcd_pci_cleanup(void)
Matt Porter7ff71d62005-09-22 22:31:15 -0700367{
David Brownellabcc9442005-11-23 15:45:32 -0800368 pci_unregister_driver(&ehci_pci_driver);
Matt Porter7ff71d62005-09-22 22:31:15 -0700369}
David Brownellabcc9442005-11-23 15:45:32 -0800370module_exit(ehci_hcd_pci_cleanup);