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

Commit 72e2adcd authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge back earlier 'pm-cpufreq' material.

parents 98a947ab 109df086
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -181,7 +181,8 @@ config CPU_FREQ_GOV_CONSERVATIVE


config GENERIC_CPUFREQ_CPU0
config GENERIC_CPUFREQ_CPU0
	tristate "Generic CPU0 cpufreq driver"
	tristate "Generic CPU0 cpufreq driver"
	depends on HAVE_CLK && REGULATOR && PM_OPP && OF
	depends on HAVE_CLK && REGULATOR && OF
	select PM_OPP
	help
	help
	  This adds a generic cpufreq driver for CPU0 frequency management.
	  This adds a generic cpufreq driver for CPU0 frequency management.
	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
+4 −2
Original line number Original line Diff line number Diff line
@@ -4,7 +4,8 @@


config ARM_BIG_LITTLE_CPUFREQ
config ARM_BIG_LITTLE_CPUFREQ
	tristate "Generic ARM big LITTLE CPUfreq driver"
	tristate "Generic ARM big LITTLE CPUfreq driver"
	depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK
	depends on ARM && ARM_CPU_TOPOLOGY && HAVE_CLK
	select PM_OPP
	help
	help
	  This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
	  This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.


@@ -54,7 +55,8 @@ config ARM_EXYNOS5250_CPUFREQ
config ARM_EXYNOS5440_CPUFREQ
config ARM_EXYNOS5440_CPUFREQ
	bool "SAMSUNG EXYNOS5440"
	bool "SAMSUNG EXYNOS5440"
	depends on SOC_EXYNOS5440
	depends on SOC_EXYNOS5440
	depends on HAVE_CLK && PM_OPP && OF
	depends on HAVE_CLK && OF
	select PM_OPP
	default y
	default y
	help
	help
	  This adds the CPUFreq driver for Samsung EXYNOS5440
	  This adds the CPUFreq driver for Samsung EXYNOS5440
+1 −1
Original line number Original line Diff line number Diff line
@@ -44,7 +44,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
	int ret;
	int ret;


	freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
	freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
	if (freq_Hz < 0)
	if (freq_Hz <= 0)
		freq_Hz = freq_table[index].frequency * 1000;
		freq_Hz = freq_table[index].frequency * 1000;


	freq_exact = freq_Hz;
	freq_exact = freq_Hz;
+54 −15
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@
#define SAMPLE_COUNT		3
#define SAMPLE_COUNT		3


#define BYT_RATIOS	0x66a
#define BYT_RATIOS	0x66a
#define BYT_VIDS        0x66b


#define FRAC_BITS 8
#define FRAC_BITS 8
#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
@@ -64,6 +65,12 @@ struct pstate_data {
	int	turbo_pstate;
	int	turbo_pstate;
};
};


struct vid_data {
	int32_t min;
	int32_t max;
	int32_t ratio;
};

struct _pid {
struct _pid {
	int setpoint;
	int setpoint;
	int32_t integral;
	int32_t integral;
@@ -82,10 +89,9 @@ struct cpudata {
	struct timer_list timer;
	struct timer_list timer;


	struct pstate_data pstate;
	struct pstate_data pstate;
	struct vid_data vid;
	struct _pid pid;
	struct _pid pid;


	int min_pstate_count;

	u64	prev_aperf;
	u64	prev_aperf;
	u64	prev_mperf;
	u64	prev_mperf;
	int	sample_ptr;
	int	sample_ptr;
@@ -106,7 +112,8 @@ struct pstate_funcs {
	int (*get_max)(void);
	int (*get_max)(void);
	int (*get_min)(void);
	int (*get_min)(void);
	int (*get_turbo)(void);
	int (*get_turbo)(void);
	void (*set)(int pstate);
	void (*set)(struct cpudata*, int pstate);
	void (*get_vid)(struct cpudata *);
};
};


struct cpu_defaults {
struct cpu_defaults {
@@ -358,6 +365,42 @@ static int byt_get_max_pstate(void)
	return (value >> 16) & 0xFF;
	return (value >> 16) & 0xFF;
}
}


static void byt_set_pstate(struct cpudata *cpudata, int pstate)
{
	u64 val;
	int32_t vid_fp;
	u32 vid;

	val = pstate << 8;
	if (limits.no_turbo)
		val |= (u64)1 << 32;

	vid_fp = cpudata->vid.min + mul_fp(
		int_tofp(pstate - cpudata->pstate.min_pstate),
		cpudata->vid.ratio);

	vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max);
	vid = fp_toint(vid_fp);

