Skip to content

Commit 5a561bb

Browse files
committed
Restores lost states after wakeup from sleep
1 parent d178c44 commit 5a561bb

File tree

2 files changed

+22
-17
lines changed

2 files changed

+22
-17
lines changed

AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ void AMDRyzenCPUPowerManagement::startWorkLoop() {
118118

119119
//Read PStateDef generated by EFI.
120120
if(pmRyzen_cpu_is_master(cpu_num))
121-
provider->dumpPstate();
121+
provider->dumpPstate(nullptr);
122122

123123

124124
if(!pmRyzen_cpu_primary_in_core(cpu_num)) return;
@@ -381,12 +381,17 @@ IOReturn AMDRyzenCPUPowerManagement::setPowerState(unsigned long powerStateOrdin
381381
if (0 == powerStateOrdinal) {
382382
// Going to sleep
383383
IOLog("AMDCPUSupport::setPowerState preparing for sleep\n");
384-
wentToSleep = true;
384+
sleepState.sleep = true;
385+
sleepState.cpb = getCPBState();
386+
dumpPstate(sleepState.pstate);
387+
385388
stopWorkLoop();
386-
} else if (1 == powerStateOrdinal && wentToSleep) {
389+
} else if (1 == powerStateOrdinal && sleepState.sleep) {
387390
// Waking up
388391
IOLog("AMDCPUSupport::setPowerState preparing for wakeup\n");
389-
wentToSleep = false;
392+
sleepState.sleep = false;
393+
setCPBState(sleepState.cpb);
394+
dumpPstate(sleepState.pstate);
390395
startWorkLoop();
391396
}
392397

@@ -637,9 +642,8 @@ void AMDRyzenCPUPowerManagement::updatePackageEnergy(){
637642
pwrLastTSC = rdtsc64();
638643
}
639644

640-
void AMDRyzenCPUPowerManagement::dumpPstate(){
645+
void AMDRyzenCPUPowerManagement::dumpPstate(uint64_t buf[8]){
641646

642-
uint8_t len = 0;
643647
for (uint32_t i = 0; i < kMSR_PSTATE_LEN; i++) {
644648
uint64_t msr_value_buf = 0;
645649
bool err = !read_msr(kMSR_PSTATE_0 + i, &msr_value_buf);
@@ -658,17 +662,12 @@ void AMDRyzenCPUPowerManagement::dumpPstate(){
658662
PStateDef_perCore[i] = msr_value_buf;
659663
PStateDefClock_perCore[i] = clock;
660664

661-
if(msr_value_buf & ((uint64_t)1 << 63)) len++;
662-
// IOLog("a: %llu", msr_value_buf);
663-
}
664-
665-
PStateEnabledLen = max(PStateEnabledLen, len);
665+
if(buf != nullptr) buf[i] = msr_value_buf;
666+
};
666667
}
667668

668669
void AMDRyzenCPUPowerManagement::writePstate(const uint64_t *buf){
669670

670-
PStateEnabledLen = 0;
671-
672671
//A bit hacky but at least works for now.
673672
void* args[] = {this, (void*)buf};
674673

@@ -691,7 +690,7 @@ void AMDRyzenCPUPowerManagement::writePstate(const uint64_t *buf){
691690

692691

693692
if(!pmRyzen_cpu_is_master(cpu_number())) return;
694-
provider->dumpPstate();
693+
provider->dumpPstate(nullptr);
695694

696695
}, nullptr, args);
697696

AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.hpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ typedef struct tctl_offset {
7171
int offset;
7272
} TempOffset;
7373

74+
typedef struct sleep_state {
75+
bool sleep;
76+
bool cpb;
77+
uint64_t pstate[8];
78+
} SleepState;
79+
7480

7581
static IOPMPowerState powerStates[kNrOfPowerStates] = {
7682
{1, kIOPMPowerOff, kIOPMPowerOff, kIOPMPowerOff, 0, 0, 0, 0, 0, 0, 0, 0},
@@ -152,7 +158,7 @@ class AMDRyzenCPUPowerManagement : public IOService {
152158

153159
void registerRequest();
154160

155-
void dumpPstate();
161+
void dumpPstate(uint64_t buf[8]);
156162
void writePstate(const uint64_t *buf);
157163

158164
bool initSuperIO(uint16_t* chipIntel);
@@ -203,7 +209,6 @@ class AMDRyzenCPUPowerManagement : public IOService {
203209
uint8_t PStateCur_perCore[CPUInfo::MaxCpus];
204210
uint8_t PStateCtl = 0;
205211
uint64_t PStateDef_perCore[8];
206-
uint8_t PStateEnabledLen = 0;
207212
float PStateDefClock_perCore[8];
208213
bool cpbSupported;
209214

@@ -249,7 +254,8 @@ class AMDRyzenCPUPowerManagement : public IOService {
249254

250255
IOPCIDevice *fIOPCIDevice;
251256
bool getPCIService();
252-
bool wentToSleep;
257+
258+
SleepState sleepState;
253259

254260
void startWorkLoop();
255261
void stopWorkLoop();

0 commit comments

Comments
 (0)