drivers: clock_control: provide support for stm32f0.

Fixes #3923

Signed-off-by: Maciej Debski <maciej.debski@rndity.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
This commit is contained in:
Maciej Debski 2017-08-09 11:21:53 +02:00 committed by Kumar Gala
parent 026be85a1c
commit d0678201c3
5 changed files with 143 additions and 8 deletions

View file

@ -1,6 +1,7 @@
# Kconfig - STM32 MCU clock control driver config
#
# Copyright (c) 2017 Linaro
# Copyright (c) 2017 RnDity Sp. z o.o.
#
# SPDX-License-Identifier: Apache-2.0
#
@ -66,11 +67,15 @@ prompt "STM32 PLL Clock Source"
depends on CLOCK_STM32_SYSCLK_SRC_PLL
default CLOCK_STM32_PLL_SRC_HSI
if SOC_SERIES_STM32F0X!=y
config CLOCK_STM32_PLL_SRC_MSI
bool "MSI"
help
Use MSI as source of PLL
endif # SOC_SERIES_STM32F0X!=y
config CLOCK_STM32_PLL_SRC_HSI
bool "HSI"
help
@ -90,6 +95,34 @@ config CLOCK_STM32_PLL_SRC_PLL2
endchoice
if SOC_SERIES_STM32F0X
config CLOCK_STM32_PLL_PREDIV
int "PREDIV Prescaler"
default 1
range 1 16
help
PREDIV is PLLSCR clock signal prescaler, allowed values: 1 - 16.
config CLOCK_STM32_PLL_PREDIV1
int "PREDIV1 Prescaler"
depends on CLOCK_STM32_PLL_SRC_HSE && (SOC_STM32F091XB || SOC_STM32F091XC)
default 1
range 1 16
help
PREDIV is PLLSCR clock signal prescaler, present on STM32F091xB, STM32F091xC.
Allowed values: 1 - 16.
config CLOCK_STM32_PLL_MULTIPLIER
int "PLL multiplier"
depends on CLOCK_STM32_SYSCLK_SRC_PLL
default 6
range 2 16
help
PLL multiplier, allowed values: 2-16. PLL output must not exceed 48MHz.
endif # SOC_SERIES_STM32F0X
if SOC_SERIES_STM32F1X
config CLOCK_STM32_PLL_XTPRE
@ -271,6 +304,8 @@ config CLOCK_STM32_APB1_PRESCALER
APB1 Low speed clock (PCLK1) prescaler, allowed values:
1, 2, 4, 8, 16
if SOC_SERIES_STM32F0X!=y
config CLOCK_STM32_APB2_PRESCALER
int "APB2 prescaler"
default 1
@ -279,5 +314,7 @@ config CLOCK_STM32_APB2_PRESCALER
APB2 High speed clock (PCLK2) prescaler, allowed values:
1, 2, 4, 8, 16
endif # SOC_SERIES_STM32F0X!=y
endif # CLOCK_CONTROL_STM32_CUBE
endif # SOC_FAMILY_STM32

View file

@ -3,6 +3,7 @@ obj-$(CONFIG_CLOCK_CONTROL_QUARK_SE) += quark_se_clock_control.o
ifeq ($(CONFIG_CLOCK_CONTROL_STM32_CUBE),y)
obj-y += stm32_ll_clock.o
obj-$(CONFIG_SOC_SERIES_STM32L4X) += stm32l4x_ll_clock.o
obj-$(CONFIG_SOC_SERIES_STM32F0X) += stm32f0x_ll_clock.o
obj-$(CONFIG_SOC_SERIES_STM32F1X) += stm32f1x_ll_clock.o
obj-$(CONFIG_SOC_SERIES_STM32F3X) += stm32f3x_ll_clock.o
obj-$(CONFIG_SOC_SERIES_STM32F4X) += stm32f4x_ll_clock.o

View file

