1 /* 2 * 3 * Copyright (c) 2017 Linaro Limited. 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 9 #include <soc.h> 10 #include <stm32_ll_bus.h> 11 #include <stm32_ll_rcc.h> 12 #include <stm32_ll_utils.h> 13 #include <zephyr/drivers/clock_control.h> 14 #include <zephyr/sys/util.h> 15 #include <zephyr/drivers/clock_control/stm32_clock_control.h> 16 #include "clock_stm32_ll_common.h" 17 18 #if defined(RCC_CFGR_USBPRE) 19 #define STM32_USB_PRE_ENABLED RCC_CFGR_USBPRE 20 #elif defined(RCC_CFGR_OTGFSPRE) 21 #define STM32_USB_PRE_ENABLED RCC_CFGR_OTGFSPRE 22 #endif 23 24 #if defined(STM32_PLL_ENABLED) 25 26 /* 27 * Select PLL source for STM32F1 Connectivity line devices (STM32F105xx and 28 * STM32F107xx). 29 * Both flags are defined in STM32Cube LL API. Keep only the selected one. 30 */ 31 32 /** 33 * @brief Set up pll configuration 34 */ 35 __unused config_pll_sysclock(void)36void config_pll_sysclock(void) 37 { 38 uint32_t pll_source, pll_mul, pll_div; 39 40 /* 41 * PLLMUL on SOC_STM32F10X_DENSITY_DEVICE 42 * 2 -> LL_RCC_PLL_MUL_2 -> 0x00000000 43 * 3 -> LL_RCC_PLL_MUL_3 -> 0x00040000 44 * 4 -> LL_RCC_PLL_MUL_4 -> 0x00080000 45 * ... 46 * 16 -> LL_RCC_PLL_MUL_16 -> 0x00380000 47 * 48 * PLLMUL on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE 49 * 4 -> LL_RCC_PLL_MUL_4 -> 0x00080000 50 * ... 51 * 9 -> LL_RCC_PLL_MUL_9 -> 0x001C0000 52 * 13 -> LL_RCC_PLL_MUL_6_5 -> 0x00340000 53 */ 54 pll_mul = ((STM32_PLL_MULTIPLIER - 2) << RCC_CFGR_PLLMULL_Pos); 55 56 if (!IS_ENABLED(STM32_PLL_SRC_HSI)) { 57 /* In case PLL source is not HSI, set prediv case by case */ 58 #ifdef CONFIG_SOC_STM32F10X_DENSITY_DEVICE 59 /* PLL prediv */ 60 if (IS_ENABLED(STM32_PLL_XTPRE)) { 61 /* 62 * SOC_STM32F10X_DENSITY_DEVICE: 63 * PLLXPTRE (depends on PLL source HSE) 64 * HSE/2 used as PLL source 65 */ 66 pll_div = LL_RCC_PREDIV_DIV_2; 67 } else { 68 /* 69 * SOC_STM32F10X_DENSITY_DEVICE: 70 * PLLXPTRE (depends on PLL source HSE) 71 * HSE used as direct PLL source 72 */ 73 pll_div = LL_RCC_PREDIV_DIV_1; 74 } 75 #else 76 /* 77 * SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE 78 * 1 -> LL_RCC_PREDIV_DIV_1 -> 0x00000000 79 * 2 -> LL_RCC_PREDIV_DIV_2 -> 0x00000001 80 * 3 -> LL_RCC_PREDIV_DIV_3 -> 0x00000002 81 * ... 82 * 16 -> LL_RCC_PREDIV_DIV_16 -> 0x0000000F 83 */ 84 pll_div = STM32_PLL_PREDIV - 1; 85 #endif /* CONFIG_SOC_STM32F10X_DENSITY_DEVICE */ 86 } 87 88 /* Configure PLL source */ 89 if (IS_ENABLED(STM32_PLL_SRC_HSI)) { 90 pll_source = LL_RCC_PLLSOURCE_HSI_DIV_2; 91 } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { 92 pll_source = LL_RCC_PLLSOURCE_HSE | pll_div; 93 #if defined(RCC_CFGR2_PREDIV1SRC) 94 } else if (IS_ENABLED(STM32_PLL_SRC_PLL2)) { 95 pll_source = LL_RCC_PLLSOURCE_PLL2 | pll_div; 96 #endif 97 } else { 98 __ASSERT(0, "Invalid source"); 99 } 100 101 LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_mul); 102 103 #ifdef STM32_USB_PRE_ENABLED 104 /* Prescaler is enabled: PLL clock is not divided */ 105 LL_RCC_SetUSBClockSource(IS_ENABLED(STM32_PLL_USBPRE) ? 106 STM32_USB_PRE_ENABLED : 0); 107 #endif 108 } 109 110 #endif /* defined(STM32_PLL_ENABLED) */ 111 112 #if defined(STM32_PLL2_ENABLED) 113 114 /** 115 * @brief Set up pll2 configuration 116 */ 117 __unused config_pll2(void)118void config_pll2(void) 119 { 120 uint32_t pll_mul, pll_div; 121 122 /* 123 * PLL2MUL on SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE 124 * 8 -> LL_RCC_PLL2_MUL_8 -> 0x00000600 125 * 9 -> LL_RCC_PLL2_MUL_9 -> 0x00000700 126 * ... 127 * 14 -> LL_RCC_PLL2_MUL_14 -> 0x00000C00 128 * 16 -> LL_RCC_PLL2_MUL_16 -> 0x00000E00 129 * 20 -> LL_RCC_PLL2_MUL_20 -> 0x00000F00 130 */ 131 if (STM32_PLL2_MULTIPLIER == 20) { 132 pll_mul = RCC_CFGR2_PLL2MUL20; 133 } else { 134 pll_mul = ((STM32_PLL2_MULTIPLIER - 2) << RCC_CFGR2_PLL2MUL_Pos); 135 } 136 137 /* 138 * SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE 139 * 1 -> LL_RCC_HSE_PREDIV2_DIV_1 -> 0x00000000 140 * 2 -> LL_RCC_HSE_PREDIV2_DIV_2 -> 0x00000010 141 * ... 142 * 16 -> LL_RCC_HSE_PREDIV2_DIV_16 -> 0x000000F0 143 */ 144 pll_div = ((STM32_PLL2_PREDIV - 1) << RCC_CFGR2_PREDIV2_Pos); 145 146 /* Check PLL2 source */ 147 if (!IS_ENABLED(STM32_PLL2_SRC_HSE)) { 148 __ASSERT(0, "Invalid source"); 149 } 150 151 LL_RCC_PLL_ConfigDomain_PLL2(pll_div, pll_mul); 152 } 153 154 #endif /* defined(STM32_PLL2_ENABLED) */ 155 156 /** 157 * @brief Activate default clocks 158 */ config_enable_default_clocks(void)159void config_enable_default_clocks(void) 160 { 161 if (IS_ENABLED(STM32_LSE_ENABLED)) { 162 /* Set the PWREN and BKPEN bits in the RCC_APB1ENR register */ 163 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); 164 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_BKP); 165 } 166 } 167