mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH] pinctrl: generic: rename PIN_CONFIG_OUTPUT to LEVEL
From: Ahmad Fatoum @ 2026-06-06 18:20 UTC (permalink / raw)
  To: barebox; +Cc: Ahmad Fatoum

To make porting drivers from newer Linux versions a bit easier,
port Linux commit 203a83112e097a501fbe12722b6342787497efe0:

|   pinctrl: generic: rename PIN_CONFIG_OUTPUT to LEVEL
|
|   This generic pin config property is confusingly named so let's
|   rename it to make things clearer.
|
|   There are already drivers in the tree that use PIN_CONFIG_OUTPUT
|   to *read* the value of an output driven pin, which is a big
|   semantic confusion for the head: are we then reading the
|   setting of the output or the actual value/level that is put
|   out on the pin?
|
|   We already have PIN_CONFIG_OUTPUT_ENABLE that turns on driver
|   buffers for output, so this can by logical conclusion only
|   drive the voltage level if it should be any different.
|
|   But if we read the pin, are we then reading the *setting* of
|   the output value or the *actual* value we can see on the
|   line?
|
|   If the pin has not first been set into output mode with
|   PIN_CONFIG_OUTPUT_ENABLE, but is instead in some input mode
|   or tristate, what will reading this property actually
|   return?
|
|   Reading the current users reading this property it is clear
|   that what we read is the logical level of the pin as 0 or 1
|   depending on if it is low or high.
|
|   Rename it to PIN_CONFIG_LEVEL so it is crystal clear that
|   we set or read the voltage level of the pin and nothing else.
|
|   Acked-by: Sudeep Holla <sudeep.holla@arm.com>
|   Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
 drivers/pinctrl/pinctrl-rockchip.c      |  8 ++++----
 drivers/pinctrl/pinctrl-stm32.c         |  2 +-
 include/linux/pinctrl/pinconf-generic.h | 12 ++++++++----
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index f2a6c0266b69..482c6d213d2b 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -323,10 +323,10 @@ static unsigned long parse_gpio_direction(struct device_node *np)
 	if (of_property_read_bool(np, "input-enable")) {
 		param = PIN_CONFIG_INPUT_ENABLE;
 	} else if (of_property_read_bool(np, "output-low")) {
-		param = PIN_CONFIG_OUTPUT;
+		param = PIN_CONFIG_LEVEL;
 		argument = 0;
 	} else if (of_property_read_bool(np, "output-high")) {
-		param = PIN_CONFIG_OUTPUT;
+		param = PIN_CONFIG_LEVEL;
 		argument = 1;
 	}
 
