- [loader] revised cpu coefficients
- [misc] report max77812 voltage reg
This commit is contained in:
@@ -38,7 +38,6 @@ This project will not be actively maintained in 2022 and I'm looking for collabo
|
|||||||
- **Overclock**
|
- **Overclock**
|
||||||
|
|
||||||
- **Official X1+ CPU/GPU Max clock: 1963.5/1267.2 MHz**.
|
- **Official X1+ CPU/GPU Max clock: 1963.5/1267.2 MHz**.
|
||||||
- Anything above that are not in the table of official module. ([issue #4](https://github.com/KazushiMe/Switch-OC-Suite/issues/4))
|
|
||||||
- All maxed out OC is not recommended, and is strongly discouraged without charger.
|
- All maxed out OC is not recommended, and is strongly discouraged without charger.
|
||||||
- See `Battery Current Flow` in sys-clk-OC overlay `Miscellaneous`.
|
- See `Battery Current Flow` in sys-clk-OC overlay `Miscellaneous`.
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ namespace pcv {
|
|||||||
// 0xF11A0,
|
// 0xF11A0,
|
||||||
0xF11F0,
|
0xF11F0,
|
||||||
};
|
};
|
||||||
// TODO: correctly derive c0-c1 dfll coefficients
|
|
||||||
constexpr cpu_freq_cvb_table_t NewCpuTables[] = {
|
constexpr cpu_freq_cvb_table_t NewCpuTables[] = {
|
||||||
// OldCpuTables
|
// OldCpuTables
|
||||||
// { 204000, { 721589, -12695, 27 }, { 1120000 } },
|
// { 204000, { 721589, -12695, 27 }, { 1120000 } },
|
||||||
@@ -80,10 +79,10 @@ namespace pcv {
|
|||||||
// { 1785000, { 1527196, -36015, 27 }, { 1120000 } },
|
// { 1785000, { 1527196, -36015, 27 }, { 1120000 } },
|
||||||
// { 1887000, { 1609246, -37515, 27 }, { 1120000 } },
|
// { 1887000, { 1609246, -37515, 27 }, { 1120000 } },
|
||||||
// { 1963500, { 1675751, -38635, 27 }, { 1120000 } },
|
// { 1963500, { 1675751, -38635, 27 }, { 1120000 } },
|
||||||
{ 2091000, { 1719782, -40440, 27 }, { NewCpuVoltageScaled } },
|
{ 2091000, { 1785520, -40523, 27 }, { NewCpuVoltageScaled } },
|
||||||
{ 2193000, { 1809766, -41939, 27 }, { NewCpuVoltageScaled } },
|
{ 2193000, { 1878755, -42027, 27 }, { NewCpuVoltageScaled } },
|
||||||
{ 2295000, { 1904458, -43439, 27 }, { NewCpuVoltageScaled } },
|
{ 2295000, { 1975655, -43531, 27 }, { NewCpuVoltageScaled } },
|
||||||
{ 2397000, { NewCpuVoltageScaled }, { NewCpuVoltageScaled } },
|
{ 2397000, { 2076220, -45036, 27 }, { NewCpuVoltageScaled } },
|
||||||
};
|
};
|
||||||
static_assert(sizeof(NewCpuTables) <= sizeof(cpu_freq_cvb_table_t)*14);
|
static_assert(sizeof(NewCpuTables) <= sizeof(cpu_freq_cvb_table_t)*14);
|
||||||
|
|
||||||
@@ -107,7 +106,7 @@ namespace pcv {
|
|||||||
// 0xF2260,
|
// 0xF2260,
|
||||||
0xF22B0,
|
0xF22B0,
|
||||||
};
|
};
|
||||||
// TODO: correctly derive c0-c5 coefficients
|
// No way to correctly derive c0-c5 coefficients, as coefficients >= 1152000 only make sense
|
||||||
constexpr gpu_cvb_pll_table_t NewGpuTables[] = {
|
constexpr gpu_cvb_pll_table_t NewGpuTables[] = {
|
||||||
// OldGpuTables
|
// OldGpuTables
|
||||||
// { 537600, {}, { 801688, -10900, -163, 298, -10599, 162 } },
|
// { 537600, {}, { 801688, -10900, -163, 298, -10599, 162 } },
|
||||||
|
|||||||
@@ -14,12 +14,14 @@
|
|||||||
|
|
||||||
MiscGui::MiscGui()
|
MiscGui::MiscGui()
|
||||||
{
|
{
|
||||||
this->chargeInfo = new ChargeInfo;
|
this->chargeInfo = new ChargeInfo {};
|
||||||
|
this->i2cInfo = new I2cInfo {};
|
||||||
}
|
}
|
||||||
|
|
||||||
MiscGui::~MiscGui()
|
MiscGui::~MiscGui()
|
||||||
{
|
{
|
||||||
delete this->chargeInfo;
|
delete this->chargeInfo;
|
||||||
|
delete this->i2cInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiscGui::preDraw(tsl::gfx::Renderer* render)
|
void MiscGui::preDraw(tsl::gfx::Renderer* render)
|
||||||
@@ -69,7 +71,8 @@ void MiscGui::update()
|
|||||||
{
|
{
|
||||||
frameCounter = 0;
|
frameCounter = 0;
|
||||||
PsmUpdate();
|
PsmUpdate();
|
||||||
GetInfo(this->infoOutput, sizeof(this->infoOutput));
|
I2cGetInfo(this->i2cInfo);
|
||||||
|
PrintInfo(this->infoOutput, sizeof(this->infoOutput));
|
||||||
this->chargingToggle->setState(this->PsmIsCharging());
|
this->chargingToggle->setState(this->PsmIsCharging());
|
||||||
this->fastChargingToggle->setState(this->PsmIsFastCharging());
|
this->fastChargingToggle->setState(this->PsmIsFastCharging());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,6 +108,20 @@ class MiscGui : public BaseMenuGui
|
|||||||
Max17050Reg_Cycle = 0x17,
|
Max17050Reg_Cycle = 0x17,
|
||||||
} Max17050Reg;
|
} Max17050Reg;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
Max77812Reg_CPUVolt = 0x26,
|
||||||
|
Max77812Reg_GPUVolt = 0x23,
|
||||||
|
Max77812Reg_DRAMVolt = 0x25,
|
||||||
|
} Max77812Reg;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float batCurrent;
|
||||||
|
u32 cpuVolt = 620;
|
||||||
|
u32 gpuVolt = 610;
|
||||||
|
u32 dramVolt = 600;
|
||||||
|
} I2cInfo;
|
||||||
|
|
||||||
void PsmUpdate(uint32_t dispatchId = 0)
|
void PsmUpdate(uint32_t dispatchId = 0)
|
||||||
{
|
{
|
||||||
smInitialize();
|
smInitialize();
|
||||||
@@ -179,72 +193,89 @@ class MiscGui : public BaseMenuGui
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Max17050ReadReg(u8 reg, u16 *out)
|
void I2cGetInfo(I2cInfo* i2cInfo)
|
||||||
{
|
{
|
||||||
|
smInitialize();
|
||||||
|
i2cInitialize();
|
||||||
u16 data = 0;
|
u16 data = 0;
|
||||||
Result res = I2cReadRegHandler(reg, I2cDevice_Max17050, &data);
|
|
||||||
|
|
||||||
if (res)
|
// Read max17050 furl gauge regs. Sense resistor and CGain are from Hekate, too lazy to query configuration from reg
|
||||||
{
|
{
|
||||||
*out = res;
|
constexpr float SenseResistor = 5.; // in uOhm
|
||||||
return false;
|
constexpr float CGain = 1.99993;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(I2cReadRegHandler(Max17050Reg_Current, I2cDevice_Max17050, &data)))
|
||||||
|
i2cInfo->batCurrent = (s16)data * (1.5625 / (SenseResistor * CGain));
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = data;
|
// Read max77812 volt regs
|
||||||
return true;
|
{
|
||||||
|
auto ConvertToMVolt = [](u32 *out, u16 data)
|
||||||
|
{
|
||||||
|
constexpr u32 MinMVolt = 250;
|
||||||
|
constexpr u32 StepMVolt = 5;
|
||||||
|
constexpr u32 VoltMask = 0xFF;
|
||||||
|
|
||||||
|
u32 mvolt = (data & VoltMask) * StepMVolt + MinMVolt;
|
||||||
|
|
||||||
|
// Ignore 850 mV as it is questionable
|
||||||
|
if (mvolt == 850)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*out = mvolt;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(I2cReadRegHandler(Max77812Reg_CPUVolt, I2cDevice_Max77812_2, &data)))
|
||||||
|
ConvertToMVolt(&(i2cInfo->cpuVolt), data);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(I2cReadRegHandler(Max77812Reg_GPUVolt, I2cDevice_Max77812_2, &data)))
|
||||||
|
ConvertToMVolt(&(i2cInfo->gpuVolt), data);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(I2cReadRegHandler(Max77812Reg_DRAMVolt, I2cDevice_Max77812_2, &data)))
|
||||||
|
ConvertToMVolt(&(i2cInfo->dramVolt), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
i2cExit();
|
||||||
|
smExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetInfo(char* out, size_t outsize)
|
void PrintInfo(char* out, size_t outsize)
|
||||||
{
|
{
|
||||||
float chargerVoltLimit = (float)chargeInfo->ChargerVoltageLimit / 1000;
|
float chargerVoltLimit = (float)chargeInfo->ChargerVoltageLimit / 1000;
|
||||||
float chargerCurrLimit = (float)chargeInfo->ChargerCurrentLimit / 1000;
|
float chargerCurrLimit = (float)chargeInfo->ChargerCurrentLimit / 1000;
|
||||||
float chargerOutWatts = chargerVoltLimit * chargerCurrLimit;
|
float chargerOutWatts = chargerVoltLimit * chargerCurrLimit;
|
||||||
|
|
||||||
float batCurrent = 0;
|
|
||||||
float batCycleCount = 0;
|
|
||||||
|
|
||||||
char chargeVoltLimit[20] = "";
|
char chargeVoltLimit[20] = "";
|
||||||
if (chargeInfo->ChargeVoltageLimit)
|
if (chargeInfo->ChargeVoltageLimit)
|
||||||
snprintf(chargeVoltLimit, sizeof(chargeVoltLimit), ", %u mV", chargeInfo->ChargeVoltageLimit);
|
snprintf(chargeVoltLimit, sizeof(chargeVoltLimit), ", %u mV", chargeInfo->ChargeVoltageLimit);
|
||||||
|
|
||||||
// From Hekate, too lazy to query configuration from reg
|
char chargWattsInfo[50] = "";
|
||||||
constexpr float max17050SenseResistor = 5.; // in uOhm
|
if (chargeInfo->ChargerType)
|
||||||
constexpr float max17050CGain = 1.99993;
|
snprintf(chargWattsInfo, sizeof(chargWattsInfo), " %.1fV/%.1fA (%.1fW)", chargerVoltLimit, chargerCurrLimit, chargerOutWatts);
|
||||||
|
|
||||||
// Init, read registers and exit I2C service all here to save resources
|
char batCurInfo[30] = "";
|
||||||
{
|
if (std::abs(i2cInfo->batCurrent) < 10)
|
||||||
smInitialize();
|
snprintf(batCurInfo, sizeof(batCurInfo), "0 mA");
|
||||||
i2cInitialize();
|
else
|
||||||
u16 data = 0;
|
snprintf(batCurInfo, sizeof(batCurInfo), "%+.2f mA (%+.2f W)",
|
||||||
|
i2cInfo->batCurrent, i2cInfo->batCurrent * (float)chargeInfo->VoltageAvg / 1000'000);
|
||||||
if (Max17050ReadReg(Max17050Reg_Cycle, &data))
|
|
||||||
batCycleCount = data / 100.;
|
|
||||||
|
|
||||||
if (Max17050ReadReg(Max17050Reg_Current, &data))
|
|
||||||
batCurrent = (s16)data * (1.5625 / (max17050SenseResistor * max17050CGain));
|
|
||||||
|
|
||||||
i2cExit();
|
|
||||||
smExit();
|
|
||||||
}
|
|
||||||
|
|
||||||
char batWattsInfo[20] = "";
|
|
||||||
if (std::abs(batCurrent) > 100)
|
|
||||||
snprintf(batWattsInfo, sizeof(batWattsInfo), " (%+.2f W)", batCurrent * (float)chargeInfo->VoltageAvg / 1000'000);
|
|
||||||
|
|
||||||
snprintf(out, outsize,
|
snprintf(out, outsize,
|
||||||
"%s"
|
"%s"
|
||||||
"\nCharger: %s %.1fV/%.1fA (%.1fW)"
|
"\nCharger: %s%s"
|
||||||
"\nBattery: %.3fV %.2f\u00B0C"
|
"\nBattery: %.3fV %.2f\u00B0C"
|
||||||
"\nCurrent Limit: %u mA IN, %u mA OUT"
|
"\nCurrent Limit: %u mA IN, %u mA OUT"
|
||||||
"\nCharging Limit: %u mA%s"
|
"\nCharging Limit: %u mA%s"
|
||||||
"\nRaw Charge: %.2f%%"
|
"\nRaw Charge: %.2f%%"
|
||||||
"\nBattery Age: %.2f%%"
|
"\nBattery Age: %.2f%%"
|
||||||
"\nPower Role: %s"
|
"\nPower Role: %s"
|
||||||
"\nCycle Count: %.2f (Reset at power-up)"
|
"\nCurrent Flow: %s\n"
|
||||||
"\nCurrent Flow: %+.2f mA%s"
|
"\nCPU Volt: %d mV"
|
||||||
|
"\nGPU Volt: %d mV"
|
||||||
|
"\nDRAM Volt: %d mV"
|
||||||
,
|
,
|
||||||
PsmIsEnoughPowerSupplied() ? "Enough Power Supplied" : "",
|
PsmIsEnoughPowerSupplied() ? "Enough Power Supplied" : "",
|
||||||
ChargeInfoChargerTypeToStr(chargeInfo->ChargerType), chargerVoltLimit, chargerCurrLimit, chargerOutWatts,
|
ChargeInfoChargerTypeToStr(chargeInfo->ChargerType), chargWattsInfo,
|
||||||
(float)chargeInfo->VoltageAvg / 1000,
|
(float)chargeInfo->VoltageAvg / 1000,
|
||||||
(float)chargeInfo->BatteryTemperature / 1000,
|
(float)chargeInfo->BatteryTemperature / 1000,
|
||||||
chargeInfo->InputCurrentLimit, chargeInfo->VBUSCurrentLimit,
|
chargeInfo->InputCurrentLimit, chargeInfo->VBUSCurrentLimit,
|
||||||
@@ -252,8 +283,10 @@ class MiscGui : public BaseMenuGui
|
|||||||
(float)chargeInfo->RawBatteryCharge / 1000,
|
(float)chargeInfo->RawBatteryCharge / 1000,
|
||||||
(float)chargeInfo->BatteryAge / 1000,
|
(float)chargeInfo->BatteryAge / 1000,
|
||||||
ChargeInfoPowerRoleToStr(chargeInfo->PowerRole),
|
ChargeInfoPowerRoleToStr(chargeInfo->PowerRole),
|
||||||
batCycleCount,
|
batCurInfo,
|
||||||
batCurrent, batWattsInfo
|
i2cInfo->cpuVolt,
|
||||||
|
i2cInfo->gpuVolt,
|
||||||
|
i2cInfo->dramVolt
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,9 +302,6 @@ class MiscGui : public BaseMenuGui
|
|||||||
|
|
||||||
bool PsmFastChargingToggler(bool enable)
|
bool PsmFastChargingToggler(bool enable)
|
||||||
{
|
{
|
||||||
if (!PsmIsChargerConnected())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
PsmUpdate(enable ? 10 : 11);
|
PsmUpdate(enable ? 10 : 11);
|
||||||
|
|
||||||
return PsmIsFastCharging() == enable;
|
return PsmIsFastCharging() == enable;
|
||||||
@@ -280,6 +310,7 @@ class MiscGui : public BaseMenuGui
|
|||||||
tsl::elm::ToggleListItem *chargingToggle, *fastChargingToggle;
|
tsl::elm::ToggleListItem *chargingToggle, *fastChargingToggle;
|
||||||
|
|
||||||
ChargeInfo* chargeInfo;
|
ChargeInfo* chargeInfo;
|
||||||
|
I2cInfo* i2cInfo;
|
||||||
bool isEnoughPowerSupplied = false;
|
bool isEnoughPowerSupplied = false;
|
||||||
char infoOutput[800] = "";
|
char infoOutput[800] = "";
|
||||||
int frameCounter = 60;
|
int frameCounter = 60;
|
||||||
|
|||||||
Reference in New Issue
Block a user