Loading drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +18 −15 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include <linux/mutex.h> Loading Loading @@ -1590,6 +1590,17 @@ static int ipa3_usb_xdci_connect_internal( return result; } /* Start MHIP UL channel before starting USB UL channel * DL channel will be started when voting for PCIe -> LPM Exit. */ if (ipa3_is_mhip_offload_enabled()) { result = ipa_mpm_mhip_xdci_pipe_enable(params->teth_prot); if (result) { IPA_USB_ERR("failed to enable MHIP UL channel\n"); goto connect_fail; } } if (params->teth_prot != IPA_USB_DIAG) { /* Start UL channel */ result = ipa3_xdci_start(params->usb_to_ipa_clnt_hdl, Loading @@ -1610,20 +1621,11 @@ static int ipa3_usb_xdci_connect_internal( goto connect_dl_fail; } /* MHIP pipe enablement */ if (ipa3_is_mhip_offload_enabled()) { result = ipa_mpm_mhip_xdci_pipe_enable(params->teth_prot); if (result) { IPA_USB_ERR("failed to enable MHIP channel\n"); goto connect_teth_prot_fail; } } /* Connect tethering protocol */ result = ipa3_usb_connect_teth_prot(params->teth_prot); if (result) { IPA_USB_ERR("failed to connect teth protocol\n"); goto connect_mhip_prot_fail; goto connect_teth_prot_fail; } if (!ipa3_usb_set_state(IPA_USB_CONNECTED, false, ttype)) { Loading @@ -1637,9 +1639,6 @@ static int ipa3_usb_xdci_connect_internal( state_change_connected_fail: ipa3_usb_disconnect_teth_prot(params->teth_prot); connect_mhip_prot_fail: if (ipa3_is_mhip_offload_enabled()) ipa_mpm_mhip_xdci_pipe_disable(params->teth_prot); connect_teth_prot_fail: ipa3_xdci_disconnect(params->ipa_to_usb_clnt_hdl, false, -1); ipa3_reset_gsi_channel(params->ipa_to_usb_clnt_hdl); Loading @@ -1651,8 +1650,12 @@ static int ipa3_usb_xdci_connect_internal( ipa3_reset_gsi_event_ring(params->usb_to_ipa_clnt_hdl); } connect_ul_fail: if (ipa3_is_mhip_offload_enabled()) ipa_mpm_mhip_xdci_pipe_disable(params->teth_prot); connect_fail: ipa_pm_deactivate_sync( ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl); return result; } Loading drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +51 −2 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2019, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #include <linux/dma-mapping.h> Loading Loading @@ -74,6 +74,7 @@ #define IPA_MHIP_HOLB_TMO 31 /* value to match granularity on ipa HW 4.5 */ #define IPA_MPM_FLOW_CTRL_ADD 1 #define IPA_MPM_FLOW_CTRL_DELETE 0 #define IPA_MPM_NUM_OF_INIT_CMD_DESC 2 enum mhip_re_type { MHIP_RE_XFER = 0x2, Loading Loading @@ -479,12 +480,56 @@ static void ipa_mpm_gsi_chan_err_cb(struct gsi_chan_err_notify *err_data) static int ipa_mpm_set_dma_mode(enum ipa_client_type src_pipe, enum ipa_client_type dst_pipe, bool reset) { int result = 0; struct ipahal_imm_cmd_pyld *cmd_pyld[IPA_MPM_NUM_OF_INIT_CMD_DESC]; struct ipahal_imm_cmd_register_write reg_write_coal_close; struct ipahal_reg_valmask valmask; struct ipa3_desc desc[IPA_MPM_NUM_OF_INIT_CMD_DESC]; int i, num_cmd = 0, result = 0; struct ipa_ep_cfg ep_cfg = { { 0 } }; IPA_MPM_FUNC_ENTRY(); IPA_MPM_DBG("DMA from %d to %d reset=%d\n", src_pipe, dst_pipe, reset); memset(desc, 0, sizeof(desc)); memset(cmd_pyld, 0, sizeof(cmd_pyld)); /* First step is to clear IPA Pipeline before changing DMA mode */ if (ipa3_get_ep_mapping(src_pipe) != IPA_EP_NOT_ALLOCATED) { i = ipa3_get_ep_mapping(src_pipe); reg_write_coal_close.skip_pipeline_clear = false; reg_write_coal_close.pipeline_clear_options = IPAHAL_HPS_CLEAR; reg_write_coal_close.offset = ipahal_get_reg_ofst( IPA_AGGR_FORCE_CLOSE); ipahal_get_aggr_force_close_valmask(i, &valmask); reg_write_coal_close.value = valmask.val; reg_write_coal_close.value_mask = valmask.mask; cmd_pyld[num_cmd] = ipahal_construct_imm_cmd( IPA_IMM_CMD_REGISTER_WRITE, ®_write_coal_close, false); if (!cmd_pyld[num_cmd]) { IPA_MPM_ERR("failed to construct coal close IC\n"); result = -ENOMEM; goto destroy_imm_cmd; } ipa3_init_imm_cmd_desc(&desc[num_cmd], cmd_pyld[num_cmd]); ++num_cmd; } /* NO-OP IC for ensuring that IPA pipeline is empty */ cmd_pyld[num_cmd] = ipahal_construct_nop_imm_cmd(false, IPAHAL_HPS_CLEAR, false); if (!cmd_pyld[num_cmd]) { IPA_MPM_ERR("failed to construct NOP imm cmd\n"); result = -ENOMEM; goto destroy_imm_cmd; } result = ipa3_send_cmd(num_cmd, desc); if (result) { IPAERR("fail to send Reset Pipeline immediate command\n"); goto destroy_imm_cmd; } /* Reset to basic if reset = 1, otherwise set to DMA */ if (reset) ep_cfg.mode.mode = IPA_BASIC; Loading @@ -496,6 +541,10 @@ static int ipa_mpm_set_dma_mode(enum ipa_client_type src_pipe, result = ipa_cfg_ep(ipa_get_ep_mapping(src_pipe), &ep_cfg); IPA_MPM_FUNC_EXIT(); destroy_imm_cmd: for (i = 0; i < num_cmd; ++i) ipahal_destroy_imm_cmd(cmd_pyld[i]); return result; } Loading Loading
drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +18 −15 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include <linux/mutex.h> Loading Loading @@ -1590,6 +1590,17 @@ static int ipa3_usb_xdci_connect_internal( return result; } /* Start MHIP UL channel before starting USB UL channel * DL channel will be started when voting for PCIe -> LPM Exit. */ if (ipa3_is_mhip_offload_enabled()) { result = ipa_mpm_mhip_xdci_pipe_enable(params->teth_prot); if (result) { IPA_USB_ERR("failed to enable MHIP UL channel\n"); goto connect_fail; } } if (params->teth_prot != IPA_USB_DIAG) { /* Start UL channel */ result = ipa3_xdci_start(params->usb_to_ipa_clnt_hdl, Loading @@ -1610,20 +1621,11 @@ static int ipa3_usb_xdci_connect_internal( goto connect_dl_fail; } /* MHIP pipe enablement */ if (ipa3_is_mhip_offload_enabled()) { result = ipa_mpm_mhip_xdci_pipe_enable(params->teth_prot); if (result) { IPA_USB_ERR("failed to enable MHIP channel\n"); goto connect_teth_prot_fail; } } /* Connect tethering protocol */ result = ipa3_usb_connect_teth_prot(params->teth_prot); if (result) { IPA_USB_ERR("failed to connect teth protocol\n"); goto connect_mhip_prot_fail; goto connect_teth_prot_fail; } if (!ipa3_usb_set_state(IPA_USB_CONNECTED, false, ttype)) { Loading @@ -1637,9 +1639,6 @@ static int ipa3_usb_xdci_connect_internal( state_change_connected_fail: ipa3_usb_disconnect_teth_prot(params->teth_prot); connect_mhip_prot_fail: if (ipa3_is_mhip_offload_enabled()) ipa_mpm_mhip_xdci_pipe_disable(params->teth_prot); connect_teth_prot_fail: ipa3_xdci_disconnect(params->ipa_to_usb_clnt_hdl, false, -1); ipa3_reset_gsi_channel(params->ipa_to_usb_clnt_hdl); Loading @@ -1651,8 +1650,12 @@ static int ipa3_usb_xdci_connect_internal( ipa3_reset_gsi_event_ring(params->usb_to_ipa_clnt_hdl); } connect_ul_fail: if (ipa3_is_mhip_offload_enabled()) ipa_mpm_mhip_xdci_pipe_disable(params->teth_prot); connect_fail: ipa_pm_deactivate_sync( ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl); return result; } Loading
drivers/platform/msm/ipa/ipa_v3/ipa_mpm.c +51 −2 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2019, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #include <linux/dma-mapping.h> Loading Loading @@ -74,6 +74,7 @@ #define IPA_MHIP_HOLB_TMO 31 /* value to match granularity on ipa HW 4.5 */ #define IPA_MPM_FLOW_CTRL_ADD 1 #define IPA_MPM_FLOW_CTRL_DELETE 0 #define IPA_MPM_NUM_OF_INIT_CMD_DESC 2 enum mhip_re_type { MHIP_RE_XFER = 0x2, Loading Loading @@ -479,12 +480,56 @@ static void ipa_mpm_gsi_chan_err_cb(struct gsi_chan_err_notify *err_data) static int ipa_mpm_set_dma_mode(enum ipa_client_type src_pipe, enum ipa_client_type dst_pipe, bool reset) { int result = 0; struct ipahal_imm_cmd_pyld *cmd_pyld[IPA_MPM_NUM_OF_INIT_CMD_DESC]; struct ipahal_imm_cmd_register_write reg_write_coal_close; struct ipahal_reg_valmask valmask; struct ipa3_desc desc[IPA_MPM_NUM_OF_INIT_CMD_DESC]; int i, num_cmd = 0, result = 0; struct ipa_ep_cfg ep_cfg = { { 0 } }; IPA_MPM_FUNC_ENTRY(); IPA_MPM_DBG("DMA from %d to %d reset=%d\n", src_pipe, dst_pipe, reset); memset(desc, 0, sizeof(desc)); memset(cmd_pyld, 0, sizeof(cmd_pyld)); /* First step is to clear IPA Pipeline before changing DMA mode */ if (ipa3_get_ep_mapping(src_pipe) != IPA_EP_NOT_ALLOCATED) { i = ipa3_get_ep_mapping(src_pipe); reg_write_coal_close.skip_pipeline_clear = false; reg_write_coal_close.pipeline_clear_options = IPAHAL_HPS_CLEAR; reg_write_coal_close.offset = ipahal_get_reg_ofst( IPA_AGGR_FORCE_CLOSE); ipahal_get_aggr_force_close_valmask(i, &valmask); reg_write_coal_close.value = valmask.val; reg_write_coal_close.value_mask = valmask.mask; cmd_pyld[num_cmd] = ipahal_construct_imm_cmd( IPA_IMM_CMD_REGISTER_WRITE, ®_write_coal_close, false); if (!cmd_pyld[num_cmd]) { IPA_MPM_ERR("failed to construct coal close IC\n"); result = -ENOMEM; goto destroy_imm_cmd; } ipa3_init_imm_cmd_desc(&desc[num_cmd], cmd_pyld[num_cmd]); ++num_cmd; } /* NO-OP IC for ensuring that IPA pipeline is empty */ cmd_pyld[num_cmd] = ipahal_construct_nop_imm_cmd(false, IPAHAL_HPS_CLEAR, false); if (!cmd_pyld[num_cmd]) { IPA_MPM_ERR("failed to construct NOP imm cmd\n"); result = -ENOMEM; goto destroy_imm_cmd; } result = ipa3_send_cmd(num_cmd, desc); if (result) { IPAERR("fail to send Reset Pipeline immediate command\n"); goto destroy_imm_cmd; } /* Reset to basic if reset = 1, otherwise set to DMA */ if (reset) ep_cfg.mode.mode = IPA_BASIC; Loading @@ -496,6 +541,10 @@ static int ipa_mpm_set_dma_mode(enum ipa_client_type src_pipe, result = ipa_cfg_ep(ipa_get_ep_mapping(src_pipe), &ep_cfg); IPA_MPM_FUNC_EXIT(); destroy_imm_cmd: for (i = 0; i < num_cmd; ++i) ipahal_destroy_imm_cmd(cmd_pyld[i]); return result; } Loading