nyx: bpmp: automatically find best clock for t210

There were 4 reports of Nyx hanging or UMS and backup verification failing because of low binned Erista SoC.

This change reduces clock for hekate main and Nyx will now automatically try and find a working one.
In case Nyx hangs it will reduce it on next inject.

If Nyx works and user still has issues with UMS/Verification, manually editing nyx.ini and setting `bpmpclock=2` will fix that.
This commit is contained in:
CTCaer 2021-05-11 09:32:38 +03:00
parent 6a4ab55930
commit 833dda7e7c
11 changed files with 81 additions and 51 deletions

View file

@ -70,7 +70,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
| jcdisable=0 | 1: Disables Joycon driver completely. |
| newpowersave=1 | 0: Timer based, 1: DRAM frequency based (Better). Use 0 if Nyx hangs. |
| bpmpclock=1 | 0: Auto, 1: Faster, 2: Fast. Use 2 if Nyx hangs or some functions like UMS/Backup Verification fail. |
### Boot entry key/value combinations:

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2021 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -58,7 +58,7 @@ int create_config_entry()
if (!sd_mount())
return 1;
char lbuf[32];
char lbuf[64];
FIL fp;
bool mainIniFound = false;

View file

@ -1544,8 +1544,7 @@ void ipl_main()
h_cfg.errors |= !sd_mount() ? ERR_SD_BOOT_EN : 0;
// Save sdram lp0 config.
void *sdram_params =
hw_get_chip_id() == GP_HIDREV_MAJOR_T210 ? sdram_get_params_patched() : sdram_get_params_t210b01();
void *sdram_params = h_cfg.t210b01 ? sdram_get_params_t210b01() : sdram_get_params_patched();
if (!ianos_loader("bootloader/sys/libsys_lp0.bso", DRAM_LIB, sdram_params))
h_cfg.errors |= ERR_LIBSYS_LP0;
@ -1564,7 +1563,7 @@ void ipl_main()
//display_backlight_brightness(h_cfg.backlight, 1000);
// Overclock BPMP.
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
bpmp_clk_rate_set(h_cfg.t210b01 ? BPMP_CLK_DEFAULT_BOOST : BPMP_CLK_LOWER_BOOST);
// Check if we had a panic while in CFW.
secmon_exo_check_panic();

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2018 naehrwert
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2021 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -59,6 +59,11 @@ bool sd_get_card_removed()
return false;
}
bool sd_get_card_mounted()
{
return sd_mounted;
}
u32 sd_get_mode()
{
return sd_mode;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020 CTCaer
* Copyright (c) 2018-2021 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -64,7 +64,7 @@ void set_nyx_default_configuration()
n_cfg.verification = 1;
n_cfg.ums_emmc_rw = 0;
n_cfg.jc_disable = 0;
n_cfg.new_powersave = 1;
n_cfg.bpmp_clock = 0;
}
int create_config_entry()
@ -72,7 +72,7 @@ int create_config_entry()
if (!sd_mount())
return 1;
char lbuf[32];
char lbuf[64];
FIL fp;
bool mainIniFound = false;
@ -173,12 +173,14 @@ int create_config_entry()
return 0;
}
int create_nyx_config_entry()
int create_nyx_config_entry(bool force_unmount)
{
bool sd_mounted = sd_get_card_mounted();
if (!sd_mount())
return 1;
char lbuf[32];
char lbuf[64];
FIL fp;
// Make sure that bootloader folder exists.
@ -206,13 +208,15 @@ int create_nyx_config_entry()
f_puts("\njcdisable=", &fp);
itoa(n_cfg.jc_disable, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\nnewpowersave=", &fp);
itoa(n_cfg.new_powersave, lbuf, 10);
f_puts("\nbpmpclock=", &fp);
itoa(n_cfg.bpmp_clock, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\n", &fp);
f_close(&fp);
sd_unmount();
if (force_unmount || !sd_mounted)
sd_unmount();
return 0;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2019 CTCaer
* Copyright (c) 2018-2021 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@ -51,12 +51,12 @@ typedef struct _nyx_config
u32 verification;
u32 ums_emmc_rw;
u32 jc_disable;
u32 new_powersave;
u32 bpmp_clock;
} nyx_config;
void set_default_configuration();
void set_nyx_default_configuration();
int create_config_entry();
int create_nyx_config_entry();
int create_nyx_config_entry(bool force_unmount);
#endif /* _CONFIG_H_ */

View file

@ -2106,6 +2106,14 @@ static void _nyx_set_default_styles(lv_theme_t * th)
s_printf(text_color, "#%06X", tmp_color.full & 0xFFFFFF);
}
lv_task_t *task_bpmp_clock;
void first_time_bpmp_clock(void *param)
{
n_cfg.bpmp_clock = 1;
create_nyx_config_entry(false);
lv_task_del(task_bpmp_clock);
}
static void _nyx_main_menu(lv_theme_t * th)
{
static lv_style_t no_padding;
@ -2240,30 +2248,9 @@ static void _nyx_main_menu(lv_theme_t * th)
lv_task_t *task_run_clock = lv_task_create(first_time_clock_edit, LV_TASK_ONESHOT, LV_TASK_PRIO_MID, NULL);
lv_task_once(task_run_clock);
}
}
static void _nyx_gui_loop_powersave_ram()
{
// Saves 280 mW.
while (true)
{
minerva_change_freq(FREQ_1600); // Takes 295 us.
lv_task_handler();
minerva_change_freq(FREQ_800); // Takes 80 us.
}
}
static void _nyx_gui_loop_powersave_cpu()
{
// Saves 75 mW.
while (true)
{
lv_task_handler();
bpmp_usleep(HALT_COP_MAX_CNT); // Takes 200 us.
}
if (!n_cfg.bpmp_clock)
task_bpmp_clock = lv_task_create(first_time_bpmp_clock, 5000, LV_TASK_PRIO_LOWEST, NULL);
}
void nyx_load_and_run()
@ -2331,8 +2318,16 @@ void nyx_load_and_run()
while (true)
lv_task_handler();
}
else if (n_cfg.new_powersave)
_nyx_gui_loop_powersave_ram(); // Alternate DRAM frequencies. Higher power savings.
else
_nyx_gui_loop_powersave_cpu(); // Suspend CPU. Lower power savings.
{
// Alternate DRAM frequencies. Saves 280 mW.
while (true)
{
minerva_change_freq(FREQ_1600); // Takes 295 us.
lv_task_handler();
minerva_change_freq(FREQ_800); // Takes 80 us.
}
}
}

