if (mode == USB_DR_MODE_OTG &&
                    (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) ||
                     !device_property_read_bool(dwc->dev, "usb-role-switch")) &&
-                   dwc->revision >= DWC3_REVISION_330A)
+                   !DWC3_VER_IS_PRIOR(DWC3, 330A))
                        mode = USB_DR_MODE_PERIPHERAL;
        }
 
         * take a little more than 50ms. Set the polling rate at 20ms
         * for 10 times instead.
         */
-       if (dwc3_is_usb31(dwc) && dwc->revision >= DWC3_USB31_REVISION_190A)
+       if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32))
                retries = 10;
 
        do {
                if (!(reg & DWC3_DCTL_CSFTRST))
                        goto done;
 
-               if (dwc3_is_usb31(dwc) &&
-                   dwc->revision >= DWC3_USB31_REVISION_190A)
+               if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32))
                        msleep(20);
                else
                        udelay(1);
         * is cleared, we must wait at least 50ms before accessing the PHY
         * domain (synchronization delay).
         */
-       if (dwc3_is_usb31(dwc) && dwc->revision <= DWC3_USB31_REVISION_180A)
+       if (DWC3_VER_IS_WITHIN(DWC31, ANY, 180A))
                msleep(50);
 
        return 0;
        u32 reg;
        u32 dft;
 
-       if (dwc->revision < DWC3_REVISION_250A)
+       if (DWC3_VER_IS_PRIOR(DWC3, 250A))
                return;
 
        if (dwc->fladj == 0)
         * will be '0' when the core is reset. Application needs to set it
         * to '1' after the core initialization is completed.
         */
-       if (dwc->revision > DWC3_REVISION_194A)
+       if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A))
                reg |= DWC3_GUSB3PIPECTL_SUSPHY;
 
        /*
         * be '0' when the core is reset. Application needs to set it to
         * '1' after the core initialization is completed.
         */
-       if (dwc->revision > DWC3_REVISION_194A)
+       if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A))
                reg |= DWC3_GUSB2PHYCFG_SUSPHY;
 
        /*
        u32 reg;
 
        reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
+       dwc->ip = DWC3_GSNPS_ID(reg);
 
        /* This should read as U3 followed by revision number */
-       if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) {
-               /* Detected DWC_usb3 IP */
+       if (DWC3_IP_IS(DWC3)) {
                dwc->revision = reg;
-       } else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) {
-               /* Detected DWC_usb31 IP */
+       } else if (DWC3_IP_IS(DWC31) || DWC3_IP_IS(DWC32)) {
                dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER);
-               dwc->revision |= DWC3_REVISION_IS_DWC31;
                dwc->version_type = dwc3_readl(dwc->regs, DWC3_VER_TYPE);
        } else {
                return false;
                 */
                if ((dwc->dr_mode == USB_DR_MODE_HOST ||
                                dwc->dr_mode == USB_DR_MODE_OTG) &&
-                               (dwc->revision >= DWC3_REVISION_210A &&
-                               dwc->revision <= DWC3_REVISION_250A))
+                               DWC3_VER_IS_WITHIN(DWC3, 210A, 250A))
                        reg |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC;
                else
                        reg &= ~DWC3_GCTL_DSBLCLKGTNG;
         * and falls back to high-speed mode which causes
         * the device to enter a Connect/Disconnect loop
         */
-       if (dwc->revision < DWC3_REVISION_190A)
+       if (DWC3_VER_IS_PRIOR(DWC3, 190A))
                reg |= DWC3_GCTL_U2RSTECN;
 
        dwc3_writel(dwc->regs, DWC3_GCTL, reg);
                goto err0a;
 
        if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD &&