@@ -3188,7 +3188,7 @@ static void rockchip_set_gpio(struct rockchip_pin_bank *bank,
 	enum pin_config_param param = pinconf_to_config_param(config);
 	struct gpio_chip *gpio;
 
-	if (param != PIN_CONFIG_OUTPUT && param != PIN_CONFIG_INPUT_ENABLE)
+	if (param != PIN_CONFIG_LEVEL && param != PIN_CONFIG_INPUT_ENABLE)
 		return;
 
 	gpio = of_gpio_get_chip_by_alias(bank->name);
@@ -3202,7 +3202,7 @@ static void rockchip_set_gpio(struct rockchip_pin_bank *bank,
 	}
 
 	switch (param) {
-	case PIN_CONFIG_OUTPUT:
+	case PIN_CONFIG_LEVEL:
 		gpio->ops->direction_output(gpio, pin_num,
 					    pinconf_to_config_argument(config));
 		break;
diff --git a/drivers/pinctrl/pinctrl-stm32.c b/drivers/pinctrl/pinctrl-stm32.c
index dd5a70c6d295..f0cfcc11d80f 100644
--- a/drivers/pinctrl/pinctrl-stm32.c
+++ b/drivers/pinctrl/pinctrl-stm32.c
@@ -289,7 +289,7 @@ static int stm32_gpio_set_config(struct gpio_chip *chip,
 	case PIN_CONFIG_BIAS_PULL_DOWN:
 		__stm32_pmx_set_bias(bank->base, gpio, STM32_PIN_PULL_DOWN);
 		break;
-	case PIN_CONFIG_OUTPUT:
+	case PIN_CONFIG_LEVEL:
 		__stm32_pmx_gpio_output(bank->base, gpio, arg);
 		break;
 	default:
diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h
index 9214258ffac4..3c79f2ed61db 100644
--- a/include/linux/pinctrl/pinconf-generic.h
+++ b/include/linux/pinctrl/pinconf-generic.h
@@ -79,9 +79,13 @@
  *	passed in the argument on a custom form, else just use argument 1
  *	to indicate low power mode, argument 0 turns low power mode off.
  * @PIN_CONFIG_MODE_PWM: this will configure the pin for PWM
- * @PIN_CONFIG_OUTPUT: this will configure the pin as an output and drive a
- * 	value on the line. Use argument 1 to indicate high level, argument 0 to
- *	indicate low level. (Please see Documentation/driver-api/pin-control.rst,
+ * @PIN_CONFIG_LEVEL: setting this will configure the pin as an output and
+ *	drive a value on the line. Use argument 1 to indicate high level,
+ *	argument 0 to indicate low level. Conversely the value of the line
+ *	can be read using this parameter, if and only if that value can be
+ *	represented as a binary 0 or 1 where 0 indicate a low voltage level
+ *	and 1 indicate a high voltage level.
+ *	(Please see Documentation/driver-api/pin-control.rst,
  *	section "GPIO mode pitfalls" for a discussion around this parameter.)
  * @PIN_CONFIG_OUTPUT_ENABLE: this will enable the pin's output mode
  * 	without driving a value there. For most platforms this reduces to
@@ -127,7 +131,7 @@ enum pin_config_param {
 	PIN_CONFIG_INPUT_SCHMITT_ENABLE,
 	PIN_CONFIG_MODE_LOW_POWER,
 	PIN_CONFIG_MODE_PWM,
-	PIN_CONFIG_OUTPUT,
+	PIN_CONFIG_LEVEL,
 	PIN_CONFIG_OUTPUT_ENABLE,
 	PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS,
 	PIN_CONFIG_PERSIST_STATE,
-- 
2.47.3




^ permalink raw reply related

* [PATCH v2 2/4] clk: socfpga: remove clk-phase setting
From: Michael Tretter @ 2026-06-05 13:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter
In-Reply-To: <20260605-socfpga-agilex5-clk-v2-0-780562ec169f@pengutronix.de>

There are no device trees that have the clk-phase property and the Linux
driver doesn't have the code. Remove the unused clk-phase setting.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 drivers/clk/socfpga/clk-gate-a10.c | 55 --------------------------------------
 1 file changed, 55 deletions(-)

diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
index e6bcc91b0490..b43e19d2ca3f 100644
--- a/drivers/clk/socfpga/clk-gate-a10.c
+++ b/drivers/clk/socfpga/clk-gate-a10.c
@@ -36,59 +36,11 @@ static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hw,
 	return parent_rate / div;
 }
 
-static int socfpga_clk_prepare(struct clk_hw *hw)
-{
-	struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hw);
-	int i;
-	u32 hs_timing;
-	u32 clk_phase[2];
-
-	if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) {
-		for (i = 0; i < ARRAY_SIZE(clk_phase); i++) {
-			switch (socfpgaclk->clk_phase[i]) {
-			case 0:
-				clk_phase[i] = 0;
-				break;
-			case 45:
-				clk_phase[i] = 1;
-				break;
-			case 90:
-				clk_phase[i] = 2;
-				break;
-			case 135:
-				clk_phase[i] = 3;
-				break;
-			case 180:
-				clk_phase[i] = 4;
-				break;
-			case 225:
-				clk_phase[i] = 5;
-				break;
-			case 270:
-				clk_phase[i] = 6;
-				break;
-			case 315:
-				clk_phase[i] = 7;
-				break;
-			default:
-				clk_phase[i] = 0;
-				break;
-			}
-		}
-
-		hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1]);
-		writel(hs_timing, ARRIA10_SYSMGR_SDMMC);
-	}
-	return 0;
-}
-
 static int clk_socfpga_enable(struct clk_hw *hw)
 {
 	struct socfpga_gate_clk *socfpga_clk = to_socfpga_gate_clk(hw);
 	u32 val;
 
-	socfpga_clk_prepare(hw);
-
 	val = readl(socfpga_clk->reg);
 	val |= 1 << socfpga_clk->bit_idx;
 	writel(val, socfpga_clk->reg);
@@ -115,7 +67,6 @@ static struct clk *__socfpga_gate_init(struct device_node *node,
 {
 	u32 clk_gate[2];
 	u32 div_reg[3];
-	u32 clk_phase[2];
 	u32 fixed_div;
 	struct clk_hw *hw_clk;
 	struct socfpga_gate_clk *socfpga_clk;
@@ -153,12 +104,6 @@ static struct clk *__socfpga_gate_init(struct device_node *node,
 		socfpga_clk->div_reg = NULL;
 	}
 
-	rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2);
-	if (!rc) {
-		socfpga_clk->clk_phase[0] = clk_phase[0];
-		socfpga_clk->clk_phase[1] = clk_phase[1];
-	}
-
 	of_property_read_string(node, "clock-output-names", &clk_name);
 
 	init.name = clk_name;

-- 
2.47.3




^ permalink raw reply related

* [PATCH v2 4/4] clk: socfpga: agilex5: sync with kernel
From: Michael Tretter @ 2026-06-05 13:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter
In-Reply-To: <20260605-socfpga-agilex5-clk-v2-0-780562ec169f@pengutronix.de>

From: Steffen Trumtrar <s.trumtrar@pengutronix.de>

Since v6.19-rc1 linux now has an Agilex5 clock driver [1]. This is
slightly different than the previous out-of-tree version. Sync with the
mainlined linux driver and cleanup on the way.

[1] commit 2050b57ecda040010ec797fb07713889372c5041

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 drivers/clk/socfpga/clk-agilex5.c    | 842 ++++++++++++-----------------------
 drivers/clk/socfpga/clk-gate-s10.c   |   7 +-
 drivers/clk/socfpga/clk-periph-s10.c |  38 ++
 drivers/clk/socfpga/clk-pll-s10.c    |   5 +-
 drivers/clk/socfpga/stratix10-clk.h  |  48 +-
 5 files changed, 366 insertions(+), 574 deletions(-)

diff --git a/drivers/clk/socfpga/clk-agilex5.c b/drivers/clk/socfpga/clk-agilex5.c
index f61b346ba4db..8be41920dbac 100644
--- a/drivers/clk/socfpga/clk-agilex5.c
+++ b/drivers/clk/socfpga/clk-agilex5.c
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
+// SPDX-Comment: Origin-URL: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clk/socfpga/clk-agilex5.c?id=2050b57ecda040010ec797fb07713889372c5041
 /*
  * Copyright (C) 2022, Intel Corporation
  */
@@ -12,506 +13,229 @@
 
 #include "stratix10-clk.h"
 
-static const struct clk_parent_data pll_mux[] = {
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+/* External parent clocks come from DT via fw_name */
+static const char * const boot_pll_parents[] = {
+	"osc1",
+	"cb-intosc-hs-div2-clk",
 };
 
-static const struct clk_parent_data boot_mux[] = {
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
+static const char * const main_pll_parents[] = {
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data core0_free_mux[] = {
-	{
-		.fw_name = "main_pll_c1",
-		.name = "main_pll_c1",
-	},
-	{
-		.fw_name = "peri_pll_c0",
-		.name = "peri_pll_c0",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const periph_pll_parents[] = {
+	"osc1",
+	"cb-intosc-hs-div2-clk",
 };
 
-static const struct clk_parent_data core1_free_mux[] = {
-	{
-		.fw_name = "main_pll_c1",
-		.name = "main_pll_c1",
-	},
-	{
-		.fw_name = "peri_pll_c0",
-		.name = "peri_pll_c0",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+/* Core free muxes */
+static const char * const core0_free_mux[] = {
+	"main_pll_c1",
+	"peri_pll_c0",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data core2_free_mux[] = {
-	{
-		.fw_name = "main_pll_c0",
-		.name = "main_pll_c0",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const core1_free_mux[] = {
+	"main_pll_c1",
+	"peri_pll_c0",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data core3_free_mux[] = {
-	{
-		.fw_name = "main_pll_c0",
-		.name = "main_pll_c0",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const core2_free_mux[] = {
+	"main_pll_c0",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data dsu_free_mux[] = {
-	{
-		.fw_name = "main_pll_c2",
-		.name = "main_pll_c2",
-	},
-	{
-		.fw_name = "peri_pll_c0",
-		.name = "peri_pll_c0",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const core3_free_mux[] = {
+	"main_pll_c0",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data noc_free_mux[] = {
-	{
-		.fw_name = "main_pll_c3",
-		.name = "main_pll_c3",
-	},
-	{
-		.fw_name = "peri_pll_c1",
-		.name = "peri_pll_c1",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const dsu_free_mux[] = {
+	"main_pll_c2",
+	"peri_pll_c0",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data emaca_free_mux[] = {
-	{
-		.fw_name = "main_pll_c1",
-		.name = "main_pll_c1",
-	},
-	{
-		.fw_name = "peri_pll_c3",
-		.name = "peri_pll_c3",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const noc_free_mux[] = {
+	"main_pll_c3",
+	"peri_pll_c1",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data emacb_free_mux[] = {
-	{
-		.fw_name = "main_pll_c1",
-		.name = "main_pll_c1",
-	},
-	{
-		.fw_name = "peri_pll_c3",
-		.name = "peri_pll_c3",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const emac_ptp_free_mux[] = {
+	"main_pll_c3",
+	"peri_pll_c3",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data emac_ptp_free_mux[] = {
-	{
-		.fw_name = "main_pll_c3",
-		.name = "main_pll_c3",
-	},
-	{
-		.fw_name = "peri_pll_c3",
-		.name = "peri_pll_c3",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const emaca_free_mux[] = {
+	"main_pll_c2",
+	"peri_pll_c3",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data gpio_db_free_mux[] = {
-	{
-		.fw_name = "main_pll_c3",
-		.name = "main_pll_c3",
-	},
-	{
-		.fw_name = "peri_pll_c1",
-		.name = "peri_pll_c1",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const emacb_free_mux[] = {
+	"main_pll_c3",
+	"peri_pll_c3",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data psi_ref_free_mux[] = {
-	{
-		.fw_name = "main_pll_c1",
-		.name = "main_pll_c1",
-	},
-	{
-		.fw_name = "peri_pll_c3",
-		.name = "peri_pll_c3",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const gpio_db_free_mux[] = {
+	"main_pll_c3",
+	"peri_pll_c1",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data usb31_free_mux[] = {
-	{
-		.fw_name = "main_pll_c3",
-		.name = "main_pll_c3",
-	},
-	{
-		.fw_name = "peri_pll_c2",
-		.name = "peri_pll_c2",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const psi_ref_free_mux[] = {
+	"main_pll_c1",
+	"peri_pll_c3",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data s2f_usr0_free_mux[] = {
-	{
-		.fw_name = "main_pll_c1",
-		.name = "main_pll_c1",
-	},
-	{
-		.fw_name = "peri_pll_c3",
-		.name = "peri_pll_c3",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const usb31_free_mux[] = {
+	"main_pll_c3",
+	"peri_pll_c2",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data s2f_usr1_free_mux[] = {
-	{
-		.fw_name = "main_pll_c1",
-		.name = "main_pll_c1",
-	},
-	{
-		.fw_name = "peri_pll_c3",
-		.name = "peri_pll_c3",
-	},
-	{
-		.fw_name = "osc1",
-		.name = "osc1",
-	},
-	{
-		.fw_name = "cb-intosc-hs-div2-clk",
-		.name = "cb-intosc-hs-div2-clk",
-	},
-	{
-		.fw_name = "f2s-free-clk",
-		.name = "f2s-free-clk",
-	},
+static const char * const s2f_user0_free_mux[] = {
+	"main_pll_c1",
+	"peri_pll_c3",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
 };
 
-static const struct clk_parent_data core0_mux[] = {
+static const char * const s2f_user1_free_mux[] = {
+	"main_pll_c1",
+	"peri_pll_c3",
+	"osc1",
+	"cb-intosc-hs-div2-clk",
+	"f2s-free-clk",
+};
+
+/* Secondary muxes between free_clk and boot_clk */
+static const char * const core0_mux[] = {
+	"core0_free_clk",
+	"boot_clk",
+};
+
+static const char * const core1_mux[] = {
+	"core1_free_clk",
+	"boot_clk",
+};
+
+static const char * const core2_mux[] = {
+	"core2_free_clk",
+	"boot_clk",
+};
+
+static const char * const core3_mux[] = {
+	"core3_free_clk",
+	"boot_clk",
+};
+
+static const char * const dsu_mux[] = {
+	"dsu_free_clk",
+	"boot_clk",
+};
+
+static const char * const noc_mux[] = {
+	"noc_free_clk",
+	"boot_clk",
+};
+
+static const char * const emac_mux[] = {
+	"emaca_free_clk",
+	"emacb_free_clk",
+	"boot_clk",
+};
+
+static const char * const s2f_user0_mux[] = {
+	"s2f_user0_free_clk",
+	"boot_clk",
+};
+
+static const char * const s2f_user1_mux[] = {
+	"s2f_user1_free_clk",
+	"boot_clk",
+};
+
+static const char * const psi_mux[] = {
+	"psi_ref_free_clk",
+	"boot_clk",
+};
+
+static const char * const gpio_db_mux[] = {
+	"gpio_db_free_clk",
+	"boot_clk",
+};
+
+static const char * const emac_ptp_mux[] = {
+	"emac_ptp_free_clk",
+	"boot_clk",
+};
+
+static const char * const usb31_mux[] = {
+	"usb31_free_clk",
+	"boot_clk",
+};
+
+static const struct agilex5_pll_clock agilex5_pll_clks[] = {
 	{
-		.fw_name = "core0_free_clk",
-		.name = "core0_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
+		.id = AGILEX5_BOOT_CLK,
 		.name = "boot_clk",
+		.parent_names = boot_pll_parents,
+		.num_parents = ARRAY_SIZE(boot_pll_parents),
+		.flags = 0,
+		.offset = 0x0,
+	},
+	{
+		.id = AGILEX5_MAIN_PLL_CLK,
+		.name = "main_pll",
+		.parent_names = main_pll_parents,
+		.num_parents = ARRAY_SIZE(main_pll_parents),
+		.flags = 0,
+		.offset = 0x48,
+	},
+	{
+		.id = AGILEX5_PERIPH_PLL_CLK,
+		.name = "periph_pll",
+		.parent_names = periph_pll_parents,
+		.num_parents = ARRAY_SIZE(periph_pll_parents),
+		.flags = 0,
+		.offset = 0x9C,
 	},
 };
 
-static const struct clk_parent_data core1_mux[] = {
-	{
-		.fw_name = "core1_free_clk",
-		.name = "core1_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data core2_mux[] = {
-	{
-		.fw_name = "core2_free_clk",
-		.name = "core2_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data core3_mux[] = {
-	{
-		.fw_name = "core3_free_clk",
-		.name = "core3_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data dsu_mux[] = {
-	{
-		.fw_name = "dsu_free_clk",
-		.name = "dsu_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data emac_mux[] = {
-	{
-		.fw_name = "emaca_free_clk",
-		.name = "emaca_free_clk",
-	},
-	{
-		.fw_name = "emacb_free_clk",
-		.name = "emacb_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data noc_mux[] = {
-	{
-		.fw_name = "noc_free_clk",
-		.name = "noc_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data s2f_user0_mux[] = {
-	{
-		.fw_name = "s2f_user0_free_clk",
-		.name = "s2f_user0_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data s2f_user1_mux[] = {
-	{
-		.fw_name = "s2f_user1_free_clk",
-		.name = "s2f_user1_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data psi_mux[] = {
-	{
-		.fw_name = "psi_ref_free_clk",
-		.name = "psi_ref_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data gpio_db_mux[] = {
-	{
-		.fw_name = "gpio_db_free_clk",
-		.name = "gpio_db_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data emac_ptp_mux[] = {
-	{
-		.fw_name = "emac_ptp_free_clk",
-		.name = "emac_ptp_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-static const struct clk_parent_data usb31_mux[] = {
-	{
-		.fw_name = "usb31_free_clk",
-		.name = "usb31_free_clk",
-	},
-	{
-		.fw_name = "boot_clk",
-		.name = "boot_clk",
-	},
-};
-
-/*
- * TODO - Clocks in AO (always on) controller
- * 2 main PLLs only
- */
-static const struct stratix10_pll_clock agilex5_pll_clks[] = {
-	{ AGILEX5_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
-	  0x0 },
-	{ AGILEX5_MAIN_PLL_CLK, "main_pll", pll_mux, ARRAY_SIZE(pll_mux), 0,
-	  0x48 },
-	{ AGILEX5_PERIPH_PLL_CLK, "periph_pll", pll_mux, ARRAY_SIZE(pll_mux), 0,
-	  0x9C },
-};
-
+/* Main PLL C0, C1, C2, C3 and Peri PLL C0, C1, C2, C3. With ping-pong counter. */
 static const struct stratix10_perip_c_clock agilex5_main_perip_c_clks[] = {
 	{ AGILEX5_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0,
 	  0x5C },
@@ -532,160 +256,153 @@ static const struct stratix10_perip_c_clock agilex5_main_perip_c_clks[] = {
 };
 
 /* Non-SW clock-gated enabled clocks */
-static const struct stratix10_perip_cnt_clock agilex5_main_perip_cnt_clks[] = {
-	{ AGILEX5_CORE0_FREE_CLK, "core0_free_clk", NULL, core0_free_mux,
-	ARRAY_SIZE(core0_free_mux), 0, 0x0104, 0, 0, 0},
-	{ AGILEX5_CORE1_FREE_CLK, "core1_free_clk", NULL, core1_free_mux,
+static const struct agilex5_perip_cnt_clock agilex5_main_perip_cnt_clks[] = {
+	{ AGILEX5_CORE0_FREE_CLK, "core0_free_clk", core0_free_mux,
+	ARRAY_SIZE(core0_free_mux), 0, 0x0100, 0, 0, 0},
+	{ AGILEX5_CORE1_FREE_CLK, "core1_free_clk", core1_free_mux,
 	ARRAY_SIZE(core1_free_mux), 0, 0x0104, 0, 0, 0},
-	{ AGILEX5_CORE2_FREE_CLK, "core2_free_clk", NULL, core2_free_mux,
+	{ AGILEX5_CORE2_FREE_CLK, "core2_free_clk", core2_free_mux,
 	ARRAY_SIZE(core2_free_mux), 0, 0x010C, 0, 0, 0},
-	{ AGILEX5_CORE3_FREE_CLK, "core3_free_clk", NULL, core3_free_mux,
+	{ AGILEX5_CORE3_FREE_CLK, "core3_free_clk", core3_free_mux,
 	ARRAY_SIZE(core3_free_mux), 0, 0x0110, 0, 0, 0},
-	{ AGILEX5_DSU_FREE_CLK, "dsu_free_clk", NULL, dsu_free_mux,
-	ARRAY_SIZE(dsu_free_mux), 0, 0x0100, 0, 0, 0},
-	{ AGILEX5_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux,
-	  ARRAY_SIZE(noc_free_mux), 0, 0x40, 0, 0, 0 },
-	{ AGILEX5_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux,
-	  ARRAY_SIZE(emaca_free_mux), 0, 0xD4, 0, 0x88, 0 },
-	{ AGILEX5_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux,
-	  ARRAY_SIZE(emacb_free_mux), 0, 0xD8, 0, 0x88, 1 },
-	{ AGILEX5_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL,
-	  emac_ptp_free_mux, ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88,
-	  2 },
-	{ AGILEX5_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
-	  ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3 },
-	{ AGILEX5_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL,
-	  s2f_usr0_free_mux, ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0x30,
-	  2 },
-	{ AGILEX5_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL,
-	  s2f_usr1_free_mux, ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88,
-	  5 },
-	{ AGILEX5_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
-	  ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6 },
-	{ AGILEX5_USB31_FREE_CLK, "usb31_free_clk", NULL, usb31_free_mux,
-	  ARRAY_SIZE(usb31_free_mux), 0, 0xF8, 0, 0x88, 7},
+	{ AGILEX5_DSU_FREE_CLK, "dsu_free_clk", dsu_free_mux,
+	ARRAY_SIZE(dsu_free_mux), 0, 0xfc, 0, 0, 0},
+	{ AGILEX5_NOC_FREE_CLK, "noc_free_clk", noc_free_mux,
+	ARRAY_SIZE(noc_free_mux), 0, 0x40, 0, 0, 0 },
+	{ AGILEX5_EMAC_A_FREE_CLK, "emaca_free_clk", emaca_free_mux,
+	ARRAY_SIZE(emaca_free_mux), 0, 0xD4, 0, 0x88, 0 },
+	{ AGILEX5_EMAC_B_FREE_CLK, "emacb_free_clk", emacb_free_mux,
+	ARRAY_SIZE(emacb_free_mux), 0, 0xD8, 0, 0x88, 1 },
+	{ AGILEX5_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", emac_ptp_free_mux,
+	ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88, 2 },
+	{ AGILEX5_GPIO_DB_FREE_CLK, "gpio_db_free_clk", gpio_db_free_mux,
+	ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3 },
+	{ AGILEX5_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", s2f_user0_free_mux,
+	ARRAY_SIZE(s2f_user0_free_mux), 0, 0xE8, 0, 0x30, 2 },
+	{ AGILEX5_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", s2f_user1_free_mux,
+	ARRAY_SIZE(s2f_user1_free_mux), 0, 0xEC, 0, 0x88, 5 },
+	{ AGILEX5_PSI_REF_FREE_CLK, "psi_ref_free_clk", psi_ref_free_mux,
+	ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6 },
+	{ AGILEX5_USB31_FREE_CLK, "usb31_free_clk", usb31_free_mux,
+	ARRAY_SIZE(usb31_free_mux), 0, 0xF8, 0, 0x88, 7},
 };
 
+static const char * const cs_pdbg_parents[] = { "cs_at_clk" };
+static const char * const usb31_bus_clk_early_parents[] = { "l4_main_clk" };
+static const char * const l4_mp_clk_parent[] = { "l4_mp_clk" };
+static const char * const l4_sp_clk_parent[] = { "l4_sp_clk" };
+static const char * const dfi_clk_parent[] = { "dfi_clk" };
+
 /* SW Clock gate enabled clocks */
-static const struct stratix10_gate_clock agilex5_gate_clks[] = {
-
-	/* TODO HW Managed Clocks list */
-
-	/* TODO SW Managed Clocks list */
-
-	/* Main PLL0 Begin */
-	/* MPU clocks */
-	{ AGILEX5_CORE0_CLK, "core0_clk", NULL, core0_mux,
+static const struct agilex5_gate_clock agilex5_gate_clks[] = {
+	{ AGILEX5_CORE0_CLK, "core0_clk", core0_mux,
 	  ARRAY_SIZE(core0_mux), 0, 0x24, 8, 0, 0, 0, 0x30, 5, 0 },
-	{ AGILEX5_CORE1_CLK, "core1_clk", NULL, core1_mux,
+	{ AGILEX5_CORE1_CLK, "core1_clk", core1_mux,
 	  ARRAY_SIZE(core1_mux), 0, 0x24, 9, 0, 0, 0, 0x30, 5, 0 },
-	{ AGILEX5_CORE2_CLK, "core2_clk", NULL, core2_mux,
+	{ AGILEX5_CORE2_CLK, "core2_clk", core2_mux,
 	  ARRAY_SIZE(core2_mux), 0, 0x24, 10, 0, 0, 0, 0x30, 6, 0 },
-	{ AGILEX5_CORE3_CLK, "core3_clk", NULL, core3_mux,
+	{ AGILEX5_CORE3_CLK, "core3_clk", core3_mux,
 	  ARRAY_SIZE(core3_mux), 0, 0x24, 11, 0, 0, 0, 0x30, 7, 0 },
-	{ AGILEX5_MPU_CLK, "dsu_clk", NULL, dsu_mux, ARRAY_SIZE(dsu_mux), 0, 0,
-	  0, 0, 0, 0, 0x34, 4, 0 },
-	{ AGILEX5_MPU_PERIPH_CLK, "mpu_periph_clk", NULL, dsu_mux,
+	{ AGILEX5_MPU_CLK, "dsu_clk", dsu_mux, ARRAY_SIZE(dsu_mux), 0, 0, 0,
+	  0, 0, 0, 0x34, 4, 0 },
+	{ AGILEX5_MPU_PERIPH_CLK, "mpu_periph_clk", dsu_mux,
 	  ARRAY_SIZE(dsu_mux), 0, 0, 0, 0x44, 20, 2, 0x34, 4, 0 },
-	{ AGILEX5_MPU_CCU_CLK, "mpu_ccu_clk", NULL, dsu_mux,
+	{ AGILEX5_MPU_CCU_CLK, "mpu_ccu_clk", dsu_mux,
 	  ARRAY_SIZE(dsu_mux), 0, 0, 0, 0x44, 18, 2, 0x34, 4, 0 },
-
-	/* ANGTS TODO l4 main clk has no divider now. To check. */
-	{ AGILEX5_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux,
-	  ARRAY_SIZE(noc_mux), 0, 0x24, 1, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
+	{ AGILEX5_L4_MAIN_CLK, "l4_main_clk", noc_mux, ARRAY_SIZE(noc_mux),
+	  CLK_IS_CRITICAL, 0x24, 1, 0, 0, 0, 0, 0, 0 },
+	{ AGILEX5_L4_MP_CLK, "l4_mp_clk", noc_mux, ARRAY_SIZE(noc_mux), 0,
 	  0x24, 2, 0x44, 4, 2, 0x30, 1, 0 },
-	{ AGILEX5_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux,
+	{ AGILEX5_L4_SYS_FREE_CLK, "l4_sys_free_clk", noc_mux,
 	  ARRAY_SIZE(noc_mux), 0, 0, 0, 0x44, 2, 2, 0x30, 1, 0 },
-	{ AGILEX5_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux),
+	{ AGILEX5_L4_SP_CLK, "l4_sp_clk", noc_mux, ARRAY_SIZE(noc_mux),
 	  CLK_IS_CRITICAL, 0x24, 3, 0x44, 6, 2, 0x30, 1, 0 },
 
 	/* Core sight clocks*/
-	{ AGILEX5_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
+	{ AGILEX5_CS_AT_CLK, "cs_at_clk", noc_mux, ARRAY_SIZE(noc_mux), 0,
 	  0x24, 4, 0x44, 24, 2, 0x30, 1, 0 },
-	{ AGILEX5_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux,
+	{ AGILEX5_CS_TRACE_CLK, "cs_trace_clk", noc_mux,
 	  ARRAY_SIZE(noc_mux), 0, 0x24, 4, 0x44, 26, 2, 0x30, 1, 0 },
-	{ AGILEX5_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24, 4,
+	{ AGILEX5_CS_PDBG_CLK, "cs_pdbg_clk", cs_pdbg_parents, 1, 0, 0x24, 4,
 	  0x44, 28, 1, 0, 0, 0 },
-	/* Main PLL0 End */
 
 	/* Main Peripheral PLL1 Begin */
-	{ AGILEX5_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux),
+	{ AGILEX5_EMAC0_CLK, "emac0_clk", emac_mux, ARRAY_SIZE(emac_mux),
 	  0, 0x7C, 0, 0, 0, 0, 0x94, 26, 0 },
-	{ AGILEX5_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux),
+	{ AGILEX5_EMAC1_CLK, "emac1_clk", emac_mux, ARRAY_SIZE(emac_mux),
 	  0, 0x7C, 1, 0, 0, 0, 0x94, 27, 0 },
-	{ AGILEX5_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux),
+	{ AGILEX5_EMAC2_CLK, "emac2_clk", emac_mux, ARRAY_SIZE(emac_mux),
 	  0, 0x7C, 2, 0, 0, 0, 0x94, 28, 0 },
-	{ AGILEX5_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux,
+	{ AGILEX5_EMAC_PTP_CLK, "emac_ptp_clk", emac_ptp_mux,
 	  ARRAY_SIZE(emac_ptp_mux), 0, 0x7C, 3, 0, 0, 0, 0x88, 2, 0 },
-	{ AGILEX5_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux,
+	{ AGILEX5_GPIO_DB_CLK, "gpio_db_clk", gpio_db_mux,
 	  ARRAY_SIZE(gpio_db_mux), 0, 0x7C, 4, 0x98, 0, 16, 0x88, 3, 1 },
 	  /* Main Peripheral PLL1 End */
 
 	  /* Peripheral clocks  */
-	{ AGILEX5_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_user0_mux,
+	{ AGILEX5_S2F_USER0_CLK, "s2f_user0_clk", s2f_user0_mux,
 	  ARRAY_SIZE(s2f_user0_mux), 0, 0x24, 6, 0, 0, 0, 0x30, 2, 0 },
-	{ AGILEX5_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux,
+	{ AGILEX5_S2F_USER1_CLK, "s2f_user1_clk", s2f_user1_mux,
 	  ARRAY_SIZE(s2f_user1_mux), 0, 0x7C, 6, 0, 0, 0, 0x88, 5, 0 },
-	{ AGILEX5_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux,
+	{ AGILEX5_PSI_REF_CLK, "psi_ref_clk", psi_mux,
 	  ARRAY_SIZE(psi_mux), 0, 0x7C, 7, 0, 0, 0, 0x88, 6, 0 },
-	{ AGILEX5_USB31_SUSPEND_CLK, "usb31_suspend_clk", NULL, usb31_mux,
+	{ AGILEX5_USB31_SUSPEND_CLK, "usb31_suspend_clk", usb31_mux,
 	  ARRAY_SIZE(usb31_mux), 0, 0x7C, 25, 0, 0, 0, 0x88, 7, 0 },
-	{ AGILEX5_USB31_BUS_CLK_EARLY, "usb31_bus_clk_early", "l4_main_clk",
-	  NULL, 1, 0, 0x7C, 25, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_USB2OTG_HCLK, "usb2otg_hclk", "l4_mp_clk", NULL, 1, 0, 0x7C,
+	{ AGILEX5_USB31_BUS_CLK_EARLY, "usb31_bus_clk_early", usb31_bus_clk_early_parents,
+	  1, 0, 0x7C, 25, 0, 0, 0, 0, 0, 0 },
+	{ AGILEX5_USB2OTG_HCLK, "usb2otg_hclk", l4_mp_clk_parent, 1, 0, 0x7C,
 	  8, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_SPIM_0_CLK, "spim_0_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, 9,
+	{ AGILEX5_SPIM_0_CLK, "spim_0_clk", l4_mp_clk_parent, 1, 0, 0x7C, 9,
 	  0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_SPIM_1_CLK, "spim_1_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, 11,
+	{ AGILEX5_SPIM_1_CLK, "spim_1_clk", l4_mp_clk_parent, 1, 0, 0x7C, 11,
 	  0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_SPIS_0_CLK, "spis_0_clk", "l4_sp_clk", NULL, 1, 0, 0x7C, 12,
+	{ AGILEX5_SPIS_0_CLK, "spis_0_clk", l4_sp_clk_parent, 1, 0, 0x7C, 12,
 	  0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_SPIS_1_CLK, "spis_1_clk", "l4_sp_clk", NULL, 1, 0, 0x7C, 13,
+	{ AGILEX5_SPIS_1_CLK, "spis_1_clk", l4_sp_clk_parent, 1, 0, 0x7C, 13,
 	  0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_DMA_CORE_CLK, "dma_core_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
+	{ AGILEX5_DMA_CORE_CLK, "dma_core_clk", l4_mp_clk_parent, 1, 0, 0x7C,
 	  14, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_DMA_HS_CLK, "dma_hs_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, 14,
+	{ AGILEX5_DMA_HS_CLK, "dma_hs_clk", l4_mp_clk_parent, 1, 0, 0x7C, 14,
 	  0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_I3C_0_CORE_CLK, "i3c_0_core_clk", "l4_mp_clk", NULL, 1, 0,
+	{ AGILEX5_I3C_0_CORE_CLK, "i3c_0_core_clk", l4_mp_clk_parent, 1, 0,
 	  0x7C, 18, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_I3C_1_CORE_CLK, "i3c_1_core_clk", "l4_mp_clk", NULL, 1, 0,
+	{ AGILEX5_I3C_1_CORE_CLK, "i3c_1_core_clk", l4_mp_clk_parent, 1, 0,
 	  0x7C, 19, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_I2C_0_PCLK, "i2c_0_pclk", "l4_sp_clk", NULL, 1, 0, 0x7C, 15,
+	{ AGILEX5_I2C_0_PCLK, "i2c_0_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 15,
 	  0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_I2C_1_PCLK, "i2c_1_pclk", "l4_sp_clk", NULL, 1, 0, 0x7C, 16,
+	{ AGILEX5_I2C_1_PCLK, "i2c_1_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 16,
 	  0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_I2C_EMAC0_PCLK, "i2c_emac0_pclk", "l4_sp_clk", NULL, 1, 0,
+	{ AGILEX5_I2C_EMAC0_PCLK, "i2c_emac0_pclk", l4_sp_clk_parent, 1, 0,
 	  0x7C, 17, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_I2C_EMAC1_PCLK, "i2c_emac1_pclk", "l4_sp_clk", NULL, 1, 0,
+	{ AGILEX5_I2C_EMAC1_PCLK, "i2c_emac1_pclk", l4_sp_clk_parent, 1, 0,
 	  0x7C, 22, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_I2C_EMAC2_PCLK, "i2c_emac2_pclk", "l4_sp_clk", NULL, 1, 0,
+	{ AGILEX5_I2C_EMAC2_PCLK, "i2c_emac2_pclk", l4_sp_clk_parent, 1, 0,
 	  0x7C, 27, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_UART_0_PCLK, "uart_0_pclk", "l4_sp_clk", NULL, 1, 0, 0x7C, 20,
+	{ AGILEX5_UART_0_PCLK, "uart_0_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 20,
 	  0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_UART_1_PCLK, "uart_1_pclk", "l4_sp_clk", NULL, 1, 0, 0x7C, 21,
+	{ AGILEX5_UART_1_PCLK, "uart_1_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 21,
 	  0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_SPTIMER_0_PCLK, "sptimer_0_pclk", "l4_sp_clk", NULL, 1, 0,
+	{ AGILEX5_SPTIMER_0_PCLK, "sptimer_0_pclk", l4_sp_clk_parent, 1, 0,
 	  0x7C, 23, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_SPTIMER_1_PCLK, "sptimer_1_pclk", "l4_sp_clk", NULL, 1, 0,
+	{ AGILEX5_SPTIMER_1_PCLK, "sptimer_1_pclk", l4_sp_clk_parent, 1, 0,
 	  0x7C, 24, 0, 0, 0, 0, 0, 0 },
 
 	/*NAND, SD/MMC and SoftPHY overall clocking*/
-	{ AGILEX5_DFI_CLK, "dfi_clk", "l4_mp_clk", NULL, 1, 0, 0, 0, 0x44, 16,
+	{ AGILEX5_DFI_CLK, "dfi_clk", l4_mp_clk_parent, 1, 0, 0, 0, 0x44, 16,
 	  2, 0, 0, 0 },
-	{ AGILEX5_NAND_NF_CLK, "nand_nf_clk", "dfi_clk", NULL, 1, 0, 0x7C, 10,
+	{ AGILEX5_NAND_NF_CLK, "nand_nf_clk", dfi_clk_parent, 1, 0, 0x7C, 10,
 	  0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_NAND_BCH_CLK, "nand_bch_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
+	{ AGILEX5_NAND_BCH_CLK, "nand_bch_clk", l4_mp_clk_parent, 1, 0, 0x7C,
 	  10, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_SDMMC_SDPHY_REG_CLK, "sdmmc_sdphy_reg_clk", "l4_mp_clk", NULL,
+	{ AGILEX5_SDMMC_SDPHY_REG_CLK, "sdmmc_sdphy_reg_clk", l4_mp_clk_parent,
 	  1, 0, 0x7C, 5, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_SDMCLK, "sdmclk", "dfi_clk", NULL, 1, 0, 0x7C, 5, 0, 0, 0, 0,
-	  0, 0 },
-	{ AGILEX5_SOFTPHY_REG_PCLK, "softphy_reg_pclk", "l4_mp_clk", NULL, 1, 0,
+	{ AGILEX5_SDMCLK, "sdmclk", dfi_clk_parent, 1, 0, 0x7C, 5, 0, 0, 0,
+	  0, 0, 0 },
+	{ AGILEX5_SOFTPHY_REG_PCLK, "softphy_reg_pclk", l4_mp_clk_parent, 1, 0,
 	  0x7C, 26, 0, 0, 0, 0, 0, 0 },
-	{ AGILEX5_SOFTPHY_PHY_CLK, "softphy_phy_clk", "l4_mp_clk", NULL, 1, 0,
+	{ AGILEX5_SOFTPHY_PHY_CLK, "softphy_phy_clk", l4_mp_clk_parent, 1, 0,
 	  0x7C, 26, 0x44, 16, 2, 0, 0, 0 },
-	{ AGILEX5_SOFTPHY_CTRL_CLK, "softphy_ctrl_clk", "dfi_clk", NULL, 1, 0,
+	{ AGILEX5_SOFTPHY_CTRL_CLK, "softphy_ctrl_clk", dfi_clk_parent, 1, 0,
 	  0x7C, 26, 0, 0, 0, 0, 0, 0 },
 };
 
@@ -710,7 +427,7 @@ agilex5_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
 }
 
 static int
-agilex5_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
+agilex5_clk_register_cnt_perip(const struct agilex5_perip_cnt_clock *clks,
 			       int nums, struct stratix10_clock_data *data)
 {
 	struct clk_hw *hw_clk;
@@ -718,7 +435,7 @@ agilex5_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
 	int i;
 
 	for (i = 0; i < nums; i++) {
-		hw_clk = s10_register_cnt_periph(&clks[i], base);
+		hw_clk = agilex5_register_cnt_periph(&clks[i], base);
 		if (IS_ERR(hw_clk)) {
 			pr_err("%s: failed to register clock %s\n", __func__,
 			       clks[i].name);
@@ -730,7 +447,7 @@ agilex5_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
 	return 0;
 }
 
-static int agilex5_clk_register_gate(const struct stratix10_gate_clock *clks,
+static int agilex5_clk_register_gate(const struct agilex5_gate_clock *clks,
 				     int nums,
 				     struct stratix10_clock_data *data)
 {
@@ -739,7 +456,7 @@ static int agilex5_clk_register_gate(const struct stratix10_gate_clock *clks,
 	int i;
 
 	for (i = 0; i < nums; i++) {
-		hw_clk = agilex_register_gate(&clks[i], base);
+		hw_clk = agilex5_register_gate(&clks[i], base);
 		if (IS_ERR(hw_clk)) {
 			pr_err("%s: failed to register clock %s\n", __func__,
 			       clks[i].name);
@@ -751,7 +468,7 @@ static int agilex5_clk_register_gate(const struct stratix10_gate_clock *clks,
 	return 0;
 }
 
-static int agilex5_clk_register_pll(const struct stratix10_pll_clock *clks,
+static int agilex5_clk_register_pll(const struct agilex5_pll_clock *clks,
 				    int nums, struct stratix10_clock_data *data)
 {
 	struct clk_hw *hw_clk;
@@ -797,6 +514,7 @@ static int agilex5_clkmgr_probe(struct device *dev)
 	agilex5_clk_register_pll(agilex5_pll_clks, ARRAY_SIZE(agilex5_pll_clks),
 				 clk_data);
 
+	/* mainPLL C0, C1, C2, C3 and periph PLL C0, C1, C2, C3*/
 	agilex5_clk_register_c_perip(agilex5_main_perip_c_clks,
 				     ARRAY_SIZE(agilex5_main_perip_c_clks),
 				     clk_data);
diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c
index 8fc8a4ea7b8f..fc803b69a2a0 100644
--- a/drivers/clk/socfpga/clk-gate-s10.c
+++ b/drivers/clk/socfpga/clk-gate-s10.c
@@ -124,12 +124,11 @@ static const struct clk_ops dbgclk_ops = {
 	.get_parent = socfpga_gate_get_parent,
 };
 
-struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, void __iomem *regbase)
+struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks, void __iomem *regbase)
 {
 	struct clk_hw *hw_clk;
 	struct socfpga_gate_clk *socfpga_clk;
 	struct clk_init_data init;
-	const char *parent_name = clks->parent_name;
 	int ret;
 
 	socfpga_clk = xzalloc(sizeof(*socfpga_clk));
@@ -161,9 +160,7 @@ struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, voi
 	init.name = clks->name;
 	init.flags = clks->flags;
 	init.num_parents = clks->num_parents;
-	init.parent_names = parent_name ? &parent_name : NULL;
-	if (init.parent_names == NULL)
-		init.parent_data = clks->parent_data;
+	init.parent_names = clks->parent_names;
 	socfpga_clk->hw.hw.init = &init;
 	hw_clk = &socfpga_clk->hw.hw;
 
diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c
index 3f527e43f0b7..4c3184b92fbe 100644
--- a/drivers/clk/socfpga/clk-periph-s10.c
+++ b/drivers/clk/socfpga/clk-periph-s10.c
@@ -157,3 +157,41 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c
 	}
 	return hw_clk;
 }
+
+struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock *clks,
+					   void __iomem *regbase)
+{
+	struct clk_hw *hw_clk;
+	struct socfpga_periph_clk *periph_clk;
+	struct clk_init_data init;
+	const char *name = clks->name;
+	int ret;
+
+	periph_clk = xzalloc(sizeof(*periph_clk));
+
+	if (clks->offset)
+		periph_clk->hw.reg = regbase + clks->offset;
+	else
+		periph_clk->hw.reg = NULL;
+
+	if (clks->bypass_reg)
+		periph_clk->bypass_reg = regbase + clks->bypass_reg;
+	else
+		periph_clk->bypass_reg = NULL;
+	periph_clk->bypass_shift = clks->bypass_shift;
+	periph_clk->fixed_div = clks->fixed_divider;
+
+	init.name = name;
+	init.ops = &peri_cnt_clk_ops;
+	init.flags = clks->flags;
+	init.num_parents = clks->num_parents;
+	init.parent_names = clks->parent_names;
+	periph_clk->hw.hw.init = &init;
+	hw_clk = &periph_clk->hw.hw;
+
+	ret = clk_hw_register(NULL, hw_clk);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return hw_clk;
+}
diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c
index 4c00c0e7481a..be07d735181e 100644
--- a/drivers/clk/socfpga/clk-pll-s10.c
+++ b/drivers/clk/socfpga/clk-pll-s10.c
@@ -113,7 +113,7 @@ static const struct clk_ops clk_boot_ops = {
 	.enable = clk_pll_enable,
 };
 
-struct clk_hw *agilex5_register_pll(const struct stratix10_pll_clock *clks,
+struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks,
 				    void __iomem *reg)
 {
 	struct clk_hw *hw_clk;
@@ -134,8 +134,7 @@ struct clk_hw *agilex5_register_pll(const struct stratix10_pll_clock *clks,
 	init.name = name;
 	init.flags = clks->flags;
 	init.num_parents = clks->num_parents;
-	init.parent_names = NULL;
-	init.parent_data = clks->parent_data;
+	init.parent_names = clks->parent_names;
 	pll_clk->hw.hw.init = &init;
 	pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER;
 	hw_clk = &pll_clk->hw.hw;
diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h
index 1fe025f65f7a..bd13424e8557 100644
--- a/drivers/clk/socfpga/stratix10-clk.h
+++ b/drivers/clk/socfpga/stratix10-clk.h
@@ -1,4 +1,5 @@
 /* SPDX-License-Identifier:    GPL-2.0 */
+/* SPDX-Comment: Origin-URL: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clk/socfpga/stratix10-clk.h?id=2050b57ecda040010ec797fb07713889372c5041 */
 /*
  * Copyright (C) 2017, Intel Corporation
  */
@@ -62,12 +63,51 @@ struct stratix10_gate_clock {
 	u8			fixed_div;
 };
 
-struct clk_hw *agilex5_register_pll(const struct stratix10_pll_clock *clks,
-				void __iomem *reg);
+struct agilex5_pll_clock {
+	unsigned int	id;
+	const char	*name;
+	const char	* const *parent_names;
+	u8	num_parents;
+	unsigned long   flags;
+	unsigned long   offset;
+};
+
+struct agilex5_perip_cnt_clock {
+	unsigned int		id;
+	const char		*name;
+	const char	* const *parent_names;
+	u8			num_parents;
+	unsigned long		flags;
+	unsigned long		offset;
+	u8			fixed_divider;
+	unsigned long		bypass_reg;
+	unsigned long		bypass_shift;
+};
+
+struct agilex5_gate_clock {
+	unsigned int		id;
+	const char		*name;
+	const char	* const *parent_names;
+	u8			num_parents;
+	unsigned long		flags;
+	unsigned long		gate_reg;
+	u8			gate_idx;
+	unsigned long		div_reg;
+	u8			div_offset;
+	u8			div_width;
+	unsigned long		bypass_reg;
+	u8			bypass_shift;
+	u8			fixed_div;
+};
+
+struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks,
+				    void __iomem *reg);
+struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock *clks,
+					   void __iomem *regbase);
+struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks,
+				     void __iomem *regbase);
 struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks,
 				void __iomem *reg);
 struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks,
 				    void __iomem *reg);
-struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks,
-			      void __iomem *reg);
 #endif	/* __STRATIX10_CLK_H */

-- 
2.47.3




^ permalink raw reply related

* [PATCH v2 0/4] clk: socfpga: agilex5: sync with kernel
From: Michael Tretter @ 2026-06-05 13:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

This is a v2 of the patch series [0] to synchronize the socfpga clock
driver with the kernel driver, which was applied by reverted due to a
compile error.

This series split the original patch into cleanup patches to synchronize
the entire socfpga clock driver with the Linux driver and another patch
to apply the synchronization of the actual Agilex5 driver. Otherwise,
the fix of the compile error would have resulted in inconsistent structs
for the various clocks.

I runtime tested this patch series only on Agilex 5, and only did build
tests on the other SoCFPGA platforms.

[0] https://lore.kernel.org/all/20251215-v2025-11-0-topic-socfpga-agilex5-clk-v1-1-e1270179d761@pengutronix.de/

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
Michael Tretter (2):
      clk: socfpga: sync arria10 clock initialization with kernel
      clk: socfpga: remove clk-phase setting

Steffen Trumtrar (2):
      clk: socfpga: sync clock structs with kernel
      clk: socfpga: agilex5: sync with kernel

 drivers/clk/socfpga/clk-agilex5.c    | 842 ++++++++++++-----------------------
 drivers/clk/socfpga/clk-gate-a10.c   | 104 +----
 drivers/clk/socfpga/clk-gate-s10.c   |  32 +-
 drivers/clk/socfpga/clk-periph-a10.c |  39 +-
 drivers/clk/socfpga/clk-periph-s10.c |  66 ++-
 drivers/clk/socfpga/clk-pll-a10.c    |  56 +--
 drivers/clk/socfpga/clk-pll-s10.c    |  57 ++-
 drivers/clk/socfpga/clk.h            |  15 +-
 drivers/clk/socfpga/stratix10-clk.h  |  48 +-
 9 files changed, 498 insertions(+), 761 deletions(-)
---
base-commit: 713a1e59dfea4516446822323b7c0db571cb214f
change-id: 20260604-socfpga-agilex5-clk-50bede6b1c8d

Best regards,
-- 
Michael Tretter <m.tretter@pengutronix.de>




^ permalink raw reply

* [PATCH v2 3/4] clk: socfpga: sync clock structs with kernel
From: Michael Tretter @ 2026-06-05 13:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter
In-Reply-To: <20260605-socfpga-agilex5-clk-v2-0-780562ec169f@pengutronix.de>

From: Steffen Trumtrar <s.trumtrar@pengutronix.de>

Sync struct socfpga_pll, struct socfpga_gate_clk, and struct
socfpga_periph_clk and change the base from clk_hw to clk_gate. This
allows easier syncing with the Linux driver.

Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 drivers/clk/socfpga/clk-gate-a10.c   | 26 +++++++++---------
 drivers/clk/socfpga/clk-gate-s10.c   | 25 ++++++++---------
 drivers/clk/socfpga/clk-periph-a10.c | 14 +++++-----
 drivers/clk/socfpga/clk-periph-s10.c | 28 ++++++++++---------
 drivers/clk/socfpga/clk-pll-a10.c    | 29 ++++++++++----------
 drivers/clk/socfpga/clk-pll-s10.c    | 52 ++++++++++++++++++++++--------------
 drivers/clk/socfpga/clk.h            | 15 +++--------
 7 files changed, 96 insertions(+), 93 deletions(-)

diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
index b43e19d2ca3f..dfa227b3f74e 100644
--- a/drivers/clk/socfpga/clk-gate-a10.c
+++ b/drivers/clk/socfpga/clk-gate-a10.c
@@ -14,7 +14,7 @@
 
 #include "clk.h"
 
-#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw)
+#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw)
 
 /* SDMMC Group for System Manager defines */
 #define SYSMGR_SDMMCGRP_CTRL_OFFSET	0x28
@@ -41,9 +41,9 @@ static int clk_socfpga_enable(struct clk_hw *hw)
 	struct socfpga_gate_clk *socfpga_clk = to_socfpga_gate_clk(hw);
 	u32 val;
 
-	val = readl(socfpga_clk->reg);
-	val |= 1 << socfpga_clk->bit_idx;
-	writel(val, socfpga_clk->reg);
+	val = readl(socfpga_clk->hw.reg);
+	val |= 1 << socfpga_clk->hw.bit_idx;
+	writel(val, socfpga_clk->hw.reg);
 
 	return 0;
 }
@@ -53,9 +53,9 @@ static void clk_socfpga_disable(struct clk_hw *hw)
 	struct socfpga_gate_clk *socfpga_clk = to_socfpga_gate_clk(hw);
 	u32 val;
 
-	val = readl(socfpga_clk->reg);
-	val &= ~(1 << socfpga_clk->shift);
-	writel(val, socfpga_clk->reg);
+	val = readl(socfpga_clk->hw.reg);
+	val &= ~(1 << socfpga_clk->hw.shift);
+	writel(val, socfpga_clk->hw.reg);
 }
 
 static struct clk_ops gateclk_ops = {
@@ -63,7 +63,7 @@ static struct clk_ops gateclk_ops = {
 };
 
 static struct clk *__socfpga_gate_init(struct device_node *node,
-	const struct clk_ops *ops)
+				       const struct clk_ops *ops)
 {
 	u32 clk_gate[2];
 	u32 div_reg[3];
@@ -82,8 +82,8 @@ static struct clk *__socfpga_gate_init(struct device_node *node,
 		clk_gate[0] = 0;
 
 	if (clk_gate[0]) {
-		socfpga_clk->reg = clk_mgr_base_addr + clk_gate[0];
-		socfpga_clk->bit_idx = clk_gate[1];
+		socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
+		socfpga_clk->hw.bit_idx = clk_gate[1];
 
 		gateclk_ops.enable = clk_socfpga_enable;
 		gateclk_ops.disable = clk_socfpga_disable;
@@ -112,14 +112,14 @@ static struct clk *__socfpga_gate_init(struct device_node *node,
 
 	init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS);
 	init.parent_names = parent_name;
-	socfpga_clk->hw.init = &init;
-	hw_clk = &socfpga_clk->hw;
+	socfpga_clk->hw.hw.init = &init;
+	hw_clk = &socfpga_clk->hw.hw;
 
 	rc = clk_hw_register(NULL, hw_clk);
 	if (rc)
 		return ERR_PTR(rc);
 
-	return &socfpga_clk->hw.clk;
+	return &hw_clk->clk;
 }
 
 struct clk *socfpga_a10_gate_init(struct device_node *node)
diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c
index c4f51b86740a..8fc8a4ea7b8f 100644
--- a/drivers/clk/socfpga/clk-gate-s10.c
+++ b/drivers/clk/socfpga/clk-gate-s10.c
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
+// SPDX-Comment: Origin-URL: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clk/socfpga/clk-gate-s10.c?id=2050b57ecda040010ec797fb07713889372c5041
 /*
  * Copyright (C) 2017, Intel Corporation
  */
@@ -13,7 +14,7 @@
 #include "clk.h"
 
 #define SOCFPGA_CS_PDBG_CLK	"cs_pdbg_clk"
-#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw)
+#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw)
 
 #define SOCFPGA_EMAC0_CLK		"emac0_clk"
 #define SOCFPGA_EMAC1_CLK		"emac1_clk"
@@ -113,7 +114,7 @@ static int socfpga_agilex_gate_get_parent(struct clk_hw *hwclk)
 	return parent;
 }
 
-static struct clk_ops agilex_gateclk_ops = {
+static const struct clk_ops agilex_gateclk_ops = {
 	.recalc_rate = socfpga_gate_clk_recalc_rate,
 	.get_parent = socfpga_agilex_gate_get_parent,
 };
@@ -132,11 +133,9 @@ struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, voi
 	int ret;
 
 	socfpga_clk = xzalloc(sizeof(*socfpga_clk));
-	socfpga_clk->reg = regbase + clks->gate_reg;
-	socfpga_clk->bit_idx = clks->gate_idx;
 
-	agilex_gateclk_ops.enable = clk_gate_ops.enable;
-	agilex_gateclk_ops.disable = clk_gate_ops.disable;
+	socfpga_clk->hw.reg = regbase + clks->gate_reg;
+	socfpga_clk->hw.bit_idx = clks->gate_idx;
 
 	socfpga_clk->fixed_div = clks->fixed_div;
 
@@ -158,21 +157,19 @@ struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, voi
 		init.ops = &dbgclk_ops;
 	else
 		init.ops = &agilex_gateclk_ops;
+
 	init.name = clks->name;
 	init.flags = clks->flags;
-
 	init.num_parents = clks->num_parents;
 	init.parent_names = parent_name ? &parent_name : NULL;
 	if (init.parent_names == NULL)
 		init.parent_data = clks->parent_data;
-	socfpga_clk->hw.init = &init;
+	socfpga_clk->hw.hw.init = &init;
+	hw_clk = &socfpga_clk->hw.hw;
 
-	hw_clk = &socfpga_clk->hw;
-
-	ret = clk_hw_register(NULL, &socfpga_clk->hw);
-	if (ret) {
-		kfree(socfpga_clk);
+	ret = clk_hw_register(NULL, &socfpga_clk->hw.hw);
+	if (ret)
 		return ERR_PTR(ret);
-	}
+
 	return hw_clk;
 }
diff --git a/drivers/clk/socfpga/clk-periph-a10.c b/drivers/clk/socfpga/clk-periph-a10.c
index 61b693d295f7..b120139bf32b 100644
--- a/drivers/clk/socfpga/clk-periph-a10.c
+++ b/drivers/clk/socfpga/clk-periph-a10.c
@@ -17,7 +17,7 @@
 #define SOCFPGA_MPU_FREE_CLK		"mpu_free_clk"
 #define SOCFPGA_NOC_FREE_CLK		"noc_free_clk"
 #define SOCFPGA_SDMMC_FREE_CLK		"sdmmc_free_clk"
-#define to_socfpga_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw)
+#define to_socfpga_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw.hw)
 
 static unsigned long clk_periclk_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
@@ -32,7 +32,7 @@ static unsigned long clk_periclk_recalc_rate(struct clk_hw *hw,
 		div &= GENMASK(socfpgaclk->width - 1, 0);
 		div += 1;
 	} else {
-		div = ((readl(socfpgaclk->reg) & 0x7ff) + 1);
+		div = ((readl(socfpgaclk->hw.reg) & 0x7ff) + 1);
 	}
 
 	return parent_rate / div;
@@ -43,7 +43,7 @@ static int clk_periclk_get_parent(struct clk_hw *hw)
 	struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hw);
 	u32 clk_src;
 
-	clk_src = readl(socfpgaclk->reg);
+	clk_src = readl(socfpgaclk->hw.reg);
 	if (streq(clk_hw_get_name(hw), SOCFPGA_MPU_FREE_CLK) ||
 	    streq(clk_hw_get_name(hw), SOCFPGA_NOC_FREE_CLK) ||
 	    streq(clk_hw_get_name(hw), SOCFPGA_SDMMC_FREE_CLK))
@@ -59,7 +59,7 @@ static const struct clk_ops periclk_ops = {
 };
 
 static struct clk *__socfpga_periph_init(struct device_node *node,
-	const struct clk_ops *ops)
+					 const struct clk_ops *ops)
 {
 	u32 reg;
 	struct clk_hw *hw_clk;
@@ -75,7 +75,7 @@ static struct clk *__socfpga_periph_init(struct device_node *node,
 
 	periph_clk = xzalloc(sizeof(*periph_clk));
 
-	periph_clk->reg = clk_mgr_base_addr + reg;
+	periph_clk->hw.reg = clk_mgr_base_addr + reg;
 
 	rc = of_property_read_u32_array(node, "div-reg", div_reg, 3);
 	if (!rc) {
@@ -101,9 +101,9 @@ static struct clk *__socfpga_periph_init(struct device_node *node,
 	init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS);
 	init.parent_names = parent_name;
 
-	periph_clk->hw.init = &init;
+	periph_clk->hw.hw.init = &init;
 
-	hw_clk = &periph_clk->hw;
+	hw_clk = &periph_clk->hw.hw;
 
 	rc = clk_hw_register(NULL, hw_clk);
 	if (rc)
diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c
index 3689b08f7d78..3f527e43f0b7 100644
--- a/drivers/clk/socfpga/clk-periph-s10.c
+++ b/drivers/clk/socfpga/clk-periph-s10.c
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
+// SPDX-Comment: Origin-URL: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clk/socfpga/clk-periph-s10.c?id=2050b57ecda040010ec797fb07713889372c5041
 /*
  * Copyright (C) 2017, Intel Corporation
  */
@@ -15,7 +16,7 @@
 #define CLK_MGR_FREE_MASK		0x7
 #define SWCTRLBTCLKSEN_SHIFT		8
 
-#define to_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw)
+#define to_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw.hw)
 
 static unsigned long clk_peri_c_clk_recalc_rate(struct clk_hw *hwclk,
 					     unsigned long parent_rate)
@@ -23,7 +24,7 @@ static unsigned long clk_peri_c_clk_recalc_rate(struct clk_hw *hwclk,
 	struct socfpga_periph_clk *socfpgaclk = to_periph_clk(hwclk);
 	u32 val;
 
-	val = readl(socfpgaclk->reg);
+	val = readl(socfpgaclk->hw.reg);
 	val &= GENMASK(SWCTRLBTCLKSEN_SHIFT - 1, 0);
 	parent_rate /= val;
 
@@ -39,8 +40,8 @@ static unsigned long clk_peri_cnt_clk_recalc_rate(struct clk_hw *hwclk,
 	if (socfpgaclk->fixed_div) {
 		div = socfpgaclk->fixed_div;
 	} else {
-		if (socfpgaclk->reg)
-			div = ((readl(socfpgaclk->reg) & 0x7ff) + 1);
+		if (socfpgaclk->hw.reg)
+			div = ((readl(socfpgaclk->hw.reg) & 0x7ff) + 1);
 	}
 
 	return parent_rate / div;
@@ -61,8 +62,8 @@ static int clk_periclk_get_parent(struct clk_hw *hwclk)
 			return parent;
 	}
 
-	if (socfpgaclk->reg) {
-		clk_src = readl(socfpgaclk->reg);
+	if (socfpgaclk->hw.reg) {
+		clk_src = readl(socfpgaclk->hw.reg);
 		parent = (clk_src >> CLK_MGR_FREE_SHIFT) &
 			  CLK_MGR_FREE_MASK;
 	}
@@ -90,7 +91,8 @@ struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks,
 	int ret;
 
 	periph_clk = xzalloc(sizeof(*periph_clk));
-	periph_clk->reg = reg + clks->offset;
+
+	periph_clk->hw.reg = reg + clks->offset;
 
 	init.name = name;
 	init.ops = &peri_c_clk_ops;
@@ -101,8 +103,8 @@ struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks,
 	if (init.parent_names == NULL)
 		init.parent_data = clks->parent_data;
 
-	periph_clk->hw.init = &init;
-	hw_clk = &periph_clk->hw;
+	periph_clk->hw.hw.init = &init;
+	hw_clk = &periph_clk->hw.hw;
 
 	ret = clk_hw_register(NULL, hw_clk);
 	if (ret) {
@@ -125,9 +127,9 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c
 	periph_clk = xzalloc(sizeof(*periph_clk));
 
 	if (clks->offset)
-		periph_clk->reg = regbase + clks->offset;
+		periph_clk->hw.reg = regbase + clks->offset;
 	else
-		periph_clk->reg = NULL;
+		periph_clk->hw.reg = NULL;
 
 	if (clks->bypass_reg)
 		periph_clk->bypass_reg = regbase + clks->bypass_reg;
@@ -145,8 +147,8 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c
 	if (init.parent_names == NULL)
 		init.parent_data = clks->parent_data;
 
-	periph_clk->hw.init = &init;
-	hw_clk = &periph_clk->hw;
+	periph_clk->hw.hw.init = &init;
+	hw_clk = &periph_clk->hw.hw;
 
 	ret = clk_hw_register(NULL, hw_clk);
 	if (ret) {
diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c
index 566d99563ff6..414a5e70a5ac 100644
--- a/drivers/clk/socfpga/clk-pll-a10.c
+++ b/drivers/clk/socfpga/clk-pll-a10.c
@@ -28,7 +28,7 @@
 #define SOCFPGA_MAIN_PLL_CLK		"main_pll"
 #define SOCFPGA_PERIP_PLL_CLK		"periph_pll"
 
-#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw)
+#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw)
 
 static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 					 unsigned long parent_rate)
@@ -38,7 +38,7 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 	unsigned long long vco_freq;
 
 	/* read VCO1 reg for numerator and denominator */
-	reg = readl(socfpgaclk->reg + 0x4);
+	reg = readl(socfpgaclk->hw.reg + 0x4);
 	divf = (reg & SOCFPGA_PLL_DIVF_MASK) >> SOCFPGA_PLL_DIVF_SHIFT;
 	divq = (reg & SOCFPGA_PLL_DIVQ_MASK) >> SOCFPGA_PLL_DIVQ_SHIFT;
 	vco_freq = (unsigned long long)parent_rate * (divf + 1);
@@ -51,7 +51,7 @@ static int clk_pll_get_parent(struct clk_hw *hw)
 	struct socfpga_pll *socfpgaclk = to_socfpga_clk(hw);
 	u32 pll_src;
 
-	pll_src = readl(socfpgaclk->reg);
+	pll_src = readl(socfpgaclk->hw.reg);
 
 	return (pll_src >> CLK_MGR_PLL_CLK_SRC_SHIFT) &
 		CLK_MGR_PLL_CLK_SRC_MASK;
@@ -62,9 +62,9 @@ static int clk_socfpga_enable(struct clk_hw *hw)
 	struct socfpga_pll *socfpga_clk = to_socfpga_clk(hw);
 	u32 val;
 
-	val = readl(socfpga_clk->reg);
-	val |= 1 << socfpga_clk->bit_idx;
-	writel(val, socfpga_clk->reg);
+	val = readl(socfpga_clk->hw.reg);
+	val |= 1 << socfpga_clk->hw.bit_idx;
+	writel(val, socfpga_clk->hw.reg);
 
 	return 0;
 }
@@ -74,9 +74,9 @@ static void clk_socfpga_disable(struct clk_hw *hw)
 	struct socfpga_pll *socfpga_clk = to_socfpga_clk(hw);
 	u32 val;
 
-	val = readl(socfpga_clk->reg);
-	val &= ~(1 << socfpga_clk->bit_idx);
-	writel(val, socfpga_clk->reg);
+	val = readl(socfpga_clk->hw.reg);
+	val &= ~(1 << socfpga_clk->hw.bit_idx);
+	writel(val, socfpga_clk->hw.reg);
 }
 
 static struct clk_ops clk_pll_ops = {
@@ -100,7 +100,7 @@ static struct clk *__socfpga_pll_init(struct device_node *node,
 
 	pll_clk = xzalloc(sizeof(*pll_clk));
 
-	pll_clk->reg = clk_mgr_base_addr + reg;
+	pll_clk->hw.reg = clk_mgr_base_addr + reg;
 
 	of_property_read_string(node, "clock-output-names", &clk_name);
 
@@ -113,18 +113,19 @@ static struct clk *__socfpga_pll_init(struct device_node *node,
 		i++;
 	init.num_parents = i;
 	init.parent_names = parent_name;
+	pll_clk->hw.hw.init = &init;
 
-	pll_clk->bit_idx = SOCFPGA_PLL_EXT_ENA;
-	hw_clk = &pll_clk->hw;
+	pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
+	hw_clk = &pll_clk->hw.hw;
 
 	clk_pll_ops.enable = clk_socfpga_enable;
 	clk_pll_ops.disable = clk_socfpga_disable;
 
-	rc = clk_hw_register(NULL, &pll_clk->hw);
+	rc = clk_hw_register(NULL, &pll_clk->hw.hw);
 	if (rc)
 		ERR_PTR(rc);
 
-	return &pll_clk->hw.clk;
+	return &pll_clk->hw.hw.clk;
 }
 
 struct clk *socfpga_a10_pll_init(struct device_node *node)
diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c
index 2b1e8f60c378..4c00c0e7481a 100644
--- a/drivers/clk/socfpga/clk-pll-s10.c
+++ b/drivers/clk/socfpga/clk-pll-s10.c
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
+// SPDX-Comment: Origin-URL: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clk/socfpga/clk-pll-s10.c?id=2050b57ecda040010ec797fb07713889372c5041
 /*
  * Copyright (C) 2017, Intel Corporation
  */
@@ -31,7 +32,7 @@
 
 #define SOCFPGA_BOOT_CLK		"boot_clk"
 
-#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw)
+#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw)
 
 static unsigned long agilex_clk_pll_recalc_rate(struct clk_hw *hwclk,
 						unsigned long parent_rate)
@@ -41,13 +42,13 @@ static unsigned long agilex_clk_pll_recalc_rate(struct clk_hw *hwclk,
 	unsigned long long vco_freq;
 
 	/* read VCO1 reg for numerator and denominator */
-	reg = readl(socfpgaclk->reg);
+	reg = readl(socfpgaclk->hw.reg);
 	arefdiv = (reg & SOCFPGA_PLL_AREFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT;
 
 	vco_freq = (unsigned long long)parent_rate / arefdiv;
 
 	/* Read mdiv and fdiv from the fdbck register */
-	reg = readl(socfpgaclk->reg + 0x24);
+	reg = readl(socfpgaclk->hw.reg + 0x24);
 	mdiv = reg & SOCFPGA_AGILEX_PLL_MDIV_MASK;
 
 	vco_freq = (unsigned long long)vco_freq * mdiv;
@@ -60,7 +61,7 @@ static unsigned long clk_boot_clk_recalc_rate(struct clk_hw *hwclk,
 	struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
 	u32 div;
 
-	div = ((readl(socfpgaclk->reg) &
+	div = ((readl(socfpgaclk->hw.reg) &
 		SWCTRLBTCLKSEL_MASK) >>
 		SWCTRLBTCLKSEL_SHIFT);
 	div += 1;
@@ -72,7 +73,7 @@ static int clk_pll_get_parent(struct clk_hw *hwclk)
 	struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
 	u32 pll_src;
 
-	pll_src = readl(socfpgaclk->reg);
+	pll_src = readl(socfpgaclk->hw.reg);
 	return (pll_src >> CLK_MGR_PLL_CLK_SRC_SHIFT) &
 		CLK_MGR_PLL_CLK_SRC_MASK;
 }
@@ -82,25 +83,38 @@ static int clk_boot_get_parent(struct clk_hw *hwclk)
 	struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
 	u32 pll_src;
 
-	pll_src = readl(socfpgaclk->reg);
+	pll_src = readl(socfpgaclk->hw.reg);
 	return (pll_src >> SWCTRLBTCLKSEL_SHIFT) &
 		SWCTRLBTCLKSEL_MASK;
 }
 
-/* TODO need to fix, Agilex5 SM requires change */
-static const struct clk_ops agilex5_clk_pll_ops = {
-	/* TODO This may require a custom Agilex5 implementation */
+static int clk_pll_enable(struct clk_hw *hwclk)
+{
+	struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
+	u32 reg;
+
+	/* Bring PLL out of reset */
+	reg = readl(socfpgaclk->hw.reg);
+	reg |= SOCFPGA_PLL_RESET_MASK;
+	writel(reg, socfpgaclk->hw.reg);
+
+	return 0;
+}
+
+static const struct clk_ops agilex_clk_pll_ops = {
 	.recalc_rate = agilex_clk_pll_recalc_rate,
 	.get_parent = clk_pll_get_parent,
+	.enable = clk_pll_enable,
 };
 
 static const struct clk_ops clk_boot_ops = {
 	.recalc_rate = clk_boot_clk_recalc_rate,
 	.get_parent = clk_boot_get_parent,
+	.enable = clk_pll_enable,
 };
 
 struct clk_hw *agilex5_register_pll(const struct stratix10_pll_clock *clks,
-				void __iomem *reg)
+				    void __iomem *reg)
 {
 	struct clk_hw *hw_clk;
 	struct socfpga_pll *pll_clk;
@@ -109,29 +123,27 @@ struct clk_hw *agilex5_register_pll(const struct stratix10_pll_clock *clks,
 	int ret;
 
 	pll_clk = xzalloc(sizeof(*pll_clk));
-	pll_clk->reg = reg + clks->offset;
+
+	pll_clk->hw.reg = reg + clks->offset;
 
 	if (streq(name, SOCFPGA_BOOT_CLK))
 		init.ops = &clk_boot_ops;
 	else
-		init.ops = &agilex5_clk_pll_ops;
+		init.ops = &agilex_clk_pll_ops;
 
 	init.name = name;
 	init.flags = clks->flags;
-
 	init.num_parents = clks->num_parents;
 	init.parent_names = NULL;
 	init.parent_data = clks->parent_data;
-	pll_clk->hw.init = &init;
-
-	pll_clk->bit_idx = SOCFPGA_PLL_POWER;
-	hw_clk = &pll_clk->hw;
+	pll_clk->hw.hw.init = &init;
+	pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER;
+	hw_clk = &pll_clk->hw.hw;
 
 	ret = clk_hw_register(NULL, hw_clk);
-	if (ret) {
-		kfree(pll_clk);
+	if (ret)
 		return ERR_PTR(ret);
-	}
+
 	return hw_clk;
 }
 
diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h
index cc682ee4e00f..e50bdc3e20f1 100644
--- a/drivers/clk/socfpga/clk.h
+++ b/drivers/clk/socfpga/clk.h
@@ -49,14 +49,11 @@ static inline struct clk *socfpga_a10_gate_init(struct device_node *node)
 #endif
 
 struct socfpga_pll {
-	struct clk_hw hw;
-	void __iomem *reg;
-	u32 bit_idx;
-	const char *parent_names[SOCFPGA_MAX_PARENTS];
+	struct clk_gate	hw;
 };
 
 struct socfpga_gate_clk {
-	struct clk_hw hw;
+	struct clk_gate hw;
 	char *parent_name;
 	u32 fixed_div;
 	void __iomem *div_reg;
@@ -64,16 +61,11 @@ struct socfpga_gate_clk {
 	struct regmap *sys_mgr_base_addr;
 	u32 width;	/* only valid if div_reg != 0 */
 	u32 shift;	/* only valid if div_reg != 0 */
-	u32 bit_idx;
-	void __iomem *reg;
 	u32 bypass_shift;      /* only valid if bypass_reg != 0 */
-	u32 clk_phase[2];
-	const char *parent_names[SOCFPGA_MAX_PARENTS];
 };
 
 struct socfpga_periph_clk {
-	struct clk_hw hw;
-	void __iomem *reg;
+	struct clk_gate hw;
 	char *parent_name;
 	u32 fixed_div;
 	void __iomem *div_reg;
@@ -81,7 +73,6 @@ struct socfpga_periph_clk {
 	u32 width;      /* only valid if div_reg != 0 */
 	u32 shift;      /* only valid if div_reg != 0 */
 	u32 bypass_shift;      /* only valid if bypass_reg != 0 */
-	const char *parent_names[SOCFPGA_MAX_PARENTS];
 };
 
 #endif /* SOCFPGA_CLK_H */

-- 
2.47.3




^ permalink raw reply related

* [PATCH v2 1/4] clk: socfpga: sync arria10 clock initialization with kernel
From: Michael Tretter @ 2026-06-05 13:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter
In-Reply-To: <20260605-socfpga-agilex5-clk-v2-0-780562ec169f@pengutronix.de>

Switch from bclk_register to clk_hw_register with clk_init_data to be
more in line with the Linux driver.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 drivers/clk/socfpga/clk-gate-a10.c   | 27 ++++++++++++---------------
 drivers/clk/socfpga/clk-periph-a10.c | 29 ++++++++++++++---------------
 drivers/clk/socfpga/clk-pll-a10.c    | 31 ++++++++++++++++---------------
 3 files changed, 42 insertions(+), 45 deletions(-)

diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c
index b66fbcdb8c54..e6bcc91b0490 100644
--- a/drivers/clk/socfpga/clk-gate-a10.c
+++ b/drivers/clk/socfpga/clk-gate-a10.c
@@ -117,10 +117,12 @@ static struct clk *__socfpga_gate_init(struct device_node *node,
 	u32 div_reg[3];
 	u32 clk_phase[2];
 	u32 fixed_div;
+	struct clk_hw *hw_clk;
 	struct socfpga_gate_clk *socfpga_clk;
 	const char *clk_name = node->name;
+	const char *parent_name[SOCFPGA_MAX_PARENTS];
+	struct clk_init_data init;
 	int rc;
-	int i;
 
 	socfpga_clk = xzalloc(sizeof(*socfpga_clk));
 
@@ -159,23 +161,18 @@ static struct clk *__socfpga_gate_init(struct device_node *node,
 
 	of_property_read_string(node, "clock-output-names", &clk_name);
 
-	socfpga_clk->hw.clk.name = xstrdup(clk_name);
-	socfpga_clk->hw.clk.ops = ops;
+	init.name = clk_name;
+	init.ops = ops;
+	init.flags = 0;
 
-	for (i = 0; i < SOCFPGA_MAX_PARENTS; i++) {
-		socfpga_clk->parent_names[i] = of_clk_get_parent_name(node, i);
-		if (!socfpga_clk->parent_names[i])
-			break;
-	}
+	init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS);
+	init.parent_names = parent_name;
+	socfpga_clk->hw.init = &init;
+	hw_clk = &socfpga_clk->hw;
 
-	socfpga_clk->hw.clk.num_parents = i;
-	socfpga_clk->hw.clk.parent_names = socfpga_clk->parent_names;
-
-	rc = bclk_register(&socfpga_clk->hw.clk);
-	if (rc) {
-		free(socfpga_clk);
+	rc = clk_hw_register(NULL, hw_clk);
+	if (rc)
 		return ERR_PTR(rc);
-	}
 
 	return &socfpga_clk->hw.clk;
 }
diff --git a/drivers/clk/socfpga/clk-periph-a10.c b/drivers/clk/socfpga/clk-periph-a10.c
index f9cf40b0aaf3..61b693d295f7 100644
--- a/drivers/clk/socfpga/clk-periph-a10.c
+++ b/drivers/clk/socfpga/clk-periph-a10.c
@@ -62,12 +62,14 @@ static struct clk *__socfpga_periph_init(struct device_node *node,
 	const struct clk_ops *ops)
 {
 	u32 reg;
+	struct clk_hw *hw_clk;
 	struct socfpga_periph_clk *periph_clk;
 	const char *clk_name = node->name;
+	const char *parent_name[SOCFPGA_MAX_PARENTS];
+	struct clk_init_data init;
 	int rc;
 	u32 fixed_div;
 	u32 div_reg[3];
-	int i;
 
 	of_property_read_u32(node, "reg", &reg);
 
@@ -92,25 +94,22 @@ static struct clk *__socfpga_periph_init(struct device_node *node,
 
 	of_property_read_string(node, "clock-output-names", &clk_name);
 
-	for (i = 0; i < SOCFPGA_MAX_PARENTS; i++) {
-		periph_clk->parent_names[i] = of_clk_get_parent_name(node, i);
-		if (!periph_clk->parent_names[i])
-			break;
-	}
+	init.name = clk_name;
+	init.ops = ops;
+	init.flags = 0;
 
-	periph_clk->hw.clk.num_parents = i;
-	periph_clk->hw.clk.parent_names = periph_clk->parent_names;
+	init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS);
+	init.parent_names = parent_name;
 
-	periph_clk->hw.clk.name = xstrdup(clk_name);
-	periph_clk->hw.clk.ops = ops;
+	periph_clk->hw.init = &init;
 
-	rc = bclk_register(&periph_clk->hw.clk);
-	if (rc) {
-		free(periph_clk);
+	hw_clk = &periph_clk->hw;
+
+	rc = clk_hw_register(NULL, hw_clk);
+	if (rc)
 		return ERR_PTR(rc);
-	}
 
-	return &periph_clk->hw.clk;
+	return &hw_clk->clk;
 }
 
 struct clk *socfpga_a10_periph_init(struct device_node *node)
diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c
index 2e58a2eb5d92..566d99563ff6 100644
--- a/drivers/clk/socfpga/clk-pll-a10.c
+++ b/drivers/clk/socfpga/clk-pll-a10.c
@@ -88,10 +88,13 @@ static struct clk *__socfpga_pll_init(struct device_node *node,
 	const struct clk_ops *ops)
 {
 	u32 reg;
+	struct clk_hw *hw_clk;
 	struct socfpga_pll *pll_clk;
 	const char *clk_name = node->name;
+	const char *parent_name[SOCFGPA_MAX_PARENTS];
+	struct clk_init_data init;
 	int rc;
-	int i;
+	int i = 0;
 
 	of_property_read_u32(node, "reg", &reg);
 
@@ -101,27 +104,25 @@ static struct clk *__socfpga_pll_init(struct device_node *node,
 
 	of_property_read_string(node, "clock-output-names", &clk_name);
 
-	pll_clk->hw.clk.name = xstrdup(clk_name);
-	pll_clk->hw.clk.ops = ops;
+	init.name = clk_name;
+	init.ops = ops;
+	init.flags = 0;
 
-	for (i = 0; i < SOCFPGA_MAX_PARENTS; i++) {
-		pll_clk->parent_names[i] = of_clk_get_parent_name(node, i);
-		if (!pll_clk->parent_names[i])
-			break;
-	}
+	while (i < SOCFGPA_MAX_PARENTS &&
+	       (parent_name[i] = of_clk_get_parent_name(node, i)) != NULL)
+		i++;
+	init.num_parents = i;
+	init.parent_names = parent_name;
 
 	pll_clk->bit_idx = SOCFPGA_PLL_EXT_ENA;
-	pll_clk->hw.clk.num_parents = i;
-	pll_clk->hw.clk.parent_names = pll_clk->parent_names;
+	hw_clk = &pll_clk->hw;
 
 	clk_pll_ops.enable = clk_socfpga_enable;
 	clk_pll_ops.disable = clk_socfpga_disable;
 
-	rc = bclk_register(&pll_clk->hw.clk);
-	if (rc) {
-		free(pll_clk);
-		return NULL;
-	}
+	rc = clk_hw_register(NULL, &pll_clk->hw);
+	if (rc)
+		ERR_PTR(rc);
 
 	return &pll_clk->hw.clk;
 }

-- 
2.47.3




^ permalink raw reply related

* [PATCH 0/3] arm: socfpga: cleanup UART for serial console
From: Michael Tretter @ 2026-06-05 12:58 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Michael Tretter

Configuring debug console output for the PBL and low level code on
SoCFPGA boards is surprisingly complex and an inconsistent configuration
bit me more than once.

Get rid of the custom UART implementation and the base addresses for the
debug UART in the barebox configuration.

While at it, set the debug UART for the Arrow AXE5 board in the board
code and don't force the developer to know and configure the correct
debug UART in the configuration.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
Michael Tretter (3):
      arm: socfpga: replace custom UART with ns16550
      arm: socfpga: get rid of UART address for low-level debug
      arm: socfpga: axe5-eagle: always use UART0

 arch/arm/boards/arrow-axe5-eagle/lowlevel.c |   6 +-
 common/Kconfig.debug_ll                     |  44 +++--------
 include/mach/socfpga/debug_ll.h             | 113 +++++++++++-----------------
 3 files changed, 57 insertions(+), 106 deletions(-)
---
base-commit: 713a1e59dfea4516446822323b7c0db571cb214f
change-id: 20260605-socfpga-debug-uart-d840aa594751

Best regards,
-- 
Michael Tretter <m.tretter@pengutronix.de>




^ permalink raw reply

* [PATCH 2/3] arm: socfpga: get rid of UART address for low-level debug
From: Michael Tretter @ 2026-06-05 12:58 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Michael Tretter
In-Reply-To: <20260605-socfpga-debug-uart-v1-0-8454bfc709bf@pengutronix.de>

There are existing address definitions for UART0 and UART1 on SoCFPGA.
Having the UART address in the config is error prone.

Change it to debug ports, which allow to select the UART instead of
setting the address. While at it, simplify the configuration.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 common/Kconfig.debug_ll         | 44 +++++++++++------------------------------
 include/mach/socfpga/debug_ll.h |  9 +++++++--
 2 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/common/Kconfig.debug_ll b/common/Kconfig.debug_ll
index 3f06e2eef418..650bfe56383e 100644
--- a/common/Kconfig.debug_ll
+++ b/common/Kconfig.debug_ll
@@ -238,33 +238,12 @@ config DEBUG_ROCKCHIP_RK3399_UART
 	  Say Y here if you want kernel low-level debugging support
 	  on RK3399.
 
-config DEBUG_SOCFPGA_UART0
-	bool "Use SOCFPGA UART0 for low-level debug"
+config DEBUG_SOCFPGA_UART
+	bool "SoCFPGA Debug UART"
 	depends on ARCH_SOCFPGA
 	help
 	  Say Y here if you want kernel low-level debugging support
-	  on SOCFPGA(Cyclone 5 and Arria 5) based platforms.
-
-config DEBUG_SOCFPGA_UART1
-	bool "Use SOCFPGA UART1 for low-level debug"
-	depends on ARCH_SOCFPGA
-	help
-	  Say Y here if you want kernel low-level debugging support
-	  on SOCFPGA(Arria 10) based platforms.
-
-config DEBUG_SOCFPGA_AGILEX5_UART0
-	bool "Use Agilex5 UART0 for low-level debug"
-	depends on ARCH_SOCFPGA_AGILEX5
-	help
-	  Say Y here if you want kernel low-level debugging support
-	  on Agilex5 based platforms.
-
-config DEBUG_SOCFPGA_AGILEX5_UART1
-	bool "Use Agilex5 UART1 for low-level debug"
-	depends on ARCH_SOCFPGA_AGILEX5
-	help
-	  Say Y here if you want kernel low-level debugging support
-	  on Agilex5 based platforms.
+	  on SoCFPGA based platforms.
 
 config DEBUG_STM32MP_UART
 	bool "Use STM32MP UART4 for low-level debug"
@@ -482,19 +461,18 @@ config DEBUG_ROCKCHIP_UART_PORT
 	  Choose UART port on which kernel low-level debug messages
 	  should be output.
 
-config DEBUG_SOCFPGA_UART_PHYS_ADDR
-	hex "Physical base address of debug UART" if DEBUG_LL
-	default 0xffc02000 if DEBUG_SOCFPGA_UART0
-	default 0xffc02100 if DEBUG_SOCFPGA_UART1
-	default 0x10c02000 if DEBUG_SOCFPGA_AGILEX5_UART0
-	default 0x10c02100 if DEBUG_SOCFPGA_AGILEX5_UART1
+config DEBUG_SOCFPGA_UART_PORT
+	int "SocFPGA UART debug port" if DEBUG_SOCFPGA_UART
+	default 0 if ARCH_SOCFPGA_CYCLONE5 || ARCH_SOCFPGA_AGILEX5
+	default 1 if ARCH_SOCFPGA_ARRIA10
 	depends on ARCH_SOCFPGA
+	help
+	  Select UART port used for early debugging.
 
 config DEBUG_SOCFPGA_UART_CLOCK
-	int "SoCFPGA UART debug clock" if DEBUG_LL
-	default 100000000 if ARCH_SOCFPGA_CYCLONE5
+	int "SoCFPGA UART debug clock" if DEBUG_SOCFPGA_UART
+	default 100000000 if ARCH_SOCFPGA_CYCLONE5 || ARCH_SOCFPGA_AGILEX5
 	default  50000000 if ARCH_SOCFPGA_ARRIA10
-	default 100000000 if ARCH_SOCFPGA_AGILEX5
 	depends on ARCH_SOCFPGA
 	help
 	  Choose UART root clock.
diff --git a/include/mach/socfpga/debug_ll.h b/include/mach/socfpga/debug_ll.h
index 86f6256af995..3d69d87545c1 100644
--- a/include/mach/socfpga/debug_ll.h
+++ b/include/mach/socfpga/debug_ll.h
@@ -4,9 +4,14 @@
 #define   __MACH_SOCFPGA_DEBUG_LL_H__
 
 #include <io.h>
+#include <mach/socfpga/soc64-regs.h>
 
-#ifdef CONFIG_DEBUG_LL
-#define UART_BASE	CONFIG_DEBUG_SOCFPGA_UART_PHYS_ADDR
+#define __SOCFPGA_UART_BASE(num)	SOCFPGA_UART##num##_ADDRESS
+#define SOCFPGA_UART_BASE(num)		__SOCFPGA_UART_BASE(num)
+
+#ifdef CONFIG_DEBUG_SOCFPGA_UART
+
+#define UART_BASE			SOCFPGA_UART_BASE(CONFIG_DEBUG_SOCFPGA_UART_PORT)
 
 #if defined(CONFIG_ARCH_SOCFPGA_CYCLONE5)
 static inline uint8_t debug_ll_read_reg(void __iomem *base, int reg)

-- 
2.47.3




^ permalink raw reply related

* [PATCH 1/3] arm: socfpga: replace custom UART with ns16550
From: Michael Tretter @ 2026-06-05 12:58 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Michael Tretter
In-Reply-To: <20260605-socfpga-debug-uart-v1-0-8454bfc709bf@pengutronix.de>

There is nothing special in the SoCFPGA UART, but it is compatible with
an ns16550 uart. Remove the custom implementation.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 include/mach/socfpga/debug_ll.h | 104 ++++++++++++++--------------------------
 1 file changed, 35 insertions(+), 69 deletions(-)

diff --git a/include/mach/socfpga/debug_ll.h b/include/mach/socfpga/debug_ll.h
index 698cca60373f..86f6256af995 100644
--- a/include/mach/socfpga/debug_ll.h
+++ b/include/mach/socfpga/debug_ll.h
@@ -4,97 +4,63 @@
 #define   __MACH_SOCFPGA_DEBUG_LL_H__
 
 #include <io.h>
-#include <errno.h>
 
 #ifdef CONFIG_DEBUG_LL
 #define UART_BASE	CONFIG_DEBUG_SOCFPGA_UART_PHYS_ADDR
+
+#if defined(CONFIG_ARCH_SOCFPGA_CYCLONE5)
+static inline uint8_t debug_ll_read_reg(void __iomem *base, int reg)
+{
+	return readb(base + (reg << 2));
+}
+
+static inline void debug_ll_write_reg(void __iomem *base, int reg, uint8_t val)
+{
+	writeb(val, base + (reg << 2));
+}
+#else
+static inline uint8_t debug_ll_read_reg(void __iomem *base, int reg)
+{
+	return readl(base + (reg << 2));
+}
+
+static inline void debug_ll_write_reg(void __iomem *base, int reg, uint8_t val)
+{
+	writel(val, base + (reg << 2));
+}
 #endif
 
-#define LSR_THRE	0x20	/* Xmit holding register empty */
-#define LSR_TEMT	0x40
+#include <debug_ll/ns16550.h>
 
-#define LCR_BKSE	0x80	/* Bank select enable */
-#define LCRVAL		0x3
-#define MCRVAL		0x3
-#define FCRVAL		0xc1
-
-#define RBR		0x0
-#define DLL		0x0
-#define IER		0x4
-#define DLM		0x4
-#define FCR		0x8
-#define LCR		0xc
-#define MCR		0x10
-#define LSR		0x14
-#define MSR		0x18
-#define SCR		0x1c
-#define THR		0x30
-
-static inline void socfpga_gen5_uart_putc(void *base, int c)
+static inline void socfpga_uart_setup(void *base)
 {
-	/* Wait until there is space in the FIFO */
-	while ((readb(base + LSR) & LSR_THRE) == 0);
-	/* Send the character */
-	writeb(c, base + THR);
-	/* Wait to make sure it hits the line, in case we die too soon. */
-	while ((readb(base + LSR) & LSR_THRE) == 0);
-}
+	unsigned int div;
 
-static inline void socfpga_uart_putc(void *base, int c)
-{
-	/* Wait until there is space in the FIFO */
-	while ((readl(base + LSR) & LSR_THRE) == 0);
-	/* Send the character */
-	writel(c, base + THR);
-	/* Wait to make sure it hits the line, in case we die too soon. */
-	while ((readl(base + LSR) & LSR_THRE) == 0);
-}
-
-#ifdef CONFIG_DEBUG_LL
-static inline unsigned int ns16550_calc_divisor(unsigned int clk,
-					 unsigned int baudrate)
-{
-	return (clk / 16 / baudrate);
+	div = debug_ll_ns16550_calc_divisor(CONFIG_DEBUG_SOCFPGA_UART_CLOCK);
+	debug_ll_ns16550_init(base, div);
 }
 
 static inline void socfpga_uart_setup_ll(void)
-{
-	unsigned int div = ns16550_calc_divisor(CONFIG_DEBUG_SOCFPGA_UART_CLOCK,
-						115200);
-
-	writel(0x00, UART_BASE + IER);
-
-	writel(LCR_BKSE, UART_BASE + LCR);
-	writel(div & 0xff, UART_BASE + DLL);
-	writel((div >> 8) & 0xff, UART_BASE + DLM);
-	writel(LCRVAL, UART_BASE + LCR);
-
-	writel(MCRVAL, UART_BASE + MCR);
-	writel(FCRVAL, UART_BASE + FCR);
-}
-
-#if defined(CONFIG_ARCH_SOCFPGA_CYCLONE5)
-static inline void PUTC_LL(char c)
 {
 	void __iomem *base = IOMEM(UART_BASE);
 
-	socfpga_gen5_uart_putc(base, c);
+	socfpga_uart_setup(base);
 }
-#else
+
+static inline void socfpga_uart_putc(void *base, int c)
+{
+	debug_ll_ns16550_putc(base, c);
+}
+
 static inline void PUTC_LL(char c)
 {
 	void __iomem *base = IOMEM(UART_BASE);
 
 	socfpga_uart_putc(base, c);
 }
-#endif
-
 #else
-static inline unsigned int ns16550_calc_divisor(unsigned int clk,
-					 unsigned int baudrate) {
-	return -ENOSYS;
-}
 static inline void socfpga_uart_setup_ll(void) {}
-static inline void PUTC_LL(char c) {}
+static inline void socfpga_uart_putc(void *base, int c) {}
+static inline void socfpga_uart_setup(void *base) {}
 #endif
 #endif /* __MACH_SOCFPGA_DEBUG_LL_H__ */

-- 
2.47.3




^ permalink raw reply related

* [PATCH 3/3] arm: socfpga: axe5-eagle: always use UART0
From: Michael Tretter @ 2026-06-05 12:58 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Michael Tretter
In-Reply-To: <20260605-socfpga-debug-uart-v1-0-8454bfc709bf@pengutronix.de>

Configuring debug_ll with the UART from the configuration, while
configuring the PBL console with a hard-coded address may lead to
inconsistencies and confusion.

Avoid this by explicitly configuring debug_ll with a UART defined by the
board low level code.

While at it, replace the address with the UART port macro.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/boards/arrow-axe5-eagle/lowlevel.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/arrow-axe5-eagle/lowlevel.c b/arch/arm/boards/arrow-axe5-eagle/lowlevel.c
index f946a8b9f616..b0a2d6673e0f 100644
--- a/arch/arm/boards/arrow-axe5-eagle/lowlevel.c
+++ b/arch/arm/boards/arrow-axe5-eagle/lowlevel.c
@@ -15,10 +15,12 @@ extern char __dtb_z_socfpga_agilex5_axe5_eagle_start[];
 
 static noinline void axe5_eagle_continue(void)
 {
+	void __iomem *uart = IOMEM(SOCFPGA_UART_BASE(0));
+
 	agilex5_clk_init();
 
-	socfpga_uart_setup_ll();
-	pbl_set_putc(socfpga_uart_putc, (void *) SOCFPGA_UART0_ADDRESS);
+	socfpga_uart_setup(uart);
+	pbl_set_putc(socfpga_uart_putc, uart);
 
 	pr_debug("Lowlevel init done\n");
 

-- 
2.47.3




^ permalink raw reply related

* Re: [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization
From: Sascha Hauer @ 2026-06-05  6:13 UTC (permalink / raw)
  To: BAREBOX, Michael Tretter; +Cc: Steffen Trumtrar
In-Reply-To: <20260604-socfpga-axe5-sdram-init-v1-0-274f6361ce98@pengutronix.de>


On Thu, 04 Jun 2026 13:06:53 +0200, Michael Tretter wrote:
> The Agilex5 SDRAM initialization contains some obscure and unclear
> workarounds, which are supposedly necessary for a successful SDRAM
> initialization.
> 
> I observed a race condition between the IOSSM firmware, which is
> responsible for the SDRAM initialization, and barebox. I assume this
> race is responsible for the observed initialization failures.
> 
> [...]

Applied, thanks!

[1/5] arm: socfpga: agilex5: separate EL3 init function
      https://git.pengutronix.de/cgit/barebox/commit/?id=f615446b218f (link may not be stable)
[2/5] arm: socfpga: agilex5: panic if DDR init failed
      https://git.pengutronix.de/cgit/barebox/commit/?id=3791fb227199 (link may not be stable)
[3/5] arm: socfpga: iossm: add delay to wait for firmware
      https://git.pengutronix.de/cgit/barebox/commit/?id=4296d8ae1181 (link may not be stable)
[4/5] arm: socfpga: agilex5: drop dual port hack
      https://git.pengutronix.de/cgit/barebox/commit/?id=36ad90f489fb (link may not be stable)
[5/5] arm: socfpga: agilex5: drop bank select before ddr_init
      https://git.pengutronix.de/cgit/barebox/commit/?id=6685029a7c78 (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply

* Re: [PATCH] lib: logo: support a single pre-rendered logo file as an alternative to SVG
From: SCHNEIDER Johannes @ 2026-06-05  5:46 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: HAEMMERLE Thomas, barebox@lists.infradead.org
In-Reply-To: <90cd7b0f-4783-4fb3-8faf-3436d21db90b@pengutronix.de>

Hoi Ahmad,


>
> Hello Johannes,
> 
> On 6/2/26 8:08 AM, Johannes Schneider wrote:
> > Add a "Logo source" choice that switches between the upstream behaviour
> > (BAREBOX_LOGO_STOCK -- render Documentation/barebox.svg at build time
> > with ImageMagick) and a new pre-rendered single-file mode
> > (BAREBOX_LOGO_FILE -- include one PNG verbatim, no conversion).
> >
> > The single-file mode addresses two issues for vendor-branded splashes
> > on fixed-resolution panels:
> >
> >   - The multi-size stock options can be combined; e.g. enabling 640
> >     and a hypothetical 800 variant in parallel embedded both blobs,
> >     even though only one is ever displayed on a given panel.  The new
> >     BAREBOX_LOGO_FILE selector replaces all of the BAREBOX_LOGO_<size>
> >     flags with a single configurable PNG path -- exactly one logo
> >     blob in the resulting binary.
> >
> >   - It removes the build-time ImageMagick dependency in the
> >     custom-logo path.  CI environments where Inkscape and ImageMagick
> >     versions drift (see the SELF_CALL=xxx Inkscape workaround at
> >     the top of cmd_png) can produce a pre-rendered PNG once and check
> >     it in.  Stock mode keeps its existing convert(1) chain.
> >
> > The new symbol is barebox-logo-custom; the resulting bblogo blob is
> > embedded under __bblogo_barebox_logo_custom_{start,end} and exposed at
> > /logo/barebox-logo-custom.<ext> in the running barebox.
> >
> > CONFIG_BAREBOX_LOGO_FILE_PATH selects the source PNG, relative to the
> > barebox srctree (default lib/logo/barebox-logo-custom.png).  The
> > existing BAREBOX_LOGO_64..640 size options remain available, gated on
> > BAREBOX_LOGO_STOCK.
> 
> CONFIG_BAREBOX_LOGO is solely about including the barebox logo.
> 
> To include your custom PNG, just put it into your environment (e.g.
> /env/data), no need to patch barebox. You are not even limited to one
> logo in that case.
>

... *that* is indeed the better solution.

so please disregard this patch :-S

>
> Tangentially related, I am in favor of including vendor logos (e.g. in
> your case Leica's) into barebox for use with the vendor board support,
> but these should also be SVGs IMO.
>

they are SVGs, but (now would) live in the yocto/bitbake level, not the sources
directly - like the rest of the files going into the /env while we build barebox


gruß
Johannes


>
> > Upstream-Status: Pending
> 
> Please drop this out-of-place tag.
> 
> Cheers,
> Ahmad
> 
> >
> > Assisted-by: Claude Opus 4.7 (1M context)
> > Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
> > ---
> >  lib/logo/Kconfig  | 35 +++++++++++++++++++++++++++++++++++
> >  lib/logo/Makefile | 19 +++++++++++++++++++
> >  2 files changed, 54 insertions(+)
> >
> > diff --git a/lib/logo/Kconfig b/lib/logo/Kconfig
> > index 7e5a6fcb63..ab64ce242d 100644
> > --- a/lib/logo/Kconfig
> > +++ b/lib/logo/Kconfig
> > @@ -35,6 +35,30 @@ config BAREBOX_LOGO_QOI
> >
> >  endchoice
> >
> > +choice
> > +     prompt "Logo source"
> > +     default BAREBOX_LOGO_STOCK
> > +     help
> > +       Choose how the boot logo is produced.
> > +
> > +config BAREBOX_LOGO_STOCK
> > +     bool "Stock barebox logo (rendered from SVG)"
> > +     help
> > +       Render Documentation/barebox.svg at build time into the sizes
> > +       selected below.  Requires ImageMagick's convert tool in the
> > +       build environment.
> > +
> > +config BAREBOX_LOGO_FILE
> > +     bool "Pre-rendered logo from file"
> > +     help
> > +       Use a pre-rendered PNG as the boot logo, taken verbatim with
> > +       no build-time conversion.  Suitable for vendor-branded boot
> > +       splashes; no ImageMagick dependency.
> > +
> > +endchoice
> > +
> > +if BAREBOX_LOGO_STOCK
> > +
> >  config BAREBOX_LOGO_64
> >       bool "include 64x32 pixel logo"
> >
> > @@ -50,4 +74,15 @@ config BAREBOX_LOGO_400
> >  config BAREBOX_LOGO_640
> >       bool "include 640x320 pixel logo"
> >
> > +endif # BAREBOX_LOGO_STOCK
> > +
> > +config BAREBOX_LOGO_FILE_PATH
> > +     string "Pre-rendered logo path (relative to srctree)"
> > +     depends on BAREBOX_LOGO_FILE
> > +     default "lib/logo/barebox-logo-custom.png"
> > +     help
> > +       Path to the pre-rendered PNG, relative to the barebox source
> > +       tree.  The file is included as-is; drop it at this location
> > +       before invoking the build.
> > +
> >  endif # BAREBOX_LOGO
> > diff --git a/lib/logo/Makefile b/lib/logo/Makefile
> > index 9792a4699f..7bd7fbb352 100644
> > --- a/lib/logo/Makefile
> > +++ b/lib/logo/Makefile
> > @@ -1,5 +1,6 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >
> > +ifdef CONFIG_BAREBOX_LOGO_STOCK
> >  OPTS_barebox-logo-w64 = -resize 64
> >  bblogo-$(CONFIG_BAREBOX_LOGO_64) += barebox-logo-w64
> >
> > @@ -14,6 +15,14 @@ bblogo-$(CONFIG_BAREBOX_LOGO_400) += barebox-logo-w400
> >
> >  OPTS_barebox-logo-w640 = -resize 640
> >  bblogo-$(CONFIG_BAREBOX_LOGO_640) += barebox-logo-w640
> > +endif
> > +
> > +ifdef CONFIG_BAREBOX_LOGO_FILE
> > +# Strip the Kconfig string's surrounding quotes.
> > +barebox-logo-file-path := $(patsubst "%",%,$(CONFIG_BAREBOX_LOGO_FILE_PATH))
> > +
> > +bblogo-y += barebox-logo-custom
> > +endif
> >
> >  obj-y += $(patsubst %,%.bblogo.o,$(bblogo-y))
> >  extra-y += $(patsubst %,%.bblogo,$(bblogo-y))
> > @@ -62,6 +71,7 @@ endif
> >
> >  CONVERTOPTS += -background none
> >
> > +ifdef CONFIG_BAREBOX_LOGO_STOCK
> >  quiet_cmd_bmp = BMP     $@
> >        cmd_bmp = convert $(OPTS_$(@F:.bmp=)) $(CONVERTOPTS) $< bmp:$@
> >
> > @@ -76,6 +86,15 @@ quiet_cmd_png = PNG     $@
> >
> >  %.png: $(srctree)/Documentation/barebox.svg FORCE
> >       $(call if_changed,png)
> > +endif
> > +
> > +ifdef CONFIG_BAREBOX_LOGO_FILE
> > +quiet_cmd_logo_copy = COPY    $@
> > +      cmd_logo_copy = cp $< $@
> > +
> > +barebox-logo-custom.png: $(srctree)/$(barebox-logo-file-path) FORCE
> > +     $(call if_changed,logo_copy)
> > +endif
> >
> >  quiet_cmd_qoi = QOI     $@
> >        cmd_qoi =      $(objtree)/scripts/qoiconv $< $@
> >
> > base-commit: 81fbe2e8d0d445032498a0bfecf9fd270f00985a
> 


^ permalink raw reply

* [PATCH v4 1/2] Add support for extlinux.conf
From: Alexander Shiyan @ 2026-06-05  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Alexander Shiyan

This adds support for the extlinux.conf configuration format, commonly
used by Syslinux and many Linux distributions. The configuration file
is typically located at /boot/extlinux/extlinux.conf or
/extlinux/extlinux.conf and defines boot entries with kernel, initrd,
device tree, and command line options.

The implementation integrates with the existing boot entry framework:
- The extlinux scanner discovers entries on mounted filesystems.
- Only the DEFAULT label is turned into a boot entry (multiple
  LABEL sections are ignored after the default is found).
- Bootm is used to load and start the kernel.
---
barebox@Diasom DS-RK3568-SOM-EVB:/ global.bootm.appendroot=true
barebox@Diasom DS-RK3568-SOM-EVB:/ global.boot.default=mmc1.2
barebox@Diasom DS-RK3568-SOM-EVB:/ boot
ext4 ext40: EXT2 rev 1, inode_size 256, descriptor size 64
Booting entry 'extlinux: linux'
extlinux: Booting extlinux label 'linux'
Adding "root=/dev/mmcblk1p3" to Kernel commandline
Loading ARM aarch64 Linux/EFI image '/mnt/mmc1.2/boot/extlinux/../vmlinuz'
commandline: root=/dev/mmcblk1p3 console=ttyS2,1500000n8 ro systemd.unit=setup.target quiet splash systemd.machine_id=181af2816b4c6b0aef77068e0ccc69ad
Loaded kernel to 0x0a400000, devicetree at 0x000000000fb49000

Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
---
 common/Kconfig    |  20 ++++
 common/Makefile   |   1 +
 common/extlinux.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 268 insertions(+)
 create mode 100644 common/extlinux.c

diff --git a/common/Kconfig b/common/Kconfig
index f9985d8aa4..0708855b78 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -773,6 +773,26 @@ config BLSPEC
 	  on a device and it allows the Operating System to install / update
 	  kernels.
 
+config EXTLINUX
+	bool
+	prompt "Support extlinux.conf"
+	depends on FLEXIBLE_BOOTARGS
+	depends on !SHELL_NONE
+	select BOOT
+	select BOOTM
+	select MMCBLKDEV_ROOTARG if MCI
+	help
+	  Enable this to let barebox parse extlinux.conf configuration files,
+	  commonly used by the Syslinux bootloader and many Linux distributions
+	  (e.g., on SD cards or USB drives).
+	  extlinux.conf is typically located at /boot/extlinux/extlinux.conf or
+	  /extlinux/extlinux.conf. It defines boot entries with kernel, initrd,
+	  device tree, and command line options.
+
+	  Note: barebox only uses the entry specified by the DEFAULT keyword.
+	  Additional LABEL sections are ignored. This allows a simple and
+	  portable way to define a single default boot option.
+
 config FLEXIBLE_BOOTARGS
 	bool
 	prompt "flexible Linux bootargs generation"
diff --git a/common/Makefile b/common/Makefile
index 27c5dea168..cd929b2194 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -9,6 +9,7 @@ obj-y				+= clock.o
 pbl-$(CONFIG_PBL_CLOCKSOURCE)	+= clock.o
 obj-y				+= console_common.o
 obj-$(CONFIG_OFDEVICE)		+= deep-probe.o
+obj-$(CONFIG_EXTLINUX)		+= extlinux.o
 obj-y				+= startup.o
 obj-y				+= misc.o
 obj-pbl-y			+= memsize.o
diff --git a/common/extlinux.c b/common/extlinux.c
new file mode 100644
index 0000000000..caa62923da
--- /dev/null
+++ b/common/extlinux.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-FileCopyrightText: Alexander Shiyan <shc_work@mail.ru> */
+
+#define pr_fmt(fmt)     "extlinux: " fmt
+
+#include <boot.h>
+#include <bootm.h>
+#include <bootscan.h>
+#include <common.h>
+#include <environment.h>
+#include <fs.h>
+#include <globalvar.h>
+#include <libfile.h>
+#include <libgen.h>
+#include <string.h>
+
+struct extlinux_entry {
+	struct bootentry entry;
+	char *rootpath;
+	char *label;
+	char *kernel;
+	char *initrd;
+	char *fdtdir;
+	char *fdt;
+	char *append;
+};
+
+static int extlinux_boot(struct bootentry *entry, int verbose, int dryrun)
+{
+	struct extlinux_entry *e =
+		container_of(entry, struct extlinux_entry, entry);
+	char *kernel_abs, *initrd_abs = NULL, *fdt_abs = NULL;
+	struct bootm_data data = {};
+	int ret;
+
+	bootm_data_init_defaults(&data);
+
+	data.dryrun = max_t(int, dryrun, data.dryrun);
+	data.verbose = max(verbose, data.verbose);
+
+	kernel_abs = basprintf("%s/%s", e->rootpath, e->kernel);
+	data.os_file = kernel_abs;
+
+	if (e->initrd) {
+		initrd_abs = basprintf("%s/%s", e->rootpath, e->initrd);
+		data.initrd_file = initrd_abs;
+	}
+
+	if (e->fdt) {
+		char *fdtdir = e->fdtdir ? : e->rootpath;
+
+		fdt_abs = basprintf("%s/%s", fdtdir, e->fdt);
+		data.oftree_file = fdt_abs;
+	}
+
+	if (e->append)
+		globalvar_add_simple("linux.bootargs.dyn.bootentries",
+				     e->append);
+
+	pr_info("Booting extlinux label '%s'\n", e->label);
+
+	ret = bootm_entry(entry, &data);
+	if (ret)
+		pr_err("bootm failed: %pe\n", ERR_PTR(ret));
+
+	free(kernel_abs);
+	free(initrd_abs);
+	free(fdt_abs);
+
+	return ret;
+}
+
+static void extlinux_entry_free(struct bootentry *entry)
+{
+	struct extlinux_entry *e =
+		container_of(entry, struct extlinux_entry, entry);
+
+	free(e->rootpath);
+	free(e->label);
+	free(e->kernel);
+	free(e->initrd);
+	free(e->fdtdir);
+	free(e->fdt);
+	free(e->append);
+	free(e);
+}
+
+/*
+ * Parse extlinux.conf. Only the entry pointed to by the DEFAULT keyword
+ * is extracted; all other LABEL sections are ignored.
+ */
+static struct extlinux_entry *parse_extlinux_conf(const char *abspath,
+						  const char *rootpath)
+{
+	char *buf, *bufptr, *line, *default_label = NULL;
+	struct extlinux_entry *entry = NULL;
+
+	bufptr = read_file(abspath, NULL);
+	if (!bufptr)
+		return ERR_PTR(-errno);
+
+	buf = bufptr;
+	while ((line = strsep(&buf, "\n\r")) != NULL) {
+		char *key, *val;
+
+		line = skip_spaces(line);
+
+		if (*line == '#' || *line == '\0')
+			continue;
+
+		key = strsep(&line, " \t");
+		val = isempty(line) ? NULL : skip_spaces(line);
+		if (!key || !val)
+			continue;
+
+		if (!default_label) {
+			if (!strcasecmp(key, "DEFAULT"))
+				default_label = xstrdup(val);
+
+			continue;
+		}
+
+		if (!strcasecmp(key, "LABEL")) {
+			if (!strcmp(val, default_label)) {
+				entry = xzalloc(sizeof(*entry));
+				entry->label = xstrdup(val);
+				entry->rootpath = dirname(xstrdup(abspath));
+			} else if (entry) {
+				break;
+			}
+			continue;
+		}
+
+		if (entry) {
+			if (!strcasecmp(key, "KERNEL"))
+				entry->kernel = xstrdup(val);
+			else if (!strcasecmp(key, "INITRD"))
+				entry->initrd = xstrdup(val);
+			else if (!strcasecmp(key, "FDTDIR"))
+				entry->fdtdir = xstrdup(val);
+			else if (!strcasecmp(key, "FDT"))
+				entry->fdt = xstrdup(val);
+			else if (!strcasecmp(key, "APPEND"))
+				entry->append = xstrdup(val);
+			else
+				pr_warn("Unhandled key: %s\n", key);
+		}
+	}
+
+	free(default_label);
+	free(bufptr);
+
+	if (!entry || !entry->kernel) {
+		if (entry)
+			extlinux_entry_free(&entry->entry);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return entry;
+}
+
+static int _extlinux_scan_file(struct bootscanner *scanner,
+			       struct bootentries *bootentries,
+			       const char *configname,
+			       const char *rootpath)
+{
+	struct extlinux_entry *e;
+
+	if (!strends(configname, "extlinux.conf"))
+		return 0;
+
+	e = parse_extlinux_conf(configname, rootpath);
+	if (IS_ERR(e))
+		return PTR_ERR(e);
+
+	e->entry.boot = extlinux_boot;
+	e->entry.release = extlinux_entry_free;
+	e->entry.path = xstrdup_const(configname);
+	e->entry.title = basprintf("extlinux: %s", e->label);
+	e->entry.description = basprintf("extlinux entry \'%s\" on %s",
+					 e->label, rootpath);
+	e->entry.me.type = MENU_ENTRY_NORMAL;
+
+	bootentries_add_entry(bootentries, &e->entry);
+
+	return 1;
+}
+
+static int extlinux_scan_file(struct bootscanner *scanner,
+			      struct bootentries *bootentries,
+			      const char *configname)
+{
+	const char *rootpath = get_mounted_path(configname);
+
+	if (IS_ERR(rootpath))
+		return PTR_ERR(rootpath);
+
+	return _extlinux_scan_file(scanner, bootentries, configname, rootpath);
+}
+
+static int extlinux_scan_directory(struct bootscanner *scanner,
+				   struct bootentries *bootentries,
+				   const char *rootpath)
+{
+	char *path;
+	struct stat s;
+	int ret;
+
+	path = basprintf("%s/boot/extlinux/extlinux.conf", rootpath);
+	ret = stat(path, &s);
+	if (!ret && S_ISREG(s.st_mode))
+		ret = _extlinux_scan_file(scanner, bootentries, path, rootpath);
+	free(path);
+	if (ret > 0)
+		return ret;
+
+	path = basprintf("%s/extlinux/extlinux.conf", rootpath);
+	ret = stat(path, &s);
+	if (!ret && S_ISREG(s.st_mode))
+		ret = _extlinux_scan_file(scanner, bootentries, path, rootpath);
+	free(path);
+
+	return ret;
+}
+
+static struct bootscanner extlinux_scanner = {
+	.name = "extlinux",
+	.scan_file = extlinux_scan_file,
+	.scan_directory = extlinux_scan_directory,
+};
+
+static int extlinux_generate(struct bootentries *bootentries, const char *name)
+{
+	return bootentry_scan_generate(&extlinux_scanner, bootentries, name);
+}
+
+static struct bootentry_provider extlinux_provider = {
+	.name = "extlinux",
+	.generate = extlinux_generate,
+	.priority = -25,
+};
+
+static int extlinux_init(void)
+{
+	return bootentry_register_provider(&extlinux_provider);
+}
+device_initcall(extlinux_init);
-- 
2.52.0




^ permalink raw reply related

* [PATCH v4 2/2] Documentation: add extlinux.conf support description
From: Alexander Shiyan @ 2026-06-05  5:23 UTC (permalink / raw)
  To: barebox; +Cc: Alexander Shiyan
In-Reply-To: <20260605052347.3009484-1-eagle.alexander923@gmail.com>

Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
---
 Documentation/user/booting-linux.rst | 41 ++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index 7bbb79ecdf..0f12256813 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -304,6 +304,47 @@ Additional notes about keys in the bootloader spec entries:
    different devices without having to specify a different ``root=`` option each
    time.
 
+.. _extlinux_conf:
+
+extlinux.conf Support
+^^^^^^^^^^^^^^^^^^^^^
+
+In addition to the Boot Loader Specification, barebox also supports the
+extlinux configuration format, commonly used by the Syslinux bootloader and
+many Linux distributions. This format is often found on SD cards, USB drives,
+or disk partitions prepared with tools like ``extlinux --install``.
+
+The configuration file is named ``extlinux.conf`` and can be located at:
+* ``/boot/extlinux/extlinux.conf``
+* ``/extlinux/extlinux.conf``
+
+The file uses a simple key-value syntax with sections labeled by ``LABEL``.
+A typical example looks like:
+
+.. code-block:: none
+
+  DEFAULT linux
+  LABEL linux
+    KERNEL /boot/vmlinuz
+    INITRD /boot/initrd.img
+    FDT /boot/board.dtb
+    APPEND console=ttyS0,115200 root=PARTUUID=deadbeef-01
+
+.. note::
+   barebox only uses the entry marked as ``DEFAULT``. Additional ``LABEL``
+   sections are ignored. This provides a simple way to define a single boot
+   option.
+
+To use extlinux support, enable ``CONFIG_EXTLINUX`` in your barebox
+configuration. Entries are automatically discovered by the :ref:`command_boot`
+command when scanning a device or mount point. For example:
+
+.. code-block:: sh
+
+  global.bootm.appendroot=true
+  global.boot.default=mmc1.2
+  boot
+
 .. _booting_linux_net:
 
 Network boot
-- 
2.52.0




^ permalink raw reply related

* [PATCH 5/5] arm: socfpga: agilex5: drop bank select before ddr_init
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter
In-Reply-To: <20260604-socfpga-axe5-sdram-init-v1-0-274f6361ce98@pengutronix.de>

I verified that the bank select on UART0 is not necessary for the
ddr_initialization. Thus, the documentation why the bank select is
necessary is not valid anymore.

Furthermore, depending on the UART used by the board, using UART0 may
not be general enough, anyway.

It seems like the bank select rather added a delay before the SDRAM
initialization and without the bank select, the serial didn't show
anything because the SDRAM initialization failed.

Remove the workaround.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/atf.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/arch/arm/mach-socfpga/atf.c b/arch/arm/mach-socfpga/atf.c
index 6ddfef34632f..ac69fb7776ca 100644
--- a/arch/arm/mach-socfpga/atf.c
+++ b/arch/arm/mach-socfpga/atf.c
@@ -68,13 +68,6 @@ static void agilex5_el3_init(void)
 	agilex5_initialize_security_policies();
 	pr_debug("Security policies initialized\n");
 
-	/*
-	 * need to set the bank select enable before the
-	 * agilex5_ddr_init_full() otherwise the serial doesn't show
-	 * anything.
-	 */
-	if (!IS_ENABLED(CONFIG_DEBUG_LL))
-		writel(LCR_BKSE, SOCFPGA_UART0_ADDRESS + LCR);
 	ret = agilex5_ddr_init_full();
 	if (ret)
 		panic("DDR initialization failed\n");

-- 
2.47.3




^ permalink raw reply related

* [PATCH 4/5] arm: socfpga: agilex5: drop dual port hack
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter
In-Reply-To: <20260604-socfpga-axe5-sdram-init-v1-0-274f6361ce98@pengutronix.de>

On Agilex 5 with a firmware generated by Quartus 25.3, the dualport
value in the handoff_table is correctly set to 0. In this case, the
workaround is not necessary.

If the Agilex 5 is configured with dual port DDR access, the hack is not
correct either, because while the firmware is configured for dual port,
barebox would incorrectly initialize the IOSSM controller.

Remove the hack.

If the dualport issues become apparent, either use this as a test case
to fix dualport support correctly or implement a proper workaround with
documentation and warning.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/agilex5-sdram.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-socfpga/agilex5-sdram.c b/arch/arm/mach-socfpga/agilex5-sdram.c
index 7a82dc6a6ad4..fa940958d104 100644
--- a/arch/arm/mach-socfpga/agilex5-sdram.c
+++ b/arch/arm/mach-socfpga/agilex5-sdram.c
@@ -94,14 +94,8 @@ static int populate_ddr_handoff(struct altera_sdram_plat *plat, struct io96b_inf
 	/* Read handoff for DDR configuration */
 	socfpga_handoff_read((void *)SOC64_HANDOFF_SDRAM, handoff_table, len);
 
-	/* Read handoff - dual port
-	   FIXME: Intel u-boot has a patch that HACKs this to 0
-	   https://github.com/altera-opensource/meta-intel-fpga-refdes/ \
-	   blob/master/recipes-bsp/u-boot/files/v1-0001-HSD-15015933655-ddr-altera-agilex5-Hack-dual-port-DO-NOT-MERGE.patch
-	   Patch doesn't say why or what is broken here: handoff files? dualport RAM access?
-	 */
-	//plat->dualport = FIELD_GET(BIT(0), handoff_table[PORT_EMIF_CONFIG_OFFSET]);
-	plat->dualport = 0;
+	/* Read handoff - dual port */
+	plat->dualport = FIELD_GET(BIT(0), handoff_table[PORT_EMIF_CONFIG_OFFSET]);
 	pr_debug("%s: dualport from handoff: 0x%x\n", __func__, plat->dualport);
 
 	if (plat->dualport)

-- 
2.47.3




^ permalink raw reply related

* [PATCH 3/5] arm: socfpga: iossm: add delay to wait for firmware
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter
In-Reply-To: <20260604-socfpga-axe5-sdram-init-v1-0-274f6361ce98@pengutronix.de>

Depending on the boot time of barebox, I observed cases, where the IOSSM
version register reported mailbox version 0 even though its version 0.
If this happens, barebox uses the wrong interface to read the SDRAM
configuration, is not able to detect and configure the SDRAM, and fails
to boot.

Unfortunately, the IOSSM firmware does not provide a proper
synchronization point to detect if the firmware finished its
initialization.

Add a workaround to delay the boot until the firmware initialized the
version register or a delay for mailbox version 0.

Don't use readl_poll_timeout, because in the PBL readl_poll_timeout
polls indefinitely and the polling needs to run into the timeout in case
of mailbox version 0.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/iossm_mailbox.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 168bef3faeeb..6a9a7a489b75 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -158,10 +158,27 @@ static int io96b_mb_version(struct io96b_info *io96b_ctrl)
 {
 	void __iomem *io96b_csr_addr = io96b_ctrl->io96b[0].io96b_csr_addr;
 	u32 mailbox_header;
-	int version;
+	int version = 0;
+	int retry;
 
-	mailbox_header = readl(io96b_csr_addr + IOSSM_MAILBOX_HEADER_OFFSET);
-	version = FIELD_GET(IOSSM_MAILBOX_SPEC_VERSION_MASK, mailbox_header);
+	/*
+	 * There is a race between barebox on the HPS and the IOSSM firmware
+	 * initialization, which may cause barebox to read a mailbox version 0
+	 * from the IOSSM even though it's actually mailbox version 1, but the
+	 * register has not been updated, yet. Unfortunately, there is no
+	 * reliable synchronization point.
+	 *
+	 * Workaround this issue by reading the mailbox version more often. On
+	 * mailbox version 1, barebox waits until the firmware wrote the
+	 * version register. On mailbox version 0, barebox runs into the
+	 * timeout caused by the number of retries.
+	 *
+	 * The number of retries has been experimentally determined.
+	 */
+	for (retry = 100; version == 0 && retry > 0; retry--) {
+		mailbox_header = readl(io96b_csr_addr + IOSSM_MAILBOX_HEADER_OFFSET);
+		version = FIELD_GET(IOSSM_MAILBOX_SPEC_VERSION_MASK, mailbox_header);
+	}
 
 	return version;
 }

-- 
2.47.3




^ permalink raw reply related

* [PATCH 1/5] arm: socfpga: agilex5: separate EL3 init function
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter
In-Reply-To: <20260604-socfpga-axe5-sdram-init-v1-0-274f6361ce98@pengutronix.de>

Extract the EL3 initialization from the entry function as cleanup and to
be able to adjust the el3_init code more easily.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/atf.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-socfpga/atf.c b/arch/arm/mach-socfpga/atf.c
index e1f0a3558b04..1fd11c426bc2 100644
--- a/arch/arm/mach-socfpga/atf.c
+++ b/arch/arm/mach-socfpga/atf.c
@@ -61,27 +61,32 @@ static void __noreturn agilex5_load_and_start_image_via_tfa(void)
 	__builtin_unreachable();
 }
 
+static void agilex5_el3_init(void)
+{
+	agilex5_initialize_security_policies();
+	pr_debug("Security policies initialized\n");
+
+	/*
+	 * need to set the bank select enable before the
+	 * agilex5_ddr_init_full() otherwise the serial doesn't show
+	 * anything.
+	 */
+	if (!IS_ENABLED(CONFIG_DEBUG_LL))
+		writel(LCR_BKSE, SOCFPGA_UART0_ADDRESS + LCR);
+	agilex5_ddr_init_full();
+
+	socfpga_agilex5_qspi_init();
+
+	agilex5_load_and_start_image_via_tfa();
+}
+
 void __noreturn agilex5_barebox_entry(void *fdt)
 {
 	phys_addr_t membase;
 	phys_size_t memsize;
 
 	if (current_el() == 3) {
-		agilex5_initialize_security_policies();
-		pr_debug("Security policies initialized\n");
-
-		/*
-		 * need to set the bank select enable before the
-		 * agilex5_ddr_init_full() otherwise the serial doesn't show
-		 * anything.
-		 */
-		if (!IS_ENABLED(CONFIG_DEBUG_LL))
-			writel(LCR_BKSE, SOCFPGA_UART0_ADDRESS + LCR);
-		agilex5_ddr_init_full();
-
-		socfpga_agilex5_qspi_init();
-
-		agilex5_load_and_start_image_via_tfa();
+		agilex5_el3_init();
 		__builtin_unreachable();
 	}
 

-- 
2.47.3




^ permalink raw reply related

* [PATCH 2/5] arm: socfpga: agilex5: panic if DDR init failed
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter
In-Reply-To: <20260604-socfpga-axe5-sdram-init-v1-0-274f6361ce98@pengutronix.de>

There is no point in continuing booting if the DDR initialization has
failed. Panic early to avoid obscure subsequent faults.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/atf.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-socfpga/atf.c b/arch/arm/mach-socfpga/atf.c
index 1fd11c426bc2..6ddfef34632f 100644
--- a/arch/arm/mach-socfpga/atf.c
+++ b/arch/arm/mach-socfpga/atf.c
@@ -63,6 +63,8 @@ static void __noreturn agilex5_load_and_start_image_via_tfa(void)
 
 static void agilex5_el3_init(void)
 {
+	int ret;
+
 	agilex5_initialize_security_policies();
 	pr_debug("Security policies initialized\n");
 
@@ -73,7 +75,9 @@ static void agilex5_el3_init(void)
 	 */
 	if (!IS_ENABLED(CONFIG_DEBUG_LL))
 		writel(LCR_BKSE, SOCFPGA_UART0_ADDRESS + LCR);
-	agilex5_ddr_init_full();
+	ret = agilex5_ddr_init_full();
+	if (ret)
+		panic("DDR initialization failed\n");
 
 	socfpga_agilex5_qspi_init();
 

-- 
2.47.3




^ permalink raw reply related

* [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

The Agilex5 SDRAM initialization contains some obscure and unclear
workarounds, which are supposedly necessary for a successful SDRAM
initialization.

I observed a race condition between the IOSSM firmware, which is
responsible for the SDRAM initialization, and barebox. I assume this
race is responsible for the observed initialization failures.

Add an explicit workaround including documentation for the race
condition and remove the other workarounds.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
Michael Tretter (5):
      arm: socfpga: agilex5: separate EL3 init function
      arm: socfpga: agilex5: panic if DDR init failed
      arm: socfpga: iossm: add delay to wait for firmware
      arm: socfpga: agilex5: drop dual port hack
      arm: socfpga: agilex5: drop bank select before ddr_init

 arch/arm/mach-socfpga/agilex5-sdram.c | 10 ++--------
 arch/arm/mach-socfpga/atf.c           | 32 +++++++++++++++++---------------
 arch/arm/mach-socfpga/iossm_mailbox.c | 23 ++++++++++++++++++++---
 3 files changed, 39 insertions(+), 26 deletions(-)
---
base-commit: 9f6b78063a365b5b2674663ba844fa928937f203
change-id: 20260604-socfpga-axe5-sdram-init-254ac55cd385

Best regards,
-- 
Michael Tretter <m.tretter@pengutronix.de>




^ permalink raw reply

* Re: [PATCH v3 1/2] Add support for extlinux.conf
From: Sascha Hauer @ 2026-06-04 10:40 UTC (permalink / raw)
  To: Alexander Shiyan; +Cc: barebox
In-Reply-To: <CAP1tNvRJvOqD4p74F5EHhaiwrh8-qXN_1X_byM6zfg1uNXSWtg@mail.gmail.com>

On 2026-06-04 11:56, Alexander Shiyan wrote:
> Hello Sascha.
> 
> This change is possible, but then the question arises of how to specify
> the default boot entry.

That's still a blind spot in barebox. Currently there is no way to
specify which entry is booted other than showing up the boot menu.

When I wrote the code I didn't have an idea how to specify an entry in a
reproducible way. Simply specifying the nth bootentry would break
whenever the numbering changes for whatever reason.

For now barebox will boot the entries in list order which means you
would have to make sure that the default entry is added to the front
of the list. You could use bootentries_add_entry_sorted() with the
compare function preferring the default entry for this.


Anyway, ...

> I'd probably prefer to simply specify in the description that we only use
> the DEFAULT entry.

That's fine for now as well.

Sascha

> 
> Thanks!
> 
> чт, 4 июн. 2026 г. в 09:25, Sascha Hauer <s.hauer@pengutronix.de>:
> >
> > Hi Alexander,
> >
> > On 2026-05-29 08:13, Alexander Shiyan wrote:
> > > This adds support for the extlinux.conf configuration format, commonly
> > > used by Syslinux and many Linux distributions. The configuration file
> > > is typically located at /boot/extlinux/extlinux.conf or
> > > /extlinux/extlinux.conf and defines boot entries with kernel, initrd,
> > > device tree, and command line options.
> > >
> > > The implementation integrates with the existing boot entry framework:
> > > - The extlinux scanner discovers entries on mounted filesystems.
> > > - The default LABEL is turned into a boot entry.
> > > - Bootm is used to load and start the kernel.
> > > ---
> > > barebox@Diasom DS-RK3568-SOM-EVB:/ global.bootm.appendroot=true
> > > barebox@Diasom DS-RK3568-SOM-EVB:/ global.boot.default=mmc1.2
> > > barebox@Diasom DS-RK3568-SOM-EVB:/ boot
> > > ext4 ext40: EXT2 rev 1, inode_size 256, descriptor size 64
> > > Booting entry 'extlinux: linux'
> > > extlinux: Booting extlinux label 'linux'
> > > Adding "root=/dev/mmcblk1p3" to Kernel commandline
> > > Loading ARM aarch64 Linux/EFI image '/mnt/mmc1.2/boot/extlinux/../vmlinuz'
> > > commandline: root=/dev/mmcblk1p3 console=ttyS2,1500000n8 ro systemd.unit=setup.target quiet splash systemd.machine_id=181af2816b4c6b0aef77068e0ccc69ad
> > > Loaded kernel to 0x0a400000, devicetree at 0x000000000fb49000
> > >
> > > Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
> > > ---
> > >  common/Kconfig    |  19 ++++
> > >  common/Makefile   |   1 +
> > >  common/extlinux.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++
> > >  3 files changed, 263 insertions(+)
> > >  create mode 100644 common/extlinux.c
> > >
> > > diff --git a/common/Kconfig b/common/Kconfig
> > > index 047dd5390b..6f1eabdf8b 100644
> > > --- a/common/Kconfig
> > > +++ b/common/Kconfig
> > > @@ -776,6 +776,25 @@ config BLSPEC
> > >         on a device and it allows the Operating System to install / update
> > >         kernels.
> > >
> > > +config EXTLINUX
> > > +     bool
> > > +     prompt "Support extlinux.conf"
> > > +     depends on FLEXIBLE_BOOTARGS
> > > +     depends on !SHELL_NONE
> > > +     select BOOT
> > > +     select BOOTM
> > > +     select MMCBLKDEV_ROOTARG if MCI
> > > +     help
> > > +       Enable this to let barebox parse extlinux.conf configuration files,
> > > +       commonly used by the Syslinux bootloader and many Linux distributions
> > > +       (e.g., on SD cards or USB drives).
> > > +       extlinux.conf is typically located at /boot/extlinux/extlinux.conf or
> > > +       /extlinux/extlinux.conf. It defines boot entries with kernel, initrd,
> > > +       device tree, and command line options.
> > > +       This option allows barebox to discover and boot operating systems
> > > +       that follow the extlinux configuration format, providing a simple
> > > +       and portable way to manage multiple boot options.
> > > +
> > >  config FLEXIBLE_BOOTARGS
> > >       bool
> > >       prompt "flexible Linux bootargs generation"
> > > diff --git a/common/Makefile b/common/Makefile
> > > index 21b6cecb3b..6b97edc2c3 100644
> > > --- a/common/Makefile
> > > +++ b/common/Makefile
> > > @@ -9,6 +9,7 @@ obj-y                         += clock.o
> > >  pbl-$(CONFIG_PBL_CLOCKSOURCE)        += clock.o
> > >  obj-y                                += console_common.o
> > >  obj-$(CONFIG_OFDEVICE)               += deep-probe.o
> > > +obj-$(CONFIG_EXTLINUX)               += extlinux.o
> > >  obj-y                                += startup.o
> > >  obj-y                                += misc.o
> > >  obj-pbl-y                    += memsize.o
> > > diff --git a/common/extlinux.c b/common/extlinux.c
> > > new file mode 100644
> > > index 0000000000..6ad01cc652
> > > --- /dev/null
> > > +++ b/common/extlinux.c
> > > @@ -0,0 +1,243 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/* SPDX-FileCopyrightText: Alexander Shiyan <shc_work@mail.ru> */
> > > +
> > > +#define pr_fmt(fmt)     "extlinux: " fmt
> > > +
> > > +#include <boot.h>
> > > +#include <bootm.h>
> > > +#include <bootscan.h>
> > > +#include <common.h>
> > > +#include <environment.h>
> > > +#include <fs.h>
> > > +#include <globalvar.h>
> > > +#include <libfile.h>
> > > +#include <libgen.h>
> > > +#include <string.h>
> > > +
> > > +struct extlinux_entry {
> > > +     struct bootentry entry;
> > > +     char *rootpath;
> > > +     char *label;
> > > +     char *kernel;
> > > +     char *initrd;
> > > +     char *fdtdir;
> > > +     char *fdt;
> > > +     char *append;
> > > +};
> > > +
> > > +static int extlinux_boot(struct bootentry *entry, int verbose, int dryrun)
> > > +{
> > > +     struct extlinux_entry *e =
> > > +             container_of(entry, struct extlinux_entry, entry);
> > > +     char *kernel_abs, *initrd_abs = NULL, *fdt_abs = NULL;
> > > +     struct bootm_data data = {};
> > > +     int ret;
> > > +
> > > +     bootm_data_init_defaults(&data);
> > > +
> > > +     data.dryrun = max_t(int, dryrun, data.dryrun);
> > > +     data.verbose = max(verbose, data.verbose);
> > > +
> > > +     kernel_abs = basprintf("%s/%s", e->rootpath, e->kernel);
> > > +     data.os_file = kernel_abs;
> > > +
> > > +     if (e->initrd) {
> > > +             initrd_abs = basprintf("%s/%s", e->rootpath, e->initrd);
> > > +             data.initrd_file = initrd_abs;
> > > +     }
> > > +
> > > +     if (e->fdt) {
> > > +             char *fdtdir = e->fdtdir ? : e->rootpath;
> > > +
> > > +             fdt_abs = basprintf("%s/%s", fdtdir, e->fdt);
> > > +             data.oftree_file = fdt_abs;
> > > +     }
> > > +
> > > +     if (e->append)
> > > +             globalvar_add_simple("linux.bootargs.dyn.bootentries",
> > > +                                  e->append);
> > > +
> > > +     pr_info("Booting extlinux label '%s'\n", e->label);
> > > +
> > > +     ret = bootm_entry(entry, &data);
> > > +     if (ret)
> > > +             pr_err("bootm failed: %pe\n", ERR_PTR(ret));
> > > +
> > > +     free(kernel_abs);
> > > +     free(initrd_abs);
> > > +     free(fdt_abs);
> > > +
> > > +     return ret;
> > > +}
> > > +
> > > +static void extlinux_entry_free(struct bootentry *entry)
> > > +{
> > > +     struct extlinux_entry *e =
> > > +             container_of(entry, struct extlinux_entry, entry);
> > > +
> > > +     free(e->rootpath);
> > > +     free(e->label);
> > > +     free(e->kernel);
> > > +     free(e->initrd);
> > > +     free(e->fdtdir);
> > > +     free(e->fdt);
> > > +     free(e->append);
> > > +     free(e);
> > > +}
> > > +
> > > +static struct extlinux_entry *parse_extlinux_conf(const char *abspath,
> > > +                                               const char *rootpath)
> > > +{
> > > +     char *buf, *bufptr, *line, *default_label = NULL;
> > > +     struct extlinux_entry *entry = NULL;
> > > +
> > > +     bufptr = read_file(abspath, NULL);
> > > +     if (!bufptr)
> > > +             return ERR_PTR(-errno);
> > > +
> > > +     buf = bufptr;
> > > +     while ((line = strsep(&buf, "\n\r")) != NULL) {
> > > +             char *key, *val;
> > > +
> > > +             line = skip_spaces(line);
> > > +
> > > +             if (*line == '#' || *line == '\0')
> > > +                     continue;
> > > +
> > > +             key = strsep(&line, " \t");
> > > +             val = isempty(line) ? NULL : skip_spaces(line);
> > > +             if (!key || !val)
> > > +                     continue;
> > > +
> > > +             if (!default_label) {
> > > +                     if (!strcasecmp(key, "DEFAULT"))
> > > +                             default_label = xstrdup(val);
> > > +
> > > +                     continue;
> > > +             }
> > > +
> > > +             if (!strcasecmp(key, "LABEL")) {
> > > +                     if (!strcmp(val, default_label)) {
> > > +                             entry = xzalloc(sizeof(*entry));
> > > +                             entry->label = xstrdup(val);
> > > +                             entry->rootpath = dirname(xstrdup(abspath));
> > > +                     } else if (entry) {
> > > +                             break;
> > > +                     }
> >
> > The extlinux format supports multiple entries, but you return here after
> > the first entry parsed. We should either document that we only support a
> > single entry or implement multiple entries.
> >
> > Unless I am overlooking something it should be quite straight forward to
> > implement multiple entries, just move the call to bootentries_add_entry()
> > into this loop.
> >
> > Sascha
> >
> > --
> > Pengutronix e.K.                           |                             |
> > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply

* Re: [PATCH v3 1/2] Add support for extlinux.conf
From: Alexander Shiyan @ 2026-06-04  8:56 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox
In-Reply-To: <E1wV1Vo-00000003qL5-1qY3@pty.whiteo.stw.pengutronix.de>

Hello Sascha.

This change is possible, but then the question arises of how to specify
the default boot entry.
I'd probably prefer to simply specify in the description that we only use
the DEFAULT entry.

Thanks!

чт, 4 июн. 2026 г. в 09:25, Sascha Hauer <s.hauer@pengutronix.de>:
>
> Hi Alexander,
>
> On 2026-05-29 08:13, Alexander Shiyan wrote:
> > This adds support for the extlinux.conf configuration format, commonly
> > used by Syslinux and many Linux distributions. The configuration file
> > is typically located at /boot/extlinux/extlinux.conf or
> > /extlinux/extlinux.conf and defines boot entries with kernel, initrd,
> > device tree, and command line options.
> >
> > The implementation integrates with the existing boot entry framework:
> > - The extlinux scanner discovers entries on mounted filesystems.
> > - The default LABEL is turned into a boot entry.
> > - Bootm is used to load and start the kernel.
> > ---
> > barebox@Diasom DS-RK3568-SOM-EVB:/ global.bootm.appendroot=true
> > barebox@Diasom DS-RK3568-SOM-EVB:/ global.boot.default=mmc1.2
> > barebox@Diasom DS-RK3568-SOM-EVB:/ boot
> > ext4 ext40: EXT2 rev 1, inode_size 256, descriptor size 64
> > Booting entry 'extlinux: linux'
> > extlinux: Booting extlinux label 'linux'
> > Adding "root=/dev/mmcblk1p3" to Kernel commandline
> > Loading ARM aarch64 Linux/EFI image '/mnt/mmc1.2/boot/extlinux/../vmlinuz'
> > commandline: root=/dev/mmcblk1p3 console=ttyS2,1500000n8 ro systemd.unit=setup.target quiet splash systemd.machine_id=181af2816b4c6b0aef77068e0ccc69ad
> > Loaded kernel to 0x0a400000, devicetree at 0x000000000fb49000
> >
> > Signed-off-by: Alexander Shiyan <eagle.alexander923@gmail.com>
> > ---
> >  common/Kconfig    |  19 ++++
> >  common/Makefile   |   1 +
> >  common/extlinux.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 263 insertions(+)
> >  create mode 100644 common/extlinux.c
> >
> > diff --git a/common/Kconfig b/common/Kconfig
> > index 047dd5390b..6f1eabdf8b 100644
> > --- a/common/Kconfig
> > +++ b/common/Kconfig
> > @@ -776,6 +776,25 @@ config BLSPEC
> >         on a device and it allows the Operating System to install / update
> >         kernels.
> >
> > +config EXTLINUX
> > +     bool
> > +     prompt "Support extlinux.conf"
> > +     depends on FLEXIBLE_BOOTARGS
> > +     depends on !SHELL_NONE
> > +     select BOOT
> > +     select BOOTM
> > +     select MMCBLKDEV_ROOTARG if MCI
> > +     help
> > +       Enable this to let barebox parse extlinux.conf configuration files,
> > +       commonly used by the Syslinux bootloader and many Linux distributions
> > +       (e.g., on SD cards or USB drives).
> > +       extlinux.conf is typically located at /boot/extlinux/extlinux.conf or
> > +       /extlinux/extlinux.conf. It defines boot entries with kernel, initrd,
> > +       device tree, and command line options.
> > +       This option allows barebox to discover and boot operating systems
> > +       that follow the extlinux configuration format, providing a simple
> > +       and portable way to manage multiple boot options.
> > +
> >  config FLEXIBLE_BOOTARGS
> >       bool
> >       prompt "flexible Linux bootargs generation"
> > diff --git a/common/Makefile b/common/Makefile
> > index 21b6cecb3b..6b97edc2c3 100644
> > --- a/common/Makefile
> > +++ b/common/Makefile
> > @@ -9,6 +9,7 @@ obj-y                         += clock.o
> >  pbl-$(CONFIG_PBL_CLOCKSOURCE)        += clock.o
> >  obj-y                                += console_common.o
> >  obj-$(CONFIG_OFDEVICE)               += deep-probe.o
> > +obj-$(CONFIG_EXTLINUX)               += extlinux.o
> >  obj-y                                += startup.o
> >  obj-y                                += misc.o
> >  obj-pbl-y                    += memsize.o
> > diff --git a/common/extlinux.c b/common/extlinux.c
> > new file mode 100644
> > index 0000000000..6ad01cc652
> > --- /dev/null
> > +++ b/common/extlinux.c
> > @@ -0,0 +1,243 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/* SPDX-FileCopyrightText: Alexander Shiyan <shc_work@mail.ru> */
> > +
> > +#define pr_fmt(fmt)     "extlinux: " fmt
> > +
> > +#include <boot.h>
> > +#include <bootm.h>
> > +#include <bootscan.h>
> > +#include <common.h>
> > +#include <environment.h>
> > +#include <fs.h>
> > +#include <globalvar.h>
> > +#include <libfile.h>
> > +#include <libgen.h>
> > +#include <string.h>
> > +
> > +struct extlinux_entry {
> > +     struct bootentry entry;
> > +     char *rootpath;
> > +     char *label;
> > +     char *kernel;
> > +     char *initrd;
> > +     char *fdtdir;
> > +     char *fdt;
> > +     char *append;
> > +};
> > +
> > +static int extlinux_boot(struct bootentry *entry, int verbose, int dryrun)
> > +{
> > +     struct extlinux_entry *e =
> > +             container_of(entry, struct extlinux_entry, entry);
> > +     char *kernel_abs, *initrd_abs = NULL, *fdt_abs = NULL;
> > +     struct bootm_data data = {};
> > +     int ret;
> > +
> > +     bootm_data_init_defaults(&data);
> > +
> > +     data.dryrun = max_t(int, dryrun, data.dryrun);
> > +     data.verbose = max(verbose, data.verbose);
> > +
> > +     kernel_abs = basprintf("%s/%s", e->rootpath, e->kernel);
> > +     data.os_file = kernel_abs;
> > +
> > +     if (e->initrd) {
> > +             initrd_abs = basprintf("%s/%s", e->rootpath, e->initrd);
> > +             data.initrd_file = initrd_abs;
> > +     }
> > +
> > +     if (e->fdt) {
> > +             char *fdtdir = e->fdtdir ? : e->rootpath;
> > +
> > +             fdt_abs = basprintf("%s/%s", fdtdir, e->fdt);
> > +             data.oftree_file = fdt_abs;
> > +     }
> > +
> > +     if (e->append)
> > +             globalvar_add_simple("linux.bootargs.dyn.bootentries",
> > +                                  e->append);
> > +
> > +     pr_info("Booting extlinux label '%s'\n", e->label);
> > +
> > +     ret = bootm_entry(entry, &data);
> > +     if (ret)
> > +             pr_err("bootm failed: %pe\n", ERR_PTR(ret));
> > +
> > +     free(kernel_abs);
> > +     free(initrd_abs);
> > +     free(fdt_abs);
> > +
> > +     return ret;
> > +}
> > +
> > +static void extlinux_entry_free(struct bootentry *entry)
> > +{
> > +     struct extlinux_entry *e =
> > +             container_of(entry, struct extlinux_entry, entry);
> > +
> > +     free(e->rootpath);
> > +     free(e->label);
> > +     free(e->kernel);
> > +     free(e->initrd);
> > +     free(e->fdtdir);
> > +     free(e->fdt);
> > +     free(e->append);
> > +     free(e);
> > +}
> > +
> > +static struct extlinux_entry *parse_extlinux_conf(const char *abspath,
> > +                                               const char *rootpath)
> > +{
> > +     char *buf, *bufptr, *line, *default_label = NULL;
> > +     struct extlinux_entry *entry = NULL;
> > +
> > +     bufptr = read_file(abspath, NULL);
> > +     if (!bufptr)
> > +             return ERR_PTR(-errno);
> > +
> > +     buf = bufptr;
> > +     while ((line = strsep(&buf, "\n\r")) != NULL) {
> > +             char *key, *val;
> > +
> > +             line = skip_spaces(line);
> > +
> > +             if (*line == '#' || *line == '\0')
> > +                     continue;
> > +
> > +             key = strsep(&line, " \t");
> > +             val = isempty(line) ? NULL : skip_spaces(line);
> > +             if (!key || !val)
> > +                     continue;
> > +
> > +             if (!default_label) {
> > +                     if (!strcasecmp(key, "DEFAULT"))
> > +                             default_label = xstrdup(val);
> > +
> > +                     continue;
> > +             }
> > +
> > +             if (!strcasecmp(key, "LABEL")) {
> > +                     if (!strcmp(val, default_label)) {
> > +                             entry = xzalloc(sizeof(*entry));
> > +                             entry->label = xstrdup(val);
> > +                             entry->rootpath = dirname(xstrdup(abspath));
> > +                     } else if (entry) {
> > +                             break;
> > +                     }
>
> The extlinux format supports multiple entries, but you return here after
> the first entry parsed. We should either document that we only support a
> single entry or implement multiple entries.
>
> Unless I am overlooking something it should be quite straight forward to
> implement multiple entries, just move the call to bootentries_add_entry()
> into this loop.
>
> Sascha
>
> --
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply

* [PATCH v2 07/11] video: lcdif: default to RGB888_1X24 on VPL_GET_BUS_FORMAT failure
From: Johannes Schneider @ 2026-06-04  6:50 UTC (permalink / raw)
  To: barebox, a.fatoum, mgr, l.stach; +Cc: thomas.haemmerle, Johannes Schneider
In-Reply-To: <20260604065006.2933142-1-johannes.schneider@leica-geosystems.com>

VPL_GET_BUS_FORMAT walks downstream through the bridge to the panel.
Today neither fsl-ldb (which forwards the call) nor simple-panel
(which reads a "bus-format" DT property) succeeds for DTs that follow
the Linux panel-lvds binding -- that binding describes the LVDS data
mapping in "data-mapping", not as a discrete bus-format integer.

The driver currently aborts enable on the -EINVAL, leaving /dev/fb0
registered but nothing scanning out.  Default to RGB888_1X24 instead
-- the parallel format LCDIFv3 hands to every RGB888 bridge regardless
of what the panel ultimately drives onto the wire.

Signed-off-by: Johannes Schneider <johannes.schneider@leica-geosystems.com>
---
 drivers/video/lcdif_kms.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/video/lcdif_kms.c b/drivers/video/lcdif_kms.c
index a113f3e681..5487d1298c 100644
--- a/drivers/video/lcdif_kms.c
+++ b/drivers/video/lcdif_kms.c
@@ -364,8 +364,11 @@ static void lcdif_enable_fb_controller(struct fb_info *info)
 
 	ret = vpl_ioctl(&lcdif->vpl, lcdif->id, VPL_GET_BUS_FORMAT, &vcstate.bus_format);
 	if (ret < 0) {
-		dev_err(lcdif->dev, "Cannot determine bus format\n");
-		return;
+		/* default for panel-lvds DTs lacking bus-format / bridges not answering */
+		dev_warn(lcdif->dev,
+			 "VPL_GET_BUS_FORMAT failed (%pe), defaulting to RGB888_1X24\n",
+			 ERR_PTR(ret));
+		vcstate.bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 	}
 
 	ret = vpl_ioctl(&lcdif->vpl, lcdif->id, VPL_GET_DISPLAY_INFO, &display_info);
-- 
2.43.0




^ permalink raw reply related

* Re: [PATCH 0/4] ARM: i.MX6UL: initialize snvs peripheral
From: Sascha Hauer @ 2026-06-04  7:02 UTC (permalink / raw)
  To: open list:BAREBOX, Stefan Kerkmann
In-Reply-To: <20260603-feature-snvs-imx6ul-v1-0-6305f63bd3fa@pengutronix.de>


On Wed, 03 Jun 2026 15:33:41 +0200, Stefan Kerkmann wrote:
> This series adds snvs peripheral initialization for the i.MX6UL soc
> which is necessary to write values into the snvs lpgpr register.
> 
> To make the code more consistent across the i.MX6/7/8M families some
> smaller cleanups are included as well.
> 
> 
> [...]

Applied, thanks!

[1/4] nvmem: snvs_lpgpr: remove unnecessary cfg->name assignment
      https://git.pengutronix.de/cgit/barebox/commit/?id=d37ceab82e82 (link may not be stable)
[2/4] ARM: i.MX8M/i.MX7: initialize SNVS glitch detection for all families
      https://git.pengutronix.de/cgit/barebox/commit/?id=f0eaecb91875 (link may not be stable)
[3/4] ARM: i.MX7: snvs: rename imx7_snvs_init -> imx7_setup_snvs
      https://git.pengutronix.de/cgit/barebox/commit/?id=536ed336c59f (link may not be stable)
[4/4] ARM: i.MX6UL: initialize SNVS
      https://git.pengutronix.de/cgit/barebox/commit/?id=7c4ecef454dd (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply

* [PATCH v2 06/11] video: lcdif: use 128B AXI bursts to avoid right-edge gap
From: Johannes Schneider @ 2026-06-04  6:50 UTC (permalink / raw)
  To: barebox, a.fatoum, mgr, l.stach; +Cc: thomas.haemmerle
In-Reply-To: <20260604065006.2933142-1-johannes.schneider@leica-geosystems.com>

From: Thomas Haemmerle <thomas.haemmerle@leica-geosystems.com>

P_SIZE/T_SIZE are undocumented AXI-burst-size selectors: 1 = 128 byte,
2 = 256 byte.  The driver inherited 256B from NXP downstream, which
works for 1080p (stride 7680 B = 30 * 256 B) but breaks on narrower
32 bpp panels whose row byte count isn't a multiple of 256.

On an 800-pixel row at XRGB8888, stride = 3200 B = 12.5 * 256 B.  The
trailing partial burst is dropped and the panel shows a ~32-pixel-wide
black strip at the right edge.  128B is a divisor of every common
32 bpp stride (3200, 3840, 5120, ...), so the gap disappears.

Signed-off-by: Thomas Haemmerle <thomas.haemmerle@leica-geosystems.com>
---
 drivers/video/lcdif_kms.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/video/lcdif_kms.c b/drivers/video/lcdif_kms.c
index 3a31633818..a113f3e681 100644
--- a/drivers/video/lcdif_kms.c
+++ b/drivers/video/lcdif_kms.c
@@ -216,18 +216,14 @@ static void lcdif_set_mode(struct lcdif_drm_private *lcdif,
 	       lcdif->base + LCDC_V8_CTRLDESCL0_1);
 
 	/*
-	 * Undocumented P_SIZE and T_SIZE register but those written in the
-	 * downstream kernel those registers control the AXI burst size. As of
-	 * now there are two known values:
-	 *  1 - 128Byte
-	 *  2 - 256Byte
-	 * Downstream set it to 256B burst size to improve the memory
-	 * efficiency so set it here too.
+	 * P_SIZE/T_SIZE are undocumented AXI-burst-size selectors:
+	 * 1 = 128 byte, 2 = 256 byte.  Use 128B so any 32 bpp row divides
+	 * into whole bursts; 256B on an 800-pixel row produces a partial
+	 * trailing burst and a ~32-pixel black strip at the right edge.
+	 *
+	 * Stride is fixed to hdisplay * 4 (DRM_FORMAT_XRGB8888).
 	 */
-	/* NOTE: Since this driver is currently fixed to DRM_FORMAT_XRGB8888
-	 * we asume a stride of vdisplay * 4
-	 */
-	ctrl = CTRLDESCL0_3_P_SIZE(2) | CTRLDESCL0_3_T_SIZE(2) |
+	ctrl = CTRLDESCL0_3_P_SIZE(1) | CTRLDESCL0_3_T_SIZE(1) |
 	       CTRLDESCL0_3_PITCH(m->hdisplay * 4);
 	writel(ctrl, lcdif->base + LCDC_V8_CTRLDESCL0_3);
 }
-- 
2.43.0




^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox