1 /*
2  * Copyright (c) 2019 Philippe Retornaz <philippe@shapescale.com>
3  * Copyright (c) 2019 STMicroelectronics
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @file
10  * @brief System/hardware module for STM32G0 processor
11  */
12 
13 #include <zephyr/device.h>
14 #include <zephyr/init.h>
15 #include <zephyr/linker/linker-defs.h>
16 #include <string.h>
17 
18 #include <cmsis_core.h>
19 #include <stm32_ll_system.h>
20 #if defined(SYSCFG_CFGR1_UCPD1_STROBE) || defined(SYSCFG_CFGR1_UCPD2_STROBE)
21 #include <stm32_ll_bus.h>
22 #endif /* SYSCFG_CFGR1_UCPD1_STROBE || SYSCFG_CFGR1_UCPD2_STROBE */
23 
24 /**
25  * @brief Disable the internal Pull-Up in Dead Battery pins of UCPD peripherals
26  *
27  * The internal Pull-Up in Dead Battery pins of UCPD peripherals are disabled,
28  * unless the UCPD driver and the corresponding peripheral is enabled. In that
29  * case this will be taken care of by the driver.
30  */
stm32g0_disable_dead_battery(void)31 static void stm32g0_disable_dead_battery(void)
32 {
33 #if defined(SYSCFG_CFGR1_UCPD1_STROBE) || defined(SYSCFG_CFGR1_UCPD2_STROBE)
34 	uint32_t strobe = 0;
35 
36 #if defined(CONFIG_USBC_TCPC_STM32)
37 #define DT_DRV_COMPAT st_stm32_ucpd
38 #define DEV_REG_ADDR_INIT(n) addr_inst[n] = DT_INST_REG_ADDR(n);
39 	uint32_t addr_inst[DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)];
40 
41 	DT_INST_FOREACH_STATUS_OKAY(DEV_REG_ADDR_INIT);
42 #else
43 	uint32_t addr_inst[0];
44 #endif
45 
46 #if defined(SYSCFG_CFGR1_UCPD1_STROBE)
47 	strobe |= LL_SYSCFG_UCPD1_STROBE;
48 #endif /* SYSCFG_CFGR1_UCPD1_STROBE */
49 
50 #if defined(SYSCFG_CFGR1_UCPD2_STROBE)
51 	strobe |= LL_SYSCFG_UCPD2_STROBE;
52 #endif /* SYSCFG_CFGR1_UCPD2_STROBE */
53 
54 	for (int n = 0; n < ARRAY_SIZE(addr_inst); n++) {
55 #if defined(SYSCFG_CFGR1_UCPD1_STROBE) && defined(UCPD1_BASE)
56 		if (addr_inst[n] == UCPD1_BASE) {
57 			strobe &= ~LL_SYSCFG_UCPD1_STROBE;
58 		}
59 #endif /* SYSCFG_CFGR1_UCPD1_STROBE && UCPD1_BASE */
60 #if defined(SYSCFG_CFGR1_UCPD2_STROBE) && defined(UCPD2_BASE)
61 		if (addr_inst[n] == UCPD2_BASE) {
62 			strobe &= ~LL_SYSCFG_UCPD2_STROBE;
63 		}
64 #endif /* SYSCFG_CFGR1_UCPD2_STROBE && UCPD2_BASE */
65 	}
66 
67 	if (strobe != 0) {
68 		LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
69 		LL_SYSCFG_DisableDBATT(strobe);
70 	}
71 #endif /* SYSCFG_CFGR1_UCPD1_STROBE || SYSCFG_CFGR1_UCPD2_STROBE */
72 }
73 
74 extern void stm32_power_init(void);
75 
76 /**
77  * @brief Perform basic hardware initialization at boot.
78  *
79  * This needs to be run from the very beginning.
80  */
soc_early_init_hook(void)81 void soc_early_init_hook(void)
82 {
83 	/* Enable ART Accelerator I-cache and prefetch */
84 	LL_FLASH_EnableInstCache();
85 	LL_FLASH_EnablePrefetch();
86 
87 	/* Update CMSIS SystemCoreClock variable (HCLK) */
88 	/* At reset, system core clock is set to 16 MHz from HSI */
89 	SystemCoreClock = 16000000;
90 
91 	/* Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral */
92 	stm32g0_disable_dead_battery();
93 #if CONFIG_PM
94 	stm32_power_init();
95 #endif
96 }
97