diff --git a/recipes-bsp/u-boot/u-boot-stm32mp-common_2021.10.inc b/recipes-bsp/u-boot/u-boot-stm32mp-common_2021.10.inc index b1eada2..1b6cd0d 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp-common_2021.10.inc +++ b/recipes-bsp/u-boot/u-boot-stm32mp-common_2021.10.inc @@ -25,6 +25,7 @@ SRC_URI += "\ file://0007-ARM-v2021.10-stm32mp-r2-BOARD.patch \ file://0008-ARM-v2021.10-stm32mp-r2-MISC-DRIVERS.patch \ file://0009-ARM-v2021.10-stm32mp-r2-DEVICETREE.patch \ + file://0010-ARM-v2021.10-stm32mp-r2.1.patch \ \ file://0099-Add-external-var-to-allow-build-of-new-devicetree-fi.patch \ " @@ -34,7 +35,7 @@ SRC_URI += "${@bb.utils.contains('ST_UBOOT_DEBUG_TRACE', '1', '', 'file://0098-s U_BOOT_VERSION = "v2021.10" U_BOOT_SUBVERSION = "stm32mp" -U_BOOT_RELEASE = "r2" +U_BOOT_RELEASE = "r2.1" PV = "${U_BOOT_VERSION}-${U_BOOT_SUBVERSION}-${U_BOOT_RELEASE}" @@ -51,7 +52,7 @@ S = "${WORKDIR}/git" BBCLASSEXTEND = "devupstream:target" SRC_URI:class-devupstream = "git://github.com/STMicroelectronics/u-boot.git;protocol=https;branch=${ARCHIVER_ST_BRANCH}" -SRCREV:class-devupstream = "3984366f6997c680b8c6ccc82d50e77a6e1cccf2" +SRCREV:class-devupstream = "d1bbf3f7edb786fe854034810355e750b08a9851" # --------------------------------- # Configure default preference to manage dynamic selection between tarball and github diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2021.10-stm32mp-r2.1.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2021.10-stm32mp-r2.1.patch new file mode 100644 index 0000000..892ac60 --- /dev/null +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0010-ARM-v2021.10-stm32mp-r2.1.patch @@ -0,0 +1,1377 @@ +From 5e602bf86a44299f1928674bec9e0348d92de2f4 Mon Sep 17 00:00:00 2001 +From: Lionel VITTE +Date: Mon, 3 Jul 2023 10:48:13 +0200 +Subject: [PATCH] ARM v2021.10-stm32mp-r2.1-rc1 + +--- + Makefile | 2 +- + arch/arm/dts/stm32mp151.dtsi | 4 +- + .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 9 +- + cmd/pxe_utils.c | 9 +- + configs/stm32mp13_defconfig | 2 +- + configs/stm32mp15_defconfig | 2 +- + drivers/clk/clk-stm32-core.c | 315 ++++++------------ + drivers/clk/clk-stm32-core.h | 294 +++++++++++----- + drivers/clk/clk-stm32mp13.c | 119 ++++--- + drivers/clk/clk.c | 65 ++++ + drivers/core/device.c | 4 +- + drivers/dfu/dfu_mtd.c | 32 +- + include/configs/stm32mp13_st_common.h | 2 +- + include/configs/stm32mp15_st_common.h | 2 +- + include/dt-bindings/gpio/gpio.h | 3 + + include/linux/clk-provider.h | 8 + + 16 files changed, 488 insertions(+), 384 deletions(-) + +diff --git a/Makefile b/Makefile +index 9e47e7b097..33c0b433bb 100644 +--- a/Makefile ++++ b/Makefile +@@ -3,7 +3,7 @@ + VERSION = 2021 + PATCHLEVEL = 10 + SUBLEVEL = +-EXTRAVERSION = -stm32mp-r2 ++EXTRAVERSION = -stm32mp-r2.1 + NAME = + + # *DOCUMENTATION* +diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi +index 4a7d413d16..e7e081f781 100644 +--- a/arch/arm/dts/stm32mp151.dtsi ++++ b/arch/arm/dts/stm32mp151.dtsi +@@ -1197,8 +1197,8 @@ + usbotg_hs: usb-otg@49000000 { + compatible = "st,stm32mp15-hsotg", "snps,dwc2"; + reg = <0x49000000 0x10000>; +- clocks = <&rcc USBO_K>; +- clock-names = "otg"; ++ clocks = <&rcc USBO_K>, <&usbphyc>; ++ clock-names = "otg", "utmi"; + resets = <&rcc USBO_R>; + reset-names = "dwc2"; + interrupts-extended = <&exti 44 IRQ_TYPE_LEVEL_HIGH>; +diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +index f9b502c937..eef002dbe4 100644 +--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c ++++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +@@ -1440,8 +1440,11 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, + + if (!data->otp_part) { + data->otp_part = memalign(CONFIG_SYS_CACHELINE_SIZE, otp_size); +- if (!data->otp_part) ++ if (!data->otp_part) { ++ stm32prog_err("OTP write issue %d", -ENOMEM); ++ + return -ENOMEM; ++ } + } + + if (!offset) +@@ -1504,6 +1507,8 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, + memcpy(buffer, (void *)((u32)data->otp_part + offset), *size); + + end_otp_read: ++ if (result) ++ stm32prog_err("OTP read issue %d", result); + log_debug("%s: result %i\n", __func__, result); + + return result; +@@ -1557,6 +1562,8 @@ int stm32prog_otp_start(struct stm32prog_data *data) + + free(data->otp_part); + data->otp_part = NULL; ++ if (result) ++ stm32prog_err("OTP write issue %d", result); + log_debug("%s: result %i\n", __func__, result); + + return result; +diff --git a/cmd/pxe_utils.c b/cmd/pxe_utils.c +index 45334fc3c7..93e1d91458 100644 +--- a/cmd/pxe_utils.c ++++ b/cmd/pxe_utils.c +@@ -569,7 +569,7 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label) + * bootm, and adjust argc appropriately. + * + * Scenario 3: If there is an fdtcontroladdr specified, pass it along to +- * bootm, and adjust argc appropriately. ++ * bootm, and adjust argc appropriately, unless the image type is fitImage. + * + * Scenario 4: fdt blob is not available. + */ +@@ -663,7 +663,10 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label) + if (!bootm_argv[3]) + bootm_argv[3] = env_get("fdt_addr"); + +- if (!bootm_argv[3]) ++ kernel_addr = genimg_get_kernel_addr(bootm_argv[1]); ++ buf = map_sysmem(kernel_addr, 0); ++ ++ if (!bootm_argv[3] && genimg_get_format(buf) != IMAGE_FORMAT_FIT) + bootm_argv[3] = env_get("fdtcontroladdr"); + + if (bootm_argv[3]) { +@@ -672,8 +675,6 @@ static int label_boot(struct cmd_tbl *cmdtp, struct pxe_label *label) + bootm_argc = 4; + } + +- kernel_addr = genimg_get_kernel_addr(bootm_argv[1]); +- buf = map_sysmem(kernel_addr, 0); + /* Try bootm for legacy and FIT format image */ + if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID) + do_bootm(cmdtp, 0, bootm_argc, bootm_argv); +diff --git a/configs/stm32mp13_defconfig b/configs/stm32mp13_defconfig +index 2429c3f411..c551b8a0e0 100644 +--- a/configs/stm32mp13_defconfig ++++ b/configs/stm32mp13_defconfig +@@ -8,7 +8,7 @@ CONFIG_ENV_OFFSET=0x900000 + CONFIG_ENV_SECT_SIZE=0x40000 + CONFIG_DEFAULT_DEVICE_TREE="stm32mp135f-dk" + CONFIG_STM32MP13x=y +-CONFIG_DDR_CACHEABLE_SIZE=0x10000000 ++CONFIG_DDR_CACHEABLE_SIZE=0x8000000 + CONFIG_CMD_STM32KEY=y + CONFIG_TARGET_ST_STM32MP13x=y + CONFIG_ENV_OFFSET_REDUND=0x940000 +diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig +index b4b2954273..439505c3c7 100644 +--- a/configs/stm32mp15_defconfig ++++ b/configs/stm32mp15_defconfig +@@ -7,7 +7,7 @@ CONFIG_SYS_MEMTEST_END=0xc4000000 + CONFIG_ENV_OFFSET=0x900000 + CONFIG_ENV_SECT_SIZE=0x40000 + CONFIG_DEFAULT_DEVICE_TREE="stm32mp157c-ev1" +-CONFIG_DDR_CACHEABLE_SIZE=0x10000000 ++CONFIG_DDR_CACHEABLE_SIZE=0x8000000 + CONFIG_CMD_STM32KEY=y + CONFIG_TARGET_ST_STM32MP15x=y + CONFIG_ENV_OFFSET_REDUND=0x940000 +diff --git a/drivers/clk/clk-stm32-core.c b/drivers/clk/clk-stm32-core.c +index 22671a0abc..37e996e78f 100644 +--- a/drivers/clk/clk-stm32-core.c ++++ b/drivers/clk/clk-stm32-core.c +@@ -1,7 +1,7 @@ +-// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause + /* +- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved +- * Author: Gabriel Fernandez for STMicroelectronics. ++ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved ++ * Author: Gabriel Fernandez for STMicroelectronics. + */ + + #define LOG_CATEGORY UCLASS_CLK +@@ -11,157 +11,84 @@ + #include + #include + #include ++#include + #include + #include "clk-stm32-core.h" + +-int stm32_rcc_init(struct device *dev, +- const struct stm32_clock_match_data *data, +- void __iomem *base) ++int stm32_rcc_init(struct udevice *dev, ++ const struct stm32_clock_match_data *data) + { + int i; ++ u8 *cpt; ++ struct stm32mp_rcc_priv *priv = dev_get_priv(dev); ++ fdt_addr_t base = dev_read_addr(dev->parent); ++ const struct clk_stm32_clock_data *clock_data = data->clock_data; + +- for (i = 0; i < data->num_clocks; i++) { +- const struct clock_config *cfg = &data->tab_clocks[i]; +- struct clk *clk = ERR_PTR(-ENOENT); +- +- if (data->check_security) { +- if ((*data->check_security)(base, cfg)) +- continue; +- } +- +- if (cfg->func) +- clk = (*cfg->func)(NULL, data, base, NULL, cfg); +- +- if (IS_ERR(clk)) { +- log_err("%s: failed to register clock %s\n", __func__, +- cfg->name); +- +- return PTR_ERR(clk); +- } +- +- clk->id = cfg->id; +- } +- +- return 0; +-} +- +-static const struct clk_ops *clk_dev_ops(struct udevice *dev) +-{ +- return (const struct clk_ops *)dev->driver->ops; +-} +- +-static int stm32_clk_enable(struct clk *clk) +-{ +- const struct clk_ops *ops; +- struct clk *clkp = NULL; +- +- if (!clk->id || clk_get_by_id(clk->id, &clkp)) +- return -ENOENT; +- +- ops = clk_dev_ops(clkp->dev); +- if (!ops->enable) +- return 0; +- +- return ops->enable(clkp); +-} +- +-static int stm32_clk_disable(struct clk *clk) +-{ +- const struct clk_ops *ops; +- struct clk *clkp = NULL; ++ if (base == FDT_ADDR_T_NONE) ++ return -EINVAL; + +- if (!clk->id || clk_get_by_id(clk->id, &clkp)) +- return -ENOENT; ++ priv->base = (void __iomem *)base; + +- ops = clk_dev_ops(clkp->dev); +- if (!ops->disable) +- return 0; ++ /* allocate the counter of user for internal RCC gates, common for several user */ ++ cpt = kzalloc(clock_data->num_gates, GFP_KERNEL); ++ if (!cpt) ++ return -ENOMEM; + +- return ops->disable(clkp); +-} +- +-static ulong stm32_clk_get_rate(struct clk *clk) +-{ +- const struct clk_ops *ops; +- struct clk *clkp = NULL; +- +- if (!clk->id || clk_get_by_id(clk->id, &clkp)) +- return -ENOENT; ++ priv->gate_cpt = cpt; + +- ops = clk_dev_ops(clkp->dev); +- if (!ops->get_rate) +- return -ENOSYS; ++ priv->data = clock_data; + +- return ops->get_rate(clkp); +-} +- +-ulong stm32_clk_set_rate(struct clk *clk, unsigned long clk_rate) +-{ +- const struct clk_ops *ops; +- struct clk *clkp = NULL; +- +- if (!clk->id || clk_get_by_id(clk->id, &clkp)) +- return -ENOENT; +- +- ops = clk_dev_ops(clkp->dev); +- if (!ops->set_rate) +- return -ENOSYS; +- +- return ops->set_rate(clkp, clk_rate); +-} +- +-int clk_stm32_get_by_name(const char *name, struct clk **clkp) +-{ +- struct udevice *dev; +- struct uclass *uc; +- int ret; +- +- ret = uclass_get(UCLASS_CLK, &uc); +- if (ret) +- return ret; ++ for (i = 0; i < data->num_clocks; i++) { ++ const struct clock_config *cfg = &data->tab_clocks[i]; ++ struct clk *clk = ERR_PTR(-ENOENT); + +- uclass_foreach_dev(dev, uc) { +- if (!strcmp(name, dev->name)) { +- struct clk *clk = dev_get_clk_ptr(dev); ++ if (data->check_security && data->check_security(priv->base, cfg)) ++ continue; + +- if (clk) { +- *clkp = clk; +- return 0; +- } +- break; ++ if (cfg->setup) { ++ clk = cfg->setup(dev, cfg); ++ clk->id = cfg->id; ++ } else { ++ dev_err(dev, "failed to register clock %s\n", cfg->name); ++ return -ENOENT; + } + } + +- return -ENOENT; ++ return 0; + } + + ulong clk_stm32_get_rate_by_name(const char *name) + { +- struct clk *clk; ++ struct udevice *dev; ++ ++ if (!uclass_get_device_by_name(UCLASS_CLK, name, &dev)) { ++ struct clk *clk = dev_get_clk_ptr(dev); + +- if (!clk_stm32_get_by_name(name, &clk)) + return clk_get_rate(clk); ++ } + + return 0; + } + + const struct clk_ops stm32_clk_ops = { +- .enable = stm32_clk_enable, +- .disable = stm32_clk_disable, +- .get_rate = stm32_clk_get_rate, +- .set_rate = stm32_clk_set_rate, ++ .enable = ccf_clk_enable, ++ .disable = ccf_clk_disable, ++ .get_rate = ccf_clk_get_rate, ++ .set_rate = ccf_clk_set_rate, + }; + + #define RCC_MP_ENCLRR_OFFSET 4 + +-static void clk_stm32_endisable_gate(const struct stm32_gate_cfg *gate_cfg, +- void __iomem *base, u8 *cpt, int enable) ++static void clk_stm32_gate_set_state(void __iomem *base, ++ const struct clk_stm32_clock_data *data, ++ u8 *cpt, u16 gate_id, int enable) + { ++ const struct stm32_gate_cfg *gate_cfg = &data->gates[gate_id]; + void __iomem *addr = base + gate_cfg->reg_off; + u8 set_clr = gate_cfg->set_clr ? RCC_MP_ENCLRR_OFFSET : 0; + + if (enable) { +- if (*cpt++ > 0) ++ if (cpt[gate_id]++ > 0) + return; + + if (set_clr) +@@ -169,7 +96,7 @@ static void clk_stm32_endisable_gate(const struct stm32_gate_cfg *gate_cfg, + else + writel(readl(addr) | BIT(gate_cfg->bit_idx), addr); + } else { +- if (--*cpt > 0) ++ if (--cpt[gate_id] > 0) + return; + + if (set_clr) +@@ -179,24 +106,24 @@ static void clk_stm32_endisable_gate(const struct stm32_gate_cfg *gate_cfg, + } + } + +-static void clk_stm32_gate_endisable(struct clk *clk, int enable) ++static int clk_stm32_gate_enable(struct clk *clk) + { + struct clk_stm32_gate *stm32_gate = to_clk_stm32_gate(clk); ++ struct stm32mp_rcc_priv *priv = stm32_gate->priv; + +- clk_stm32_endisable_gate(stm32_gate->gate, stm32_gate->base, +- &stm32_gate->cpt, enable); +-} +- +-static int clk_stm32_gate_enable(struct clk *clk) +-{ +- clk_stm32_gate_endisable(clk, 1); ++ clk_stm32_gate_set_state(priv->base, priv->data, priv->gate_cpt, ++ stm32_gate->gate_id, 1); + + return 0; + } + + static int clk_stm32_gate_disable(struct clk *clk) + { +- clk_stm32_gate_endisable(clk, 0); ++ struct clk_stm32_gate *stm32_gate = to_clk_stm32_gate(clk); ++ struct stm32mp_rcc_priv *priv = stm32_gate->priv; ++ ++ clk_stm32_gate_set_state(priv->base, priv->data, priv->gate_cpt, ++ stm32_gate->gate_id, 0); + + return 0; + } +@@ -215,14 +142,11 @@ U_BOOT_DRIVER(clk_stm32_gate) = { + .ops = &clk_stm32_gate_ops, + }; + +-struct clk *clk_stm32_gate_register(struct device *dev, +- const char *name, +- const char *parent_name, +- unsigned long flags, +- void __iomem *base, +- const struct stm32_gate_cfg *gate_cfg, +- spinlock_t *lock) ++struct clk *clk_stm32_gate_register(struct udevice *dev, ++ const struct clock_config *cfg) + { ++ struct stm32mp_rcc_priv *priv = dev_get_priv(dev); ++ struct stm32_clk_gate_cfg *clk_cfg = cfg->clock_cfg; + struct clk_stm32_gate *stm32_gate; + struct clk *clk; + int ret; +@@ -231,13 +155,14 @@ struct clk *clk_stm32_gate_register(struct device *dev, + if (!stm32_gate) + return ERR_PTR(-ENOMEM); + +- stm32_gate->base = base; +- stm32_gate->gate = gate_cfg; ++ stm32_gate->priv = priv; ++ stm32_gate->gate_id = clk_cfg->gate_id; + + clk = &stm32_gate->clk; +- clk->flags = flags; ++ clk->flags = cfg->flags; + +- ret = clk_register(clk, UBOOT_DM_CLK_STM32_GATE, name, parent_name); ++ ret = clk_register(clk, UBOOT_DM_CLK_STM32_GATE, ++ cfg->name, cfg->parent_name); + if (ret) { + kfree(stm32_gate); + return ERR_PTR(ret); +@@ -246,15 +171,13 @@ struct clk *clk_stm32_gate_register(struct device *dev, + return clk; + } + +-struct clk *clk_stm32_register_composite(const char *name, +- const char * const *parent_names, +- int num_parents, +- unsigned long flags, +- void __iomem *base, +- const struct stm32_mux_cfg *mcfg, +- const struct stm32_div_cfg *dcfg, +- const struct stm32_gate_cfg *gcfg) ++struct clk * ++clk_stm32_register_composite(struct udevice *dev, ++ const struct clock_config *cfg) + { ++ struct stm32_clk_composite_cfg *composite = cfg->clock_cfg; ++ const char *const *parent_names; ++ int num_parents; + struct clk *clk = ERR_PTR(-ENOMEM); + struct clk_mux *mux = NULL; + struct clk_stm32_gate *gate = NULL; +@@ -265,57 +188,73 @@ struct clk *clk_stm32_register_composite(const char *name, + const struct clk_ops *gate_ops = NULL; + struct clk *div_clk = NULL; + const struct clk_ops *div_ops = NULL; ++ struct stm32mp_rcc_priv *priv = dev_get_priv(dev); ++ const struct clk_stm32_clock_data *data = priv->data; ++ ++ if (composite->mux_id != NO_STM32_MUX) { ++ const struct stm32_mux_cfg *mux_cfg; + +- if (mcfg) { + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + goto fail; + +- mux->reg = base + mcfg->reg_off; +- mux->shift = mcfg->shift; +- mux->mask = BIT(mcfg->width) - 1; +- mux->num_parents = mcfg->num_parents; ++ mux_cfg = &data->muxes[composite->mux_id]; ++ ++ mux->reg = priv->base + mux_cfg->reg_off; ++ mux->shift = mux_cfg->shift; ++ mux->mask = BIT(mux_cfg->width) - 1; ++ mux->num_parents = mux_cfg->num_parents; + mux->flags = 0; +- mux->parent_names = mcfg->parent_names; ++ mux->parent_names = mux_cfg->parent_names; + + mux_clk = &mux->clk; + mux_ops = &clk_mux_ops; ++ ++ parent_names = mux_cfg->parent_names; ++ num_parents = mux_cfg->num_parents; ++ } else { ++ parent_names = &cfg->parent_name; ++ num_parents = 1; + } + +- if (dcfg) { ++ if (composite->div_id != NO_STM32_DIV) { ++ const struct stm32_div_cfg *div_cfg; ++ + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + goto fail; + +- div->reg = base + dcfg->reg_off; +- div->shift = dcfg->shift; +- div->width = dcfg->width; +- div->width = dcfg->width; +- div->flags = dcfg->div_flags; +- div->table = dcfg->table; ++ div_cfg = &data->dividers[composite->div_id]; ++ ++ div->reg = priv->base + div_cfg->reg_off; ++ div->shift = div_cfg->shift; ++ div->width = div_cfg->width; ++ div->width = div_cfg->width; ++ div->flags = div_cfg->div_flags; ++ div->table = div_cfg->table; + + div_clk = &div->clk; + div_ops = &clk_divider_ops; + } + +- if (gcfg) { ++ if (composite->gate_id != NO_STM32_GATE) { + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + goto fail; + +- gate->base = base; +- gate->gate = gcfg; ++ gate->priv = priv; ++ gate->gate_id = composite->gate_id; + + gate_clk = &gate->clk; + gate_ops = &clk_stm32_gate_ops; + } + +- clk = clk_register_composite(NULL, name, ++ clk = clk_register_composite(NULL, cfg->name, + parent_names, num_parents, + mux_clk, mux_ops, + div_clk, div_ops, + gate_clk, gate_ops, +- flags); ++ cfg->flags); + if (IS_ERR(clk)) + goto fail; + +@@ -327,49 +266,3 @@ fail: + kfree(mux); + return ERR_CAST(clk); + } +- +-struct clk *_clk_stm32_gate_register(struct device *dev, +- const struct stm32_clock_match_data *data, +- void __iomem *base, +- spinlock_t *lock, +- const struct clock_config *cfg) +-{ +- struct stm32_clk_gate_cfg *clk_cfg = cfg->clock_cfg; +- const struct stm32_gate_cfg *gate_cfg = &data->gates[clk_cfg->gate_id]; +- +- return clk_stm32_gate_register(dev, cfg->name, cfg->parent_name, +- cfg->flags, base, gate_cfg, lock); +-} +- +-struct clk * +-_clk_stm32_register_composite(struct device *dev, +- const struct stm32_clock_match_data *data, +- void __iomem *base, spinlock_t *lock, +- const struct clock_config *cfg) +-{ +- struct stm32_clk_composite_cfg *composite = cfg->clock_cfg; +- const struct stm32_mux_cfg *mux_cfg = NULL; +- const struct stm32_gate_cfg *gate_cfg = NULL; +- const struct stm32_div_cfg *div_cfg = NULL; +- const char *const *parent_names; +- int num_parents; +- +- if (composite->mux_id != NO_STM32_MUX) { +- mux_cfg = &data->muxes[composite->mux_id]; +- parent_names = mux_cfg->parent_names; +- num_parents = mux_cfg->num_parents; +- } else { +- parent_names = &cfg->parent_name; +- num_parents = 1; +- } +- +- if (composite->gate_id != NO_STM32_GATE) +- gate_cfg = &data->gates[composite->gate_id]; +- +- if (composite->div_id != NO_STM32_DIV) +- div_cfg = &data->dividers[composite->div_id]; +- +- return clk_stm32_register_composite(cfg->name, parent_names, +- num_parents, cfg->flags, base, +- mux_cfg, div_cfg, gate_cfg); +-} +diff --git a/drivers/clk/clk-stm32-core.h b/drivers/clk/clk-stm32-core.h +index 79ca27fbaa..53c2b467ab 100644 +--- a/drivers/clk/clk-stm32-core.h ++++ b/drivers/clk/clk-stm32-core.h +@@ -1,42 +1,93 @@ +-/* SPDX-License-Identifier: GPL-2.0 */ ++/* SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause */ + /* +- * Copyright (C) STMicroelectronics 2020 - All Rights Reserved +- * Author: Gabriel Fernandez for STMicroelectronics. ++ * Copyright (C) STMicroelectronics 2022 - All Rights Reserved ++ * Author: Gabriel Fernandez for STMicroelectronics. + */ + + struct stm32_clock_match_data; + ++/** ++ * struct stm32_mux_cfg - multiplexer configuration ++ * ++ * @parent_names: array of string names for all possible parents ++ * @num_parents: number of possible parents ++ * @reg_off: register controlling multiplexer ++ * @shift: shift to multiplexer bit field ++ * @width: width of the multiplexer bit field ++ * @mux_flags: hardware-specific flags ++ * @table: array of register values corresponding to the parent ++ * index ++ */ + struct stm32_mux_cfg { + const char * const *parent_names; +- u8 num_parents; +- u32 reg_off; +- u8 shift; +- u8 width; +- u8 mux_flags; +- u32 *table; ++ u8 num_parents; ++ u32 reg_off; ++ u8 shift; ++ u8 width; ++ u8 mux_flags; ++ u32 *table; + }; + ++/** ++ * struct stm32_gate_cfg - gating configuration ++ * ++ * @reg_off: register controlling gate ++ * @bit_idx: single bit controlling gate ++ * @gate_flags: hardware-specific flags ++ * @set_clr: 0 : normal gate, 1 : has a register to clear the gate ++ */ + struct stm32_gate_cfg { +- u32 reg_off; +- u8 bit_idx; +- u8 gate_flags; +- u8 set_clr; ++ u32 reg_off; ++ u8 bit_idx; ++ u8 gate_flags; ++ u8 set_clr; + }; + ++/** ++ * struct stm32_div_cfg - divider configuration ++ * ++ * @reg_off: register containing the divider ++ * @shift: shift to the divider bit field ++ * @width: width of the divider bit field ++ * @table: array of value/divider pairs, last entry should have div = 0 ++ */ + struct stm32_div_cfg { +- u32 reg_off; +- u8 shift; +- u8 width; +- u8 div_flags; ++ u32 reg_off; ++ u8 shift; ++ u8 width; ++ u8 div_flags; + const struct clk_div_table *table; + }; + ++#define NO_STM32_MUX -1 ++#define NO_STM32_DIV -1 ++#define NO_STM32_GATE -1 ++ ++/** ++ * struct stm32_composite_cfg - composite configuration ++ * ++ * @mux: index of a multiplexer ++ * @gate: index of a gate ++ * @div: index of a divider ++ */ + struct stm32_composite_cfg { + int mux; + int gate; + int div; + }; + ++/** ++ * struct clock_config - clock configuration ++ * ++ * @id: binding id of the clock ++ * @name: clock name ++ * @parent_name: name of the clock parent ++ * @flags: framework-specific flags ++ * @sec_id: secure id (use to known if the clock is secured or not) ++ * @clock_cfg: specific clock data configuration ++ * @setup: specific call back to reister the clock (will use ++ * clock_cfg data as input) ++ */ + struct clock_config { + unsigned long id; + const char *name; +@@ -45,71 +96,142 @@ struct clock_config { + int sec_id; + void *clock_cfg; + +- struct clk *(*func)(struct device *dev, +- const struct stm32_clock_match_data *data, +- void __iomem *base, +- spinlock_t *lock, +- const struct clock_config *cfg); ++ struct clk *(*setup)(struct udevice *dev, ++ const struct clock_config *cfg); + }; + +-struct stm32_clock_match_data { +- unsigned int num_clocks; +- const struct clock_config *tab_clocks; +- unsigned int maxbinding; +- const struct stm32_gate_cfg *gates; +- const struct stm32_mux_cfg *muxes; +- const struct stm32_div_cfg *dividers; ++/** ++ * struct clk_stm32_clock_data - clock data ++ * ++ * @num_gates: number of defined gates ++ * @gates: array of gate configuration ++ * @muxes: array of multiplexer configuration ++ * @dividers: array of divider configuration ++ */ ++struct clk_stm32_clock_data { ++ unsigned int num_gates; ++ const struct stm32_gate_cfg *gates; ++ const struct stm32_mux_cfg *muxes; ++ const struct stm32_div_cfg *dividers; ++}; + ++/** ++ * struct stm32_clock_match_data - clock match data ++ * ++ * @num_gates: number of clocks ++ * @tab_clocks: array of clock configuration ++ * @clock_data: definition of all gates / dividers / multiplexers ++ * @check_security: call back to check if clock is secured or not ++ */ ++struct stm32_clock_match_data { ++ unsigned int num_clocks; ++ const struct clock_config *tab_clocks; ++ const struct clk_stm32_clock_data *clock_data; + int (*check_security)(void __iomem *base, + const struct clock_config *cfg); + }; + +-int stm32_rcc_init(struct device *dev, +- const struct stm32_clock_match_data *data, +- void __iomem *base); ++/** ++ * struct stm32mp_rcc_priv - private struct for stm32mp clocks ++ * ++ * @base: base register of RCC driver ++ * @gate_cpt: array of refcounting for gate with more than one ++ * clocks as input. See explanation of Peripheral clock enabling ++ * below. ++ * @data: data for gate / divider / multiplexer configuration ++ */ ++struct stm32mp_rcc_priv { ++ void __iomem *base; ++ u8 *gate_cpt; ++ const struct clk_stm32_clock_data *data; ++}; + +-#define NO_ID 0xFFFF0000 ++int stm32_rcc_init(struct udevice *dev, ++ const struct stm32_clock_match_data *data); + +-#define NO_STM32_MUX -1 +-#define NO_STM32_DIV -1 +-#define NO_STM32_GATE -1 ++/** ++ * STM32 Gate ++ * ++ * PCE (Peripheral Clock Enabling) Peripheral ++ * ++ * ------------------------------ ---------- ++ * | | | | ++ * | | | PERx | ++ * bus_ck | ----- | | | ++ * ------------->|------------------| | | ckg_bus_perx | | ++ * | | AND |-----|---------------->| | ++ * | -----------| | | | | ++ * | | ----- | | | ++ * | | | | | ++ * | ----- | | | ++ * Perx_EN |-----|---| GCL | Gating | | | ++ * | ----- Control | | | ++ * | | Logic | | | ++ * | | | | | ++ * | | ----- | | | ++ * | -----------| | | ckg_ker_perx | | ++ * perx_ker_ck | | AND |-----|---------------->| | ++ * ------------->|------------------| | | | | ++ * | ----- | | | ++ * | | | | ++ * | | | | ++ * ------------------------------ ---------- ++ ++ * Each peripheral requires a bus interface clock, named ckg_bus_perx ++ * (for peripheral ‘x’). ++ * Some peripherals (SAI, UART...) need also a dedicated clock for their ++ * communication interface, this clock is generally asynchronous with respect to ++ * the bus interface clock, and is named kernel clock (ckg_ker_perx). ++ ++ * Both clocks can be gated by one Perx_EN enable bit. ++ * Then we have to manage a refcounting on gate level to avoid gate if one ++ * the bus or the Kernel was enable. ++ * ++ * Example: ++ * 1) enable the bus clock ++ * --> bus_clk ref_counting = 1, gate_ref_count = 1 ++ * 2) enable the kernel clock ++ * --> perx_ker_ck ref_counting = 1, gate_ref_count = 2 ++ * 3) disable kernel clock ++ *  ---> perx_ker_ck ref_counting = 0, gate_ref_count = 1 ++ *  ==> then i will not gate because gate_ref_count > 0 ++ * 4) disable bus clock ++ * --> bus_clk ref_counting = 0, gate_ref_count = 0 ++ * ==> then i can gate (write in the register) because ++ * gate_ref_count = 0 ++ */ + + struct clk_stm32_gate { + struct clk clk; +- void __iomem *base; +- const struct stm32_gate_cfg *gate; +- u8 cpt; ++ struct stm32mp_rcc_priv *priv; ++ int gate_id; + }; + + #define to_clk_stm32_gate(_clk) container_of(_clk, struct clk_stm32_gate, clk) + + struct clk * +-_clk_stm32_gate_register(struct device *dev, +- const struct stm32_clock_match_data *data, +- void __iomem *base, spinlock_t *lock, +- const struct clock_config *cfg); ++clk_stm32_gate_register(struct udevice *dev, ++ const struct clock_config *cfg); + + struct clk * +-_clk_stm32_register_composite(struct device *dev, +- const struct stm32_clock_match_data *data, +- void __iomem *base, spinlock_t *lock, +- const struct clock_config *cfg); ++clk_stm32_register_composite(struct udevice *dev, ++ const struct clock_config *cfg); + + struct stm32_clk_gate_cfg { + int gate_id; + }; + +-#define STM32_GATE(_id, _name, _parent, _flags, _gate_id, _sec_id)\ +-{\ +- .id = _id,\ +- .sec_id = _sec_id,\ +- .name = _name,\ +- .parent_name = _parent,\ +- .flags = _flags,\ +- .clock_cfg = &(struct stm32_clk_gate_cfg) {\ +- .gate_id = _gate_id,\ +- },\ +- .func = _clk_stm32_gate_register,\ ++#define STM32_GATE(_id, _name, _parent, _flags, _gate_id, _sec_id) \ ++{ \ ++ .id = _id, \ ++ .sec_id = _sec_id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .flags = _flags, \ ++ .clock_cfg = &(struct stm32_clk_gate_cfg) { \ ++ .gate_id = _gate_id, \ ++ }, \ ++ .setup = clk_stm32_gate_register, \ + } + + struct stm32_clk_composite_cfg { +@@ -118,39 +240,37 @@ struct stm32_clk_composite_cfg { + int div_id; + }; + +-#define STM32_COMPOSITE(_id, _name, _flags, _sec_id,\ +- _gate_id, _mux_id, _div_id)\ +-{\ +- .id = _id,\ +- .name = _name,\ +- .sec_id = _sec_id,\ +- .flags = _flags,\ +- .clock_cfg = &(struct stm32_clk_composite_cfg) {\ +- .gate_id = _gate_id,\ +- .mux_id = _mux_id,\ +- .div_id = _div_id,\ +- },\ +- .func = _clk_stm32_register_composite,\ ++#define STM32_COMPOSITE(_id, _name, _flags, _sec_id, \ ++ _gate_id, _mux_id, _div_id) \ ++{ \ ++ .id = _id, \ ++ .name = _name, \ ++ .sec_id = _sec_id, \ ++ .flags = _flags, \ ++ .clock_cfg = &(struct stm32_clk_composite_cfg) { \ ++ .gate_id = _gate_id, \ ++ .mux_id = _mux_id, \ ++ .div_id = _div_id, \ ++ }, \ ++ .setup = clk_stm32_register_composite, \ + } + +-#define STM32_COMPOSITE_NOMUX(_id, _name, _parent, _flags, _sec_id,\ +- _gate_id, _div_id)\ +-{\ +- .id = _id,\ +- .name = _name,\ +- .parent_name = _parent,\ +- .sec_id = _sec_id,\ +- .flags = _flags,\ +- .clock_cfg = &(struct stm32_clk_composite_cfg) {\ +- .gate_id = _gate_id,\ +- .mux_id = NO_STM32_MUX,\ +- .div_id = _div_id,\ +- },\ +- .func = _clk_stm32_register_composite,\ ++#define STM32_COMPOSITE_NOMUX(_id, _name, _parent, _flags, _sec_id, \ ++ _gate_id, _div_id) \ ++{ \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .sec_id = _sec_id, \ ++ .flags = _flags, \ ++ .clock_cfg = &(struct stm32_clk_composite_cfg) { \ ++ .gate_id = _gate_id, \ ++ .mux_id = NO_STM32_MUX, \ ++ .div_id = _div_id, \ ++ }, \ ++ .setup = clk_stm32_register_composite, \ + } + + extern const struct clk_ops stm32_clk_ops; + + ulong clk_stm32_get_rate_by_name(const char *name); +-int clk_stm32_get_by_name(const char *name, struct clk **clkp); +- +diff --git a/drivers/clk/clk-stm32mp13.c b/drivers/clk/clk-stm32mp13.c +index bd82200e55..5174ae53a1 100644 +--- a/drivers/clk/clk-stm32mp13.c ++++ b/drivers/clk/clk-stm32mp13.c +@@ -1,7 +1,7 @@ +-// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause ++// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause + /* +- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved +- * Author: Gabriel Fernandez for STMicroelectronics. ++ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved ++ * Author: Gabriel Fernandez for STMicroelectronics. + */ + + #define LOG_CATEGORY UCLASS_CLK +@@ -19,10 +19,6 @@ + + DECLARE_GLOBAL_DATA_PTR; + +-struct stm32mp1_clk_priv { +- fdt_addr_t base; +-}; +- + static const char * const adc12_src[] = { + "pll4_r", "ck_per", "pll3_q" + }; +@@ -176,13 +172,14 @@ enum enum_mux_cfg { + MUX_MCO2 + }; + +-#define MUX_CFG(id, src, _offset, _shift, _witdh)[id] = {\ +- .num_parents = ARRAY_SIZE(src),\ +- .parent_names = src,\ +- .reg_off = (_offset),\ +- .shift = (_shift),\ +- .width = (_witdh),\ +-} ++#define MUX_CFG(id, src, _offset, _shift, _witdh) \ ++ [id] = { \ ++ .num_parents = ARRAY_SIZE(src), \ ++ .parent_names = (src), \ ++ .reg_off = (_offset), \ ++ .shift = (_shift), \ ++ .width = (_witdh), \ ++ } + + static const struct stm32_mux_cfg stm32mp13_muxes[] = { + MUX_CFG(MUX_I2C12, i2c12_src, RCC_I2C12CKSELR, 0, 3), +@@ -344,11 +341,12 @@ enum enum_gate_cfg { + GATE_MDMA + }; + +-#define GATE_CFG(id, _offset, _bit_idx, _offset_clr)[id] = {\ +- .reg_off = (_offset),\ +- .bit_idx = (_bit_idx),\ +- .set_clr = (_offset_clr),\ +-} ++#define GATE_CFG(id, _offset, _bit_idx, _offset_clr) \ ++ [id] = { \ ++ .reg_off = (_offset), \ ++ .bit_idx = (_bit_idx), \ ++ .set_clr = (_offset_clr), \ ++ } + + static const struct stm32_gate_cfg stm32mp13_gates[] = { + GATE_CFG(GATE_MCO1, RCC_MCO1CFGR, 12, 0), +@@ -483,13 +481,14 @@ enum enum_div_cfg { + LAST_DIV + }; + +-#define DIV_CFG(id, _offset, _shift, _width, _flags, _table)[id] = {\ +- .reg_off = _offset,\ +- .shift = _shift,\ +- .width = _width,\ +- .div_flags = _flags,\ +- .table = _table,\ +-} ++#define DIV_CFG(id, _offset, _shift, _width, _flags, _table) \ ++ [id] = { \ ++ .reg_off = _offset, \ ++ .shift = _shift, \ ++ .width = _width, \ ++ .div_flags = _flags, \ ++ .table = _table, \ ++ } + + static const struct stm32_div_cfg stm32mp13_dividers[LAST_DIV] = { + DIV_CFG(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL), +@@ -562,10 +561,11 @@ enum securit_clk { + SECF_MCO2 + }; + +-#define SECF(_sec_id, _offset, _bit_idx)[_sec_id] = {\ +- .offset = _offset,\ +- .bit_idx = _bit_idx,\ +-} ++#define SECF(_sec_id, _offset, _bit_idx) \ ++ [_sec_id] = { \ ++ .offset = _offset, \ ++ .bit_idx = _bit_idx, \ ++ } + + static const struct clk_stm32_securiy stm32mp13_security[] = { + SECF(SECF_LPTIM2, RCC_APB3SECSR, RCC_APB3SECSR_LPTIM2SECF), +@@ -624,15 +624,15 @@ static const struct clk_stm32_securiy stm32mp13_security[] = { + SECF(SECF_MCO2, RCC_SECCFGR, RCC_SECCFGR_MCO2SECF), + }; + +-#define PCLK(_id, _name, _parent, _flags, _gate_id, _sec_id)\ ++#define PCLK(_id, _name, _parent, _flags, _gate_id, _sec_id) \ + STM32_GATE(_id, _name, _parent, _flags, _gate_id, _sec_id) + +-#define TIMER(_id, _name, _parent, _flags, _gate_id, _sec_id)\ +- STM32_GATE(_id, _name, _parent, ((_flags) | CLK_SET_RATE_PARENT),\ ++#define TIMER(_id, _name, _parent, _flags, _gate_id, _sec_id) \ ++ STM32_GATE(_id, _name, _parent, ((_flags) | CLK_SET_RATE_PARENT), \ + _gate_id, _sec_id) + +-#define KCLK(_id, _name, _flags, _gate_id, _mux_id, _sec_id)\ +- STM32_COMPOSITE(_id, _name, _flags, _sec_id,\ ++#define KCLK(_id, _name, _flags, _gate_id, _mux_id, _sec_id) \ ++ STM32_COMPOSITE(_id, _name, _flags, _sec_id, \ + _gate_id, _mux_id, NO_STM32_DIV) + + static const struct clock_config stm32mp13_clock_cfg[] = { +@@ -789,48 +789,45 @@ static int stm32mp13_check_security(void __iomem *base, + static const struct stm32_clock_match_data stm32mp13_data = { + .tab_clocks = stm32mp13_clock_cfg, + .num_clocks = ARRAY_SIZE(stm32mp13_clock_cfg), +- .gates = stm32mp13_gates, +- .muxes = stm32mp13_muxes, +- .dividers = stm32mp13_dividers, +- .check_security = &stm32mp13_check_security ++ .clock_data = &(const struct clk_stm32_clock_data) { ++ .num_gates = ARRAY_SIZE(stm32mp13_gates), ++ .gates = stm32mp13_gates, ++ .muxes = stm32mp13_muxes, ++ .dividers = stm32mp13_dividers, ++ }, ++ .check_security = stm32mp13_check_security, + }; + + static int stm32mp1_clk_probe(struct udevice *dev) + { +- fdt_addr_t base = dev_read_addr(dev->parent); + struct udevice *scmi; +- +- if (base == FDT_ADDR_T_NONE) +- return -EINVAL; ++ int err; + + /* force SCMI probe to register all SCMI clocks */ + uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(scmi_clock), &scmi); + +- stm32_rcc_init(NULL, &stm32mp13_data, (void __iomem *)base); ++ err = stm32_rcc_init(dev, &stm32mp13_data); ++ if (err) ++ return err; + +-#if defined(DEBUG) +- /* display debug information for probe after relocation */ +- if (gd->flags & GD_FLG_RELOC) +- stm32mp1_clk_dump(priv); +-#endif + gd->cpu_clk = clk_stm32_get_rate_by_name("ck_mpu"); + gd->bus_clk = clk_stm32_get_rate_by_name("ck_axi"); + + /* DDRPHYC father */ + gd->mem_clk = clk_stm32_get_rate_by_name("pll2_r"); + +-#if defined(CONFIG_DISPLAY_CPUINFO) +- if (gd->flags & GD_FLG_RELOC) { +- char buf[32]; +- +- log_info("Clocks:\n"); +- log_info("- MPU : %s MHz\n", strmhz(buf, gd->cpu_clk)); +- log_info("- AXI : %s MHz\n", strmhz(buf, gd->bus_clk)); +- log_info("- PER : %s MHz\n", +- strmhz(buf, clk_stm32_get_rate_by_name("ck_per"))); +- log_info("- DDR : %s MHz\n", strmhz(buf, gd->mem_clk)); ++ if (IS_ENABLED(CONFIG_DISPLAY_CPUINFO)) { ++ if (gd->flags & GD_FLG_RELOC) { ++ char buf[32]; ++ ++ log_info("Clocks:\n"); ++ log_info("- MPU : %s MHz\n", strmhz(buf, gd->cpu_clk)); ++ log_info("- AXI : %s MHz\n", strmhz(buf, gd->bus_clk)); ++ log_info("- PER : %s MHz\n", ++ strmhz(buf, clk_stm32_get_rate_by_name("ck_per"))); ++ log_info("- DDR : %s MHz\n", strmhz(buf, gd->mem_clk)); ++ } + } +-#endif /* CONFIG_DISPLAY_CPUINFO */ + + return 0; + } +@@ -839,6 +836,6 @@ U_BOOT_DRIVER(stm32mp1_clock) = { + .name = "stm32mp13_clk", + .id = UCLASS_CLK, + .ops = &stm32_clk_ops, +- .priv_auto = sizeof(struct stm32mp1_clk_priv), ++ .priv_auto = sizeof(struct stm32mp_rcc_priv), + .probe = stm32mp1_clk_probe, + }; +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index eff0fa134f..a5a3461b66 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -74,3 +74,68 @@ bool clk_dev_binded(struct clk *clk) + + return false; + } ++ ++/* Helper functions for clock ops */ ++ ++ulong ccf_clk_get_rate(struct clk *clk) ++{ ++ struct clk *c; ++ int err = clk_get_by_id(clk->id, &c); ++ ++ if (err) ++ return err; ++ return clk_get_rate(c); ++} ++ ++ulong ccf_clk_set_rate(struct clk *clk, unsigned long rate) ++{ ++ struct clk *c; ++ int err = clk_get_by_id(clk->id, &c); ++ ++ if (err) ++ return err; ++ return clk_set_rate(c, rate); ++} ++ ++int ccf_clk_set_parent(struct clk *clk, struct clk *parent) ++{ ++ struct clk *c, *p; ++ int err = clk_get_by_id(clk->id, &c); ++ ++ if (err) ++ return err; ++ ++ err = clk_get_by_id(parent->id, &p); ++ if (err) ++ return err; ++ ++ return clk_set_parent(c, p); ++} ++ ++static int ccf_clk_endisable(struct clk *clk, bool enable) ++{ ++ struct clk *c; ++ int err = clk_get_by_id(clk->id, &c); ++ ++ if (err) ++ return err; ++ return enable ? clk_enable(c) : clk_disable(c); ++} ++ ++int ccf_clk_enable(struct clk *clk) ++{ ++ return ccf_clk_endisable(clk, true); ++} ++ ++int ccf_clk_disable(struct clk *clk) ++{ ++ return ccf_clk_endisable(clk, false); ++} ++ ++const struct clk_ops ccf_clk_ops = { ++ .set_rate = ccf_clk_set_rate, ++ .get_rate = ccf_clk_get_rate, ++ .set_parent = ccf_clk_set_parent, ++ .enable = ccf_clk_enable, ++ .disable = ccf_clk_disable, ++}; +diff --git a/drivers/core/device.c b/drivers/core/device.c +index 6f84762ebd..9e470e3076 100644 +--- a/drivers/core/device.c ++++ b/drivers/core/device.c +@@ -1082,9 +1082,7 @@ bool device_is_compatible(const struct udevice *dev, const char *compat) + + bool of_machine_is_compatible(const char *compat) + { +- const void *fdt = gd->fdt_blob; +- +- return !fdt_node_check_compatible(fdt, 0, compat); ++ return ofnode_device_is_compatible(ofnode_root(), compat); + } + + int dev_disable_by_path(const char *path) +diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c +index cce9ce0845..2a160181a1 100644 +--- a/drivers/dfu/dfu_mtd.c ++++ b/drivers/dfu/dfu_mtd.c +@@ -85,27 +85,39 @@ static int mtd_block_op(enum dfu_op op, struct dfu_entity *dfu, + + while (remaining) { + if (erase_op.addr + remaining > lim) { +- printf("Limit reached 0x%llx while erasing at offset 0x%llx\n", +- lim, off); ++ printf("Limit reached 0x%llx while erasing at offset 0x%llx, remaining 0x%llx\n", ++ lim, erase_op.addr, remaining); + return -EIO; + } + ++ /* Skip the block if it is bad, don't erase it again */ ++ if (mtd_block_isbad(mtd, erase_op.addr)) { ++ printf("Skipping bad block at 0x%08llx\n", ++ erase_op.addr); ++ erase_op.addr += mtd->erasesize; ++ continue; ++ } ++ + ret = mtd_erase(mtd, &erase_op); + + if (ret) { +- /* Abort if its not a bad block error */ +- if (ret != -EIO) { +- printf("Failure while erasing at offset 0x%llx\n", +- erase_op.fail_addr); +- return 0; ++ /* If this is not -EIO, we have no idea what to do. */ ++ if (ret == -EIO) { ++ printf("Marking bad block at 0x%08llx (%d)\n", ++ erase_op.fail_addr, ret); ++ ret = mtd_block_markbad(mtd, erase_op.addr); ++ } ++ /* Abort if it is not -EIO or can't mark bad */ ++ if (ret) { ++ printf("Failure while erasing at offset 0x%llx (%d)\n", ++ erase_op.fail_addr, ret); ++ return ret; + } +- printf("Skipping bad block at 0x%08llx\n", +- erase_op.addr); + } else { + remaining -= mtd->erasesize; + } + +- /* Continue erase behind bad block */ ++ /* Continue erase behind the current block */ + erase_op.addr += mtd->erasesize; + } + } +diff --git a/include/configs/stm32mp13_st_common.h b/include/configs/stm32mp13_st_common.h +index 41681537a2..82a428fe63 100644 +--- a/include/configs/stm32mp13_st_common.h ++++ b/include/configs/stm32mp13_st_common.h +@@ -9,7 +9,7 @@ + #define __CONFIG_STM32MP13_ST_COMMON_H__ + + #define STM32MP_BOARD_EXTRA_ENV \ +- "usb_pgood_delay=1000\0" \ ++ "usb_pgood_delay=2000\0" \ + "console=ttySTM0\0" + + #include +diff --git a/include/configs/stm32mp15_st_common.h b/include/configs/stm32mp15_st_common.h +index c395f7f986..9865ef5843 100644 +--- a/include/configs/stm32mp15_st_common.h ++++ b/include/configs/stm32mp15_st_common.h +@@ -9,7 +9,7 @@ + #define __CONFIG_STM32MP15_ST_COMMON_H__ + + #define STM32MP_BOARD_EXTRA_ENV \ +- "usb_pgood_delay=1000\0" \ ++ "usb_pgood_delay=2000\0" \ + "console=ttySTM0\0" + + #include +diff --git a/include/dt-bindings/gpio/gpio.h b/include/dt-bindings/gpio/gpio.h +index c029467e82..5566e58196 100644 +--- a/include/dt-bindings/gpio/gpio.h ++++ b/include/dt-bindings/gpio/gpio.h +@@ -39,4 +39,7 @@ + /* Bit 5 express pull down */ + #define GPIO_PULL_DOWN 32 + ++/* Bit 6 express pull disable */ ++#define GPIO_PULL_DISABLE 64 ++ + #endif +diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h +index 9d296f240a..26d91d564f 100644 +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -254,4 +254,12 @@ const char *clk_hw_get_name(const struct clk *hw); + ulong clk_generic_get_rate(struct clk *clk); + + struct clk *dev_get_clk_ptr(struct udevice *dev); ++ ++ulong ccf_clk_get_rate(struct clk *clk); ++ulong ccf_clk_set_rate(struct clk *clk, unsigned long rate); ++int ccf_clk_set_parent(struct clk *clk, struct clk *parent); ++int ccf_clk_enable(struct clk *clk); ++int ccf_clk_disable(struct clk *clk); ++extern const struct clk_ops ccf_clk_ops; ++ + #endif /* __LINUX_CLK_PROVIDER_H */ +-- +2.25.1 + diff --git a/recipes-bsp/u-boot/u-boot-stm32mp/0098-silent_mode.patch b/recipes-bsp/u-boot/u-boot-stm32mp/0098-silent_mode.patch index db8ce76..bc7133e 100644 --- a/recipes-bsp/u-boot/u-boot-stm32mp/0098-silent_mode.patch +++ b/recipes-bsp/u-boot/u-boot-stm32mp/0098-silent_mode.patch @@ -1,22 +1,21 @@ -From 9538ad0348aef5f00cd0a6858873d5ffac2e287f Mon Sep 17 00:00:00 2001 -From: Christophe Priouzeau -Date: Wed, 28 Sep 2022 10:52:51 +0200 +From 8ba56fabc89de0df9613c30c8e9d72513a09b017 Mon Sep 17 00:00:00 2001 +From: Lionel VITTE +Date: Thu, 6 Jul 2023 17:38:46 +0200 Subject: [PATCH] silent_mode -Signed-off-by: Christophe Priouzeau --- include/configs/stm32mp13_st_common.h | 3 ++- include/configs/stm32mp15_st_common.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/configs/stm32mp13_st_common.h b/include/configs/stm32mp13_st_common.h -index 41681537a2..49d3398663 100644 +index 82a428fe63..1ee1beaae6 100644 --- a/include/configs/stm32mp13_st_common.h +++ b/include/configs/stm32mp13_st_common.h @@ -10,7 +10,8 @@ #define STM32MP_BOARD_EXTRA_ENV \ - "usb_pgood_delay=1000\0" \ + "usb_pgood_delay=2000\0" \ - "console=ttySTM0\0" + "console=ttySTM0\0" \ + "silent=1\0" @@ -24,13 +23,13 @@ index 41681537a2..49d3398663 100644 #include diff --git a/include/configs/stm32mp15_st_common.h b/include/configs/stm32mp15_st_common.h -index c395f7f986..81865b24ea 100644 +index 9865ef5843..2542012148 100644 --- a/include/configs/stm32mp15_st_common.h +++ b/include/configs/stm32mp15_st_common.h @@ -10,7 +10,8 @@ #define STM32MP_BOARD_EXTRA_ENV \ - "usb_pgood_delay=1000\0" \ + "usb_pgood_delay=2000\0" \ - "console=ttySTM0\0" + "console=ttySTM0\0" \ + "silent=1\0"