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

Commit 2f2eea29 authored by Chaitanya Pratapa's avatar Chaitanya Pratapa Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: add support to updated wdi3 scratch register2 alone



To update QMAP ID there is no need to start and stop the GSI
channel. Make changes to read only scratch2 register for WDI3
protocol and update the QMAP ID without affecting other registers.

Change-Id: I7f873386fd01d624629fed15b841c6abd558a9ce
Signed-off-by: default avatarChaitanya Pratapa <cpratapa@codeaurora.org>
parent 24a21204
Loading
Loading
Loading
Loading
+89 −0
Original line number Diff line number Diff line
@@ -2562,6 +2562,15 @@ static void __gsi_write_channel_scratch(unsigned long chan_hdl,
			gsi_ctx->per.ee));
}

static void __gsi_write_wdi3_channel_scratch2_reg(unsigned long chan_hdl,
		union __packed gsi_wdi3_channel_scratch2_reg val)
{
	gsi_writel(val.data.word1, gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_2_OFFS(chan_hdl,
			gsi_ctx->per.ee));
}


int gsi_write_channel_scratch3_reg(unsigned long chan_hdl,
		union __packed gsi_wdi_channel_scratch3_reg val)
{
@@ -2645,6 +2654,17 @@ static void __gsi_read_channel_scratch(unsigned long chan_hdl,
			gsi_ctx->per.ee));
}

static void __gsi_read_wdi3_channel_scratch2_reg(unsigned long chan_hdl,
		union __packed gsi_wdi3_channel_scratch2_reg * val)
{

