Skip to content

Commit 222ca5f

Browse files
committed
Restores lost states after wakeup from sleep
1 parent 66d6508 commit 222ca5f

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+
writePstate(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
@@ -72,6 +72,12 @@ typedef struct tctl_offset {
7272
int offset;
7373
} TempOffset;
7474

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

7682
static IOPMPowerState powerStates[kNrOfPowerStates] = {
7783
{1, kIOPMPowerOff, kIOPMPowerOff, kIOPMPowerOff, 0, 0, 0, 0, 0, 0, 0, 0},
@@ -153,7 +159,7 @@ class AMDRyzenCPUPowerManagement : public IOService {
153159

154160
void registerRequest();
155161

156-
void dumpPstate();
162+
void dumpPstate(uint64_t buf[8]);
157163
void writePstate(const uint64_t *buf);
158164

159165
bool initSuperIO(uint16_t* chipIntel);
@@ -204,7 +210,6 @@ class AMDRyzenCPUPowerManagement : public IOService {
204210
uint8_t PStateCur_perCore[CPUInfo::MaxCpus];
205211
uint8_t PStateCtl = 0;
206212
uint64_t PStateDef_perCore[8];
207-
uint8_t PStateEnabledLen = 0;
208213
float PStateDefClock_perCore[8];
209214
bool cpbSupported;
210215

@@ -250,7 +255,8 @@ class AMDRyzenCPUPowerManagement : public IOService {
250255

251256
IOPCIDevice *fIOPCIDevice;
252257
bool getPCIService();
253-
bool wentToSleep;
258+
259+
SleepState sleepState;
254260

255261
void startWorkLoop();
256262
void stopWorkLoop();

0 commit comments

Comments
 (0)