/* Max prefetch is 1 segment (do not set MAX_PREFETCH_FMASK) */
 
-       /* We enable the doorbell engine for IPA v3.5.1 */
-       if (gsi->version == IPA_VERSION_3_5_1 && doorbell)
+       /* No need to use the doorbell engine starting at IPA v4.0 */
+       if (gsi->version < IPA_VERSION_4_0 && doorbell)
                val |= USE_DB_ENG_FMASK;
 
        /* v4.0 introduces an escape buffer for prefetch.  We use it
         * on all but the AP command channel.
         */
-       if (gsi->version != IPA_VERSION_3_5_1 && !channel->command) {
+       if (gsi->version >= IPA_VERSION_4_0 && !channel->command) {
                /* If not otherwise set, prefetch buffers are used */
                if (gsi->version < IPA_VERSION_4_5)
                        val |= USE_ESCAPE_BUF_ONLY_FMASK;
 
        gsi_channel_reset_command(channel);
        /* Due to a hardware quirk we may need to reset RX channels twice. */
-       if (gsi->version == IPA_VERSION_3_5_1 && !channel->toward_ipa)
+       if (gsi->version < IPA_VERSION_4_0 && !channel->toward_ipa)
                gsi_channel_reset_command(channel);
 
        gsi_channel_program(channel, doorbell);
 
 
 /* IPA_CMD_REGISTER_WRITE */
 
-/* For IPA v4.0+, this opcode gets modified with pipeline clear options */
-
+/* For IPA v4.0+, the pipeline clear options are encoded in the opcode */
 #define REGISTER_WRITE_OPCODE_SKIP_CLEAR_FMASK         GENMASK(8, 8)
 #define REGISTER_WRITE_OPCODE_CLEAR_OPTION_FMASK       GENMASK(10, 9)
 
 struct ipa_cmd_register_write {
-       __le16 flags;           /* Unused/reserved for IPA v3.5.1 */
+       __le16 flags;           /* Unused/reserved prior to IPA v4.0 */
        __le16 offset;
        __le32 value;
        __le32 value_mask;
 };
 
 /* Field masks for ipa_cmd_register_write structure fields */
-/* The next field is present for IPA v4.0 and above */
+/* The next field is present for IPA v4.0+ */
 #define REGISTER_WRITE_FLAGS_OFFSET_HIGH_FMASK         GENMASK(14, 11)
-/* The next field is present for IPA v3.5.1 only */
+/* The next field is not present for IPA v4.0+ */
 #define REGISTER_WRITE_FLAGS_SKIP_CLEAR_FMASK          GENMASK(15, 15)
 
-/* The next field and its values are present for IPA v3.5.1 only */
+/* The next field and its values are not present for IPA v4.0+ */
 #define REGISTER_WRITE_CLEAR_OPTIONS_FMASK             GENMASK(1, 0)
 
 /* IPA_CMD_IP_PACKET_INIT */
 
 /* Field masks for ipa_cmd_hw_dma_mem_mem structure fields */
 #define DMA_SHARED_MEM_FLAGS_DIRECTION_FMASK           GENMASK(0, 0)
-/* The next two fields are present for IPA v3.5.1 only. */
+/* The next two fields are not present for IPA v4.0+ */
 #define DMA_SHARED_MEM_FLAGS_SKIP_CLEAR_FMASK          GENMASK(1, 1)
 #define DMA_SHARED_MEM_FLAGS_CLEAR_OPTIONS_FMASK       GENMASK(3, 2)
 
        u32 bit_count;
 
        /* The maximum offset in a register_write immediate command depends
-        * on the version of IPA.  IPA v3.5.1 supports a 16 bit offset, but
-        * newer versions allow some additional high-order bits.
+        * on the version of IPA.  A 16 bit offset is always supported,
+        * but starting with IPA v4.0 some additional high-order bits are
+        * allowed.
         */
        bit_count = BITS_PER_BYTE * sizeof(payload->offset);
-       if (ipa->version != IPA_VERSION_3_5_1)
+       if (ipa->version >= IPA_VERSION_4_0)
                bit_count += hweight32(REGISTER_WRITE_FLAGS_OFFSET_HIGH_FMASK);
        BUILD_BUG_ON(bit_count > 32);
        offset_max = ~0U >> (32 - bit_count);
        /* pipeline_clear_src_grp is not used */
        clear_option = clear_full ? pipeline_clear_full : pipeline_clear_hps;
 
-       if (ipa->version != IPA_VERSION_3_5_1) {
+       /* IPA v4.0+ represents the pipeline clear options in the opcode.  It
+        * also supports a larger offset by encoding additional high-order
+        * bits in the payload flags field.
+        */
+       if (ipa->version >= IPA_VERSION_4_0) {
                u16 offset_high;
                u32 val;
 
 
         * if (endpoint->toward_ipa)
         *      assert(ipa->version != IPA_VERSION_4.2);
         * else
-        *      assert(ipa->version == IPA_VERSION_3_5_1);
+        *      assert(ipa->version < IPA_VERSION_4_0);
         */
        mask = endpoint->toward_ipa ? ENDP_DELAY_FMASK : ENDP_SUSPEND_FMASK;
 
 {
        bool suspended;
 
-       if (endpoint->ipa->version != IPA_VERSION_3_5_1)
+       if (endpoint->ipa->version >= IPA_VERSION_4_0)
                return enable;  /* For IPA v4.0+, no change made */
 
        /* assert(!endpoint->toward_ipa); */
                        /* Where IPA will write the length */
                        offset = offsetof(struct rmnet_map_header, pkt_len);
                        /* Upper bits are stored in HDR_EXT with IPA v4.5 */
-                       if (version == IPA_VERSION_4_5)
+                       if (version >= IPA_VERSION_4_5)
                                offset &= field_mask(HDR_OFST_PKT_SIZE_FMASK);
 
                        val |= HDR_OFST_PKT_SIZE_VALID_FMASK;
        /* IPA v4.5 adds some most-significant bits to a few fields,
         * two of which are defined in the HDR (not HDR_EXT) register.
         */
-       if (ipa->version == IPA_VERSION_4_5) {
+       if (ipa->version >= IPA_VERSION_4_5) {
                /* HDR_TOTAL_LEN_OR_PAD_OFFSET is 0, so MSB is 0 */
                if (endpoint->data->qmap && !endpoint->toward_ipa) {
                        u32 offset;
        if (!microseconds)
                return 0;       /* Nothing to compute if timer period is 0 */
 
-       if (ipa->version == IPA_VERSION_4_5)
+       if (ipa->version >= IPA_VERSION_4_5)
                return hol_block_timer_qtime_val(ipa, microseconds);
 
        /* Use 64 bit arithmetic to avoid overflow... */
         * is active, we need to handle things specially to recover.
         * All other cases just need to reset the underlying GSI channel.
         */
-       special = ipa->version == IPA_VERSION_3_5_1 &&
-                       !endpoint->toward_ipa &&
+       special = ipa->version < IPA_VERSION_4_0 && !endpoint->toward_ipa &&
                        endpoint->data->aggregation;
        if (special && ipa_endpoint_aggr_active(endpoint))
                ret = ipa_endpoint_reset_rx_aggr(endpoint);
                (void)ipa_endpoint_program_suspend(endpoint, true);
        }
 
-       /* IPA v3.5.1 doesn't use channel stop for suspend */
-       stop_channel = endpoint->ipa->version != IPA_VERSION_3_5_1;
+       /* Starting with IPA v4.0, endpoints are suspended by stopping the
+        * underlying GSI channel rather than using endpoint suspend mode.
+        */
+       stop_channel = endpoint->ipa->version >= IPA_VERSION_4_0;
        ret = gsi_channel_suspend(gsi, endpoint->channel_id, stop_channel);
        if (ret)
                dev_err(dev, "error %d suspending channel %u\n", ret,
        if (!endpoint->toward_ipa)
                (void)ipa_endpoint_program_suspend(endpoint, false);
 
-       /* IPA v3.5.1 doesn't use channel start for resume */
-       start_channel = endpoint->ipa->version != IPA_VERSION_3_5_1;
+       /* Starting with IPA v4.0, the underlying GSI channel must be
+        * restarted for resume.
+        */
+       start_channel = endpoint->ipa->version >= IPA_VERSION_4_0;
        ret = gsi_channel_resume(gsi, endpoint->channel_id, start_channel);
        if (ret)
                dev_err(dev, "error %d resuming channel %u\n", ret,
 
 {
        u32 val;
 
-       /* Nothing to configure for IPA v3.5.1 */
-       if (ipa->version == IPA_VERSION_3_5_1)
+       /* Nothing to configure prior to IPA v4.0 */
+       if (ipa->version < IPA_VERSION_4_0)
                return;
 
        val = ioread32(ipa->reg_virt + IPA_REG_COMP_CFG_OFFSET);
        }
 
        /* Implement some hardware workarounds */
-       if (version != IPA_VERSION_3_5_1 && version < IPA_VERSION_4_5) {
+       if (version >= IPA_VERSION_4_0 && version < IPA_VERSION_4_5) {
                /* Enable open global clocks (not needed for IPA v4.5) */
                val = GLOBAL_FMASK;
                val |= GLOBAL_2X_CLK_FMASK;
 
 
        /* None of the stats fields are valid (IPA v4.0 and above) */
 
-       if (ipa->version != IPA_VERSION_3_5_1) {
+       if (ipa->version >= IPA_VERSION_4_0) {
                mem = &ipa->mem[IPA_MEM_STATS_QUOTA_MODEM];
                if (mem->size) {
                        req.hw_stats_quota_base_addr_valid = 1;