diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-17 12:54:16 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-17 12:54:16 -0500 |
commit | 479b46b5599b1e610630d7332e168c1f9c4ee0b4 (patch) | |
tree | c5d7e48576f5b5b6a61a2a2e5f85abaa941b85ab /drivers/usb/host/ohci-pci.c | |
parent | ce1fd3585709e833ad102167024e97217734dbfd (diff) |
Revert "USB host: Move AMD PLL quirk to pci-quirks.c"
This reverts commit b7d5b439b7a40dd0a0202fe1c118615a3fcc3b25.
It conflicts with commit baab93afc2844b68d57b0dcca5e1d34c5d7cf411 "USB:
EHCI: ASPM quirk of ISOC on AMD Hudson" and merging the two just doesn't
work properly.
Cc: Andiry Xu <andiry.xu@amd.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Alex He <alex.he@amd.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ohci-pci.c')
-rw-r--r-- | drivers/usb/host/ohci-pci.c | 110 |
1 files changed, 102 insertions, 8 deletions
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 9816a2870d00..36ee9a666e93 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -22,6 +22,24 @@ | |||
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | 23 | ||
24 | 24 | ||
25 | /* constants used to work around PM-related transfer | ||
26 | * glitches in some AMD 700 series southbridges | ||
27 | */ | ||
28 | #define AB_REG_BAR 0xf0 | ||
29 | #define AB_INDX(addr) ((addr) + 0x00) | ||
30 | #define AB_DATA(addr) ((addr) + 0x04) | ||
31 | #define AX_INDXC 0X30 | ||
32 | #define AX_DATAC 0x34 | ||
33 | |||
34 | #define NB_PCIE_INDX_ADDR 0xe0 | ||
35 | #define NB_PCIE_INDX_DATA 0xe4 | ||
36 | #define PCIE_P_CNTL 0x10040 | ||
37 | #define BIF_NB 0x10002 | ||
38 | |||
39 | static struct pci_dev *amd_smbus_dev; | ||
40 | static struct pci_dev *amd_hb_dev; | ||
41 | static int amd_ohci_iso_count; | ||
42 | |||
25 | /*-------------------------------------------------------------------------*/ | 43 | /*-------------------------------------------------------------------------*/ |
26 | 44 | ||
27 | static int broken_suspend(struct usb_hcd *hcd) | 45 | static int broken_suspend(struct usb_hcd *hcd) |
@@ -150,14 +168,11 @@ static int ohci_quirk_nec(struct usb_hcd *hcd) | |||
150 | static int ohci_quirk_amd700(struct usb_hcd *hcd) | 168 | static int ohci_quirk_amd700(struct usb_hcd *hcd) |
151 | { | 169 | { |
152 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | 170 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
153 | struct pci_dev *amd_smbus_dev; | ||
154 | u8 rev = 0; | 171 | u8 rev = 0; |
155 | 172 | ||
156 | if (usb_amd_find_chipset_info()) | 173 | if (!amd_smbus_dev) |
157 | ohci->flags |= OHCI_QUIRK_AMD_PLL; | 174 | amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, |
158 | 175 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); | |
159 | amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, | ||
160 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); | ||
161 | if (!amd_smbus_dev) | 176 | if (!amd_smbus_dev) |
162 | return 0; | 177 | return 0; |
163 | 178 | ||
@@ -169,8 +184,19 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) | |||
169 | ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); | 184 | ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); |
170 | } | 185 | } |
171 | 186 | ||
172 | pci_dev_put(amd_smbus_dev); | 187 | if ((rev > 0x3b) || (rev < 0x30)) { |
173 | amd_smbus_dev = NULL; | 188 | pci_dev_put(amd_smbus_dev); |
189 | amd_smbus_dev = NULL; | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | amd_ohci_iso_count++; | ||
194 | |||
195 | if (!amd_hb_dev) | ||
196 | amd_hb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9600, NULL); | ||
197 | |||
198 | ohci->flags |= OHCI_QUIRK_AMD_ISO; | ||
199 | ohci_dbg(ohci, "enabled AMD ISO transfers quirk\n"); | ||
174 | 200 | ||
175 | return 0; | 201 | return 0; |
176 | } | 202 | } |
@@ -189,6 +215,74 @@ static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd) | |||
189 | return 0; | 215 | return 0; |
190 | } | 216 | } |
191 | 217 | ||
218 | /* | ||
219 | * The hardware normally enables the A-link power management feature, which | ||
220 | * lets the system lower the power consumption in idle states. | ||
221 | * | ||
222 | * Assume the system is configured to have USB 1.1 ISO transfers going | ||
223 | * to or from a USB device. Without this quirk, that stream may stutter | ||
224 | * or have breaks occasionally. For transfers going to speakers, this | ||
225 | * makes a very audible mess... | ||
226 | * | ||
227 | * That audio playback corruption is due to the audio stream getting | ||
228 | * interrupted occasionally when the link goes in lower power state | ||
229 | * This USB quirk prevents the link going into that lower power state | ||
230 | * during audio playback or other ISO operations. | ||
231 | */ | ||
232 | static void quirk_amd_pll(int on) | ||
233 | { | ||
234 | u32 addr; | ||
235 | u32 val; | ||
236 | u32 bit = (on > 0) ? 1 : 0; | ||
237 | |||
238 | pci_read_config_dword(amd_smbus_dev, AB_REG_BAR, &addr); | ||
239 | |||
240 | /* BIT names/meanings are NDA-protected, sorry ... */ | ||
241 | |||
242 | outl(AX_INDXC, AB_INDX(addr)); | ||
243 | outl(0x40, AB_DATA(addr)); | ||
244 | outl(AX_DATAC, AB_INDX(addr)); | ||
245 | val = inl(AB_DATA(addr)); | ||
246 | val &= ~((1 << 3) | (1 << 4) | (1 << 9)); | ||
247 | val |= (bit << 3) | ((!bit) << 4) | ((!bit) << 9); | ||
248 | outl(val, AB_DATA(addr)); | ||
249 | |||
250 | if (amd_hb_dev) { | ||
251 | addr = PCIE_P_CNTL; | ||
252 | pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr); | ||
253 | |||
254 | pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val); | ||
255 | val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12)); | ||
256 | val |= bit | (bit << 3) | (bit << 12); | ||
257 | val |= ((!bit) << 4) | ((!bit) << 9); | ||
258 | pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val); | ||
259 | |||
260 | addr = BIF_NB; | ||
261 | pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr); | ||
262 | |||
263 | pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val); | ||
264 | val &= ~(1 << 8); | ||
265 | val |= bit << 8; | ||
266 | pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | static void amd_iso_dev_put(void) | ||
271 | { | ||
272 | amd_ohci_iso_count--; | ||
273 | if (amd_ohci_iso_count == 0) { | ||
274 | if (amd_smbus_dev) { | ||
275 | pci_dev_put(amd_smbus_dev); | ||
276 | amd_smbus_dev = NULL; | ||
277 | } | ||
278 | if (amd_hb_dev) { | ||
279 | pci_dev_put(amd_hb_dev); | ||
280 | amd_hb_dev = NULL; | ||
281 | } | ||
282 | } | ||
283 | |||
284 | } | ||
285 | |||
192 | static void sb800_prefetch(struct ohci_hcd *ohci, int on) | 286 | static void sb800_prefetch(struct ohci_hcd *ohci, int on) |
193 | { | 287 | { |
194 | struct pci_dev *pdev; | 288 | struct pci_dev *pdev; |