diff --git a/bdk/utils/util.c b/bdk/utils/util.c index d62fe51..e2ef9e8 100644 --- a/bdk/utils/util.c +++ b/bdk/utils/util.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert -* Copyright (c) 2018 CTCaer +* Copyright (c) 2018-2020 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, @@ -132,53 +132,57 @@ void panic(u32 val) usleep(1); } -void reboot_normal() +void power_set_state(power_state_t state) { + u8 reg; + + // Unmount and power down sd card. sd_end(); - hw_reinit_workaround(false, 0); - panic(0x21); // Bypass fuse programming in package1. -} - -void reboot_rcm() -{ - sd_end(); - hw_reinit_workaround(false, 0); - - PMC(APBDEV_PMC_SCRATCH0) = PMC_SCRATCH0_MODE_RCM; - PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST; - - while (true) - bpmp_halt(); -} - -void reboot_full() -{ - sd_end(); - hw_reinit_workaround(false, 0); - - // Enable soft reset wake event. - u8 reg = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2); - reg |= MAX77620_ONOFFCNFG2_SFT_RST_WK; - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2, reg); - - // Do a soft reset. - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_SFT_RST); - - while (true) - bpmp_halt(); -} - -void power_off() -{ - sd_end(); + // De-initialize and power down various hardware. hw_reinit_workaround(false, 0); // Stop the alarm, in case we injected and powered off too fast. max77620_rtc_stop_alarm(); - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF); + // Set power state. + switch (state) + { + case REBOOT_RCM: + PMC(APBDEV_PMC_SCRATCH0) = PMC_SCRATCH0_MODE_RCM; // Enable RCM path. + PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST; // PMC reset. + break; + + case REBOOT_BYPASS_FUSES: + panic(0x21); // Bypass fuse programming in package1. + break; + + case POWER_OFF: + // Initiate power down sequence and do not generate a reset (regulators retain state). + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF); + break; + + case POWER_OFF_RESET: + case POWER_OFF_REBOOT: + // Disable soft reset wake event. + reg = i2c_recv_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2); + if (state == POWER_OFF_RESET) + reg &= ~MAX77620_ONOFFCNFG2_SFT_RST_WK; // Do not wake up after power off. + else // POWER_OFF_REBOOT. + reg |= MAX77620_ONOFFCNFG2_SFT_RST_WK; // Wake up after power off. + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG2, reg); + + // Initiate power down sequence and generate a reset (regulators' state resets). + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_SFT_RST); + break; + } while (true) bpmp_halt(); } + +void power_set_state_ex(void *param) +{ + power_state_t *state = (power_state_t *)param; + power_set_state(*state); +} diff --git a/bdk/utils/util.h b/bdk/utils/util.h index dbbb76c..9a6d00a 100644 --- a/bdk/utils/util.h +++ b/bdk/utils/util.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018 CTCaer + * Copyright (c) 2018-2020 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, @@ -23,6 +23,16 @@ #define NYX_NEW_INFO 0x3058594E +typedef enum +{ + REBOOT_RCM, // PMC reset. Enter RCM mode. + REBOOT_BYPASS_FUSES, // PMC reset via watchdog. Enter Normal mode. Bypass fuse programming in package1. + + POWER_OFF, // Power off PMIC. Do not reset regulators. + POWER_OFF_RESET, // Power off PMIC. Reset regulators. + POWER_OFF_REBOOT, // Power off PMIC. Reset regulators. Power on. +} power_state_t; + typedef enum { NYX_CFG_BIS = BIT(5), @@ -71,17 +81,18 @@ typedef struct _nyx_storage_t emc_table_t mtc_table[10]; } nyx_storage_t; -u32 get_tmr_us(); -u32 get_tmr_ms(); -u32 get_tmr_s(); -void usleep(u32 us); -void msleep(u32 ms); -void panic(u32 val); -void reboot_normal(); -void reboot_rcm(); -void reboot_full(); -void power_off(); void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); u32 crc32_calc(u32 crc, const u8 *buf, u32 len); +u32 get_tmr_us(); +u32 get_tmr_ms(); +u32 get_tmr_s(); +void usleep(u32 us); +void msleep(u32 ms); + +void panic(u32 val); +void power_set_state(power_state_t state); +void power_set_state_ex(void *param); + + #endif diff --git a/bootloader/main.c b/bootloader/main.c index cad0f29..9e0bb4a 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -133,7 +133,7 @@ void check_power_off_from_hos() msleep(600); display_backlight_brightness(0, 20000); } - power_off(); + power_set_state(POWER_OFF); } } @@ -1304,7 +1304,7 @@ static void _check_low_battery() if (!current_charge_status) { max77620_low_battery_monitor_config(true); - power_off(); + power_set_state(POWER_OFF); } display_end(); @@ -1498,17 +1498,21 @@ ment_t ment_tools[] = { menu_t menu_tools = { ment_tools, "Tools", 0, 0 }; +power_state_t STATE_POWER_OFF = POWER_OFF; +power_state_t STATE_REBOOT_RCM = REBOOT_RCM; +power_state_t STATE_REBOOT_BYPASS_FUSES = REBOOT_BYPASS_FUSES; + ment_t ment_top[] = { MDEF_HANDLER("Launch", launch_firmware), //MDEF_MENU("Options", &menu_options), MDEF_CAPTION("---------------", 0xFF444444), - MDEF_MENU("Tools", &menu_tools), + MDEF_MENU("Tools", &menu_tools), MDEF_MENU("Console info", &menu_cinfo), MDEF_CAPTION("---------------", 0xFF444444), MDEF_HANDLER("Reload", ipl_reload), - MDEF_HANDLER("Reboot (Normal)", reboot_normal), - MDEF_HANDLER("Reboot (RCM)", reboot_rcm), - MDEF_HANDLER("Power off", power_off), + MDEF_HANDLER_EX("Reboot (Normal)", &STATE_REBOOT_BYPASS_FUSES, power_set_state_ex), + MDEF_HANDLER_EX("Reboot (RCM)", &STATE_REBOOT_RCM, power_set_state_ex), + MDEF_HANDLER_EX("Power off", &STATE_POWER_OFF, power_set_state_ex), MDEF_CAPTION("---------------", 0xFF444444), MDEF_HANDLER("About", _about), MDEF_END() diff --git a/nyx/nyx_gui/frontend/gui.c b/nyx/nyx_gui/frontend/gui.c index 1620c0f..5192c78 100644 --- a/nyx/nyx_gui/frontend/gui.c +++ b/nyx/nyx_gui/frontend/gui.c @@ -901,12 +901,12 @@ static lv_res_t _removed_sd_action(lv_obj_t *btns, const char *txt) { case 0: if (h_cfg.rcm_patched) - reboot_full(); + power_set_state(POWER_OFF_REBOOT); else - reboot_rcm(); + power_set_state(REBOOT_RCM); break; case 1: - power_off(); + power_set_state(POWER_OFF); break; case 2: sd_end(); @@ -955,14 +955,14 @@ static lv_res_t _reboot_action(lv_obj_t *btns, const char *txt) { case 0: if (h_cfg.rcm_patched) - reboot_full(); + power_set_state(POWER_OFF_REBOOT); else - reboot_normal(); + power_set_state(REBOOT_BYPASS_FUSES); break; case 1: if (h_cfg.rcm_patched) break; - reboot_rcm(); + power_set_state(REBOOT_RCM); break; } @@ -972,7 +972,7 @@ static lv_res_t _reboot_action(lv_obj_t *btns, const char *txt) static lv_res_t _poweroff_action(lv_obj_t *btns, const char *txt) { if (!lv_btnm_get_pressed(btns)) - power_off(); + power_set_state(POWER_OFF); return mbox_action(btns, txt); }