1 /***************************************************************************/ /**
2 * @file sl_platform_wireless.c
3 *******************************************************************************
4 * # License
5 * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
6 *******************************************************************************
7 *
8 * SPDX-License-Identifier: Zlib
9 *
10 * The licensor of this software is Silicon Laboratories Inc.
11 *
12 * This software is provided 'as-is', without any express or implied
13 * warranty. In no event will the authors be held liable for any damages
14 * arising from the use of this software.
15 *
16 * Permission is granted to anyone to use this software for any purpose,
17 * including commercial applications, and to alter it and redistribute it
18 * freely, subject to the following restrictions:
19 *
20 * 1. The origin of this software must not be misrepresented; you must not
21 * claim that you wrote the original software. If you use this software
22 * in a product, an acknowledgment in the product documentation would be
23 * appreciated but is not required.
24 * 2. Altered source versions must be plainly marked as such, and must not be
25 * misrepresented as being the original software.
26 * 3. This notice may not be removed or altered from any source distribution.
27 *
28 ******************************************************************************/
29
30 #include "rsi_wisemcu_hardware_setup.h"
31 #include "rsi_m4.h"
32 #include "rsi_rom_egpio.h"
33 #include "rsi_pll.h"
34 #include "rsi_rom_clks.h"
35 #include "rsi_rom_ulpss_clk.h"
36 #include "rsi_rom_power_save.h"
37 #include "sl_si91x_host_interface.h"
38 #include "sl_rsi_utility.h"
39 #include "system_si91x.h"
40 #include <stdio.h>
41 #include "cmsis_os2.h"
42 #include "sl_rsi_utility.h"
43
44 extern osEventFlagsId_t si91x_events;
45 extern osEventFlagsId_t si91x_bus_events;
46 extern osEventFlagsId_t si91x_async_events;
47 extern uint32_t frontend_switch_control;
48 extern osMutexId_t side_band_crypto_mutex;
49 extern sli_si91x_command_queue_t cmd_queues[SI91X_CMD_MAX];
50
51 /** @addtogroup SOC2
52 * @{
53 */
54
55 /**
56 * @brief Configure the default hardware configuration required for 'WiSeMCU' mode.
57 * @param[in] None
58 * @note Must be called in main before using any power save related configurations in applications.
59 * @return Void
60 */
sl_si91x_hardware_setup(void)61 void sl_si91x_hardware_setup(void)
62 {
63 /* Disable OTHER_CLK that was enabled at Start-up*/
64 RSI_CLK_PeripheralClkDisable3(M4CLK, M4_SOC_CLK_FOR_OTHER_ENABLE);
65
66 #ifndef SL_ULP_TIMER
67 /* Disable Timer clock that was enabled in Bootloader*/
68 RSI_ULPSS_TimerClkDisable(ULPCLK);
69 #endif
70
71 #if !(defined(SLI_SI917) || defined(SLI_SI915))
72 /* Disable 40MHz Clocks*/
73 RSI_ULPSS_DisableRefClks(MCU_ULP_40MHZ_CLK_EN);
74 #endif
75
76 /* Power-Down Button Calibration*/
77 RSI_PS_BodPwrGateButtonCalibDisable();
78
79 /* Disable PTAT for Analog Peripherals*/
80 RSI_PS_AnalogPeriPtatDisable();
81
82 /* Disable PTAT for Brown-Out Detection Clocks*/
83 RSI_PS_BodClksPtatDisable();
84
85 /* Power-Down unused Analog(IPMU) Domain peripherals*/
86 RSI_IPMU_PowerGateClr(AUXDAC_PG_ENB | AUXADC_PG_ENB | WURX_CORR_PG_ENB | WURX_PG_ENB | ULP_ANG_CLKS_PG_ENB
87 | CMP_NPSS_PG_ENB);
88
89 /* Power-Down unused NPSS Domain peripherals*/
90 RSI_PS_NpssPeriPowerDown(SLPSS_PWRGATE_ULP_MCUWDT | SLPSS_PWRGATE_ULP_MCUPS | SLPSS_PWRGATE_ULP_MCUTS
91 | SLPSS_PWRGATE_ULP_MCUSTORE2 | SLPSS_PWRGATE_ULP_MCUSTORE3
92 #ifndef SL_SLEEP_TIMER
93 | SLPSS_PWRGATE_ULP_MCURTC
94 #endif
95 );
96
97 #ifndef DS_BASED_WKP
98 RSI_PS_PowerSupplyDisable(POWER_ENABLE_DEEPSLEEP_TIMER);
99 #endif
100 /* Power-Down unused NPSS Domain peripherals*/
101 RSI_PS_PowerSupplyDisable(POWER_ENABLE_TIMESTAMPING);
102
103 #ifdef CHIP_9118
104 /* Power-Down Unused M4SS Domain peripherals */
105 RSI_PS_M4ssPeriPowerDown(
106
107 #ifndef DEBUG_UART
108 M4SS_PWRGATE_ULP_M4_FPU |
109 #endif
110 M4SS_PWRGATE_ULP_ETHERNET | M4SS_PWRGATE_ULP_EFUSE | M4SS_PWRGATE_ULP_SDIO_SPI | M4SS_PWRGATE_ULP_USB
111 | M4SS_PWRGATE_ULP_RPDMA
112 #ifndef DEBUG_UART
113 | M4SS_PWRGATE_ULP_PERI1
114 #endif
115 | M4SS_PWRGATE_ULP_PERI2 | M4SS_PWRGATE_ULP_PERI3 | M4SS_PWRGATE_ULP_CCI | M4SS_PWRGATE_ULP_SD_MEM);
116 /* Power-Down unused ULPSS Domain peripherals*/
117 RSI_PS_UlpssPeriPowerDown(
118 #ifndef SL_ULP_TIMER
119 ULPSS_PWRGATE_ULP_MISC |
120 #endif
121 ULPSS_PWRGATE_ULP_AUX | ULPSS_PWRGATE_ULP_CAP | ULPSS_PWRGATE_ULP_VAD
122 #ifndef DEBUG_UART
123 | ULPSS_PWRGATE_ULP_UART
124 #endif
125 | ULPSS_PWRGATE_ULP_SSI | ULPSS_PWRGATE_ULP_I2S | ULPSS_PWRGATE_ULP_I2C | ULPSS_PWRGATE_ULP_IR
126 | ULPSS_PWRGATE_ULP_UDMA | ULPSS_PWRGATE_ULP_FIM);
127
128 /* Turn off ULPSS SRAM domains*/
129 RSI_PS_UlpssRamBanksPowerDown(ULPSS_2K_BANK_0 | ULPSS_2K_BANK_1 | ULPSS_2K_BANK_2 | ULPSS_2K_BANK_3 | ULPSS_2K_BANK_4
130 | ULPSS_2K_BANK_5 | ULPSS_2K_BANK_6 | ULPSS_2K_BANK_7);
131 /* Turn off ULPSS SRAM Core/Periphery domains*/
132 RSI_PS_UlpssRamBanksPeriPowerDown(ULPSS_2K_BANK_0 | ULPSS_2K_BANK_1 | ULPSS_2K_BANK_2 | ULPSS_2K_BANK_3
133 | ULPSS_2K_BANK_4 | ULPSS_2K_BANK_5 | ULPSS_2K_BANK_6 | ULPSS_2K_BANK_7);
134 #endif
135
136 #if defined(SLI_SI917) || defined(SLI_SI915)
137 /* Power-Down Unused M4SS Domains */
138 RSI_PS_M4ssPeriPowerDown(
139 #ifndef SLI_SI91X_MCU_ENABLE_FLASH_BASED_EXECUTION
140 M4SS_PWRGATE_ULP_QSPI_ICACHE |
141 #endif
142 #ifndef DEBUG_UART
143 M4SS_PWRGATE_ULP_EFUSE_PERI |
144 #endif
145 M4SS_PWRGATE_ULP_SDIO_SPI | M4SS_PWRGATE_ULP_RPDMA);
146
147 /* Power-Down Unused ULPSS Domain peripherals */
148 RSI_PS_UlpssPeriPowerDown(
149 #ifndef SL_ULP_TIMER
150 ULPSS_PWRGATE_ULP_MISC |
151 #endif
152 ULPSS_PWRGATE_ULP_AUX | ULPSS_PWRGATE_ULP_CAP
153 #ifndef DEBUG_UART
154 | ULPSS_PWRGATE_ULP_UART
155 #endif
156 | ULPSS_PWRGATE_ULP_SSI | ULPSS_PWRGATE_ULP_I2S | ULPSS_PWRGATE_ULP_I2C | ULPSS_PWRGATE_ULP_IR
157 | ULPSS_PWRGATE_ULP_UDMA | ULPSS_PWRGATE_ULP_FIM);
158 #endif
159 /* Power-Down High-Frequency PLL Domain */
160 RSI_PS_SocPllSpiDisable();
161 /* Power-Down QSPI-DLL Domain */
162 RSI_PS_QspiDllDomainDisable();
163 /* Configure PMU Start-up Time to be used on Wake-up*/
164 RSI_PS_PmuGoodTimeDurationConfig(PMU_GOOD_TIME);
165 /* Configure XTAL Start-up Time to be used on Wake-up*/
166 RSI_PS_XtalGoodTimeDurationConfig(XTAL_GOOD_TIME);
167 /*Enable first boot up*/
168 RSI_PS_EnableFirstBootUp(1);
169 }
170
171 /**
172 * @brief This API is used to configure wireless GPIO front end controls from NWP to M4
173 * @return none
174 */
sli_si91x_configure_wireless_frontend_controls(uint32_t switch_sel)175 void sli_si91x_configure_wireless_frontend_controls(uint32_t switch_sel)
176 {
177 #if SLI_SI91X_MCU_INTERFACE
178 switch (switch_sel) {
179 case FRONT_END_SWITCH_SEL0:
180 //!GPIO 46,47,48
181 break;
182 case FRONT_END_SWITCH_SEL1:
183 #if defined(SLI_SI917B0) || defined(SLI_SI915)
184 {
185 //!Program GPIO mode6 in ULP for ULP4,ULP5,ULP0 GPIOS
186 RSI_EGPIO_SetPinMux(EGPIO1, 0, GPIO4, 6);
187 RSI_EGPIO_SetPinMux(EGPIO1, 0, GPIO5, 6);
188 RSI_EGPIO_SetPinMux(EGPIO1, 0, GPIO0, 6);
189 }
190 #else
191 {
192 //!GPIO 46,47,48
193 }
194 #endif
195 break;
196 case FRONT_END_SWITCH_SEL2:
197 #if !defined(SLI_SI917B0) && !defined(SLI_SI915)
198 //!Program GPIO mode6 in ULP for ULP4,ULP5,ULP0 GPIOS
199 RSI_EGPIO_SetPinMux(EGPIO1, 0, GPIO4, 6);
200 RSI_EGPIO_SetPinMux(EGPIO1, 0, GPIO5, 6);
201 RSI_EGPIO_SetPinMux(EGPIO1, 0, GPIO0, 6);
202 #endif
203 break;
204 case FRONT_END_SWITCH_SEL3:
205 #if !defined(SLI_SI917B0) && !defined(SLI_SI915)
206 //!Program GPIO mode6 in ULP for ULP4,ULP5,ULP7 GPIOS
207 RSI_EGPIO_SetPinMux(EGPIO1, 0, GPIO4, 6);
208 RSI_EGPIO_SetPinMux(EGPIO1, 0, GPIO5, 6);
209 RSI_EGPIO_SetPinMux(EGPIO1, 0, GPIO7, 6);
210 #endif
211 break;
212 default:
213 break;
214 }
215 #endif
216 }
217
218 /**
219 * @brief Configure the default hardware configuration required for 'WiSeMCU' mode.
220 * @param[in] rams_in_use - RAMs to be powered functionally (the rest of the RAM banks will be power gates)
221 * \n Macros used for this parameter:
222 * \n WISEMCU_0KB_RAM_IN_USE : None of the RAMs will be powered , i.e., all RAM banks will be power gates
223 * \n WISEMCU_16KB_RAM_IN_USE : Only 16KB RAM will be retained
224 * \n WISEMCU_48KB_RAM_IN_USE : Only 48KB RAM will be retained
225 * \n WISEMCU_112KB_RAM_IN_USE : Only 112KB RAM will be retained
226 * \n WISEMCU_128KB_RAM_IN_USE : Only 128KB RAM will be retained
227 * \n WISEMCU_144KB_RAM_IN_USE : Only 114KB RAM will be retained
228 * \n WISEMCU_176KB_RAM_IN_USE : Only 176KB RAM will be retained
229 * \n WISEMCU_192KB_RAM_IN_USE : Only 192KB RAM will be retained
230 * \n WISEMCU_208KB_RAM_IN_USE : Only 208KB RAM will be retained
231 * \n WISEMCU_240KB_RAM_IN_USE : Only 240KB RAM will be retained
232 * \n WISEMCU_320KB_RAM_IN_USE : Only 320KB RAM will be retained
233 * \n WISEMCU_384KB_RAM_IN_USE : Only 384KB RAM will be retained
234 *
235 * \n Macros used for 9117:
236 * \n WISEMCU_64KB_RAM_IN_USE : 320KB RAM will be retained
237 * \n WISEMCU_128KB_RAM_IN_USE : 320KB RAM will be retained
238 * \n WISEMCU_192KB_RAM_IN_USE : 320KB RAM will be retained
239 * \n WISEMCU_256KB_RAM_IN_USE : 320KB RAM will be retained
240 *
241 * @param[in] rams_retention_during_sleep - Configure RAM retentions to the hardware so that particular RAM banks are retained during sleep
242 * \n Macros used for this parameter:
243 * \n WISEMCU_RETAIN_DEFAULT_RAM_DURING_SLEEP : Select the RAM Retention controls automatically by API based on 'rams_power_gate' value passed by user
244 * \n WISEMCU_RETAIN_16K_RAM_DURING_SLEEP : Retain 16KB M4-ULP RAM
245 * \n WISEMCU_RETAIN_128K_RAM_DURING_SLEEP : Retain 16KB M4-ULP RAM and 112KB M4-ULP RAM
246 * \n WISEMCU_RETAIN_192K_RAM_DURING_SLEEP : Retain 16KB M4-ULP RAM and 112KB M4-ULP RAM and 64KB M4SS RAM
247 * \n WISEMCU_RETAIN_384K_RAM_DURING_SLEEP : Retain 16KB M4-ULP RAM and 112KB M4-ULP RAM and 64KB M4SS RAM and TASS 192KB RAM
248 * \n WISEMCU_RETAIN_M4SS_RAM_DURING_SLEEP : Retain Only 64KB M4SS RAM
249 * \n WISEMCU_RETAIN_ULPSS_RAM_DURING_SLEEP : Retain Only 16KB ULPSS RAM
250 * \n WISEMCU_RETAIN_TASS_RAM_DURING_SLEEP : Retain Only 192KB TASS RAM
251 * \n WISEMCU_RETAIN_M4ULP_RAM_DURING_SLEEP : Retain Only 112KB M4-ULP RAM
252 * @return void
253 * @note Must be called in main before using any power save related configurations in applications.
254 */
sl_si91x_configure_ram_retention(uint32_t rams_in_use,uint32_t rams_retention_during_sleep)255 void sl_si91x_configure_ram_retention(uint32_t rams_in_use, uint32_t rams_retention_during_sleep)
256 {
257
258 uint32_t rams_to_be_powered_down = rams_in_use;
259
260 #if (SL_SI91X_SI917_RAM_MEM_CONFIG == 1) // SL_SI91X_RAM_LEVEL_NWP_ADV_MCU_BASIC
261 rams_to_be_powered_down &= ~(RAM_BANK_8 | RAM_BANK_9);
262 #elif (SL_SI91X_SI917_RAM_MEM_CONFIG == 2) // SL_SI91X_RAM_LEVEL_NWP_MEDIUM_MCU_MEDIUM
263 rams_to_be_powered_down &= ~(RAM_BANK_9);
264 #endif
265
266 /* Turn off Unused SRAMs*/
267 RSI_PS_M4ssRamBanksPowerDown(rams_to_be_powered_down);
268
269 /* Turn off Unused SRAM Core/Periphery domains*/
270 RSI_PS_M4ssRamBanksPeriPowerDown(rams_to_be_powered_down);
271
272 /* Clear all RAM retention control before configuring the user RAM retentions*/
273 RSI_PS_ClrRamRetention(M4ULP_RAM16K_RETENTION_MODE_EN | TA_RAM_RETENTION_MODE_EN | M4ULP_RAM_RETENTION_MODE_EN);
274
275 /* If user selects the default RAM retentions, then select the RAM retentions based on RAM power gates*/
276 if (rams_retention_during_sleep & WISEMCU_RETAIN_DEFAULT_RAM_DURING_SLEEP) {
277 /* If none of the banks are powered on, clear all retention controls*/
278 if (rams_in_use & WISEMCU_0KB_RAM_IN_USE) {
279 RSI_PS_ClrRamRetention(M4ULP_RAM16K_RETENTION_MODE_EN | TA_RAM_RETENTION_MODE_EN | M4ULP_RAM_RETENTION_MODE_EN);
280 }
281 /* Set the 16KB SRAM memory retention */
282 if (rams_in_use == WISEMCU_16KB_RAM_IN_USE) {
283 RSI_PS_SetRamRetention(M4ULP_RAM16K_RETENTION_MODE_EN);
284 }
285 /* Set the full SRAM memory retention if the SRAM memory usage is greater than 16KB */
286 /* For different SRAM retention modes, respective unused SRAM banks (both SRAM power and core/periphery domains) are powered down as part of the initial configuration above */
287 else {
288 RSI_PS_SetRamRetention(M4ULP_RAM16K_RETENTION_MODE_EN | M4ULP_RAM_RETENTION_MODE_EN);
289 }
290 } else {
291 /* Program user configuration*/
292 RSI_PS_SetRamRetention(rams_retention_during_sleep);
293 }
294 }
295
296 /** @} */
297