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

Commit d8186113 authored by Jacob Pan's avatar Jacob Pan Committed by Zhang Rui
Browse files

thermal/powerclamp: fix missing newer package c-states



Package C8 to C10 was introduced in newer Intel CPUs, we need to
include them in the package c-state residency calculation.
Otherwise, idle injection target is not accurately maintained by
the closed control loop.

Also cleaned up the code to make it scale better with large number
of c-states.

Reported-by: default avatarKristen Carlson Accardi <kristen@linux.intel.com>
Signed-off-by: default avatarJacob Pan <jacob.jun.pan@linux.intel.com>
Signed-off-by: default avatarZhang Rui <rui.zhang@intel.com>
parent f09bfdb6
Loading
Loading
Loading
Loading
+43 −37
Original line number Diff line number Diff line
@@ -206,51 +206,57 @@ static void find_target_mwait(void)

}

static bool has_pkg_state_counter(void)
{
	u64 tmp;
	return !rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &tmp) ||
	       !rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &tmp) ||
	       !rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &tmp) ||
	       !rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &tmp);
struct pkg_cstate_info {
	bool skip;
	int msr_index;
	int cstate_id;
};

#define PKG_CSTATE_INIT(id) {				\
		.msr_index = MSR_PKG_C##id##_RESIDENCY, \
		.cstate_id = id				\
			}

static u64 pkg_state_counter(void)
static struct pkg_cstate_info pkg_cstates[] = {
	PKG_CSTATE_INIT(2),
	PKG_CSTATE_INIT(3),
	PKG_CSTATE_INIT(6),
	PKG_CSTATE_INIT(7),
	PKG_CSTATE_INIT(8),
	PKG_CSTATE_INIT(9),
	PKG_CSTATE_INIT(10),
	{NULL},
};

static bool has_pkg_state_counter(void)
{
	u64 val;
	u64 count = 0;
	struct pkg_cstate_info *info = pkg_cstates;

	static bool skip_c2;
	static bool skip_c3;
	static bool skip_c6;
	static bool skip_c7;

	if (!skip_c2) {
		if (!rdmsrl_safe(MSR_PKG_C2_RESIDENCY, &val))
			count += val;
		else
			skip_c2 = true;
	/* check if any one of the counter msrs exists */
	while (info->msr_index) {
		if (!rdmsrl_safe(info->msr_index, &val))
			return true;
		info++;
	}

	if (!skip_c3) {
		if (!rdmsrl_safe(MSR_PKG_C3_RESIDENCY, &val))
			count += val;
		else
			skip_c3 = true;
	return false;
}

	if (!skip_c6) {
		if (!rdmsrl_safe(MSR_PKG_C6_RESIDENCY, &val))
			count += val;
		else
			skip_c6 = true;
	}
static u64 pkg_state_counter(void)
{
	u64 val;
	u64 count = 0;
	struct pkg_cstate_info *info = pkg_cstates;

	if (!skip_c7) {
		if (!rdmsrl_safe(MSR_PKG_C7_RESIDENCY, &val))
	while (info->msr_index) {
		if (!info->skip) {
			if (!rdmsrl_safe(info->msr_index, &val))
				count += val;
			else
			skip_c7 = true;
				info->skip = true;
		}
		info++;
	}

	return count;