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

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

Merge "msm: kgsl: Limits Management support for A650"

parents 7a5974f9 e251f809
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3526,7 +3526,7 @@ 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;
				adj = 0;

			gpu_busy += adj;
		}
+7 −17
Original line number Diff line number Diff line
@@ -460,9 +460,6 @@ static void a6xx_start(struct adreno_device *adreno_dev)
	/* enable hardware clockgating */
	a6xx_hwcg_set(adreno_dev, true);

	if (ADRENO_FEATURE(adreno_dev, ADRENO_LM))
		adreno_dev->lm_threshold_count = A6XX_GMU_GENERAL_1;

	/* Set up VBIF registers from the GPU core definition */
	adreno_reglist_write(adreno_dev, a6xx_core->vbif,
		a6xx_core->vbif_count);
@@ -1105,13 +1102,19 @@ static int a6xx_soft_reset(struct adreno_device *adreno_dev)
	return 0;
}

/* Number of throttling counters for A6xx */
#define A6XX_GMU_THROTTLE_COUNTERS 3

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

	if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM))
		return 0;

	for (i = 0; i < ARRAY_SIZE(counts); i++) {
		if (!adreno_dev->gpmu_throttle_counters[i])
			counts[i] = 0;
@@ -1136,18 +1139,6 @@ static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev)
	return adj;
}

static void a6xx_count_throttles(struct adreno_device *adreno_dev,
	uint64_t adj)
{
	if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM) ||
		!test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag))
		return;

	gmu_core_regread(KGSL_DEVICE(adreno_dev),
		adreno_dev->lm_threshold_count,
		&adreno_dev->lm_threshold_cross);
}

/**
 * a6xx_reset() - Helper function to reset the GPU
 * @device: Pointer to the KGSL device structure for the GPU
@@ -2670,7 +2661,6 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
	.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,
	.llc_configure_gpu_scid = a6xx_llc_configure_gpu_scid,
+22 −70
Original line number Diff line number Diff line
@@ -1351,99 +1351,51 @@ static int a6xx_gmu_rpmh_gpu_pwrctrl(struct kgsl_device *device,
	return ret;
}

#define LM_DEFAULT_LIMIT	6000
#define GPU_LIMIT_THRESHOLD_ENABLE	BIT(31)

static uint32_t lm_limit(struct adreno_device *adreno_dev)
static int _setup_throttling_counter(struct adreno_device *adreno_dev,
						int countable, u32 *offset)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);

	if (adreno_dev->lm_limit)
		return adreno_dev->lm_limit;

	if (of_property_read_u32(device->pdev->dev.of_node, "qcom,lm-limit",
		&adreno_dev->lm_limit))
		adreno_dev->lm_limit = LM_DEFAULT_LIMIT;
	if (*offset)
		return 0;

	return adreno_dev->lm_limit;
	return adreno_perfcounter_get(adreno_dev,
			KGSL_PERFCOUNTER_GROUP_GPMU_PWR,
			countable, offset, NULL,
			PERFCOUNTER_FLAG_KERNEL);
}

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;
	int ret;

	for (i = 0; i < ARRAY_SIZE(a640_throttling_counters); i++) {
		adreno_dev->busy_data.throttle_cycles[i] = 0;
	ret = _setup_throttling_counter(adreno_dev, 0x10,
				&adreno_dev->gpmu_throttle_counters[0]);
	ret |= _setup_throttling_counter(adreno_dev, 0x15,
				&adreno_dev->gpmu_throttle_counters[1]);
	ret |= _setup_throttling_counter(adreno_dev, 0x19,
				&adreno_dev->gpmu_throttle_counters[2]);

		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]);
	}
}
			"Could not get all the throttling counters for LM\n");

#define LIMITS_CONFIG(t, s, c, i, a) ( \
		(t & 0xF) | \
		((s & 0xF) << 4) | \
		((c & 0xF) << 8) | \
		((i & 0xF) << 12) | \
		((a & 0xF) << 16))
}

void a6xx_gmu_enable_lm(struct kgsl_device *device)
{
	int result;
	struct gmu_device *gmu = KGSL_GMU_DEVICE(device);
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct device *dev = &gmu->pdev->dev;
	struct hfi_lmconfig_cmd cmd;

	memset(adreno_dev->busy_data.throttle_cycles, 0,
		sizeof(adreno_dev->busy_data.throttle_cycles));

	if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM) ||
			!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);
	gmu_core_regwrite(device, A6XX_GPU_GMU_CX_GMU_ISENSE_CTRL, 0x1);

	gmu->lm_config = LIMITS_CONFIG(1, 1, 1, 0, 0);
	gmu->bcl_config = 0;
	gmu->lm_dcvs_level = 0;

	cmd.limit_conf = gmu->lm_config;
	cmd.bcl_conf = gmu->bcl_config;
	cmd.lm_enable_bitmask = 0;

	if (gmu->lm_dcvs_level <= MAX_GX_LEVELS)
		cmd.lm_enable_bitmask =
			(1 << (gmu->lm_dcvs_level + 1)) - 1;

	result = hfi_send_req(gmu, H2F_MSG_LM_CFG, &cmd);
	if (result)
		dev_err(dev, "Failure enabling limits management:%d\n", result);
}

static int a6xx_gmu_ifpc_store(struct kgsl_device *device,
+0 −7
Original line number Diff line number Diff line
@@ -152,10 +152,6 @@ struct kgsl_mailbox {
 * @dump_mem: pointer to GMU debug dump memory
 * @gmu_log: gmu event log memory
 * @hfi: HFI controller
 * @lm_config: GPU LM configuration data
 * @lm_dcvs_level: Minimal DCVS level that enable LM. LM disable in
 *		lower levels
 * @bcl_config: Battery Current Limit configuration data
 * @gmu_freqs: GMU frequency table with lowest freq at index 0
 * @gpu_freqs: GPU frequency table with lowest freq at index 0
 * @num_gmupwrlevels: number GMU frequencies in GMU freq table
@@ -194,9 +190,6 @@ struct gmu_device {
	struct gmu_memdesc *dump_mem;
	struct gmu_memdesc *gmu_log;
	struct kgsl_hfi hfi;
	unsigned int lm_config;
	unsigned int lm_dcvs_level;
	unsigned int bcl_config;
	unsigned int gmu_freqs[MAX_CX_LEVELS];
	unsigned int gpu_freqs[MAX_GX_LEVELS];
	unsigned int num_gmupwrlevels;
+0 −7
Original line number Diff line number Diff line
@@ -776,13 +776,6 @@ void hfi_stop(struct gmu_device *gmu)
int hfi_send_req(struct gmu_device *gmu, unsigned int id, void *data)
{
	switch (id) {
	case H2F_MSG_LM_CFG: {
		struct hfi_lmconfig_cmd *cmd = data;

		cmd->hdr = CMD_MSG_HDR(H2F_MSG_LM_CFG, sizeof(*cmd));

		return hfi_send_generic_req(gmu, HFI_CMD_ID, &cmd);
	}
	case H2F_MSG_GX_BW_PERF_VOTE: {
		struct hfi_gx_bw_perf_vote_cmd *cmd = data;

Loading