msm: ipa3: disable TX prefetch to support MBIM
In order to enable MBIM aggregation TX prefetch needs to be disabled.
Disable TX prefetch on boot when non MHI configuration is detected.
CRs-Fixed: 1097871
Change-Id: I4107f3e54293421b9b4fdbcb62a09528bb6b775c
Acked-by: Ady Abraham <adya@qti.qualcomm.com>
Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
Signed-off-by: Amir Levy <alevy@codeaurora.org>
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index c6f1ea0..c6eec53 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -3962,6 +3962,13 @@
IPADBG("Initialization of ipa interrupts skipped\n");
}
+ /*
+ * IPAv3.5.x requires to disable prefetch for USB in order to allow
+ * MBIM to work, currently MBIM is not needed in MHI mode.
+ */
+ if (!ipa3_ctx->ipa_config_is_mhi)
+ ipa3_disable_prefetch(IPA_CLIENT_USB_CONS);
+
memset(&gsi_props, 0, sizeof(gsi_props));
gsi_props.ver = ipa3_get_gsi_ver(resource_p->ipa_hw_type);
gsi_props.ee = resource_p->ee;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 5a6dcaa..244c80c 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -1962,4 +1962,5 @@
bool ipa3_is_msm_device(void);
struct device *ipa3_get_pdev(void);
void ipa3_enable_dcd(void);
+void ipa3_disable_prefetch(enum ipa_client_type client);
#endif /* _IPA3_I_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index a98eedc..84722df 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -4465,6 +4465,33 @@
}
/**
+* ipa3_disable_prefetch() - disable\enable tx prefetch
+*
+* @client: the client which is related to the TX where prefetch will be
+* disabled
+*
+* Return value: Non applicable
+*
+*/
+void ipa3_disable_prefetch(enum ipa_client_type client)
+{
+ struct ipahal_reg_tx_cfg cfg;
+ u8 qmb;
+
+ qmb = ipa3_get_qmb_master_sel(client);
+
+ IPADBG("disabling prefetch for qmb %d\n", (int)qmb);
+
+ ipahal_read_reg_fields(IPA_TX_CFG, &cfg);
+ /* QMB0 (DDR) correlates with TX0, QMB1(PCIE) correlates with TX1 */
+ if (qmb == QMB_MASTER_SELECT_DDR)
+ cfg.tx0_prefetch_disable = true;
+ else
+ cfg.tx1_prefetch_disable = true;
+ ipahal_write_reg_fields(IPA_TX_CFG, &cfg);
+}
+
+/**
* ipa3_get_pdev() - return a pointer to IPA dev struct
*
* Return value: a pointer to IPA dev struct
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
index 2a780b6..3c8688e7 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -901,6 +901,26 @@
IPA_QSB_MAX_READS_GEN_QMB_1_MAX_READS_BMSK);
}
+static void ipareg_parse_tx_cfg(enum ipahal_reg_name reg,
+ void *fields, u32 val)
+{
+ struct ipahal_reg_tx_cfg *tx_cfg;
+
+ tx_cfg = (struct ipahal_reg_tx_cfg *)fields;
+
+ tx_cfg->tx0_prefetch_disable = IPA_GETFIELD_FROM_REG(val,
+ IPA_TX_CFG_TX0_PREFETCH_DISABLE_SHFT_V3_5,
+ IPA_TX_CFG_TX0_PREFETCH_DISABLE_BMSK_V3_5);
+
+ tx_cfg->tx1_prefetch_disable = IPA_GETFIELD_FROM_REG(val,
+ IPA_TX_CFG_TX1_PREFETCH_DISABLE_SHFT_V3_5,
+ IPA_TX_CFG_TX1_PREFETCH_DISABLE_BMSK_V3_5);
+
+ tx_cfg->prefetch_almost_empty_size = IPA_GETFIELD_FROM_REG(val,
+ IPA_TX_CFG_PREFETCH_ALMOST_EMPTY_SIZE_SHFT_V3_5,
+ IPA_TX_CFG_PREFETCH_ALMOST_EMPTY_SIZE_BMSK_V3_5);
+}
+
static void ipareg_construct_tx_cfg(enum ipahal_reg_name reg,
const void *fields, u32 *val)
{
@@ -1174,7 +1194,7 @@
/* IPAv3.5 */
[IPA_HW_v3_5][IPA_TX_CFG] = {
- ipareg_construct_tx_cfg, ipareg_parse_dummy,
+ ipareg_construct_tx_cfg, ipareg_parse_tx_cfg,
0x000001FC, 0},
[IPA_HW_v3_5][IPA_SRC_RSRC_GRP_01_RSRC_TYPE_n] = {
ipareg_construct_rsrg_grp_xy_v3_5, ipareg_parse_dummy,