Updated: Sys-clk-OC, Loader, System_settings

- Sys-clk-OC

  - Major cleanup in clock_manager, preparing to add basic Erista support.

  - Added an experimental CPU & GPU frequency governor.

    - Known issue:

      - Occasional stuttering is expected: GPU load% metric PMU_GET_GPU_LOAD does not reflect real utilization precisely. Use another metric, some interpolation algo or add min frequency option for improvement.

- Loader

  - Addressed an issue for Erista variants: Boot with unmodified Fusee or Hekate, nn::pcv::EmcDvfsPeriodicCompHandler will fail with rc 0x8C5. Fixed by removing 40.8 MHz while retaining 1600.0 MHz MEM table -- however, this means user has to use modified sys-clk.
This commit is contained in:
KazushiM
2022-10-23 23:01:50 +08:00
parent d596016c84
commit b52bef3c31
27 changed files with 925 additions and 433 deletions

View File

@@ -22,7 +22,7 @@ static inline std::string formatListFreqMhz(std::uint32_t mhz)
}
else if (mhz == 1862)
{
return "Max MHz";
return "Maximum";
}
char buf[10];

View File

@@ -15,7 +15,7 @@
MiscGui::MiscGui()
{
this->configList = new SysClkConfigValueList {};
this->chargeInfo = new ChargeInfo {};
this->chargeInfo = new PsmChargeInfo {};
this->i2cInfo = new I2cInfo {};
}
@@ -48,6 +48,14 @@ void MiscGui::updateConfigToggle(tsl::elm::ToggleListItem *toggle, SysClkConfigV
void MiscGui::listUI()
{
this->listElement->addItem(new tsl::elm::CategoryHeader("Temporary toggles"));
this->backlightToggle = new tsl::elm::ToggleListItem("Screen Backlight", false);
backlightToggle->setStateChangedListener([this](bool state) {
LblUpdate(true);
});
this->listElement->addItem(this->backlightToggle);
sysclkIpcGetConfigValues(this->configList);
this->listElement->addItem(new tsl::elm::CategoryHeader("Config"));
@@ -55,6 +63,7 @@ void MiscGui::listUI()
this->cpuBoostToggle = addConfigToggle(SysClkConfigValue_AutoCPUBoost, "Auto CPU Boost");
this->syncModeToggle = addConfigToggle(SysClkConfigValue_SyncReverseNXMode, "Sync ReverseNX Mode");
this->fastChargingToggle = addConfigToggle(SysClkConfigValue_DisableFastCharging, "Disable Fast Charging");
this->governorToggle = addConfigToggle(SysClkConfigValue_GovernorExperimental, "Governor (Experimental)");
this->chargingLimitHeader = new tsl::elm::CategoryHeader("");
this->listElement->addItem(this->chargingLimitHeader);
@@ -69,7 +78,7 @@ void MiscGui::listUI()
snprintf(chargingLimitBarDesc, 30, "Battery Charging Limit: %lu%%", this->configList->values[SysClkConfigValue_ChargingLimitPercentage]);
this->chargingLimitHeader->setText(chargingLimitBarDesc);
this->chargingLimitBar->setIcon(getBatteryStateIcon());
this->chargingLimitBar->setIcon(PsmGetBatteryStateIcon(this->chargeInfo));
Result rc = sysclkIpcSetConfigValues(this->configList);
if (R_FAILED(rc))
@@ -82,14 +91,6 @@ void MiscGui::listUI()
renderer->drawString("\uE016 Long-term use may render the battery gauge \ninaccurate!", false, x, y + 20, SMALL_TEXT_SIZE, DESC_COLOR);
}), SMALL_TEXT_SIZE * 2 + 20);
this->listElement->addItem(new tsl::elm::CategoryHeader("Temporary toggles"));
this->backlightToggle = new tsl::elm::ToggleListItem("Screen Backlight", false);
backlightToggle->setStateChangedListener([this](bool state) {
LblUpdate(true);
});
this->listElement->addItem(this->backlightToggle);
this->listElement->addItem(new tsl::elm::CategoryHeader("Info"));
this->listElement->addItem(new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) {
renderer->drawString(this->infoNames, false, x, y + 20, SMALL_TEXT_SIZE, DESC_COLOR);
@@ -114,7 +115,7 @@ void MiscGui::refresh() {
this->chargingLimitHeader->setText(chargingLimitBarDesc);
PsmUpdate();
this->chargingLimitBar->setIcon(getBatteryStateIcon());
this->chargingLimitBar->setIcon(PsmGetBatteryStateIcon(this->chargeInfo));
LblUpdate();
this->backlightToggle->setState(lblstatus);

View File

@@ -30,84 +30,6 @@ class MiscGui : public BaseMenuGui
void refresh() override;
protected:
typedef enum {
PDCtrler_NewPDO = 1, //Received new Power Data Object
PDCtrler_NoPD = 2, //No Power Delivery source is detected
PDCtrler_AcceptedRDO = 3 //Received and accepted Request Data Object
} ChargeInfoPDCtrler; //BM92T series
typedef enum {
PowerRole_Sink = 1,
PowerRole_Source = 2
} ChargeInfoPowerRole;
constexpr const char* ChargeInfoPowerRoleToStr(ChargeInfoPowerRole in)
{
switch (in)
{
case PowerRole_Sink: return "Sink";
case PowerRole_Source: return "Source";
default: return "Unknown";
}
};
typedef enum {
ChargerType_None = 0,
ChargerType_PD = 1,
ChargerType_TypeC_1500mA = 2,
ChargerType_TypeC_3000mA = 3,
ChargerType_DCP = 4,
ChargerType_CDP = 5,
ChargerType_SDP = 6,
ChargerType_Apple_500mA = 7,
ChargerType_Apple_1000mA = 8,
ChargerType_Apple_2000mA = 9
} ChargeInfoChargerType;
constexpr const char* ChargeInfoChargerTypeToStr(ChargeInfoChargerType in) noexcept
{
switch (in)
{
case ChargerType_None: return "None";
case ChargerType_PD: return "USB-C PD";
case ChargerType_TypeC_1500mA:
case ChargerType_TypeC_3000mA: return "USB-C";
case ChargerType_DCP: return "USB DCP";
case ChargerType_CDP: return "USB CDP";
case ChargerType_SDP: return "USB SDP";
case ChargerType_Apple_500mA:
case ChargerType_Apple_1000mA:
case ChargerType_Apple_2000mA: return "Apple";
default: return "Unknown";
}
};
typedef enum {
Flags_NoHub = BIT(0), //If hub is disconnected
Flags_Rail = BIT(8), //At least one Joy-con is charging from rail
Flags_SPDSRC = BIT(12), //OTG
Flags_ACC = BIT(16) //Accessory
} ChargeInfoFlags;
typedef struct {
int32_t InputCurrentLimit; //Input (Sink) current limit in mA
int32_t VBUSCurrentLimit; //Output (Source/VBUS/OTG) current limit in mA
int32_t ChargeCurrentLimit; //Battery charging current limit in mA (512mA when Docked, 768mA when BatteryTemperature < 17.0 C)
int32_t ChargeVoltageLimit; //Battery charging voltage limit in mV (3952mV when BatteryTemperature >= 51.0 C)
int32_t unk_x10; //Possibly an emum, getting the same value as PowerRole in all tested cases
int32_t unk_x14; //Possibly flags
ChargeInfoPDCtrler PDCtrlerState; //Power Delivery Controller State
int32_t BatteryTemperature; //Battery temperature in milli C
int32_t RawBatteryCharge; //Raw battery charged capacity per cent-mille (i.e. 100% = 100000 pcm)
int32_t VoltageAvg; //Voltage avg in mV (more in Notes)
int32_t BatteryAge; //Battery age (capacity full / capacity design) per cent-mille (i.e. 100% = 100000 pcm)
ChargeInfoPowerRole PowerRole;
ChargeInfoChargerType ChargerType;
int32_t ChargerVoltageLimit; //Charger and external device voltage limit in mV
int32_t ChargerCurrentLimit; //Charger and external device current limit in mA
ChargeInfoFlags Flags; //Unknown flags
} ChargeInfo;
typedef struct {
float batCurrent;
u32 cpuVolt = 620;
@@ -132,16 +54,6 @@ class MiscGui : public BaseMenuGui
smExit();
}
bool PsmIsChargerConnected()
{
return this->chargeInfo->ChargerType != ChargerType_None;
}
bool PsmIsCharging()
{
return PsmIsChargerConnected() && ((this->chargeInfo->unk_x14 >> 8) & 1);
}
Result I2cRead_OutU16(u8 reg, I2cDevice dev, u16 *out)
{
// ams::fatal::srv::StopSoundTask::StopSound()
@@ -285,14 +197,14 @@ class MiscGui : public BaseMenuGui
"%dmV\n"
"%dmV\n"
,
ChargeInfoChargerTypeToStr(chargeInfo->ChargerType), chargWattsInfo,
PsmInfoChargerTypeToStr(chargeInfo->ChargerType), chargWattsInfo,
(float)chargeInfo->VoltageAvg / 1000,
(float)chargeInfo->BatteryTemperature / 1000,
chargeInfo->InputCurrentLimit, chargeInfo->VBUSCurrentLimit,
chargeInfo->ChargeCurrentLimit, chargeVoltLimit,
(float)chargeInfo->RawBatteryCharge / 1000,
(float)chargeInfo->BatteryAge / 1000,
ChargeInfoPowerRoleToStr(chargeInfo->PowerRole),
PsmPowerRoleToStr(chargeInfo->PowerRole),
batCurInfo,
i2cInfo->cpuVolt,
i2cInfo->gpuVolt,
@@ -302,7 +214,7 @@ class MiscGui : public BaseMenuGui
void PsmChargingToggler(bool* enable)
{
if (!PsmIsChargerConnected())
if (!PsmIsChargerConnected(this->chargeInfo))
{
*enable = false;
return;
@@ -310,7 +222,7 @@ class MiscGui : public BaseMenuGui
PsmUpdate(*enable ? 2 : 3);
*enable = (PsmIsCharging() == *enable);
*enable = (PsmIsCharging(this->chargeInfo) == *enable);
}
void LblUpdate(bool shouldSwitch = false)
@@ -324,44 +236,16 @@ class MiscGui : public BaseMenuGui
smExit();
}
typedef enum {
Discharging,
ChargingPaused,
SlowCharging,
FastCharging
} BatteryState;
BatteryState getBatteryState() {
if (!PsmIsChargerConnected())
return Discharging;
if (!PsmIsCharging())
return ChargingPaused;
return chargeInfo->ChargeCurrentLimit > 768 ? FastCharging : SlowCharging;
}
const char* getBatteryStateIcon() {
switch (getBatteryState()) {
case Discharging: return "\u25c0"; // ◀
case ChargingPaused:return "| |";
case SlowCharging: return "\u25b6"; // ▶
case FastCharging: return "\u25b6\u25b6"; // ▶▶
default: return "?";
}
}
tsl::elm::ToggleListItem* addConfigToggle(SysClkConfigValue, std::string);
void updateConfigToggle(tsl::elm::ToggleListItem*, SysClkConfigValue);
void updateLiftChargingLimitToggle();
tsl::elm::ToggleListItem *unsafeFreqToggle, *cpuBoostToggle, *syncModeToggle, *chargingToggle, *fastChargingToggle, *backlightToggle;
tsl::elm::ToggleListItem *backlightToggle, *unsafeFreqToggle, *cpuBoostToggle, *syncModeToggle, *fastChargingToggle, *governorToggle;
tsl::elm::CategoryHeader *chargingLimitHeader;
StepTrackBarIcon *chargingLimitBar;
SysClkConfigValueList* configList;
ChargeInfo* chargeInfo;
I2cInfo* i2cInfo;
PsmChargeInfo* chargeInfo;
I2cInfo* i2cInfo;
LblBacklightSwitchStatus lblstatus = LblBacklightSwitchStatus_Disabled;
const char* infoNames = "Charger:\nBattery:\nCurrent Limit:\nCharging Limit:\nRaw Charge:\nBattery Age:\nPower Role:\nCurrent Flow:\n\nCPU Volt:\nGPU Volt:\nDRAM Volt:";