[PATCH 0/2] ARM: mach-meson: fix HDMI since DT update to v6.11

The DT was updated with unhandled clocks and a shared power domain, causing a probe failure and a green output.
Add the missing clocks and avoid enabling a power domain twice.
Signed-off-by: Neil Armstrong neil.armstrong@linaro.org --- Neil Armstrong (2): clk: meson: gxbb: add HDMI clocks power/domain: meson-ee-pwrc: make sure to not enable a domain twice
drivers/clk/meson/gxbb.c | 50 +++++++++++++++++++++++++++++++++++- drivers/power/domain/meson-ee-pwrc.c | 15 +++++++++-- 2 files changed, 62 insertions(+), 3 deletions(-) --- base-commit: 28dc47038edc4e93f32d75a357131bcf01a18d85 change-id: 20241009-u-boot-topic-fix-hdmi-bb39cd876446
Best regards,

Align with g12a driver to handle the CLKID_HDMI, CLKID_HDMI_SEL and CLKID_HDMI_DIV clocks since they were added to the upstream GXBB/GXL Devicetree on v6.11 with [1]
[1] https://lore.kernel.org/all/20240626152733.1350376-1-jbrunet@baylibre.com/
Signed-off-by: Neil Armstrong neil.armstrong@linaro.org --- drivers/clk/meson/gxbb.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 72ad4fd0e85..51f124869c9 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -66,6 +66,8 @@ #define CLKID_VDEC_HEVC_SEL 154 #define CLKID_VDEC_HEVC_DIV 155
+#define CLKID_XTAL 0x10000000 + #define XTAL_RATE 24000000
struct meson_clk { @@ -192,6 +194,7 @@ static struct meson_gate gates[] = { MESON_GATE(CLKID_VAPB_0, HHI_VAPBCLK_CNTL, 8), MESON_GATE(CLKID_VAPB_1, HHI_VAPBCLK_CNTL, 24), MESON_GATE(CLKID_VAPB, HHI_VAPBCLK_CNTL, 30), + MESON_GATE(CLKID_HDMI, HHI_HDMI_CLK_CNTL, 8), };
static int meson_set_gate_by_id(struct clk *clk, unsigned long id, bool on) @@ -267,6 +270,12 @@ static struct parm meson_vapb_1_div_parm = {
int meson_vapb_1_div_parent = CLKID_VAPB_1_SEL;
+static struct parm meson_hdmi_div_parm = { + HHI_HDMI_CLK_CNTL, 0, 7, +}; + +int meson_hdmi_div_parent = CLKID_HDMI_SEL; + static ulong meson_div_get_rate(struct clk *clk, unsigned long id) { struct meson_clk *priv = dev_get_priv(clk->dev); @@ -292,6 +301,10 @@ static ulong meson_div_get_rate(struct clk *clk, unsigned long id) parm = &meson_vapb_1_div_parm; parent = meson_vapb_1_div_parent; break; + case CLKID_HDMI_DIV: + parm = &meson_hdmi_div_parm; + parent = meson_hdmi_div_parent; + break; default: return -ENOENT; } @@ -347,6 +360,10 @@ static ulong meson_div_set_rate(struct clk *clk, unsigned long id, ulong rate, parm = &meson_vapb_1_div_parm; parent = meson_vapb_1_div_parent; break; + case CLKID_HDMI_DIV: + parm = &meson_hdmi_div_parm; + parent = meson_hdmi_div_parent; + break; default: return -ENOENT; } @@ -443,6 +460,17 @@ static int meson_vapb_0_1_mux_parents[] = { CLKID_FCLK_DIV7, };
+static struct parm meson_hdmi_mux_parm = { + HHI_HDMI_CLK_CNTL, 9, 2, +}; + +static int meson_hdmi_mux_parents[] = { + CLKID_XTAL, + CLKID_FCLK_DIV4, + CLKID_FCLK_DIV3, + CLKID_FCLK_DIV5, +}; + static ulong meson_mux_get_parent(struct clk *clk, unsigned long id) { struct meson_clk *priv = dev_get_priv(clk->dev); @@ -475,6 +503,10 @@ static ulong meson_mux_get_parent(struct clk *clk, unsigned long id) parm = &meson_vapb_1_mux_parm; parents = meson_vapb_0_1_mux_parents; break; + case CLKID_HDMI_SEL: + parm = &meson_hdmi_mux_parm; + parents = meson_hdmi_mux_parents; + break; default: return -ENOENT; } @@ -532,6 +564,10 @@ static ulong meson_mux_set_parent(struct clk *clk, unsigned long id, parm = &meson_vapb_1_mux_parm; parents = meson_vapb_0_1_mux_parents; break; + case CLKID_HDMI_SEL: + parm = &meson_hdmi_mux_parm; + parents = meson_hdmi_mux_parents; + break; default: /* Not a mux */ return -ENOENT; @@ -572,7 +608,7 @@ static unsigned long meson_clk81_get_rate(struct clk *clk) unsigned long parent_rate; uint reg; int parents[] = { - -1, + CLKID_XTAL, -1, CLKID_FCLK_DIV7, CLKID_MPLL1, @@ -727,6 +763,9 @@ static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id) ulong rate;
switch (id) { + case CLKID_XTAL: + rate = XTAL_RATE; + break; case CLKID_FIXED_PLL: case CLKID_SYS_PLL: rate = meson_pll_get_rate(clk, id); @@ -769,10 +808,14 @@ static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id) case CLKID_VAPB_1: rate = meson_div_get_rate(clk, CLKID_VAPB_1_DIV); break; + case CLKID_HDMI: + rate = meson_div_get_rate(clk, CLKID_HDMI_DIV); + break; case CLKID_VPU_0_DIV: case CLKID_VPU_1_DIV: case CLKID_VAPB_0_DIV: case CLKID_VAPB_1_DIV: + case CLKID_HDMI_DIV: rate = meson_div_get_rate(clk, id); break; case CLKID_VPU: @@ -781,6 +824,7 @@ static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id) case CLKID_VAPB_SEL: case CLKID_VAPB_0_SEL: case CLKID_VAPB_1_SEL: + case CLKID_HDMI_SEL: rate = meson_mux_get_rate(clk, id); break; default: @@ -851,7 +895,11 @@ static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id, case CLKID_VPU_1_DIV: case CLKID_VAPB_0_DIV: case CLKID_VAPB_1_DIV: + case CLKID_HDMI_DIV: return meson_div_set_rate(clk, id, rate, current_rate); + case CLKID_HDMI: + return meson_clk_set_rate_by_id(clk, CLKID_HDMI_DIV, + rate, current_rate); default: return -ENOENT; }

The upstream Device Tree for GXBB/GXL/G12A was updated with VPU domain shared between the VPU and HDMI node, causing a double enable.
Simply store the enable state and avoid enabling twice, fixing HDMI output on all platforms.
Signed-off-by: Neil Armstrong neil.armstrong@linaro.org --- drivers/power/domain/meson-ee-pwrc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/power/domain/meson-ee-pwrc.c b/drivers/power/domain/meson-ee-pwrc.c index 20e9f32b381..4d9f3bba644 100644 --- a/drivers/power/domain/meson-ee-pwrc.c +++ b/drivers/power/domain/meson-ee-pwrc.c @@ -60,6 +60,7 @@ struct meson_ee_pwrc_domain_desc { unsigned int mem_pd_count; struct meson_ee_pwrc_mem_domain *mem_pd; bool (*get_power)(struct power_domain *power_domain); + bool enabled; };
struct meson_ee_pwrc_domain_data { @@ -306,6 +307,8 @@ static int meson_ee_pwrc_off(struct power_domain *power_domain) clk_disable_bulk(&priv->clks); }
+ pwrc_domain->enabled = false; + return 0; }
@@ -317,6 +320,9 @@ static int meson_ee_pwrc_on(struct power_domain *power_domain)
pwrc_domain = &priv->data->domains[power_domain->id];
+ if (pwrc_domain->enabled) + return 0; + if (pwrc_domain->top_pd) regmap_update_bits(priv->regmap_ao, pwrc_domain->top_pd->sleep_reg, @@ -347,8 +353,13 @@ static int meson_ee_pwrc_on(struct power_domain *power_domain) return ret; }
- if (pwrc_domain->clk_names_count) - return clk_enable_bulk(&priv->clks); + if (pwrc_domain->clk_names_count) { + ret = clk_enable_bulk(&priv->clks); + if (ret) + return ret; + } + + pwrc_domain->enabled = true;
return 0; }

