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

Commit 69499579 authored by Ghanim Fodi's avatar Ghanim Fodi Committed by Gerrit - the friendly Code Review server
Browse files

msm: gsi: Update Channel Scratch structures for GSI 2.5



GSI 2.5 introduced changes to the GSI channel scratches
including the SWI fields. E.g. due to removal of smart
prefetch from MCS. This change adapt the code for the new
scratch structures for MHI, xDCI and GPI protocols.

CRs-Fixed: 2260038
Change-Id: Ib79e3dc3356e65c8767d1f8e9005db34dd0061e4
Signed-off-by: default avatarGhanim Fodi <gfodi@codeaurora.org>
parent d664828b
Loading
Loading
Loading
Loading
+88 −6
Original line number Diff line number Diff line
@@ -1909,8 +1909,6 @@ EXPORT_SYMBOL(gsi_alloc_channel);
static void __gsi_write_channel_scratch(unsigned long chan_hdl,
		union __packed gsi_channel_scratch val)
{
	uint32_t reg;

	gsi_writel(val.data.word1, gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(chan_hdl,
			gsi_ctx->per.ee));
@@ -1920,17 +1918,69 @@ static void __gsi_write_channel_scratch(unsigned long chan_hdl,
	gsi_writel(val.data.word3, gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl,
			gsi_ctx->per.ee));

	gsi_writel(val.data.word4, gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_3_OFFS(chan_hdl,
			gsi_ctx->per.ee));
}

static union __packed gsi_channel_scratch __gsi_update_mhi_channel_scratch(
	unsigned long chan_hdl, struct __packed gsi_mhi_channel_scratch mscr)
{
	union __packed gsi_channel_scratch scr;

	/* below sequence is not atomic. assumption is sequencer specific fields
	 * will remain unchanged across this sequence
	 */
	reg = gsi_readl(gsi_ctx->base +

	/* READ */
	scr.data.word1 = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(chan_hdl,
			gsi_ctx->per.ee));

	scr.data.word2 = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_1_OFFS(chan_hdl,
			gsi_ctx->per.ee));

	scr.data.word3 = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl,
			gsi_ctx->per.ee));

	scr.data.word4 = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_3_OFFS(chan_hdl,
			gsi_ctx->per.ee));
	reg &= 0xFFFF;
	reg |= (val.data.word4 & 0xFFFF0000);
	gsi_writel(reg, gsi_ctx->base +

	/* UPDATE */
	scr.mhi.mhi_host_wp_addr = mscr.mhi_host_wp_addr;
	scr.mhi.assert_bit40 = mscr.assert_bit40;
	scr.mhi.polling_configuration = mscr.polling_configuration;
	scr.mhi.burst_mode_enabled = mscr.burst_mode_enabled;
	scr.mhi.polling_mode = mscr.polling_mode;
	scr.mhi.oob_mod_threshold = mscr.oob_mod_threshold;

	if (gsi_ctx->per.ver < GSI_VER_2_5) {
		scr.mhi.max_outstanding_tre = mscr.max_outstanding_tre;
		scr.mhi.outstanding_threshold = mscr.outstanding_threshold;
	}

	/* WRITE */
	gsi_writel(scr.data.word1, gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(chan_hdl,
			gsi_ctx->per.ee));

	gsi_writel(scr.data.word2, gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_1_OFFS(chan_hdl,
			gsi_ctx->per.ee));

	gsi_writel(scr.data.word3, gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl,
			gsi_ctx->per.ee));

	gsi_writel(scr.data.word4, gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_3_OFFS(chan_hdl,
			gsi_ctx->per.ee));

	return scr;
}

