Revert "sysclk: add PWM dimming"

This reverts commit ec661ac1c0.
This commit is contained in:
souldbminersmwc
2026-03-29 14:45:09 -04:00
parent 1f2b3848e4
commit 1f2999df2f
6 changed files with 6 additions and 429 deletions

View File

@@ -66,7 +66,6 @@ typedef enum {
HorizonOCConfigValue_RAMVoltUsageDisplayMode,
HorizonOCConfigValue_CpuGovernorMinimumFreq,
HorizonOCConfigValue_PWMDimming,
KipConfigValue_custRev,
// KipConfigValue_mtcConf,
@@ -253,10 +252,6 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
return pretty ? "RAM Voltage / Usage Display Mode" : "ram_volt_usage_display_mode";
case HorizonOCConfigValue_CpuGovernorMinimumFreq:
return pretty ? "CPU Governor Minimum Frequency" : "cpu_gov_min_freq";
case HorizonOCConfigValue_PWMDimming:
return pretty ? "PWM Dimming" : "pwm_dimming";
// KIP config values
case KipConfigValue_custRev:
return pretty ? "Custom Revision" : "kip_cust_rev";
@@ -447,7 +442,6 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
case HocClkConfigValue_HandheldTDP:
case HocClkConfigValue_IsFirstLoad:
case HorizonOCConfigValue_DVFSMode:
case HorizonOCConfigValue_PWMDimming:
return 1ULL;
case HocClkConfigValue_ThermalThrottleThreshold:
return 70ULL;
@@ -490,7 +484,6 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
case HorizonOCConfigValue_EnableExperimentalSettings:
case HorizonOCConfigValue_LiveCpuUv:
case HorizonOCConfigValue_GPUSchedulingMethod:
case HorizonOCConfigValue_PWMDimming:
return (input & 0x1) == input;
case KipConfigValue_custRev:

View File

@@ -650,9 +650,6 @@ protected:
false
);
}
if(IsAula()) {
addConfigToggle(HorizonOCConfigValue_PWMDimming, nullptr);
}
}
};

View File

@@ -235,30 +235,6 @@
"is_ro": false,
"is_io": true
}
}, {
"type": "map",
"value": {
"address": "0x54200000",
"size": "0x40000",
"is_ro": false,
"is_io": true
}
}, {
"type": "map",
"value": {
"address": "0x54240000",
"size": "0x40000",
"is_ro": false,
"is_io": true
}
}, {
"type": "map",
"value": {
"address": "0x54400000",
"size": "0x40000",
"is_ro": false,
"is_io": true
}
}
]
}

View File

