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

Commit edb15719 authored by Mohammed Javid's avatar Mohammed Javid
Browse files

msm: ipa4: Adding support to configure the WDI protocol gsi channel



Adding support to configure the WDI protocol gsi channel and
starting the GSI channel only in WDI pipe resume time and
stopping in WDI suspend time.

Change-Id: Iaf51173d456121c051b1a40560719a8810ca05ee
Acked-by: default avatarAshok Vuyyuru <avuyyuru@qti.qualcomm.com>
Signed-off-by: default avatarMohammed Javid <mjavid@codeaurora.org>
parent b7459312
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1956,6 +1956,7 @@ static void gsi_program_chan_ctx(struct gsi_chan_props *props, unsigned int ee,
	case GSI_CHAN_PROT_XHCI:
	case GSI_CHAN_PROT_GPI:
	case GSI_CHAN_PROT_XDCI:
	case GSI_CHAN_PROT_WDI:
		prot = props->prot;
		prot_msb = 0;
		break;
+80 −39
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@
#define IPA_WDI_RESUMED BIT(2)
#define IPA_UC_POLL_SLEEP_USEC 100

#define GSI_STOP_MAX_RETRY_CNT 10

struct ipa_wdi_res {
	struct ipa_wdi_buffer_info *res;
	unsigned int nents;
@@ -882,6 +884,8 @@ static int ipa3_wdi2_gsi_alloc_evt_ring(
	evt_scratch.wdi.update_ri_mod_timer_running = 0;
	evt_scratch.wdi.evt_comp_count = 0;
	evt_scratch.wdi.last_update_ri = 0;
	evt_scratch.wdi.resvd1 = 0;
	evt_scratch.wdi.resvd2 = 0;
	result = gsi_write_evt_ring_scratch(*evt_ring_hdl, evt_scratch);
	if (result != GSI_STATUS_SUCCESS) {
		IPAERR("Error writing WDI event ring scratch: %d\n", result);
@@ -1113,6 +1117,7 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
			result = -ENOMEM;
			goto gsi_timeout;
		}
		gsi_evt_ring_props.rp_update_addr = va;
	} else {
		len = in->smmu_enabled ? in->u.ul_smmu.rdy_ring_size :
			in->u.ul.rdy_ring_size;
@@ -1189,13 +1194,13 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
			result = -ENOMEM;
			goto gsi_timeout;
		}

		gsi_evt_ring_props.rp_update_addr = va;
		gsi_scratch.wdi.wdi_rx_vdev_id = 0xff;
		gsi_scratch.wdi.wdi_rx_fw_desc = 0xff;
		gsi_scratch.wdi.endp_metadatareg_offset =
					ipahal_get_reg_mn_ofst(
					IPA_ENDP_INIT_HDR_METADATA_n, 0,
							ipa_ep_idx);
							ipa_ep_idx)/4;
		gsi_scratch.wdi.qmap_id = 0;
	}

@@ -1258,7 +1263,7 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
		min(UPDATE_RI_MODERATION_THRESHOLD, num_ring_ele);
	gsi_scratch.wdi.update_ri_moderation_counter = 0;
	gsi_scratch.wdi.wdi_rx_tre_proc_in_progress = 0;

	gsi_scratch.wdi.resv1 = 0;
	result = gsi_write_channel_scratch(ep->gsi_chan_hdl,
			gsi_scratch);
	if (result != GSI_STATUS_SUCCESS) {
@@ -1267,13 +1272,6 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
		goto fail_write_channel_scratch;
	}

	result =  gsi_start_channel(ep->gsi_chan_hdl);
	if (result != GSI_STATUS_SUCCESS) {
		IPAERR("gsi_start_channel failed %d\n", result);
		goto fail_start_channel;
	}
	IPADBG("GSI channel started\n");

	/* for AP+STA stats update */
	if (in->wdi_notify)
		ipa3_ctx->uc_wdi_ctx.stats_notify = in->wdi_notify;
