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

Commit 383731d9 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'pm-cpufreq' and 'pm-devfreq'

* pm-cpufreq:
  cpufreq: CPPC: Correct desired_perf calculation
  cpufreq: conservative: Fix next frequency selection
  cpufreq: skip invalid entries when searching the frequency
  cpufreq: intel_pstate: Fix struct pstate_adjust_policy kerneldoc
  cpufreq: intel_pstate: Proportional algorithm for Atom
  cpufreq: intel_pstate: Clarify comment in get_target_pstate_use_performance()
  cpufreq: intel_pstate: Fix unsafe HWP MSR access

* pm-devfreq:
  PM / devfreq: Skip status update on uninitialized previous_freq
  PM / devfreq: Add proper locking around list_del()
  PM / devfreq: exynos-nocp: Remove redundant code
  PM / devfreq: exynos-nocp: Select REGMAP_MMIO
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -80,11 +80,17 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
{
	struct cpudata *cpu;
	struct cpufreq_freqs freqs;
	u32 desired_perf;
	int ret = 0;

	cpu = all_cpu_data[policy->cpu];

	cpu->perf_ctrls.desired_perf = (u64)target_freq * policy->max / cppc_dmi_max_khz;
	desired_perf = (u64)target_freq * cpu->perf_caps.highest_perf / cppc_dmi_max_khz;
	/* Return if it is exactly the same perf */
	if (desired_perf == cpu->perf_ctrls.desired_perf)
		return ret;

	cpu->perf_ctrls.desired_perf = desired_perf;
	freqs.old = policy->cur;
	freqs.new = target_freq;

+16 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
struct cs_policy_dbs_info {
	struct policy_dbs_info policy_dbs;
	unsigned int down_skip;
	unsigned int requested_freq;
};

static inline struct cs_policy_dbs_info *to_dbs_info(struct policy_dbs_info *policy_dbs)
@@ -61,6 +62,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
{
	struct policy_dbs_info *policy_dbs = policy->governor_data;
	struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
	unsigned int requested_freq = dbs_info->requested_freq;
	struct dbs_data *dbs_data = policy_dbs->dbs_data;
	struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
	unsigned int load = dbs_update(policy);
@@ -72,10 +74,16 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
	if (cs_tuners->freq_step == 0)
		goto out;

	/*
	 * If requested_freq is out of range, it is likely that the limits
	 * changed in the meantime, so fall back to current frequency in that
	 * case.
	 */
	if (requested_freq > policy->max || requested_freq < policy->min)
		requested_freq = policy->cur;

	/* Check for frequency increase */
	if (load > dbs_data->up_threshold) {
		unsigned int requested_freq = policy->cur;

		dbs_info->down_skip = 0;

		/* if we are already at full speed then break out early */
@@ -83,8 +91,11 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
			goto out;

		requested_freq += get_freq_target(cs_tuners, policy);
		if (requested_freq > policy->max)
			requested_freq = policy->max;

		__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_H);
		dbs_info->requested_freq = requested_freq;
		goto out;
	}

@@ -95,7 +106,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)

	/* Check for frequency decrease */
	if (load < cs_tuners->down_threshold) {
		unsigned int freq_target, requested_freq = policy->cur;
		unsigned int freq_target;
		/*
		 * if we cannot reduce the frequency anymore, break out early
		 */
@@ -109,6 +120,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
			requested_freq = policy->min;

		__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_L);
		dbs_info->requested_freq = requested_freq;
	}

 out:
@@ -287,6 +299,7 @@ static void cs_start(struct cpufreq_policy *policy)
	struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data);

	dbs_info->down_skip = 0;
	dbs_info->requested_freq = policy->cur;
}

