aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-pci.c
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2011-03-01 01:57:05 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-03-01 16:01:45 -0500
commitad93562bdeecdded7d02eaaaf1aa5705ab57b1b7 (patch)
tree92bd220ce673a8260fb4cb4799024529af664208 /drivers/usb/host/ehci-pci.c
parent53689ac1b677532be666a779e24b0ac9bd266354 (diff)
USB host: Move AMD PLL quirk to pci-quirks.c
This patch moves the AMD PLL quirk code in OHCI/EHCI driver to pci-quirks.c, and exports the functions to be used by xHCI driver later. AMD PLL quirk disable the optional PM feature inside specific SB700/SB800/Hudson-2/3 platforms under the following conditions: 1. If an isochronous device is connected to OHCI/EHCI/xHCI port and is active; 2. Optional PM feature that powers down the internal Bus PLL when the link is in low power state is enabled. Without AMD PLL quirk, USB isochronous stream may stutter or have breaks occasionally, which greatly impair the performance of audio/video streams. Currently AMD PLL quirk is implemented in OHCI and EHCI driver, and will be added to xHCI driver too. They are doing similar things actually, so move the quirk code to pci-quirks.c, which has several advantages: 1. Remove duplicate defines and functions in OHCI/EHCI (and xHCI) driver and make them cleaner; 2. AMD chipset information will be probed only once and then stored. Currently they're probed during every OHCI/EHCI initialization, move the detect code to pci-quirks.c saves the repeat detect cost; 3. Build up synchronization among OHCI/EHCI/xHCI driver. In current code, every host controller enable/disable PLL only according to its own status, and may enable PLL while there is still isoc transfer on other HCs. Move the quirk to pci-quirks.c prevents this issue. Signed-off-by: Andiry Xu <andiry.xu@amd.com> Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: Alex He <alex.he@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-pci.c')
-rw-r--r--drivers/usb/host/ehci-pci.c45
1 files changed, 6 insertions, 39 deletions
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 07bb982e59f6..d5eaea7caf89 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -44,42 +44,6 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
44 return 0; 44 return 0;
45} 45}
46 46
47static int ehci_quirk_amd_hudson(struct ehci_hcd *ehci)
48{
49 struct pci_dev *amd_smbus_dev;
50 u8 rev = 0;
51
52 amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL);
53 if (amd_smbus_dev) {
54 pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
55 if (rev < 0x40) {
56 pci_dev_put(amd_smbus_dev);
57 amd_smbus_dev = NULL;
58 return 0;
59 }
60 } else {
61 amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x780b, NULL);
62 if (!amd_smbus_dev)
63 return 0;
64 pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
65 if (rev < 0x11 || rev > 0x18) {
66 pci_dev_put(amd_smbus_dev);
67 amd_smbus_dev = NULL;
68 return 0;
69 }
70 }
71
72 if (!amd_nb_dev)
73 amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL);
74
75 ehci_info(ehci, "QUIRK: Enable exception for AMD Hudson ASPM\n");
76
77 pci_dev_put(amd_smbus_dev);
78 amd_smbus_dev = NULL;
79
80 return 1;
81}
82
83/* called during probe() after chip reset completes */ 47/* called during probe() after chip reset completes */
84static int ehci_pci_setup(struct usb_hcd *hcd) 48static int ehci_pci_setup(struct usb_hcd *hcd)
85{ 49{
@@ -138,9 +102,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
138 /* cache this readonly data; minimize chip reads */ 102 /* cache this readonly data; minimize chip reads */
139 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); 103 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
140 104
141 if (ehci_quirk_amd_hudson(ehci))
142 ehci->amd_l1_fix = 1;
143
144 retval = ehci_halt(ehci); 105 retval = ehci_halt(ehci);
145 if (retval) 106 if (retval)
146 return retval; 107 return retval;
@@ -191,6 +152,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
191 } 152 }
192 break; 153 break;
193 case PCI_VENDOR_ID_AMD: 154 case PCI_VENDOR_ID_AMD:
155 /* AMD PLL quirk */
156 if (usb_amd_find_chipset_info())
157 ehci->amd_pll_fix = 1;
194 /* AMD8111 EHCI doesn't work, according to AMD errata */ 158 /* AMD8111 EHCI doesn't work, according to AMD errata */
195 if (pdev->device == 0x7463) { 159 if (pdev->device == 0x7463) {
196 ehci_info(ehci, "ignoring AMD8111 (errata)\n"); 160 ehci_info(ehci, "ignoring AMD8111 (errata)\n");
@@ -236,6 +200,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
236 } 200 }
237 break; 201 break;
238 case PCI_VENDOR_ID_ATI: 202 case PCI_VENDOR_ID_ATI:
203 /* AMD PLL quirk */
204 if (usb_amd_find_chipset_info())
205 ehci->amd_pll_fix = 1;
239 /* SB600 and old version of SB700 have a bug in EHCI controller, 206 /* SB600 and old version of SB700 have a bug in EHCI controller,
240 * which causes usb devices lose response in some cases. 207 * which causes usb devices lose response in some cases.
241 */ 208 */