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

Commit a9351cb4 authored by Michael Adisumarta's avatar Michael Adisumarta Committed by Gerrit - the friendly Code Review server
Browse files

msm:ipa : enable HOLB drop timeout on MHIP producer channels



This fix enables HOLB drop timeout for MHIP TX channels which will
cause IPA to drop the packets if the packet is not processed within
the timeout. This will help relieve the back pressure on MHIP Producer
channels.

Change-Id: I607ebb460c970ccbcce2f0e364ff22e0222ded03
Signed-off-by: default avatarMichael Adisumarta <madisuma@codeaurora.org>
parent 5398ee57
Loading
Loading
Loading
Loading
+29 −90
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@
#define IPA_POLL_FOR_EMPTINESS_SLEEP_USEC 20
#define IPA_CHANNEL_STOP_IN_PROC_TO_MSEC 5
#define IPA_CHANNEL_STOP_IN_PROC_SLEEP_USEC 200

#define IPA_MHIP_HOLB_TMO 31 /* value to match granularity on ipa HW 4.5 */
enum mhip_re_type {
	MHIP_RE_XFER = 0x2,
	MHIP_RE_NOP = 0x4,
@@ -424,8 +424,6 @@ static void ipa_mpm_change_teth_state(int probe_id,
static void ipa_mpm_change_gsi_state(int probe_id,
	enum ipa_mpm_mhip_chan mhip_chan,
	enum ipa_mpm_gsi_state next_state);
static int ipa_mpm_start_stop_ul_mhip_data_path(int probe_id,
	enum ipa_mpm_start_stop_type start);
static int ipa_mpm_probe(struct platform_device *pdev);
static int ipa_mpm_vote_unvote_pcie_clk(enum ipa_mpm_clk_vote_type vote,
	int probe_id);
@@ -435,6 +433,7 @@ static enum mhip_status_type ipa_mpm_start_stop_mhip_chan(
	enum ipa_mpm_mhip_chan mhip_chan,
	int probe_id,
	enum ipa_mpm_start_stop_type start_stop);
static int ipa_mpm_start_mhip_holb_tmo(u32 clnt_hdl);

static struct mhi_driver mhi_driver = {
	.id_table = mhi_driver_match_table,
@@ -500,6 +499,17 @@ static int ipa_mpm_set_dma_mode(enum ipa_client_type src_pipe,
	return result;
}

static int ipa_mpm_start_mhip_holb_tmo(u32 clnt_hdl)
{
	struct ipa_ep_cfg_holb holb_cfg;

	memset(&holb_cfg, 0, sizeof(holb_cfg));
	holb_cfg.en = IPA_HOLB_TMR_EN;
	/* 31 ms timer, which is less than tag timeout */
	holb_cfg.tmr_val = IPA_MHIP_HOLB_TMO;
	return ipa3_cfg_ep_holb(clnt_hdl, &holb_cfg);
}

/**
 * ipa_mpm_smmu_map() - SMMU maps ring and the buffer pointer.
 * @va_addr: virtual address that needs to be mapped
@@ -1034,6 +1044,21 @@ static int ipa_mpm_connect_mhip_gsi_pipe(enum ipa_client_type mhip_client,
		goto fail_alloc_channel;
	}

	if (IPA_CLIENT_IS_CONS(mhip_client)) {
		/*
		 * Enable HOLB timer one time after bootup/SSR.
		 * The HOLB timeout drops the packets on MHIP if
		 * there is a stall on MHIP TX pipe greater than
		 * configured timeout.
		 */
		result = ipa_mpm_start_mhip_holb_tmo(ipa_ep_idx);
		if (result) {
			IPA_MPM_ERR("HOLB config failed for %d, fail = %d\n",
				ipa_ep_idx, result);
			goto fail_alloc_channel;
		}
	}

	if (IPA_CLIENT_IS_PROD(mhip_client))
		ipa_mpm_change_gsi_state(mhi_idx,
			IPA_MPM_MHIP_CHAN_DL,
@@ -1326,11 +1351,9 @@ static void ipa_mpm_mhip_shutdown(int mhip_idx)

	get_ipa3_client(mhip_idx, &ul_prod_chan, &dl_cons_chan);

	if (mhip_idx != IPA_MPM_MHIP_CH_ID_2) {
	if (mhip_idx != IPA_MPM_MHIP_CH_ID_2)
		/* For DPL, stop only DL channel */
		ipa_mpm_start_stop_ul_mhip_data_path(mhip_idx, MPM_MHIP_STOP);
		ipa_mpm_clean_mhip_chan(mhip_idx, ul_prod_chan);
	}

	ipa_mpm_clean_mhip_chan(mhip_idx, dl_cons_chan);

@@ -1713,13 +1736,6 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state)
		case MHIP_STATUS_SUCCESS:
			ipa_mpm_ctx->md[probe_id].teth_state =
						IPA_MPM_TETH_CONNECTED;
			ret = ipa_mpm_start_stop_ul_mhip_data_path(
						probe_id, MPM_MHIP_START);
			if (ret) {
				IPA_MPM_ERR("UL chan start err = %d\n", ret);
				ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id);
				return ret;
			}
			break;
		case MHIP_STATUS_EP_NOT_READY:
		case MHIP_STATUS_NO_OP:
@@ -1767,8 +1783,6 @@ int ipa_mpm_notify_wan_state(struct wan_ioctl_notify_wan_state *state)
		switch (status) {
		case MHIP_STATUS_SUCCESS:
			ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INIT);
			ipa_mpm_start_stop_ul_mhip_data_path(probe_id,
							MPM_MHIP_STOP);
			break;
		case MHIP_STATUS_NO_OP:
		case MHIP_STATUS_EP_NOT_READY:
@@ -1881,64 +1895,6 @@ static void ipa_mpm_read_channel(enum ipa_client_type chan)
		IPA_MPM_ERR("Reading of channel failed for ep %d\n", ep);
}

