]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
dwc3: versal: Correct the logic for GFLADJ adjustment
authorAshok Reddy Soma <ashok.reddy.soma@xilinx.com>
Thu, 26 Sep 2019 11:31:00 +0000 (05:31 -0600)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 2 Feb 2021 12:49:33 +0000 (13:49 +0100)
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 <ashok.reddy.soma@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
State: pending

drivers/usb/host/xhci-dwc3.c
include/linux/usb/dwc3.h

index 045de2ffdec0198d1c8cb2703e64d8162997a187..301d113792dbdc86781d5cccd3afd8d15e4fae7c 100644 (file)
@@ -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]);
 
index 9ceee0a1c9f6eb61dd349a725a89276959c73747..55e11fe463d18dc815b5ae44e8ffa915fdd73005 100644 (file)
@@ -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);