[12/21] clk: imx8mn: add video clocks support

Message ID 20240713084526.922537-12-michael@amarulasolutions.com
State New
Headers show
Series
  • [01/21] clk: Propagate clk_set_rate() if CLK_SET_PARENT_RATE present for gate and mux
Related show

Commit Message

Michael Trimarchi July 13, 2024, 8:45 a.m. UTC
Add clocks support for the video subsystem.

Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
---
 drivers/clk/imx/clk-imx8mn.c | 72 ++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

Patch

diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index 31d2faa97a..089f5169da 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -17,6 +17,7 @@ 
 static u32 share_count_nand;
 
 static const char * const pll_ref_sels[] = { "clock-osc-24m", "dummy", "dummy", "dummy", };
+static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
 static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
 static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
 static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
@@ -44,6 +45,34 @@  static const char * const imx8mn_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_2
 						    "video_pll_out", "sys_pll3_out", };
 
 #ifndef CONFIG_SPL_BUILD
+static const char * const imx8mn_disp_axi_sels[] = {"clock-osc-24m", "sys_pll2_1000m", "sys_pll1_800m",
+					     "sys_pll3_out", "sys_pll1_40m", "audio_pll2_out",
+					     "clk_ext1", "clk_ext4", };
+
+static const char * const imx8mn_disp_apb_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll1_800m",
+					     "sys_pll3_out", "sys_pll1_40m", "audio_pll2_out",
+					     "clk_ext1", "clk_ext3", };
+
+static const char * const imx8mn_disp_pixel_sels[] = {"clock-osc-24m", "video_pll_out", "audio_pll2_out",
+					     "audio_pll1_out", "sys_pll1_800m", "sys_pll2_1000m",
+					     "sys_pll3_out", "clk_ext4", };
+
+static const char * const imx8mn_dsi_core_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll2_250m",
+					     "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+					     "audio_pll2_out", "video_pll_out", };
+
+static const char * const imx8mn_dsi_phy_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_100m",
+					     "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+					     "audio_pll2_out", "video_pll_out", };
+
+static const char * const imx8mn_dsi_dbi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll2_100m",
+					     "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+					     "audio_pll2_out", "video_pll_out", };
+
+static const char * const imx8mn_camera_pixel_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll2_250m",
+					     "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+					     "audio_pll2_out", "video_pll_out", };
+
 static const char * const imx8mn_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m",
 						    "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
 						    "video_pll_out", "clk_ext4", };
@@ -148,6 +177,10 @@  static const char * const imx8mn_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_10
 						   "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
 						   "clk_ext3", "audio_pll2_out", };
 
+#ifndef CONFIG_SPL_BUILD
+static unsigned int share_count_disp;
+#endif
+
 static int imx8mn_clk_probe(struct udevice *dev)
 {
 	struct clk osc_24m_clk;
@@ -188,8 +221,19 @@  static int imx8mn_clk_probe(struct udevice *dev)
 	clk_dm(IMX8MN_SYS_PLL3,
 	       imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel",
 			       base + 0x114, &imx_1416x_pll));
+	clk_dm(IMX8MN_VIDEO_PLL_REF_SEL,
+	       imx_clk_mux("video_pll_ref_sel", base + 0x28, 0, 2,
+			   pll_ref_sels, ARRAY_SIZE(pll_ref_sels)));
+	clk_dm(IMX8MN_VIDEO_PLL1,
+	       imx_clk_pll14xx("video_pll", "video_pll_ref_sel",
+			       base + 0x28, &imx_1443x_pll));
 
 	/* PLL bypass out */
+	clk_dm(IMX8MN_VIDEO_PLL_BYPASS,
+	       imx_clk_mux_flags("video_pll_bypass", base + 0x28, 16, 1,
+				 video_pll_bypass_sels,
+				 ARRAY_SIZE(video_pll_bypass_sels),
+				 CLK_SET_RATE_PARENT));
 	clk_dm(IMX8MN_DRAM_PLL_BYPASS,
 	       imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1,
 				 dram_pll_bypass_sels,
@@ -217,6 +261,9 @@  static int imx8mn_clk_probe(struct udevice *dev)
 				 CLK_SET_RATE_PARENT));
 
 	/* PLL out gate */
+	clk_dm(IMX8MN_VIDEO_PLL_OUT,
+	       imx_clk_gate("video_pll_out", "video_pll_bypass",
+			    base + 0x28, 13));
 	clk_dm(IMX8MN_DRAM_PLL_OUT,
 	       imx_clk_gate("dram_pll_out", "dram_pll_bypass",
 			    base + 0x50, 13));
@@ -373,6 +420,31 @@  static int imx8mn_clk_probe(struct udevice *dev)
 
 	/* clks not needed in SPL stage */
 #ifndef CONFIG_SPL_BUILD
+	clk_dm(IMX8MN_CLK_DISP_AXI,
+	       imx8m_clk_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00));
+	clk_dm(IMX8MN_CLK_DISP_APB,
+	       imx8m_clk_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80));
+	clk_dm(IMX8MN_CLK_DISP_PIXEL,
+	       __imx8m_clk_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500,
+	       CLK_SET_RATE_PARENT));
+	clk_dm(IMX8MN_CLK_DSI_CORE,
+	       imx8m_clk_composite("dsi_core", imx8mn_dsi_core_sels, base + 0xbb00));
+	clk_dm(IMX8MN_CLK_DSI_PHY_REF,
+	       imx8m_clk_composite("dsi_phy_ref", imx8mn_dsi_phy_sels, base + 0xbb80));
+	clk_dm(IMX8MN_CLK_DSI_DBI,
+	       imx8m_clk_composite("dsi_dbi", imx8mn_dsi_dbi_sels, base + 0xbc00));
+	clk_dm(IMX8MN_CLK_CAMERA_PIXEL,
+	       imx8m_clk_composite("camera_pixel", imx8mn_camera_pixel_sels, base + 0xbd00));
+
+	clk_dm(IMX8MN_CLK_DISP_AXI_ROOT,
+	       imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp));
+	clk_dm(IMX8MN_CLK_DISP_APB_ROOT,
+	       imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp));
+	clk_dm(IMX8MN_CLK_CAMERA_PIXEL_ROOT,
+	       imx_clk_gate2_shared2("camera_pixel_clk", "camera_pixel", base + 0x45d0, 0, &share_count_disp));
+	clk_dm(IMX8MN_CLK_DISP_PIXEL_ROOT,
+	       imx_clk_gate2_shared2("disp_pixel_clk", "disp_pixel", base + 0x45d0, 0, &share_count_disp));
+
 	clk_dm(IMX8MN_CLK_ENET_REF,
 	       imx8m_clk_composite("enet_ref", imx8mn_enet_ref_sels,
 	       base + 0xa980));