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

Commit d9ba4d25 authored by Oleg Perelet's avatar Oleg Perelet
Browse files

msm: kgsl: Provide support for Limits Management upper value



Create dtsi entry for Limits Management value. Expose debugfs
inode 'lm_limit' for changing upper limit value in mA on the fly:
echo 2000 > lm_limit

Change-Id: Ia1be13e153bb1ac3eb1449817e1edf1b6c48c4cf
Signed-off-by: default avatarOleg Perelet <operelet@codeaurora.org>
parent 3380d16c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ Required properties:

- qcom,gpu-efuse-leakage:	memory region for GPU power rail leakage.
- qcom,base-leakage-coefficient: Dynamic leakage coefficient.
- qcom,lm-limit:	Current limit for GPU limit management.

Bus Scaling Data:
- qcom,msm-bus,name: String property to describe the name of the 3D graphics processor.
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@
		qcom,chipid = <0x05030000>;
		qcom,gpu-efuse-leakage = <0x00070130 24>;
		qcom,base-leakage-coefficient = <34>;
		qcom,lm-limit = <6000>;

		qcom,initial-pwrlevel = <2>;

+2 −0
Original line number Diff line number Diff line
@@ -290,6 +290,7 @@ struct adreno_gpu_core {
 * @lm_fw: The LM firmware handle
 * @lm_sequence: Pointer to the start of the register write sequence for LM
 * @lm_size: The dword size of the LM sequence
 * @lm_limit: limiting value for LM
 */
struct adreno_device {
	struct kgsl_device dev;    /* Must be first field in this struct */
@@ -341,6 +342,7 @@ struct adreno_device {
	struct kgsl_memdesc preemption_counters;
	struct work_struct gpmu_work;
	uint32_t lm_leakage;
	uint32_t lm_limit;

	struct kgsl_memdesc capturescript;
	struct kgsl_memdesc snapshot_registers;
+17 −1
Original line number Diff line number Diff line
@@ -102,6 +102,8 @@ static void a5xx_gpmu_reset(struct work_struct *work);
#define AGC_POWER_CONFIG_PRODUCTION_ID	1

#define GFX_DEFAULT_LEAKAGE 0x004E001A
#define LM_DEFAULT_LIMIT    6000


/*
 * a5xx_preemption_start() - Setup state to start preemption
@@ -1365,6 +1367,19 @@ static uint32_t gfx_base_leakage(struct adreno_device *adreno_dev)
	return adreno_dev->lm_leakage;
}

static uint32_t lm_limit(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = &adreno_dev->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;

	return adreno_dev->lm_limit;
}
/*
 * a5xx_lm_init() - Initialize LM/DPM on the GPMU
 * @adreno_dev: The adreno device pointer
@@ -1404,7 +1419,8 @@ static void a5xx_lm_init(struct adreno_device *adreno_dev)
		gfx_base_leakage(adreno_dev));

	/* Enable the power threshold and set it to 6000m */
	kgsl_regwrite(device, A5XX_GPMU_GPMU_PWR_THRESHOLD, 0x80000000 | 6000);
	kgsl_regwrite(device, A5XX_GPMU_GPMU_PWR_THRESHOLD,
		0x80000000 | lm_limit(adreno_dev));

	kgsl_regwrite(device, A5XX_GPMU_BEC_ENABLE, 0x10001FFF);
	kgsl_regwrite(device, A5XX_GDPM_CONFIG1, 0x00201FF1);
+44 −0
Original line number Diff line number Diff line
@@ -57,6 +57,46 @@ static int _isdb_get(void *data, u64 *val)

DEFINE_SIMPLE_ATTRIBUTE(_isdb_fops, _isdb_get, _isdb_set, "%llu\n");

static int _lm_limit_set(void *data, u64 val)
{
	struct kgsl_device *device = data;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

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

	/* assure value is between 3A and 10A */
	if (val > 10000)
		val = 10000;
	else if (val < 3000)
		val = 3000;

	adreno_dev->lm_limit = val;

	if (test_bit(ADRENO_LM_CTRL, &adreno_dev->pwrctrl_flag)) {
		mutex_lock(&device->mutex);
		kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND);
		kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);
		mutex_unlock(&device->mutex);
	}

	return 0;
}

static int _lm_limit_get(void *data, u64 *val)
{
	struct kgsl_device *device = data;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	if (!ADRENO_FEATURE(adreno_dev, ADRENO_LM))
		*val = 0;

	*val = (u64) adreno_dev->lm_limit;
	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(_lm_limit_fops, _lm_limit_get, _lm_limit_set, "%llu\n");

static int _active_count_get(void *data, u64 *val)
{
	struct kgsl_device *device = data;
@@ -308,6 +348,10 @@ void adreno_debugfs_init(struct adreno_device *adreno_dev)
	adreno_dev->ctx_d_debugfs = debugfs_create_dir("ctx",
							device->d_debugfs);

	if (ADRENO_FEATURE(adreno_dev, ADRENO_LM))
		debugfs_create_file("lm_limit", 0644, device->d_debugfs, device,
			&_lm_limit_fops);

	if (adreno_is_a5xx(adreno_dev))
		debugfs_create_file("isdb", 0644, device->d_debugfs,
			device, &_isdb_fops);