1 /*
2  * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stdbool.h>
7 #include <assert.h>
8 #include "soc_init.h"
9 #include <soc/soc.h>
10 #include "soc/lp_analog_peri_reg.h"
11 #include "hal/clk_tree_ll.h"
12 #include "esp32c6/rom/spi_flash.h"
13 #include "modem/modem_lpcon_reg.h"
14 #include "soc/system_reg.h"
15 #include "soc/assist_debug_reg.h"
16 #include "soc/hp_apm_reg.h"
17 #include "soc/lp_apm_reg.h"
18 #include "soc/lp_apm0_reg.h"
19 #include "soc/pcr_reg.h"
20 #include "soc/lp_wdt_reg.h"
21 #include "esp_log.h"
22 
23 const static char *TAG = "soc_init";
24 
soc_hw_init(void)25 void soc_hw_init(void)
26 {
27 	/* In 80MHz flash mode, ROM sets the mspi module clk divider to 2, fix it here */
28 #if CONFIG_ESPTOOLPY_FLASHFREQ_80M
29 	clk_ll_mspi_fast_set_hs_divider(6);
30 	esp_rom_spiflash_config_clk(1, 0);
31 	esp_rom_spiflash_config_clk(1, 1);
32 	esp_rom_spiflash_fix_dummylen(0, 1);
33 	esp_rom_spiflash_fix_dummylen(1, 1);
34 #endif
35 
36 	/* Enable analog i2c master clock */
37 	SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN);
38 	SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M);
39 }
40 
ana_super_wdt_reset_config(bool enable)41 void ana_super_wdt_reset_config(bool enable)
42 {
43 	/* C6 doesn't support bypass super WDT reset */
44 	assert(enable);
45 	REG_CLR_BIT(LP_ANALOG_PERI_LP_ANA_FIB_ENABLE_REG, LP_ANALOG_PERI_LP_ANA_FIB_SUPER_WDT_RST);
46 }
47 
ana_bod_reset_config(bool enable)48 void ana_bod_reset_config(bool enable)
49 {
50 	REG_CLR_BIT(LP_ANALOG_PERI_LP_ANA_FIB_ENABLE_REG, LP_ANALOG_PERI_LP_ANA_FIB_BOD_RST);
51 
52 	if (enable) {
53 		REG_SET_BIT(LP_ANALOG_PERI_LP_ANA_BOD_MODE1_CNTL_REG,
54 			    LP_ANALOG_PERI_LP_ANA_BOD_MODE1_RESET_ENA);
55 	} else {
56 		REG_CLR_BIT(LP_ANALOG_PERI_LP_ANA_BOD_MODE1_CNTL_REG,
57 			    LP_ANALOG_PERI_LP_ANA_BOD_MODE1_RESET_ENA);
58 	}
59 }
60 
ana_reset_config(void)61 void ana_reset_config(void)
62 {
63 	ana_super_wdt_reset_config(true);
64 	ana_bod_reset_config(true);
65 }
66 
super_wdt_auto_feed(void)67 void super_wdt_auto_feed(void)
68 
69 {
70 	REG_WRITE(LP_WDT_SWD_WPROTECT_REG, LP_WDT_SWD_WKEY_VALUE);
71 	REG_SET_BIT(LP_WDT_SWD_CONFIG_REG, LP_WDT_SWD_AUTO_FEED_EN);
72 	REG_WRITE(LP_WDT_SWD_WPROTECT_REG, 0);
73 }
74 
wdt_reset_cpu0_info_enable(void)75 void wdt_reset_cpu0_info_enable(void)
76 {
77 	REG_SET_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_CLK_EN);
78 	REG_CLR_BIT(PCR_ASSIST_CONF_REG, PCR_ASSIST_RST_EN);
79 	REG_WRITE(ASSIST_DEBUG_CORE_0_RCD_EN_REG,
80 		  ASSIST_DEBUG_CORE_0_RCD_PDEBUGEN | ASSIST_DEBUG_CORE_0_RCD_RECORDEN);
81 }
82 
check_wdt_reset(void)83 void check_wdt_reset(void)
84 {
85 	int wdt_rst = 0;
86 	soc_reset_reason_t rst_reas;
87 
88 	rst_reas = esp_rom_get_reset_reason(0);
89 	if (rst_reas == RESET_REASON_CORE_RTC_WDT || rst_reas == RESET_REASON_CORE_MWDT0 ||
90 	    rst_reas == RESET_REASON_CORE_MWDT1 || rst_reas == RESET_REASON_CPU0_MWDT0 ||
91 	    rst_reas == RESET_REASON_CPU0_MWDT1 || rst_reas == RESET_REASON_CPU0_RTC_WDT) {
92 		ESP_EARLY_LOGW(TAG, "PRO CPU has been reset by WDT.");
93 		wdt_rst = 1;
94 	}
95 
96 	wdt_reset_cpu0_info_enable();
97 }
98 
99 /* Not supported but common bootloader calls the function. Do nothing */
ana_clock_glitch_reset_config(bool enable)100 void ana_clock_glitch_reset_config(bool enable)
101 {
102 	(void)enable;
103 }
104