diff --git a/src/target/esp32p4/include/soc/hp_sys_clkrst_reg.h b/src/target/esp32p4/include/soc/hp_sys_clkrst_reg.h index 4ca591de..91e22f63 100644 --- a/src/target/esp32p4/include/soc/hp_sys_clkrst_reg.h +++ b/src/target/esp32p4/include/soc/hp_sys_clkrst_reg.h @@ -57,3 +57,72 @@ #define HP_SYS_CLKRST_REG_APB_CLK_DIV_NUM_M (HP_SYS_CLKRST_REG_APB_CLK_DIV_NUM_V << HP_SYS_CLKRST_REG_APB_CLK_DIV_NUM_S) #define HP_SYS_CLKRST_REG_APB_CLK_DIV_NUM_V 0x000000FFU #define HP_SYS_CLKRST_REG_APB_CLK_DIV_NUM_S 16 + +/** HP_SYS_CLKRST_SOC_CLK_CTRL1_REG register */ +#define HP_SYS_CLKRST_SOC_CLK_CTRL1_REG (DR_REG_HP_SYS_CLKRST_BASE + 0x18) +#define HP_SYS_CLKRST_REG_PVT_SYS_CLK_EN (BIT(25)) +#define HP_SYS_CLKRST_REG_PVT_SYS_CLK_EN_M (HP_SYS_CLKRST_REG_PVT_SYS_CLK_EN_V << HP_SYS_CLKRST_REG_PVT_SYS_CLK_EN_S) +#define HP_SYS_CLKRST_REG_PVT_SYS_CLK_EN_V 0x00000001U +#define HP_SYS_CLKRST_REG_PVT_SYS_CLK_EN_S 25 + +/** HP_SYS_CLKRST_REF_CLK_CTRL2_REG register */ +#define HP_SYS_CLKRST_REF_CLK_CTRL2_REG (DR_REG_HP_SYS_CLKRST_BASE + 0x2c) +#define HP_SYS_CLKRST_REG_REF_160M_CLK_EN (BIT(0)) +#define HP_SYS_CLKRST_REG_REF_160M_CLK_EN_M (HP_SYS_CLKRST_REG_REF_160M_CLK_EN_V << HP_SYS_CLKRST_REG_REF_160M_CLK_EN_S) +#define HP_SYS_CLKRST_REG_REF_160M_CLK_EN_V 0x00000001U +#define HP_SYS_CLKRST_REG_REF_160M_CLK_EN_S 0 + +/** HP_SYS_CLKRST_PERI_CLK_CTRL24_REG register */ +#define HP_SYS_CLKRST_PERI_CLK_CTRL24_REG (DR_REG_HP_SYS_CLKRST_BASE + 0xa4) +#define HP_SYS_CLKRST_REG_PVT_CLK_DIV_NUM 0x000000FFU +#define HP_SYS_CLKRST_REG_PVT_CLK_DIV_NUM_M (HP_SYS_CLKRST_REG_PVT_CLK_DIV_NUM_V << HP_SYS_CLKRST_REG_PVT_CLK_DIV_NUM_S) +#define HP_SYS_CLKRST_REG_PVT_CLK_DIV_NUM_V 0x000000FFU +#define HP_SYS_CLKRST_REG_PVT_CLK_DIV_NUM_S 16 +#define HP_SYS_CLKRST_REG_PVT_CLK_EN (BIT(24)) +#define HP_SYS_CLKRST_REG_PVT_CLK_EN_M (HP_SYS_CLKRST_REG_PVT_CLK_EN_V << HP_SYS_CLKRST_REG_PVT_CLK_EN_S) +#define HP_SYS_CLKRST_REG_PVT_CLK_EN_V 0x00000001U +#define HP_SYS_CLKRST_REG_PVT_CLK_EN_S 24 + +/** HP_SYS_CLKRST_PERI_CLK_CTRL25_REG register */ +#define HP_SYS_CLKRST_PERI_CLK_CTRL25_REG (DR_REG_HP_SYS_CLKRST_BASE + 0xa8) +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP_CLK_DIV_NUM 0x000000FFU +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP_CLK_DIV_NUM_M \ + (HP_SYS_CLKRST_REG_PVT_PERI_GROUP_CLK_DIV_NUM_V << HP_SYS_CLKRST_REG_PVT_PERI_GROUP_CLK_DIV_NUM_S) +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP_CLK_DIV_NUM_V 0x000000FFU +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP_CLK_DIV_NUM_S 0 +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP1_CLK_EN (BIT(8)) +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP1_CLK_EN_M (HP_SYS_CLKRST_REG_PVT_PERI_GROUP1_CLK_EN_V << HP_SYS_CLKRST_REG_PVT_PERI_GROUP1_CLK_EN_S) +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP1_CLK_EN_V 0x00000001U +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP1_CLK_EN_S 8 +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP2_CLK_EN (BIT(9)) +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP2_CLK_EN_M (HP_SYS_CLKRST_REG_PVT_PERI_GROUP2_CLK_EN_V << HP_SYS_CLKRST_REG_PVT_PERI_GROUP2_CLK_EN_S) +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP2_CLK_EN_V 0x00000001U +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP2_CLK_EN_S 9 +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP3_CLK_EN (BIT(10)) +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP3_CLK_EN_M (HP_SYS_CLKRST_REG_PVT_PERI_GROUP3_CLK_EN_V << HP_SYS_CLKRST_REG_PVT_PERI_GROUP3_CLK_EN_S) +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP3_CLK_EN_V 0x00000001U +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP3_CLK_EN_S 10 +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP4_CLK_EN (BIT(11)) +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP4_CLK_EN_M (HP_SYS_CLKRST_REG_PVT_PERI_GROUP4_CLK_EN_V << HP_SYS_CLKRST_REG_PVT_PERI_GROUP4_CLK_EN_S) +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP4_CLK_EN_V 0x00000001U +#define HP_SYS_CLKRST_REG_PVT_PERI_GROUP4_CLK_EN_S 11 + +/** HP_SYS_CLKRST_ANA_PLL_CTRL0_REG register */ +#define HP_SYS_CLKRST_ANA_PLL_CTRL0_REG (DR_REG_HP_SYS_CLKRST_BASE + 0xbc) +/** HP_SYS_CLKRST_REG_CPU_PLL_CAL_END : RO; bitpos: [2] */ +#define HP_SYS_CLKRST_REG_CPU_PLL_CAL_END (BIT(2)) +#define HP_SYS_CLKRST_REG_CPU_PLL_CAL_END_M (HP_SYS_CLKRST_REG_CPU_PLL_CAL_END_V << HP_SYS_CLKRST_REG_CPU_PLL_CAL_END_S) +#define HP_SYS_CLKRST_REG_CPU_PLL_CAL_END_V 0x00000001U +#define HP_SYS_CLKRST_REG_CPU_PLL_CAL_END_S 2 +/** HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP : R/W; bitpos: [3] */ +#define HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP (BIT(3)) +#define HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP_M (HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP_V << HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP_S) +#define HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP_V 0x00000001U +#define HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP_S 3 + +/** HP_SYS_CLKRST_HP_RST_EN0_REG register */ +#define HP_SYS_CLKRST_HP_RST_EN0_REG (DR_REG_HP_SYS_CLKRST_BASE + 0xc0) +#define HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4 (BIT(5)) +#define HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4_M (HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4_V << HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4_S) +#define HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4_V 0x00000001U +#define HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4_S 5 diff --git a/src/target/esp32p4/include/soc/lp_i2c_ana_mst_reg.h b/src/target/esp32p4/include/soc/lp_i2c_ana_mst_reg.h new file mode 100644 index 00000000..1ea9f268 --- /dev/null +++ b/src/target/esp32p4/include/soc/lp_i2c_ana_mst_reg.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + * Minimal LP_I2C_ANA_MST defs for CPLL regi2c writes. + */ + +#pragma once + +#include +#include "reg_base.h" + +/** LP_I2C_ANA_MST_I2C0_CTRL_REG register */ +#define LP_I2C_ANA_MST_I2C0_CTRL_REG (DR_REG_LP_I2C_ANA_MST_BASE + 0x0) + +/** LP_I2C_ANA_MST_ANA_CONF1_REG register */ +#define LP_I2C_ANA_MST_ANA_CONF1_REG (DR_REG_LP_I2C_ANA_MST_BASE + 0x1c) +#define LP_I2C_ANA_MST_ANA_CONF1 0x00FFFFFFU +#define LP_I2C_ANA_MST_ANA_CONF1_M (LP_I2C_ANA_MST_ANA_CONF1_V << LP_I2C_ANA_MST_ANA_CONF1_S) +#define LP_I2C_ANA_MST_ANA_CONF1_V 0x00FFFFFFU +#define LP_I2C_ANA_MST_ANA_CONF1_S 0 + +/** LP_I2C_ANA_MST_ANA_CONF2_REG register */ +#define LP_I2C_ANA_MST_ANA_CONF2_REG (DR_REG_LP_I2C_ANA_MST_BASE + 0x20) +#define LP_I2C_ANA_MST_ANA_CONF2 0x00FFFFFFU +#define LP_I2C_ANA_MST_ANA_CONF2_M (LP_I2C_ANA_MST_ANA_CONF2_V << LP_I2C_ANA_MST_ANA_CONF2_S) +#define LP_I2C_ANA_MST_ANA_CONF2_V 0x00FFFFFFU +#define LP_I2C_ANA_MST_ANA_CONF2_S 0 + +/** LP_I2C_ANA_MST_CLK160M_REG register */ +#define LP_I2C_ANA_MST_CLK160M_REG (DR_REG_LP_I2C_ANA_MST_BASE + 0x34) +#define LP_I2C_ANA_MST_CLK_I2C_MST_SEL_160M (BIT(0)) +#define LP_I2C_ANA_MST_CLK_I2C_MST_SEL_160M_M \ + (LP_I2C_ANA_MST_CLK_I2C_MST_SEL_160M_V << LP_I2C_ANA_MST_CLK_I2C_MST_SEL_160M_S) +#define LP_I2C_ANA_MST_CLK_I2C_MST_SEL_160M_V 0x00000001U +#define LP_I2C_ANA_MST_CLK_I2C_MST_SEL_160M_S 0 diff --git a/src/target/esp32p4/include/soc/lpperi_reg.h b/src/target/esp32p4/include/soc/lpperi_reg.h new file mode 100644 index 00000000..ebc259ab --- /dev/null +++ b/src/target/esp32p4/include/soc/lpperi_reg.h @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + * Minimal LPPERI defs for analog I2C master clock gating (CPLL regi2c). + */ + +#pragma once + +#include +#include "reg_base.h" + +/** LPPERI_CLK_EN_REG register */ +#define LPPERI_CLK_EN_REG (DR_REG_LPPERI_BASE + 0x0) +/** LPPERI_CK_EN_LP_I2CMST : R/W; bitpos: [27]; default: 1 */ +#define LPPERI_CK_EN_LP_I2CMST (BIT(27)) +#define LPPERI_CK_EN_LP_I2CMST_M (LPPERI_CK_EN_LP_I2CMST_V << LPPERI_CK_EN_LP_I2CMST_S) +#define LPPERI_CK_EN_LP_I2CMST_V 0x00000001U +#define LPPERI_CK_EN_LP_I2CMST_S 27 diff --git a/src/target/esp32p4/include/soc/pmu_reg.h b/src/target/esp32p4/include/soc/pmu_reg.h index 76bf7a36..50f7c5f6 100644 --- a/src/target/esp32p4/include/soc/pmu_reg.h +++ b/src/target/esp32p4/include/soc/pmu_reg.h @@ -53,6 +53,11 @@ /** PMU_HP_ACTIVE_HP_REGULATOR0_REG register */ #define PMU_HP_ACTIVE_HP_REGULATOR0_REG (DR_REG_PMU_BASE + 0x28) +/** PMU_LP_DBIAS_VOL : RO; bitpos: [8:4] */ +#define PMU_LP_DBIAS_VOL 0x0000001FU +#define PMU_LP_DBIAS_VOL_M (PMU_LP_DBIAS_VOL_V << PMU_LP_DBIAS_VOL_S) +#define PMU_LP_DBIAS_VOL_V 0x0000001FU +#define PMU_LP_DBIAS_VOL_S 4 /** PMU_HP_DBIAS_VOL : RO; bitpos: [13:9] — PVT-sampled HP dbias/dcm hint */ #define PMU_HP_DBIAS_VOL 0x0000001FU #define PMU_HP_DBIAS_VOL_M (PMU_HP_DBIAS_VOL_V << PMU_HP_DBIAS_VOL_S) @@ -62,6 +67,10 @@ #define PMU_DIG_REGULATOR0_DBIAS_SEL_M (PMU_DIG_REGULATOR0_DBIAS_SEL_V << PMU_DIG_REGULATOR0_DBIAS_SEL_S) #define PMU_DIG_REGULATOR0_DBIAS_SEL_V 0x00000001U #define PMU_DIG_REGULATOR0_DBIAS_SEL_S 14 +#define PMU_DIG_DBIAS_INIT (BIT(15)) +#define PMU_DIG_DBIAS_INIT_M (PMU_DIG_DBIAS_INIT_V << PMU_DIG_DBIAS_INIT_S) +#define PMU_DIG_DBIAS_INIT_V 0x00000001U +#define PMU_DIG_DBIAS_INIT_S 15 #define PMU_HP_ACTIVE_HP_REGULATOR_XPD (BIT(18)) #define PMU_HP_ACTIVE_HP_REGULATOR_XPD_M (PMU_HP_ACTIVE_HP_REGULATOR_XPD_V << PMU_HP_ACTIVE_HP_REGULATOR_XPD_S) #define PMU_HP_ACTIVE_HP_REGULATOR_XPD_V 0x00000001U @@ -71,12 +80,17 @@ #define PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_V 0x0000001FU #define PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S 27 -/** PMU_LP_ACTIVE_LP_REGULATOR0_REG register (lp_sys[PMU_MODE_LP_ACTIVE]) */ +/** PMU_LP_ACTIVE_LP_REGULATOR0_REG / PMU_HP_SLEEP_LP_REGULATOR0_REG (same offset) */ #define PMU_LP_ACTIVE_LP_REGULATOR0_REG (DR_REG_PMU_BASE + 0x9c) +#define PMU_HP_SLEEP_LP_REGULATOR0_REG PMU_LP_ACTIVE_LP_REGULATOR0_REG #define PMU_LP_ACTIVE_LP_REGULATOR_DBIAS 0x0000001FU #define PMU_LP_ACTIVE_LP_REGULATOR_DBIAS_M (PMU_LP_ACTIVE_LP_REGULATOR_DBIAS_V << PMU_LP_ACTIVE_LP_REGULATOR_DBIAS_S) #define PMU_LP_ACTIVE_LP_REGULATOR_DBIAS_V 0x0000001FU #define PMU_LP_ACTIVE_LP_REGULATOR_DBIAS_S 27 +#define PMU_HP_SLEEP_LP_REGULATOR_DBIAS PMU_LP_ACTIVE_LP_REGULATOR_DBIAS +#define PMU_HP_SLEEP_LP_REGULATOR_DBIAS_M PMU_LP_ACTIVE_LP_REGULATOR_DBIAS_M +#define PMU_HP_SLEEP_LP_REGULATOR_DBIAS_V PMU_LP_ACTIVE_LP_REGULATOR_DBIAS_V +#define PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S PMU_LP_ACTIVE_LP_REGULATOR_DBIAS_S /** PMU_IMM_HP_CK_POWER_REG register */ #define PMU_IMM_HP_CK_POWER_REG (DR_REG_PMU_BASE + 0xcc) diff --git a/src/target/esp32p4/include/soc/pvt_reg.h b/src/target/esp32p4/include/soc/pvt_reg.h new file mode 100644 index 00000000..9164b648 --- /dev/null +++ b/src/target/esp32p4/include/soc/pvt_reg.h @@ -0,0 +1,105 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + * Subset of PVT register definitions for stub auto-dbias init. + * See ESP-IDF components/soc/esp32p4/register/hw_ver3/soc/pvt_reg.h. + */ + +#pragma once + +#include +#include "reg_base.h" + +#define PVT_CLK_CFG_REG (DR_REG_PVT_BASE + 0x30) +#define PVT_MONITOR_CLK_PVT_EN (BIT(8)) +#define PVT_MONITOR_CLK_PVT_EN_M (PVT_MONITOR_CLK_PVT_EN_V << PVT_MONITOR_CLK_PVT_EN_S) +#define PVT_MONITOR_CLK_PVT_EN_V 0x00000001U +#define PVT_MONITOR_CLK_PVT_EN_S 8 + +#define PVT_DBIAS_CHANNEL_SEL0_REG (DR_REG_PVT_BASE + 0x34) +#define PVT_DBIAS_CHANNEL0_SEL 0x0000007FU +#define PVT_DBIAS_CHANNEL0_SEL_M (PVT_DBIAS_CHANNEL0_SEL_V << PVT_DBIAS_CHANNEL0_SEL_S) +#define PVT_DBIAS_CHANNEL0_SEL_V 0x0000007FU +#define PVT_DBIAS_CHANNEL0_SEL_S 25 +#define PVT_DBIAS_CHANNEL1_SEL 0x0000007FU +#define PVT_DBIAS_CHANNEL1_SEL_M (PVT_DBIAS_CHANNEL1_SEL_V << PVT_DBIAS_CHANNEL1_SEL_S) +#define PVT_DBIAS_CHANNEL1_SEL_V 0x0000007FU +#define PVT_DBIAS_CHANNEL1_SEL_S 18 + +#define PVT_DBIAS_CHANNEL0_SEL_REG (DR_REG_PVT_BASE + 0x3c) +#define PVT_DBIAS_CHANNEL0_CFG 0x0001FFFFU +#define PVT_DBIAS_CHANNEL0_CFG_M (PVT_DBIAS_CHANNEL0_CFG_V << PVT_DBIAS_CHANNEL0_CFG_S) +#define PVT_DBIAS_CHANNEL0_CFG_V 0x0001FFFFU +#define PVT_DBIAS_CHANNEL0_CFG_S 0 + +#define PVT_DBIAS_CHANNEL1_SEL_REG (DR_REG_PVT_BASE + 0x40) +#define PVT_DBIAS_CHANNEL1_CFG 0x0001FFFFU +#define PVT_DBIAS_CHANNEL1_CFG_M (PVT_DBIAS_CHANNEL1_CFG_V << PVT_DBIAS_CHANNEL1_CFG_S) +#define PVT_DBIAS_CHANNEL1_CFG_V 0x0001FFFFU +#define PVT_DBIAS_CHANNEL1_CFG_S 0 + +#define PVT_DBIAS_CHANNEL2_SEL_REG (DR_REG_PVT_BASE + 0x44) +#define PVT_DBIAS_CHANNEL2_CFG 0x0001FFFFU +#define PVT_DBIAS_CHANNEL2_CFG_M (PVT_DBIAS_CHANNEL2_CFG_V << PVT_DBIAS_CHANNEL2_CFG_S) +#define PVT_DBIAS_CHANNEL2_CFG_V 0x0001FFFFU +#define PVT_DBIAS_CHANNEL2_CFG_S 0 + +#define PVT_DBIAS_CMD0_REG (DR_REG_PVT_BASE + 0x50) +#define PVT_DBIAS_CMD0_PVT 0x7FF +#define PVT_DBIAS_CMD0_PVT_S 0 +#define PVT_DBIAS_CMD0_OFFSET_FLAG 1 +#define PVT_DBIAS_CMD0_OFFSET_FLAG_S 16 +#define PVT_DBIAS_CMD0_OFFSET_VALUE 0x1F +#define PVT_DBIAS_CMD0_OFFSET_VALUE_S 11 + +#define PVT_DBIAS_CMD1_REG (DR_REG_PVT_BASE + 0x54) +#define PVT_DBIAS_CMD1_PVT 0x7FF +#define PVT_DBIAS_CMD1_PVT_S 0 +#define PVT_DBIAS_CMD1_OFFSET_FLAG 1 +#define PVT_DBIAS_CMD1_OFFSET_FLAG_S 16 +#define PVT_DBIAS_CMD1_OFFSET_VALUE 0x1F +#define PVT_DBIAS_CMD1_OFFSET_VALUE_S 11 + +#define PVT_DBIAS_CMD2_REG (DR_REG_PVT_BASE + 0x58) +#define PVT_DBIAS_CMD2_PVT 0x7FF +#define PVT_DBIAS_CMD2_PVT_S 0 +#define PVT_DBIAS_CMD2_OFFSET_FLAG 1 +#define PVT_DBIAS_CMD2_OFFSET_FLAG_S 16 +#define PVT_DBIAS_CMD2_OFFSET_VALUE 0x1F +#define PVT_DBIAS_CMD2_OFFSET_VALUE_S 11 + +#define PVT_DBIAS_TIMER_REG (DR_REG_PVT_BASE + 0x64) +#define PVT_TIMER_EN (BIT(31)) +#define PVT_TIMER_EN_M (PVT_TIMER_EN_V << PVT_TIMER_EN_S) +#define PVT_TIMER_EN_V 0x00000001U +#define PVT_TIMER_EN_S 31 +#define PVT_TIMER_TARGET 0x0000FFFFU +#define PVT_TIMER_TARGET_M (PVT_TIMER_TARGET_V << PVT_TIMER_TARGET_S) +#define PVT_TIMER_TARGET_V 0x0000FFFFU +#define PVT_TIMER_TARGET_S 15 + +#define PVT_COMB_PD_SITE3_UNIT0_VT1_CONF1_REG (DR_REG_PVT_BASE + 0x108) +#define PVT_COMB_PD_SITE3_UNIT1_VT1_CONF1_REG (DR_REG_PVT_BASE + 0x10c) +#define PVT_COMB_PD_SITE3_UNIT0_VT1_CONF2_REG (DR_REG_PVT_BASE + 0x1c8) + +#define PVT_MONITOR_EDG_MOD_VT1_PD_SITE3_UNIT0 0x00000003U +#define PVT_MONITOR_EDG_MOD_VT1_PD_SITE3_UNIT0_M (PVT_MONITOR_EDG_MOD_VT1_PD_SITE3_UNIT0_V << PVT_MONITOR_EDG_MOD_VT1_PD_SITE3_UNIT0_S) +#define PVT_MONITOR_EDG_MOD_VT1_PD_SITE3_UNIT0_V 0x00000003U +#define PVT_MONITOR_EDG_MOD_VT1_PD_SITE3_UNIT0_S 0 + +#define PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT0 0x000000FFU +#define PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT0_M (PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT0_V << PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT0_S) +#define PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT0_V 0x000000FFU +#define PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT0_S 2 + +#define PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT1 0x000000FFU +#define PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT1_M (PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT1_V << PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT1_S) +#define PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT1_V 0x000000FFU +#define PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT1_S 2 + +#define PVT_MONITOR_EN_VT1_PD_SITE3_UNIT0 (BIT(0)) +#define PVT_MONITOR_EN_VT1_PD_SITE3_UNIT0_M (PVT_MONITOR_EN_VT1_PD_SITE3_UNIT0_V << PVT_MONITOR_EN_VT1_PD_SITE3_UNIT0_S) +#define PVT_MONITOR_EN_VT1_PD_SITE3_UNIT0_V 0x00000001U +#define PVT_MONITOR_EN_VT1_PD_SITE3_UNIT0_S 0 diff --git a/src/target/esp32p4/include/soc/reg_base.h b/src/target/esp32p4/include/soc/reg_base.h index ed70fce5..950f1f18 100644 --- a/src/target/esp32p4/include/soc/reg_base.h +++ b/src/target/esp32p4/include/soc/reg_base.h @@ -152,6 +152,7 @@ #define DR_REG_LP_I2C_BASE (DR_REG_LPPERIPH_BASE + 0x2000) #define DR_REG_LP_SPI_BASE (DR_REG_LPPERIPH_BASE + 0x3000) #define DR_REG_I2C_ANA_MST_BASE (DR_REG_LPPERIPH_BASE + 0x4000) +#define DR_REG_LP_I2C_ANA_MST_BASE DR_REG_I2C_ANA_MST_BASE #define DR_REG_LP_I2S_BASE (DR_REG_LPPERIPH_BASE + 0x5000) #define DR_REG_LP_ADC_BASE (DR_REG_LPPERIPH_BASE + 0x7000) #define DR_REG_LP_TOUCH_BASE (DR_REG_LPPERIPH_BASE + 0x8000) diff --git a/src/target/esp32p4/include/soc/regi2c_cpll.h b/src/target/esp32p4/include/soc/regi2c_cpll.h new file mode 100644 index 00000000..2589ed38 --- /dev/null +++ b/src/target/esp32p4/include/soc/regi2c_cpll.h @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + * Register definitions for CPU_PLL (CPLL) on the internal regi2c bus. + * See ESP-IDF components/soc/esp32p4/include/soc/regi2c_cpll.h. + */ + +#pragma once + +#define I2C_CPLL 0x67 +#define I2C_CPLL_HOSTID 0 + +#define I2C_CPLL_OC_REF_DIV 2 +#define I2C_CPLL_OC_REF_DIV_MSB 3 +#define I2C_CPLL_OC_REF_DIV_LSB 0 + +#define I2C_CPLL_OC_DCHGP 2 +#define I2C_CPLL_OC_DCHGP_MSB 6 +#define I2C_CPLL_OC_DCHGP_LSB 4 + +#define I2C_CPLL_OC_ENB_FCAL 2 +#define I2C_CPLL_OC_ENB_FCAL_MSB 7 +#define I2C_CPLL_OC_ENB_FCAL_LSB 7 + +#define I2C_CPLL_OC_DIV_7_0 3 +#define I2C_CPLL_OC_DIV_7_0_MSB 7 +#define I2C_CPLL_OC_DIV_7_0_LSB 0 + +#define I2C_CPLL_OC_DCUR 6 +#define I2C_CPLL_OC_DCUR_MSB 2 +#define I2C_CPLL_OC_DCUR_LSB 0 + +#define I2C_CPLL_OC_DHREF_SEL 6 +#define I2C_CPLL_OC_DHREF_SEL_MSB 5 +#define I2C_CPLL_OC_DHREF_SEL_LSB 4 + +#define I2C_CPLL_OC_DLREF_SEL 6 +#define I2C_CPLL_OC_DLREF_SEL_MSB 7 +#define I2C_CPLL_OC_DLREF_SEL_LSB 6 diff --git a/src/target/esp32p4/src/clock.c b/src/target/esp32p4/src/clock.c index d9b80178..070d8a39 100644 --- a/src/target/esp32p4/src/clock.c +++ b/src/target/esp32p4/src/clock.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 OR MIT */ +#include #include #include @@ -15,10 +16,14 @@ #include #include #include +#include #include #include +#include #include +#include #include +#include #include /* Match ESP-IDF pmu_param.h defaults used in rtc_clk_init(). */ @@ -29,8 +34,28 @@ /* IDF rtc_clk_init() delay after DCDC enable / dbias handoff. */ #define DCDC_SETTLE_US 1000 -/* CPLL stays at ROM-calibrated 400 MHz; CPU uses integer /2 (no CPLL recall). */ -#define CPU_FREQ_MHZ 200 +/* IDF pmu_init() delay after pvt_func_enable(true). */ +#define PVT_SETTLE_US 1000 + +/* Match IDF default CPU config for rev >= v3: CPLL 400 MHz, CPU /1. */ +#define XTAL_FREQ_MHZ 40 +#define CPLL_FREQ_MHZ 400 +#define CPU_FREQ_MHZ 400 + +/* Match ESP-IDF rtc.h PVT constants (CONFIG_ESP_ENABLE_PVT, rev >= v3). */ +#define PVT_CHANNEL0_SEL 49 +#define PVT_CHANNEL1_SEL 53 +#define PVT_CHANNEL0_CFG 0x11fff +#define PVT_CHANNEL1_CFG 0x17fff +#define PVT_CHANNEL2_CFG 0x10000 +#define PVT_CMD0 0x24 +#define PVT_CMD1 0x5 +#define PVT_CMD2 0x427 +#define PVT_TARGET 0xffff +#define PVT_CLK_DIV 1 +#define PVT_EDG_MODE 1 +#define PVT_DELAY_NUM_HIGH 160 +#define PVT_DELAY_NUM_LOW 153 extern uint32_t esp_rom_get_cpu_freq(void); extern void esp_rom_set_cpu_ticks_per_us(uint32_t ticks_per_us); @@ -59,6 +84,13 @@ static unsigned stub_target_get_blk_version(void) return major * 100U + minor; } +/* Match IDF efuse_ll_get_dbias_vol_gap(). */ +static int32_t stub_target_get_dbias_vol_gap(void) +{ + return (int32_t)((REG_READ(EFUSE_RD_MAC_SYS_5_REG) >> EFUSE_LP_DCDC_DBIAS_VOL_GAP_S) & + EFUSE_LP_DCDC_DBIAS_VOL_GAP_V); +} + static uint32_t stub_target_get_act_hp_dbias(void) { uint32_t hp_cali_dbias = HP_CALI_ACTIVE_DBIAS_DEFAULT; @@ -103,17 +135,165 @@ static void stub_target_bus_update(void) } } +/* + * Ported from ESP-IDF components/esp_hw_support/port/esp32p4/pmu_pvt.c + * Keep as separate functions; do not inline into stub_target_clock_init(). + */ +static uint8_t get_lp_hp_gap(void) +{ + int8_t lp_hp_gap = 0; + uint32_t blk_version = stub_target_get_blk_version(); + uint8_t lp_hp_gap_efuse = 0; + if (blk_version >= 2 && blk_version != 100) { + lp_hp_gap_efuse = (uint8_t)stub_target_get_dbias_vol_gap(); + bool gap_flag = lp_hp_gap_efuse >> 4; + uint8_t gap_abs_value = lp_hp_gap_efuse & 0xf; + if (gap_flag) { + lp_hp_gap = (int8_t)(-1 * (int)gap_abs_value); + } else { + lp_hp_gap = (int8_t)gap_abs_value; + } + lp_hp_gap = (int8_t)(lp_hp_gap - 8); + if (lp_hp_gap < 0) { + lp_hp_gap = (int8_t)(16 - lp_hp_gap); + } + } + return (uint8_t)lp_hp_gap; +} + +static void set_pvt_hp_lp_gap(uint8_t value) +{ + bool flag = value >> 4; + uint8_t abs_value = value & 0xf; + + SET_PERI_REG_BITS(PVT_DBIAS_CMD0_REG, PVT_DBIAS_CMD0_OFFSET_FLAG, flag, PVT_DBIAS_CMD0_OFFSET_FLAG_S); + SET_PERI_REG_BITS(PVT_DBIAS_CMD0_REG, PVT_DBIAS_CMD0_OFFSET_VALUE, abs_value, PVT_DBIAS_CMD0_OFFSET_VALUE_S); + SET_PERI_REG_BITS(PVT_DBIAS_CMD1_REG, PVT_DBIAS_CMD1_OFFSET_FLAG, flag, PVT_DBIAS_CMD1_OFFSET_FLAG_S); + SET_PERI_REG_BITS(PVT_DBIAS_CMD1_REG, PVT_DBIAS_CMD1_OFFSET_VALUE, abs_value, PVT_DBIAS_CMD1_OFFSET_VALUE_S); + SET_PERI_REG_BITS(PVT_DBIAS_CMD2_REG, PVT_DBIAS_CMD2_OFFSET_FLAG, flag, PVT_DBIAS_CMD2_OFFSET_FLAG_S); + SET_PERI_REG_BITS(PVT_DBIAS_CMD2_REG, PVT_DBIAS_CMD2_OFFSET_VALUE, abs_value, PVT_DBIAS_CMD2_OFFSET_VALUE_S); +} + +static uint32_t pvt_get_dcmvset(void) +{ + return GET_PERI_REG_BITS2(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_DBIAS_VOL_V, PMU_HP_DBIAS_VOL_S); +} + +static uint32_t pvt_get_lp_dbias(void) +{ + return GET_PERI_REG_BITS2(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_LP_DBIAS_VOL_V, PMU_LP_DBIAS_VOL_S); +} + +static void pvt_auto_dbias_init(void) +{ + uint32_t blk_version = stub_target_get_blk_version(); + if (blk_version >= 2 && blk_version != 100) { + REG_SET_BIT(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4); // Must reset after pd_cpu + REG_CLR_BIT(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_PVT_PERI_GROUP4); + SET_PERI_REG_MASK(HP_SYS_CLKRST_REF_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_REF_160M_CLK_EN); + SET_PERI_REG_MASK(HP_SYS_CLKRST_SOC_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_PVT_SYS_CLK_EN); + /*config for dbias func*/ + CLEAR_PERI_REG_MASK(PVT_DBIAS_TIMER_REG, PVT_TIMER_EN); + stub_lib_delay_us(1); + SET_PERI_REG_BITS(PVT_DBIAS_CHANNEL_SEL0_REG, + PVT_DBIAS_CHANNEL0_SEL, + PVT_CHANNEL0_SEL, + PVT_DBIAS_CHANNEL0_SEL_S); + SET_PERI_REG_BITS(PVT_DBIAS_CHANNEL_SEL0_REG, + PVT_DBIAS_CHANNEL1_SEL, + PVT_CHANNEL1_SEL, + PVT_DBIAS_CHANNEL1_SEL_S); + SET_PERI_REG_BITS(PVT_DBIAS_CHANNEL0_SEL_REG, + PVT_DBIAS_CHANNEL0_CFG, + PVT_CHANNEL0_CFG, + PVT_DBIAS_CHANNEL0_CFG_S); + SET_PERI_REG_BITS(PVT_DBIAS_CHANNEL1_SEL_REG, + PVT_DBIAS_CHANNEL1_CFG, + PVT_CHANNEL1_CFG, + PVT_DBIAS_CHANNEL1_CFG_S); + SET_PERI_REG_BITS(PVT_DBIAS_CHANNEL2_SEL_REG, + PVT_DBIAS_CHANNEL2_CFG, + PVT_CHANNEL2_CFG, + PVT_DBIAS_CHANNEL2_CFG_S); + SET_PERI_REG_BITS(PVT_DBIAS_CMD0_REG, PVT_DBIAS_CMD0_PVT, PVT_CMD0, PVT_DBIAS_CMD0_PVT_S); + SET_PERI_REG_BITS(PVT_DBIAS_CMD1_REG, PVT_DBIAS_CMD1_PVT, PVT_CMD1, PVT_DBIAS_CMD1_PVT_S); + SET_PERI_REG_BITS(PVT_DBIAS_CMD2_REG, PVT_DBIAS_CMD2_PVT, PVT_CMD2, PVT_DBIAS_CMD2_PVT_S); + SET_PERI_REG_BITS(PVT_DBIAS_TIMER_REG, PVT_TIMER_TARGET, PVT_TARGET, PVT_TIMER_TARGET_S); + + SET_PERI_REG_BITS(HP_SYS_CLKRST_PERI_CLK_CTRL24_REG, + HP_SYS_CLKRST_REG_PVT_CLK_DIV_NUM, + PVT_CLK_DIV, + HP_SYS_CLKRST_REG_PVT_CLK_DIV_NUM_S); + SET_PERI_REG_BITS(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, + HP_SYS_CLKRST_REG_PVT_PERI_GROUP_CLK_DIV_NUM, + PVT_CLK_DIV, + HP_SYS_CLKRST_REG_PVT_PERI_GROUP_CLK_DIV_NUM_S); + SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL24_REG, HP_SYS_CLKRST_REG_PVT_CLK_EN); + SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_PVT_PERI_GROUP1_CLK_EN); + SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_PVT_PERI_GROUP2_CLK_EN); + SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_PVT_PERI_GROUP3_CLK_EN); + SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL25_REG, HP_SYS_CLKRST_REG_PVT_PERI_GROUP4_CLK_EN); + + /*config for pvt cell: unit0; site3; vt1*/ + SET_PERI_REG_BITS(PVT_COMB_PD_SITE3_UNIT0_VT1_CONF2_REG, + PVT_MONITOR_EDG_MOD_VT1_PD_SITE3_UNIT0, + PVT_EDG_MODE, + PVT_MONITOR_EDG_MOD_VT1_PD_SITE3_UNIT0_S); + SET_PERI_REG_BITS(PVT_COMB_PD_SITE3_UNIT0_VT1_CONF1_REG, + PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT0, + PVT_DELAY_NUM_HIGH, + PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT0_S); + SET_PERI_REG_BITS(PVT_COMB_PD_SITE3_UNIT1_VT1_CONF1_REG, + PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT1, + PVT_DELAY_NUM_LOW, + PVT_DELAY_LIMIT_VT1_PD_SITE3_UNIT1_S); + + /*config lp offset for pvt func*/ + uint8_t lp_hp_gap = get_lp_hp_gap(); + set_pvt_hp_lp_gap(lp_hp_gap); + } +} + +static void pvt_func_enable(bool enable) +{ + uint32_t blk_version = stub_target_get_blk_version(); + if (blk_version >= 2 && blk_version != 100) { + if (enable) { + SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL24_REG, HP_SYS_CLKRST_REG_PVT_CLK_EN); + SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_DBIAS_INIT); + SET_PERI_REG_MASK(PVT_CLK_CFG_REG, PVT_MONITOR_CLK_PVT_EN); + SET_PERI_REG_MASK(PVT_COMB_PD_SITE3_UNIT0_VT1_CONF1_REG, PVT_MONITOR_EN_VT1_PD_SITE3_UNIT0); + stub_lib_delay_us(10); + CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_REGULATOR0_DBIAS_SEL); + CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_DBIAS_INIT); + SET_PERI_REG_MASK(PVT_DBIAS_TIMER_REG, PVT_TIMER_EN); + stub_lib_delay_us(50); + } else { + uint32_t pvt_dcmvset = pvt_get_dcmvset(); + uint32_t pvt_lpdbias = pvt_get_lp_dbias(); + SET_PERI_REG_BITS(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, pvt_dcmvset, PMU_HP_ACTIVE_DCM_VSET_S); + SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, + PMU_HP_SLEEP_LP_REGULATOR_DBIAS, + pvt_lpdbias, + PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); + SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_DIG_REGULATOR0_DBIAS_SEL); + CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL24_REG, HP_SYS_CLKRST_REG_PVT_CLK_EN); + } + } +} + static void stub_target_switch_to_dcdc(void) { unsigned chip_version = stub_target_get_chip_revision(); uint32_t hp_dbias = stub_target_get_act_hp_dbias(); uint32_t lp_dbias = stub_target_get_act_lp_dbias(); - /* - * IDF may raise this from PMU_HP_DBIAS_VOL when PVT is enabled. PVT is disabled - * in the stub because that flow is not stable enough for ROM-download use and - * may keep changing in IDF, so the default DCDC setting is sufficient here. - */ + /* Match IDF rtc_clk_init(): prefer PVT-sampled dcmvset when higher than default. */ + uint32_t pvt_hp_dcmvset = + GET_PERI_REG_BITS2(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_DBIAS_VOL_V, PMU_HP_DBIAS_VOL_S); uint32_t hp_dcmvset = HP_CALI_ACTIVE_DCM_VSET_DEFAULT; + if (pvt_hp_dcmvset > hp_dcmvset) { + hp_dcmvset = pvt_hp_dcmvset; + } SET_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD); REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_dbias); @@ -144,31 +324,128 @@ static void stub_target_switch_to_dcdc(void) CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD); } -static void stub_target_apply_cpu_cpll_div2(void) +/* + * Minimal P4 regi2c write path (ESP-IDF esp_hal_regi2c/esp32p4/regi2c_impl.c). + * ROM has ESP_ROM_WITHOUT_REGI2C; stub must drive LP_I2C_ANA_MST itself. + */ +#define REGI2C_PLL_CPU_MST_SEL (BIT(11)) +#define REGI2C_RTC_BUSY (BIT(25)) +#define REGI2C_RTC_WR_CNTL_S 24 +#define REGI2C_RTC_DATA_S 16 +#define REGI2C_RTC_ADDR_S 8 +#define REGI2C_RTC_SLAVE_ID_S 0 + +static void stub_target_regi2c_master_enable(void) +{ + /* Match bootloader_esp32p4: keep ana i2c mst clock enabled + 160M sel. */ + SET_PERI_REG_MASK(LPPERI_CLK_EN_REG, LPPERI_CK_EN_LP_I2CMST); + SET_PERI_REG_MASK(LP_I2C_ANA_MST_CLK160M_REG, LP_I2C_ANA_MST_CLK_I2C_MST_SEL_160M); +} + +static void stub_target_regi2c_write(uint8_t block, uint8_t reg_add, uint8_t data) +{ + REG_SET_FIELD(LP_I2C_ANA_MST_ANA_CONF2_REG, LP_I2C_ANA_MST_ANA_CONF2, 0); + REG_SET_FIELD(LP_I2C_ANA_MST_ANA_CONF1_REG, LP_I2C_ANA_MST_ANA_CONF1, 0); + REG_SET_BIT(LP_I2C_ANA_MST_ANA_CONF2_REG, REGI2C_PLL_CPU_MST_SEL); + + while (REG_GET_BIT(LP_I2C_ANA_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY)) { + } + uint32_t temp = ((uint32_t)block << REGI2C_RTC_SLAVE_ID_S) | ((uint32_t)reg_add << REGI2C_RTC_ADDR_S) | + (1U << REGI2C_RTC_WR_CNTL_S) | ((uint32_t)data << REGI2C_RTC_DATA_S); + REG_WRITE(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); + while (REG_GET_BIT(LP_I2C_ANA_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY)) { + } +} + +static void stub_target_cpll_enable(void) +{ + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_CPLL | PMU_TIE_HIGH_XPD_CPLL_I2C); + SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_CPLL_ICG); +} + +/* + * Ported from IDF clk_ll_cpll_set_config() + rtc_clk_cpll_configure(). + * Must run while CPU root is on XTAL (not CPLL). + */ +static void stub_target_cpll_configure(uint32_t xtal_freq_mhz, uint32_t cpll_freq_mhz) +{ + uint8_t div_ref; + uint8_t div7_0; + const uint8_t dchgp = 5; + const uint8_t dcur = 3; + const uint8_t oc_enb_fcal = 0; + unsigned chip_version = stub_target_get_chip_revision(); + + (void)xtal_freq_mhz; /* Only 40 MHz XTAL is supported on P4. */ + + /* Match IDF !ESP_CHIP_REV_ABOVE(rev, 1): ECO1+ uses swapped div7_0 encoding. */ + if (chip_version < 1U) { + div7_0 = (cpll_freq_mhz == CPLL_FREQ_MHZ) ? 6 : 5; + div_ref = 0; + } else { + div7_0 = (cpll_freq_mhz == CPLL_FREQ_MHZ) ? 10 : 9; + div_ref = 0; + } + + uint8_t i2c_cpll_lref = + (uint8_t)((oc_enb_fcal << I2C_CPLL_OC_ENB_FCAL_LSB) | (dchgp << I2C_CPLL_OC_DCHGP_LSB) | div_ref); + uint8_t i2c_cpll_dcur = (uint8_t)((1U << I2C_CPLL_OC_DLREF_SEL_LSB) | (3U << I2C_CPLL_OC_DHREF_SEL_LSB) | dcur); + + stub_target_regi2c_master_enable(); + + /* CPLL calibration start */ + CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP); + stub_target_regi2c_write(I2C_CPLL, I2C_CPLL_OC_REF_DIV, i2c_cpll_lref); + stub_target_regi2c_write(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, div7_0); + stub_target_regi2c_write(I2C_CPLL, I2C_CPLL_OC_DCUR, i2c_cpll_dcur); + while ((REG_READ(HP_SYS_CLKRST_ANA_PLL_CTRL0_REG) & HP_SYS_CLKRST_REG_CPU_PLL_CAL_END) == 0) { + } + stub_lib_delay_us(10); + SET_PERI_REG_MASK(HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, HP_SYS_CLKRST_REG_CPU_PLL_CAL_STOP); +} + +/* + * Match IDF rtc_clk_cpu_freq_to_xtal(xtal, 1, false): + * switch root to XTAL first, then set CPU/MEM/SYS/APB dividers to 1. + */ +static void stub_target_cpu_freq_to_xtal(void) +{ + uint32_t ctrl0; + + REG_SET_FIELD(LP_CLKRST_HP_CLK_CTRL_REG, LP_CLKRST_HP_ROOT_CLK_SRC_SEL, 0); + + ctrl0 = READ_PERI_REG(HP_SYS_CLKRST_ROOT_CLK_CTRL0_REG); + ctrl0 &= ~(HP_SYS_CLKRST_REG_CPU_CLK_DIV_NUM_M | HP_SYS_CLKRST_REG_CPU_CLK_DIV_NUMERATOR_M | + HP_SYS_CLKRST_REG_CPU_CLK_DIV_DENOMINATOR_M); + WRITE_PERI_REG(HP_SYS_CLKRST_ROOT_CLK_CTRL0_REG, ctrl0); + REG_SET_FIELD(HP_SYS_CLKRST_ROOT_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_MEM_CLK_DIV_NUM, 0); + REG_SET_FIELD(HP_SYS_CLKRST_ROOT_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_SYS_CLK_DIV_NUM, 0); + REG_SET_FIELD(HP_SYS_CLKRST_ROOT_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_APB_CLK_DIV_NUM, 0); + stub_target_bus_update(); + + esp_rom_set_cpu_ticks_per_us(XTAL_FREQ_MHZ); +} + +/* + * Match IDF rtc_clk_cpu_freq_to_cpll_mhz(400) for rev >= v3: + * CPLL 400 /1 -> CPU 400, MEM /2 -> 200, SYS /1 -> 200, APB /2 -> 100. + * Divider register fields store (divider - 1). Upscale order: APB -> SYS -> MEM -> CPU -> mux. + */ +static void stub_target_apply_cpu_cpll_div1(void) { uint32_t ctrl0; - /* - * Upscale from ROM download ~100 MHz (CPLL/4) to 200 MHz (CPLL/2). - * Match IDF rtc_clk_cpu_freq_to_cpll_mhz(200): APB -> SYS -> MEM -> CPU, - * then switch root mux to CPLL last (ROM may still be on XTAL). Do not - * recalibrate CPLL. - * - * Divider register fields store (divider - 1), same as clk_ll_*_set_divider(). - */ REG_SET_FIELD(HP_SYS_CLKRST_ROOT_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_APB_CLK_DIV_NUM, 1); stub_target_bus_update(); - /* sys_divider = 1 => div_num field 0 (IDF keeps SYS divider unchanged). */ REG_SET_FIELD(HP_SYS_CLKRST_ROOT_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_SYS_CLK_DIV_NUM, 0); stub_target_bus_update(); - REG_SET_FIELD(HP_SYS_CLKRST_ROOT_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_MEM_CLK_DIV_NUM, 0); + REG_SET_FIELD(HP_SYS_CLKRST_ROOT_CLK_CTRL1_REG, HP_SYS_CLKRST_REG_MEM_CLK_DIV_NUM, 1); stub_target_bus_update(); - /* 400 / 2 = 200 */ + /* 400 / 1 = 400 */ ctrl0 = READ_PERI_REG(HP_SYS_CLKRST_ROOT_CLK_CTRL0_REG); ctrl0 &= ~(HP_SYS_CLKRST_REG_CPU_CLK_DIV_NUM_M | HP_SYS_CLKRST_REG_CPU_CLK_DIV_NUMERATOR_M | HP_SYS_CLKRST_REG_CPU_CLK_DIV_DENOMINATOR_M); - ctrl0 |= (1U << HP_SYS_CLKRST_REG_CPU_CLK_DIV_NUM_S); WRITE_PERI_REG(HP_SYS_CLKRST_ROOT_CLK_CTRL0_REG, ctrl0); stub_target_bus_update(); @@ -177,12 +454,25 @@ static void stub_target_apply_cpu_cpll_div2(void) void stub_target_clock_init(void) { + /* Bootloader-equivalent: DCDC first (rtc_clk_init). */ stub_target_switch_to_dcdc(); - /* Publish ticks before divider change so ROM delays stay coherent. */ + /* App-equivalent: pmu_init() enables PVT before final CPU boost. */ + pvt_auto_dbias_init(); + pvt_func_enable(true); + stub_lib_delay_us(PVT_SETTLE_US); + + /* + * App-equivalent: rtc_clk_cpu_freq_set_config(CPLL 400 /1). + * Recalibrating CPLL requires switching CPU root to XTAL first. + */ + stub_target_cpll_enable(); + stub_target_cpu_freq_to_xtal(); + stub_target_cpll_configure(XTAL_FREQ_MHZ, CPLL_FREQ_MHZ); + stub_target_apply_cpu_cpll_div1(); + s_cpu_freq = CPU_FREQ_MHZ * MHZ; esp_rom_set_cpu_ticks_per_us(CPU_FREQ_MHZ); - stub_target_apply_cpu_cpll_div2(); } uint32_t stub_target_get_cpu_freq(void)