[PATCH] clk: imx: composite-8m: Fix clock divisions greater than 8

Adam Ford aford173 at gmail.com
Sun Apr 16 12:10:51 PDT 2023


When adding imx8m_clk_divider_determine_rate to let the imx8mm
and imx8mn get finer granulatiry of video clocks, it accidentally
broke the imx8mp ability to divide clocks by more than 8 on clocks
when the CLK_SET_RATE_PARENT flag is not set.

On the imx8mp, the CLK_SET_RATE_PARENT flag cannot be set on either
media_disp1_pix or media_disp2_pix, because they both share the
video_pll as a common clock, and if two displays are used, the
parent clock needs to be something that both child clocks can
divide.

imx8m_clk_divider_determine_rate ends up calling clk_divider_bestdiv
which uses the value of 'width' to setup the maximum divisor.  The
clk-composite-8m driver sets the with to 3 which means the maximum
divisor is 8, but these clocks can divide by up to 64.

Currently, if the video_pll is set to 1039500000, the slowest clock
rate achievable is 129937500 which breaks a whole bunch of lower
resolution and refresh options for both media_disp1_pix and
media_disp2_pix.

By changing the 'width' variable to PCG_DIV_WIDTH, the maximum
divisor becomes 64 which allows the clocks to divide down more,
so the lower resolutions and refresh rates are achievable again.

Fixes: 156e96ff2172 ("clk: imx: composite-8m: Add support to determine_rate")
Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c
index 6883a8199b6c..805e6aada83d 100644
--- a/drivers/clk/imx/clk-composite-8m.c
+++ b/drivers/clk/imx/clk-composite-8m.c
@@ -47,6 +47,7 @@ static unsigned long imx8m_clk_composite_divider_recalc_rate(struct clk_hw *hw,
 				   divider->flags, PCG_DIV_WIDTH);
 }
 
+
 static int imx8m_clk_composite_compute_dividers(unsigned long rate,
 						unsigned long parent_rate,
 						int *prediv, int *postdiv)
@@ -215,12 +216,12 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
 		mux_ops = &imx8m_clk_composite_mux_ops;
 	} else if (composite_flags & IMX_COMPOSITE_BUS) {
 		div->shift = PCG_PREDIV_SHIFT;
-		div->width = PCG_PREDIV_WIDTH;
+		div->width = PCG_DIV_WIDTH;
 		divider_ops = &imx8m_clk_composite_divider_ops;
 		mux_ops = &imx8m_clk_composite_mux_ops;
 	} else {
 		div->shift = PCG_PREDIV_SHIFT;
-		div->width = PCG_PREDIV_WIDTH;
+		div->width = PCG_DIV_WIDTH;
 		divider_ops = &imx8m_clk_composite_divider_ops;
 		mux_ops = &clk_mux_ops;
 		if (!(composite_flags & IMX_COMPOSITE_FW_MANAGED))
-- 
2.39.2




More information about the linux-arm-kernel mailing list