Loading drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c +12 −8 Original line number Diff line number Diff line Loading @@ -2119,6 +2119,15 @@ int ipa_mhi_suspend(bool force) IPA_MHI_ERR("ipa_mhi_set_state failed %d\n", res); return res; } res = ipa_mhi_suspend_dl(force); if (res) { IPA_MHI_ERR("ipa_mhi_suspend_dl failed %d\n", res); goto fail_suspend_dl_channel; } usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN, IPA_MHI_SUSPEND_SLEEP_MAX); res = ipa_mhi_suspend_ul(force, &empty, &force_clear); if (res) { IPA_MHI_ERR("ipa_mhi_suspend_ul failed %d\n", res); Loading Loading @@ -2147,12 +2156,6 @@ int ipa_mhi_suspend(bool force) usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN, IPA_MHI_SUSPEND_SLEEP_MAX); res = ipa_mhi_suspend_dl(force); if (res) { IPA_MHI_ERR("ipa_mhi_suspend_dl failed %d\n", res); goto fail_suspend_dl_channel; } if (!empty) ipa_set_tag_process_before_gating(false); Loading @@ -2166,14 +2169,12 @@ int ipa_mhi_suspend(bool force) IPA_MHI_FUNC_EXIT(); return 0; fail_suspend_dl_channel: fail_release_cons: ipa_mhi_request_prod(); fail_release_prod: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); fail_suspend_ul_channel: ipa_mhi_resume_channels(true, ipa_mhi_client_ctx->ul_channels); ipa_mhi_set_state(IPA_MHI_STATE_STARTED); if (force_clear) { if ( ipa_mhi_disable_force_clear(ipa_mhi_client_ctx->qmi_req_id)) { Loading @@ -2183,6 +2184,9 @@ fail_suspend_ul_channel: IPA_MHI_DBG("force clear datapath disabled\n"); ipa_mhi_client_ctx->qmi_req_id++; } fail_suspend_dl_channel: ipa_mhi_resume_channels(true, ipa_mhi_client_ctx->dl_channels); ipa_mhi_set_state(IPA_MHI_STATE_STARTED); return res; } Loading drivers/platform/msm/ipa/ipa_v3/ipa.c +8 −2 Original line number Diff line number Diff line Loading @@ -2608,6 +2608,9 @@ void ipa3_q6_pre_shutdown_cleanup(void) ipa3_q6_pipe_delay(true); ipa3_q6_avoid_holb(); if (ipa3_ctx->ipa_config_is_mhi) ipa3_set_reset_client_cons_pipe_sus_holb(true, IPA_CLIENT_MHI_CONS); if (ipa3_q6_clean_q6_tables()) { IPAERR("Failed to clean Q6 tables\n"); BUG(); Loading @@ -2620,8 +2623,11 @@ void ipa3_q6_pre_shutdown_cleanup(void) * on pipe reset procedure */ ipa3_q6_pipe_delay(false); ipa3_set_usb_prod_pipe_delay(); ipa3_set_reset_client_prod_pipe_delay(true, IPA_CLIENT_USB_PROD); if (ipa3_ctx->ipa_config_is_mhi) ipa3_set_reset_client_prod_pipe_delay(true, IPA_CLIENT_MHI_PROD); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG_LOW("Exit with success\n"); Loading drivers/platform/msm/ipa/ipa_v3/ipa_client.c +65 −7 Original line number Diff line number Diff line Loading @@ -1848,27 +1848,32 @@ exit: } /* * Set USB PROD pipe delay for MBIM/RMNET config * Set reset eo_deay for CLEINT PROD pipe * Clocks, should be voted before calling this API * locks should be taken before calling this API */ void ipa3_set_usb_prod_pipe_delay(void) int ipa3_set_reset_client_prod_pipe_delay(bool set_reset, enum ipa_client_type client) { int result; int result = 0; int pipe_idx; struct ipa3_ep_context *ep; struct ipa_ep_cfg_ctrl ep_ctrl; memset(&ep_ctrl, 0, sizeof(struct ipa_ep_cfg_ctrl)); ep_ctrl.ipa_ep_delay = true; ep_ctrl.ipa_ep_delay = set_reset; if (IPA_CLIENT_IS_CONS(client)) { IPAERR("client (%d) not PROD\n", client); return -EINVAL; } pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD); pipe_idx = ipa3_get_ep_mapping(client); if (pipe_idx == IPA_EP_NOT_ALLOCATED) { IPAERR("client (%d) not valid\n", IPA_CLIENT_USB_PROD); return; IPAERR("client (%d) not valid\n", client); return -EINVAL; } ep = &ipa3_ctx->ep[pipe_idx]; Loading @@ -1885,6 +1890,59 @@ void ipa3_set_usb_prod_pipe_delay(void) IPADBG("client (ep: %d) success\n", pipe_idx); } client_lock_unlock_cb(pipe_idx, false); return result; } int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset, enum ipa_client_type client) { int pipe_idx; struct ipa3_ep_context *ep; struct ipa_ep_cfg_ctrl ep_suspend; struct ipa_ep_cfg_holb ep_holb; memset(&ep_suspend, 0, sizeof(ep_suspend)); memset(&ep_holb, 0, sizeof(ep_holb)); ep_suspend.ipa_ep_suspend = set_reset; ep_holb.tmr_val = 0; ep_holb.en = set_reset; if (IPA_CLIENT_IS_PROD(client)) { IPAERR("client (%d) not CONS\n", client); return -EINVAL; } pipe_idx = ipa3_get_ep_mapping(client); if (pipe_idx == IPA_EP_NOT_ALLOCATED) { IPAERR("client (%d) not valid\n", client); return -EINVAL; } ep = &ipa3_ctx->ep[pipe_idx]; /* Setting sus/holb on MHI_CONS with skip_ep_cfg */ client_lock_unlock_cb(pipe_idx, true); if (ep->valid && ep->skip_ep_cfg) { if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) ipahal_write_reg_n_fields( IPA_ENDP_INIT_CTRL_n, pipe_idx, &ep_suspend); /* * ipa3_cfg_ep_holb is not used here because we are * setting HOLB on Q6 pipes, and from APPS perspective * they are not valid, therefore, the above function * will fail. */ ipahal_write_reg_n_fields( IPA_ENDP_INIT_HOL_BLOCK_TIMER_n, pipe_idx, &ep_holb); ipahal_write_reg_n_fields( IPA_ENDP_INIT_HOL_BLOCK_EN_n, pipe_idx, &ep_holb); } client_lock_unlock_cb(pipe_idx, false); return 0; } void ipa3_xdci_ep_delay_rm(u32 clnt_hdl) Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +4 −1 Original line number Diff line number Diff line Loading @@ -1544,7 +1544,10 @@ int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id); void ipa3_xdci_ep_delay_rm(u32 clnt_hdl); void ipa3_register_lock_unlock_callback(int (*client_cb)(bool), u32 ipa_ep_idx); void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx); void ipa3_set_usb_prod_pipe_delay(void); int ipa3_set_reset_client_prod_pipe_delay(bool set_reset, enum ipa_client_type client); int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset, enum ipa_client_type client); int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, bool should_force_clear, u32 qmi_req_id, bool is_dpl); Loading drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c +33 −0 Original line number Diff line number Diff line Loading @@ -198,6 +198,7 @@ static int ipa_mhi_start_gsi_channel(enum ipa_client_type client, union __packed gsi_channel_scratch ch_scratch; struct ipa3_ep_context *ep; const struct ipa_gsi_ep_config *ep_cfg; struct ipa_ep_cfg_ctrl ep_cfg_ctrl; IPA_MHI_FUNC_ENTRY(); Loading Loading @@ -323,6 +324,20 @@ static int ipa_mhi_start_gsi_channel(enum ipa_client_type client, *params->mhi = ch_scratch.mhi; if (IPA_CLIENT_IS_PROD(ep->client) && ep->skip_ep_cfg) { memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = true; ep->ep_delay_set = true; res = ipa3_cfg_ep_ctrl(ipa_ep_idx, &ep_cfg_ctrl); if (res) IPA_MHI_ERR("client (ep: %d) failed result=%d\n", ipa_ep_idx, res); else IPA_MHI_DBG("client (ep: %d) success\n", ipa_ep_idx); } else { ep->ep_delay_set = false; } IPA_MHI_DBG("Starting channel\n"); res = gsi_start_channel(ep->gsi_chan_hdl); if (res) { Loading Loading @@ -496,6 +511,7 @@ int ipa3_disconnect_mhi_pipe(u32 clnt_hdl) { struct ipa3_ep_context *ep; int res; struct ipa_ep_cfg_ctrl ep_cfg_ctrl; IPA_MHI_FUNC_ENTRY(); Loading @@ -510,6 +526,23 @@ int ipa3_disconnect_mhi_pipe(u32 clnt_hdl) } ep = &ipa3_ctx->ep[clnt_hdl]; IPA_MHI_ERR("Debug --> Remove ep_delay start"); if (ep->ep_delay_set == true) { memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = false; res = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl); if (res) { IPAERR ("client(ep:%d) failed to remove delay res=%d\n", clnt_hdl, res); } else { IPADBG("client (ep: %d) delay removed\n", clnt_hdl); ep->ep_delay_set = false; } } IPA_MHI_ERR("Debug --> Remov ep_delay end"); if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) { res = gsi_dealloc_channel(ep->gsi_chan_hdl); Loading Loading
drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c +12 −8 Original line number Diff line number Diff line Loading @@ -2119,6 +2119,15 @@ int ipa_mhi_suspend(bool force) IPA_MHI_ERR("ipa_mhi_set_state failed %d\n", res); return res; } res = ipa_mhi_suspend_dl(force); if (res) { IPA_MHI_ERR("ipa_mhi_suspend_dl failed %d\n", res); goto fail_suspend_dl_channel; } usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN, IPA_MHI_SUSPEND_SLEEP_MAX); res = ipa_mhi_suspend_ul(force, &empty, &force_clear); if (res) { IPA_MHI_ERR("ipa_mhi_suspend_ul failed %d\n", res); Loading Loading @@ -2147,12 +2156,6 @@ int ipa_mhi_suspend(bool force) usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN, IPA_MHI_SUSPEND_SLEEP_MAX); res = ipa_mhi_suspend_dl(force); if (res) { IPA_MHI_ERR("ipa_mhi_suspend_dl failed %d\n", res); goto fail_suspend_dl_channel; } if (!empty) ipa_set_tag_process_before_gating(false); Loading @@ -2166,14 +2169,12 @@ int ipa_mhi_suspend(bool force) IPA_MHI_FUNC_EXIT(); return 0; fail_suspend_dl_channel: fail_release_cons: ipa_mhi_request_prod(); fail_release_prod: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); fail_suspend_ul_channel: ipa_mhi_resume_channels(true, ipa_mhi_client_ctx->ul_channels); ipa_mhi_set_state(IPA_MHI_STATE_STARTED); if (force_clear) { if ( ipa_mhi_disable_force_clear(ipa_mhi_client_ctx->qmi_req_id)) { Loading @@ -2183,6 +2184,9 @@ fail_suspend_ul_channel: IPA_MHI_DBG("force clear datapath disabled\n"); ipa_mhi_client_ctx->qmi_req_id++; } fail_suspend_dl_channel: ipa_mhi_resume_channels(true, ipa_mhi_client_ctx->dl_channels); ipa_mhi_set_state(IPA_MHI_STATE_STARTED); return res; } Loading
drivers/platform/msm/ipa/ipa_v3/ipa.c +8 −2 Original line number Diff line number Diff line Loading @@ -2608,6 +2608,9 @@ void ipa3_q6_pre_shutdown_cleanup(void) ipa3_q6_pipe_delay(true); ipa3_q6_avoid_holb(); if (ipa3_ctx->ipa_config_is_mhi) ipa3_set_reset_client_cons_pipe_sus_holb(true, IPA_CLIENT_MHI_CONS); if (ipa3_q6_clean_q6_tables()) { IPAERR("Failed to clean Q6 tables\n"); BUG(); Loading @@ -2620,8 +2623,11 @@ void ipa3_q6_pre_shutdown_cleanup(void) * on pipe reset procedure */ ipa3_q6_pipe_delay(false); ipa3_set_usb_prod_pipe_delay(); ipa3_set_reset_client_prod_pipe_delay(true, IPA_CLIENT_USB_PROD); if (ipa3_ctx->ipa_config_is_mhi) ipa3_set_reset_client_prod_pipe_delay(true, IPA_CLIENT_MHI_PROD); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG_LOW("Exit with success\n"); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_client.c +65 −7 Original line number Diff line number Diff line Loading @@ -1848,27 +1848,32 @@ exit: } /* * Set USB PROD pipe delay for MBIM/RMNET config * Set reset eo_deay for CLEINT PROD pipe * Clocks, should be voted before calling this API * locks should be taken before calling this API */ void ipa3_set_usb_prod_pipe_delay(void) int ipa3_set_reset_client_prod_pipe_delay(bool set_reset, enum ipa_client_type client) { int result; int result = 0; int pipe_idx; struct ipa3_ep_context *ep; struct ipa_ep_cfg_ctrl ep_ctrl; memset(&ep_ctrl, 0, sizeof(struct ipa_ep_cfg_ctrl)); ep_ctrl.ipa_ep_delay = true; ep_ctrl.ipa_ep_delay = set_reset; if (IPA_CLIENT_IS_CONS(client)) { IPAERR("client (%d) not PROD\n", client); return -EINVAL; } pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD); pipe_idx = ipa3_get_ep_mapping(client); if (pipe_idx == IPA_EP_NOT_ALLOCATED) { IPAERR("client (%d) not valid\n", IPA_CLIENT_USB_PROD); return; IPAERR("client (%d) not valid\n", client); return -EINVAL; } ep = &ipa3_ctx->ep[pipe_idx]; Loading @@ -1885,6 +1890,59 @@ void ipa3_set_usb_prod_pipe_delay(void) IPADBG("client (ep: %d) success\n", pipe_idx); } client_lock_unlock_cb(pipe_idx, false); return result; } int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset, enum ipa_client_type client) { int pipe_idx; struct ipa3_ep_context *ep; struct ipa_ep_cfg_ctrl ep_suspend; struct ipa_ep_cfg_holb ep_holb; memset(&ep_suspend, 0, sizeof(ep_suspend)); memset(&ep_holb, 0, sizeof(ep_holb)); ep_suspend.ipa_ep_suspend = set_reset; ep_holb.tmr_val = 0; ep_holb.en = set_reset; if (IPA_CLIENT_IS_PROD(client)) { IPAERR("client (%d) not CONS\n", client); return -EINVAL; } pipe_idx = ipa3_get_ep_mapping(client); if (pipe_idx == IPA_EP_NOT_ALLOCATED) { IPAERR("client (%d) not valid\n", client); return -EINVAL; } ep = &ipa3_ctx->ep[pipe_idx]; /* Setting sus/holb on MHI_CONS with skip_ep_cfg */ client_lock_unlock_cb(pipe_idx, true); if (ep->valid && ep->skip_ep_cfg) { if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) ipahal_write_reg_n_fields( IPA_ENDP_INIT_CTRL_n, pipe_idx, &ep_suspend); /* * ipa3_cfg_ep_holb is not used here because we are * setting HOLB on Q6 pipes, and from APPS perspective * they are not valid, therefore, the above function * will fail. */ ipahal_write_reg_n_fields( IPA_ENDP_INIT_HOL_BLOCK_TIMER_n, pipe_idx, &ep_holb); ipahal_write_reg_n_fields( IPA_ENDP_INIT_HOL_BLOCK_EN_n, pipe_idx, &ep_holb); } client_lock_unlock_cb(pipe_idx, false); return 0; } void ipa3_xdci_ep_delay_rm(u32 clnt_hdl) Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +4 −1 Original line number Diff line number Diff line Loading @@ -1544,7 +1544,10 @@ int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id); void ipa3_xdci_ep_delay_rm(u32 clnt_hdl); void ipa3_register_lock_unlock_callback(int (*client_cb)(bool), u32 ipa_ep_idx); void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx); void ipa3_set_usb_prod_pipe_delay(void); int ipa3_set_reset_client_prod_pipe_delay(bool set_reset, enum ipa_client_type client); int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset, enum ipa_client_type client); int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl, bool should_force_clear, u32 qmi_req_id, bool is_dpl); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c +33 −0 Original line number Diff line number Diff line Loading @@ -198,6 +198,7 @@ static int ipa_mhi_start_gsi_channel(enum ipa_client_type client, union __packed gsi_channel_scratch ch_scratch; struct ipa3_ep_context *ep; const struct ipa_gsi_ep_config *ep_cfg; struct ipa_ep_cfg_ctrl ep_cfg_ctrl; IPA_MHI_FUNC_ENTRY(); Loading Loading @@ -323,6 +324,20 @@ static int ipa_mhi_start_gsi_channel(enum ipa_client_type client, *params->mhi = ch_scratch.mhi; if (IPA_CLIENT_IS_PROD(ep->client) && ep->skip_ep_cfg) { memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = true; ep->ep_delay_set = true; res = ipa3_cfg_ep_ctrl(ipa_ep_idx, &ep_cfg_ctrl); if (res) IPA_MHI_ERR("client (ep: %d) failed result=%d\n", ipa_ep_idx, res); else IPA_MHI_DBG("client (ep: %d) success\n", ipa_ep_idx); } else { ep->ep_delay_set = false; } IPA_MHI_DBG("Starting channel\n"); res = gsi_start_channel(ep->gsi_chan_hdl); if (res) { Loading Loading @@ -496,6 +511,7 @@ int ipa3_disconnect_mhi_pipe(u32 clnt_hdl) { struct ipa3_ep_context *ep; int res; struct ipa_ep_cfg_ctrl ep_cfg_ctrl; IPA_MHI_FUNC_ENTRY(); Loading @@ -510,6 +526,23 @@ int ipa3_disconnect_mhi_pipe(u32 clnt_hdl) } ep = &ipa3_ctx->ep[clnt_hdl]; IPA_MHI_ERR("Debug --> Remove ep_delay start"); if (ep->ep_delay_set == true) { memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl)); ep_cfg_ctrl.ipa_ep_delay = false; res = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl); if (res) { IPAERR ("client(ep:%d) failed to remove delay res=%d\n", clnt_hdl, res); } else { IPADBG("client (ep: %d) delay removed\n", clnt_hdl); ep->ep_delay_set = false; } } IPA_MHI_ERR("Debug --> Remov ep_delay end"); if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) { res = gsi_dealloc_channel(ep->gsi_chan_hdl); Loading