Skip to content

Commit

Permalink
Restores lost states after wakeup from sleep
Browse files Browse the repository at this point in the history
  • Loading branch information
aluveitie committed May 20, 2020
1 parent d178c44 commit 5a561bb
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 17 deletions.
27 changes: 13 additions & 14 deletions AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ void AMDRyzenCPUPowerManagement::startWorkLoop() {

//Read PStateDef generated by EFI.
if(pmRyzen_cpu_is_master(cpu_num))
provider->dumpPstate();
provider->dumpPstate(nullptr);


if(!pmRyzen_cpu_primary_in_core(cpu_num)) return;
Expand Down Expand Up @@ -381,12 +381,17 @@ IOReturn AMDRyzenCPUPowerManagement::setPowerState(unsigned long powerStateOrdin
if (0 == powerStateOrdinal) {
// Going to sleep
IOLog("AMDCPUSupport::setPowerState preparing for sleep\n");
wentToSleep = true;
sleepState.sleep = true;
sleepState.cpb = getCPBState();
dumpPstate(sleepState.pstate);

stopWorkLoop();
} else if (1 == powerStateOrdinal && wentToSleep) {
} else if (1 == powerStateOrdinal && sleepState.sleep) {
// Waking up
IOLog("AMDCPUSupport::setPowerState preparing for wakeup\n");
wentToSleep = false;
sleepState.sleep = false;
setCPBState(sleepState.cpb);
dumpPstate(sleepState.pstate);
startWorkLoop();
}

Expand Down Expand Up @@ -637,9 +642,8 @@ void AMDRyzenCPUPowerManagement::updatePackageEnergy(){
pwrLastTSC = rdtsc64();
}

void AMDRyzenCPUPowerManagement::dumpPstate(){
void AMDRyzenCPUPowerManagement::dumpPstate(uint64_t buf[8]){

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

if(msr_value_buf & ((uint64_t)1 << 63)) len++;
// IOLog("a: %llu", msr_value_buf);
}

PStateEnabledLen = max(PStateEnabledLen, len);
if(buf != nullptr) buf[i] = msr_value_buf;
};
}

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

PStateEnabledLen = 0;

//A bit hacky but at least works for now.
void* args[] = {this, (void*)buf};

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


if(!pmRyzen_cpu_is_master(cpu_number())) return;
provider->dumpPstate();
provider->dumpPstate(nullptr);

}, nullptr, args);

Expand Down
12 changes: 9 additions & 3 deletions AMDRyzenCPUPowerManagement/AMDRyzenCPUPowerManagement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ typedef struct tctl_offset {
int offset;
} TempOffset;

typedef struct sleep_state {
bool sleep;
bool cpb;
uint64_t pstate[8];
} SleepState;


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

void registerRequest();

void dumpPstate();
void dumpPstate(uint64_t buf[8]);
void writePstate(const uint64_t *buf);

bool initSuperIO(uint16_t* chipIntel);
Expand Down Expand Up @@ -203,7 +209,6 @@ class AMDRyzenCPUPowerManagement : public IOService {
uint8_t PStateCur_perCore[CPUInfo::MaxCpus];
uint8_t PStateCtl = 0;
uint64_t PStateDef_perCore[8];
uint8_t PStateEnabledLen = 0;
float PStateDefClock_perCore[8];
bool cpbSupported;

Expand Down Expand Up @@ -249,7 +254,8 @@ class AMDRyzenCPUPowerManagement : public IOService {

IOPCIDevice *fIOPCIDevice;
bool getPCIService();
bool wentToSleep;

SleepState sleepState;

void startWorkLoop();
void stopWorkLoop();
Expand Down

0 comments on commit 5a561bb

Please sign in to comment.