summaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorSkylar Chang <chiaweic@codeaurora.org>2016-11-29 13:36:24 -0800
committerSkylar Chang <chiaweic@codeaurora.org>2016-12-07 10:50:58 -0800
commit38b489ccd4c78d3d1bf69a1a0a57812d0fc0d73e (patch)
tree01c854d3a2417d6bdacdc61e00f1d9174ad336a9 /drivers/platform
parent2be8fc81c3adef891480d3abd19639860d838443 (diff)
msm: ipa3: check the rx_door_bell value on disable
In WDI2.0, seeing some issue about rdy_ring_rp_va is not equal to rdy_comp_ring_wp_va because wlan-fw still update the doorbell after ipa host-driver issue the CH_DISABLE cmd to ipa-uc. The fix is to compare rdy_comp_ring_wp_va and rx_door_bell values instead. Change-Id: Ibe57c7d5ba9e45260c12528910f173e347259d7c Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c55
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c32
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h5
3 files changed, 69 insertions, 23 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
index ab4911462ddf..e38f6f2860cf 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
@@ -1356,6 +1356,7 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl)
struct ipa_ep_cfg_ctrl ep_cfg_ctrl;
u32 prod_hdl;
int i;
+ u32 rx_door_bell_value;
if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
ipa3_ctx->ep[clnt_hdl].valid == 0) {
@@ -1367,28 +1368,6 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl)
if (result)
return result;
- /* checking rdy_ring_rp_pa matches the rdy_comp_ring_wp_pa on WDI2.0 */
- if (ipa3_ctx->ipa_wdi2) {
- for (i = 0; i < IPA_UC_FINISH_MAX; i++) {
- IPADBG("(%d) rp_value(%u), comp_wp_value(%u)\n",
- i,
- *ipa3_ctx->uc_ctx.rdy_ring_rp_va,
- *ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va);
- if (*ipa3_ctx->uc_ctx.rdy_ring_rp_va !=
- *ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va) {
- usleep_range(IPA_UC_WAIT_MIN_SLEEP,
- IPA_UC_WAII_MAX_SLEEP);
- } else {
- break;
- }
- }
- /* In case ipa_uc still haven't processed all
- * pending descriptors, we have to assert
- */
- if (i == IPA_UC_FINISH_MAX)
- WARN_ON(1);
- }
-
IPADBG("ep=%d\n", clnt_hdl);
ep = &ipa3_ctx->ep[clnt_hdl];
@@ -1429,10 +1408,40 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl)
}
usleep_range(IPA_UC_POLL_SLEEP_USEC * IPA_UC_POLL_SLEEP_USEC,
IPA_UC_POLL_SLEEP_USEC * IPA_UC_POLL_SLEEP_USEC);
+
+ /*
+ * checking rdy_ring_rp_pa matches the
+ * rdy_comp_ring_wp_pa on WDI2.0
+ */
+ if (ipa3_ctx->ipa_wdi2) {
+ for (i = 0; i < IPA_UC_FINISH_MAX; i++) {
+ rx_door_bell_value = ipahal_read_reg_mn(
+ IPA_UC_MAILBOX_m_n,
+ IPA_HW_WDI_RX_MBOX_START_INDEX/32,
+ IPA_HW_WDI_RX_MBOX_START_INDEX % 32);
+ IPADBG("(%d)rx_DB(%u)rp(%u),comp_wp(%u)\n",
+ i,
+ rx_door_bell_value,
+ *ipa3_ctx->uc_ctx.rdy_ring_rp_va,
+ *ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va);
+ if (rx_door_bell_value !=
+ *ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va) {
+ usleep_range(IPA_UC_WAIT_MIN_SLEEP,
+ IPA_UC_WAII_MAX_SLEEP);
+ } else {
+ break;
+ }
+ }
+ /*
+ * In case ipa_uc still haven't processed all
+ * pending descriptors, we have to assert
+ */
+ if (i == IPA_UC_FINISH_MAX)
+ ipa_assert();
+ }
}
disable.params.ipa_pipe_number = clnt_hdl;
-
result = ipa3_uc_send_cmd(disable.raw32b,
IPA_CPU_2_HW_CMD_WDI_CH_DISABLE,
IPA_HW_2_CPU_WDI_CMD_STATUS_SUCCESS,
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 cef9f7ef3fe4..347a8c418ebb 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -1287,6 +1287,38 @@ u32 ipahal_read_reg_n(enum ipahal_reg_name reg, u32 n)
}
/*
+ * ipahal_read_reg_mn() - Get mn parameterized reg value
+ */
+u32 ipahal_read_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n)
+{
+ u32 offset;
+
+ if (reg >= IPA_REG_MAX) {
+ IPAHAL_ERR("Invalid register reg=%u\n", reg);
+ return -EFAULT;
+ }
+
+ IPAHAL_DBG_LOW("read %s m=%u n=%u\n",
+ ipahal_reg_name_str(reg), m, n);
+ offset = ipahal_reg_objs[ipahal_ctx->hw_type][reg].offset;
+ if (offset == -1) {
+ IPAHAL_ERR("Read access to obsolete reg=%s\n",
+ ipahal_reg_name_str(reg));
+ WARN_ON_ONCE(1);
+ return -EFAULT;
+ }
+ /*
+ * Currently there is one register with m and n parameters
+ * IPA_UC_MAILBOX_m_n. The m value of it is 0x80.
+ * If more such registers will be added in the future,
+ * we can move the m parameter to the table above.
+ */
+ offset += 0x80 * m;
+ offset += ipahal_reg_objs[ipahal_ctx->hw_type][reg].n_ofst * n;
+ return ioread32(ipahal_ctx->base + offset);
+}
+
+/*
* ipahal_write_reg_mn() - Write to m/n parameterized reg a raw value
*/
void ipahal_write_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n, u32 val)
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
index 8fb9040360ea..5f1e3fe410b1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
@@ -341,6 +341,11 @@ const char *ipahal_reg_name_str(enum ipahal_reg_name reg_name);
u32 ipahal_read_reg_n(enum ipahal_reg_name reg, u32 n);
/*
+ * ipahal_read_reg_mn() - Get mn parameterized reg value
+ */
+u32 ipahal_read_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n);
+
+/*
* ipahal_write_reg_mn() - Write to m/n parameterized reg a raw value
*/
void ipahal_write_reg_mn(enum ipahal_reg_name reg, u32 m, u32 n, u32 val);