@ -1,6 +1,7 @@
/*
*
* Copyright (c) 2017 Linaro Limited.
* Copyright (c) 2017 RnDity Sp. z o.o.
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -19,8 +20,10 @@
#define _apb1_prescaler(v) LL_RCC_APB1_DIV_ ## v
#define apb1_prescaler(v) _apb1_prescaler(v)
#ifndef CONFIG_SOC_SERIES_STM32F0X
#define _apb2_prescaler(v) LL_RCC_APB2_DIV_ ## v
#define apb2_prescaler(v) _apb2_prescaler(v)
#endif /* CONFIG_SOC_SERIES_STM32F0X */
/**
* @brief fill in AHB/APB buses configuration structure
@ -31,8 +34,10 @@ static void config_bus_clk_init(LL_UTILS_ClkInitTypeDef *clk_init)
CONFIG_CLOCK_STM32_AHB_PRESCALER);
clk_init->APB1CLKDivider = apb1_prescaler(
CONFIG_CLOCK_STM32_APB1_PRESCALER);
#ifndef CONFIG_SOC_SERIES_STM32F0X
clk_init->APB2CLKDivider = apb2_prescaler(
CONFIG_CLOCK_STM32_APB2_PRESCALER);
#endif /* CONFIG_SOC_SERIES_STM32F0X */
}
static u32_t get_bus_clock(u32_t clock, u32_t prescaler)
@ -59,14 +64,16 @@ static inline int stm32_clock_control_on(struct device *dev,
case STM32_CLOCK_BUS_APB1:
LL_APB1_GRP1_EnableClock(pclken->enr);
break;
#ifdef CONFIG_SOC_SERIES_STM32L4X
#if defined(CONFIG_SOC_SERIES_STM32L4X) || defined(CONFIG_SOC_SERIES_STM32F0X)
case STM32_CLOCK_BUS_APB1_2:
LL_APB1_GRP2_EnableClock(pclken->enr);
break;
#endif /* CONFIG_SOC_SERIES_STM32L4X */
#endif /* CONFIG_SOC_SERIES_STM32L4X || CONFIG_SOC_SERIES_STM32F0X */
#ifndef CONFIG_SOC_SERIES_STM32F0X
case STM32_CLOCK_BUS_APB2:
LL_APB2_GRP1_EnableClock(pclken->enr);
break;
#endif /* CONFIG_SOC_SERIES_STM32F0X */
}
return 0;
@ -92,14 +99,16 @@ static inline int stm32_clock_control_off(struct device *dev,
case STM32_CLOCK_BUS_APB1:
LL_APB1_GRP1_DisableClock(pclken->enr);
break;
#ifdef CONFIG_SOC_SERIES_STM32L4X
#if defined(CONFIG_SOC_SERIES_STM32L4X) || defined(CONFIG_SOC_SERIES_STM32F0X)
case STM32_CLOCK_BUS_APB1_2:
LL_APB1_GRP2_DisableClock(pclken->enr);
break;
#endif
#endif /* CONFIG_SOC_SERIES_STM32L4X || CONFIG_SOC_SERIES_STM32F0X */
#ifndef CONFIG_SOC_SERIES_STM32F0X
case STM32_CLOCK_BUS_APB2:
LL_APB2_GRP1_DisableClock(pclken->enr);
break;
#endif /* CONFIG_SOC_SERIES_STM32F0X */
}
return 0;
@ -120,8 +129,10 @@ static int stm32_clock_control_get_subsys_rate(struct device *clock,
u32_t ahb_clock = SystemCoreClock;
u32_t apb1_clock = get_bus_clock(ahb_clock,
CONFIG_CLOCK_STM32_APB1_PRESCALER);
#ifndef CONFIG_SOC_SERIES_STM32F0X
u32_t apb2_clock = get_bus_clock(ahb_clock,
CONFIG_CLOCK_STM32_APB2_PRESCALER);
#endif /* CONFIG_SOC_SERIES_STM32F0X */
ARG_UNUSED(clock);
@ -131,14 +142,16 @@ static int stm32_clock_control_get_subsys_rate(struct device *clock,
*rate = ahb_clock;
break;
case STM32_CLOCK_BUS_APB1:
#ifdef CONFIG_SOC_SERIES_STM32L4X
#if defined(CONFIG_SOC_SERIES_STM32L4X) || defined(CONFIG_SOC_SERIES_STM32F0X)
case STM32_CLOCK_BUS_APB1_2:
#endif
#endif /* CONFIG_SOC_SERIES_STM32L4X || CONFIG_SOC_SERIES_STM32F0X */
*rate = apb1_clock;
break;
#ifndef CONFIG_SOC_SERIES_STM32F0X
case STM32_CLOCK_BUS_APB2:
*rate = apb2_clock;
break;
#endif /* CONFIG_SOC_SERIES_STM32F0X */
}
return 0;
@ -274,7 +287,9 @@ static int stm32_clock_control_init(struct device *dev)
/* Set APB1 & APB2 prescaler*/
LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider);
#ifndef CONFIG_SOC_SERIES_STM32F0X
LL_RCC_SetAPB2Prescaler(s_ClkInitStruct.APB2CLKDivider);
#endif /* CONFIG_SOC_SERIES_STM32F0X */
/* Set flash latency */
/* HSI used as SYSCLK, set latency to 0 */
@ -295,7 +310,9 @@ static int stm32_clock_control_init(struct device *dev)
/* Set APB1 & APB2 prescaler*/
LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider);
#ifndef CONFIG_SOC_SERIES_STM32F0X
LL_RCC_SetAPB2Prescaler(s_ClkInitStruct.APB2CLKDivider);
#endif /* CONFIG_SOC_SERIES_STM32F0X */
/* Set flash latency */
/* HSI used as SYSCLK, set latency to 0 */

