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

Commit f1af104b authored by Abhilash Kumar's avatar Abhilash Kumar Committed by Gerrit - the friendly Code Review server
Browse files

msm: kgsl: Set the abnormal power perf counter value to zero



During preemption microcode does save restore for all perf
counters. If we read the power counters at preemption boundary
we might get abnormal value from the perf counter. This will
result in showing incorrect GPU busy percentage. Fix this by
setting the abnormal power perf counter value with zero.

Change-Id: I96ba367ceeeb92d6adb507d0d917113297b4b58d
Signed-off-by: default avatarAbhilash Kumar <krabhi@codeaurora.org>
parent f5d98565
Loading
Loading
Loading
Loading
+44 −3
Original line number Diff line number Diff line
@@ -621,6 +621,8 @@ enum adreno_regs {
	ADRENO_REG_RBBM_RBBM_CTL,
	ADRENO_REG_UCHE_INVALIDATE0,
	ADRENO_REG_UCHE_INVALIDATE1,
	ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO,
	ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI,
	ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
	ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
	ADRENO_REG_RBBM_SECVID_TRUST_CONTROL,
@@ -1697,21 +1699,60 @@ static inline void adreno_ringbuffer_set_pagetable(struct adreno_ringbuffer *rb,
	spin_unlock_irqrestore(&rb->preempt_lock, flags);
}

static inline bool is_power_counter_overflow(struct adreno_device *adreno_dev,
	unsigned int reg, unsigned int prev_val, unsigned int *perfctr_pwr_hi)
{
	unsigned int val;
	bool ret = false;

	/*
	 * If prev_val is zero, it is first read after perf counter reset.
	 * So set perfctr_pwr_hi register to zero.
	 */
	if (prev_val == 0) {
		*perfctr_pwr_hi = 0;
		return ret;
	}
	adreno_readreg(adreno_dev, ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI, &val);
	if (val != *perfctr_pwr_hi) {
		*perfctr_pwr_hi = val;
		ret = true;
	}
	return ret;
}

static inline unsigned int counter_delta(struct kgsl_device *device,
			unsigned int reg, unsigned int *counter)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned int val;
	unsigned int ret = 0;
	bool overflow = true;
	static unsigned int perfctr_pwr_hi;

	/* Read the value */
	kgsl_regread(device, reg, &val);

	if (adreno_is_a5xx(adreno_dev) && reg == adreno_getreg
		(adreno_dev, ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO))
		overflow = is_power_counter_overflow(adreno_dev, reg,
				*counter, &perfctr_pwr_hi);

	/* Return 0 for the first read */
	if (*counter != 0) {
		if (val < *counter)
			ret = (0xFFFFFFFF - *counter) + val;
		else
		if (val >= *counter) {
			ret = val - *counter;
		} else if (overflow == true) {
			ret = (0xFFFFFFFF - *counter) + val;
		} else {
			/*
			 * Since KGSL got abnormal value from the counter,
			 * We will drop the value from being accumulated.
			 */
			pr_warn_once("KGSL: Abnormal value :0x%x (0x%x) from perf counter : 0x%x\n",
					val, *counter, reg);
			return 0;
		}
	}

	*counter = val;
+4 −0
Original line number Diff line number Diff line
@@ -1533,6 +1533,10 @@ static unsigned int a3xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
			A3XX_UCHE_CACHE_INVALIDATE0_REG),
	ADRENO_REG_DEFINE(ADRENO_REG_UCHE_INVALIDATE1,
			A3XX_UCHE_CACHE_INVALIDATE1_REG),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO,
			A3XX_RBBM_PERFCTR_RBBM_0_LO),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI,
			A3XX_RBBM_PERFCTR_RBBM_0_HI),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
				A3XX_RBBM_PERFCTR_LOAD_VALUE_LO),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
+4 −0
Original line number Diff line number Diff line
@@ -808,6 +808,10 @@ static unsigned int a4xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_SW_RESET_CMD, A4XX_RBBM_SW_RESET_CMD),
	ADRENO_REG_DEFINE(ADRENO_REG_UCHE_INVALIDATE0, A4XX_UCHE_INVALIDATE0),
	ADRENO_REG_DEFINE(ADRENO_REG_UCHE_INVALIDATE1, A4XX_UCHE_INVALIDATE1),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO,
				A4XX_RBBM_PERFCTR_RBBM_0_LO),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI,
				A4XX_RBBM_PERFCTR_RBBM_0_HI),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
				A4XX_RBBM_PERFCTR_LOAD_VALUE_LO),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
+4 −0
Original line number Diff line number Diff line
@@ -2998,6 +2998,10 @@ static unsigned int a5xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
		ADRENO_REG_DEFINE(ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD2,
					  A5XX_RBBM_BLOCK_SW_RESET_CMD2),
	ADRENO_REG_DEFINE(ADRENO_REG_UCHE_INVALIDATE0, A5XX_UCHE_INVALIDATE0),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO,
				A5XX_RBBM_PERFCTR_RBBM_0_LO),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI,
				A5XX_RBBM_PERFCTR_RBBM_0_HI),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
				A5XX_RBBM_PERFCTR_LOAD_VALUE_LO),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,