This patch corrects display clocks for i.MX8qxp DC0 subsystem by calling imx_clk_scu2() to register them, instead of calling imx_clk_scu(). The reason is that the clocks can source from various parents. The clock source selection is controlled by Distributed Slave System Controller(DSC). According to the DSC spec, the below table describes the generic source selections for clocks with the same type in various subsystems. And, the display controller subsystem spec says the display clocks can source from PLL1, PLL2 or bypass clock, thus we may specify the correct parents for imx_clk_scu2(). The bypass clock's parent is determined by the SCU firmware. Currently, the parent is 'pixel_link_clk_in' from HW point of view. To be more specific, the parent is dummy for i.MX8qxp DC0, while HDMI TX PHY PLL for i.MX8qm DC0. In practice, the display clocks source from the bypass clock only when driving i.MX8qm HDMI TX. So, for the both display clocks, we simply specify 'dc0_bypass0_clk' bypass clock as a valid parent. ----------------------------------------- | src_sel[28:26] | | ----------------------------------------- | 0x0 | xtal24M | | 0x1 | PLL0 | | 0x2 | PLL1 | | 0x3 | PLL2 | | 0x4 | bypass reference clock | | 0x5 to 0x7 | reserved | ----------------------------------------- Cc: Michael Turquette <mturquette@xxxxxxxxxxxx> Cc: Stephen Boyd <sboyd@xxxxxxxxxx> Cc: Shawn Guo <shawnguo@xxxxxxxxxx> Cc: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> Cc: Pengutronix Kernel Team <kernel@xxxxxxxxxxxxxx> Cc: Fabio Estevam <festevam@xxxxxxxxx> Cc: NXP Linux Team <linux-imx@xxxxxxx> Cc: Dong Aisheng <aisheng.dong@xxxxxxx> Signed-off-by: Liu Ying <victor.liu@xxxxxxx> --- v1->v2: * Newly introduced in v2. drivers/clk/imx/clk-imx8qxp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c index af6a545..0b4bb2c 100644 --- a/drivers/clk/imx/clk-imx8qxp.c +++ b/drivers/clk/imx/clk-imx8qxp.c @@ -17,6 +17,14 @@ #include <dt-bindings/clock/imx8-clock.h> #include <dt-bindings/firmware/imx/rsrc.h> +static const char *dc0_sels[] = { + "clk_dummy", + "clk_dummy", + "dc0_pll0_clk", + "dc0_pll1_clk", + "dc0_bypass0_clk", +}; + static int imx8qxp_clk_probe(struct platform_device *pdev) { struct device_node *ccm_node = pdev->dev.of_node; @@ -115,8 +123,8 @@ static int imx8qxp_clk_probe(struct platform_device *pdev) clks[IMX_CONN_USB2_LPM_CLK] = imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC, clk_cells); /* Display controller SS */ - clks[IMX_DC0_DISP0_CLK] = imx_clk_scu("dc0_disp0_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0, clk_cells); - clks[IMX_DC0_DISP1_CLK] = imx_clk_scu("dc0_disp1_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1, clk_cells); + clks[IMX_DC0_DISP0_CLK] = imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0, clk_cells); + clks[IMX_DC0_DISP1_CLK] = imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1, clk_cells); clks[IMX_DC0_PLL0_CLK] = imx_clk_scu("dc0_pll0_clk", IMX_SC_R_DC_0_PLL_0, IMX_SC_PM_CLK_PLL, clk_cells); clks[IMX_DC0_PLL1_CLK] = imx_clk_scu("dc0_pll1_clk", IMX_SC_R_DC_0_PLL_1, IMX_SC_PM_CLK_PLL, clk_cells); clks[IMX_DC0_BYPASS0_CLK] = imx_clk_scu("dc0_bypass0_clk", IMX_SC_R_DC_0_VIDEO0, IMX_SC_PM_CLK_BYPASS, clk_cells); -- 2.7.4