summaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorSkylar Chang <chiaweic@codeaurora.org>2015-10-15 22:35:30 -0700
committerJeevan Shriram <jshriram@codeaurora.org>2016-04-07 15:58:32 -0700
commit2bb6f282727499ecc05d2f948804c376c5b040b9 (patch)
treec0cf7d56a1e49cc449df76b8bf6c95c4ced82bff /drivers/platform
parentb63c02a6187b85ea589fa025805c1377da1c863f (diff)
msm: ipa: support WDI 2.0 suspend
IPA-driver only suspends the WDI pipe when rdy_ring_rp value equals to the value of rdy_comp_ring_wp Change-Id: I520b7943b85cd61065703c7bf9a5d8efb6302a56 Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h11
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c71
2 files changed, 79 insertions, 3 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 17ea15fc62cb..288cdc0759a1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -49,6 +49,9 @@
#define IPA_DL_CHECKSUM_LENGTH (8)
#define IPA_NUM_DESC_PER_SW_TX (3)
#define IPA_GENERIC_RX_POOL_SZ 192
+#define IPA_UC_FINISH_MAX 6
+#define IPA_UC_WAIT_MIN_SLEEP 1000
+#define IPA_UC_WAII_MAX_SLEEP 1200
#define IPA_MAX_STATUS_STAT_NUM 30
#define __FILENAME__ \
@@ -1385,6 +1388,14 @@ struct ipa3_uc_ctx {
u32 uc_status;
u32 uc_error_type;
u32 uc_error_timestamp;
+ phys_addr_t rdy_ring_base_pa;
+ phys_addr_t rdy_ring_rp_pa;
+ u32 rdy_ring_size;
+ phys_addr_t rdy_comp_ring_base_pa;
+ phys_addr_t rdy_comp_ring_wp_pa;
+ u32 rdy_comp_ring_size;
+ u32 *rdy_ring_rp_va;
+ u32 *rdy_comp_ring_wp_va;
};
/**
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 3ae3f087e450..8ba2aa2a8b4d 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c
@@ -12,6 +12,7 @@
#include "ipa_i.h"
#include <linux/dmapool.h>
#include <linux/delay.h>
+#include <linux/mm.h>
#define IPA_HOLB_TMR_DIS 0x0
@@ -804,9 +805,50 @@ int ipa3_connect_wdi_pipe(struct ipa_wdi_in_params *in,
cmd.size = sizeof(*rx_2);
else
cmd.size = sizeof(*rx);
- IPADBG("rx_ring_base_pa=0x%pa\n", &in->u.ul.rdy_ring_base_pa);
- IPADBG("rx_ring_size=%d\n", in->u.ul.rdy_ring_size);
- IPADBG("rx_ring_rp_pa=0x%pa\n", &in->u.ul.rdy_ring_rp_pa);
+ IPADBG("rx_ring_base_pa=0x%pa\n",
+ &in->u.ul.rdy_ring_base_pa);
+ IPADBG("rx_ring_size=%d\n",
+ in->u.ul.rdy_ring_size);
+ IPADBG("rx_ring_rp_pa=0x%pa\n",
+ &in->u.ul.rdy_ring_rp_pa);
+ IPADBG("rdy_ring_rp value =%d\n",
+ *in->u.ul.rdy_ring_rp_va);
+ IPADBG("rx_comp_ring_base_pa=0x%pa\n",
+ &in->u.ul.rdy_comp_ring_base_pa);
+ IPADBG("rx_comp_ring_size=%d\n",
+ in->u.ul.rdy_comp_ring_size);
+ IPADBG("rx_comp_ring_wp_pa=0x%pa\n",
+ &in->u.ul.rdy_comp_ring_wp_pa);
+ IPADBG("rx_comp_ring_wp value=%d\n",
+ *in->u.ul.rdy_comp_ring_wp_va);
+ ipa3_ctx->uc_ctx.rdy_ring_base_pa =
+ in->u.ul.rdy_ring_base_pa;
+ ipa3_ctx->uc_ctx.rdy_ring_rp_pa =
+ in->u.ul.rdy_ring_rp_pa;
+ ipa3_ctx->uc_ctx.rdy_ring_size =
+ in->u.ul.rdy_ring_size;
+ ipa3_ctx->uc_ctx.rdy_comp_ring_base_pa =
+ in->u.ul.rdy_comp_ring_base_pa;
+ ipa3_ctx->uc_ctx.rdy_comp_ring_wp_pa =
+ in->u.ul.rdy_comp_ring_wp_pa;
+ ipa3_ctx->uc_ctx.rdy_comp_ring_size =
+ in->u.ul.rdy_comp_ring_size;
+ ipa3_ctx->uc_ctx.rdy_ring_rp_va =
+ in->u.ul.rdy_ring_rp_va;
+ ipa3_ctx->uc_ctx.rdy_comp_ring_wp_va =
+ in->u.ul.rdy_comp_ring_wp_va;
+ /* check if the VA is empty */
+ if (!in->u.ul.rdy_ring_rp_va && ipa3_ctx->ipa_wdi2) {
+ IPAERR("rdy_ring_rp_va is empty, wdi2.0(%d)\n",
+ ipa3_ctx->ipa_wdi2);
+ goto dma_alloc_fail;
+ }
+ if (!in->u.ul.rdy_comp_ring_wp_va &&
+ ipa3_ctx->ipa_wdi2) {
+ IPAERR("comp_ring_wp_va is empty, wdi2.0(%d)\n",
+ ipa3_ctx->ipa_wdi2);
+ goto dma_alloc_fail;
+ }
}
cmd.base = dma_alloc_coherent(ipa3_ctx->uc_pdev, cmd.size,
@@ -1299,6 +1341,7 @@ int ipa3_disable_wdi_pipe(u32 clnt_hdl)
union IpaHwWdiCommonChCmdData_t disable;
struct ipa_ep_cfg_ctrl ep_cfg_ctrl;
u32 prod_hdl;
+ int i;
if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
ipa3_ctx->ep[clnt_hdl].valid == 0) {
@@ -1310,6 +1353,28 @@ 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];