Merge changes from topic "st_clock_updates" into integration
* changes:
fix(st-clock): correct types in error messages
refactor(st-clock): directly use oscillator name
feat(st-clock): check HSE configuration in serial boot
feat(st-clock): manage disabled oscillator
refactor(st-clock): improve DT parsing for PLL nodes
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index 684ab1a..3227f1c 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@@ -9,10 +9,6 @@
#include <stdint.h>
#include <stdio.h>
-#include <libfdt.h>
-
-#include <platform_def.h>
-
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
@@ -27,8 +23,11 @@
#include <lib/mmio.h>
#include <lib/spinlock.h>
#include <lib/utils_def.h>
+#include <libfdt.h>
#include <plat/common/platform.h>
+#include <platform_def.h>
+
#define MAX_HSI_HZ 64000000
#define USB_PHY_48_MHZ 48000000
@@ -699,7 +698,7 @@
}
}
- ERROR("%s: clk id %d not found\n", __func__, (uint32_t)id);
+ ERROR("%s: clk id %lu not found\n", __func__, id);
return -EINVAL;
}
@@ -1114,7 +1113,7 @@
i = stm32mp1_clk_get_gated_id(id);
if (i < 0) {
- ERROR("Clock %d can't be enabled\n", (uint32_t)id);
+ ERROR("Clock %lu can't be enabled\n", id);
panic();
}
@@ -1142,7 +1141,7 @@
i = stm32mp1_clk_get_gated_id(id);
if (i < 0) {
- ERROR("Clock %d can't be disabled\n", (uint32_t)id);
+ ERROR("Clock %lu can't be disabled\n", id);
panic();
}
@@ -1351,6 +1350,13 @@
if (css) {
mmio_write_32(rcc_base + RCC_OCENSETR, RCC_OCENR_HSECSSON);
}
+
+#if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
+ if ((mmio_read_32(rcc_base + RCC_OCENSETR) & RCC_OCENR_HSEBYP) &&
+ (!(digbyp || bypass))) {
+ panic();
+ }
+#endif
}
static void stm32mp1_csi_set(bool enable)
@@ -1772,15 +1778,50 @@
mmio_clrsetbits_32(address, mask, value);
}
+static int clk_get_pll_settings_from_dt(int plloff, unsigned int *pllcfg,
+ uint32_t *fracv, uint32_t *csg,
+ bool *csg_set)
+{
+ void *fdt;
+ int ret;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ ret = fdt_read_uint32_array(fdt, plloff, "cfg", (uint32_t)PLLCFG_NB,
+ pllcfg);
+ if (ret < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ *fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0);
+
+ ret = fdt_read_uint32_array(fdt, plloff, "csg", (uint32_t)PLLCSG_NB,
+ csg);
+
+ *csg_set = (ret == 0);
+
+ if (ret == -FDT_ERR_NOTFOUND) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
int stm32mp1_clk_init(void)
{
uintptr_t rcc_base = stm32mp_rcc_base();
+ uint32_t pllfracv[_PLL_NB];
+ uint32_t pllcsg[_PLL_NB][PLLCSG_NB];
unsigned int clksrc[CLKSRC_NB];
unsigned int clkdiv[CLKDIV_NB];
unsigned int pllcfg[_PLL_NB][PLLCFG_NB];
int plloff[_PLL_NB];
int ret, len;
enum stm32mp1_pll_id i;
+ bool pllcsg_set[_PLL_NB];
+ bool pllcfg_valid[_PLL_NB];
bool lse_css = false;
bool pll3_preserve = false;
bool pll4_preserve = false;
@@ -1817,14 +1858,16 @@
snprintf(name, sizeof(name), "st,pll@%d", i);
plloff[i] = fdt_rcc_subnode_offset(name);
- if (!fdt_check_node(plloff[i])) {
+ pllcfg_valid[i] = fdt_check_node(plloff[i]);
+ if (!pllcfg_valid[i]) {
continue;
}
- ret = fdt_read_uint32_array(fdt, plloff[i], "cfg",
- (int)PLLCFG_NB, pllcfg[i]);
- if (ret < 0) {
- return -FDT_ERR_NOTFOUND;
+ ret = clk_get_pll_settings_from_dt(plloff[i], pllcfg[i],
+ &pllfracv[i], pllcsg[i],
+ &pllcsg_set[i]);
+ if (ret != 0) {
+ return ret;
}
}
@@ -1839,22 +1882,24 @@
stm32mp1_lsi_set(true);
}
if (stm32mp1_osc[_LSE] != 0U) {
+ const char *name = stm32mp_osc_node_label[_LSE];
bool bypass, digbyp;
uint32_t lsedrv;
- bypass = fdt_osc_read_bool(_LSE, "st,bypass");
- digbyp = fdt_osc_read_bool(_LSE, "st,digbypass");
- lse_css = fdt_osc_read_bool(_LSE, "st,css");
- lsedrv = fdt_osc_read_uint32_default(_LSE, "st,drive",
+ bypass = fdt_clk_read_bool(name, "st,bypass");
+ digbyp = fdt_clk_read_bool(name, "st,digbypass");
+ lse_css = fdt_clk_read_bool(name, "st,css");
+ lsedrv = fdt_clk_read_uint32_default(name, "st,drive",
LSEDRV_MEDIUM_HIGH);
stm32mp1_lse_enable(bypass, digbyp, lsedrv);
}
if (stm32mp1_osc[_HSE] != 0U) {
+ const char *name = stm32mp_osc_node_label[_HSE];
bool bypass, digbyp, css;
- bypass = fdt_osc_read_bool(_HSE, "st,bypass");
- digbyp = fdt_osc_read_bool(_HSE, "st,digbypass");
- css = fdt_osc_read_bool(_HSE, "st,css");
+ bypass = fdt_clk_read_bool(name, "st,bypass");
+ digbyp = fdt_clk_read_bool(name, "st,digbypass");
+ css = fdt_clk_read_bool(name, "st,css");
stm32mp1_hse_enable(bypass, digbyp, css);
}
/*
@@ -1976,15 +2021,12 @@
/* Configure and start PLLs */
for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
- uint32_t fracv;
- uint32_t csg[PLLCSG_NB];
-
if (((i == _PLL3) && pll3_preserve) ||
((i == _PLL4) && pll4_preserve && !pll4_bootrom)) {
continue;
}
- if (!fdt_check_node(plloff[i])) {
+ if (!pllcfg_valid[i]) {
continue;
}
@@ -1994,25 +2036,20 @@
continue;
}
- fracv = fdt_read_uint32_default(fdt, plloff[i], "frac", 0);
-
- ret = stm32mp1_pll_config(i, pllcfg[i], fracv);
+ ret = stm32mp1_pll_config(i, pllcfg[i], pllfracv[i]);
if (ret != 0) {
return ret;
}
- ret = fdt_read_uint32_array(fdt, plloff[i], "csg",
- (uint32_t)PLLCSG_NB, csg);
- if (ret == 0) {
- stm32mp1_pll_csg(i, csg);
- } else if (ret != -FDT_ERR_NOTFOUND) {
- return ret;
+
+ if (pllcsg_set[i]) {
+ stm32mp1_pll_csg(i, pllcsg[i]);
}
stm32mp1_pll_start(i);
}
/* Wait and start PLLs ouptut when ready */
for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
- if (!fdt_check_node(plloff[i])) {
+ if (!pllcfg_valid[i]) {
continue;
}
diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c
index c83b8ad..5ba64fd 100644
--- a/drivers/st/clk/stm32mp_clkfunc.c
+++ b/drivers/st/clk/stm32mp_clkfunc.c
@@ -1,19 +1,18 @@
/*
- * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
-#include <libfdt.h>
-
-#include <platform_def.h>
-
#include <common/fdt_wrappers.h>
#include <drivers/clk.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp_clkfunc.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
#define DT_UART_COMPAT "st,stm32h7-uart"
/*
@@ -45,7 +44,8 @@
return ret;
}
- if (strncmp(cchar, name, (size_t)ret) == 0) {
+ if ((strncmp(cchar, name, (size_t)ret) == 0) &&
+ (fdt_get_status(subnode) != DT_DISABLED)) {
const fdt32_t *cuint;
cuint = fdt_getprop(fdt, subnode, "clock-frequency",
@@ -67,11 +67,11 @@
/*
* Check the presence of an oscillator property from its id.
- * @param osc_id: oscillator ID
+ * @param node_label: clock node name
* @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)
+bool fdt_clk_read_bool(const char *node_label, const char *prop_name)
{
int node, subnode;
void *fdt;
@@ -80,10 +80,6 @@
return false;
}
- if (osc_id >= NB_OSC) {
- return false;
- }
-
node = fdt_path_offset(fdt, "/clocks");
if (node < 0) {
return false;
@@ -98,8 +94,7 @@
return false;
}
- if (strncmp(cchar, stm32mp_osc_node_label[osc_id],
- (size_t)ret) != 0) {
+ if (strncmp(cchar, node_label, (size_t)ret) != 0) {
continue;
}
@@ -112,13 +107,13 @@
}
/*
- * Get the value of a oscillator property from its ID.
- * @param osc_id: oscillator ID
+ * Get the value of a oscillator property from its name.
+ * @param node_label: oscillator name
* @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,
+uint32_t fdt_clk_read_uint32_default(const char *node_label,
const char *prop_name, uint32_t dflt_value)
{
int node, subnode;
@@ -128,10 +123,6 @@
return dflt_value;
}
- if (osc_id >= NB_OSC) {
- return dflt_value;
- }
-
node = fdt_path_offset(fdt, "/clocks");
if (node < 0) {
return dflt_value;
@@ -146,8 +137,7 @@
return dflt_value;
}
- if (strncmp(cchar, stm32mp_osc_node_label[osc_id],
- (size_t)ret) != 0) {
+ if (strncmp(cchar, node_label, (size_t)ret) != 0) {
continue;
}
diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h
index a282035..4876213 100644
--- a/include/drivers/st/stm32mp_clkfunc.h
+++ b/include/drivers/st/stm32mp_clkfunc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,8 +14,8 @@
#include <platform_def.h>
int fdt_osc_read_freq(const char *name, uint32_t *freq);
-bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name);
-uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
+bool fdt_clk_read_bool(const char *node_label, const char *prop_name);
+uint32_t fdt_clk_read_uint32_default(const char *node_label,
const char *prop_name,
uint32_t dflt_value);