1 /*
2  * Copyright (c) 2024 Silicon Laboratories Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief SoC initialization for Silicon Labs Series 2 products
10  */
11 
12 #include <zephyr/kernel.h>
13 #include <zephyr/logging/log.h>
14 
15 #include <em_chip.h>
16 #include <sl_device_init_dcdc.h>
17 #include <sl_clock_manager_init.h>
18 #include <sl_hfxo_manager.h>
19 #include <sl_power_manager.h>
20 
21 #if defined(CONFIG_PRINTK) || defined(CONFIG_LOG)
22 #define PR_EXC(...) LOG_ERR(__VA_ARGS__)
23 #else
24 #define PR_EXC(...)
25 #endif /* CONFIG_PRINTK || CONFIG_LOG */
26 
27 #if (CONFIG_FAULT_DUMP == 2)
28 #define PR_FAULT_INFO(...) PR_EXC(__VA_ARGS__)
29 #else
30 #define PR_FAULT_INFO(...)
31 #endif
32 
33 LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL);
34 
35 #if defined(CONFIG_SOC_SILABS_HFXO_MANAGER)
36 Z_ISR_DECLARE_DIRECT(DT_IRQ(DT_NODELABEL(hfxo), irq), 0, sl_hfxo_manager_irq_handler);
37 #endif
38 
soc_early_init_hook(void)39 void soc_early_init_hook(void)
40 {
41 	/* Handle chip errata */
42 	CHIP_Init();
43 
44 	if (DT_HAS_COMPAT_STATUS_OKAY(silabs_series2_dcdc)) {
45 		sl_device_init_dcdc();
46 	}
47 	sl_clock_manager_init();
48 
49 	if (IS_ENABLED(CONFIG_SOC_SILABS_HFXO_MANAGER)) {
50 		sl_hfxo_manager_init_hardware();
51 		sl_hfxo_manager_init();
52 	}
53 	if (IS_ENABLED(CONFIG_PM)) {
54 		sl_power_manager_init();
55 	}
56 }
57 
58 #if defined(CONFIG_ARM_SECURE_FIRMWARE) && !defined(CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS)
smu_fault(void)59 static void smu_fault(void)
60 {
61 	PR_FAULT_INFO("***** SMU FAULT *****");
62 
63 	if (SMU->IF & SMU_IF_BMPUSEC) {
64 		PR_FAULT_INFO("Bus Manager Fault");
65 		PR_EXC("SMU.BMPUFS=%d", SMU->BMPUFS);
66 	}
67 	if (SMU->IF & SMU_IF_PPUSEC) {
68 		PR_FAULT_INFO("Peripheral Access Fault");
69 		PR_EXC("SMU.PPUFS=%d", SMU->PPUFS);
70 	}
71 
72 	z_fatal_error(K_ERR_CPU_EXCEPTION, NULL);
73 }
74 #endif
75 
soc_prep_hook(void)76 void soc_prep_hook(void)
77 {
78 	/* Initialize TrustZone state of the device.
79 	 * If this is a secure app with no non-secure callable functions, it is a secure-only app.
80 	 * Configure all peripherals except the SMU and SEMAILBOX to non-secure aliases, and make
81 	 * all bus transactions from the CPU have non-secure attribution.
82 	 * This makes the secure-only app behave more like a non-secure app, allowing the use of
83 	 * libraries that only expect to use non-secure peripherals, such as the radio subsystem.
84 	 */
85 #if defined(CONFIG_ARM_SECURE_FIRMWARE) && !defined(CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS)
86 #if defined(CMU_CLKEN1_SMU)
87 	CMU_S->CLKEN1_SET = CMU_CLKEN1_SMU;
88 #endif
89 	SMU->PPUSATD0_CLR = _SMU_PPUSATD0_MASK;
90 #if defined(SEMAILBOX_PRESENT)
91 	SMU->PPUSATD1_CLR = (_SMU_PPUSATD1_MASK & (~SMU_PPUSATD1_SMU & ~SMU_PPUSATD1_SEMAILBOX));
92 #else
93 	SMU->PPUSATD1_CLR = (_SMU_PPUSATD1_MASK & ~SMU_PPUSATD1_SMU);
94 #endif
95 
96 	SAU->CTRL = SAU_CTRL_ALLNS_Msk;
97 	__DSB();
98 	__ISB();
99 
100 	NVIC_ClearPendingIRQ(SMU_SECURE_IRQn);
101 	SMU->IF_CLR = SMU_IF_PPUSEC | SMU_IF_BMPUSEC;
102 	SMU->IEN = SMU_IEN_PPUSEC | SMU_IEN_BMPUSEC;
103 
104 	IRQ_DIRECT_CONNECT(SMU_SECURE_IRQn, 0, smu_fault, 0);
105 	irq_enable(SMU_SECURE_IRQn);
106 #endif
107 }
108