@@ -56,30 +56,6 @@
#define NVSCHED_CTRL_ENABLE 0x00000601
#define NVSCHED_CTRL_DISABLE 0x00000602
#define PWM_CSC_COEFF_0 0xCA8 /* Blue / Channel 0 */
#define PWM_CSC_COEFF_1 0xCB8 /* Green / Channel 1 */
#define PWM_CSC_COEFF_2 0xCC8 /* Red / Channel 2 */
#define PWM_CMD_STATE_CTRL 0xE4
#define CSC_COEFF_MASK 0x3FF
#define CSC_IDENTITY 0x100
#define DISP_OUT_PWM_CTRL 0x138
#define DISP_OUT_PWM_ENABLE 9
#define DISP_OUT_PWM_DISABLE 0
#define DISP_OUT_RESET_CTRL 0x04
#define DSI_WR_DATA 0x28
#define DSI_TRIGGER 0x4C
#define DSI_TRIGGER_HOST 2
#define DSI_PKT_SHORT_NO_PARAM 0x05
#define DSI_PKT_SHORT_1_PARAM 0x15
#define DSI_PKT_LONG_WRITE 0x39
#define DCS_WRITE_DISPLAY_BRIGHTNESS 0x51
#define DCS_WRITE_CTRL_DISPLAY 0x53
#define DCS_CTRL_DISPLAY_PARAM 0x28
constexpr u64 CpuTimeOutNs = 500'000'000;
constexpr double Systemtickfrequency = 19200000.0 * (static_cast<double>(CpuTimeOutNs) / 1'000'000'000.0);
Result nvInitialize_rc;
@@ -121,21 +97,6 @@ u8 g_dramID = 0;
u64 cldvfs, cldvfs_temp;
u32 cachedEristaUvLowTune0 = 0, cachedEristaUvLowTune1 = 0, cachedMarikoUvHighTune0 = 0;
u64 g_clk_vaddr;
u64 g_dca_vaddr;
u64 g_dcb_vaddr;
u64 g_dsi_vaddr;
u64 g_unk_vaddr;
bool g_pwmDimEnabled = false;
bool g_pwmFirstApply = false;
u32 g_cscR = CSC_IDENTITY;
u32 g_cscG = CSC_IDENTITY;
u32 g_cscB = CSC_IDENTITY;
u32 g_cscR2 = CSC_IDENTITY;
u32 g_cscG2 = CSC_IDENTITY;
u32 g_cscB2 = CSC_IDENTITY;
static const u32 ramBrackets[][22] = {
{ 2133, 2200, 2266, 2300, 2366, 2400, 2433, 2466, 2533, 2566, 2600, 2633, 2700, 2733, 2766, 2833, 2866, 2900, 2933, 3033, 3066, 3100, },
{ 2300, 2366, 2433, 2466, 2533, 2566, 2633, 2700, 2733, 2800, 2833, 2900, 2933, 2966, 3033, 3066, 3100, 3133, 3166, 3200, 3233, 3266, },
@@ -150,70 +111,6 @@ u64 dvfsAddress;
u32 ramVmin;
bool isRetro = false;
static const struct {
u16 clk_src;
u16 dc_div;
} g_dispClkColorTable[78] = {
{0x0020, 0xF200}, {0x0020, 0xFF0C}, {0x0020, 0x0C16},
{0x0028, 0xF906}, {0x0028, 0x0610},
{0x0030, 0xF300}, {0x0030, 0x000B}, {0x0030, 0x0D16},
{0x0038, 0xFA06}, {0x0038, 0x0710},
{0x0040, 0xF400}, {0x0040, 0x010A}, {0x0040, 0x0E16},
{0x0048, 0xFB06}, {0x0048, 0x0810},
{0x0050, 0xF500}, {0x0050, 0x020A}, {0x0050, 0x0F16},
{0x0058, 0xFC06}, {0x0058, 0x0910},
{0x0060, 0xF600}, {0x0060, 0x030A}, {0x0060, 0x1016},
{0x0068, 0xFD06}, {0x0068, 0x0A10},
{0x0070, 0xF700}, {0x0070, 0x040A},
{0x0078, 0xF0FB}, {0x0078, 0xFE06}, {0x0078, 0x0B10},
{0x0080, 0xF800}, {0x0080, 0x050A},
{0x0088, 0xF1FB}, {0x0088, 0xFF06}, {0x0088, 0x0C10},
{0x0090, 0xF900}, {0x0090, 0x060A},
{0x0098, 0xF2FB}, {0x0098, 0x0005}, {0x0098, 0x0D10},
{0x00A0, 0xFA00}, {0x00A0, 0x070A},
{0x00A8, 0xF3FB}, {0x00A8, 0x0105}, {0x00A8, 0x0E10},
{0x00B0, 0xFB00}, {0x00B0, 0x080A},
{0x00B8, 0xF4FB}, {0x00B8, 0x0205}, {0x00B8, 0x0F10},
{0x00C0, 0xFC00}, {0x00C0, 0x090A},
{0x00C8, 0xF5FB}, {0x00C8, 0x0305}, {0x00C8, 0x1010},
{0x00D0, 0xFD00}, {0x00D0, 0x0A0A},
{0x00D8, 0xF6FA}, {0x00D8, 0x0405},
{0x00E0, 0xF0F5}, {0x00E0, 0xFE00}, {0x00E0, 0x0B0A},
{0x00E8, 0xF7FA}, {0x00E8, 0x0505},
{0x00F0, 0xEEB2}, {0x00F0, 0xFF00}, {0x00F0, 0x0C0A},
{0x00F8, 0xF8FA}, {0x00F8, 0x0605},
{0x00F8, 0x130F}, {0x00F8, 0x2019}, {0x00F8, 0x2D23},
{0x00F8, 0x3A2D}, {0x00F8, 0x4737}, {0x00F8, 0x5441},
{0x00F8, 0x614B}, {0x00F8, 0x6E55}, {0x00F8, 0x0000},
};
const char* Board::GetModuleName(SysClkModule module, bool pretty)
{
ASSERT_ENUM_VALID(SysClkModule, module);
@@ -353,9 +250,6 @@ void Board::Initialize()
rc = pmdmntInitialize();
ASSERT_RESULT_OK(rc, "pmdmntInitialize");
rc = lblInitialize();
ASSERT_RESULT_OK(rc, "lblInitialize");
threadCreate(&gpuLThread, gpuLoadThread, NULL, NULL, 0x1000, 0x3F, -2);
threadStart(&gpuLThread);
leventClear(&threadexit);
@@ -380,13 +274,13 @@ void Board::Initialize()
struct stat st = {0};
isRetro = (stat("sdmc:/" FILE_CONFIG_DIR "/retro.flag", &st) == 0);
u64 outsize;
rc = svcQueryMemoryMapping(&g_clk_vaddr, &outsize, 0x60006000, 0x1000);
u64 clkVirtAddr, dsiVirtAddr, outsize;
rc = svcQueryMemoryMapping(&clkVirtAddr, &outsize, 0x60006000, 0x1000);
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (clk)");
rc = svcQueryMemoryMapping(&g_dsi_vaddr, &outsize, 0x54300000, 0x40000);
rc = svcQueryMemoryMapping(&dsiVirtAddr, &outsize, 0x54300000, 0x40000);
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (dsi)");
DisplayRefreshConfig cfg = {.clkVirtAddr = g_clk_vaddr, .dsiVirtAddr = g_dsi_vaddr, .isLite = IsHoag(), .isRetroSUPER = isRetro, .isPossiblySpoofedRetro = isRetro};
DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr, .isLite = IsHoag(), .isRetroSUPER = isRetro, .isPossiblySpoofedRetro = isRetro};
DisplayRefresh_Initialize(&cfg);
@@ -402,17 +296,7 @@ void Board::Initialize()
Board::ResetToStockCpu();
}
rc = svcQueryMemoryMapping(&g_dca_vaddr, &outsize, 0x54200000, 0x40000);
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (dca)");
rc = svcQueryMemoryMapping(&g_dcb_vaddr, &outsize, 0x54240000, 0x40000);
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (dcb)");
rc = svcQueryMemoryMapping(&g_unk_vaddr, &outsize, 0x54400000, 0x40000);
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (unk)");
}
bool Board::IsDisplayClockActive()
{
return (*(volatile uint32_t *) (g_clk_vaddr + 0x10) >> 27) & 1;
}
bool Board::IsUsingRetroSuperDisplay() {
@@ -545,7 +429,6 @@ void Board::Exit()
batteryInfoExit();
pmdmntExit();
nvExit();
lblExit();
}
@@ -1436,250 +1319,4 @@ u32 Board::CalculateTbreak(u32 table) {
bool Board::IsHoag() {
return Board::GetConsoleType() == HorizonOCConsoleType_Hoag;
}
void Board::SetPWMDimEnabled(bool enabled)
{
g_pwmDimEnabled = enabled;
}
static void WritePWMRegister(uint32_t offset, uint32_t value)
{
bool is_dc_a = (*(volatile uint32_t *) (g_clk_vaddr + 0x10) >> 27) & 1;
u64 base = is_dc_a ? g_dca_vaddr : g_dcb_vaddr;
*(volatile uint32_t *) (base + offset) = value;
}
static uint32_t ReadPWMRegister(uint32_t offset) {
bool is_dc_a = (*(volatile uint32_t *)(g_clk_vaddr + 0x10) >> 27) & 1;
u64 base = is_dc_a ? g_dca_vaddr : g_dcb_vaddr;
return *(volatile uint32_t *)(base + offset);
}
static u64 GetDisplayOutputBase()
{
return Board::IsDisplayClockActive() ? g_dsi_vaddr : g_unk_vaddr;
}
static void WriteDisplayOutputRegister(uint32_t offset, uint32_t value)
{
*(volatile uint32_t *) (GetDisplayOutputBase() + offset) = value;
}
static int GetDisplayClockColorOffset(void)
{
if (g_clk_vaddr == 0)
return 60;
u8 clkSrc = (*(volatile u32 *) (g_clk_vaddr + 0xD0) >> 8) & 0xFF;
u16 dcDiv = (u16) * (volatile u32 *) (g_clk_vaddr + 0xDC);
for (int i = 0; i < 78; i++) {
if (g_dispClkColorTable[i].clk_src == clkSrc &&
g_dispClkColorTable[i].dc_div == dcDiv)
return i + 10;
}
return 60; /* default */
}
static void DSIWait(uint32_t us)
{
svcSleepThread((s64) us * 1000);
}
static void PWMTriggerStateControl(uint32_t bits)
{
u32 val = ReadPWMRegister(PWM_CMD_STATE_CTRL);
WritePWMRegister(PWM_CMD_STATE_CTRL, val | bits);
}
static void PWMClearStateControl(uint32_t bits)
{
u32 val = ReadPWMRegister(PWM_CMD_STATE_CTRL);
WritePWMRegister(PWM_CMD_STATE_CTRL, val & ~bits);
WritePWMRegister(0xDC, bits);
}
static void PWMFlushAndWait(uint32_t bits)
{
WritePWMRegister(0xDC, bits);
for (int i = 0; i < 40000; i++) {
if (ReadPWMRegister(0xDC) & bits)
return;
}
}
static void DSISetHostControl(bool enable)
{
if (enable) {
PWMTriggerStateControl(2);
WriteDisplayOutputRegister(DISP_OUT_PWM_CTRL, DISP_OUT_PWM_ENABLE);
PWMFlushAndWait(2);
} else {
PWMFlushAndWait(2);
DSIWait(14);
WriteDisplayOutputRegister(DISP_OUT_RESET_CTRL, 1);
DSIWait(300);
WriteDisplayOutputRegister(DISP_OUT_RESET_CTRL, 0);
DSIWait(300);
WriteDisplayOutputRegister(DISP_OUT_PWM_CTRL, DISP_OUT_PWM_DISABLE);
PWMClearStateControl(2);
}
}
static void SendDSIShortWrite(uint8_t type, int data, uint32_t wait)
{
if (!Board::IsDisplayClockActive())
return;
uint32_t cmd = (type & 0xFF) | (data << 8);
WriteDisplayOutputRegister(DSI_WR_DATA, cmd);
WriteDisplayOutputRegister(DSI_TRIGGER, DSI_TRIGGER_HOST);
if (wait != 0)
DSIWait(wait);
}
static void SendDSIPacket(uint8_t cmd, uint32_t len, void *payload)
{
static uint32_t *dsiCmdBuf = nullptr;
static uint32_t *dsiCmdBufHead = nullptr;
if (dsiCmdBuf == nullptr) {
dsiCmdBuf = (uint32_t *) malloc(0x3E0);
dsiCmdBufHead = dsiCmdBuf;
}
DSISetHostControl(true);
if (len == 0) {
uint32_t word = ((uint32_t) cmd << 8) | DSI_PKT_SHORT_NO_PARAM;
WriteDisplayOutputRegister(DSI_WR_DATA, word);
} else if (len == 1) {
uint8_t param = *(uint8_t *) payload;
uint32_t word = ((uint32_t) param << 16) | ((uint32_t) cmd << 8) |
DSI_PKT_SHORT_1_PARAM;
WriteDisplayOutputRegister(DSI_WR_DATA, word);
} else {
memcpy((uint8_t *) dsiCmdBuf + 5, payload, len);
memset((uint8_t *) dsiCmdBuf + 5 + len, 0, len & 3);
uint32_t headerWord = ((len + 1) << 8) | DSI_PKT_LONG_WRITE;
*dsiCmdBufHead = headerWord;
*((uint8_t *) (dsiCmdBuf + 1)) = cmd;
uint32_t numWords = (len + 5 + 3) >> 2;
for (uint32_t i = 0; i < numWords; i++)
WriteDisplayOutputRegister(
DSI_WR_DATA, ((uint32_t *) dsiCmdBufHead)[i]);
DSISetHostControl(false);
return;
}
DSISetHostControl(false);
}
void Board::SetPWMDimBrightness(u32 prevBrightness, u32 targetBrightness, bool applyAllChannels) {
if (!g_pwmDimEnabled) {
g_cscR = g_cscG = g_cscB = CSC_IDENTITY;
g_cscR2 = g_cscG2 = g_cscB2 = CSC_IDENTITY;
if (Board::IsDisplayClockActive()) {
WritePWMRegister(PWM_CSC_COEFF_0, CSC_IDENTITY);
WritePWMRegister(PWM_CSC_COEFF_1, CSC_IDENTITY);
WritePWMRegister(PWM_CSC_COEFF_2, CSC_IDENTITY);
}
return;
}
u32 prevPct = prevBrightness & 0xFF;
u32 targetPct = targetBrightness & 0xFF;
if (!Board::IsDisplayClockActive())
return;
bool autoBrightness = false;
lblIsAutoBrightnessControlEnabled(&autoBrightness);
if (autoBrightness) {
FileUtils::LogLine(
"[pwmDim] Auto-brightness enabled, applying default CSC values");
g_cscR = g_cscG = g_cscB = CSC_IDENTITY;
g_cscR2 = g_cscG2 = g_cscB2 = CSC_IDENTITY;
if (Board::IsDisplayClockActive()) {
WritePWMRegister(PWM_CSC_COEFF_0, CSC_IDENTITY);
WritePWMRegister(PWM_CSC_COEFF_1, CSC_IDENTITY);
WritePWMRegister(PWM_CSC_COEFF_2, CSC_IDENTITY);
}
g_pwmFirstApply = false;
return;
}
u32 cscValue;
if (targetPct < 50)
cscValue = CSC_IDENTITY - (((targetPct << 8) / 0x31) * 0x85 >> 8);
else
cscValue = ((((targetPct - 50) * 0x100) / 50) * 0x85 >> 8) + 0x7B;
if (applyAllChannels) {
g_cscR2 = g_cscG2 = g_cscB2 = cscValue;
g_cscR = g_cscG = g_cscB = cscValue;
if (Board::IsDisplayClockActive()) {
WritePWMRegister(PWM_CSC_COEFF_0, cscValue & CSC_COEFF_MASK);
WritePWMRegister(PWM_CSC_COEFF_2, cscValue & CSC_COEFF_MASK);
int colorOffset = GetDisplayClockColorOffset();
WritePWMRegister(
PWM_CSC_COEFF_1, ((cscValue & CSC_COEFF_MASK) - 0x40 + colorOffset) &
CSC_COEFF_MASK);
}
g_pwmFirstApply = false;
} else {
g_cscB2 = cscValue;
if (!g_pwmFirstApply) {
if (Board::IsDisplayClockActive()) {
g_cscB = ReadPWMRegister(PWM_CSC_COEFF_0) & CSC_COEFF_MASK;
g_cscG = ReadPWMRegister(PWM_CSC_COEFF_1) & CSC_COEFF_MASK;
g_cscR = ReadPWMRegister(PWM_CSC_COEFF_2) & CSC_COEFF_MASK;
} else {
g_pwmFirstApply = true;
}
}
g_cscR2 = g_cscB2;
g_cscG2 = g_cscB2;
}
int pwmLevel;
if (targetPct >= 50)
pwmLevel = 0xFF;
else {
pwmLevel = (targetPct * 0xFF / 100) << 1;
if (pwmLevel < 5)
pwmLevel = 5;
}
if (!Board::IsDisplayClockActive())
return;
WriteDisplayOutputRegister(DISP_OUT_PWM_CTRL, DISP_OUT_PWM_ENABLE);
SendDSIShortWrite(DSI_PKT_SHORT_1_PARAM,
(DCS_CTRL_DISPLAY_PARAM << 8) | DCS_WRITE_CTRL_DISPLAY, 0);
u32 pwm11bit = (pwmLevel * 0x7FF) / 0xFF;
u16 pwmSwapped = (u16) ((pwm11bit >> 8) | ((pwm11bit & 0xFF) << 8));
if (!Board::IsDisplayClockActive())
return;
SendDSIPacket(DCS_WRITE_DISPLAY_BRIGHTNESS, 2, &pwmSwapped);
if (Board::IsDisplayClockActive()) {
u32 stateCtrl = ReadPWMRegister(PWM_CMD_STATE_CTRL);
WritePWMRegister(PWM_CMD_STATE_CTRL, stateCtrl | 2);
}
if (Board::IsDisplayClockActive())
WriteDisplayOutputRegister(DISP_OUT_PWM_CTRL, DISP_OUT_PWM_DISABLE);
if (prevPct == targetPct)
FileUtils::LogLine("[pwmDim] PWM Brightness: %u%%", targetPct);
else
FileUtils::LogLine("[pwmDim] PWM Brightness: %u%% -> %u%%", prevPct, targetPct);
}

View File

@@ -24,6 +24,7 @@
* --------------------------------------------------------------------------
*/
#pragma once
#include <cstdint>
#include <switch.h>
@@ -70,17 +71,12 @@ class Board
static u32 CalculateTbreak(u32 table);
static bool IsHoag();
static bool IsUsingRetroSuperDisplay();
static bool IsDisplayClockActive();
static void SetPWMDimBrightness(u32 prevBrightness, u32 targetBrightness, bool applyAllChannels);
static void SetPWMDimEnabled(bool enabled);
protected:
static void FetchHardwareInfos();
static PcvModule GetPcvModule(SysClkModule sysclkModule);
static PcvModuleId GetPcvModuleId(SysClkModule sysclkModule);
private:
static void SetSpeedoBracket();
static void CacheDvfsTable();
static Handle GetPcvHandle();
};
};

