* [PATCH v2 1/5] dt-bindings: clock: Add STM32MP25 SYSCFG clock controller
2026-11-10 13:10 [PATCH v2 0/5] clk: stm32: Add the STM32MP2 SYSCFG LTDC pixel clock mux Gabriel Fernandez
@ 2026-11-10 13:10 ` Gabriel Fernandez
2026-11-10 13:10 ` [PATCH v2 2/5] dt-bindings: arm: stm32: Add clock-controller sub-node to STM32MP2 SYSCFG Gabriel Fernandez
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Gabriel Fernandez @ 2026-11-10 13:10 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue, Christophe Roullier
Cc: Dario Binacchi, linux-clk, devicetree, linux-stm32,
linux-arm-kernel, linux-kernel, Gabriel Fernandez
The SYSCFG of the STM32MP23x and STM32MP25x SoCs selects the LTDC pixel
clock among the LTDC kernel clock, the LVDS PHY pixel clock and the DSI
PHY byte lane clock.
Add the binding for this clock controller, described as a
clock-controller sub-node of the SYSCFG node, along with the header
defining the identifiers of the provided clocks.
A sub-node is needed since the inputs of the mux can't be described by
the "clocks" property of the SYSCFG node: the SYSCFG is a syscon, whose
first clock is taken as the clock of its registers and enabled around
each register access.
The inputs are listed in the "ltdc", "lvds", "dsi" order so that the
ones missing on a SoC (no LVDS nor DSI on STM32MP231/233 and
STM32MP251/253) can be omitted at the end of the list. "#clock-cells"
is 1 so that the other clocks of the SYSCFG can be added later without
changing the binding.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
---
.../bindings/clock/st,stm32mp25-syscfg-clk.yaml | 61 ++++++++++++++++++++++
.../dt-bindings/clock/st,stm32mp25-syscfg-clk.h | 12 +++++
2 files changed, 73 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/st,stm32mp25-syscfg-clk.yaml b/Documentation/devicetree/bindings/clock/st,stm32mp25-syscfg-clk.yaml
new file mode 100644
index 000000000000..027d14f28b0c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/st,stm32mp25-syscfg-clk.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/st,stm32mp25-syscfg-clk.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STM32MP2 SYSCFG clock controller
+
+maintainers:
+ - Gabriel Fernandez <gabriel.fernandez@foss.st.com>
+
+description: |
+ The SYSCFG of the STM32MP23x and STM32MP25x SoCs provides clocks, described
+ by a clock controller sub-node of the SYSCFG node.
+
+ The provided clocks are identified by the macros defined in
+ include/dt-bindings/clock/st,stm32mp25-syscfg-clk.h:
+ - CK_SYSCFG_PIX_LTDC: LTDC pixel clock, selected in the DISPLAYCLKCR
+ register among the LTDC kernel clock, used by the RGB parallel output,
+ the LVDS PHY pixel clock and the DSI PHY byte lane clock.
+
+properties:
+ compatible:
+ const: st,stm32mp25-syscfg-clk
+
+ "#clock-cells":
+ const: 1
+
+ clocks:
+ minItems: 1
+ items:
+ - description: LTDC kernel clock
+ - description: LVDS PHY pixel clock
+ - description: DSI PHY byte lane clock
+
+ clock-names:
+ minItems: 1
+ items:
+ - const: ltdc
+ - const: lvds
+ - const: dsi
+
+required:
+ - compatible
+ - "#clock-cells"
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/st,stm32mp25-rcc.h>
+
+ clock-controller {
+ compatible = "st,stm32mp25-syscfg-clk";
+ #clock-cells = <1>;
+ clocks = <&rcc CK_KER_LTDC>, <&lvds>, <&dsi>;
+ clock-names = "ltdc", "lvds", "dsi";
+ };
+...
diff --git a/include/dt-bindings/clock/st,stm32mp25-syscfg-clk.h b/include/dt-bindings/clock/st,stm32mp25-syscfg-clk.h
new file mode 100644
index 000000000000..74673942898c
--- /dev/null
+++ b/include/dt-bindings/clock/st,stm32mp25-syscfg-clk.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2026 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_ST_STM32MP25_SYSCFG_CLK_H_
+#define _DT_BINDINGS_CLOCK_ST_STM32MP25_SYSCFG_CLK_H_
+
+#define CK_SYSCFG_PIX_LTDC 0
+
+#endif /* _DT_BINDINGS_CLOCK_ST_STM32MP25_SYSCFG_CLK_H_ */
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 2/5] dt-bindings: arm: stm32: Add clock-controller sub-node to STM32MP2 SYSCFG
2026-11-10 13:10 [PATCH v2 0/5] clk: stm32: Add the STM32MP2 SYSCFG LTDC pixel clock mux Gabriel Fernandez
2026-11-10 13:10 ` [PATCH v2 1/5] dt-bindings: clock: Add STM32MP25 SYSCFG clock controller Gabriel Fernandez
@ 2026-11-10 13:10 ` Gabriel Fernandez
2026-11-10 13:17 ` sashiko-bot
2026-11-10 13:10 ` [PATCH v2 3/5] clk: stm32: Add STM32MP25 SYSCFG clock driver Gabriel Fernandez
` (2 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Gabriel Fernandez @ 2026-11-10 13:10 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue, Christophe Roullier
Cc: Dario Binacchi, linux-clk, devicetree, linux-stm32,
linux-arm-kernel, linux-kernel, Gabriel Fernandez
The SYSCFG of the STM32MP23x and STM32MP25x SoCs is described as the
provider of the LTDC pixel clock, but the inputs of this mux (LTDC
kernel clock, LVDS PHY pixel clock and DSI PHY byte lane clock) can't
be described by the "clocks" property of the SYSCFG node: the SYSCFG is
a syscon, whose first clock is taken as the clock of its registers and
enabled around each register access.
Add a clock-controller sub-node to describe the mux with its own clock
inputs. It is required on STM32MP23x and STM32MP25x and not allowed on
the other SoCs.
Deprecate the '#clock-cells' property of the SYSCFG node, which is no
longer required. No driver ever registered a clock on the SYSCFG node,
so this doesn't change anything for existing devicetrees.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
---
.../devicetree/bindings/arm/stm32/st,stm32-syscon.yaml | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
index a559f8b03b84..13c02844a91f 100644
--- a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
+++ b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
@@ -38,6 +38,10 @@ properties:
"#clock-cells":
const: 0
+ deprecated: true
+ description:
+ The LTDC pixel clock multiplexer is described by the clock-controller
+ sub-node.
"#address-cells":
const: 1
@@ -45,6 +49,10 @@ properties:
"#size-cells":
const: 1
+ clock-controller:
+ type: object
+ $ref: /schemas/clock/st,stm32mp25-syscfg-clk.yaml#
+
patternProperties:
"^phy@2[48]00$":
type: object
@@ -78,8 +86,8 @@ allOf:
then:
required:
- "#address-cells"
- - "#clock-cells"
- "#size-cells"
+ - clock-controller
- phy@2400
- phy@2800
else:
@@ -87,6 +95,7 @@ allOf:
'#address-cells': false
'#clock-cells': false
'#size-cells': false
+ clock-controller: false
phy@2400: false
phy@2800: false
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v2 2/5] dt-bindings: arm: stm32: Add clock-controller sub-node to STM32MP2 SYSCFG
2026-11-10 13:10 ` [PATCH v2 2/5] dt-bindings: arm: stm32: Add clock-controller sub-node to STM32MP2 SYSCFG Gabriel Fernandez
@ 2026-11-10 13:17 ` sashiko-bot
0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-11-10 13:17 UTC (permalink / raw)
To: Gabriel Fernandez; +Cc: linux-clk, devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Low] dt-bindings: arm: stm32: split STM32MP23/25 SYSCFG into separate
schema
--
commit a6e3f1e2b7c45d1069bba34abc7927e0b05e5a42
Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
dt-bindings: arm: stm32: Add clock-controller sub-node to STM32MP2 SYSCFG
This commit adds a required clock-controller sub-node to the STM32MP23x and
STM32MP25x SYSCFG bindings and deprecates the top-level #clock-cells
property.
> diff --git a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
> index a559f8b03b842..13c02844a91f9 100644
> --- a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
> +++ b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
> @@ -38,6 +38,10 @@ properties:
>
> "#clock-cells":
> const: 0
> + deprecated: true
> + description:
> + The LTDC pixel clock multiplexer is described by the clock-controller
> + sub-node.
>
> "#address-cells":
> const: 1
> @@ -45,6 +49,10 @@ properties:
> "#size-cells":
> const: 1
>
> + clock-controller:
> + type: object
> + $ref: /schemas/clock/st,stm32mp25-syscfg-clk.yaml#
> +
> patternProperties:
> "^phy@2[48]00$":
> type: object
> @@ -78,8 +86,8 @@ allOf:
> then:
> required:
> - "#address-cells"
> - - "#clock-cells"
> - "#size-cells"
> + - clock-controller
> - phy@2400
> - phy@2800
> else:
> @@ -87,6 +95,7 @@ allOf:
> '#address-cells': false
> '#clock-cells': false
> '#size-cells': false
> + clock-controller: false
> phy@2400: false
> phy@2800: false
[Severity: Low]
This isn't a bug, but should st,stm32mp23-syscfg and st,stm32mp25-syscfg be
split into a separate schema document instead of adding more conditionals
to st,stm32-syscon.yaml?
Unlike the simple syscon nodes in this binding, the STM32MP23/25 variants
forbid the top-level clocks property and require a distinct set of child
nodes and cell properties (#address-cells, #size-cells, clock-controller,
phy@2400, and phy@2800) that have to be explicitly disallowed for every
other compatible in the file.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261110-ups_mp25_clk_syscfg-v2-0-624559bb8ec7@foss.st.com?part=2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 3/5] clk: stm32: Add STM32MP25 SYSCFG clock driver
2026-11-10 13:10 [PATCH v2 0/5] clk: stm32: Add the STM32MP2 SYSCFG LTDC pixel clock mux Gabriel Fernandez
2026-11-10 13:10 ` [PATCH v2 1/5] dt-bindings: clock: Add STM32MP25 SYSCFG clock controller Gabriel Fernandez
2026-11-10 13:10 ` [PATCH v2 2/5] dt-bindings: arm: stm32: Add clock-controller sub-node to STM32MP2 SYSCFG Gabriel Fernandez
@ 2026-11-10 13:10 ` Gabriel Fernandez
2026-11-12 0:44 ` Brian Masney
2026-11-10 13:10 ` [PATCH v2 4/5] arm64: dts: st: add LTDC pixel clock controller on stm32mp23 Gabriel Fernandez
2026-11-10 13:10 ` [PATCH v2 5/5] arm64: dts: st: add LTDC pixel clock controller on stm32mp25 Gabriel Fernandez
4 siblings, 1 reply; 8+ messages in thread
From: Gabriel Fernandez @ 2026-11-10 13:10 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue, Christophe Roullier
Cc: Dario Binacchi, linux-clk, devicetree, linux-stm32,
linux-arm-kernel, linux-kernel, Gabriel Fernandez
On STM32MP23x and STM32MP25x, the LTDC pixel clock is selected in the
SYSCFG DISPLAYCLKCR register among the DSI PHY byte lane clock, the LVDS
PHY pixel clock (reset value) and the LTDC kernel clock, the latter
being the one needed by the RGB (DPI) output.
No driver registers this clock, so the selection can't be changed from
its reset value and a display connected to the LTDC RGB output can't
work.
Add a driver registering this clock as a mux. The SYSCFG node is bound
to the STM32MP2 SYSCFG driver, which populates its sub-nodes, so the
driver is probed from the "st,stm32mp25-syscfg-clk" clock-controller
sub-node and uses the regmap of the parent SYSCFG node. The mux parents
are taken from the "clocks" property of the sub-node, and the clock is
exposed through a onecell provider so that the other SYSCFG clocks can
be added later.
Co-developed-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
---
drivers/clk/stm32/Kconfig | 11 +++
drivers/clk/stm32/Makefile | 1 +
drivers/clk/stm32/clk-stm32mp25-syscfg.c | 134 +++++++++++++++++++++++++++++++
3 files changed, 146 insertions(+)
diff --git a/drivers/clk/stm32/Kconfig b/drivers/clk/stm32/Kconfig
index 5dbd75cde657..a298983f5511 100644
--- a/drivers/clk/stm32/Kconfig
+++ b/drivers/clk/stm32/Kconfig
@@ -39,5 +39,16 @@ config COMMON_CLK_STM32MP257
help
Support for stm32mp25x SoC family clocks.
+config COMMON_CLK_STM32MP25_SYSCFG
+ tristate "Clock driver for stm32mp25x SYSCFG clocks"
+ depends on COMMON_CLK_STM32MP257
+ select MFD_SYSCON
+ default COMMON_CLK_STM32MP257
+ help
+ Support for the clocks provided by the stm32mp25x SYSCFG, i.e.
+ the LTDC pixel clock source selection between the LTDC kernel
+ clock (RGB output), the LVDS PHY pixel clock and the DSI byte
+ lane clock.
+
endif
diff --git a/drivers/clk/stm32/Makefile b/drivers/clk/stm32/Makefile
index e04727b59449..8088d172651f 100644
--- a/drivers/clk/stm32/Makefile
+++ b/drivers/clk/stm32/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_COMMON_CLK_STM32MP135) += clk-stm32mp13.o clk-stm32-core.o reset-st
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o reset-stm32.o
obj-$(CONFIG_COMMON_CLK_STM32MP215) += clk-stm32mp21.o clk-stm32-core.o reset-stm32.o
obj-$(CONFIG_COMMON_CLK_STM32MP257) += clk-stm32mp25.o clk-stm32-core.o reset-stm32.o
+obj-$(CONFIG_COMMON_CLK_STM32MP25_SYSCFG) += clk-stm32mp25-syscfg.o
diff --git a/drivers/clk/stm32/clk-stm32mp25-syscfg.c b/drivers/clk/stm32/clk-stm32mp25-syscfg.c
new file mode 100644
index 000000000000..69b9a7592838
--- /dev/null
+++ b/drivers/clk/stm32/clk-stm32mp25-syscfg.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/st,stm32mp25-syscfg-clk.h>
+
+#define SYSCFG_DISPLAYCLKCR 0x5000
+#define DISPLAYCLKCR_DPIVSLVDS GENMASK(1, 0)
+
+#define STM32MP25_SYSCFG_NUM_CLKS (CK_SYSCFG_PIX_LTDC + 1)
+
+/*
+ * The LTDC pixel clock source is selected in SYSCFG_DISPLAYCLKCR among
+ * the DSI byte lane clock, the LVDS PHY pixel clock (reset value) and
+ * the LTDC kernel clock, which is used with the RGB (DPI) output.
+ *
+ * The parents are listed in the DPIVSLVDS field order, while .index refers
+ * to the "clocks" property of the node, ordered "ltdc", "lvds", "dsi" so
+ * that the inputs missing on a SoC can be omitted at the end of the list.
+ */
+static const struct clk_parent_data clk_pix_ltdc_parents[] = {
+ { .index = 2 }, /* dsi */
+ { .index = 1 }, /* lvds */
+ { .index = 0 }, /* ltdc */
+};
+
+struct stm32mp25_syscfg_mux {
+ struct clk_hw hw;
+ struct regmap *regmap;
+};
+
+static inline struct stm32mp25_syscfg_mux *to_syscfg_mux(struct clk_hw *hw)
+{
+ return container_of(hw, struct stm32mp25_syscfg_mux, hw);
+}
+
+static u8 stm32mp25_syscfg_mux_get_parent(struct clk_hw *hw)
+{
+ struct stm32mp25_syscfg_mux *mux = to_syscfg_mux(hw);
+ unsigned int val;
+
+ regmap_read(mux->regmap, SYSCFG_DISPLAYCLKCR, &val);
+
+ return FIELD_GET(DISPLAYCLKCR_DPIVSLVDS, val);
+}
+
+static int stm32mp25_syscfg_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct stm32mp25_syscfg_mux *mux = to_syscfg_mux(hw);
+
+ return regmap_update_bits(mux->regmap, SYSCFG_DISPLAYCLKCR,
+ DISPLAYCLKCR_DPIVSLVDS,
+ FIELD_PREP(DISPLAYCLKCR_DPIVSLVDS, index));
+}
+
+static const struct clk_ops stm32mp25_syscfg_mux_ops = {
+ .get_parent = stm32mp25_syscfg_mux_get_parent,
+ .set_parent = stm32mp25_syscfg_mux_set_parent,
+ .determine_rate = clk_hw_determine_rate_no_reparent,
+};
+
+static int stm32mp25_syscfg_clk_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct clk_hw_onecell_data *clk_data;
+ struct clk_init_data init = { };
+ struct stm32mp25_syscfg_mux *mux;
+ int ret;
+
+ clk_data = devm_kzalloc_flex(dev, *clk_data, hws,
+ STM32MP25_SYSCFG_NUM_CLKS);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clk_data->num = STM32MP25_SYSCFG_NUM_CLKS;
+
+ mux = devm_kzalloc_obj(dev, *mux);
+ if (!mux)
+ return -ENOMEM;
+
+ /* The mux is a sub-node of the SYSCFG, whose regmap it shares */
+ mux->regmap = syscon_node_to_regmap(dev->parent->of_node);
+ if (IS_ERR(mux->regmap))
+ return dev_err_probe(dev, PTR_ERR(mux->regmap),
+ "failed to get the SYSCFG regmap\n");
+
+ init.name = "clk_pix_ltdc";
+ init.ops = &stm32mp25_syscfg_mux_ops;
+ init.parent_data = clk_pix_ltdc_parents;
+ init.num_parents = ARRAY_SIZE(clk_pix_ltdc_parents);
+ init.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT;
+ mux->hw.init = &init;
+
+ ret = devm_clk_hw_register(dev, &mux->hw);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register %s\n",
+ init.name);
+
+ clk_data->hws[CK_SYSCFG_PIX_LTDC] = &mux->hw;
+
+ return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+}
+
+static const struct of_device_id stm32mp25_syscfg_clk_of_match[] = {
+ { .compatible = "st,stm32mp25-syscfg-clk" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, stm32mp25_syscfg_clk_of_match);
+
+static struct platform_driver stm32mp25_syscfg_clk_driver = {
+ .probe = stm32mp25_syscfg_clk_probe,
+ .driver = {
+ .name = "stm32mp25-syscfg-clk",
+ .of_match_table = stm32mp25_syscfg_clk_of_match,
+ },
+};
+module_platform_driver(stm32mp25_syscfg_clk_driver);
+
+MODULE_AUTHOR("Gabriel Fernandez <gabriel.fernandez@foss.st.com>");
+MODULE_DESCRIPTION("STM32MP25 SYSCFG clock driver");
+MODULE_LICENSE("GPL");
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v2 3/5] clk: stm32: Add STM32MP25 SYSCFG clock driver
2026-11-10 13:10 ` [PATCH v2 3/5] clk: stm32: Add STM32MP25 SYSCFG clock driver Gabriel Fernandez
@ 2026-11-12 0:44 ` Brian Masney
0 siblings, 0 replies; 8+ messages in thread
From: Brian Masney @ 2026-11-12 0:44 UTC (permalink / raw)
To: Gabriel Fernandez
Cc: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue, Christophe Roullier, Dario Binacchi, linux-clk,
devicetree, linux-stm32, linux-arm-kernel, linux-kernel,
Brian Masney
Hi Gabriel,
> On STM32MP23x and STM32MP25x, the LTDC pixel clock is selected in the
> SYSCFG DISPLAYCLKCR register among the DSI PHY byte lane clock, the LVDS
> PHY pixel clock (reset value) and the LTDC kernel clock, the latter
> being the one needed by the RGB (DPI) output.
>
> No driver registers this clock, so the selection can't be changed from
> its reset value and a display connected to the LTDC RGB output can't
> work.
>
> Add a driver registering this clock as a mux. The SYSCFG node is bound
> to the STM32MP2 SYSCFG driver, which populates its sub-nodes, so the
> driver is probed from the "st,stm32mp25-syscfg-clk" clock-controller
> sub-node and uses the regmap of the parent SYSCFG node. The mux parents
> are taken from the "clocks" property of the sub-node, and the clock is
> exposed through a onecell provider so that the other SYSCFG clocks can
> be added later.
>
> Co-developed-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
> ---
> drivers/clk/stm32/Kconfig | 11 +++
> drivers/clk/stm32/Makefile | 1 +
> drivers/clk/stm32/clk-stm32mp25-syscfg.c | 134 +++++++++++++++++++++++++++++++
> 3 files changed, 146 insertions(+)
>
> diff --git a/drivers/clk/stm32/Kconfig b/drivers/clk/stm32/Kconfig
> index 5dbd75cde657..a298983f5511 100644
> --- a/drivers/clk/stm32/Kconfig
> +++ b/drivers/clk/stm32/Kconfig
> @@ -39,5 +39,16 @@ config COMMON_CLK_STM32MP257
> help
> Support for stm32mp25x SoC family clocks.
>
> +config COMMON_CLK_STM32MP25_SYSCFG
> + tristate "Clock driver for stm32mp25x SYSCFG clocks"
> + depends on COMMON_CLK_STM32MP257
Note for my future reference: The common has || COMPILE_TEST already.
Also add:
depends on SOC_STM32MP2 || COMPILE_TEST
> + select MFD_SYSCON
> + default COMMON_CLK_STM32MP257
> + help
> + Support for the clocks provided by the stm32mp25x SYSCFG, i.e.
> + the LTDC pixel clock source selection between the LTDC kernel
> + clock (RGB output), the LVDS PHY pixel clock and the DSI byte
> + lane clock.
> +
> endif
>
> diff --git a/drivers/clk/stm32/Makefile b/drivers/clk/stm32/Makefile
> index e04727b59449..8088d172651f 100644
> --- a/drivers/clk/stm32/Makefile
> +++ b/drivers/clk/stm32/Makefile
> @@ -2,3 +2,4 @@ obj-$(CONFIG_COMMON_CLK_STM32MP135) += clk-stm32mp13.o clk-stm32-core.o reset-st
> obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o reset-stm32.o
> obj-$(CONFIG_COMMON_CLK_STM32MP215) += clk-stm32mp21.o clk-stm32-core.o reset-stm32.o
> obj-$(CONFIG_COMMON_CLK_STM32MP257) += clk-stm32mp25.o clk-stm32-core.o reset-stm32.o
> +obj-$(CONFIG_COMMON_CLK_STM32MP25_SYSCFG) += clk-stm32mp25-syscfg.o
> diff --git a/drivers/clk/stm32/clk-stm32mp25-syscfg.c b/drivers/clk/stm32/clk-stm32mp25-syscfg.c
> new file mode 100644
> index 000000000000..69b9a7592838
> --- /dev/null
> +++ b/drivers/clk/stm32/clk-stm32mp25-syscfg.c
> @@ -0,0 +1,134 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
It's currently 2026.
> + * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <dt-bindings/clock/st,stm32mp25-syscfg-clk.h>
> +
> +#define SYSCFG_DISPLAYCLKCR 0x5000
> +#define DISPLAYCLKCR_DPIVSLVDS GENMASK(1, 0)
> +
> +#define STM32MP25_SYSCFG_NUM_CLKS (CK_SYSCFG_PIX_LTDC + 1)
> +
> +/*
> + * The LTDC pixel clock source is selected in SYSCFG_DISPLAYCLKCR among
> + * the DSI byte lane clock, the LVDS PHY pixel clock (reset value) and
> + * the LTDC kernel clock, which is used with the RGB (DPI) output.
> + *
> + * The parents are listed in the DPIVSLVDS field order, while .index refers
> + * to the "clocks" property of the node, ordered "ltdc", "lvds", "dsi" so
> + * that the inputs missing on a SoC can be omitted at the end of the list.
> + */
> +static const struct clk_parent_data clk_pix_ltdc_parents[] = {
> + { .index = 2 }, /* dsi */
> + { .index = 1 }, /* lvds */
> + { .index = 0 }, /* ltdc */
> +};
> +
> +struct stm32mp25_syscfg_mux {
> + struct clk_hw hw;
> + struct regmap *regmap;
> +};
> +
> +static inline struct stm32mp25_syscfg_mux *to_syscfg_mux(struct clk_hw *hw)
> +{
> + return container_of(hw, struct stm32mp25_syscfg_mux, hw);
> +}
> +
> +static u8 stm32mp25_syscfg_mux_get_parent(struct clk_hw *hw)
> +{
> + struct stm32mp25_syscfg_mux *mux = to_syscfg_mux(hw);
> + unsigned int val;
> +
> + regmap_read(mux->regmap, SYSCFG_DISPLAYCLKCR, &val);
regmap return value is not checked and val is uninitialized if an error
occurs.
> +
> + return FIELD_GET(DISPLAYCLKCR_DPIVSLVDS, val);
> +}
> +
> +static int stm32mp25_syscfg_mux_set_parent(struct clk_hw *hw, u8 index)
> +{
> + struct stm32mp25_syscfg_mux *mux = to_syscfg_mux(hw);
> +
> + return regmap_update_bits(mux->regmap, SYSCFG_DISPLAYCLKCR,
> + DISPLAYCLKCR_DPIVSLVDS,
> + FIELD_PREP(DISPLAYCLKCR_DPIVSLVDS, index));
> +}
> +
> +static const struct clk_ops stm32mp25_syscfg_mux_ops = {
> + .get_parent = stm32mp25_syscfg_mux_get_parent,
> + .set_parent = stm32mp25_syscfg_mux_set_parent,
> + .determine_rate = clk_hw_determine_rate_no_reparent,
> +};
> +
> +static int stm32mp25_syscfg_clk_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct clk_hw_onecell_data *clk_data;
> + struct clk_init_data init = { };
> + struct stm32mp25_syscfg_mux *mux;
> + int ret;
Put in reverse Christmas tree order.
> +
> + clk_data = devm_kzalloc_flex(dev, *clk_data, hws,
> + STM32MP25_SYSCFG_NUM_CLKS);
> + if (!clk_data)
> + return -ENOMEM;
> +
> + clk_data->num = STM32MP25_SYSCFG_NUM_CLKS;
> +
> + mux = devm_kzalloc_obj(dev, *mux);
> + if (!mux)
> + return -ENOMEM;
> +
> + /* The mux is a sub-node of the SYSCFG, whose regmap it shares */
> + mux->regmap = syscon_node_to_regmap(dev->parent->of_node);
Instead of dev->parent->of_node, you can use:
struct device_node *np __free(device_node) = of_get_parent(dev->of_node);
mux->regmap = syscon_node_to_regmap(np);
> + if (IS_ERR(mux->regmap))
> + return dev_err_probe(dev, PTR_ERR(mux->regmap),
> + "failed to get the SYSCFG regmap\n");
> +
> + init.name = "clk_pix_ltdc";
> + init.ops = &stm32mp25_syscfg_mux_ops;
> + init.parent_data = clk_pix_ltdc_parents;
> + init.num_parents = ARRAY_SIZE(clk_pix_ltdc_parents);
> + init.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT;
clk_hw_determine_rate_no_reparent() already prevents reparenting, so
CLK_SET_RATE_NO_REPARENT is redundant here. It doesn't hurt anything
though.
Brian
--
Brian Masney <masneyb@kernel.org>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 4/5] arm64: dts: st: add LTDC pixel clock controller on stm32mp23
2026-11-10 13:10 [PATCH v2 0/5] clk: stm32: Add the STM32MP2 SYSCFG LTDC pixel clock mux Gabriel Fernandez
` (2 preceding siblings ...)
2026-11-10 13:10 ` [PATCH v2 3/5] clk: stm32: Add STM32MP25 SYSCFG clock driver Gabriel Fernandez
@ 2026-11-10 13:10 ` Gabriel Fernandez
2026-11-10 13:10 ` [PATCH v2 5/5] arm64: dts: st: add LTDC pixel clock controller on stm32mp25 Gabriel Fernandez
4 siblings, 0 replies; 8+ messages in thread
From: Gabriel Fernandez @ 2026-11-10 13:10 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue, Christophe Roullier
Cc: Dario Binacchi, linux-clk, devicetree, linux-stm32,
linux-arm-kernel, linux-kernel, Gabriel Fernandez
Describe the LTDC pixel clock multiplexer of the SYSCFG as a
clock-controller sub-node and use it as the LTDC "ref" clock instead of
the SYSCFG node itself, whose deprecated "#clock-cells" property is
removed.
Only the LTDC kernel clock is available as parent on STM32MP231; the
LVDS and DSI clocks are added on STM32MP235.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
---
arch/arm64/boot/dts/st/stm32mp231.dtsi | 9 ++++++++-
arch/arm64/boot/dts/st/stm32mp235.dtsi | 8 +++++++-
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/st/stm32mp231.dtsi b/arch/arm64/boot/dts/st/stm32mp231.dtsi
index fefbf6f4f153..df446f0c1539 100644
--- a/arch/arm64/boot/dts/st/stm32mp231.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp231.dtsi
@@ -4,6 +4,7 @@
* Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
*/
#include <dt-bindings/clock/st,stm32mp25-rcc.h>
+#include <dt-bindings/clock/st,stm32mp25-syscfg-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/regulator/st,stm32mp25-regulator.h>
#include <dt-bindings/reset/st,stm32mp25-rcc.h>
@@ -1121,10 +1122,16 @@ exti1: interrupt-controller@44220000 {
syscfg: syscon@44230000 {
compatible = "st,stm32mp23-syscfg", "syscon";
reg = <0x44230000 0x10000>;
- #clock-cells = <0>;
#address-cells = <1>;
#size-cells = <1>;
+ syscfg_clk: clock-controller {
+ compatible = "st,stm32mp25-syscfg-clk";
+ #clock-cells = <1>;
+ clocks = <&rcc CK_KER_LTDC>;
+ clock-names = "ltdc";
+ };
+
usb2_phy1: phy@2400 {
compatible = "st,stm32mp25-usb2phy1";
reg = <0x2400 0x24>;
diff --git a/arch/arm64/boot/dts/st/stm32mp235.dtsi b/arch/arm64/boot/dts/st/stm32mp235.dtsi
index 7a87c344a4fe..0ef5f2cdd18e 100644
--- a/arch/arm64/boot/dts/st/stm32mp235.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp235.dtsi
@@ -7,10 +7,16 @@
<dc {
compatible = "st,stm32mp255-ltdc";
- clocks = <&clk_flexgen_27_fixed>, <&rcc CK_BUS_LTDC>, <&syscfg>, <&lvds>;
+ clocks = <&clk_flexgen_27_fixed>, <&rcc CK_BUS_LTDC>,
+ <&syscfg_clk CK_SYSCFG_PIX_LTDC>, <&lvds>;
clock-names = "lcd", "bus", "ref", "lvds";
};
+&syscfg_clk {
+ clocks = <&rcc CK_KER_LTDC>, <&lvds>, <&clk_dsi_txbyte>;
+ clock-names = "ltdc", "lvds", "dsi";
+};
+
&rifsc {
lvds: lvds@48060000 {
compatible = "st,stm32mp255-lvds", "st,stm32mp25-lvds";
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v2 5/5] arm64: dts: st: add LTDC pixel clock controller on stm32mp25
2026-11-10 13:10 [PATCH v2 0/5] clk: stm32: Add the STM32MP2 SYSCFG LTDC pixel clock mux Gabriel Fernandez
` (3 preceding siblings ...)
2026-11-10 13:10 ` [PATCH v2 4/5] arm64: dts: st: add LTDC pixel clock controller on stm32mp23 Gabriel Fernandez
@ 2026-11-10 13:10 ` Gabriel Fernandez
4 siblings, 0 replies; 8+ messages in thread
From: Gabriel Fernandez @ 2026-11-10 13:10 UTC (permalink / raw)
To: Stephen Boyd, Brian Masney, Jerome Brunet, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
Alexandre Torgue, Christophe Roullier
Cc: Dario Binacchi, linux-clk, devicetree, linux-stm32,
linux-arm-kernel, linux-kernel, Gabriel Fernandez
Describe the LTDC pixel clock multiplexer of the SYSCFG as a
clock-controller sub-node and use it as the LTDC "ref" clock instead of
the SYSCFG node itself, whose deprecated "#clock-cells" property is
removed.
Only the LTDC kernel clock is available as parent on STM32MP251; the
LVDS and DSI clocks are added on STM32MP255.
Signed-off-by: Gabriel Fernandez <gabriel.fernandez@foss.st.com>
---
arch/arm64/boot/dts/st/stm32mp251.dtsi | 9 ++++++++-
arch/arm64/boot/dts/st/stm32mp255.dtsi | 8 +++++++-
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index dac3d2d23ff0..8d644153dbcb 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -4,6 +4,7 @@
* Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
*/
#include <dt-bindings/clock/st,stm32mp25-rcc.h>
+#include <dt-bindings/clock/st,stm32mp25-syscfg-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/st,stm32mp25-rcc.h>
#include <dt-bindings/regulator/st,stm32mp25-regulator.h>
@@ -2076,10 +2077,16 @@ exti1: interrupt-controller@44220000 {
syscfg: syscon@44230000 {
compatible = "st,stm32mp25-syscfg", "syscon";
reg = <0x44230000 0x10000>;
- #clock-cells = <0>;
#address-cells = <1>;
#size-cells = <1>;
+ syscfg_clk: clock-controller {
+ compatible = "st,stm32mp25-syscfg-clk";
+ #clock-cells = <1>;
+ clocks = <&rcc CK_KER_LTDC>;
+ clock-names = "ltdc";
+ };
+
usb2_phy1: phy@2400 {
compatible = "st,stm32mp25-usb2phy1";
reg = <0x2400 0x24>;
diff --git a/arch/arm64/boot/dts/st/stm32mp255.dtsi b/arch/arm64/boot/dts/st/stm32mp255.dtsi
index 7a598f53a2a0..08cbc383af20 100644
--- a/arch/arm64/boot/dts/st/stm32mp255.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp255.dtsi
@@ -7,10 +7,16 @@
<dc {
compatible = "st,stm32mp255-ltdc";
- clocks = <&clk_flexgen_27_fixed>, <&rcc CK_BUS_LTDC>, <&syscfg>, <&lvds>;
+ clocks = <&clk_flexgen_27_fixed>, <&rcc CK_BUS_LTDC>,
+ <&syscfg_clk CK_SYSCFG_PIX_LTDC>, <&lvds>;
clock-names = "lcd", "bus", "ref", "lvds";
};
+&syscfg_clk {
+ clocks = <&rcc CK_KER_LTDC>, <&lvds>, <&clk_dsi_txbyte>;
+ clock-names = "ltdc", "lvds", "dsi";
+};
+
&rifsc {
lvds: lvds@48060000 {
compatible = "st,stm32mp255-lvds", "st,stm32mp25-lvds";
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread