Hi Andiry, I saw that your PLL quirk refactoring patch got into 2.6.39. Does this xHCI PLL quirk patch still apply to Greg's usb-next tree after all the USB 3.0 hub changes? If so I'll queue it for 2.6.40, if not, please resend. Sarah Sharp On Mon, Feb 14, 2011 at 06:08:39PM +0800, Andiry Xu wrote: > This patch disable the optional PM feature inside the Hudson3 platform under > the following conditions: > > 1. If an isochronous device is connected to 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. > > The PM feature needs to be disabled to eliminate PLL startup delays when the > link comes out of low power state. The performance of DMA data transfer could > be impacted if system delay were encountered and in addition to the PLL start > up delays. Disabling the PM would leave room for unpredictable system delays > in order to guarantee uninterrupted data transfer to isochronous audio or > video stream devices that require time sensitive information. If data in an > audio/video stream was interrupted then erratic audio or video performance > may be encountered. > > AMD PLL quirk is already implemented in OHCI/EHCI driver. After moving the > quirk code to pci-quirks.c and export them, xHCI driver can call it directly > without having the quirk implementation in itself. > > Signed-off-by: Andiry Xu <andiry.xu@xxxxxxx> > --- > drivers/usb/host/xhci-pci.c | 4 ++++ > drivers/usb/host/xhci-ring.c | 29 ++++++++++++++++++++++++++++- > drivers/usb/host/xhci.c | 3 +++ > drivers/usb/host/xhci.h | 2 ++ > 4 files changed, 37 insertions(+), 1 deletions(-) > > diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c > index bb668a8..d4530a1 100644 > --- a/drivers/usb/host/xhci-pci.c > +++ b/drivers/usb/host/xhci-pci.c > @@ -82,6 +82,10 @@ static int xhci_pci_setup(struct usb_hcd *hcd) > if (pdev->vendor == PCI_VENDOR_ID_NEC) > xhci->quirks |= XHCI_NEC_HOST; > > + /* AMD PLL quirk */ > + if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) > + xhci->quirks |= XHCI_AMD_PLL_FIX; > + > /* Make sure the HC is halted. */ > retval = xhci_halt(xhci); > if (retval) > diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c > index 3e8211c..efd757e 100644 > --- a/drivers/usb/host/xhci-ring.c > +++ b/drivers/usb/host/xhci-ring.c > @@ -604,6 +604,15 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, > > /* Only giveback urb when this is the last td in urb */ > if (urb_priv->td_cnt == urb_priv->length) { > + switch (usb_pipetype(urb->pipe)) { > + case PIPE_ISOCHRONOUS: > + xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--; > + if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) { > + if (xhci->quirks & XHCI_AMD_PLL_FIX) > + usb_amd_quirk_pll_enable(); > + } > + break; > + } > usb_hcd_unlink_urb_from_ep(hcd, urb); > xhci_dbg(xhci, "Giveback %s URB %p\n", adjective, urb); > > @@ -1448,8 +1457,20 @@ td_cleanup: > > urb_priv->td_cnt++; > /* Giveback the urb when all the tds are completed */ > - if (urb_priv->td_cnt == urb_priv->length) > + if (urb_priv->td_cnt == urb_priv->length) { > ret = 1; > + > + switch (usb_pipetype(urb->pipe)) { > + case PIPE_ISOCHRONOUS: > + xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--; > + if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs > + == 0) { > + if (xhci->quirks & XHCI_AMD_PLL_FIX) > + usb_amd_quirk_pll_enable(); > + } > + break; > + } > + } > } > > return ret; > @@ -3016,6 +3037,12 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, > } > } > > + if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) { > + if (xhci->quirks & XHCI_AMD_PLL_FIX) > + usb_amd_quirk_pll_disable(); > + } > + xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs++; > + > giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, > start_cycle, start_trb); > return 0; > diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c > index 34cf4e1..4e0f715 100644 > --- a/drivers/usb/host/xhci.c > +++ b/drivers/usb/host/xhci.c > @@ -522,6 +522,9 @@ void xhci_stop(struct usb_hcd *hcd) > del_timer_sync(&xhci->event_ring_timer); > #endif > > + if (xhci->quirks & XHCI_AMD_PLL_FIX) > + usb_amd_dev_put(); > + > xhci_dbg(xhci, "// Disabling event ring interrupts\n"); > temp = xhci_readl(xhci, &xhci->op_regs->status); > xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); > diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h > index 7f236fd..b9bd1f6 100644 > --- a/drivers/usb/host/xhci.h > +++ b/drivers/usb/host/xhci.h > @@ -30,6 +30,7 @@ > > /* Code sharing between pci-quirks and xhci hcd */ > #include "xhci-ext-caps.h" > +#include "pci-quirks.h" > > /* xHCI PCI Configuration Registers */ > #define XHCI_SBRN_OFFSET (0x60) > @@ -1250,6 +1251,7 @@ struct xhci_hcd { > #define XHCI_LINK_TRB_QUIRK (1 << 0) > #define XHCI_RESET_EP_QUIRK (1 << 1) > #define XHCI_NEC_HOST (1 << 2) > +#define XHCI_AMD_PLL_FIX (1 << 3) > u32 port_c_suspend[8]; /* port suspend change*/ > u32 suspended_ports[8]; /* which ports are > suspended */ > -- > 1.7.1 > > > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html