Skip to content

Commit 50d4b15

Browse files
Michal Wilczynskitt-fustini
authored andcommitted
clk: thead: Add clock support for VO subsystem in T-HEAD TH1520 SoC
The T-Head TH1520 SoC integrates a variety of clocks for its subsystems, including the Application Processor (AP) and the Video Output (VO) [1]. Up until now, the T-Head clock driver only supported AP clocks. Extend the driver to provide clock functionality for the VO subsystem. At this stage, the focus is on implementing the VO clock gates, as these are currently the most relevant and required components for enabling and disabling the VO subsystem functionality. Future enhancements may introduce additional VO-related clocks as necessary. Link: https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf [1] Reviewed-by: Drew Fustini <drew@pdp7.com> Signed-off-by: Michal Wilczynski <m.wilczynski@samsung.com> Signed-off-by: Drew Fustini <drew@pdp7.com>
1 parent 1b4bb45 commit 50d4b15

File tree

1 file changed

+168
-28
lines changed

1 file changed

+168
-28
lines changed

drivers/clk/thead/clk-th1520-ap.c

Lines changed: 168 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,67 @@ static CCU_GATE(CLK_SRAM1, sram1_clk, "sram1", axi_aclk_pd, 0x20c, BIT(3), 0);
847847
static CCU_GATE(CLK_SRAM2, sram2_clk, "sram2", axi_aclk_pd, 0x20c, BIT(2), 0);
848848
static CCU_GATE(CLK_SRAM3, sram3_clk, "sram3", axi_aclk_pd, 0x20c, BIT(1), 0);
849849

