From 72ae10425f28878d7e754c324f889eee8acae819 Mon Sep 17 00:00:00 2001 From: Imre Vadasz Date: Sun, 23 Feb 2014 01:08:12 +0100 Subject: [PATCH] Avoiding an infinite loop during P-state adjustment on the HP6715s notebook. The code is taken from the OpenBSD counterpart to amd0f_set_fidvid. The infinite loop probably occurs on my HP6715s because the rvo adjustment doesn't get applied by the hardware when entering the highest P-state (maybe because of some kind of overvolting protection). --- sys/platform/pc64/x86_64/cpufreq_machdep.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/sys/platform/pc64/x86_64/cpufreq_machdep.c b/sys/platform/pc64/x86_64/cpufreq_machdep.c index 21a48ec..40db2e6 100644 --- a/sys/platform/pc64/x86_64/cpufreq_machdep.c +++ b/sys/platform/pc64/x86_64/cpufreq_machdep.c @@ -67,7 +67,8 @@ do { \ int amd0f_set_fidvid(const struct amd0f_fidvid *fv, const struct amd0f_xsit *xsit) { - uint32_t val, cfid, cvid, tvid; + uint32_t val, cfid, cvid; + int rvo; uint64_t status; /* @@ -84,16 +85,15 @@ amd0f_set_fidvid(const struct amd0f_fidvid *fv, const struct amd0f_xsit *xsit) return 0; /* - * Phase 1: Raise core voltage to the TargetVID + * Phase 1: Raise core voltage to requested VID if frequency is + * going up. */ if ((fv->fid & ~0x1) > (cfid & ~0x1) || cvid > fv->vid) { KKASSERT(fv->vid >= xsit->rvo); - tvid = fv->vid - xsit->rvo; } else { KKASSERT(cvid >= xsit->rvo); - tvid = cvid - xsit->rvo; } - while (cvid > tvid) { + while (cvid > fv->vid) { if (cvid > (1 << xsit->mvs)) val = cvid - (1 << xsit->mvs); else @@ -103,6 +103,16 @@ amd0f_set_fidvid(const struct amd0f_fidvid *fv, const struct amd0f_xsit *xsit) cvid = AMD0F_STA_CVID(status); AMD0F_DELAY_VST(xsit->vst); } + /* ... then raise to voltage + RVO (if required) */ + for (rvo = xsit->rvo; rvo > 0 && cvid > 0; --rvo) { + /* XXX It's not clear from spec if we have to do that + * in 0.25 step or in MVS. Therefore do it as it's done + * under Linux */ + AMD0F_WRITE_FIDVID(cfid, cvid - 1, 0ULL); + AMD0F_WAIT_FIDVID_CHG(status); + cvid = AMD0F_STA_CVID(status); + AMD0F_DELAY_VST(xsit->vst); + } /* * Phase 2: Change to requested core frequency -- 1.8.5.1