From 4c3412faaa1a22939586603b63205c36141a51b3 Mon Sep 17 00:00:00 2001 From: Abdelatif Guettouche Date: Mon, 8 Feb 2021 10:47:21 +0100 Subject: [PATCH] risc-v/esp32c3: Add clock configuration Signed-off-by: Abdelatif Guettouche --- arch/risc-v/src/esp32c3/Kconfig | 29 +++ arch/risc-v/src/esp32c3/Make.defs | 1 + arch/risc-v/src/esp32c3/esp32c3_clockconfig.c | 198 ++++++++++++++++++ arch/risc-v/src/esp32c3/esp32c3_clockconfig.h | 81 +++++++ 4 files changed, 309 insertions(+) create mode 100644 arch/risc-v/src/esp32c3/esp32c3_clockconfig.c create mode 100644 arch/risc-v/src/esp32c3/esp32c3_clockconfig.h diff --git a/arch/risc-v/src/esp32c3/Kconfig b/arch/risc-v/src/esp32c3/Kconfig index 23d2428e3c..d5a15a91d2 100644 --- a/arch/risc-v/src/esp32c3/Kconfig +++ b/arch/risc-v/src/esp32c3/Kconfig @@ -73,6 +73,35 @@ config ESP32C3_ESP32C3XXX default n select ESP32C3_SINGLE_CPU +choice ESP32C3_CPU_FREQ + prompt "CPU frequency" + default ESP32C3_CPU_FREQ_160 + help + CPU frequency to be set on application startup. + +config ESP32C3_CPU_FREQ_40 + bool "40 MHz" + help + Set the CPU to 40 MHz. This frequency is obtained from the XTAL. + +config ESP32C3_CPU_FREQ_80 + bool "80 MHz" + help + Set the CPU to 80 MHz. This frequency is obtained from the 480 MHz PLL. + +config ESP32C3_CPU_FREQ_160 + bool "160 MHz" + help + Set the CPU to 160 MHz. This frequency is obtained from the 480 MHz PLL. + +endchoice # CPU frequency + +config ESP32C3_CPU_FREQ_MHZ + int + default 40 if ESP32C3_CPU_FREQ_40 + default 80 if ESP32C3_CPU_FREQ_80 + default 160 if ESP32C3_CPU_FREQ_160 + menu "ESP32-C3 Peripheral Support" config ESP32C3_UART0 diff --git a/arch/risc-v/src/esp32c3/Make.defs b/arch/risc-v/src/esp32c3/Make.defs index defe8393b7..42804663a3 100644 --- a/arch/risc-v/src/esp32c3/Make.defs +++ b/arch/risc-v/src/esp32c3/Make.defs @@ -51,4 +51,5 @@ endif CHIP_CSRCS = esp32c3_allocateheap.c esp32c3_start.c esp32c3_idle.c CHIP_CSRCS += esp32c3_irq.c esp32c3_timerisr.c +CHIP_CSRCS += esp32c3_clockconfig.c CHIP_CSRCS += esp32c3_serial.c esp32c3_lowputc.c diff --git a/arch/risc-v/src/esp32c3/esp32c3_clockconfig.c b/arch/risc-v/src/esp32c3/esp32c3_clockconfig.c new file mode 100644 index 0000000000..94ee5f580e --- /dev/null +++ b/arch/risc-v/src/esp32c3/esp32c3_clockconfig.c @@ -0,0 +1,198 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c3/esp32c3_clockconfig.c + * + * 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 "riscv_arch.h" + +#include "hardware/esp32c3_system.h" + +#include "esp32c3.h" +#include "esp32c3_clockconfig.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +enum esp32c3_clksrc_e +{ + ESP32C3_CLKSRC_XTAL = 0, + ESP32C3_CLKSRC_PLL +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline void esp32c3_clksrc(int src); +static inline void esp32c3_sysprediv(int div); +static inline void esp32c3_pllcfg(int pllfreq, int cpuprd); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32c3_clksrc + ****************************************************************************/ + +static inline void esp32c3_clksrc(int src) +{ + uint32_t set = 0; + uint32_t clear = 0; + + set |= src << SYSTEM_SOC_CLK_SEL_S; + clear |= SYSTEM_SOC_CLK_SEL_M; + + modifyreg32(SYSTEM_SYSCLK_CONF_REG, clear, set); +} + +/**************************************************************************** + * Name: esp32c3_sysprediv + ****************************************************************************/ + +static inline void esp32c3_sysprediv(int div) +{ + uint32_t set = 0; + uint32_t clear = 0; + + clear |= SYSTEM_PRE_DIV_CNT_M; + set |= div << SYSTEM_PRE_DIV_CNT_S; + + modifyreg32(SYSTEM_SYSCLK_CONF_REG, clear, set); +} + +/**************************************************************************** + * Name: esp32c3_pllcfg + ****************************************************************************/ + +static inline void esp32c3_pllcfg(int pllfreq, int cpuprd) +{ + uint32_t set = 0; + uint32_t clear = 0; + + clear |= SYSTEM_PLL_FREQ_SEL_M | SYSTEM_CPUPERIOD_SEL_M; + set |= pllfreq << SYSTEM_PLL_FREQ_SEL_S; + set |= cpuprd << SYSTEM_CPUPERIOD_SEL_S; + + modifyreg32(SYSTEM_CPU_PER_CONF_REG, clear, set); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32c3_clockconfig + ****************************************************************************/ + +void esp32c3_clockconfig(void) +{ + uint32_t freq_mhz = CONFIG_ESP32C3_CPU_FREQ_MHZ; + + switch (freq_mhz) + { + case 40: + /* 40 MHz is obtained from the XTAL. + * In this case CPU_CLK = XTAL / (DIV + 1). Set the divider as 0 and + * the source as XTAL. + */ + + esp32c3_sysprediv(0); + esp32c3_clksrc(ESP32C3_CLKSRC_XTAL); + break; + + case 80: + /* 80 MHz is obtained from the 480 MHz PLL. + * In this case CPU_CLK = PLL_CLK / 6. Config the PLL as 480 MHz + * with a 6 divider and set the source clock as PLL_CLK. + */ + + esp32c3_pllcfg(1, 0); + esp32c3_clksrc(ESP32C3_CLKSRC_PLL); + break; + + case 160: + /* 160 MHz is obtained from the 480 MHz PLL. + * In this case CPU_CLK = PLL_CLK / 3. Config the PLL as 480 MHz + * with a 3 divider and set the source clock as PLL_CLK. + */ + + esp32c3_pllcfg(1, 1); + esp32c3_clksrc(ESP32C3_CLKSRC_PLL); + break; + + default: + + /* Unsupported clock config. */ + + return; + } +} + +/**************************************************************************** + * Name: esp32c3_clk_apb_freq + * + * Description: + * Returns ABP frequency in Hertz. + * + ****************************************************************************/ + +int esp32c3_clk_apb_freq(void) +{ + uint32_t cpufreq = CONFIG_ESP32C3_CPU_FREQ_MHZ; + + /* APB frequency is 80 MHz if PLL is selected as CPU source, otherwise it's + * the same as the CPU frequency. + */ + + return (cpufreq == 40) ? (40 * 1000000) : (80 * 1000000); +} + +/**************************************************************************** + * Name: esp32c3_clk_crypto_freq + * + * Description: + * Returns crypto engine frequency in Hertz. + * + ****************************************************************************/ + +int esp32c3_clk_crypto_freq(void) +{ + uint32_t cpufreq = CONFIG_ESP32C3_CPU_FREQ_MHZ; + + /* Crypto frequency is 160 MHz if PLL is selected as CPU source, otherwise + * it's the same as the CPU frequency. + */ + + return (cpufreq == 40) ? (40 * 1000000) : (160 * 1000000); +} + diff --git a/arch/risc-v/src/esp32c3/esp32c3_clockconfig.h b/arch/risc-v/src/esp32c3/esp32c3_clockconfig.h new file mode 100644 index 0000000000..5048239393 --- /dev/null +++ b/arch/risc-v/src/esp32c3/esp32c3_clockconfig.h @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c3/esp32c3_clockconfig.h + * + * 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_RISCV_SRC_ESP32C3_ESP32C3_CLOCKCONFIG_H +#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_CLOCKCONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32c3_clockconfig + ****************************************************************************/ + +void esp32c3_clockconfig(void); + +/**************************************************************************** + * Name: esp32c3_clk_apb_freq + * + * Description: + * Returns ABP frequency in Hertz. + * + ****************************************************************************/ + +int esp32c3_clk_apb_freq(void); + +/**************************************************************************** + * Name: esp32c3_clk_crypto_freq + * + * Description: + * Returns crypto engine frequency in Hertz. + * + ****************************************************************************/ + +int esp32c3_clk_crypto_freq(void); + +#if defined(__cplusplus) +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_CLOCKCONFIG_H */