Re: [PATCH resend] xHCI: Implement AMD PLL quirk

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux