[PATCH 2/3][v4] drivers: usb: dwc3: Add frame length adjustment quirk
Add adjust_frame_length_quirk for writing to fladj register which adjusts (micro)frame length to value provided by "snps,quirk-frame-length-adjustment" property thus avoiding USB 2.0 devices to time-out over a longer run Signed-off-by: Nikhil Badola <nikhil.bad...@freescale.com> --- Changes for v4: Removed mixed declerations and code drivers/usb/dwc3/core.c | 34 ++ drivers/usb/dwc3/core.h | 5 + drivers/usb/dwc3/platform_data.h | 2 ++ 3 files changed, 41 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 064123e..6270581 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -143,6 +143,32 @@ static int dwc3_soft_reset(struct dwc3 *dwc) return 0; } +/* + * dwc3_frame_length_adjustment - Adjusts frame length if required + * @dwc3: Pointer to our controller context structure + * @fladj: Value of GFLADJ_30MHZ to adjust frame length + */ +static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj) +{ + u32 reg; + u32 dft; + + if (dwc->revision < DWC3_REVISION_250A) + return; + + if (fladj == 0) + return; + + reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); + dft = reg & DWC3_GFLADJ_30MHZ_MASK; + if (!dev_WARN_ONCE(dwc->dev, dft == fladj, + "request value same as default, ignoring\n")) { + reg &= ~DWC3_GFLADJ_30MHZ_MASK; + reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | fladj; + dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); + } +} + /** * dwc3_free_one_event_buffer - Frees one event buffer * @dwc: Pointer to our controller context structure @@ -779,6 +805,7 @@ static int dwc3_probe(struct platform_device *pdev) u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; + u32 fladj = 0; int ret; @@ -886,6 +913,9 @@ static int dwc3_probe(struct platform_device *pdev) _de_emphasis); of_property_read_string(node, "snps,hsphy_interface", >hsphy_interface); + of_property_read_u32(node, +"snps,quirk-frame-length-adjustment", +); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -915,6 +945,7 @@ static int dwc3_probe(struct platform_device *pdev) tx_de_emphasis = pdata->tx_de_emphasis; dwc->hsphy_interface = pdata->hsphy_interface; + fladj = pdata->fladj_value; } /* default to superspeed if no maximum_speed passed */ @@ -971,6 +1002,9 @@ static int dwc3_probe(struct platform_device *pdev) goto err1; } + /* Adjust Frame Length */ + dwc3_frame_length_adjustment(dwc, fladj); + usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 0447788..9188745 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -124,6 +124,7 @@ #define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10)) #define DWC3_GHWPARAMS80xc600 +#define DWC3_GFLADJ0xc630 /* Device Registers */ #define DWC3_DCFG 0xc700 @@ -234,6 +235,10 @@ /* Global HWPARAMS6 Register */ #define DWC3_GHWPARAMS6_EN_FPGA(1 << 7) +/* Global Frame Length Adjustment Register */ +#define DWC3_GFLADJ_30MHZ_SDBND_SEL(1 << 7) +#define DWC3_GFLADJ_30MHZ_MASK 0x3f + /* Device Configuration Register */ #define DWC3_DCFG_DEVADDR(addr)((addr) << 3) #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index d3614ec..400b197 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -46,5 +46,7 @@ struct dwc3_platform_data { unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; + u32 fladj_value; + const char *hsphy_interface; }; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3][v3] drivers: usb: dwc3: Add frame length adjustment quirk
Add adjust_frame_length_quirk for writing to fladj register which adjusts (micro)frame length to value provided by "snps,quirk-frame-length-adjustment" property thus avoiding USB 2.0 devices to time-out over a longer run Signed-off-by: Nikhil Badola <nikhil.bad...@freescale.com> --- Changes for v3: - removed unnecessary if(fladj) condition - removed stray newline drivers/usb/dwc3/core.c | 34 ++ drivers/usb/dwc3/core.h | 5 + drivers/usb/dwc3/platform_data.h | 2 ++ 3 files changed, 41 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 064123e..75a17bf 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -143,6 +143,32 @@ static int dwc3_soft_reset(struct dwc3 *dwc) return 0; } +/* + * dwc3_frame_length_adjustment - Adjusts frame length if required + * @dwc3: Pointer to our controller context structure + * @fladj: Value of GFLADJ_30MHZ to adjust frame length + */ +static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj) +{ + if (dwc->revision < DWC3_REVISION_250A) + return; + + if (fladj == 0) + return; + + u32 reg; + u32 dft; + + reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); + dft = reg & DWC3_GFLADJ_30MHZ_MASK; + if (!dev_WARN_ONCE(dwc->dev, dft == fladj, + "request value same as default, ignoring\n")) { + reg &= ~DWC3_GFLADJ_30MHZ_MASK; + reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | fladj; + dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); + } +} + /** * dwc3_free_one_event_buffer - Frees one event buffer * @dwc: Pointer to our controller context structure @@ -779,6 +805,7 @@ static int dwc3_probe(struct platform_device *pdev) u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; + u32 fladj = 0; int ret; @@ -886,6 +913,9 @@ static int dwc3_probe(struct platform_device *pdev) _de_emphasis); of_property_read_string(node, "snps,hsphy_interface", >hsphy_interface); + of_property_read_u32(node, +"snps,quirk-frame-length-adjustment", +); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -915,6 +945,7 @@ static int dwc3_probe(struct platform_device *pdev) tx_de_emphasis = pdata->tx_de_emphasis; dwc->hsphy_interface = pdata->hsphy_interface; + fladj = pdata->fladj_value; } /* default to superspeed if no maximum_speed passed */ @@ -971,6 +1002,9 @@ static int dwc3_probe(struct platform_device *pdev) goto err1; } + /* Adjust Frame Length */ + dwc3_frame_length_adjustment(dwc, fladj); + usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 0447788..9188745 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -124,6 +124,7 @@ #define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10)) #define DWC3_GHWPARAMS80xc600 +#define DWC3_GFLADJ0xc630 /* Device Registers */ #define DWC3_DCFG 0xc700 @@ -234,6 +235,10 @@ /* Global HWPARAMS6 Register */ #define DWC3_GHWPARAMS6_EN_FPGA(1 << 7) +/* Global Frame Length Adjustment Register */ +#define DWC3_GFLADJ_30MHZ_SDBND_SEL(1 << 7) +#define DWC3_GFLADJ_30MHZ_MASK 0x3f + /* Device Configuration Register */ #define DWC3_DCFG_DEVADDR(addr)((addr) << 3) #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index d3614ec..400b197 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -46,5 +46,7 @@ struct dwc3_platform_data { unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; + u32 fladj_value; + const char *hsphy_interface; }; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3][v2] drivers: usb: dwc3: Add frame length adjustment quirk
Add adjust_frame_length_quirk for writing to fladj register which adjusts (micro)frame length to value provided by snps,quirk-frame-length-adjustment property thus avoiding USB 2.0 devices to time-out over a longer run Signed-off-by: Nikhil Badola nikhil.bad...@freescale.com --- changes for v2 : - updated quirk's name - added separate function for frame length adjustment - added frame length adjustment for pdata users - removed unnecessary flag from struct dwc3 drivers/usb/dwc3/core.c | 37 + drivers/usb/dwc3/core.h | 5 + drivers/usb/dwc3/platform_data.h | 2 ++ 3 files changed, 44 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 064123e..f3beb2e 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -143,6 +143,34 @@ static int dwc3_soft_reset(struct dwc3 *dwc) return 0; } +/* + * dwc3_frame_length_adjustment - Adjusts frame length if required + * @dwc3: Pointer to our controller context structure + * @fladj: Value of GFLADJ_30MHZ to adjust frame length + */ +static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj) +{ + if (dwc-revision DWC3_REVISION_250A) + return; + + if (fladj == 0) + return; + + if (fladj) { + u32 reg; + u32 dft; + + reg = dwc3_readl(dwc-regs, DWC3_GFLADJ); + dft = reg DWC3_GFLADJ_30MHZ_MASK; + if (!dev_WARN_ONCE(dwc-dev, dft == fladj, + request value same as default, ignoring\n)) { + reg = ~DWC3_GFLADJ_30MHZ_MASK; + reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | fladj; + dwc3_writel(dwc-regs, DWC3_GFLADJ, reg); + } + } +} + /** * dwc3_free_one_event_buffer - Frees one event buffer * @dwc: Pointer to our controller context structure @@ -779,6 +807,7 @@ static int dwc3_probe(struct platform_device *pdev) u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; + u32 fladj = 0; int ret; @@ -886,6 +915,9 @@ static int dwc3_probe(struct platform_device *pdev) tx_de_emphasis); of_property_read_string(node, snps,hsphy_interface, dwc-hsphy_interface); + of_property_read_u32(node, +snps,quirk-frame-length-adjustment, +fladj); } else if (pdata) { dwc-maximum_speed = pdata-maximum_speed; dwc-has_lpm_erratum = pdata-has_lpm_erratum; @@ -915,6 +947,7 @@ static int dwc3_probe(struct platform_device *pdev) tx_de_emphasis = pdata-tx_de_emphasis; dwc-hsphy_interface = pdata-hsphy_interface; + fladj = pdata-fladj_value; } /* default to superspeed if no maximum_speed passed */ @@ -957,6 +990,7 @@ static int dwc3_probe(struct platform_device *pdev) goto err1; } + if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) dwc-dr_mode = USB_DR_MODE_HOST; else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) @@ -971,6 +1005,9 @@ static int dwc3_probe(struct platform_device *pdev) goto err1; } + /* Adjust Frame Length */ + dwc3_frame_length_adjustment(dwc, fladj); + usb_phy_set_suspend(dwc-usb2_phy, 0); usb_phy_set_suspend(dwc-usb3_phy, 0); ret = phy_power_on(dwc-usb2_generic_phy); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 0447788..9188745 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -124,6 +124,7 @@ #define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10)) #define DWC3_GHWPARAMS80xc600 +#define DWC3_GFLADJ0xc630 /* Device Registers */ #define DWC3_DCFG 0xc700 @@ -234,6 +235,10 @@ /* Global HWPARAMS6 Register */ #define DWC3_GHWPARAMS6_EN_FPGA(1 7) +/* Global Frame Length Adjustment Register */ +#define DWC3_GFLADJ_30MHZ_SDBND_SEL(1 7) +#define DWC3_GFLADJ_30MHZ_MASK 0x3f + /* Device Configuration Register */ #define DWC3_DCFG_DEVADDR(addr)((addr) 3) #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index d3614ec..400b197 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -46,5 +46,7 @@ struct dwc3_platform_data { unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; + u32 fladj_value; + const char *hsphy_interface; }; -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe
[PATCH 2/3] drivers: usb: dwc3: Add adjust_frame_length_quirk
Add adjust_frame_length_quirk for writing to fladj register which adjusts (micro)frame length to value provided by snps,configure-fladj property thus avoiding USB 2.0 devices to time-out over a longer run Signed-off-by: Nikhil Badola nikhil.bad...@freescale.com --- drivers/usb/dwc3/core.c | 12 drivers/usb/dwc3/core.h | 7 +++ 2 files changed, 19 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 5c110d8..72ba025 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -779,6 +779,7 @@ static int dwc3_probe(struct platform_device *pdev) u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; + u32 fladj_value; int ret; @@ -886,6 +887,12 @@ static int dwc3_probe(struct platform_device *pdev) tx_de_emphasis); of_property_read_string(node, snps,hsphy_interface, dwc-hsphy_interface); + ret = of_property_read_u32(node, snps,configure-fladj, + fladj_value); + if (!ret) + dwc-adjust_frame_length_quirk = 1; + else + dwc-adjust_frame_length_quirk = 0; } else if (pdata) { dwc-maximum_speed = pdata-maximum_speed; dwc-has_lpm_erratum = pdata-has_lpm_erratum; @@ -957,6 +964,11 @@ static int dwc3_probe(struct platform_device *pdev) goto err1; } + /* Adjust Frame Length */ + if (dwc-adjust_frame_length_quirk) + dwc3_writel(dwc-regs, DWC3_GFLADJ, GFLADJ_30MHZ_REG_SEL | + GFLADJ_30MHZ(fladj_value)); + if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) dwc-dr_mode = USB_DR_MODE_HOST; else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 0447788..b7a5119 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -124,6 +124,7 @@ #define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10)) #define DWC3_GHWPARAMS80xc600 +#define DWC3_GFLADJ0xc630 /* Device Registers */ #define DWC3_DCFG 0xc700 @@ -234,6 +235,10 @@ /* Global HWPARAMS6 Register */ #define DWC3_GHWPARAMS6_EN_FPGA(1 7) +/* Global Frame Length Adjustment Register */ +#define GFLADJ_30MHZ_REG_SEL (1 7) +#define GFLADJ_30MHZ(n)((n) 0x3f) + /* Device Configuration Register */ #define DWC3_DCFG_DEVADDR(addr)((addr) 3) #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) @@ -712,6 +717,7 @@ struct dwc3_scratchpad_array { * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy + * @adjust_frame_length_quirk: enables post-silicon frame length adjustment * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk * @tx_de_emphasis: Tx de-emphasis value * 0 - -6dB de-emphasis @@ -841,6 +847,7 @@ struct dwc3 { unsignedrx_detect_poll_quirk:1; unsigneddis_u3_susphy_quirk:1; unsigneddis_u2_susphy_quirk:1; + unsignedadjust_frame_length_quirk:1; unsignedtx_de_emphasis_quirk:1; unsignedtx_de_emphasis:2; -- 2.1.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html