850+
static CCU_GATE(CLK_AXI4_VO_ACLK, axi4_vo_aclk, "axi4-vo-aclk",
851+
video_pll_clk_pd, 0x0, BIT(0), 0);
852+
static CCU_GATE(CLK_GPU_CORE, gpu_core_clk, "gpu-core-clk", video_pll_clk_pd,
853+
0x0, BIT(3), 0);
854+
static CCU_GATE(CLK_GPU_CFG_ACLK, gpu_cfg_aclk, "gpu-cfg-aclk",
855+
video_pll_clk_pd, 0x0, BIT(4), 0);
856+
static CCU_GATE(CLK_DPU_PIXELCLK0, dpu0_pixelclk, "dpu0-pixelclk",
857+
video_pll_clk_pd, 0x0, BIT(5), 0);
858+
static CCU_GATE(CLK_DPU_PIXELCLK1, dpu1_pixelclk, "dpu1-pixelclk",
859+
video_pll_clk_pd, 0x0, BIT(6), 0);
860+
static CCU_GATE(CLK_DPU_HCLK, dpu_hclk, "dpu-hclk", video_pll_clk_pd, 0x0,
861+
BIT(7), 0);
862+
static CCU_GATE(CLK_DPU_ACLK, dpu_aclk, "dpu-aclk", video_pll_clk_pd, 0x0,
863+
BIT(8), 0);
864+
static CCU_GATE(CLK_DPU_CCLK, dpu_cclk, "dpu-cclk", video_pll_clk_pd, 0x0,
865+
BIT(9), 0);
866+
static CCU_GATE(CLK_HDMI_SFR, hdmi_sfr_clk, "hdmi-sfr-clk", video_pll_clk_pd,
867+
0x0, BIT(10), 0);
868+
static CCU_GATE(CLK_HDMI_PCLK, hdmi_pclk, "hdmi-pclk", video_pll_clk_pd, 0x0,
869+
BIT(11), 0);
870+
static CCU_GATE(CLK_HDMI_CEC, hdmi_cec_clk, "hdmi-cec-clk", video_pll_clk_pd,
871+
0x0, BIT(12), 0);
872+
static CCU_GATE(CLK_MIPI_DSI0_PCLK, mipi_dsi0_pclk, "mipi-dsi0-pclk",
873+
video_pll_clk_pd, 0x0, BIT(13), 0);
874+
static CCU_GATE(CLK_MIPI_DSI1_PCLK, mipi_dsi1_pclk, "mipi-dsi1-pclk",
875+
video_pll_clk_pd, 0x0, BIT(14), 0);
876+
static CCU_GATE(CLK_MIPI_DSI0_CFG, mipi_dsi0_cfg_clk, "mipi-dsi0-cfg-clk",
877+
video_pll_clk_pd, 0x0, BIT(15), 0);
878+
static CCU_GATE(CLK_MIPI_DSI1_CFG, mipi_dsi1_cfg_clk, "mipi-dsi1-cfg-clk",
879+
video_pll_clk_pd, 0x0, BIT(16), 0);
880+
static CCU_GATE(CLK_MIPI_DSI0_REFCLK, mipi_dsi0_refclk, "mipi-dsi0-refclk",
881+
video_pll_clk_pd, 0x0, BIT(17), 0);
882+
static CCU_GATE(CLK_MIPI_DSI1_REFCLK, mipi_dsi1_refclk, "mipi-dsi1-refclk",
883+
video_pll_clk_pd, 0x0, BIT(18), 0);
884+
static CCU_GATE(CLK_HDMI_I2S, hdmi_i2s_clk, "hdmi-i2s-clk", video_pll_clk_pd,
885+
0x0, BIT(19), 0);
886+
static CCU_GATE(CLK_X2H_DPU1_ACLK, x2h_dpu1_aclk, "x2h-dpu1-aclk",
887+
video_pll_clk_pd, 0x0, BIT(20), 0);
888+
static CCU_GATE(CLK_X2H_DPU_ACLK, x2h_dpu_aclk, "x2h-dpu-aclk",
889+
video_pll_clk_pd, 0x0, BIT(21), 0);
890+
static CCU_GATE(CLK_AXI4_VO_PCLK, axi4_vo_pclk, "axi4-vo-pclk",
891+
video_pll_clk_pd, 0x0, BIT(22), 0);
892+
static CCU_GATE(CLK_IOPMP_VOSYS_DPU_PCLK, iopmp_vosys_dpu_pclk,
893+
"iopmp-vosys-dpu-pclk", video_pll_clk_pd, 0x0, BIT(23), 0);
894+
static CCU_GATE(CLK_IOPMP_VOSYS_DPU1_PCLK, iopmp_vosys_dpu1_pclk,
895+
"iopmp-vosys-dpu1-pclk", video_pll_clk_pd, 0x0, BIT(24), 0);
896+
static CCU_GATE(CLK_IOPMP_VOSYS_GPU_PCLK, iopmp_vosys_gpu_pclk,
897+
"iopmp-vosys-gpu-pclk", video_pll_clk_pd, 0x0, BIT(25), 0);
898+
static CCU_GATE(CLK_IOPMP_DPU1_ACLK, iopmp_dpu1_aclk, "iopmp-dpu1-aclk",
899+
video_pll_clk_pd, 0x0, BIT(27), 0);
900+
static CCU_GATE(CLK_IOPMP_DPU_ACLK, iopmp_dpu_aclk, "iopmp-dpu-aclk",
901+
video_pll_clk_pd, 0x0, BIT(28), 0);
902+
static CCU_GATE(CLK_IOPMP_GPU_ACLK, iopmp_gpu_aclk, "iopmp-gpu-aclk",
903+
video_pll_clk_pd, 0x0, BIT(29), 0);
904+
static CCU_GATE(CLK_MIPIDSI0_PIXCLK, mipi_dsi0_pixclk, "mipi-dsi0-pixclk",
905+
video_pll_clk_pd, 0x0, BIT(30), 0);
906+
static CCU_GATE(CLK_MIPIDSI1_PIXCLK, mipi_dsi1_pixclk, "mipi-dsi1-pixclk",
907+
video_pll_clk_pd, 0x0, BIT(31), 0);
908+
static CCU_GATE(CLK_HDMI_PIXCLK, hdmi_pixclk, "hdmi-pixclk", video_pll_clk_pd,
909+
0x4, BIT(0), 0);
910+
850911
static CLK_FIXED_FACTOR_HW(gmac_pll_clk_100m, "gmac-pll-clk-100m",
851912
&gmac_pll_clk.common.hw, 10, 1, 0);
852913

@@ -963,7 +1024,38 @@ static struct ccu_common *th1520_gate_clks[] = {
9631024
&sram3_clk.common,
9641025
};
9651026

966-
#define NR_CLKS (CLK_UART_SCLK + 1)
1027+
static struct ccu_common *th1520_vo_gate_clks[] = {
1028+
&axi4_vo_aclk.common,
1029+
&gpu_core_clk.common,
1030+
&gpu_cfg_aclk.common,
1031+
&dpu0_pixelclk.common,
1032+
&dpu1_pixelclk.common,
1033+
&dpu_hclk.common,
1034+
&dpu_aclk.common,
1035+
&dpu_cclk.common,
1036+
&hdmi_sfr_clk.common,
1037+
&hdmi_pclk.common,
1038+
&hdmi_cec_clk.common,
1039+
&mipi_dsi0_pclk.common,
1040+
&mipi_dsi1_pclk.common,
1041+
&mipi_dsi0_cfg_clk.common,
1042+
&mipi_dsi1_cfg_clk.common,
1043+
&mipi_dsi0_refclk.common,
1044+
&mipi_dsi1_refclk.common,
1045+
&hdmi_i2s_clk.common,
1046+
&x2h_dpu1_aclk.common,
1047+
&x2h_dpu_aclk.common,
1048+
&axi4_vo_pclk.common,
1049+
&iopmp_vosys_dpu_pclk.common,
1050+
&iopmp_vosys_dpu1_pclk.common,
1051+
&iopmp_vosys_gpu_pclk.common,
1052+
&iopmp_dpu1_aclk.common,
1053+
&iopmp_dpu_aclk.common,
1054+
&iopmp_gpu_aclk.common,
1055+
&mipi_dsi0_pixclk.common,
1056+
&mipi_dsi1_pixclk.common,
1057+
&hdmi_pixclk.common
1058+
};
9671059

