dca92cf01f
As we will never get their FGPA source code. Zero loss.
4223 lines
117 KiB
C
4223 lines
117 KiB
C
/***************************************************************************
|
|
*
|
|
* Copyright 2015-2019 BES.
|
|
* All rights reserved. All unpublished rights reserved.
|
|
*
|
|
* No part of this work may be used or reproduced in any form or by any
|
|
* means, or stored in a database or retrieval system, without prior written
|
|
* permission of BES.
|
|
*
|
|
* Use of this work is governed by a license granted by BES.
|
|
* This work contains confidential and proprietary information of
|
|
* BES. which is protected by copyright, trade secret,
|
|
* trademark and other intellectual property rights.
|
|
*
|
|
****************************************************************************/
|
|
#include "analog.h"
|
|
#include "cmsis.h"
|
|
#include "cmsis_nvic.h"
|
|
#include "hal_aud.h"
|
|
#include "hal_cache.h"
|
|
#include "hal_chipid.h"
|
|
#include "hal_cmu.h"
|
|
#include "hal_location.h"
|
|
#include "hal_psc.h"
|
|
#include "hal_sysfreq.h"
|
|
#include "hal_timer.h"
|
|
#include "hal_trace.h"
|
|
#include "pmu.h"
|
|
#include "tgt_hardware.h"
|
|
#include "usbphy.h"
|
|
|
|
#define PMU_LED_VIA_PWM
|
|
#define DCDC_ULP_LP_ON
|
|
|
|
// LDO soft start interval is about 1000 us
|
|
#define PMU_LDO_PU_STABLE_TIME_US 1800
|
|
#define PMU_DCDC_PU_STABLE_TIME_US 100
|
|
#define PMU_VANA_STABLE_TIME_US 10
|
|
#define PMU_VCORE_STABLE_TIME_US 10
|
|
|
|
#ifdef __PMU_VIO_DYNAMIC_CTRL_MODE__
|
|
#define IO_VOLT_ACTIVE_NORMAL PMU_IO_2_6V
|
|
#else
|
|
#define IO_VOLT_ACTIVE_NORMAL PMU_IO_2_6V
|
|
#endif
|
|
#ifdef DIGMIC_HIGH_VOLT
|
|
#define IO_VOLT_ACTIVE_RISE PMU_IO_3_0V
|
|
#else
|
|
#define IO_VOLT_ACTIVE_RISE PMU_IO_2_8V
|
|
#endif
|
|
#define IO_VOLT_SLEEP PMU_IO_2_6V
|
|
|
|
#define HPPA_RAMP_UP_VOLT_MV 1950
|
|
|
|
#define PMU_DCDC_ANA_2_1V 0xF0
|
|
#define PMU_DCDC_ANA_2_0V 0xE0
|
|
#define PMU_DCDC_ANA_1_9V 0xD0
|
|
#define PMU_DCDC_ANA_1_8V 0xC0
|
|
#define PMU_DCDC_ANA_1_7V 0xB0
|
|
#define PMU_DCDC_ANA_1_6V 0xA0
|
|
#define PMU_DCDC_ANA_1_5V 0x90
|
|
#define PMU_DCDC_ANA_1_4V 0x80
|
|
#define PMU_DCDC_ANA_1_35V 0x77
|
|
#define PMU_DCDC_ANA_1_3V 0x70
|
|
#define PMU_DCDC_ANA_1_2V 0x60
|
|
#define PMU_DCDC_ANA_1_1V 0x50
|
|
#define PMU_DCDC_ANA_1_0V 0x40
|
|
|
|
#define PMU_DCDC_ANA_SLEEP_1_3V PMU_DCDC_ANA_1_3V
|
|
#define PMU_DCDC_ANA_SLEEP_1_2V PMU_DCDC_ANA_1_2V
|
|
#define PMU_DCDC_ANA_SLEEP_1_1V PMU_DCDC_ANA_1_1V
|
|
#define PMU_DCDC_ANA_SLEEP_1_0V PMU_DCDC_ANA_1_0V
|
|
|
|
#define PMU_VBUCK2ANA_1_5V 0x30
|
|
#define PMU_VBUCK2ANA_1_4V 0x2C
|
|
#define PMU_VBUCK2ANA_1_3V 0x28
|
|
#define PMU_VBUCK2ANA_1_2V 0x24
|
|
#define PMU_VBUCK2ANA_1_1V 0x20
|
|
#define PMU_VBUCK2ANA_1_0V 0x1C
|
|
|
|
#define PMU_DCDC_DIG_1_1V 0xFF
|
|
#define PMU_DCDC_DIG_1_05V 0xF0
|
|
#define PMU_DCDC_DIG_1_0V 0xE0
|
|
#define PMU_DCDC_DIG_0_95V 0xD0
|
|
#define PMU_DCDC_DIG_0_9V 0xC0
|
|
#define PMU_DCDC_DIG_0_85V 0xB0
|
|
#define PMU_DCDC_DIG_0_8V 0xA0
|
|
#define PMU_DCDC_DIG_0_75V 0x90
|
|
#define PMU_DCDC_DIG_0_7V 0x80
|
|
#define PMU_DCDC_DIG_0_65V 0x70
|
|
#define PMU_DCDC_DIG_0_6V 0x60
|
|
#define PMU_DCDC_DIG_0_55V 0x50
|
|
#define PMU_DCDC_DIG_0_5V 0x40
|
|
#define PMU_DCDC_DIG_0_45V 0x30
|
|
#define PMU_DCDC_DIG_0_4V 0x20
|
|
|
|
#define PMU_VDIG_1_2V 0x24
|
|
#define PMU_VDIG_1_1V 0x20
|
|
#define PMU_VDIG_1_05V 0x1E
|
|
#define PMU_VDIG_1_0V 0x1C
|
|
#define PMU_VDIG_0_95V 0x1A
|
|
#define PMU_VDIG_0_9V 0x18
|
|
#define PMU_VDIG_0_85V 0x16
|
|
#define PMU_VDIG_0_8V 0x14
|
|
#define PMU_VDIG_0_75V 0x12
|
|
#define PMU_VDIG_0_7V 0x10
|
|
#define PMU_VDIG_0_65V 0x0E
|
|
#define PMU_VDIG_0_6V 0x0C
|
|
#define PMU_VDIG_0_55V 0x0A
|
|
#define PMU_VDIG_0_5V 0x08
|
|
#define PMU_VDIG_0_45V 0x06
|
|
#define PMU_VDIG_0_4V 0x04
|
|
#define PMU_VDIG_MAX PMU_VDIG_1_2V
|
|
|
|
#define PMU_IO_3_3V 0x15
|
|
#define PMU_IO_3_2V 0x14
|
|
#define PMU_IO_3_1V 0x13
|
|
#define PMU_IO_3_0V 0x12
|
|
#define PMU_IO_2_9V 0x11
|
|
#define PMU_IO_2_8V 0x10
|
|
#define PMU_IO_2_7V 0xF
|
|
#define PMU_IO_2_6V 0xE
|
|
#define PMU_IO_2_5V 0xD
|
|
#define PMU_IO_2_4V 0xC
|
|
#define PMU_IO_2_3V 0xB
|
|
#define PMU_IO_2_2V 0xA
|
|
#define PMU_IO_2_1V 0x9
|
|
#define PMU_IO_2_0V 0x8
|
|
#define PMU_IO_1_9V 0x7
|
|
#define PMU_IO_1_8V 0x6
|
|
#define PMU_IO_1_7V 0x5
|
|
|
|
#define PMU_VMEM_2_8V 0x10
|
|
#define PMU_VMEM_2_0V 0x8
|
|
#define PMU_VMEM_1_9V 0x7
|
|
#define PMU_VMEM_1_8V 0x6
|
|
#define PMU_VMEM_1_7V 0x5
|
|
#define PMU_VMEM_1_6V 0x4
|
|
|
|
#define PMU_CODEC_2_7V 0xF
|
|
#define PMU_CODEC_2_6V 0xE
|
|
#define PMU_CODEC_2_5V 0xD
|
|
#define PMU_CODEC_2_4V 0xC
|
|
#define PMU_CODEC_2_3V 0xB
|
|
#define PMU_CODEC_2_2V 0xA
|
|
#define PMU_CODEC_2_1V 0x9
|
|
#define PMU_CODEC_2_0V 0x8
|
|
#define PMU_CODEC_1_9V 0x7
|
|
#define PMU_CODEC_1_8V 0x6
|
|
#define PMU_CODEC_1_7V 0x5
|
|
#define PMU_CODEC_1_6V 0x4
|
|
#define PMU_CODEC_1_5V 0x3
|
|
|
|
#define PMU_HPPA2CODEC_2_3V 0x1C
|
|
#define PMU_HPPA2CODEC_2_2V 0x18
|
|
#define PMU_HPPA2CODEC_2_1V 0x14
|
|
#define PMU_HPPA2CODEC_2_0V 0x10
|
|
#define PMU_HPPA2CODEC_1_95V 0xE
|
|
#define PMU_HPPA2CODEC_1_9V 0xC
|
|
#define PMU_HPPA2CODEC_1_8V 0x8
|
|
#define PMU_HPPA2CODEC_1_7V 0x4
|
|
#define PMU_HPPA2CODEC_1_6V 0x0
|
|
|
|
#define PMU_USB_3_4V 0xA
|
|
#define PMU_USB_3_3V 0x9
|
|
#define PMU_USB_3_2V 0x8
|
|
#define PMU_USB_3_1V 0x7
|
|
#define PMU_USB_3_0V 0x6
|
|
#define PMU_USB_2_9V 0x5
|
|
#define PMU_USB_2_8V 0x4
|
|
#define PMU_USB_2_7V 0x3
|
|
#define PMU_USB_2_6V 0x2
|
|
|
|
#define PMU_VHPPA_2_0V 0x8
|
|
#define PMU_VHPPA_1_9V 0x7
|
|
#define PMU_VHPPA_1_8V 0x6
|
|
#define PMU_VHPPA_1_7V 0x5
|
|
#define PMU_VHPPA_1_6V 0x4
|
|
#define PMU_VHPPA_1_5V 0x3
|
|
|
|
#define PMU_DCDC_HPPA_2_1V 0xF0
|
|
#define PMU_DCDC_HPPA_2_0V 0xE0
|
|
#define PMU_DCDC_HPPA_1_95V 0xD8
|
|
#define PMU_DCDC_HPPA_1_9V 0xD0
|
|
#define PMU_DCDC_HPPA_1_8V 0xC0
|
|
#define PMU_DCDC_HPPA_1_7V 0xB0
|
|
#define PMU_DCDC_HPPA_1_6V 0xA0
|
|
#define PMU_DCDC_HPPA_1_5V 0x90
|
|
#define PMU_DCDC_HPPA_1_4V 0x80
|
|
#define PMU_DCDC_HPPA_1_3V 0x70
|
|
#define PMU_DCDC_HPPA_1_2V 0x60
|
|
|
|
#define PMU_VMIC_3_3V 0x14
|
|
#define PMU_VMIC_3_2V 0x13
|
|
#define PMU_VMIC_3_1V 0x12
|
|
#define PMU_VMIC_3_0V 0x11
|
|
#define PMU_VMIC_2_9V 0x10
|
|
#define PMU_VMIC_2_8V 0xF
|
|
#define PMU_VMIC_2_7V 0xF
|
|
#define PMU_VMIC_2_6V 0xE
|
|
#define PMU_VMIC_2_5V 0xD
|
|
#define PMU_VMIC_2_4V 0xC
|
|
#define PMU_VMIC_2_3V 0xB
|
|
#define PMU_VMIC_2_2V 0xA
|
|
#define PMU_VMIC_2_1V 0x9
|
|
#define PMU_VMIC_2_0V 0x8
|
|
#define PMU_VMIC_1_9V 0x7
|
|
#define PMU_VMIC_1_8V 0x6
|
|
#define PMU_VMIC_1_7V 0x5
|
|
#define PMU_VMIC_1_6V 0x4
|
|
|
|
#define PMU_VMIC_RES_3_3V 0xF
|
|
#define PMU_VMIC_RES_2_8V 0xA
|
|
#define PMU_VMIC_RES_2_2V 0x4
|
|
|
|
// 00 PMU_REG_METAL_ID
|
|
#define PMU_METAL_ID_SHIFT 0
|
|
#define PMU_METAL_ID_MASK (0xF << PMU_METAL_ID_SHIFT)
|
|
#define PMU_METAL_ID(n) (((n)&0xF) << PMU_METAL_ID_SHIFT)
|
|
|
|
// 02 PMU_REG_POWER_KEY_CFG
|
|
#define REG_PU_VBAT_DIV (1 << 15)
|
|
#define PU_LPO_DR (1 << 14)
|
|
#define PU_LPO_REG (1 << 13)
|
|
#define POWERKEY_WAKEUP_OSC_EN (1 << 12)
|
|
#define RTC_POWER_ON_EN (1 << 11)
|
|
#define PU_ALL_REG (1 << 10)
|
|
#define CLK_32K_SEL_SHIFT 8
|
|
#define CLK_32K_SEL_MASK (0x3 << CLK_32K_SEL_SHIFT)
|
|
#define CLK_32K_SEL(n) BITFIELD_VAL(CLK_32K_SEL, n)
|
|
#define DEEPSLEEP_MODE_DIGI_DR (1 << 7)
|
|
#define DEEPSLEEP_MODE_DIGI_REG (1 << 6)
|
|
#define REG_VCORE_SSTIME_MODE_SHIFT 4
|
|
#define REG_VCORE_SSTIME_MODE_MASK (0x3 << REG_VCORE_SSTIME_MODE_SHIFT)
|
|
#define REG_VCORE_SSTIME_MODE(n) BITFIELD_VAL(REG_VCORE_SSTIME_MODE, n)
|
|
#define REG_LDO_SS_BIAS_EN_DR (1 << 3)
|
|
#define REG_LDO_SS_BIAS_EN (1 << 2)
|
|
#define REG_LP_EN_VHPPA_DSLEEP (1 << 1)
|
|
#define REG_LP_EN_VHPPA_NORMAL (1 << 0)
|
|
|
|
// 03 PMU_REG_BIAS_CFG
|
|
#define REG_VSENSE_SEL_VMEM (1 << 15)
|
|
#define PU_LP_BIAS_LDO_DSLEEP (1 << 14)
|
|
#define PU_LP_BIAS_LDO_DR (1 << 13)
|
|
#define PU_LP_BIAS_LDO_REG (1 << 12)
|
|
#define PU_BIAS_LDO_DR (1 << 11)
|
|
#define PU_BIAS_LDO_REG (1 << 10)
|
|
#define BG_VBG_SEL_DR (1 << 9)
|
|
#define BG_VBG_SEL_REG (1 << 8)
|
|
#define BG_CONSTANT_GM_BIAS_DR (1 << 7)
|
|
#define BG_CONSTANT_GM_BIAS_REG (1 << 6)
|
|
#define BG_CORE_EN_DR (1 << 5)
|
|
#define BG_CORE_EN_REG (1 << 4)
|
|
#define REG_PU_LDO_VANA_DR (1 << 3)
|
|
#define REG_PU_LDO_VANA (1 << 2)
|
|
#define BG_NOTCH_EN_DR (1 << 1)
|
|
#define BG_NOTCH_EN_REG (1 << 0)
|
|
|
|
#define REG_PU_LDO_VANA_REG REG_PU_LDO_VANA
|
|
|
|
// 05 PMU_REG_CHARGER_CFG
|
|
#define REG_PU_LDO_VRTC_RF_DSLEEP (1 << 15)
|
|
#define REG_PU_LDO_VRTC_RF_DR (1 << 14)
|
|
#define REG_PU_LDO_VRTC_RF_REG (1 << 13)
|
|
#define REG_CHARGE_OUT_INTR_MSK (1 << 12)
|
|
#define REG_CHARGE_IN_INTR_MSK (1 << 11)
|
|
#define REG_AC_ON_OUT_EN (1 << 10)
|
|
#define REG_AC_ON_IN_EN (1 << 9)
|
|
#define REG_CHARGE_INTR_EN (1 << 8)
|
|
#define REG_AC_ON_DB_VALUE_SHIFT 0
|
|
#define REG_AC_ON_DB_VALUE_MASK (0xFF << REG_AC_ON_DB_VALUE_SHIFT)
|
|
#define REG_AC_ON_DB_VALUE(n) BITFIELD_VAL(REG_AC_ON_DB_VALUE, n)
|
|
|
|
// 07 PMU_REG_ANA_CFG
|
|
#define REG_LIGHT_LOAD_VANA_BUCK_LDO (1 << 15)
|
|
#define REG_PULLDOWN_VANA_LDO (1 << 14)
|
|
#define LP_EN_VANA_LDO_DSLEEP (1 << 13)
|
|
#define LP_EN_VANA_LDO_DR (1 << 12)
|
|
#define LP_EN_VANA_LDO_REG (1 << 11)
|
|
#define REG_PU_LDO_VANA_DSLEEP (1 << 10)
|
|
#define LDO_ANA_VBIT_DSLEEP_SHIFT 5
|
|
#define LDO_ANA_VBIT_DSLEEP_MASK (0x1F << LDO_ANA_VBIT_DSLEEP_SHIFT)
|
|
#define LDO_ANA_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_ANA_VBIT_DSLEEP, n)
|
|
#define LDO_ANA_VBIT_NORMAL_SHIFT 0
|
|
#define LDO_ANA_VBIT_NORMAL_MASK (0x1F << LDO_ANA_VBIT_NORMAL_SHIFT)
|
|
#define LDO_ANA_VBIT_NORMAL(n) BITFIELD_VAL(LDO_ANA_VBIT_NORMAL, n)
|
|
|
|
#define LDO_VANA_VBIT_DSLEEP_SHIFT LDO_ANA_VBIT_DSLEEP_SHIFT
|
|
#define LDO_VANA_VBIT_DSLEEP_MASK LDO_ANA_VBIT_DSLEEP_MASK
|
|
#define LDO_VANA_VBIT_NORMAL_SHIFT LDO_ANA_VBIT_NORMAL_SHIFT
|
|
#define LDO_VANA_VBIT_NORMAL_MASK LDO_ANA_VBIT_NORMAL_MASK
|
|
|
|
// 08 PMU_REG_DIG_CFG
|
|
#define REG_DCDC_CLK_SE_EN (1 << 15)
|
|
#define LP_EN_VCORE_LDO_DSLEEP (1 << 14)
|
|
#define LP_EN_VCORE_LDO_DR (1 << 13)
|
|
#define LP_EN_VCORE_LDO_REG (1 << 12)
|
|
#define LDO_DIG_VBIT_DSLEEP_SHIFT 6
|
|
#define LDO_DIG_VBIT_DSLEEP_MASK (0x3F << LDO_DIG_VBIT_DSLEEP_SHIFT)
|
|
#define LDO_DIG_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_DIG_VBIT_DSLEEP, n)
|
|
#define LDO_DIG_VBIT_NORMAL_SHIFT 0
|
|
#define LDO_DIG_VBIT_NORMAL_MASK (0x3F << LDO_DIG_VBIT_NORMAL_SHIFT)
|
|
#define LDO_DIG_VBIT_NORMAL(n) BITFIELD_VAL(LDO_DIG_VBIT_NORMAL, n)
|
|
|
|
#define LDO_VCORE_VBIT_DSLEEP_SHIFT LDO_DIG_VBIT_DSLEEP_SHIFT
|
|
#define LDO_VCORE_VBIT_DSLEEP_MASK LDO_DIG_VBIT_DSLEEP_MASK
|
|
#define LDO_VCORE_VBIT_NORMAL_SHIFT LDO_DIG_VBIT_NORMAL_SHIFT
|
|
#define LDO_VCORE_VBIT_NORMAL_MASK LDO_DIG_VBIT_NORMAL_MASK
|
|
|
|
// Real bit is in REG_101 -- but we never change the default value
|
|
#define REG_PU_LDO_VCORE_DSLEEP 0
|
|
|
|
// 09 PMU_REG_IO_CFG
|
|
#define LP_EN_VIO_LDO_DSLEEP (1 << 15)
|
|
#define LP_EN_VIO_LDO_DR (1 << 14)
|
|
#define LP_EN_VIO_LDO_REG (1 << 13)
|
|
#define REG_PU_LDO_VIO_DSLEEP (1 << 12)
|
|
#define REG_PU_LDO_VIO_DR (1 << 11)
|
|
#define REG_PU_LDO_VIO (1 << 10)
|
|
#define LDO_VIO_VBIT_NORMAL_SHIFT 5
|
|
#define LDO_VIO_VBIT_NORMAL_MASK (0x1F << LDO_VIO_VBIT_NORMAL_SHIFT)
|
|
#define LDO_VIO_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VIO_VBIT_NORMAL, n)
|
|
#define LDO_VIO_VBIT_DSLEEP_SHIFT 0
|
|
#define LDO_VIO_VBIT_DSLEEP_MASK (0x1F << LDO_VIO_VBIT_DSLEEP_SHIFT)
|
|
#define LDO_VIO_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VIO_VBIT_DSLEEP, n)
|
|
|
|
#define REG_PU_LDO_VIO_REG REG_PU_LDO_VIO
|
|
|
|
// 0A PMU_REG_MEM_CFG
|
|
#define LP_EN_VMEM_LDO_DSLEEP (1 << 15)
|
|
#define LP_EN_VMEM_LDO_DR (1 << 14)
|
|
#define LP_EN_VMEM_LDO_REG (1 << 13)
|
|
#define REG_PU_LDO_VMEM_DSLEEP (1 << 12)
|
|
#define REG_PU_LDO_VMEM_DR (1 << 11)
|
|
#define REG_PU_LDO_VMEM_REG (1 << 10)
|
|
#define LDO_VMEM_VBIT_NORMAL_SHIFT 5
|
|
#define LDO_VMEM_VBIT_NORMAL_MASK (0x1F << LDO_VMEM_VBIT_NORMAL_SHIFT)
|
|
#define LDO_VMEM_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VMEM_VBIT_NORMAL, n)
|
|
#define LDO_VMEM_VBIT_DSLEEP_SHIFT 0
|
|
#define LDO_VMEM_VBIT_DSLEEP_MASK (0x1F << LDO_VMEM_VBIT_DSLEEP_SHIFT)
|
|
#define LDO_VMEM_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VMEM_VBIT_DSLEEP, n)
|
|
|
|
// 0B PMU_REG_GP_CFG
|
|
#define LP_EN_VGP_LDO_DSLEEP (1 << 15)
|
|
#define LP_EN_VGP_LDO_DR (1 << 14)
|
|
#define LP_EN_VGP_LDO_REG (1 << 13)
|
|
#define REG_PU_LDO_VGP_DSLEEP (1 << 12)
|
|
#define REG_PU_LDO_VGP_DR (1 << 11)
|
|
#define REG_PU_LDO_VGP_REG (1 << 10)
|
|
#define LDO_VGP_VBIT_NORMAL_SHIFT 5
|
|
#define LDO_VGP_VBIT_NORMAL_MASK (0x1F << LDO_VGP_VBIT_NORMAL_SHIFT)
|
|
#define LDO_VGP_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VGP_VBIT_NORMAL, n)
|
|
#define LDO_VGP_VBIT_DSLEEP_SHIFT 0
|
|
#define LDO_VGP_VBIT_DSLEEP_MASK (0x1F << LDO_VGP_VBIT_DSLEEP_SHIFT)
|
|
#define LDO_VGP_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VGP_VBIT_DSLEEP, n)
|
|
|
|
// 0C PMU_REG_USB_CFG
|
|
#define REG_LDO_VANA_LV_MODE (1 << 15)
|
|
#define REG_PULLDOWN_VUSB (1 << 14)
|
|
#define LP_EN_VUSB_LDO_DSLEEP (1 << 13)
|
|
#define LP_EN_VUSB_LDO_DR (1 << 12)
|
|
#define LP_EN_VUSB_LDO_REG (1 << 11)
|
|
#define PU_LDO_VUSB_DSLEEP (1 << 10)
|
|
#define PU_LDO_VUSB_DR (1 << 9)
|
|
#define PU_LDO_VUSB_REG (1 << 8)
|
|
#define LDO_VUSB_VBIT_NORMAL_SHIFT 4
|
|
#define LDO_VUSB_VBIT_NORMAL_MASK (0xF << LDO_VUSB_VBIT_NORMAL_SHIFT)
|
|
#define LDO_VUSB_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VUSB_VBIT_NORMAL, n)
|
|
#define LDO_VUSB_VBIT_DSLEEP_SHIFT 0
|
|
#define LDO_VUSB_VBIT_DSLEEP_MASK (0xF << LDO_VUSB_VBIT_DSLEEP_SHIFT)
|
|
#define LDO_VUSB_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VUSB_VBIT_DSLEEP, n)
|
|
|
|
#define REG_PU_LDO_VUSB_DSLEEP PU_LDO_VUSB_DSLEEP
|
|
#define REG_PU_LDO_VUSB_DR PU_LDO_VUSB_DR
|
|
#define REG_PU_LDO_VUSB_REG PU_LDO_VUSB_REG
|
|
|
|
// 0D PMU_REG_BAT2DIG_CFG
|
|
#define LP_EN_VBAT2VCORE_LDO_DR (1 << 15)
|
|
#define LP_EN_VBAT2VCORE_LDO (1 << 14)
|
|
#define REG_PU_VBAT2VCORE_LDO_DR (1 << 13)
|
|
#define REG_PU_VBAT2VCORE_LDO (1 << 12)
|
|
#define LDO_VBAT2VCORE_VBIT_DSLEEP_SHIFT 6
|
|
#define LDO_VBAT2VCORE_VBIT_DSLEEP_MASK \
|
|
(0x3F << LDO_VBAT2VCORE_VBIT_DSLEEP_SHIFT)
|
|
#define LDO_VBAT2VCORE_VBIT_DSLEEP(n) \
|
|
BITFIELD_VAL(LDO_VBAT2VCORE_VBIT_DSLEEP, n)
|
|
#define LDO_VBAT2VCORE_VBIT_NORMAL_SHIFT 0
|
|
#define LDO_VBAT2VCORE_VBIT_NORMAL_MASK \
|
|
(0x3F << LDO_VBAT2VCORE_VBIT_NORMAL_SHIFT)
|
|
#define LDO_VBAT2VCORE_VBIT_NORMAL(n) \
|
|
BITFIELD_VAL(LDO_VBAT2VCORE_VBIT_NORMAL, n)
|
|
|
|
#define LP_EN_VBAT2VCORE_LDO_REG LP_EN_VBAT2VCORE_LDO
|
|
#define REG_PU_LDO_VBAT2VCORE_DR REG_PU_VBAT2VCORE_LDO_DR
|
|
#define REG_PU_LDO_VBAT2VCORE_REG REG_PU_VBAT2VCORE_LDO
|
|
// Real bit is in REG_101 -- but we never change the default value
|
|
#define REG_PU_LDO_VBAT2VCORE_DSLEEP 0
|
|
|
|
// 0E PMU_REG_HPPA_LDO_EN
|
|
#define REG_PULL_DOWN_VHPPA (1 << 15)
|
|
#define REG_PU_LDO_VHPPA_DSLEEP (1 << 14)
|
|
#define REG_PU_LDO_VHPPA_EN (1 << 13)
|
|
#define REG_RES_SEL_VHPPA_SHIFT 8
|
|
#define REG_RES_SEL_VHPPA_MASK (0x1F << REG_RES_SEL_VHPPA_SHIFT)
|
|
#define REG_RES_SEL_VHPPA(n) BITFIELD_VAL(REG_RES_SEL_VHPPA, n)
|
|
#define REG_LP_BIAS_SEL_LDO_SHIFT 6
|
|
#define REG_LP_BIAS_SEL_LDO_MASK (0x3 << REG_LP_BIAS_SEL_LDO_SHIFT)
|
|
#define REG_LP_BIAS_SEL_LDO(n) BITFIELD_VAL(REG_LP_BIAS_SEL_LDO, n)
|
|
#define REG_BYPASS_VBUCK2ANA (1 << 5)
|
|
#define REG_PULLDOWN_VBUCK2ANA (1 << 4)
|
|
#define REG_PULLDOWN_VIO (1 << 3)
|
|
#define REG_PULLDOWN_VMEM (1 << 2)
|
|
#define REG_PULLDOWN_VCORE (1 << 1)
|
|
#define REG_PULLDOWN_VHPPA2VCODEC (1 << 0)
|
|
|
|
// 0F PMU_REG_HPPA2CODEC_CFG
|
|
#define PU_LDO_VCODEC_DSLEEP (1 << 15)
|
|
#define REG_BYPASS_VCORE (1 << 14)
|
|
#define REG_PU_LDO_VHPPA2VCODEC_DR (1 << 13)
|
|
#define REG_PU_LDO_VHPPA2VCODEC (1 << 12)
|
|
#define LP_EN_VHPPA2VCODEC_LDO_DR (1 << 11)
|
|
#define LP_EN_VHPPA2VCODEC_LDO (1 << 10)
|
|
#define LDO_VHPPA2VCODEC_VBIT_DSLEEP_SHIFT 5
|
|
#define LDO_VHPPA2VCODEC_VBIT_DSLEEP_MASK \
|
|
(0x1F << LDO_VHPPA2VCODEC_VBIT_DSLEEP_SHIFT)
|
|
#define LDO_VHPPA2VCODEC_VBIT_DSLEEP(n) \
|
|
BITFIELD_VAL(LDO_VHPPA2VCODEC_VBIT_DSLEEP, n)
|
|
#define LDO_VHPPA2VCODEC_VBIT_NORMAL_SHIFT 0
|
|
#define LDO_VHPPA2VCODEC_VBIT_NORMAL_MASK \
|
|
(0x1F << LDO_VHPPA2VCODEC_VBIT_NORMAL_SHIFT)
|
|
#define LDO_VHPPA2VCODEC_VBIT_NORMAL(n) \
|
|
BITFIELD_VAL(LDO_VHPPA2VCODEC_VBIT_NORMAL, n)
|
|
|
|
#define REG_PU_LDO_VHPPA2VCODEC_REG REG_PU_LDO_VHPPA2VCODEC
|
|
#define LP_EN_VHPPA2VCODEC_LDO_REG LP_EN_VHPPA2VCODEC_LDO
|
|
#define REG_PU_LDO_VCODEC_DSLEEP PU_LDO_VCODEC_DSLEEP
|
|
|
|
// 10 PMU_REG_CODEC_CFG
|
|
#define PU_LDO_VCODEC_DR (1 << 15)
|
|
#define PU_LDO_VCODEC_REG (1 << 14)
|
|
#define LP_EN_VCODEC_LDO_DSLEEP (1 << 13)
|
|
#define LP_EN_VCODEC_LDO_DR (1 << 12)
|
|
#define LP_EN_VCODEC_LDO_REG (1 << 11)
|
|
#define REG_PULLDOWN_VCODEC (1 << 10)
|
|
#define LDO_VCODEC_VBIT_NORMAL_SHIFT 5
|
|
#define LDO_VCODEC_VBIT_NORMAL_MASK (0x1F << LDO_VCODEC_VBIT_NORMAL_SHIFT)
|
|
#define LDO_VCODEC_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VCODEC_VBIT_NORMAL, n)
|
|
#define LDO_VCODEC_VBIT_DSLEEP_SHIFT 0
|
|
#define LDO_VCODEC_VBIT_DSLEEP_MASK (0x1F << LDO_VCODEC_VBIT_DSLEEP_SHIFT)
|
|
#define LDO_VCODEC_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VCODEC_VBIT_DSLEEP, n)
|
|
|
|
#define REG_PU_LDO_VCODEC_DR PU_LDO_VCODEC_DR
|
|
#define REG_PU_LDO_VCODEC_REG PU_LDO_VCODEC_REG
|
|
|
|
// 15 PMU_REG_DCDC_DIG_EN
|
|
#define REG_UVLO_SEL_SHIFT 14
|
|
#define REG_UVLO_SEL_MASK (0x3 << REG_UVLO_SEL_SHIFT)
|
|
#define REG_UVLO_SEL(n) BITFIELD_VAL(REG_UVLO_SEL, n)
|
|
#define REG_PU_LDO_DIG_DR (1 << 13)
|
|
#define REG_PU_LDO_DIG_REG (1 << 12)
|
|
#define REG_DCDC1_PFM_SEL_DSLEEP (1 << 11)
|
|
#define REG_DCDC1_PFM_SEL_NORMAL (1 << 10)
|
|
#define REG_DCDC1_ULP_MODE_DSLEEP (1 << 9)
|
|
#define REG_DCDC1_ULP_MODE_NORMAL (1 << 8)
|
|
#define REG_DCDC1_BURST_MODE_SEL_DSLEEP (1 << 7)
|
|
#define REG_DCDC1_BURST_MODE_SEL_NORMAL (1 << 6)
|
|
#define REG_DCDC1_VREF_SEL_DSLEEP_SHIFT 4
|
|
#define REG_DCDC1_VREF_SEL_DSLEEP_MASK (0x3 << REG_DCDC1_VREF_SEL_DSLEEP_SHIFT)
|
|
#define REG_DCDC1_VREF_SEL_DSLEEP(n) BITFIELD_VAL(REG_DCDC1_VREF_SEL_DSLEEP, n)
|
|
#define REG_DCDC1_VREF_SEL_NORMAL_SHIFT 2
|
|
#define REG_DCDC1_VREF_SEL_NORMAL_MASK (0x3 << REG_DCDC1_VREF_SEL_NORMAL_SHIFT)
|
|
#define REG_DCDC1_VREF_SEL_NORMAL(n) BITFIELD_VAL(REG_DCDC1_VREF_SEL_NORMAL, n)
|
|
#define REG_PU_DCDC1_DR (1 << 1)
|
|
#define REG_PU_DCDC1 (1 << 0)
|
|
|
|
#define REG_PU_LDO_VCORE_DR REG_PU_LDO_DIG_DR
|
|
#define REG_PU_LDO_VCORE_REG REG_PU_LDO_DIG_REG
|
|
|
|
// 19 PMU_REG_DCDC_ANA_CFG_19
|
|
#define DCDC2_IX2_ERR (1 << 15)
|
|
#define DCDC2_IX2_IRCOMP (1 << 14)
|
|
#define DCDC2_LP_ERR (1 << 13)
|
|
#define DCDC2_LP_VCOMP (1 << 12)
|
|
#define DCDC2_PULLDOWN_EN (1 << 11)
|
|
#define DCDC2_SLOPE_DOUBLE (1 << 10)
|
|
#define DCDC2_SLOPE_EN_BURST (1 << 9)
|
|
#define DCDC2_SOFT_START_EN (1 << 8)
|
|
#define DCDC2_SS_TIME_SEL (1 << 7)
|
|
#define DCDC2_SYNC_DISABLE (1 << 6)
|
|
#define DCDC2_TEST_MODE_EN (1 << 5)
|
|
#define DCDC2_ZCD_CAL_BIT_SHIFT 1
|
|
#define DCDC2_ZCD_CAL_BIT_MASK (0xF << DCDC2_ZCD_CAL_BIT_SHIFT)
|
|
#define DCDC2_ZCD_CAL_BIT(n) BITFIELD_VAL(DCDC2_ZCD_CAL_BIT, n)
|
|
#define DCDC2_REG_BYPASS (1 << 0)
|
|
|
|
// 1D PMU_REG_DCDC_HPPA_CFG_1D
|
|
#define DCDC3_IX2_ERR (1 << 15)
|
|
#define DCDC3_IX2_IRCOMP (1 << 14)
|
|
#define DCDC3_LP_ERR (1 << 13)
|
|
#define DCDC3_LP_VCOMP (1 << 12)
|
|
#define DCDC3_PULLDOWN_EN (1 << 11)
|
|
#define DCDC3_SLOPE_DOUBLE (1 << 10)
|
|
#define DCDC3_SLOPE_EN_BURST (1 << 9)
|
|
#define DCDC3_SOFT_START_EN (1 << 8)
|
|
#define DCDC3_SS_TIME_SEL (1 << 7)
|
|
#define DCDC3_SYNC_DISABLE (1 << 6)
|
|
#define DCDC3_TEST_MODE_EN (1 << 5)
|
|
#define DCDC3_ZCD_CAL_BIT_SHIFT 1
|
|
#define DCDC3_ZCD_CAL_BIT_MASK (0xF << DCDC3_ZCD_CAL_BIT_SHIFT)
|
|
#define DCDC3_ZCD_CAL_BIT(n) BITFIELD_VAL(DCDC3_ZCD_CAL_BIT, n)
|
|
#define DCDC3_REG_BYPASS (1 << 0)
|
|
|
|
// 21 PMU_REG_PWR_SEL
|
|
#define REG_PMU_VSEL1_SHIFT 13
|
|
#define REG_PMU_VSEL1_MASK (0x7 << REG_PMU_VSEL1_SHIFT)
|
|
#define REG_PMU_VSEL1(n) BITFIELD_VAL(REG_PMU_VSEL1, n)
|
|
#define REG_POWER_SEL_CNT_SHIFT 8
|
|
#define REG_POWER_SEL_CNT_MASK (0x1F << REG_POWER_SEL_CNT_SHIFT)
|
|
#define REG_POWER_SEL_CNT(n) BITFIELD_VAL(REG_POWER_SEL_CNT, n)
|
|
#define REG_PWR_SEL_DR (1 << 7)
|
|
#define REG_PWR_SEL (1 << 6)
|
|
#define CLK_BG_EN (1 << 5)
|
|
#define CLK_BG_DIV_VALUE_SHIFT 0
|
|
#define CLK_BG_DIV_VALUE_MASK (0x1F << CLK_BG_DIV_VALUE_SHIFT)
|
|
#define CLK_BG_DIV_VALUE(n) BITFIELD_VAL(CLK_BG_DIV_VALUE, n)
|
|
|
|
// 26 PMU_REG_INT_MASK
|
|
#define RESET_EN_VCORE_LOW (1 << 15)
|
|
#define RTC_INT1_MSK (1 << 14)
|
|
#define RTC_INT0_MSK (1 << 13)
|
|
#define KEY_ERR1_INTR_MSK (1 << 12)
|
|
#define KEY_ERR0_INTR_MSK (1 << 11)
|
|
#define KEY_PRESS_INTR_MSK (1 << 10)
|
|
#define KEY_RELEASE_INTR_MSK (1 << 9)
|
|
#define SAMPLE_DONE_INTR_MSK (1 << 8)
|
|
#define CHAN_DATA_INTR_MSK_SHIFT 0
|
|
#define CHAN_DATA_INTR_MSK_MASK (0xFF << CHAN_DATA_INTR_MSK_SHIFT)
|
|
#define CHAN_DATA_INTR_MSK(n) BITFIELD_VAL(CHAN_DATA_INTR_MSK, n)
|
|
|
|
// 27 PMU_REG_INT_EN
|
|
#define REG_BG_SLEEP_MSK (1 << 15)
|
|
#define RTC_INT_EN_1 (1 << 14)
|
|
#define RTC_INT_EN_0 (1 << 13)
|
|
#define KEY_ERR1_INTR_EN (1 << 12)
|
|
#define KEY_ERR0_INTR_EN (1 << 11)
|
|
#define KEY_PRESS_INTR_EN (1 << 10)
|
|
#define KEY_RELEASE_INTR_EN (1 << 9)
|
|
#define SAMPLE_DONE_INTR_EN (1 << 8)
|
|
#define CHAN_DATA_INTR_EN_SHIFT 0
|
|
#define CHAN_DATA_INTR_EN_MASK (0xFF << CHAN_DATA_INTR_EN_SHIFT)
|
|
#define CHAN_DATA_INTR_EN(n) BITFIELD_VAL(CHAN_DATA_INTR_EN, n)
|
|
|
|
// 36 PMU_REG_DCDC_DIG_CFG_36
|
|
#define DCDC1_IX2_ERR (1 << 15)
|
|
#define DCDC1_IX2_IRCOMP (1 << 14)
|
|
#define DCDC1_LP_ERR (1 << 13)
|
|
#define DCDC1_LP_VCOMP (1 << 12)
|
|
#define DCDC1_PULLDOWN_EN (1 << 11)
|
|
#define DCDC1_SLOPE_DOUBLE (1 << 10)
|
|
#define DCDC1_SLOPE_EN_BURST (1 << 9)
|
|
#define DCDC1_SOFT_START_EN (1 << 8)
|
|
#define DCDC1_SS_TIME_SEL (1 << 7)
|
|
#define DCDC1_SYNC_DISABLE (1 << 6)
|
|
#define DCDC1_TEST_MODE_EN (1 << 5)
|
|
#define DCDC1_ZCD_CAL_BIT_SHIFT 1
|
|
#define DCDC1_ZCD_CAL_BIT_MASK (0xF << DCDC1_ZCD_CAL_BIT_SHIFT)
|
|
#define DCDC1_ZCD_CAL_BIT(n) BITFIELD_VAL(DCDC1_ZCD_CAL_BIT, n)
|
|
#define DCDC1_REG_BYPASS (1 << 0)
|
|
|
|
// 38 PMU_REG_MIC_BIAS_E
|
|
#define REG_MIC_BIASE_CHANSEL_SHIFT 14
|
|
#define REG_MIC_BIASE_CHANSEL_MASK (0x3 << REG_MIC_BIASE_CHANSEL_SHIFT)
|
|
#define REG_MIC_BIASE_CHANSEL(n) BITFIELD_VAL(REG_MIC_BIASE_CHANSEL, n)
|
|
#define REG_MIC_BIASE_EN (1 << 13)
|
|
#define REG_MIC_BIASE_ENLPF (1 << 12)
|
|
#define REG_MIC_BIASE_LPFSEL_SHIFT 10
|
|
#define REG_MIC_BIASE_LPFSEL_MASK (0x3 << REG_MIC_BIASE_LPFSEL_SHIFT)
|
|
#define REG_MIC_BIASE_LPFSEL(n) BITFIELD_VAL(REG_MIC_BIASE_LPFSEL, n)
|
|
#define REG_MIC_BIASE_VSEL_SHIFT 5
|
|
#define REG_MIC_BIASE_VSEL_MASK (0x1F << REG_MIC_BIASE_VSEL_SHIFT)
|
|
#define REG_MIC_BIASE_VSEL(n) BITFIELD_VAL(REG_MIC_BIASE_VSEL, n)
|
|
#define REG_MIC_LDOE_RES_SHIFT 1
|
|
#define REG_MIC_LDOE_RES_MASK (0xF << REG_MIC_LDOE_RES_SHIFT)
|
|
#define REG_MIC_LDOE_RES(n) BITFIELD_VAL(REG_MIC_LDOE_RES, n)
|
|
#define REG_MIC_LDOE_LOOPCTRL (1 << 0)
|
|
|
|
// 39 PMU_REG_MIC_LDO_EN
|
|
#define REG_LED_IO1_AIO_EN (1 << 15)
|
|
#define REG_LED_IO2_AIO_EN (1 << 14)
|
|
#define REG_LED_IO1_RX_EN (1 << 13)
|
|
#define REG_LED_IO2_RX_EN (1 << 12)
|
|
#define REG_MIC_LDOA_EN (1 << 11)
|
|
#define REG_MIC_LDOB_EN (1 << 10)
|
|
#define REG_MIC_LDOC_EN (1 << 9)
|
|
#define REG_MIC_LDOD_EN (1 << 8)
|
|
#define REG_MIC_LDOE_EN (1 << 7)
|
|
#define DCDC1_OFFSET_CURRENT_EN (1 << 6)
|
|
#define DCDC2_OFFSET_CURRENT_EN (1 << 5)
|
|
#define DCDC3_OFFSET_CURRENT_EN (1 << 4)
|
|
#define DCDC4_OFFSET_CURRENT_EN (1 << 3)
|
|
|
|
// 3A PMU_REG_LED_CFG
|
|
#define REG_LED_IO1_IBIT_SHIFT 14
|
|
#define REG_LED_IO1_IBIT_MASK (0x3 << REG_LED_IO1_IBIT_SHIFT)
|
|
#define REG_LED_IO1_IBIT(n) BITFIELD_VAL(REG_LED_IO1_IBIT, n)
|
|
#define REG_LED_IO1_OENB (1 << 13)
|
|
#define REG_LED_IO1_PDEN (1 << 12)
|
|
#define REG_LED_IO1_PU (1 << 11)
|
|
#define REG_LED_IO1_PUEN (1 << 10)
|
|
#define REG_LED_IO1_SEL_SHIFT 8
|
|
#define REG_LED_IO1_SEL_MASK (0x3 << REG_LED_IO1_SEL_SHIFT)
|
|
#define REG_LED_IO1_SEL(n) BITFIELD_VAL(REG_LED_IO1_SEL, n)
|
|
#define REG_LED_IO2_IBIT_SHIFT 6
|
|
#define REG_LED_IO2_IBIT_MASK (0x3 << REG_LED_IO2_IBIT_SHIFT)
|
|
#define REG_LED_IO2_IBIT(n) BITFIELD_VAL(REG_LED_IO2_IBIT, n)
|
|
#define REG_LED_IO2_OENB (1 << 5)
|
|
#define REG_LED_IO2_PDEN (1 << 4)
|
|
#define REG_LED_IO2_PU (1 << 3)
|
|
#define REG_LED_IO2_PUEN (1 << 2)
|
|
#define REG_LED_IO2_SEL_SHIFT 0
|
|
#define REG_LED_IO2_SEL_MASK (0x3 << REG_LED_IO2_SEL_SHIFT)
|
|
#define REG_LED_IO2_SEL(n) BITFIELD_VAL(REG_LED_IO2_SEL, n)
|
|
|
|
// 3B PMU_REG_MIC_BIAS_A
|
|
#define REG_MIC_BIASA_CHANSEL_SHIFT 14
|
|
#define REG_MIC_BIASA_CHANSEL_MASK (0x3 << REG_MIC_BIASA_CHANSEL_SHIFT)
|
|
#define REG_MIC_BIASA_CHANSEL(n) BITFIELD_VAL(REG_MIC_BIASA_CHANSEL, n)
|
|
#define REG_MIC_BIASA_EN (1 << 13)
|
|
#define REG_MIC_BIASA_ENLPF (1 << 12)
|
|
#define REG_MIC_BIASA_LPFSEL_SHIFT 10
|
|
#define REG_MIC_BIASA_LPFSEL_MASK (0x3 << REG_MIC_BIASA_LPFSEL_SHIFT)
|
|
#define REG_MIC_BIASA_LPFSEL(n) BITFIELD_VAL(REG_MIC_BIASA_LPFSEL, n)
|
|
#define REG_MIC_BIASA_VSEL_SHIFT 5
|
|
#define REG_MIC_BIASA_VSEL_MASK (0x1F << REG_MIC_BIASA_VSEL_SHIFT)
|
|
#define REG_MIC_BIASA_VSEL(n) BITFIELD_VAL(REG_MIC_BIASA_VSEL, n)
|
|
#define REG_MIC_LDOA_RES_SHIFT 1
|
|
#define REG_MIC_LDOA_RES_MASK (0xF << REG_MIC_LDOA_RES_SHIFT)
|
|
#define REG_MIC_LDOA_RES(n) BITFIELD_VAL(REG_MIC_LDOA_RES, n)
|
|
#define REG_MIC_LDOA_LOOPCTRL (1 << 0)
|
|
|
|
// 3C PMU_REG_MIC_BIAS_B
|
|
#define REG_MIC_BIASB_CHANSEL_SHIFT 14
|
|
#define REG_MIC_BIASB_CHANSEL_MASK (0x3 << REG_MIC_BIASB_CHANSEL_SHIFT)
|
|
#define REG_MIC_BIASB_CHANSEL(n) BITFIELD_VAL(REG_MIC_BIASB_CHANSEL, n)
|
|
#define REG_MIC_BIASB_EN (1 << 13)
|
|
#define REG_MIC_BIASB_ENLPF (1 << 12)
|
|
#define REG_MIC_BIASB_LPFSEL_SHIFT 10
|
|
#define REG_MIC_BIASB_LPFSEL_MASK (0x3 << REG_MIC_BIASB_LPFSEL_SHIFT)
|
|
#define REG_MIC_BIASB_LPFSEL(n) BITFIELD_VAL(REG_MIC_BIASB_LPFSEL, n)
|
|
#define REG_MIC_BIASB_VSEL_SHIFT 5
|
|
#define REG_MIC_BIASB_VSEL_MASK (0x1F << REG_MIC_BIASB_VSEL_SHIFT)
|
|
#define REG_MIC_BIASB_VSEL(n) BITFIELD_VAL(REG_MIC_BIASB_VSEL, n)
|
|
#define REG_MIC_LDOB_RES_SHIFT 1
|
|
#define REG_MIC_LDOB_RES_MASK (0xF << REG_MIC_LDOB_RES_SHIFT)
|
|
#define REG_MIC_LDOB_RES(n) BITFIELD_VAL(REG_MIC_LDOB_RES, n)
|
|
#define REG_MIC_LDOB_LOOPCTRL (1 << 0)
|
|
|
|
// 3D PMU_REG_MIC_BIAS_C
|
|
#define REG_MIC_BIASC_CHANSEL_SHIFT 14
|
|
#define REG_MIC_BIASC_CHANSEL_MASK (0x3 << REG_MIC_BIASC_CHANSEL_SHIFT)
|
|
#define REG_MIC_BIASC_CHANSEL(n) BITFIELD_VAL(REG_MIC_BIASC_CHANSEL, n)
|
|
#define REG_MIC_BIASC_EN (1 << 13)
|
|
#define REG_MIC_BIASC_ENLPF (1 << 12)
|
|
#define REG_MIC_BIASC_LPFSEL_SHIFT 10
|
|
#define REG_MIC_BIASC_LPFSEL_MASK (0x3 << REG_MIC_BIASC_LPFSEL_SHIFT)
|
|
#define REG_MIC_BIASC_LPFSEL(n) BITFIELD_VAL(REG_MIC_BIASC_LPFSEL, n)
|
|
#define REG_MIC_BIASC_VSEL_SHIFT 5
|
|
#define REG_MIC_BIASC_VSEL_MASK (0x1F << REG_MIC_BIASC_VSEL_SHIFT)
|
|
#define REG_MIC_BIASC_VSEL(n) BITFIELD_VAL(REG_MIC_BIASC_VSEL, n)
|
|
#define REG_MIC_LDOC_RES_SHIFT 1
|
|
#define REG_MIC_LDOC_RES_MASK (0xF << REG_MIC_LDOC_RES_SHIFT)
|
|
#define REG_MIC_LDOC_RES(n) BITFIELD_VAL(REG_MIC_LDOC_RES, n)
|
|
#define REG_MIC_LDOC_LOOPCTRL (1 << 0)
|
|
|
|
// 3E PMU_REG_MIC_BIAS_D
|
|
#define REG_MIC_BIASD_CHANSEL_SHIFT 14
|
|
#define REG_MIC_BIASD_CHANSEL_MASK (0x3 << REG_MIC_BIASD_CHANSEL_SHIFT)
|
|
#define REG_MIC_BIASD_CHANSEL(n) BITFIELD_VAL(REG_MIC_BIASD_CHANSEL, n)
|
|
#define REG_MIC_BIASD_EN (1 << 13)
|
|
#define REG_MIC_BIASD_ENLPF (1 << 12)
|
|
#define REG_MIC_BIASD_LPFSEL_SHIFT 10
|
|
#define REG_MIC_BIASD_LPFSEL_MASK (0x3 << REG_MIC_BIASD_LPFSEL_SHIFT)
|
|
#define REG_MIC_BIASD_LPFSEL(n) BITFIELD_VAL(REG_MIC_BIASD_LPFSEL, n)
|
|
#define REG_MIC_BIASD_VSEL_SHIFT 5
|
|
#define REG_MIC_BIASD_VSEL_MASK (0x1F << REG_MIC_BIASD_VSEL_SHIFT)
|
|
#define REG_MIC_BIASD_VSEL(n) BITFIELD_VAL(REG_MIC_BIASD_VSEL, n)
|
|
#define REG_MIC_LDOD_RES_SHIFT 1
|
|
#define REG_MIC_LDOD_RES_MASK (0xF << REG_MIC_LDOD_RES_SHIFT)
|
|
#define REG_MIC_LDOD_RES(n) BITFIELD_VAL(REG_MIC_LDOD_RES, n)
|
|
#define REG_MIC_LDOD_LOOPCTRL (1 << 0)
|
|
|
|
// 3F PMU_REG_EFUSE_CTRL
|
|
#define TSMC_EFUSE_A_SHIFT 0
|
|
#define TSMC_EFUSE_A_MASK (0x3F << TSMC_EFUSE_A_SHIFT)
|
|
#define TSMC_EFUSE_A(n) BITFIELD_VAL(TSMC_EFUSE_A, n)
|
|
#define TSMC_EFUSE_CLK_EN (1 << 8)
|
|
#define TSMC_EFUSE_NR (1 << 9)
|
|
#define TSMC_EFUSE_MR (1 << 10)
|
|
#define MANUAL_MODE (1 << 11)
|
|
#define TSMC_EFUSE_PGENB (1 << 12)
|
|
#define REG_MARGIN_READ (1 << 13)
|
|
|
|
// 40 PMU_REG_EFUSE_SEL
|
|
#define TSMC_EFUSE_STROBE_TRIG (1 << 0)
|
|
#define TSMC_EFUSE_STROBE_WIDTH_SHIFT 1
|
|
#define TSMC_EFUSE_STROBE_WIDTH_MASK (0xFF << TSMC_EFUSE_STROBE_WIDTH_SHIFT)
|
|
#define TSMC_EFUSE_STROBE_WIDTH(n) BITFIELD_VAL(TSMC_EFUSE_STROBE_WIDTH, n)
|
|
#define REG_READ_STROBE_WIDTH_SHIFT 9
|
|
#define REG_READ_STROBE_WIDTH_MASK (0xF << REG_READ_STROBE_WIDTH_SHIFT)
|
|
#define REG_READ_STROBE_WIDTH(n) BITFIELD_VAL(REG_READ_STROBE_WIDTH, n)
|
|
#define EFUSE_SEL_SHIFT 13
|
|
#define EFUSE_SEL_MASK (0x7 << EFUSE_SEL_SHIFT)
|
|
#define EFUSE_SEL(n) BITFIELD_VAL(EFUSE_SEL, n)
|
|
|
|
// 41 PMU_REG_DCDC1_OFFSET
|
|
#define DCDC1_OFFSET_BIT_SHIFT 8
|
|
#define DCDC1_OFFSET_BIT_MASK (0xFF << DCDC1_OFFSET_BIT_SHIFT)
|
|
#define DCDC1_OFFSET_BIT(n) BITFIELD_VAL(DCDC1_OFFSET_BIT, n)
|
|
#define DCDC2_OFFSET_BIT_SHIFT 0
|
|
#define DCDC2_OFFSET_BIT_MASK (0xFF << DCDC2_OFFSET_BIT_SHIFT)
|
|
#define DCDC2_OFFSET_BIT(n) BITFIELD_VAL(DCDC2_OFFSET_BIT, n)
|
|
|
|
// 43 PMU_REG_BUCK2ANA_CFG
|
|
#define REG_PU_VBUCK2ANA_LDO_DR (1 << 15)
|
|
#define REG_PU_VBUCK2ANA_LDO (1 << 14)
|
|
#define LP_EN_VBUCK2ANA_LDO_DR (1 << 13)
|
|
#define LP_EN_VBUCK2ANA_LDO (1 << 12)
|
|
#define LDO_VBUCK2ANA_VBIT_DSLEEP_SHIFT 6
|
|
#define LDO_VBUCK2ANA_VBIT_DSLEEP_MASK (0x3F << LDO_VBUCK2ANA_VBIT_DSLEEP_SHIFT)
|
|
#define LDO_VBUCK2ANA_VBIT_DSLEEP(n) BITFIELD_VAL(LDO_VBUCK2ANA_VBIT_DSLEEP, n)
|
|
#define LDO_VBUCK2ANA_VBIT_NORMAL_SHIFT 0
|
|
#define LDO_VBUCK2ANA_VBIT_NORMAL_MASK (0x3F << LDO_VBUCK2ANA_VBIT_NORMAL_SHIFT)
|
|
#define LDO_VBUCK2ANA_VBIT_NORMAL(n) BITFIELD_VAL(LDO_VBUCK2ANA_VBIT_NORMAL, n)
|
|
|
|
#define REG_PU_LDO_VBUCK2ANA_DR REG_PU_VBUCK2ANA_LDO_DR
|
|
#define REG_PU_LDO_VBUCK2ANA_REG REG_PU_VBUCK2ANA_LDO
|
|
#define LP_EN_VBUCK2ANA_LDO_REG LP_EN_VBUCK2ANA_LDO
|
|
// No pu dsleep cfg
|
|
#define REG_PU_LDO_VBUCK2ANA_DSLEEP 0
|
|
|
|
// 44 PMU_REG_SLEEP_CFG
|
|
#define PMIC_TMODE_1300_SHIFT 0
|
|
#define PMIC_TMODE_1300_MASK (0x7 << PMIC_TMODE_1300_SHIFT)
|
|
#define PMIC_TMODE_1300(n) BITFIELD_VAL(PMIC_TMODE_1300, n)
|
|
#define POWERON_PRESS_EN (1 << 3)
|
|
#define POWERON_RELEASE_EN (1 << 4)
|
|
#define SLEEP_ALLOW (1 << 5)
|
|
#define REG_VHPPA2VCODEC_SLP_ON (1 << 6)
|
|
|
|
#define REG_PU_LDO_VHPPA2VCODEC_DSLEEP REG_VHPPA2VCODEC_SLP_ON
|
|
|
|
// 46 PMU_REG_DCDC_DIG_VOLT
|
|
#define REG_DCDC1_VBIT_DSLEEP_SHIFT 8
|
|
#define REG_DCDC1_VBIT_DSLEEP_MASK (0xFF << REG_DCDC1_VBIT_DSLEEP_SHIFT)
|
|
#define REG_DCDC1_VBIT_DSLEEP(n) BITFIELD_VAL(REG_DCDC1_VBIT_DSLEEP, n)
|
|
#define REG_DCDC1_VBIT_NORMAL_SHIFT 0
|
|
#define REG_DCDC1_VBIT_NORMAL_MASK (0xFF << REG_DCDC1_VBIT_NORMAL_SHIFT)
|
|
#define REG_DCDC1_VBIT_NORMAL(n) BITFIELD_VAL(REG_DCDC1_VBIT_NORMAL, n)
|
|
#define MAX_DCDC1_VBIT_VAL \
|
|
(REG_DCDC1_VBIT_NORMAL_MASK >> REG_DCDC1_VBIT_NORMAL_SHIFT)
|
|
|
|
// 47 PMU_REG_DCDC_ANA_VOLT
|
|
#define REG_DCDC2_VBIT_DSLEEP_SHIFT 8
|
|
#define REG_DCDC2_VBIT_DSLEEP_MASK (0xFF << REG_DCDC2_VBIT_DSLEEP_SHIFT)
|
|
#define REG_DCDC2_VBIT_DSLEEP(n) BITFIELD_VAL(REG_DCDC2_VBIT_DSLEEP, n)
|
|
#define REG_DCDC2_VBIT_NORMAL_SHIFT 0
|
|
#define REG_DCDC2_VBIT_NORMAL_MASK (0xFF << REG_DCDC2_VBIT_NORMAL_SHIFT)
|
|
#define REG_DCDC2_VBIT_NORMAL(n) BITFIELD_VAL(REG_DCDC2_VBIT_NORMAL, n)
|
|
#define MAX_DCDC2_VBIT_VAL \
|
|
(REG_DCDC2_VBIT_NORMAL_MASK >> REG_DCDC2_VBIT_NORMAL_SHIFT)
|
|
|
|
// 48 PMU_REG_DCDC_HPPA_VOLT
|
|
#define REG_DCDC3_VBIT_DSLEEP_SHIFT 8
|
|
#define REG_DCDC3_VBIT_DSLEEP_MASK (0xFF << REG_DCDC3_VBIT_DSLEEP_SHIFT)
|
|
#define REG_DCDC3_VBIT_DSLEEP(n) BITFIELD_VAL(REG_DCDC3_VBIT_DSLEEP, n)
|
|
#define REG_DCDC3_VBIT_NORMAL_SHIFT 0
|
|
#define REG_DCDC3_VBIT_NORMAL_MASK (0xFF << REG_DCDC3_VBIT_NORMAL_SHIFT)
|
|
#define REG_DCDC3_VBIT_NORMAL(n) BITFIELD_VAL(REG_DCDC3_VBIT_NORMAL, n)
|
|
#define MAX_DCDC3_VBIT_VAL \
|
|
(REG_DCDC3_VBIT_NORMAL_MASK >> REG_DCDC3_VBIT_NORMAL_SHIFT)
|
|
|
|
// 49 PMU_REG_DCDC4_VOLT
|
|
#define REG_DCDC4_VBIT_DSLEEP_SHIFT 8
|
|
#define REG_DCDC4_VBIT_DSLEEP_MASK (0xFF << REG_DCDC4_VBIT_DSLEEP_SHIFT)
|
|
#define REG_DCDC4_VBIT_DSLEEP(n) BITFIELD_VAL(REG_DCDC4_VBIT_DSLEEP, n)
|
|
#define REG_DCDC4_VBIT_NORMAL_SHIFT 0
|
|
#define REG_DCDC4_VBIT_NORMAL_MASK (0xFF << REG_DCDC4_VBIT_NORMAL_SHIFT)
|
|
#define REG_DCDC4_VBIT_NORMAL(n) BITFIELD_VAL(REG_DCDC4_VBIT_NORMAL, n)
|
|
|
|
// 4A PMU_REG_DCDC_ANA_EN
|
|
#define REG_DCDC2_PFM_SEL_DSLEEP (1 << 11)
|
|
#define REG_DCDC2_PFM_SEL_NORMAL (1 << 10)
|
|
#define REG_DCDC2_ULP_MODE_DSLEEP (1 << 9)
|
|
#define REG_DCDC2_ULP_MODE_NORMAL (1 << 8)
|
|
#define REG_DCDC2_BURST_MODE_SEL_DSLEEP (1 << 7)
|
|
#define REG_DCDC2_BURST_MODE_SEL_NORMAL (1 << 6)
|
|
#define REG_DCDC2_VREF_SEL_DSLEEP_SHIFT 4
|
|
#define REG_DCDC2_VREF_SEL_DSLEEP_MASK (0x3 << REG_DCDC2_VREF_SEL_DSLEEP_SHIFT)
|
|
#define REG_DCDC2_VREF_SEL_DSLEEP(n) BITFIELD_VAL(REG_DCDC2_VREF_SEL_DSLEEP, n)
|
|
#define REG_DCDC2_VREF_SEL_NORMAL_SHIFT 2
|
|
#define REG_DCDC2_VREF_SEL_NORMAL_MASK (0x3 << REG_DCDC2_VREF_SEL_NORMAL_SHIFT)
|
|
#define REG_DCDC2_VREF_SEL_NORMAL(n) BITFIELD_VAL(REG_DCDC2_VREF_SEL_NORMAL, n)
|
|
#define REG_PU_DCDC2_DR (1 << 1)
|
|
#define REG_PU_DCDC2 (1 << 0)
|
|
|
|
// 4B PMU_REG_DCDC_HPPA_EN
|
|
#define REG_DCDC3_PFM_SEL_DSLEEP (1 << 11)
|
|
#define REG_DCDC3_PFM_SEL_NORMAL (1 << 10)
|
|
#define REG_DCDC3_ULP_MODE_DSLEEP (1 << 9)
|
|
#define REG_DCDC3_ULP_MODE_NORMAL (1 << 8)
|
|
#define REG_DCDC3_BURST_MODE_SEL_DSLEEP (1 << 7)
|
|
#define REG_DCDC3_BURST_MODE_SEL_NORMAL (1 << 6)
|
|
#define REG_DCDC3_VREF_SEL_DSLEEP_SHIFT 4
|
|
#define REG_DCDC3_VREF_SEL_DSLEEP_MASK (0x3 << REG_DCDC3_VREF_SEL_DSLEEP_SHIFT)
|
|
#define REG_DCDC3_VREF_SEL_DSLEEP(n) BITFIELD_VAL(REG_DCDC3_VREF_SEL_DSLEEP, n)
|
|
#define REG_DCDC3_VREF_SEL_NORMAL_SHIFT 2
|
|
#define REG_DCDC3_VREF_SEL_NORMAL_MASK (0x3 << REG_DCDC3_VREF_SEL_NORMAL_SHIFT)
|
|
#define REG_DCDC3_VREF_SEL_NORMAL(n) BITFIELD_VAL(REG_DCDC3_VREF_SEL_NORMAL, n)
|
|
#define REG_PU_DCDC3_DR (1 << 1)
|
|
#define REG_PU_DCDC3 (1 << 0)
|
|
|
|
// 4C PMU_REG_DCDC4_EN
|
|
#define REG_DCDC4_PFM_SEL_DSLEEP (1 << 11)
|
|
#define REG_DCDC4_PFM_SEL_NORMAL (1 << 10)
|
|
#define REG_DCDC4_ULP_MODE_DSLEEP (1 << 9)
|
|
#define REG_DCDC4_ULP_MODE_NORMAL (1 << 8)
|
|
#define REG_DCDC4_BURST_MODE_SEL_DSLEEP (1 << 7)
|
|
#define REG_DCDC4_BURST_MODE_SEL_NORMAL (1 << 6)
|
|
#define REG_DCDC4_VREF_SEL_DSLEEP_SHIFT 4
|
|
#define REG_DCDC4_VREF_SEL_DSLEEP_MASK (0x3 << REG_DCDC4_VREF_SEL_DSLEEP_SHIFT)
|
|
#define REG_DCDC4_VREF_SEL_DSLEEP(n) BITFIELD_VAL(REG_DCDC4_VREF_SEL_DSLEEP, n)
|
|
#define REG_DCDC4_VREF_SEL_NORMAL_SHIFT 2
|
|
#define REG_DCDC4_VREF_SEL_NORMAL_MASK (0x3 << REG_DCDC4_VREF_SEL_NORMAL_SHIFT)
|
|
#define REG_DCDC4_VREF_SEL_NORMAL(n) BITFIELD_VAL(REG_DCDC4_VREF_SEL_NORMAL, n)
|
|
#define REG_PU_DCDC4_DR (1 << 1)
|
|
#define REG_PU_DCDC4 (1 << 0)
|
|
|
|
// 4F PMU_REG_POWER_OFF
|
|
#define SOFT_POWER_OFF (1 << 0)
|
|
#define HARDWARE_POWER_OFF_EN (1 << 1)
|
|
#define AC_ON_EN (1 << 2)
|
|
#define RC_CAL_READY (1 << 3)
|
|
#define KEY_START (1 << 4)
|
|
#define GPADC_START (1 << 5)
|
|
#define EFUSE_READ_DONE (1 << 6)
|
|
#define EFUSE_READ_BUSY (1 << 7)
|
|
#define VBAT_OVP (1 << 8)
|
|
#define VCORE_LOW (1 << 9)
|
|
#define REG_LED_IO1_DATA_IN (1 << 10)
|
|
#define REG_LED_IO2_DATA_IN (1 << 11)
|
|
#define RD_EFUSE_REG (1 << 12)
|
|
#define REG_WDT_LOAD (1 << 13)
|
|
|
|
#define EFUSE_READ_TRIG_SHIFT (12)
|
|
#define EFUSE_READ_TRIG_MASK (0xF << EFUSE_READ_TRIG_SHIFT)
|
|
#define EFUSE_READ_TRIG(n) BITFIELD_VAL(EFUSE_READ_TRIG, n)
|
|
#define EFUSE_READ_TRIG_WORD (0xA)
|
|
|
|
// 52 PMU_REG_INT_STATUS
|
|
#define RD_RES1 (1 << 15)
|
|
#define RTC_INT_1 (1 << 14)
|
|
#define RTC_INT_0 (1 << 13)
|
|
#define KEY_ERR1_INTR (1 << 12)
|
|
#define KEY_ERR0_INTR (1 << 11)
|
|
#define KEY_PRESS_INTR (1 << 10)
|
|
#define KEY_RELEASE_INTR (1 << 9)
|
|
#define SAMPLE_PERIOD_DONE_INTR (1 << 8)
|
|
#define CHAN_DATA_VALID_INTR_SHIFT 0
|
|
#define CHAN_DATA_VALID_INTR_MASK (0xFF << CHAN_DATA_VALID_INTR_SHIFT)
|
|
#define CHAN_DATA_VALID_INTR(n) BITFIELD_VAL(CHAN_DATA_VALID_INTR, n)
|
|
|
|
// 53 PMU_REG_INT_MSKED_STATUS
|
|
// 51 PMU_REG_INT_CLR
|
|
#define PMIC_CODEC_PWM (1 << 15)
|
|
#define RTC_INT1_MSKED (1 << 14)
|
|
#define RTC_INT0_MSKED (1 << 13)
|
|
#define KEY_ERR1_INTR_MSKED (1 << 12)
|
|
#define KEY_ERR0_INTR_MSKED (1 << 11)
|
|
#define KEY_PRESS_INTR_MSKED (1 << 10)
|
|
#define KEY_RELEASE_INTR_MSKED (1 << 9)
|
|
#define SAMPLE_DONE_INTR_MSKED (1 << 8)
|
|
#define CHAN_DATA_INTR_MSKED_SHIFT 0
|
|
#define CHAN_DATA_INTR_MSKED_MASK (0xFF << CHAN_DATA_INTR_MSKED_SHIFT)
|
|
#define CHAN_DATA_INTR_MSKED(n) BITFIELD_VAL(CHAN_DATA_INTR_MSKED, n)
|
|
|
|
// 5E PMU_REG_CHARGER_STATUS
|
|
#define DIG_PU_VHPPA (1 << 15)
|
|
#define DIG_PU_VRTC_RF (1 << 14)
|
|
#define DIG_PU_VCODEC (1 << 13)
|
|
#define DIG_PU_VUSB (1 << 12)
|
|
#define POWER_ON_RELEASE (1 << 11)
|
|
#define POWER_ON_PRESS (1 << 10)
|
|
#define POWER_ON (1 << 9)
|
|
#define DEEPSLEEP_MODE (1 << 8)
|
|
// #define PMU_LDO_ON (1 << 7)
|
|
#define PU_OSC_OUT (1 << 6)
|
|
#define UVLO_LV (1 << 5)
|
|
#define AC_ON_DET_OUT_MASKED (1 << 4)
|
|
#define AC_ON_DET_IN_MASKED (1 << 3)
|
|
#define AC_ON (1 << 2)
|
|
#define AC_ON_DET_OUT (1 << 1)
|
|
#define AC_ON_DET_IN (1 << 0)
|
|
|
|
// 77 PMU_REG_ANA_77
|
|
#define REG_AUDPLL_DIVN_SHIFT 0
|
|
#define REG_AUDPLL_DIVN_MASK (0x1F << REG_AUDPLL_DIVN_SHIFT)
|
|
#define REG_AUDPLL_DIVN(n) BITFIELD_VAL(REG_AUDPLL_DIVN, n)
|
|
#define REG_AUDPLL_DIVN_RST (1 << 5)
|
|
#define REG_AUDPLL_DIV_DR (1 << 6)
|
|
#define REG_AUDPLL_EN_CLKA (1 << 7)
|
|
#define REG_AUDPLL_EN_CLKD (1 << 8)
|
|
#define REG_AUDPLL_FORCE_LK (1 << 9)
|
|
#define REG_AUDPLL_LK_ERR23 (1 << 10)
|
|
#define REG_AUDPLL_LK_LONG (1 << 11)
|
|
#define REG_AUDPLL_LK_RSTB (1 << 12)
|
|
#define REG_AUDPLL_LK_WIN_SHIFT 13
|
|
#define REG_AUDPLL_LK_WIN_MASK (0x7 << REG_AUDPLL_LK_WIN_SHIFT)
|
|
#define REG_AUDPLL_LK_WIN(n) BITFIELD_VAL(REG_AUDPLL_LK_WIN, n)
|
|
|
|
// 101 PMU_REG_DCDC_RAMP_EN
|
|
#define REG_MIC_BIASA_IX2 (1 << 15)
|
|
#define REG_MIC_BIASB_IX2 (1 << 14)
|
|
#define REG_MIC_BIASC_IX2 (1 << 13)
|
|
#define REG_MIC_BIASD_IX2 (1 << 12)
|
|
#define REG_MIC_BIASE_IX2 (1 << 11)
|
|
#define REG_PULLDOWN_VGP (1 << 10)
|
|
#define REG_PU_LDO_DIG_DSLEEP (1 << 9)
|
|
#define LDO_VHPPA2VCODEC_BYPASS (1 << 8)
|
|
#define LDO_VGP_LV_MODE (1 << 7)
|
|
#define IPTAT_EN (1 << 6)
|
|
#define REG_PU_AVDD25_ANA (1 << 5)
|
|
#define REG_DCDC1_RAMP_EN (1 << 4)
|
|
#define REG_DCDC2_RAMP_EN (1 << 3)
|
|
#define REG_DCDC3_RAMP_EN (1 << 2)
|
|
#define REG_PU_VMEM_DELAY_DR (1 << 1)
|
|
#define REG_PU_VMEM_DELAY (1 << 0)
|
|
|
|
// 107 PMU_REG_SUBCNT_DATA
|
|
#define SUBCNT_DATA2_SHIFT 8
|
|
#define SUBCNT_DATA2_MASK (0xFF << SUBCNT_DATA2_SHIFT)
|
|
#define SUBCNT_DATA2(n) BITFIELD_VAL(SUBCNT_DATA2, n)
|
|
#define SUBCNT_DATA3_SHIFT 0
|
|
#define SUBCNT_DATA3_MASK (0xFF << SUBCNT_DATA3_SHIFT)
|
|
#define SUBCNT_DATA3(n) BITFIELD_VAL(SUBCNT_DATA3, n)
|
|
|
|
// 108 PMU_REG_PWM_BR_EN
|
|
#define TG_SUBCNT_D2_ST_SHIFT 9
|
|
#define TG_SUBCNT_D2_ST_MASK (0x7F << TG_SUBCNT_D2_ST_SHIFT)
|
|
#define TG_SUBCNT_D2_ST(n) BITFIELD_VAL(TG_SUBCNT_D2_ST, n)
|
|
#define REG_PWM2_BR_EN (1 << 8)
|
|
#define TG_SUBCNT_D3_ST_SHIFT 1
|
|
#define TG_SUBCNT_D3_ST_MASK (0x7F << TG_SUBCNT_D3_ST_SHIFT)
|
|
#define TG_SUBCNT_D3_ST(n) BITFIELD_VAL(TG_SUBCNT_D3_ST, n)
|
|
#define REG_PWM3_BR_EN (1 << 0)
|
|
|
|
// 109 PMU_REG_PWM_EN
|
|
#define REG_LED0_OUT (1 << 15)
|
|
#define REG_LED1_OUT (1 << 14)
|
|
#define PWM_SELECT_EN_SHIFT 12
|
|
#define PWM_SELECT_EN_MASK (0x3 << PWM_SELECT_EN_SHIFT)
|
|
#define PWM_SELECT_EN(n) BITFIELD_VAL(PWM_SELECT_EN, n)
|
|
#define PWM_SELECT_INV_SHIFT 10
|
|
#define PWM_SELECT_INV_MASK (0x3 << PWM_SELECT_INV_SHIFT)
|
|
#define PWM_SELECT_INV(n) BITFIELD_VAL(PWM_SELECT_INV, n)
|
|
#define REG_CLK_PWM_DIV_SHIFT 5
|
|
#define REG_CLK_PWM_DIV_MASK (0x1F << REG_CLK_PWM_DIV_SHIFT)
|
|
#define REG_CLK_PWM_DIV(n) BITFIELD_VAL(REG_CLK_PWM_DIV, n)
|
|
|
|
// 10B PMU_REG_WDT_TIMER
|
|
#define REG_WDT_TIMER_SHIFT 0
|
|
#define REG_WDT_TIMER_MASK (0xFFFF << REG_WDT_TIMER_SHIFT)
|
|
#define REG_WDT_TIMER(n) BITFIELD_VAL(REG_WDT_TIMER, n)
|
|
|
|
// 10C PMU_REG_WDT_CFG
|
|
#define REG_HW_RESET_TIME_SHIFT 10
|
|
#define REG_HW_RESET_TIME_MASK (0x3F << REG_HW_RESET_TIME_SHIFT)
|
|
#define REG_HW_RESET_TIME(n) BITFIELD_VAL(REG_HW_RESET_TIME, n)
|
|
#define REG_HW_RESET_EN (1 << 9)
|
|
#define REG_WDT_RESET_EN (1 << 8)
|
|
#define REG_WDT_EN (1 << 7)
|
|
#define BG_R_TEMP_SHIFT 4
|
|
#define BG_R_TEMP_MASK (0x7 << BG_R_TEMP_SHIFT)
|
|
#define BG_R_TEMP(n) BITFIELD_VAL(BG_R_TEMP, n)
|
|
#define BG_TRIM_VBG_SHIFT 1
|
|
#define BG_TRIM_VBG_MASK (0x7 << BG_TRIM_VBG_SHIFT)
|
|
#define BG_TRIM_VBG(n) BITFIELD_VAL(BG_TRIM_VBG, n)
|
|
#define SAR_PU_OVP (1 << 0)
|
|
|
|
// 80 PMU_REG_RF_80
|
|
#define RF_80_PAGE_IDX (1 << 15)
|
|
#define RF_80_S_DONE_SHIFT 4
|
|
#define RF_80_S_DONE_MASK (0x7FF << RF_80_S_DONE_SHIFT)
|
|
#define RF_80_S_DONE(n) BITFIELD_VAL(RF_80_S_DONE, n)
|
|
#define RF_80_REVID_SHIFT 0
|
|
#define RF_80_REVID_MASK (0xF << RF_80_REVID_SHIFT)
|
|
#define RF_80_REVID(n) BITFIELD_VAL(RF_80_REVID, n)
|
|
|
|
// BD PMU_REG_RF_BD
|
|
#define REG_BBPLL_FREQ_34_32_SHIFT 0
|
|
#define REG_BBPLL_FREQ_34_32_MASK (0x7 << REG_BBPLL_FREQ_34_32_SHIFT)
|
|
#define REG_BBPLL_FREQ_34_32(n) BITFIELD_VAL(REG_BBPLL_FREQ_34_32, n)
|
|
#define REG_BBPLL_FREQ_EN (1 << 3)
|
|
|
|
enum PMU_REG_T {
|
|
PMU_REG_METAL_ID = 0x00,
|
|
PMU_REG_POWER_KEY_CFG = 0x02,
|
|
PMU_REG_BIAS_CFG = 0x03,
|
|
PMU_REG_CHARGER_CFG = 0x05,
|
|
PMU_REG_ANA_CFG = 0x07,
|
|
PMU_REG_DIG_CFG = 0x08,
|
|
PMU_REG_IO_CFG = 0x09,
|
|
PMU_REG_MEM_CFG = 0x0A,
|
|
PMU_REG_GP_CFG = 0x0B,
|
|
PMU_REG_USB_CFG = 0x0C,
|
|
PMU_REG_BAT2DIG_CFG = 0x0D,
|
|
PMU_REG_HPPA_LDO_EN = 0x0E,
|
|
PMU_REG_HPPA2CODEC_CFG = 0x0F,
|
|
PMU_REG_CODEC_CFG = 0x10,
|
|
PMU_REG_DCDC_DIG_EN = 0x15,
|
|
PMU_REG_DCDC_ANA_CFG_16 = 0x16,
|
|
PMU_REG_DCDC_ANA_CFG_17 = 0x17,
|
|
PMU_REG_DCDC_ANA_CFG_18 = 0x18,
|
|
PMU_REG_DCDC_ANA_CFG_19 = 0x19,
|
|
PMU_REG_DCDC_HPPA_CFG_1A = 0x1A,
|
|
PMU_REG_DCDC_HPPA_CFG_1B = 0x1B,
|
|
PMU_REG_DCDC_HPPA_CFG_1C = 0x1C,
|
|
PMU_REG_DCDC_HPPA_CFG_1D = 0x1D,
|
|
PMU_REG_PWR_SEL = 0x21,
|
|
PMU_REG_INT_MASK = 0x26,
|
|
PMU_REG_INT_EN = 0x27,
|
|
PMU_REG_RTC_LOAD_LOW = 0x2D,
|
|
PMU_REG_RTC_LOAD_HIGH = 0x2E,
|
|
PMU_REG_RTC_MATCH1_LOW = 0x31,
|
|
PMU_REG_RTC_MATCH1_HIGH = 0x32,
|
|
PMU_REG_DCDC_DIG_CFG_33 = 0x33,
|
|
PMU_REG_DCDC_DIG_CFG_34 = 0x34,
|
|
PMU_REG_DCDC_DIG_CFG_35 = 0x35,
|
|
PMU_REG_DCDC_DIG_CFG_36 = 0x36,
|
|
PMU_REG_RTC_DIV_1HZ = 0x37,
|
|
PMU_REG_MIC_BIAS_E = 0x38,
|
|
PMU_REG_MIC_LDO_EN = 0x39,
|
|
PMU_REG_LED_CFG = 0x3A,
|
|
PMU_REG_MIC_BIAS_A = 0x3B,
|
|
PMU_REG_MIC_BIAS_B = 0x3C,
|
|
PMU_REG_MIC_BIAS_C = 0x3D,
|
|
PMU_REG_MIC_BIAS_D = 0x3E,
|
|
PMU_REG_EFUSE_CTRL = 0x3F,
|
|
PMU_REG_EFUSE_SEL = 0x40,
|
|
PMU_REG_DCDC1_OFFSET = 0x41,
|
|
PMU_REG_BUCK2ANA_CFG = 0x43,
|
|
PMU_REG_SLEEP_CFG = 0x44,
|
|
PMU_REG_DCDC_DIG_VOLT = 0x46,
|
|
PMU_REG_DCDC_ANA_VOLT = 0x47,
|
|
PMU_REG_DCDC_HPPA_VOLT = 0x48,
|
|
PMU_REG_DCDC4_VOLT = 0x49,
|
|
PMU_REG_DCDC_ANA_EN = 0x4A,
|
|
PMU_REG_DCDC_HPPA_EN = 0x4B,
|
|
PMU_REG_POWER_OFF = 0x4F,
|
|
PMU_REG_INT_CLR = 0x51,
|
|
PMU_REG_INT_STATUS = 0x52,
|
|
PMU_REG_INT_MSKED_STATUS = 0x53,
|
|
PMU_REG_RTC_VAL_LOW = 0x54,
|
|
PMU_REG_RTC_VAL_HIGH = 0x55,
|
|
PMU_REG_CHARGER_STATUS = 0x5E,
|
|
|
|
PMU_REG_DCDC_RAMP_EN = 0x101,
|
|
|
|
PMU_REG_PWM2_TOGGLE = 0x103,
|
|
PMU_REG_PWM3_TOGGLE = 0x104,
|
|
PMU_REG_PWM2_ST1 = 0x105,
|
|
PMU_REG_PWM3_ST1 = 0x106,
|
|
PMU_REG_SUBCNT_DATA = 0x107,
|
|
PMU_REG_PWM_BR_EN = 0x108,
|
|
PMU_REG_PWM_EN = 0x109,
|
|
|
|
PMU_REG_WDT_TIMER = 0x10B,
|
|
PMU_REG_WDT_CFG = 0x10C,
|
|
|
|
PMU_REG_MODULE_START = PMU_REG_ANA_CFG,
|
|
PMU_REG_EFUSE_VAL_START = 0x148,
|
|
|
|
PMU_REG_ANA_60 = 0x60,
|
|
PMU_REG_ANA_77 = 0x77,
|
|
|
|
PMU_REG_RF_80 = 0x80,
|
|
PMU_REG_RF_B5 = 0xB5,
|
|
PMU_REG_RF_BB = 0xBB,
|
|
PMU_REG_RF_BC = 0xBC,
|
|
PMU_REG_RF_BD = 0xBD,
|
|
};
|
|
|
|
enum PMU_VCORE_REQ_T {
|
|
PMU_VCORE_FLASH_WRITE_ENABLED = (1 << 0),
|
|
PMU_VCORE_FLASH_FREQ_HIGH = (1 << 1),
|
|
PMU_VCORE_PSRAM_FREQ_HIGH = (1 << 2),
|
|
PMU_VCORE_USB_HS_ENABLED = (1 << 3),
|
|
PMU_VCORE_RS_FREQ_HIGH = (1 << 4),
|
|
PMU_VCORE_SYS_FREQ_MEDIUM = (1 << 5),
|
|
PMU_VCORE_SYS_FREQ_HIGH = (1 << 6),
|
|
};
|
|
|
|
enum PMU_VUSB_REQ_T {
|
|
PMU_VUSB_REQ_INIT = (1 << 0),
|
|
PMU_VUSB_REQ_USB = (1 << 1),
|
|
PMU_VUSB_REQ_LBRT = (1 << 2),
|
|
};
|
|
|
|
union BOOT_SETTINGS_T {
|
|
struct {
|
|
unsigned short usb_dld_dis : 1;
|
|
unsigned short uart_dld_en : 1;
|
|
unsigned short uart_trace_en : 1;
|
|
unsigned short pll_dis : 1;
|
|
unsigned short uart_baud_div2 : 1;
|
|
unsigned short sec_freq_div2 : 1;
|
|
unsigned short crystal_freq : 2;
|
|
unsigned short reserved : 4;
|
|
unsigned short chksum : 4;
|
|
};
|
|
unsigned short reg;
|
|
};
|
|
|
|
enum PMU_MODUAL_T {
|
|
PMU_ANA,
|
|
PMU_DIG,
|
|
PMU_IO,
|
|
PMU_MEM,
|
|
PMU_GP,
|
|
PMU_USB,
|
|
PMU_BAT2DIG,
|
|
PMU_HPPA2CODEC,
|
|
PMU_CODEC,
|
|
PMU_BUCK2ANA,
|
|
};
|
|
|
|
struct PMU_MODULE_CFG_T {
|
|
unsigned short pu_dr;
|
|
unsigned short pu;
|
|
unsigned short lp_en_dr;
|
|
unsigned short lp_en;
|
|
unsigned short pu_dsleep;
|
|
unsigned short vbit_dsleep_mask;
|
|
unsigned short vbit_dsleep_shift;
|
|
unsigned short vbit_normal_mask;
|
|
unsigned short vbit_normal_shift;
|
|
};
|
|
|
|
#define PMU_MOD_CFG_VAL(m) \
|
|
{ \
|
|
REG_PU_LDO_V##m##_DR, REG_PU_LDO_V##m##_REG, LP_EN_V##m##_LDO_DR, \
|
|
LP_EN_V##m##_LDO_REG, REG_PU_LDO_V##m##_DSLEEP, \
|
|
LDO_V##m##_VBIT_DSLEEP_MASK, LDO_V##m##_VBIT_DSLEEP_SHIFT, \
|
|
LDO_V##m##_VBIT_NORMAL_MASK, LDO_V##m##_VBIT_NORMAL_SHIFT \
|
|
}
|
|
|
|
static const struct PMU_MODULE_CFG_T pmu_module_cfg[] = {
|
|
PMU_MOD_CFG_VAL(ANA), PMU_MOD_CFG_VAL(CORE),
|
|
PMU_MOD_CFG_VAL(IO), PMU_MOD_CFG_VAL(MEM),
|
|
PMU_MOD_CFG_VAL(GP), PMU_MOD_CFG_VAL(USB),
|
|
PMU_MOD_CFG_VAL(BAT2VCORE), PMU_MOD_CFG_VAL(HPPA2VCODEC),
|
|
PMU_MOD_CFG_VAL(CODEC), PMU_MOD_CFG_VAL(BUCK2ANA),
|
|
};
|
|
|
|
#ifdef ANC_PROD_TEST
|
|
#define OPT_TYPE
|
|
#else
|
|
#define OPT_TYPE const
|
|
#endif
|
|
|
|
static OPT_TYPE bool vcodec_off =
|
|
#ifdef VCODEC_OFF
|
|
true;
|
|
#else
|
|
false;
|
|
#endif
|
|
static OPT_TYPE uint8_t ana_act_dcdc =
|
|
#ifdef VANA_1P2V
|
|
PMU_DCDC_ANA_1_2V;
|
|
#elif defined(VANA_1P35V)
|
|
PMU_DCDC_ANA_1_35V;
|
|
#elif defined(VANA_1P4V)
|
|
PMU_DCDC_ANA_1_4V;
|
|
#elif defined(VANA_1P5V)
|
|
PMU_DCDC_ANA_1_5V;
|
|
#elif defined(VANA_1P6V)
|
|
PMU_DCDC_ANA_1_6V;
|
|
#else
|
|
PMU_DCDC_ANA_1_3V;
|
|
#endif
|
|
static OPT_TYPE POSSIBLY_UNUSED uint16_t vcodec_mv =
|
|
(uint16_t)(VCODEC_VOLT * 1000);
|
|
static OPT_TYPE POSSIBLY_UNUSED uint16_t vhppa_mv =
|
|
(uint16_t)(VHPPA_VOLT * 1000);
|
|
|
|
static enum HAL_CHIP_METAL_ID_T BOOT_BSS_LOC pmu_metal_id;
|
|
|
|
static enum PMU_POWER_MODE_T BOOT_BSS_LOC pmu_power_mode = PMU_POWER_MODE_NONE;
|
|
|
|
static enum PMU_VCORE_REQ_T BOOT_BSS_LOC pmu_vcore_req;
|
|
|
|
// Move all the data/bss invovled in pmu_open() to .sram_data/.sram_bss,
|
|
// so that pmu_open() can be called at the end of BootInit(),
|
|
// for data/bss is initialized after BootInit().
|
|
static enum PMU_VUSB_REQ_T SRAM_BSS_DEF(pmu_vusb_req);
|
|
|
|
static uint16_t SRAM_BSS_DEF(dcdc_ramp_map);
|
|
|
|
static PMU_CHARGER_IRQ_HANDLER_T charger_irq_handler;
|
|
|
|
static PMU_IRQ_UNIFIED_HANDLER_T pmu_irq_hdlrs[PMU_IRQ_TYPE_QTY];
|
|
|
|
static uint8_t SRAM_BSS_DEF(vio_risereq_map);
|
|
STATIC_ASSERT(sizeof(vio_risereq_map) * 8 >= PMU_VIORISE_REQ_USER_QTY,
|
|
"vio_risereq_map size too small");
|
|
|
|
static uint8_t SRAM_DATA_DEF(vio_act_normal) = IO_VOLT_ACTIVE_NORMAL;
|
|
static uint8_t SRAM_DATA_DEF(vio_act_rise) = IO_VOLT_ACTIVE_RISE;
|
|
static uint8_t SRAM_DATA_DEF(vio_lp) = IO_VOLT_SLEEP;
|
|
|
|
static const uint8_t ana_lp_dcdc = PMU_DCDC_ANA_SLEEP_1_3V;
|
|
|
|
// BT might have connection drop issues if dig_lp is lower than 0.8V
|
|
static const uint8_t dig_lp_ldo = PMU_VDIG_0_8V;
|
|
static const uint8_t dig_lp_dcdc = PMU_DCDC_DIG_0_8V;
|
|
|
|
static uint8_t BOOT_DATA_DEF(audpll_codec_div) = 16;
|
|
|
|
#ifdef HIGH_VCORE
|
|
static const bool high_vcore = true;
|
|
#else
|
|
static bool BOOT_BSS_DEF(high_vcore);
|
|
#endif
|
|
|
|
static uint16_t wdt_timer;
|
|
|
|
#if defined(MCU_HIGH_PERFORMANCE_MODE)
|
|
static const uint16_t high_perf_freq_mhz =
|
|
#if defined(MTEST_ENABLED) && defined(MTEST_CLK_MHZ)
|
|
MTEST_CLK_MHZ;
|
|
#else
|
|
300;
|
|
#endif
|
|
static bool high_perf_on;
|
|
#endif
|
|
|
|
void pmu_wdt_save_context(void);
|
|
void pmu_wdt_restore_context(void);
|
|
void pmu_charger_save_context(void);
|
|
void pmu_charger_shutdown_config(void);
|
|
|
|
#if defined(PMU_INIT) || (!defined(PROGRAMMER))
|
|
static void pmu_hppa_dcdc_to_ldo(void);
|
|
#endif
|
|
|
|
#if defined(_AUTO_TEST_)
|
|
static bool at_skip_shutdown = false;
|
|
|
|
void pmu_at_skip_shutdown(bool enable) { at_skip_shutdown = enable; }
|
|
#endif
|
|
|
|
#ifdef RTC_ENABLE
|
|
struct PMU_RTC_CTX_T {
|
|
bool enabled;
|
|
bool alarm_set;
|
|
uint32_t alarm_val;
|
|
};
|
|
|
|
static struct PMU_RTC_CTX_T BOOT_BSS_LOC rtc_ctx;
|
|
|
|
static PMU_RTC_IRQ_HANDLER_T rtc_irq_handler;
|
|
|
|
static void BOOT_TEXT_SRAM_LOC pmu_rtc_save_context(void) {
|
|
if (pmu_rtc_enabled()) {
|
|
rtc_ctx.enabled = true;
|
|
if (pmu_rtc_alarm_status_set()) {
|
|
rtc_ctx.alarm_set = true;
|
|
rtc_ctx.alarm_val = pmu_rtc_get_alarm();
|
|
}
|
|
} else {
|
|
rtc_ctx.enabled = false;
|
|
}
|
|
}
|
|
|
|
static void pmu_rtc_restore_context(void) {
|
|
uint32_t rtc_val;
|
|
|
|
if (rtc_ctx.enabled) {
|
|
pmu_rtc_enable();
|
|
if (rtc_ctx.alarm_set) {
|
|
rtc_val = pmu_rtc_get();
|
|
if (rtc_val - rtc_ctx.alarm_val <= 1 || rtc_ctx.alarm_val - rtc_val < 5) {
|
|
rtc_ctx.alarm_val = rtc_val + 5;
|
|
}
|
|
pmu_rtc_set_alarm(rtc_ctx.alarm_val);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef PMU_DCDC_CALIB
|
|
union VOLT_COMP_T {
|
|
struct VOLT_COMP_FIELD_T {
|
|
uint16_t dcdc1_v : 5; // bit[4:0]: 0 ~ 31
|
|
uint16_t dcdc1_f : 1; // bit[5] : 1: negative, 0: positive;
|
|
uint16_t dcdc2_v : 4; // bit[9:6]: 0 ~ 15
|
|
uint16_t dcdc2_f : 1; // bit[10] :
|
|
uint16_t dcdc3_v : 4; // bit[14:11]: 0 ~ 15
|
|
uint16_t dcdc3_f : 1; // bit[15]
|
|
} f;
|
|
uint16_t v;
|
|
};
|
|
|
|
static int8_t pmu_dcdc_dig_comp = 0;
|
|
static int8_t pmu_dcdc_ana_comp = 0;
|
|
static int8_t pmu_dcdc_hppa_comp = 0;
|
|
|
|
static POSSIBLY_UNUSED void pmu_get_dcdc_calib_value(void) {
|
|
union VOLT_COMP_T cv;
|
|
|
|
pmu_get_efuse(PMU_EFUSE_PAGE_RESERVED_7, &cv.v);
|
|
if (cv.f.dcdc1_f) { // digital
|
|
pmu_dcdc_dig_comp = -(int8_t)(cv.f.dcdc1_v);
|
|
} else {
|
|
pmu_dcdc_dig_comp = (int8_t)(cv.f.dcdc1_v);
|
|
}
|
|
if (cv.f.dcdc2_f) { // ana
|
|
pmu_dcdc_ana_comp = -(int8_t)(cv.f.dcdc2_v);
|
|
} else {
|
|
pmu_dcdc_ana_comp = (int8_t)(cv.f.dcdc2_v);
|
|
}
|
|
if (cv.f.dcdc3_f) { // hppa
|
|
pmu_dcdc_hppa_comp = -(int8_t)(cv.f.dcdc3_v);
|
|
} else {
|
|
pmu_dcdc_hppa_comp = (int8_t)(cv.f.dcdc3_v);
|
|
}
|
|
}
|
|
|
|
static POSSIBLY_UNUSED unsigned short
|
|
pmu_reg_val_add(unsigned short val, int delta, unsigned short max) {
|
|
int result = val + delta;
|
|
|
|
if (result > max) {
|
|
result = max;
|
|
} else if (result < 0) {
|
|
result = 0;
|
|
}
|
|
|
|
return (unsigned short)result;
|
|
}
|
|
#endif
|
|
|
|
static unsigned int NOINLINE BOOT_TEXT_SRAM_LOC
|
|
pmu_count_zeros(unsigned int val, unsigned int bits) {
|
|
int cnt = 0;
|
|
int i;
|
|
|
|
for (i = 0; i < bits; i++) {
|
|
if ((val & (1 << i)) == 0) {
|
|
cnt++;
|
|
}
|
|
}
|
|
|
|
return cnt;
|
|
}
|
|
|
|
static int BOOT_TEXT_FLASH_LOC pmu_read_efuse_block(unsigned int block) {
|
|
int ret;
|
|
unsigned short val;
|
|
uint32_t start;
|
|
uint32_t timeout = MS_TO_TICKS(50);
|
|
|
|
val = TSMC_EFUSE_PGENB | TSMC_EFUSE_CLK_EN;
|
|
ret = pmu_write(PMU_REG_EFUSE_CTRL, val);
|
|
if (ret) {
|
|
return ret;
|
|
}
|
|
|
|
val =
|
|
TSMC_EFUSE_STROBE_WIDTH(20) | REG_READ_STROBE_WIDTH(4) | EFUSE_SEL(block);
|
|
ret = pmu_write(PMU_REG_EFUSE_SEL, val);
|
|
if (ret) {
|
|
return ret;
|
|
}
|
|
|
|
ret = pmu_read(PMU_REG_POWER_OFF, &val);
|
|
if (ret) {
|
|
return ret;
|
|
}
|
|
val = SET_BITFIELD(val, EFUSE_READ_TRIG, EFUSE_READ_TRIG_WORD);
|
|
ret = pmu_write(PMU_REG_POWER_OFF, val);
|
|
if (ret) {
|
|
return ret;
|
|
}
|
|
|
|
hal_sys_timer_delay(US_TO_TICKS(500));
|
|
|
|
start = hal_sys_timer_get();
|
|
do {
|
|
ret = pmu_read(PMU_REG_POWER_OFF, &val);
|
|
if (ret) {
|
|
return ret;
|
|
}
|
|
if (hal_sys_timer_get() - start > timeout) {
|
|
return -2;
|
|
}
|
|
} while ((val & (EFUSE_READ_DONE | EFUSE_READ_BUSY)) != EFUSE_READ_DONE);
|
|
|
|
val = TSMC_EFUSE_PGENB;
|
|
ret = pmu_write(PMU_REG_EFUSE_CTRL, val);
|
|
if (ret) {
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void BOOT_TEXT_FLASH_LOC bbpll_freq_pll_config(uint32_t freq) {
|
|
int ret;
|
|
uint64_t PLL_cfg_val;
|
|
uint16_t v[3];
|
|
uint16_t val;
|
|
uint32_t crystal = hal_cmu_get_crystal_freq();
|
|
|
|
PLL_cfg_val = ((uint64_t)(1 << 28) * (freq / 2) + crystal / 2) / crystal;
|
|
v[0] = PLL_cfg_val & 0xFFFF;
|
|
v[1] = (PLL_cfg_val >> 16) & 0xFFFF;
|
|
v[2] = (PLL_cfg_val >> 32) & 0xFFFF;
|
|
|
|
ret = pmu_write(PMU_REG_RF_BB, v[0]);
|
|
if (ret) {
|
|
return;
|
|
}
|
|
|
|
ret = pmu_write(PMU_REG_RF_BC, v[1]);
|
|
if (ret) {
|
|
return;
|
|
}
|
|
|
|
ret = pmu_read(PMU_REG_RF_BD, &val);
|
|
if (ret) {
|
|
return;
|
|
}
|
|
val = SET_BITFIELD(val, REG_BBPLL_FREQ_34_32, v[2]) | REG_BBPLL_FREQ_EN;
|
|
ret = pmu_write(PMU_REG_RF_BD, val);
|
|
if (ret) {
|
|
return;
|
|
}
|
|
|
|
// Delay at least for 7us
|
|
hal_sys_timer_delay(US_TO_TICKS(100));
|
|
}
|
|
|
|
uint32_t BOOT_TEXT_FLASH_LOC read_hw_metal_id(void) {
|
|
int ret;
|
|
uint16_t val;
|
|
uint32_t metal_id;
|
|
int i;
|
|
union BOOT_SETTINGS_T boot;
|
|
|
|
#ifdef RTC_ENABLE
|
|
// RTC will be restored in pmu_open()
|
|
pmu_rtc_save_context();
|
|
#endif
|
|
|
|
pmu_wdt_save_context();
|
|
|
|
pmu_charger_save_context();
|
|
|
|
// Reset PMU (to recover from a possible insane state, e.g., ESD reset)
|
|
pmu_write(PMU_REG_METAL_ID, 0xCAFE);
|
|
pmu_write(PMU_REG_METAL_ID, 0x5FEE);
|
|
hal_sys_timer_delay(US_TO_TICKS(500));
|
|
|
|
#if defined(PMU_FULL_INIT) || (!defined(PROGRAMMER))
|
|
// Reset RF
|
|
pmu_write(PMU_REG_RF_80, 0xCAFE);
|
|
pmu_write(PMU_REG_RF_80, 0x5FEE);
|
|
hal_sys_timer_delay(US_TO_TICKS(500));
|
|
|
|
// Reset ANA
|
|
pmu_write(PMU_REG_ANA_60, 0xCAFE);
|
|
pmu_write(PMU_REG_ANA_60, 0x5FEE);
|
|
hal_sys_timer_delay(US_TO_TICKS(500));
|
|
#endif
|
|
|
|
#ifdef __WATCHER_DOG_RESET__
|
|
pmu_wdt_restore_context();
|
|
#endif
|
|
|
|
#ifndef EFUSE_BLOCK_NUM
|
|
#define EFUSE_BLOCK_NUM 6
|
|
#endif
|
|
|
|
for (i = 0; i < EFUSE_BLOCK_NUM; i++) {
|
|
ret = pmu_read_efuse_block(i);
|
|
if (ret) {
|
|
SAFE_PROGRAM_STOP();
|
|
}
|
|
}
|
|
|
|
ret = pmu_get_efuse(PMU_EFUSE_PAGE_BOOT, &boot.reg);
|
|
if (ret) {
|
|
boot.reg = 0;
|
|
} else {
|
|
if (pmu_count_zeros(boot.reg, 12) != boot.chksum) {
|
|
boot.reg = 0;
|
|
}
|
|
}
|
|
hal_cmu_set_crystal_freq_index(boot.crystal_freq);
|
|
// Update ISPI cfg
|
|
ret = hal_analogif_open();
|
|
if (ret) {
|
|
SAFE_PROGRAM_STOP();
|
|
}
|
|
|
|
#if !defined(PROGRAMMER) && !defined(MCU_HIGH_PERFORMANCE_MODE)
|
|
if (hal_cmu_get_crystal_freq() != hal_cmu_get_default_crystal_freq()) {
|
|
// Update bbpll freq after resetting RF and getting crystal freq
|
|
bbpll_freq_pll_config(384000000);
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
#ifndef HIGH_VCORE
|
|
pmu_get_efuse(PMU_EFUSE_PAGE_SW_CFG, &val);
|
|
if ((val & (3 << 13)) == (3 << 13)) {
|
|
high_vcore = true;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
// enhance xtal drv
|
|
pmu_write(0x9d, 0x886c);
|
|
// Enable 26M doubler (52M)
|
|
pmu_write(0xB5, 0x8000);
|
|
#ifdef ANA_26M_X4_ENABLE
|
|
pmu_write(0xBF, 0x0400);
|
|
#endif
|
|
|
|
// Power up bbpll and audpll clk buf
|
|
// Clk buf bits:
|
|
// 0-rfpll 1-bt_dac 2-codec_resample&audpll_prechr 3-bbpll 4-audpll 5-usbhspll
|
|
// 6-lbrt 7-dig
|
|
pmu_read(0xC4, &val);
|
|
val &= ~0xFF;
|
|
val |= (1 << 2) | (1 << 3) | (1 << 4) | (1 << 7);
|
|
#if defined(USB_HIGH_SPEED) || defined(USB_USE_USBPLL)
|
|
val |= (1 << 5);
|
|
#endif
|
|
pmu_write(0xC4, val);
|
|
|
|
// Cfg bbpll
|
|
pmu_write(0x9F, 0xC22F);
|
|
pmu_write(0xA0, 0x2788);
|
|
|
|
// Cfg audpll
|
|
pmu_write(0x79, 0x0011);
|
|
pmu_write(0x77, 0x71B1);
|
|
|
|
// Set audpll to 24.576M*17
|
|
pmu_write(0x7C, 0x4F16);
|
|
pmu_write(0x7B, 0x011A);
|
|
pmu_write(0x7A, 0x2008);
|
|
|
|
// Clear reg_bt_tst_buf_sel_in/out to avoid impacting P00-P03 and P30-P33 pins
|
|
pmu_write(0xA2, 0x01C2);
|
|
|
|
// Enable SWD debug mode
|
|
pmu_read(PMU_REG_SLEEP_CFG, &val);
|
|
val = SET_BITFIELD(val, PMIC_TMODE_1300, 2);
|
|
pmu_write(PMU_REG_SLEEP_CFG, val);
|
|
|
|
pmu_read(PMU_REG_METAL_ID, &val);
|
|
pmu_metal_id = GET_BITFIELD(val, PMU_METAL_ID);
|
|
|
|
metal_id = hal_cmu_get_aon_revision_id();
|
|
|
|
if (metal_id == HAL_CHIP_METAL_ID_1) {
|
|
uint32_t data;
|
|
|
|
hal_psc_bt_enable();
|
|
hal_cmu_bt_clock_enable();
|
|
hal_cmu_bt_reset_clear();
|
|
data = *(volatile uint32_t *)0xA0000004;
|
|
hal_cmu_bt_reset_set();
|
|
hal_cmu_bt_clock_disable();
|
|
hal_psc_bt_disable();
|
|
|
|
if (data == 0xA0007471) {
|
|
metal_id = HAL_CHIP_METAL_ID_2;
|
|
}
|
|
}
|
|
|
|
// Init pll dividers
|
|
pmu_read(PMU_REG_ANA_77, &val);
|
|
val = SET_BITFIELD(val, REG_AUDPLL_DIVN, audpll_codec_div);
|
|
pmu_write(PMU_REG_ANA_77, val);
|
|
|
|
return metal_id;
|
|
}
|
|
|
|
void BOOT_TEXT_SRAM_LOC pmu_pll_div_reset_set(enum HAL_CMU_PLL_T pll) {
|
|
uint32_t lock;
|
|
uint16_t val;
|
|
|
|
lock = int_lock();
|
|
if (pll == HAL_CMU_PLL_AUD) {
|
|
pmu_read(PMU_REG_ANA_77, &val);
|
|
val |= REG_AUDPLL_DIVN_MASK | REG_AUDPLL_DIVN_RST;
|
|
pmu_write(PMU_REG_ANA_77, val);
|
|
} else if (pll == HAL_CMU_PLL_USB) {
|
|
// In fact bbpll
|
|
#ifdef AUDIO_USE_BBPLL
|
|
// 0xD2, bit13 (reset)
|
|
// 0xF5, bit[4:0] (div)
|
|
#endif
|
|
} else if (pll == HAL_CMU_PLL_QTY) {
|
|
// In fact usbhspll
|
|
}
|
|
int_unlock(lock);
|
|
}
|
|
|
|
void BOOT_TEXT_SRAM_LOC pmu_pll_div_reset_clear(enum HAL_CMU_PLL_T pll) {
|
|
uint32_t lock;
|
|
uint16_t val;
|
|
|
|
lock = int_lock();
|
|
if (pll == HAL_CMU_PLL_AUD) {
|
|
pmu_read(PMU_REG_ANA_77, &val);
|
|
val &= ~REG_AUDPLL_DIVN_RST;
|
|
pmu_write(PMU_REG_ANA_77, val);
|
|
val = SET_BITFIELD(val, REG_AUDPLL_DIVN, audpll_codec_div);
|
|
pmu_write(PMU_REG_ANA_77, val);
|
|
} else if (pll == HAL_CMU_PLL_USB) {
|
|
// In fact bbpll
|
|
#ifdef AUDIO_USE_BBPLL
|
|
#endif
|
|
} else if (pll == HAL_CMU_PLL_QTY) {
|
|
// In fact usbhspll
|
|
}
|
|
int_unlock(lock);
|
|
}
|
|
|
|
void pmu_pll_div_set(enum HAL_CMU_PLL_T pll, enum PMU_PLL_DIV_TYPE_T type,
|
|
uint32_t div) {
|
|
uint32_t lock;
|
|
uint16_t val;
|
|
|
|
if (type != PMU_PLL_DIV_CODEC) {
|
|
return;
|
|
}
|
|
|
|
lock = int_lock();
|
|
if (pll == HAL_CMU_PLL_AUD) {
|
|
if (div != audpll_codec_div) {
|
|
audpll_codec_div = div;
|
|
pmu_read(PMU_REG_ANA_77, &val);
|
|
val |= REG_AUDPLL_DIVN_MASK;
|
|
pmu_write(PMU_REG_ANA_77, val);
|
|
if (div != (REG_AUDPLL_DIVN_MASK >> REG_AUDPLL_DIVN_SHIFT)) {
|
|
val = SET_BITFIELD(val, REG_AUDPLL_DIVN, audpll_codec_div);
|
|
pmu_write(PMU_REG_ANA_77, val);
|
|
}
|
|
}
|
|
} else if (pll == HAL_CMU_PLL_USB) {
|
|
// In fact bbpll
|
|
#ifdef AUDIO_USE_BBPLL
|
|
#endif
|
|
} else if (pll == HAL_CMU_PLL_QTY) {
|
|
// In fact usbhspll
|
|
}
|
|
int_unlock(lock);
|
|
}
|
|
|
|
#if defined(USE_CYBERON)
|
|
static uint32_t BOOT_BSS_LOC cyb_hack_efuse_check = 0;
|
|
void cyb_efuse_check_enable(int enabled) { cyb_hack_efuse_check = enabled; }
|
|
|
|
int cyb_efuse_check_status(void) { return cyb_hack_efuse_check; }
|
|
|
|
#if 1
|
|
int BOOT_TEXT_SRAM_LOC Cyb_pmu_get_efuse(enum PMU_EFUSE_PAGE_T page,
|
|
unsigned short *efuse) {
|
|
// PMU_DEBUG_TRACE(2,"page %x, efuse %x", page, efuse);
|
|
if (page == 0XE) {
|
|
*efuse = 0x1B9C;
|
|
}
|
|
if (page == 0xF) {
|
|
*efuse = 0x098B;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
int BOOT_TEXT_SRAM_LOC pmu_get_efuse(enum PMU_EFUSE_PAGE_T page,
|
|
unsigned short *efuse) {
|
|
int ret;
|
|
|
|
// #if defined(USE_CYBERON)
|
|
#if 0
|
|
if (cyb_efuse_check_status()) {
|
|
PMU_DEBUG_TRACE(2,"page %x, efuse %x", page, efuse);
|
|
if((int)page==0xE){
|
|
*efuse=0x1B9C;
|
|
return 0;
|
|
}
|
|
if((int)page==0xF){
|
|
*efuse = 0x098B;
|
|
return 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
ret = pmu_read(PMU_REG_EFUSE_VAL_START + page, efuse);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int pmu_get_security_value(union SECURITY_VALUE_T *val) {
|
|
int ret;
|
|
|
|
ret = pmu_get_efuse(PMU_EFUSE_PAGE_SECURITY, &val->reg);
|
|
if (ret) {
|
|
// Error
|
|
goto _no_security;
|
|
}
|
|
|
|
if (!val->security_en) {
|
|
// OK
|
|
goto _no_security;
|
|
}
|
|
ret = 1;
|
|
if (pmu_count_zeros(val->key_id, 3) != val->key_chksum) {
|
|
// Error
|
|
goto _no_security;
|
|
}
|
|
if (pmu_count_zeros(val->vendor_id, 6) != val->vendor_chksum) {
|
|
// Error
|
|
goto _no_security;
|
|
}
|
|
if ((pmu_count_zeros(val->reg, 15) & 1) != val->chksum) {
|
|
// Error
|
|
goto _no_security;
|
|
}
|
|
|
|
// OK
|
|
return 0;
|
|
|
|
_no_security:
|
|
val->reg = 0;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void pmu_sys_ctrl(bool shutdown) {
|
|
uint16_t val;
|
|
uint32_t lock = int_lock();
|
|
|
|
PMU_INFO_TRACE_IMM(0, "Start pmu %s", shutdown ? "shutdown" : "reboot");
|
|
|
|
#if defined(PMU_INIT) || (!defined(PROGRAMMER))
|
|
#if defined(MCU_HIGH_PERFORMANCE_MODE)
|
|
// Default vcore might not be high enough to support high performance mode
|
|
pmu_high_performance_mode_enable(false);
|
|
hal_cmu_sys_set_freq(HAL_CMU_FREQ_26M);
|
|
#endif
|
|
pmu_hppa_dcdc_to_ldo();
|
|
pmu_mode_change(PMU_POWER_MODE_LDO);
|
|
hal_sys_timer_delay(MS_TO_TICKS(1));
|
|
#endif
|
|
|
|
#ifdef RTC_ENABLE
|
|
pmu_rtc_save_context();
|
|
#endif
|
|
|
|
// Reset PMU
|
|
pmu_write(PMU_REG_METAL_ID, 0xCAFE);
|
|
pmu_write(PMU_REG_METAL_ID, 0x5FEE);
|
|
hal_sys_timer_delay(4);
|
|
|
|
#ifdef RTC_ENABLE
|
|
pmu_rtc_restore_context();
|
|
#endif
|
|
|
|
if (shutdown) {
|
|
#if defined(_AUTO_TEST_)
|
|
if (at_skip_shutdown) {
|
|
hal_cmu_sys_reboot();
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
#if defined(PMU_INIT) || (!defined(PROGRAMMER))
|
|
pmu_wdt_config(3 * 1000, 3 * 1000);
|
|
pmu_wdt_start();
|
|
pmu_charger_shutdown_config();
|
|
#endif
|
|
|
|
// Power off
|
|
pmu_read(PMU_REG_POWER_OFF, &val);
|
|
val |= SOFT_POWER_OFF;
|
|
for (int i = 0; i < 100; i++) {
|
|
pmu_write(PMU_REG_POWER_OFF, val);
|
|
hal_sys_timer_delay(MS_TO_TICKS(5));
|
|
}
|
|
|
|
hal_sys_timer_delay(MS_TO_TICKS(50));
|
|
|
|
// can't reach here
|
|
PMU_INFO_TRACE_IMM(0, "\nError: pmu shutdown failed!\n");
|
|
hal_sys_timer_delay(MS_TO_TICKS(5));
|
|
} else {
|
|
#if defined(PMU_FULL_INIT) || (!defined(PROGRAMMER))
|
|
// CAUTION:
|
|
// 1) Never reset RF because system or flash might be using X2/X4, which are
|
|
// off by default 2) Never reset RF/ANA because system or flash might be
|
|
// using PLL, and the reset might cause clock glitch
|
|
// TODO:
|
|
// Restore BBPLL settings in RF
|
|
#endif
|
|
}
|
|
|
|
hal_cmu_sys_reboot();
|
|
|
|
int_unlock(lock);
|
|
}
|
|
|
|
void pmu_shutdown(void) { pmu_sys_ctrl(true); }
|
|
|
|
void pmu_reboot(void) { pmu_sys_ctrl(false); }
|
|
|
|
static inline uint16_t pmu_get_module_addr(enum PMU_MODUAL_T module) {
|
|
if (module == PMU_HPPA2CODEC || module == PMU_CODEC) {
|
|
return PMU_REG_MODULE_START + module + 1;
|
|
} else if (module == PMU_BUCK2ANA) {
|
|
return PMU_REG_BUCK2ANA_CFG;
|
|
} else {
|
|
return PMU_REG_MODULE_START + module;
|
|
}
|
|
}
|
|
|
|
void pmu_module_config(enum PMU_MODUAL_T module, unsigned short is_manual,
|
|
unsigned short ldo_on, unsigned short lp_mode,
|
|
unsigned short dpmode) {
|
|
unsigned short val;
|
|
unsigned char module_address;
|
|
const struct PMU_MODULE_CFG_T *module_cfg_p = &pmu_module_cfg[module];
|
|
|
|
module_address = pmu_get_module_addr(module);
|
|
|
|
if (module == PMU_ANA) {
|
|
pmu_read(PMU_REG_BIAS_CFG, &val);
|
|
if (is_manual) {
|
|
val |= module_cfg_p->pu_dr;
|
|
} else {
|
|
val &= ~module_cfg_p->pu_dr;
|
|
}
|
|
|
|
if (ldo_on) {
|
|
val |= module_cfg_p->pu;
|
|
} else {
|
|
val &= ~module_cfg_p->pu;
|
|
}
|
|
pmu_write(PMU_REG_BIAS_CFG, val);
|
|
} else if (module == PMU_DIG) {
|
|
pmu_read(PMU_REG_DCDC_DIG_EN, &val);
|
|
if (is_manual) {
|
|
val |= module_cfg_p->pu_dr;
|
|
} else {
|
|
val &= ~module_cfg_p->pu_dr;
|
|
}
|
|
|
|
if (ldo_on) {
|
|
val |= module_cfg_p->pu;
|
|
} else {
|
|
val &= ~module_cfg_p->pu;
|
|
}
|
|
pmu_write(PMU_REG_DCDC_DIG_EN, val);
|
|
} else if (module == PMU_HPPA2CODEC) {
|
|
pmu_read(PMU_REG_SLEEP_CFG, &val);
|
|
if (dpmode) {
|
|
val |= module_cfg_p->pu_dsleep;
|
|
} else {
|
|
val &= ~module_cfg_p->pu_dsleep;
|
|
}
|
|
pmu_write(PMU_REG_SLEEP_CFG, val);
|
|
} else if (module == PMU_CODEC) {
|
|
pmu_read(PMU_REG_HPPA2CODEC_CFG, &val);
|
|
if (dpmode) {
|
|
val |= module_cfg_p->pu_dsleep;
|
|
} else {
|
|
val &= ~module_cfg_p->pu_dsleep;
|
|
}
|
|
pmu_write(PMU_REG_HPPA2CODEC_CFG, val);
|
|
}
|
|
|
|
pmu_read(module_address, &val);
|
|
|
|
if (module != PMU_ANA && module != PMU_DIG) {
|
|
if (is_manual) {
|
|
val |= module_cfg_p->pu_dr;
|
|
} else {
|
|
val &= ~module_cfg_p->pu_dr;
|
|
}
|
|
|
|
if (ldo_on) {
|
|
val |= module_cfg_p->pu;
|
|
} else {
|
|
val &= ~module_cfg_p->pu;
|
|
}
|
|
}
|
|
|
|
if (lp_mode) {
|
|
val &= ~module_cfg_p->lp_en_dr;
|
|
} else {
|
|
val = (val & ~module_cfg_p->lp_en) | module_cfg_p->lp_en_dr;
|
|
}
|
|
|
|
if (module != PMU_HPPA2CODEC && module != PMU_CODEC) {
|
|
if (dpmode) {
|
|
val |= module_cfg_p->pu_dsleep;
|
|
} else {
|
|
val &= ~module_cfg_p->pu_dsleep;
|
|
}
|
|
}
|
|
|
|
pmu_write(module_address, val);
|
|
}
|
|
|
|
void pmu_module_set_volt(unsigned char module, unsigned short sleep_v,
|
|
unsigned short normal_v) {
|
|
unsigned short val;
|
|
unsigned char module_address;
|
|
const struct PMU_MODULE_CFG_T *module_cfg_p = &pmu_module_cfg[module];
|
|
|
|
module_address = pmu_get_module_addr(module);
|
|
|
|
pmu_read(module_address, &val);
|
|
val &= ~module_cfg_p->vbit_normal_mask;
|
|
val |= (normal_v << module_cfg_p->vbit_normal_shift) &
|
|
module_cfg_p->vbit_normal_mask;
|
|
val &= ~module_cfg_p->vbit_dsleep_mask;
|
|
val |= (sleep_v << module_cfg_p->vbit_dsleep_shift) &
|
|
module_cfg_p->vbit_dsleep_mask;
|
|
pmu_write(module_address, val);
|
|
}
|
|
|
|
int pmu_module_get_volt(unsigned char module, unsigned short *sleep_vp,
|
|
unsigned short *normal_vp) {
|
|
unsigned short val;
|
|
unsigned char module_address;
|
|
const struct PMU_MODULE_CFG_T *module_cfg_p = &pmu_module_cfg[module];
|
|
|
|
module_address = pmu_get_module_addr(module);
|
|
|
|
pmu_read(module_address, &val);
|
|
if (normal_vp) {
|
|
*normal_vp = (val & module_cfg_p->vbit_normal_mask) >>
|
|
module_cfg_p->vbit_normal_shift;
|
|
}
|
|
if (sleep_vp) {
|
|
*sleep_vp = (val & module_cfg_p->vbit_dsleep_mask) >>
|
|
module_cfg_p->vbit_dsleep_shift;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void pmu_module_ramp_volt(unsigned char module, unsigned short sleep_v,
|
|
unsigned short normal_v) {
|
|
uint16_t old_normal_v;
|
|
uint16_t old_sleep_v;
|
|
|
|
pmu_module_get_volt(module, &old_sleep_v, &old_normal_v);
|
|
|
|
if (old_normal_v < normal_v) {
|
|
while (old_normal_v++ < normal_v) {
|
|
pmu_module_set_volt(module, sleep_v, old_normal_v);
|
|
}
|
|
} else if (old_normal_v != normal_v || old_sleep_v != sleep_v) {
|
|
pmu_module_set_volt(module, sleep_v, normal_v);
|
|
}
|
|
}
|
|
|
|
static void pmu_dcdc_ana_get_volt(unsigned short *normal_vp,
|
|
unsigned short *dsleep_vp) {
|
|
unsigned short val;
|
|
|
|
pmu_read(PMU_REG_DCDC_ANA_VOLT, &val);
|
|
if (normal_vp) {
|
|
*normal_vp = GET_BITFIELD(val, REG_DCDC2_VBIT_NORMAL);
|
|
}
|
|
if (dsleep_vp) {
|
|
*dsleep_vp = GET_BITFIELD(val, REG_DCDC2_VBIT_DSLEEP);
|
|
}
|
|
|
|
#ifdef PMU_DCDC_CALIB
|
|
if (normal_vp) {
|
|
*normal_vp =
|
|
pmu_reg_val_add(*normal_vp, -pmu_dcdc_ana_comp, MAX_DCDC2_VBIT_VAL);
|
|
}
|
|
if (dsleep_vp) {
|
|
*dsleep_vp =
|
|
pmu_reg_val_add(*dsleep_vp, -pmu_dcdc_ana_comp, MAX_DCDC2_VBIT_VAL);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void pmu_dcdc_ana_set_volt(unsigned short normal_v,
|
|
unsigned short dsleep_v) {
|
|
unsigned short val;
|
|
|
|
#ifdef PMU_DCDC_CALIB
|
|
normal_v = pmu_reg_val_add(normal_v, pmu_dcdc_ana_comp, MAX_DCDC2_VBIT_VAL);
|
|
dsleep_v = pmu_reg_val_add(dsleep_v, pmu_dcdc_ana_comp, MAX_DCDC2_VBIT_VAL);
|
|
#endif
|
|
|
|
pmu_read(PMU_REG_DCDC_ANA_VOLT, &val);
|
|
val &= ~REG_DCDC2_VBIT_DSLEEP_MASK;
|
|
val &= ~REG_DCDC2_VBIT_NORMAL_MASK;
|
|
val |= REG_DCDC2_VBIT_DSLEEP(dsleep_v);
|
|
val |= REG_DCDC2_VBIT_NORMAL(normal_v);
|
|
pmu_write(PMU_REG_DCDC_ANA_VOLT, val);
|
|
|
|
if (normal_v > dsleep_v) {
|
|
dcdc_ramp_map |= REG_DCDC2_RAMP_EN;
|
|
} else {
|
|
dcdc_ramp_map &= ~REG_DCDC2_RAMP_EN;
|
|
}
|
|
}
|
|
|
|
static void pmu_ana_set_volt(int mode_change, enum PMU_POWER_MODE_T mode) {
|
|
uint16_t old_act_dcdc;
|
|
uint16_t old_lp_dcdc;
|
|
uint16_t new_act_dcdc;
|
|
|
|
if (mode == PMU_POWER_MODE_ANA_DCDC || mode == PMU_POWER_MODE_DIG_DCDC) {
|
|
pmu_dcdc_ana_get_volt(&old_act_dcdc, &old_lp_dcdc);
|
|
new_act_dcdc = ana_act_dcdc;
|
|
if (old_act_dcdc < new_act_dcdc) {
|
|
while (old_act_dcdc++ < new_act_dcdc) {
|
|
pmu_dcdc_ana_set_volt(old_act_dcdc, ana_lp_dcdc);
|
|
}
|
|
hal_sys_timer_delay_us(PMU_VANA_STABLE_TIME_US);
|
|
} else if (old_act_dcdc != new_act_dcdc || old_lp_dcdc != ana_lp_dcdc) {
|
|
pmu_dcdc_ana_set_volt(new_act_dcdc, ana_lp_dcdc);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void pmu_dcdc_dig_get_volt(unsigned short *normal_vp,
|
|
unsigned short *dsleep_vp) {
|
|
unsigned short val;
|
|
|
|
pmu_read(PMU_REG_DCDC_DIG_VOLT, &val);
|
|
if (normal_vp) {
|
|
*normal_vp = GET_BITFIELD(val, REG_DCDC1_VBIT_NORMAL);
|
|
}
|
|
if (dsleep_vp) {
|
|
*dsleep_vp = GET_BITFIELD(val, REG_DCDC1_VBIT_DSLEEP);
|
|
}
|
|
|
|
#ifdef PMU_DCDC_CALIB
|
|
if (normal_vp) {
|
|
*normal_vp =
|
|
pmu_reg_val_add(*normal_vp, -pmu_dcdc_dig_comp, MAX_DCDC1_VBIT_VAL);
|
|
}
|
|
if (dsleep_vp) {
|
|
*dsleep_vp =
|
|
pmu_reg_val_add(*dsleep_vp, -pmu_dcdc_dig_comp, MAX_DCDC1_VBIT_VAL);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void pmu_dcdc_dig_set_volt(unsigned short normal_v,
|
|
unsigned short dsleep_v) {
|
|
unsigned short val;
|
|
|
|
#ifdef PMU_DCDC_CALIB
|
|
normal_v = pmu_reg_val_add(normal_v, pmu_dcdc_dig_comp, MAX_DCDC1_VBIT_VAL);
|
|
dsleep_v = pmu_reg_val_add(dsleep_v, pmu_dcdc_dig_comp, MAX_DCDC1_VBIT_VAL);
|
|
#endif
|
|
|
|
pmu_read(PMU_REG_DCDC_DIG_VOLT, &val);
|
|
val &= ~REG_DCDC1_VBIT_DSLEEP_MASK;
|
|
val &= ~REG_DCDC1_VBIT_NORMAL_MASK;
|
|
val |= REG_DCDC1_VBIT_DSLEEP(dsleep_v);
|
|
val |= REG_DCDC1_VBIT_NORMAL(normal_v);
|
|
pmu_write(PMU_REG_DCDC_DIG_VOLT, val);
|
|
|
|
if (normal_v > dsleep_v) {
|
|
dcdc_ramp_map |= REG_DCDC1_RAMP_EN;
|
|
} else {
|
|
dcdc_ramp_map &= ~REG_DCDC1_RAMP_EN;
|
|
}
|
|
}
|
|
|
|
static void BOOT_TEXT_SRAM_LOC pmu_dig_get_target_volt(uint16_t *ldo,
|
|
uint16_t *dcdc) {
|
|
uint16_t ldo_volt;
|
|
uint16_t dcdc_volt;
|
|
|
|
if (0) {
|
|
#if defined(MCU_HIGH_PERFORMANCE_MODE)
|
|
} else if (pmu_vcore_req & (PMU_VCORE_SYS_FREQ_HIGH)) {
|
|
if (high_perf_freq_mhz <= 260) {
|
|
ldo_volt = PMU_VDIG_1_05V;
|
|
dcdc_volt = PMU_DCDC_DIG_1_05V;
|
|
} else if (high_perf_freq_mhz <= 300) {
|
|
ldo_volt = PMU_VDIG_1_1V;
|
|
dcdc_volt = PMU_DCDC_DIG_1_1V;
|
|
} else {
|
|
ldo_volt = PMU_VDIG_1_2V;
|
|
dcdc_volt = PMU_DCDC_DIG_1_1V;
|
|
}
|
|
#endif
|
|
} else if (pmu_vcore_req &
|
|
(PMU_VCORE_USB_HS_ENABLED | PMU_VCORE_RS_FREQ_HIGH |
|
|
PMU_VCORE_SYS_FREQ_MEDIUM)) {
|
|
ldo_volt = PMU_VDIG_0_9V;
|
|
dcdc_volt = PMU_DCDC_DIG_0_9V;
|
|
} else if (pmu_vcore_req &
|
|
(PMU_VCORE_FLASH_FREQ_HIGH | PMU_VCORE_PSRAM_FREQ_HIGH |
|
|
PMU_VCORE_FLASH_WRITE_ENABLED)) {
|
|
ldo_volt = PMU_VDIG_0_8V;
|
|
dcdc_volt = PMU_DCDC_DIG_0_8V;
|
|
} else {
|
|
// Common cases
|
|
if (high_vcore) {
|
|
ldo_volt = PMU_VDIG_0_8V;
|
|
dcdc_volt = PMU_DCDC_DIG_0_8V;
|
|
} else {
|
|
ldo_volt = PMU_VDIG_0_75V;
|
|
dcdc_volt = PMU_DCDC_DIG_0_75V;
|
|
}
|
|
#ifdef __SAVE_POWER_MODE__
|
|
ldo_volt = PMU_VDIG_0_75V;
|
|
dcdc_volt = PMU_DCDC_DIG_0_75V;
|
|
#endif
|
|
}
|
|
|
|
#if defined(PROGRAMMER) || defined(__BES_OTA_MODE__) && !defined(PMU_FULL_INIT)
|
|
// Try to keep the same vcore voltage as ROM (hardware default)
|
|
if (ldo_volt < PMU_VDIG_0_9V) {
|
|
ldo_volt = PMU_VDIG_0_9V;
|
|
}
|
|
if (dcdc_volt < PMU_DCDC_DIG_0_9V) {
|
|
dcdc_volt = PMU_DCDC_DIG_0_9V;
|
|
}
|
|
#endif
|
|
|
|
#if defined(MTEST_ENABLED) && defined(MTEST_VOLT)
|
|
#ifdef DIG_DCDC_MODE
|
|
dcdc_volt = MTEST_VOLT;
|
|
#else
|
|
ldo_volt = MTEST_VOLT;
|
|
#endif
|
|
#endif
|
|
|
|
if (ldo) {
|
|
*ldo = ldo_volt;
|
|
}
|
|
if (dcdc) {
|
|
*dcdc = dcdc_volt;
|
|
}
|
|
}
|
|
|
|
static void pmu_dig_set_volt(int mode_change, enum PMU_POWER_MODE_T mode) {
|
|
uint32_t lock;
|
|
uint16_t dcdc_volt, old_act_dcdc, old_lp_dcdc;
|
|
uint16_t ldo_volt, old_act_ldo, old_lp_ldo;
|
|
uint16_t ldo_real, dcdc_real;
|
|
bool volt_inc = false;
|
|
|
|
lock = int_lock();
|
|
|
|
if (mode == PMU_POWER_MODE_NONE) {
|
|
mode = pmu_power_mode;
|
|
}
|
|
|
|
pmu_dig_get_target_volt(&ldo_volt, &dcdc_volt);
|
|
|
|
pmu_module_get_volt(PMU_DIG, &old_lp_ldo, &old_act_ldo);
|
|
pmu_dcdc_dig_get_volt(&old_act_dcdc, &old_lp_dcdc);
|
|
|
|
if (mode_change) {
|
|
// Both DCDC and LDO might have been enabled
|
|
ldo_real = (old_act_ldo - PMU_VDIG_0_4V) / 0x2;
|
|
dcdc_real = (old_act_dcdc - PMU_DCDC_DIG_0_4V) / 0x10;
|
|
if (dcdc_real < ldo_real) {
|
|
dcdc_real = ldo_real;
|
|
}
|
|
ldo_real = PMU_VDIG_0_4V + dcdc_real * 0x2;
|
|
dcdc_real = PMU_DCDC_DIG_0_4V + dcdc_real * 0x10;
|
|
|
|
// Set the voltage to current real voltage
|
|
if (old_act_ldo < ldo_real) {
|
|
old_act_ldo = ldo_real;
|
|
old_lp_ldo = dig_lp_ldo;
|
|
pmu_module_set_volt(PMU_DIG, old_lp_ldo, old_act_ldo);
|
|
}
|
|
if (old_act_dcdc < dcdc_real) {
|
|
old_act_dcdc = dcdc_real;
|
|
old_lp_dcdc = dig_lp_dcdc;
|
|
pmu_dcdc_dig_set_volt(old_act_dcdc, old_lp_dcdc);
|
|
}
|
|
}
|
|
|
|
if (mode_change || mode == PMU_POWER_MODE_DIG_DCDC) {
|
|
if (old_act_dcdc < dcdc_volt) {
|
|
volt_inc = true;
|
|
while (old_act_dcdc++ < dcdc_volt) {
|
|
pmu_dcdc_dig_set_volt(old_act_dcdc, dig_lp_dcdc);
|
|
}
|
|
} else if (old_act_dcdc != dcdc_volt || old_lp_dcdc != dig_lp_dcdc) {
|
|
pmu_dcdc_dig_set_volt(dcdc_volt, dig_lp_dcdc);
|
|
}
|
|
}
|
|
|
|
if (mode_change || mode != PMU_POWER_MODE_DIG_DCDC) {
|
|
if (old_act_ldo < ldo_volt) {
|
|
volt_inc = true;
|
|
}
|
|
pmu_module_ramp_volt(PMU_DIG, dig_lp_ldo, ldo_volt);
|
|
}
|
|
|
|
if (mode_change == 0) {
|
|
// Update the voltage of the other mode
|
|
if (mode == PMU_POWER_MODE_DIG_DCDC) {
|
|
pmu_module_set_volt(PMU_DIG, dig_lp_ldo, ldo_volt);
|
|
} else {
|
|
pmu_dcdc_dig_set_volt(dcdc_volt, dig_lp_dcdc);
|
|
}
|
|
}
|
|
|
|
if (volt_inc) {
|
|
hal_sys_timer_delay_us(PMU_VCORE_STABLE_TIME_US);
|
|
}
|
|
|
|
int_unlock(lock);
|
|
}
|
|
|
|
static void pmu_ldo_mode_en(void) {
|
|
unsigned short val;
|
|
|
|
// Enable vana ldo
|
|
pmu_module_config(PMU_ANA, PMU_AUTO_MODE, PMU_LDO_ON, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_ON);
|
|
// Enable vcore ldo
|
|
pmu_module_config(PMU_DIG, PMU_AUTO_MODE, PMU_LDO_ON, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_ON);
|
|
|
|
pmu_ana_set_volt(1, PMU_POWER_MODE_LDO);
|
|
pmu_dig_set_volt(1, PMU_POWER_MODE_LDO);
|
|
|
|
hal_sys_timer_delay_us(PMU_LDO_PU_STABLE_TIME_US);
|
|
|
|
// Disable vcore dcdc
|
|
pmu_read(PMU_REG_DCDC_DIG_EN, &val);
|
|
val = (val & ~REG_PU_DCDC1) | REG_PU_DCDC1_DR;
|
|
pmu_write(PMU_REG_DCDC_DIG_EN, val);
|
|
// Disable vana dcdc
|
|
pmu_read(PMU_REG_DCDC_ANA_EN, &val);
|
|
val = (val & ~REG_PU_DCDC2) | REG_PU_DCDC2_DR;
|
|
pmu_write(PMU_REG_DCDC_ANA_EN, val);
|
|
}
|
|
|
|
static void pmu_dcdc_ana_mode_en(void) {
|
|
unsigned short val;
|
|
|
|
if (pmu_power_mode == PMU_POWER_MODE_DIG_DCDC) {
|
|
// Enable vcore ldo
|
|
pmu_module_config(PMU_DIG, PMU_AUTO_MODE, PMU_LDO_ON, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_ON);
|
|
|
|
pmu_ana_set_volt(1, PMU_POWER_MODE_ANA_DCDC);
|
|
pmu_dig_set_volt(1, PMU_POWER_MODE_ANA_DCDC);
|
|
|
|
hal_sys_timer_delay_us(PMU_LDO_PU_STABLE_TIME_US);
|
|
|
|
// Disable vcore dcdc
|
|
pmu_read(PMU_REG_DCDC_DIG_EN, &val);
|
|
val = (val & ~REG_PU_DCDC1) | REG_PU_DCDC1_DR;
|
|
pmu_write(PMU_REG_DCDC_DIG_EN, val);
|
|
} else {
|
|
pmu_read(PMU_REG_DCDC_ANA_CFG_19, &val);
|
|
val |= DCDC2_REG_BYPASS;
|
|
pmu_write(PMU_REG_DCDC_ANA_CFG_19, val);
|
|
|
|
// Enable vana dcdc
|
|
pmu_read(PMU_REG_DCDC_ANA_EN, &val);
|
|
#ifdef DCDC_ULP_LP_ON
|
|
val = (val & ~REG_DCDC2_ULP_MODE_NORMAL) | REG_DCDC2_ULP_MODE_DSLEEP |
|
|
REG_PU_DCDC2_DR | REG_PU_DCDC2;
|
|
#else
|
|
val = (val & ~REG_DCDC2_ULP_MODE_NORMAL) | REG_PU_DCDC2_DR | REG_PU_DCDC2;
|
|
#endif
|
|
pmu_write(PMU_REG_DCDC_ANA_EN, val);
|
|
|
|
pmu_ana_set_volt(1, PMU_POWER_MODE_ANA_DCDC);
|
|
pmu_dig_set_volt(1, PMU_POWER_MODE_ANA_DCDC);
|
|
|
|
hal_sys_timer_delay_us(PMU_DCDC_PU_STABLE_TIME_US);
|
|
|
|
// Disable vana ldo
|
|
pmu_module_config(PMU_ANA, PMU_MANUAL_MODE, PMU_LDO_OFF, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
|
|
pmu_read(PMU_REG_DCDC_ANA_CFG_19, &val);
|
|
val &= ~DCDC2_REG_BYPASS;
|
|
pmu_write(PMU_REG_DCDC_ANA_CFG_19, val);
|
|
}
|
|
}
|
|
|
|
static void pmu_dcdc_dual_mode_en(void) {
|
|
unsigned short val;
|
|
|
|
pmu_read(PMU_REG_DCDC_ANA_CFG_19, &val);
|
|
val |= DCDC2_REG_BYPASS;
|
|
pmu_write(PMU_REG_DCDC_ANA_CFG_19, val);
|
|
pmu_read(PMU_REG_DCDC_DIG_CFG_36, &val);
|
|
val |= DCDC1_REG_BYPASS;
|
|
pmu_write(PMU_REG_DCDC_DIG_CFG_36, val);
|
|
|
|
// Enable vana dcdc
|
|
pmu_read(PMU_REG_DCDC_ANA_EN, &val);
|
|
#ifdef DCDC_ULP_LP_ON
|
|
val = (val & ~REG_DCDC2_ULP_MODE_NORMAL) | REG_DCDC2_ULP_MODE_DSLEEP |
|
|
REG_PU_DCDC2_DR | REG_PU_DCDC2;
|
|
#else
|
|
val = (val & ~(REG_DCDC2_ULP_MODE_NORMAL | REG_DCDC2_ULP_MODE_DSLEEP)) |
|
|
REG_PU_DCDC2_DR | REG_PU_DCDC2;
|
|
#endif
|
|
pmu_write(PMU_REG_DCDC_ANA_EN, val);
|
|
// Enable vcore dcdc
|
|
pmu_read(PMU_REG_DCDC_DIG_EN, &val);
|
|
#ifdef DCDC_ULP_LP_ON
|
|
val = (val & ~REG_DCDC1_ULP_MODE_NORMAL) | REG_DCDC1_ULP_MODE_DSLEEP |
|
|
REG_PU_DCDC1_DR | REG_PU_DCDC1;
|
|
#else
|
|
val = (val & ~(REG_DCDC1_ULP_MODE_NORMAL | REG_DCDC1_ULP_MODE_DSLEEP)) |
|
|
REG_PU_DCDC1_DR | REG_PU_DCDC1;
|
|
#endif
|
|
pmu_write(PMU_REG_DCDC_DIG_EN, val);
|
|
|
|
pmu_ana_set_volt(1, PMU_POWER_MODE_DIG_DCDC);
|
|
pmu_dig_set_volt(1, PMU_POWER_MODE_DIG_DCDC);
|
|
|
|
hal_sys_timer_delay_us(PMU_DCDC_PU_STABLE_TIME_US);
|
|
|
|
// Disable vana ldo
|
|
pmu_module_config(PMU_ANA, PMU_MANUAL_MODE, PMU_LDO_OFF, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
// Disable vcore ldo
|
|
pmu_module_config(PMU_DIG, PMU_MANUAL_MODE, PMU_LDO_OFF, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
|
|
pmu_read(PMU_REG_DCDC_ANA_CFG_19, &val);
|
|
val &= ~DCDC2_REG_BYPASS;
|
|
pmu_write(PMU_REG_DCDC_ANA_CFG_19, val);
|
|
pmu_read(PMU_REG_DCDC_DIG_CFG_36, &val);
|
|
val &= ~DCDC1_REG_BYPASS;
|
|
pmu_write(PMU_REG_DCDC_DIG_CFG_36, val);
|
|
}
|
|
|
|
void pmu_mode_change(enum PMU_POWER_MODE_T mode) {
|
|
uint32_t lock;
|
|
|
|
if (pmu_power_mode == mode || mode == PMU_POWER_MODE_NONE) {
|
|
return;
|
|
}
|
|
|
|
lock = int_lock();
|
|
|
|
if (mode == PMU_POWER_MODE_ANA_DCDC) {
|
|
pmu_dcdc_ana_mode_en();
|
|
} else if (mode == PMU_POWER_MODE_DIG_DCDC) {
|
|
pmu_dcdc_dual_mode_en();
|
|
} else if (mode == PMU_POWER_MODE_LDO) {
|
|
pmu_ldo_mode_en();
|
|
}
|
|
|
|
pmu_power_mode = mode;
|
|
|
|
int_unlock(lock);
|
|
}
|
|
|
|
void pmu_sleep_en(unsigned char sleep_en) {
|
|
unsigned short val;
|
|
|
|
pmu_read(PMU_REG_SLEEP_CFG, &val);
|
|
if (sleep_en) {
|
|
val |= SLEEP_ALLOW;
|
|
} else {
|
|
val &= ~SLEEP_ALLOW;
|
|
}
|
|
pmu_write(PMU_REG_SLEEP_CFG, val);
|
|
}
|
|
|
|
#if defined(PMU_INIT) || (!defined(PROGRAMMER))
|
|
static uint32_t pmu_vcodec_mv_to_val(uint16_t mv) {
|
|
uint32_t val;
|
|
|
|
#ifdef VHPPA2VCODEC
|
|
if (mv == 1900) {
|
|
val = PMU_HPPA2CODEC_1_9V;
|
|
} else if (mv >= 1950) {
|
|
val = PMU_HPPA2CODEC_1_95V;
|
|
} else {
|
|
val = PMU_HPPA2CODEC_1_7V;
|
|
}
|
|
#else
|
|
if (mv == 1900) {
|
|
val = PMU_CODEC_1_9V;
|
|
} else if (mv >= 1950) {
|
|
val = PMU_CODEC_1_9V;
|
|
} else {
|
|
val = PMU_CODEC_1_7V;
|
|
}
|
|
#endif
|
|
|
|
return val;
|
|
}
|
|
|
|
static uint32_t pmu_ldo_hppa_mv_to_val(uint16_t mv) {
|
|
uint32_t val;
|
|
|
|
if (mv == 1600) {
|
|
val = PMU_VHPPA_1_6V;
|
|
} else if (mv == 1700) {
|
|
val = PMU_VHPPA_1_7V;
|
|
} else if (mv >= 1900) {
|
|
val = PMU_VHPPA_1_9V;
|
|
} else {
|
|
val = PMU_VHPPA_1_8V;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
static void POSSIBLY_UNUSED pmu_ldo_hppa_get_volt(unsigned short *normal_vp,
|
|
unsigned short *dsleep_vp) {
|
|
uint16_t val;
|
|
|
|
pmu_read(PMU_REG_HPPA_LDO_EN, &val);
|
|
val = GET_BITFIELD(val, REG_RES_SEL_VHPPA);
|
|
if (normal_vp) {
|
|
*normal_vp = val;
|
|
}
|
|
if (dsleep_vp) {
|
|
*dsleep_vp = val;
|
|
}
|
|
}
|
|
|
|
static void pmu_ldo_hppa_set_volt(unsigned short normal_v,
|
|
unsigned short dsleep_v) {
|
|
uint16_t val;
|
|
|
|
pmu_read(PMU_REG_HPPA_LDO_EN, &val);
|
|
val = SET_BITFIELD(val, REG_RES_SEL_VHPPA, normal_v);
|
|
pmu_write(PMU_REG_HPPA_LDO_EN, val);
|
|
}
|
|
|
|
static void pmu_ldo_hppa_en(int enable) {
|
|
uint16_t val;
|
|
|
|
pmu_read(PMU_REG_HPPA_LDO_EN, &val);
|
|
if (enable) {
|
|
val |= (REG_PU_LDO_VHPPA_DSLEEP | REG_PU_LDO_VHPPA_EN);
|
|
} else {
|
|
val &= ~(REG_PU_LDO_VHPPA_DSLEEP | REG_PU_LDO_VHPPA_EN);
|
|
}
|
|
pmu_write(PMU_REG_HPPA_LDO_EN, val);
|
|
}
|
|
|
|
#ifndef HPPA_LDO_ON
|
|
static uint32_t pmu_dcdc_hppa_mv_to_val(uint16_t mv) {
|
|
uint32_t val;
|
|
|
|
if (mv == 1600) {
|
|
val = PMU_DCDC_HPPA_1_6V;
|
|
} else if (mv == 1700) {
|
|
val = PMU_DCDC_HPPA_1_7V;
|
|
} else if (mv == 1900) {
|
|
val = PMU_DCDC_HPPA_1_9V;
|
|
} else if (mv >= 1950) {
|
|
val = PMU_DCDC_HPPA_1_95V;
|
|
} else {
|
|
val = PMU_DCDC_HPPA_1_8V;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
static void pmu_dcdc_hppa_get_volt(unsigned short *normal_vp,
|
|
unsigned short *dsleep_vp) {
|
|
unsigned short val;
|
|
|
|
pmu_read(PMU_REG_DCDC_HPPA_VOLT, &val);
|
|
if (normal_vp) {
|
|
*normal_vp = GET_BITFIELD(val, REG_DCDC3_VBIT_NORMAL);
|
|
}
|
|
if (dsleep_vp) {
|
|
*dsleep_vp = GET_BITFIELD(val, REG_DCDC3_VBIT_DSLEEP);
|
|
}
|
|
|
|
#ifdef PMU_DCDC_CALIB
|
|
if (normal_vp) {
|
|
*normal_vp =
|
|
pmu_reg_val_add(*normal_vp, -pmu_dcdc_hppa_comp, MAX_DCDC3_VBIT_VAL);
|
|
}
|
|
if (dsleep_vp) {
|
|
*dsleep_vp =
|
|
pmu_reg_val_add(*dsleep_vp, -pmu_dcdc_hppa_comp, MAX_DCDC3_VBIT_VAL);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void pmu_dcdc_hppa_set_volt(unsigned short normal_v,
|
|
unsigned short dsleep_v) {
|
|
unsigned short val;
|
|
|
|
#ifdef PMU_DCDC_CALIB
|
|
normal_v = pmu_reg_val_add(normal_v, pmu_dcdc_hppa_comp, MAX_DCDC3_VBIT_VAL);
|
|
dsleep_v = pmu_reg_val_add(dsleep_v, pmu_dcdc_hppa_comp, MAX_DCDC3_VBIT_VAL);
|
|
#endif
|
|
|
|
pmu_read(PMU_REG_DCDC_HPPA_VOLT, &val);
|
|
val &= ~REG_DCDC3_VBIT_DSLEEP_MASK;
|
|
val &= ~REG_DCDC3_VBIT_NORMAL_MASK;
|
|
val |= REG_DCDC3_VBIT_DSLEEP(dsleep_v);
|
|
val |= REG_DCDC3_VBIT_NORMAL(normal_v);
|
|
pmu_write(PMU_REG_DCDC_HPPA_VOLT, val);
|
|
|
|
if (normal_v > dsleep_v) {
|
|
dcdc_ramp_map |= REG_DCDC3_RAMP_EN;
|
|
} else {
|
|
dcdc_ramp_map &= ~REG_DCDC3_RAMP_EN;
|
|
}
|
|
}
|
|
|
|
static void pmu_dcdc_hppa_en(int enable) {
|
|
uint16_t val;
|
|
|
|
if (enable) {
|
|
pmu_read(PMU_REG_DCDC_HPPA_CFG_1D, &val);
|
|
val |= DCDC3_REG_BYPASS;
|
|
pmu_write(PMU_REG_DCDC_HPPA_CFG_1D, val);
|
|
}
|
|
|
|
pmu_read(PMU_REG_DCDC_HPPA_EN, &val);
|
|
if (enable) {
|
|
#ifdef DCDC_ULP_LP_ON
|
|
val = (val & ~REG_DCDC3_ULP_MODE_NORMAL) | REG_DCDC3_ULP_MODE_DSLEEP |
|
|
REG_PU_DCDC3_DR | REG_PU_DCDC3;
|
|
#else
|
|
val = (val & ~REG_DCDC3_ULP_MODE_NORMAL) | REG_PU_DCDC3_DR | REG_PU_DCDC3;
|
|
#endif
|
|
} else {
|
|
val = (val & ~(REG_DCDC3_ULP_MODE_NORMAL | REG_PU_DCDC3)) | REG_PU_DCDC3_DR;
|
|
}
|
|
pmu_write(PMU_REG_DCDC_HPPA_EN, val);
|
|
|
|
if (enable) {
|
|
hal_sys_timer_delay_us(PMU_DCDC_PU_STABLE_TIME_US);
|
|
pmu_read(PMU_REG_DCDC_HPPA_CFG_1D, &val);
|
|
val &= ~DCDC3_REG_BYPASS;
|
|
pmu_write(PMU_REG_DCDC_HPPA_CFG_1D, val);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static uint32_t pmu_vhppa_mv_to_val(uint16_t mv) {
|
|
#ifdef HPPA_LDO_ON
|
|
return pmu_ldo_hppa_mv_to_val(mv);
|
|
#else
|
|
return pmu_dcdc_hppa_mv_to_val(mv);
|
|
#endif
|
|
}
|
|
|
|
static void POSSIBLY_UNUSED pmu_hppa_get_volt(unsigned short *normal_vp,
|
|
unsigned short *dsleep_vp) {
|
|
#ifdef HPPA_LDO_ON
|
|
pmu_ldo_hppa_get_volt(normal_vp, dsleep_vp);
|
|
#else
|
|
pmu_dcdc_hppa_get_volt(normal_vp, dsleep_vp);
|
|
#endif
|
|
}
|
|
|
|
static void pmu_hppa_set_volt(unsigned short normal_v,
|
|
unsigned short dsleep_v) {
|
|
#ifdef HPPA_LDO_ON
|
|
pmu_ldo_hppa_set_volt(normal_v, dsleep_v);
|
|
#else
|
|
pmu_dcdc_hppa_set_volt(normal_v, dsleep_v);
|
|
#endif
|
|
}
|
|
|
|
static void pmu_hppa_en(int enable) {
|
|
#ifdef HPPA_LDO_ON
|
|
pmu_ldo_hppa_en(enable);
|
|
#else
|
|
pmu_dcdc_hppa_en(enable);
|
|
#endif
|
|
}
|
|
|
|
static void pmu_hppa_dcdc_to_ldo(void) {
|
|
#ifndef HPPA_LDO_ON
|
|
uint16_t val;
|
|
uint16_t act_volt;
|
|
|
|
pmu_ldo_hppa_en(true);
|
|
|
|
val = pmu_dcdc_hppa_mv_to_val(vhppa_mv);
|
|
pmu_dcdc_hppa_get_volt(&act_volt, NULL);
|
|
if (val < act_volt) {
|
|
val = pmu_ldo_hppa_mv_to_val(HPPA_RAMP_UP_VOLT_MV);
|
|
} else {
|
|
val = pmu_ldo_hppa_mv_to_val(vhppa_mv);
|
|
}
|
|
pmu_ldo_hppa_set_volt(val, val);
|
|
|
|
hal_sys_timer_delay_us(PMU_LDO_PU_STABLE_TIME_US);
|
|
#endif
|
|
}
|
|
|
|
static void BOOT_TEXT_FLASH_LOC pmu_dig_init_volt(void) {
|
|
uint16_t ldo_volt;
|
|
uint16_t val;
|
|
|
|
pmu_dig_get_target_volt(&ldo_volt, NULL);
|
|
|
|
pmu_read(PMU_REG_DIG_CFG, &val);
|
|
if (GET_BITFIELD(val, LDO_DIG_VBIT_NORMAL) < ldo_volt) {
|
|
val = SET_BITFIELD(val, LDO_DIG_VBIT_NORMAL, ldo_volt);
|
|
pmu_write(PMU_REG_DIG_CFG, val);
|
|
}
|
|
}
|
|
|
|
int pmu_codec_volt_ramp_up(void) {
|
|
#ifndef VMEM_ON
|
|
unsigned short normal, dsleep;
|
|
unsigned short target;
|
|
const unsigned short step =
|
|
#ifdef HPPA_LDO_ON
|
|
1;
|
|
#else
|
|
8;
|
|
#endif
|
|
|
|
if (vcodec_off) {
|
|
target = pmu_vhppa_mv_to_val(HPPA_RAMP_UP_VOLT_MV);
|
|
|
|
pmu_hppa_get_volt(&normal, &dsleep);
|
|
|
|
if (normal < target) {
|
|
if (normal + step < target) {
|
|
normal += step;
|
|
} else {
|
|
normal = target;
|
|
}
|
|
|
|
pmu_hppa_set_volt(normal, dsleep);
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
int pmu_codec_volt_ramp_down(void) {
|
|
#ifndef VMEM_ON
|
|
unsigned short normal, dsleep;
|
|
unsigned short target;
|
|
const unsigned short step =
|
|
#ifdef HPPA_LDO_ON
|
|
1;
|
|
#else
|
|
8;
|
|
#endif
|
|
|
|
if (vcodec_off) {
|
|
target = pmu_vhppa_mv_to_val(vhppa_mv);
|
|
|
|
pmu_hppa_get_volt(&normal, &dsleep);
|
|
|
|
if (normal > target) {
|
|
if (normal - step > target) {
|
|
normal -= step;
|
|
} else {
|
|
normal = target;
|
|
}
|
|
|
|
pmu_hppa_set_volt(normal, dsleep);
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
int BOOT_TEXT_FLASH_LOC pmu_open(void) {
|
|
#if defined(PMU_INIT) || (!defined(PROGRAMMER))
|
|
|
|
uint16_t val;
|
|
enum PMU_POWER_MODE_T mode;
|
|
enum PMU_MODUAL_T codec;
|
|
|
|
ASSERT(!vcodec_off || vcodec_mv == vhppa_mv,
|
|
"Invalid vcodec/vhppa cfg: vcodec_off=%d vcodec_mv=%u vhppa_mv=%u",
|
|
vcodec_off, vcodec_mv, vhppa_mv);
|
|
ASSERT(vcodec_mv == 1600 || vcodec_mv == 1700 || vcodec_mv == 1800 ||
|
|
vcodec_mv == 1900 || vcodec_mv == 1950,
|
|
"Invalid vcodec cfg: vcodec_mv=%u", vcodec_mv);
|
|
ASSERT(vhppa_mv == 1600 || vhppa_mv == 1700 || vhppa_mv == 1800 ||
|
|
vhppa_mv == 1900 || vhppa_mv == 1950,
|
|
"Invalid vhppa cfg: vhppa_mv=%u", vhppa_mv);
|
|
|
|
// Disable and clear all PMU irqs by default
|
|
pmu_write(PMU_REG_INT_MASK, 0);
|
|
pmu_write(PMU_REG_INT_EN, 0);
|
|
// PMU irqs cannot be cleared by PMU soft reset
|
|
pmu_read(PMU_REG_CHARGER_STATUS, &val);
|
|
pmu_write(PMU_REG_CHARGER_STATUS, val);
|
|
pmu_read(PMU_REG_INT_STATUS, &val);
|
|
pmu_write(PMU_REG_INT_CLR, val);
|
|
|
|
pmu_read(PMU_REG_POWER_KEY_CFG, &val);
|
|
// Allow PMU to sleep when power key is pressed
|
|
val &= ~POWERKEY_WAKEUP_OSC_EN;
|
|
// Increase big bandgap startup time (stable time)
|
|
val = SET_BITFIELD(val, REG_VCORE_SSTIME_MODE, 2);
|
|
pmu_write(PMU_REG_POWER_KEY_CFG, val);
|
|
|
|
#ifdef FORCE_BIG_BANDGAP
|
|
// Force big bandgap
|
|
pmu_read(PMU_REG_INT_EN, &val);
|
|
val |= REG_BG_SLEEP_MSK;
|
|
pmu_write(PMU_REG_INT_EN, val);
|
|
pmu_read(PMU_REG_BIAS_CFG, &val);
|
|
val |= BG_CONSTANT_GM_BIAS_DR | BG_CONSTANT_GM_BIAS_REG;
|
|
val |= BG_CORE_EN_DR | BG_CORE_EN_REG;
|
|
pmu_write(PMU_REG_BIAS_CFG, val);
|
|
hal_sys_timer_delay_us(20);
|
|
val |= BG_VBG_SEL_DR | BG_VBG_SEL_REG;
|
|
pmu_write(PMU_REG_BIAS_CFG, val);
|
|
#else
|
|
// Allow low power bandgap
|
|
pmu_read(PMU_REG_BIAS_CFG, &val);
|
|
val &= ~BG_VBG_SEL_DR;
|
|
pmu_write(PMU_REG_BIAS_CFG, val);
|
|
#endif
|
|
|
|
// Init DCDC settings part 1
|
|
if (pmu_metal_id >= HAL_CHIP_METAL_ID_1) {
|
|
pmu_write(PMU_REG_DCDC_ANA_CFG_16, 0x8E0F);
|
|
pmu_write(PMU_REG_DCDC_ANA_CFG_17, 0x0211);
|
|
pmu_write(PMU_REG_DCDC_ANA_CFG_18, 0xA484);
|
|
pmu_write(PMU_REG_DCDC_ANA_CFG_19, 0xE210);
|
|
|
|
pmu_write(PMU_REG_DCDC_HPPA_CFG_1A, 0x8E0F);
|
|
pmu_write(PMU_REG_DCDC_HPPA_CFG_1B, 0x0211);
|
|
pmu_write(PMU_REG_DCDC_HPPA_CFG_1C, 0xA484);
|
|
pmu_write(PMU_REG_DCDC_HPPA_CFG_1D, 0xE210);
|
|
|
|
pmu_write(PMU_REG_DCDC_DIG_CFG_33, 0x8E0F);
|
|
pmu_write(PMU_REG_DCDC_DIG_CFG_34, 0x0211);
|
|
pmu_write(PMU_REG_DCDC_DIG_CFG_35, 0xA484);
|
|
pmu_write(PMU_REG_DCDC_DIG_CFG_36, 0xE210);
|
|
|
|
pmu_read(PMU_REG_MIC_LDO_EN, &val);
|
|
val |= DCDC1_OFFSET_CURRENT_EN;
|
|
pmu_write(PMU_REG_MIC_LDO_EN, val);
|
|
|
|
pmu_read(PMU_REG_DCDC1_OFFSET, &val);
|
|
val = SET_BITFIELD(val, DCDC1_OFFSET_BIT, 0xE0);
|
|
pmu_write(PMU_REG_DCDC1_OFFSET, val);
|
|
}
|
|
|
|
#ifdef PMU_DCDC_CALIB
|
|
pmu_get_dcdc_calib_value();
|
|
#endif
|
|
|
|
#ifndef NO_SLEEP
|
|
pmu_sleep_en(true);
|
|
#endif
|
|
|
|
// Disable vbat2vcore
|
|
pmu_module_config(PMU_BAT2DIG, PMU_MANUAL_MODE, PMU_LDO_OFF, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
#ifdef LBRT
|
|
// Enable vbuck2ana
|
|
pmu_module_config(PMU_BUCK2ANA, PMU_MANUAL_MODE, PMU_LDO_ON, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_ON);
|
|
pmu_module_set_volt(PMU_BUCK2ANA, PMU_VBUCK2ANA_1_3V, PMU_VBUCK2ANA_1_3V);
|
|
// Disable vana dcdc
|
|
pmu_read(PMU_REG_HPPA_LDO_EN, &val);
|
|
val &= ~REG_BYPASS_VBUCK2ANA;
|
|
pmu_write(PMU_REG_HPPA_LDO_EN, val);
|
|
#else
|
|
// Disable vbuck2ana
|
|
pmu_module_config(PMU_BUCK2ANA, PMU_MANUAL_MODE, PMU_LDO_OFF, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
#endif
|
|
|
|
// Disable vhppa ldo
|
|
pmu_ldo_hppa_en(false);
|
|
|
|
#ifdef VMEM_ON
|
|
pmu_module_config(PMU_MEM, PMU_MANUAL_MODE, PMU_LDO_ON, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_ON);
|
|
pmu_module_ramp_volt(PMU_MEM, PMU_VMEM_1_8V, PMU_VMEM_1_8V);
|
|
pmu_hppa_en(false);
|
|
// VHPPA will be enabled/disabled dynamically. Enable soft start.
|
|
pmu_read(PMU_REG_DCDC_HPPA_CFG_1D, &val);
|
|
val |= DCDC3_SOFT_START_EN;
|
|
pmu_write(PMU_REG_DCDC_HPPA_CFG_1D, val);
|
|
#else
|
|
// vmem and vhppa is shorted -- enable vhppa dcdc and disable vmem ldo
|
|
val = pmu_vhppa_mv_to_val(1800);
|
|
pmu_hppa_set_volt(val, val);
|
|
pmu_hppa_en(true);
|
|
pmu_module_config(PMU_MEM, PMU_MANUAL_MODE, PMU_LDO_OFF, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
#endif
|
|
|
|
pmu_module_config(PMU_GP, PMU_MANUAL_MODE, PMU_LDO_OFF, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
|
|
#ifndef PROGRAMMER
|
|
#ifdef VUSB_ON
|
|
pmu_vusb_req |= PMU_VUSB_REQ_INIT;
|
|
#endif
|
|
// Disable usbphy power, and vusb if possible
|
|
pmu_usb_config(PMU_USB_CONFIG_TYPE_NONE);
|
|
#ifdef VUSB_ON
|
|
pmu_vusb_req &= ~PMU_VUSB_REQ_INIT;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef __BEST_FLASH_VIA_ANA__
|
|
pmu_module_config(PMU_IO, PMU_AUTO_MODE, PMU_LDO_ON, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
#else
|
|
pmu_module_config(PMU_IO, PMU_AUTO_MODE, PMU_LDO_ON, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_ON);
|
|
#endif
|
|
pmu_module_ramp_volt(PMU_IO, vio_lp, vio_act_normal);
|
|
|
|
// Disable vcodec
|
|
pmu_module_config(PMU_CODEC, PMU_MANUAL_MODE, PMU_LDO_OFF, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
// Disable vhppa2vcodec
|
|
pmu_module_config(PMU_HPPA2CODEC, PMU_MANUAL_MODE, PMU_LDO_OFF,
|
|
PMU_LP_MODE_ON, PMU_DSLEEP_MODE_OFF);
|
|
#ifdef VHPPA2VCODEC
|
|
codec = PMU_HPPA2CODEC;
|
|
#else
|
|
codec = PMU_CODEC;
|
|
#endif
|
|
val = pmu_vcodec_mv_to_val(vcodec_mv);
|
|
// No need to ramp because the LDO is disabled (and its soft start is enabled)
|
|
pmu_module_set_volt(codec, val, val);
|
|
|
|
val = pmu_vhppa_mv_to_val(vhppa_mv);
|
|
#ifdef VMEM_ON
|
|
// No need to ramp because VHPPA is disabled (and its soft start is enabled)
|
|
pmu_hppa_set_volt(val, val);
|
|
#else
|
|
uint16_t old_act_volt;
|
|
uint16_t old_lp_volt;
|
|
|
|
// VHPPA is on. Ramp is needed.
|
|
pmu_hppa_get_volt(&old_act_volt, &old_lp_volt);
|
|
if (old_act_volt < val) {
|
|
while (old_act_volt++ < val) {
|
|
pmu_hppa_set_volt(old_act_volt, val);
|
|
}
|
|
} else if (old_act_volt != val || old_lp_volt != val) {
|
|
pmu_hppa_set_volt(val, val);
|
|
}
|
|
#endif
|
|
|
|
#ifdef DIG_DCDC_MODE
|
|
mode = PMU_POWER_MODE_DIG_DCDC;
|
|
#elif defined(ANA_DCDC_MODE)
|
|
mode = PMU_POWER_MODE_ANA_DCDC;
|
|
#else // LDO_MODE
|
|
mode = PMU_POWER_MODE_LDO;
|
|
#endif
|
|
|
|
pmu_mode_change(mode);
|
|
|
|
#ifdef RTC_ENABLE
|
|
pmu_rtc_restore_context();
|
|
#endif
|
|
|
|
#if defined(MCU_HIGH_PERFORMANCE_MODE)
|
|
// Increase bbpll voltage
|
|
pmu_write(0xA0, 0x3FE8); // div=2 (bit14=0)
|
|
pmu_write(0xA1, 0xF918);
|
|
|
|
pmu_high_performance_mode_enable(true);
|
|
#endif
|
|
|
|
// Init DCDC settings part 2
|
|
if (pmu_metal_id >= HAL_CHIP_METAL_ID_1) {
|
|
hal_sys_timer_delay_us(5000);
|
|
pmu_write(PMU_REG_DCDC_ANA_CFG_16, 0x8E1F);
|
|
pmu_write(PMU_REG_DCDC_HPPA_CFG_1A, 0x8E1F);
|
|
pmu_write(PMU_REG_DCDC_DIG_CFG_33, 0x8E1F);
|
|
}
|
|
#endif // PMU_INIT || (!PROGRAMMER)
|
|
|
|
return 0;
|
|
}
|
|
|
|
void pmu_codec_vad_save_power(void) {
|
|
uint16_t val;
|
|
|
|
// reduce ldo power supply
|
|
pmu_read(PMU_REG_DCDC_RAMP_EN, &val);
|
|
val &= ~REG_MIC_BIASA_IX2;
|
|
pmu_write(PMU_REG_DCDC_RAMP_EN, val);
|
|
|
|
// enable dcdc1 low power mode
|
|
pmu_read(PMU_REG_DCDC_DIG_EN, &val);
|
|
val |= REG_DCDC1_ULP_MODE_NORMAL;
|
|
pmu_write(PMU_REG_DCDC_DIG_EN, val);
|
|
|
|
// enable dcdc2 low power mode
|
|
pmu_read(PMU_REG_DCDC_ANA_EN, &val);
|
|
val |= REG_DCDC2_ULP_MODE_NORMAL;
|
|
pmu_write(PMU_REG_DCDC_ANA_EN, val);
|
|
|
|
// enable dcdc3 low power mode
|
|
pmu_read(PMU_REG_DCDC_HPPA_EN, &val);
|
|
val |= REG_DCDC3_ULP_MODE_NORMAL;
|
|
pmu_write(PMU_REG_DCDC_HPPA_EN, val);
|
|
}
|
|
|
|
void pmu_codec_vad_restore_power(void) {
|
|
uint16_t val;
|
|
|
|
// restore ldo power supply
|
|
pmu_read(PMU_REG_DCDC_RAMP_EN, &val);
|
|
val |= REG_MIC_BIASA_IX2;
|
|
pmu_write(PMU_REG_DCDC_RAMP_EN, val);
|
|
|
|
// disable dcdc1 low power mode
|
|
pmu_read(PMU_REG_DCDC_DIG_EN, &val);
|
|
val &= ~REG_DCDC1_ULP_MODE_NORMAL;
|
|
pmu_write(PMU_REG_DCDC_DIG_EN, val);
|
|
|
|
// disable dcdc2 low power mode
|
|
pmu_read(PMU_REG_DCDC_ANA_EN, &val);
|
|
val &= ~REG_DCDC2_ULP_MODE_NORMAL;
|
|
pmu_write(PMU_REG_DCDC_ANA_EN, val);
|
|
|
|
// disable dcdc3 low power mode
|
|
pmu_read(PMU_REG_DCDC_HPPA_EN, &val);
|
|
val &= ~REG_DCDC3_ULP_MODE_NORMAL;
|
|
pmu_write(PMU_REG_DCDC_HPPA_EN, val);
|
|
}
|
|
|
|
void pmu_sleep(void) {
|
|
uint16_t val;
|
|
|
|
if (dcdc_ramp_map) {
|
|
// Enable DCDC ramp
|
|
pmu_read(PMU_REG_DCDC_RAMP_EN, &val);
|
|
val |= dcdc_ramp_map;
|
|
pmu_write(PMU_REG_DCDC_RAMP_EN, val);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void pmu_wakeup(void) {
|
|
uint16_t val;
|
|
|
|
if (dcdc_ramp_map) {
|
|
// Disable DCDC ramp so that s/w can control the voltages freely
|
|
pmu_read(PMU_REG_DCDC_RAMP_EN, &val);
|
|
val &= ~dcdc_ramp_map;
|
|
pmu_write(PMU_REG_DCDC_RAMP_EN, val);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void pmu_codec_config(int enable) {
|
|
enum PMU_MODUAL_T codec;
|
|
|
|
#ifdef VHPPA2VCODEC
|
|
codec = PMU_HPPA2CODEC;
|
|
#else
|
|
codec = PMU_CODEC;
|
|
#endif
|
|
|
|
if (vcodec_off) {
|
|
#ifdef VMEM_ON
|
|
pmu_hppa_en(enable);
|
|
#endif
|
|
} else {
|
|
if (enable) {
|
|
pmu_module_config(codec, PMU_MANUAL_MODE, PMU_LDO_ON, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
} else {
|
|
pmu_module_config(codec, PMU_MANUAL_MODE, PMU_LDO_OFF, PMU_LP_MODE_ON,
|
|
PMU_DSLEEP_MODE_OFF);
|
|
}
|
|
}
|
|
}
|
|
|
|
void pmu_codec_hppa_enable(int enable) {
|
|
if (!vcodec_off) {
|
|
#ifdef VMEM_ON
|
|
pmu_hppa_en(enable);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static uint32_t mic_bias_remap(uint32_t map) {
|
|
// The vmic1 pin has been replaced by the vmic3 pin in package bonding for all
|
|
// chip models since ver-B
|
|
if (hal_get_chip_metal_id() >= HAL_CHIP_METAL_ID_1) {
|
|
if (map & AUD_VMIC_MAP_VMIC1) {
|
|
map = (map & ~AUD_VMIC_MAP_VMIC1) | AUD_VMIC_MAP_VMIC3;
|
|
}
|
|
}
|
|
|
|
return map;
|
|
}
|
|
|
|
void pmu_codec_mic_bias_enable(uint32_t map) {
|
|
uint16_t val;
|
|
int i;
|
|
enum PMU_REG_T bias_reg;
|
|
uint16_t ldo_en;
|
|
uint8_t volt;
|
|
uint8_t res;
|
|
static const uint16_t ldo_mask = REG_MIC_LDOA_EN | REG_MIC_LDOB_EN |
|
|
REG_MIC_LDOC_EN | REG_MIC_LDOD_EN |
|
|
REG_MIC_LDOE_EN;
|
|
|
|
map = mic_bias_remap(map);
|
|
|
|
#ifdef DIGMIC_HIGH_VOLT
|
|
volt = PMU_VMIC_3_3V;
|
|
#else
|
|
volt = PMU_VMIC_2_2V;
|
|
#endif
|
|
|
|
if (vcodec_mv < 1900) {
|
|
if (volt >= 0x1F) {
|
|
volt = 0x1F;
|
|
} else {
|
|
volt += 1;
|
|
}
|
|
}
|
|
|
|
res = PMU_VMIC_RES_3_3V;
|
|
|
|
ldo_en = 0;
|
|
for (i = 0; i < MAX_ANA_MIC_CH_NUM; i++) {
|
|
if (i == MAX_ANA_MIC_CH_NUM - 1) {
|
|
bias_reg = PMU_REG_MIC_BIAS_E;
|
|
} else {
|
|
bias_reg = PMU_REG_MIC_BIAS_A + i;
|
|
}
|
|
pmu_read(bias_reg, &val);
|
|
if (map & (AUD_VMIC_MAP_VMIC1 << i)) {
|
|
ldo_en |= (REG_MIC_LDOA_EN >> i);
|
|
val = (val & ~(REG_MIC_BIASA_VSEL_MASK | REG_MIC_LDOA_RES_MASK)) |
|
|
REG_MIC_BIASA_VSEL(volt) | REG_MIC_LDOA_RES(res) | REG_MIC_BIASA_EN;
|
|
} else {
|
|
val &= ~REG_MIC_BIASA_EN;
|
|
}
|
|
pmu_write(bias_reg, val);
|
|
}
|
|
pmu_read(PMU_REG_MIC_LDO_EN, &val);
|
|
val = (val & ~ldo_mask) | ldo_en;
|
|
pmu_write(PMU_REG_MIC_LDO_EN, val);
|
|
}
|
|
|
|
void pmu_codec_mic_bias_lowpower_mode(uint32_t map) {
|
|
uint16_t val;
|
|
|
|
map = mic_bias_remap(map);
|
|
|
|
if (map & AUD_VMIC_MAP_VMIC3) {
|
|
pmu_read(PMU_REG_DCDC_RAMP_EN, &val);
|
|
val &= ~REG_MIC_BIASC_IX2;
|
|
pmu_write(PMU_REG_DCDC_RAMP_EN, val);
|
|
|
|
pmu_read(PMU_REG_MIC_BIAS_C, &val);
|
|
val = SET_BITFIELD(val, REG_MIC_BIASC_CHANSEL, 0x3);
|
|
pmu_write(PMU_REG_MIC_BIAS_C, val);
|
|
}
|
|
}
|
|
|
|
void pmu_codec_adc_pre_start(void) {}
|
|
|
|
void pmu_codec_adc_post_start(void (*delay_ms)(uint32_t)) {}
|
|
|
|
void pmu_codec_dac_pre_start(void) {}
|
|
|
|
void pmu_codec_dac_post_start(void (*delay_ms)(uint32_t)) {}
|
|
|
|
SRAM_TEXT_LOC void pmu_flash_write_config(void) {
|
|
#ifdef FLASH_WRITE_AT_HIGH_VCORE
|
|
uint32_t lock;
|
|
|
|
if (pmu_vcore_req & PMU_VCORE_FLASH_WRITE_ENABLED) {
|
|
return;
|
|
}
|
|
|
|
#if defined(__PMU_VIO_DYNAMIC_CTRL_MODE__)
|
|
pmu_viorise_req(PMU_VIORISE_REQ_USER_FLASH, true);
|
|
#endif
|
|
|
|
lock = int_lock();
|
|
pmu_vcore_req |= PMU_VCORE_FLASH_WRITE_ENABLED;
|
|
int_unlock(lock);
|
|
|
|
pmu_dig_set_volt(0, PMU_POWER_MODE_NONE);
|
|
#endif
|
|
}
|
|
|
|
SRAM_TEXT_LOC void pmu_flash_read_config(void) {
|
|
#ifdef FLASH_WRITE_AT_HIGH_VCORE
|
|
uint32_t lock;
|
|
|
|
if ((pmu_vcore_req & PMU_VCORE_FLASH_WRITE_ENABLED) == 0) {
|
|
return;
|
|
}
|
|
|
|
lock = int_lock();
|
|
pmu_vcore_req &= ~PMU_VCORE_FLASH_WRITE_ENABLED;
|
|
int_unlock(lock);
|
|
|
|
pmu_dig_set_volt(0, PMU_POWER_MODE_NONE);
|
|
|
|
#if defined(__PMU_VIO_DYNAMIC_CTRL_MODE__)
|
|
pmu_viorise_req(PMU_VIORISE_REQ_USER_FLASH, false);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
void BOOT_TEXT_FLASH_LOC pmu_flash_freq_config(uint32_t freq) {
|
|
#if defined(PMU_INIT) || (!defined(PROGRAMMER))
|
|
uint32_t lock;
|
|
|
|
lock = int_lock();
|
|
if (freq > 52000000) {
|
|
// The real max freq is 120M
|
|
// pmu_vcore_req |= PMU_VCORE_FLASH_FREQ_HIGH;
|
|
} else {
|
|
pmu_vcore_req &= ~PMU_VCORE_FLASH_FREQ_HIGH;
|
|
}
|
|
int_unlock(lock);
|
|
|
|
if (pmu_power_mode == PMU_POWER_MODE_NONE) {
|
|
// PMU not init yet
|
|
pmu_dig_init_volt();
|
|
return;
|
|
}
|
|
|
|
pmu_dig_set_volt(0, PMU_POWER_MODE_NONE);
|
|
#endif
|
|
}
|
|
|
|
void BOOT_TEXT_FLASH_LOC pmu_psram_freq_config(uint32_t freq) {
|
|
#if defined(PMU_INIT) || (!defined(PROGRAMMER))
|
|
uint32_t lock;
|
|
|
|
lock = int_lock();
|
|
if (freq > 52000000) {
|
|
pmu_vcore_req |= PMU_VCORE_PSRAM_FREQ_HIGH;
|
|
} else {
|
|
pmu_vcore_req &= ~PMU_VCORE_PSRAM_FREQ_HIGH;
|
|
}
|
|
int_unlock(lock);
|
|
|
|
if (pmu_power_mode == PMU_POWER_MODE_NONE) {
|
|
// PMU not init yet
|
|
pmu_dig_init_volt();
|
|
return;
|
|
}
|
|
|
|
pmu_dig_set_volt(0, PMU_POWER_MODE_NONE);
|
|
#endif
|
|
}
|
|
|
|
void pmu_anc_config(int enable) {}
|
|
|
|
void pmu_fir_high_speed_config(int enable) {}
|
|
|
|
void pmu_iir_freq_config(uint32_t freq) {}
|
|
|
|
void pmu_rs_freq_config(uint32_t freq) {
|
|
uint32_t lock;
|
|
|
|
lock = int_lock();
|
|
if (freq >= 60000000) {
|
|
pmu_vcore_req |= PMU_VCORE_RS_FREQ_HIGH;
|
|
} else {
|
|
pmu_vcore_req &= ~PMU_VCORE_RS_FREQ_HIGH;
|
|
}
|
|
int_unlock(lock);
|
|
|
|
pmu_dig_set_volt(0, PMU_POWER_MODE_NONE);
|
|
}
|
|
|
|
void BOOT_TEXT_SRAM_LOC pmu_sys_freq_config(enum HAL_CMU_FREQ_T freq) {
|
|
#if defined(PMU_INIT) || (!defined(PROGRAMMER))
|
|
#if defined(MCU_HIGH_PERFORMANCE_MODE) || defined(ULTRA_LOW_POWER) || \
|
|
!defined(OSC_26M_X4_AUD2BB)
|
|
uint32_t lock;
|
|
enum PMU_VCORE_REQ_T old_req;
|
|
bool update = false;
|
|
|
|
lock = int_lock();
|
|
old_req = pmu_vcore_req;
|
|
pmu_vcore_req &= ~(PMU_VCORE_SYS_FREQ_HIGH | PMU_VCORE_SYS_FREQ_MEDIUM);
|
|
#if defined(MCU_HIGH_PERFORMANCE_MODE)
|
|
if (freq > HAL_CMU_FREQ_104M) {
|
|
if (high_perf_on) {
|
|
// The real freq is 350M
|
|
pmu_vcore_req |= PMU_VCORE_SYS_FREQ_HIGH;
|
|
} else {
|
|
pmu_vcore_req |= PMU_VCORE_SYS_FREQ_MEDIUM;
|
|
}
|
|
} else {
|
|
#ifndef OSC_26M_X4_AUD2BB
|
|
if (freq == HAL_CMU_FREQ_104M) {
|
|
// The real freq is 200M
|
|
pmu_vcore_req |= PMU_VCORE_SYS_FREQ_MEDIUM;
|
|
}
|
|
#endif
|
|
}
|
|
#else
|
|
if (freq > HAL_CMU_FREQ_104M) {
|
|
pmu_vcore_req |= PMU_VCORE_SYS_FREQ_MEDIUM;
|
|
}
|
|
#endif
|
|
if (old_req != pmu_vcore_req) {
|
|
update = true;
|
|
}
|
|
int_unlock(lock);
|
|
|
|
if (!update) {
|
|
// Nothing changes
|
|
return;
|
|
}
|
|
|
|
if (pmu_power_mode == PMU_POWER_MODE_NONE) {
|
|
// PMU not init yet
|
|
pmu_dig_init_volt();
|
|
return;
|
|
}
|
|
|
|
pmu_dig_set_volt(0, PMU_POWER_MODE_NONE);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
void pmu_high_performance_mode_enable(bool enable) {
|
|
#if defined(MCU_HIGH_PERFORMANCE_MODE)
|
|
uint16_t val;
|
|
|
|
if (high_perf_on == enable) {
|
|
return;
|
|
}
|
|
high_perf_on = enable;
|
|
|
|
if (!enable) {
|
|
if (high_perf_freq_mhz > 300) {
|
|
// Switch to 52M to avoid using PLL
|
|
hal_cmu_sys_set_freq(HAL_CMU_FREQ_52M);
|
|
// Restore the default div
|
|
pmu_read(0xA0, &val);
|
|
val &= ~(1 << 14); // div=2 (bit14=0)
|
|
pmu_write(0xA0, val);
|
|
// Restore the sys freq
|
|
hal_cmu_sys_set_freq(hal_sysfreq_get_hw_freq());
|
|
}
|
|
// Restore the default PLL freq (384M)
|
|
bbpll_freq_pll_config(192 * 1000000 * 2);
|
|
}
|
|
|
|
pmu_sys_freq_config(hal_sysfreq_get_hw_freq());
|
|
|
|
if (enable) {
|
|
uint32_t pll_freq;
|
|
|
|
// Change freq first, and then change divider.
|
|
// Otherwise there will be an instant very high freq sent to digital domain.
|
|
|
|
if (high_perf_freq_mhz <= 300) {
|
|
pll_freq = high_perf_freq_mhz * 1000000 * 2;
|
|
} else {
|
|
pll_freq = high_perf_freq_mhz * 1000000;
|
|
}
|
|
bbpll_freq_pll_config(pll_freq);
|
|
|
|
if (high_perf_freq_mhz > 300) {
|
|
// Switch to 52M to avoid using PLL
|
|
hal_cmu_sys_set_freq(HAL_CMU_FREQ_52M);
|
|
pmu_read(0xA0, &val);
|
|
val |= (1 << 14); // div=1 (bit14=1)
|
|
pmu_write(0xA0, val);
|
|
// Restore the sys freq
|
|
hal_cmu_sys_set_freq(hal_sysfreq_get_hw_freq());
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void pmu_usb_config(enum PMU_USB_CONFIG_TYPE_T type) {
|
|
uint32_t lock;
|
|
bool update;
|
|
unsigned short ldo_on, deep_sleep_on;
|
|
|
|
update = false;
|
|
|
|
if (type == PMU_USB_CONFIG_TYPE_NONE) {
|
|
usbphy_ldo_config(false);
|
|
|
|
ldo_on = PMU_LDO_OFF;
|
|
deep_sleep_on = PMU_DSLEEP_MODE_OFF;
|
|
} else {
|
|
ldo_on = PMU_LDO_ON;
|
|
deep_sleep_on = PMU_DSLEEP_MODE_ON;
|
|
}
|
|
|
|
lock = int_lock();
|
|
|
|
if (type == PMU_USB_CONFIG_TYPE_NONE) {
|
|
pmu_vusb_req &= ~PMU_VUSB_REQ_USB;
|
|
if (pmu_vusb_req == 0) {
|
|
update = true;
|
|
}
|
|
} else {
|
|
if (pmu_vusb_req == 0) {
|
|
update = true;
|
|
}
|
|
pmu_vusb_req |= PMU_VUSB_REQ_USB;
|
|
}
|
|
|
|
if (update) {
|
|
pmu_module_config(PMU_USB, PMU_MANUAL_MODE, ldo_on, PMU_LP_MODE_ON,
|
|
deep_sleep_on);
|
|
}
|
|
|
|
#ifdef USB_HIGH_SPEED
|
|
if (type == PMU_USB_CONFIG_TYPE_NONE) {
|
|
pmu_vcore_req &= ~PMU_VCORE_USB_HS_ENABLED;
|
|
} else {
|
|
pmu_vcore_req |= PMU_VCORE_USB_HS_ENABLED;
|
|
}
|
|
#endif
|
|
|
|
int_unlock(lock);
|
|
|
|
if (pmu_power_mode != PMU_POWER_MODE_NONE) {
|
|
// PMU has been inited
|
|
pmu_dig_set_volt(0, PMU_POWER_MODE_NONE);
|
|
}
|
|
|
|
if (type != PMU_USB_CONFIG_TYPE_NONE) {
|
|
usbphy_ldo_config(true);
|
|
}
|
|
}
|
|
|
|
void pmu_lbrt_config(int enable) {
|
|
uint32_t lock;
|
|
bool update;
|
|
unsigned short ldo_on, deep_sleep_on;
|
|
|
|
update = false;
|
|
|
|
if (enable) {
|
|
ldo_on = PMU_LDO_ON;
|
|
deep_sleep_on = PMU_DSLEEP_MODE_ON;
|
|
} else {
|
|
ldo_on = PMU_LDO_OFF;
|
|
deep_sleep_on = PMU_DSLEEP_MODE_OFF;
|
|
}
|
|
|
|
lock = int_lock();
|
|
|
|
if (enable) {
|
|
if (pmu_vusb_req == 0) {
|
|
update = true;
|
|
}
|
|
pmu_vusb_req |= PMU_VUSB_REQ_LBRT;
|
|
} else {
|
|
pmu_vusb_req &= ~PMU_VUSB_REQ_LBRT;
|
|
if (pmu_vusb_req == 0) {
|
|
update = true;
|
|
}
|
|
}
|
|
|
|
if (update) {
|
|
pmu_module_config(PMU_USB, PMU_MANUAL_MODE, ldo_on, PMU_LP_MODE_ON,
|
|
deep_sleep_on);
|
|
}
|
|
|
|
int_unlock(lock);
|
|
}
|
|
|
|
struct PMU_CHG_CTX_T {
|
|
uint16_t pmu_chg_status;
|
|
};
|
|
|
|
struct PMU_CHG_CTX_T BOOT_BSS_LOC pmu_chg_ctx;
|
|
|
|
void BOOT_TEXT_SRAM_LOC pmu_charger_save_context(void) {
|
|
pmu_read(PMU_REG_CHARGER_STATUS, &pmu_chg_ctx.pmu_chg_status);
|
|
}
|
|
|
|
enum PMU_POWER_ON_CAUSE_T pmu_charger_poweron_status(void) {
|
|
enum PMU_POWER_ON_CAUSE_T pmu_power_on_cause = PMU_POWER_ON_CAUSE_NONE;
|
|
|
|
if (pmu_chg_ctx.pmu_chg_status & AC_ON_DET_OUT) {
|
|
pmu_power_on_cause = PMU_POWER_ON_CAUSE_CHARGER_ACOFF;
|
|
} else if (pmu_chg_ctx.pmu_chg_status & AC_ON) {
|
|
pmu_power_on_cause = PMU_POWER_ON_CAUSE_CHARGER_ACON;
|
|
}
|
|
return pmu_power_on_cause;
|
|
}
|
|
|
|
void pmu_charger_init(void) {
|
|
unsigned short readval_cfg;
|
|
uint32_t lock;
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_CHARGER_CFG, &readval_cfg);
|
|
readval_cfg &= ~(REG_CHARGE_IN_INTR_MSK | REG_CHARGE_OUT_INTR_MSK |
|
|
REG_AC_ON_OUT_EN | REG_AC_ON_IN_EN | REG_CHARGE_INTR_EN);
|
|
pmu_write(PMU_REG_CHARGER_CFG, readval_cfg);
|
|
int_unlock(lock);
|
|
|
|
// PMU irqs cannot be cleared by PMU soft reset
|
|
pmu_read(PMU_REG_CHARGER_STATUS, &readval_cfg);
|
|
pmu_write(PMU_REG_CHARGER_STATUS, readval_cfg);
|
|
pmu_read(PMU_REG_INT_STATUS, &readval_cfg);
|
|
pmu_write(PMU_REG_INT_CLR, readval_cfg);
|
|
|
|
hal_sys_timer_delay(MS_TO_TICKS(1));
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_CHARGER_CFG, &readval_cfg);
|
|
readval_cfg |= REG_AC_ON_OUT_EN | REG_AC_ON_IN_EN | REG_CHARGE_INTR_EN;
|
|
readval_cfg = SET_BITFIELD(readval_cfg, REG_AC_ON_DB_VALUE, 8);
|
|
pmu_write(PMU_REG_CHARGER_CFG, readval_cfg);
|
|
int_unlock(lock);
|
|
|
|
#ifdef PMU_ACON_CAUSE_POWER_UP
|
|
pmu_read(0x102, &readval_cfg);
|
|
readval_cfg |= 1;
|
|
pmu_write(0x102, readval_cfg);
|
|
#endif
|
|
}
|
|
|
|
void pmu_charger_shutdown_config(void) {
|
|
#ifdef PMU_ACON_CAUSE_POWER_UP
|
|
pmu_wdt_stop();
|
|
pmu_charger_init();
|
|
#endif
|
|
}
|
|
|
|
static void pmu_charger_irq_handler(uint16_t irq_status) {
|
|
enum PMU_CHARGER_STATUS_T status = PMU_CHARGER_UNKNOWN;
|
|
|
|
PMU_DEBUG_TRACE(3, "%s REG_%02X=0x%04X", __func__, PMU_REG_CHARGER_STATUS,
|
|
irq_status);
|
|
|
|
if ((irq_status & (AC_ON_DET_IN_MASKED | AC_ON_DET_OUT_MASKED)) == 0) {
|
|
PMU_DEBUG_TRACE(1, "%s SKIP", __func__);
|
|
return;
|
|
} else if ((irq_status & (AC_ON_DET_IN_MASKED | AC_ON_DET_OUT_MASKED)) ==
|
|
(AC_ON_DET_IN_MASKED | AC_ON_DET_OUT_MASKED)) {
|
|
PMU_DEBUG_TRACE(1, "%s DITHERING", __func__);
|
|
hal_sys_timer_delay(2);
|
|
} else {
|
|
PMU_DEBUG_TRACE(1, "%s NORMAL", __func__);
|
|
}
|
|
|
|
status = pmu_charger_get_status();
|
|
|
|
if (charger_irq_handler) {
|
|
charger_irq_handler(status);
|
|
}
|
|
}
|
|
|
|
void pmu_charger_set_irq_handler(PMU_CHARGER_IRQ_HANDLER_T handler) {
|
|
uint32_t lock;
|
|
uint16_t val;
|
|
|
|
charger_irq_handler = handler;
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_CHARGER_CFG, &val);
|
|
if (handler) {
|
|
val |= REG_CHARGE_IN_INTR_MSK | REG_CHARGE_OUT_INTR_MSK;
|
|
} else {
|
|
val &= ~(REG_CHARGE_IN_INTR_MSK | REG_CHARGE_OUT_INTR_MSK);
|
|
}
|
|
pmu_write(PMU_REG_CHARGER_CFG, val);
|
|
pmu_set_irq_unified_handler(PMU_IRQ_TYPE_CHARGER,
|
|
handler ? pmu_charger_irq_handler : NULL);
|
|
int_unlock(lock);
|
|
}
|
|
|
|
void pmu_charger_plugin_config(void) {
|
|
if (IO_VOLT_ACTIVE_RISE < PMU_IO_3_1V) {
|
|
vio_act_rise = PMU_IO_3_1V;
|
|
}
|
|
if (IO_VOLT_SLEEP < PMU_IO_3_2V) {
|
|
vio_lp = PMU_IO_3_2V;
|
|
}
|
|
pmu_viorise_req(PMU_VIORISE_REQ_USER_CHARGER, true);
|
|
}
|
|
|
|
void pmu_charger_plugout_config(void) {
|
|
vio_act_rise = IO_VOLT_ACTIVE_RISE;
|
|
vio_lp = IO_VOLT_SLEEP;
|
|
pmu_viorise_req(PMU_VIORISE_REQ_USER_CHARGER, false);
|
|
}
|
|
|
|
enum PMU_CHARGER_STATUS_T pmu_charger_get_status(void) {
|
|
unsigned short readval;
|
|
enum PMU_CHARGER_STATUS_T status;
|
|
|
|
pmu_read(PMU_REG_CHARGER_STATUS, &readval);
|
|
if (readval & AC_ON)
|
|
status = PMU_CHARGER_PLUGIN;
|
|
else
|
|
status = PMU_CHARGER_PLUGOUT;
|
|
|
|
return status;
|
|
}
|
|
|
|
#ifdef RTC_ENABLE
|
|
void pmu_rtc_enable(void) {
|
|
uint16_t readval;
|
|
uint32_t lock;
|
|
|
|
#ifdef SIMU
|
|
// Set RTC counter to 1KHz
|
|
pmu_write(PMU_REG_RTC_DIV_1HZ, 32 - 2);
|
|
#else
|
|
// Set RTC counter to 1Hz
|
|
pmu_write(PMU_REG_RTC_DIV_1HZ, CONFIG_SYSTICK_HZ * 2 - 2);
|
|
#endif
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_POWER_KEY_CFG, &readval);
|
|
readval |= RTC_POWER_ON_EN | PU_LPO_DR | PU_LPO_REG;
|
|
pmu_write(PMU_REG_POWER_KEY_CFG, readval);
|
|
int_unlock(lock);
|
|
}
|
|
|
|
void pmu_rtc_disable(void) {
|
|
uint16_t readval;
|
|
uint32_t lock;
|
|
|
|
pmu_rtc_clear_alarm();
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_POWER_KEY_CFG, &readval);
|
|
readval &= ~(RTC_POWER_ON_EN | PU_LPO_DR);
|
|
pmu_write(PMU_REG_POWER_KEY_CFG, readval);
|
|
int_unlock(lock);
|
|
}
|
|
|
|
int BOOT_TEXT_SRAM_LOC pmu_rtc_enabled(void) {
|
|
uint16_t readval;
|
|
|
|
pmu_read(PMU_REG_POWER_KEY_CFG, &readval);
|
|
|
|
return !!(readval & RTC_POWER_ON_EN);
|
|
}
|
|
|
|
void pmu_rtc_set(uint32_t seconds) {
|
|
uint16_t high, low;
|
|
|
|
// Need 3 seconds to load a new value
|
|
seconds += 3;
|
|
|
|
high = seconds >> 16;
|
|
low = seconds & 0xFFFF;
|
|
|
|
pmu_write(PMU_REG_RTC_LOAD_LOW, low);
|
|
pmu_write(PMU_REG_RTC_LOAD_HIGH, high);
|
|
}
|
|
|
|
uint32_t pmu_rtc_get(void) {
|
|
uint16_t high, low, high2;
|
|
|
|
pmu_read(PMU_REG_RTC_VAL_HIGH, &high);
|
|
pmu_read(PMU_REG_RTC_VAL_LOW, &low);
|
|
// Handle counter wrap
|
|
pmu_read(PMU_REG_RTC_VAL_HIGH, &high2);
|
|
if (high != high2) {
|
|
high = high2;
|
|
pmu_read(PMU_REG_RTC_VAL_LOW, &low);
|
|
}
|
|
|
|
return (high << 16) | low;
|
|
}
|
|
|
|
void pmu_rtc_set_alarm(uint32_t seconds) {
|
|
uint16_t readval;
|
|
uint16_t high, low;
|
|
uint32_t lock;
|
|
|
|
// Need 1 second to raise the interrupt
|
|
if (seconds > 0) {
|
|
seconds -= 1;
|
|
}
|
|
|
|
high = seconds >> 16;
|
|
low = seconds & 0xFFFF;
|
|
|
|
pmu_write(PMU_REG_INT_CLR, RTC_INT1_MSKED);
|
|
|
|
pmu_write(PMU_REG_RTC_MATCH1_LOW, low);
|
|
pmu_write(PMU_REG_RTC_MATCH1_HIGH, high);
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_INT_EN, &readval);
|
|
readval |= RTC_INT_EN_1;
|
|
pmu_write(PMU_REG_INT_EN, readval);
|
|
int_unlock(lock);
|
|
}
|
|
|
|
uint32_t BOOT_TEXT_SRAM_LOC pmu_rtc_get_alarm(void) {
|
|
uint16_t high, low;
|
|
|
|
pmu_read(PMU_REG_RTC_MATCH1_LOW, &low);
|
|
pmu_read(PMU_REG_RTC_MATCH1_HIGH, &high);
|
|
|
|
// Compensate the alarm offset
|
|
return (uint32_t)((high << 16) | low) + 1;
|
|
}
|
|
|
|
void pmu_rtc_clear_alarm(void) {
|
|
uint16_t readval;
|
|
uint32_t lock;
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_INT_EN, &readval);
|
|
readval &= ~RTC_INT_EN_1;
|
|
pmu_write(PMU_REG_INT_EN, readval);
|
|
int_unlock(lock);
|
|
|
|
pmu_write(PMU_REG_INT_CLR, RTC_INT1_MSKED);
|
|
}
|
|
|
|
int BOOT_TEXT_SRAM_LOC pmu_rtc_alarm_status_set(void) {
|
|
uint16_t readval;
|
|
|
|
pmu_read(PMU_REG_INT_EN, &readval);
|
|
|
|
return !!(readval & RTC_INT_EN_1);
|
|
}
|
|
|
|
int pmu_rtc_alarm_alerted() {
|
|
uint16_t readval;
|
|
|
|
pmu_read(PMU_REG_INT_STATUS, &readval);
|
|
|
|
return !!(readval & RTC_INT_1);
|
|
}
|
|
|
|
static void pmu_rtc_irq_handler(uint16_t irq_status) {
|
|
uint32_t seconds;
|
|
|
|
if (irq_status & RTC_INT1_MSKED) {
|
|
pmu_rtc_clear_alarm();
|
|
|
|
if (rtc_irq_handler) {
|
|
seconds = pmu_rtc_get();
|
|
rtc_irq_handler(seconds);
|
|
}
|
|
}
|
|
}
|
|
|
|
void pmu_rtc_set_irq_handler(PMU_RTC_IRQ_HANDLER_T handler) {
|
|
uint16_t readval;
|
|
uint32_t lock;
|
|
|
|
rtc_irq_handler = handler;
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_INT_MASK, &readval);
|
|
if (handler) {
|
|
readval |= RTC_INT1_MSK;
|
|
} else {
|
|
readval &= ~RTC_INT1_MSK;
|
|
}
|
|
pmu_write(PMU_REG_INT_MASK, readval);
|
|
pmu_set_irq_unified_handler(PMU_IRQ_TYPE_RTC,
|
|
handler ? pmu_rtc_irq_handler : NULL);
|
|
int_unlock(lock);
|
|
}
|
|
#endif
|
|
|
|
int pmu_pwrkey_set_irq(enum HAL_PWRKEY_IRQ_T type) {
|
|
uint16_t val;
|
|
uint16_t int_en;
|
|
|
|
if (type == HAL_PWRKEY_IRQ_NONE) {
|
|
// Clear existing IRQs
|
|
pmu_write(PMU_REG_CHARGER_STATUS, (POWER_ON_PRESS | POWER_ON_RELEASE));
|
|
// Disable future IRQs
|
|
int_en = 0;
|
|
} else if (type == HAL_PWRKEY_IRQ_FALLING_EDGE) {
|
|
int_en = POWERON_PRESS_EN;
|
|
} else if (type == HAL_PWRKEY_IRQ_RISING_EDGE) {
|
|
int_en = POWERON_RELEASE_EN;
|
|
} else if (type == HAL_PWRKEY_IRQ_BOTH_EDGE) {
|
|
int_en = POWERON_PRESS_EN | POWERON_RELEASE_EN;
|
|
} else {
|
|
return 1;
|
|
}
|
|
|
|
pmu_read(PMU_REG_SLEEP_CFG, &val);
|
|
val = (val & ~(POWERON_PRESS_EN | POWERON_RELEASE_EN)) | int_en;
|
|
pmu_write(PMU_REG_SLEEP_CFG, val);
|
|
|
|
return 0;
|
|
}
|
|
int hal_pwrkey_set_irq(enum HAL_PWRKEY_IRQ_T type)
|
|
__attribute__((alias("pmu_pwrkey_set_irq")));
|
|
|
|
bool pmu_pwrkey_pressed(void) {
|
|
uint16_t val;
|
|
|
|
pmu_read(PMU_REG_CHARGER_STATUS, &val);
|
|
|
|
return !!(val & POWER_ON);
|
|
}
|
|
bool hal_pwrkey_pressed(void) __attribute__((alias("pmu_pwrkey_pressed")));
|
|
|
|
enum HAL_PWRKEY_IRQ_T pmu_pwrkey_irq_value_to_state(uint16_t irq_status) {
|
|
enum HAL_PWRKEY_IRQ_T state = HAL_PWRKEY_IRQ_NONE;
|
|
|
|
if (irq_status & POWER_ON_PRESS) {
|
|
state |= HAL_PWRKEY_IRQ_FALLING_EDGE;
|
|
}
|
|
|
|
if (irq_status & POWER_ON_RELEASE) {
|
|
state |= HAL_PWRKEY_IRQ_RISING_EDGE;
|
|
}
|
|
|
|
return state;
|
|
}
|
|
|
|
static void pmu_general_irq_handler(void) {
|
|
uint32_t lock;
|
|
uint16_t val;
|
|
bool pwrkey, charger, gpadc, rtc;
|
|
|
|
pwrkey = false;
|
|
charger = false;
|
|
gpadc = false;
|
|
rtc = false;
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_CHARGER_STATUS, &val);
|
|
if (val & (POWER_ON_PRESS | POWER_ON_RELEASE)) {
|
|
pwrkey = true;
|
|
}
|
|
if (val & (AC_ON_DET_OUT_MASKED | AC_ON_DET_IN_MASKED)) {
|
|
charger = true;
|
|
}
|
|
if (pwrkey || charger) {
|
|
pmu_write(PMU_REG_CHARGER_STATUS, val);
|
|
}
|
|
int_unlock(lock);
|
|
|
|
if (pwrkey) {
|
|
if (pmu_irq_hdlrs[PMU_IRQ_TYPE_PWRKEY]) {
|
|
pmu_irq_hdlrs[PMU_IRQ_TYPE_PWRKEY](val);
|
|
}
|
|
}
|
|
if (charger) {
|
|
if (pmu_irq_hdlrs[PMU_IRQ_TYPE_CHARGER]) {
|
|
pmu_irq_hdlrs[PMU_IRQ_TYPE_CHARGER](val);
|
|
}
|
|
}
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_INT_MSKED_STATUS, &val);
|
|
if (val & (KEY_ERR1_INTR_MSKED | KEY_ERR0_INTR_MSKED | KEY_PRESS_INTR_MSKED |
|
|
KEY_RELEASE_INTR_MSKED | SAMPLE_DONE_INTR_MSKED |
|
|
CHAN_DATA_INTR_MSKED_MASK)) {
|
|
gpadc = true;
|
|
}
|
|
if (val & (RTC_INT1_MSKED | RTC_INT0_MSKED)) {
|
|
rtc = true;
|
|
}
|
|
if (gpadc || rtc) {
|
|
pmu_write(PMU_REG_INT_CLR, val);
|
|
}
|
|
int_unlock(lock);
|
|
|
|
if (gpadc) {
|
|
if (pmu_irq_hdlrs[PMU_IRQ_TYPE_GPADC]) {
|
|
pmu_irq_hdlrs[PMU_IRQ_TYPE_GPADC](val);
|
|
}
|
|
}
|
|
if (rtc) {
|
|
if (pmu_irq_hdlrs[PMU_IRQ_TYPE_RTC]) {
|
|
pmu_irq_hdlrs[PMU_IRQ_TYPE_RTC](val);
|
|
}
|
|
}
|
|
}
|
|
|
|
int pmu_set_irq_unified_handler(enum PMU_IRQ_TYPE_T type,
|
|
PMU_IRQ_UNIFIED_HANDLER_T hdlr) {
|
|
bool update;
|
|
uint32_t lock;
|
|
int i;
|
|
|
|
if (type >= PMU_IRQ_TYPE_QTY) {
|
|
return 1;
|
|
}
|
|
|
|
update = false;
|
|
|
|
lock = int_lock();
|
|
|
|
for (i = 0; i < PMU_IRQ_TYPE_QTY; i++) {
|
|
if (pmu_irq_hdlrs[i]) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
pmu_irq_hdlrs[type] = hdlr;
|
|
|
|
if (hdlr) {
|
|
update = (i >= PMU_IRQ_TYPE_QTY);
|
|
} else {
|
|
if (i == type) {
|
|
for (; i < PMU_IRQ_TYPE_QTY; i++) {
|
|
if (pmu_irq_hdlrs[i]) {
|
|
break;
|
|
}
|
|
}
|
|
update = (i >= PMU_IRQ_TYPE_QTY);
|
|
}
|
|
}
|
|
|
|
if (update) {
|
|
if (hdlr) {
|
|
NVIC_SetVector(PMU_IRQn, (uint32_t)pmu_general_irq_handler);
|
|
NVIC_SetPriority(PMU_IRQn, IRQ_PRIORITY_NORMAL);
|
|
NVIC_ClearPendingIRQ(PMU_IRQn);
|
|
NVIC_EnableIRQ(PMU_IRQn);
|
|
} else {
|
|
NVIC_DisableIRQ(PMU_IRQn);
|
|
}
|
|
}
|
|
|
|
int_unlock(lock);
|
|
|
|
return 0;
|
|
}
|
|
|
|
enum PMU_POWER_ON_CAUSE_T pmu_get_power_on_cause(void) {
|
|
enum PMU_POWER_ON_CAUSE_T pmu_power_on_cause = PMU_POWER_ON_CAUSE_NONE;
|
|
|
|
pmu_power_on_cause = pmu_charger_poweron_status();
|
|
if (pmu_power_on_cause == PMU_POWER_ON_CAUSE_NONE) {
|
|
pmu_power_on_cause = PMU_POWER_ON_CAUSE_POWER_KEY;
|
|
}
|
|
|
|
return pmu_power_on_cause;
|
|
}
|
|
|
|
void pmu_viorise_req(enum PMU_VIORISE_REQ_USER_T user, bool rise) {
|
|
uint32_t lock;
|
|
|
|
lock = int_lock();
|
|
if (rise) {
|
|
if (vio_risereq_map == 0) {
|
|
pmu_module_ramp_volt(PMU_IO, vio_lp, vio_act_rise);
|
|
}
|
|
vio_risereq_map |= (1 << user);
|
|
} else {
|
|
vio_risereq_map &= ~(1 << user);
|
|
if (vio_risereq_map == 0) {
|
|
pmu_module_ramp_volt(PMU_IO, vio_lp, vio_act_normal);
|
|
}
|
|
}
|
|
int_unlock(lock);
|
|
}
|
|
|
|
int pmu_debug_config_ana(uint16_t volt) { return 0; }
|
|
|
|
int pmu_debug_config_codec(uint16_t volt) {
|
|
#ifdef ANC_PROD_TEST
|
|
if (volt == 1600 || volt == 1700 || volt == 1800 || volt == 1900 ||
|
|
volt == 1950) {
|
|
vhppa_mv = vcodec_mv = volt;
|
|
vcodec_off = true;
|
|
} else {
|
|
vcodec_off = false;
|
|
return 1;
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
int pmu_debug_config_vcrystal(bool on) { return 0; }
|
|
|
|
int pmu_debug_config_audio_output(bool diff) { return 0; }
|
|
|
|
void pmu_debug_reliability_test(int stage) {
|
|
uint16_t volt;
|
|
|
|
if (stage == 0) {
|
|
volt = PMU_DCDC_ANA_1_2V;
|
|
} else {
|
|
volt = PMU_DCDC_ANA_1_3V;
|
|
}
|
|
pmu_dcdc_ana_set_volt(volt, ana_lp_dcdc);
|
|
}
|
|
|
|
void pmu_led_set_hiz(enum HAL_GPIO_PIN_T pin) {
|
|
uint16_t val1, val2;
|
|
uint32_t lock;
|
|
|
|
if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) {
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_MIC_LDO_EN, &val1);
|
|
pmu_read(PMU_REG_LED_CFG, &val2);
|
|
if (pin == HAL_GPIO_PIN_LED1) {
|
|
val1 &= ~REG_LED_IO1_RX_EN;
|
|
val2 = (val2 | REG_LED_IO1_PU | REG_LED_IO1_OENB) &
|
|
~(REG_LED_IO1_PUEN | REG_LED_IO1_PDEN);
|
|
} else {
|
|
val1 &= ~REG_LED_IO2_RX_EN;
|
|
val2 = (val2 | REG_LED_IO2_PU | REG_LED_IO2_OENB) &
|
|
~(REG_LED_IO2_PUEN | REG_LED_IO2_PDEN);
|
|
}
|
|
pmu_write(PMU_REG_MIC_LDO_EN, val1);
|
|
pmu_write(PMU_REG_LED_CFG, val2);
|
|
int_unlock(lock);
|
|
}
|
|
}
|
|
|
|
void pmu_led_set_direction(enum HAL_GPIO_PIN_T pin, enum HAL_GPIO_DIR_T dir) {
|
|
uint16_t val;
|
|
uint16_t val_rx;
|
|
uint32_t lock;
|
|
|
|
if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) {
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_LED_CFG, &val);
|
|
pmu_read(PMU_REG_MIC_LDO_EN, &val_rx);
|
|
if (pin == HAL_GPIO_PIN_LED1) {
|
|
val |= REG_LED_IO1_PU;
|
|
if (dir == HAL_GPIO_DIR_IN) {
|
|
val |= REG_LED_IO1_OENB;
|
|
val_rx |= REG_LED_IO1_RX_EN;
|
|
} else {
|
|
val &= ~REG_LED_IO1_OENB;
|
|
val_rx &= ~REG_LED_IO1_RX_EN;
|
|
}
|
|
} else {
|
|
val |= REG_LED_IO2_PU;
|
|
if (dir == HAL_GPIO_DIR_IN) {
|
|
val |= REG_LED_IO2_OENB;
|
|
val_rx |= REG_LED_IO2_RX_EN;
|
|
} else {
|
|
val &= ~REG_LED_IO2_OENB;
|
|
val_rx &= ~REG_LED_IO2_RX_EN;
|
|
}
|
|
}
|
|
pmu_write(PMU_REG_LED_CFG, val);
|
|
pmu_write(PMU_REG_MIC_LDO_EN, val_rx);
|
|
;
|
|
int_unlock(lock);
|
|
}
|
|
}
|
|
|
|
enum HAL_GPIO_DIR_T pmu_led_get_direction(enum HAL_GPIO_PIN_T pin) {
|
|
uint16_t val;
|
|
|
|
if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) {
|
|
pmu_read(PMU_REG_LED_CFG, &val);
|
|
if (pin == HAL_GPIO_PIN_LED1) {
|
|
return (val & REG_LED_IO1_OENB) ? HAL_GPIO_DIR_IN : HAL_GPIO_DIR_OUT;
|
|
} else {
|
|
return (val & REG_LED_IO2_OENB) ? HAL_GPIO_DIR_IN : HAL_GPIO_DIR_OUT;
|
|
}
|
|
} else {
|
|
return HAL_GPIO_DIR_IN;
|
|
}
|
|
}
|
|
|
|
void pmu_led_set_voltage_domains(enum HAL_IOMUX_PIN_T pin,
|
|
enum HAL_IOMUX_PIN_VOLTAGE_DOMAINS_T volt) {
|
|
enum PMU_LED_VOLT_T {
|
|
PMU_LED_VOLT_VBAT,
|
|
PMU_LED_VOLT_VMEM,
|
|
PMU_LED_VOLT_VIO,
|
|
};
|
|
enum PMU_LED_VOLT_T sel;
|
|
uint16_t val;
|
|
uint32_t lock;
|
|
|
|
if (pin == HAL_IOMUX_PIN_LED1 || pin == HAL_IOMUX_PIN_LED2) {
|
|
if (volt == HAL_IOMUX_PIN_VOLTAGE_VIO) {
|
|
sel = PMU_LED_VOLT_VIO;
|
|
} else if (volt == HAL_IOMUX_PIN_VOLTAGE_MEM) {
|
|
sel = PMU_LED_VOLT_VMEM;
|
|
} else {
|
|
sel = PMU_LED_VOLT_VBAT;
|
|
}
|
|
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_LED_CFG, &val);
|
|
if (pin == HAL_IOMUX_PIN_LED1) {
|
|
val = SET_BITFIELD(val, REG_LED_IO1_SEL, sel);
|
|
} else {
|
|
val = SET_BITFIELD(val, REG_LED_IO2_SEL, sel);
|
|
}
|
|
pmu_write(PMU_REG_LED_CFG, val);
|
|
int_unlock(lock);
|
|
}
|
|
}
|
|
|
|
void pmu_led_set_pull_select(enum HAL_IOMUX_PIN_T pin,
|
|
enum HAL_IOMUX_PIN_PULL_SELECT_T pull_sel) {
|
|
uint16_t val;
|
|
uint32_t lock;
|
|
|
|
if (pin == HAL_IOMUX_PIN_LED1 || pin == HAL_IOMUX_PIN_LED2) {
|
|
lock = int_lock();
|
|
pmu_read(PMU_REG_LED_CFG, &val);
|
|
if (pin == HAL_IOMUX_PIN_LED1) {
|
|
val &= ~(REG_LED_IO1_PDEN | REG_LED_IO1_PUEN);
|
|
if (pull_sel == HAL_IOMUX_PIN_PULLUP_ENABLE) {
|
|
val |= REG_LED_IO1_PUEN;
|
|
} else if (pull_sel == HAL_IOMUX_PIN_PULLDOWN_ENABLE) {
|
|
val |= REG_LED_IO1_PDEN;
|
|
}
|
|
} else {
|
|
val &= ~(REG_LED_IO2_PDEN | REG_LED_IO2_PUEN);
|
|
if (pull_sel == HAL_IOMUX_PIN_PULLUP_ENABLE) {
|
|
val |= REG_LED_IO2_PUEN;
|
|
} else if (pull_sel == HAL_IOMUX_PIN_PULLDOWN_ENABLE) {
|
|
val |= REG_LED_IO2_PDEN;
|
|
}
|
|
}
|
|
pmu_write(PMU_REG_LED_CFG, val);
|
|
int_unlock(lock);
|
|
}
|
|
}
|
|
|
|
void pmu_led_set_value(enum HAL_GPIO_PIN_T pin, int data) {
|
|
uint16_t val;
|
|
uint32_t lock;
|
|
#ifdef PMU_LED_VIA_PWM
|
|
uint16_t br_val;
|
|
#endif
|
|
if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) {
|
|
lock = int_lock();
|
|
#ifdef PMU_LED_VIA_PWM
|
|
pmu_read(PMU_REG_PWM_BR_EN, &br_val);
|
|
#endif
|
|
pmu_read(PMU_REG_PWM_EN, &val);
|
|
if (pin == HAL_GPIO_PIN_LED1) {
|
|
#ifdef PMU_LED_VIA_PWM
|
|
pmu_write(PMU_REG_PWM2_TOGGLE, 0xFFFF);
|
|
br_val &= ~REG_PWM2_BR_EN;
|
|
val |= PWM_SELECT_EN(1 << 0);
|
|
if (data) {
|
|
val &= ~PWM_SELECT_INV(1 << 0);
|
|
} else {
|
|
val |= PWM_SELECT_INV(1 << 0);
|
|
}
|
|
#else
|
|
if (data) {
|
|
val |= REG_LED0_OUT;
|
|
} else {
|
|
val &= ~REG_LED0_OUT;
|
|
}
|
|
#endif
|
|
} else {
|
|
#ifdef PMU_LED_VIA_PWM
|
|
pmu_write(PMU_REG_PWM3_TOGGLE, 0xFFFF);
|
|
br_val &= ~REG_PWM3_BR_EN;
|
|
val |= PWM_SELECT_EN(1 << 1);
|
|
if (data) {
|
|
val &= ~PWM_SELECT_INV(1 << 1);
|
|
} else {
|
|
val |= PWM_SELECT_INV(1 << 1);
|
|
}
|
|
#else
|
|
if (data) {
|
|
val |= REG_LED1_OUT;
|
|
} else {
|
|
val &= ~REG_LED1_OUT;
|
|
}
|
|
#endif
|
|
}
|
|
#ifdef PMU_LED_VIA_PWM
|
|
pmu_write(PMU_REG_PWM_BR_EN, br_val);
|
|
#endif
|
|
pmu_write(PMU_REG_PWM_EN, val);
|
|
int_unlock(lock);
|
|
}
|
|
}
|
|
|
|
int pmu_led_get_value(enum HAL_GPIO_PIN_T pin) {
|
|
uint16_t val;
|
|
int data = 0;
|
|
|
|
if (pin == HAL_GPIO_PIN_LED1 || pin == HAL_GPIO_PIN_LED2) {
|
|
pmu_read(PMU_REG_POWER_OFF, &val);
|
|
if (pin == HAL_GPIO_PIN_LED1) {
|
|
data = REG_LED_IO1_DATA_IN;
|
|
} else {
|
|
data = REG_LED_IO2_DATA_IN;
|
|
}
|
|
data &= val;
|
|
}
|
|
|
|
return !!data;
|
|
}
|
|
|
|
struct PMU_WDT_CTX_T {
|
|
bool enabled;
|
|
uint16_t wdt_timer;
|
|
uint16_t wdt_cfg;
|
|
};
|
|
|
|
static struct PMU_WDT_CTX_T BOOT_BSS_LOC wdt_ctx;
|
|
|
|
void BOOT_TEXT_SRAM_LOC pmu_wdt_save_context(void) {
|
|
uint16_t wdt_cfg = 0, wdt_timer = 0;
|
|
pmu_read(PMU_REG_WDT_CFG, &wdt_cfg);
|
|
if (wdt_cfg & (REG_WDT_RESET_EN | REG_WDT_EN)) {
|
|
wdt_ctx.enabled = true;
|
|
wdt_ctx.wdt_cfg = wdt_cfg;
|
|
pmu_read(PMU_REG_WDT_TIMER, &wdt_timer);
|
|
wdt_ctx.wdt_timer = wdt_timer;
|
|
}
|
|
}
|
|
|
|
void BOOT_TEXT_SRAM_LOC pmu_wdt_restore_context(void) {
|
|
if (wdt_ctx.enabled) {
|
|
pmu_write(PMU_REG_WDT_TIMER, wdt_ctx.wdt_timer);
|
|
pmu_write(PMU_REG_WDT_CFG, wdt_ctx.wdt_cfg);
|
|
}
|
|
}
|
|
|
|
void pmu_wdt_set_irq_handler(PMU_WDT_IRQ_HANDLER_T handler) {}
|
|
|
|
int pmu_wdt_config(uint32_t irq_ms, uint32_t reset_ms) {
|
|
// No wdt irq on best2300
|
|
if (irq_ms + reset_ms > 0xFFFF) {
|
|
return 1;
|
|
}
|
|
wdt_timer = irq_ms + reset_ms;
|
|
|
|
pmu_write(PMU_REG_WDT_TIMER, wdt_timer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void pmu_wdt_start(void) {
|
|
uint16_t val;
|
|
|
|
if (wdt_timer == 0) {
|
|
return;
|
|
}
|
|
|
|
pmu_read(PMU_REG_WDT_CFG, &val);
|
|
val |= (REG_WDT_RESET_EN | REG_WDT_EN);
|
|
pmu_write(PMU_REG_WDT_CFG, val);
|
|
}
|
|
|
|
void pmu_wdt_stop(void) {
|
|
uint16_t val;
|
|
|
|
if (wdt_timer == 0) {
|
|
return;
|
|
}
|
|
|
|
pmu_read(PMU_REG_WDT_CFG, &val);
|
|
val &= ~(REG_WDT_RESET_EN | REG_WDT_EN);
|
|
pmu_write(PMU_REG_WDT_CFG, val);
|
|
}
|
|
|
|
void pmu_wdt_feed(void) {
|
|
if (wdt_timer == 0) {
|
|
return;
|
|
}
|
|
|
|
pmu_write(PMU_REG_WDT_TIMER, wdt_timer);
|
|
}
|
|
|
|
void pmu_ntc_capture_enable(void) {}
|
|
|
|
void pmu_ntc_capture_disable(void) {}
|