12 Commits

Author SHA1 Message Date
souldbminersmwc
f90ba2ca59 2.3.0 2026-05-11 19:07:44 -04:00
Lightos1
f97fdc9528 conversion script: fix 3200mhz 2026-05-11 21:34:01 +02:00
Lightos1
ed63a95488 conversion script: fix 3200mhz 2026-05-11 21:33:44 +02:00
Lightos1
e24512c9d6 raise vddq min validator to 400 2026-05-11 21:26:31 +02:00
Lightos1
1efd91d535 reaise vddq validator 2026-05-11 21:22:05 +02:00
Lightos1
3337738dcc conversion script: fix silly bugs 2026-05-11 19:58:08 +02:00
Lightos1
7f1f504c36 Merge branch 'main' of https://github.com/horizon-OC/Horizon-OC 2026-05-11 19:36:10 +02:00
Lightos1
2f21f23266 experimental: add improved dvb table (+ conversion script) 2026-05-11 19:35:48 +02:00
Lightos1
3c99ad0186 Update README.md 2026-05-11 17:22:54 +02:00
Lightos1
e4dd690ac9 Update README.md 2026-05-11 17:19:36 +02:00
Lightos1
9122768953 delete ams_patch.bat from the right branch 2026-05-10 22:44:32 +02:00
Lightos1
3539916cfd fix compilation errors 2026-05-10 22:36:29 +02:00
20 changed files with 256 additions and 47 deletions

View File

