diff --git a/makefile b/makefile index 9a5e2d4..967e914 100644 --- a/makefile +++ b/makefile @@ -32,6 +32,7 @@ sys: cd ./src/keymon && make cd ./src/minarch && make cd ./src/minui && make + cd ./src/overclock && make cd ./src/boot && ./build.sh all-cores: @@ -63,6 +64,7 @@ bundle: cp ./src/libmsettings/libmsettings.so ./build/SYSTEM/rg35xx/lib cp ./src/keymon/keymon.elf ./build/SYSTEM/rg35xx/bin cp ./src/minarch/minarch.elf ./build/SYSTEM/rg35xx/bin + cp ./src/overclock/overclock.elf ./build/SYSTEM/rg35xx/bin cp ./src/minui/minui.elf ./build/SYSTEM/rg35xx/paks/MinUI.pak cp ./src/clock/clock.elf ./build/EXTRAS/Tools/rg35xx/Clock.pak diff --git a/src/overclock/credits.txt b/src/overclock/credits.txt new file mode 100644 index 0000000..a428c91 --- /dev/null +++ b/src/overclock/credits.txt @@ -0,0 +1,2 @@ +based on eggs example code: + https://discord.com/channels/529983248114122762/1009790045303087125/1085260407788290168 \ No newline at end of file diff --git a/src/overclock/makefile b/src/overclock/makefile new file mode 100755 index 0000000..bb1a806 --- /dev/null +++ b/src/overclock/makefile @@ -0,0 +1,14 @@ +ifeq (,$(CROSS_COMPILE)) +$(error missing CROSS_COMPILE for this toolchain) +endif + +TARGET = overclock + +CC = $(CROSS_COMPILE)gcc +CFLAGS = -Os -lrt -ldl -Wl,--gc-sections -s +CFLAGS += -I. -DPLATFORM=\"$(UNION_PLATFORM)\" + +all: + $(CC) $(TARGET).c -o $(TARGET).elf $(CFLAGS) +clean: + rm -rf $(TARGET).elf \ No newline at end of file diff --git a/src/overclock/overclock.c b/src/overclock/overclock.c new file mode 100644 index 0000000..e270ccc --- /dev/null +++ b/src/overclock/overclock.c @@ -0,0 +1,112 @@ +// +// cpu over/underclock (based on code from eggs) +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// -- 0xe64e v 1000000 : 700000 + (25000x12) / 0x0c 01100 1110[01100]1001110 +// - 0xe6ce v 1025000 : 700000 + (25000x13) / 0x0d 01101 1110[01101]1001110 +// 0xe84e v 1100000 : 700000 + (25000x16) / 0x10 10000 1110[10000]1001110 +// + 0xebce v 1275000 : 700000 + (25000x23) / 0x17 10111 1110[10111]1001110 +// ++ 0xedce v 1375000 : 700000 + (25000x27) / 0x1b 11011 1110[11011]1001110 +#define VOLTMIN (700000) +#define VOLTMAX (1400000) +#define VOLTMUL (25000) +void setcpuvolt(int volt) { + if (volt < VOLTMIN) volt = VOLTMIN; + else if (volt > VOLTMAX) volt = VOLTMAX; + volt = ((volt-VOLTMIN) / VOLTMUL)<<7; + + char str[16]; + sprintf(str, "11=%04x", 0xe04e | volt); + int fd_reg = open("/sys/class/i2c-adapter/i2c-1/1-0065/reg_dbg", O_WRONLY); + write(fd_reg, str, strlen(str)); + close(fd_reg); +} + +#define CMU_BASE (0xB0160000) +#define CLKMIN (192000) +#define CLKMAX (1524000) +#define CLKMUL (12000) +void setcpuclock(int clock) { + if (clock < CLKMIN) clock = CLKMIN; + else if (clock > CLKMAX) clock = CLKMAX; + clock = clock / CLKMUL; + + int fd_mem = open("/dev/mem", O_RDWR); + uint32_t* cmu_mem = mmap(0, 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd_mem, CMU_BASE); + cmu_mem[0] = (cmu_mem[0] & 0xFFFFFF80) | clock; + munmap(cmu_mem, 4); + close(fd_mem); +} + +void setcpu(int clock, int volt) { + setcpuvolt(VOLTMAX); // Temporarily maximize + setcpuclock(clock); + setcpuvolt(volt); +} + +// clk 240000 volt 975000 +// clk 504000 volt 1000000 +// clk 720000 volt 1025000 +// clk 1008000 volt 1100000 +// clk 1296000 volt 1275000 +// clk 1488000 volt 1375000 + +static struct cpu_opp { + int clk; + int volt; + char* desc; +} cpu_opps[] = { + { CLKMAX, VOLTMAX}, // just a smidge above 1.5GHz + {1488000, 1375000}, // 1.5GHz, MinUI Performance + launch + {1392000, 1325000}, // 1.4GHz + {1296000, 1275000}, // 1.3GHz, MinUI Normal + {1200000, 1200000}, // 1.2GHz + {1104000, 1175000}, // 1.1GHz, MinUI Powersave + {1008000, 1100000}, // 1.0GHz, Anbernic default max, overvolted to stabilize + { 840000, 1075000}, // 840MHz, overvolted to stabilize + { 720000, 1025000}, // 720MHz, overvolted to stabilize + { 504000, 1000000}, // 500MHz, overvolted to stabilize, MinUI Menus + { 240000, 975000}, // 240MHz, overvolted to stabilize + { 0, 0}, +}; + +int main(int argc, char* argv[]) { + if (argc<2) { + printf("Usage: %s \n", argv[0]); + for (int i=0; cpu_opps[i].clk; i++) { + printf(" %8i\n", cpu_opps[i].clk); + } + return 0; + } + + int clk = 1008000; // default + char *p; + errno = 0; + long arg = strtol(argv[1], &p, 10); + + if (errno != 0 || *p != '\0' || arg > INT_MAX || arg < INT_MIN); // buh + else clk = arg; + + for (int i=0; cpu_opps[i].clk; i++) { + struct cpu_opp* cpu = &cpu_opps[i]; + if (clk>=cpu->clk) { + setcpu( cpu->clk, cpu->volt ); + // TODO: this doesn't work... + // char cmd[128]; + // sprintf(cmd, "echo %i > /tmp/cpu_freq", cpu->clk); + // puts(cmd); + // system(cmd); + break; + } + } + return 0; +}