In preparation for adding support for the MSM8998 SoC's IPA,
add the necessary bits for IPA version 3.1 featuring GSI 1.0,
found on at least MSM8998.

Signed-off-by: AngeloGioacchino Del Regno 
<angelogioacchino.delre...@somainline.org>
---
 drivers/net/ipa/gsi.c          |  8 ++++----
 drivers/net/ipa/ipa_endpoint.c | 17 +++++++++--------
 drivers/net/ipa/ipa_main.c     |  8 ++++++--
 drivers/net/ipa/ipa_reg.h      |  3 +++
 drivers/net/ipa/ipa_version.h  |  1 +
 5 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index 14d9a791924b..6315336b3ca8 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -794,14 +794,14 @@ static void gsi_channel_program(struct gsi_channel 
*channel, bool doorbell)
 
        /* 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)
+       /* We enable the doorbell engine for IPA v3.x */
+       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;
@@ -899,7 +899,7 @@ void gsi_channel_reset(struct gsi *gsi, u32 channel_id, 
bool doorbell)
 
        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_3_5_1 && !channel->toward_ipa)
                gsi_channel_reset_command(channel);
 
        gsi_channel_program(channel, doorbell);
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c
index 9f4be9812a1f..06d8aa34276e 100644
--- a/drivers/net/ipa/ipa_endpoint.c
+++ b/drivers/net/ipa/ipa_endpoint.c
@@ -347,7 +347,7 @@ ipa_endpoint_program_suspend(struct ipa_endpoint *endpoint, 
bool enable)
 {
        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); */
@@ -1422,11 +1422,12 @@ static void ipa_endpoint_reset(struct ipa_endpoint 
*endpoint)
        bool special;
        int ret = 0;
 
-       /* On IPA v3.5.1, if an RX endpoint is reset while aggregation
-        * is active, we need to handle things specially to recover.
+       /* On IPA v3.5.1 and older, if an RX endpoint is reset while
+        * aggregation is active, we need to handle things in a special
+        * way in order to recover.
         * All other cases just need to reset the underlying GSI channel.
         */
-       special = ipa->version == IPA_VERSION_3_5_1 &&
+       special = ipa->version <= IPA_VERSION_3_5_1 &&
                        !endpoint->toward_ipa &&
                        endpoint->data->aggregation;
        if (special && ipa_endpoint_aggr_active(endpoint))
@@ -1525,8 +1526,8 @@ void ipa_endpoint_suspend_one(struct ipa_endpoint 
*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;
+       /* IPA v3.x doesn't use channel stop for suspend */
+       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,
@@ -1546,8 +1547,8 @@ void ipa_endpoint_resume_one(struct ipa_endpoint 
*endpoint)
        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;
+       /* IPA v3.x doesn't use channel start 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,
diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
index 84bb8ae92725..be191993fbec 100644
--- a/drivers/net/ipa/ipa_main.c
+++ b/drivers/net/ipa/ipa_main.c
@@ -228,8 +228,8 @@ static void ipa_hardware_config_comp(struct ipa *ipa)
 {
        u32 val;
 
-       /* Nothing to configure for IPA v3.5.1 */
-       if (ipa->version == IPA_VERSION_3_5_1)
+       /* Nothing to configure for IPA v3.5.1 and below */
+       if (ipa->version <= IPA_VERSION_3_5_1)
                return;
 
        val = ioread32(ipa->reg_virt + IPA_REG_COMP_CFG_OFFSET);
@@ -276,6 +276,7 @@ static void ipa_hardware_config_qsb(struct ipa *ipa)
 
        max1 = 12;
        switch (version) {
+       case IPA_VERSION_3_1:
        case IPA_VERSION_3_5_1:
                max0 = 8;
                break;
@@ -404,6 +405,9 @@ static void ipa_hardware_config(struct ipa *ipa)
                /* Enable open global clocks (not needed for IPA v4.5) */
                val = GLOBAL_FMASK;
                val |= GLOBAL_2X_CLK_FMASK;
+               if (version == IPA_VERSION_3_1)
+                       val |= MISC_FMASK;
+
                iowrite32(val, ipa->reg_virt + IPA_REG_CLKON_CFG_OFFSET);
 
                /* Disable PA mask to allow HOLB drop */
diff --git a/drivers/net/ipa/ipa_reg.h b/drivers/net/ipa/ipa_reg.h
index e6b0827a244e..9b9d6e0397bb 100644
--- a/drivers/net/ipa/ipa_reg.h
+++ b/drivers/net/ipa/ipa_reg.h
@@ -199,6 +199,9 @@ static inline u32 ipa_reg_state_aggr_active_offset(enum 
ipa_version version)
 /* Backward compatibility register value to use for each version */
 static inline u32 ipa_reg_bcr_val(enum ipa_version version)
 {
+       if (version == IPA_VERSION_3_1)
+               return BCR_CMDQ_L_LACK_ONE_ENTRY_FMASK;
+
        if (version == IPA_VERSION_3_5_1)
                return BCR_CMDQ_L_LACK_ONE_ENTRY_FMASK |
                        BCR_TX_NOT_USING_BRESP_FMASK |
diff --git a/drivers/net/ipa/ipa_version.h b/drivers/net/ipa/ipa_version.h
index 2944e2a89023..47f68975d576 100644
--- a/drivers/net/ipa/ipa_version.h
+++ b/drivers/net/ipa/ipa_version.h
@@ -14,6 +14,7 @@
  * it where it's needed.
  */
 enum ipa_version {
+       IPA_VERSION_3_1,        /* GSI version 1.0 */
        IPA_VERSION_3_5_1,      /* GSI version 1.3.0 */
        IPA_VERSION_4_0,        /* GSI version 2.0 */
        IPA_VERSION_4_1,        /* GSI version 2.1 */
-- 
2.30.0

Reply via email to