	val |= vid;

	wrmsrl(MSR_IA32_PERF_CTL, val);
}

static void byt_get_vid(struct cpudata *cpudata)
{
	u64 value;

	rdmsrl(BYT_VIDS, value);
	cpudata->vid.min = int_tofp((value >> 8) & 0x7f);
	cpudata->vid.max = int_tofp((value >> 16) & 0x7f);
	cpudata->vid.ratio = div_fp(
		cpudata->vid.max - cpudata->vid.min,
		int_tofp(cpudata->pstate.max_pstate -
			cpudata->pstate.min_pstate));
}


static int core_get_min_pstate(void)
static int core_get_min_pstate(void)
{
{
	u64 value;
	u64 value;
@@ -384,7 +427,7 @@ static int core_get_turbo_pstate(void)
	return ret;
	return ret;
}
}


static void core_set_pstate(int pstate)
static void core_set_pstate(struct cpudata *cpudata, int pstate)
{
{
	u64 val;
	u64 val;


@@ -425,7 +468,8 @@ static struct cpu_defaults byt_params = {
		.get_max = byt_get_max_pstate,
		.get_max = byt_get_max_pstate,
		.get_min = byt_get_min_pstate,
		.get_min = byt_get_min_pstate,
		.get_turbo = byt_get_max_pstate,
		.get_turbo = byt_get_max_pstate,
		.set = core_set_pstate,
		.set = byt_set_pstate,
		.get_vid = byt_get_vid,
	},
	},
};
};


@@ -462,7 +506,7 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)


	cpu->pstate.current_pstate = pstate;
	cpu->pstate.current_pstate = pstate;


	pstate_funcs.set(pstate);
	pstate_funcs.set(cpu, pstate);
}
}


static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
@@ -488,6 +532,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
	cpu->pstate.max_pstate = pstate_funcs.get_max();
	cpu->pstate.max_pstate = pstate_funcs.get_max();
	cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
	cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();


	if (pstate_funcs.get_vid)
		pstate_funcs.get_vid(cpu);

	/*
	/*
	 * goto max pstate so we don't slow up boot if we are built-in if we are
	 * goto max pstate so we don't slow up boot if we are built-in if we are
	 * a module we will take care of it during normal operation
	 * a module we will take care of it during normal operation
@@ -568,15 +615,6 @@ static void intel_pstate_timer_func(unsigned long __data)


	intel_pstate_sample(cpu);
	intel_pstate_sample(cpu);
	intel_pstate_adjust_busy_pstate(cpu);
	intel_pstate_adjust_busy_pstate(cpu);

	if (cpu->pstate.current_pstate == cpu->pstate.min_pstate) {
		cpu->min_pstate_count++;
		if (!(cpu->min_pstate_count % 5)) {
			intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
		}
	} else
		cpu->min_pstate_count = 0;

	intel_pstate_set_sample_time(cpu);
	intel_pstate_set_sample_time(cpu);
}
}


@@ -781,6 +819,7 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
	pstate_funcs.get_min   = funcs->get_min;
	pstate_funcs.get_min   = funcs->get_min;
	pstate_funcs.get_turbo = funcs->get_turbo;
	pstate_funcs.get_turbo = funcs->get_turbo;
	pstate_funcs.set       = funcs->set;
	pstate_funcs.set       = funcs->set;
	pstate_funcs.get_vid   = funcs->get_vid;
}
}


#if IS_ENABLED(CONFIG_ACPI)
#if IS_ENABLED(CONFIG_ACPI)
+1 −1
Original line number Original line Diff line number Diff line
@@ -138,7 +138,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy,
	}
	}


	newfreq = clk_round_rate(srcclk, newfreq * mult);
	newfreq = clk_round_rate(srcclk, newfreq * mult);
	if (newfreq < 0) {
	if (newfreq <= 0) {
		pr_err("clk_round_rate failed for cpu src clock\n");
		pr_err("clk_round_rate failed for cpu src clock\n");
		return newfreq;
		return newfreq;
	}
	}