From: Ashok Reddy Soma Date: Thu, 26 Sep 2019 11:31:00 +0000 (-0600) Subject: dwc3: versal: Correct the logic for GFLADJ adjustment X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6e51fd18863d04d9b2ab28e84c8a84563f0c1657;p=thirdparty%2Fu-boot.git dwc3: versal: Correct the logic for GFLADJ adjustment This patch corrects the logic used for adjusting GFLADJ register. Currently during phy initialization, USB core reset is happening. Because of reset USB GFLADJ register is getting restored to default values. This patch updates the GFADJ[21:8] & GFLADJ[5:0] bits if they are not equal to the requested value from dts. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek State: pending --- diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c index 045de2ffdec..301d113792d 100644 --- a/drivers/usb/host/xhci-dwc3.c +++ b/drivers/usb/host/xhci-dwc3.c @@ -110,6 +110,42 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val) GFLADJ_30MHZ(val)); } +#if defined(CONFIG_ARCH_VERSAL) +static void dwc3_frame_length_adjustment(struct udevice *dev, struct dwc3 *dwc) +{ + u32 fladj, gfladj, reg; + bool refclk_fladj; + + fladj = dev_read_u32_default(dev, "snps,quirk-frame-length-adjustment", + 0); + if (!fladj) + return; + + /* Save the initial GFLADJ register value */ + reg = readl(&dwc->g_fladj); + gfladj = reg; + + refclk_fladj = dev_read_bool(dev, "snps,refclk_fladj"); + + if (refclk_fladj) { + if ((reg & GFLADJ_REFCLK_FLADJ) != (fladj & + GFLADJ_REFCLK_FLADJ)) { + reg &= ~GFLADJ_REFCLK_FLADJ; + reg |= (fladj & GFLADJ_REFCLK_FLADJ); + } + } + + if ((reg & GFLADJ_30MHZ_MASK) != fladj) { + reg &= ~GFLADJ_30MHZ_MASK; + reg |= GFLADJ_30MHZ_REG_SEL | fladj; + } + + /* Update GFLADJ if there is any change from initial value */ + if (reg != gfladj) + writel(reg, &dwc->g_fladj); +} +#endif + #if CONFIG_IS_ENABLED(DM_USB) static int xhci_dwc3_probe(struct udevice *dev) { @@ -134,6 +170,10 @@ static int xhci_dwc3_probe(struct udevice *dev) dwc3_core_init(dwc3_reg); +#if defined(CONFIG_ARCH_VERSAL) + /* Adjust Frame Length */ + dwc3_frame_length_adjustment(dev, dwc3_reg); +#endif /* Set dwc3 usb2 phy config */ reg = readl(&dwc3_reg->g_usb2phycfg[0]); diff --git a/include/linux/usb/dwc3.h b/include/linux/usb/dwc3.h index 9ceee0a1c9f..55e11fe463d 100644 --- a/include/linux/usb/dwc3.h +++ b/include/linux/usb/dwc3.h @@ -211,8 +211,10 @@ struct dwc3 { /* offset: 0xC100 */ /* Global Frame Length Adjustment Register */ #define GFLADJ_30MHZ_REG_SEL (1 << 7) -#define GFLADJ_30MHZ(n) ((n) & 0x3f) +#define GFLADJ_30MHZ(n) ((n) & GFLADJ_30MHZ_MASK) +#define GFLADJ_30MHZ_MASK 0x3f #define GFLADJ_30MHZ_DEFAULT 0x20 +#define GFLADJ_REFCLK_FLADJ (0x3fff << 8) #ifdef CONFIG_USB_XHCI_DWC3 void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode);