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

Commit 7cc46fb3 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: gsi: Update Channel Scratch structures for GSI 2.5"

parents 5cd75ce7 69499579
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