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

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

Merge "msm: kgsl: Add support for Limits Management on A640"

parents bbb71613 679abd9d
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -3574,7 +3574,7 @@ static void adreno_power_stats(struct kgsl_device *device,
	struct adreno_gpudev *gpudev  = ADRENO_GPU_DEVICE(adreno_dev);
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct adreno_busy_data *busy = &adreno_dev->busy_data;
	uint64_t adj = 0;
	int64_t adj = 0;

	memset(stats, 0, sizeof(*stats));

@@ -3587,6 +3587,9 @@ static void adreno_power_stats(struct kgsl_device *device,

		if (gpudev->read_throttling_counters) {
			adj = gpudev->read_throttling_counters(adreno_dev);
			if (adj < 0 && -adj > gpu_busy)
				adj = -gpu_busy;

			gpu_busy += adj;
		}

+1 −1
Original line number Diff line number Diff line
@@ -967,7 +967,7 @@ struct adreno_gpudev {
	void (*pwrlevel_change_settings)(struct adreno_device *,
				unsigned int prelevel, unsigned int postlevel,
				bool post);
	uint64_t (*read_throttling_counters)(struct adreno_device *);
	int64_t (*read_throttling_counters)(struct adreno_device *);
	void (*count_throttles)(struct adreno_device *, uint64_t adj);
	int (*enable_pwr_counters)(struct adreno_device *,
				unsigned int counter);
+3 −2
Original line number Diff line number Diff line
@@ -1688,9 +1688,10 @@ static int a5xx_enable_pwr_counters(struct adreno_device *adreno_dev,
/* number of cycles when clock is throttle by less than 50% (CRC) */
#define CRC_LESS50PCT 3

static uint64_t a5xx_read_throttling_counters(struct adreno_device *adreno_dev)
static int64_t a5xx_read_throttling_counters(struct adreno_device *adreno_dev)
{
	int i, adj;
	int i;
	int64_t adj;
	uint32_t th[ADRENO_GPMU_THROTTLE_COUNTERS];
	struct adreno_busy_data *busy = &adreno_dev->busy_data;

+32 −0
Original line number Diff line number Diff line
@@ -1414,6 +1414,37 @@ static int a6xx_soft_reset(struct adreno_device *adreno_dev)
	return 0;
}

static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev)
{
	int i;
	int64_t adj = 0;
	uint32_t counts[ADRENO_GPMU_THROTTLE_COUNTERS];
	struct adreno_busy_data *busy = &adreno_dev->busy_data;

	for (i = 0; i < ARRAY_SIZE(counts); i++) {
		if (!adreno_dev->gpmu_throttle_counters[i])
			counts[i] = 0;
		else
			counts[i] = counter_delta(KGSL_DEVICE(adreno_dev),
					adreno_dev->gpmu_throttle_counters[i],
					&busy->throttle_cycles[i]);
	}

	/*
	 * The adjustment is the number of cycles lost to throttling, which
	 * is calculated as a weighted average of the cycles throttled
	 * at 10%, 50%, and 90%. The adjustment is negative because in A6XX,
	 * the busy count includes the throttled cycles. Therefore, we want
	 * to remove them to prevent appearing to be busier than
	 * we actually are.
	 */
	adj = -((counts[0] * 1) + (counts[1] * 5) + (counts[2] * 9)) / 10;

	trace_kgsl_clock_throttling(0, counts[1], counts[2],
			counts[0], adj);
	return adj;
}

static void a6xx_count_throttles(struct adreno_device *adreno_dev,
	uint64_t adj)
{
@@ -2951,6 +2982,7 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
	.regulator_disable = a6xx_sptprac_disable,
	.perfcounters = &a6xx_perfcounters,
	.enable_pwr_counters = a6xx_enable_pwr_counters,
	.read_throttling_counters = a6xx_read_throttling_counters,
	.count_throttles = a6xx_count_throttles,
	.microcode_read = a6xx_microcode_read,
	.enable_64bit = a6xx_enable_64bit,
+37 −0
Original line number Diff line number Diff line
@@ -1259,6 +1259,37 @@ static uint32_t lm_limit(struct adreno_device *adreno_dev)
	return adreno_dev->lm_limit;
}

static int a640_throttling_counters[ADRENO_GPMU_THROTTLE_COUNTERS] = {
	0x11, 0x15, 0x19
};

static void _setup_throttling_counters(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct gmu_device *gmu = KGSL_GMU_DEVICE(device);
	int i, ret;

	for (i = 0; i < ARRAY_SIZE(a640_throttling_counters); i++) {
		adreno_dev->busy_data.throttle_cycles[i] = 0;

		if (!a640_throttling_counters[i])
			continue;
		if (adreno_dev->gpmu_throttle_counters[i])
			continue;

		ret = adreno_perfcounter_get(adreno_dev,
				KGSL_PERFCOUNTER_GROUP_GPMU_PWR,
				a640_throttling_counters[i],
				&adreno_dev->gpmu_throttle_counters[i],
				NULL,
				PERFCOUNTER_FLAG_KERNEL);
		if (ret)
			dev_err_once(&gmu->pdev->dev,
				"Unable to get counter for LM: GPMU_PWR %d\n",
				a640_throttling_counters[i]);
	}
}

#define LIMITS_CONFIG(t, s, c, i, a) ( \
		(t & 0xF) | \
		((s & 0xF) << 4) | \
@@ -1278,6 +1309,12 @@ void a6xx_gmu_enable_lm(struct kgsl_device *device)
			!test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
		return;

	/* a640 only needs to set up throttling counters for DCVS */
	if (adreno_is_a640(adreno_dev)) {
		_setup_throttling_counters(adreno_dev);
		return;
	}

	gmu_core_regwrite(device, A6XX_GPU_GMU_CX_GMU_PWR_THRESHOLD,
		GPU_LIMIT_THRESHOLD_ENABLE | lm_limit(adreno_dev));
	gmu_core_regwrite(device, A6XX_GMU_AO_SPARE_CNTL, 1);
Loading