diff mbox series

[1/2] clk: meson: gxbb: add HDMI clocks

Message ID 20241009-u-boot-topic-fix-hdmi-v1-1-2479cd90c4ea@linaro.org
State Accepted
Commit 53a9baeefb646a929483aee02ed8ed92a08169e0
Headers show
Series ARM: mach-meson: fix HDMI since DT update to v6.11 | expand

Commit Message

Neil Armstrong Oct. 9, 2024, 9:15 a.m. UTC
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 mbox series

Patch

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;
 	}