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

Commit c5b0fe8f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Disable GPU isense clock below nominal power level"

parents d487ef9a fb1c6ee3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ Required properties:

- qcom,base-leakage-coefficient: Dynamic leakage coefficient.
- qcom,lm-limit:	Current limit for GPU limit management.
- qcom,isense-clk-on-level: below or equal this power level isense clock is at XO rate,
				above this powerlevel isense clock is at working frequency.

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
@@ -91,6 +91,7 @@
			"mem_clk", "mem_iface_clk", "isense_clk", "rbcpr_clk",
			"iref_clk";

		qcom,isense-clk-on-level = <1>;
		/* Bus Scale Settings */
		qcom,gpubw-dev = <&gpubw>;
		qcom,bus-control;
+34 −5
Original line number Diff line number Diff line
@@ -81,6 +81,8 @@ static void kgsl_pwrctrl_set_state(struct kgsl_device *device,
static void kgsl_pwrctrl_request_state(struct kgsl_device *device,
				unsigned int state);
static void kgsl_pwrctrl_retention_clk(struct kgsl_device *device, int state);
static int _isense_clk_set_rate(struct kgsl_pwrctrl *pwr, int level);


/**
 * _record_pwrevent() - Record the history of the new event
@@ -387,6 +389,8 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device,
	/* Change register settings if any  BEFORE pwrlevel change*/
	kgsl_pwrctrl_pwrlevel_change_settings(device, 0);
	clk_set_rate(pwr->grp_clks[0], pwrlevel->gpu_freq);
	_isense_clk_set_rate(pwr, pwr->active_pwrlevel);

	trace_kgsl_pwrlevel(device,
			pwr->active_pwrlevel, pwrlevel->gpu_freq,
			pwr->previous_pwrlevel,
@@ -1374,15 +1378,20 @@ static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state,
				clk_set_rate(pwr->grp_clks[0],
					pwr->pwrlevels[pwr->num_pwrlevels - 1].
					gpu_freq);
				_isense_clk_set_rate(pwr,
					pwr->num_pwrlevels - 1);
			}
		} else if (requested_state == KGSL_STATE_SLEEP) {
			/* High latency clock maintenance. */
			for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
				clk_unprepare(pwr->grp_clks[i]);
			if ((pwr->pwrlevels[0].gpu_freq > 0))
			if ((pwr->pwrlevels[0].gpu_freq > 0)) {
				clk_set_rate(pwr->grp_clks[0],
					pwr->pwrlevels[pwr->num_pwrlevels - 1].
					gpu_freq);
				_isense_clk_set_rate(pwr,
					pwr->num_pwrlevels - 1);
			}
		}
	} else if (state == KGSL_PWRFLAGS_ON) {
		if (!test_and_set_bit(KGSL_PWRFLAGS_CLK_ON,
@@ -1392,11 +1401,15 @@ static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state,
			/* High latency clock maintenance. */
			if ((device->state != KGSL_STATE_NAP) &&
			(device->state != KGSL_STATE_DEEP_NAP)) {
				if (pwr->pwrlevels[0].gpu_freq > 0)
				if (pwr->pwrlevels[0].gpu_freq > 0) {
					clk_set_rate(pwr->grp_clks[0],
						pwr->pwrlevels
						[pwr->active_pwrlevel].
						gpu_freq);
					_isense_clk_set_rate(pwr,
						pwr->active_pwrlevel);
				}

				for (i = KGSL_MAX_CLKS - 1; i > 0; i--)
					clk_prepare(pwr->grp_clks[i]);
			}
@@ -1720,9 +1733,27 @@ static int _get_clocks(struct kgsl_device *device)
		}
	}

	if (pwr->isense_clk_indx && of_property_read_u32(dev->of_node,
		"qcom,isense-clk-on-level", &pwr->isense_clk_on_level)) {
		KGSL_CORE_ERR("Couldn't get isense clock on level\n");
		return -ENXIO;
	}
	return 0;
}

static int _isense_clk_set_rate(struct kgsl_pwrctrl *pwr, int level)
{
	int rate;

	if (!pwr->isense_clk_indx)
		return -EINVAL;

	rate = clk_round_rate(pwr->grp_clks[pwr->isense_clk_indx],
		level > pwr->isense_clk_on_level ?
		KGSL_XO_CLK_FREQ : KGSL_ISENSE_CLK_FREQ);
	return clk_set_rate(pwr->grp_clks[pwr->isense_clk_indx], rate);
}

int kgsl_pwrctrl_init(struct kgsl_device *device)
{
	int i, k, m, n = 0, result;
@@ -1799,9 +1830,7 @@ int kgsl_pwrctrl_init(struct kgsl_device *device)
	clk_set_rate(pwr->grp_clks[6],
		clk_round_rate(pwr->grp_clks[6], KGSL_RBBMTIMER_CLK_FREQ));

	if (pwr->isense_clk_indx)
		clk_set_rate(pwr->grp_clks[pwr->isense_clk_indx],
			KGSL_ISENSE_CLK_FREQ);
	_isense_clk_set_rate(pwr, pwr->num_pwrlevels - 1);

	result = get_regulators(device);
	if (result)
+5 −1
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@
/* Only two supported levels, min & max */
#define KGSL_CONSTRAINT_PWR_MAXLEVELS 2

#define KGSL_RBBMTIMER_CLK_FREQ	19200000
#define KGSL_XO_CLK_FREQ	19200000
#define KGSL_RBBMTIMER_CLK_FREQ	KGSL_XO_CLK_FREQ
#define KGSL_ISENSE_CLK_FREQ	200000000

/* Symbolic table for the constraint type */
@@ -154,6 +155,8 @@ struct kgsl_regulator {
 * @deep_nap_timer - Timer struct for entering deep nap
 * @deep_nap_timeout - Timeout for entering deep nap
 * @gx_retention - true if retention voltage is allowed
 * isense_clk_indx - index of isense clock, 0 if no isense
 * isense_clk_on_level - isense clock rate is XO rate below this level.
 */

struct kgsl_pwrctrl {
@@ -162,6 +165,7 @@ struct kgsl_pwrctrl {
	struct clk *dummy_mx_clk;
	struct clk *gpu_bimc_int_clk;
	int isense_clk_indx;
	int isense_clk_on_level;
	unsigned long power_flags;
	unsigned long ctrl_flags;
	struct kgsl_pwrlevel pwrlevels[KGSL_MAX_PWRLEVELS];