@@ -1301,7 +1299,6 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,

ipa_cfg_ep_fail:
	memset(&ipa3_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa3_ep_context));
fail_start_channel:
fail_write_channel_scratch:
	gsi_dealloc_channel(ep->gsi_chan_hdl);
gsi_timeout:
@@ -1859,18 +1856,6 @@ int ipa3_disconnect_gsi_wdi_pipe(u32 clnt_hdl)
	if (!ep->keep_ipa_awake)
		IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl));

	result = ipa3_stop_gsi_channel(clnt_hdl);
	if (result != GSI_STATUS_SUCCESS) {
		IPAERR("GSI stop chan err: %d.\n", result);
		ipa_assert();
		return result;
	}
	result = ipa3_reset_gsi_channel(clnt_hdl);
	if (result != GSI_STATUS_SUCCESS) {
		IPAERR("Failed to reset chan: %d.\n", result);
		ipa_assert();
		return result;
	}
	result = gsi_reset_evt_ring(ep->gsi_evt_ring_hdl);
	if (result != GSI_STATUS_SUCCESS) {
		IPAERR("Failed to reset evt ring: %d.\n",
@@ -2335,6 +2320,10 @@ int ipa3_suspend_gsi_wdi_pipe(u32 clnt_hdl)
	int ipa_ep_idx;
	struct ipa3_ep_context *ep;
	int res = 0;
	u32 source_pipe_bitmask = 0;
	bool disable_force_clear = false;
	struct ipahal_ep_cfg_ctrl_scnd ep_ctrl_scnd = { 0 };
	int retry_cnt = 0;

	ipa_ep_idx = ipa3_get_ep_mapping(ipa3_get_client_mapping(clnt_hdl));
	if (ipa_ep_idx < 0) {
@@ -2350,15 +2339,56 @@ int ipa3_suspend_gsi_wdi_pipe(u32 clnt_hdl)
	}
	if (ep->valid) {
		IPADBG("suspended pipe %d\n", ipa_ep_idx);
		res = ipa3_stop_gsi_channel(ipa_ep_idx);
		source_pipe_bitmask = 1 <<
			ipa3_get_ep_mapping(ep->client);
		res = ipa3_enable_force_clear(clnt_hdl,
				false, source_pipe_bitmask);
		if (res) {
			IPAERR("failed to stop LAN channel\n");
			ipa_assert();
			/*
			 * assuming here modem SSR, AP can remove
			 * the delay in this case
			 */
			IPAERR("failed to force clear %d\n", res);
			IPAERR("remove delay from SCND reg\n");
			ep_ctrl_scnd.endp_delay = false;
			ipahal_write_reg_n_fields(
					IPA_ENDP_INIT_CTRL_SCND_n, clnt_hdl,
					&ep_ctrl_scnd);
		} else {
			disable_force_clear = true;
		}
retry_gsi_stop:
		res = ipa3_stop_gsi_channel(ipa_ep_idx);
		if (res != 0 && res != -GSI_STATUS_AGAIN &&
				res != -GSI_STATUS_TIMED_OUT) {
			IPAERR("failed to stop channel res = %d\n", res);
			goto fail_stop_channel;
		} else if (res == -GSI_STATUS_AGAIN) {
			IPADBG("GSI stop channel failed retry cnt = %d\n",
						retry_cnt);
			retry_cnt++;
			if (retry_cnt >= GSI_STOP_MAX_RETRY_CNT)
				goto fail_stop_channel;
			goto retry_gsi_stop;
		} else {
			IPADBG("GSI channel %ld STOP\n", ep->gsi_chan_hdl);
		}

		res = ipa3_reset_gsi_channel(clnt_hdl);
		if (res != GSI_STATUS_SUCCESS) {
			IPAERR("Failed to reset chan: %d.\n", res);
			goto fail_stop_channel;
		}

	}
	if (disable_force_clear)
		ipa3_disable_force_clear(clnt_hdl);
	IPA_ACTIVE_CLIENTS_DEC_EP(ipa3_get_client_mapping(clnt_hdl));
	ep->gsi_offload_state &= ~IPA_WDI_RESUMED;
	return res;
fail_stop_channel:
	ipa_assert();
	return res;
}

/**
@@ -2510,6 +2540,7 @@ int ipa3_write_qmapid_gsi_wdi_pipe(u32 clnt_hdl, u8 qmap_id)
	int result = 0;
	struct ipa3_ep_context *ep;
	union __packed gsi_channel_scratch gsi_scratch;
	int retry_cnt = 0;

	memset(&gsi_scratch, 0, sizeof(gsi_scratch));
	ep = &ipa3_ctx->ep[clnt_hdl];
@@ -2521,18 +2552,25 @@ int ipa3_write_qmapid_gsi_wdi_pipe(u32 clnt_hdl, u8 qmap_id)
			result);
		goto fail_read_channel_scratch;
	}
	if (ep->gsi_offload_state == (IPA_WDI_CONNECTED | IPA_WDI_ENABLED |
						IPA_WDI_RESUMED)) {
retry_gsi_stop:
		result = ipa3_stop_gsi_channel(clnt_hdl);
	if (result != 0) {
		if (result != 0 && result != -GSI_STATUS_AGAIN &&
				result != -GSI_STATUS_TIMED_OUT) {
			IPAERR("GSI stop channel failed %d\n",
					result);
		}
			goto fail_stop_channel;
		} else if (result == -GSI_STATUS_AGAIN) {
			IPADBG("GSI stop channel failed retry cnt = %d\n",
						retry_cnt);
			retry_cnt++;
			if (retry_cnt >= GSI_STOP_MAX_RETRY_CNT)
				goto fail_stop_channel;
			goto retry_gsi_stop;
		} else {
			IPADBG("GSI channel %ld STOP\n", ep->gsi_chan_hdl);
		}
	if (result == 0) {
		IPAERR("GSI channel %ld STOP\n",
			ep->gsi_chan_hdl);
	}
	gsi_scratch.wdi.qmap_id = qmap_id;
	result = gsi_write_channel_scratch(ep->gsi_chan_hdl,
@@ -2542,11 +2580,14 @@ int ipa3_write_qmapid_gsi_wdi_pipe(u32 clnt_hdl, u8 qmap_id)
			result);
		goto fail_write_channel_scratch;
	}
	if (ep->gsi_offload_state == (IPA_WDI_CONNECTED | IPA_WDI_ENABLED |
						IPA_WDI_RESUMED)) {
		result =  gsi_start_channel(ep->gsi_chan_hdl);
		if (result != GSI_STATUS_SUCCESS) {
			IPAERR("gsi_start_channel failed %d\n", result);
			goto fail_start_channel;
		}
	}
	return 0;
fail_start_channel:
fail_read_channel_scratch:
+3 −2
Original line number Diff line number Diff line
@@ -659,15 +659,16 @@ struct __packed gsi_wdi_channel_scratch {
	uint32_t update_ri_moderation_threshold:5;
	uint32_t update_ri_moderation_counter:6;
	uint32_t wdi_rx_tre_proc_in_progress:1;
	uint32_t resv1:4;
	uint32_t wdi_rx_vdev_id:8;
	uint32_t wdi_rx_fw_desc:8;
	uint32_t endp_metadatareg_offset:16;
	uint32_t qmap_id:16;
	uint32_t wdi_rx_pkt_length:16;
	uint32_t resv1:2;
	uint32_t resv2:2;
	uint32_t pkt_comp_count:11;
	uint32_t stop_in_progress_stm:3;
	uint32_t resv2:16;
	uint32_t resv3:16;
	uint32_t wdi_rx_qmap_id_internal:16;
};