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

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

Merge "msm: gsi: add support for h/w smart prefetch"

parents 0bf00b60 96b0ea90
Loading
Loading
Loading
Loading
+54 −13
Original line number Diff line number Diff line
@@ -1623,6 +1623,56 @@ int gsi_set_evt_ring_cfg(unsigned long evt_ring_hdl,
}
EXPORT_SYMBOL(gsi_set_evt_ring_cfg);

static void gsi_program_chan_ctx_qos(struct gsi_chan_props *props,
	unsigned int ee)
{
	uint32_t val;

	val =
	(((props->low_weight <<
		GSI_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_SHFT) &
		GSI_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_BMSK) |
	((props->max_prefetch <<
		 GSI_EE_n_GSI_CH_k_QOS_MAX_PREFETCH_SHFT) &
		 GSI_EE_n_GSI_CH_k_QOS_MAX_PREFETCH_BMSK) |
	((props->use_db_eng <<
		GSI_EE_n_GSI_CH_k_QOS_USE_DB_ENG_SHFT) &
		 GSI_EE_n_GSI_CH_k_QOS_USE_DB_ENG_BMSK));
	if (gsi_ctx->per.ver >= GSI_VER_2_0)
		val |= ((props->prefetch_mode <<
			GSI_EE_n_GSI_CH_k_QOS_USE_ESCAPE_BUF_ONLY_SHFT)
			& GSI_EE_n_GSI_CH_k_QOS_USE_ESCAPE_BUF_ONLY_BMSK);

	gsi_writel(val, gsi_ctx->base +
			GSI_EE_n_GSI_CH_k_QOS_OFFS(props->ch_id, ee));
}

static void gsi_program_chan_ctx_qos_v2_5(struct gsi_chan_props *props,
	unsigned int ee)
{
	uint32_t val;

	val =
	(((props->low_weight <<
		GSI_V2_5_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_SHFT) &
		GSI_V2_5_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_BMSK) |
	((props->max_prefetch <<
		 GSI_V2_5_EE_n_GSI_CH_k_QOS_MAX_PREFETCH_SHFT) &
		 GSI_V2_5_EE_n_GSI_CH_k_QOS_MAX_PREFETCH_BMSK) |
	((props->use_db_eng <<
		GSI_V2_5_EE_n_GSI_CH_k_QOS_USE_DB_ENG_SHFT) &
		GSI_V2_5_EE_n_GSI_CH_k_QOS_USE_DB_ENG_BMSK) |
	((props->prefetch_mode <<
		GSI_V2_5_EE_n_GSI_CH_k_QOS_PREFETCH_MODE_SHFT) &
		GSI_V2_5_EE_n_GSI_CH_k_QOS_PREFETCH_MODE_BMSK) |
	((props->empty_lvl_threshold <<
		GSI_V2_5_EE_n_GSI_CH_k_QOS_EMPTY_LVL_THRSHOLD_SHFT) &
		GSI_V2_5_EE_n_GSI_CH_k_QOS_EMPTY_LVL_THRSHOLD_BMSK));

	gsi_writel(val, gsi_ctx->base +
			GSI_V2_5_EE_n_GSI_CH_k_QOS_OFFS(props->ch_id, ee));
}