9681060
static const struct regmap_config th1520_clk_regmap_config = {
9691061
.reg_bits = 32,
@@ -972,8 +1064,44 @@ static const struct regmap_config th1520_clk_regmap_config = {
9721064
.fast_io = true,
9731065
};
9741066

1067+
struct th1520_plat_data {
1068+
struct ccu_common **th1520_pll_clks;
1069+
struct ccu_common **th1520_div_clks;
1070+
struct ccu_common **th1520_mux_clks;
1071+
struct ccu_common **th1520_gate_clks;
1072+
1073+
int nr_clks;
1074+
int nr_pll_clks;
1075+
int nr_div_clks;
1076+
int nr_mux_clks;
1077+
int nr_gate_clks;
1078+
};
1079+
1080+
static const struct th1520_plat_data th1520_ap_platdata = {
1081+
.th1520_pll_clks = th1520_pll_clks,
1082+
.th1520_div_clks = th1520_div_clks,
1083+
.th1520_mux_clks = th1520_mux_clks,
1084+
.th1520_gate_clks = th1520_gate_clks,
1085+
1086+
.nr_clks = CLK_UART_SCLK + 1,
1087+
1088+
.nr_pll_clks = ARRAY_SIZE(th1520_pll_clks),
1089+
.nr_div_clks = ARRAY_SIZE(th1520_div_clks),
1090+
.nr_mux_clks = ARRAY_SIZE(th1520_mux_clks),
1091+
.nr_gate_clks = ARRAY_SIZE(th1520_gate_clks),
1092+
};
1093+
1094+
static const struct th1520_plat_data th1520_vo_platdata = {
1095+
.th1520_gate_clks = th1520_vo_gate_clks,
1096+
1097+
.nr_clks = CLK_HDMI_PIXCLK + 1,
1098+
1099+
.nr_gate_clks = ARRAY_SIZE(th1520_vo_gate_clks),
1100+
};
1101+
9751102
static int th1520_clk_probe(struct platform_device *pdev)
9761103
{
1104+
const struct th1520_plat_data *plat_data;
9771105
struct device *dev = &pdev->dev;
9781106
struct clk_hw_onecell_data *priv;
9791107

@@ -982,11 +1110,16 @@ static int th1520_clk_probe(struct platform_device *pdev)
9821110
struct clk_hw *hw;
9831111
int ret, i;
9841112

985-
priv = devm_kzalloc(dev, struct_size(priv, hws, NR_CLKS), GFP_KERNEL);
1113+
plat_data = device_get_match_data(&pdev->dev);
1114+
if (!plat_data)
1115+
return dev_err_probe(&pdev->dev, -ENODEV,
1116+
"No device match data found\n");
1117+
1118+
priv = devm_kzalloc(dev, struct_size(priv, hws, plat_data->nr_clks), GFP_KERNEL);
9861119
if (!priv)
9871120
return -ENOMEM;
9881121

989-
priv->num = NR_CLKS;
1122+
priv->num = plat_data->nr_clks;
9901123

9911124
base = devm_platform_ioremap_resource(pdev, 0);
9921125
if (IS_ERR(base))
@@ -996,35 +1129,35 @@ static int th1520_clk_probe(struct platform_device *pdev)
9961129
if (IS_ERR(map))
9971130
return PTR_ERR(map);
9981131

999-
for (i = 0; i < ARRAY_SIZE(th1520_pll_clks); i++) {
1000-
struct ccu_pll *cp = hw_to_ccu_pll(&th1520_pll_clks[i]->hw);
1132+
for (i = 0; i < plat_data->nr_pll_clks; i++) {
1133+
struct ccu_pll *cp = hw_to_ccu_pll(&plat_data->th1520_pll_clks[i]->hw);
10011134

1002-
th1520_pll_clks[i]->map = map;
1135+
plat_data->th1520_pll_clks[i]->map = map;
10031136

1004-
ret = devm_clk_hw_register(dev, &th1520_pll_clks[i]->hw);
1137+
ret = devm_clk_hw_register(dev, &plat_data->th1520_pll_clks[i]->hw);
10051138
if (ret)
10061139
return ret;
10071140

10081141
priv->hws[cp->common.clkid] = &cp->common.hw;
10091142
}
10101143

1011-
for (i = 0; i < ARRAY_SIZE(th1520_div_clks); i++) {
1012-
struct ccu_div *cd = hw_to_ccu_div(&th1520_div_clks[i]->hw);
1144+
for (i = 0; i < plat_data->nr_div_clks; i++) {
1145+
struct ccu_div *cd = hw_to_ccu_div(&plat_data->th1520_div_clks[i]->hw);
10131146

1014-
th1520_div_clks[i]->map = map;
1147+
plat_data->th1520_div_clks[i]->map = map;
10151148

1016-
ret = devm_clk_hw_register(dev, &th1520_div_clks[i]->hw);
1149+
ret = devm_clk_hw_register(dev, &plat_data->th1520_div_clks[i]->hw);
10171150
if (ret)
10181151
return ret;
10191152

10201153
priv->hws[cd->common.clkid] = &cd->common.hw;
10211154
}
10221155

1023-
for (i = 0; i < ARRAY_SIZE(th1520_mux_clks); i++) {
1024-
struct ccu_mux *cm = hw_to_ccu_mux(&th1520_mux_clks[i]->hw);
1156+
for (i = 0; i < plat_data->nr_mux_clks; i++) {
1157+
struct ccu_mux *cm = hw_to_ccu_mux(&plat_data->th1520_mux_clks[i]->hw);
10251158
const struct clk_init_data *init = cm->common.hw.init;
10261159

1027-
th1520_mux_clks[i]->map = map;
1160+
plat_data->th1520_mux_clks[i]->map = map;
10281161
hw = devm_clk_hw_register_mux_parent_data_table(dev,
10291162
init->name,
10301163
init->parent_data,
@@ -1040,10 +1173,10 @@ static int th1520_clk_probe(struct platform_device *pdev)
10401173
priv->hws[cm->common.clkid] = hw;
10411174
}
10421175

1043-
for (i = 0; i < ARRAY_SIZE(th1520_gate_clks); i++) {
1044-
struct ccu_gate *cg = hw_to_ccu_gate(&th1520_gate_clks[i]->hw);
1176+
for (i = 0; i < plat_data->nr_gate_clks; i++) {
1177+
struct ccu_gate *cg = hw_to_ccu_gate(&plat_data->th1520_gate_clks[i]->hw);
10451178

1046-
th1520_gate_clks[i]->map = map;
1179+
plat_data->th1520_gate_clks[i]->map = map;
10471180

10481181
hw = devm_clk_hw_register_gate_parent_data(dev,
10491182
cg->common.hw.init->name,
@@ -1057,19 +1190,21 @@ static int th1520_clk_probe(struct platform_device *pdev)
10571190
priv->hws[cg->common.clkid] = hw;
10581191
}
10591192

1060-
ret = devm_clk_hw_register(dev, &osc12m_clk.hw);
1061-
if (ret)
1062-
return ret;
1063-
priv->hws[CLK_OSC12M] = &osc12m_clk.hw;
1193+
if (plat_data == &th1520_ap_platdata) {
1194+
ret = devm_clk_hw_register(dev, &osc12m_clk.hw);
1195+
if (ret)
1196+
return ret;
1197+
priv->hws[CLK_OSC12M] = &osc12m_clk.hw;
10641198

1065-
ret = devm_clk_hw_register(dev, &gmac_pll_clk_100m.hw);
1066-
if (ret)
1067-
return ret;
1068-
priv->hws[CLK_PLL_GMAC_100M] = &gmac_pll_clk_100m.hw;
1199+
ret = devm_clk_hw_register(dev, &gmac_pll_clk_100m.hw);
1200+
if (ret)
1201+
return ret;
1202+
priv->hws[CLK_PLL_GMAC_100M] = &gmac_pll_clk_100m.hw;
10691203

1070-
ret = devm_clk_hw_register(dev, &emmc_sdio_ref_clk.hw);
1071-
if (ret)
1072-
return ret;
1204+
ret = devm_clk_hw_register(dev, &emmc_sdio_ref_clk.hw);
1205+
if (ret)
1206+
return ret;
1207+
}
10731208

10741209
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, priv);
10751210
if (ret)
@@ -1081,6 +1216,11 @@ static int th1520_clk_probe(struct platform_device *pdev)
10811216
static const struct of_device_id th1520_clk_match[] = {
10821217
{
10831218
.compatible = "thead,th1520-clk-ap",
1219+
.data = &th1520_ap_platdata,
1220+
},
1221+
{
1222+
.compatible = "thead,th1520-clk-vo",
1223+
.data = &th1520_vo_platdata,
10841224
},
10851225
{ /* sentinel */ },
10861226
};

0 commit comments

Comments
 (0)