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

Commit 007bea09 authored by Dirk Brandewie's avatar Dirk Brandewie Committed by Rafael J. Wysocki
Browse files

intel_pstate: Add setting voltage value for baytrail P states.



Baytrail requires setting P state and voltage pairs when adjusting the
requested P state.  Add function for retrieving the valid voltage
values and modify *_set_pstate() functions to caluclate the
appropriate voltage for the requested P state.

Signed-off-by: default avatarDirk Brandewie <dirk.j.brandewie@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 189c9b8d
Loading
Loading
Loading
Loading
+54 −4
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#define SAMPLE_COUNT		3

#define BYT_RATIOS	0x66a
#define BYT_VIDS        0x66b

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

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

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

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

	int min_pstate_count;
@@ -106,7 +114,8 @@ struct pstate_funcs {
	int (*get_max)(void);
	int (*get_min)(void);
	int (*get_turbo)(void);
	void (*set)(int pstate);
	void (*set)(struct cpudata*, int pstate);
	void (*get_vid)(struct cpudata *);
};

struct cpu_defaults {
@@ -358,6 +367,42 @@ static int byt_get_max_pstate(void)
	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)
{
	u64 value;
@@ -384,7 +429,7 @@ static int core_get_turbo_pstate(void)
	return ret;
}

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

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

@@ -462,7 +508,7 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int 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)
@@ -488,6 +534,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
	cpu->pstate.max_pstate = pstate_funcs.get_max();
	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
	 * a module we will take care of it during normal operation
@@ -776,6 +825,7 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
	pstate_funcs.get_min   = funcs->get_min;
	pstate_funcs.get_turbo = funcs->get_turbo;
	pstate_funcs.set       = funcs->set;
	pstate_funcs.get_vid   = funcs->get_vid;
}

#if IS_ENABLED(CONFIG_ACPI)