static void gsi_program_chan_ctx(struct gsi_chan_props *props, unsigned int ee,
		uint8_t erindex)
{
@@ -1656,19 +1706,10 @@ static void gsi_program_chan_ctx(struct gsi_chan_props *props, unsigned int ee,
	gsi_writel(val, gsi_ctx->base +
			GSI_EE_n_GSI_CH_k_CNTXT_3_OFFS(props->ch_id, ee));

	val = (((props->low_weight << GSI_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_SHFT) &
				GSI_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_BMSK) |
		((props->max_prefetch <<
			 GSI_EE_n_GSI_CH_k_QOS_MAX_PREFETCH_SHFT) &
			 GSI_EE_n_GSI_CH_k_QOS_MAX_PREFETCH_BMSK) |
		((props->use_db_eng << GSI_EE_n_GSI_CH_k_QOS_USE_DB_ENG_SHFT) &
			 GSI_EE_n_GSI_CH_k_QOS_USE_DB_ENG_BMSK));
	if (gsi_ctx->per.ver >= GSI_VER_2_0)
		val |= ((props->prefetch_mode <<
			GSI_EE_n_GSI_CH_k_QOS_USE_ESCAPE_BUF_ONLY_SHFT)
			& GSI_EE_n_GSI_CH_k_QOS_USE_ESCAPE_BUF_ONLY_BMSK);
	gsi_writel(val, gsi_ctx->base +
			GSI_EE_n_GSI_CH_k_QOS_OFFS(props->ch_id, ee));
	if (gsi_ctx->per.ver >= GSI_VER_2_5)
		gsi_program_chan_ctx_qos_v2_5(props, ee);
	else
		gsi_program_chan_ctx_qos(props, ee);
}

static void gsi_init_chan_ring(struct gsi_chan_props *props,
+7 −2
Original line number Diff line number Diff line
@@ -220,8 +220,13 @@ static ssize_t gsi_dump_ch(struct file *file,
		GSI_EE_n_GSI_CH_k_RE_FETCH_WRITE_PTR_OFFS(arg1,
			gsi_ctx->per.ee));
	TERR("CH%2d REFWP 0x%x\n", arg1, val);
	if (gsi_ctx->per.ver >= GSI_VER_2_5) {
		val = gsi_readl(gsi_ctx->base +
			GSI_V2_5_EE_n_GSI_CH_k_QOS_OFFS(arg1, gsi_ctx->per.ee));
	} else {
		val = gsi_readl(gsi_ctx->base +
			GSI_EE_n_GSI_CH_k_QOS_OFFS(arg1, gsi_ctx->per.ee));
	}
	TERR("CH%2d QOS   0x%x\n", arg1, val);
	val = gsi_readl(gsi_ctx->base +
		GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(arg1, gsi_ctx->per.ee));
+14 −0
Original line number Diff line number Diff line
@@ -1144,6 +1144,20 @@
#define GSI_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_BMSK 0xf
#define GSI_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_SHFT 0x0

#define GSI_V2_5_EE_n_GSI_CH_k_QOS_OFFS(k, n) \
	(GSI_GSI_REG_BASE_OFFS + 0x0000f05c + 0x4000 * (n) + 0x80 * (k))
#define GSI_V2_5_EE_n_GSI_CH_k_QOS_EMPTY_LVL_THRSHOLD_BMSK 0xff0000
#define GSI_V2_5_EE_n_GSI_CH_k_QOS_EMPTY_LVL_THRSHOLD_SHFT 0x10
#define GSI_V2_5_EE_n_GSI_CH_k_QOS_PREFETCH_MODE_BMSK 0x3c00
#define GSI_V2_5_EE_n_GSI_CH_k_QOS_PREFETCH_MODE_SHFT 0xa
#define GSI_V2_5_EE_n_GSI_CH_k_QOS_USE_DB_ENG_BMSK 0x200
#define GSI_V2_5_EE_n_GSI_CH_k_QOS_USE_DB_ENG_SHFT 0x9
#define GSI_V2_5_EE_n_GSI_CH_k_QOS_MAX_PREFETCH_BMSK 0x100
#define GSI_V2_5_EE_n_GSI_CH_k_QOS_MAX_PREFETCH_SHFT 0x8
#define GSI_V2_5_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_BMSK 0xf
#define GSI_V2_5_EE_n_GSI_CH_k_QOS_WRR_WEIGHT_SHFT 0x0


#define GSI_EE_n_GSI_CH_k_SCRATCH_0_OFFS(k, n) \
	(GSI_GSI_REG_BASE_OFFS + 0x0001c060 + 0x4000 * (n) + 0x80 * (k))
#define GSI_EE_n_GSI_CH_k_SCRATCH_0_RMSK 0xffffffff
+18 −1
Original line number Diff line number Diff line
@@ -221,9 +221,19 @@ enum gsi_max_prefetch {
	GSI_TWO_PREFETCH_SEG = 0x1
};

/**
 * @GSI_USE_PREFETCH_BUFS: Channel will use normal prefetch buffers if possible
 * @GSI_ESCAPE_BUF_ONLY: Channel will always use escape buffers only
 * @GSI_SMART_PRE_FETCH: Channel will work in smart prefetch mode.
 *	relevant starting GSI 2.5
 * @GSI_FREE_PRE_FETCH: Channel will work in free prefetch mode.
 *	relevant starting GSI 2.5
 */
enum gsi_prefetch_mode {
	GSI_USE_PREFETCH_BUFS = 0x0,
	GSI_ESCAPE_BUF_ONLY = 0x1
	GSI_ESCAPE_BUF_ONLY = 0x1,
	GSI_SMART_PRE_FETCH = 0x2,
	GSI_FREE_PRE_FETCH = 0x3,
};

enum gsi_chan_evt {
@@ -315,6 +325,12 @@ enum gsi_chan_use_db_eng {
 * @max_prefetch:    limit number of pre-fetch segments for channel
 * @low_weight:      low channel weight (priority of channel for RE engine
 *                   round robin algorithm); must be >= 1
 * @empty_lvl_threshold:
 *                   The thershold number of free entries available in the
 *                   receiving fifos of GSI-peripheral. If Smart PF mode
 *                   is used, REE will fetch/send new TRE to peripheral only
 *                   if peripheral's empty_level_count is higher than
 *                   EMPTY_LVL_THRSHOLD defined for this channel
 * @xfer_cb:         transfer notification callback, this callback happens
 *                   on event boundaries
 *
@@ -365,6 +381,7 @@ struct gsi_chan_props {
	enum gsi_max_prefetch max_prefetch;
	uint8_t low_weight;
	enum gsi_prefetch_mode prefetch_mode;
	uint8_t empty_lvl_threshold;
	void (*xfer_cb)(struct gsi_chan_xfer_notify *notify);
	void (*err_cb)(struct gsi_chan_err_notify *notify);
	void *chan_user_data;