hocclk: fix gm20b driver bug at >1305mhz

This commit is contained in:
souldbminersmwc
2026-05-28 20:02:33 -04:00
parent e52d57a961
commit a18efcbed7
3 changed files with 39 additions and 29 deletions

View File

@@ -43,8 +43,12 @@
#include "../soc/gm20b.hpp" #include "../soc/gm20b.hpp"
#include "../file/config.hpp" #include "../file/config.hpp"
namespace board { namespace board {
#define MIDDLE_FREQ_TABLE_START_POINT 1228800000
static u32 currentInjectedHz = 0; static u32 currentInjectedHz = 0;
static u32 gMarikoGm20bCutoff = 1228800000;
void SetMarikoGm20bCutoff(u32 hz) {
gMarikoGm20bCutoff = hz;
}
PcvModule GetPcvModule(HocClkModule hocclkModule) { PcvModule GetPcvModule(HocClkModule hocclkModule) {
switch (hocclkModule) { switch (hocclkModule) {
case HocClkModule_CPU: case HocClkModule_CPU:
@@ -97,7 +101,7 @@ namespace board {
return; return;
} }
bool useGm20b = (module == HocClkModule_GPU) && (GetSocType() == HocClkSocType_Mariko) && (hz % 38400000 == 0) && (hz % 76800000 != 0) && hz < MIDDLE_FREQ_TABLE_START_POINT; bool useGm20b = (module == HocClkModule_GPU) && (GetSocType() == HocClkSocType_Mariko) && (hz % 38400000 == 0) && (hz % 76800000 != 0) && hz < gMarikoGm20bCutoff;
u32 pcvHz = useGm20b ? ((hz + 76800000 - 1) / 76800000) * 76800000 : hz; u32 pcvHz = useGm20b ? ((hz + 76800000 - 1) / 76800000) * 76800000 : hz;

View File

@@ -39,6 +39,7 @@
namespace board { namespace board {
void SetHz(HocClkModule module, u32 hz); void SetHz(HocClkModule module, u32 hz);
void SetMarikoGm20bCutoff(u32 hz);
u32 GetHz(HocClkModule module); u32 GetHz(HocClkModule module);
u32 GetRealHz(HocClkModule module); u32 GetRealHz(HocClkModule module);

View File

@@ -182,52 +182,57 @@ namespace clockManager {
std::uint32_t *hz = &gFreqTable[module].list[0]; std::uint32_t *hz = &gFreqTable[module].list[0];
gFreqTable[module].count = 0; gFreqTable[module].count = 0;
if (module == HocClkModule_GPU && board::GetSocType() == HocClkSocType_Mariko && config::GetConfigValue(HocClkConfigValue_MarikoMiddleFreqs)) { if (module == HocClkModule_GPU && board::GetSocType() == HocClkSocType_Mariko) {
constexpr u32 kStep = 38400000; constexpr u32 kStep = 38400000;
constexpr u32 kPcvStep = 76800000; constexpr u32 kPcvStep = 76800000;
bool middleFreqs = config::GetConfigValue(HocClkConfigValue_MarikoMiddleFreqs) != 0;
u32 kMax = 0; u32 kMax = ~0;
for (u32 i = 0; i < count; i++) { for (u32 i = 0; i < count; i++) {
for (u32 j = 0; j < count; j++) { for (u32 j = 0; j < count; j++) {
if (freqs[j] == freqs[i] + kStep) { if (freqs[j] + kStep == freqs[i]) {
kMax = freqs[j]; if (freqs[j] < kMax) kMax = freqs[j];
break; break;
} }
} }
} }
if (kMax == 0) { if (kMax == (u32)~0) {
kMax = 0;
for (u32 i = 0; i < count; i++) { for (u32 i = 0; i < count; i++) {
if (freqs[i] > kMax) if (freqs[i] > kMax) kMax = freqs[i];
kMax = freqs[i];
} }
} }
for (u32 f = kPcvStep; f <= kMax && gFreqTable[module].count < HOCCLK_FREQ_LIST_MAX; f += kStep) { board::SetMarikoGm20bCutoff(middleFreqs ? kMax : 0);
if (f % kPcvStep != 0) {
*hz = f; if (middleFreqs) {
gFreqTable[module].count++; for (u32 f = kPcvStep; f <= kMax && gFreqTable[module].count < HOCCLK_FREQ_LIST_MAX; f += kStep) {
hz++; if (f % kPcvStep != 0) {
} else { *hz = f;
for (u32 i = 0; i < count; i++) { gFreqTable[module].count++;
if (freqs[i] == f) { hz++;
*hz = f; } else {
gFreqTable[module].count++; for (u32 i = 0; i < count; i++) {
hz++; if (freqs[i] == f) {
break; *hz = f;
gFreqTable[module].count++;
hz++;
break;
}
} }
} }
} }
}
for (u32 i = 0; i < count && gFreqTable[module].count < HOCCLK_FREQ_LIST_MAX; i++) { for (u32 i = 0; i < count && gFreqTable[module].count < HOCCLK_FREQ_LIST_MAX; i++) {
if (freqs[i] > kMax && IsAssignableHz(module, freqs[i])) { if (freqs[i] > kMax && IsAssignableHz(module, freqs[i])) {
*hz = freqs[i]; *hz = freqs[i];
gFreqTable[module].count++; gFreqTable[module].count++;
hz++; hz++;
}
} }
return;
} }
return;
} }
for (std::uint32_t i = 0; i < count; i++) { for (std::uint32_t i = 0; i < count; i++) {