1 /******************************************************************************
2 * Copyright (c) 2019 Texas Instruments Incorporated - http://www.ti.com
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 *****************************************************************************/
34 /** \file board_clock.c
35 *
36 * \brief This file contains initialization of wakeup and main PSC
37 * configuration structures and function definitions to get the number
38 * of wakeup and main PSC config exists.
39 */
41 #include "board_clock.h"
42 #include "board_utils.h"
43 #include <ti/drv/sciclient/sciclient.h>
45 extern Board_initParams_t gBoardInitParams;
47 uint32_t gBoardClkModuleMcuID[] = {
48 TISCI_DEV_MCU_ADC0,
49 TISCI_DEV_MCU_ADC1,
50 TISCI_DEV_MCU_CPSW0,
51 TISCI_DEV_MCU_TIMER0,
52 TISCI_DEV_MCU_FSS0_HYPERBUS1P0_0,
53 TISCI_DEV_MCU_FSS0_OSPI_0,
54 TISCI_DEV_MCU_FSS0_OSPI_1,
55 TISCI_DEV_WKUP_GPIO0,
56 TISCI_DEV_WKUP_GPIO1,
57 TISCI_DEV_WKUP_GPIOMUX_INTRTR0,
58 TISCI_DEV_MCU_UART0,
59 TISCI_DEV_MCU_MCAN0,
60 TISCI_DEV_MCU_MCAN1,
61 TISCI_DEV_MCU_I2C0,
62 TISCI_DEV_MCU_I2C1,
63 TISCI_DEV_WKUP_I2C0,
64 TISCI_DEV_WKUP_UART0,
65 TISCI_DEV_SA2_UL0,
66 };
68 uint32_t gBoardClkModuleMainID[] = {
69 TISCI_DEV_DDR0,
70 TISCI_DEV_TIMER0,
71 TISCI_DEV_TIMER1,
72 TISCI_DEV_TIMER2,
73 TISCI_DEV_TIMER3,
74 TISCI_DEV_EMIF_DATA_0_VD,
75 TISCI_DEV_MMCSD0,
76 TISCI_DEV_MMCSD1,
77 TISCI_DEV_MMCSD2,
78 TISCI_DEV_GPIO0,
79 TISCI_DEV_GPIO1,
80 TISCI_DEV_GPIO2,
81 TISCI_DEV_GPIO3,
82 TISCI_DEV_GPIO4,
83 TISCI_DEV_GPIO5,
84 TISCI_DEV_GPIO6,
85 TISCI_DEV_GPIO7,
86 TISCI_DEV_PRU_ICSSG0,
87 TISCI_DEV_PRU_ICSSG1,
88 TISCI_DEV_UART0,
89 TISCI_DEV_MCAN0,
90 TISCI_DEV_MCAN1,
91 TISCI_DEV_MCAN2,
92 TISCI_DEV_MCAN3,
93 TISCI_DEV_MCAN4,
94 TISCI_DEV_MCAN5,
95 TISCI_DEV_MCAN6,
96 TISCI_DEV_MCAN7,
97 TISCI_DEV_MCAN8,
98 TISCI_DEV_MCAN9,
99 TISCI_DEV_MCAN10,
100 TISCI_DEV_MCAN11,
101 TISCI_DEV_MCAN12,
102 TISCI_DEV_MCAN13,
103 TISCI_DEV_MCASP0,
104 TISCI_DEV_MCASP1,
105 TISCI_DEV_MCASP2,
106 TISCI_DEV_MCASP3,
107 TISCI_DEV_MCASP4,
108 TISCI_DEV_MCASP5,
109 TISCI_DEV_MCASP6,
110 TISCI_DEV_MCASP7,
111 TISCI_DEV_MCASP8,
112 TISCI_DEV_MCASP9,
113 TISCI_DEV_MCASP10,
114 TISCI_DEV_MCASP11,
115 TISCI_DEV_I2C0,
116 TISCI_DEV_I2C1,
117 TISCI_DEV_I2C2,
118 TISCI_DEV_I2C3,
119 TISCI_DEV_I2C4,
120 TISCI_DEV_I2C5,
121 TISCI_DEV_I2C6,
122 TISCI_DEV_PCIE0,
123 TISCI_DEV_PCIE1,
124 TISCI_DEV_PCIE2,
125 TISCI_DEV_PCIE3,
126 TISCI_DEV_UFS0,
127 TISCI_DEV_UART1,
128 TISCI_DEV_UART2,
129 TISCI_DEV_UART3,
130 TISCI_DEV_UART4,
131 TISCI_DEV_UART5,
132 TISCI_DEV_UART6,
133 TISCI_DEV_UART7,
134 TISCI_DEV_UART8,
135 TISCI_DEV_UART9,
136 TISCI_DEV_USB0,
137 TISCI_DEV_USB1,
138 TISCI_DEV_VPFE0,
139 TISCI_DEV_SERDES_16G0,
140 TISCI_DEV_SERDES_16G1,
141 TISCI_DEV_SERDES_16G2,
142 TISCI_DEV_SERDES_16G3,
143 TISCI_DEV_SERDES_10G0,
144 TISCI_DEV_SA2_UL0,
145 };
147 /**
148 * \brief Disables module clock
149 *
150 * \return BOARD_SOK - Clock disable successful.
151 * BOARD_FAIL - Clock disable failed.
152 *
153 */
154 Board_STATUS Board_moduleClockDisable(uint32_t moduleId)
155 {
156 Board_STATUS retVal = BOARD_SOK;
157 int32_t status = CSL_EFAIL;
158 uint32_t moduleState = 0U;
159 uint32_t resetState = 0U;
160 uint32_t contextLossState = 0U;
162 /* Get the module state.
163 No need to change the module state if it
164 is already OFF
165 */
166 status = Sciclient_pmGetModuleState(moduleId,
167 &moduleState,
168 &resetState,
169 &contextLossState,
170 SCICLIENT_SERVICE_WAIT_FOREVER);
171 if(moduleState != TISCI_MSG_VALUE_DEVICE_HW_STATE_OFF)
172 {
173 status = Sciclient_pmSetModuleState(moduleId,
174 TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF,
175 (TISCI_MSG_FLAG_AOP |
176 TISCI_MSG_FLAG_DEVICE_RESET_ISO),
177 SCICLIENT_SERVICE_WAIT_FOREVER);
178 if (status == CSL_PASS)
179 {
180 status = Sciclient_pmSetModuleRst (moduleId,
181 0x1U,
182 SCICLIENT_SERVICE_WAIT_FOREVER);
183 if (status != CSL_PASS)
184 {
185 retVal = BOARD_FAIL;
186 }
187 }
188 else
189 {
190 retVal = BOARD_FAIL;
191 }
192 }
194 return retVal;
195 }
197 /**
198 * \brief Enables module clock
199 *
200 * \return BOARD_SOK - Clock enable sucessful.
201 * BOARD_FAIL - Clock enable failed.
202 *
203 */
204 Board_STATUS Board_moduleClockEnable(uint32_t moduleId)
205 {
206 Board_STATUS retVal = BOARD_SOK;
207 int32_t status = CSL_EFAIL;
208 uint32_t moduleState = 0U;
209 uint32_t resetState = 0U;
210 uint32_t contextLossState = 0U;
212 /* Get the module state.
213 No need to change the module state if it
214 is already ON
215 */
216 status = Sciclient_pmGetModuleState(moduleId,
217 &moduleState,
218 &resetState,
219 &contextLossState,
220 SCICLIENT_SERVICE_WAIT_FOREVER);
221 if(moduleState == TISCI_MSG_VALUE_DEVICE_HW_STATE_OFF)
222 {
223 if(gBoardInitParams.pscMode == BOARD_PSC_DEVICE_MODE_NONEXCLUSIVE)
224 {
225 status = Sciclient_pmSetModuleState(moduleId,
226 TISCI_MSG_VALUE_DEVICE_SW_STATE_ON,
227 (TISCI_MSG_FLAG_AOP |
228 TISCI_MSG_FLAG_DEVICE_RESET_ISO),
229 SCICLIENT_SERVICE_WAIT_FOREVER);
230 }
231 else
232 {
233 status = Sciclient_pmSetModuleState(moduleId,
234 TISCI_MSG_VALUE_DEVICE_SW_STATE_ON,
235 (TISCI_MSG_FLAG_AOP |
236 TISCI_MSG_FLAG_DEVICE_EXCLUSIVE |
237 TISCI_MSG_FLAG_DEVICE_RESET_ISO),
238 SCICLIENT_SERVICE_WAIT_FOREVER);
239 }
240 if (status == CSL_PASS)
241 {
242 status = Sciclient_pmSetModuleRst (moduleId,
243 0x0U,
244 SCICLIENT_SERVICE_WAIT_FOREVER);
245 if (status != CSL_PASS)
246 {
247 retVal = BOARD_FAIL;
248 }
249 }
250 else
251 {
252 retVal = BOARD_FAIL;
253 }
254 }
256 return retVal;
257 }
259 /**
260 * \brief clock Initialization function for MCU domain
261 *
262 * Enables different power domains and peripheral clocks of the MCU.
263 * Some of the power domains and peripherals will be OFF by default.
264 * Enabling the power domains is mandatory before accessing using
265 * board interfaces connected to those peripherals.
266 *
267 * \return BOARD_SOK - Clock initialization sucessful.
268 * BOARD_INIT_CLOCK_FAIL - Clock initialization failed.
269 *
270 */
271 Board_STATUS Board_moduleClockInitMcu(void)
272 {
273 Board_STATUS status = BOARD_SOK;
274 uint32_t index;
275 uint32_t loopCount;
277 loopCount = sizeof(gBoardClkModuleMcuID) / sizeof(uint32_t);
279 for(index = 0; index < loopCount; index++)
280 {
281 status = Board_moduleClockEnable(gBoardClkModuleMcuID[index]);
282 if(status != BOARD_SOK)
283 {
284 status = BOARD_INIT_CLOCK_FAIL;
285 break;
286 }
287 }
289 #if defined(BUILD_MCU)
290 if(status == BOARD_SOK)
291 {
292 int32_t ret;
293 uint64_t mcuClkFreq;
295 ret = Sciclient_pmGetModuleClkFreq(TISCI_DEV_MCU_R5FSS0_CORE0,
296 TISCI_DEV_MCU_R5FSS0_CORE0_CPU_CLK,
297 &mcuClkFreq,
298 SCICLIENT_SERVICE_WAIT_FOREVER);
299 if(ret == 0)
300 {
301 Osal_HwAttrs hwAttrs;
302 uint32_t ctrlBitmap;
304 ret = Osal_getHwAttrs(&hwAttrs);
305 if(ret == 0)
306 {
307 /*
308 * Change the timer input clock frequency configuration
309 based on R5 CPU clock configured
310 */
311 hwAttrs.cpuFreqKHz = (int32_t)(mcuClkFreq/1000U);
312 ctrlBitmap = OSAL_HWATTR_SET_CPU_FREQ;
313 ret = Osal_setHwAttrs(ctrlBitmap, &hwAttrs);
314 }
315 }
316 if(ret != 0)
317 {
318 status = BOARD_INIT_CLOCK_FAIL;
319 }
320 }
321 #endif
323 return status;
324 }
326 /**
327 * \brief clock Initialization function for MAIN domain
328 *
329 * Enables different power domains and peripheral clocks of the SoC.
330 * Some of the power domains and peripherals will be OFF by default.
331 * Enabling the power domains is mandatory before accessing using
332 * board interfaces connected to those peripherals.
333 *
334 * \return BOARD_SOK - Clock initialization successful.
335 * BOARD_INIT_CLOCK_FAIL - Clock initialization failed.
336 *
337 */
338 Board_STATUS Board_moduleClockInitMain(void)
339 {
340 Board_STATUS status = BOARD_SOK;
341 uint32_t index;
342 uint32_t loopCount;
344 loopCount = sizeof(gBoardClkModuleMainID) / sizeof(uint32_t);
346 for(index = 0; index < loopCount; index++)
347 {
348 status = Board_moduleClockEnable(gBoardClkModuleMainID[index]);
349 if(status != BOARD_SOK)
350 {
351 return BOARD_INIT_CLOCK_FAIL;
352 }
353 }
355 return status;
356 }
358 /**
359 * \brief clock de-initialization function for MCU domain
360 *
361 * Disables different power domains and peripheral clocks of the SoC.
362 *
363 * \return BOARD_SOK - Clock de-initialization successful.
364 * BOARD_INIT_CLOCK_FAIL - Clock de-initialization failed.
365 *
366 */
367 Board_STATUS Board_moduleClockDeinitMcu(void)
368 {
369 Board_STATUS status = BOARD_SOK;
370 uint32_t index;
371 uint32_t loopCount;
373 loopCount = sizeof(gBoardClkModuleMcuID) / sizeof(uint32_t);
375 for(index = 0; index < loopCount; index++)
376 {
377 status = Board_moduleClockDisable(gBoardClkModuleMcuID[index]);
378 if(status != BOARD_SOK)
379 {
380 return BOARD_INIT_CLOCK_FAIL;
381 }
382 }
384 return status;
385 }
387 /**
388 * \brief clock de-initialization function for MAIN domain
389 *
390 * Disables different power domains and peripheral clocks of the SoC.
391 *
392 * \return BOARD_SOK - Clock de-initialization successful.
393 * BOARD_INIT_CLOCK_FAIL - Clock de-initialization failed.
394 *
395 */
396 Board_STATUS Board_moduleClockDeinitMain(void)
397 {
398 Board_STATUS status = BOARD_SOK;
399 uint32_t index;
400 uint32_t loopCount;
402 loopCount = sizeof(gBoardClkModuleMainID) / sizeof(uint32_t);
404 for(index = 0; index < loopCount; index++)
405 {
406 status = Board_moduleClockDisable(gBoardClkModuleMainID[index]);
407 if(status != BOARD_SOK)
408 {
409 return BOARD_INIT_CLOCK_FAIL;
410 }
411 }
413 return status;
414 }