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 "../file/config.hpp"
namespace board {
#define MIDDLE_FREQ_TABLE_START_POINT 1228800000
static u32 currentInjectedHz = 0;
static u32 gMarikoGm20bCutoff = 1228800000;
void SetMarikoGm20bCutoff(u32 hz) {
gMarikoGm20bCutoff = hz;
}
PcvModule GetPcvModule(HocClkModule hocclkModule) {
switch (hocclkModule) {
case HocClkModule_CPU:
@@ -97,7 +101,7 @@ namespace board {
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;

View File

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

View File

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