aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers')
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_clock.cmake16
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_memory.cmake15
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_reset.cmake14
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_sc_event.cmake18
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_clock.c377
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_clock.h517
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_memory.h116
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_sc_event.c399
-rw-r--r--lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_sc_event.h266
9 files changed, 1738 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_clock.cmake b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_clock.cmake
new file mode 100644
index 000000000..154d6a23a
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_clock.cmake
@@ -0,0 +1,16 @@
1if(NOT DRIVER_CLOCK_INCLUDED)
2
3 set(DRIVER_CLOCK_INCLUDED true CACHE BOOL "driver_clock component is included.")
4
5 target_sources(${MCUX_SDK_PROJECT_NAME} PRIVATE
6 ${CMAKE_CURRENT_LIST_DIR}/fsl_clock.c
7 )
8
9 target_include_directories(${MCUX_SDK_PROJECT_NAME} PRIVATE
10 ${CMAKE_CURRENT_LIST_DIR}/.
11 )
12
13
14 include(driver_common)
15
16endif() \ No newline at end of file
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_memory.cmake b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_memory.cmake
new file mode 100644
index 000000000..f2142de90
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_memory.cmake
@@ -0,0 +1,15 @@
1if(NOT DRIVER_MEMORY_INCLUDED)
2
3 set(DRIVER_MEMORY_INCLUDED true CACHE BOOL "driver_memory component is included.")
4
5 target_sources(${MCUX_SDK_PROJECT_NAME} PRIVATE
6 )
7
8 target_include_directories(${MCUX_SDK_PROJECT_NAME} PRIVATE
9 ${CMAKE_CURRENT_LIST_DIR}/.
10 )
11
12
13 include(driver_common)
14
15endif() \ No newline at end of file
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_reset.cmake b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_reset.cmake
new file mode 100644
index 000000000..989530f6f
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_reset.cmake
@@ -0,0 +1,14 @@
1if(NOT DRIVER_RESET_INCLUDED)
2
3 set(DRIVER_RESET_INCLUDED true CACHE BOOL "driver_reset component is included.")
4
5 target_sources(${MCUX_SDK_PROJECT_NAME} PRIVATE
6 )
7
8 target_include_directories(${MCUX_SDK_PROJECT_NAME} PRIVATE
9 ${CMAKE_CURRENT_LIST_DIR}/.
10 )
11
12
13
14endif() \ No newline at end of file
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_sc_event.cmake b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_sc_event.cmake
new file mode 100644
index 000000000..a1ce1f2af
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/driver_sc_event.cmake
@@ -0,0 +1,18 @@
1if(NOT DRIVER_SC_EVENT_INCLUDED)
2
3 set(DRIVER_SC_EVENT_INCLUDED true CACHE BOOL "driver_sc_event component is included.")
4
5 target_sources(${MCUX_SDK_PROJECT_NAME} PRIVATE
6 ${CMAKE_CURRENT_LIST_DIR}/fsl_sc_event.c
7 )
8
9 target_include_directories(${MCUX_SDK_PROJECT_NAME} PRIVATE
10 ${CMAKE_CURRENT_LIST_DIR}/.
11 )
12
13
14 include(driver_common)
15 include(driver_scfw_api)
16 include(driver_mu)
17
18endif() \ No newline at end of file
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_clock.c b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_clock.c
new file mode 100644
index 000000000..bd9117091
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_clock.c
@@ -0,0 +1,377 @@
1/*
2 * Copyright 2017-2020 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include "fsl_clock.h"
8
9/*******************************************************************************
10 * Definitions
11 ******************************************************************************/
12/* Component ID definition, used by tools. */
13#ifndef FSL_COMPONENT_ID
14#define FSL_COMPONENT_ID "platform.drivers.clock"
15#endif
16/* LPCG register Bits Mask. LPCG register generally comes in four bit groups, a STOP, Reserved, [P|B]CG(SWEN), HWEN
17 * nibble. The HWEN bits are optional, but the allocations of the nibble always be on four bit boundaries. */
18#define LPCG_CLK_HWEN_MASK (0x11111111U)
19#define LPCG_CLK_SWEN_MASK (0x22222222U)
20#define LPCG_CLK_STOP_MASK (0x88888888U)
21
22/*******************************************************************************
23 * Variables
24 ******************************************************************************/
25static sc_ipc_t ipcHandle;
26
27/*******************************************************************************
28 * Prototypes
29 ******************************************************************************/
30
31/*******************************************************************************
32 * Code
33 ******************************************************************************/
34
35/*!
36 * brief Initialize Clock module.
37 *
38 * param ipc IPC handle for communication with SCU, see \ref sc_ipc_t.
39 */
40void CLOCK_Init(sc_ipc_t ipc)
41{
42 ipcHandle = ipc;
43}
44
45/*!
46 * brief Deinitialize Clock module.
47 */
48void CLOCK_Deinit(void)
49{
50}
51
52/*!
53 * brief Enable the clock for specific IP, with gate setting.
54 *
55 * param name Which clock to enable, see \ref clock_ip_name_t.
56 * param gate 0: clock always on, 1: HW auto clock gating.
57 * return true if success, false if failure.
58 */
59bool CLOCK_EnableClockExt(clock_ip_name_t name, uint32_t gate)
60{
61 sc_err_t err;
62
63 err = sc_pm_clock_enable(ipcHandle, LPCG_TUPLE_RSRC(name), SC_PM_CLK_PER, true, (bool)gate);
64
65 /* Enable the Clock Gate control in LPCG */
66 CLOCK_ConfigLPCG(name, true, (bool)gate);
67
68 if (err != SC_ERR_NONE)
69 {
70 return false;
71 }
72 else
73 {
74 return true;
75 }
76}
77
78/*!
79 * brief Disable the clock for specific IP.
80 *
81 * param name Which clock to disable, see \ref clock_ip_name_t.
82 * return true for success, false for failure.
83 */
84bool CLOCK_DisableClock(clock_ip_name_t name)
85{
86 sc_err_t err;
87
88 /* Disable the Clock Gate control in LPCG */
89 CLOCK_ConfigLPCG(name, false, false);
90
91 err = sc_pm_clock_enable(ipcHandle, LPCG_TUPLE_RSRC(name), SC_PM_CLK_PER, false, false);
92
93 if (err != SC_ERR_NONE)
94 {
95 return false;
96 }
97 else
98 {
99 return true;
100 }
101}
102
103/*!
104 * brief Set the clock frequency for specific IP module.
105 *
106 * This function sets the IP module clock frequency.
107 *
108 * param name Which peripheral to check, see \ref clock_ip_name_t.
109 * param freq Target clock frequency value in hertz.
110 * return the Real clock frequency value in hertz, or 0 if failed
111 */
112uint32_t CLOCK_SetIpFreq(clock_ip_name_t name, uint32_t freq)
113{
114 uint32_t target = freq;
115 sc_err_t err;
116
117 err = sc_pm_set_clock_rate(ipcHandle, LPCG_TUPLE_RSRC(name), SC_PM_CLK_PER, &target);
118 if (err != SC_ERR_NONE)
119 {
120 return 0;
121 }
122 else
123 {
124 return target;
125 }
126}
127
128/*!
129 * brief Get the clock frequency for a specific IP module.
130 *
131 * This function gets the IP module clock frequency.
132 *
133 * param name Which peripheral to get, see \ref clock_ip_name_t.
134 * return Clock frequency value in hertz, or 0 if failed
135 */
136uint32_t CLOCK_GetIpFreq(clock_ip_name_t name)
137{
138 uint32_t freq;
139 sc_err_t err;
140
141 err = sc_pm_get_clock_rate(ipcHandle, LPCG_TUPLE_RSRC(name), SC_PM_CLK_PER, &freq);
142 if (err != SC_ERR_NONE)
143 {
144 return 0;
145 }
146 else
147 {
148 return freq;
149 }
150}
151
152/*!
153 * brief Get the core clock or system clock frequency.
154 *
155 * return Clock frequency in Hz.
156 */
157uint32_t CLOCK_GetCoreSysClkFreq(void)
158{
159 uint32_t freq;
160 sc_err_t err;
161#if defined(MIMX8QM_CM4_CORE0)
162 err = sc_pm_get_clock_rate(ipcHandle, SC_R_M4_0_PID0, SC_PM_CLK_PER, &freq);
163#elif defined(MIMX8QM_CM4_CORE1)
164 err = sc_pm_get_clock_rate(ipcHandle, SC_R_M4_1_PID0, SC_PM_CLK_PER, &freq);
165#else
166#error "Clock driver not support the core!"
167#endif
168 if (err != SC_ERR_NONE)
169 {
170 freq = 0U;
171 }
172
173 return freq;
174}
175
176/*!
177 * brief Gets the clock frequency for a specific clock name.
178 *
179 * This function checks the current clock configurations and then calculates
180 * the clock frequency for a specific clock name defined in clock_name_t.
181 *
182 * param clockName Clock names defined in clock_name_t
183 * return Clock frequency value in hertz
184 */
185uint32_t CLOCK_GetFreq(clock_name_t name)
186{
187 uint32_t freq;
188
189 switch (name)
190 {
191 case kCLOCK_CONECTIVITY_AhbClk:
192 freq = 167000000U; /* The CONNECTIVITY SS AHB clock is fixed to 166MHZ */
193 break;
194 case kCLOCK_CoreSysClk:
195 freq = CLOCK_GetCoreSysClkFreq();
196 break;
197 default:
198 freq = 0U;
199 break;
200 }
201
202 return freq;
203}
204
205/*!
206 * brief Set LPCG gate for specific LPCG.
207 *
208 * param regBase LPCG register base address.
209 * param swGate Software clock gating. 0: clock is gated; 1: clock is enabled
210 * param hwGate Hardware auto gating. 0: disable the HW clock gate control; 1: HW clock gating is enabled
211 * param bitsMask The available bits in LPCG register. Each bit indicate the corresponding bit is available or not.
212 */
213void CLOCK_SetLpcgGate(volatile uint32_t *regBase, bool swGate, bool hwGate, uint32_t bitsMask)
214{
215 if (regBase != NULL)
216 {
217 if (swGate)
218 {
219 *regBase |= bitsMask & LPCG_CLK_SWEN_MASK;
220 }
221 else
222 {
223 *regBase &= ~(bitsMask & LPCG_CLK_SWEN_MASK);
224 }
225
226 if (hwGate)
227 {
228 *regBase |= bitsMask & LPCG_CLK_HWEN_MASK;
229 }
230 else
231 {
232 *regBase &= ~(bitsMask & LPCG_CLK_HWEN_MASK);
233 }
234 }
235}
236
237/*!
238 * brief Config the LPCG cell for specific IP.
239 *
240 * param name Which clock to enable, see \ref clock_ip_name_t.
241 * param swGate Software clock gating. 0: clock is gated; 1: clock is enabled
242 * param swGate Hardware auto gating. 0: disable the HW clock gate control; 1: HW clock gating is enabled
243 */
244void CLOCK_ConfigLPCG(clock_ip_name_t name, bool swGate, bool hwGate)
245{
246 volatile uint32_t *regBase;
247
248 regBase = LPCG_TUPLE_REG_BASE(name);
249
250 /* Return if LPCG Cell is not available. */
251 if (regBase == NULL)
252 {
253 return;
254 }
255
256 /* Config the LPCG. LPCG Cells have different configurations per each clock target. */
257 switch (name)
258 {
259 /* LPCG cell avalialbe bits field mask 0xBBAAAB, 0xBBAAAB (2 32-bits LPCG registers). */
260 case kCLOCK_CONNECTIVITY_Enet0:
261 case kCLOCK_CONNECTIVITY_Enet1:
262 CLOCK_SetLpcgGate(regBase, swGate, hwGate, 0xBBAAABU);
263 CLOCK_SetLpcgGate(&regBase[1U], swGate, hwGate, 0xAU);
264 break;
265
266 /* LPCG cell avalialbe bits field mask 0xA000B.*/
267 case kCLOCK_AUDIO_Esai0:
268 case kCLOCK_AUDIO_Esai1:
269 CLOCK_SetLpcgGate(regBase, swGate, hwGate, 0xA000BU);
270 break;
271
272 /* LPCG cell avalialbe bits field mask 0xAA000B.*/
273 case kCLOCK_AUDIO_Gpt0:
274 case kCLOCK_AUDIO_Gpt1:
275 case kCLOCK_AUDIO_Gpt2:
276 case kCLOCK_AUDIO_Gpt3:
277 case kCLOCK_AUDIO_Gpt4:
278 case kCLOCK_AUDIO_Gpt5:
279 CLOCK_SetLpcgGate(regBase, swGate, hwGate, 0xAA000BU);
280 break;
281
282 /* LPCG cell avalialbe bits field mask 0xAAB0AAB.*/
283 case kCLOCK_LSIO_Gpt0:
284 case kCLOCK_LSIO_Gpt1:
285 case kCLOCK_LSIO_Gpt2:
286 case kCLOCK_LSIO_Gpt3:
287 case kCLOCK_LSIO_Gpt4:
288 CLOCK_SetLpcgGate(regBase, swGate, hwGate, 0xAAB0AABU);
289 break;
290
291 /* LPCG cell avalialbe bits field mask 0xB0000.*/
292 case kCLOCK_HSIO_Gpio:
293 case kCLOCK_LSIO_Gpio0:
294 case kCLOCK_LSIO_Gpio1:
295 case kCLOCK_LSIO_Gpio2:
296 case kCLOCK_LSIO_Gpio3:
297 case kCLOCK_LSIO_Gpio4:
298 case kCLOCK_LSIO_Gpio5:
299 case kCLOCK_LSIO_Gpio6:
300 case kCLOCK_LSIO_Gpio7:
301 CLOCK_SetLpcgGate(regBase, swGate, hwGate, 0xB0000U);
302 break;
303 /* LPCG cell avalialbe bits field mask 0xB000A. */
304 case kCLOCK_DMA_Lpadc0:
305 case kCLOCK_DMA_Lpadc1:
306 case kCLOCK_LSIO_Mu5A:
307 case kCLOCK_LSIO_Mu6A:
308 case kCLOCK_LSIO_Mu7A:
309 case kCLOCK_LSIO_Mu8A:
310 case kCLOCK_LSIO_Mu9A:
311 case kCLOCK_LSIO_Mu10A:
312 case kCLOCK_LSIO_Mu11A:
313 case kCLOCK_LSIO_Mu12A:
314 case kCLOCK_LSIO_Mu13A:
315 case kCLOCK_LSIO_Mu5B:
316 case kCLOCK_LSIO_Mu6B:
317 case kCLOCK_LSIO_Mu7B:
318 case kCLOCK_LSIO_Mu8B:
319 case kCLOCK_LSIO_Mu9B:
320 case kCLOCK_LSIO_Mu10B:
321 case kCLOCK_LSIO_Mu11B:
322 case kCLOCK_LSIO_Mu12B:
323 case kCLOCK_LSIO_Mu13B:
324 CLOCK_SetLpcgGate(regBase, swGate, hwGate, 0xB000AU);
325 break;
326
327 /* LPCG cell avalialbe bits field mask 0xB000B. */
328 case kCLOCK_DMA_Lpspi0:
329 case kCLOCK_DMA_Lpspi1:
330 case kCLOCK_DMA_Lpspi2:
331 case kCLOCK_DMA_Lpspi3:
332 case kCLOCK_DMA_Lpuart0:
333 case kCLOCK_DMA_Lpuart1:
334 case kCLOCK_DMA_Lpuart2:
335 case kCLOCK_DMA_Lpuart3:
336 case kCLOCK_DMA_Lpuart4:
337 case kCLOCK_DMA_Lpi2c0:
338 case kCLOCK_DMA_Lpi2c1:
339 case kCLOCK_DMA_Lpi2c2:
340 case kCLOCK_DMA_Lpi2c3:
341 case kCLOCK_DMA_Lpi2c4:
342 case kCLOCK_DMA_Ftm0:
343 case kCLOCK_DMA_Ftm1:
344 CLOCK_SetLpcgGate(regBase, swGate, hwGate, 0xB000BU);
345 break;
346
347 /* LPCG cell avalialbe bits field mask 0xA0B0A.*/
348 case kCLOCK_AUDIO_Sai0:
349 case kCLOCK_AUDIO_Sai1:
350 case kCLOCK_AUDIO_Sai2:
351 case kCLOCK_AUDIO_Sai3:
352 case kCLOCK_AUDIO_Sai4:
353 case kCLOCK_AUDIO_Sai5:
354 case kCLOCK_AUDIO_Sai6:
355 case kCLOCK_AUDIO_Sai7:
356 CLOCK_SetLpcgGate(regBase, swGate, hwGate, 0xA0B0AU);
357 break;
358
359 /* LPCG cell avalialbe bits field mask 0xBB000B.*/
360 case kCLOCK_DMA_Can0:
361 case kCLOCK_DMA_Can1:
362 case kCLOCK_DMA_Can2:
363 CLOCK_SetLpcgGate(regBase, swGate, hwGate, 0xBB000B);
364 break;
365
366 /* LPCG cell avalialbe bits field mask 0xBAA000A.*/
367 case kCLOCK_LSIO_Flexspi0:
368 case kCLOCK_LSIO_Flexspi1:
369 CLOCK_SetLpcgGate(regBase, swGate, hwGate, 0xBAA000A);
370 break;
371
372 /* LPCG cell is not avaliable or is not supported by this function. */
373 default:
374 /* Add comments to avoid the violation of MISRA C-2012 rule 16.4. */
375 break;
376 }
377}
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_clock.h b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_clock.h
new file mode 100644
index 000000000..a49264442
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_clock.h
@@ -0,0 +1,517 @@
1/*
2 * Copyright 2017-2020 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _FSL_CLOCK_H_
8#define _FSL_CLOCK_H_
9
10#include "fsl_device_registers.h"
11#include <stdint.h>
12#include <stdbool.h>
13#include <assert.h>
14
15#include "svc/pm/pm_api.h"
16
17/*! @addtogroup clock */
18/*! @{ */
19
20/*******************************************************************************
21 * Definitions
22 ******************************************************************************/
23/*! @brief Configure whether driver controls clock
24 *
25 * When set to 0, peripheral drivers will enable clock in initialize function
26 * and disable clock in de-initialize function. When set to 1, peripheral
27 * driver will not control the clock, application could control the clock out of
28 * the driver.
29 *
30 * @note All drivers share this feature switcher. If it is set to 1, application
31 * should handle clock enable and disable for all drivers.
32 */
33#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
34#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
35#endif
36
37/*! @name Driver version */
38/*@{*/
39/*! @brief CLOCK driver version 2.4.0. */
40#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 4, 0))
41/*@}*/
42
43/* Definition for delay API in clock driver, users can redefine it to the real application. */
44#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
45#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (400000000UL)
46#endif
47
48/*! @brief Clock ip name array for MU. */
49#define MU_CLOCKS \
50 { \
51 kCLOCK_M4_0_Mu0B, kCLOCK_M4_0_Mu0B, kCLOCK_M4_0_Mu0B, kCLOCK_M4_0_Mu0B, kCLOCK_M4_0_Mu0A0, kCLOCK_M4_0_Mu0A1, \
52 kCLOCK_M4_0_Mu0A2, kCLOCK_M4_0_Mu0A3, kCLOCK_M4_0_Mu1A, kCLOCK_M4_1_Mu0B, kCLOCK_M4_1_Mu0B, \
53 kCLOCK_M4_1_Mu0B, kCLOCK_M4_1_Mu0B, kCLOCK_M4_1_Mu0A0, kCLOCK_M4_1_Mu0A1, kCLOCK_M4_1_Mu0A2, \
54 kCLOCK_M4_1_Mu0A3, kCLOCK_M4_1_Mu1A, kCLOCK_LSIO_Mu0A, kCLOCK_LSIO_Mu1A, kCLOCK_LSIO_Mu2A, \
55 kCLOCK_LSIO_Mu3A, kCLOCK_LSIO_Mu4A, kCLOCK_LSIO_Mu5A, kCLOCK_LSIO_Mu6A, kCLOCK_LSIO_Mu7A, \
56 kCLOCK_LSIO_Mu8A, kCLOCK_LSIO_Mu9A, kCLOCK_LSIO_Mu10A, kCLOCK_LSIO_Mu11A, kCLOCK_LSIO_Mu12A, \
57 kCLOCK_LSIO_Mu13A, kCLOCK_LSIO_Mu5B, kCLOCK_LSIO_Mu6B, kCLOCK_LSIO_Mu7B, kCLOCK_LSIO_Mu8B, \
58 kCLOCK_LSIO_Mu9B, kCLOCK_LSIO_Mu10B, kCLOCK_LSIO_Mu11B, kCLOCK_LSIO_Mu12B, kCLOCK_LSIO_Mu13B, \
59 }
60
61/*! @brief Clock ip name array for GPIO. */
62#define GPIO_CLOCKS \
63 { \
64 kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_IpInvalid, kCLOCK_HSIO_Gpio, \
65 kCLOCK_LSIO_Gpio0, kCLOCK_LSIO_Gpio1, kCLOCK_LSIO_Gpio2, kCLOCK_LSIO_Gpio3, kCLOCK_LSIO_Gpio4, \
66 kCLOCK_LSIO_Gpio5, kCLOCK_LSIO_Gpio6, kCLOCK_LSIO_Gpio7, kCLOCK_IpInvalid, kCLOCK_IpInvalid, \
67 kCLOCK_IpInvalid, \
68 }
69
70/*! @brief Clock ip name array for RGPIO. */
71#define RGPIO_CLOCKS \
72 { \
73 kCLOCK_M4_0_Rgpio, kCLOCK_M4_1_Rgpio, \
74 }
75
76/*! @brief Clock ip name array for FTM. */
77#define FTM_CLOCKS \
78 { \
79 kCLOCK_DMA_Ftm0, kCLOCK_DMA_Ftm1, \
80 }
81
82/*! @brief Clock ip name array for GPT. */
83#define GPT_CLOCKS \
84 { \
85 kCLOCK_AUDIO_Gpt0, kCLOCK_AUDIO_Gpt1, kCLOCK_AUDIO_Gpt2, kCLOCK_AUDIO_Gpt3, kCLOCK_AUDIO_Gpt4, \
86 kCLOCK_AUDIO_Gpt5, kCLOCK_LSIO_Gpt0, kCLOCK_LSIO_Gpt1, kCLOCK_LSIO_Gpt2, kCLOCK_LSIO_Gpt3, \
87 kCLOCK_LSIO_Gpt4, \
88 }
89/*! @brief Clock ip name array for FLEXCAN. */
90#define FLEXCAN_CLOCKS \
91 { \
92 kCLOCK_DMA_Can0, kCLOCK_DMA_Can1, kCLOCK_DMA_Can2, \
93 }
94/*! @brief Clock ip name array for FLEXSPI. */
95#define FLEXSPI_CLOCKS \
96 { \
97 kCLOCK_LSIO_Flexspi0, kCLOCK_LSIO_Flexspi1, \
98 }
99/*! @brief Clock ip name array for LPUART. */
100#define LPUART_CLOCKS \
101 { \
102 kCLOCK_M4_0_Lpuart, kCLOCK_M4_1_Lpuart, kCLOCK_DMA_Lpuart0, kCLOCK_DMA_Lpuart1, kCLOCK_DMA_Lpuart2, \
103 kCLOCK_DMA_Lpuart3, kCLOCK_DMA_Lpuart4, kCLOCK_SCU_Lpuart, \
104 }
105
106/*! @brief Clock ip name array for LPADC. */
107#define LPADC_CLOCKS \
108 { \
109 kCLOCK_DMA_Lpadc0, kCLOCK_DMA_Lpadc1, \
110 }
111
112/*! @brief Clock ip name array for INTMUX. */
113#define INTMUX_CLOCKS \
114 { \
115 kCLOCK_M4_0_Intmux, kCLOCK_M4_1_Intmux, kCLOCK_IpInvalid, \
116 }
117
118/*! @brief Clock ip name array for SAI. */
119#define SAI_CLOCKS \
120 { \
121 kCLOCK_AUDIO_Sai0, kCLOCK_AUDIO_Sai1, kCLOCK_AUDIO_Sai2, kCLOCK_AUDIO_Sai3, kCLOCK_AUDIO_Sai4, \
122 kCLOCK_AUDIO_Sai5, kCLOCK_AUDIO_Sai6, kCLOCK_AUDIO_Sai7, \
123 }
124
125/*! @brief Clock ip name array for SEMA42. */
126#define SEMA42_CLOCKS \
127 { \
128 kCLOCK_M4_0_Sema42, kCLOCK_M4_1_Sema42, kCLOCK_SCU_Sema42, \
129 }
130
131/*! @brief Clock ip name array for TPM. */
132#define TPM_CLOCKS \
133 { \
134 kCLOCK_M4_0_Tpm, kCLOCK_M4_1_Tpm, kCLOCK_SCU_Tpm, \
135 }
136
137/*! @brief Clock ip name array for LPIT. */
138#define LPIT_CLOCKS \
139 { \
140 kCLOCK_M4_0_Lpit, kCLOCK_M4_1_Lpit, kCLOCK_SCU_Lpit, \
141 }
142
143/*! @brief Clock ip name array for LPI2C. */
144#define LPI2C_CLOCKS \
145 { \
146 kCLOCK_M4_0_Lpi2c, kCLOCK_M4_1_Lpi2c, kCLOCK_HDMI_Lpi2c0, kCLOCK_LVDS_0_Lpi2c1, kCLOCK_LVDS_0_Lpi2c0, \
147 kCLOCK_LVDS_1_Lpi2c1, kCLOCK_LVDS_1_Lpi2c0, kCLOCK_MIPI_0_Lpi2c0, kCLOCK_MIPI_0_Lpi2c1, \
148 kCLOCK_MIPI_1_Lpi2c0, kCLOCK_MIPI_1_Lpi2c1, kCLOCK_DMA_Lpi2c0, kCLOCK_DMA_Lpi2c1, kCLOCK_DMA_Lpi2c2, \
149 kCLOCK_DMA_Lpi2c3, kCLOCK_DMA_Lpi2c4, kCLOCK_CSI_0_Lpi2c0, kCLOCK_CSI_1_Lpi2c0, kCLOCK_HDMI_RX_Lpi2c0, \
150 kCLOCK_SCU_Lpi2c, \
151 }
152
153/*! @brief Clock ip name array for LPSPI. */
154#define LPSPI_CLOCKS \
155 { \
156 kCLOCK_DMA_Lpspi0, kCLOCK_DMA_Lpspi1, kCLOCK_DMA_Lpspi2, kCLOCK_DMA_Lpspi3, \
157 }
158#if defined(MIMX8QM_CM4_CORE0)
159#define IRQSTEER_CLOCKS \
160 { \
161 kCLOCK_M4_0_Irqsteer, \
162 }
163#elif defined(MIMX8QM_CM4_CORE1)
164#define IRQSTEER_CLOCKS \
165 { \
166 kCLOCK_M4_1_Irqsteer, \
167 }
168#endif
169
170/*! @brief Clock ip name array for EDMA. */
171#define EDMA_CLOCKS \
172 { \
173 kCLOCK_DMA_Dma0, \
174 }
175
176/*! @brief Clock ip name array for ESAI. */
177#define ESAI_CLOCKS \
178 { \
179 kCLOCK_AUDIO_Esai0, kCLOCK_AUDIO_Esai1 \
180 }
181
182/*! @brief Clock ip name array for ISI. */
183#define ISI_CLOCKS \
184 { \
185 kCLOCK_IMAGING_Isi0, kCLOCK_IMAGING_Isi1, kCLOCK_IMAGING_Isi2, kCLOCK_IMAGING_Isi3, kCLOCK_IMAGING_Isi4, \
186 kCLOCK_IMAGING_Isi5, kCLOCK_IMAGING_Isi6, kCLOCK_IMAGING_Isi7, \
187 }
188
189/*! @brief Clock ip name array for MIPI CSI2 RX. */
190#define MIPI_CSI2RX_CLOCKS \
191 { \
192 kCLOCK_MipiCsi2Rx0, kCLOCK_MipiCsi2Rx1 \
193 }
194
195/*! @brief Clock ip name array for MIPI DSI host. */
196#define MIPI_DSI_HOST_CLOCKS \
197 { \
198 kCLOCK_MipiDsiHost0, kCLOCK_MipiDsiHost1 \
199 }
200
201/*! @brief Clock ip name array for ENET. */
202#define ENET_CLOCKS \
203 { \
204 kCLOCK_CONNECTIVITY_Enet0, kCLOCK_CONNECTIVITY_Enet1 \
205 }
206
207/*! @brief Clock ip name array for EMVSIM. */
208#define EMVSIM_CLOCKS \
209 { \
210 kCLOCK_DMA_EmvSim0, kCLOCK_DMA_EmvSim1, \
211 }
212
213/*! @brief Clock ip name array for DPU. */
214#define DPU_CLOCKS \
215 { \
216 kCLOCK_Dpu0, kCLOCK_Dpu1, \
217 }
218
219/*! @brief Clock ip name array for LVDS display bridge(LDB). */
220#define LDB_CLOCKS \
221 { \
222 kCLOCK_Ldb0, kCLOCK_Ldb1 \
223 }
224
225/*!
226 * @brief Clock source for peripherals that support various clock selections.
227 */
228typedef enum _clock_ip_src
229{
230 kCLOCK_IpSrcNone = 0U, /*!< Clock is off. */
231 kCLOCK_IpSrcDummy = 1U, /*!< Clock option 1. */
232} clock_ip_src_t;
233
234/*! @brief Clock name used to get clock frequency. */
235typedef enum _clock_name
236{
237 /* ----------------------------- System layer clock ---------------------- */
238 kCLOCK_CoreSysClk, /*!< Core/system clock for M4 */
239
240 /* --------------------------------- Other clock ------------------------- */
241 kCLOCK_CONECTIVITY_AhbClk, /*!< AHB clock in Connectivity subsystem */
242} clock_name_t;
243
244/*!
245 * @brief LPCG TUPLE macors to map corresponding ip clock name, SCFW API resource index and LPCG Register base address.
246 * The LPCG base should be 4KB aligned, if not it will be truncated.
247 */
248#define LPCG_TUPLE(rsrc, base) ((uint32_t)((((base) >> 12U) << 10U) | (rsrc)))
249/*! @brief Get the LPCG REG base address. */
250#define LPCG_TUPLE_REG_BASE(tuple) ((volatile uint32_t *)((((uint32_t)(tuple) >> 10U) & 0xFFFFFU) << 12U))
251/*! @brief Get the resource index. */
252#define LPCG_TUPLE_RSRC(tuple) ((sc_rsrc_t)((uint32_t)(tuple)&0x3FFU))
253/*! @brief LPCG Cell not available. */
254#define NV (0U)
255
256/*!
257 * @brief Peripheral clock name difinition used for clock gate, clock source
258 * and clock divider setting. It is defined as the corresponding register address.
259 */
260typedef enum _clock_ip_name
261{
262 kCLOCK_M4_0_Irqsteer = LPCG_TUPLE(SC_R_IRQSTR_M4_0, NV),
263 kCLOCK_M4_1_Irqsteer = LPCG_TUPLE(SC_R_IRQSTR_M4_1, NV),
264 kCLOCK_DMA_Lpspi0 = LPCG_TUPLE(SC_R_SPI_0, DMA__LPCG_LPSPI0_BASE),
265 kCLOCK_DMA_Lpspi1 = LPCG_TUPLE(SC_R_SPI_1, DMA__LPCG_LPSPI1_BASE),
266 kCLOCK_DMA_Lpspi2 = LPCG_TUPLE(SC_R_SPI_2, DMA__LPCG_LPSPI2_BASE),
267 kCLOCK_DMA_Lpspi3 = LPCG_TUPLE(SC_R_SPI_3, DMA__LPCG_LPSPI3_BASE),
268 kCLOCK_DMA_Lpuart0 = LPCG_TUPLE(SC_R_UART_0, DMA__LPCG_LPUART0_BASE),
269 kCLOCK_DMA_Lpuart1 = LPCG_TUPLE(SC_R_UART_1, DMA__LPCG_LPUART1_BASE),
270 kCLOCK_DMA_Lpuart2 = LPCG_TUPLE(SC_R_UART_2, DMA__LPCG_LPUART2_BASE),
271 kCLOCK_DMA_Lpuart3 = LPCG_TUPLE(SC_R_UART_3, DMA__LPCG_LPUART3_BASE),
272 kCLOCK_DMA_Lpuart4 = LPCG_TUPLE(SC_R_UART_4, DMA__LPCG_LPUART4_BASE),
273 kCLOCK_DMA_EmvSim0 = LPCG_TUPLE(SC_R_EMVSIM_0, DMA__LPCG_EMV_SIM0_BASE),
274 kCLOCK_DMA_EmvSim1 = LPCG_TUPLE(SC_R_EMVSIM_1, DMA__LPCG_EMV_SIM1_BASE),
275 kCLOCK_DMA_Dma0 = LPCG_TUPLE(SC_R_DMA_0_CH0, NV),
276 kCLOCK_DMA_Lpi2c0 = LPCG_TUPLE(SC_R_I2C_0, DMA__LPCG_LPI2C0_BASE),
277 kCLOCK_DMA_Lpi2c1 = LPCG_TUPLE(SC_R_I2C_1, DMA__LPCG_LPI2C1_BASE),
278 kCLOCK_DMA_Lpi2c2 = LPCG_TUPLE(SC_R_I2C_2, DMA__LPCG_LPI2C2_BASE),
279 kCLOCK_DMA_Lpi2c3 = LPCG_TUPLE(SC_R_I2C_3, DMA__LPCG_LPI2C3_BASE),
280 kCLOCK_DMA_Lpi2c4 = LPCG_TUPLE(SC_R_I2C_4, DMA__LPCG_LPI2C4_BASE),
281 kCLOCK_DMA_Lpadc0 = LPCG_TUPLE(SC_R_ADC_0, DMA__LPCG_ADC0_BASE),
282 kCLOCK_DMA_Lpadc1 = LPCG_TUPLE(SC_R_ADC_1, DMA__LPCG_ADC1_BASE),
283 kCLOCK_DMA_Ftm0 = LPCG_TUPLE(SC_R_FTM_0, DMA__LPCG_FTM0_BASE),
284 kCLOCK_DMA_Ftm1 = LPCG_TUPLE(SC_R_FTM_1, DMA__LPCG_FTM1_BASE),
285 kCLOCK_DMA_Can0 = LPCG_TUPLE(SC_R_CAN_0, DMA__LPCG_CAN0_BASE),
286 kCLOCK_DMA_Can1 = LPCG_TUPLE(SC_R_CAN_1, DMA__LPCG_CAN1_BASE),
287 kCLOCK_DMA_Can2 = LPCG_TUPLE(SC_R_CAN_2, DMA__LPCG_CAN2_BASE),
288 kCLOCK_HSIO_Gpio = LPCG_TUPLE(SC_R_HSIO_GPIO, HSIO__LPCG_GPIO_BASE),
289 kCLOCK_LVDS_0_Lpi2c0 = LPCG_TUPLE(SC_R_LVDS_0_I2C_0, DI_LVDS_0__LPCG_CLK_BASE),
290 kCLOCK_LVDS_0_Lpi2c1 = LPCG_TUPLE(SC_R_LVDS_0_I2C_1, DI_LVDS_0__LPCG_CLK_BASE),
291 kCLOCK_LVDS_1_Lpi2c0 = LPCG_TUPLE(SC_R_LVDS_1_I2C_0, DI_LVDS_1__LPCG_CLK_BASE),
292 kCLOCK_LVDS_1_Lpi2c1 = LPCG_TUPLE(SC_R_LVDS_1_I2C_1, DI_LVDS_1__LPCG_CLK_BASE),
293 kCLOCK_LSIO_Gpio0 = LPCG_TUPLE(SC_R_GPIO_0, LSIO__LPCG_GPIO0_BASE),
294 kCLOCK_LSIO_Gpio1 = LPCG_TUPLE(SC_R_GPIO_1, LSIO__LPCG_GPIO1_BASE),
295 kCLOCK_LSIO_Gpio2 = LPCG_TUPLE(SC_R_GPIO_2, LSIO__LPCG_GPIO2_BASE),
296 kCLOCK_LSIO_Gpio3 = LPCG_TUPLE(SC_R_GPIO_3, LSIO__LPCG_GPIO3_BASE),
297 kCLOCK_LSIO_Gpio4 = LPCG_TUPLE(SC_R_GPIO_4, LSIO__LPCG_GPIO4_BASE),
298 kCLOCK_LSIO_Gpio5 = LPCG_TUPLE(SC_R_GPIO_5, LSIO__LPCG_GPIO5_BASE),
299 kCLOCK_LSIO_Gpio6 = LPCG_TUPLE(SC_R_GPIO_6, LSIO__LPCG_GPIO6_BASE),
300 kCLOCK_LSIO_Gpio7 = LPCG_TUPLE(SC_R_GPIO_7, LSIO__LPCG_GPIO7_BASE),
301 kCLOCK_AUDIO_Gpt0 = LPCG_TUPLE(SC_R_GPT_5, AUDIO__LPCG_GPT0_BASE),
302 kCLOCK_AUDIO_Gpt1 = LPCG_TUPLE(SC_R_GPT_6, AUDIO__LPCG_GPT1_BASE),
303 kCLOCK_AUDIO_Gpt2 = LPCG_TUPLE(SC_R_GPT_7, AUDIO__LPCG_GPT2_BASE),
304 kCLOCK_AUDIO_Gpt3 = LPCG_TUPLE(SC_R_GPT_8, AUDIO__LPCG_GPT3_BASE),
305 kCLOCK_AUDIO_Gpt4 = LPCG_TUPLE(SC_R_GPT_9, AUDIO__LPCG_GPT4_BASE),
306 kCLOCK_AUDIO_Gpt5 = LPCG_TUPLE(SC_R_GPT_10, AUDIO__LPCG_GPT5_BASE),
307 kCLOCK_LSIO_Gpt0 = LPCG_TUPLE(SC_R_GPT_0, LSIO__LPCG_GPT0_BASE),
308 kCLOCK_LSIO_Gpt1 = LPCG_TUPLE(SC_R_GPT_1, LSIO__LPCG_GPT1_BASE),
309 kCLOCK_LSIO_Gpt2 = LPCG_TUPLE(SC_R_GPT_2, LSIO__LPCG_GPT2_BASE),
310 kCLOCK_LSIO_Gpt3 = LPCG_TUPLE(SC_R_GPT_3, LSIO__LPCG_GPT3_BASE),
311 kCLOCK_LSIO_Gpt4 = LPCG_TUPLE(SC_R_GPT_4, LSIO__LPCG_GPT4_BASE),
312 kCLOCK_LSIO_Mu0A = LPCG_TUPLE(SC_R_MU_0A, NV),
313 kCLOCK_LSIO_Mu1A = LPCG_TUPLE(SC_R_MU_1A, NV),
314 kCLOCK_LSIO_Mu2A = LPCG_TUPLE(SC_R_MU_2A, NV),
315 kCLOCK_LSIO_Mu3A = LPCG_TUPLE(SC_R_MU_3A, NV),
316 kCLOCK_LSIO_Mu4A = LPCG_TUPLE(SC_R_MU_4A, NV),
317 kCLOCK_LSIO_Mu5A = LPCG_TUPLE(SC_R_MU_5A, LSIO__LPCG_MU5_MCU_BASE),
318 kCLOCK_LSIO_Mu6A = LPCG_TUPLE(SC_R_MU_6A, LSIO__LPCG_MU6_MCU_BASE),
319 kCLOCK_LSIO_Mu7A = LPCG_TUPLE(SC_R_MU_7A, LSIO__LPCG_MU7_MCU_BASE),
320 kCLOCK_LSIO_Mu8A = LPCG_TUPLE(SC_R_MU_8A, LSIO__LPCG_MU8_MCU_BASE),
321 kCLOCK_LSIO_Mu9A = LPCG_TUPLE(SC_R_MU_9A, LSIO__LPCG_MU9_MCU_BASE),
322 kCLOCK_LSIO_Mu10A = LPCG_TUPLE(SC_R_MU_10A, LSIO__LPCG_MU10_MCU_BASE),
323 kCLOCK_LSIO_Mu11A = LPCG_TUPLE(SC_R_MU_11A, LSIO__LPCG_MU11_MCU_BASE),
324 kCLOCK_LSIO_Mu12A = LPCG_TUPLE(SC_R_MU_12A, LSIO__LPCG_MU12_MCU_BASE),
325 kCLOCK_LSIO_Mu13A = LPCG_TUPLE(SC_R_MU_13A, LSIO__LPCG_MU13_MCU_BASE),
326 kCLOCK_LSIO_Mu5B = LPCG_TUPLE(SC_R_MU_5B, LSIO__LPCG_MU5_DSP_BASE),
327 kCLOCK_LSIO_Mu6B = LPCG_TUPLE(SC_R_MU_6B, LSIO__LPCG_MU6_DSP_BASE),
328 kCLOCK_LSIO_Mu7B = LPCG_TUPLE(SC_R_MU_7B, LSIO__LPCG_MU7_DSP_BASE),
329 kCLOCK_LSIO_Mu8B = LPCG_TUPLE(SC_R_MU_8B, LSIO__LPCG_MU8_DSP_BASE),
330 kCLOCK_LSIO_Mu9B = LPCG_TUPLE(SC_R_MU_9B, LSIO__LPCG_MU9_DSP_BASE),
331 kCLOCK_LSIO_Mu10B = LPCG_TUPLE(SC_R_MU_10B, LSIO__LPCG_MU10_DSP_BASE),
332 kCLOCK_LSIO_Mu11B = LPCG_TUPLE(SC_R_MU_11B, LSIO__LPCG_MU11_DSP_BASE),
333 kCLOCK_LSIO_Mu12B = LPCG_TUPLE(SC_R_MU_12B, LSIO__LPCG_MU12_DSP_BASE),
334 kCLOCK_LSIO_Mu13B = LPCG_TUPLE(SC_R_MU_13B, LSIO__LPCG_MU13_DSP_BASE),
335 kCLOCK_LSIO_Flexspi0 = LPCG_TUPLE(SC_R_FSPI_0, LSIO__LPCG_QSPI0_BASE),
336 kCLOCK_LSIO_Flexspi1 = LPCG_TUPLE(SC_R_FSPI_1, LSIO__LPCG_QSPI1_BASE),
337 kCLOCK_M4_0_Rgpio = LPCG_TUPLE(SC_R_M4_0_RGPIO, NV),
338 kCLOCK_M4_0_Sema42 = LPCG_TUPLE(SC_R_M4_0_SEMA42, NV),
339 kCLOCK_M4_0_Tpm = LPCG_TUPLE(SC_R_M4_0_TPM, CM4_0__LPCG_TPM_BASE),
340 kCLOCK_M4_0_Lpit = LPCG_TUPLE(SC_R_M4_0_PIT, CM4_0__LPCG_LPIT_BASE),
341 kCLOCK_M4_0_Lpuart = LPCG_TUPLE(SC_R_M4_0_UART, CM4_0__LPCG_LPUART_BASE),
342 kCLOCK_M4_0_Lpi2c = LPCG_TUPLE(SC_R_M4_0_I2C, CM4_0__LPCG_LPI2C_BASE),
343 kCLOCK_M4_0_Intmux = LPCG_TUPLE(SC_R_M4_0_INTMUX, NV),
344 kCLOCK_M4_0_Mu0B = LPCG_TUPLE(SC_R_M4_0_MU_0B, NV),
345 kCLOCK_M4_0_Mu0A0 = LPCG_TUPLE(SC_R_M4_0_MU_0A0, NV),
346 kCLOCK_M4_0_Mu0A1 = LPCG_TUPLE(SC_R_M4_0_MU_0A1, NV),
347 kCLOCK_M4_0_Mu0A2 = LPCG_TUPLE(SC_R_M4_0_MU_0A2, NV),
348 kCLOCK_M4_0_Mu0A3 = LPCG_TUPLE(SC_R_M4_0_MU_0A3, NV),
349 kCLOCK_M4_0_Mu1A = LPCG_TUPLE(SC_R_M4_0_MU_1A, NV),
350 kCLOCK_M4_1_Rgpio = LPCG_TUPLE(SC_R_M4_1_RGPIO, NV),
351 kCLOCK_M4_1_Sema42 = LPCG_TUPLE(SC_R_M4_1_SEMA42, NV),
352 kCLOCK_M4_1_Tpm = LPCG_TUPLE(SC_R_M4_1_TPM, CM4_1__LPCG_TPM_BASE),
353 kCLOCK_M4_1_Lpit = LPCG_TUPLE(SC_R_M4_1_PIT, CM4_1__LPCG_LPIT_BASE),
354 kCLOCK_M4_1_Lpuart = LPCG_TUPLE(SC_R_M4_1_UART, CM4_1__LPCG_LPUART_BASE),
355 kCLOCK_SCU_Lpuart = LPCG_TUPLE(SC_R_SC_UART, SCU__LPCG_LPUART_BASE),
356 kCLOCK_M4_1_Lpi2c = LPCG_TUPLE(SC_R_M4_1_I2C, CM4_1__LPCG_LPI2C_BASE),
357 kCLOCK_M4_1_Intmux = LPCG_TUPLE(SC_R_M4_1_INTMUX, NV),
358 kCLOCK_M4_1_Mu0B = LPCG_TUPLE(SC_R_M4_1_MU_0B, NV),
359 kCLOCK_M4_1_Mu0A0 = LPCG_TUPLE(SC_R_M4_1_MU_0A0, NV),
360 kCLOCK_M4_1_Mu0A1 = LPCG_TUPLE(SC_R_M4_1_MU_0A1, NV),
361 kCLOCK_M4_1_Mu0A2 = LPCG_TUPLE(SC_R_M4_1_MU_0A2, NV),
362 kCLOCK_M4_1_Mu0A3 = LPCG_TUPLE(SC_R_M4_1_MU_0A3, NV),
363 kCLOCK_M4_1_Mu1A = LPCG_TUPLE(SC_R_M4_1_MU_1A, NV),
364 kCLOCK_SCU_Lpi2c = LPCG_TUPLE(SC_R_SC_I2C, SCU__LPCG_LPI2C_BASE),
365 kCLOCK_SCU_Sema42 = LPCG_TUPLE(SC_R_SC_SEMA42, NV),
366 kCLOCK_SCU_Lpit = LPCG_TUPLE(SC_R_SC_PIT, SCU__LPCG_LPIT_BASE),
367 kCLOCK_SCU_Tpm = LPCG_TUPLE(SC_R_SC_TPM, SCU__LPCG_TPM_BASE),
368 kCLOCK_AUDIO_Sai0 = LPCG_TUPLE(SC_R_SAI_0, AUDIO__LPCG_SAI0_BASE),
369 kCLOCK_AUDIO_Sai1 = LPCG_TUPLE(SC_R_SAI_1, AUDIO__LPCG_SAI1_BASE),
370 kCLOCK_AUDIO_Sai2 = LPCG_TUPLE(SC_R_SAI_2, AUDIO__LPCG_SAI2_BASE),
371 kCLOCK_AUDIO_Sai3 = LPCG_TUPLE(SC_R_SAI_3, AUDIO__LPCG_SAI3_BASE),
372 kCLOCK_AUDIO_Sai4 = LPCG_TUPLE(SC_R_SAI_4, AUDIO__LPCG_SAI_HDMIRX0_BASE),
373 kCLOCK_AUDIO_Sai5 = LPCG_TUPLE(SC_R_SAI_5, AUDIO__LPCG_SAI_HDMITX0_BASE),
374 kCLOCK_AUDIO_Sai6 = LPCG_TUPLE(SC_R_SAI_6, AUDIO__LPCG_SAI6_BASE),
375 kCLOCK_AUDIO_Sai7 = LPCG_TUPLE(SC_R_SAI_7, AUDIO__LPCG_SAI7_BASE),
376 kCLOCK_AUDIO_Esai0 = LPCG_TUPLE(SC_R_ESAI_0, AUDIO__LPCG_ESAI0_BASE),
377 kCLOCK_AUDIO_Esai1 = LPCG_TUPLE(SC_R_ESAI_1, AUDIO__LPCG_ESAI1_BASE),
378 kCLOCK_IMAGING_Isi0 = LPCG_TUPLE(SC_R_ISI_CH0, NV),
379 kCLOCK_IMAGING_Isi1 = LPCG_TUPLE(SC_R_ISI_CH1, NV),
380 kCLOCK_IMAGING_Isi2 = LPCG_TUPLE(SC_R_ISI_CH2, NV),
381 kCLOCK_IMAGING_Isi3 = LPCG_TUPLE(SC_R_ISI_CH3, NV),
382 kCLOCK_IMAGING_Isi4 = LPCG_TUPLE(SC_R_ISI_CH4, NV),
383 kCLOCK_IMAGING_Isi5 = LPCG_TUPLE(SC_R_ISI_CH5, NV),
384 kCLOCK_IMAGING_Isi6 = LPCG_TUPLE(SC_R_ISI_CH6, NV),
385 kCLOCK_IMAGING_Isi7 = LPCG_TUPLE(SC_R_ISI_CH7, NV),
386 kCLOCK_MIPI_0_Lpi2c0 = LPCG_TUPLE(SC_R_MIPI_0_I2C_0, DI_MIPI_0__LPCG_CLK_BASE),
387 kCLOCK_MIPI_0_Lpi2c1 = LPCG_TUPLE(SC_R_MIPI_0_I2C_1, DI_MIPI_0__LPCG_CLK_BASE),
388 kCLOCK_MIPI_1_Lpi2c0 = LPCG_TUPLE(SC_R_MIPI_1_I2C_0, DI_MIPI_1__LPCG_CLK_BASE),
389 kCLOCK_MIPI_1_Lpi2c1 = LPCG_TUPLE(SC_R_MIPI_1_I2C_1, DI_MIPI_1__LPCG_CLK_BASE),
390 kCLOCK_CSI_0_Lpi2c0 = LPCG_TUPLE(SC_R_CSI_0_I2C_0, MIPI_CSI_0__LPCG_CLK_BASE),
391 kCLOCK_CSI_1_Lpi2c0 = LPCG_TUPLE(SC_R_CSI_1_I2C_0, MIPI_CSI_1__LPCG_CLK_BASE),
392 kCLOCK_Dpu0 = LPCG_TUPLE(SC_R_DC_0, DC_0__LPCG_DSP0_CLK_BASE),
393 kCLOCK_Dpu1 = LPCG_TUPLE(SC_R_DC_1, DC_1__LPCG_DSP0_CLK_BASE),
394 kCLOCK_HDMI_Lpi2c0 = LPCG_TUPLE(SC_R_HDMI_I2C_0, DI_HDMI__LPCG_CLK_BASE),
395 kCLOCK_HDMI_RX_Lpi2c0 = LPCG_TUPLE(SC_R_HDMI_RX_I2C_0, RX_HDMI__LPCG_GPIO_IPG_CLK_S_BASE),
396 kCLOCK_MipiCsi2Rx0 = LPCG_TUPLE(SC_R_CSI_0, MIPI_CSI_0__LPCG_CLK_BASE),
397 kCLOCK_MipiCsi2Rx1 = LPCG_TUPLE(SC_R_CSI_1, MIPI_CSI_1__LPCG_CLK_BASE),
398 kCLOCK_MipiDsiHost0 = LPCG_TUPLE(SC_R_MIPI_0, DI_MIPI_0__LPCG_CLK_BASE),
399 kCLOCK_MipiDsiHost1 = LPCG_TUPLE(SC_R_MIPI_1, DI_MIPI_1__LPCG_CLK_BASE),
400 kCLOCK_Ldb0 = LPCG_TUPLE(SC_R_LVDS_0, NV),
401 kCLOCK_Ldb1 = LPCG_TUPLE(SC_R_LVDS_1, NV),
402 kCLOCK_CONNECTIVITY_Enet0 = LPCG_TUPLE(SC_R_ENET_0, CONNECTIVITY__LPCG_ENET0_BASE),
403 kCLOCK_CONNECTIVITY_Enet1 = LPCG_TUPLE(SC_R_ENET_1, CONNECTIVITY__LPCG_ENET1_BASE),
404 kCLOCK_AUDIO_Pll0 = LPCG_TUPLE(SC_R_AUDIO_PLL_0, NV),
405 kCLOCK_AUDIO_Pll1 = LPCG_TUPLE(SC_R_AUDIO_PLL_1, NV),
406 kCLOCK_IpInvalid = LPCG_TUPLE(SC_R_LAST, NV) /* The selected IP does not support clock control. */
407} clock_ip_name_t;
408
409#if defined(__cplusplus)
410extern "C" {
411#endif /* _cplusplus */
412
413/*!
414 * @brief Initialize Clock module.
415 *
416 * @param ipc IPC handle for communication with SCU, see sc_ipc_t.
417 */
418void CLOCK_Init(sc_ipc_t ipc);
419
420/*!
421 * @brief Deinitialize Clock module.
422 */
423void CLOCK_Deinit(void);
424
425/*!
426 * @brief Enable the clock for specific IP, with gate setting.
427 *
428 * @param name Which clock to enable, see \ref clock_ip_name_t.
429 * @param gate 0: clock always on, 1: HW auto clock gating.
430 * @return true if success, false if failure.
431 */
432bool CLOCK_EnableClockExt(clock_ip_name_t name, uint32_t gate);
433
434/*!
435 * @brief Enable the clock for specific IP.
436 *
437 * @param name Which clock to enable, see \ref clock_ip_name_t.
438 * @return true for success, false for failure.
439 */
440static inline bool CLOCK_EnableClock(clock_ip_name_t name)
441{
442 return CLOCK_EnableClockExt(name, 0);
443}
444
445/*!
446 * @brief Disable the clock for specific IP.
447 *
448 * @param name Which clock to disable, see \ref clock_ip_name_t.
449 * @return true for success, false for failure.
450 */
451bool CLOCK_DisableClock(clock_ip_name_t name);
452
453/*!
454 * @brief Set the clock frequency for specific IP module.
455 *
456 * This function sets the IP module clock frequency.
457 *
458 * @param name Which peripheral to check, see \ref clock_ip_name_t.
459 * @param freq Target clock frequency value in hertz.
460 * @return the Real clock frequency value in hertz, or 0 if failed
461 */
462uint32_t CLOCK_SetIpFreq(clock_ip_name_t name, uint32_t freq);
463
464/*!
465 * @brief Get the clock frequency for a specific IP module.
466 *
467 * This function gets the IP module clock frequency.
468 *
469 * @param name Which peripheral to get, see \ref clock_ip_name_t.
470 * @return Clock frequency value in hertz, or 0 if failed
471 */
472uint32_t CLOCK_GetIpFreq(clock_ip_name_t name);
473
474/*!
475 * @brief Gets the clock frequency for a specific clock name.
476 *
477 * This function checks the current clock configurations and then calculates
478 * the clock frequency for a specific clock name defined in clock_name_t.
479 *
480 * @param name Clock names defined in clock_name_t
481 * @return Clock frequency value in hertz
482 */
483uint32_t CLOCK_GetFreq(clock_name_t name);
484
485/*!
486 * @brief Get the core clock or system clock frequency.
487 *
488 * @return Clock frequency in Hz.
489 */
490uint32_t CLOCK_GetCoreSysClkFreq(void);
491
492/*!
493 * @brief Config the LPCG cell for specific IP.
494 *
495 * @param name Which clock to enable, see \ref clock_ip_name_t.
496 * @param swGate Software clock gating. false: clock is gated; true: clock is enabled
497 * @param hwGate Hardware auto gating. false: disable the HW clock gate control; true: HW clock gating is enabled
498 */
499void CLOCK_ConfigLPCG(clock_ip_name_t name, bool swGate, bool hwGate);
500
501/*!
502 * @brief Set LPCG gate for specific LPCG.
503 *
504 * @param regBase LPCG register base address.
505 * @param swGate Software clock gating. false: clock is gated; true: clock is enabled
506 * @param hwGate Hardware auto gating. false: disable the HW clock gate control; true: HW clock gating is enabled
507 * @param bitsMask The available bits in LPCG register. Each bit indicate the corresponding bit is available or not.
508 */
509void CLOCK_SetLpcgGate(volatile uint32_t *regBase, bool swGate, bool hwGate, uint32_t bitsMask);
510
511#if defined(__cplusplus)
512}
513#endif /* __cplusplus */
514
515/*! @} */
516
517#endif /* _FSL_CLOCK_H_ */
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_memory.h b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_memory.h
new file mode 100644
index 000000000..1f83092f1
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_memory.h
@@ -0,0 +1,116 @@
1/*
2 * Copyright 2017-2018 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _FSL_MEMORY_H_
8#define _FSL_MEMORY_H_
9
10#include "fsl_common.h"
11
12/*******************************************************************************
13 * Definitions
14 ******************************************************************************/
15/* Component ID definition, used by tools. */
16#ifndef FSL_COMPONENT_ID
17#define FSL_COMPONENT_ID "platform.drivers.memory"
18#endif
19/* The CM4 subsystem local TCM start address, refer to Reference Manual for detailed information */
20#define FSL_MEM_M4_TCM_BEGIN 0x1FFE0000U
21/* The CM4 subsystem local TCM end address, refer to Reference Manual for detailed information */
22#define FSL_MEM_M4_TCM_END 0x2001FFFFU
23
24/* The alias start address for CM4 subsystem */
25#define FSL_MEM_M4_ALIAS_BEGIN 0x21000000U
26/* The alias end address for CM4 subsystem */
27#define FSL_MEM_M4_ALIAS_END 0x211FFFFFU
28/*
29 This alias allows the ROM and OCRAM to be mapped to the CM4 system address space without the need
30 to enable and configure SMMU.
31 System-level address 0x0000_0000 to 0x001F_FFFF is mapped to the CM4 system address space 0x2100_0000 to 0x211F_FFFF
32*/
33#define FSL_MEM_M4_ALIAS_OFFSET 0x21000000U
34
35#if defined(MIMX8QM_CM4_CORE0)
36/* System level TCM memory address = CM4 subsystem local TCM address + FSL_FEATURE_TCM_OFFSET */
37#define FSL_MEM_M4_TCM_OFFSET 0x15000000U
38#elif defined(MIMX8QM_CM4_CORE1)
39/* System level TCM memory address = CM4 subsystem local TCM address + FSL_FEATURE_TCM_OFFSET */
40#define FSL_MEM_M4_TCM_OFFSET 0x19000000U
41#else
42#error "Device is not supported by this driver!"
43#endif
44
45typedef enum _mem_direction
46{
47 kMEMORY_Local2DMA = 0,
48 kMEMORY_DMA2Local,
49} mem_direction_t;
50
51/*******************************************************************************
52 * API
53 ******************************************************************************/
54#if defined(__cplusplus)
55extern "C" {
56#endif
57/*!
58 * @brief Convert the memory map address.
59 *
60 * This function convert the address between system mapped address and native mapped address.
61 * There maybe offset between subsystem native address and system address for some memory,
62 * this funciton convert the address to different memory map.
63 * @param addr address need to be converted.
64 * @param direction convert direction.
65 * @return the converted address
66 */
67static inline uint32_t MEMORY_ConvertMemoryMapAddress(uint32_t addr, mem_direction_t direction)
68{
69 uint32_t dest;
70
71 switch (direction)
72 {
73 case kMEMORY_Local2DMA:
74 {
75 if ((addr >= FSL_MEM_M4_TCM_BEGIN) && (addr <= FSL_MEM_M4_TCM_END))
76 {
77 dest = addr + FSL_MEM_M4_TCM_OFFSET;
78 }
79 else if ((addr >= FSL_MEM_M4_ALIAS_BEGIN) && (addr <= FSL_MEM_M4_ALIAS_END))
80 {
81 dest = addr - FSL_MEM_M4_ALIAS_OFFSET;
82 }
83 else
84 {
85 dest = addr;
86 }
87 break;
88 }
89 case kMEMORY_DMA2Local:
90 {
91 if ((addr >= (FSL_MEM_M4_TCM_BEGIN + FSL_MEM_M4_TCM_OFFSET)) &&
92 (addr <= (FSL_MEM_M4_TCM_END + FSL_MEM_M4_TCM_OFFSET)))
93 {
94 dest = addr - FSL_MEM_M4_TCM_OFFSET;
95 }
96 else if (addr <= (FSL_MEM_M4_ALIAS_END - FSL_MEM_M4_ALIAS_OFFSET))
97 {
98 dest = addr + FSL_MEM_M4_ALIAS_OFFSET;
99 }
100 else
101 {
102 dest = addr;
103 }
104 break;
105 }
106 default:
107 dest = addr;
108 break;
109 }
110
111 return dest;
112}
113#if defined(__cplusplus)
114}
115#endif /* __cplusplus */
116#endif /* _FSL_MEMORY_H_ */ \ No newline at end of file
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_sc_event.c b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_sc_event.c
new file mode 100644
index 000000000..9c3bdf774
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_sc_event.c
@@ -0,0 +1,399 @@
1/*
2 * Copyright 2019 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include "fsl_sc_event.h"
9#include "fsl_mu.h"
10#include "assert.h"
11
12/*******************************************************************************
13 * Definitions
14 ******************************************************************************/
15
16/* Component ID definition, used by tools. */
17#ifndef FSL_COMPONENT_ID
18#define FSL_COMPONENT_ID "platform.drivers.sc_event"
19#endif
20
21#if defined(MIMX8QM_CM4_CORE0)
22#define IPC_MU CM4_0__MU1_A
23#define SCEvent_MU_IRQHandler M4_0_MU1_A_IRQHandler
24#define IPC_MU_IRQn M4_0_MU1_A_IRQn
25#define IPC_MU_RSRC SC_R_M4_0_MU_1A
26#elif defined(MIMX8QM_CM4_CORE1)
27#define IPC_MU CM4_1__MU1_A
28#define SCEvent_MU_IRQHandler M4_1_MU1_A_IRQHandler
29#define IPC_MU_IRQn M4_1_MU1_A_IRQn
30#define IPC_MU_RSRC SC_R_M4_1_MU_1A
31#else
32#error "Unsupported CPU."
33#endif
34
35/*******************************************************************************
36 * Prototypes
37 ******************************************************************************/
38/* Define a structure to hold SRTM_MESSAGE_BUF_SIZE buffer. */
39typedef struct
40{
41 sc_event_list_t node;
42 uint8_t buf[sizeof(struct _sc_event_handler) - sizeof(sc_event_list_t)];
43} sc_event_handler_buf_t;
44/*******************************************************************************
45 * Code
46 ******************************************************************************/
47static volatile bool s_irq; /* MU interrupt status. */
48
49static uint32_t s_irqEnabled[SC_IRQ_NUM_GROUP] = {0U};
50static sc_event_list_t s_registeredHandler;
51static sc_ipc_t ipc; /* ipc handle */
52
53static sc_event_handler_buf_t s_handlerBuf[SC_EVENT_HANDLER_MEM_POOL_SIZE / sizeof(sc_event_handler_t)];
54static sc_event_list_t s_freeHandlerPool;
55
56static void *s_sem = NULL;
57static sc_event_sema4_post_t s_postFunc = NULL;
58
59void SCEvent_MU_IRQHandler(void);
60/*!
61 * @brief Initialize SC Event Handler list head.
62 *
63 * @param list SC Event Handler list head pointer.
64 */
65static inline void SCEvent_List_Init(sc_event_list_t *list)
66{
67 assert(list);
68
69 list->prev = list;
70 list->next = list;
71}
72
73/*!
74 * @brief Check whether SC Event Handler list is empty.
75 *
76 * @param list SC Event Handler list head pointer.
77 * @return TRUE when list is empty, FALSE otherwise.
78 */
79static inline bool SCEvent_List_IsEmpty(sc_event_list_t *list)
80{
81 assert(list);
82
83 return list->next == list;
84}
85
86/*!
87 * @brief Add list node at list tail.
88 *
89 * @param list SC Event Handler list head pointer.
90 * @param node SC Event Handler list node pointer to add.
91 */
92static inline void SCEvent_List_AddTail(sc_event_list_t *list, sc_event_list_t *node)
93{
94 assert(list);
95 assert(node);
96
97 node->prev = list->prev;
98 node->next = list;
99 list->prev->next = node;
100 list->prev = node;
101}
102
103/*!
104 * @brief Remove list node from list.
105 *
106 * @param node SC Event Handler list node pointer to remove.
107 */
108static inline void SCEvent_List_Remove(sc_event_list_t *node)
109{
110 assert(node);
111
112 node->prev->next = node->next;
113 node->next->prev = node->prev;
114 /* clear node */
115 SCEvent_List_Init(node);
116}
117
118/*!
119 * @brief Allocate memory with specific size.
120 *
121 * @param size memory size to allocate.
122 *
123 * @return allocated memory address.
124 */
125static void *SCEvent_Pool_Alloc(uint32_t size)
126{
127 uint32_t i;
128 void *buf;
129 uint32_t primask;
130
131 if (s_freeHandlerPool.next == NULL)
132 {
133 primask = DisableGlobalIRQ();
134 if (s_freeHandlerPool.next == NULL)
135 {
136 /* Handler list not initialized, initialize now. */
137 SCEvent_List_Init(&s_freeHandlerPool);
138 for (i = 0U; i < sizeof(s_handlerBuf) / sizeof(sc_event_handler_buf_t); i++)
139 {
140 SCEvent_List_AddTail(&s_freeHandlerPool, &s_handlerBuf[i].node);
141 }
142 }
143 EnableGlobalIRQ(primask);
144 }
145
146 if (size > sizeof(sc_event_handler_buf_t))
147 {
148 return NULL;
149 }
150 else
151 {
152 primask = DisableGlobalIRQ();
153 if (SCEvent_List_IsEmpty(&s_freeHandlerPool))
154 {
155 return NULL;
156 }
157 else
158 {
159 buf = (void *)s_freeHandlerPool.next;
160 SCEvent_List_Remove(s_freeHandlerPool.next);
161 EnableGlobalIRQ(primask);
162 }
163 }
164
165 return buf;
166}
167
168/*!
169 * @brief Free the allocated memory.
170 *
171 * @param buf the address of the allocated memory
172 */
173static void SCEvent_Pool_Free(void *buf)
174{
175 sc_event_handler_t hBuf;
176 uint32_t primask;
177
178 /* buffer locates in handler pool */
179 assert(((uint32_t)((sc_event_handler_buf_t*)buf) - (uint32_t)&s_handlerBuf[0]) % sizeof(sc_event_handler_buf_t) == 0U);
180 hBuf = (sc_event_handler_t)buf;
181 primask = DisableGlobalIRQ();
182 SCEvent_List_AddTail(&s_freeHandlerPool, &hBuf->node);
183 EnableGlobalIRQ(primask);
184}
185
186void SCEvent_Init(uint8_t priority)
187{
188 ipc = SystemGetScfwIpcHandle();
189 NVIC_SetPriority(IPC_MU_IRQn, priority);
190 (void)EnableIRQ(IPC_MU_IRQn);
191 MU_EnableInterrupts(IPC_MU, MU_SR_GIPn_MASK);
192
193 SCEvent_List_Init(&s_registeredHandler);
194}
195
196void SCEvent_Deinit(void)
197{
198 sc_event_list_t *list;
199 sc_event_handler_t handler;
200
201 /* Unregister all handler. */
202 while (!SCEvent_List_IsEmpty(&s_registeredHandler))
203 {
204 list = s_registeredHandler.next;
205 SCEvent_List_Remove(list);
206 handler = SC_EVENT_LIST_OBJ(sc_event_handler_t, node, list);
207 SCEvent_Pool_Free(handler);
208 }
209
210 MU_DisableInterrupts(IPC_MU, MU_SR_GIPn_MASK);
211 (void)DisableIRQ(IPC_MU_IRQn);
212}
213
214status_t SCEvent_Config(sc_event_t event, bool enable, uint32_t pt)
215{
216 uint32_t status;
217 sc_err_t err;
218 uint32_t mask = SC_EVENT_GET_IRQ(event);
219 uint8_t group = (uint8_t)SC_EVENT_GET_IRQ_GROUP(event);
220
221 /*
222 * The SCFW IRQ pending flags will be set even the IRQ not enabled. If it's the first IRQ to be enabled in the
223 * group, clear the group's pending IRQ status in case some IRQ has already pending.
224 */
225 if ((s_irqEnabled[group] == 0U) && enable)
226 {
227 err = sc_irq_status(ipc, IPC_MU_RSRC, group, &status);
228 if (err != SC_ERR_NONE)
229 {
230 return kStatus_Fail;
231 }
232 }
233
234 if (mask == SC_EVENT_IRQ_DUMMY)
235 {
236 err = sc_irq_enable(ipc, IPC_MU_RSRC, group, (0x1UL << pt), enable);
237 if (err != SC_ERR_NONE)
238 {
239 return kStatus_Fail;
240 }
241
242 if (enable)
243 {
244 s_irqEnabled[group] |= 0x1UL << pt;
245 }
246 else
247 {
248 /* Clear the flag if IRQ disabled. */
249 s_irqEnabled[group] &= (~(0x1UL << pt)) & SC_EVENT_IRQ_DUMMY;
250 }
251 }
252 else
253 {
254 err = sc_irq_enable(ipc, IPC_MU_RSRC, group, mask, enable);
255 if (err != SC_ERR_NONE)
256 {
257 return kStatus_Fail;
258 }
259 if (enable)
260 {
261 s_irqEnabled[group] |= mask;
262 }
263 else
264 {
265 s_irqEnabled[group] &= ~mask;
266 }
267 }
268
269 return kStatus_Success;
270}
271
272sc_event_handler_t SCEvent_RegisterEventHandler(sc_event_t event, sc_event_callback_t callback, void *userData)
273{
274 assert(callback);
275 uint32_t primask;
276 sc_event_handler_t handler = (sc_event_handler_t)SCEvent_Pool_Alloc(sizeof(sc_event_handler_buf_t));
277
278 if (handler == NULL)
279 {
280 return NULL;
281 }
282 else
283 {
284 (void)memset(handler, 0, sizeof(sc_event_handler_buf_t));
285 /* clear node */
286 SCEvent_List_Init(&handler->node);
287
288 handler->event = event;
289 handler->callback = callback;
290 handler->data = userData;
291
292 /* Add handler into registered handler list. */
293 primask = DisableGlobalIRQ();
294 SCEvent_List_AddTail(&s_registeredHandler, &handler->node);
295 EnableGlobalIRQ(primask);
296 return handler;
297 }
298}
299
300void SCEvent_UnregisterEventHandler(sc_event_handler_t handler)
301{
302 assert(handler);
303 uint32_t primask;
304
305 primask = DisableGlobalIRQ();
306 SCEvent_List_Remove(&handler->node);
307 EnableGlobalIRQ(primask);
308
309 SCEvent_Pool_Free(handler);
310}
311
312void SCEvent_Process(void)
313{
314 sc_err_t err;
315 uint32_t mask; /* Enabled IRQ mask. */
316 uint8_t group; /* Event group. */
317 uint32_t irqStatus[SC_IRQ_NUM_GROUP] = {0U};
318
319 sc_event_list_t *list;
320 sc_event_handler_t handler;
321
322 if (s_irq)
323 {
324 for (list = s_registeredHandler.next; list != &s_registeredHandler; list = list->next)
325 {
326 handler = SC_EVENT_LIST_OBJ(sc_event_handler_t, node, list);
327
328 mask = SC_EVENT_GET_IRQ(handler->event);
329 group = (uint8_t)SC_EVENT_GET_IRQ_GROUP(handler->event);
330 /* Only read and clear status once for a group. */
331 if (irqStatus[group] == 0U)
332 {
333 err = sc_irq_status(ipc, IPC_MU_RSRC, group, &irqStatus[group]);
334 if (err != SC_ERR_NONE)
335 {
336 continue;
337 }
338
339 }
340 /* If there's event pending and the event IRQ enabled, call the handler. */
341 if ((irqStatus[group] & mask & s_irqEnabled[group]) != 0U)
342 {
343 handler->callback(irqStatus[group], handler->data);
344 }
345 }
346
347 /* Clean up the status. */
348 (void)memset(irqStatus, 0, sizeof(irqStatus));
349
350 s_irq = false;
351 }
352}
353
354status_t SCEvent_WaitEvent(sc_event_sema4_wait_t wait, sc_event_sema4_post_t post, void *sem, uint32_t timeout)
355{
356 status_t ret = kStatus_Success;
357 uint32_t primask;
358
359 assert(post);
360 assert(wait);
361
362 primask = DisableGlobalIRQ();
363 if (!s_irq) /* Return immediately if there's event pending. */
364 {
365 s_sem = sem;
366 s_postFunc = post;
367 EnableGlobalIRQ(primask);
368 ret = wait(sem, timeout);
369 s_postFunc = NULL;
370 }
371 else
372 {
373 EnableGlobalIRQ(primask);
374 }
375
376 return ret;
377}
378
379/*!
380 * IRQ Handler for SCEvent Triggling MU IRQ
381 */
382void SCEvent_MU_IRQHandler(void)
383{
384 /* Clear interrupt flag */
385 MU_ClearStatusFlags(IPC_MU, MU_SR_GIPn_MASK);
386
387 if (s_postFunc != NULL)
388 {
389 s_postFunc(s_sem);
390 }
391
392 s_irq = true;
393
394/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
395 exception return operation might vector to incorrect interrupt */
396#if defined __CORTEX_M && (__CORTEX_M == 4U)
397 __DSB();
398#endif
399}
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_sc_event.h b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_sc_event.h
new file mode 100644
index 000000000..7aa4e2f5b
--- /dev/null
+++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8QM6/drivers/fsl_sc_event.h
@@ -0,0 +1,266 @@
1/*
2 * Copyright 2019 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#ifndef _FSL_SC_EVENT_H_
9#define _FSL_SC_EVENT_H_
10
11#include "fsl_common.h"
12#include "svc/irq/irq_api.h"
13#include "svc/pad/pad_api.h"
14
15/*!
16 * @addtogroup sc_event_driver
17 * @{
18 */
19
20/*******************************************************************************
21 * Definitions
22 ******************************************************************************/
23
24/*! @name Driver version */
25/*@{*/
26/*! @brief Group interrupt driver version for SDK */
27#define FSL_SC_EVENT_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */
28/*@}*/
29
30/*! @brief The SC Event handler memory pool size in bytes. */
31#ifndef SC_EVENT_HANDLER_MEM_POOL_SIZE
32#define SC_EVENT_HANDLER_MEM_POOL_SIZE (200U)
33#endif
34
35/*!
36 * @brief The SYSCTR SC Event maybe used as wakeup source in low power applications.
37 * Such as in LPM module(lpm.c), the SYSCTR is used as wakeup source in tickless idle.
38 */
39#ifndef SC_EVENT_USE_SYSCTR
40#define SC_EVENT_USE_SYSCTR (0)
41#endif
42
43#define SC_EVENT_IRQ_DUMMY (0xFFFFFFFU) /* Dummy mask. */
44#define SC_EVENT_TYPE_TUPLE(group, irq) (((group) << 28) | (irq)) /* Marco to compose SC Event type. */
45#define SC_EVENT_GET_IRQ_GROUP(type) (((uint32_t)(type) >> 28) & 0xFU) /* Marco to get SC IRQ group. */
46#define SC_EVENT_GET_IRQ(type) ((uint32_t)(type) & 0xFFFFFFFU) /* Marco to get SC IRQ mask. */
47
48/*!
49 * @brief Get SC Event list object structure pointer.
50 */
51#define SC_EVENT_LIST_OBJ(type, field, list) (type)((uint32_t)(list) - (uint32_t)(&((type)0)->field))
52
53/*! @brief SC Event type. */
54typedef enum _sc_event
55{
56 kSCEvent_TempHigh = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_HIGH), /*!< Temp alarm interrupt */
57 kSCEvent_TempCpu0High =
58 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_CPU0_HIGH), /*!< CPU0 temp alarm interrupt */
59 kSCEvent_TempCpu1High =
60 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_CPU1_HIGH), /*!< CPU1 temp alarm interrupt */
61 kSCEvent_TempGpu0High =
62 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_GPU0_HIGH), /*!< GPU0 temp alarm interrupt */
63 kSCEvent_TempGpu1High =
64 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_GPU1_HIGH), /*!< GPU1 temp alarm interrupt */
65 kSCEvent_TempDrc0High =
66 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_DRC0_HIGH), /*!< DRC0 temp alarm interrupt */
67 kSCEvent_TempDrc1High =
68 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_DRC1_HIGH), /*!< DRC1 temp alarm interrupt */
69 kSCEvent_TempVpuHigh =
70 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_VPU_HIGH), /*!< VPU temp alarm interrupt */
71 kSCEvent_TempPmic0High =
72 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_PMIC0_HIGH), /*!< PMIC0 temp alarm interrupt */
73 kSCEvent_TempPmic1High =
74 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_PMIC1_HIGH), /*!< PMIC1 temp alarm interrupt */
75 kSCEvent_TempLow = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_LOW), /*!< Temp alarm interrupt */
76 kSCEvent_TempCpu0Low =
77 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_CPU0_LOW), /*!< CPU0 temp alarm interrupt */
78 kSCEvent_TempCpu1Low =
79 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_CPU1_LOW), /*!< CPU1 temp alarm interrupt */
80 kSCEvent_TempGpu0Low =
81 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_GPU0_LOW), /*!< GPU0 temp alarm interrupt */
82 kSCEvent_TempGpu1Low =
83 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_GPU1_LOW), /*!< GPU1 temp alarm interrupt */
84 kSCEvent_TempDrc0Low =
85 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_DRC0_LOW), /*!< DRC0 temp alarm interrupt */
86 kSCEvent_TempDrc1Low =
87 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_DRC1_LOW), /*!< DRC1 temp alarm interrupt */
88 kSCEvent_TempVpuLow = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_VPU_LOW), /*!< VPU temp alarm interrupt */
89 kSCEvent_TempPmic0Low =
90 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_PMIC0_LOW), /*!< PMIC0 temp alarm interrupt */
91 kSCEvent_TempPmic1Low =
92 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_PMIC1_LOW), /*!< PMIC1 temp alarm interrupt */
93 kSCEvent_TempPmic2High =
94 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_PMIC2_HIGH), /*!< PMIC2 temp alarm interrupt */
95 kSCEvent_TempPmic2Low =
96 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_TEMP, SC_IRQ_TEMP_PMIC2_LOW), /*!< PMIC2 temp alarm interrupt */
97
98 kSCEvent_Wdog = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_WDOG, SC_IRQ_WDOG), /*!< Watchdog interrupt */
99
100 kSCEvent_Rtc = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_RTC, SC_IRQ_RTC), /*!< RTC interrupt */
101
102 kSCEvent_Button = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON), /*!< Button interrupt */
103 kSCEvent_Pad = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_WAKE, SC_IRQ_PAD), /*!< Pad wakeup */
104 kSCEvent_User1 = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_WAKE, SC_IRQ_USR1), /*!< User defined 1 */
105 kSCEvent_User2 = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_WAKE, SC_IRQ_USR2), /*!< User defined 2 */
106 kSCEvent_BcPad =
107 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_WAKE, SC_IRQ_BC_PAD), /*!< Pad wakeup (broadcast to all partitions) */
108#if (defined(SC_EVENT_USE_SYSCTR) && SC_EVENT_USE_SYSCTR)
109 kSCEvent_SysCtr = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_SYSCTR, SC_IRQ_SYSCTR), /*!< System counter interrupts */
110#endif
111 kSCEvent_Rebooted =
112 SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_REBOOTED, SC_EVENT_IRQ_DUMMY), /*!< Partition reboot complete */
113
114 kSCEvent_Reboot = SC_EVENT_TYPE_TUPLE(SC_IRQ_GROUP_REBOOT, SC_EVENT_IRQ_DUMMY) /*!< Partition reboot starting */
115} sc_event_t;
116
117/*! @brief SC Event callback function.
118 *
119 * The SC Event callback returns a status from the underlying layer.
120 * The status reflects the SC IRQ status got by sc_irq_status SCFW API. It's the bitmask of enabled IRQ in a group.
121 * Such as for kSCEvent_Reboot/kSCEvent_Rebooted event, if more than one partition reboot event is enabled, this status
122 * flag can be used to identify which partition the event comes from. Refer to SCFW API sc_irq_status for more details.
123 */
124typedef void (*sc_event_callback_t)(uint32_t status, void *userData);
125
126/*! @brief SC Event Semaphore Wait function.
127 *
128 * The Semaphore Wait/Post function is used in RTOS envirnoment to pass Semaphore Wait/Post function into SC Event
129 * driver. Unused in baremetal envirnonment. The task can wait the event by calling SCEvent_WaitEvent function.
130 */
131typedef status_t (*sc_event_sema4_wait_t)(void *sem, uint32_t timeout);
132
133/*! @brief SC Event Semaphore Post function.
134 *
135 * The Semaphore Wait/Post function is used in RTOS envirnoment to pass Semaphore Wait/Post function into SC Event
136 * driver. Unused in baremetal envirnonment. The post function is called to give semaphore if event triggered in IRQ.
137 */
138typedef void (*sc_event_sema4_post_t)(void *sem);
139
140/**
141 * @brief SC Event list fields
142 */
143typedef struct _sc_event_list
144{
145 struct _sc_event_list *prev; /*!< previous list node */
146 struct _sc_event_list *next; /*!< next list node */
147} sc_event_list_t;
148
149/*! @brief SC Event handler structure. */
150struct _sc_event_handler
151{
152 sc_event_list_t node;
153 sc_event_t event; /*!< Event type. */
154 sc_event_callback_t callback; /*!< Event callback. */
155 void *data; /*!< User data. */
156};
157
158/*!
159 * @brief SC Event handler is a pointer to the SC Event handler instance
160 */
161typedef struct _sc_event_handler *sc_event_handler_t;
162/*******************************************************************************
163 * API
164 ******************************************************************************/
165
166#ifdef __cplusplus
167extern "C" {
168#endif
169
170/*!
171 * @brief Initialize SC Event module.
172
173 * This function enable the IPC MU interrupt, setup to listen the event comes from SCU/SCFW.
174 *
175 * @param priority The SC IRQ interrupt priority. Once any SC IRQ enabled, the SCU will broadcast MU interrupt through
176 * the IPC MU to M4 cores.
177 *
178 * @retval None.
179 */
180void SCEvent_Init(uint8_t priority);
181
182/*!
183 * @brief Deinitialize SC Event.
184 *
185 * This function disable the IPC MU interrupt.
186 *
187 */
188void SCEvent_Deinit(void);
189
190/*!
191 * @brief Register SC Event handler.
192
193 * This function register the handler for the specified event. When the event is enabled by SCEvent_Config and happens,
194 * the callback will be called from SCEvent_process. More than one callback can be added for an event.
195 * But the total registered events are limited to
196 * SC_EVENT_HANDLER_MEM_POOL_SIZE/(sizeof(struct _sc_event_handler)).
197 *
198 * @param event The event to be registered with.
199 * @param callback The callback function. This function will be called from SCEvent_process.
200 * @param userData User defined callback function parameter.
201 *
202 * @retval SC Event handler.
203 */
204sc_event_handler_t SCEvent_RegisterEventHandler(sc_event_t event, sc_event_callback_t callback, void *userData);
205
206/*!
207 * @brief Unregister SC Event handler.
208
209 * This function unregister and delete the given event handler.
210 *
211 * @param handler The SC Event handler to unregister.
212 *
213 * @retval none.
214 */
215void SCEvent_UnregisterEventHandler(sc_event_handler_t handler);
216
217/*!
218 * @brief Configure SC Event.
219
220 * This function enables/disables response for the event comes from SCU/SCFW.
221 *
222 * @param event The event to be configured.
223 * @param enable Enable the event or not.
224 * @param pt Which partition the event comes from. Only applicable for partition reboot event: kSCEvent_Rebooted,
225 kSCEvent_Reboot.
226 *
227 * @retval kStatus_Success - Configure SC Event Successfully.
228 * @retval kStatus_Fail - Failed to configure SC Event.
229 */
230status_t SCEvent_Config(sc_event_t event, bool enable, uint32_t pt);
231
232/*!
233 * @brief SCEvent Process function.
234 *
235 * This function is used to check SC event status and handle all the registered event handlers. The SCFW API call is
236 * a blocking call and used to check SC IRQ status, so this function should be executed in task context to make sure
237 * other event(interrupt) handled in time. In RTOS enviroment, application creats a task and wait for some events came
238 * using SCEvent_WaitEvent to run this function to handle the events. In baremetal enviroment, application need
239 * preiodically call this function to make sure the pending events handled.
240 */
241void SCEvent_Process(void);
242
243/*!
244 * @brief Set Semaphore and Semaphore wait/post funciton in RTOS environment.
245 *
246 * The Semaphore Wait/Post function is used in RTOS envirnoment to pass Semaphore Wait/Post function into SC Event
247 * driver. Unused in baremetal envirnonment. The SCEvent_process will wait the Semaphore registered by
248 * SCEvent_SetWaitPostFunc until the event comes, and give the Semaphore, then it will handle the event and call the
249 * event handler's callback.
250 *
251 * @param wait Semaphore wait function.
252 * @param post Semaphore post function.
253 * @param sem Semaphore.
254 * @param timeout timeout.
255 *
256 * @retval kStatus_Success if succeed, kStatus_Timeout if timeout.
257 */
258status_t SCEvent_WaitEvent(sc_event_sema4_wait_t wait, sc_event_sema4_post_t post, void *sem, uint32_t timeout);
259
260#ifdef __cplusplus
261}
262#endif
263
264/*@}*/
265
266#endif /* _SC_EVENT_H_ */