aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohn Tsichritzis <john.tsichritzis@arm.com>2019-06-19 15:06:00 +0000
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2019-06-19 15:06:00 +0000
commitfc3c382f2ccb910554d0608a7db67c3fbefca4f7 (patch)
tree78ef472e449b85595f5c1ca61771b4d86bd8c77b /drivers
parentde3ad4f0963cdf5206a9736185d23514cfb45111 (diff)
parentf237822f0b003dc5bec54d8c4ee961597a11116c (diff)
downloadplatform_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.c86
-rw-r--r--drivers/st/clk/stm32mp1_clkfunc.c167
-rw-r--r--drivers/st/clk/stm32mp_clkfunc.c141
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