mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-21 03:43:03 +00:00
msm ipa: fix IPA stall when do SAP on/off
Fix IPA stall when do SAP on/off during high data transfer rate. Change the IPA-pipe reset sequence. Change-Id: I4754e15f41d87ba22e860ef9bdcb91b17d781d08 Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
This commit is contained in:
parent
9071c08e71
commit
485ae7719c
|
@ -1117,6 +1117,7 @@ int ipa_disable_wdi_pipe(u32 clnt_hdl)
|
|||
struct ipa_ep_context *ep;
|
||||
union IpaHwWdiCommonChCmdData_t disable;
|
||||
struct ipa_ep_cfg_ctrl ep_cfg_ctrl;
|
||||
u32 prod_hdl;
|
||||
|
||||
if (clnt_hdl >= IPA_NUM_PIPES || ipa_ctx->ep[clnt_hdl].valid == 0) {
|
||||
IPAERR("bad parm.\n");
|
||||
|
@ -1152,11 +1153,30 @@ int ipa_disable_wdi_pipe(u32 clnt_hdl)
|
|||
result = -EPERM;
|
||||
goto uc_timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* To avoid data stall during continuous SAP on/off before
|
||||
* setting delay to IPA Consumer pipe, remove delay and enable
|
||||
* holb on IPA Producer pipe
|
||||
*/
|
||||
if (IPA_CLIENT_IS_PROD(ep->client)) {
|
||||
memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl));
|
||||
ep_cfg_ctrl.ipa_ep_delay = true;
|
||||
ipa_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl);
|
||||
|
||||
prod_hdl = ipa_get_ep_mapping(IPA_CLIENT_WLAN1_CONS);
|
||||
if (ipa_ctx->ep[prod_hdl].valid == 1) {
|
||||
result = ipa_disable_data_path(prod_hdl);
|
||||
if (result) {
|
||||
IPAERR("disable data path failed\n");
|
||||
IPAERR("res=%d clnt=%d\n",
|
||||
result, prod_hdl);
|
||||
result = -EPERM;
|
||||
goto uc_timeout;
|
||||
}
|
||||
}
|
||||
usleep(IPA_UC_POLL_SLEEP_USEC * IPA_UC_POLL_SLEEP_USEC);
|
||||
}
|
||||
|
||||
ipa_write_reg(ipa_ctx->mmio, IPA_IRQ_EE_UC_n_OFFS(0), 0x1);
|
||||
if (wait_for_completion_timeout
|
||||
(&ipa_ctx->uc_ctx.uc_completion, 10*HZ) == 0) {
|
||||
|
@ -1173,6 +1193,13 @@ int ipa_disable_wdi_pipe(u32 clnt_hdl)
|
|||
mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
|
||||
goto uc_timeout;
|
||||
}
|
||||
|
||||
/* Set the delay after disabling IPA Producer pipe */
|
||||
if (IPA_CLIENT_IS_PROD(ep->client)) {
|
||||
memset(&ep_cfg_ctrl, 0, sizeof(struct ipa_ep_cfg_ctrl));
|
||||
ep_cfg_ctrl.ipa_ep_delay = true;
|
||||
ipa_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl);
|
||||
}
|
||||
mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
|
||||
|
||||
ipa_dec_client_disable_clks();
|
||||
|
@ -1302,6 +1329,31 @@ int ipa_suspend_wdi_pipe(u32 clnt_hdl)
|
|||
init_completion(&ipa_ctx->uc_ctx.uc_completion);
|
||||
ipa_ctx->uc_ctx.pending_cmd = ipa_ctx->uc_ctx.uc_sram_mmio->cmdOp;
|
||||
wmb();
|
||||
|
||||
if (IPA_CLIENT_IS_PROD(ep->client)) {
|
||||
IPADBG("Post suspend event first for IPA Producer\n");
|
||||
IPADBG("Client: %d clnt_hdl: %d\n", ep->client, clnt_hdl);
|
||||
ipa_write_reg(ipa_ctx->mmio, IPA_IRQ_EE_UC_n_OFFS(0), 0x1);
|
||||
if (wait_for_completion_timeout
|
||||
(&ipa_ctx->uc_ctx.uc_completion,
|
||||
10 * HZ) == 0) {
|
||||
IPAERR("uc timed out on suspend ep=%d.\n",
|
||||
clnt_hdl);
|
||||
result = -EFAULT;
|
||||
ipa_ctx->uc_ctx.uc_failed = true;
|
||||
mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
|
||||
goto uc_timeout;
|
||||
}
|
||||
if (ipa_ctx->uc_ctx.uc_status !=
|
||||
IPA_HW_2_CPU_WDI_CMD_STATUS_SUCCESS) {
|
||||
IPAERR("cmd failed on suspend ep=%d status=%d.\n",
|
||||
clnt_hdl, ipa_ctx->uc_ctx.uc_status);
|
||||
result = -EFAULT;
|
||||
mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
|
||||
goto uc_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl));
|
||||
if (IPA_CLIENT_IS_CONS(ep->client)) {
|
||||
ep_cfg_ctrl.ipa_ep_suspend = true;
|
||||
|
@ -1320,22 +1372,27 @@ int ipa_suspend_wdi_pipe(u32 clnt_hdl)
|
|||
else
|
||||
IPADBG("client (ep: %d) delayed\n", clnt_hdl);
|
||||
}
|
||||
ipa_write_reg(ipa_ctx->mmio, IPA_IRQ_EE_UC_n_OFFS(0), 0x1);
|
||||
if (wait_for_completion_timeout
|
||||
(&ipa_ctx->uc_ctx.uc_completion, 10*HZ) == 0) {
|
||||
IPAERR("uc timed out on suspend ep=%d.\n", clnt_hdl);
|
||||
result = -EFAULT;
|
||||
ipa_ctx->uc_ctx.uc_failed = true;
|
||||
mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
|
||||
goto uc_timeout;
|
||||
}
|
||||
if (ipa_ctx->uc_ctx.uc_status != IPA_HW_2_CPU_WDI_CMD_STATUS_SUCCESS) {
|
||||
IPAERR("cmd failed on suspend ep=%d status=%d.\n", clnt_hdl,
|
||||
ipa_ctx->uc_ctx.uc_status);
|
||||
result = -EFAULT;
|
||||
mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
|
||||
goto uc_timeout;
|
||||
|
||||
if (IPA_CLIENT_IS_CONS(ep->client)) {
|
||||
ipa_write_reg(ipa_ctx->mmio, IPA_IRQ_EE_UC_n_OFFS(0), 0x1);
|
||||
if (wait_for_completion_timeout
|
||||
(&ipa_ctx->uc_ctx.uc_completion, 10*HZ) == 0) {
|
||||
IPAERR("uc timed out on suspend ep=%d.\n", clnt_hdl);
|
||||
result = -EFAULT;
|
||||
ipa_ctx->uc_ctx.uc_failed = true;
|
||||
mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
|
||||
goto uc_timeout;
|
||||
}
|
||||
if (ipa_ctx->uc_ctx.uc_status !=
|
||||
IPA_HW_2_CPU_WDI_CMD_STATUS_SUCCESS) {
|
||||
IPAERR("cmd failed on suspend ep=%d status=%d.\n",
|
||||
clnt_hdl, ipa_ctx->uc_ctx.uc_status);
|
||||
result = -EFAULT;
|
||||
mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
|
||||
goto uc_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&ipa_ctx->uc_ctx.uc_lock);
|
||||
|
||||
ipa_ctx->tag_process_before_gating = true;
|
||||
|
|
Loading…
Reference in a new issue