/* Copyright (C) 2017 RDA Technologies Limited and/or its affiliates("RDA"). * All rights reserved. * * This software is supplied "AS IS" without any warranties. * RDA assumes no responsibility or liability for the use of the software, * conveys no license or title under any patent, copyright, or mask work * right to the product. RDA reserves the right to make changes in the * software without notification. RDA also make no representation or * warranty that such application will be suitable for the specified use * without further testing or modification. */ #include "boot_platform.h" #include "hal_adi_bus.h" #include "hwregs.h" #include "osi_compiler.h" #include "osi_api.h" #include "osi_tick_unit.h" #include "hal_config.h" #include "hal_chip.h" #include "hal_blue_screen.h" #include "cmsis_core.h" #include "quec_proj_config.h" #include "quec_cust_patch.h" #define PSM_MODE_REG (hwp_pmicPsm->reserved_2) // should be sync with psm sleep #define PSM_WR_PROT_MAGIC (0x454e) void bootReset(bootResetMode_t mode) { REG_LPS_APB_CFG_BOOT_MODE_T cfg_boot_mode = {}; if (mode == BOOT_RESET_FORCE_DOWNLOAD) { cfg_boot_mode.v = hwp_lpsApb->cfg_boot_mode; cfg_boot_mode.b.boot_mode_pin |= 1; cfg_boot_mode.b.boot_mode_pin &= ~1; // force download, clear product test cfg_boot_mode.b.boot_mode_sw = 0; hwp_lpsApb->cfg_boot_mode = cfg_boot_mode.v; REG_AP_APB_AP_RST0_T ap_rst0 = {}; ap_rst0.b.rst_ap_a5 = 1; hwp_apApb->ap_rst0 = ap_rst0.v; OSI_DEAD_LOOP; } else { #ifdef QUEC_PATCH_BOOT_RESET_MMU_PSRAM #if 1 //pmic reset:通过pmic对cpu就行复位,同时pmic也会清除自身的某些寄存器,但是LDO不掉电除非配置了掉电操作 REG_PMIC_RTC_ANA_SWRST_CTRL0_T swrst_ctrl0 = {halAdiBusRead(&hwp_pmicRtcAna->swrst_ctrl0)}; swrst_ctrl0.b.reg_rst_en = 1; halAdiBusWrite(&hwp_pmicRtcAna->swrst_ctrl0, swrst_ctrl0.v); REG_PMIC_RTC_ANA_SOFT_RST_HW_T soft_rst_hw; soft_rst_hw.b.reg_soft_rst_sw = 1; halAdiBusWrite(&hwp_pmicRtcAna->soft_rst_hw, soft_rst_hw.v); OSI_DEAD_LOOP; #else //chip reset:没经过pmic的复位,CPU自身复位,pmic的状态不变 REG_LPS_APB_RESET_SYS_SOFT_T reset_enable = {hwp_lpsApb->reset_sys_soft}; reset_enable.b.chip_soft_reset = 1; hwp_lpsApb->reset_sys_soft = reset_enable.v; OSI_DEAD_LOOP; #endif #else REG_PMIC_RTC_ANA_SWRST_CTRL0_T swrst_ctrl0; swrst_ctrl0.b.reg_rst_en = 1; halAdiBusWrite(&hwp_pmicRtcAna->swrst_ctrl0, swrst_ctrl0.v); REG_PMIC_RTC_ANA_SOFT_RST_HW_T soft_rst_hw; soft_rst_hw.b.reg_soft_rst_sw = 1; halAdiBusWrite(&hwp_pmicRtcAna->soft_rst_hw, soft_rst_hw.v); #endif } } void _psmPrepare(void) { // psm pclk enable halAdiBusWrite(&hwp_pmicRtcAna->module_en0, 0x12); //rtc soft_reset halAdiBusWrite(&hwp_pmicRtcAna->soft_rst0, 0x20); //powkey_time osiDelayUS(10); halAdiBusWrite(&hwp_pmicRtcAna->soft_rst0, 0x00); //config psm register //REG_PMIC_PSM_PSM_REG_WR_PROTECT_T halAdiBusWrite(&hwp_pmicPsm->psm_reg_wr_protect, PSM_WR_PROT_MAGIC); // psm apb soft_reset halAdiBusWrite(&hwp_pmicPsm->psm_ctrl, 0x100); osiDelayUS(10); // open PSM protect register halAdiBusWrite(&hwp_pmicPsm->psm_reg_wr_protect, PSM_WR_PROT_MAGIC); // psm module soft_reset, auto clear halAdiBusWrite(&hwp_pmicPsm->psm_ctrl, 0xc00); halAdiBusWrite(&hwp_pmicPsm->psm_ctrl, 0x0); REG_PMIC_RTC_ANA_CLK32KLESS_CTRL0_T clk32kless_ctrl0; clk32kless_ctrl0.v = halAdiBusRead(&hwp_pmicRtcAna->clk32kless_ctrl0); if (clk32kless_ctrl0.b.rtc_mode == 0) { REG_PMIC_PSM_CLK_32K_XTAL_CALIBRA_SEL_T clk_32k_xtal_cal_sel; REG_ADI_CHANGE1(hwp_pmicPsm->clk_32k_xtal_calibra_sel, clk_32k_xtal_cal_sel, clk_32k_xtal_calibra_sel, 0); REG_PMIC_PSM_XTAL_POR_1ST_CLK_SEL_T xtal_por_1st_clk; REG_ADI_CHANGE1(hwp_pmicPsm->xtal_por_1st_clk_sel, xtal_por_1st_clk, xtal_por_1st_clk_sel, 0); halAdiBusWrite(&hwp_pmicPsm->psm_rc_clk_div, 0x470); } else { halAdiBusWrite(&hwp_pmicPsm->psm_rc_clk_div, 0x4f0); } halAdiBusWrite(&hwp_pmicPsm->psm_32k_cal_th, 0x808); halAdiBusWrite(&hwp_pmicPsm->psm_26m_cal_dn_th, 0x0); halAdiBusWrite(&hwp_pmicPsm->psm_26m_cal_up_th, 0xffff); halAdiBusWrite(&hwp_pmicPsm->rtc_pwr_off_th1, 0x1810); halAdiBusWrite(&hwp_pmicPsm->rtc_pwr_off_th2, 0x2820); halAdiBusWrite(&hwp_pmicPsm->rtc_pwr_off_th3, 0x40); halAdiBusWrite(&hwp_pmicPsm->rtc_pwr_on_th1, 0x2004); halAdiBusWrite(&hwp_pmicPsm->rtc_pwr_on_th2, 0x0506); halAdiBusWrite(&hwp_pmicPsm->rtc_pwr_on_th3, 0x48ff); // configure psm cal interval halAdiBusWrite(&hwp_pmicPsm->psm_cnt_interval_th, 0x6); // configure psm cal phase, <=psm_cnt_interval_th halAdiBusWrite(&hwp_pmicPsm->psm_cnt_interval_phase, 0x6); } void bootPowerOff(void) { bool pwrkey_en = false; bool wakeup_en = false; _psmPrepare(); //halAdiBusWrite(&PSM_MODE_REG, OSI_SHUTDOWN_POWER_OFF); #ifdef CONFIG_PWRKEY_POWERUP pwrkey_en = true; #else pwrkey_en = false; #endif #ifdef CONFIG_WAKEUP_PIN_POWERUP wakeup_en = true; #endif // configure psm each function enable signal REG_PMIC_PSM_PSM_CTRL_T psm_ctrl = { .b.psm_en = 1, .b.rtc_pwr_on_timeout_en = 0, .b.ext_int_pwr_en = wakeup_en ? 1 : 0, .b.pbint1_pwr_en = pwrkey_en ? 1 : 0, .b.pbint2_pwr_en = 0, #ifdef CONFIG_CHARGER_POWERUP .b.charger_pwr_en = 1, #else .b.charger_pwr_en = 0, #endif .b.psm_cnt_alarm_en = 0, .b.psm_cnt_alm_en = 0, .b.psm_software_reset = 0, .b.psm_cnt_update = 1, .b.psm_cnt_en = 1, .b.psm_status_clr = 0, .b.psm_cal_en = 1, .b.rtc_32k_clk_sel = 0, // 32k less }; //halAdiBusWrite(&hwp_pmicPsm->psm_alarm_cnt_l_th, 0x880); //halAdiBusWrite(&hwp_pmicPsm->psm_alarm_cnt_h_th, 0x0); //halAdiBusWrite(&hwp_pmicPsm->psm_cnt_interval_th, 0x2); //halAdiBusWrite(&hwp_pmicPsm->psm_cnt_interval_phase, 0x2); REG_PMIC_RTC_ANA_CLK32KLESS_CTRL0_T clk32kless_ctrl0; clk32kless_ctrl0.v = halAdiBusRead(&hwp_pmicRtcAna->clk32kless_ctrl0); if (clk32kless_ctrl0.b.rtc_mode == 0) { psm_ctrl.b.psm_cal_en = 0; } halAdiBusWrite(&hwp_pmicPsm->psm_ctrl, psm_ctrl.v); //halAdiBusWrite(&hwp_pmicPsm->psm_ctrl, 0x1641); REG_PMIC_PSM_PSM_STATUS_T psm_psm_status; REG_ADI_WAIT_FIELD_NEZ(psm_psm_status, hwp_pmicPsm->psm_status, psm_cnt_update_vld); halAdiBusWrite(&(hwp_pmicPsm->reserved_4), halAdiBusRead(&hwp_pmicPsm->psm_fsm_status)); // power off rtc //REG_PMIC_RTC_ANA_POWER_PD_HW_T rtc_ana_power_pd_hw; //rtc_ana_power_pd_hw.b.pwr_off_seq_en = 1; //halAdiBusWrite(&hwp_pmicRtcAna->power_pd_hw, rtc_ana_power_pd_hw.v); halAdiBusWrite(&hwp_pmicRtcAna->power_pd_hw, 1); //OSI_DEAD_LOOP; } bool bootIsFromPsmSleep(void) { REG_PMIC_RTC_ANA_MODULE_EN0_T module_en0; // enable PSM module module_en0.v = halAdiBusRead(&hwp_pmicRtcAna->module_en0); module_en0.b.psm_topa_en = 1; halAdiBusWrite(&hwp_pmicRtcAna->module_en0, module_en0.v); uint32_t psm_magic = halAdiBusRead(&PSM_MODE_REG); // disable PSM module module_en0.b.psm_topa_en = 0; halAdiBusWrite(&hwp_pmicRtcAna->module_en0, module_en0.v); return (psm_magic == OSI_SHUTDOWN_PSM_SLEEP); } uint32_t bootSecondOffsetBytes(void) { return 0; } int bootPowerOnCause() { REG_PMIC_RTC_ANA_SWRST_CTRL0_T swrst_ctrl0; swrst_ctrl0.v = halAdiBusRead(&hwp_pmicRtcAna->swrst_ctrl0); if (swrst_ctrl0.b.reg_rst_en == 0) { REG_PMIC_RTC_ANA_POR_SRC_FLAG_T por_src_flag; por_src_flag.v = halAdiBusRead(&hwp_pmicRtcAna->por_src_flag); if (por_src_flag.v & (1 << 11)) return OSI_BOOTCAUSE_PIN_RESET; if (por_src_flag.v & ((1 << 12) | (1 << 9) | (1 << 8))) return OSI_BOOTCAUSE_PWRKEY; if (por_src_flag.v & (1 << 6)) return OSI_BOOTCAUSE_ALARM; if (por_src_flag.v & ((1 << 4) | (1 << 5) | (1 << 10))) return OSI_BOOTCAUSE_CHARGE; } return OSI_BOOTCAUSE_UNKNOWN; } void bootResetPinEnable(void) { //ext_rstn_mode : EXT_RSTN PIN function mode when 1key 7S reset0: EXT_INT 1: RESET //key2_7s_rst_en: 1: One-key Reset Mode;0: Two-key Reset Mode; //pbint_7s_rst_disable: 0: enable 7s reset function; 1: disable 7s reset function; REG_PMIC_RTC_ANA_POR_7S_CTRL_T por_7s_ctrl; REG_PMIC_RTC_ANA_MIXED_CTRL_T bat; bat.v = halAdiBusRead(&hwp_pmicRtcAna->mixed_ctrl); if (bat.b.batdet_ok == 1) { REG_ADI_CHANGE2(hwp_pmicRtcAna->por_7s_ctrl, por_7s_ctrl, ext_rstn_mode, 1, key2_7s_rst_en, 1); } #ifdef CONFIG_BOOT_PB_7S_RESET_ENABLE REG_ADI_CHANGE1(hwp_pmicRtcAna->por_7s_ctrl, por_7s_ctrl, pbint_7s_rst_disable, 0); #else REG_ADI_CHANGE1(hwp_pmicRtcAna->por_7s_ctrl, por_7s_ctrl, pbint_7s_rst_disable, 1); #endif REG_PMIC_RTC_ANA_SWRST_CTRL0_T swrst_ctrl0 = {halAdiBusRead(&hwp_pmicRtcAna->swrst_ctrl0)}; swrst_ctrl0.b.ext_rstn_pd_en = 1; swrst_ctrl0.b.pb_7s_rst_pd_en = 1; swrst_ctrl0.b.reg_rst_pd_en = 1; swrst_ctrl0.b.wdg_rst_pd_en = 0; halAdiBusWrite(&hwp_pmicRtcAna->swrst_ctrl0, swrst_ctrl0.v); REG_PMIC_RTC_ANA_SWRST_CTRL1_T swrst_ctrl1 = {}; //swrst_ctrl1.b.sw_rst_sdcore_pd_en = 0; //swrst_ctrl1.b.sw_rst_sdio_pd_en = 0; swrst_ctrl1.b.sw_rst_vio33_pd_en = 0; swrst_ctrl1.b.sw_rst_usb_pd_en = 0; swrst_ctrl1.b.sw_rst_rf15_pd_en = 0; swrst_ctrl1.b.sw_rst_ana_pd_en = 0; swrst_ctrl1.b.sw_rst_rf12_pd_en = 0; swrst_ctrl1.b.sw_rst_dcxo_pd_en = 0; #ifdef QUEC_PATCH_BOOT_RESET_MMU_PSRAM swrst_ctrl1.b.sw_rst_mem_pd_en = 1; //reset时Vmem掉电 #else swrst_ctrl1.b.sw_rst_mem_pd_en = 0; //Software reset LDO_MEM_PD enable when global reset valid. 0: disable 1: enable #endif swrst_ctrl1.b.sw_rst_dcdccore_pd_en = 0; swrst_ctrl1.b.sw_rst_dcdcgen_pd_en = 0; swrst_ctrl1.b.sw_rst_vio18_pd_en = 0; swrst_ctrl1.b.sw_rst_spimem_pd_en = 0; halAdiBusWrite(&hwp_pmicRtcAna->swrst_ctrl1, swrst_ctrl1.v); } static void prvMedConfig(void) { REG_MED_MED_WORK_MODE_T med_work_mode = {hwp_med->med_work_mode}; med_work_mode.b.med_key_iv_sel = 1; hwp_med->med_work_mode = med_work_mode.v; REG_MED_MED_INT_EN_T med_int_en = {}; med_int_en.b.med_wr_done_int_en = 1; hwp_med->med_int_en = med_int_en.v; REG_MED_MED_CH0_WORK_CFG_T med_ch0_work_cfg = { .b.med_ch0_enable = 1, .b.med_ch0_bypass_en = 1, }; #ifdef CONFIG_MED_CODE_ENCRYPT med_ch0_work_cfg.b.med_ch0_bypass_en = 0; hwp_med->med_ch0_work_cfg = med_ch0_work_cfg.v; hwp_med->med_ch0_addr_size_cfg = HAL_FLASH_OFFSET(CONFIG_FS_SYS_FLASH_ADDRESS); hwp_med->med_ch0_base_addr_cfg = CONFIG_NOR_PHY_ADDRESS; hwp_med->med_ch0_read_addr_remap = CONFIG_NOR_PHY_ADDRESS; REG_MED_MED_CH1_WORK_CFG_T med_ch1_work_cfg = { .b.med_ch1_enable = 1, .b.med_ch1_bypass_en = 1, }; hwp_med->med_ch1_work_cfg = med_ch1_work_cfg.v; hwp_med->med_ch1_addr_size_cfg = 0xffffff; hwp_med->med_ch1_base_addr_cfg = CONFIG_FS_SYS_FLASH_ADDRESS; hwp_med->med_ch1_read_addr_remap = hwp_med->med_ch1_base_addr_cfg; #else hwp_med->med_ch0_work_cfg = med_ch0_work_cfg.v; hwp_med->med_ch0_addr_size_cfg = 0xffffff; hwp_med->med_ch0_base_addr_cfg = CONFIG_NOR_PHY_ADDRESS; hwp_med->med_ch0_read_addr_remap = hwp_med->med_ch0_base_addr_cfg; #endif hwp_med->med_clr = 0xffffffff; } void bootPlatformInit(void) { halSysWdtStop(); prvMedConfig(); } OSI_NO_RETURN OSI_WEAK void bootBlueScreen(void *ctx) { halBlueScreenSaveContext(); osiDCacheCleanInvalidateAll(); OSI_DEAD_LOOP; }