Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68557cdb authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: clear the ipa pipeline before any ep config"

parents 2a69d401 1f0a50de
Loading
Loading
Loading
Loading
+18 −15
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
// 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>
#include <linux/mutex.h>
@@ -1590,6 +1590,17 @@ static int ipa3_usb_xdci_connect_internal(
		return result;
		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) {
	if (params->teth_prot != IPA_USB_DIAG) {
		/* Start UL channel */
		/* Start UL channel */
		result = ipa3_xdci_start(params->usb_to_ipa_clnt_hdl,
		result = ipa3_xdci_start(params->usb_to_ipa_clnt_hdl,
@@ -1610,20 +1621,11 @@ static int ipa3_usb_xdci_connect_internal(
		goto connect_dl_fail;
		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 */
	/* Connect tethering protocol */
	result = ipa3_usb_connect_teth_prot(params->teth_prot);
	result = ipa3_usb_connect_teth_prot(params->teth_prot);
	if (result) {
	if (result) {
		IPA_USB_ERR("failed to connect teth protocol\n");
		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)) {
	if (!ipa3_usb_set_state(IPA_USB_CONNECTED, false, ttype)) {
@@ -1637,9 +1639,6 @@ static int ipa3_usb_xdci_connect_internal(


state_change_connected_fail:
state_change_connected_fail:
	ipa3_usb_disconnect_teth_prot(params->teth_prot);
	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:
connect_teth_prot_fail:
	ipa3_xdci_disconnect(params->ipa_to_usb_clnt_hdl, false, -1);
	ipa3_xdci_disconnect(params->ipa_to_usb_clnt_hdl, false, -1);
	ipa3_reset_gsi_channel(params->ipa_to_usb_clnt_hdl);
	ipa3_reset_gsi_channel(params->ipa_to_usb_clnt_hdl);
@@ -1651,8 +1650,12 @@ static int ipa3_usb_xdci_connect_internal(
		ipa3_reset_gsi_event_ring(params->usb_to_ipa_clnt_hdl);
		ipa3_reset_gsi_event_ring(params->usb_to_ipa_clnt_hdl);
	}
	}
connect_ul_fail:
connect_ul_fail:
	if (ipa3_is_mhip_offload_enabled())
		ipa_mpm_mhip_xdci_pipe_disable(params->teth_prot);
connect_fail:
	ipa_pm_deactivate_sync(
	ipa_pm_deactivate_sync(
			ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);
			ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);

	return result;
	return result;
}
}


+51 −2
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
// 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>
#include <linux/dma-mapping.h>
@@ -74,6 +74,7 @@
#define IPA_MHIP_HOLB_TMO 31 /* value to match granularity on ipa HW 4.5 */
#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_ADD 1
#define IPA_MPM_FLOW_CTRL_DELETE 0
#define IPA_MPM_FLOW_CTRL_DELETE 0
#define IPA_MPM_NUM_OF_INIT_CMD_DESC 2


enum mhip_re_type {
enum mhip_re_type {
	MHIP_RE_XFER = 0x2,
	MHIP_RE_XFER = 0x2,
@@ -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,
static int ipa_mpm_set_dma_mode(enum ipa_client_type src_pipe,
	enum ipa_client_type dst_pipe, bool reset)
	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 } };
	struct ipa_ep_cfg ep_cfg = { { 0 } };


	IPA_MPM_FUNC_ENTRY();
	IPA_MPM_FUNC_ENTRY();
	IPA_MPM_DBG("DMA from %d to %d reset=%d\n", src_pipe, dst_pipe, reset);
	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,
					&reg_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 */
	/* Reset to basic if reset = 1, otherwise set to DMA */
	if (reset)
	if (reset)
		ep_cfg.mode.mode = IPA_BASIC;
		ep_cfg.mode.mode = IPA_BASIC;
@@ -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);
	result = ipa_cfg_ep(ipa_get_ep_mapping(src_pipe), &ep_cfg);
	IPA_MPM_FUNC_EXIT();
	IPA_MPM_FUNC_EXIT();


destroy_imm_cmd:
	for (i = 0; i < num_cmd; ++i)
		ipahal_destroy_imm_cmd(cmd_pyld[i]);

	return result;
	return result;
}
}