@@ -11,3 +11,14 @@ config CLK_THEAD_TH1520_AP
on the T-HEAD TH1520 SoC. This includes configuration of
both CPU PLLs, both DPU PLLs as well as the GMAC, VIDEO,
and TEE PLLs.
+
+config CLK_THEAD_TH1520_VO
+ bool "T-HEAD TH1520 VO clock support"
+ depends on ARCH_THEAD || COMPILE_TEST
+ depends on 64BIT
+ default ARCH_THEAD
+ select REGMAP_MMIO
+ help
+ Say yes here to support the VO sub system clock controller
+ on the T-HEAD TH1520 SoC. This includes clock gates for the
+ Video Output components like HDMI, MIPI, DPU and GPU.
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_CLK_THEAD_TH1520_AP) += clk-th1520.o clk-th1520-ap.o
+obj-$(CONFIG_CLK_THEAD_TH1520_VO) += clk-th1520.o clk-th1520-vo.o
new file mode 100644
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Author: Michal Wilczynski <m.wilczynski@samsung.com>
+ */
+
+#include <linux/mfd/syscon.h>
+#include "clk-th1520.h"
+
+#define NR_CLKS (CLK_HDMI_PIXCLK + 1)
+
+static const struct clk_parent_data video_pll_pd[] = {
+ /* TODO: provide a proper parent here */
+ NULL,
+};
+
+static CCU_GATE_REGMAP(CLK_AXI4_VO_ACLK, axi4_vo_aclk, "axi4-vo-aclk",
+ video_pll_pd, 0x50, BIT(0), 0);
+static CCU_GATE_REGMAP(CLK_GPU_CORE, gpu_core_clk, "gpu-core-clk", video_pll_pd,
+ 0x50, BIT(3), 0);
+static CCU_GATE_REGMAP(CLK_GPU_CFG_ACLK, gpu_cfg_aclk, "gpu-cfg-aclk",
+ video_pll_pd, 0x50, BIT(4), 0);
+static CCU_GATE_REGMAP(CLK_DPU_PIXELCLK0, dpu0_pixelclk, "dpu0-pixelclk",
+ video_pll_pd, 0x50, BIT(5), 0);
+static CCU_GATE_REGMAP(CLK_DPU_PIXELCLK1, dpu1_pixelclk, "dpu1-pixelclk",
+ video_pll_pd, 0x50, BIT(6), 0);
+static CCU_GATE_REGMAP(CLK_DPU_HCLK, dpu_hclk, "dpu-hclk", video_pll_pd, 0x50,
+ BIT(7), 0);
+static CCU_GATE_REGMAP(CLK_DPU_ACLK, dpu_aclk, "dpu-aclk", video_pll_pd, 0x50,
+ BIT(8), 0);
+static CCU_GATE_REGMAP(CLK_DPU_CCLK, dpu_cclk, "dpu-cclk", video_pll_pd, 0x50,
+ BIT(9), 0);
+static CCU_GATE_REGMAP(CLK_HDMI_SFR, hdmi_sfr_clk, "hdmi-sfr-clk", video_pll_pd,
+ 0x50, BIT(10), 0);
+static CCU_GATE_REGMAP(CLK_HDMI_PCLK, hdmi_pclk, "hdmi-pclk", video_pll_pd,
+ 0x50, BIT(11), 0);
+static CCU_GATE_REGMAP(CLK_HDMI_CEC, hdmi_cec_clk, "hdmi-cec-clk", video_pll_pd,
+ 0x50, BIT(12), 0);
+static CCU_GATE_REGMAP(CLK_MIPI_DSI0_PCLK, mipi_dsi0_pclk, "mipi-dsi0-pclk",
+ video_pll_pd, 0x50, BIT(13), 0);
+static CCU_GATE_REGMAP(CLK_MIPI_DSI1_PCLK, mipi_dsi1_pclk, "mipi-dsi1-pclk",
+ video_pll_pd, 0x50, BIT(14), 0);
+static CCU_GATE_REGMAP(CLK_MIPI_DSI0_CFG, mipi_dsi0_cfg_clk,
+ "mipi-dsi0-cfg-clk", video_pll_pd, 0x50, BIT(15), 0);
+static CCU_GATE_REGMAP(CLK_MIPI_DSI1_CFG, mipi_dsi1_cfg_clk,
+ "mipi-dsi1-cfg-clk", video_pll_pd, 0x50, BIT(16), 0);
+static CCU_GATE_REGMAP(CLK_MIPI_DSI0_REFCLK, mipi_dsi0_refclk,
+ "mipi-dsi0-refclk", video_pll_pd, 0x50, BIT(17), 0);
+static CCU_GATE_REGMAP(CLK_MIPI_DSI1_REFCLK, mipi_dsi1_refclk,
+ "mipi-dsi1-refclk", video_pll_pd, 0x50, BIT(18), 0);
+static CCU_GATE_REGMAP(CLK_HDMI_I2S, hdmi_i2c_clk, "hdmi-i2c-clk", video_pll_pd,
+ 0x50, BIT(19), 0);
+static CCU_GATE_REGMAP(CLK_X2H_DPU1_ACLK, x2h_dpu1_aclk, "x2h-dpu1-aclk",
+ video_pll_pd, 0x50, BIT(20), 0);
+static CCU_GATE_REGMAP(CLK_X2H_DPU_ACLK, x2h_dpu_aclk, "x2h-dpu-aclk",
+ video_pll_pd, 0x50, BIT(21), 0);
+static CCU_GATE_REGMAP(CLK_AXI4_VO_PCLK, axi4_vo_pclk, "axi4-vo-pclk",
+ video_pll_pd, 0x50, BIT(22), 0);
+static CCU_GATE_REGMAP(CLK_IOPMP_VOSYS_DPU_PCLK, iopmp_vosys_dpu_pclk,
+ "iopmp-vosys-dpu-pclk", video_pll_pd, 0x50, BIT(23), 0);
+static CCU_GATE_REGMAP(CLK_IOPMP_VOSYS_DPU1_PCLK, iopmp_vosys_dpu1_pclk,
+ "iopmp-vosys-dpu1-pclk", video_pll_pd, 0x50, BIT(24), 0);
+static CCU_GATE_REGMAP(CLK_IOPMP_VOSYS_GPU_PCLK, iopmp_vosys_gpu_pclk,
+ "iopmp-vosys-gpu-pclk", video_pll_pd, 0x50, BIT(25), 0);
+static CCU_GATE_REGMAP(CLK_IOPMP_DPU1_ACLK, iopmp_dpu1_aclk, "iopmp-dpu1-aclk",
+ video_pll_pd, 0x50, BIT(27), 0);
+static CCU_GATE_REGMAP(CLK_IOPMP_DPU_ACLK, iopmp_dpu_aclk, "iopmp-dpu-aclk",
+ video_pll_pd, 0x50, BIT(28), 0);
+static CCU_GATE_REGMAP(CLK_IOPMP_GPU_ACLK, iopmp_gpu_aclk, "iopmp-gpu-aclk",
+ video_pll_pd, 0x50, BIT(29), 0);
+static CCU_GATE_REGMAP(CLK_MIPIDSI0_PIXCLK, mipi_dsi0_pixclk,
+ "mipi-dsi0-pixclk", video_pll_pd, 0x50, BIT(30), 0);
+static CCU_GATE_REGMAP(CLK_MIPIDSI1_PIXCLK, mipi_dsi1_pixclk,
+ "mipi-dsi1-pixclk", video_pll_pd, 0x50, BIT(31), 0);
+static CCU_GATE_REGMAP(CLK_HDMI_PIXCLK, hdmi_pixclk, "hdmi-pixclk",
+ video_pll_pd, 0x54, BIT(0), 0);
+
+static struct ccu_common *th1520_vo_gate_clks[] = {
+ &axi4_vo_aclk.common,
+ &gpu_core_clk.common,
+ &gpu_cfg_aclk.common,
+ &dpu0_pixelclk.common,
+ &dpu1_pixelclk.common,
+ &dpu_hclk.common,
+ &dpu_aclk.common,
+ &dpu_cclk.common,
+ &hdmi_sfr_clk.common,
+ &hdmi_pclk.common,
+ &hdmi_cec_clk.common,
+ &mipi_dsi0_pclk.common,
+ &mipi_dsi1_pclk.common,
+ &mipi_dsi0_cfg_clk.common,
+ &mipi_dsi1_cfg_clk.common,
+ &mipi_dsi0_refclk.common,
+ &mipi_dsi1_refclk.common,
+ &hdmi_i2c_clk.common,
+ &x2h_dpu1_aclk.common,
+ &x2h_dpu_aclk.common,
+ &axi4_vo_pclk.common,
+ &iopmp_vosys_dpu_pclk.common,
+ &iopmp_vosys_dpu1_pclk.common,
+ &iopmp_vosys_gpu_pclk.common,
+ &iopmp_dpu1_aclk.common,
+ &iopmp_dpu_aclk.common,
+ &iopmp_gpu_aclk.common,
+ &mipi_dsi0_pixclk.common,
+ &mipi_dsi1_pixclk.common,
+ &hdmi_pixclk.common
+};
+
+static int th1520_clk_vo_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct clk_hw_onecell_data *priv;
+ struct regmap *map;
+ struct clk_hw *hw;
+ int ret, i;
+
+ priv = devm_kzalloc(dev, struct_size(priv, hws, NR_CLKS), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->num = NR_CLKS;
+
+ map = syscon_regmap_lookup_by_phandle(np, "thead,vosys-regmap");
+ if (IS_ERR(map))
+ return PTR_ERR(map);
+
+ for (i = 0; i < ARRAY_SIZE(th1520_vo_gate_clks); i++) {
+ struct ccu_gate *cg = hw_to_ccu_gate(&th1520_vo_gate_clks[i]->hw);
+
+ th1520_vo_gate_clks[i]->map = map;
+
+ ret = devm_clk_hw_register(dev, &th1520_vo_gate_clks[i]->hw);
+ if (ret)
+ return ret;
+
+ priv->hws[cg->common.clkid] = hw;
+ }
+
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct of_device_id th1520_clk_vo_match[] = {
+ {
+ .compatible = "thead,th1520-clk-vo",
+ },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, th1520_clk_vo_match);
+
+static struct platform_driver th1520_clk_vo_driver = {
+ .probe = th1520_clk_vo_probe,
+ .driver = {
+ .name = "th1520-clk-vo",
+ .of_match_table = th1520_clk_vo_match,
+ },
+};
+module_platform_driver(th1520_clk_vo_driver);
+
+MODULE_DESCRIPTION("T-HEAD TH1520 VO Clock driver");
+MODULE_AUTHOR("Michal Wilczynski <m.wilczynski@samsung.com>");
+MODULE_LICENSE("GPL");
@@ -7,6 +7,7 @@
#ifndef _DT_BINDINGS_CLK_TH1520_H_
#define _DT_BINDINGS_CLK_TH1520_H_
+/* AP clocks */
#define CLK_CPU_PLL0 0
#define CLK_CPU_PLL1 1
#define CLK_GMAC_PLL 2
@@ -93,4 +94,37 @@
#define CLK_SRAM3 83
#define CLK_PLL_GMAC_100M 84
#define CLK_UART_SCLK 85
+
+/* VO clocks */
+#define CLK_AXI4_VO_ACLK 0
+#define CLK_GPU_CORE 1
+#define CLK_GPU_CFG_ACLK 2
+#define CLK_DPU_PIXELCLK0 3
+#define CLK_DPU_PIXELCLK1 4
+#define CLK_DPU_HCLK 5
+#define CLK_DPU_ACLK 6
+#define CLK_DPU_CCLK 7
+#define CLK_HDMI_SFR 8
+#define CLK_HDMI_PCLK 9
+#define CLK_HDMI_CEC 10
+#define CLK_MIPI_DSI0_PCLK 11
+#define CLK_MIPI_DSI1_PCLK 12
+#define CLK_MIPI_DSI0_CFG 13
+#define CLK_MIPI_DSI1_CFG 14
+#define CLK_MIPI_DSI0_REFCLK 15
+#define CLK_MIPI_DSI1_REFCLK 16
+#define CLK_HDMI_I2S 17
+#define CLK_X2H_DPU1_ACLK 18
+#define CLK_X2H_DPU_ACLK 19
+#define CLK_AXI4_VO_PCLK 20
+#define CLK_IOPMP_VOSYS_DPU_PCLK 21
+#define CLK_IOPMP_VOSYS_DPU1_PCLK 22
+#define CLK_IOPMP_VOSYS_GPU_PCLK 23
+#define CLK_IOPMP_DPU1_ACLK 24
+#define CLK_IOPMP_DPU_ACLK 25
+#define CLK_IOPMP_GPU_ACLK 26
+#define CLK_MIPIDSI0_PIXCLK 27
+#define CLK_MIPIDSI1_PIXCLK 28
+#define CLK_HDMI_PIXCLK 29
+
#endif
The Video Output (VO) module on the T-Head TH1520 SoC has its own set of clocks that need proper management. This commit introduces the clk-th1520-vo driver to support the VO subsystem clocks. Currently, only the clock gates are implemented, as they are the primary relevant clocks for the VO subsystem at this stage. Signed-off-by: Michal Wilczynski <m.wilczynski@samsung.com> --- drivers/clk/thead/Kconfig | 11 ++ drivers/clk/thead/Makefile | 1 + drivers/clk/thead/clk-th1520-vo.c | 168 +++++++++++++++++++ include/dt-bindings/clock/thead,th1520-clk.h | 34 ++++ 4 files changed, 214 insertions(+) create mode 100644 drivers/clk/thead/clk-th1520-vo.c