static struct dbs_governor cs_governor = {
+32 −11
Original line number Diff line number Diff line
@@ -225,7 +225,7 @@ struct cpudata {
static struct cpudata **all_cpu_data;

/**
 * struct pid_adjust_policy - Stores static PID configuration data
 * struct pstate_adjust_policy - Stores static PID configuration data
 * @sample_rate_ms:	PID calculation sample rate in ms
 * @sample_rate_ns:	Sample rate calculation in ns
 * @deadband:		PID deadband
@@ -562,12 +562,12 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask)
	int min, hw_min, max, hw_max, cpu, range, adj_range;
	u64 value, cap;

	rdmsrl(MSR_HWP_CAPABILITIES, cap);
	for_each_cpu(cpu, cpumask) {
		rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
		hw_min = HWP_LOWEST_PERF(cap);
		hw_max = HWP_HIGHEST_PERF(cap);
		range = hw_max - hw_min;

	for_each_cpu(cpu, cpumask) {
		rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value);
		adj_range = limits->min_perf_pct * range / 100;
		min = hw_min + adj_range;
@@ -1232,6 +1232,7 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
{
	struct sample *sample = &cpu->sample;
	int32_t busy_frac, boost;
	int target, avg_pstate;

	busy_frac = div_fp(sample->mperf, sample->tsc);

@@ -1242,7 +1243,26 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
		busy_frac = boost;

	sample->busy_scaled = busy_frac * 100;
	return get_avg_pstate(cpu) - pid_calc(&cpu->pid, sample->busy_scaled);

	target = limits->no_turbo || limits->turbo_disabled ?
			cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
	target += target >> 2;
	target = mul_fp(target, busy_frac);
	if (target < cpu->pstate.min_pstate)
		target = cpu->pstate.min_pstate;

	/*
	 * If the average P-state during the previous cycle was higher than the
	 * current target, add 50% of the difference to the target to reduce
	 * possible performance oscillations and offset possible performance
	 * loss related to moving the workload from one CPU to another within
	 * a package/module.
	 */
	avg_pstate = get_avg_pstate(cpu);
	if (avg_pstate > target)
		target += (avg_pstate - target) >> 1;

	return target;
}

static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
@@ -1251,10 +1271,11 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
	u64 duration_ns;

	/*
	 * perf_scaled is the average performance during the last sampling
	 * period scaled by the ratio of the maximum P-state to the P-state
	 * requested last time (in percent).  That measures the system's
	 * response to the previous P-state selection.
	 * perf_scaled is the ratio of the average P-state during the last
	 * sampling period to the P-state requested last time (in percent).
	 *
	 * That measures the system's response to the previous P-state
	 * selection.
	 */
	max_pstate = cpu->pstate.max_pstate_physical;
	current_pstate = cpu->pstate.current_pstate;
+7 −1
Original line number Diff line number Diff line
@@ -137,6 +137,10 @@ static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)

	cur_time = jiffies;

	/* Immediately exit if previous_freq is not initialized yet. */
	if (!devfreq->previous_freq)
		goto out;

	prev_lev = devfreq_get_freq_level(devfreq, devfreq->previous_freq);
	if (prev_lev < 0) {
		ret = prev_lev;
@@ -594,17 +598,19 @@ struct devfreq *devfreq_add_device(struct device *dev,
	if (devfreq->governor)
		err = devfreq->governor->event_handler(devfreq,
					DEVFREQ_GOV_START, NULL);
	mutex_unlock(&devfreq_list_lock);
	if (err) {
		dev_err(dev, "%s: Unable to start governor for the device\n",
			__func__);
		goto err_init;
	}
	mutex_unlock(&devfreq_list_lock);

	return devfreq;

err_init:
	list_del(&devfreq->node);
	mutex_unlock(&devfreq_list_lock);

	device_unregister(&devfreq->dev);
err_out:
	return ERR_PTR(err);
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ config DEVFREQ_EVENT_EXYNOS_NOCP
	tristate "EXYNOS NoC (Network On Chip) Probe DEVFREQ event Driver"
	depends on ARCH_EXYNOS || COMPILE_TEST
	select PM_OPP
	select REGMAP_MMIO
	help
	  This add the devfreq-event driver for Exynos SoC. It provides NoC
	  (Network on Chip) Probe counters to measure the bandwidth of AXI bus.
Loading