diff --git a/arch/arm/src/armv7-m/CMakeLists.txt b/arch/arm/src/armv7-m/CMakeLists.txt index c8d415ea927bf..7316713b2d9ba 100644 --- a/arch/arm/src/armv7-m/CMakeLists.txt +++ b/arch/arm/src/armv7-m/CMakeLists.txt @@ -34,7 +34,6 @@ set(SRCS arm_initialstate.c arm_itm.c arm_memfault.c - arm_perf.c arm_schedulesigaction.c arm_sigdeliver.c arm_svcall.c @@ -45,6 +44,11 @@ set(SRCS arm_vectors.c arm_dbgmonitor.c) + +if(CONFIG_ARCH_HAVE_PERF_EVENTS) + arm_perf.c +endif() + if(CONFIG_ARMV7M_SYSTICK) list(APPEND SRCS arm_systick.c) endif() diff --git a/arch/arm/src/armv7-m/Make.defs b/arch/arm/src/armv7-m/Make.defs index 8edd3e1ca9c01..7f6edc178d1f8 100644 --- a/arch/arm/src/armv7-m/Make.defs +++ b/arch/arm/src/armv7-m/Make.defs @@ -28,7 +28,7 @@ CMN_ASRCS += arm_exception.S arm_saveusercontext.S CMN_CSRCS += arm_busfault.c arm_cache.c arm_cpuinfo.c arm_doirq.c CMN_CSRCS += arm_hardfault.c arm_initialstate.c arm_itm.c -CMN_CSRCS += arm_memfault.c arm_perf.c +CMN_CSRCS += arm_memfault.c CMN_CSRCS += arm_schedulesigaction.c arm_sigdeliver.c CMN_CSRCS += arm_svcall.c arm_systemreset.c arm_tcbinfo.c CMN_CSRCS += arm_trigger_irq.c arm_usagefault.c arm_dbgmonitor.c @@ -37,6 +37,10 @@ ifneq ($(CONFIG_ARCH_HAVE_CUSTOM_VECTORS),y) CMN_CSRCS += arm_vectors.c endif +ifeq ($(CONFIG_ARCH_HAVE_PERF_EVENTS),y) + CMN_CSRDS += arm_perf.c +endif + ifeq ($(CONFIG_ARMV7M_SYSTICK),y) CMN_CSRCS += arm_systick.c endif diff --git a/arch/arm/src/armv7-m/arm_perf.c b/arch/arm/src/armv7-m/arm_perf.c index a8b58c5ea9447..dd3814e21758e 100644 --- a/arch/arm/src/armv7-m/arm_perf.c +++ b/arch/arm/src/armv7-m/arm_perf.c @@ -32,8 +32,6 @@ #include "itm.h" #include "nvic.h" -#ifdef CONFIG_ARCH_HAVE_PERF_EVENTS - /**************************************************************************** * Private Data ****************************************************************************/ @@ -78,4 +76,3 @@ void up_perf_convert(clock_t elapsed, struct timespec *ts) left = elapsed - ts->tv_sec * g_cpu_freq; ts->tv_nsec = NSEC_PER_SEC * (uint64_t)left / g_cpu_freq; } -#endif diff --git a/arch/arm/src/stm32h7/CMakeLists.txt b/arch/arm/src/stm32h7/CMakeLists.txt index 85c278d67d505..b079ed24d8937 100644 --- a/arch/arm/src/stm32h7/CMakeLists.txt +++ b/arch/arm/src/stm32h7/CMakeLists.txt @@ -30,11 +30,14 @@ list( stm32_gpio.c stm32_irq.c stm32_start.c - stm32_rcc.c stm32_lowputc.c stm32_serial.c stm32_uid.c) +if(CONFIG_CLK) + list(APPEND SRCS stm32_clk.c) +endif() + if(CONFIG_STM32H7_PROGMEM) list(APPEND SRCS stm32_flash.c) endif() diff --git a/arch/arm/src/stm32h7/Make.defs b/arch/arm/src/stm32h7/Make.defs index 008dfc475ade9..8c9a6ff24a8ea 100644 --- a/arch/arm/src/stm32h7/Make.defs +++ b/arch/arm/src/stm32h7/Make.defs @@ -46,9 +46,13 @@ endif # Required STM32H7 files CHIP_CSRCS += stm32_allocateheap.c stm32_exti_gpio.c stm32_gpio.c stm32_irq.c -CHIP_CSRCS += stm32_start.c stm32_rcc.c stm32_lowputc.c stm32_serial.c +CHIP_CSRCS += stm32_start.c stm32_serial.c CHIP_CSRCS += stm32_uid.c +ifeq ($(CONFIG_CLK),y) +CHIP_CSRCS += stm32_clk.c +endif + ifeq ($(CONFIG_SCHED_TICKLESS),y) CHIP_CSRCS += stm32_tickless.c else diff --git a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_rcc.h b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_rcc.h index 8124fbd9c7b71..b27cea15ac7d8 100644 --- a/arch/arm/src/stm32h7/hardware/stm32h7x3xx_rcc.h +++ b/arch/arm/src/stm32h7/hardware/stm32h7x3xx_rcc.h @@ -431,6 +431,17 @@ /* Bit definitions for RCC_PLL1DIVR register */ +#define RCC_PLLDIVR_N_SHIFT (0ul) +#define RCC_PLLDIVR_N(x) (((x) - 1) << RCC_PLL1DIVR_N_SHIFT) /* Multiplication factor for VCO: 4 - 512 */ +#define RCC_PLLDIVR_P_SHIFT (9ul) +#define RCC_PLLDIVR_P(x) (((x) - 1) << RCC_PLL1DIVR_P_SHIFT) /* DIVP division factor: 2 - 128, must be even */ +#define RCC_PLLDIVR_Q_SHIFT (16ul) +#define RCC_PLLDIVR_Q(x) (((x) - 1) << RCC_PLL1DIVR_Q_SHIFT) /* DIVQ division factor: 2 - 128 */ +#define RCC_PLLDIVR_R_SHIFT (24ul) +#define RCC_PLLDIVR_R(x) (((x) - 1) << RCC_PLL1DIVR_R_SHIFT) /* DIVR division factor: 2 - 128 */ + +/* Bit definitions for RCC_PLL1DIVR register */ + #define RCC_PLL1DIVR_N1_SHIFT (0ul) #define RCC_PLL1DIVR_N1(x) (((x) - 1) << RCC_PLL1DIVR_N1_SHIFT) /* Multiplication factor for VCO: 4 - 512 */ #define RCC_PLL1DIVR_P1_SHIFT (9ul) diff --git a/arch/arm/src/stm32h7/stm32_clk.c b/arch/arm/src/stm32h7/stm32_clk.c new file mode 100644 index 0000000000000..788656b331038 --- /dev/null +++ b/arch/arm/src/stm32h7/stm32_clk.c @@ -0,0 +1,1649 @@ +/**************************************************************************** + * arch/arm/src/stm32h7/stm32_rcc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "arm_internal.h" +#include "stm32_clk.h" +#include "hardware/stm32h7x3xx_rcc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Helper macro to define a gate configuration (for nested use) */ + +#define STM32_GATE(_name, _reg, _bit, _flags) \ + { .gate_name = _name, \ + .gate = { \ + .reg = _reg, \ + .bit_idx = _bit, \ + .flags = _flags \ + } \ + } + +/* Helper macro to define a divider configuration (for nested use) */ + +#define STM32_DIVIDER(_name, _reg, _shift, _width, _flags) \ + { .div_name = _name, \ + .div = { \ + .reg = _reg, \ + .shift = _shift, \ + .width = _width, \ + .flags = _flags \ + } \ + } + +/* Helper macro to define a mux configuration (for nested use) */ + +#define STM32_MUX(_name, _reg, _shift, _width, _flags) \ + { .mux_name = _name, \ + .mux = { \ + .reg = _reg, \ + .shift = _shift, \ + .width = _width, \ + .flags = _flags \ + } \ + } + +/* Helper macro to define a fixed rate configuration (for nested use) */ + +#define STM32_FIXED_RATE(_name, _rate, _flags) \ + { \ + .fixed_rate_name = _name, \ + .fixed_rate = { \ + .fixed_rate = _rate, \ + .flags = _flags, \ + } \ + } + +/* Helper macro to define a multiplier configuration (for nested use) */ + +#define STM32_MULTIPLIER(_name, _reg, _shift, _width, _flags) \ + { \ + .mult_name = _name, \ + .mult = { \ + .reg = _reg, \ + .shift = _shift, \ + .width = _width, \ + .flags = _flags \ + } \ + } + +/* Macro to define N-gated fixed rate oscillators */ + +#define STM32_GATED_FIXED_RATE_N(_fixed_rate, _flags, _num_gates, ...) \ +{ \ + .num_gates = _num_gates, \ + .base_flags = _flags, \ + .fixed_rate = _fixed_rate, \ + .gates = (const struct stm32_gate_s []) { __VA_ARGS__ }, \ +} + +/* Macro to define N-gated mux with variadic gates */ + +#define STM32_GATED_MUX_N(_parents, _parents_n, _mux, _flags, _num_gates, ...)\ +{ \ + .parent_names = _parents, \ + .parent_names_count = _parents_n, \ + .num_gates = _num_gates, \ + .base_flags = _flags, \ + .mux = _mux, \ + .gates = (const struct stm32_gate_s []) { __VA_ARGS__ } \ +} + +/* Macro to define PLL configuration */ + +#define STM32_PLL(_parent, _flags, _divn, _divp, _divq, _divr, \ + _gatep, _gateq, _gater) \ +{ \ + .parent_name = _parent, \ + .base_flags = _flags, \ + .divn = _divn, \ + .divp = _divp, \ + .divq = _divq, \ + .divr = _divr, \ + .gatep = _gatep, \ + .gateq = _gateq, \ + .gater = _gater, \ +} + +/* Macro to define divided mux with multiple dividers */ + +#define STM32_DIVIDED_MUX_N(_parents, _parents_n, _mux, _flags, _num_divs, ...)\ +{ \ + .parent_names = _parents, \ + .parent_names_count = _parents_n, \ + .num_divs = _num_divs, \ + .base_flags = _flags, \ + .mux = _mux, \ + .divs = (const struct stm32_divider_s []) { __VA_ARGS__ } \ +} + +/* Macro to define system clock */ + +#define STM32_SYSCLK(_sysclk_parents, _sysclk_parents_n, _sysclk_mux, \ + _traceclk_parents, _traceclk_parents_n, _traceclk_mux, \ + _flags, _cdcpre, _hpre, _cdppre, _cdppre1, _cdppre2, \ + _sdrppre) \ +{ \ + .sysclk_parent_names = _sysclk_parents, \ + .sysclk_parent_names_count = _sysclk_parents_n, \ + .traceclk_parent_names = _traceclk_parents, \ + .traceclk_parent_names_count = _traceclk_parents_n, \ + .base_flags = _flags, \ + .sysclk_mux = _sysclk_mux, \ + .traceclk_mux = _traceclk_mux, \ + .cdcpre = _cdcpre, \ + .hpre = _hpre, \ + .cdppre = _cdppre, \ + .cdppre1 = _cdppre1, \ + .cdppre2 = _cdppre2, \ + .sdrppre = _sdrppre, \ +} + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct stm32_gate_s +{ + const char *gate_name; + struct clk_gate_s gate; +}; + +struct stm32_fixed_rate_s +{ + const char *fixed_rate_name; + struct clk_fixed_rate_s fixed_rate; +}; + +struct stm32_multiplier_s +{ + const char *mult_name; + struct clk_multiplier_s mult; +}; + +struct stm32_divider_s +{ + const char *div_name; + struct clk_divider_s div; +}; + +struct stm32_mux_s +{ + const char *mux_name; + struct clk_mux_s mux; +}; + +/* Oscillators configuration */ + +struct stm32_gated_fixed_rate_s +{ + const uint8_t num_gates; + const uint8_t base_flags; + + const struct stm32_gate_s *gates; + struct stm32_fixed_rate_s fixed_rate; +}; + +/* PLL configuration */ + +struct stm32_pll_s +{ + const char *parent_name; + + const uint8_t base_flags; + + struct stm32_multiplier_s divn; + struct stm32_divider_s divp; + struct stm32_divider_s divq; + struct stm32_divider_s divr; + struct stm32_gate_s gatep; + struct stm32_gate_s gateq; + struct stm32_gate_s gater; +}; + +struct stm32_sysclk_s +{ + const char * const *sysclk_parent_names; + const int sysclk_parent_names_count; + const char * const *traceclk_parent_names; + const int traceclk_parent_names_count; + + const uint8_t base_flags; + + struct stm32_mux_s sysclk_mux; + struct stm32_mux_s traceclk_mux; + struct stm32_divider_s cdcpre; + struct stm32_divider_s hpre; + struct stm32_divider_s cdppre; + struct stm32_divider_s cdppre1; + struct stm32_divider_s cdppre2; + struct stm32_divider_s sdrppre; +}; + +struct stm32_gated_mux_s +{ + const char * const *parent_names; + const int parent_names_count; + + const char *mux_name; + + const uint8_t num_gates; + const uint8_t base_flags; + + const struct stm32_gate_s *gates; + struct stm32_mux_s mux; +}; + +/* Divided mux with multiple dividers configuration */ + +struct stm32_divided_mux_n_s +{ + const char * const *parent_names; + const int parent_names_count; + + const uint8_t num_divs; + const uint8_t base_flags; + + const struct stm32_divider_s *divs; + struct stm32_mux_s mux; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* STM32H7 gated oscillators */ + +static const struct stm32_gated_fixed_rate_s stm32h7_gated_oscs[] = +{ + STM32_GATED_FIXED_RATE_N( + STM32_FIXED_RATE("csi", STM32_CSI_FREQUENCY, 0), + CLK_IS_CRITICAL | CLK_NAME_IS_STATIC, + 2, + STM32_GATE("csi_ck", STM32_RCC_CR, 7, 0), + STM32_GATE("csi_ker_ck", STM32_RCC_CR, 9, 0) + ), + STM32_GATED_FIXED_RATE_N( + STM32_FIXED_RATE("hse", STM32_HSE_FREQUENCY, 0), + CLK_IS_CRITICAL | CLK_NAME_IS_STATIC, + 1, + STM32_GATE("hse_ck", STM32_RCC_CR, 16, 0) + ), + STM32_GATED_FIXED_RATE_N( + STM32_FIXED_RATE("hsi48", STM32_HSI48_FREQUENCY, 0), + CLK_IS_CRITICAL | CLK_NAME_IS_STATIC, + 1, + STM32_GATE("hsi48_ck", STM32_RCC_CR, 12, 0) + ), + STM32_GATED_FIXED_RATE_N( + STM32_FIXED_RATE("lsi", STM32_LSI_FREQUENCY, 0), + CLK_IS_CRITICAL | CLK_NAME_IS_STATIC, + 1, + STM32_GATE("lsi_ck", STM32_RCC_CSR, 0, 0) + ), + STM32_GATED_FIXED_RATE_N( + STM32_FIXED_RATE("hsi", STM32_HSI_FREQUENCY, 0), + CLK_IS_CRITICAL | CLK_NAME_IS_STATIC, + 0 + ), + STM32_GATED_FIXED_RATE_N( + STM32_FIXED_RATE("lse", STM32_LSE_FREQUENCY, 0), + CLK_IS_CRITICAL | CLK_NAME_IS_STATIC, + 1, + STM32_GATE("lse_ck", STM32_RCC_BDCR, 0, 0) + ), +}; + +/* STM32H7 PLL clock selection parent names */ + +static const char * const pll_cksel_parents[] = +{ + "hsi_ck", "csi_ck", "hse_ck", "off" +}; + +/* STM32H7 PLL clock selection */ + +static const struct stm32_divided_mux_n_s stm32h7_pll_cksel = + STM32_DIVIDED_MUX_N( + pll_cksel_parents, + nitems(pll_cksel_parents), + STM32_MUX( + "pllsrc", + STM32_RCC_PLLCKSELR, + RCC_PLLCKSELR_PLLSRC_SHIFT, + 2, + CLK_MUX_SET_RATE_NO_REPARENT + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + 3, + STM32_DIVIDER( + "divm1", + STM32_RCC_PLLCKSELR, + RCC_PLLCKSELR_DIVM1_SHIFT, + 6, + CLK_DIVIDER_ONE_BASED + ), + STM32_DIVIDER( + "divm2", + STM32_RCC_PLLCKSELR, + RCC_PLLCKSELR_DIVM2_SHIFT, + 6, + CLK_DIVIDER_ONE_BASED + ), + STM32_DIVIDER( + "divm3", + STM32_RCC_PLLCKSELR, + RCC_PLLCKSELR_DIVM3_SHIFT, + 6, + CLK_DIVIDER_ONE_BASED + ) + ); + +/* STM32H7 PLLs */ + +static const struct stm32_pll_s stm32h7_plls[] = +{ + STM32_PLL( + "divm1", + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | + CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + STM32_MULTIPLIER( + "divn1", + STM32_RCC_PLL1DIVR, + RCC_PLLDIVR_N_SHIFT, + 9, + CLK_MULT_ONE_BASED | CLK_MULT_ROUND_CLOSEST + ), + STM32_DIVIDER( + "divp1", + STM32_RCC_PLL1DIVR, + RCC_PLLDIVR_P_SHIFT, + 7, + CLK_DIVIDER_DIV_NEED_EVEN | CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "divq1", + STM32_RCC_PLL1DIVR, + RCC_PLLDIVR_Q_SHIFT, + 7, + CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "divr1", + STM32_RCC_PLL1DIVR, + RCC_PLLDIVR_R_SHIFT, + 7, + CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_GATE( + "pll1_p_ck", + STM32_RCC_PLLCFGR, + RCC_PLLCFGR_DIVP1EN_SHIFT, + 0 + ), + STM32_GATE( + "pll1_q_ck", + STM32_RCC_PLLCFGR, + RCC_PLLCFGR_DIVQ1EN_SHIFT, + 0 + ), + STM32_GATE( + "pll1_r_ck", + STM32_RCC_PLLCFGR, + RCC_PLLCFGR_DIVR1EN_SHIFT, + 0 + ) + ), + STM32_PLL( + "divm2", + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + STM32_MULTIPLIER( + "divn2", + STM32_RCC_PLL2DIVR, + RCC_PLLDIVR_N_SHIFT, + 9, + CLK_MULT_ONE_BASED | CLK_MULT_ROUND_CLOSEST + ), + STM32_DIVIDER( + "divp2", + STM32_RCC_PLL2DIVR, + RCC_PLLDIVR_P_SHIFT, + 7, + CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "divq2", + STM32_RCC_PLL2DIVR, + RCC_PLLDIVR_Q_SHIFT, + 7, + CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "divr2", + STM32_RCC_PLL2DIVR, + RCC_PLLDIVR_R_SHIFT, + 7, + CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_GATE( + "pll2_p_ck", + STM32_RCC_PLLCFGR, + RCC_PLLCFGR_DIVP2EN_SHIFT, + 0 + ), + STM32_GATE( + "pll2_q_ck", + STM32_RCC_PLLCFGR, + RCC_PLLCFGR_DIVQ2EN_SHIFT, + 0 + ), + STM32_GATE( + "pll2_r_ck", + STM32_RCC_PLLCFGR, + RCC_PLLCFGR_DIVR2EN_SHIFT, + 0 + ) + ), + STM32_PLL( + "divm3", + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + STM32_MULTIPLIER( + "divn3", + STM32_RCC_PLL3DIVR, + RCC_PLLDIVR_N_SHIFT, + 9, + CLK_MULT_ONE_BASED | CLK_MULT_ROUND_CLOSEST + ), + STM32_DIVIDER( + "divp3", + STM32_RCC_PLL3DIVR, + RCC_PLLDIVR_P_SHIFT, + 7, + CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "divq3", + STM32_RCC_PLL3DIVR, + RCC_PLLDIVR_Q_SHIFT, + 7, + CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "divr3", + STM32_RCC_PLL3DIVR, + RCC_PLLDIVR_R_SHIFT, + 7, + CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_GATE( + "pll3_p_ck", + STM32_RCC_PLLCFGR, + RCC_PLLCFGR_DIVP3EN_SHIFT, + 0 + ), + STM32_GATE( + "pll3_q_ck", + STM32_RCC_PLLCFGR, + RCC_PLLCFGR_DIVQ3EN_SHIFT, + 0 + ), + STM32_GATE( + "pll3_r_ck", + STM32_RCC_PLLCFGR, + RCC_PLLCFGR_DIVR3EN_SHIFT, + 0 + ) + ), +}; + +/* STM32H7 system clock parent names */ + +static const char * const sysclk_parents[] = +{ + "hsi_ck", "csi_ck", "hse_ck", "pll1_p_ck" +}; + +static const char * const traceclk_parents[] = +{ + "hsi_ck", "csi_ck", "hse_ck", "pll1_r_ck" +}; + +/* STM32H7 system clock */ + +static const struct stm32_sysclk_s stm32h7_sysclk = + STM32_SYSCLK( + sysclk_parents, + nitems(sysclk_parents), + STM32_MUX( + "sys_ck", + STM32_RCC_CFGR, + RCC_CFGR_SW_SHIFT, + 3, + CLK_MUX_SET_RATE_NO_REPARENT + ), + traceclk_parents, + nitems(traceclk_parents), + STM32_MUX( + "traceportck", + STM32_RCC_CFGR, + RCC_CFGR_SW_SHIFT, + 1, + CLK_MUX_SET_RATE_NO_REPARENT + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + STM32_DIVIDER( + "cdcpre", + STM32_RCC_D1CFGR, + RCC_D1CFGR_D1CPRE_SHIFT, + 4, + CLK_DIVIDER_POWER_OF_TWO | (8 << CLK_DIVIDER_MINDIV_OFF) | + CLK_DIVIDER_APPLY_OFFSET | CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "hpre", + STM32_RCC_D1CFGR, + RCC_D1CFGR_HPRE_SHIFT, + 4, + CLK_DIVIDER_POWER_OF_TWO | (8 << CLK_DIVIDER_MINDIV_OFF) | + CLK_DIVIDER_APPLY_OFFSET | CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "cdppre", + STM32_RCC_D1CFGR, + RCC_D1CFGR_D1PPRE_SHIFT, + 3, + CLK_DIVIDER_POWER_OF_TWO | (4 << CLK_DIVIDER_MINDIV_OFF) | + CLK_DIVIDER_APPLY_OFFSET | CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "cdppre1", + STM32_RCC_D2CFGR, + RCC_D2CFGR_D2PPRE1_SHIFT, + 3, + CLK_DIVIDER_POWER_OF_TWO | (4 << CLK_DIVIDER_MINDIV_OFF) | + CLK_DIVIDER_APPLY_OFFSET | CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "cdppre2", + STM32_RCC_D2CFGR, + RCC_D2CFGR_D2PPRE2_SHIFT, + 3, + CLK_DIVIDER_POWER_OF_TWO | (4 << CLK_DIVIDER_MINDIV_OFF) | + CLK_DIVIDER_APPLY_OFFSET | CLK_DIVIDER_ROUND_CLOSEST + ), + STM32_DIVIDER( + "sdrppre", + STM32_RCC_D3CFGR, + RCC_D3CFGR_D3PPRE_SHIFT, + 3, + CLK_DIVIDER_POWER_OF_TWO | (4 << CLK_DIVIDER_MINDIV_OFF) | + CLK_DIVIDER_APPLY_OFFSET | CLK_DIVIDER_ROUND_CLOSEST + ) + ); + +/* STM32H7 gated muxes parent names */ + +static const char * const sdmmcsel_parents[] = +{ + "pll1_q_ck", "pll2_r_ck" +}; + +static const char * const qspisel_parents[] = +{ + "hpre", "pll1_q_ck", "pll2_r_ck", "per_ck" +}; + +static const char * const ckpersel_parents[] = +{ + "hsi_ker_ck", "csi_ker_ck", "hse_ck" +}; + +static const char * const fmcsel_parents[] = +{ + "hpre", "pll1_q_ck", "pll2_r_ck", "per_ck" +}; + +static const char * const swpsel_parents[] = +{ + "cdppre1", "hsi_ker_ck" +}; + +static const char * const fdcansel_parents[] = +{ + "hse_ck", "pll1_q_ck", "pll2_q_ck" +}; + +static const char * const dfsdm1sel_parents[] = +{ + "cdppre2", "sysclk" +}; + +static const char * const spdifsel_parents[] = +{ + "pll1_q_ck", "pll2_r_ck", "pll3_r_ck", "hsi_ker_ck" +}; + +static const char * const spi45sel_parents[] = +{ + "cdppre2", "pll2_r_ck", "pll3_r_ck", + "hsi_ker_ck", "csi_ker_ck", "hse_ck" +}; + +static const char * const spi123sel_parents[] = +{ + "pll1_q_ck", "pll2_p_ck", "pll3_p_ck", + "i2s_ckin", "per_ck" +}; + +static const char * const sai23sel_parents[] = +{ + "pll1_q_ck", "pll2_p_ck", "pll3_p_ck", + "i2s_ckin", "per_ck" +}; + +static const char * const sai1sel_parents[] = +{ + "pll1_q_ck", "pll2_p_ck", "pll3_p_ck", + "i2s_ckin", "per_ck" +}; + +static const char * const lptim1sel_parents[] = +{ + "cdppre1", "pll2_p_ck", "pll3_r_ck", + "lse_ck", "lsi_ck", "per_ck" +}; + +static const char * const cecsel_parents[] = +{ + "lse_ck", "lsi_ck", "csi_ker_ck" +}; + +static const char * const usbsel_parents[] = +{ + "pll1_q_ck", "pll3_q_ck", "hsi48_ck" +}; + +static const char * const i2c123sel_parents[] = +{ + "cdppre1", "pll3_r_ck", "hsi_ker_ck", "csi_ker_ck" +}; + +static const char * const rngsel_parents[] = +{ + "hsi48_ck", "pll1_q_ck", "lse_ck", "lsi_ck" +}; + +static const char * const usart16sel_parents[] = +{ + "cdppre2", "pll2_r_ck", "pll3_r_ck", + "hsi_ker_ck", "csi_ker_ck", "lse_ck" +}; + +static const char * const usart234578sel_parents[] = +{ + "cdppre1", "pll2_r_ck", "pll3_r_ck", + "hsi_ker_ck", "csi_ker_ck", "lse_ck" +}; + +static const char * const spi6sel_parents[] = +{ + "sdrppre", "pll2_r_ck", "pll3_r_ck", + "hsi_ker_ck", "csi_ker_ck", "hse_ck" +}; + +static const char * const sai4bsel_parents[] = +{ + "pll1_q_ck", "pll2_p_ck", "pll3_p_ck", + "i2s_ckin", "per_ck" +}; + +static const char * const sai4asel_parents[] = +{ + "pll1_q_ck", "pll2_p_ck", "pll3_p_ck", + "i2s_ckin", "per_ck" +}; + +static const char * const adcsel_parents[] = +{ + "pll2_p_ck", "pll3_r_ck", "per_ck" +}; + +static const char * const lptim345sel_parents[] = +{ + "sdrppre", "pll2_p_ck", "pll3_r_ck", + "lse_ck", "lsi_ck", "per_ck" +}; + +static const char * const lptim2sel_parents[] = +{ + "sdrppre", "pll2_p_ck", "pll3_r_ck", + "lse_ck", "lsi_ck", "per_ck" +}; + +static const char * const i2c4sel_parents[] = +{ + "sdrppre", "pll3_r_ck", "hsi_ker_ck", "csi_ker_ck" +}; + +static const char * const lpuart1sel_parents[] = +{ + "sdrppre", "pll2_r_ck", "pll3_r_ck", + "hsi_ker_ck", "csi_ker_ck", "lse_ck" +}; + +/* STM32H7 gated muxes */ + +static const struct stm32_gated_mux_s stm32h7_gated_muxes[] = +{ + STM32_GATED_MUX_N( + ckpersel_parents, nitems(ckpersel_parents), + STM32_MUX( + "per_ck", STM32_RCC_D1CCIPR, RCC_D1CCIPR_CKPERSEL_SHIFT, 2, + CLK_MUX_SET_RATE_NO_REPARENT + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 0 + ), + STM32_GATED_MUX_N( + sdmmcsel_parents, nitems(sdmmcsel_parents), + STM32_MUX( + "sdmmcsel", + STM32_RCC_D1CCIPR, + RCC_D1CCIPR_SDMMC_SHIFT, + 1, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 2, + STM32_GATE("sdmmc1_ker_ck", STM32_RCC_AHB3ENR, 16, 0), + STM32_GATE("sdmmc2_ker_ck", STM32_RCC_AHB2ENR, 9, 0) + ), + STM32_GATED_MUX_N( + qspisel_parents, nitems(qspisel_parents), + STM32_MUX( + "qspisel", + STM32_RCC_D1CCIPR, + RCC_D1CCIPR_QSPISEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("quadspi_ker_ck", STM32_RCC_AHB3ENR, 14, 0) + ), + STM32_GATED_MUX_N( + fmcsel_parents, nitems(fmcsel_parents), + STM32_MUX( + "fmcsel", + STM32_RCC_D1CCIPR, + RCC_D1CCIPR_FMCSEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("fmc_ker_ck", STM32_RCC_AHB3ENR, 12, 0) + ), + STM32_GATED_MUX_N( + swpsel_parents, nitems(swpsel_parents), + STM32_MUX( + "swpsel", + STM32_RCC_D2CCIP1R, + RCC_D2CCIP1R_SWPSEL_SHIFT, + 1, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("swpmi_ker_ck", STM32_RCC_APB3ENR, 2, 0) + ), + STM32_GATED_MUX_N( + fdcansel_parents, nitems(fdcansel_parents), + STM32_MUX( + "fdcansel", + STM32_RCC_D2CCIP1R, + RCC_D2CCIP1R_FDCANSEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("fdcan_ker_ck", STM32_RCC_APB1HENR, 8, 0) + ), + STM32_GATED_MUX_N( + dfsdm1sel_parents, nitems(dfsdm1sel_parents), + STM32_MUX( + "dfsdm1sel", + STM32_RCC_D2CCIP1R, + RCC_D2CCIP1R_DFSDM1SEL_SHIFT, + 1, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("dfsdm1_ker_ck", STM32_RCC_APB2ENR, 28, 0) + ), + STM32_GATED_MUX_N( + spdifsel_parents, nitems(spdifsel_parents), + STM32_MUX( + "spdifsel", + STM32_RCC_D2CCIP1R, + RCC_D2CCIP1R_SPDIFSEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("spdifrx_ker_ck", STM32_RCC_APB1LENR, 16, 0) + ), + STM32_GATED_MUX_N( + spi45sel_parents, nitems(spi45sel_parents), + STM32_MUX( + "spi45sel", + STM32_RCC_D2CCIP1R, + RCC_D2CCIP1R_SPI45SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 2, + STM32_GATE("spi4_ker_ck", STM32_RCC_APB2ENR, 13, 0), + STM32_GATE("spi5_ker_ck", STM32_RCC_APB2ENR, 20, 0) + ), + STM32_GATED_MUX_N( + spi123sel_parents, nitems(spi123sel_parents), + STM32_MUX( + "spi123sel", + STM32_RCC_D2CCIP1R, + RCC_D2CCIP1R_SPI123SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 3, + STM32_GATE("spi1_ker_ck", STM32_RCC_APB2ENR, 12, 0), + STM32_GATE("spi2_ker_ck", STM32_RCC_APB1LENR, 14, 0), + STM32_GATE("spi3_ker_ck", STM32_RCC_APB1LENR, 15, 0) + ), + STM32_GATED_MUX_N( + sai23sel_parents, nitems(sai23sel_parents), + STM32_MUX( + "sai23sel", + STM32_RCC_D2CCIP1R, + RCC_D2CCIP1R_SAI23SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 2, + STM32_GATE("sai2_ker_ck", STM32_RCC_APB2ENR, 22, 0), + STM32_GATE("sai3_ker_ck", STM32_RCC_APB2ENR, 23, 0) + ), + STM32_GATED_MUX_N( + sai1sel_parents, nitems(sai1sel_parents), + STM32_MUX( + "sai1sel", + STM32_RCC_D2CCIP1R, + RCC_D2CCIP1R_SAI1SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("sai1_ker_ck", STM32_RCC_APB2ENR, 22, 0) + ), + STM32_GATED_MUX_N( + lptim1sel_parents, nitems(lptim1sel_parents), + STM32_MUX( + "lptim1sel", + STM32_RCC_D2CCIP2R, + RCC_D2CCIP2R_LPTIM1SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("lptim1_ker_ck", STM32_RCC_APB1LENR, 9, 0) + ), + STM32_GATED_MUX_N( + cecsel_parents, nitems(cecsel_parents), + STM32_MUX( + "cecsel", + STM32_RCC_D2CCIP2R, + RCC_D2CCIP2R_CECSEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("cec_ker_ck", STM32_RCC_APB1LENR, 27, 0) + ), + STM32_GATED_MUX_N( + usbsel_parents, nitems(usbsel_parents), + STM32_MUX( + "usbsel", + STM32_RCC_D2CCIP2R, + RCC_D2CCIP2R_USBSEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("usb_ker_ck", STM32_RCC_AHB1ENR, 25, 0) + ), + STM32_GATED_MUX_N( + i2c123sel_parents, nitems(i2c123sel_parents), + STM32_MUX( + "i2c123sel", + STM32_RCC_D2CCIP2R, + RCC_D2CCIP2R_I2C123SEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 3, + STM32_GATE("i2c1_ker_ck", STM32_RCC_APB1LENR, 21, 0), + STM32_GATE("i2c2_ker_ck", STM32_RCC_APB1LENR, 22, 0), + STM32_GATE("i2c3_ker_ck", STM32_RCC_APB1LENR, 23, 0) + ), + STM32_GATED_MUX_N( + rngsel_parents, nitems(rngsel_parents), + STM32_MUX( + "rngsel", + STM32_RCC_D2CCIP2R, + RCC_D2CCIP2R_RNGSEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("rng_ker_ck", STM32_RCC_AHB2ENR, 6, 0) + ), + STM32_GATED_MUX_N( + usart16sel_parents, nitems(usart16sel_parents), + STM32_MUX( + "usart16sel", + STM32_RCC_D2CCIP2R, + RCC_D2CCIP2R_USART16SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + 2, + STM32_GATE("usart1_ker_ck", STM32_RCC_APB2ENR, 4, 0), + STM32_GATE("usart6_ker_ck", STM32_RCC_APB2ENR, 5, 0) + ), + STM32_GATED_MUX_N( + usart234578sel_parents, nitems(usart234578sel_parents), + STM32_MUX( + "usart234578sel", + STM32_RCC_D2CCIP2R, + RCC_D2CCIP2R_USART234578SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 6, + STM32_GATE("usart2_ker_ck", STM32_RCC_APB1LENR, 17, 0), + STM32_GATE("usart3_ker_ck", STM32_RCC_APB1LENR, 18, 0), + STM32_GATE("uart4_ker_ck", STM32_RCC_APB1LENR, 19, 0), + STM32_GATE("uart5_ker_ck", STM32_RCC_APB1LENR, 20, 0), + STM32_GATE("uart7_ker_ck", STM32_RCC_APB1LENR, 30, 0), + STM32_GATE("uart8_ker_ck", STM32_RCC_APB1LENR, 31, 0) + ), + STM32_GATED_MUX_N( + spi6sel_parents, nitems(spi6sel_parents), + STM32_MUX( + "spi6sel", + STM32_RCC_D3CCIPR, + RCC_D3CCIPR_SPI6SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("spi6_ker_ck", STM32_RCC_APB4ENR, 5, 0) + ), + STM32_GATED_MUX_N( + sai4bsel_parents, nitems(sai4bsel_parents), + STM32_MUX( + "sai4bsel", + STM32_RCC_D3CCIPR, + RCC_D3CCIPR_SAI4BSEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("sai4b_ker_ck", STM32_RCC_APB4ENR, 21, 0) + ), + STM32_GATED_MUX_N( + sai4asel_parents, nitems(sai4asel_parents), + STM32_MUX( + "sai4asel", + STM32_RCC_D3CCIPR, + RCC_D3CCIPR_SAI4ASEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("sai4a_ker_ck", STM32_RCC_APB4ENR, 21, 0) + ), + STM32_GATED_MUX_N( + adcsel_parents, nitems(adcsel_parents), + STM32_MUX( + "adcsel", + STM32_RCC_D3CCIPR, + RCC_D3CCIPR_ADCSEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("adc_ker_ck", STM32_RCC_AHB1ENR, 5, 0) + ), + STM32_GATED_MUX_N( + lptim345sel_parents, nitems(lptim345sel_parents), + STM32_MUX( + "lptim345sel", + STM32_RCC_D3CCIPR, + RCC_D3CCIPR_LPTIM345SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 3, + STM32_GATE("lptim3_ker_ck", STM32_RCC_APB4ENR, 3, 0), + STM32_GATE("lptim4_ker_ck", STM32_RCC_APB4ENR, 4, 0), + STM32_GATE("lptim5_ker_ck", STM32_RCC_APB4ENR, 5, 0) + ), + STM32_GATED_MUX_N( + lptim2sel_parents, nitems(lptim2sel_parents), + STM32_MUX( + "lptim2sel", + STM32_RCC_D3CCIPR, + RCC_D3CCIPR_LPTIM2SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("lptim2_ker_ck", STM32_RCC_APB4ENR, 9, 0) + ), + STM32_GATED_MUX_N( + i2c4sel_parents, nitems(i2c4sel_parents), + STM32_MUX( + "i2c4sel", + STM32_RCC_D3CCIPR, + RCC_D3CCIPR_I2C4SEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("i2c4_ker_ck", STM32_RCC_APB4ENR, 7, 0) + ), + STM32_GATED_MUX_N( + lpuart1sel_parents, nitems(lpuart1sel_parents), + STM32_MUX( + "lpuart1sel", + STM32_RCC_D3CCIPR, + RCC_D3CCIPR_LPUART1SEL_SHIFT, + 3, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC | CLK_SET_RATE_PARENT, + 1, + STM32_GATE("lpuart1_ker_ck", STM32_RCC_APB4ENR, 3, 0) + ), +}; + +/* STM32H7 RTC clock parent names */ + +static const char * const rtcsel_parents[] = +{ + "off", "lse_ck_gate", "lsi_ck_gate", "hse_ck_gate" +}; + +/* STM32H7 RTC clock */ + +static const struct stm32_gated_mux_s stm32h7_rtcsel = + STM32_GATED_MUX_N( + rtcsel_parents, nitems(rtcsel_parents), + STM32_MUX( + "rtcsel", + STM32_RCC_BDCR, + RCC_BDCR_RTCSEL_SHIFT, + 2, + CLK_MUX_ROUND_CLOSEST + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + 1, + STM32_GATE("rcc_rtc_ck", STM32_RCC_BDCR, 15, 0) + ); + +/* STM32H7 MCO clocks parent names */ + +static const char * const mco1_parents[] = +{ + "hsi_ck", "lse_ck", "hse_ck", "pll1_q_ck", "hsi48_ck" +}; + +static const char * const mco2_parents[] = +{ + "sys_ck", "pll2_p_ck", "hse_ck", + "pll1_p_ck", "csi_ck", "lsi_ck" +}; + +/* STM32H7 MCO clocks */ + +static const struct stm32_divided_mux_n_s stm32h7_mco[] = +{ + STM32_DIVIDED_MUX_N( + mco1_parents, + nitems(mco1_parents), + STM32_MUX( + "mco1", + STM32_RCC_CFGR, + RCC_CFGR_MCO1_SHIFT, + 3, + 0 + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + 1, + STM32_DIVIDER( + "mco1pre", + STM32_RCC_CFGR, + RCC_CFGR_MCO1PRE_SHIFT, + 4, + CLK_DIVIDER_POWER_OF_TWO + ) + ), + STM32_DIVIDED_MUX_N( + mco2_parents, + nitems(mco2_parents), + STM32_MUX( + "mco2", + STM32_RCC_CFGR, + RCC_CFGR_MCO2_SHIFT, + 3, + 0 + ), + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + 1, + STM32_DIVIDER( + "mco2pre", + STM32_RCC_CFGR, + RCC_CFGR_MCO2PRE_SHIFT, + 4, + CLK_DIVIDER_POWER_OF_TWO + ) + ), +}; + +/* STM32H7 GPIO gates */ + +static const struct stm32_gate_s stm32h7_gpio_gates[] = +{ + STM32_GATE("gpioa_ker_ck", STM32_RCC_AHB4ENR, 0, 0), + STM32_GATE("gpiob_ker_ck", STM32_RCC_AHB4ENR, 1, 0), + STM32_GATE("gpioc_ker_ck", STM32_RCC_AHB4ENR, 2, 0), + STM32_GATE("gpiod_ker_ck", STM32_RCC_AHB4ENR, 3, 0), + STM32_GATE("gpioe_ker_ck", STM32_RCC_AHB4ENR, 4, 0), + STM32_GATE("gpiof_ker_ck", STM32_RCC_AHB4ENR, 5, 0), + STM32_GATE("gpiog_ker_ck", STM32_RCC_AHB4ENR, 6, 0), + STM32_GATE("gpioh_ker_ck", STM32_RCC_AHB4ENR, 7, 0), + STM32_GATE("gpioi_ker_ck", STM32_RCC_AHB4ENR, 8, 0), + STM32_GATE("gpioj_ker_ck", STM32_RCC_AHB4ENR, 9, 0), + STM32_GATE("gpiok_ker_ck", STM32_RCC_AHB4ENR, 10, 0), +}; + +/* STM32H7 APB1 timer gates (parent: cdppre1) */ + +static const struct stm32_gate_s stm32h7_apb1_tim_gates[] = +{ + STM32_GATE("tim2_ker_ck", STM32_RCC_APB1LENR, 0, 0), + STM32_GATE("tim3_ker_ck", STM32_RCC_APB1LENR, 1, 0), + STM32_GATE("tim4_ker_ck", STM32_RCC_APB1LENR, 2, 0), + STM32_GATE("tim5_ker_ck", STM32_RCC_APB1LENR, 3, 0), + STM32_GATE("tim6_ker_ck", STM32_RCC_APB1LENR, 4, 0), + STM32_GATE("tim7_ker_ck", STM32_RCC_APB1LENR, 5, 0), + STM32_GATE("tim12_ker_ck", STM32_RCC_APB1LENR, 6, 0), + STM32_GATE("tim13_ker_ck", STM32_RCC_APB1LENR, 7, 0), + STM32_GATE("tim14_ker_ck", STM32_RCC_APB1LENR, 8, 0), +}; + +/* STM32H7 APB2 timer gates (parent: cdppre2) */ + +static const struct stm32_gate_s stm32h7_apb2_tim_gates[] = +{ + STM32_GATE("tim1_ker_ck", STM32_RCC_APB2ENR, 0, 0), + STM32_GATE("tim8_ker_ck", STM32_RCC_APB2ENR, 1, 0), + STM32_GATE("tim15_ker_ck", STM32_RCC_APB2ENR, 16, 0), + STM32_GATE("tim16_ker_ck", STM32_RCC_APB2ENR, 17, 0), + STM32_GATE("tim17_ker_ck", STM32_RCC_APB2ENR, 18, 0), +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void +stm32_register_gated_osc(const struct stm32_gated_fixed_rate_s *osc); +static void +stm32_register_pll(const struct stm32_pll_s *pll); +static void +stm32_register_sysclk(const struct stm32_sysclk_s *sysclk); +static void +stm32_register_gated_mux(const struct stm32_gated_mux_s *gated_mux); +static void +stm32_register_divided_mux_n(const struct stm32_divided_mux_n_s *divided_mux_n); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void +stm32_register_gated_osc(const struct stm32_gated_fixed_rate_s *osc) +{ + int i; + + /* Register the fixed rate clock */ + + ASSERT(clk_register_fixed_rate( + osc->fixed_rate.fixed_rate_name, + NULL, + osc->base_flags, + (FAR struct clk_fixed_rate_s *)&osc->fixed_rate.fixed_rate + )); + + /* Register all gate clocks using the fixed rate as parent */ + + for (i = 0; i < osc->num_gates; i++) + { + ASSERT(clk_register_gate( + osc->gates[i].gate_name, + osc->fixed_rate.fixed_rate_name, + osc->base_flags, + (FAR struct clk_gate_s *)&osc->gates[i].gate + )); + } +} + +static void +stm32_register_sysclk(const struct stm32_sysclk_s *sysclk) +{ + /* Register the sysclk mux */ + + ASSERT(clk_register_mux( + sysclk->sysclk_mux.mux_name, + sysclk->sysclk_parent_names, + sysclk->sysclk_parent_names_count, + sysclk->base_flags, + (FAR struct clk_mux_s *)&sysclk->sysclk_mux.mux + )); + + /* Register the traceclk mux */ + + ASSERT(clk_register_mux( + sysclk->traceclk_mux.mux_name, + sysclk->traceclk_parent_names, + sysclk->traceclk_parent_names_count, + sysclk->base_flags, + (FAR struct clk_mux_s *)&sysclk->traceclk_mux.mux + )); + + /* Register cdcpre divider */ + + ASSERT(clk_register_divider( + sysclk->cdcpre.div_name, + sysclk->sysclk_mux.mux_name, + sysclk->base_flags, + (FAR struct clk_divider_s *)&sysclk->cdcpre.div + )); + + /* Register hpre divider */ + + ASSERT(clk_register_divider( + sysclk->hpre.div_name, + sysclk->cdcpre.div_name, + sysclk->base_flags, + (FAR struct clk_divider_s *)&sysclk->hpre.div + )); + + /* Register cdppre divider */ + + ASSERT(clk_register_divider( + sysclk->cdppre.div_name, + sysclk->hpre.div_name, + sysclk->base_flags, + (FAR struct clk_divider_s *)&sysclk->cdppre.div + )); + + /* Register cdppre1 divider */ + + ASSERT(clk_register_divider( + sysclk->cdppre1.div_name, + sysclk->hpre.div_name, + sysclk->base_flags, + (FAR struct clk_divider_s *)&sysclk->cdppre1.div + )); + + /* Register cdppre2 divider */ + + ASSERT(clk_register_divider( + sysclk->cdppre2.div_name, + sysclk->hpre.div_name, + sysclk->base_flags, + (FAR struct clk_divider_s *)&sysclk->cdppre2.div + )); + + /* Register sdrppre divider */ + + ASSERT(clk_register_divider( + sysclk->sdrppre.div_name, + sysclk->cdcpre.div_name, + sysclk->base_flags, + (FAR struct clk_divider_s *)&sysclk->sdrppre.div + )); +} + +static void +stm32_register_pll(const struct stm32_pll_s *pll) +{ + /* Register the PLL multiplier (divn) */ + + ASSERT(clk_register_multiplier( + pll->divn.mult_name, + pll->parent_name, + pll->base_flags, + (FAR struct clk_multiplier_s *)&pll->divn.mult + )); + + /* Register divp divider */ + + ASSERT(clk_register_divider( + pll->divp.div_name, + pll->divn.mult_name, + pll->base_flags, + (FAR struct clk_divider_s *)&pll->divp.div + )); + + /* Register divp gate */ + + ASSERT(clk_register_gate( + pll->gatep.gate_name, + pll->divp.div_name, + pll->base_flags, + (FAR struct clk_gate_s *)&pll->gatep.gate + )); + + /* Register divq divider */ + + ASSERT(clk_register_divider( + pll->divq.div_name, + pll->divn.mult_name, + pll->base_flags, + (FAR struct clk_divider_s *)&pll->divq.div + )); + + /* Register divq gate */ + + ASSERT(clk_register_gate( + pll->gateq.gate_name, + pll->divq.div_name, + pll->base_flags, + (FAR struct clk_gate_s *)&pll->gateq.gate + )); + + /* Register divr divider */ + + ASSERT(clk_register_divider( + pll->divr.div_name, + pll->divn.mult_name, + pll->base_flags, + (FAR struct clk_divider_s *)&pll->divr.div + )); + + /* Register divr gate */ + + ASSERT(clk_register_gate( + pll->gater.gate_name, + pll->divr.div_name, + pll->base_flags, + (FAR struct clk_gate_s *)&pll->gater.gate + )); +} + +static void +stm32_register_gated_mux(const struct stm32_gated_mux_s *gated_mux) +{ + int i; + + /* Register the mux */ + + ASSERT(clk_register_mux( + gated_mux->mux.mux_name, + gated_mux->parent_names, + gated_mux->parent_names_count, + gated_mux->base_flags, + (FAR struct clk_mux_s *)&gated_mux->mux.mux + )); + + /* Register all gate clocks */ + + for (i = 0; i < gated_mux->num_gates; i++) + { + ASSERT(clk_register_gate( + gated_mux->gates[i].gate_name, + gated_mux->mux.mux_name, + gated_mux->base_flags, + (FAR struct clk_gate_s *)&gated_mux->gates[i].gate + )); + } +} + +static void +stm32_register_divided_mux_n(const struct stm32_divided_mux_n_s *divided_mux_n) +{ + int i; + + /* Register the mux */ + + ASSERT(clk_register_mux( + divided_mux_n->mux.mux_name, + divided_mux_n->parent_names, + divided_mux_n->parent_names_count, + divided_mux_n->base_flags, + (FAR struct clk_mux_s *)÷d_mux_n->mux.mux + )); + + /* Register all dividers */ + + for (i = 0; i < divided_mux_n->num_divs; i++) + { + ASSERT(clk_register_divider( + divided_mux_n->divs[i].div_name, + divided_mux_n->mux.mux_name, + divided_mux_n->base_flags, + (FAR struct clk_divider_s *)÷d_mux_n->divs[i].div + )); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_clk_register + * + * Description: + * Initialize the STM32H7 clock system using common clock framework + * + ****************************************************************************/ + +void up_clk_register() +{ + int i; + + /* Register HSI divider */ + + struct clk_divider_s hsi_div = { + .reg = STM32_RCC_CR, + .shift = RCC_CR_HSIDIV_SHIFT, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO + }; + + ASSERT(clk_register_divider( + "hsi_div", + "hsi", + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + &hsi_div + )); + + /* Register HSI gates */ + + struct clk_gate_s hsi_ck_gate = { + .reg = STM32_RCC_CR, + .bit_idx = 0, + .flags = 0 + }; + + ASSERT(clk_register_gate( + "hsi_ck", + "hsi_div", + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + &hsi_ck_gate + )); + + struct clk_gate_s hsi_ker_ck_gate = { + .reg = STM32_RCC_CR, + .bit_idx = 1, + .flags = 0 + }; + + ASSERT(clk_register_gate( + "hsi_ker_ck", + "hsi_div", + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + &hsi_ker_ck_gate + )); + + /* Register all gated oscillators */ + + for (i = 0; + i < sizeof(stm32h7_gated_oscs) / sizeof(stm32h7_gated_oscs[0]); + i++) + { + stm32_register_gated_osc(&stm32h7_gated_oscs[i]); + } + + /* Register PLL clock selection */ + + stm32_register_divided_mux_n(&stm32h7_pll_cksel); + + /* Register all PLLs */ + + for (i = 0; i < sizeof(stm32h7_plls) / sizeof(stm32h7_plls[0]); i++) + { + stm32_register_pll(&stm32h7_plls[i]); + } + + /* Register system clock */ + + stm32_register_sysclk(&stm32h7_sysclk); + + /* Register all gated muxes */ + + for (i = 0; + i < sizeof(stm32h7_gated_muxes) / sizeof(stm32h7_gated_muxes[0]); + i++) + { + stm32_register_gated_mux(&stm32h7_gated_muxes[i]); + } + + /* Register RTC clock */ + + stm32_register_gated_mux(&stm32h7_rtcsel); + + /* Register MCO clocks */ + + for (i = 0; i < sizeof(stm32h7_mco) / sizeof(stm32h7_mco[0]); i++) + { + stm32_register_divided_mux_n(&stm32h7_mco[i]); + } + + /* Register GPIO clocks */ + + for (i = 0; + i < sizeof(stm32h7_gpio_gates) / sizeof(stm32h7_gpio_gates[0]); + i++) + { + ASSERT(clk_register_gate( + stm32h7_gpio_gates[i].gate_name, + "hpre", + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + (FAR struct clk_gate_s *)&stm32h7_gpio_gates[i].gate + )); + } + + /* Register APB1 timer clocks */ + + for (i = 0; + i < sizeof(stm32h7_apb1_tim_gates) / sizeof(stm32h7_apb1_tim_gates[0]); + i++) + { + ASSERT(clk_register_gate( + stm32h7_apb1_tim_gates[i].gate_name, + "cdppre1", + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + (FAR struct clk_gate_s *)&stm32h7_apb1_tim_gates[i].gate + )); + } + + /* Register APB2 timer clocks */ + + for (i = 0; + i < sizeof(stm32h7_apb2_tim_gates) / sizeof(stm32h7_apb2_tim_gates[0]); + i++) + { + ASSERT(clk_register_gate( + stm32h7_apb2_tim_gates[i].gate_name, + "cdppre2", + CLK_NAME_IS_STATIC | CLK_PARENT_NAME_IS_STATIC, + (FAR struct clk_gate_s *)&stm32h7_apb2_tim_gates[i].gate + )); + } +} diff --git a/arch/arm/src/stm32h7/stm32_clk.h b/arch/arm/src/stm32h7/stm32_clk.h new file mode 100644 index 0000000000000..f727b31cc5de9 --- /dev/null +++ b/arch/arm/src/stm32h7/stm32_clk.h @@ -0,0 +1,63 @@ +/**************************************************************************** + * arch/arm/src/stm32h7/stm32_rcc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32H7_STM32_RCC_H +#define __ARCH_ARM_SRC_STM32H7_STM32_RCC_H + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + + /* Oscillator frequencies */ + +#define STM32_HSI_FREQUENCY 64000000u +#define STM32_CSI_FREQUENCY 4000000u +#define STM32_HSI48_FREQUENCY 48000000u +#define STM32_LSI_FREQUENCY 32000u + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32H7_STM32_RCC_H */ diff --git a/arch/arm/src/stm32h7/stm32_lowputc.c b/arch/arm/src/stm32h7/stm32_lowputc.c index e0c1c62d3e836..2a13aec00372a 100644 --- a/arch/arm/src/stm32h7/stm32_lowputc.c +++ b/arch/arm/src/stm32h7/stm32_lowputc.c @@ -31,6 +31,7 @@ #include "arm_internal.h" #include "chip.h" +#include "hardware/stm32_rcc.h" #include "hardware/stm32_pinmap.h" #include "stm32_rcc.h" #include "stm32_gpio.h" @@ -313,16 +314,16 @@ ****************************************************************************/ /**************************************************************************** - * Name: arm_lowputc + * Name: up_putc * * Description: - * Output one byte on the serial console + * Provide priority, low-level access to support OS debug writes * ****************************************************************************/ -void arm_lowputc(char ch) -{ #ifdef HAVE_CONSOLE +void up_putc(int ch) +{ /* Wait until the TX data register is empty */ while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_ISR_OFFSET) & @@ -341,9 +342,8 @@ void arm_lowputc(char ch) stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, !STM32_CONSOLE_RS485_DIR_POLARITY); #endif - -#endif /* HAVE_CONSOLE */ } +#endif /* HAVE_CONSOLE */ /**************************************************************************** * Name: stm32_lowsetup diff --git a/arch/arm/src/stm32h7/stm32_rcc.c b/arch/arm/src/stm32h7/stm32_rcc.c deleted file mode 100644 index f79c9c1125922..0000000000000 --- a/arch/arm/src/stm32h7/stm32_rcc.c +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32h7/stm32_rcc.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include - -#include "arm_internal.h" -#include "hardware/stm32_flash.h" -#include "stm32_gpio.h" -#include "stm32_rcc.h" -#include "stm32_pwr.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Allow up to 100 milliseconds for the high speed clock to become ready. - * that is a very long delay, but if the clock does not become ready we are - * hosed anyway. - */ - -#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -/* Include chip-specific clocking initialization logic */ - -#if defined(CONFIG_STM32H7_STM32H7X0XX) -# include "stm32h7x3xx_rcc.c" -#elif defined(CONFIG_STM32H7_STM32H7X3XX) -# include "stm32h7x3xx_rcc.c" -#elif defined(CONFIG_STM32H7_STM32H7B3XX) -# include "stm32h7x3xx_rcc.c" -#elif defined(CONFIG_STM32H7_STM32H7X5XX) -# include "stm32h7x3xx_rcc.c" -#elif defined(CONFIG_STM32H7_STM32H7X7XX) -# include "stm32h7x7xx_rcc.c" -#else -# error "Unsupported STM32 H7 chip" -#endif - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: stm32_clockconfig - * - * Description: - * Called to establish the clock settings based on the values in board.h. - * This function (by default) will reset most everything, enable the PLL, - * and enable peripheral clocking for all peripherals enabled in the NuttX - * configuration file. - * - * If CONFIG_STM32H7_CUSTOM_CLOCKCONFIG is defined, then clocking will be - * enabled by an externally provided, board-specific function called - * stm32_board_clockconfig(). - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - -void stm32_clockconfig(void) -{ -#ifndef CONFIG_STM32H7_BYPASS_CLOCKCONFIG - /* Make sure that we are starting in the reset state */ - - rcc_reset(); - -# if defined(CONFIG_STM32H7_PWR) - - /* Insure the bkp is initialized */ - - stm32_pwr_initbkp(false); -# endif - -# if defined(CONFIG_STM32H7_CUSTOM_CLOCKCONFIG) - - /* Invoke Board Custom Clock Configuration */ - - stm32_board_clockconfig(); - -# else - - /* Invoke standard, fixed clock configuration based on definitions in - * board.h - */ - - stm32_stdclockconfig(); - -# endif -#endif /* !CONFIG_STM32H7_BYPASS_CLOCKCONFIG */ - - /* Enable peripheral clocking */ - - rcc_enableperipherals(); - -#ifdef CONFIG_STM32H7_SYSCFG_IOCOMPENSATION - /* Enable I/O Compensation */ - - stm32_iocompensation(); -#endif -} - -/**************************************************************************** - * Name: stm32_clockenable - * - * Description: - * Re-enable the clock and restore the clock settings based on settings in - * board.h. This function is only available to support low-power modes of - * operation: When re-awakening from deep-sleep modes, it is necessary to - * re-enable/re-start the PLL - * - * This functional performs a subset of the operations performed by - * stm32_clockconfig(): It does not reset any devices, and it does not - * reset the currently enabled peripheral clocks. - * - * If CONFIG_STM32H7_CUSTOM_CLOCKCONFIG is defined, then clocking will be - * enabled by an externally provided, board-specific function called - * stm32_board_clockconfig(). - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - -#ifdef CONFIG_PM -void stm32_clockenable(void) -{ -#if defined(CONFIG_STM32H7_CUSTOM_CLOCKCONFIG) - - /* Invoke Board Custom Clock Configuration */ - - stm32_board_clockconfig(); - -#else - - /* Invoke standard, fixed clock configuration based on definitions in - * board.h - */ - - stm32_stdclockconfig(); - -#endif -} -#endif diff --git a/arch/arm/src/stm32h7/stm32_rcc.h b/arch/arm/src/stm32h7/stm32_rcc.h deleted file mode 100644 index 786bb7064db3e..0000000000000 --- a/arch/arm/src/stm32h7/stm32_rcc.h +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32h7/stm32_rcc.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __ARCH_ARM_SRC_STM32H7_STM32_RCC_H -#define __ARCH_ARM_SRC_STM32H7_STM32_RCC_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include "arm_internal.h" -#include "hardware/stm32_rcc.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifndef __ASSEMBLY__ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Inline Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: stm32_mco1config - * - * Description: - * Selects the clock source to output on MCO1 pin (PA8). PA8 should be - * configured in alternate function mode. - * - * Input Parameters: - * source - One of the definitions for the RCC_CFGR_MCO1 definitions from - * chip/stm32h7xxxx_rcc.h {RCC_CFGR_MCO1_HSI, RCC_CFGR_MCO1_LSE, - * RCC_CFGR_MCO1_HSE, RCC_CFGR_MCO1_PLL} - * div - One of the definitions for the RCC_CFGR_MCO1PRE definitions from - * chip/stm32h7xxxx_rcc.h {RCC_CFGR_MCO1PRE_NONE, RCC_CFGR_MCO1PRE_DIV2, - * RCC_CFGR_MCO1PRE_DIV3, RCC_CFGR_MCO1PRE_DIV4, RCC_CFGR_MCO1PRE_DIV5} - * - * Returned Value: - * None - * - ****************************************************************************/ - -static inline void stm32_mco1config(uint32_t source, uint32_t div) -{ - uint32_t regval; - - regval = getreg32(STM32_RCC_CFGR); - regval &= ~(RCC_CFGR_MCO1_MASK | RCC_CFGR_MCO1PRE_MASK); - regval |= (source | div); - putreg32(regval, STM32_RCC_CFGR); -} - -/**************************************************************************** - * Name: stm32_mco2config - * - * Description: - * Selects the clock source to output on MCO2 pin (PC9). PC9 should be - * configured in alternate function mode. - * - * Input Parameters: - * source - One of the definitions for the RCC_CFGR_MCO2 definitions from - * chip/stn32h7xxxx_rcc.h {RCC_CFGR_MCO2_SYSCLK, RCC_CFGR_MCO2_PLLI2S, - * RCC_CFGR_MCO2_HSE, RCC_CFGR_MCO2_PLL} - * div - One of the definitions for the RCC_CFGR_MCO2PRE definitions from - * chip/stn32h7xxxx_rcc.h {RCC_CFGR_MCO2PRE_NONE, RCC_CFGR_MCO2PRE_DIV2, - * RCC_CFGR_MCO2PRE_DIV3, RCC_CFGR_MCO2PRE_DIV4, RCC_CFGR_MCO2PRE_DIV5} - * - * Returned Value: - * None - * - ****************************************************************************/ - -static inline void stm32_mco2config(uint32_t source, uint32_t div) -{ - uint32_t regval; - - regval = getreg32(STM32_RCC_CFGR); - regval &= ~(RCC_CFGR_MCO2_MASK | RCC_CFGR_MCO2PRE_MASK); - regval |= (source | div); - putreg32(regval, STM32_RCC_CFGR); -} - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Name: stm32_clockconfig - * - * Description: - * Called to establish the clock settings based on the values in board.h. - * This function (by default) will reset most everything, enable the PLL, - * and enable peripheral clocking for all peripherals enabled in the NuttX - * configuration file. - * - * If CONFIG_STM32H7_CUSTOM_CLOCKCONFIG is defined, then clocking will be - * enabled by an externally provided, board-specific function called - * stm32_board_clockconfig(). - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - -void stm32_clockconfig(void); - -/**************************************************************************** - * Name: stm32_stdclockconfig - * - * Description: - * Setup the system using the "standard" clock configuration - * - ****************************************************************************/ - -void stm32_stdclockconfig(void); - -/**************************************************************************** - * Name: stm32_board_clockconfig - * - * Description: - * Any STM32 board may replace the "standard" board clock configuration - * logic with its own, custom clock configuration logic. - * - ****************************************************************************/ - -#ifdef CONFIG_STM32H7_CUSTOM_CLOCKCONFIG -void stm32_board_clockconfig(void); -#endif - -/**************************************************************************** - * Name: stm32_clockenable - * - * Description: - * Re-enable the clock and restore the clock settings based on settings in - * board.h. This function is only available to support low-power modes of - * operation: When re-awakening from deep-sleep modes, it is necessary to - * re-enable/re-start the PLL - * - * This functional performs a subset of the operations performed by - * stm32_clockconfig(): It does not reset any devices, and it does not - * reset the currently enabled peripheral clocks. - * - * If CONFIG_STM32H7_CUSTOM_CLOCKCONFIG is defined, then clocking will be - * enabled by an externally provided, board-specific function called - * stm32_board_clockconfig(). - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - -#ifdef CONFIG_PM -void stm32_clockenable(void); -#endif - -/**************************************************************************** - * Name: stm32_rcc_enablelse - * - * Description: - * Enable the External Low-Speed (LSE) Oscillator. - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - -void stm32_rcc_enablelse(void); - -/**************************************************************************** - * Name: stm32_rcc_enablelsi - * - * Description: - * Enable the Internal Low-Speed (LSI) RC Oscillator. - * - ****************************************************************************/ - -void stm32_rcc_enablelsi(void); - -/**************************************************************************** - * Name: stm32_rcc_disablelsi - * - * Description: - * Disable the Internal Low-Speed (LSI) RC Oscillator. - * - ****************************************************************************/ - -void stm32_rcc_disablelsi(void); - -#undef EXTERN -#if defined(__cplusplus) -} -#endif -#endif /* __ASSEMBLY__ */ -#endif /* __ARCH_ARM_SRC_STM32H7_STM32_RCC_H */ diff --git a/arch/arm/src/stm32h7/stm32_serial.c b/arch/arm/src/stm32h7/stm32_serial.c index e73dbd599cc53..8ae3114fd600a 100644 --- a/arch/arm/src/stm32h7/stm32_serial.c +++ b/arch/arm/src/stm32h7/stm32_serial.c @@ -52,7 +52,8 @@ #include "stm32_gpio.h" #include "hardware/stm32_pinmap.h" #include "stm32_dma.h" -#include "stm32_rcc.h" +#include "stm32_clk.h" +#include "hardware/stm32_rcc.h" #include "stm32_uart.h" #include @@ -506,7 +507,6 @@ # define USART_CR1_IE_BREAK_INPROGRESS (1 << USART_CR1_IE_BREAK_INPROGRESS_SHFTS) #endif -#ifdef USE_SERIALDRIVER #ifdef HAVE_UART /* Warnings for potentially unsafe configuration combinations. */ @@ -590,6 +590,7 @@ struct up_dev_s #ifdef CONFIG_SERIAL_TERMIOS uint8_t rxftcfg; /* Rx FIFO threshold level */ + bool over8; /* True: oversampling by 8, False: oversampling by 16 */ uint8_t parity; /* 0=none, 1=odd, 2=even */ uint8_t bits; /* Number of bits (7 or 8) */ bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ @@ -602,6 +603,7 @@ struct up_dev_s uint32_t baud; /* Configured baud */ #else const uint8_t rxftcfg; /* Rx FIFO threshold level */ + const bool over8; /* True: oversampling by 8, False: oversampling by 16 */ const uint8_t parity; /* 0=none, 1=odd, 2=even */ const uint8_t bits; /* Number of bits (7 or 8) */ const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ @@ -615,8 +617,8 @@ struct up_dev_s #endif const uint8_t irq; /* IRQ associated with this USART */ - const uint32_t apbclock; /* PCLK 1 or 2 frequency */ const uint32_t usartbase; /* Base address of USART registers */ + const char *const clkbase; /* Common Clock Framework device name */ const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ const uint32_t rx_gpio; /* U[S]ART RX GPIO pin configuration */ #ifdef CONFIG_SERIAL_IFLOWCONTROL @@ -669,7 +671,6 @@ struct pm_config_s * Private Function Prototypes ****************************************************************************/ -static void up_set_format(struct uart_dev_s *dev); static int up_setup(struct uart_dev_s *dev); static void up_shutdown(struct uart_dev_s *dev); static int up_attach(struct uart_dev_s *dev); @@ -954,7 +955,7 @@ static struct up_dev_s g_usart1priv = .bits = CONFIG_USART1_BITS, .stopbits2 = CONFIG_USART1_2STOP, .baud = CONFIG_USART1_BAUD, - .apbclock = STM32_PCLK2_FREQUENCY, + .clkbase = "usart1_ker_ck", .usartbase = STM32_USART1_BASE, .tx_gpio = GPIO_USART1_TX, .rx_gpio = GPIO_USART1_RX, @@ -1024,7 +1025,7 @@ static struct up_dev_s g_usart2priv = .bits = CONFIG_USART2_BITS, .stopbits2 = CONFIG_USART2_2STOP, .baud = CONFIG_USART2_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .clkbase = "usart2_ker_ck", .usartbase = STM32_USART2_BASE, .tx_gpio = GPIO_USART2_TX, .rx_gpio = GPIO_USART2_RX, @@ -1090,11 +1091,12 @@ static struct up_dev_s g_usart3priv = .irq = STM32_IRQ_USART3, .rxftcfg = CONFIG_USART3_RXFIFO_THRES, + .over8 = false, .parity = CONFIG_USART3_PARITY, .bits = CONFIG_USART3_BITS, .stopbits2 = CONFIG_USART3_2STOP, .baud = CONFIG_USART3_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .clkbase = "usart3_ker_ck", .usartbase = STM32_USART3_BASE, .tx_gpio = GPIO_USART3_TX, .rx_gpio = GPIO_USART3_RX, @@ -1172,7 +1174,7 @@ static struct up_dev_s g_uart4priv = .rts_gpio = GPIO_UART4_RTS, #endif .baud = CONFIG_UART4_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .clkbase = "uart4_ker_ck", .usartbase = STM32_UART4_BASE, .tx_gpio = GPIO_UART4_TX, .rx_gpio = GPIO_UART4_RX, @@ -1242,7 +1244,7 @@ static struct up_dev_s g_uart5priv = .rts_gpio = GPIO_UART5_RTS, #endif .baud = CONFIG_UART5_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .clkbase = "uart5_ker_ck", .usartbase = STM32_UART5_BASE, .tx_gpio = GPIO_UART5_TX, .rx_gpio = GPIO_UART5_RX, @@ -1304,7 +1306,7 @@ static struct up_dev_s g_usart6priv = .bits = CONFIG_USART6_BITS, .stopbits2 = CONFIG_USART6_2STOP, .baud = CONFIG_USART6_BAUD, - .apbclock = STM32_PCLK2_FREQUENCY, + .clkbase = "usart6_ker_ck", .usartbase = STM32_USART6_BASE, .tx_gpio = GPIO_USART6_TX, .rx_gpio = GPIO_USART6_RX, @@ -1374,7 +1376,7 @@ static struct up_dev_s g_uart7priv = .bits = CONFIG_UART7_BITS, .stopbits2 = CONFIG_UART7_2STOP, .baud = CONFIG_UART7_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .clkbase = "uart7_ker_ck", .usartbase = STM32_UART7_BASE, .tx_gpio = GPIO_UART7_TX, .rx_gpio = GPIO_UART7_RX, @@ -1444,7 +1446,7 @@ static struct up_dev_s g_uart8priv = .bits = CONFIG_UART8_BITS, .stopbits2 = CONFIG_UART8_2STOP, .baud = CONFIG_UART8_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, + .clkbase = "uart8_ker_ck", .usartbase = STM32_UART8_BASE, .tx_gpio = GPIO_UART8_TX, .rx_gpio = GPIO_UART8_RX, @@ -1568,12 +1570,13 @@ static inline void up_setusartint(struct up_dev_s *priv, uint16_t ie) up_serialout(priv, STM32_USART_CR3_OFFSET, cr); } +#if !defined(SERIAL_HAVE_ONLY_DMA) || defined(CONFIG_PM) || \ + defined(HAVE_RS485) + /**************************************************************************** * Name: up_restoreusartint ****************************************************************************/ -#if !defined(SERIAL_HAVE_ONLY_DMA) || defined(CONFIG_PM) || \ - defined(HAVE_RS485) static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie) { irqstate_t flags; @@ -1641,6 +1644,8 @@ static void up_disableusartint(struct up_dev_s *priv, uint16_t *ie) spin_unlock_irqrestore(&priv->lock, flags); } +#ifdef SERIAL_HAVE_RXDMA + /**************************************************************************** * Name: up_dma_nextrx * @@ -1650,7 +1655,6 @@ static void up_disableusartint(struct up_dev_s *priv, uint16_t *ie) * ****************************************************************************/ -#ifdef SERIAL_HAVE_RXDMA static int up_dma_nextrx(struct up_dev_s *priv) { size_t dmaresidual; @@ -1661,161 +1665,7 @@ static int up_dma_nextrx(struct up_dev_s *priv) } #endif -/**************************************************************************** - * Name: up_set_format - * - * Description: - * Set the serial line format and speed. - * - ****************************************************************************/ - -#ifndef CONFIG_SUPPRESS_UART_CONFIG -static void up_set_format(struct uart_dev_s *dev) -{ - struct up_dev_s *priv = (struct up_dev_s *)dev->priv; - uint32_t regval; - uint32_t usartdiv8; - uint32_t cr1; - uint32_t cr1_ue; - uint32_t brr; - irqstate_t flags; - - flags = enter_critical_section(); - - /* Get the original state of UE */ - - cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET); - cr1_ue = cr1 & USART_CR1_UE; - cr1 &= ~USART_CR1_UE; - - /* Disable UE as the format bits and baud rate registers can not be - * updated while UE = 1 - */ - - up_serialout(priv, STM32_USART_CR1_OFFSET, cr1); - - /* In case of oversampling by 8, the equation is: - * - * baud = 2 * fCK / usartdiv8 - * usartdiv8 = 2 * fCK / baud - */ - - usartdiv8 = ((priv->apbclock << 1) + (priv->baud >> 1)) / priv->baud; - - /* Baud rate for standard USART (SPI mode included): - * - * In case of oversampling by 16, the equation is: - * baud = fCK / usartdiv16 - * usartdiv16 = fCK / baud - * = 2 * usartdiv8 - */ - - /* Use oversamply by 8 only if the divisor is small. But what is small? */ - - if (usartdiv8 > 100) - { - /* Use usartdiv16 */ - - brr = (usartdiv8 + 1) >> 1; - - /* Clear oversampling by 8 to enable oversampling by 16 */ - - cr1 &= ~USART_CR1_OVER8; - } - else - { - DEBUGASSERT(usartdiv8 >= 8); - - /* Perform mysterious operations on bits 0-3 */ - - brr = ((usartdiv8 & 0xfff0) | ((usartdiv8 & 0x000f) >> 1)); - - /* Set oversampling by 8 */ - - cr1 |= USART_CR1_OVER8; - } - - up_serialout(priv, STM32_USART_CR1_OFFSET, cr1); - up_serialout(priv, STM32_USART_BRR_OFFSET, brr); - - /* Configure parity mode */ - - cr1 &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0 | USART_CR1_M1); - - if (priv->parity == 1) /* Odd parity */ - { - cr1 |= (USART_CR1_PCE | USART_CR1_PS); - } - else if (priv->parity == 2) /* Even parity */ - { - cr1 |= USART_CR1_PCE; - } - - /* Configure word length (parity uses one of configured bits) - * - * Default: 1 start, 8 data (no parity), n stop, OR - * 1 start, 7 data + parity, n stop - */ - - if (priv->bits == 9 || (priv->bits == 8 && priv->parity != 0)) - { - /* Select: 1 start, 8 data + parity, n stop, OR - * 1 start, 9 data (no parity), n stop. - */ - - cr1 |= USART_CR1_M0; - } - else if (priv->bits == 7 && priv->parity == 0) - { - /* Select: 1 start, 7 data (no parity), n stop, OR - */ - - cr1 |= USART_CR1_M1; - } - - /* Else Select: 1 start, 7 data + parity, n stop, OR - * 1 start, 8 data (no parity), n stop. - */ - - up_serialout(priv, STM32_USART_CR1_OFFSET, cr1); - - /* Configure STOP bits */ - - regval = up_serialin(priv, STM32_USART_CR2_OFFSET); - regval &= ~(USART_CR2_STOP_MASK); - - if (priv->stopbits2) - { - regval |= USART_CR2_STOP2; - } - - up_serialout(priv, STM32_USART_CR2_OFFSET, regval); - - /* Configure hardware flow control */ - - regval = up_serialin(priv, STM32_USART_CR3_OFFSET); - regval &= ~(USART_CR3_CTSE | USART_CR3_RTSE); - -#if defined(CONFIG_SERIAL_IFLOWCONTROL) && \ - !defined(CONFIG_STM32H7_FLOWCONTROL_BROKEN) - if (priv->iflow && (priv->rts_gpio != 0)) - { - regval |= USART_CR3_RTSE; - } -#endif - -#ifdef CONFIG_SERIAL_OFLOWCONTROL - if (priv->oflow && (priv->cts_gpio != 0)) - { - regval |= USART_CR3_CTSE; - } -#endif - - up_serialout(priv, STM32_USART_CR3_OFFSET, regval); - up_serialout(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); - leave_critical_section(flags); -} -#endif /* CONFIG_SUPPRESS_UART_CONFIG */ +#ifdef CONFIG_PM /**************************************************************************** * Name: up_setsuspend @@ -1825,7 +1675,6 @@ static void up_set_format(struct uart_dev_s *dev) * ****************************************************************************/ -#ifdef CONFIG_PM static void up_setsuspend(struct uart_dev_s *dev, bool suspend) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; @@ -1930,6 +1779,8 @@ static void up_setsuspend(struct uart_dev_s *dev, bool suspend) } #endif +#ifdef CONFIG_PM + /**************************************************************************** * Name: up_pm_setsuspend * @@ -1938,7 +1789,6 @@ static void up_setsuspend(struct uart_dev_s *dev, bool suspend) * ****************************************************************************/ -#ifdef CONFIG_PM static void up_pm_setsuspend(bool suspend) { int n; @@ -1966,92 +1816,6 @@ static void up_pm_setsuspend(bool suspend) } #endif -/**************************************************************************** - * Name: up_set_apb_clock - * - * Description: - * Enable or disable APB clock for the USART peripheral - * - * Input Parameters: - * dev - A reference to the UART driver state structure - * on - Enable clock if 'on' is 'true' and disable if 'false' - * - ****************************************************************************/ - -static void up_set_apb_clock(struct uart_dev_s *dev, bool on) -{ - struct up_dev_s *priv = (struct up_dev_s *)dev->priv; - uint32_t rcc_en; - uint32_t regaddr; - - /* Determine which USART to configure */ - - switch (priv->usartbase) - { - default: - return; -#ifdef CONFIG_STM32H7_USART1 - case STM32_USART1_BASE: - rcc_en = RCC_APB2ENR_USART1EN; - regaddr = STM32_RCC_APB2ENR; - break; -#endif -#ifdef CONFIG_STM32H7_USART2 - case STM32_USART2_BASE: - rcc_en = RCC_APB1LENR_USART2EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32H7_USART3 - case STM32_USART3_BASE: - rcc_en = RCC_APB1LENR_USART3EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32H7_UART4 - case STM32_UART4_BASE: - rcc_en = RCC_APB1LENR_UART4EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32H7_UART5 - case STM32_UART5_BASE: - rcc_en = RCC_APB1LENR_UART5EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32H7_USART6 - case STM32_USART6_BASE: - rcc_en = RCC_APB2ENR_USART6EN; - regaddr = STM32_RCC_APB2ENR; - break; -#endif -#ifdef CONFIG_STM32H7_UART7 - case STM32_UART7_BASE: - rcc_en = RCC_APB1LENR_UART7EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif -#ifdef CONFIG_STM32H7_UART8 - case STM32_UART8_BASE: - rcc_en = RCC_APB1LENR_UART8EN; - regaddr = STM32_RCC_APB1LENR; - break; -#endif - } - - /* Enable/disable APB 1/2 clock for USART */ - - if (on) - { - modifyreg32(regaddr, 0, rcc_en); - } - else - { - modifyreg32(regaddr, rcc_en, 0); - } -} - /**************************************************************************** * Name: up_setup * @@ -2063,22 +1827,24 @@ static void up_set_apb_clock(struct uart_dev_s *dev, bool on) static int up_setup(struct uart_dev_s *dev) { - struct up_dev_s *priv = (struct up_dev_s *)dev->priv; - /* Make sure that USART is disabled */ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; - up_serialout(priv, STM32_USART_CR1_OFFSET, 0); + if (priv->initialized == true) + { + return OK; + } #ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t regval; - /* Note: The logic here depends on the fact that that the USART module - * was enabled in stm32_lowsetup(). - */ + struct clk_s *clk = clk_get(priv->clkbase); + clk_enable(clk); - /* Enable USART APB1/2 clock */ + /* Make sure that USART is disabled */ - up_set_apb_clock(dev, true); + up_serialout(priv, STM32_USART_CR1_OFFSET, 0); /* Configure pins for USART use */ @@ -2116,11 +1882,11 @@ static int up_setup(struct uart_dev_s *dev) /* Configure CR2 * - * Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits + * Clear STOP, CPOL, CPHA, LBCL, and interrupt enable bits */ regval = up_serialin(priv, STM32_USART_CR2_OFFSET); - regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CLKEN | USART_CR2_CPOL | + regval &= ~(USART_CR2_STOP_MASK | USART_CR2_CPOL | USART_CR2_CPHA | USART_CR2_LBCL | USART_CR2_LBDIE); /* Configure STOP bits */ @@ -2132,16 +1898,6 @@ static int up_setup(struct uart_dev_s *dev) up_serialout(priv, STM32_USART_CR2_OFFSET, regval); - /* Configure CR1 - * - * Clear TE, REm and all interrupt enable bits - */ - - regval = up_serialin(priv, STM32_USART_CR1_OFFSET); - regval &= ~(USART_CR1_TE | USART_CR1_RE | USART_CR1_ALLINTS); - - up_serialout(priv, STM32_USART_CR1_OFFSET, regval); - /* Configure CR3 * * Clear CTSE, RTSE, and all interrupt enable bits @@ -2155,24 +1911,118 @@ static int up_setup(struct uart_dev_s *dev) regval |= USART_CR3_RXFTCFG(priv->rxftcfg); +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && \ + !defined(CONFIG_STM32H7_FLOWCONTROL_BROKEN) + if (priv->iflow && (priv->rts_gpio != 0)) + { + regval |= USART_CR3_RTSE; + } +#endif + +#ifdef CONFIG_SERIAL_OFLOWCONTROL + if (priv->oflow && (priv->cts_gpio != 0)) + { + regval |= USART_CR3_CTSE; + } +#endif + up_serialout(priv, STM32_USART_CR3_OFFSET, regval); - /* Configure the USART line format and speed. */ + /* Configure the USART Baud Rate */ - up_set_format(dev); + /* Calculate USART BAUD rate divider */ - /* Enable Rx, Tx, and the USART */ + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / UARTDIV + * UARTDIV = fCK / baud + * + * In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / UARTDIV + * UARTDIV = 2 * fCK / baud + */ - /* Enable FIFO */ + regval = clk_get_rate(clk); + + if (priv->over8) + { + regval = (regval << 1); + } + + regval = (regval + (priv->baud >> 1)) / priv->baud; + + up_serialout(priv, STM32_USART_BRR_OFFSET, regval); + + /* Configure CR1 + * + * Clear TE, RE and all interrupt enable bits + */ regval = up_serialin(priv, STM32_USART_CR1_OFFSET); + regval &= ~(USART_CR1_ALLINTS); + + /* Enable Rx, Tx, and the USART */ + regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + #ifdef SERIAL_HAVE_RXDMA regval |= USART_CR1_IDLEIE; #endif + /* Enable FIFO */ + regval |= USART_CR1_FIFOEN; + /* Configure parity mode */ + + regval &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0 | USART_CR1_M1); + + if (priv->parity == 1) /* Odd parity */ + { + regval |= (USART_CR1_PCE | USART_CR1_PS); + } + else if (priv->parity == 2) /* Even parity */ + { + regval |= USART_CR1_PCE; + } + + if (priv->over8) + { + regval |= USART_CR1_OVER8; + } + + /* Configure word length (parity uses one of configured bits) + * + * Default: 1 start, 8 data (no parity), n stop, OR + * 1 start, 7 data + parity, n stop + */ + + if (priv->bits == 9 || (priv->bits == 8 && priv->parity != 0)) + { + /* Select: 1 start, 8 data + parity, n stop, OR + * 1 start, 9 data (no parity), n stop. + */ + + regval |= USART_CR1_M0; + } + else if (priv->bits == 7 && priv->parity == 0) + { + /* Select: 1 start, 7 data (no parity), n stop, OR + */ + + regval |= USART_CR1_M1; + } + + /* Else Select: 1 start, 7 data + parity, n stop, OR + * 1 start, 8 data (no parity), n stop. + */ + + /* Enable Rx, Tx and the USART */ + + regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); + up_serialout(priv, STM32_USART_CR1_OFFSET, regval); #endif /* CONFIG_SUPPRESS_UART_CONFIG */ @@ -2295,10 +2145,6 @@ static void up_shutdown(struct uart_dev_s *dev) up_disableusartint(priv, NULL); - /* Disable USART APB1/2 clock */ - - up_set_apb_clock(dev, false); - /* Disable Rx, Tx, and the UART */ regval = up_serialin(priv, STM32_USART_CR1_OFFSET); @@ -2924,6 +2770,8 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) return ret; } +#ifndef SERIAL_HAVE_ONLY_RXDMA + /**************************************************************************** * Name: up_receive * @@ -2934,7 +2782,6 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) * ****************************************************************************/ -#ifndef SERIAL_HAVE_ONLY_RXDMA static int up_receive(struct uart_dev_s *dev, unsigned int *status) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; @@ -2955,6 +2802,8 @@ static int up_receive(struct uart_dev_s *dev, unsigned int *status) } #endif +#ifndef SERIAL_HAVE_ONLY_RXDMA + /**************************************************************************** * Name: up_rxint * @@ -2963,7 +2812,6 @@ static int up_receive(struct uart_dev_s *dev, unsigned int *status) * ****************************************************************************/ -#ifndef SERIAL_HAVE_ONLY_RXDMA static void up_rxint(struct uart_dev_s *dev, bool enable) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; @@ -3014,6 +2862,8 @@ static void up_rxint(struct uart_dev_s *dev, bool enable) } #endif +#ifndef SERIAL_HAVE_ONLY_RXDMA + /**************************************************************************** * Name: up_rxavailable * @@ -3022,7 +2872,6 @@ static void up_rxint(struct uart_dev_s *dev, bool enable) * ****************************************************************************/ -#ifndef SERIAL_HAVE_ONLY_RXDMA static bool up_rxavailable(struct uart_dev_s *dev) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; @@ -3030,6 +2879,8 @@ static bool up_rxavailable(struct uart_dev_s *dev) } #endif +#ifdef CONFIG_SERIAL_IFLOWCONTROL + /**************************************************************************** * Name: up_rxflowcontrol * @@ -3053,7 +2904,6 @@ static bool up_rxavailable(struct uart_dev_s *dev) * ****************************************************************************/ -#ifdef CONFIG_SERIAL_IFLOWCONTROL static bool up_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered, bool upper) { @@ -3126,6 +2976,8 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev, } #endif +#ifdef SERIAL_HAVE_RXDMA + /**************************************************************************** * Name: up_dma_receive * @@ -3136,7 +2988,6 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev, * ****************************************************************************/ -#ifdef SERIAL_HAVE_RXDMA static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; @@ -3463,6 +3314,8 @@ static void up_send(struct uart_dev_s *dev, int ch) up_serialout(priv, STM32_USART_TDR_OFFSET, (uint32_t)ch); } + +#ifdef SERIAL_HAVE_TXDMA /**************************************************************************** * Name: up_dma_txint * @@ -3471,7 +3324,7 @@ static void up_send(struct uart_dev_s *dev, int ch) * ****************************************************************************/ -#ifdef SERIAL_HAVE_TXDMA + static void up_dma_txint(struct uart_dev_s *dev, bool enable) { /* Nothing to do. */ @@ -3783,14 +3636,11 @@ static int up_pm_prepare(struct pm_callback_s *cb, int domain, } #endif #endif /* HAVE_UART */ -#endif /* USE_SERIALDRIVER */ /**************************************************************************** * Public Functions ****************************************************************************/ -#ifdef USE_SERIALDRIVER - /**************************************************************************** * Name: stm32_serial_get_uart * @@ -3816,47 +3666,11 @@ uart_dev_t *stm32_serial_get_uart(int uart_num) return &g_uart_devs[uart_idx]->dev; } -/**************************************************************************** - * Name: arm_earlyserialinit - * - * Description: - * Performs the low level USART initialization early in debug so that the - * serial console will be available during boot up. This must be called - * before arm_serialinit. - * - ****************************************************************************/ - -#ifdef USE_EARLYSERIALINIT -void arm_earlyserialinit(void) -{ -#ifdef HAVE_UART - unsigned i; - - /* Disable all USART interrupts */ - - for (i = 0; i < STM32_NSERIAL; i++) - { - if (g_uart_devs[i]) - { - up_disableusartint(g_uart_devs[i], NULL); - } - } - - /* Configure whichever one is the console */ - -#if CONSOLE_UART > 0 - up_setup(&g_uart_devs[CONSOLE_UART - 1]->dev); -#endif -#endif /* HAVE UART */ -} -#endif - /**************************************************************************** * Name: arm_serialinit * * Description: - * Register serial console and serial ports. This assumes - * that arm_earlyserialinit was called previously. + * Register serial console and serial ports. * ****************************************************************************/ @@ -3869,6 +3683,7 @@ void arm_serialinit(void) #ifdef CONFIG_PM int ret; #endif + irqstate_t flags = enter_critical_section(); #ifdef CONFIG_PM /* Register to receive power management callbacks */ @@ -3877,10 +3692,13 @@ void arm_serialinit(void) DEBUGASSERT(ret == OK); UNUSED(ret); #endif - + /* Register the console */ #if CONSOLE_UART > 0 + + up_setup(&g_uart_devs[CONSOLE_UART - 1]->dev); + uart_register("/dev/console", &g_uart_devs[CONSOLE_UART - 1]->dev); #ifndef CONFIG_STM32H7_SERIAL_DISABLE_REORDERING @@ -3923,9 +3741,13 @@ void arm_serialinit(void) /* Register USARTs as devices in increasing order */ + up_setup(&g_uart_devs[i]->dev); devname[9] = '0' + minor++; uart_register(devname, &g_uart_devs[i]->dev); } + + leave_critical_section(flags); + #endif /* HAVE UART */ } @@ -4022,27 +3844,8 @@ void up_putc(int ch) uint16_t ie; up_disableusartint(priv, &ie); - arm_lowputc(ch); + up_send(&priv->dev, ch); up_restoreusartint(priv, ie); #endif -} - -#else /* USE_SERIALDRIVER */ - -/**************************************************************************** - * Name: up_putc - * - * Description: - * Provide priority, low-level access to support OS debug writes - * - ****************************************************************************/ - -void up_putc(int ch) -{ -#if CONSOLE_UART > 0 - arm_lowputc(ch); -#endif -} - -#endif /* USE_SERIALDRIVER */ +} \ No newline at end of file diff --git a/arch/arm/src/stm32h7/stm32_start.c b/arch/arm/src/stm32h7/stm32_start.c index a91a9f66bf52b..f8c68cb17731a 100644 --- a/arch/arm/src/stm32h7/stm32_start.c +++ b/arch/arm/src/stm32h7/stm32_start.c @@ -42,7 +42,7 @@ # include "stm32_mpuinit.h" #endif -#include "stm32_rcc.h" +#include "stm32_clk.h" #include "stm32_userspace.h" #include "stm32_lowputc.h" #include "stm32_start.h" @@ -93,20 +93,6 @@ const uintptr_t g_idle_topstack = HEAP_BASE; * Private Function prototypes ****************************************************************************/ -/**************************************************************************** - * Name: showprogress - * - * Description: - * Print a character on the UART to show boot status. - * - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_FEATURES -# define showprogress(c) arm_lowputc(c) -#else -# define showprogress(c) -#endif - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -198,9 +184,12 @@ void __start(void) stm32h7_waitfor_cm7(); #endif - /* If enabled reset the MPU */ +#ifdef CONFIG_ARM_MPU_EARLY_RESET + /* If enabled reset the MPU */ + mpu_early_reset(); +#endif /* Clear .bss. We'll do this inline (vs. calling memset) just to be * certain that there are no issues with the state of global variables. @@ -244,12 +233,9 @@ void __start(void) arm_stack_check_init(); #endif - /* Configure the UART so that we can get debug output as soon as possible */ - - stm32_clockconfig(); +#ifdef CONFIG_ARCH_FPU arm_fpuconfig(); - stm32_lowsetup(); - showprogress('A'); +#endif #ifdef CONFIG_ARCH_CHIP_STM32H7_CORTEXM7 /* Enable/disable tightly coupled memories */ @@ -260,7 +246,6 @@ void __start(void) /* Initialize onboard resources */ stm32_boardinitialize(); - showprogress('B'); #ifdef CONFIG_ARCH_CHIP_STM32H7_CORTEXM7 /* Enable I- and D-Caches */ @@ -268,19 +253,11 @@ void __start(void) up_enable_icache(); up_enable_dcache(); #endif - showprogress('C'); #ifdef CONFIG_ARCH_PERF_EVENTS up_perf_init((void *)STM32_CPUCLK_FREQUENCY); #endif - /* Perform early serial initialization */ - -#ifdef USE_EARLYSERIALINIT - arm_earlyserialinit(); -#endif - showprogress('D'); - /* For the case of the separate user-/kernel-space build, perform whatever * platform specific initialization of the user memory is required. * Normally this just means initializing the user space .data and .bss @@ -296,12 +273,6 @@ void __start(void) stm32_mpuinitialize(); #endif - showprogress('E'); - - /* Then start NuttX */ - - showprogress('\r'); - showprogress('\n'); #if defined(CONFIG_ARCH_STM32H7_DUALCORE) && \ defined(CONFIG_ARCH_CHIP_STM32H7_CORTEXM7) && \ diff --git a/arch/arm/src/stm32h7/stm32_tim.c b/arch/arm/src/stm32h7/stm32_tim.c index 6ef544ba9a119..f46fc3b0251d0 100644 --- a/arch/arm/src/stm32h7/stm32_tim.c +++ b/arch/arm/src/stm32h7/stm32_tim.c @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -242,9 +243,12 @@ struct stm32_tim_priv_s { - const struct stm32_tim_ops_s *ops; - stm32_tim_mode_t mode; - uint32_t base; /* TIMn base address */ + const struct stm32_tim_ops_s *ops; + const char *clkbase; + const int vectorno; + const int width; + stm32_tim_mode_t mode; + uint32_t base; /* TIMn base address */ }; /**************************************************************************** @@ -316,6 +320,9 @@ static const struct stm32_tim_ops_s stm32_tim_ops = struct stm32_tim_priv_s stm32_tim1_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim1_ker_ck", + .vectorno = STM32_IRQ_TIM1UP, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM1_BASE, }; @@ -324,6 +331,9 @@ struct stm32_tim_priv_s stm32_tim1_priv = struct stm32_tim_priv_s stm32_tim2_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim2_ker_ck", + .vectorno = STM32_IRQ_TIM2, + .width = 32, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM2_BASE, }; @@ -333,6 +343,9 @@ struct stm32_tim_priv_s stm32_tim2_priv = struct stm32_tim_priv_s stm32_tim3_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim3_ker_ck", + .vectorno = STM32_IRQ_TIM3, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM3_BASE, }; @@ -342,6 +355,9 @@ struct stm32_tim_priv_s stm32_tim3_priv = struct stm32_tim_priv_s stm32_tim4_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim4_ker_ck", + .vectorno = STM32_IRQ_TIM4, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM4_BASE, }; @@ -351,6 +367,9 @@ struct stm32_tim_priv_s stm32_tim4_priv = struct stm32_tim_priv_s stm32_tim5_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim5_ker_ck", + .vectorno = STM32_IRQ_TIM5, + .width = 32, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM5_BASE, }; @@ -360,6 +379,9 @@ struct stm32_tim_priv_s stm32_tim5_priv = struct stm32_tim_priv_s stm32_tim6_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim6_ker_ck", + .vectorno = STM32_IRQ_TIM6, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM6_BASE, }; @@ -369,6 +391,9 @@ struct stm32_tim_priv_s stm32_tim6_priv = struct stm32_tim_priv_s stm32_tim7_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim7_ker_ck", + .vectorno = STM32_IRQ_TIM7, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM7_BASE, }; @@ -378,6 +403,9 @@ struct stm32_tim_priv_s stm32_tim7_priv = struct stm32_tim_priv_s stm32_tim8_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim8_ker_ck", + .vectorno = STM32_IRQ_TIM8UP, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM8_BASE, }; @@ -387,6 +415,9 @@ struct stm32_tim_priv_s stm32_tim8_priv = struct stm32_tim_priv_s stm32_tim12_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim12_ker_ck", + .vectorno = STM32_IRQ_TIM12, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM12_BASE, }; @@ -396,6 +427,9 @@ struct stm32_tim_priv_s stm32_tim12_priv = struct stm32_tim_priv_s stm32_tim13_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim13_ker_ck", + .vectorno = STM32_IRQ_TIM13, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM13_BASE, }; @@ -405,6 +439,9 @@ struct stm32_tim_priv_s stm32_tim13_priv = struct stm32_tim_priv_s stm32_tim14_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim14_ker_ck", + .vectorno = STM32_IRQ_TIM14, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM14_BASE, }; @@ -414,6 +451,9 @@ struct stm32_tim_priv_s stm32_tim14_priv = struct stm32_tim_priv_s stm32_tim15_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim15_ker_ck", + .vectorno = STM32_IRQ_TIM15, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM15_BASE, }; @@ -423,6 +463,9 @@ struct stm32_tim_priv_s stm32_tim15_priv = struct stm32_tim_priv_s stm32_tim16_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim16_ker_ck", + .vectorno = STM32_IRQ_TIM16, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM16_BASE, }; @@ -432,6 +475,9 @@ struct stm32_tim_priv_s stm32_tim16_priv = struct stm32_tim_priv_s stm32_tim17_priv = { .ops = &stm32_tim_ops, + .clkbase = "tim17_ker_ck", + .vectorno = STM32_IRQ_TIM17, + .width = 16, .mode = STM32_TIM_MODE_UNUSED, .base = STM32_TIM17_BASE, }; @@ -496,7 +542,14 @@ static void stm32_tim_reload_counter(struct stm32_tim_dev_s *dev) static void stm32_tim_enable(struct stm32_tim_dev_s *dev) { - uint16_t val = stm32_getreg16(dev, STM32_GTIM_CR1_OFFSET); + struct stm32_tim_priv_s *priv = (struct stm32_tim_priv_s *)dev; + struct clk_s *clk; + uint16_t val; + + clk = clk_get(priv->clkbase); + clk_enable(clk); + + val = stm32_getreg16(dev, STM32_GTIM_CR1_OFFSET); val |= GTIM_CR1_CEN; stm32_tim_reload_counter(dev); stm32_putreg16(dev, STM32_GTIM_CR1_OFFSET, val); @@ -504,9 +557,16 @@ static void stm32_tim_enable(struct stm32_tim_dev_s *dev) static void stm32_tim_disable(struct stm32_tim_dev_s *dev) { - uint16_t val = stm32_getreg16(dev, STM32_GTIM_CR1_OFFSET); + struct stm32_tim_priv_s *priv = (struct stm32_tim_priv_s *)dev; + struct clk_s *clk; + uint16_t val; + + val = stm32_getreg16(dev, STM32_GTIM_CR1_OFFSET); val &= ~GTIM_CR1_CEN; stm32_putreg16(dev, STM32_GTIM_CR1_OFFSET, val); + + clk = clk_get(priv->clkbase); + clk_disable(clk); } /**************************************************************************** @@ -515,25 +575,7 @@ static void stm32_tim_disable(struct stm32_tim_dev_s *dev) static int stm32_tim_getwidth(struct stm32_tim_dev_s *dev) { - /* Only TIM2 and TIM5 timers may be 32-bits in width */ - - switch (((struct stm32_tim_priv_s *)dev)->base) - { -#if defined(CONFIG_STM32H7_TIM2) - case STM32_TIM2_BASE: - return 32; -#endif - -#if defined(CONFIG_STM32H7_TIM5) - case STM32_TIM5_BASE: - return 32; -#endif - - /* All others are 16-bit times */ - - default: - return 16; - } + return ((struct stm32_tim_priv_s *)dev)->width; } /**************************************************************************** @@ -605,6 +647,8 @@ static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode) static int stm32_tim_setclock(struct stm32_tim_dev_s *dev, uint32_t freq) { + struct stm32_tim_priv_s *priv = (struct stm32_tim_priv_s *)dev; + struct clk_s *clk; uint32_t freqin; int prescaler; @@ -618,87 +662,12 @@ static int stm32_tim_setclock(struct stm32_tim_dev_s *dev, uint32_t freq) return 0; } - /* Get the input clock frequency for this timer. These vary with - * different timer clock sources, MCU-specific timer configuration, and - * board-specific clock configuration. The correct input clock frequency - * must be defined in the board.h header file. - */ + /* Get the input clock frequency for this timer from the clock framework */ - switch (((struct stm32_tim_priv_s *)dev)->base) - { -#ifdef CONFIG_STM32H7_TIM1 - case STM32_TIM1_BASE: - freqin = STM32_APB2_TIM1_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM2 - case STM32_TIM2_BASE: - freqin = STM32_APB1_TIM2_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM3 - case STM32_TIM3_BASE: - freqin = STM32_APB1_TIM3_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM4 - case STM32_TIM4_BASE: - freqin = STM32_APB1_TIM4_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM5 - case STM32_TIM5_BASE: - freqin = STM32_APB1_TIM5_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM6 - case STM32_TIM6_BASE: - freqin = STM32_APB1_TIM6_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM7 - case STM32_TIM7_BASE: - freqin = STM32_APB1_TIM7_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM8 - case STM32_TIM8_BASE: - freqin = STM32_APB2_TIM8_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM12 - case STM32_TIM12_BASE: - freqin = STM32_APB1_TIM12_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM13 - case STM32_TIM13_BASE: - freqin = STM32_APB1_TIM13_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM14 - case STM32_TIM14_BASE: - freqin = STM32_APB1_TIM14_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM15 - case STM32_TIM15_BASE: - freqin = STM32_APB2_TIM15_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM16 - case STM32_TIM16_BASE: - freqin = STM32_APB2_TIM16_CLKIN; - break; -#endif -#ifdef CONFIG_STM32H7_TIM17 - case STM32_TIM17_BASE: - freqin = STM32_APB2_TIM17_CLKIN; - break; -#endif - default: - return -EINVAL; - } + clk = clk_get(priv->clkbase); + DEBUGASSERT(clk != NULL); + + freqin = clk_get_rate(clk_get_parent(clk)); /* Select a pre-scaler value for this timer using the input clock * frequency. @@ -738,106 +707,29 @@ static void stm32_tim_setperiod(struct stm32_tim_dev_s *dev, static int stm32_tim_setisr(struct stm32_tim_dev_s *dev, xcpt_t handler, void *arg, int source) { - int vectorno; + struct stm32_tim_priv_s *priv = (struct stm32_tim_priv_s *)dev; DEBUGASSERT(dev != NULL); DEBUGASSERT(source == 0); - switch (((struct stm32_tim_priv_s *)dev)->base) - { -#ifdef CONFIG_STM32H7_TIM1 - case STM32_TIM1_BASE: - vectorno = STM32_IRQ_TIM1UP; - break; -#endif -#ifdef CONFIG_STM32H7_TIM2 - case STM32_TIM2_BASE: - vectorno = STM32_IRQ_TIM2; - break; -#endif -#ifdef CONFIG_STM32H7_TIM3 - case STM32_TIM3_BASE: - vectorno = STM32_IRQ_TIM3; - break; -#endif -#ifdef CONFIG_STM32H7_TIM4 - case STM32_TIM4_BASE: - vectorno = STM32_IRQ_TIM4; - break; -#endif -#ifdef CONFIG_STM32H7_TIM5 - case STM32_TIM5_BASE: - vectorno = STM32_IRQ_TIM5; - break; -#endif -#ifdef CONFIG_STM32H7_TIM6 - case STM32_TIM6_BASE: - vectorno = STM32_IRQ_TIM6; - break; -#endif -#ifdef CONFIG_STM32H7_TIM7 - case STM32_TIM7_BASE: - vectorno = STM32_IRQ_TIM7; - break; -#endif -#ifdef CONFIG_STM32H7_TIM8 - case STM32_TIM8_BASE: - vectorno = STM32_IRQ_TIM8UP; - break; -#endif -#ifdef CONFIG_STM32H7_TIM12 - case STM32_TIM12_BASE: - vectorno = STM32_IRQ_TIM12; - break; -#endif -#ifdef CONFIG_STM32H7_TIM13 - case STM32_TIM13_BASE: - vectorno = STM32_IRQ_TIM13; - break; -#endif -#ifdef CONFIG_STM32H7_TIM14 - case STM32_TIM14_BASE: - vectorno = STM32_IRQ_TIM14; - break; -#endif -#ifdef CONFIG_STM32H7_TIM15 - case STM32_TIM15_BASE: - vectorno = STM32_IRQ_TIM15; - break; -#endif -#ifdef CONFIG_STM32H7_TIM16 - case STM32_TIM16_BASE: - vectorno = STM32_IRQ_TIM16; - break; -#endif -#ifdef CONFIG_STM32H7_TIM17 - case STM32_TIM17_BASE: - vectorno = STM32_IRQ_TIM17; - break; -#endif - - default: - return -EINVAL; - } - /* Disable interrupt when callback is removed */ if (!handler) { - up_disable_irq(vectorno); - irq_detach(vectorno); + up_disable_irq(priv->vectorno); + irq_detach(priv->vectorno); return OK; } /* Otherwise set callback and enable interrupt */ - irq_attach(vectorno, handler, arg); - up_enable_irq(vectorno); + irq_attach(priv->vectorno, handler, arg); + up_enable_irq(priv->vectorno); #ifdef CONFIG_ARCH_IRQPRIO /* Set the interrupt priority */ - up_prioritize_irq(vectorno, NVIC_SYSH_PRIORITY_DEFAULT); + up_prioritize_irq(priv->vectorno, NVIC_SYSH_PRIORITY_DEFAULT); #endif return OK; @@ -1362,95 +1254,8 @@ struct stm32_tim_dev_s *stm32_tim_init(int timer) /* Get structure and enable power */ - switch (timer) - { -#ifdef CONFIG_STM32H7_TIM1 - case 1: - dev = (struct stm32_tim_dev_s *)&stm32_tim1_priv; - modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM1EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM2 - case 2: - dev = (struct stm32_tim_dev_s *)&stm32_tim2_priv; - modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM2EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM3 - case 3: - dev = (struct stm32_tim_dev_s *)&stm32_tim3_priv; - modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM3EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM4 - case 4: - dev = (struct stm32_tim_dev_s *)&stm32_tim4_priv; - modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM4EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM5 - case 5: - dev = (struct stm32_tim_dev_s *)&stm32_tim5_priv; - modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM5EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM6 - case 6: - dev = (struct stm32_tim_dev_s *)&stm32_tim6_priv; - modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM6EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM7 - case 7: - dev = (struct stm32_tim_dev_s *)&stm32_tim7_priv; - modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM7EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM8 - case 8: - dev = (struct stm32_tim_dev_s *)&stm32_tim8_priv; - modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM8EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM12 - case 12: - dev = (struct stm32_tim_dev_s *)&stm32_tim12_priv; - modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM12EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM13 - case 13: - dev = (struct stm32_tim_dev_s *)&stm32_tim13_priv; - modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM13EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM14 - case 14: - dev = (struct stm32_tim_dev_s *)&stm32_tim14_priv; - modifyreg32(STM32_RCC_APB1LENR, 0, RCC_APB1LENR_TIM14EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM15 - case 15: - dev = (struct stm32_tim_dev_s *)&stm32_tim15_priv; - modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM15EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM16 - case 16: - dev = (struct stm32_tim_dev_s *)&stm32_tim16_priv; - modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM16EN); - break; -#endif -#ifdef CONFIG_STM32H7_TIM17 - case 17: - dev = (struct stm32_tim_dev_s *)&stm32_tim17_priv; - modifyreg32(STM32_RCC_APB2ENR, 0, RCC_APB2ENR_TIM17EN); - break; -#endif - default: - return NULL; - } + struct clk_s *clk = clk_get(((struct stm32_tim_priv_s *)dev)->clkbase); + clk_enable(clk); /* Is device already allocated */ @@ -1472,81 +1277,8 @@ int stm32_tim_deinit(struct stm32_tim_dev_s * dev) /* Disable power */ - switch (((struct stm32_tim_priv_s *)dev)->base) - { -#ifdef CONFIG_STM32H7_TIM1 - case STM32_TIM1_BASE: - modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM1EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM2 - case STM32_TIM2_BASE: - modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM2EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM3 - case STM32_TIM3_BASE: - modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM3EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM4 - case STM32_TIM4_BASE: - modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM4EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM5 - case STM32_TIM5_BASE: - modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM5EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM6 - case STM32_TIM6_BASE: - modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM6EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM7 - case STM32_TIM7_BASE: - modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM7EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM8 - case STM32_TIM8_BASE: - modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM8EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM12 - case STM32_TIM12_BASE: - modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM12EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM13 - case STM32_TIM13_BASE: - modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM13EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM14 - case STM32_TIM14_BASE: - modifyreg32(STM32_RCC_APB1LENR, RCC_APB1LENR_TIM14EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM15 - case STM32_TIM15_BASE: - modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM15EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM16 - case STM32_TIM16_BASE: - modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM16EN, 0); - break; -#endif -#ifdef CONFIG_STM32H7_TIM17 - case STM32_TIM17_BASE: - modifyreg32(STM32_RCC_APB2ENR, RCC_APB2ENR_TIM17EN, 0); - break; -#endif - default: - return -EINVAL; - } + struct clk_s *clk = clk_get(((struct stm32_tim_priv_s *)dev)->clkbase); + clk_disable(clk); /* Mark it as free */ diff --git a/arch/arm/src/stm32h7/stm32_timerisr.c b/arch/arm/src/stm32h7/stm32_timerisr.c index 420b1bdee930b..fe9c9d028fd8d 100644 --- a/arch/arm/src/stm32h7/stm32_timerisr.c +++ b/arch/arm/src/stm32h7/stm32_timerisr.c @@ -30,12 +30,12 @@ #include #include #include -#include #include "nvic.h" #include "clock/clock.h" #include "arm_internal.h" #include "chip.h" +#include /**************************************************************************** * Pre-processor Definitions @@ -65,40 +65,6 @@ * 224-1). */ -#undef CONFIG_STM32H7_SYSTICK_HCLKd8 - -/* REVISIT: - * It looks like SYSTICK for H7 is always clocked from CPUCLK and doesn't - * depend on the SYSTICK_CTRL_CLKSOURCE bit settings. - */ - -#ifdef CONFIG_STM32H7_SYSTICK_HCLKd8 -# define STM32_SYSTICK_CLOCK (STM32_HCLK_FREQUENCY / 8) -#else -# define STM32_SYSTICK_CLOCK (STM32_CPUCLK_FREQUENCY) -#endif - -/* The desired timer interrupt frequency is provided by the definition - * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of - * system clock ticks per second. That value is a user configurable setting - * that defaults to 100 (100 ticks per second = 10 MS interval). - * - * For example, suppose HCLK = 216 MHz and CLK_TCK = 100, then: - * - * STM32_SYSTICK_CLOCK = 216 MHz / 8 = 27 MHz - * SYSTICK_RELOAD = (27,000,000 / 100) - 1 = 269,999 - */ - -#define SYSTICK_RELOAD ((STM32_SYSTICK_CLOCK / CLK_TCK) - 1) - -/* The size of the reload field is 24 bits. Verify that the reload value - * will fit in the reload register. - */ - -#if SYSTICK_RELOAD > 0x00ffffff -# error SYSTICK_RELOAD exceeds the range of the RELOAD register -#endif - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -135,11 +101,30 @@ static int stm32_timerisr(int irq, uint32_t *regs, void *arg) void up_timer_initialize(void) { - uint32_t regval; + struct clk_s *clk = clk_get("hpre"); + uint32_t regval = clk_get_rate(clk); + + /* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * For example, suppose HCLK = 216 MHz and CLK_TCK = 100, then: + * + * STM32_SYSTICK_CLOCK = 216 MHz / 8 = 27 MHz + * SYSTICK_RELOAD = (27,000,000 / 100) - 1 = 269,999 + */ + + regval = (regval / CLK_TCK) - 1; + + if (regval > 0x00ffffff) + { + /* PANIC */ + } /* Configure SysTick to interrupt at the requested rate */ - putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD); + putreg32(regval, NVIC_SYSTICK_RELOAD); putreg32(0, NVIC_SYSTICK_CURRENT); /* Attach the timer interrupt vector */ @@ -154,11 +139,6 @@ void up_timer_initialize(void) */ regval = (NVIC_SYSTICK_CTRL_TICKINT | NVIC_SYSTICK_CTRL_ENABLE); -#ifndef CONFIG_STM32H7_SYSTICK_HCLKd8 - regval |= NVIC_SYSTICK_CTRL_CLKSOURCE; -#else - regval &= ~NVIC_SYSTICK_CTRL_CLKSOURCE; -#endif putreg32(regval, NVIC_SYSTICK_CTRL); /* And enable the timer interrupt */ diff --git a/arch/arm/src/stm32h7/stm32_uart.h b/arch/arm/src/stm32h7/stm32_uart.h index 92234cb4c4556..a36bc8abf7500 100644 --- a/arch/arm/src/stm32h7/stm32_uart.h +++ b/arch/arm/src/stm32h7/stm32_uart.h @@ -78,95 +78,31 @@ /* Is there a serial console? */ #if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32H7_USART1) -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE # define CONSOLE_UART 1 # define HAVE_CONSOLE 1 #elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32H7_USART2) -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE # define CONSOLE_UART 2 # define HAVE_CONSOLE 1 #elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_STM32H7_USART3) -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE # define CONSOLE_UART 3 # define HAVE_CONSOLE 1 #elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_STM32H7_UART4) -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE # define CONSOLE_UART 4 # define HAVE_CONSOLE 1 #elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_STM32H7_UART5) -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE # define CONSOLE_UART 5 # define HAVE_CONSOLE 1 #elif defined(CONFIG_USART6_SERIAL_CONSOLE) && defined(CONFIG_STM32H7_USART6) -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE # define CONSOLE_UART 6 # define HAVE_CONSOLE 1 #elif defined(CONFIG_UART7_SERIAL_CONSOLE) && defined(CONFIG_STM32H7_UART7) -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE # define CONSOLE_UART 7 # define HAVE_CONSOLE 1 #elif defined(CONFIG_UART8_SERIAL_CONSOLE) && defined(CONFIG_STM32H7_UART8) -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE # define CONSOLE_UART 8 # define HAVE_CONSOLE 1 #else -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# undef CONFIG_USART6_SERIAL_CONSOLE -# undef CONFIG_UART7_SERIAL_CONSOLE -# undef CONFIG_UART8_SERIAL_CONSOLE -# define CONSOLE_UART 0 +# undef CONSOLE_UART # undef HAVE_CONSOLE #endif diff --git a/boards/arm/stm32h7/nucleo-h743zi/include/board.h b/boards/arm/stm32h7/nucleo-h743zi/include/board.h index c6927c46443fe..b6dfc34b18fa0 100644 --- a/boards/arm/stm32h7/nucleo-h743zi/include/board.h +++ b/boards/arm/stm32h7/nucleo-h743zi/include/board.h @@ -57,165 +57,11 @@ #define STM32_BOARD_XTAL 8000000ul /* ST-LINK MCO */ -#define STM32_HSI_FREQUENCY 16000000ul -#define STM32_LSI_FREQUENCY 32000 #define STM32_HSE_FREQUENCY STM32_BOARD_XTAL #define STM32_LSE_FREQUENCY 32768 -/* Main PLL Configuration. - * - * PLL source is HSE = 8,000,000 - * - * To use HSE, configure the solder bridges on the board: - * - * - SB148, SB8 and SB9 OFF - * - SB112 and SB149 ON - * - * When STM32_HSE_FREQUENCY / PLLM <= 2MHz VCOL must be selected. - * VCOH otherwise. - * - * PLL_VCOx = (STM32_HSE_FREQUENCY / PLLM) * PLLN - * Subject to: - * - * 1 <= PLLM <= 63 - * 4 <= PLLN <= 512 - * 150 MHz <= PLL_VCOL <= 420MHz - * 192 MHz <= PLL_VCOH <= 836MHz - * - * SYSCLK = PLL_VCO / PLLP - * CPUCLK = SYSCLK / D1CPRE - * Subject to - * - * PLLP1 = {2, 4, 6, 8, ..., 128} - * PLLP2,3 = {2, 3, 4, ..., 128} - * CPUCLK <= 400 MHz - */ - -#define STM32_BOARD_USEHSE #define STM32_HSEBYP_ENABLE -#define STM32_PLLCFG_PLLSRC RCC_PLLCKSELR_PLLSRC_HSE - -/* PLL1, wide 4 - 8 MHz input, enable DIVP, DIVQ, DIVR - * - * PLL1_VCO = (8,000,000 / 2) * 200 = 800 MHz - * - * PLL1P = PLL1_VCO/2 = 800 MHz / 2 = 400 MHz - * PLL1Q = PLL1_VCO/4 = 800 MHz / 4 = 200 MHz - * PLL1R = PLL1_VCO/8 = 800 MHz / 8 = 100 MHz - */ - -#define STM32_PLLCFG_PLL1CFG (RCC_PLLCFGR_PLL1VCOSEL_WIDE | \ - RCC_PLLCFGR_PLL1RGE_4_8_MHZ | \ - RCC_PLLCFGR_DIVP1EN | \ - RCC_PLLCFGR_DIVQ1EN | \ - RCC_PLLCFGR_DIVR1EN) -#define STM32_PLLCFG_PLL1M RCC_PLLCKSELR_DIVM1(2) -#define STM32_PLLCFG_PLL1N RCC_PLL1DIVR_N1(200) -#define STM32_PLLCFG_PLL1P RCC_PLL1DIVR_P1(2) -#define STM32_PLLCFG_PLL1Q RCC_PLL1DIVR_Q1(4) -#define STM32_PLLCFG_PLL1R RCC_PLL1DIVR_R1(8) - -#define STM32_VCO1_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 200) -#define STM32_PLL1P_FREQUENCY (STM32_VCO1_FREQUENCY / 2) -#define STM32_PLL1Q_FREQUENCY (STM32_VCO1_FREQUENCY / 4) -#define STM32_PLL1R_FREQUENCY (STM32_VCO1_FREQUENCY / 8) - -/* PLL2 */ - -#define STM32_PLLCFG_PLL2CFG (RCC_PLLCFGR_PLL2VCOSEL_WIDE | \ - RCC_PLLCFGR_PLL2RGE_4_8_MHZ | \ - RCC_PLLCFGR_DIVP2EN) -#define STM32_PLLCFG_PLL2M RCC_PLLCKSELR_DIVM2(2) -#define STM32_PLLCFG_PLL2N RCC_PLL2DIVR_N2(200) -#define STM32_PLLCFG_PLL2P RCC_PLL2DIVR_P2(40) -#define STM32_PLLCFG_PLL2Q 0 -#define STM32_PLLCFG_PLL2R 0 - -#define STM32_VCO2_FREQUENCY ((STM32_HSE_FREQUENCY / 2) * 200) -#define STM32_PLL2P_FREQUENCY (STM32_VCO2_FREQUENCY / 2) -#define STM32_PLL2Q_FREQUENCY -#define STM32_PLL2R_FREQUENCY - -/* PLL3 */ - -#define STM32_PLLCFG_PLL3CFG 0 -#define STM32_PLLCFG_PLL3M 0 -#define STM32_PLLCFG_PLL3N 0 -#define STM32_PLLCFG_PLL3P 0 -#define STM32_PLLCFG_PLL3Q 0 -#define STM32_PLLCFG_PLL3R 0 - -#define STM32_VCO3_FREQUENCY -#define STM32_PLL3P_FREQUENCY -#define STM32_PLL3Q_FREQUENCY -#define STM32_PLL3R_FREQUENCY - -/* SYSCLK = PLL1P = 400 MHz - * CPUCLK = SYSCLK / 1 = 400 MHz - */ - -#define STM32_RCC_D1CFGR_D1CPRE (RCC_D1CFGR_D1CPRE_SYSCLK) -#define STM32_SYSCLK_FREQUENCY (STM32_PLL1P_FREQUENCY) -#define STM32_CPUCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 1) - -/* Configure Clock Assignments */ - -/* AHB clock (HCLK) is SYSCLK/2 (200 MHz max) - * HCLK1 = HCLK2 = HCLK3 = HCLK4 - */ - -#define STM32_RCC_D1CFGR_HPRE RCC_D1CFGR_HPRE_SYSCLKd2 /* HCLK = SYSCLK / 2 */ -#define STM32_ACLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 2) /* ACLK in D1, HCLK3 in D1 */ -#define STM32_HCLK_FREQUENCY (STM32_SYSCLK_FREQUENCY / 2) /* HCLK in D2, HCLK4 in D3 */ - -/* APB1 clock (PCLK1) is HCLK/4 (54 MHz) */ - -#define STM32_RCC_D2CFGR_D2PPRE1 RCC_D2CFGR_D2PPRE1_HCLKd4 /* PCLK1 = HCLK / 4 */ -#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/4) - -/* APB2 clock (PCLK2) is HCLK/4 (54 MHz) */ - -#define STM32_RCC_D2CFGR_D2PPRE2 RCC_D2CFGR_D2PPRE2_HCLKd4 /* PCLK2 = HCLK / 4 */ -#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/4) - -/* APB3 clock (PCLK3) is HCLK/4 (54 MHz) */ - -#define STM32_RCC_D1CFGR_D1PPRE RCC_D1CFGR_D1PPRE_HCLKd4 /* PCLK3 = HCLK / 4 */ -#define STM32_PCLK3_FREQUENCY (STM32_HCLK_FREQUENCY/4) - -/* APB4 clock (PCLK4) is HCLK/4 (54 MHz) */ - -#define STM32_RCC_D3CFGR_D3PPRE RCC_D3CFGR_D3PPRE_HCLKd4 /* PCLK4 = HCLK / 4 */ -#define STM32_PCLK4_FREQUENCY (STM32_HCLK_FREQUENCY/4) - -/* Timer clock frequencies */ - -/* Timers driven from APB1 will be twice PCLK1 */ - -#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY) -#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY) -#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY) -#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY) -#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY) -#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY) -#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY) -#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY) -#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY) - -/* Timers driven from APB2 will be twice PCLK2 */ - -#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY) -#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY) -#define STM32_APB2_TIM15_CLKIN (2*STM32_PCLK2_FREQUENCY) -#define STM32_APB2_TIM16_CLKIN (2*STM32_PCLK2_FREQUENCY) -#define STM32_APB2_TIM17_CLKIN (2*STM32_PCLK2_FREQUENCY) - -/* Kernel Clock Configuration - * - * Note: look at Table 54 in ST Manual - */ - /* I2C123 clock source - HSI */ #define STM32_RCC_D2CCIP2R_I2C123SRC RCC_D2CCIP2R_I2C123SEL_HSI diff --git a/boards/arm/stm32h7/nucleo-h743zi/src/Makefile b/boards/arm/stm32h7/nucleo-h743zi/src/Makefile index 14d0b78569a84..f0a8b822849b2 100644 --- a/boards/arm/stm32h7/nucleo-h743zi/src/Makefile +++ b/boards/arm/stm32h7/nucleo-h743zi/src/Makefile @@ -34,6 +34,10 @@ else CSRCS += stm32_userleds.c endif +ifeq ($(CONFIG_CLK), y) +CSRCS += stm32_clk.c +endif + ifeq ($(CONFIG_ARCH_BUTTONS),y) CSRCS += stm32_buttons.c endif diff --git a/boards/arm/stm32h7/nucleo-h743zi/src/nucleo-h743zi.h b/boards/arm/stm32h7/nucleo-h743zi/src/nucleo-h743zi.h index b9d0156998017..d5fbc38a2bc94 100644 --- a/boards/arm/stm32h7/nucleo-h743zi/src/nucleo-h743zi.h +++ b/boards/arm/stm32h7/nucleo-h743zi/src/nucleo-h743zi.h @@ -405,4 +405,9 @@ int stm32_progmem_init(void); int stm32_mmcsd_initialize(int minor); #endif + +#ifdef CONFIG_CLK +int stm32_clk_initialize(void); +#endif + #endif /* __BOARDS_ARM_STM32H7_NUCLEO_H743ZI_SRC_NUCLEO_H743ZI_H */ diff --git a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_boot.c b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_boot.c index 137a004ac064d..7977b26aa7cae 100644 --- a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_boot.c +++ b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_boot.c @@ -30,6 +30,7 @@ #include #include +#include #include "arm_internal.h" #include "stm32_start.h" @@ -91,3 +92,15 @@ void board_late_initialize(void) stm32_bringup(); } #endif + + +#ifdef CONFIG_BOARD_EARLY_INITIALIZE + /* Call the board-specific up_initialize() extension to support + * early initialization of board-specific drivers and resources + * that cannot wait until board_late_initialize. + */ + + void board_early_initialize() + { + } +#endif \ No newline at end of file diff --git a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_buttons.c b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_buttons.c index 4ac77a540edf4..2c942a520507b 100644 --- a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_buttons.c +++ b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_buttons.c @@ -36,8 +36,6 @@ #include "nucleo-h743zi.h" #include -#ifdef CONFIG_ARCH_BUTTONS - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -104,4 +102,3 @@ int board_button_irq(int id, xcpt_t irqhandler, void *arg) return ret; } #endif -#endif /* CONFIG_ARCH_BUTTONS */ diff --git a/boards/arm/stm32h7/nucleo-h743zi/src/stm32_clk.c b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_clk.c new file mode 100644 index 0000000000000..462c7193c7dc1 --- /dev/null +++ b/boards/arm/stm32h7/nucleo-h743zi/src/stm32_clk.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * boards/arm/stm32h7/nucleo-h743zi/src/stm32_clk.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#include +#include +#include +#include + +void up_clk_initialize(void) +{ + struct clk_s *clk; + struct clk_s *parent_clk; + + clk = clk_get("pll1_q_ck"); + VERIFY(clk_disable(clk)); + + clk = clk_get("pllsrc"); + parent_clk = clk_get_parent_by_index(clk, 2); + VERIFY(clk_set_parent(clk, parent_clk)); + + clk = clk_get("sys_ck"); + parent_clk = clk_get_parent_by_index(clk, 3); + VERIFY(clk_set_parent(clk, parent_clk)); + + clk = clk_get("divm1"); + VERIFY(clk_set_rate(clk, 4000000)); + + clk = clk_get("pll1_p_ck"); + VERIFY(clk_set_rate(clk, 160000000)); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpioa_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpiob_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpioc_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpiod_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpioe_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpiof_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpiog_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpioh_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpioi_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpioj_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("gpiok_ker_ck"); + VERIFY(clk_enable(clk)); + + clk = clk_get("usart234578sel"); + parent_clk = clk_get_parent_by_index(clk, 3); + VERIFY(clk_set_parent(clk, parent_clk)); +} \ No newline at end of file diff --git a/drivers/clk/clk_divider.c b/drivers/clk/clk_divider.c index dbd94dec90413..6d0b1d572effd 100644 --- a/drivers/clk/clk_divider.c +++ b/drivers/clk/clk_divider.c @@ -244,10 +244,11 @@ static uint32_t clk_divider_bestdiv(FAR struct clk_s *clk, uint32_t rate, } mindiv = 0; - if (divider->flags & CLK_DIVIDER_MINDIV_MSK) + if ((divider->flags & CLK_DIVIDER_MINDIV_MSK) && + (divider->flags & CLK_DIVIDER_APPLY_OFFSET)) { mindiv = (divider->flags & CLK_DIVIDER_MINDIV_MSK) - >> CLK_DIVIDER_MINDIV_OFF; + >> CLK_DIVIDER_MINDIV_OFF; mindiv -= 1; } @@ -363,17 +364,15 @@ const struct clk_ops_s g_clk_divider_ops = FAR struct clk_s *clk_register_divider(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t reg, - uint8_t shift, uint8_t width, - uint16_t clk_divider_flags) + uint8_t flags, + FAR struct clk_divider_s *div) { - struct clk_divider_s div; FAR const char **parent_names; uint8_t num_parents; - if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) + if (div->flags & CLK_DIVIDER_HIWORD_MASK) { - if (width + shift > 16) + if (div->width + div->shift > 16) { return NULL; } @@ -382,11 +381,6 @@ FAR struct clk_s *clk_register_divider(FAR const char *name, parent_names = parent_name ? &parent_name: NULL; num_parents = parent_name ? 1 : 0; - div.reg = reg; - div.shift = shift; - div.width = width; - div.flags = clk_divider_flags; - return clk_register(name, parent_names, num_parents, flags, - &g_clk_divider_ops, &div, sizeof(div)); + &g_clk_divider_ops, div, sizeof(*div)); } diff --git a/drivers/clk/clk_fixed_factor.c b/drivers/clk/clk_fixed_factor.c index 647e58539c0e8..27591530bbf7d 100644 --- a/drivers/clk/clk_fixed_factor.c +++ b/drivers/clk/clk_fixed_factor.c @@ -82,19 +82,15 @@ const struct clk_ops_s g_clk_fixed_factor_ops = FAR struct clk_s *clk_register_fixed_factor(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint8_t mult, - uint8_t div) + uint8_t flags, + FAR struct clk_fixed_factor_s *fixed) { - struct clk_fixed_factor_s fixed; FAR const char **parent_names; uint8_t num_parents; parent_names = parent_name ? &parent_name : NULL; num_parents = parent_name ? 1 : 0; - fixed.mult = mult; - fixed.div = div; - return clk_register(name, parent_names, num_parents, flags, - &g_clk_fixed_factor_ops, &fixed, sizeof(fixed)); + &g_clk_fixed_factor_ops, fixed, sizeof(*fixed)); } diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c index b788982f45b2c..45536b5b49edf 100644 --- a/drivers/clk/clk_fixed_rate.c +++ b/drivers/clk/clk_fixed_rate.c @@ -59,17 +59,15 @@ const struct clk_ops_s clk_fixed_rate_ops = FAR struct clk_s *clk_register_fixed_rate(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t fixed_rate) + uint8_t flags, + FAR struct clk_fixed_rate_s *fixed) { - struct clk_fixed_rate_s fixed; FAR const char **parent_names; uint8_t num_parents; parent_names = parent_name ? &parent_name: NULL; num_parents = parent_name ? 1 : 0; - fixed.fixed_rate = fixed_rate; - return clk_register(name, parent_names, num_parents, flags, - &clk_fixed_rate_ops, &fixed, sizeof(fixed)); + &clk_fixed_rate_ops, fixed, sizeof(*fixed)); } diff --git a/drivers/clk/clk_fractional_divider.c b/drivers/clk/clk_fractional_divider.c index 784123da70714..1e27379f9a2d8 100644 --- a/drivers/clk/clk_fractional_divider.c +++ b/drivers/clk/clk_fractional_divider.c @@ -159,25 +159,15 @@ const struct clk_ops_s g_clk_fractional_divider_ops = FAR struct clk_s * clk_register_fractional_divider(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t reg, - uint8_t mshift, uint8_t mwidth, - uint8_t nshift, uint8_t nwidth, - uint8_t clk_divider_flags) + uint8_t flags, + FAR struct clk_fractional_divider_s *fd) { - struct clk_fractional_divider_s fd; FAR const char **parent_names; uint8_t num_parents; parent_names = parent_name ? &parent_name : NULL; num_parents = parent_name ? 1 : 0; - fd.reg = reg; - fd.mshift = mshift; - fd.mwidth = mwidth; - fd.nshift = nshift; - fd.nwidth = nwidth; - fd.flags = clk_divider_flags; - return clk_register(name, parent_names, num_parents, flags, - &g_clk_fractional_divider_ops, &fd, sizeof(fd)); + &g_clk_fractional_divider_ops, fd, sizeof(*fd)); } diff --git a/drivers/clk/clk_gate.c b/drivers/clk/clk_gate.c index 1eab53984df6c..cba7a7a88a6b4 100644 --- a/drivers/clk/clk_gate.c +++ b/drivers/clk/clk_gate.c @@ -119,17 +119,15 @@ const struct clk_ops_s g_clk_gate_ops = FAR struct clk_s *clk_register_gate(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t reg, - uint8_t bit_idx, - uint8_t clk_gate_flags) + uint8_t flags, + FAR struct clk_gate_s *gate) { - FAR struct clk_gate_s gate; FAR const char **parent_names; uint8_t num_parents; - if (clk_gate_flags & CLK_GATE_HIWORD_MASK) + if (gate->flags & CLK_GATE_HIWORD_MASK) { - if (bit_idx > 16) + if (gate->bit_idx > 16) { return NULL; } @@ -138,10 +136,6 @@ FAR struct clk_s *clk_register_gate(FAR const char *name, parent_names = parent_name ? &parent_name : NULL; num_parents = parent_name ? 1 : 0; - gate.reg = reg; - gate.bit_idx = bit_idx; - gate.flags = clk_gate_flags; - return clk_register(name, parent_names, num_parents, flags, - &g_clk_gate_ops, &gate, sizeof(gate)); + &g_clk_gate_ops, gate, sizeof(*gate)); } diff --git a/drivers/clk/clk_multiplier.c b/drivers/clk/clk_multiplier.c index a18a0bd371717..ecd9694eae607 100644 --- a/drivers/clk/clk_multiplier.c +++ b/drivers/clk/clk_multiplier.c @@ -97,8 +97,21 @@ static uint32_t clk_multiplier_recalc_rate(FAR struct clk_s *clk, { return -EINVAL; } + else + { + return parent_rate; + } + } + + if (multiplier->flags & CLK_MULT_MINMULT_MSK) + { + uint32_t minmult = (multiplier->flags & CLK_MULT_MINMULT_MSK) + >> CLK_MULT_MINMULT_OFF; - return parent_rate; + if (mult < minmult) + { + return -EINVAL; + } } return parent_rate * mult; @@ -193,11 +206,22 @@ static int clk_multiplier_set_rate(FAR struct clk_s *clk, uint32_t rate, value = MASK(multiplier->width); } + if (multiplier->flags & CLK_MULT_MINMULT_MSK) + { + uint32_t minmult = (multiplier->flags & CLK_MULT_MINMULT_MSK) + >> CLK_MULT_MINMULT_OFF; + + if (mult < minmult) + { + return -EINVAL; + } + } + + if (multiplier->flags & CLK_MULT_HIWORD_MASK) { val = MASK(multiplier->width) << (multiplier->shift + 16); } - else { val = clk_read(multiplier->reg); @@ -227,18 +251,15 @@ const struct clk_ops_s g_clk_multiplier_ops = FAR struct clk_s *clk_register_multiplier(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t reg, - uint8_t shift, - uint8_t width, - uint8_t clk_multiplier_flags) + uint8_t flags, + FAR struct clk_multiplier_s *mult) { - struct clk_multiplier_s mult; FAR const char **parent_names; uint8_t num_parents; - if (clk_multiplier_flags & CLK_MULT_HIWORD_MASK) + if (mult->flags & CLK_MULT_HIWORD_MASK) { - if (width + shift > 16) + if (mult->width + mult->shift > 16) { return NULL; } @@ -247,11 +268,6 @@ FAR struct clk_s *clk_register_multiplier(FAR const char *name, parent_names = parent_name ? &parent_name : NULL; num_parents = parent_name ? 1 : 0; - mult.reg = reg; - mult.shift = shift; - mult.width = width; - mult.flags = clk_multiplier_flags; - return clk_register(name, parent_names, num_parents, flags, - &g_clk_multiplier_ops, &mult, sizeof(mult)); + &g_clk_multiplier_ops, mult, sizeof(*mult)); } diff --git a/drivers/clk/clk_mux.c b/drivers/clk/clk_mux.c index d982b6da8d28b..d1532edbbd017 100644 --- a/drivers/clk/clk_mux.c +++ b/drivers/clk/clk_mux.c @@ -177,25 +177,18 @@ const struct clk_ops_s g_clk_mux_ro_ops = FAR struct clk_s *clk_register_mux(FAR const char *name, FAR const char * const *parent_names, uint8_t num_parents, - uint8_t flags, uint32_t reg, - uint8_t shift, uint8_t width, - uint8_t clk_mux_flags) + uint8_t flags, + FAR struct clk_mux_s *mux) { - struct clk_mux_s mux; - mux.reg = reg; - mux.shift = shift; - mux.width = width; - mux.flags = clk_mux_flags; - - if (clk_mux_flags & CLK_MUX_READ_ONLY) + if (mux->flags & CLK_MUX_READ_ONLY) { return clk_register(name, parent_names, num_parents, flags, - &g_clk_mux_ro_ops, &mux, sizeof(mux)); + &g_clk_mux_ro_ops, mux, sizeof(*mux)); } else { return clk_register(name, parent_names, num_parents, flags, - &g_clk_mux_ops, &mux, sizeof(mux)); + &g_clk_mux_ops, mux, sizeof(*mux)); } } diff --git a/drivers/clk/clk_phase.c b/drivers/clk/clk_phase.c index 8a96d7453368c..bc7bde2bed450 100644 --- a/drivers/clk/clk_phase.c +++ b/drivers/clk/clk_phase.c @@ -92,22 +92,15 @@ const struct clk_ops_s g_clk_phase_ops = FAR struct clk_s *clk_register_phase(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t reg, - uint8_t shift, uint8_t width, - uint8_t clk_phase_flags) + uint8_t flags, + FAR struct clk_phase_s *phase) { - struct clk_phase_s phase; FAR const char **parent_names; uint8_t num_parents; parent_names = parent_name ? &parent_name : NULL; num_parents = parent_name ? 1 : 0; - phase.reg = reg; - phase.shift = shift; - phase.width = width; - phase.flags = clk_phase_flags; - return clk_register(name, parent_names, num_parents, flags, - &g_clk_phase_ops, &phase, sizeof(phase)); + &g_clk_phase_ops, phase, sizeof(*phase)); } diff --git a/include/nuttx/clk/clk_provider.h b/include/nuttx/clk/clk_provider.h index c64b174d4d4c6..4ee1a69e55291 100644 --- a/include/nuttx/clk/clk_provider.h +++ b/include/nuttx/clk/clk_provider.h @@ -58,6 +58,7 @@ #define CLK_DIVIDER_MAX_HALF 0x10 #define CLK_DIVIDER_DIV_NEED_EVEN 0x20 #define CLK_DIVIDER_POWER_OF_TWO 0x40 +#define CLK_DIVIDER_APPLY_OFFSET 0x80 #define CLK_DIVIDER_MINDIV_OFF 8 #define CLK_DIVIDER_MINDIV_MSK 0xff00 @@ -69,6 +70,8 @@ #define CLK_MULT_HIWORD_MASK 0x04 #define CLK_MULT_MAX_HALF 0x08 #define CLK_MULT_ROUND_CLOSEST 0x10 +#define CLK_MULT_MINMULT_OFF 8 +#define CLK_MULT_MINMULT_MSK 0xff00 #define CLK_MUX_HIWORD_MASK 0x01 #define CLK_MUX_READ_ONLY 0x02 @@ -205,51 +208,44 @@ FAR struct clk_s *clk_register(FAR const char *name, FAR struct clk_s *clk_register_gate(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t reg, - uint8_t bit_idx, - uint8_t clk_gate_flags); + uint8_t flags, + FAR struct clk_gate_s *gate); FAR struct clk_s *clk_register_fixed_rate(FAR const char *name, FAR const char *parent_name, uint8_t flags, - uint32_t fixed_rate); + FAR struct clk_fixed_rate_s *fixed); FAR struct clk_s *clk_register_fixed_factor(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint8_t mult, - uint8_t div); + uint8_t flags, + FAR struct clk_fixed_factor_s *fixed); FAR struct clk_s *clk_register_divider(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t reg, - uint8_t shift, uint8_t width, - uint16_t clk_divider_flags); + uint8_t flags, + FAR struct clk_divider_s *div); FAR struct clk_s *clk_register_phase(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t reg, - uint8_t shift, uint8_t width, - uint8_t clk_phase_flags); + uint8_t flags, + FAR struct clk_phase_s *phase); FAR struct clk_s * clk_register_fractional_divider(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t reg, - uint8_t mshift, uint8_t mwidth, - uint8_t nshift, uint8_t nwidth, - uint8_t clk_divider_flags); + uint8_t flags, + FAR struct clk_fractional_divider_s *fd); FAR struct clk_s *clk_register_multiplier(FAR const char *name, FAR const char *parent_name, - uint8_t flags, uint32_t reg, - uint8_t shift, uint8_t width, - uint8_t clk_multiplier_flags); + uint8_t flags, + FAR struct clk_multiplier_s *mult); FAR struct clk_s *clk_register_mux(FAR const char *name, FAR const char * const *parent_names, uint8_t num_parents, uint8_t flags, - uint32_t reg, uint8_t shift, - uint8_t width, uint8_t clk_mux_flags); + FAR struct clk_mux_s *mux); #ifdef CONFIG_CLK_RPMSG FAR struct clk_s *clk_register_rpmsg(FAR const char *name, uint8_t flags); @@ -257,6 +253,44 @@ FAR struct clk_s *clk_register_rpmsg(FAR const char *name, uint8_t flags); int clk_rpmsg_server_initialize(void); #endif +/**************************************************************************** + * Name: up_clk_initialize + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * This function (by default) will reset most everything, enable the PLL, + * and enable peripheral clocking for all peripherals enabled in the NuttX + * configuration file. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_clk_register(void); + +/**************************************************************************** + * Name: up_clk_initialize + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * This function (by default) will reset most everything, enable the PLL, + * and enable peripheral clocking for all peripherals enabled in the NuttX + * configuration file. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_clk_initialize(void); + #undef EXTERN #if defined(__cplusplus) } diff --git a/sched/clock/clock_initialize.c b/sched/clock/clock_initialize.c index 36f1749d5d386..50cb4acaf5ffc 100644 --- a/sched/clock/clock_initialize.c +++ b/sched/clock/clock_initialize.c @@ -42,7 +42,12 @@ #include +#if defined (CONFIG_CLK) +# include +#endif + #include "clock/clock.h" +#include "timer/timer.h" #ifdef CONFIG_CLOCK_TIMEKEEPING # include "clock/clock_timekeeping.h" #endif @@ -205,6 +210,11 @@ void clock_initialize(void) { sched_trace_begin(); +#if defined(CONFIG_CLK) + up_clk_register(); + up_clk_initialize(); +#endif + #if !defined(CONFIG_SUPPRESS_INTERRUPTS) && \ !defined(CONFIG_SUPPRESS_TIMER_INTS) && \ !defined(CONFIG_SYSTEMTICK_EXTCLK) @@ -234,6 +244,10 @@ void clock_initialize(void) cpuload_init(); #endif +#ifndef CONFIG_DISABLE_POSIX_TIMERS + timer_initialize(); +#endif + sched_trace_end(); } diff --git a/sched/init/nx_start.c b/sched/init/nx_start.c index 3f4a4e1820c75..fd985bebd64b3 100644 --- a/sched/init/nx_start.c +++ b/sched/init/nx_start.c @@ -56,7 +56,6 @@ #include "mqueue/mqueue.h" #include "mqueue/msg.h" #include "clock/clock.h" -#include "timer/timer.h" #include "irq/irq.h" #include "group/group.h" #include "init/init.h" @@ -634,14 +633,10 @@ void nx_start(void) irq_initialize(); - /* Initialize the POSIX timer facility (if included in the link) */ + /* Initialize system clocking and POSIX timer facility (if included) */ clock_initialize(); -#ifndef CONFIG_DISABLE_POSIX_TIMERS - timer_initialize(); -#endif - /* Initialize the signal facility (if in link) */ nxsig_initialize();