diff options
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index d9f78eb26572..aa46f57f9ec8 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1590,6 +1590,63 @@ itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) | |||
1590 | *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); | 1590 | *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); |
1591 | } | 1591 | } |
1592 | 1592 | ||
1593 | #define AB_REG_BAR_LOW 0xe0 | ||
1594 | #define AB_REG_BAR_HIGH 0xe1 | ||
1595 | #define AB_INDX(addr) ((addr) + 0x00) | ||
1596 | #define AB_DATA(addr) ((addr) + 0x04) | ||
1597 | #define NB_PCIE_INDX_ADDR 0xe0 | ||
1598 | #define NB_PCIE_INDX_DATA 0xe4 | ||
1599 | #define NB_PIF0_PWRDOWN_0 0x01100012 | ||
1600 | #define NB_PIF0_PWRDOWN_1 0x01100013 | ||
1601 | |||
1602 | static void ehci_quirk_amd_L1(struct ehci_hcd *ehci, int disable) | ||
1603 | { | ||
1604 | u32 addr, addr_low, addr_high, val; | ||
1605 | |||
1606 | outb_p(AB_REG_BAR_LOW, 0xcd6); | ||
1607 | addr_low = inb_p(0xcd7); | ||
1608 | outb_p(AB_REG_BAR_HIGH, 0xcd6); | ||
1609 | addr_high = inb_p(0xcd7); | ||
1610 | addr = addr_high << 8 | addr_low; | ||
1611 | outl_p(0x30, AB_INDX(addr)); | ||
1612 | outl_p(0x40, AB_DATA(addr)); | ||
1613 | outl_p(0x34, AB_INDX(addr)); | ||
1614 | val = inl_p(AB_DATA(addr)); | ||
1615 | |||
1616 | if (disable) { | ||
1617 | val &= ~0x8; | ||
1618 | val |= (1 << 4) | (1 << 9); | ||
1619 | } else { | ||
1620 | val |= 0x8; | ||
1621 | val &= ~((1 << 4) | (1 << 9)); | ||
1622 | } | ||
1623 | outl_p(val, AB_DATA(addr)); | ||
1624 | |||
1625 | if (amd_nb_dev) { | ||
1626 | addr = NB_PIF0_PWRDOWN_0; | ||
1627 | pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr); | ||
1628 | pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val); | ||
1629 | if (disable) | ||
1630 | val &= ~(0x3f << 7); | ||
1631 | else | ||
1632 | val |= 0x3f << 7; | ||
1633 | |||
1634 | pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val); | ||
1635 | |||
1636 | addr = NB_PIF0_PWRDOWN_1; | ||
1637 | pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr); | ||
1638 | pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val); | ||
1639 | if (disable) | ||
1640 | val &= ~(0x3f << 7); | ||
1641 | else | ||
1642 | val |= 0x3f << 7; | ||
1643 | |||
1644 | pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val); | ||
1645 | } | ||
1646 | |||
1647 | return; | ||
1648 | } | ||
1649 | |||
1593 | /* fit urb's itds into the selected schedule slot; activate as needed */ | 1650 | /* fit urb's itds into the selected schedule slot; activate as needed */ |
1594 | static int | 1651 | static int |
1595 | itd_link_urb ( | 1652 | itd_link_urb ( |
@@ -1616,6 +1673,12 @@ itd_link_urb ( | |||
1616 | urb->interval, | 1673 | urb->interval, |
1617 | next_uframe >> 3, next_uframe & 0x7); | 1674 | next_uframe >> 3, next_uframe & 0x7); |
1618 | } | 1675 | } |
1676 | |||
1677 | if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { | ||
1678 | if (ehci->amd_l1_fix == 1) | ||
1679 | ehci_quirk_amd_L1(ehci, 1); | ||
1680 | } | ||
1681 | |||
1619 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; | 1682 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; |
1620 | 1683 | ||
1621 | /* fill iTDs uframe by uframe */ | 1684 | /* fill iTDs uframe by uframe */ |
@@ -1740,6 +1803,11 @@ itd_complete ( | |||
1740 | (void) disable_periodic(ehci); | 1803 | (void) disable_periodic(ehci); |
1741 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; | 1804 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; |
1742 | 1805 | ||
1806 | if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { | ||
1807 | if (ehci->amd_l1_fix == 1) | ||
1808 | ehci_quirk_amd_L1(ehci, 0); | ||
1809 | } | ||
1810 | |||
1743 | if (unlikely(list_is_singular(&stream->td_list))) { | 1811 | if (unlikely(list_is_singular(&stream->td_list))) { |
1744 | ehci_to_hcd(ehci)->self.bandwidth_allocated | 1812 | ehci_to_hcd(ehci)->self.bandwidth_allocated |
1745 | -= stream->bandwidth; | 1813 | -= stream->bandwidth; |
@@ -2025,6 +2093,12 @@ sitd_link_urb ( | |||
2025 | (next_uframe >> 3) & (ehci->periodic_size - 1), | 2093 | (next_uframe >> 3) & (ehci->periodic_size - 1), |
2026 | stream->interval, hc32_to_cpu(ehci, stream->splits)); | 2094 | stream->interval, hc32_to_cpu(ehci, stream->splits)); |
2027 | } | 2095 | } |
2096 | |||
2097 | if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { | ||
2098 | if (ehci->amd_l1_fix == 1) | ||
2099 | ehci_quirk_amd_L1(ehci, 1); | ||
2100 | } | ||
2101 | |||
2028 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; | 2102 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; |
2029 | 2103 | ||
2030 | /* fill sITDs frame by frame */ | 2104 | /* fill sITDs frame by frame */ |
@@ -2125,6 +2199,11 @@ sitd_complete ( | |||
2125 | (void) disable_periodic(ehci); | 2199 | (void) disable_periodic(ehci); |
2126 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; | 2200 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; |
2127 | 2201 | ||
2202 | if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { | ||
2203 | if (ehci->amd_l1_fix == 1) | ||
2204 | ehci_quirk_amd_L1(ehci, 0); | ||
2205 | } | ||
2206 | |||
2128 | if (list_is_singular(&stream->td_list)) { | 2207 | if (list_is_singular(&stream->td_list)) { |
2129 | ehci_to_hcd(ehci)->self.bandwidth_allocated | 2208 | ehci_to_hcd(ehci)->self.bandwidth_allocated |
2130 | -= stream->bandwidth; | 2209 | -= stream->bandwidth; |