static int ipa_mpm_start_stop_ul_mhip_data_path(int probe_id,
	enum ipa_mpm_start_stop_type start)
{
	int ipa_ep_idx;
	int res = 0;
	enum ipa_client_type ul_chan, dl_chan;

	if (probe_id >= IPA_MPM_MHIP_CH_ID_MAX) {
		IPA_MPM_ERR("Unknown probe_id\n");
		return 0;
	}
	get_ipa3_client(probe_id, &ul_chan, &dl_chan);
	IPA_MPM_DBG("Start/Stop Data Path ? = %d\n", start);


	/* MHIP Start Data path:
	 * IPA MHIP Producer: remove HOLB
	 * IPA MHIP Consumer : no op as there is no delay on these pipes.
	 */
	if (start) {
		IPA_MPM_DBG("Enabling data path\n");
		if (ul_chan != IPA_CLIENT_MAX) {
			/* Remove HOLB on the producer pipe */
			IPA_MPM_DBG("Removing HOLB on ep = %s\n",
				__stringify(ul_chan));
			ipa_ep_idx = ipa3_get_ep_mapping(ul_chan);

			if (ipa_ep_idx == IPA_EP_NOT_ALLOCATED) {
				IPAERR("failed to get idx");
				return ipa_ep_idx;
			}

			res = ipa3_enable_data_path(ipa_ep_idx);
			if (res)
				IPA_MPM_ERR("Enable data path failed res=%d\n",
					res);
		}
	} else {
		IPA_MPM_DBG("Disabling data path\n");
		if (ul_chan != IPA_CLIENT_MAX) {
			/* Set HOLB on the producer pipe */
			ipa_ep_idx = ipa3_get_ep_mapping(ul_chan);

			if (ipa_ep_idx == IPA_EP_NOT_ALLOCATED) {
				IPAERR("failed to get idx");
				return ipa_ep_idx;
			}

			res = ipa3_disable_data_path(ipa_ep_idx);
			if (res)
				IPA_MPM_ERR("disable data path failed res=%d\n",
					res);
		}
	}