int gsi_write_channel_scratch(unsigned long chan_hdl,
@@ -1966,6 +2016,38 @@ int gsi_write_channel_scratch(unsigned long chan_hdl,
}
EXPORT_SYMBOL(gsi_write_channel_scratch);

int gsi_update_mhi_channel_scratch(unsigned long chan_hdl,
		struct __packed gsi_mhi_channel_scratch mscr)
{
	struct gsi_chan_ctx *ctx;

	if (!gsi_ctx) {
		pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
		return -GSI_STATUS_NODEV;
	}

	if (chan_hdl >= gsi_ctx->max_ch) {
		GSIERR("bad params chan_hdl=%lu\n", chan_hdl);
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (gsi_ctx->chan[chan_hdl].state != GSI_CHAN_STATE_ALLOCATED &&
		gsi_ctx->chan[chan_hdl].state != GSI_CHAN_STATE_STOPPED) {
		GSIERR("bad state %d\n",
				gsi_ctx->chan[chan_hdl].state);
		return -GSI_STATUS_UNSUPPORTED_OP;
	}

	ctx = &gsi_ctx->chan[chan_hdl];

	mutex_lock(&ctx->mlock);
	ctx->scratch = __gsi_update_mhi_channel_scratch(chan_hdl, mscr);
	mutex_unlock(&ctx->mlock);

	return GSI_STATUS_SUCCESS;
}
EXPORT_SYMBOL(gsi_update_mhi_channel_scratch);

int gsi_query_channel_db_addr(unsigned long chan_hdl,
		uint32_t *db_addr_wp_lsb, uint32_t *db_addr_wp_msb)
{
+11 −5
Original line number Diff line number Diff line
@@ -1351,14 +1351,20 @@ static int ipa3_usb_request_xdci_channel(
		params->xfer_scratch.depcmd_low_addr;
	chan_params.chan_scratch.xdci.depcmd_hi_addr =
		params->xfer_scratch.depcmd_hi_addr;

	/*
	 * Update scratch for MCS smart prefetch:
	 * Starting IPA4.5, smart prefetch implemented by H/W.
	 * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch
	 *  so keep the fields zero.
	 */
	if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) {
		chan_params.chan_scratch.xdci.outstanding_threshold =
		((params->teth_prot == IPA_USB_MBIM) ? 1 : 2) *
		chan_params.chan_params.re_size;

	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0)
		chan_params.chan_scratch.xdci.outstanding_threshold = 0;

	}
	/* max_outstanding_tre is set in ipa3_request_gsi_channel() */

	result = ipa3_request_gsi_channel(&chan_params, out_params);
	if (result) {
		IPA_USB_ERR("failed to allocate GSI channel\n");
+10 −4
Original line number Diff line number Diff line
@@ -823,11 +823,17 @@ int ipa3_request_gsi_channel(struct ipa_request_gsi_channel_params *params,

	memcpy(&ep->chan_scratch, &params->chan_scratch,
		sizeof(union __packed gsi_channel_scratch));

	/*
	 * Update scratch for MCS smart prefetch:
	 * Starting IPA4.5, smart prefetch implemented by H/W.
	 * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch
	 *  so keep the fields zero.
	 */
	if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) {
		ep->chan_scratch.xdci.max_outstanding_tre =
		params->chan_params.re_size * gsi_ep_cfg_ptr->ipa_if_tlv;

	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0)
		ep->chan_scratch.xdci.max_outstanding_tre = 0;
	}

	gsi_res = gsi_write_channel_scratch(ep->gsi_chan_hdl,
		params->chan_scratch);
+14 −9
Original line number Diff line number Diff line
@@ -3792,15 +3792,20 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
		goto fail_alloc_channel;

	memset(&ch_scratch, 0, sizeof(ch_scratch));
	ch_scratch.gpi.max_outstanding_tre = gsi_ep_info->ipa_if_tlv *
		GSI_CHAN_RE_SIZE_16B;
	ch_scratch.gpi.outstanding_threshold = 2 * GSI_CHAN_RE_SIZE_16B;

	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
		ch_scratch.gpi.max_outstanding_tre = 0;
		ch_scratch.gpi.outstanding_threshold = 0;
	}

	/*
	 * Update scratch for MCS smart prefetch:
	 * Starting IPA4.5, smart prefetch implemented by H/W.
	 * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch
	 *  so keep the fields zero.
	 */
	if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) {
		ch_scratch.gpi.max_outstanding_tre =
			gsi_ep_info->ipa_if_tlv * GSI_CHAN_RE_SIZE_16B;
		ch_scratch.gpi.outstanding_threshold =
			2 * GSI_CHAN_RE_SIZE_16B;
	}
	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_5)
		ch_scratch.gpi.dl_nlo_channel = 0;
	result = gsi_write_channel_scratch(ep->gsi_chan_hdl, ch_scratch);
	if (result != GSI_STATUS_SUCCESS) {
		IPAERR("failed to write scratch %d\n", result);
+19 −9
Original line number Diff line number Diff line
@@ -298,13 +298,18 @@ static int ipa_mhi_start_gsi_channel(enum ipa_client_type client,
			params->channel_context_addr +
			offsetof(struct ipa_mhi_ch_ctx, wp));
	ch_scratch.mhi.assert_bit40 = params->assert_bit40;

	/*
	 * Update scratch for MCS smart prefetch:
	 * Starting IPA4.5, smart prefetch implemented by H/W.
	 * At IPA 4.0/4.1/4.2, we do not use MCS smart prefetch
	 *  so keep the fields zero.
	 */
	if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) {
		ch_scratch.mhi.max_outstanding_tre =
			ep_cfg->ipa_if_tlv * ch_props.re_size;
		ch_scratch.mhi.outstanding_threshold =
			min(ep_cfg->ipa_if_tlv / 2, 8) * ch_props.re_size;
	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) {
		ch_scratch.mhi.max_outstanding_tre = 0;
		ch_scratch.mhi.outstanding_threshold = 0;
	}
	ch_scratch.mhi.oob_mod_threshold = 4;
	if (params->ch_ctx_host->brstmode == IPA_MHI_BURST_MODE_DEFAULT ||
@@ -564,8 +569,13 @@ int ipa3_mhi_resume_channels_internal(enum ipa_client_type client,
		 * set polling mode bit to DB mode before
		 * resuming the channel
		 */
		res = gsi_write_channel_scratch(
			ep->gsi_chan_hdl, ch_scratch);
		ch_scratch.mhi.polling_mode = IPA_MHI_POLLING_MODE_DB_MODE;

		/* Use GSI update API to not affect non-SWI fields
		 * inside the scratch while in suspend-resume operation
		 */
		res = gsi_update_mhi_channel_scratch(
			ep->gsi_chan_hdl, ch_scratch.mhi);
		if (res) {
			IPA_MHI_ERR("write ch scratch fail %d\n"
				, res);
Loading