-----Original Message----- From: Neil Armstrong neil.armstrong@linaro.org Sent: Wednesday, October 9, 2024 6:15 PM To: Lukasz Majewski lukma@denx.de; Sean Anderson seanga2@gmail.com; Tom Rini trini@konsulko.com; Jaehoon Chung jh80.chung@samsung.com Cc: u-boot-amlogic@groups.io; u-boot@lists.denx.de; Neil Armstrong neil.armstrong@linaro.org Subject: [PATCH 2/2] power/domain: meson-ee-pwrc: make sure to not enable a domain twice
The upstream Device Tree for GXBB/GXL/G12A was updated with VPU domain shared between the VPU and HDMI node, causing a double enable.
Simply store the enable state and avoid enabling twice, fixing HDMI output on all platforms.
Signed-off-by: Neil Armstrong neil.armstrong@linaro.org
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
drivers/power/domain/meson-ee-pwrc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/power/domain/meson-ee-pwrc.c b/drivers/power/domain/meson-ee-pwrc.c index 20e9f32b381..4d9f3bba644 100644 --- a/drivers/power/domain/meson-ee-pwrc.c +++ b/drivers/power/domain/meson-ee-pwrc.c @@ -60,6 +60,7 @@ struct meson_ee_pwrc_domain_desc { unsigned int mem_pd_count; struct meson_ee_pwrc_mem_domain *mem_pd; bool (*get_power)(struct power_domain *power_domain);
- bool enabled;
};
struct meson_ee_pwrc_domain_data { @@ -306,6 +307,8 @@ static int meson_ee_pwrc_off(struct power_domain *power_domain) clk_disable_bulk(&priv->clks); }
- pwrc_domain->enabled = false;
- return 0;
}
@@ -317,6 +320,9 @@ static int meson_ee_pwrc_on(struct power_domain *power_domain)
pwrc_domain = &priv->data->domains[power_domain->id];
- if (pwrc_domain->enabled)
return 0;
- if (pwrc_domain->top_pd) regmap_update_bits(priv->regmap_ao, pwrc_domain->top_pd->sleep_reg,
@@ -347,8 +353,13 @@ static int meson_ee_pwrc_on(struct power_domain *power_domain) return ret; }
- if (pwrc_domain->clk_names_count)
return clk_enable_bulk(&priv->clks);
if (pwrc_domain->clk_names_count) {
ret = clk_enable_bulk(&priv->clks);
if (ret)
return ret;
}
pwrc_domain->enabled = true;
return 0;
}
-- 2.34.1

Hi,
On Wed, 09 Oct 2024 11:15:19 +0200, Neil Armstrong wrote:
The DT was updated with unhandled clocks and a shared power domain, causing a probe failure and a green output.
Add the missing clocks and avoid enabling a power domain twice.
Thanks, Applied to https://source.denx.de/u-boot/custodians/u-boot-amlogic (u-boot-amlogic-next)
[1/2] clk: meson: gxbb: add HDMI clocks https://source.denx.de/u-boot/custodians/u-boot-amlogic/-/commit/2958fd431af... [2/2] power/domain: meson-ee-pwrc: make sure to not enable a domain twice https://source.denx.de/u-boot/custodians/u-boot-amlogic/-/commit/25b489e2cb8...
participants (2)
-
Jaehoon Chung
-
Neil Armstrong