diff options
Diffstat (limited to 'drivers/usb/host/pci-quirks.c')
-rw-r--r-- | drivers/usb/host/pci-quirks.c | 523 |
1 files changed, 444 insertions, 79 deletions
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 83b5f9cea85a..fd930618c28f 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/acpi.h> | 16 | #include <linux/acpi.h> |
17 | #include <linux/dmi.h> | ||
17 | #include "pci-quirks.h" | 18 | #include "pci-quirks.h" |
18 | #include "xhci-ext-caps.h" | 19 | #include "xhci-ext-caps.h" |
19 | 20 | ||
@@ -52,6 +53,298 @@ | |||
52 | #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ | 53 | #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ |
53 | #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ | 54 | #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ |
54 | 55 | ||
56 | /* AMD quirk use */ | ||
57 | #define AB_REG_BAR_LOW 0xe0 | ||
58 | #define AB_REG_BAR_HIGH 0xe1 | ||
59 | #define AB_REG_BAR_SB700 0xf0 | ||
60 | #define AB_INDX(addr) ((addr) + 0x00) | ||
61 | #define AB_DATA(addr) ((addr) + 0x04) | ||
62 | #define AX_INDXC 0x30 | ||
63 | #define AX_DATAC 0x34 | ||
64 | |||
65 | #define NB_PCIE_INDX_ADDR 0xe0 | ||
66 | #define NB_PCIE_INDX_DATA 0xe4 | ||
67 | #define PCIE_P_CNTL 0x10040 | ||
68 | #define BIF_NB 0x10002 | ||
69 | #define NB_PIF0_PWRDOWN_0 0x01100012 | ||
70 | #define NB_PIF0_PWRDOWN_1 0x01100013 | ||
71 | |||
72 | #define USB_INTEL_XUSB2PR 0xD0 | ||
73 | #define USB_INTEL_USB3_PSSEN 0xD8 | ||
74 | |||
75 | static struct amd_chipset_info { | ||
76 | struct pci_dev *nb_dev; | ||
77 | struct pci_dev *smbus_dev; | ||
78 | int nb_type; | ||
79 | int sb_type; | ||
80 | int isoc_reqs; | ||
81 | int probe_count; | ||
82 | int probe_result; | ||
83 | } amd_chipset; | ||
84 | |||
85 | static DEFINE_SPINLOCK(amd_lock); | ||
86 | |||
87 | int usb_amd_find_chipset_info(void) | ||
88 | { | ||
89 | u8 rev = 0; | ||
90 | unsigned long flags; | ||
91 | struct amd_chipset_info info; | ||
92 | int ret; | ||
93 | |||
94 | spin_lock_irqsave(&amd_lock, flags); | ||
95 | |||
96 | /* probe only once */ | ||
97 | if (amd_chipset.probe_count > 0) { | ||
98 | amd_chipset.probe_count++; | ||
99 | spin_unlock_irqrestore(&amd_lock, flags); | ||
100 | return amd_chipset.probe_result; | ||
101 | } | ||
102 | memset(&info, 0, sizeof(info)); | ||
103 | spin_unlock_irqrestore(&amd_lock, flags); | ||
104 | |||
105 | info.smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); | ||
106 | if (info.smbus_dev) { | ||
107 | rev = info.smbus_dev->revision; | ||
108 | if (rev >= 0x40) | ||
109 | info.sb_type = 1; | ||
110 | else if (rev >= 0x30 && rev <= 0x3b) | ||
111 | info.sb_type = 3; | ||
112 | } else { | ||
113 | info.smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, | ||
114 | 0x780b, NULL); | ||
115 | if (!info.smbus_dev) { | ||
116 | ret = 0; | ||
117 | goto commit; | ||
118 | } | ||
119 | |||
120 | rev = info.smbus_dev->revision; | ||
121 | if (rev >= 0x11 && rev <= 0x18) | ||
122 | info.sb_type = 2; | ||
123 | } | ||
124 | |||
125 | if (info.sb_type == 0) { | ||
126 | if (info.smbus_dev) { | ||
127 | pci_dev_put(info.smbus_dev); | ||
128 | info.smbus_dev = NULL; | ||
129 | } | ||
130 | ret = 0; | ||
131 | goto commit; | ||
132 | } | ||
133 | |||
134 | info.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9601, NULL); | ||
135 | if (info.nb_dev) { | ||
136 | info.nb_type = 1; | ||
137 | } else { | ||
138 | info.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL); | ||
139 | if (info.nb_dev) { | ||
140 | info.nb_type = 2; | ||
141 | } else { | ||
142 | info.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, | ||
143 | 0x9600, NULL); | ||
144 | if (info.nb_dev) | ||
145 | info.nb_type = 3; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | ret = info.probe_result = 1; | ||
150 | printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n"); | ||
151 | |||
152 | commit: | ||
153 | |||
154 | spin_lock_irqsave(&amd_lock, flags); | ||
155 | if (amd_chipset.probe_count > 0) { | ||
156 | /* race - someone else was faster - drop devices */ | ||
157 | |||
158 | /* Mark that we where here */ | ||
159 | amd_chipset.probe_count++; | ||
160 | ret = amd_chipset.probe_result; | ||
161 | |||
162 | spin_unlock_irqrestore(&amd_lock, flags); | ||
163 | |||
164 | if (info.nb_dev) | ||
165 | pci_dev_put(info.nb_dev); | ||
166 | if (info.smbus_dev) | ||
167 | pci_dev_put(info.smbus_dev); | ||
168 | |||
169 | } else { | ||
170 | /* no race - commit the result */ | ||
171 | info.probe_count++; | ||
172 | amd_chipset = info; | ||
173 | spin_unlock_irqrestore(&amd_lock, flags); | ||
174 | } | ||
175 | |||
176 | return ret; | ||
177 | } | ||
178 | EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info); | ||
179 | |||
180 | /* | ||
181 | * The hardware normally enables the A-link power management feature, which | ||
182 | * lets the system lower the power consumption in idle states. | ||
183 | * | ||
184 | * This USB quirk prevents the link going into that lower power state | ||
185 | * during isochronous transfers. | ||
186 | * | ||
187 | * Without this quirk, isochronous stream on OHCI/EHCI/xHCI controllers of | ||
188 | * some AMD platforms may stutter or have breaks occasionally. | ||
189 | */ | ||
190 | static void usb_amd_quirk_pll(int disable) | ||
191 | { | ||
192 | u32 addr, addr_low, addr_high, val; | ||
193 | u32 bit = disable ? 0 : 1; | ||
194 | unsigned long flags; | ||
195 | |||
196 | spin_lock_irqsave(&amd_lock, flags); | ||
197 | |||
198 | if (disable) { | ||
199 | amd_chipset.isoc_reqs++; | ||
200 | if (amd_chipset.isoc_reqs > 1) { | ||
201 | spin_unlock_irqrestore(&amd_lock, flags); | ||
202 | return; | ||
203 | } | ||
204 | } else { | ||
205 | amd_chipset.isoc_reqs--; | ||
206 | if (amd_chipset.isoc_reqs > 0) { | ||
207 | spin_unlock_irqrestore(&amd_lock, flags); | ||
208 | return; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | if (amd_chipset.sb_type == 1 || amd_chipset.sb_type == 2) { | ||
213 | outb_p(AB_REG_BAR_LOW, 0xcd6); | ||
214 | addr_low = inb_p(0xcd7); | ||
215 | outb_p(AB_REG_BAR_HIGH, 0xcd6); | ||
216 | addr_high = inb_p(0xcd7); | ||
217 | addr = addr_high << 8 | addr_low; | ||
218 | |||
219 | outl_p(0x30, AB_INDX(addr)); | ||
220 | outl_p(0x40, AB_DATA(addr)); | ||
221 | outl_p(0x34, AB_INDX(addr)); | ||
222 | val = inl_p(AB_DATA(addr)); | ||
223 | } else if (amd_chipset.sb_type == 3) { | ||
224 | pci_read_config_dword(amd_chipset.smbus_dev, | ||
225 | AB_REG_BAR_SB700, &addr); | ||
226 | outl(AX_INDXC, AB_INDX(addr)); | ||
227 | outl(0x40, AB_DATA(addr)); | ||
228 | outl(AX_DATAC, AB_INDX(addr)); | ||
229 | val = inl(AB_DATA(addr)); | ||
230 | } else { | ||
231 | spin_unlock_irqrestore(&amd_lock, flags); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | if (disable) { | ||
236 | val &= ~0x08; | ||
237 | val |= (1 << 4) | (1 << 9); | ||
238 | } else { | ||
239 | val |= 0x08; | ||
240 | val &= ~((1 << 4) | (1 << 9)); | ||
241 | } | ||
242 | outl_p(val, AB_DATA(addr)); | ||
243 | |||
244 | if (!amd_chipset.nb_dev) { | ||
245 | spin_unlock_irqrestore(&amd_lock, flags); | ||
246 | return; | ||
247 | } | ||
248 | |||
249 | if (amd_chipset.nb_type == 1 || amd_chipset.nb_type == 3) { | ||
250 | addr = PCIE_P_CNTL; | ||
251 | pci_write_config_dword(amd_chipset.nb_dev, | ||
252 | NB_PCIE_INDX_ADDR, addr); | ||
253 | pci_read_config_dword(amd_chipset.nb_dev, | ||
254 | NB_PCIE_INDX_DATA, &val); | ||
255 | |||
256 | val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12)); | ||
257 | val |= bit | (bit << 3) | (bit << 12); | ||
258 | val |= ((!bit) << 4) | ((!bit) << 9); | ||
259 | pci_write_config_dword(amd_chipset.nb_dev, | ||
260 | NB_PCIE_INDX_DATA, val); | ||
261 | |||
262 | addr = BIF_NB; | ||
263 | pci_write_config_dword(amd_chipset.nb_dev, | ||
264 | NB_PCIE_INDX_ADDR, addr); | ||
265 | pci_read_config_dword(amd_chipset.nb_dev, | ||
266 | NB_PCIE_INDX_DATA, &val); | ||
267 | val &= ~(1 << 8); | ||
268 | val |= bit << 8; | ||
269 | |||
270 | pci_write_config_dword(amd_chipset.nb_dev, | ||
271 | NB_PCIE_INDX_DATA, val); | ||
272 | } else if (amd_chipset.nb_type == 2) { | ||
273 | addr = NB_PIF0_PWRDOWN_0; | ||
274 | pci_write_config_dword(amd_chipset.nb_dev, | ||
275 | NB_PCIE_INDX_ADDR, addr); | ||
276 | pci_read_config_dword(amd_chipset.nb_dev, | ||
277 | NB_PCIE_INDX_DATA, &val); | ||
278 | if (disable) | ||
279 | val &= ~(0x3f << 7); | ||
280 | else | ||
281 | val |= 0x3f << 7; | ||
282 | |||
283 | pci_write_config_dword(amd_chipset.nb_dev, | ||
284 | NB_PCIE_INDX_DATA, val); | ||
285 | |||
286 | addr = NB_PIF0_PWRDOWN_1; | ||
287 | pci_write_config_dword(amd_chipset.nb_dev, | ||
288 | NB_PCIE_INDX_ADDR, addr); | ||
289 | pci_read_config_dword(amd_chipset.nb_dev, | ||
290 | NB_PCIE_INDX_DATA, &val); | ||
291 | if (disable) | ||
292 | val &= ~(0x3f << 7); | ||
293 | else | ||
294 | val |= 0x3f << 7; | ||
295 | |||
296 | pci_write_config_dword(amd_chipset.nb_dev, | ||
297 | NB_PCIE_INDX_DATA, val); | ||
298 | } | ||
299 | |||
300 | spin_unlock_irqrestore(&amd_lock, flags); | ||
301 | return; | ||
302 | } | ||
303 | |||
304 | void usb_amd_quirk_pll_disable(void) | ||
305 | { | ||
306 | usb_amd_quirk_pll(1); | ||
307 | } | ||
308 | EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable); | ||
309 | |||
310 | void usb_amd_quirk_pll_enable(void) | ||
311 | { | ||
312 | usb_amd_quirk_pll(0); | ||
313 | } | ||
314 | EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_enable); | ||
315 | |||
316 | void usb_amd_dev_put(void) | ||
317 | { | ||
318 | struct pci_dev *nb, *smbus; | ||
319 | unsigned long flags; | ||
320 | |||
321 | spin_lock_irqsave(&amd_lock, flags); | ||
322 | |||
323 | amd_chipset.probe_count--; | ||
324 | if (amd_chipset.probe_count > 0) { | ||
325 | spin_unlock_irqrestore(&amd_lock, flags); | ||
326 | return; | ||
327 | } | ||
328 | |||
329 | /* save them to pci_dev_put outside of spinlock */ | ||
330 | nb = amd_chipset.nb_dev; | ||
331 | smbus = amd_chipset.smbus_dev; | ||
332 | |||
333 | amd_chipset.nb_dev = NULL; | ||
334 | amd_chipset.smbus_dev = NULL; | ||
335 | amd_chipset.nb_type = 0; | ||
336 | amd_chipset.sb_type = 0; | ||
337 | amd_chipset.isoc_reqs = 0; | ||
338 | amd_chipset.probe_result = 0; | ||
339 | |||
340 | spin_unlock_irqrestore(&amd_lock, flags); | ||
341 | |||
342 | if (nb) | ||
343 | pci_dev_put(nb); | ||
344 | if (smbus) | ||
345 | pci_dev_put(smbus); | ||
346 | } | ||
347 | EXPORT_SYMBOL_GPL(usb_amd_dev_put); | ||
55 | 348 | ||
56 | /* | 349 | /* |
57 | * Make sure the controller is completely inactive, unable to | 350 | * Make sure the controller is completely inactive, unable to |
@@ -169,6 +462,7 @@ static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx) | |||
169 | static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | 462 | static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) |
170 | { | 463 | { |
171 | void __iomem *base; | 464 | void __iomem *base; |
465 | u32 control; | ||
172 | 466 | ||
173 | if (!mmio_resource_enabled(pdev, 0)) | 467 | if (!mmio_resource_enabled(pdev, 0)) |
174 | return; | 468 | return; |
@@ -177,10 +471,14 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
177 | if (base == NULL) | 471 | if (base == NULL) |
178 | return; | 472 | return; |
179 | 473 | ||
474 | control = readl(base + OHCI_CONTROL); | ||
475 | |||
180 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ | 476 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ |
181 | #ifndef __hppa__ | 477 | #ifdef __hppa__ |
182 | { | 478 | #define OHCI_CTRL_MASK (OHCI_CTRL_RWC | OHCI_CTRL_IR) |
183 | u32 control = readl(base + OHCI_CONTROL); | 479 | #else |
480 | #define OHCI_CTRL_MASK OHCI_CTRL_RWC | ||
481 | |||
184 | if (control & OHCI_CTRL_IR) { | 482 | if (control & OHCI_CTRL_IR) { |
185 | int wait_time = 500; /* arbitrary; 5 seconds */ | 483 | int wait_time = 500; /* arbitrary; 5 seconds */ |
186 | writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); | 484 | writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); |
@@ -194,13 +492,12 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
194 | dev_warn(&pdev->dev, "OHCI: BIOS handoff failed" | 492 | dev_warn(&pdev->dev, "OHCI: BIOS handoff failed" |
195 | " (BIOS bug?) %08x\n", | 493 | " (BIOS bug?) %08x\n", |
196 | readl(base + OHCI_CONTROL)); | 494 | readl(base + OHCI_CONTROL)); |
197 | |||
198 | /* reset controller, preserving RWC */ | ||
199 | writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); | ||
200 | } | 495 | } |
201 | } | ||
202 | #endif | 496 | #endif |
203 | 497 | ||
498 | /* reset controller, preserving RWC (and possibly IR) */ | ||
499 | writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); | ||
500 | |||
204 | /* | 501 | /* |
205 | * disable interrupts | 502 | * disable interrupts |
206 | */ | 503 | */ |
@@ -210,14 +507,84 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
210 | iounmap(base); | 507 | iounmap(base); |
211 | } | 508 | } |
212 | 509 | ||
510 | static void __devinit ehci_bios_handoff(struct pci_dev *pdev, | ||
511 | void __iomem *op_reg_base, | ||
512 | u32 cap, u8 offset) | ||
513 | { | ||
514 | int try_handoff = 1, tried_handoff = 0; | ||
515 | |||
516 | /* The Pegatron Lucid (ExoPC) tablet sporadically waits for 90 | ||
517 | * seconds trying the handoff on its unused controller. Skip | ||
518 | * it. */ | ||
519 | if (pdev->vendor == 0x8086 && pdev->device == 0x283a) { | ||
520 | const char *dmi_bn = dmi_get_system_info(DMI_BOARD_NAME); | ||
521 | const char *dmi_bv = dmi_get_system_info(DMI_BIOS_VERSION); | ||
522 | if (dmi_bn && !strcmp(dmi_bn, "EXOPG06411") && | ||
523 | dmi_bv && !strcmp(dmi_bv, "Lucid-CE-133")) | ||
524 | try_handoff = 0; | ||
525 | } | ||
526 | |||
527 | if (try_handoff && (cap & EHCI_USBLEGSUP_BIOS)) { | ||
528 | dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n"); | ||
529 | |||
530 | #if 0 | ||
531 | /* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on, | ||
532 | * but that seems dubious in general (the BIOS left it off intentionally) | ||
533 | * and is known to prevent some systems from booting. so we won't do this | ||
534 | * unless maybe we can determine when we're on a system that needs SMI forced. | ||
535 | */ | ||
536 | /* BIOS workaround (?): be sure the pre-Linux code | ||
537 | * receives the SMI | ||
538 | */ | ||
539 | pci_read_config_dword(pdev, offset + EHCI_USBLEGCTLSTS, &val); | ||
540 | pci_write_config_dword(pdev, offset + EHCI_USBLEGCTLSTS, | ||
541 | val | EHCI_USBLEGCTLSTS_SOOE); | ||
542 | #endif | ||
543 | |||
544 | /* some systems get upset if this semaphore is | ||
545 | * set for any other reason than forcing a BIOS | ||
546 | * handoff.. | ||
547 | */ | ||
548 | pci_write_config_byte(pdev, offset + 3, 1); | ||
549 | } | ||
550 | |||
551 | /* if boot firmware now owns EHCI, spin till it hands it over. */ | ||
552 | if (try_handoff) { | ||
553 | int msec = 1000; | ||
554 | while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { | ||
555 | tried_handoff = 1; | ||
556 | msleep(10); | ||
557 | msec -= 10; | ||
558 | pci_read_config_dword(pdev, offset, &cap); | ||
559 | } | ||
560 | } | ||
561 | |||
562 | if (cap & EHCI_USBLEGSUP_BIOS) { | ||
563 | /* well, possibly buggy BIOS... try to shut it down, | ||
564 | * and hope nothing goes too wrong | ||
565 | */ | ||
566 | if (try_handoff) | ||
567 | dev_warn(&pdev->dev, "EHCI: BIOS handoff failed" | ||
568 | " (BIOS bug?) %08x\n", cap); | ||
569 | pci_write_config_byte(pdev, offset + 2, 0); | ||
570 | } | ||
571 | |||
572 | /* just in case, always disable EHCI SMIs */ | ||
573 | pci_write_config_dword(pdev, offset + EHCI_USBLEGCTLSTS, 0); | ||
574 | |||
575 | /* If the BIOS ever owned the controller then we can't expect | ||
576 | * any power sessions to remain intact. | ||
577 | */ | ||
578 | if (tried_handoff) | ||
579 | writel(0, op_reg_base + EHCI_CONFIGFLAG); | ||
580 | } | ||
581 | |||
213 | static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | 582 | static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) |
214 | { | 583 | { |
215 | int wait_time, delta; | ||
216 | void __iomem *base, *op_reg_base; | 584 | void __iomem *base, *op_reg_base; |
217 | u32 hcc_params, val; | 585 | u32 hcc_params, cap, val; |
218 | u8 offset, cap_length; | 586 | u8 offset, cap_length; |
219 | int count = 256/4; | 587 | int wait_time, delta, count = 256/4; |
220 | int tried_handoff = 0; | ||
221 | 588 | ||
222 | if (!mmio_resource_enabled(pdev, 0)) | 589 | if (!mmio_resource_enabled(pdev, 0)) |
223 | return; | 590 | return; |
@@ -236,77 +603,17 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
236 | hcc_params = readl(base + EHCI_HCC_PARAMS); | 603 | hcc_params = readl(base + EHCI_HCC_PARAMS); |
237 | offset = (hcc_params >> 8) & 0xff; | 604 | offset = (hcc_params >> 8) & 0xff; |
238 | while (offset && --count) { | 605 | while (offset && --count) { |
239 | u32 cap; | ||
240 | int msec; | ||
241 | |||
242 | pci_read_config_dword(pdev, offset, &cap); | 606 | pci_read_config_dword(pdev, offset, &cap); |
243 | switch (cap & 0xff) { | ||
244 | case 1: /* BIOS/SMM/... handoff support */ | ||
245 | if ((cap & EHCI_USBLEGSUP_BIOS)) { | ||
246 | dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n"); | ||
247 | 607 | ||
248 | #if 0 | 608 | switch (cap & 0xff) { |
249 | /* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on, | 609 | case 1: |
250 | * but that seems dubious in general (the BIOS left it off intentionally) | 610 | ehci_bios_handoff(pdev, op_reg_base, cap, offset); |
251 | * and is known to prevent some systems from booting. so we won't do this | ||
252 | * unless maybe we can determine when we're on a system that needs SMI forced. | ||
253 | */ | ||
254 | /* BIOS workaround (?): be sure the | ||
255 | * pre-Linux code receives the SMI | ||
256 | */ | ||
257 | pci_read_config_dword(pdev, | ||
258 | offset + EHCI_USBLEGCTLSTS, | ||
259 | &val); | ||
260 | pci_write_config_dword(pdev, | ||
261 | offset + EHCI_USBLEGCTLSTS, | ||
262 | val | EHCI_USBLEGCTLSTS_SOOE); | ||
263 | #endif | ||
264 | |||
265 | /* some systems get upset if this semaphore is | ||
266 | * set for any other reason than forcing a BIOS | ||
267 | * handoff.. | ||
268 | */ | ||
269 | pci_write_config_byte(pdev, offset + 3, 1); | ||
270 | } | ||
271 | |||
272 | /* if boot firmware now owns EHCI, spin till | ||
273 | * it hands it over. | ||
274 | */ | ||
275 | msec = 1000; | ||
276 | while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { | ||
277 | tried_handoff = 1; | ||
278 | msleep(10); | ||
279 | msec -= 10; | ||
280 | pci_read_config_dword(pdev, offset, &cap); | ||
281 | } | ||
282 | |||
283 | if (cap & EHCI_USBLEGSUP_BIOS) { | ||
284 | /* well, possibly buggy BIOS... try to shut | ||
285 | * it down, and hope nothing goes too wrong | ||
286 | */ | ||
287 | dev_warn(&pdev->dev, "EHCI: BIOS handoff failed" | ||
288 | " (BIOS bug?) %08x\n", cap); | ||
289 | pci_write_config_byte(pdev, offset + 2, 0); | ||
290 | } | ||
291 | |||
292 | /* just in case, always disable EHCI SMIs */ | ||
293 | pci_write_config_dword(pdev, | ||
294 | offset + EHCI_USBLEGCTLSTS, | ||
295 | 0); | ||
296 | |||
297 | /* If the BIOS ever owned the controller then we | ||
298 | * can't expect any power sessions to remain intact. | ||
299 | */ | ||
300 | if (tried_handoff) | ||
301 | writel(0, op_reg_base + EHCI_CONFIGFLAG); | ||
302 | break; | 611 | break; |
303 | case 0: /* illegal reserved capability */ | 612 | case 0: /* Illegal reserved cap, set cap=0 so we exit */ |
304 | cap = 0; | 613 | cap = 0; /* then fallthrough... */ |
305 | /* FALLTHROUGH */ | ||
306 | default: | 614 | default: |
307 | dev_warn(&pdev->dev, "EHCI: unrecognized capability " | 615 | dev_warn(&pdev->dev, "EHCI: unrecognized capability " |
308 | "%02x\n", cap & 0xff); | 616 | "%02x\n", cap & 0xff); |
309 | break; | ||
310 | } | 617 | } |
311 | offset = (cap >> 8) & 0xff; | 618 | offset = (cap >> 8) & 0xff; |
312 | } | 619 | } |
@@ -338,8 +645,6 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
338 | writel(0x3f, op_reg_base + EHCI_USBSTS); | 645 | writel(0x3f, op_reg_base + EHCI_USBSTS); |
339 | 646 | ||
340 | iounmap(base); | 647 | iounmap(base); |
341 | |||
342 | return; | ||
343 | } | 648 | } |
344 | 649 | ||
345 | /* | 650 | /* |
@@ -371,6 +676,64 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done, | |||
371 | return -ETIMEDOUT; | 676 | return -ETIMEDOUT; |
372 | } | 677 | } |
373 | 678 | ||
679 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev) | ||
680 | { | ||
681 | return pdev->class == PCI_CLASS_SERIAL_USB_XHCI && | ||
682 | pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
683 | pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI; | ||
684 | } | ||
685 | EXPORT_SYMBOL_GPL(usb_is_intel_switchable_xhci); | ||
686 | |||
687 | /* | ||
688 | * Intel's Panther Point chipset has two host controllers (EHCI and xHCI) that | ||
689 | * share some number of ports. These ports can be switched between either | ||
690 | * controller. Not all of the ports under the EHCI host controller may be | ||
691 | * switchable. | ||
692 | * | ||
693 | * The ports should be switched over to xHCI before PCI probes for any device | ||
694 | * start. This avoids active devices under EHCI being disconnected during the | ||
695 | * port switchover, which could cause loss of data on USB storage devices, or | ||
696 | * failed boot when the root file system is on a USB mass storage device and is | ||
697 | * enumerated under EHCI first. | ||
698 | * | ||
699 | * We write into the xHC's PCI configuration space in some Intel-specific | ||
700 | * registers to switch the ports over. The USB 3.0 terminations and the USB | ||
701 | * 2.0 data wires are switched separately. We want to enable the SuperSpeed | ||
702 | * terminations before switching the USB 2.0 wires over, so that USB 3.0 | ||
703 | * devices connect at SuperSpeed, rather than at USB 2.0 speeds. | ||
704 | */ | ||
705 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | ||
706 | { | ||
707 | u32 ports_available; | ||
708 | |||
709 | ports_available = 0xffffffff; | ||
710 | /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable | ||
711 | * Register, to turn on SuperSpeed terminations for all | ||
712 | * available ports. | ||
713 | */ | ||
714 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, | ||
715 | cpu_to_le32(ports_available)); | ||
716 | |||
717 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, | ||
718 | &ports_available); | ||
719 | dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " | ||
720 | "under xHCI: 0x%x\n", ports_available); | ||
721 | |||
722 | ports_available = 0xffffffff; | ||
723 | /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to | ||
724 | * switch the USB 2.0 power and data lines over to the xHCI | ||
725 | * host. | ||
726 | */ | ||
727 | pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, | ||
728 | cpu_to_le32(ports_available)); | ||
729 | |||
730 | pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, | ||
731 | &ports_available); | ||
732 | dev_dbg(&xhci_pdev->dev, "USB 2.0 ports that are now switched over " | ||
733 | "to xHCI: 0x%x\n", ports_available); | ||
734 | } | ||
735 | EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); | ||
736 | |||
374 | /** | 737 | /** |
375 | * PCI Quirks for xHCI. | 738 | * PCI Quirks for xHCI. |
376 | * | 739 | * |
@@ -430,6 +793,8 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
430 | writel(XHCI_LEGACY_DISABLE_SMI, | 793 | writel(XHCI_LEGACY_DISABLE_SMI, |
431 | base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); | 794 | base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); |
432 | 795 | ||
796 | if (usb_is_intel_switchable_xhci(pdev)) | ||
797 | usb_enable_xhci_ports(pdev); | ||
433 | hc_init: | 798 | hc_init: |
434 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); | 799 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); |
435 | 800 | ||