View file

@ -0,0 +1,81 @@
/*
*
* Copyright (c) 2017 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <soc.h>
#include <soc_registers.h>
#include <clock_control.h>
#include <misc/util.h>
#include <clock_control/stm32_clock_control.h>
#include "stm32_ll_clock.h"
#ifdef CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL
/**
* @brief fill in pll configuration structure
*/
void config_pll_init(LL_UTILS_PLLInitTypeDef *pllinit)
{
/*
* PLL MUL
* 2 -> LL_RCC_PLL_MUL_2 -> 0x00000000
* 3 -> LL_RCC_PLL_MUL_3 -> 0x00040000
* 4 -> LL_RCC_PLL_MUL_4 -> 0x00080000
* ...
* 16 -> LL_RCC_PLL_MUL_16 -> 0x00380000
*/
pllinit->PLLMul = ((CONFIG_CLOCK_STM32_PLL_MULTIPLIER - 2)
<< RCC_CFGR_PLLMUL_Pos);
#if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
/* PREDIV support is a specific RCC configuration present on */
/* following SoCs: STM32F070x6, STM32F070xB and STM32F030xC */
/* cf Reference manual for more details */
#if defined(CONFIG_CLOCK_STM32_PLL_SRC_HSI)
pllinit->PLLDiv = LL_RCC_PLLSOURCE_HSI_DIV_2;
#else
/*
* PLL DIV
* 1 -> LL_RCC_PLLSOURCE_HSE_DIV_1 -> 0x00010000
* 2 -> LL_RCC_PLLSOURCE_HSE_DIV_2 -> 0x00010001
* 3 -> LL_RCC_PLLSOURCE_HSE_DIV_3 -> 0x00010002
* ...
* 16 -> LL_RCC_PLLSOURCE_HSE_DIV_16 -> 0x0001000F
*/
pllinit->PLLDiv = (RCC_CFGR_PLLSRC_HSE_PREDIV |
(CONFIG_CLOCK_STM32_PLL_PREDIV1 - 1));
#endif /* CONFIG_CLOCK_STM32_PLL_SRC_HSI */
#else
/*
* PLL Prediv
* 1 -> LL_RCC_PREDIV_DIV_1 -> 0x00000000
* 2 -> LL_RCC_PREDIV_DIV_2 -> 0x00000001
* 3 -> LL_RCC_PREDIV_DIV_3 -> 0x00000002
* ...
* 16 -> LL_RCC_PREDIV_DIV_16 -> 0x0000000F
*/
pllinit->Prediv = CONFIG_CLOCK_STM32_PLL_PREDIV - 1;
#endif /* RCC_PLLSRC_PREDIV1_SUPPORT */
}
#endif /* CONFIG_CLOCK_STM32_SYSCLK_SRC_PLL */
/**
* @brief Activate default clocks
*/
void config_enable_default_clocks(void)
{
/* Nothing for now */
}
/**
* @brief Function kept for driver genericity
*/
void LL_RCC_MSI_Disable(void)
{
/* Do nothing */
}

View file

@ -1,8 +1,8 @@
/*
* Copyright (c) 2016 Open-RnD Sp. z o.o.
* Copyright (c) 2016 BayLibre, SAS
* Copyright (c) 2016 RnDity Sp. z o.o.
* Copyright (c) 2017 Linaro Limited.
* Copyright (c) 2017 RnDity Sp. z o.o.
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -15,7 +15,6 @@
/* common clock control device name for all STM32 chips */
#define STM32_CLOCK_CONTROL_NAME "stm32-cc"
struct stm32_pclken {
u32_t bus;
u32_t enr;