diff options
author | John Tsichritzis <john.tsichritzis@arm.com> | 2019-06-19 15:06:00 +0000 |
---|---|---|
committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2019-06-19 15:06:00 +0000 |
commit | fc3c382f2ccb910554d0608a7db67c3fbefca4f7 (patch) | |
tree | 78ef472e449b85595f5c1ca61771b4d86bd8c77b /drivers | |
parent | de3ad4f0963cdf5206a9736185d23514cfb45111 (diff) | |
parent | f237822f0b003dc5bec54d8c4ee961597a11116c (diff) | |
download | platform_external_arm-trusted-firmware-fc3c382f2ccb910554d0608a7db67c3fbefca4f7.tar.gz platform_external_arm-trusted-firmware-fc3c382f2ccb910554d0608a7db67c3fbefca4f7.tar.bz2 platform_external_arm-trusted-firmware-fc3c382f2ccb910554d0608a7db67c3fbefca4f7.zip |
Merge changes from topic "yg/clk_syscfg_dt" into integration
* changes:
fdts: stm32mp1: realign device tree files with internal devs
stm32mp1: increase device tree size to 20kB
stm32mp1: make dt_get_stdout_node_offset() static
stm32mp1: use unsigned values for SDMMC defines
stm32mp1: remove useless LIBFDT_SRCS from PLAT_BL_COMMON_SOURCES
stm32mp1: update doc for U-Boot compilation
stm32mp1: add general SYSCFG management
stm32mp1: move stm32_get_gpio_bank_clock() to private file
clk: stm32mp1: correctly handle Clock Spreading Generator
clk: stm32mp1: use defines for mask values in stm32mp1_clk_sel array
clk: stm32mp1: move oscillator functions to generic file
arch: add some defines for generic timer registers
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/st/clk/stm32mp1_clk.c | 86 | ||||
-rw-r--r-- | drivers/st/clk/stm32mp1_clkfunc.c | 167 | ||||
-rw-r--r-- | drivers/st/clk/stm32mp_clkfunc.c | 141 |
3 files changed, 191 insertions, 203 deletions
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 11fd6667d..76e6e6fdc 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -20,7 +20,6 @@ #include <drivers/generic_delay_timer.h> #include <drivers/st/stm32mp_clkfunc.h> #include <drivers/st/stm32mp1_clk.h> -#include <drivers/st/stm32mp1_clkfunc.h> #include <drivers/st/stm32mp1_rcc.h> #include <dt-bindings/clock/stm32mp1-clksrc.h> #include <lib/mmio.h> @@ -40,6 +39,15 @@ #define HSIDIV_TIMEOUT TIMEOUT_US_200MS #define OSCRDY_TIMEOUT TIMEOUT_US_1S +const char *stm32mp_osc_node_label[NB_OSC] = { + [_LSI] = "clk-lsi", + [_LSE] = "clk-lse", + [_HSI] = "clk-hsi", + [_HSE] = "clk-hse", + [_CSI] = "clk-csi", + [_I2S_CKIN] = "i2s_ckin", +}; + enum stm32mp1_parent_id { /* Oscillators are defined in enum stm32mp_osc_id */ @@ -83,7 +91,7 @@ enum stm32mp1_parent_sel { _STGEN_SEL, _I2C46_SEL, _SPI6_SEL, - _USART1_SEL, + _UART1_SEL, _RNG1_SEL, _UART6_SEL, _UART24_SEL, @@ -93,8 +101,8 @@ enum stm32mp1_parent_sel { _SDMMC3_SEL, _QSPI_SEL, _FMC_SEL, - _ASS_SEL, - _MSS_SEL, + _AXIS_SEL, + _MCUS_SEL, _USBPHY_SEL, _USBO_SEL, _PARENT_SEL_NB, @@ -246,13 +254,13 @@ struct stm32mp1_clk_pll { .fixed = (f), \ } -#define _CLK_PARENT(idx, off, s, m, p) \ - [(idx)] = { \ - .offset = (off), \ - .src = (s), \ - .msk = (m), \ - .parent = (p), \ - .nb_parent = ARRAY_SIZE(p) \ +#define _CLK_PARENT_SEL(_label, _rcc_selr, _parents) \ + [_ ## _label ## _SEL] = { \ + .offset = _rcc_selr, \ + .src = _rcc_selr ## _ ## _label ## SRC_SHIFT, \ + .msk = _rcc_selr ## _ ## _label ## SRC_MASK, \ + .parent = (_parents), \ + .nb_parent = ARRAY_SIZE(_parents) \ } #define _CLK_PLL(idx, type, off1, off2, off3, \ @@ -315,6 +323,8 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { _CLK_SC_FIXED(RCC_MP_APB2ENSETR, 2, TIM15_K, _PCLK2), _CLK_SC_SELEC(RCC_MP_APB2ENSETR, 13, USART6_K, _UART6_SEL), + _CLK_SC_FIXED(RCC_MP_APB3ENSETR, 11, SYSCFG, _UNKNOWN_ID), + _CLK_SC_SELEC(RCC_MP_APB4ENSETR, 8, DDRPERFM, _UNKNOWN_SEL), _CLK_SC_SELEC(RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL), _CLK_SC_SELEC(RCC_MP_APB4ENSETR, 16, USBPHY_K, _USBPHY_SEL), @@ -322,7 +332,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { _CLK_SC_SELEC(RCC_MP_APB5ENSETR, 0, SPI6_K, _SPI6_SEL), _CLK_SC_SELEC(RCC_MP_APB5ENSETR, 2, I2C4_K, _I2C46_SEL), _CLK_SC_SELEC(RCC_MP_APB5ENSETR, 3, I2C6_K, _I2C46_SEL), - _CLK_SC_SELEC(RCC_MP_APB5ENSETR, 4, USART1_K, _USART1_SEL), + _CLK_SC_SELEC(RCC_MP_APB5ENSETR, 4, USART1_K, _UART1_SEL), _CLK_SC_FIXED(RCC_MP_APB5ENSETR, 8, RTCAPB, _PCLK5), _CLK_SC_FIXED(RCC_MP_APB5ENSETR, 11, TZC1, _PCLK5), _CLK_SC_FIXED(RCC_MP_APB5ENSETR, 12, TZC2, _PCLK5), @@ -430,25 +440,25 @@ static const uint8_t usbo_parents[] = { }; static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { - _CLK_PARENT(_I2C12_SEL, RCC_I2C12CKSELR, 0, 0x7, i2c12_parents), - _CLK_PARENT(_I2C35_SEL, RCC_I2C35CKSELR, 0, 0x7, i2c35_parents), - _CLK_PARENT(_STGEN_SEL, RCC_STGENCKSELR, 0, 0x3, stgen_parents), - _CLK_PARENT(_I2C46_SEL, RCC_I2C46CKSELR, 0, 0x7, i2c46_parents), - _CLK_PARENT(_SPI6_SEL, RCC_SPI6CKSELR, 0, 0x7, spi6_parents), - _CLK_PARENT(_USART1_SEL, RCC_UART1CKSELR, 0, 0x7, usart1_parents), - _CLK_PARENT(_RNG1_SEL, RCC_RNG1CKSELR, 0, 0x3, rng1_parents), - _CLK_PARENT(_UART6_SEL, RCC_UART6CKSELR, 0, 0x7, uart6_parents), - _CLK_PARENT(_UART24_SEL, RCC_UART24CKSELR, 0, 0x7, uart234578_parents), - _CLK_PARENT(_UART35_SEL, RCC_UART35CKSELR, 0, 0x7, uart234578_parents), - _CLK_PARENT(_UART78_SEL, RCC_UART78CKSELR, 0, 0x7, uart234578_parents), - _CLK_PARENT(_SDMMC12_SEL, RCC_SDMMC12CKSELR, 0, 0x7, sdmmc12_parents), - _CLK_PARENT(_SDMMC3_SEL, RCC_SDMMC3CKSELR, 0, 0x7, sdmmc3_parents), - _CLK_PARENT(_QSPI_SEL, RCC_QSPICKSELR, 0, 0xf, qspi_parents), - _CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0xf, fmc_parents), - _CLK_PARENT(_ASS_SEL, RCC_ASSCKSELR, 0, 0x3, ass_parents), - _CLK_PARENT(_MSS_SEL, RCC_MSSCKSELR, 0, 0x3, mss_parents), - _CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents), - _CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents), + _CLK_PARENT_SEL(I2C12, RCC_I2C12CKSELR, i2c12_parents), + _CLK_PARENT_SEL(I2C35, RCC_I2C35CKSELR, i2c35_parents), + _CLK_PARENT_SEL(STGEN, RCC_STGENCKSELR, stgen_parents), + _CLK_PARENT_SEL(I2C46, RCC_I2C46CKSELR, i2c46_parents), + _CLK_PARENT_SEL(SPI6, RCC_SPI6CKSELR, spi6_parents), + _CLK_PARENT_SEL(UART1, RCC_UART1CKSELR, usart1_parents), + _CLK_PARENT_SEL(RNG1, RCC_RNG1CKSELR, rng1_parents), + _CLK_PARENT_SEL(UART6, RCC_UART6CKSELR, uart6_parents), + _CLK_PARENT_SEL(UART24, RCC_UART24CKSELR, uart234578_parents), + _CLK_PARENT_SEL(UART35, RCC_UART35CKSELR, uart234578_parents), + _CLK_PARENT_SEL(UART78, RCC_UART78CKSELR, uart234578_parents), + _CLK_PARENT_SEL(SDMMC12, RCC_SDMMC12CKSELR, sdmmc12_parents), + _CLK_PARENT_SEL(SDMMC3, RCC_SDMMC3CKSELR, sdmmc3_parents), + _CLK_PARENT_SEL(QSPI, RCC_QSPICKSELR, qspi_parents), + _CLK_PARENT_SEL(FMC, RCC_FMCCKSELR, fmc_parents), + _CLK_PARENT_SEL(AXIS, RCC_ASSCKSELR, ass_parents), + _CLK_PARENT_SEL(MCUS, RCC_MSSCKSELR, mss_parents), + _CLK_PARENT_SEL(USBPHY, RCC_USBCKSELR, usbphy_parents), + _CLK_PARENT_SEL(USBO, RCC_USBCKSELR, usbo_parents), }; /* Define characteristic of PLL according type */ @@ -648,7 +658,7 @@ static int stm32mp1_clk_get_parent(unsigned long id) } sel = clk_sel_ref(s); - p_sel = (mmio_read_32(rcc_base + sel->offset) >> sel->src) & sel->msk; + p_sel = (mmio_read_32(rcc_base + sel->offset) & sel->msk) >> sel->src; if (p_sel < sel->nb_parent) { return (int)sel->parent[p_sel]; } @@ -1305,7 +1315,11 @@ static void stm32mp1_pll_start(enum stm32mp1_pll_id pll_id) const struct stm32mp1_clk_pll *pll = pll_ref(pll_id); uintptr_t pllxcr = stm32mp_rcc_base() + pll->pllxcr; - mmio_write_32(pllxcr, RCC_PLLNCR_PLLON); + /* Preserve RCC_PLLNCR_SSCG_CTRL value */ + mmio_clrsetbits_32(pllxcr, + RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN | + RCC_PLLNCR_DIVREN, + RCC_PLLNCR_PLLON); } static int stm32mp1_pll_output(enum stm32mp1_pll_id pll_id, uint32_t output) @@ -1434,6 +1448,9 @@ static void stm32mp1_pll_csg(enum stm32mp1_pll_id pll_id, uint32_t *csg) RCC_PLLNCSGR_SSCG_MODE_MASK; mmio_write_32(stm32mp_rcc_base() + pll->pllxcsgr, pllxcsg); + + mmio_setbits_32(stm32mp_rcc_base() + pll->pllxcr, + RCC_PLLNCR_SSCG_CTRL); } static int stm32mp1_set_clksrc(unsigned int clksrc) @@ -1516,9 +1533,6 @@ static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css) } } -#define CNTCVL_OFF 0x008 -#define CNTCVU_OFF 0x00C - static void stm32mp1_stgen_config(void) { uintptr_t stgen; diff --git a/drivers/st/clk/stm32mp1_clkfunc.c b/drivers/st/clk/stm32mp1_clkfunc.c deleted file mode 100644 index 1aa05bf55..000000000 --- a/drivers/st/clk/stm32mp1_clkfunc.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <errno.h> - -#include <libfdt.h> - -#include <platform_def.h> - -#include <drivers/st/stm32_gpio.h> -#include <drivers/st/stm32mp_clkfunc.h> -#include <drivers/st/stm32mp1_clk.h> -#include <drivers/st/stm32mp1_clkfunc.h> -#include <dt-bindings/clock/stm32mp1-clksrc.h> - -const char *stm32mp_osc_node_label[NB_OSC] = { - [_LSI] = "clk-lsi", - [_LSE] = "clk-lse", - [_HSI] = "clk-hsi", - [_HSE] = "clk-hse", - [_CSI] = "clk-csi", - [_I2S_CKIN] = "i2s_ckin", -}; - -/* - * Get the frequency of an oscillator from its name in device tree. - * @param name: oscillator name - * @param freq: stores the frequency of the oscillator - * @return: 0 on success, and a negative FDT/ERRNO error code on failure. - */ -int fdt_osc_read_freq(const char *name, uint32_t *freq) -{ - int node, subnode; - void *fdt; - - if (fdt_get_address(&fdt) == 0) { - return -ENOENT; - } - - node = fdt_path_offset(fdt, "/clocks"); - if (node < 0) { - return -FDT_ERR_NOTFOUND; - } - - fdt_for_each_subnode(subnode, fdt, node) { - const char *cchar; - int ret; - - cchar = fdt_get_name(fdt, subnode, &ret); - if (cchar == NULL) { - return ret; - } - - if (strncmp(cchar, name, (size_t)ret) == 0) { - const fdt32_t *cuint; - - cuint = fdt_getprop(fdt, subnode, "clock-frequency", - &ret); - if (cuint == NULL) { - return ret; - } - - *freq = fdt32_to_cpu(*cuint); - - return 0; - } - } - - /* Oscillator not found, freq=0 */ - *freq = 0; - return 0; -} - -/* - * Check the presence of an oscillator property from its id. - * @param osc_id: oscillator ID - * @param prop_name: property name - * @return: true/false regarding search result. - */ -bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name) -{ - int node, subnode; - void *fdt; - - if (fdt_get_address(&fdt) == 0) { - return false; - } - - if (osc_id >= NB_OSC) { - return false; - } - - node = fdt_path_offset(fdt, "/clocks"); - if (node < 0) { - return false; - } - - fdt_for_each_subnode(subnode, fdt, node) { - const char *cchar; - int ret; - - cchar = fdt_get_name(fdt, subnode, &ret); - if (cchar == NULL) { - return false; - } - - if (strncmp(cchar, stm32mp_osc_node_label[osc_id], - (size_t)ret) != 0) { - continue; - } - - if (fdt_getprop(fdt, subnode, prop_name, NULL) != NULL) { - return true; - } - } - - return false; -} - -/* - * Get the value of a oscillator property from its ID. - * @param osc_id: oscillator ID - * @param prop_name: property name - * @param dflt_value: default value - * @return oscillator value on success, default value if property not found. - */ -uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, - const char *prop_name, uint32_t dflt_value) -{ - int node, subnode; - void *fdt; - - if (fdt_get_address(&fdt) == 0) { - return dflt_value; - } - - if (osc_id >= NB_OSC) { - return dflt_value; - } - - node = fdt_path_offset(fdt, "/clocks"); - if (node < 0) { - return dflt_value; - } - - fdt_for_each_subnode(subnode, fdt, node) { - const char *cchar; - int ret; - - cchar = fdt_get_name(fdt, subnode, &ret); - if (cchar == NULL) { - return dflt_value; - } - - if (strncmp(cchar, stm32mp_osc_node_label[osc_id], - (size_t)ret) != 0) { - continue; - } - - return fdt_read_uint32_default(subnode, prop_name, dflt_value); - } - - return dflt_value; -} diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c index 16acef07b..87c8e2b84 100644 --- a/drivers/st/clk/stm32mp_clkfunc.c +++ b/drivers/st/clk/stm32mp_clkfunc.c @@ -16,6 +16,147 @@ #define DT_STGEN_COMPAT "st,stm32-stgen" /* + * Get the frequency of an oscillator from its name in device tree. + * @param name: oscillator name + * @param freq: stores the frequency of the oscillator + * @return: 0 on success, and a negative FDT/ERRNO error code on failure. + */ +int fdt_osc_read_freq(const char *name, uint32_t *freq) +{ + int node, subnode; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return -ENOENT; + } + + node = fdt_path_offset(fdt, "/clocks"); + if (node < 0) { + return -FDT_ERR_NOTFOUND; + } + + fdt_for_each_subnode(subnode, fdt, node) { + const char *cchar; + int ret; + + cchar = fdt_get_name(fdt, subnode, &ret); + if (cchar == NULL) { + return ret; + } + + if (strncmp(cchar, name, (size_t)ret) == 0) { + const fdt32_t *cuint; + + cuint = fdt_getprop(fdt, subnode, "clock-frequency", + &ret); + if (cuint == NULL) { + return ret; + } + + *freq = fdt32_to_cpu(*cuint); + + return 0; + } + } + + /* Oscillator not found, freq=0 */ + *freq = 0; + return 0; +} + +/* + * Check the presence of an oscillator property from its id. + * @param osc_id: oscillator ID + * @param prop_name: property name + * @return: true/false regarding search result. + */ +bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name) +{ + int node, subnode; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return false; + } + + if (osc_id >= NB_OSC) { + return false; + } + + node = fdt_path_offset(fdt, "/clocks"); + if (node < 0) { + return false; + } + + fdt_for_each_subnode(subnode, fdt, node) { + const char *cchar; + int ret; + + cchar = fdt_get_name(fdt, subnode, &ret); + if (cchar == NULL) { + return false; + } + + if (strncmp(cchar, stm32mp_osc_node_label[osc_id], + (size_t)ret) != 0) { + continue; + } + + if (fdt_getprop(fdt, subnode, prop_name, NULL) != NULL) { + return true; + } + } + + return false; +} + +/* + * Get the value of a oscillator property from its ID. + * @param osc_id: oscillator ID + * @param prop_name: property name + * @param dflt_value: default value + * @return oscillator value on success, default value if property not found. + */ +uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, + const char *prop_name, uint32_t dflt_value) +{ + int node, subnode; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return dflt_value; + } + + if (osc_id >= NB_OSC) { + return dflt_value; + } + + node = fdt_path_offset(fdt, "/clocks"); + if (node < 0) { + return dflt_value; + } + + fdt_for_each_subnode(subnode, fdt, node) { + const char *cchar; + int ret; + + cchar = fdt_get_name(fdt, subnode, &ret); + if (cchar == NULL) { + return dflt_value; + } + + if (strncmp(cchar, stm32mp_osc_node_label[osc_id], + (size_t)ret) != 0) { + continue; + } + + return fdt_read_uint32_default(subnode, prop_name, dflt_value); + } + + return dflt_value; +} + +/* * Get the RCC node offset from the device tree * @param fdt: Device tree reference * @return: Node offset or a negative value on error |