1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2019, MediaTek Inc. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <common/debug.h> 8*91f16700Schasinglulu #include <drivers/delay_timer.h> 9*91f16700Schasinglulu #include <rtc.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu static void RTC_Config_Interface(uint32_t addr, uint16_t data, 12*91f16700Schasinglulu uint16_t MASK, uint16_t SHIFT) 13*91f16700Schasinglulu { 14*91f16700Schasinglulu uint16_t pmic_reg = 0; 15*91f16700Schasinglulu 16*91f16700Schasinglulu pmic_reg = RTC_Read(addr); 17*91f16700Schasinglulu 18*91f16700Schasinglulu pmic_reg &= ~(MASK << SHIFT); 19*91f16700Schasinglulu pmic_reg |= (data << SHIFT); 20*91f16700Schasinglulu 21*91f16700Schasinglulu RTC_Write(addr, pmic_reg); 22*91f16700Schasinglulu } 23*91f16700Schasinglulu 24*91f16700Schasinglulu static void rtc_disable_2sec_reboot(void) 25*91f16700Schasinglulu { 26*91f16700Schasinglulu uint16_t reboot; 27*91f16700Schasinglulu 28*91f16700Schasinglulu reboot = (RTC_Read(RTC_AL_SEC) & ~RTC_BBPU_2SEC_EN) & 29*91f16700Schasinglulu ~RTC_BBPU_AUTO_PDN_SEL; 30*91f16700Schasinglulu RTC_Write(RTC_AL_SEC, reboot); 31*91f16700Schasinglulu RTC_Write_Trigger(); 32*91f16700Schasinglulu } 33*91f16700Schasinglulu 34*91f16700Schasinglulu static void rtc_xosc_write(uint16_t val, bool reload) 35*91f16700Schasinglulu { 36*91f16700Schasinglulu uint16_t bbpu; 37*91f16700Schasinglulu 38*91f16700Schasinglulu RTC_Write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK1); 39*91f16700Schasinglulu rtc_busy_wait(); 40*91f16700Schasinglulu RTC_Write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK2); 41*91f16700Schasinglulu rtc_busy_wait(); 42*91f16700Schasinglulu 43*91f16700Schasinglulu RTC_Write(RTC_OSC32CON, val); 44*91f16700Schasinglulu rtc_busy_wait(); 45*91f16700Schasinglulu 46*91f16700Schasinglulu if (reload) { 47*91f16700Schasinglulu bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD; 48*91f16700Schasinglulu RTC_Write(RTC_BBPU, bbpu); 49*91f16700Schasinglulu RTC_Write_Trigger(); 50*91f16700Schasinglulu } 51*91f16700Schasinglulu } 52*91f16700Schasinglulu 53*91f16700Schasinglulu static void rtc_enable_k_eosc(void) 54*91f16700Schasinglulu { 55*91f16700Schasinglulu uint16_t osc32; 56*91f16700Schasinglulu uint16_t rtc_eosc_cali_td = 8; /* eosc cali period time */ 57*91f16700Schasinglulu 58*91f16700Schasinglulu /* Truning on eosc cali mode clock */ 59*91f16700Schasinglulu RTC_Config_Interface(PMIC_RG_TOP_CON, 1, 60*91f16700Schasinglulu PMIC_RG_SRCLKEN_IN0_HW_MODE_MASK, 61*91f16700Schasinglulu PMIC_RG_SRCLKEN_IN0_HW_MODE_SHIFT); 62*91f16700Schasinglulu RTC_Config_Interface(PMIC_RG_TOP_CON, 1, 63*91f16700Schasinglulu PMIC_RG_SRCLKEN_IN1_HW_MODE_MASK, 64*91f16700Schasinglulu PMIC_RG_SRCLKEN_IN1_HW_MODE_SHIFT); 65*91f16700Schasinglulu RTC_Config_Interface(PMIC_RG_SCK_TOP_CKPDN_CON0, 0, 66*91f16700Schasinglulu PMIC_RG_RTC_EOSC32_CK_PDN_MASK, 67*91f16700Schasinglulu PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT); 68*91f16700Schasinglulu 69*91f16700Schasinglulu switch (rtc_eosc_cali_td) { 70*91f16700Schasinglulu case 1: 71*91f16700Schasinglulu RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x3, 72*91f16700Schasinglulu PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT); 73*91f16700Schasinglulu break; 74*91f16700Schasinglulu case 2: 75*91f16700Schasinglulu RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x4, 76*91f16700Schasinglulu PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT); 77*91f16700Schasinglulu break; 78*91f16700Schasinglulu case 4: 79*91f16700Schasinglulu RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x5, 80*91f16700Schasinglulu PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT); 81*91f16700Schasinglulu break; 82*91f16700Schasinglulu case 16: 83*91f16700Schasinglulu RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x7, 84*91f16700Schasinglulu PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT); 85*91f16700Schasinglulu break; 86*91f16700Schasinglulu default: 87*91f16700Schasinglulu RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x6, 88*91f16700Schasinglulu PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT); 89*91f16700Schasinglulu break; 90*91f16700Schasinglulu } 91*91f16700Schasinglulu /* Switch the DCXO from 32k-less mode to RTC mode, 92*91f16700Schasinglulu * otherwise, EOSC cali will fail 93*91f16700Schasinglulu */ 94*91f16700Schasinglulu /* RTC mode will have only OFF mode and FPM */ 95*91f16700Schasinglulu RTC_Config_Interface(PMIC_RG_DCXO_CW02, 0, PMIC_RG_XO_EN32K_MAN_MASK, 96*91f16700Schasinglulu PMIC_RG_XO_EN32K_MAN_SHIFT); 97*91f16700Schasinglulu RTC_Write(RTC_BBPU, 98*91f16700Schasinglulu RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD); 99*91f16700Schasinglulu RTC_Write_Trigger(); 100*91f16700Schasinglulu /* Enable K EOSC mode for normal power off and then plug out battery */ 101*91f16700Schasinglulu RTC_Write(RTC_AL_YEA, ((RTC_Read(RTC_AL_YEA) | RTC_K_EOSC_RSV_0) 102*91f16700Schasinglulu & (~RTC_K_EOSC_RSV_1)) | RTC_K_EOSC_RSV_2); 103*91f16700Schasinglulu RTC_Write_Trigger(); 104*91f16700Schasinglulu 105*91f16700Schasinglulu osc32 = RTC_Read(RTC_OSC32CON); 106*91f16700Schasinglulu rtc_xosc_write(osc32 | RTC_EMBCK_SRC_SEL, true); 107*91f16700Schasinglulu INFO("[RTC] RTC_enable_k_eosc\n"); 108*91f16700Schasinglulu } 109*91f16700Schasinglulu 110*91f16700Schasinglulu void rtc_power_off_sequence(void) 111*91f16700Schasinglulu { 112*91f16700Schasinglulu uint16_t bbpu; 113*91f16700Schasinglulu 114*91f16700Schasinglulu rtc_disable_2sec_reboot(); 115*91f16700Schasinglulu rtc_enable_k_eosc(); 116*91f16700Schasinglulu 117*91f16700Schasinglulu /* clear alarm */ 118*91f16700Schasinglulu bbpu = RTC_BBPU_KEY | RTC_BBPU_CLR | RTC_BBPU_PWREN; 119*91f16700Schasinglulu if (Writeif_unlock()) { 120*91f16700Schasinglulu RTC_Write(RTC_BBPU, bbpu); 121*91f16700Schasinglulu 122*91f16700Schasinglulu RTC_Write(RTC_AL_MASK, RTC_AL_MASK_DOW); 123*91f16700Schasinglulu RTC_Write_Trigger(); 124*91f16700Schasinglulu mdelay(1); 125*91f16700Schasinglulu 126*91f16700Schasinglulu bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD; 127*91f16700Schasinglulu RTC_Write(RTC_BBPU, bbpu); 128*91f16700Schasinglulu RTC_Write_Trigger(); 129*91f16700Schasinglulu INFO("[RTC] BBPU=0x%x, IRQ_EN=0x%x, AL_MSK=0x%x, AL_SEC=0x%x\n", 130*91f16700Schasinglulu RTC_Read(RTC_BBPU), RTC_Read(RTC_IRQ_EN), 131*91f16700Schasinglulu RTC_Read(RTC_AL_MASK), RTC_Read(RTC_AL_SEC)); 132*91f16700Schasinglulu } 133*91f16700Schasinglulu } 134