usb: dwc2: New bitfield definition and programming in GRSTCTL
authorMinas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Wed, 13 Mar 2024 09:20:12 +0000 (09:20 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Mar 2024 09:44:53 +0000 (10:44 +0100)
Added new bitfield GRSTCTL_CLOCK_SWITH_TIMER in GRSTCTL register.
This bitfield applicable HSOTG cores v5.00 or higher and not
applicable to HS/FS IOT devices.
This bitfield must be programmed to 3'b010 if core will be
used in Low-speed and core configured for any HS/FS PHY interface.
This bitfield must be programmed to 3'b111 if core configured
to use either:
- HS PHY interface UTMI or ULPI
- FS PHY any interface

Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Link: https://lore.kernel.org/r/0616838cfee958774c9321c6eeeda4be92f900d8.1708948356.git.Minas.Harutyunyan@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc2/core.c
drivers/usb/dwc2/hw.h

index b7a76eb089c9a132d80d32b6e1e70ff0aed0c616..9919ab725d544caacce42aa25971151f50d060ec 100644 (file)
@@ -980,6 +980,41 @@ void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg)
        dwc2_writel(hsotg, hcfg, HCFG);
 }
 
+static void dwc2_set_clock_switch_timer(struct dwc2_hsotg *hsotg)
+{
+       u32 grstctl, gsnpsid, val = 0;
+
+       gsnpsid = dwc2_readl(hsotg, GSNPSID);
+
+       /*
+        * Applicable only to HSOTG core v5.00a or higher.
+        * Not applicable to HS/FS IOT devices.
+        */
+       if ((gsnpsid & ~DWC2_CORE_REV_MASK) != DWC2_OTG_ID ||
+           gsnpsid < DWC2_CORE_REV_5_00a)
+               return;
+
+       if ((hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI &&
+            hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED) ||
+           (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_ULPI &&
+            hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED) ||
+           (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED &&
+            hsotg->hw_params.fs_phy_type != GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED)) {
+               val = GRSTCTL_CLOCK_SWITH_TIMER_VALUE_DIS;
+       }
+
+       if (hsotg->params.speed == DWC2_SPEED_PARAM_LOW &&
+           hsotg->hw_params.hs_phy_type != GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED &&
+           hsotg->hw_params.fs_phy_type != GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED) {
+               val = GRSTCTL_CLOCK_SWITH_TIMER_VALUE_147;
+       }
+
+       grstctl = dwc2_readl(hsotg, GRSTCTL);
+       grstctl &= ~GRSTCTL_CLOCK_SWITH_TIMER_MASK;
+       grstctl |= GRSTCTL_CLOCK_SWITH_TIMER(val);
+       dwc2_writel(hsotg, grstctl, GRSTCTL);
+}
+
 static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
 {
        u32 usbcfg, ggpio, i2cctl;
@@ -997,6 +1032,8 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy)
                        usbcfg |= GUSBCFG_PHYSEL;
                        dwc2_writel(hsotg, usbcfg, GUSBCFG);
 
+                       dwc2_set_clock_switch_timer(hsotg);
+
                        /* Reset after a PHY select */
                        retval = dwc2_core_reset(hsotg, false);
 
index 5e449393b0d723beed6c795054a4ff3bf8c8e71a..48699caa8739c0c067d65fed8fa07878f2f31c33 100644 (file)
 #define GRSTCTL_AHBIDLE                        BIT(31)
 #define GRSTCTL_DMAREQ                 BIT(30)
 #define GRSTCTL_CSFTRST_DONE           BIT(29)
+#define GRSTCTL_CLOCK_SWITH_TIMER_MASK         (0x7 << 11)
+#define GRSTCTL_CLOCK_SWITH_TIMER_SHIFT                11
+#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_19             0x0
+#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_15             0x1
+#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_147            0x2
+#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_50             0x3
+#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_100            0x4
+#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_125            0x5
+#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_200            0x6
+#define GRSTCTL_CLOCK_SWITH_TIMER_VALUE_DIS            0x7
+#define GRSTCTL_CLOCK_SWITH_TIMER(_x)          ((_x) << 11)
 #define GRSTCTL_TXFNUM_MASK            (0x1f << 6)
 #define GRSTCTL_TXFNUM_SHIFT           6
 #define GRSTCTL_TXFNUM_LIMIT           0x1f