aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-sched.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-sched.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-sched.c')
-rw-r--r--drivers/usb/host/ehci-sched.c73
1 files changed, 8 insertions, 65 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 30fbdbe1cf1e..1543c838b3d1 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1587,63 +1587,6 @@ itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
1587 *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); 1587 *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
1588} 1588}
1589 1589
1590#define AB_REG_BAR_LOW 0xe0
1591#define AB_REG_BAR_HIGH 0xe1
1592#define AB_INDX(addr) ((addr) + 0x00)
1593#define AB_DATA(addr) ((addr) + 0x04)
1594#define NB_PCIE_INDX_ADDR 0xe0
1595#define NB_PCIE_INDX_DATA 0xe4
1596#define NB_PIF0_PWRDOWN_0 0x01100012
1597#define NB_PIF0_PWRDOWN_1 0x01100013
1598
1599static void ehci_quirk_amd_L1(struct ehci_hcd *ehci, int disable)
1600{
1601 u32 addr, addr_low, addr_high, val;
1602
1603 outb_p(AB_REG_BAR_LOW, 0xcd6);
1604 addr_low = inb_p(0xcd7);
1605 outb_p(AB_REG_BAR_HIGH, 0xcd6);
1606 addr_high = inb_p(0xcd7);
1607 addr = addr_high << 8 | addr_low;
1608 outl_p(0x30, AB_INDX(addr));
1609 outl_p(0x40, AB_DATA(addr));
1610 outl_p(0x34, AB_INDX(addr));
1611 val = inl_p(AB_DATA(addr));
1612
1613 if (disable) {
1614 val &= ~0x8;
1615 val |= (1 << 4) | (1 << 9);
1616 } else {
1617 val |= 0x8;
1618 val &= ~((1 << 4) | (1 << 9));
1619 }
1620 outl_p(val, AB_DATA(addr));
1621
1622 if (amd_nb_dev) {
1623 addr = NB_PIF0_PWRDOWN_0;
1624 pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr);
1625 pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val);
1626 if (disable)
1627 val &= ~(0x3f << 7);
1628 else
1629 val |= 0x3f << 7;
1630
1631 pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val);
1632
1633 addr = NB_PIF0_PWRDOWN_1;
1634 pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr);
1635 pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val);
1636 if (disable)
1637 val &= ~(0x3f << 7);
1638 else
1639 val |= 0x3f << 7;
1640
1641 pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val);
1642 }
1643
1644 return;
1645}
1646
1647/* fit urb's itds into the selected schedule slot; activate as needed */ 1590/* fit urb's itds into the selected schedule slot; activate as needed */
1648static int 1591static int
1649itd_link_urb ( 1592itd_link_urb (
@@ -1672,8 +1615,8 @@ itd_link_urb (
1672 } 1615 }
1673 1616
1674 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { 1617 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
1675 if (ehci->amd_l1_fix == 1) 1618 if (ehci->amd_pll_fix == 1)
1676 ehci_quirk_amd_L1(ehci, 1); 1619 usb_amd_quirk_pll_disable();
1677 } 1620 }
1678 1621
1679 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; 1622 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
@@ -1801,8 +1744,8 @@ itd_complete (
1801 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; 1744 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
1802 1745
1803 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { 1746 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
1804 if (ehci->amd_l1_fix == 1) 1747 if (ehci->amd_pll_fix == 1)
1805 ehci_quirk_amd_L1(ehci, 0); 1748 usb_amd_quirk_pll_enable();
1806 } 1749 }
1807 1750
1808 if (unlikely(list_is_singular(&stream->td_list))) { 1751 if (unlikely(list_is_singular(&stream->td_list))) {
@@ -2092,8 +2035,8 @@ sitd_link_urb (
2092 } 2035 }
2093 2036
2094 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { 2037 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
2095 if (ehci->amd_l1_fix == 1) 2038 if (ehci->amd_pll_fix == 1)
2096 ehci_quirk_amd_L1(ehci, 1); 2039 usb_amd_quirk_pll_disable();
2097 } 2040 }
2098 2041
2099 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; 2042 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
@@ -2197,8 +2140,8 @@ sitd_complete (
2197 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; 2140 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
2198 2141
2199 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { 2142 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
2200 if (ehci->amd_l1_fix == 1) 2143 if (ehci->amd_pll_fix == 1)
2201 ehci_quirk_amd_L1(ehci, 0); 2144 usb_amd_quirk_pll_enable();
2202 } 2145 }
2203 2146
2204 if (list_is_singular(&stream->td_list)) { 2147 if (list_is_singular(&stream->td_list)) {