Skip to content

Commit 35e83b7

Browse files
committed
Restores lost states after wakeup from sleep
1 parent 81b501a commit 35e83b7

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;
@@ -374,12 +374,17 @@ IOReturn AMDRyzenCPUPowerManagement::setPowerState(unsigned long powerStateOrdin
374374
if (0 == powerStateOrdinal) {
375375
// Going to sleep
376376
IOLog("AMDCPUSupport::setPowerState preparing for sleep\n");
377-
wentToSleep = true;
377+
sleepState.sleep = true;
378+
sleepState.cpb = getCPBState();
379+
dumpPstate(sleepState.pstate);
380+
378381
stopWorkLoop();
379-
} else if (1 == powerStateOrdinal && wentToSleep) {
382+
} else if (1 == powerStateOrdinal && sleepState.sleep) {
380383
// Waking up
381384
IOLog("AMDCPUSupport::setPowerState preparing for wakeup\n");
382-
wentToSleep = false;
385+
sleepState.sleep = false;
386+
setCPBState(sleepState.cpb);
387+
writePstate(sleepState.pstate);
383388
startWorkLoop();
384389
}
385390

@@ -630,9 +635,8 @@ void AMDRyzenCPUPowerManagement::updatePackageEnergy(){
630635
pwrLastTSC = rdtsc64();
631636
}
632637

633-
void AMDRyzenCPUPowerManagement::dumpPstate(){
638+
void AMDRyzenCPUPowerManagement::dumpPstate(uint64_t buf[8]){
634639

635-
uint8_t len = 0;
636640
for (uint32_t i = 0; i < kMSR_PSTATE_LEN; i++) {
637641
uint64_t msr_value_buf = 0;
638642
bool err = !read_msr(kMSR_PSTATE_0 + i, &msr_value_buf);
@@ -651,17 +655,12 @@ void AMDRyzenCPUPowerManagement::dumpPstate(){
651655
PStateDef_perCore[i] = msr_value_buf;
652656
PStateDefClock_perCore[i] = clock;
653657

654-
if(msr_value_buf & ((uint64_t)1 << 63)) len++;
655-
// IOLog("a: %llu", msr_value_buf);
656-
}
657-
658-
PStateEnabledLen = max(PStateEnabledLen, len);
658+
if(buf != nullptr) buf[i] = msr_value_buf;
659+
};
659660
}
660661

661662
void AMDRyzenCPUPowerManagement::writePstate(const uint64_t *buf){
662663

663-
PStateEnabledLen = 0;
664-
665664
//A bit hacky but at least works for now.
666665
void* args[] = {this, (void*)buf};
667666

@@ -684,7 +683,7 @@ void AMDRyzenCPUPowerManagement::writePstate(const uint64_t *buf){
684683

685684

686685
if(!pmRyzen_cpu_is_master(cpu_number())) return;
687-
provider->dumpPstate();
686+
provider->dumpPstate(nullptr);
688687

689688
}, nullptr, args);
690689

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)