From f50c439f21456a53b790ffb39ba4735dcd8afd0a Mon Sep 17 00:00:00 2001 From: Ville Juven Date: Tue, 26 Mar 2024 10:19:43 +0200 Subject: [PATCH] imx9_clockconfig.c: Add way to query clock frequency The frequency of a clock source is stored in a LUT. Currently the LUT contains the PLL frequencies set by the boot ROM code. --- .../arm64/src/imx9/hardware/imx93/imx93_ccm.h | 4 +- arch/arm64/src/imx9/imx9_clockconfig.c | 104 ++++++++++++++++++ arch/arm64/src/imx9/imx9_clockconfig.h | 44 ++++++++ 3 files changed, 150 insertions(+), 2 deletions(-) diff --git a/arch/arm64/src/imx9/hardware/imx93/imx93_ccm.h b/arch/arm64/src/imx9/hardware/imx93/imx93_ccm.h index 7ac0f77954f..ae46d228ff7 100644 --- a/arch/arm64/src/imx9/hardware/imx93/imx93_ccm.h +++ b/arch/arm64/src/imx9/hardware/imx93/imx93_ccm.h @@ -579,13 +579,13 @@ enum ccm_clock_name_e ARM_PLL = 1, /* ARM PLL */ ARM_PLLOUT = 2, /* ARM PLL OUT */ SYS_PLL1_IN = 3, /* SYSTEM PLL1 IN */ - SYS_PLL1PFD0_IN = 5, /* SYSTEM PLL1 PFD0 IN */ + SYS_PLL1PFD0_IN = 4, /* SYSTEM PLL1 PFD0 IN */ SYS_PLL1PFD0 = 5, /* SYSTEM PLL1 PFD0 */ SYS_PLL1PFD0DIV2 = 6, /* SYSTEM PLL1 PFD0 DIV2 */ SYS_PLL1PFD1_IN = 7, /* SYSTEM PLL1 PFD1 IN */ SYS_PLL1PFD1 = 8, /* SYSTEM PLL1 PFD1 */ SYS_PLL1PFD1DIV2 = 9, /* SYSTEM PLL1 PFD1 DIV2 */ - SYS_PLL1PFD2_IN = 11, /* SYSTEM PLL1 PFD2 IN */ + SYS_PLL1PFD2_IN = 10, /* SYSTEM PLL1 PFD2 IN */ SYS_PLL1PFD2 = 11, /* SYSTEM PLL1 PFD2 */ SYS_PLL1PFD2DIV2 = 12, /* SYSTEM PLL1 PFD2 DIV2 */ AUDIO_PLL1 = 13, /* AUDIO PLL1 */ diff --git a/arch/arm64/src/imx9/imx9_clockconfig.c b/arch/arm64/src/imx9/imx9_clockconfig.c index bf097f6dcf4..cc4d87a0b03 100644 --- a/arch/arm64/src/imx9/imx9_clockconfig.c +++ b/arch/arm64/src/imx9/imx9_clockconfig.c @@ -58,6 +58,30 @@ * Private Data ****************************************************************************/ +static uint32_t g_pll_freqs[] = +{ + [OSC_24M] = 24000000U, /* 24MHZ OSCILLATOR. */ + [ARM_PLL] = 2000000000U, /* ARM PLL */ + [ARM_PLLOUT] = 2000000000U, /* ARM PLL OUT */ + [SYS_PLL1_IN] = 4000000000U, /* SYSTEM PLL1 IN */ + [SYS_PLL1PFD0_IN] = 1000000000U, /* SYSTEM PLL1 PFD0 IN */ + [SYS_PLL1PFD0] = 1000000000U, /* SYSTEM PLL1 PFD0 */ + [SYS_PLL1PFD0DIV2] = 500000000U, /* SYSTEM PLL1 PFD0 DIV2 */ + [SYS_PLL1PFD1_IN] = 800000000U, /* SYSTEM PLL1 PFD1 IN */ + [SYS_PLL1PFD1] = 800000000U, /* SYSTEM PLL1 PFD1 */ + [SYS_PLL1PFD1DIV2] = 400000000U, /* SYSTEM PLL1 PFD1 DIV2 */ + [SYS_PLL1PFD2_IN] = 625000000U, /* SYSTEM PLL1 PFD2 IN */ + [SYS_PLL1PFD2] = 625000000U, /* SYSTEM PLL1 PFD2 */ + [SYS_PLL1PFD2DIV2] = 312500000U, /* SYSTEM PLL1 PFD2 DIV2 */ + [AUDIO_PLL1] = 0U, /* AUDIO PLL1 */ + [AUDIO_PLL1OUT] = 0U, /* AUDIO PLL1 OUT */ + [DRAM_PLL] = 1000000000U, /* DRAM PLL */ + [DRAM_PLLOUT] = 1000000000U, /* DRAM PLL OUT */ + [VIDEO_PLL1] = 0U, /* VIDEO PLL1 */ + [VIDEO_PLL1OUT] = 0U, /* VIDEO PLL1 OUT */ + [EXT] = 0U /* EXT */ +}; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -214,3 +238,83 @@ void imx9_clockconfig(void) * By default, all peripheral root clocks are set to the 24 MHz oscillator. */ } + +/**************************************************************************** + * Name: imx9_get_clock + * + * Description: + * This function returns the clock frequency of the specified functional + * clock. + * + * Input Parameters: + * clkname - Identifies the clock of interest + * frequency - The location where the peripheral clock frequency will be + * returned + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. -ENODEV is returned if the clock is not enabled or is not + * being clocked. + * + ****************************************************************************/ + +int imx9_get_clock(int clkname, uint32_t *frequency) +{ + if (clkname >= EXT) + { + *frequency = 0; + return -ENODEV; + } + + *frequency = g_pll_freqs[clkname]; + return OK; +} + +/**************************************************************************** + * Name: imx9_get_rootclock + * + * Description: + * This function returns the clock frequency of the specified root + * functional clock. + * + * Input Parameters: + * clkroot - Identifies the peripheral clock of interest + * frequency - The location where the peripheral clock frequency will be + * returned + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. -ENODEV is returned if the clock is not enabled or is not + * being clocked. + * + ****************************************************************************/ + +int imx9_get_rootclock(int clkroot, uint32_t *frequency) +{ + uint32_t reg; + uint32_t div; + uint32_t mux; + int clk_name; + + if (clkroot <= CCM_CR_COUNT) + { + reg = getreg32(IMX9_CCM_CR_CTRL(clkroot)); + + if ((reg & CCM_CR_CTRL_OFF) == CCM_CR_CTRL_OFF) + { + *frequency = 0; + } + else + { + mux = (reg & CCM_CR_CTRL_MUX_MASK) >> CCM_CR_CTRL_MUX_SHIFT; + clk_name = g_ccm_root_mux[clkroot][mux]; + imx9_get_clock(clk_name, frequency); + div = ((reg & CCM_CR_CTRL_DIV_MASK) >> CCM_CR_CTRL_DIV_SHIFT) + 1; + *frequency = *frequency / div; + } + + return OK; + } + + return -ENODEV; +} diff --git a/arch/arm64/src/imx9/imx9_clockconfig.h b/arch/arm64/src/imx9/imx9_clockconfig.h index b688e450f38..90301989a94 100644 --- a/arch/arm64/src/imx9/imx9_clockconfig.h +++ b/arch/arm64/src/imx9/imx9_clockconfig.h @@ -27,6 +27,8 @@ #include +#include + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -43,4 +45,46 @@ void imx9_clockconfig(void); +/**************************************************************************** + * Name: imx9_get_clock + * + * Description: + * This function returns the clock frequency of the specified functional + * clock. + * + * Input Parameters: + * clkname - Identifies the clock of interest + * frequency - The location where the peripheral clock frequency will be + * returned + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. -ENODEV is returned if the clock is not enabled or is not + * being clocked. + * + ****************************************************************************/ + +int imx9_get_clock(int clkname, uint32_t *frequency); + +/**************************************************************************** + * Name: imx9_get_rootclock + * + * Description: + * This function returns the clock frequency of the specified root + * functional clock. + * + * Input Parameters: + * clkroot - Identifies the peripheral clock of interest + * frequency - The location where the peripheral clock frequency will be + * returned + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. -ENODEV is returned if the clock is not enabled or is not + * being clocked. + * + ****************************************************************************/ + +int imx9_get_rootclock(int clkroot, uint32_t *frequency); + #endif /* __ARCH_ARM64_SRC_IMX9_IMX9_CLOCKCONFIG_H */