added CPU speed api and minarch frontend option
This commit is contained in:
parent
d9af2b88d0
commit
a6847e7ab4
6 changed files with 90 additions and 26 deletions
|
|
@ -1,5 +1,9 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
# disable MicroSD card powersaving (should help reduce load stutter, test)
|
||||||
|
echo on > /sys/devices/b0238000.mmc/mmc_host/mmc0/power/control
|
||||||
|
echo on > /sys/devices/b0230000.mmc/mmc_host/mmc1/power/control
|
||||||
|
|
||||||
export SDCARD_PATH="/mnt/sdcard"
|
export SDCARD_PATH="/mnt/sdcard"
|
||||||
export BIOS_PATH="$SDCARD_PATH/Bios"
|
export BIOS_PATH="$SDCARD_PATH/Bios"
|
||||||
export SAVES_PATH="$SDCARD_PATH/Saves"
|
export SAVES_PATH="$SDCARD_PATH/Saves"
|
||||||
|
|
@ -14,7 +18,11 @@ export LD_LIBRARY_PATH=$SYSTEM_PATH/lib:$LD_LIBRARY_PATH
|
||||||
mkdir -p "$LOGS_PATH"
|
mkdir -p "$LOGS_PATH"
|
||||||
mkdir -p "$USERDATA_PATH/.minui"
|
mkdir -p "$USERDATA_PATH/.minui"
|
||||||
|
|
||||||
CPU_PATH="/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
|
echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
|
||||||
|
export CPU_SPEED_MENU=504000
|
||||||
|
export CPU_SPEED_GAME=1296000
|
||||||
|
export CPU_SPEED_PERF=1488000 # improves binary launch times
|
||||||
|
export CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
|
||||||
|
|
||||||
cd $(dirname "$0")
|
cd $(dirname "$0")
|
||||||
|
|
||||||
|
|
@ -25,11 +33,10 @@ export EXEC_PATH=/tmp/minui_exec
|
||||||
touch "$EXEC_PATH" && sync
|
touch "$EXEC_PATH" && sync
|
||||||
|
|
||||||
while [ -f "$EXEC_PATH" ]; do
|
while [ -f "$EXEC_PATH" ]; do
|
||||||
echo ondemand > "$CPU_PATH"
|
|
||||||
|
|
||||||
./minui.elf &> $LOGS_PATH/minui.txt
|
./minui.elf &> $LOGS_PATH/minui.txt
|
||||||
|
|
||||||
echo performance > "$CPU_PATH"
|
# overclock to speedup binary launch time
|
||||||
|
echo $CPU_SPEED_PERF > "$CPU_PATH"
|
||||||
sync
|
sync
|
||||||
|
|
||||||
NEXT="/tmp/next"
|
NEXT="/tmp/next"
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc , char* argv[]) {
|
int main(int argc , char* argv[]) {
|
||||||
|
POW_setCPUSpeed(CPU_SPEED_MENU);
|
||||||
|
|
||||||
SDL_Surface* screen = GFX_init(MODE_MAIN);
|
SDL_Surface* screen = GFX_init(MODE_MAIN);
|
||||||
InitSettings();
|
InitSettings();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1099,26 +1099,33 @@ void POW_powerOff(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BACKLIGHT_PATH "/sys/class/backlight/backlight.2/bl_power"
|
#define BACKLIGHT_PATH "/sys/class/backlight/backlight.2/bl_power"
|
||||||
#define GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
|
|
||||||
static char governor[128];
|
#define CPU_SPEED_SET_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"
|
||||||
|
#define CPU_SPEED_GET_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"
|
||||||
|
static int previous_speed = CPU_SPEED_NORMAL;
|
||||||
|
|
||||||
|
void POW_setCPUSpeed(int speed) {
|
||||||
|
putInt(CPU_SPEED_SET_PATH, speed);
|
||||||
|
sync();
|
||||||
|
}
|
||||||
|
|
||||||
static void POW_enterSleep(void) {
|
static void POW_enterSleep(void) {
|
||||||
SetRawVolume(0);
|
SetRawVolume(0);
|
||||||
putInt(BACKLIGHT_PATH, FB_BLANK_POWERDOWN);
|
putInt(BACKLIGHT_PATH, FB_BLANK_POWERDOWN);
|
||||||
|
|
||||||
// save current governor (either ondemand or performance)
|
// TODO: not sure this is necessary
|
||||||
getFile(GOVERNOR_PATH, governor, 128);
|
// previous_speed = getInt(CPU_SPEED_GET_PATH);
|
||||||
trimTrailingNewlines(governor);
|
// POW_setCPUSpeed(CPU_SPEED_MENU);
|
||||||
|
|
||||||
putFile(GOVERNOR_PATH, "powersave");
|
|
||||||
sync();
|
sync();
|
||||||
}
|
}
|
||||||
static void POW_exitSleep(void) {
|
static void POW_exitSleep(void) {
|
||||||
putInt(BACKLIGHT_PATH, FB_BLANK_UNBLANK);
|
putInt(BACKLIGHT_PATH, FB_BLANK_UNBLANK);
|
||||||
SetVolume(GetVolume());
|
SetVolume(GetVolume());
|
||||||
|
|
||||||
// restore previous governor
|
// TODO: not sure this is necessary
|
||||||
putFile(GOVERNOR_PATH, governor);
|
// POW_setCPUSpeed(previous_speed);
|
||||||
|
|
||||||
sync();
|
sync();
|
||||||
}
|
}
|
||||||
static void POW_waitForWake(void) {
|
static void POW_waitForWake(void) {
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,12 @@ int POW_isCharging(void);
|
||||||
int POW_getBattery(void);
|
int POW_getBattery(void);
|
||||||
void POW_setRumble(int strength); // 0-100
|
void POW_setRumble(int strength); // 0-100
|
||||||
|
|
||||||
|
#define CPU_SPEED_MENU 504000 // 240000 was having latency issues
|
||||||
|
#define CPU_SPEED_POWERSAVE 1104000
|
||||||
|
#define CPU_SPEED_NORMAL 1296000
|
||||||
|
#define CPU_SPEED_PERFORMANCE 1488000
|
||||||
|
void POW_setCPUSpeed(int speed);
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ static int optimize_text = 1;
|
||||||
static int show_debug = 0;
|
static int show_debug = 0;
|
||||||
static int max_ff_speed = 3; // 4x
|
static int max_ff_speed = 3; // 4x
|
||||||
static int fast_forward = 0;
|
static int fast_forward = 0;
|
||||||
|
static int overclock = 1; // normal
|
||||||
|
|
||||||
static struct Renderer {
|
static struct Renderer {
|
||||||
int src_w;
|
int src_w;
|
||||||
|
|
@ -384,6 +385,7 @@ enum {
|
||||||
FE_OPT_SCANLINES,
|
FE_OPT_SCANLINES,
|
||||||
FE_OPT_TEXT,
|
FE_OPT_TEXT,
|
||||||
FE_OPT_TEARING,
|
FE_OPT_TEARING,
|
||||||
|
FE_OPT_OVERCLOCK,
|
||||||
FE_OPT_DEBUG,
|
FE_OPT_DEBUG,
|
||||||
FE_OPT_MAXFF,
|
FE_OPT_MAXFF,
|
||||||
FE_OPT_COUNT,
|
FE_OPT_COUNT,
|
||||||
|
|
@ -485,10 +487,16 @@ static char* shortcut_labels[] = {
|
||||||
"MENU+R2",
|
"MENU+R2",
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
static char* overclock_labels[] = {
|
||||||
|
"Powersave",
|
||||||
|
"Normal",
|
||||||
|
"Performance",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CONFIG_NONE,
|
CONFIG_NONE,
|
||||||
CONFIG_GLOBAL,
|
CONFIG_CONSOLE,
|
||||||
CONFIG_GAME,
|
CONFIG_GAME,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -532,6 +540,16 @@ static struct Config {
|
||||||
.values = tearing_labels,
|
.values = tearing_labels,
|
||||||
.labels = tearing_labels,
|
.labels = tearing_labels,
|
||||||
},
|
},
|
||||||
|
[FE_OPT_OVERCLOCK] = {
|
||||||
|
.key = "minarch_cpu_speed",
|
||||||
|
.name = "CPU Speed",
|
||||||
|
.desc = "Over- or underclock the CPU to prioritize\npure performance or power savings.",
|
||||||
|
.default_value = 1,
|
||||||
|
.value = 1,
|
||||||
|
.count = 3,
|
||||||
|
.values = overclock_labels,
|
||||||
|
.labels = overclock_labels,
|
||||||
|
},
|
||||||
[FE_OPT_DEBUG] = {
|
[FE_OPT_DEBUG] = {
|
||||||
.key = "minarch_debug_hud",
|
.key = "minarch_debug_hud",
|
||||||
.name = "Debug HUD",
|
.name = "Debug HUD",
|
||||||
|
|
@ -579,11 +597,21 @@ static void Config_getValue(char* cfg, const char* key, char* out_value) {
|
||||||
if (!tmp) tmp = strchr(out_value, '\r');
|
if (!tmp) tmp = strchr(out_value, '\r');
|
||||||
if (tmp) *tmp = '\0';
|
if (tmp) *tmp = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setOverclock(int i) {
|
||||||
|
overclock = i;
|
||||||
|
switch (i) {
|
||||||
|
case 0: POW_setCPUSpeed(CPU_SPEED_POWERSAVE); break;
|
||||||
|
case 1: POW_setCPUSpeed(CPU_SPEED_NORMAL); break;
|
||||||
|
case 2: POW_setCPUSpeed(CPU_SPEED_PERFORMANCE); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
static void Config_syncFrontend(int i, int value) {
|
static void Config_syncFrontend(int i, int value) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case FE_OPT_SCANLINES: show_scanlines = value; renderer.src_w = 0; break;
|
case FE_OPT_SCANLINES: show_scanlines = value; renderer.src_w = 0; break;
|
||||||
case FE_OPT_TEXT: optimize_text = value; renderer.src_w = 0; break;
|
case FE_OPT_TEXT: optimize_text = value; renderer.src_w = 0; break;
|
||||||
case FE_OPT_TEARING: GFX_setVsync(value); break;
|
case FE_OPT_TEARING: GFX_setVsync(value); break;
|
||||||
|
case FE_OPT_OVERCLOCK: setOverclock(value); break;
|
||||||
case FE_OPT_DEBUG: show_debug = value; break;
|
case FE_OPT_DEBUG: show_debug = value; break;
|
||||||
case FE_OPT_MAXFF: max_ff_speed = value; break;
|
case FE_OPT_MAXFF: max_ff_speed = value; break;
|
||||||
}
|
}
|
||||||
|
|
@ -609,7 +637,7 @@ static void Config_read(void) {
|
||||||
char* cfg = allocFile(path);
|
char* cfg = allocFile(path);
|
||||||
if (!cfg) return;
|
if (!cfg) return;
|
||||||
|
|
||||||
config.loaded = override ? CONFIG_GAME : CONFIG_GLOBAL;
|
config.loaded = override ? CONFIG_GAME : CONFIG_CONSOLE;
|
||||||
|
|
||||||
char key[256];
|
char key[256];
|
||||||
char value[256];
|
char value[256];
|
||||||
|
|
@ -676,7 +704,7 @@ static void Config_write(int override) {
|
||||||
if (config.loaded==CONFIG_GAME) unlink(path);
|
if (config.loaded==CONFIG_GAME) unlink(path);
|
||||||
Config_getPath(path, CONFIG_WRITE_ALL);
|
Config_getPath(path, CONFIG_WRITE_ALL);
|
||||||
}
|
}
|
||||||
config.loaded = override ? CONFIG_GAME : CONFIG_GLOBAL;
|
config.loaded = override ? CONFIG_GAME : CONFIG_CONSOLE;
|
||||||
|
|
||||||
FILE *file = fopen(path, "wb");
|
FILE *file = fopen(path, "wb");
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
@ -711,7 +739,7 @@ static void Config_restore(void) {
|
||||||
sprintf(path, "%s/%s.cfg", core.config_dir, game.name);
|
sprintf(path, "%s/%s.cfg", core.config_dir, game.name);
|
||||||
unlink(path);
|
unlink(path);
|
||||||
}
|
}
|
||||||
else if (config.loaded==CONFIG_GLOBAL) {
|
else if (config.loaded==CONFIG_CONSOLE) {
|
||||||
sprintf(path, "%s/minarch.cfg", core.config_dir);
|
sprintf(path, "%s/minarch.cfg", core.config_dir);
|
||||||
unlink(path);
|
unlink(path);
|
||||||
}
|
}
|
||||||
|
|
@ -2427,9 +2455,12 @@ void Menu_quit(void) {
|
||||||
void Menu_beforeSleep(void) {
|
void Menu_beforeSleep(void) {
|
||||||
State_autosave();
|
State_autosave();
|
||||||
putFile(AUTO_RESUME_PATH, game.path + strlen(SDCARD_PATH));
|
putFile(AUTO_RESUME_PATH, game.path + strlen(SDCARD_PATH));
|
||||||
|
POW_setCPUSpeed(CPU_SPEED_MENU);
|
||||||
}
|
}
|
||||||
void Menu_afterSleep(void) {
|
void Menu_afterSleep(void) {
|
||||||
unlink(AUTO_RESUME_PATH);
|
unlink(AUTO_RESUME_PATH);
|
||||||
|
setOverclock(overclock);
|
||||||
|
// POW_setCPUSpeed(CPU_SPEED_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct MenuList MenuList;
|
typedef struct MenuList MenuList;
|
||||||
|
|
@ -2658,9 +2689,9 @@ static MenuList OptionShortcuts_menu = {
|
||||||
};
|
};
|
||||||
static char* getSaveDesc(void) {
|
static char* getSaveDesc(void) {
|
||||||
switch (config.loaded) {
|
switch (config.loaded) {
|
||||||
case CONFIG_NONE: return "Using defaults."; break;
|
case CONFIG_NONE: return "Using defaults."; break;
|
||||||
case CONFIG_GLOBAL: return "Using global config."; break;
|
case CONFIG_CONSOLE: return "Using console config."; break;
|
||||||
case CONFIG_GAME: return "Using game config."; break;
|
case CONFIG_GAME: return "Using game config."; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int OptionShortcuts_openMenu(MenuList* list, int i) {
|
static int OptionShortcuts_openMenu(MenuList* list, int i) {
|
||||||
|
|
@ -2697,17 +2728,18 @@ static int OptionSaveChanges_onConfirm(MenuList* list, int i) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0: {
|
case 0: {
|
||||||
Config_write(CONFIG_WRITE_ALL);
|
Config_write(CONFIG_WRITE_ALL);
|
||||||
message = "Saved for all games.";
|
message = "Saved for console.";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
Config_write(CONFIG_WRITE_GAME);
|
Config_write(CONFIG_WRITE_GAME);
|
||||||
message = "Saved for this game.";
|
message = "Saved for game.";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
Config_restore();
|
Config_restore();
|
||||||
message = "Restored defaults.";
|
if (config.loaded) message = "Restored console defaults.";
|
||||||
|
else message = "Restored defaults.";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2739,8 +2771,8 @@ static MenuList OptionSaveChanges_menu = {
|
||||||
.type = MENU_LIST,
|
.type = MENU_LIST,
|
||||||
.on_confirm = OptionSaveChanges_onConfirm,
|
.on_confirm = OptionSaveChanges_onConfirm,
|
||||||
.items = (MenuItem[]){
|
.items = (MenuItem[]){
|
||||||
{"Save for all games"},
|
{"Save for console"},
|
||||||
{"Save for this game"},
|
{"Save for game"},
|
||||||
{"Restore defaults"},
|
{"Restore defaults"},
|
||||||
{NULL},
|
{NULL},
|
||||||
}
|
}
|
||||||
|
|
@ -3146,6 +3178,8 @@ static int Menu_options(MenuList* list) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static void Menu_loop(void) {
|
static void Menu_loop(void) {
|
||||||
|
POW_setCPUSpeed(CPU_SPEED_MENU); // set Hz directly
|
||||||
|
|
||||||
fast_forward = 0;
|
fast_forward = 0;
|
||||||
POW_enableAutosleep();
|
POW_enableAutosleep();
|
||||||
PAD_reset();
|
PAD_reset();
|
||||||
|
|
@ -3504,6 +3538,8 @@ static void Menu_loop(void) {
|
||||||
GFX_flip(screen);
|
GFX_flip(screen);
|
||||||
|
|
||||||
POW_disableAutosleep();
|
POW_disableAutosleep();
|
||||||
|
|
||||||
|
if (!quit) setOverclock(overclock); // restore overclock value
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move to POW_*?
|
// TODO: move to POW_*?
|
||||||
|
|
@ -3561,7 +3597,11 @@ static void limitFF(void) {
|
||||||
uint64_t ff_frame_time = 1000000 / (core.fps * (max_ff_speed + 1)); // TODO: define this only when max_ff_speed changes
|
uint64_t ff_frame_time = 1000000 / (core.fps * (max_ff_speed + 1)); // TODO: define this only when max_ff_speed changes
|
||||||
if (elapsed<ff_frame_time) {
|
if (elapsed<ff_frame_time) {
|
||||||
int delay = (ff_frame_time - elapsed) / 1000;
|
int delay = (ff_frame_time - elapsed) / 1000;
|
||||||
if (delay>0) SDL_Delay(delay);
|
if (delay>0) {
|
||||||
|
// TODO: huh, this isn't causing the Tekken 3 hangs...
|
||||||
|
// printf("limitFF delay: %i\n", delay); fflush(stdout);
|
||||||
|
SDL_Delay(delay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
last_time += ff_frame_time;
|
last_time += ff_frame_time;
|
||||||
return;
|
return;
|
||||||
|
|
@ -3571,6 +3611,7 @@ static void limitFF(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc , char* argv[]) {
|
int main(int argc , char* argv[]) {
|
||||||
|
setOverclock(overclock); // default to normal
|
||||||
// force a stack overflow to ensure asan is linked and actually working
|
// force a stack overflow to ensure asan is linked and actually working
|
||||||
// char tmp[2];
|
// char tmp[2];
|
||||||
// tmp[2] = 'a';
|
// tmp[2] = 'a';
|
||||||
|
|
|
||||||
|
|
@ -1233,6 +1233,7 @@ int main (int argc, char *argv[]) {
|
||||||
if (autoResume()) return 0; // nothing to do
|
if (autoResume()) return 0; // nothing to do
|
||||||
|
|
||||||
dump("MinUI");
|
dump("MinUI");
|
||||||
|
POW_setCPUSpeed(CPU_SPEED_MENU);
|
||||||
|
|
||||||
SDL_Surface* screen = GFX_init(MODE_MAIN);
|
SDL_Surface* screen = GFX_init(MODE_MAIN);
|
||||||
InitSettings();
|
InitSettings();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue