From 833dda7e7ceb095988cd40471f7c7182e58de21b Mon Sep 17 00:00:00 2001 From: CTCaer Date: Tue, 11 May 2021 09:32:38 +0300 Subject: [PATCH] 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. --- README.md | 2 +- bootloader/config.c | 4 +-- bootloader/main.c | 5 ++-- bootloader/storage/nx_sd.c | 7 ++++- nyx/nyx_gui/config.c | 20 ++++++++----- nyx/nyx_gui/config.h | 6 ++-- nyx/nyx_gui/frontend/gui.c | 47 +++++++++++++----------------- nyx/nyx_gui/frontend/gui_options.c | 6 ++-- nyx/nyx_gui/frontend/gui_tools.c | 4 +-- nyx/nyx_gui/nyx.c | 21 +++++++++++-- nyx/nyx_gui/storage/nx_sd.c | 10 +++++++ 11 files changed, 81 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 044aacc..838cb8d 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/bootloader/config.c b/bootloader/config.c index 04fd638..664a025 100644 --- a/bootloader/config.c +++ b/bootloader/config.c @@ -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; diff --git a/bootloader/main.c b/bootloader/main.c index e02b476..322b1f4 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -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(); diff --git a/bootloader/storage/nx_sd.c b/bootloader/storage/nx_sd.c index 69f0c50..f2cec2f 100644 --- a/bootloader/storage/nx_sd.c +++ b/bootloader/storage/nx_sd.c @@ -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; diff --git a/nyx/nyx_gui/config.c b/nyx/nyx_gui/config.c index 944ac23..22a1623 100644 --- a/nyx/nyx_gui/config.c +++ b/nyx/nyx_gui/config.c @@ -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; } diff --git a/nyx/nyx_gui/config.h b/nyx/nyx_gui/config.h index eb8cb66..b1c940c 100644 --- a/nyx/nyx_gui/config.h +++ b/nyx/nyx_gui/config.h @@ -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_ */ diff --git a/nyx/nyx_gui/frontend/gui.c b/nyx/nyx_gui/frontend/gui.c index 1d905cf..135c588 100644 --- a/nyx/nyx_gui/frontend/gui.c +++ b/nyx/nyx_gui/frontend/gui.c @@ -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. + } + } } diff --git a/nyx/nyx_gui/frontend/gui_options.c b/nyx/nyx_gui/frontend/gui_options.c index 8da550a..854bb64 100644 --- a/nyx/nyx_gui/frontend/gui_options.c +++ b/nyx/nyx_gui/frontend/gui_options.c @@ -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; } diff --git a/nyx/nyx_gui/frontend/gui_tools.c b/nyx/nyx_gui/frontend/gui_tools.c index f51f83f..0898bbc 100644 --- a/nyx/nyx_gui/frontend/gui_tools.c +++ b/nyx/nyx_gui/frontend/gui_tools.c @@ -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; diff --git a/nyx/nyx_gui/nyx.c b/nyx/nyx_gui/nyx.c index 8d85f50..a8a026d 100644 --- a/nyx/nyx_gui/nyx.c +++ b/nyx/nyx_gui/nyx.c @@ -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)) { diff --git a/nyx/nyx_gui/storage/nx_sd.c b/nyx/nyx_gui/storage/nx_sd.c index 3251b13..5037df1 100644 --- a/nyx/nyx_gui/storage/nx_sd.c +++ b/nyx/nyx_gui/storage/nx_sd.c @@ -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;