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