-           dwc->revision > DWC3_REVISION_194A) {
+           !DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) {
                if (!dwc->dis_u3_susphy_quirk) {
                        reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
                        reg |= DWC3_GUSB3PIPECTL_SUSPHY;
         * the DWC_usb3 controller. It is NOT available in the
         * DWC_usb31 controller.
         */
-       if (!dwc3_is_usb31(dwc) && dwc->revision >= DWC3_REVISION_310A) {
+       if (DWC3_VER_IS_WITHIN(DWC3, 310A, ANY)) {
                reg = dwc3_readl(dwc->regs, DWC3_GUCTL2);
                reg |= DWC3_GUCTL2_RST_ACTBITLATER;
                dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
        }
 
-       if (dwc->revision >= DWC3_REVISION_250A) {
+       if (!DWC3_VER_IS_PRIOR(DWC3, 250A)) {
                reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
 
                /*
                 * Enable hardware control of sending remote wakeup
                 * in HS when the device is in the L1 state.
                 */
-               if (dwc->revision >= DWC3_REVISION_290A)
+               if (!DWC3_VER_IS_PRIOR(DWC3, 290A))
                        reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
 
                if (dwc->dis_tx_ipgap_linecheck_quirk)
         * Must config both number of packets and max burst settings to enable
         * RX and/or TX threshold.
         */
-       if (dwc3_is_usb31(dwc) && dwc->dr_mode == USB_DR_MODE_HOST) {
+       if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) {
                u8 rx_thr_num = dwc->rx_thr_num_pkt_prd;
                u8 rx_maxburst = dwc->rx_max_burst_prd;
                u8 tx_thr_num = dwc->tx_thr_num_pkt_prd;
 /* check whether the core supports IMOD */
 bool dwc3_has_imod(struct dwc3 *dwc)
 {
-       return ((dwc3_is_usb3(dwc) &&
-                dwc->revision >= DWC3_REVISION_300A) ||
-               (dwc3_is_usb31(dwc) &&
-                dwc->revision >= DWC3_USB31_REVISION_120A));
+       return DWC3_VER_IS_WITHIN(DWC3, 300A, ANY) ||
+               DWC3_VER_IS_WITHIN(DWC31, 120A, ANY) ||
+               DWC3_IP_IS(DWC32);
 }
 
 static void dwc3_check_params(struct dwc3 *dwc)
         * affected version.
         */
        if (!dwc->imod_interval &&
-           (dwc->revision == DWC3_REVISION_300A))
+           DWC3_VER_IS(DWC3, 300A))
                dwc->imod_interval = 1;
 
        /* Check the maximum_speed parameter */
                /*
                 * default to superspeed plus if we are capable.
                 */
-               if (dwc3_is_usb31(dwc) &&
+               if ((DWC3_IP_IS(DWC31) || DWC3_IP_IS(DWC32)) &&
                    (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
                     DWC3_GHWPARAMS3_SSPHY_IFC_GEN2))
                        dwc->maximum_speed = USB_SPEED_SUPER_PLUS;
 
 #define DWC3_GEVNTCOUNT_EHB    BIT(31)
 #define DWC3_GSNPSID_MASK      0xffff0000
 #define DWC3_GSNPSREV_MASK     0xffff
+#define DWC3_GSNPS_ID(p)       (((p) & DWC3_GSNPSID_MASK) >> 16)
 
 /* DWC3 registers memory space boundries */
 #define DWC3_XHCI_REGS_START           0x0
  * @nr_scratch: number of scratch buffers
  * @u1u2: only used on revisions <1.83a for workaround
  * @maximum_speed: maximum speed requested (mainly for testing purposes)
- * @revision: revision register contents
+ * @ip: controller's ID
+ * @revision: controller's version of an IP
  * @version_type: VERSIONTYPE register contents, a sub release of a revision
  * @dr_mode: requested mode of operation
  * @current_dr_role: current role of operation when in dual-role mode
        u32                     u1u2;
        u32                     maximum_speed;
 
-       /*
-        * All 3.1 IP version constants are greater than the 3.0 IP
-        * version constants. This works for most version checks in
-        * dwc3. However, in the future, this may not apply as
-        * features may be developed on newer versions of the 3.0 IP
-        * that are not in the 3.1 IP.
-        */
+       u32                     ip;
+
+#define DWC3_IP                        0x5533
+#define DWC31_IP               0x3331
+#define DWC32_IP               0x3332
+
        u32                     revision;
 
+#define DWC3_REVISION_ANY      0x0
 #define DWC3_REVISION_173A     0x5533173a
 #define DWC3_REVISION_175A     0x5533175a
 #define DWC3_REVISION_180A     0x5533180a
 #define DWC3_REVISION_310A     0x5533310a
 #define DWC3_REVISION_330A     0x5533330a
 
-/*
- * NOTICE: we're using bit 31 as a "is usb 3.1" flag. This is really
- * just so dwc31 revisions are always larger than dwc3.
- */
-#define DWC3_REVISION_IS_DWC31         0x80000000
-#define DWC3_USB31_REVISION_110A       (0x3131302a | DWC3_REVISION_IS_DWC31)
-#define DWC3_USB31_REVISION_120A       (0x3132302a | DWC3_REVISION_IS_DWC31)
-#define DWC3_USB31_REVISION_160A       (0x3136302a | DWC3_REVISION_IS_DWC31)
-#define DWC3_USB31_REVISION_170A       (0x3137302a | DWC3_REVISION_IS_DWC31)
-#define DWC3_USB31_REVISION_180A       (0x3138302a | DWC3_REVISION_IS_DWC31)
-#define DWC3_USB31_REVISION_190A       (0x3139302a | DWC3_REVISION_IS_DWC31)
+#define DWC31_REVISION_ANY     0x0
+#define DWC31_REVISION_110A    0x3131302a
+#define DWC31_REVISION_120A    0x3132302a
+#define DWC31_REVISION_160A    0x3136302a
+#define DWC31_REVISION_170A    0x3137302a
+#define DWC31_REVISION_180A    0x3138302a
+#define DWC31_REVISION_190A    0x3139302a
 
        u32                     version_type;
 
+#define DWC31_VERSIONTYPE_ANY          0x0
 #define DWC31_VERSIONTYPE_EA01         0x65613031
 #define DWC31_VERSIONTYPE_EA02         0x65613032
 #define DWC31_VERSIONTYPE_EA03         0x65613033
 void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
 u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type);
 
-/* check whether we are on the DWC_usb3 core */
-static inline bool dwc3_is_usb3(struct dwc3 *dwc)
-{
-       return !(dwc->revision & DWC3_REVISION_IS_DWC31);
-}
+#define DWC3_IP_IS(_ip)                                                        \
+       (dwc->ip == _ip##_IP)
 
-/* check whether we are on the DWC_usb31 core */
-static inline bool dwc3_is_usb31(struct dwc3 *dwc)
-{
-       return !!(dwc->revision & DWC3_REVISION_IS_DWC31);
-}
+#define DWC3_VER_IS(_ip, _ver)                                         \
+       (DWC3_IP_IS(_ip) && dwc->revision == _ip##_REVISION_##_ver)
+
+#define DWC3_VER_IS_PRIOR(_ip, _ver)                                   \
+       (DWC3_IP_IS(_ip) && dwc->revision < _ip##_REVISION_##_ver)
+
+#define DWC3_VER_IS_WITHIN(_ip, _from, _to)                            \
+       (DWC3_IP_IS(_ip) &&                                             \
+        dwc->revision >= _ip##_REVISION_##_from &&                     \
+        (!(_ip##_REVISION_##_to) ||                                    \
+         dwc->revision <= _ip##_REVISION_##_to))
+
+#define DWC3_VER_TYPE_IS_WITHIN(_ip, _ver, _from, _to)                 \
+       (DWC3_VER_IS(_ip, _ver) &&                                      \
+        dwc->version_type >= _ip##_VERSIONTYPE_##_from &&              \
+        (!(_ip##_VERSIONTYPE_##_to) ||                                 \
+         dwc->version_type <= _ip##_VERSIONTYPE_##_to))
 
 bool dwc3_has_imod(struct dwc3 *dwc);
 
 
         * Wait until device controller is ready. Only applies to 1.94a and
         * later RTL.
         */
-       if (dwc->revision >= DWC3_REVISION_194A) {
+       if (!DWC3_VER_IS_PRIOR(DWC3, 194A)) {
                while (--retries) {
                        reg = dwc3_readl(dwc->regs, DWC3_DSTS);
                        if (reg & DWC3_DSTS_DCNRD)
         * The following code is racy when called from dwc3_gadget_wakeup,
         * and is not needed, at least on newer versions
         */
-       if (dwc->revision >= DWC3_REVISION_194A)
+       if (!DWC3_VER_IS_PRIOR(DWC3, 194A))
                return 0;
 
        /* wait for a change in DSTS */
         * IN transfers due to a mishandled error condition. Synopsys
         * STAR 9000614252.
         */
-       if (dep->direction && (dwc->revision >= DWC3_REVISION_260A) &&
+       if (dep->direction &&
+           !DWC3_VER_IS_PRIOR(DWC3, 260A) &&
            (dwc->gadget.speed >= USB_SPEED_SUPER))
                cmd |= DWC3_DEPCMD_CLEARPENDIN;
 
                return -EAGAIN;
        }
 
-       if (!dwc->dis_start_transfer_quirk && dwc3_is_usb31(dwc) &&
-           (dwc->revision <= DWC3_USB31_REVISION_160A ||
-            (dwc->revision == DWC3_USB31_REVISION_170A &&
-             dwc->version_type >= DWC31_VERSIONTYPE_EA01 &&
-             dwc->version_type <= DWC31_VERSIONTYPE_EA06))) {
-
+       if (!dwc->dis_start_transfer_quirk &&
+           (DWC3_VER_IS_PRIOR(DWC31, 170A) ||
+            DWC3_VER_TYPE_IS_WITHIN(DWC31, 170A, EA01, EA06))) {
                if (dwc->gadget.speed <= USB_SPEED_HIGH && dep->direction)
                        return dwc3_gadget_start_isoc_quirk(dep);
        }
        }
 
        /* Recent versions do this automatically */
-       if (dwc->revision < DWC3_REVISION_194A) {
+       if (DWC3_VER_IS_PRIOR(DWC3, 194A)) {
                /* write zeroes to Link Change Request */
                reg = dwc3_readl(dwc->regs, DWC3_DCTL);
                reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
 
        reg = dwc3_readl(dwc->regs, DWC3_DCTL);
        if (is_on) {
-               if (dwc->revision <= DWC3_REVISION_187A) {
+               if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) {
                        reg &= ~DWC3_DCTL_TRGTULST_MASK;
                        reg |= DWC3_DCTL_TRGTULST_RX_DET;
                }
 
-               if (dwc->revision >= DWC3_REVISION_194A)
+               if (!DWC3_VER_IS_PRIOR(DWC3, 194A))
                        reg &= ~DWC3_DCTL_KEEP_CONNECT;
                reg |= DWC3_DCTL_RUN_STOP;
 
                        DWC3_DEVTEN_USBRSTEN |
                        DWC3_DEVTEN_DISCONNEVTEN);
 
-       if (dwc->revision < DWC3_REVISION_250A)
+       if (DWC3_VER_IS_PRIOR(DWC3, 250A))
                reg |= DWC3_DEVTEN_ULSTCNGEN;
 
        dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
         * bursts of data without going through any sort of endpoint throttling.
         */
        reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG);
-       if (dwc3_is_usb31(dwc))
-               reg &= ~DWC31_GRXTHRCFG_PKTCNTSEL;
-       else
+       if (DWC3_IP_IS(DWC3))
                reg &= ~DWC3_GRXTHRCFG_PKTCNTSEL;
+       else
+               reg &= ~DWC31_GRXTHRCFG_PKTCNTSEL;
 
        dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg);
 
         * STAR#9000525659: Clock Domain Crossing on DCTL in
         * USB 2.0 Mode
         */
-       if (dwc->revision < DWC3_REVISION_220A &&
+       if (DWC3_VER_IS_PRIOR(DWC3, 220A) &&
            !dwc->dis_metastability_quirk) {
                reg |= DWC3_DCFG_SUPERSPEED;
        } else {
                        reg |= DWC3_DCFG_SUPERSPEED;
                        break;
                case USB_SPEED_SUPER_PLUS:
-                       if (dwc3_is_usb31(dwc))
-                               reg |= DWC3_DCFG_SUPERSPEED_PLUS;
-                       else
+                       if (DWC3_IP_IS(DWC3))
                                reg |= DWC3_DCFG_SUPERSPEED;
+                       else
+                               reg |= DWC3_DCFG_SUPERSPEED_PLUS;
                        break;
                default:
                        dev_err(dwc->dev, "invalid speed (%d)\n", speed);
 
-                       if (dwc->revision & DWC3_REVISION_IS_DWC31)
-                               reg |= DWC3_DCFG_SUPERSPEED_PLUS;
-                       else
+                       if (DWC3_IP_IS(DWC3))
                                reg |= DWC3_DCFG_SUPERSPEED;
+                       else
+                               reg |= DWC3_DCFG_SUPERSPEED_PLUS;
                }
        }
        dwc3_writel(dwc->regs, DWC3_DCFG, reg);
        mdwidth /= 8;
 
        size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1));
-       if (dwc3_is_usb31(dwc))
-               size = DWC31_GTXFIFOSIZ_TXFDEP(size);
-       else
+       if (DWC3_IP_IS(DWC3))
                size = DWC3_GTXFIFOSIZ_TXFDEP(size);
+       else
+               size = DWC31_GTXFIFOSIZ_TXFDEP(size);
 
        /* FIFO Depth is in MDWDITH bytes. Multiply */
        size *= mdwidth;
 
        /* All OUT endpoints share a single RxFIFO space */
        size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0));
-       if (dwc3_is_usb31(dwc))
-               size = DWC31_GRXFIFOSIZ_RXFDEP(size);
-       else
+       if (DWC3_IP_IS(DWC3))
                size = DWC3_GRXFIFOSIZ_RXFDEP(size);
+       else
+               size = DWC31_GRXFIFOSIZ_RXFDEP(size);
 
        /* FIFO depth is in MDWDITH bytes */
        size *= mdwidth;
         * WORKAROUND: This is the 2nd half of U1/U2 -> U0 workaround.
         * See dwc3_gadget_linksts_change_interrupt() for 1st half.
         */
-       if (dwc->revision < DWC3_REVISION_183A) {
+       if (DWC3_VER_IS_PRIOR(DWC3, 183A)) {
                u32             reg;
                int             i;
 
         * STAR#9000466709: RTL: Device : Disconnect event not
         * generated if setup packet pending in FIFO
         */
-       if (dwc->revision < DWC3_REVISION_188A) {
+       if (DWC3_VER_IS_PRIOR(DWC3, 188A)) {
                if (dwc->setup_packet_pending)
                        dwc3_gadget_disconnect_interrupt(dwc);
        }
                 * STAR#9000483510: RTL: SS : USB3 reset event may
                 * not be generated always when the link enters poll
                 */
-               if (dwc->revision < DWC3_REVISION_190A)
+               if (DWC3_VER_IS_PRIOR(DWC3, 190A))
                        dwc3_gadget_reset_interrupt(dwc);
 
                dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
 
        /* Enable USB2 LPM Capability */
 
-       if ((dwc->revision > DWC3_REVISION_194A) &&
+       if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A) &&
            (speed != DWC3_DSTS_SUPERSPEED) &&
            (speed != DWC3_DSTS_SUPERSPEED_PLUS)) {
                reg = dwc3_readl(dwc->regs, DWC3_DCFG);
                 * BESL value in the LPM token is less than or equal to LPM
                 * NYET threshold.
                 */
-               WARN_ONCE(dwc->revision < DWC3_REVISION_240A
-                               && dwc->has_lpm_erratum,
+               WARN_ONCE(DWC3_VER_IS_PRIOR(DWC3, 240A) && dwc->has_lpm_erratum,
                                "LPM Erratum not available on dwc3 revisions < 2.40a\n");
 
-               if (dwc->has_lpm_erratum && dwc->revision >= DWC3_REVISION_240A)
+               if (dwc->has_lpm_erratum && !DWC3_VER_IS_PRIOR(DWC3, 240A))
                        reg |= DWC3_DCTL_NYET_THRES(dwc->lpm_nyet_threshold);
 
                dwc3_gadget_dctl_write_safe(dwc, reg);
         * operational mode
         */
        pwropt = DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1);
-       if ((dwc->revision < DWC3_REVISION_250A) &&
+       if (DWC3_VER_IS_PRIOR(DWC3, 250A) &&
                        (pwropt != DWC3_GHWPARAMS1_EN_PWROPT_HIB)) {
                if ((dwc->link_state == DWC3_LINK_STATE_U3) &&
                                (next == DWC3_LINK_STATE_RESUME)) {
         * STAR#9000446952: RTL: Device SS : if U1/U2 ->U0 takes >128us
         * core send LGO_Ux entering U0
         */
-       if (dwc->revision < DWC3_REVISION_183A) {
+       if (DWC3_VER_IS_PRIOR(DWC3, 183A)) {
                if (next == DWC3_LINK_STATE_U0) {
                        u32     u1u2;
                        u32     reg;
                break;
        case DWC3_DEVICE_EVENT_EOPF:
                /* It changed to be suspend event for version 2.30a and above */
-               if (dwc->revision >= DWC3_REVISION_230A) {
+               if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) {
                        /*
                         * Ignore suspend event until the gadget enters into
                         * USB_STATE_CONFIGURED state.
         * is less than super speed because we don't have means, yet, to tell
         * composite.c that we are USB 2.0 + LPM ECN.
         */
-       if (dwc->revision < DWC3_REVISION_220A &&
+       if (DWC3_VER_IS_PRIOR(DWC3, 220A) &&
            !dwc->dis_metastability_quirk)
                dev_info(dwc->dev, "changing max_speed on rev %08x\n",
                                dwc->revision);
 
         *
         * This following flag tells XHCI to do just that.
         */
-       if (dwc->revision <= DWC3_REVISION_300A)
+       if (DWC3_VER_IS_WITHIN(DWC3, ANY, 300A))
                props[prop_idx++] = PROPERTY_ENTRY_BOOL("quirk-broken-port-ped");
 
        if (prop_idx) {