- [loader] revised cpu coefficients

- [misc] report max77812 voltage reg
This commit is contained in:
KazushiM
2022-01-02 03:03:16 +08:00
parent 82fccb99e1
commit 4373f4fda8
4 changed files with 83 additions and 51 deletions

View File

@@ -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`.

View File

@@ -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 } },

View File

@@ -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());
} }

View File

@@ -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;