diff options
| author | Skylar Chang <chiaweic@codeaurora.org> | 2015-10-15 22:35:30 -0700 |
|---|---|---|
| committer | Jeevan Shriram <jshriram@codeaurora.org> | 2016-04-07 15:58:32 -0700 |
| commit | 2bb6f282727499ecc05d2f948804c376c5b040b9 (patch) | |
| tree | c0cf7d56a1e49cc449df76b8bf6c95c4ced82bff /drivers/platform | |
| parent | b63c02a6187b85ea589fa025805c1377da1c863f (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.h | 11 | ||||
| -rw-r--r-- | drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c | 71 |
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]; |
