drivers: clock-control: st: add MCO support for H7 family

Create clock_stm32_ll_mco.h file to bring stm32_clock_control_mco_init,
mco1_prescaler, mco2_prescaler, MCO1_SOURCE and MCO2_SOURCE definitions
which were previously in clock_stm32_ll_common.{c,h}. This is done so that
stm32_clock_control_mco_init can be called from clock_stm32_ll_h7.c.

Also update Kconfig.stm32 and add new MCO sources to allow H7 support.

Signed-off-by: Johan Lafon <johan.lafon@syslinbit.com>
This commit is contained in:
Johan Lafon 2023-07-17 16:00:09 +02:00 committed by Fabio Baltieri
parent c3d515755d
commit 691b357b59
5 changed files with 162 additions and 79 deletions

View file

@ -65,7 +65,8 @@ config CLOCK_STM32_MCO1_SRC_LSE
bool "LSE"
depends on SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32L4X
SOC_SERIES_STM32L4X || \
SOC_SERIES_STM32H7X
help
Use LSE as source of MCO1
@ -74,7 +75,8 @@ config CLOCK_STM32_MCO1_SRC_HSE
depends on SOC_SERIES_STM32F1X || \
SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32L4X
SOC_SERIES_STM32L4X || \
SOC_SERIES_STM32H7X
help
Use HSE as source of MCO1
@ -92,7 +94,10 @@ config CLOCK_STM32_MCO1_SRC_MSI
config CLOCK_STM32_MCO1_SRC_HSI
bool "HSI"
depends on SOC_SERIES_STM32F1X || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X
depends on SOC_SERIES_STM32F1X || \
SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32H7X
help
Use HSI as source of MCO1
@ -104,7 +109,8 @@ config CLOCK_STM32_MCO1_SRC_HSI16
config CLOCK_STM32_MCO1_SRC_HSI48
bool "HSI48"
depends on SOC_SERIES_STM32L4X
depends on SOC_SERIES_STM32L4X || \
SOC_SERIES_STM32H7X
help
Use HSI48 as source of MCO1
@ -114,6 +120,12 @@ config CLOCK_STM32_MCO1_SRC_PLLCLK
help
Use PLLCLK as source of MCO1
config CLOCK_STM32_MCO1_SRC_PLLQCLK
bool "PLLQ"
depends on SOC_SERIES_STM32H7X
help
Use PLLQ as source of MCO1
config CLOCK_STM32_MCO1_SRC_PLLCLK_DIV2
bool "PLLCLK_DIV2"
depends on SOC_SERIES_STM32F1X
@ -150,10 +162,12 @@ config CLOCK_STM32_MCO1_DIV
depends on !CLOCK_STM32_MCO1_SRC_NOCLOCK && (\
SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32L4X \
SOC_SERIES_STM32L4X || \
SOC_SERIES_STM32H7X \
)
default 1
range 1 5 if SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X
range 1 15 if SOC_SERIES_STM32H7X
range 1 16 if SOC_SERIES_STM32L4X
help
Prescaler for MCO1 output clock
@ -169,7 +183,9 @@ config CLOCK_STM32_MCO2_SRC_NOCLOCK
config CLOCK_STM32_MCO2_SRC_SYSCLK
bool "SYSCLK"
depends on SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X
depends on SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32H7X
help
Use SYSCLK as source of MCO2
@ -181,24 +197,54 @@ config CLOCK_STM32_MCO2_SRC_PLLI2S
config CLOCK_STM32_MCO2_SRC_HSE
bool "HSE"
depends on SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X
depends on SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32H7X
help
Use HSE as source of MCO2
config CLOCK_STM32_MCO2_SRC_LSI
bool "LSI"
depends on SOC_SERIES_STM32H7X
help
Use LSI as source of MCO2
config CLOCK_STM32_MCO2_SRC_CSI
bool "CSI"
depends on SOC_SERIES_STM32H7X
help
Use CSI as source of MCO2
config CLOCK_STM32_MCO2_SRC_PLLCLK
bool "PLLCLK"
depends on SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X
help
Use PLLCLK as source of MCO2
config CLOCK_STM32_MCO2_SRC_PLLPCLK
bool "PLLPCLK"
depends on SOC_SERIES_STM32H7X
help
Use PLLPCLK as source of MC02
config CLOCK_STM32_MCO2_SRC_PLL2PCLK
bool "PLL2PCLK"
depends on SOC_SERIES_STM32H7X
help
Use PLL2PCLK as source of MC02
endchoice
config CLOCK_STM32_MCO2_DIV
int "MCO2 prescaler"
depends on !CLOCK_STM32_MCO2_SRC_NOCLOCK
depends on !CLOCK_STM32_MCO2_SRC_NOCLOCK && (\
SOC_SERIES_STM32F4X || \
SOC_SERIES_STM32F7X || \
SOC_SERIES_STM32H7X \
)
default 1
range 1 5
range 1 5 if SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X
range 1 15 if SOC_SERIES_STM32H7X
help
allowed values: 1, 2, 3, 4, 5
Prescaler for MCO2 output clock
endif # CLOCK_CONTROL_STM32_CUBE