View File

@@ -595,28 +595,6 @@ void ClockManager::HandleSafetyFeatures() {
}
void ClockManager::HandleMiscFeatures() {
static u32 prevBrightness = 100;
static bool wasPWMDimEnabled = false;
if(Board::GetConsoleType() == HorizonOCConsoleType_Aula && this->config->GetConfigValue(HorizonOCConfigValue_PWMDimming)) {
float out = 1.0;
Result rc = lblGetCurrentBrightnessSetting(&out);
ASSERT_RESULT_OK(rc, "lblGetCurrentBrightnessSetting");
u32 brightness = (u32)(out * 100);
Board::SetPWMDimEnabled(true);
Board::SetPWMDimBrightness(prevBrightness, brightness, true);
prevBrightness = brightness;
wasPWMDimEnabled = true;
} else if (Board::GetConsoleType() == HorizonOCConsoleType_Aula && wasPWMDimEnabled) {
Board::SetPWMDimEnabled(false);
Board::SetPWMDimBrightness(0, 0, false);
float out = 1.0;
Result rc = lblGetCurrentBrightnessSetting(&out);
ASSERT_RESULT_OK(rc, "lblGetCurrentBrightnessSetting");
rc = lblSetCurrentBrightnessSetting(out);
ASSERT_RESULT_OK(rc, "lblSetCurrentBrightnessSetting");
wasPWMDimEnabled = false;
}
if(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent)) {
I2c_Bq24193_SetFastChargeCurrentLimit(this->config->GetConfigValue(HorizonOCConfigValue_BatteryChargeCurrent));
}