1 /*
2  * Copyright (c) 2017-2022 Linaro Limited.
3  * Copyright (c) 2017 RnDity Sp. z o.o.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #ifndef ZEPHYR_DRIVERS_CLOCK_CONTROL_CLOCK_STM32_LL_MCO_H_
9 #define ZEPHYR_DRIVERS_CLOCK_CONTROL_CLOCK_STM32_LL_MCO_H_
10 
11 #include <stm32_ll_utils.h>
12 
13 #if CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK
14 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_NOCLOCK
15 #elif CONFIG_CLOCK_STM32_MCO1_SRC_EXT_HSE
16 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_EXT_HSE
17 #elif CONFIG_CLOCK_STM32_MCO1_SRC_LSE
18 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_LSE
19 #elif CONFIG_CLOCK_STM32_MCO1_SRC_HSE
20 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_HSE
21 #elif CONFIG_CLOCK_STM32_MCO1_SRC_LSI
22 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_LSI
23 #elif CONFIG_CLOCK_STM32_MCO1_SRC_MSI
24 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_MSI
25 #elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI
26 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_HSI
27 #elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI16
28 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_HSI
29 #elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI48
30 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_HSI48
31 #elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLCLK
32 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_PLLCLK
33 #elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLQCLK
34 	#if (CONFIG_SOC_SERIES_STM32G0X || CONFIG_SOC_SERIES_STM32WLX)
35 		#define MCO1_SOURCE	LL_RCC_MCO1SOURCE_PLLQCLK
36 	#elif (CONFIG_SOC_SERIES_STM32H5X || CONFIG_SOC_SERIES_STM32H7X)
37 		#define MCO1_SOURCE	LL_RCC_MCO1SOURCE_PLL1QCLK
38 	#else
39 		#error "PLLQCLK is not a valid clock source on your SOC"
40 	#endif
41 #elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLCLK_DIV2
42 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_PLLCLK_DIV_2
43 #elif CONFIG_CLOCK_STM32_MCO1_SRC_PLL2CLK
44 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_PLL2CLK
45 #elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLI2SCLK
46 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_PLLI2SCLK
47 #elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLI2SCLK_DIV2
48 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_PLLI2SCLK_DIV2
49 #elif CONFIG_CLOCK_STM32_MCO1_SRC_SYSCLK
50 	#define MCO1_SOURCE		LL_RCC_MCO1SOURCE_SYSCLK
51 #endif
52 
53 #if CONFIG_CLOCK_STM32_MCO2_SRC_SYSCLK
54 	#define MCO2_SOURCE		LL_RCC_MCO2SOURCE_SYSCLK
55 #elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLI2S
56 	#define MCO2_SOURCE		LL_RCC_MCO2SOURCE_PLLI2S
57 #elif CONFIG_CLOCK_STM32_MCO2_SRC_HSE
58 	#define MCO2_SOURCE		LL_RCC_MCO2SOURCE_HSE
59 #elif CONFIG_CLOCK_STM32_MCO2_SRC_LSI
60 	#define MCO2_SOURCE		LL_RCC_MCO2SOURCE_LSI
61 #elif CONFIG_CLOCK_STM32_MCO2_SRC_CSI
62 	#define MCO2_SOURCE		LL_RCC_MCO2SOURCE_CSI
63 #elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLCLK
64 	#define MCO2_SOURCE		LL_RCC_MCO2SOURCE_PLLCLK
65 #elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLPCLK
66 	#define MCO2_SOURCE		LL_RCC_MCO2SOURCE_PLL1PCLK
67 #elif CONFIG_CLOCK_STM32_MCO2_SRC_PLL2PCLK
68 	#define MCO2_SOURCE		LL_RCC_MCO2SOURCE_PLL2PCLK
69 #endif
70 
71 #define fn_mco1_prescaler(v) LL_RCC_MCO1_DIV_ ## v
72 #define mco1_prescaler(v) fn_mco1_prescaler(v)
73 
74 #define fn_mco2_prescaler(v) LL_RCC_MCO2_DIV_ ## v
75 #define mco2_prescaler(v) fn_mco2_prescaler(v)
76 
77 #ifdef __cplusplus
78 extern "C" {
79 #endif
80 
81 /*
82  * MCO configure doesn't active requested clock source,
83  * so please make sure the clock source was enabled.
84  */
85 __unused
stm32_clock_control_mco_init(void)86 static inline void stm32_clock_control_mco_init(void)
87 {
88 #ifndef CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK
89 #ifdef CONFIG_SOC_SERIES_STM32F1X
90 	LL_RCC_ConfigMCO(MCO1_SOURCE);
91 #else
92 	LL_RCC_ConfigMCO(MCO1_SOURCE,
93 			 mco1_prescaler(CONFIG_CLOCK_STM32_MCO1_DIV));
94 #endif
95 #endif /* CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK */
96 
97 #ifndef CONFIG_CLOCK_STM32_MCO2_SRC_NOCLOCK
98 	LL_RCC_ConfigMCO(MCO2_SOURCE,
99 			 mco2_prescaler(CONFIG_CLOCK_STM32_MCO2_DIV));
100 #endif /* CONFIG_CLOCK_STM32_MCO2_SRC_NOCLOCK */
101 }
102 
103 #ifdef __cplusplus
104 }
105 #endif
106 
107 #endif /* ZEPHYR_DRIVERS_CLOCK_CONTROL_CLOCK_STM32_LL_MCO_H_ */
108