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

Commit 4e994b95 authored by Kyle Yan's avatar Kyle Yan Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: gsi: reduce register accesses on data path" into msm-4.9

parents 8f452229 8568eb9e
Loading
Loading
Loading
Loading
+43 −30
Original line number Diff line number Diff line
@@ -415,6 +415,16 @@ static void gsi_ring_chan_doorbell(struct gsi_chan_ctx *ctx)
{
	uint32_t val;

	/*
	 * allocate new events for this channel first
	 * before submitting the new TREs.
	 * for TO_GSI channels the event ring doorbell is rang as part of
	 * interrupt handling.
	 */
	if (ctx->evtr && ctx->props.dir == GSI_CHAN_DIR_FROM_GSI)
		gsi_ring_evt_doorbell(ctx->evtr);
	ctx->ring.wp = ctx->ring.wp_local;

	/* write order MUST be MSB followed by LSB */
	val = ((ctx->ring.wp_local >> 32) &
			GSI_EE_n_GSI_CH_k_DOORBELL_1_WRITE_PTR_MSB_BMSK) <<
@@ -470,8 +480,8 @@ static void gsi_handle_ieob(int ee)
			cntr = 0;
			rp = gsi_readl(gsi_ctx->base +
				GSI_EE_n_EV_CH_k_CNTXT_4_OFFS(i, ee));
			rp |= ((uint64_t)gsi_readl(gsi_ctx->base +
				GSI_EE_n_EV_CH_k_CNTXT_5_OFFS(i, ee))) << 32;
			rp |= ctx->ring.rp & 0xFFFFFFFF00000000;

			ctx->ring.rp = rp;
			while (ctx->ring.rp_local != rp) {
				++cntr;
@@ -1529,6 +1539,7 @@ static void gsi_init_chan_ring(struct gsi_chan_props *props,
static int gsi_validate_channel_props(struct gsi_chan_props *props)
{
	uint64_t ra;
	uint64_t last;

	if (props->ch_id >= gsi_ctx->max_ch) {
		GSIERR("ch_id %u invalid\n", props->ch_id);
@@ -1556,6 +1567,17 @@ static int gsi_validate_channel_props(struct gsi_chan_props *props)
		return -GSI_STATUS_INVALID_PARAMS;
	}

	last = props->ring_base_addr + props->ring_len - props->re_size;

	/* MSB should stay same within the ring */
	if ((props->ring_base_addr & 0xFFFFFFFF00000000ULL) !=
	    (last & 0xFFFFFFFF00000000ULL)) {
		GSIERR("MSB is not fixed on ring base 0x%llx size 0x%x\n",
			props->ring_base_addr,
			props->ring_len);
		return -GSI_STATUS_INVALID_PARAMS;
	}

	if (props->prot == GSI_CHAN_PROT_GPI &&
			!props->ring_base_vaddr) {
		GSIERR("protocol %u requires ring base VA\n", props->prot);
@@ -2128,29 +2150,22 @@ static void __gsi_query_channel_free_re(struct gsi_chan_ctx *ctx,
		uint16_t *num_free_re)
{
	uint16_t start;
	uint16_t start_hw;
	uint16_t end;
	uint64_t rp;
	uint64_t rp_hw;
	int ee = gsi_ctx->per.ee;
	uint16_t used;
	uint16_t used_hw;

	rp_hw = gsi_readl(gsi_ctx->base +
	if (!ctx->evtr) {
		rp = gsi_readl(gsi_ctx->base +
			GSI_EE_n_GSI_CH_k_CNTXT_4_OFFS(ctx->props.ch_id, ee));
	rp_hw |= ((uint64_t)gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_CNTXT_5_OFFS(ctx->props.ch_id, ee)))
		<< 32;
		rp |= ctx->ring.rp & 0xFFFFFFFF00000000;

	if (!ctx->evtr) {
		rp = rp_hw;
		ctx->ring.rp = rp;
	} else {
		rp = ctx->ring.rp_local;
	}

	start = gsi_find_idx_from_addr(&ctx->ring, rp);
	start_hw = gsi_find_idx_from_addr(&ctx->ring, rp_hw);
	end = gsi_find_idx_from_addr(&ctx->ring, ctx->ring.wp_local);

	if (end >= start)
@@ -2158,13 +2173,7 @@ static void __gsi_query_channel_free_re(struct gsi_chan_ctx *ctx,
	else
		used = ctx->ring.max_num_elem + 1 - (start - end);

	if (end >= start_hw)
		used_hw = end - start_hw;
	else
		used_hw = ctx->ring.max_num_elem + 1 - (start_hw - end);

	*num_free_re = ctx->ring.max_num_elem - used;
	gsi_update_ch_dp_stats(ctx, used_hw);
}

int gsi_query_channel_info(unsigned long chan_hdl,
@@ -2274,14 +2283,12 @@ int gsi_is_channel_empty(unsigned long chan_hdl, bool *is_empty)

	rp = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_CNTXT_4_OFFS(ctx->props.ch_id, ee));
	rp |= ((uint64_t)gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_CNTXT_5_OFFS(ctx->props.ch_id, ee))) << 32;
	rp |= ctx->ring.rp & 0xFFFFFFFF00000000;
	ctx->ring.rp = rp;

	wp = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_CNTXT_6_OFFS(ctx->props.ch_id, ee));
	wp |= ((uint64_t)gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_CNTXT_7_OFFS(ctx->props.ch_id, ee))) << 32;
	wp |= ctx->ring.wp & 0xFFFFFFFF00000000;
	ctx->ring.wp = wp;

	if (ctx->props.dir == GSI_CHAN_DIR_FROM_GSI)
@@ -2420,6 +2427,9 @@ int gsi_start_xfer(unsigned long chan_hdl)
		return -GSI_STATUS_UNSUPPORTED_OP;
	}

	if (ctx->ring.wp == ctx->ring.wp_local)
		return GSI_STATUS_SUCCESS;

	gsi_ring_chan_doorbell(ctx);

	return GSI_STATUS_SUCCESS;
@@ -2457,19 +2467,22 @@ int gsi_poll_channel(unsigned long chan_hdl,
	}

	spin_lock_irqsave(&ctx->evtr->ring.slock, flags);
	if (ctx->evtr->ring.rp == ctx->evtr->ring.rp_local) {
		/* update rp to see of we have anything new to process */
		rp = gsi_readl(gsi_ctx->base +
			GSI_EE_n_EV_CH_k_CNTXT_4_OFFS(ctx->evtr->id, ee));
	rp |= ((uint64_t)gsi_readl(gsi_ctx->base +
		GSI_EE_n_EV_CH_k_CNTXT_5_OFFS(ctx->evtr->id, ee))) << 32;
		rp |= ctx->ring.rp & 0xFFFFFFFF00000000;

		ctx->evtr->ring.rp = rp;
	if (rp == ctx->evtr->ring.rp_local) {
	}

	if (ctx->evtr->ring.rp == ctx->evtr->ring.rp_local) {
		spin_unlock_irqrestore(&ctx->evtr->ring.slock, flags);
		ctx->stats.poll_empty++;
		return GSI_STATUS_POLL_EMPTY;
	}

	gsi_process_evt_re(ctx->evtr, notify, false);
	gsi_ring_evt_doorbell(ctx->evtr);
	spin_unlock_irqrestore(&ctx->evtr->ring.slock, flags);
	ctx->stats.poll_ok++;

+1 −7
Original line number Diff line number Diff line
@@ -490,11 +490,6 @@ static ssize_t gsi_enable_dp_stats(struct file *file,
		goto error;
	}

	if (gsi_ctx->chan[ch_id].props.prot == GSI_CHAN_PROT_GPI) {
		TERR("valid for non GPI channels only\n");
		goto error;
	}

	if (gsi_ctx->chan[ch_id].enable_dp_stats == enable) {
		TERR("ch_%d: already enabled/disabled\n", ch_id);
		return -EFAULT;
@@ -631,7 +626,7 @@ static void gsi_dbg_update_ch_dp_stats(struct gsi_chan_ctx *ctx)
	else
		used_hw = ctx->ring.max_num_elem + 1 - (start_hw - end_hw);

	TERR("ch %d used %d\n", ctx->props.ch_id, used_hw);
	TDBG("ch %d used %d\n", ctx->props.ch_id, used_hw);
	gsi_update_ch_dp_stats(ctx, used_hw);
}

@@ -641,7 +636,6 @@ static void gsi_wq_update_dp_stats(struct work_struct *work)

	for (ch_id = 0; ch_id < gsi_ctx->max_ch; ch_id++) {
		if (gsi_ctx->chan[ch_id].allocated &&
		    gsi_ctx->chan[ch_id].props.prot != GSI_CHAN_PROT_GPI &&
		    gsi_ctx->chan[ch_id].enable_dp_stats)
			gsi_dbg_update_ch_dp_stats(&gsi_ctx->chan[ch_id]);
	}