View file

@ -336,7 +336,7 @@ static lv_res_t _save_nyx_options_action(lv_obj_t *btn)
lv_obj_t * mbox = lv_mbox_create(lv_scr_act(), NULL);
lv_mbox_set_recolor_text(mbox, true);
int res = !create_nyx_config_entry();
int res = !create_nyx_config_entry(true);
nyx_changes_made = false;
@ -400,7 +400,7 @@ static lv_res_t _save_theme_color_action(lv_obj_t *btn)
n_cfg.themecolor = color_test.hue;
// Save nyx config.
create_nyx_config_entry();
create_nyx_config_entry(true);
reload_nyx();
@ -622,6 +622,8 @@ static lv_res_t _action_clock_edit(lv_obj_t *btns, const char * txt)
u32 new_epoch = max77620_rtc_date_to_epoch(&time);
n_cfg.timeoff = new_epoch - epoch;
if (!n_cfg.timeoff)
n_cfg.timeoff = 1;
nyx_changes_made = true;
}

View file

@ -348,7 +348,7 @@ static lv_res_t _action_hid_jc(lv_obj_t *btn)
// Reduce BPMP, RAM and backlight and power off SDMMC1 to conserve power.
sd_end();
minerva_change_freq(FREQ_800);
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
display_backlight_brightness(10, 1000);
usb_ctxt_t usbs;
@ -360,7 +360,7 @@ static lv_res_t _action_hid_jc(lv_obj_t *btn)
// Restore BPMP, RAM and backlight.
minerva_change_freq(FREQ_1600);
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
bpmp_clk_rate_set(prev_fid);
display_backlight_brightness(h_cfg.backlight - 20, 1000);
return LV_RES_OK;

View file

@ -292,8 +292,8 @@ void load_saved_configuration()
n_cfg.ums_emmc_rw = atoi(kv->val) == 1;
else if (!strcmp("jcdisable", kv->key))
n_cfg.jc_disable = atoi(kv->val) == 1;
else if (!strcmp("newpowersave", kv->key))
n_cfg.new_powersave = atoi(kv->val) == 1;
else if (!strcmp("bpmpclock", kv->key))
n_cfg.bpmp_clock = strtol(kv->val, NULL, 10);
}
break;
@ -361,7 +361,9 @@ void nyx_init_load_res()
{
bpmp_mmu_enable();
bpmp_clk_rate_get();
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
// Set a modest clock for init. It will be restored later if possible.
bpmp_clk_rate_set(BPMP_CLK_LOWER_BOOST);
// Set bootloader's default configuration.
set_default_configuration();
@ -395,6 +397,19 @@ void nyx_init_load_res()
load_saved_configuration();
// Initialize nyx cfg to lower clock for T210.
// In case of lower binned SoC, this can help with hangs.
if (!n_cfg.bpmp_clock)
{
n_cfg.bpmp_clock = h_cfg.t210b01 ? 1 : 2; // Set lower clock for T210.
create_nyx_config_entry(false);
n_cfg.bpmp_clock = h_cfg.t210b01 ? 1 : 0; // Restore for T210 and keep for T210B01.
}
// Restore clock to max.
if (n_cfg.bpmp_clock < 2)
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
FIL fp;
if (!f_open(&fp, "bootloader/sys/res.pak", FA_READ))
{

View file

@ -65,6 +65,11 @@ bool sd_get_card_initialized()
return sd_init_done;
}
bool sd_get_card_mounted()
{
return sd_mounted;
}
u32 sd_get_mode()
{
return sd_mode;
@ -197,6 +202,11 @@ static void _sd_deinit(bool deinit)
void sd_unmount() { _sd_deinit(false); }
void sd_end() { _sd_deinit(true); }
bool sd_is_gpt()
{
return sd_fs.part_type;
}
void *sd_file_read(const char *path, u32 *fsize)
{
FIL fp;