@@ -211,4 +211,5 @@ Refer to COMPILATION.md
* **Samybigio2011, Miki** - Italian translations
* **angelblaster** - Korean translations
* **q1332348216-glitch** - Chinese translations
* **th3-ne0undr5c0r** - French translations
* **Nvidia** - [Tegra X1 Technical Reference Manual](https://developer.nvidia.com/embedded/dlc/tegra-x1-technical-reference-manual), soctherm driver, L4T

View File

@@ -20,8 +20,8 @@
#pragma once
#define CUST_REV 2
#define KIP_VERSION 220
#define CUST_REV 3
#define KIP_VERSION 230
#include "oc_common.hpp"
#include "pcv/pcv_common.hpp"
@@ -92,7 +92,7 @@ struct CustomizeTable {
StepMode stepMode;
u32 marikoEmcMaxClock;
u32 marikoEmcVddqVolt;
u32 emcDvbShift;
s32 emcDvbShift;
u32 marikoSocVmax;
// advanced config
u32 t1_tRCD;

View File

@@ -153,7 +153,7 @@ namespace ams::ldr::hoc::pcv {
{ C.commonEmcMemVolt, 912'500, 1350'000, false, panic::Emc }, // Official burst vmax for the RAMs is 1500mV
{ GET_MAX_OF_ARR(erista::maxEmcClocks), 1600'000, 2600'000, false, panic::Emc },
{ C.marikoEmcMaxClock, 1600'000, 3500'000, false, panic::Emc },
{ C.marikoEmcVddqVolt, 250'000, 700'000, false, panic::Emc },
{ C.marikoEmcVddqVolt, 400'000, 750'000, false, panic::Emc },
{ C.marikoSocVmax, 1000, 1200, false, panic::Emc },
{ eristaGpuDvfsMaxFreq, 768'000, 1152'000, false, panic::Gpu },
{ marikoGpuDvfsMaxFreq, 768'000, 1536'000, false, panic::Gpu },

View File

@@ -357,7 +357,7 @@ namespace ams::ldr::hoc::pcv::erista {
table->dram_timings.t_rp = tRFCpb;
table->dram_timings.t_rfc = tRFCab;
table->emc_cfg_2 = 0x11083D;
table->min_volt = std::min(static_cast<u32>(1050), 900 + C.emcDvbShift * 25);
table->min_volt = (u32)std::min(static_cast<s32>(1050), 900 + C.emcDvbShift * 25);
}
/* Probably more intuitive to point to 40800 rather than 1600000, but oh well. */

View File

@@ -809,9 +809,9 @@ namespace ams::ldr::hoc::pcv::mariko {
auto DvbVolt = [&](u32 zero, u32 one, u32 two) {
return std::array<u32, 3>{
std::min(zero + voltAdd, max0),
std::min(one + voltAdd, max1),
std::min(two + voltAdd, max2)
std::min((u32)((s32)zero + voltAdd), max0),
std::min((u32)((s32)one + voltAdd), max1),
std::min((u32)((s32)two + voltAdd), max2)
};
};
@@ -820,16 +820,16 @@ namespace ams::ldr::hoc::pcv::mariko {
static_cast<u32>((v)[1]), \
static_cast<u32>((v)[2])
DvbEntry emcDvbTableNew[] = {
{ 204000, { 637, 637, 637, } },
{ 1331200, { 650, 637, 637, } },
{ 1600000, { 675, 650, 637, } },
{ 1866000, { DVB(DvbVolt(700, 675, 650)) } },
{ 2133000, { DVB(DvbVolt(725, 700, 675)) } },
{ 2400000, { DVB(DvbVolt(750, 725, 700)) } },
{ 2666000, { DVB(DvbVolt(775, 750, 725)) } },
{ 2933000, { DVB(DvbVolt(800, 775, 750)) } },
{ 3200000, { DVB(DvbVolt(800, 800, 775)) } },
{ 0xFFFFFFFF, { } },
{ 204000, { 637, 637, 637, }, },
{ 1331200, { 650, 637, 637, }, },
{ 1600000, { 675, 650, 637, }, },
{ 1866000, { DVB(DvbVolt( 700, 675, 650)) }, },
{ 2133000, { DVB(DvbVolt( 725, 700, 675)) }, },
{ 2400000, { DVB(DvbVolt( 750, 725, 700)) }, },
{ 2666000, { DVB(DvbVolt( 850, 825, 800)) }, },
{ 2933000, { DVB(DvbVolt( 950, 925, 900)) }, },
{ 3200000, { DVB(DvbVolt(1050, 1025, 1000)) }, },
{ 0xFFFFFFFF, { }, },
};
#undef DVB

View File

@@ -35,7 +35,6 @@ echo
echo "*** Copying assets ***"
mkdir -p "$DIST_DIR/config/horizon-oc"
cp -vf "$ROOT_DIR/config.ini.template" "$DIST_DIR/config/horizon-oc/config.ini.template"
cp -vf "$ROOT_DIR/../../README.md" "$DIST_DIR/README.md"
mkdir -p "$DIST_DIR/config/ultrahand/assets/notifications"
cp -vf "$ROOT_DIR/assets/hoc.rgba" "$DIST_DIR/config/ultrahand/assets/notifications/hoc.rgba"

View File

@@ -39,7 +39,7 @@ include ${TOPDIR}/lib/libultrahand/ultrahand.mk
# version control constants
#---------------------------------------------------------------------------------
#TARGET_VERSION := $(shell git describe --dirty --always --tags)
APP_VERSION := 2.2.0 # ensure to set KIP_VERSION and CUST_REV in sysmodule Makefile when updating this
APP_VERSION := 2.3.0 # ensure to set KIP_VERSION and CUST_REV in sysmodule Makefile when updating this
TARGET_VERSION := $(APP_VERSION)
#---------------------------------------------------------------------------------

View File

@@ -933,7 +933,10 @@ protected:
this->listElement->addItem(new tsl::elm::CategoryHeader("RAM Settings"));
addConfigTrackbar(KipConfigValue_emcDvbShift, "SoC DVB Shift", ValueRange(0, 16, 1)); // yes, DVB 16 is nessesary
addMappedConfigTrackbar(KipConfigValue_emcDvbShift, "DVB Shift",
{0xFFFFFFFCu, 0xFFFFFFFDu, 0xFFFFFFFEu, 0xFFFFFFFFu, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u},
{"-4", "-3", "-2", "-1", " 0", "1", "2", "3", "4", "5", "6", "7", "8"});
if(IsMariko()) {
u32 socSpeedo = this->context->speedos[HocClkSpeedo_SOC];
std::string autoText = "1000 mV";

View File

@@ -28,9 +28,9 @@ INCLUDES := ../common/include src/hos src/soc src/i2c src/util src/pwr src/ipc
EXEFS_SRC := exefs_src
LIBNAMES := minIni
# major minor patch
TARGET_VERSION := 2.2.0
KIP_VERSION := 220
CUST_REV := 2
TARGET_VERSION := 2.3.0
KIP_VERSION := 230
CUST_REV := 3
#---------------------------------------------------------------------------------
# options for code generation

View File

@@ -3,7 +3,7 @@
"title_id": "0x00FF0000636C6BFF",
"title_id_range_min": "0x00FF0000636C6BFF",
"title_id_range_max": "0x00FF0000636C6BFF",
"main_thread_stack_size": "0x0000B000",
"main_thread_stack_size": "0x0000C000",
"main_thread_priority": 16,
"default_cpu_id": 3,
"process_category": 1,

View File

@@ -54,7 +54,7 @@ namespace kip {
}
u32 custRev = cust_get_cust_rev(&table);
u32 kipVersion = cust_get_kip_version(&table)
u32 kipVersion = cust_get_kip_version(&table);
if (custRev < CUST_REV || kipVersion < KIP_VERSION) {
notification::writeNotification("Horizon OC\nOutdated kip detected!\nPlease update Horizon OC");
fileUtils::LogLine("Cust revision: %u", custRev);
@@ -76,7 +76,7 @@ namespace kip {
CUST_WRITE_FIELD_BATCH(&table, eristaEmcMaxClock2, config::GetConfigValue(KipConfigValue_eristaEmcMaxClock2));
CUST_WRITE_FIELD_BATCH(&table, marikoEmcMaxClock, config::GetConfigValue(KipConfigValue_marikoEmcMaxClock));
CUST_WRITE_FIELD_BATCH(&table, marikoEmcVddqVolt, config::GetConfigValue(KipConfigValue_marikoEmcVddqVolt));
CUST_WRITE_FIELD_BATCH(&table, emcDvbShift, config::GetConfigValue(KipConfigValue_emcDvbShift));
CUST_WRITE_FIELD_BATCH(&table, emcDvbShift, config::GetConfigValue(KipConfigValue_emcDvbShift) > 8 && config::GetConfigValue(KipConfigValue_emcDvbShift) <= 16 ? 8 : config::GetConfigValue(KipConfigValue_emcDvbShift)); // 2.2.0 -> 2.3.0 compat
CUST_WRITE_FIELD_BATCH(&table, marikoSocVmax, config::GetConfigValue(KipConfigValue_marikoSocVmax));
CUST_WRITE_FIELD_BATCH(&table, t1_tRCD, config::GetConfigValue(KipConfigValue_t1_tRCD));
@@ -210,7 +210,7 @@ namespace kip {
clockManager::gContext.custRev = cust_get_cust_rev(&table);
u32 custRev = cust_get_cust_rev(&table);
u32 kipVersion = cust_get_kip_version(&table)
u32 kipVersion = cust_get_kip_version(&table);
if (custRev < CUST_REV || kipVersion < KIP_VERSION) {
notification::writeNotification("Horizon OC\nOutdated kip detected!\nPlease update Horizon OC");
fileUtils::LogLine("Cust revision: %u", custRev);
@@ -233,7 +233,7 @@ namespace kip {
configValues.values[KipConfigValue_eristaEmcMaxClock2] = cust_get_erista_emc_max2(&table);
configValues.values[KipConfigValue_marikoEmcMaxClock] = cust_get_mariko_emc_max(&table);
configValues.values[KipConfigValue_marikoEmcVddqVolt] = cust_get_mariko_emc_vddq(&table);
configValues.values[KipConfigValue_emcDvbShift] = cust_get_emc_dvb_shift(&table);
configValues.values[KipConfigValue_emcDvbShift] = cust_get_emc_dvb_shift(&table) > 8 && cust_get_emc_dvb_shift(&table) <= 16 ? 8 : cust_get_emc_dvb_shift(&table); // 2.2.0 -> 2.3.0 compat
configValues.values[KipConfigValue_marikoSocVmax] = cust_get_marikoSocVmax(&table);
configValues.values[KipConfigValue_t1_tRCD] = cust_get_tRCD(&table);
@@ -313,4 +313,5 @@ namespace kip {
notification::writeNotification("Horizon OC\nConfig Buffer Mismatch");
}
}
}
}

View File

@@ -38,7 +38,7 @@
#include "ipc/ipc_service.hpp"
#include "file/config.hpp"
#define INNER_HEAP_SIZE 0x3A000
#define INNER_HEAP_SIZE 0x40000
extern "C"
{

View File

@@ -252,7 +252,6 @@ namespace clockManager {
return;
}
}
void HandleMiscFeatures()
{
// these dont need to run that often, so dont bother
@@ -381,7 +380,6 @@ namespace clockManager {
board::SetHz(HocClkModule_CPU, board::GetHz(HocClkModule_CPU));
prepareBoostExit = false;
}
bool returnRaw = false; // Return a value scaled to MHz instead of raw value
for (unsigned int module = 0; module < HocClkModule_EnumMax; module++) {
u32 oldHz = board::GetHz((HocClkModule)module); // Get Old hz (used primarily for DVFS Logic)
@@ -715,8 +713,9 @@ namespace clockManager {
HandleSafetyFeatures();
HandleMiscFeatures();
if (RefreshContext() || config::Refresh()) {
// GPU clock should always be the same unless PCV has overwriten our change, so reset it
if (RefreshContext() || config::Refresh() || board::GetRealHz(HocClkModule_GPU) != gContext.freqs[HocClkModule_GPU]) {
SetClocks(isBoost);
}
}

View File

@@ -0,0 +1,98 @@
#include <cstdio>
#include <cstdint>
#include <iterator>
typedef uint32_t u32;
typedef int32_t s32;
struct DvbEntry {
u32 freq;
u32 volts[3];
};
DvbEntry oldDvbTable[] = {
{ 204000, { 637, 637, 637, }, },
{ 1331200, { 650, 637, 637, }, },
{ 1600000, { 675, 650, 637, }, },
{ 1866000, { 700, 675, 650, }, },
{ 2133000, { 725, 700, 675, }, },
{ 2400000, { 750, 725, 700, }, },
{ 2666000, { 775, 750, 725, }, },
{ 2933000, { 800, 775, 750, }, },
{ 3200000, { 800, 800, 775, }, },
{ ~0u, { }, },
};
DvbEntry newDvbTable[] = {
{ 204000, { 637, 637, 637, }, },
{ 1331200, { 650, 637, 637, }, },
{ 1600000, { 675, 650, 637, }, },
{ 1866000, { 700, 675, 650, }, },
{ 2133000, { 725, 700, 675, }, },
{ 2400000, { 750, 725, 700, }, },
{ 2666000, { 850, 825, 800, }, },
{ 2933000, { 950, 925, 900, }, },
{ 3200000, { 1050, 1025, 1000, }, },
{ ~0u, { }, },
};
constexpr u32 DvbTableSize = std::size(oldDvbTable);
u32 PrintAndScan(const char *message) {
u32 scanV;
printf("%s: ", message);
scanf("%i", &scanV);
return scanV;
}
u32 GetProcessId(u32 speedo) {
if (speedo <= 1597) {
return 0;
}
if (speedo <= 1708) {
return 1;
}
/* >= 1709. */
return 2;
}
u32 GetVoltageAndIndex(u32 dvbShift, u32 emc, u32 processId, DvbEntry *dvbTable, u32 &index) {
for (u32 i = 0; i < DvbTableSize - 1; ++i) {
if (emc < dvbTable[i].freq || emc >= dvbTable[i + 1].freq) {
continue;
}
index = i;
return dvbTable[i].volts[processId] + (25 * dvbShift);
}
return 0;
}
s32 GetShift(u32 oldVoltage, u32 processId, DvbEntry *dvbTable, u32 index) {
return (static_cast<s32>(oldVoltage) - static_cast<s32>(dvbTable[index].volts[processId])) / 25;
}
int main() {
u32 oldDvb = PrintAndScan("Enter old dvb shift");
u32 emcMaxMhz = PrintAndScan("Enter max ram freq (MHz)");
u32 speedo = PrintAndScan("Enter soc speedo");
u32 emcMaxKhz = emcMaxMhz * 1000;
u32 processId = GetProcessId(speedo);
#define INVALID_TABLE_INDEX 32
u32 tableIndex = INVALID_TABLE_INDEX;
u32 oldVoltage = GetVoltageAndIndex(oldDvb, emcMaxKhz, processId, oldDvbTable, tableIndex);
if (oldVoltage == 0 || tableIndex == INVALID_TABLE_INDEX) {
printf("Invalid values!\n");
return -1;
}
s32 newShift = GetShift(oldVoltage, processId, newDvbTable, tableIndex);
printf("New dvb table shift: %d", newShift);
}

View File

@@ -0,0 +1,120 @@
from dataclasses import dataclass
from typing import List
u32 = int
s32 = int
@dataclass
class DvbEntry:
freq: u32
volts: List[u32]
oldDvbTable = [
DvbEntry(204000, [637, 637, 637]),
DvbEntry(1331200, [650, 637, 637]),
DvbEntry(1600000, [675, 650, 637]),
DvbEntry(1866000, [700, 675, 650]),
DvbEntry(2133000, [725, 700, 675]),
DvbEntry(2400000, [750, 725, 700]),
DvbEntry(2666000, [775, 750, 725]),
DvbEntry(2933000, [800, 775, 750]),
DvbEntry(3200000, [800, 800, 775]),
DvbEntry(0xFFFFFFFF, []),
]
newDvbTable = [
DvbEntry(204000, [637, 637, 637]),
DvbEntry(1331200, [650, 637, 637]),
DvbEntry(1600000, [675, 650, 637]),
DvbEntry(1866000, [700, 675, 650]),
DvbEntry(2133000, [725, 700, 675]),
DvbEntry(2400000, [750, 725, 700]),
DvbEntry(2666000, [850, 825, 800]),
DvbEntry(2933000, [950, 925, 900]),
DvbEntry(3200000, [1050, 1025, 1000]),
DvbEntry(0xFFFFFFFF, []),
]
DVB_TABLE_SIZE = len(oldDvbTable)
INVALID_TABLE_INDEX = 32
def print_and_scan(message: str) -> u32:
return int(input(f"{message}: "))
def get_process_id(speedo: u32) -> u32:
if speedo <= 1597:
return 0
if speedo <= 1708:
return 1
# >= 1709
return 2
def get_voltage_and_index(
dvb_shift: u32,
emc: u32,
process_id: u32,
dvb_table: List[DvbEntry],
):
for i in range(DVB_TABLE_SIZE - 1):
if emc < dvb_table[i].freq or emc >= dvb_table[i + 1].freq:
continue
voltage = dvb_table[i].volts[process_id] + (25 * dvb_shift)
return voltage, i
return 0, INVALID_TABLE_INDEX
def get_shift(
old_voltage: u32,
process_id: u32,
dvb_table: List[DvbEntry],
index: u32,
) -> s32:
return (
int(old_voltage)
- int(dvb_table[index].volts[process_id])
) // 25
def main():
old_dvb = print_and_scan("Enter old dvb shift")
emc_max_mhz = print_and_scan("Enter max ram freq (MHz)")
speedo = print_and_scan("Enter soc speedo")
emc_max_khz = emc_max_mhz * 1000
process_id = get_process_id(speedo)
table_index = INVALID_TABLE_INDEX
old_voltage, table_index = get_voltage_and_index(
old_dvb,
emc_max_khz,
process_id,
oldDvbTable,
)
if old_voltage == 0 or table_index == INVALID_TABLE_INDEX:
print("Invalid values!")
return -1
new_shift = get_shift(
old_voltage,
process_id,
newDvbTable,
table_index,
)
print(f"New dvb table shift: {new_shift}")
if __name__ == "__main__":
main()

View File

@@ -1,12 +0,0 @@
@echo off
set ROOT=build
set PATCHES=Source/Atmosphere-Patches
copy "%PATCHES%\secmon_memory_layout.hpp" "%ROOT%\libraries\libexosphere/include/exosphere/secmon/" /Y
copy "%PATCHES%\secmon_emc_access_table_data.inc" "%ROOT%\exosphere/program/source/smc/" /Y
copy "%PATCHES%\secmon_soctherm_access_table_data.inc" "%ROOT%\exosphere/program/source/smc/" /Y
copy "%PATCHES%\secmon_define_emc_access_table.inc" "%ROOT%\exosphere/program/source/smc/" /Y
copy "%PATCHES%\secmon_define_soctherm_access_table.inc" "%ROOT%\exosphere/program/source/smc/" /Y
copy "%PATCHES%\secmon_smc_register_access.cpp" "%ROOT%\exosphere/program/source/smc/" /Y
echo Patched!
pause

Binary file not shown.

Binary file not shown.

Binary file not shown.