	val->data.word1 = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_2_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)
{
@@ -2737,6 +2757,41 @@ int gsi_write_channel_scratch(unsigned long chan_hdl,
}
EXPORT_SYMBOL(gsi_write_channel_scratch);

int gsi_write_wdi3_channel_scratch2_reg(unsigned long chan_hdl,
		union __packed gsi_wdi3_channel_scratch2_reg val)
{
	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_STARTED &&
		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.data.word3 = val.data.word1;
	__gsi_write_wdi3_channel_scratch2_reg(chan_hdl, val);
	mutex_unlock(&ctx->mlock);

	return GSI_STATUS_SUCCESS;
}
EXPORT_SYMBOL(gsi_write_wdi3_channel_scratch2_reg);


int gsi_read_channel_scratch(unsigned long chan_hdl,
		union __packed gsi_channel_scratch *val)
{
@@ -2770,6 +2825,40 @@ int gsi_read_channel_scratch(unsigned long chan_hdl,
}
EXPORT_SYMBOL(gsi_read_channel_scratch);

int gsi_read_wdi3_channel_scratch2_reg(unsigned long chan_hdl,
		union __packed gsi_wdi3_channel_scratch2_reg * val)
{
	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_STARTED &&
		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);
	__gsi_read_wdi3_channel_scratch2_reg(chan_hdl, val);
	mutex_unlock(&ctx->mlock);

	return GSI_STATUS_SUCCESS;
}
EXPORT_SYMBOL(gsi_read_wdi3_channel_scratch2_reg);


int gsi_update_mhi_channel_scratch(unsigned long chan_hdl,
		struct __packed gsi_mhi_channel_scratch mscr)
{
+9 −20
Original line number Diff line number Diff line
@@ -908,9 +908,9 @@ int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id)
{
	int result = 0;
	struct ipa3_ep_context *ep;
	union __packed gsi_channel_scratch ch_scratch;
	union __packed gsi_wdi3_channel_scratch2_reg scratch2_reg;

	memset(&ch_scratch, 0, sizeof(ch_scratch));
	memset(&scratch2_reg, 0, sizeof(scratch2_reg));
	if (clnt_hdl >= ipa3_ctx->ipa_num_pipes ||
		ipa3_ctx->ep[clnt_hdl].valid == 0) {
		IPAERR_RL("bad parm, %d\n", clnt_hdl);
@@ -918,30 +918,19 @@ int ipa3_write_qmapid_wdi3_gsi_pipe(u32 clnt_hdl, u8 qmap_id)
	}
	ep = &ipa3_ctx->ep[clnt_hdl];
	IPA_ACTIVE_CLIENTS_INC_EP(ipa3_get_client_mapping(clnt_hdl));
	result = gsi_read_channel_scratch(ep->gsi_chan_hdl, &ch_scratch);

	if (result != GSI_STATUS_SUCCESS) {
		IPAERR("failed to read channel scratch %d\n", result);
		goto exit;
	}
	result = gsi_stop_channel(ep->gsi_chan_hdl);
	if (result != GSI_STATUS_SUCCESS && result != -GSI_STATUS_AGAIN &&
		result != -GSI_STATUS_TIMED_OUT) {
		IPAERR("failed to stop gsi channel %d\n", result);
		goto exit;
	}
	result = gsi_read_wdi3_channel_scratch2_reg(ep->gsi_chan_hdl,
			&scratch2_reg);

	ch_scratch.wdi3.qmap_id = qmap_id;
	result = gsi_write_channel_scratch(ep->gsi_chan_hdl,
			ch_scratch);
	if (result != GSI_STATUS_SUCCESS) {
		IPAERR("failed to write channel scratch %d\n", result);
		IPAERR("failed to read channel scratch2 reg %d\n", result);
		goto exit;
	}

	result =  gsi_start_channel(ep->gsi_chan_hdl);
	scratch2_reg.wdi.qmap_id = qmap_id;
	result = gsi_write_wdi3_channel_scratch2_reg(ep->gsi_chan_hdl,
			scratch2_reg);
	if (result != GSI_STATUS_SUCCESS) {
		IPAERR("failed to start gsi channel %d\n", result);
		IPAERR("failed to write channel scratch2 reg %d\n", result);
		goto exit;
	}

+63 −0
Original line number Diff line number Diff line
@@ -867,6 +867,43 @@ struct __packed gsi_wdi3_channel_scratch {
	uint32_t reserved2 : 16;
};

/**
 * gsi_wdi3_channel_scratch2 - WDI3 protocol SW config area of
 * channel scratch2
 *
 * @update_ri_moderation_threshold: Threshold N for Transfer ring Read Index
 *		N is the number of packets that IPA will
 *		process before Wifi transfer ring Ri will
 *		be updated.
 * @qmap_id: Rx only, used for setting metadata register in IPA. Read only
 *		field for MCS. Write for SW.
 * @resv: reserved bits.
 * @endp_metadata_reg_offset: Rx only, the offset of
 *		IPA_ENDP_INIT_HDR_METADATA_n of the
 *		corresponding endpoint in 4B words from IPA
 *		base address.
 */

struct __packed gsi_wdi3_channel_scratch2 {
	uint32_t update_rp_moderation_threshold : 5;
	uint32_t qmap_id : 8;
	uint32_t reserved1 : 3;
	uint32_t endp_metadata_reg_offset : 16;
};

/**
 * gsi_wdi3_channel_scratch2_reg - channel scratch2 SW config area
 *
 */

union __packed gsi_wdi3_channel_scratch2_reg {
	struct __packed gsi_wdi3_channel_scratch2 wdi;
	struct __packed {
		uint32_t word1;
	} data;
};


/**
 * gsi_channel_scratch - channel scratch SW config area
 *
@@ -1305,6 +1342,19 @@ int gsi_write_channel_scratch3_reg(unsigned long chan_hdl,
int gsi_write_channel_scratch2_reg(unsigned long chan_hdl,
		union __packed gsi_wdi2_channel_scratch2_reg val);

/**
 * gsi_write_wdi3_channel_scratch2_reg - Peripheral should call this function
 * to write to the WDI3 scratch 3 register area of the channel context
 *
 * @chan_hdl:  Client handle previously obtained from
 *             gsi_alloc_channel
 * @val:       Read value
 *
 * @Return gsi_status
 */
int gsi_write_wdi3_channel_scratch2_reg(unsigned long chan_hdl,
		union __packed gsi_wdi3_channel_scratch2_reg val);

/**
 * gsi_read_channel_scratch - Peripheral should call this function to
 * read to the scratch area of the channel context
@@ -1318,6 +1368,19 @@ int gsi_write_channel_scratch2_reg(unsigned long chan_hdl,
int gsi_read_channel_scratch(unsigned long chan_hdl,
		union __packed gsi_channel_scratch *val);

/**
 * gsi_read_wdi3_channel_scratch2_reg - Peripheral should call this function to
 * read to the WDI3 scratch 2 register area of the channel context
 *
 * @chan_hdl:  Client handle previously obtained from
 *             gsi_alloc_channel
 * @val:       Read value
 *
 * @Return gsi_status
 */
int gsi_read_wdi3_channel_scratch2_reg(unsigned long chan_hdl,
		union __packed gsi_wdi3_channel_scratch2_reg *val);

/**
 * gsi_update_mhi_channel_scratch - MHI Peripheral should call this
 * function to update the scratch area of the channel context. Updating