Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate PSC function support from #111 #116

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
246 changes: 182 additions & 64 deletions YogaSMC/YogaVPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,51 +257,69 @@ void YogaVPC::setPropertiesGated(OSObject* props) {
AlwaysLog(notSupported, DYTCPrompt);
continue;
}
bool ret;
UInt32 mode;
OSNumber *raw = OSDynamicCast(OSNumber, dict->getObject(DYTCPrompt));
if (raw != nullptr) {
DYTC_CMD cmd = {.raw = raw->unsigned32BitValue()};
mode = raw->unsigned32BitValue();
DYTC_CMD cmd = {.raw = mode};
DYTC_RESULT res;
if (DYTCCommand(cmd, &res) && parseDYTC(res))
AlwaysLog(toggleSuccess, DYTCPrompt, raw->unsigned32BitValue(), "see ioreg");
else
AlwaysLog(toggleFailure, DYTCPrompt);
continue;
}
OSString *value;
getPropertyString(DYTCPrompt);
int mode;
switch (value->getChar(0)) {
case 'l':
case 'L':
case 'q':
case 'Q':
mode = DYTC_MODE_QUIET;
break;

case 'b':
case 'B':
case 'm':
case 'M':
mode = DYTC_MODE_BALANCE;
break;

case 'h':
case 'H':
case 'p':
case 'P':
mode = DYTC_MODE_PERFORM;
break;

default:
AlwaysLog(valueInvalid, DYTCPrompt);
continue;
}
if (!setDYTC(mode)) {
AlwaysLog(toggleFailure, DYTCPrompt);
updateDYTC();
ret = DYTCCommand(cmd, &res) && parseDYTC(res);
} else {
DebugLog(toggleSuccess, DYTCPrompt, mode, "see ioreg");
OSString *value;
getPropertyString(DYTCPrompt);
switch (value->getChar(0)) {
case 'l':
case 'L':
case 'q':
case 'Q':
mode = DYTC_MODE_QUIET;
ret = setDYTCMMC(mode);
break;

case 'b':
case 'B':
case 'm':
case 'M':
mode = DYTC_MODE_BALANCE;
ret = setDYTCMMC(mode);
break;

case 'd':
case 'D':
mode = DYTC_MODE_NEW_DEFAULT;
ret = setDYTCPSC(mode);
break;

case 'h':
case 'H':
case 'p':
case 'P':
mode = DYTC_MODE_PERFORM;
ret = setDYTCMMC(mode);
break;

case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
mode = DYTC_MODE_NEW_1 + (value->getChar(0) - '1');
ret = setDYTCPSC(mode);
break;

default:
AlwaysLog(valueInvalid, DYTCPrompt);
continue;
}
}
if (ret)
DebugLog(toggleSuccess, DYTCPrompt, mode, "see ioreg");
else
AlwaysLog(toggleFailure, DYTCPrompt);
} else if (key->isEqualTo(updatePrompt)) {
updateAll();
} else {
Expand Down Expand Up @@ -448,7 +466,6 @@ bool YogaVPC::parseDYTC(DYTC_RESULT result) {
case DYTC_FUNCTION_STD:
setPropertyString(status, "FuncMode", "Standard");
break;

case DYTC_FUNCTION_CQL:
/* We can't get the mode when in CQL mode - so we disable CQL
* mode retrieve the mode and then enable it again.
Expand All @@ -460,13 +477,14 @@ bool YogaVPC::parseDYTC(DYTC_RESULT result) {
status->release();
return false;
}
setPropertyString(status, "FuncMode", "Lap");
setPropertyString(status, "FuncMode", "Lap (Reduced thermals)");
break;

case DYTC_FUNCTION_MMC:
setPropertyString(status, "FuncMode", "Desk");
break;

case DYTC_FUNCTION_PSC:
setPropertyString(status, "FuncMode", "Controlled");
break;
default:
AlwaysLog(valueUnknown, DYTCFuncPrompt, result.get.funcmode);
char Unknown[10];
Expand All @@ -475,28 +493,64 @@ bool YogaVPC::parseDYTC(DYTC_RESULT result) {
break;
}

switch (result.get.perfmode) {
case DYTC_MODE_PERFORM:
if (result.get.funcmode == DYTC_FUNCTION_CQL)
setPropertyString(status, "PerfMode", "Performance (Reduced as lapmode active)");
else
setPropertyString(status, "PerfMode", "Performance");
break;
if (result.get.funcmode == DYTC_FUNCTION_PSC) {
switch (result.get.perfmode) {
case DYTC_MODE_NEW_1:
case DYTC_MODE_NEW_2:
case DYTC_MODE_NEW_3:
case DYTC_MODE_NEW_4: {
char pm[20];
snprintf(pm, sizeof(pm), "Quiet %d", result.get.perfmode - DYTC_MODE_NEW_1 + 1);
setPropertyString(status, "PerfMode", pm);
break;
}

case DYTC_MODE_QUIET:
setPropertyString(status, "PerfMode", "Quiet");
break;
case DYTC_MODE_NEW_DEFAULT: {
setPropertyString(status, "PerfMode", "Balance");
break;
}

case DYTC_MODE_BALANCE:
setPropertyString(status, "PerfMode", "Balance");
break;
case DYTC_MODE_NEW_5:
case DYTC_MODE_NEW_6:
case DYTC_MODE_NEW_7:
case DYTC_MODE_NEW_8: {
char pm[20];
snprintf(pm, sizeof(pm), "Performance %d", result.get.perfmode - DYTC_MODE_NEW_5 + 1);
setPropertyString(status, "PerfMode", pm);
break;
}

default:
AlwaysLog(valueUnknown, DYTCPerfPrompt, result.get.perfmode);
char Unknown[10];
snprintf(Unknown, 10, "Unknown:%1x", result.get.perfmode);
setPropertyString(status, "PerfMode", Unknown);
break;
default:
AlwaysLog(valueUnknown, DYTCPerfPrompt, result.get.perfmode);
char Unknown[10];
snprintf(Unknown, sizeof(Unknown), "Unknown:%1x", result.get.perfmode);
setPropertyString(status, "PerfMode", Unknown);
break;
}
} else {
switch (result.get.perfmode) {
case DYTC_MODE_PERFORM:
if (result.get.funcmode == DYTC_FUNCTION_CQL)
setPropertyString(status, "PerfMode", "Performance (Reduced as lapmode active)");
else
setPropertyString(status, "PerfMode", "Performance");
break;

case DYTC_MODE_QUIET:
setPropertyString(status, "PerfMode", "Quiet");
break;

case DYTC_MODE_BALANCE:
setPropertyString(status, "PerfMode", "Balance");
break;

default:
AlwaysLog(valueUnknown, DYTCPerfPrompt, result.get.perfmode);
char Unknown[10];
snprintf(Unknown, sizeof(Unknown), "Unknown:%1x", result.get.perfmode);
setPropertyString(status, "PerfMode", Unknown);
break;
}
}

for (int func_bit = 0; func_bit < 16; func_bit++) {
Expand All @@ -513,6 +567,10 @@ bool YogaVPC::parseDYTC(DYTC_RESULT result) {
case DYTC_FUNCTION_MMC:
DebugLog("Found DYTC_FUNCTION_MMC");
break;

case DYTC_FUNCTION_PSC:
DebugLog("Found DYTC_FUNCTION_PSC");
break;

case DYTC_FUNCTION_STP:
DebugLog("Found DYTC_FUNCTION_STP");
Expand Down Expand Up @@ -544,7 +602,7 @@ bool YogaVPC::updateDYTC() {
return parseDYTC(result);
}

bool YogaVPC::setDYTC(int perfmode) {
bool YogaVPC::setDYTCMMC(int perfmode) {
if (!DYTCCap)
return true;

Expand All @@ -569,6 +627,66 @@ bool YogaVPC::setDYTC(int perfmode) {
return parseDYTC(result);
}

bool YogaVPC::setDYTCPSC(int newPerfMode) {
if (!DYTCCap)
return true;

DYTC_RESULT result;
// retrieve current state
if (!DYTCCommand(dytc_get_cmd, &result))
return false;

int curFuncMode = result.get.funcmode;
int curPerfMode = result.get.perfmode;

bool lapMode = false;
if (curFuncMode == DYTC_FUNCTION_CQL) {
// the result of disable command will contain real funcmode & perfmode
// the result of enable command will contain lapmode funcmode
DYTC_RESULT temp;
if (!DYTCCommand(dytc_set_cmd, &temp, DYTC_FUNCTION_CQL, 0xf, false))
return false;
curFuncMode = temp.get.funcmode;
curPerfMode = temp.get.perfmode;
lapMode = true;
}

if (curFuncMode == DYTC_FUNCTION_PSC) {
// psc mode tends to be glitchy (at least on my laptop), and can lock up cpu in low mhz state so we need to bombard it with resets first
// and yes, 1 reset is not enough at some cases so why not hold up kernel while we bombard it with resets :)))
DYTC_RESULT temp;
for (int a = 0; a < 20; a++) {
if (!DYTCCommand(dytc_set_cmd, &temp, DYTC_FUNCTION_PSC, 0xf, false))
return false;
if (!DYTCCommand(dytc_reset_cmd, &temp))
return false;
}

}

{
DYTC_RESULT temp;
// try reset if we wanna go to default
if (newPerfMode == DYTC_MODE_NEW_DEFAULT && !DYTCCommand(dytc_reset_cmd, &temp))
return false;
// try both new & old if we wanna control
else if (newPerfMode != DYTC_MODE_NEW_DEFAULT && !DYTCCommand(dytc_set_cmd, &temp, DYTC_FUNCTION_PSC, newPerfMode, true) &&
!DYTCCommand(dytc_set_cmd, &temp, DYTC_FUNCTION_MMC, newPerfMode < DYTC_MODE_NEW_5 ? DYTC_MODE_QUIET : DYTC_MODE_PERFORM, true)) {
return false;
}
}


// if we were in lapmode, enable that back and fetch the result that should have funcmode set back to lapmode (so that parse can show correct func)
if (lapMode && !DYTCCommand(dytc_set_cmd, &result, DYTC_FUNCTION_CQL, 0xf, true))
return false;
// if we weren't in lapmode, retrieve the altered mode just to make sure we really got it
else if (!lapMode && !DYTCCommand(dytc_get_cmd, &result))
return false;

return parseDYTC(result);
}

bool YogaVPC::dumpECOffset(UInt32 value) {
bool ret = false;
UInt32 size = value >> 8;
Expand Down
13 changes: 11 additions & 2 deletions YogaSMC/YogaVPC.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,22 @@ class YogaVPC : public YogaBaseService
bool updateDYTC();

/**
* Set DYTC status
* Set DYTC status for MMC functions
*
* @param perfmode Performance mode
*
* @return true if success
*/
bool setDYTC(int perfmode);
bool setDYTCMMC(int perfmode);

/**
* Set DYTC status for PSC functions
*
* @param newPerfMode Performance mode
*
* @return true if success
*/
bool setDYTCPSC(int newPerfMode);

public:
virtual IOService *probe(IOService *provider, SInt32 *score) APPLE_KEXT_OVERRIDE;
Expand Down
11 changes: 11 additions & 0 deletions YogaSMC/YogaVPC/DYTC.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ enum {
#define DYTC_MODE_QUIET 3 /* low power mode aka quiet */
#define DYTC_MODE_BALANCE 0xF /* default mode aka balance */

// available mode for the DYTC_FUNCTION_PSC (0xD)
#define DYTC_MODE_NEW_1 1 // pretty much unusable, cripples the cpu
#define DYTC_MODE_NEW_2 2 // thermal throttle 55-60c, low fans, low to none boost
#define DYTC_MODE_NEW_3 3 // thermal throttle 55-60c, low fans, low to none boost
#define DYTC_MODE_NEW_4 4 // thermal throttle 55-60c, low fans, low to none boost (seems like this is what windows sets it by default to)
#define DYTC_MODE_NEW_5 5 // thermal throttle 75-80c, normal fans, standard boost
#define DYTC_MODE_NEW_6 6 // thermal throttle 75-80c, normal fans, standard boost++
#define DYTC_MODE_NEW_7 7 // thermal throttle 80c+, normal fans, lots of boost
#define DYTC_MODE_NEW_8 8 // thermal throttle 80c+, normal fans, lots of boost++
#define DYTC_MODE_NEW_DEFAULT 0xF

// Error code
#define DYTC_EXCEPTION 0
#define DYTC_SUCCESS 1
Expand Down
12 changes: 12 additions & 0 deletions YogaSMCPane/Base.lproj/YogaSMCPane.xib
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<outlet property="vCustomLEDSlider" destination="5gQ-az-9US" id="nY3-qK-vvb"/>
<outlet property="vCycleCount" destination="cFi-NC-K0C" id="axy-Rg-jnS"/>
<outlet property="vDYTCFuncMode" destination="fZZ-Y6-z0X" id="v6d-fS-QEH"/>
<outlet property="vDYTCPSCAvailable" destination="yGD-Vg-eaY" id="UY0-JV-2vn"/>
<outlet property="vDYTCRevision" destination="W8B-pr-Ckq" id="JAI-9h-llK"/>
<outlet property="vDisableFan" destination="5sT-I1-ipX" id="0X7-Qq-6Zs"/>
<outlet property="vECRead" destination="w0X-ID-3TJ" id="8MX-ad-Owg"/>
Expand Down Expand Up @@ -398,6 +399,17 @@
<action selector="vClamshellModeSet:" target="-2" id="nCo-wo-ZZj"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="yGD-Vg-eaY">
<rect key="frame" x="382" y="135" width="105" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="check" title="PSCFunction" bezelStyle="regularSquare" imagePosition="left" enabled="NO" inset="2" id="6gG-Fb-m9Q">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="vDYTCPSCset:" target="-2" id="gct-7R-UKX"/>
</connections>
</button>
</subviews>
</view>
</tabViewItem>
Expand Down
Loading