View file

@ -17,6 +17,7 @@
#include <zephyr/sys/__assert.h>
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
#include "clock_stm32_ll_common.h"
#include "clock_stm32_ll_mco.h"
#include "stm32_hsem.h"
/* Macros to fill up prescaler values */
@ -34,12 +35,6 @@
#define apb2_prescaler(v) fn_apb2_prescaler(v)
#endif
#define fn_mco1_prescaler(v) LL_RCC_MCO1_DIV_ ## v
#define mco1_prescaler(v) fn_mco1_prescaler(v)
#define fn_mco2_prescaler(v) LL_RCC_MCO2_DIV_ ## v
#define mco2_prescaler(v) fn_mco2_prescaler(v)
#if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb4_prescaler)
#define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK4_FREQ
#define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHB4Prescaler
@ -479,27 +474,6 @@ static void stm32_clock_switch_to_hsi(void)
}
}
/*
* MCO configure doesn't active requested clock source,
* so please make sure the clock source was enabled.
*/
static inline void stm32_clock_control_mco_init(void)
{
#ifndef CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK
#ifdef CONFIG_SOC_SERIES_STM32F1X
LL_RCC_ConfigMCO(MCO1_SOURCE);
#else
LL_RCC_ConfigMCO(MCO1_SOURCE,
mco1_prescaler(CONFIG_CLOCK_STM32_MCO1_DIV));
#endif
#endif /* CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK */
#ifndef CONFIG_CLOCK_STM32_MCO2_SRC_NOCLOCK
LL_RCC_ConfigMCO(MCO2_SOURCE,
mco2_prescaler(CONFIG_CLOCK_STM32_MCO2_DIV));
#endif /* CONFIG_CLOCK_STM32_MCO2_SRC_NOCLOCK */
}
__unused
static void set_up_plls(void)
{

View file

@ -14,48 +14,6 @@
#include <stm32_ll_utils.h>
#if CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_NOCLOCK
#elif CONFIG_CLOCK_STM32_MCO1_SRC_EXT_HSE
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_EXT_HSE
#elif CONFIG_CLOCK_STM32_MCO1_SRC_LSE
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_LSE
#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSE
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSE
#elif CONFIG_CLOCK_STM32_MCO1_SRC_LSI
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_LSI
#elif CONFIG_CLOCK_STM32_MCO1_SRC_MSI
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_MSI
#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSI
#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI16
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSI
#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI48
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSI48
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLCLK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLCLK
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLCLK_DIV2
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLCLK_DIV_2
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLL2CLK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLL2CLK
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLI2SCLK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLI2SCLK
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLI2SCLK_DIV2
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLI2SCLK_DIV2
#elif CONFIG_CLOCK_STM32_MCO1_SRC_SYSCLK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_SYSCLK
#endif
#if CONFIG_CLOCK_STM32_MCO2_SRC_SYSCLK
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_SYSCLK
#elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLI2S
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_PLLI2S
#elif CONFIG_CLOCK_STM32_MCO2_SRC_HSE
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_HSE
#elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLCLK
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_PLLCLK
#endif
/* Macros to fill up multiplication and division factors values */
#define z_pllm(v) LL_RCC_PLLM_DIV_ ## v
#define pllm(v) z_pllm(v)

View file

@ -16,6 +16,7 @@
#include <zephyr/drivers/clock_control.h>
#include <zephyr/sys/util.h>
#include <zephyr/drivers/clock_control/stm32_clock_control.h>
#include "clock_stm32_ll_mco.h"
#include "stm32_hsem.h"
@ -836,6 +837,9 @@ int stm32_clock_control_init(const struct device *dev)
z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
/* Configure MCO1/MCO2 based on Kconfig */
stm32_clock_control_mco_init();
/* Set up indiviual enabled clocks */
set_up_fixed_clock_sources();

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2017-2022 Linaro Limited.
* Copyright (c) 2017 RnDity Sp. z o.o.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_DRIVERS_CLOCK_CONTROL_CLOCK_STM32_LL_MCO_H_
#define ZEPHYR_DRIVERS_CLOCK_CONTROL_CLOCK_STM32_LL_MCO_H_
#include <stm32_ll_utils.h>
#if CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_NOCLOCK
#elif CONFIG_CLOCK_STM32_MCO1_SRC_EXT_HSE
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_EXT_HSE
#elif CONFIG_CLOCK_STM32_MCO1_SRC_LSE
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_LSE
#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSE
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSE
#elif CONFIG_CLOCK_STM32_MCO1_SRC_LSI
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_LSI
#elif CONFIG_CLOCK_STM32_MCO1_SRC_MSI
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_MSI
#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSI
#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI16
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSI
#elif CONFIG_CLOCK_STM32_MCO1_SRC_HSI48
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_HSI48
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLCLK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLCLK
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLQCLK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLL1QCLK
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLCLK_DIV2
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLCLK_DIV_2
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLL2CLK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLL2CLK
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLI2SCLK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLI2SCLK
#elif CONFIG_CLOCK_STM32_MCO1_SRC_PLLI2SCLK_DIV2
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_PLLI2SCLK_DIV2
#elif CONFIG_CLOCK_STM32_MCO1_SRC_SYSCLK
#define MCO1_SOURCE LL_RCC_MCO1SOURCE_SYSCLK
#endif
#if CONFIG_CLOCK_STM32_MCO2_SRC_SYSCLK
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_SYSCLK
#elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLI2S
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_PLLI2S
#elif CONFIG_CLOCK_STM32_MCO2_SRC_HSE
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_HSE
#elif CONFIG_CLOCK_STM32_MCO2_SRC_LSI
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_LSI
#elif CONFIG_CLOCK_STM32_MCO2_SRC_CSI
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_CSI
#elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLCLK
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_PLLCLK
#elif CONFIG_CLOCK_STM32_MCO2_SRC_PLLPCLK
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_PLL1PCLK
#elif CONFIG_CLOCK_STM32_MCO2_SRC_PLL2PCLK
#define MCO2_SOURCE LL_RCC_MCO2SOURCE_PLL2PCLK
#endif
#define fn_mco1_prescaler(v) LL_RCC_MCO1_DIV_ ## v
#define mco1_prescaler(v) fn_mco1_prescaler(v)
#define fn_mco2_prescaler(v) LL_RCC_MCO2_DIV_ ## v
#define mco2_prescaler(v) fn_mco2_prescaler(v)
#ifdef __cplusplus
extern "C" {
#endif
/*
* MCO configure doesn't active requested clock source,
* so please make sure the clock source was enabled.
*/
__unused
static inline void stm32_clock_control_mco_init(void)
{
#ifndef CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK
#ifdef CONFIG_SOC_SERIES_STM32F1X
LL_RCC_ConfigMCO(MCO1_SOURCE);
#else
LL_RCC_ConfigMCO(MCO1_SOURCE,
mco1_prescaler(CONFIG_CLOCK_STM32_MCO1_DIV));
#endif
#endif /* CONFIG_CLOCK_STM32_MCO1_SRC_NOCLOCK */
#ifndef CONFIG_CLOCK_STM32_MCO2_SRC_NOCLOCK
LL_RCC_ConfigMCO(MCO2_SOURCE,
mco2_prescaler(CONFIG_CLOCK_STM32_MCO2_DIV));
#endif /* CONFIG_CLOCK_STM32_MCO2_SRC_NOCLOCK */
}
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_DRIVERS_CLOCK_CONTROL_CLOCK_STM32_LL_MCO_H_ */