	return res;
}

/* ipa_mpm_mhi_probe_cb is received for each MHI'/MHI channel
 * Currently we have 4 MHI channels.
 */
@@ -2294,12 +2250,6 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev,
			/* No teth started yet, disable UL channel */
			ipa_mpm_start_stop_mhip_chan(IPA_MPM_MHIP_CHAN_UL,
						probe_id, MPM_MHIP_STOP);
			/* Disable data path */
			if (ipa_mpm_start_stop_ul_mhip_data_path(probe_id,
				MPM_MHIP_STOP)) {
				IPA_MPM_ERR("MHIP Enable data path failed\n");
				goto fail_start_channel;
			}
		}
		ipa_mpm_vote_unvote_pcie_clk(CLK_OFF, probe_id);
		break;
@@ -2308,14 +2258,6 @@ static int ipa_mpm_mhi_probe_cb(struct mhi_device *mhi_dev,
		IPA_MPM_DBG("UL channel is already started, continue\n");
		ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_CONNECTED);

		/* Enable data path */
		if (ul_prod != IPA_CLIENT_MAX) {
			if (ipa_mpm_start_stop_ul_mhip_data_path(probe_id,
				MPM_MHIP_START)) {
				IPA_MPM_ERR("MHIP Enable data path failed\n");
				goto fail_start_channel;
			}
		}
		/* Lift the delay for rmnet USB prod pipe */
		if (probe_id == IPA_MPM_MHIP_CH_ID_1) {
			pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);
@@ -2596,8 +2538,6 @@ int ipa_mpm_mhip_xdci_pipe_enable(enum ipa_usb_teth_prot xdci_teth_prot)
	case MHIP_STATUS_SUCCESS:
	case MHIP_STATUS_NO_OP:
		ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_CONNECTED);
		ipa_mpm_start_stop_ul_mhip_data_path(probe_id,
						MPM_MHIP_START);

		pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);

@@ -2717,7 +2657,6 @@ int ipa_mpm_mhip_xdci_pipe_disable(enum ipa_usb_teth_prot xdci_teth_prot)
	case MHIP_STATUS_NO_OP:
	case MHIP_STATUS_EP_NOT_READY:
		ipa_mpm_change_teth_state(probe_id, IPA_MPM_TETH_INIT);
		ipa_mpm_start_stop_ul_mhip_data_path(probe_id, MPM_MHIP_STOP);
		break;
	case MHIP_STATUS_FAIL:
	case MHIP_STATUS_BAD_STATE:
+2 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@
#define IPA_V4_0_CLK_RATE_NOMINAL (220 * 1000 * 1000UL)
#define IPA_V4_0_CLK_RATE_TURBO (250 * 1000 * 1000UL)

#define IPA_V3_0_MAX_HOLB_TMR_VAL (4294967296 - 1)
#define IPA_MAX_HOLB_TMR_VAL (4294967296 - 1)

#define IPA_V3_0_BW_THRESHOLD_TURBO_MBPS (1000)
#define IPA_V3_0_BW_THRESHOLD_NOMINAL_MBPS (600)
@@ -5985,6 +5985,7 @@ int ipa3_controller_static_bind(struct ipa3_controller *ctrl,
	ctrl->ipa_init_sram = _ipa_init_sram_v3;
	ctrl->ipa_sram_read_settings = _ipa_sram_settings_read_v3_0;
	ctrl->ipa_init_hdr = _ipa_init_hdr_v3_0;
	ctrl->max_holb_tmr_val = IPA_MAX_HOLB_TMR_VAL;

	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0)
		ctrl->ipa3_read_ep_reg = _ipa_read_ep_reg_v4_0;