usb: dwc3: add dis-u1u2-quirk to reject enter U1 and U2

The DWC3 with Innosilicon USB 3.0 PHY on Rockchip platforms
(e.g. rk3328, rk1808) has problem to exit to U0 state from
U1 or U2 state when DWC3 work as peripheral mode. This patch
adds a quirk to reject transition to U1 and U2 state to
workaround this issue.

Change-Id: Ib5a7a603193df23e4d274681bad155d005238349
Signed-off-by: William Wu <william.wu@rock-chips.com>
This commit is contained in:
William Wu
2018-10-23 16:31:23 +08:00
committed by Tao Huang
parent fb49b9e04d
commit aaa5c055cc
3 changed files with 12 additions and 3 deletions

View File

@@ -1016,6 +1016,8 @@ static int dwc3_probe(struct platform_device *pdev)
"snps,dis_u3_susphy_quirk");
dwc->dis_u2_susphy_quirk = device_property_read_bool(dev,
"snps,dis_u2_susphy_quirk");
dwc->dis_u1u2_quirk = device_property_read_bool(dev,
"snps,dis-u1u2-quirk");
dwc->dis_enblslpm_quirk = device_property_read_bool(dev,
"snps,dis_enblslpm_quirk");
dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,

View File

@@ -821,6 +821,7 @@ struct dwc3_scratchpad_array {
* @dis_u3_autosuspend_quirk: set if the we disable usb3 autosuspend
* @dis_u3_susphy_quirk: set if we disable usb3 suspend phy
* @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
* @dis_u1u2_quirk: set if we reject transition to U1 or U2 state
* @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG,
* disabling the suspend signal to the PHY.
* @dis_u2_freeclk_exists_quirk : set if we clear u2_freeclk_exists
@@ -980,6 +981,7 @@ struct dwc3 {
unsigned dis_u3_autosuspend_quirk:1;
unsigned dis_u3_susphy_quirk:1;
unsigned dis_u2_susphy_quirk:1;
unsigned dis_u1u2_quirk:1;
unsigned dis_enblslpm_quirk:1;
unsigned dis_rxdet_inp3_quirk:1;
unsigned dis_u2_freeclk_exists_quirk:1;

View File

@@ -431,7 +431,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
return -EINVAL;
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (set)
if (set && !dwc->dis_u1u2_quirk)
reg |= DWC3_DCTL_INITU1ENA;
else
reg &= ~DWC3_DCTL_INITU1ENA;
@@ -445,7 +445,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
return -EINVAL;
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (set)
if (set && !dwc->dis_u1u2_quirk)
reg |= DWC3_DCTL_INITU2ENA;
else
reg &= ~DWC3_DCTL_INITU2ENA;
@@ -592,7 +592,12 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
* nothing is pending from application.
*/
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA);
if (dwc->dis_u1u2_quirk)
reg &= ~(DWC3_DCTL_ACCEPTU1ENA |
DWC3_DCTL_ACCEPTU2ENA);
else
reg |= (DWC3_DCTL_ACCEPTU1ENA |
DWC3_DCTL_ACCEPTU2ENA);
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
}
break;