Loading drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +96 −39 Original line number Original line Diff line number Diff line Loading @@ -421,7 +421,7 @@ static void ipa_mpm_change_gsi_state(int probe_id, enum ipa_mpm_gsi_state next_state); enum ipa_mpm_gsi_state next_state); static int ipa_mpm_probe(struct platform_device *pdev); static int ipa_mpm_probe(struct platform_device *pdev); static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, int probe_id); int probe_id, bool is_force, bool *is_acted); static void ipa_mpm_vote_unvote_ipa_clk(enum ipa_mpm_clk_vote_type vote, static void ipa_mpm_vote_unvote_ipa_clk(enum ipa_mpm_clk_vote_type vote, int probe_id); int probe_id); static enum mhip_status_type ipa_mpm_start_stop_mhip_chan( static enum mhip_status_type ipa_mpm_start_stop_mhip_chan( Loading Loading @@ -1365,12 +1365,20 @@ static void ipa_mpm_mhip_shutdown(int mhip_idx) IPA_MPM_FUNC_EXIT(); IPA_MPM_FUNC_EXIT(); } } /* /** * Turning on/OFF PCIE Clock is done once for all clients. * @ipa_mpm_vote_unvote_pcie_clk - Vote/Unvote PCIe Clock per probe_id * Always vote for Probe_ID 0 as a standard. * Returns if success or failure. * @ipa_mpm_clk_vote_type - Vote or Unvote for PCIe Clock * @probe_id - MHI probe_id per client. * @is_force - Forcebly casts vote - should be true only in probe. * @is_acted - Output param - This indicates the clk is actually voted or not * The flag output is checked only when we vote for clocks. * Return value: PCIe clock voting is success or failure. */ */ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, int probe_id) int probe_id, bool is_force, bool *is_acted) { { int result = 0; int result = 0; Loading @@ -1384,20 +1392,27 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, return -EINVAL; return -EINVAL; } } if (!is_acted) { IPA_MPM_ERR("Invalid clk_vote ptr\n"); return -EFAULT; } mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); if (ipa_mpm_ctx->md[probe_id].mhi_dev == NULL) { if (ipa_mpm_ctx->md[probe_id].mhi_dev == NULL) { IPA_MPM_ERR("MHI not initialized yet\n"); IPA_MPM_ERR("MHI not initialized yet\n"); *is_acted = false; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return 0; return 0; } } if (!ipa_mpm_ctx->md[probe_id].init_complete) { if (!ipa_mpm_ctx->md[probe_id].init_complete && !is_force) { /* /* * SSR might be in progress, dont have to vote/unvote for * SSR might be in progress, dont have to vote/unvote for * IPA clocks as it will be taken care in remove_cb/subsequent * IPA clocks as it will be taken care in remove_cb/subsequent * probe. * probe. */ */ IPA_MPM_DBG("SSR in progress, return\n"); IPA_MPM_DBG("SSR in progress, return\n"); *is_acted = false; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return 0; return 0; } } Loading @@ -1413,6 +1428,7 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, if (result) { if (result) { IPA_MPM_ERR("mhi_sync_get failed for probe_id %d\n", IPA_MPM_ERR("mhi_sync_get failed for probe_id %d\n", result, probe_id); result, probe_id); *is_acted = false; return result; return result; } } Loading @@ -1433,6 +1449,7 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, atomic_dec(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt); atomic_dec(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt); atomic_dec(&ipa_mpm_ctx->pcie_clk_total_cnt); atomic_dec(&ipa_mpm_ctx->pcie_clk_total_cnt); } } *is_acted = true; return result; return result; } } Loading Loading @@ -1637,6 +1654,7 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) static enum mhip_status_type status; static enum mhip_status_type status; int ret = 0; int ret = 0; enum ipa_mpm_mhip_client_type mhip_client = IPA_MPM_MHIP_TETH; enum ipa_mpm_mhip_client_type mhip_client = IPA_MPM_MHIP_TETH; bool is_acted = true; if (!state) if (!state) return -EPERM; return -EPERM; Loading @@ -1660,10 +1678,10 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) if (state->up) { if (state->up) { /* Start UL MHIP channel for offloading tethering connection */ /* Start UL MHIP channel for offloading tethering connection */ ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", IPA_MPM_ERR("Err %d cloking on PCIe clk %d\n", ret); ret); return ret; return ret; } } status = ipa_mpm_start_stop_mhip_chan( status = ipa_mpm_start_stop_mhip_chan( Loading @@ -1677,18 +1695,24 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) case MHIP_STATUS_NO_OP: case MHIP_STATUS_NO_OP: IPA_MPM_DBG("UL chan already start, status = %d\n", IPA_MPM_DBG("UL chan already start, status = %d\n", status); status); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) return ret; return ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); break; case MHIP_STATUS_FAIL: case MHIP_STATUS_FAIL: case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_EP_NOT_FOUND: case MHIP_STATUS_EP_NOT_FOUND: IPA_MPM_ERR("UL chan start err =%d\n", status); IPA_MPM_ERR("UL chan start err =%d\n", status); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); ipa_assert(); ipa_assert(); return -EFAULT; return -EFAULT; default: default: IPA_MPM_ERR("Err not found\n"); IPA_MPM_ERR("Err not found\n"); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); ret = -EFAULT; ret = -EFAULT; break; break; } } Loading Loading @@ -1718,7 +1742,8 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) return -EFAULT; return -EFAULT; } } /* Stop UL MHIP channel for offloading tethering connection */ /* Stop UL MHIP channel for offloading tethering connection */ ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", Loading Loading @@ -1829,6 +1854,7 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, u32 evt_ring_db_addr_low, evt_ring_db_addr_high; u32 evt_ring_db_addr_low, evt_ring_db_addr_high; u32 wp_addr; u32 wp_addr; int pipe_idx; int pipe_idx; bool is_acted = true; IPA_MPM_FUNC_ENTRY(); IPA_MPM_FUNC_ENTRY(); Loading Loading @@ -1864,7 +1890,12 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, ipa_mpm_ctx->mhi_parent_dev = ipa_mpm_ctx->mhi_parent_dev = ipa_mpm_ctx->md[probe_id].mhi_dev->dev.parent; ipa_mpm_ctx->md[probe_id].mhi_dev->dev.parent; ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id, true, &is_acted); if (ret) { IPA_MPM_ERR("Err %d voitng PCIe clocks\n", ret); return -EPERM; } ipa_mpm_vote_unvote_ipa_clk(CLK_ON, probe_id); ipa_mpm_vote_unvote_ipa_clk(CLK_ON, probe_id); ipa_mpm_ctx->md[probe_id].in_lpm = false; ipa_mpm_ctx->md[probe_id].in_lpm = false; IPA_MPM_DBG("ul chan = %d, dl_chan = %d\n", ul_prod, dl_cons); IPA_MPM_DBG("ul chan = %d, dl_chan = %d\n", ul_prod, dl_cons); Loading Loading @@ -2159,7 +2190,9 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, ipa_mpm_start_stop_mhip_chan(IPA_MPM_MHIP_CHAN_UL, ipa_mpm_start_stop_mhip_chan(IPA_MPM_MHIP_CHAN_UL, probe_id, MPM_MHIP_STOP); probe_id, MPM_MHIP_STOP); } } ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, true, &is_acted); break; break; case IPA_MPM_TETH_INPROGRESS: case IPA_MPM_TETH_INPROGRESS: case IPA_MPM_TETH_CONNECTED: case IPA_MPM_TETH_CONNECTED: Loading Loading @@ -2198,7 +2231,9 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, fail_smmu: fail_smmu: if (ipa_mpm_ctx->dev_info.ipa_smmu_enabled) if (ipa_mpm_ctx->dev_info.ipa_smmu_enabled) IPA_MPM_DBG("SMMU failed\n"); IPA_MPM_DBG("SMMU failed\n"); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, true, &is_acted); ipa_mpm_vote_unvote_ipa_clk(CLK_OFF, probe_id); ipa_mpm_vote_unvote_ipa_clk(CLK_OFF, probe_id); ipa_assert(); ipa_assert(); return ret; return ret; Loading Loading @@ -2374,8 +2409,9 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) int i; int i; enum ipa_mpm_mhip_client_type mhip_client; enum ipa_mpm_mhip_client_type mhip_client; enum mhip_status_type status; enum mhip_status_type status; int ret = 0; int pipe_idx; int pipe_idx; bool is_acted = true; int ret = 0; if (ipa_mpm_ctx == NULL) { if (ipa_mpm_ctx == NULL) { IPA_MPM_ERR("MPM not platform probed yet, returning ..\n"); IPA_MPM_ERR("MPM not platform probed yet, returning ..\n"); Loading @@ -2401,7 +2437,8 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) ipa_mpm_ctx->md[probe_id].mhip_client = mhip_client; ipa_mpm_ctx->md[probe_id].mhip_client = mhip_client; ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", ret); IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", ret); return ret; return ret; Loading @@ -2419,12 +2456,16 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) return 0; return 0; default: default: IPA_MPM_DBG("mhip_client = %d not processed\n", mhip_client); IPA_MPM_DBG("mhip_client = %d not processed\n", mhip_client); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) { ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error unvoting on PCIe clk, err = %d\n", IPA_MPM_ERR("Err %d unvoting on PCIe clk\n", ret); ret); return ret; return ret; } } } return 0; return 0; } } Loading @@ -2442,26 +2483,33 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) /* Lift the delay for rmnet USB prod pipe */ /* Lift the delay for rmnet USB prod pipe */ ipa3_xdci_ep_delay_rm(pipe_idx); ipa3_xdci_ep_delay_rm(pipe_idx); if (status == MHIP_STATUS_NO_OP) { if (status == MHIP_STATUS_NO_OP && is_acted) { /* Channels already have been started, /* Channels already have been started, * we can devote for pcie clocks * we can devote for pcie clocks */ */ ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); } } break; break; case MHIP_STATUS_EP_NOT_READY: case MHIP_STATUS_EP_NOT_READY: ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INPROGRESS); ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INPROGRESS); break; break; case MHIP_STATUS_FAIL: case MHIP_STATUS_FAIL: case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_EP_NOT_FOUND: case MHIP_STATUS_EP_NOT_FOUND: IPA_MPM_ERR("UL chan cant be started err =%d\n", status); IPA_MPM_ERR("UL chan cant be started err =%d\n", status); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); ret = -EFAULT; ret = -EFAULT; break; break; default: default: ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); IPA_MPM_ERR("Err not found\n"); IPA_MPM_ERR("Err not found\n"); break; break; } } Loading @@ -2474,6 +2522,7 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot) int i; int i; enum ipa_mpm_mhip_client_type mhip_client; enum ipa_mpm_mhip_client_type mhip_client; enum mhip_status_type status; enum mhip_status_type status; bool is_acted = true; int ret = 0; int ret = 0; if (ipa_mpm_ctx == NULL) { if (ipa_mpm_ctx == NULL) { Loading Loading @@ -2519,7 +2568,8 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot) ipa_mpm_ctx->md[probe_id].mhip_client = ipa_mpm_ctx->md[probe_id].mhip_client = IPA_MPM_MHIP_NONE; IPA_MPM_MHIP_NONE; } } ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); if (ret) if (ret) IPA_MPM_ERR("Error clking off PCIe clk err%d\n", ret); IPA_MPM_ERR("Error clking off PCIe clk err%d\n", ret); atomic_set(&ipa_mpm_ctx->adpl_over_usb_available, 0); atomic_set(&ipa_mpm_ctx->adpl_over_usb_available, 0); Loading @@ -2542,7 +2592,8 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot) case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_EP_NOT_FOUND: case MHIP_STATUS_EP_NOT_FOUND: IPA_MPM_ERR("UL chan cant be started err =%d\n", status); IPA_MPM_ERR("UL chan cant be started err =%d\n", status); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); return -EFAULT; return -EFAULT; break; break; default: default: Loading @@ -2550,7 +2601,8 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot) break; break; } } ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking off PCIe clk, err = %d\n", ret); IPA_MPM_ERR("Error cloking off PCIe clk, err = %d\n", ret); Loading Loading @@ -2842,6 +2894,7 @@ int ipa3_get_mhip_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) int ipa3_mpm_enable_adpl_over_odl(bool enable) int ipa3_mpm_enable_adpl_over_odl(bool enable) { { int ret; int ret; bool is_acted = true; IPA_MPM_FUNC_ENTRY(); IPA_MPM_FUNC_ENTRY(); Loading @@ -2855,10 +2908,9 @@ int ipa3_mpm_enable_adpl_over_odl(bool enable) IPA_MPM_DBG("mpm enabling ADPL over ODL\n"); IPA_MPM_DBG("mpm enabling ADPL over ODL\n"); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, IPA_MPM_MHIP_CH_ID_2); IPA_MPM_MHIP_CH_ID_2, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", IPA_MPM_ERR("Err %d cloking on PCIe clk\n", ret); ret); return ret; return ret; } } Loading @@ -2866,8 +2918,11 @@ int ipa3_mpm_enable_adpl_over_odl(bool enable) IPA_CLIENT_ODL_DPL_CONS, false); IPA_CLIENT_ODL_DPL_CONS, false); if (ret) { if (ret) { IPA_MPM_ERR("MPM failed to set dma mode to ODL\n"); IPA_MPM_ERR("MPM failed to set dma mode to ODL\n"); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, IPA_MPM_MHIP_CH_ID_2); IPA_MPM_MHIP_CH_ID_2, false, &is_acted); return ret; return ret; } } Loading @@ -2878,7 +2933,7 @@ int ipa3_mpm_enable_adpl_over_odl(bool enable) IPA_MPM_DBG("mpm disabling ADPL over ODL\n"); IPA_MPM_DBG("mpm disabling ADPL over ODL\n"); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, IPA_MPM_MHIP_CH_ID_2); IPA_MPM_MHIP_CH_ID_2, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking off PCIe clk, err = %d\n", IPA_MPM_ERR("Error cloking off PCIe clk, err = %d\n", ret); ret); Loading @@ -2889,8 +2944,10 @@ int ipa3_mpm_enable_adpl_over_odl(bool enable) IPA_CLIENT_USB_DPL_CONS, false); IPA_CLIENT_USB_DPL_CONS, false); if (ret) { if (ret) { IPA_MPM_ERR("MPM failed to set dma mode to USB\n"); IPA_MPM_ERR("MPM failed to set dma mode to USB\n"); ipa_mpm_vote_unvote_pcie_clk(CLK_ON, if (ipa_mpm_vote_unvote_pcie_clk(CLK_ON, IPA_MPM_MHIP_CH_ID_2); IPA_MPM_MHIP_CH_ID_2, false, &is_acted)) IPA_MPM_ERR("Err clocking on pcie\n"); return ret; return ret; } } Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +96 −39 Original line number Original line Diff line number Diff line Loading @@ -421,7 +421,7 @@ static void ipa_mpm_change_gsi_state(int probe_id, enum ipa_mpm_gsi_state next_state); enum ipa_mpm_gsi_state next_state); static int ipa_mpm_probe(struct platform_device *pdev); static int ipa_mpm_probe(struct platform_device *pdev); static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, int probe_id); int probe_id, bool is_force, bool *is_acted); static void ipa_mpm_vote_unvote_ipa_clk(enum ipa_mpm_clk_vote_type vote, static void ipa_mpm_vote_unvote_ipa_clk(enum ipa_mpm_clk_vote_type vote, int probe_id); int probe_id); static enum mhip_status_type ipa_mpm_start_stop_mhip_chan( static enum mhip_status_type ipa_mpm_start_stop_mhip_chan( Loading Loading @@ -1365,12 +1365,20 @@ static void ipa_mpm_mhip_shutdown(int mhip_idx) IPA_MPM_FUNC_EXIT(); IPA_MPM_FUNC_EXIT(); } } /* /** * Turning on/OFF PCIE Clock is done once for all clients. * @ipa_mpm_vote_unvote_pcie_clk - Vote/Unvote PCIe Clock per probe_id * Always vote for Probe_ID 0 as a standard. * Returns if success or failure. * @ipa_mpm_clk_vote_type - Vote or Unvote for PCIe Clock * @probe_id - MHI probe_id per client. * @is_force - Forcebly casts vote - should be true only in probe. * @is_acted - Output param - This indicates the clk is actually voted or not * The flag output is checked only when we vote for clocks. * Return value: PCIe clock voting is success or failure. */ */ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, int probe_id) int probe_id, bool is_force, bool *is_acted) { { int result = 0; int result = 0; Loading @@ -1384,20 +1392,27 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, return -EINVAL; return -EINVAL; } } if (!is_acted) { IPA_MPM_ERR("Invalid clk_vote ptr\n"); return -EFAULT; } mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); mutex_lock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); if (ipa_mpm_ctx->md[probe_id].mhi_dev == NULL) { if (ipa_mpm_ctx->md[probe_id].mhi_dev == NULL) { IPA_MPM_ERR("MHI not initialized yet\n"); IPA_MPM_ERR("MHI not initialized yet\n"); *is_acted = false; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return 0; return 0; } } if (!ipa_mpm_ctx->md[probe_id].init_complete) { if (!ipa_mpm_ctx->md[probe_id].init_complete && !is_force) { /* /* * SSR might be in progress, dont have to vote/unvote for * SSR might be in progress, dont have to vote/unvote for * IPA clocks as it will be taken care in remove_cb/subsequent * IPA clocks as it will be taken care in remove_cb/subsequent * probe. * probe. */ */ IPA_MPM_DBG("SSR in progress, return\n"); IPA_MPM_DBG("SSR in progress, return\n"); *is_acted = false; mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); mutex_unlock(&ipa_mpm_ctx->md[probe_id].mhi_mutex); return 0; return 0; } } Loading @@ -1413,6 +1428,7 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, if (result) { if (result) { IPA_MPM_ERR("mhi_sync_get failed for probe_id %d\n", IPA_MPM_ERR("mhi_sync_get failed for probe_id %d\n", result, probe_id); result, probe_id); *is_acted = false; return result; return result; } } Loading @@ -1433,6 +1449,7 @@ static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote, atomic_dec(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt); atomic_dec(&ipa_mpm_ctx->md[probe_id].clk_cnt.pcie_clk_cnt); atomic_dec(&ipa_mpm_ctx->pcie_clk_total_cnt); atomic_dec(&ipa_mpm_ctx->pcie_clk_total_cnt); } } *is_acted = true; return result; return result; } } Loading Loading @@ -1637,6 +1654,7 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) static enum mhip_status_type status; static enum mhip_status_type status; int ret = 0; int ret = 0; enum ipa_mpm_mhip_client_type mhip_client = IPA_MPM_MHIP_TETH; enum ipa_mpm_mhip_client_type mhip_client = IPA_MPM_MHIP_TETH; bool is_acted = true; if (!state) if (!state) return -EPERM; return -EPERM; Loading @@ -1660,10 +1678,10 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) if (state->up) { if (state->up) { /* Start UL MHIP channel for offloading tethering connection */ /* Start UL MHIP channel for offloading tethering connection */ ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", IPA_MPM_ERR("Err %d cloking on PCIe clk %d\n", ret); ret); return ret; return ret; } } status = ipa_mpm_start_stop_mhip_chan( status = ipa_mpm_start_stop_mhip_chan( Loading @@ -1677,18 +1695,24 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) case MHIP_STATUS_NO_OP: case MHIP_STATUS_NO_OP: IPA_MPM_DBG("UL chan already start, status = %d\n", IPA_MPM_DBG("UL chan already start, status = %d\n", status); status); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) return ret; return ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); break; case MHIP_STATUS_FAIL: case MHIP_STATUS_FAIL: case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_EP_NOT_FOUND: case MHIP_STATUS_EP_NOT_FOUND: IPA_MPM_ERR("UL chan start err =%d\n", status); IPA_MPM_ERR("UL chan start err =%d\n", status); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); ipa_assert(); ipa_assert(); return -EFAULT; return -EFAULT; default: default: IPA_MPM_ERR("Err not found\n"); IPA_MPM_ERR("Err not found\n"); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); ret = -EFAULT; ret = -EFAULT; break; break; } } Loading Loading @@ -1718,7 +1742,8 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state) return -EFAULT; return -EFAULT; } } /* Stop UL MHIP channel for offloading tethering connection */ /* Stop UL MHIP channel for offloading tethering connection */ ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", Loading Loading @@ -1829,6 +1854,7 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, u32 evt_ring_db_addr_low, evt_ring_db_addr_high; u32 evt_ring_db_addr_low, evt_ring_db_addr_high; u32 wp_addr; u32 wp_addr; int pipe_idx; int pipe_idx; bool is_acted = true; IPA_MPM_FUNC_ENTRY(); IPA_MPM_FUNC_ENTRY(); Loading Loading @@ -1864,7 +1890,12 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, ipa_mpm_ctx->mhi_parent_dev = ipa_mpm_ctx->mhi_parent_dev = ipa_mpm_ctx->md[probe_id].mhi_dev->dev.parent; ipa_mpm_ctx->md[probe_id].mhi_dev->dev.parent; ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id, true, &is_acted); if (ret) { IPA_MPM_ERR("Err %d voitng PCIe clocks\n", ret); return -EPERM; } ipa_mpm_vote_unvote_ipa_clk(CLK_ON, probe_id); ipa_mpm_vote_unvote_ipa_clk(CLK_ON, probe_id); ipa_mpm_ctx->md[probe_id].in_lpm = false; ipa_mpm_ctx->md[probe_id].in_lpm = false; IPA_MPM_DBG("ul chan = %d, dl_chan = %d\n", ul_prod, dl_cons); IPA_MPM_DBG("ul chan = %d, dl_chan = %d\n", ul_prod, dl_cons); Loading Loading @@ -2159,7 +2190,9 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, ipa_mpm_start_stop_mhip_chan(IPA_MPM_MHIP_CHAN_UL, ipa_mpm_start_stop_mhip_chan(IPA_MPM_MHIP_CHAN_UL, probe_id, MPM_MHIP_STOP); probe_id, MPM_MHIP_STOP); } } ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, true, &is_acted); break; break; case IPA_MPM_TETH_INPROGRESS: case IPA_MPM_TETH_INPROGRESS: case IPA_MPM_TETH_CONNECTED: case IPA_MPM_TETH_CONNECTED: Loading Loading @@ -2198,7 +2231,9 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev, fail_smmu: fail_smmu: if (ipa_mpm_ctx->dev_info.ipa_smmu_enabled) if (ipa_mpm_ctx->dev_info.ipa_smmu_enabled) IPA_MPM_DBG("SMMU failed\n"); IPA_MPM_DBG("SMMU failed\n"); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, true, &is_acted); ipa_mpm_vote_unvote_ipa_clk(CLK_OFF, probe_id); ipa_mpm_vote_unvote_ipa_clk(CLK_OFF, probe_id); ipa_assert(); ipa_assert(); return ret; return ret; Loading Loading @@ -2374,8 +2409,9 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) int i; int i; enum ipa_mpm_mhip_client_type mhip_client; enum ipa_mpm_mhip_client_type mhip_client; enum mhip_status_type status; enum mhip_status_type status; int ret = 0; int pipe_idx; int pipe_idx; bool is_acted = true; int ret = 0; if (ipa_mpm_ctx == NULL) { if (ipa_mpm_ctx == NULL) { IPA_MPM_ERR("MPM not platform probed yet, returning ..\n"); IPA_MPM_ERR("MPM not platform probed yet, returning ..\n"); Loading @@ -2401,7 +2437,8 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) ipa_mpm_ctx->md[probe_id].mhip_client = mhip_client; ipa_mpm_ctx->md[probe_id].mhip_client = mhip_client; ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, probe_id, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", ret); IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", ret); return ret; return ret; Loading @@ -2419,12 +2456,16 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) return 0; return 0; default: default: IPA_MPM_DBG("mhip_client = %d not processed\n", mhip_client); IPA_MPM_DBG("mhip_client = %d not processed\n", mhip_client); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) { ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error unvoting on PCIe clk, err = %d\n", IPA_MPM_ERR("Err %d unvoting on PCIe clk\n", ret); ret); return ret; return ret; } } } return 0; return 0; } } Loading @@ -2442,26 +2483,33 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot) /* Lift the delay for rmnet USB prod pipe */ /* Lift the delay for rmnet USB prod pipe */ ipa3_xdci_ep_delay_rm(pipe_idx); ipa3_xdci_ep_delay_rm(pipe_idx); if (status == MHIP_STATUS_NO_OP) { if (status == MHIP_STATUS_NO_OP && is_acted) { /* Channels already have been started, /* Channels already have been started, * we can devote for pcie clocks * we can devote for pcie clocks */ */ ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); } } break; break; case MHIP_STATUS_EP_NOT_READY: case MHIP_STATUS_EP_NOT_READY: ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INPROGRESS); ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INPROGRESS); break; break; case MHIP_STATUS_FAIL: case MHIP_STATUS_FAIL: case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_EP_NOT_FOUND: case MHIP_STATUS_EP_NOT_FOUND: IPA_MPM_ERR("UL chan cant be started err =%d\n", status); IPA_MPM_ERR("UL chan cant be started err =%d\n", status); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); ret = -EFAULT; ret = -EFAULT; break; break; default: default: ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); IPA_MPM_ERR("Err not found\n"); IPA_MPM_ERR("Err not found\n"); break; break; } } Loading @@ -2474,6 +2522,7 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot) int i; int i; enum ipa_mpm_mhip_client_type mhip_client; enum ipa_mpm_mhip_client_type mhip_client; enum mhip_status_type status; enum mhip_status_type status; bool is_acted = true; int ret = 0; int ret = 0; if (ipa_mpm_ctx == NULL) { if (ipa_mpm_ctx == NULL) { Loading Loading @@ -2519,7 +2568,8 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot) ipa_mpm_ctx->md[probe_id].mhip_client = ipa_mpm_ctx->md[probe_id].mhip_client = IPA_MPM_MHIP_NONE; IPA_MPM_MHIP_NONE; } } ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); if (ret) if (ret) IPA_MPM_ERR("Error clking off PCIe clk err%d\n", ret); IPA_MPM_ERR("Error clking off PCIe clk err%d\n", ret); atomic_set(&ipa_mpm_ctx->adpl_over_usb_available, 0); atomic_set(&ipa_mpm_ctx->adpl_over_usb_available, 0); Loading @@ -2542,7 +2592,8 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot) case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_BAD_STATE: case MHIP_STATUS_EP_NOT_FOUND: case MHIP_STATUS_EP_NOT_FOUND: IPA_MPM_ERR("UL chan cant be started err =%d\n", status); IPA_MPM_ERR("UL chan cant be started err =%d\n", status); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); return -EFAULT; return -EFAULT; break; break; default: default: Loading @@ -2550,7 +2601,8 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot) break; break; } } ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking off PCIe clk, err = %d\n", ret); IPA_MPM_ERR("Error cloking off PCIe clk, err = %d\n", ret); Loading Loading @@ -2842,6 +2894,7 @@ int ipa3_get_mhip_gsi_stats(struct ipa3_uc_dbg_ring_stats *stats) int ipa3_mpm_enable_adpl_over_odl(bool enable) int ipa3_mpm_enable_adpl_over_odl(bool enable) { { int ret; int ret; bool is_acted = true; IPA_MPM_FUNC_ENTRY(); IPA_MPM_FUNC_ENTRY(); Loading @@ -2855,10 +2908,9 @@ int ipa3_mpm_enable_adpl_over_odl(bool enable) IPA_MPM_DBG("mpm enabling ADPL over ODL\n"); IPA_MPM_DBG("mpm enabling ADPL over ODL\n"); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, ret = ipa_mpm_vote_unvote_pcie_clk(CLK_ON, IPA_MPM_MHIP_CH_ID_2); IPA_MPM_MHIP_CH_ID_2, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking on PCIe clk, err = %d\n", IPA_MPM_ERR("Err %d cloking on PCIe clk\n", ret); ret); return ret; return ret; } } Loading @@ -2866,8 +2918,11 @@ int ipa3_mpm_enable_adpl_over_odl(bool enable) IPA_CLIENT_ODL_DPL_CONS, false); IPA_CLIENT_ODL_DPL_CONS, false); if (ret) { if (ret) { IPA_MPM_ERR("MPM failed to set dma mode to ODL\n"); IPA_MPM_ERR("MPM failed to set dma mode to ODL\n"); if (is_acted) ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, IPA_MPM_MHIP_CH_ID_2); IPA_MPM_MHIP_CH_ID_2, false, &is_acted); return ret; return ret; } } Loading @@ -2878,7 +2933,7 @@ int ipa3_mpm_enable_adpl_over_odl(bool enable) IPA_MPM_DBG("mpm disabling ADPL over ODL\n"); IPA_MPM_DBG("mpm disabling ADPL over ODL\n"); ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, ret = ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, IPA_MPM_MHIP_CH_ID_2); IPA_MPM_MHIP_CH_ID_2, false, &is_acted); if (ret) { if (ret) { IPA_MPM_ERR("Error cloking off PCIe clk, err = %d\n", IPA_MPM_ERR("Error cloking off PCIe clk, err = %d\n", ret); ret); Loading @@ -2889,8 +2944,10 @@ int ipa3_mpm_enable_adpl_over_odl(bool enable) IPA_CLIENT_USB_DPL_CONS, false); IPA_CLIENT_USB_DPL_CONS, false); if (ret) { if (ret) { IPA_MPM_ERR("MPM failed to set dma mode to USB\n"); IPA_MPM_ERR("MPM failed to set dma mode to USB\n"); ipa_mpm_vote_unvote_pcie_clk(CLK_ON, if (ipa_mpm_vote_unvote_pcie_clk(CLK_ON, IPA_MPM_MHIP_CH_ID_2); IPA_MPM_MHIP_CH_ID_2, false, &is_acted)) IPA_MPM_ERR("Err clocking on pcie\n"); return ret; return ret; } } Loading