RE: [PATCH 2/2] usb: dwc3: Add workaround for host mode VBUS glitch when boot
Hi Felipe, Sorry for the late response, I didn't receive your mail. Felipe Balbi wrotes: >Hi, > >Ran Wang writes: >> +static void dwc3_power_off_all_roothub_ports(struct dwc3 *dwc) >> +{ >> +int i, port_num; >> +u32 reg, op_regs_base, offset; >> +void __iomem*xhci_regs; >> + >> +/* xhci regs is not mapped yet, do it temperary here */ >> +if (dwc->xhci_resources[0].start) { >> +xhci_regs = ioremap(dwc->xhci_resources[0].start, >> +DWC3_XHCI_REGS_END); >> +if (IS_ERR(xhci_regs)) { >> +dev_err(dwc->dev, "Failed to ioremap xhci_regs\n"); >> +return; >> +} >> + >> +op_regs_base = HC_LENGTH(readl(xhci_regs)); >> +reg = readl(xhci_regs + XHCI_HCSPARAMS1); >> +port_num = HCS_MAX_PORTS(reg); >> + >> +for (i = 1; i <= port_num; i++) { >> +offset = op_regs_base + XHCI_PORTSC_BASE + 0x10*(i-1); >> +reg = readl(xhci_regs + offset); >> +reg &= ~PORT_POWER; >> +writel(reg, xhci_regs + offset); >> +} >> + >> +iounmap(xhci_regs); > >why can't this be done during xhci_gen_setup()? Actually I have done experiment like what you suggested (in xhci-plat.c), but the timing seems too late--making VBUS waveform look like a square wave as below: Here DWC3 enable host mode, VBUS on | +5V /-\ 40ms /--- 0V / 90ms \__/ | | | Here do xhci reset, VBUS back to +5V again Here set all PORTSC[PP] to 0 in xhci_gen_setup() So I am afraid the solution might have to be added in DWC3 core driver where just after host mode enabling code if want fix this :( Regards, Ran
Re: [PATCH 2/2] usb: dwc3: Add workaround for host mode VBUS glitch when boot
Hi Ran, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on usb/usb-testing] [also build test WARNING on v5.0-rc2 next-20190116] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Ran-Wang/usb-dwc3-Add-avoiding-vbus-glitch-happen-during-xhci-reset/20190116-153950 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing reproduce: make htmldocs All warnings (new ones prefixed by >>): WARNING: convert(1) not found, for SVG to PDF conversion install ImageMagick (https://www.imagemagick.org) include/linux/interrupt.h:268: warning: Function parameter or member 'is_managed' not described in 'irq_affinity_desc' include/linux/rcupdate_wait.h:1: warning: no structured comments found include/linux/rcutree.h:1: warning: no structured comments found kernel/rcu/tree.c:710: warning: Excess function parameter 'irq' description in 'rcu_nmi_exit' include/linux/gfp.h:1: warning: no structured comments found include/net/cfg80211.h:4687: warning: Function parameter or member 'wext.ibss' not described in 'wireless_dev' include/net/cfg80211.h:4687: warning: Function parameter or member 'wext.connect' not described in 'wireless_dev' include/net/cfg80211.h:4687: warning: Function parameter or member 'wext.keys' not described in 'wireless_dev' include/net/cfg80211.h:4687: warning: Function parameter or member 'wext.ie' not described in 'wireless_dev' include/net/cfg80211.h:4687: warning: Function parameter or member 'wext.ie_len' not described in 'wireless_dev' include/net/cfg80211.h:4687: warning: Function parameter or member 'wext.bssid' not described in 'wireless_dev' include/net/cfg80211.h:4687: warning: Function parameter or member 'wext.ssid' not described in 'wireless_dev' include/net/cfg80211.h:4687: warning: Function parameter or member 'wext.default_key' not described in 'wireless_dev' include/net/cfg80211.h:4687: warning: Function parameter or member 'wext.default_mgmt_key' not described in 'wireless_dev' include/net/cfg80211.h:4687: warning: Function parameter or member 'wext.prev_bssid_valid' not described in 'wireless_dev' include/net/mac80211.h:2393: warning: Function parameter or member 'radiotap_timestamp.units_pos' not described in 'ieee80211_hw' include/net/mac80211.h:2393: warning: Function parameter or member 'radiotap_timestamp.accuracy' not described in 'ieee80211_hw' include/net/mac80211.h:1004: warning: Function parameter or member 'control.rates' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'control.rts_cts_rate_idx' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'control.use_rts' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'control.use_cts_prot' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'control.short_preamble' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'control.skip_table' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'control.jiffies' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'control.vif' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'control.hw_key' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'control.flags' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'control.enqueue_time' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'ack' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'ack.cookie' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'status.rates' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'status.ack_signal' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'status.ampdu_ack_len' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'status.ampdu_len' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'status.antenna' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter or member 'status.tx_time' not described in 'ieee80211_tx_info' include/net/mac80211.h:1004: warning: Function parameter o
Re: [PATCH 2/2] usb: dwc3: Add workaround for host mode VBUS glitch when boot
Hi, Ran Wang writes: > +static void dwc3_power_off_all_roothub_ports(struct dwc3 *dwc) > +{ > + int i, port_num; > + u32 reg, op_regs_base, offset; > + void __iomem*xhci_regs; > + > + /* xhci regs is not mapped yet, do it temperary here */ > + if (dwc->xhci_resources[0].start) { > + xhci_regs = ioremap(dwc->xhci_resources[0].start, > + DWC3_XHCI_REGS_END); > + if (IS_ERR(xhci_regs)) { > + dev_err(dwc->dev, "Failed to ioremap xhci_regs\n"); > + return; > + } > + > + op_regs_base = HC_LENGTH(readl(xhci_regs)); > + reg = readl(xhci_regs + XHCI_HCSPARAMS1); > + port_num = HCS_MAX_PORTS(reg); > + > + for (i = 1; i <= port_num; i++) { > + offset = op_regs_base + XHCI_PORTSC_BASE + 0x10*(i-1); > + reg = readl(xhci_regs + offset); > + reg &= ~PORT_POWER; > + writel(reg, xhci_regs + offset); > + } > + > + iounmap(xhci_regs); why can't this be done during xhci_gen_setup()? -- balbi signature.asc Description: PGP signature
[PATCH 2/2] usb: dwc3: Add workaround for host mode VBUS glitch when boot
When DWC3 is set to host mode by programming register DWC3_GCTL, VUBS (or its control signal) will be turned on immediately on related Root Hub ports. Then, the VUBS is turned off for a little while(15us) when do xhci reset (conducted by xhci driver) and back to normal finally, we can observed a negative glitch of related signal from scope. This VBUS glitch might cause some USB devices enumeration fail if kernel boot with them connected. Such as LS1012AFWRY/LS1043ARDB/LX2160AQDS /LS1088ARDB with Kingston 16GB USB2.0/Kingston USB3.0/JetFlash Transcend 4GB USB2.0 drives. The fail cases include enumerated as full-speed device or report wrong device descriptor, etc. One SW workaround which can fix this is to program all xhci PORTSC[PP] to 0 to turn off VBUS immediately after setting host mode in DWC3 driver (per signal measurement result, it will be too late to do it in xhci-plat.c or xhci.c). Then, after xhci reset complete in xhci driver, PORTSC[PP]s' value will back to 1 automatically and VBUS on at that time, no glitch happen and normal enumeration process has no impact. Signed-off-by: Ran Wang --- drivers/usb/dwc3/core.c | 47 +++ drivers/usb/dwc3/core.h | 10 +- 2 files changed, 56 insertions(+), 1 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index a1b126f..1508397 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -100,6 +100,41 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc) return 0; } +/* + * dwc3_power_of_all_roothub_ports - Power off all Root hub ports + * @dwc3: Pointer to our controller context structure + */ +static void dwc3_power_off_all_roothub_ports(struct dwc3 *dwc) +{ + int i, port_num; + u32 reg, op_regs_base, offset; + void __iomem*xhci_regs; + + /* xhci regs is not mapped yet, do it temperary here */ + if (dwc->xhci_resources[0].start) { + xhci_regs = ioremap(dwc->xhci_resources[0].start, + DWC3_XHCI_REGS_END); + if (IS_ERR(xhci_regs)) { + dev_err(dwc->dev, "Failed to ioremap xhci_regs\n"); + return; + } + + op_regs_base = HC_LENGTH(readl(xhci_regs)); + reg = readl(xhci_regs + XHCI_HCSPARAMS1); + port_num = HCS_MAX_PORTS(reg); + + for (i = 1; i <= port_num; i++) { + offset = op_regs_base + XHCI_PORTSC_BASE + 0x10*(i-1); + reg = readl(xhci_regs + offset); + reg &= ~PORT_POWER; + writel(reg, xhci_regs + offset); + } + + iounmap(xhci_regs); + } else + dev_err(dwc->dev, "xhci base reg invalid\n"); +} + void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode) { u32 reg; @@ -109,6 +144,15 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode) reg |= DWC3_GCTL_PRTCAPDIR(mode); dwc3_writel(dwc->regs, DWC3_GCTL, reg); + /* +* We have to power off all Root hub ports immediately after DWC3 set +* to host mode to avoid VBUS glitch happen when xhci get reset later. +*/ + if (dwc->avoid_vbus_glitch_when_set_host) { + if (mode == DWC3_GCTL_PRTCAP_HOST) + dwc3_power_off_all_roothub_ports(dwc); + } + dwc->current_dr_role = mode; } @@ -1306,6 +1350,9 @@ static void dwc3_get_properties(struct dwc3 *dwc) dwc->dis_metastability_quirk = device_property_read_bool(dev, "snps,dis_metastability_quirk"); + dwc->avoid_vbus_glitch_when_set_host = device_property_read_bool(dev, + "snps,avoid-vbus-glitch-when-set-host"); + dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index df87641..691093b 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -606,6 +606,14 @@ #define DWC3_OSTS_VBUSVLD BIT(1) #define DWC3_OSTS_CONIDSTS BIT(0) +/* Partial XHCI Register and Bit fields for quirk */ +#define XHCI_HCSPARAMS10x4 +#define XHCI_PORTSC_BASE 0x400 +#define PORT_POWER (1 << 9) +#define HCS_MAX_PORTS(p) (((p) >> 24) & 0x7f) +#define XHCI_HC_LENGTH(p) (((p)>>00)&0x00ff) +#define HC_LENGTH(p) XHCI_HC_LENGTH(p) + /* Structures */ struct dwc3_trb; @@ -1209,6 +1217,7 @@ struct dwc3 { unsignedtx_de_emphasis:2; unsigneddis_metastability_quirk:1; + unsignedavoid_vbus_glitch_when_set_host:1; u16 imod_interval; }; @@ -1217,7 +1226,6 @@ struct dwc3 { #define INCRX_UNDEF_LENGTH_BURST_MODE 1 #define work_to_dwc(w) (container_of((w), struct dwc3, drd_work))