提交 2cdcec4f 编写于 作者: T Tuomas Tynkkynen 提交者: Felipe Balbi

usb: host: add has_tdi_phy_lpm capability bit

The has_hostpc capability bit indicates that the host controller has the
HOSTPC register extensions, but at the same time enables clock disabling
power saving features with the PHY Low Power Clock Disable (PHCD) bit.

However, some host controllers have the HOSTPC extensions but don't
support the low-power feature, so the PHCD bit must not be set on those
controllers. Add a separate capability bit for the low-power feature
instead, and change all existing users of has_hostpc to use this new
capability bit.

The idea for this commit is taken from an old 2012 commit that never got
merged ("disociate chipidea PHY low power suspend control from hostpc")
Inspired-by: NMatthieu CASTET <matthieu.castet@parrot.com>
Signed-off-by: NTuomas Tynkkynen <ttynkkynen@nvidia.com>
Acked-by: NAlan Stern <stern@rowland.harvard.edu>
Tested-by: NStephen Warren <swarren@nvidia.com>
Reviewed-by: NStephen Warren <swarren@nvidia.com>
Signed-off-by: NFelipe Balbi <balbi@ti.com>
上级 23381db7
...@@ -63,6 +63,7 @@ static int host_start(struct ci_hdrc *ci) ...@@ -63,6 +63,7 @@ static int host_start(struct ci_hdrc *ci)
ehci = hcd_to_ehci(hcd); ehci = hcd_to_ehci(hcd);
ehci->caps = ci->hw_bank.cap; ehci->caps = ci->hw_bank.cap;
ehci->has_hostpc = ci->hw_bank.lpm; ehci->has_hostpc = ci->hw_bank.lpm;
ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
ret = usb_add_hcd(hcd, 0, 0); ret = usb_add_hcd(hcd, 0, 0);
if (ret) if (ret)
......
...@@ -183,7 +183,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, ...@@ -183,7 +183,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
spin_lock_irq(&ehci->lock); spin_lock_irq(&ehci->lock);
/* clear phy low-power mode before changing wakeup flags */ /* clear phy low-power mode before changing wakeup flags */
if (ehci->has_hostpc) { if (ehci->has_tdi_phy_lpm) {
port = HCS_N_PORTS(ehci->hcs_params); port = HCS_N_PORTS(ehci->hcs_params);
while (port--) { while (port--) {
u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
...@@ -217,7 +217,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, ...@@ -217,7 +217,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
} }
/* enter phy low-power mode again */ /* enter phy low-power mode again */
if (ehci->has_hostpc) { if (ehci->has_tdi_phy_lpm) {
port = HCS_N_PORTS(ehci->hcs_params); port = HCS_N_PORTS(ehci->hcs_params);
while (port--) { while (port--) {
u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
...@@ -309,7 +309,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ...@@ -309,7 +309,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
} }
} }
if (changed && ehci->has_hostpc) { if (changed && ehci->has_tdi_phy_lpm) {
spin_unlock_irq(&ehci->lock); spin_unlock_irq(&ehci->lock);
msleep(5); /* 5 ms for HCD to enter low-power mode */ msleep(5); /* 5 ms for HCD to enter low-power mode */
spin_lock_irq(&ehci->lock); spin_lock_irq(&ehci->lock);
...@@ -435,7 +435,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) ...@@ -435,7 +435,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
goto shutdown; goto shutdown;
/* clear phy low-power mode before resume */ /* clear phy low-power mode before resume */
if (ehci->bus_suspended && ehci->has_hostpc) { if (ehci->bus_suspended && ehci->has_tdi_phy_lpm) {
i = HCS_N_PORTS(ehci->hcs_params); i = HCS_N_PORTS(ehci->hcs_params);
while (i--) { while (i--) {
if (test_bit(i, &ehci->bus_suspended)) { if (test_bit(i, &ehci->bus_suspended)) {
...@@ -788,7 +788,7 @@ static int ehci_hub_control ( ...@@ -788,7 +788,7 @@ static int ehci_hub_control (
goto error; goto error;
/* clear phy low-power mode before resume */ /* clear phy low-power mode before resume */
if (ehci->has_hostpc) { if (ehci->has_tdi_phy_lpm) {
temp1 = ehci_readl(ehci, hostpc_reg); temp1 = ehci_readl(ehci, hostpc_reg);
ehci_writel(ehci, temp1 & ~HOSTPC_PHCD, ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
hostpc_reg); hostpc_reg);
...@@ -1032,12 +1032,12 @@ static int ehci_hub_control ( ...@@ -1032,12 +1032,12 @@ static int ehci_hub_control (
/* After above check the port must be connected. /* After above check the port must be connected.
* Set appropriate bit thus could put phy into low power * Set appropriate bit thus could put phy into low power
* mode if we have hostpc feature * mode if we have tdi_phy_lpm feature
*/ */
temp &= ~PORT_WKCONN_E; temp &= ~PORT_WKCONN_E;
temp |= PORT_WKDISC_E | PORT_WKOC_E; temp |= PORT_WKDISC_E | PORT_WKOC_E;
ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
if (ehci->has_hostpc) { if (ehci->has_tdi_phy_lpm) {
spin_unlock_irqrestore(&ehci->lock, flags); spin_unlock_irqrestore(&ehci->lock, flags);
msleep(5);/* 5ms for HCD enter low pwr mode */ msleep(5);/* 5ms for HCD enter low pwr mode */
spin_lock_irqsave(&ehci->lock, flags); spin_lock_irqsave(&ehci->lock, flags);
......
...@@ -210,6 +210,7 @@ struct ehci_hcd { /* one per controller */ ...@@ -210,6 +210,7 @@ struct ehci_hcd { /* one per controller */
#define OHCI_HCCTRL_LEN 0x4 #define OHCI_HCCTRL_LEN 0x4
__hc32 *ohci_hcctrl_reg; __hc32 *ohci_hcctrl_reg;
unsigned has_hostpc:1; unsigned has_hostpc:1;
unsigned has_tdi_phy_lpm:1;
unsigned has_ppcd:1; /* support per-port change bits */ unsigned has_ppcd:1; /* support per-port change bits */
u8 sbrn; /* packed release number */ u8 sbrn; /* packed release number */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册