1 // SPDX-License-Identifier: GPL-2.0
3 * StarFive JH7110 stg Clock Generator Driver
5 * Copyright (C) 2022 Xingyu Wu <xingyu.wu@starfivetech.com>
9 #include <linux/clk-provider.h>
10 #include <linux/init.h>
11 #include <linux/platform_device.h>
13 #include <dt-bindings/clock/starfive-jh7110-clkgen.h>
14 #include "clk-starfive-jh7110.h"
17 #define JH7110_OSC (JH7110_CLK_END + 0)
18 /* stg external clocks */
19 #define JH7110_STG_APB (JH7110_CLK_END + 11)
21 static const struct jh7110_clk_data jh7110_clk_stg_data[] __initconst = {
23 JH7110_GATE(JH7110_HIFI4_CLK_CORE, "u0_hifi4_clk_core",
24 GATE_FLAG_NORMAL, JH7110_HIFI4_CORE),
26 JH7110_GATE(JH7110_USB0_CLK_USB_APB, "u0_cdn_usb_clk_usb_apb",
27 GATE_FLAG_NORMAL, JH7110_STG_APB),
28 JH7110_GATE(JH7110_USB0_CLK_UTMI_APB, "u0_cdn_usb_clk_utmi_apb",
29 GATE_FLAG_NORMAL, JH7110_STG_APB),
30 JH7110_GATE(JH7110_USB0_CLK_AXI, "u0_cdn_usb_clk_axi",
31 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
32 JH7110_GDIV(JH7110_USB0_CLK_LPM, "u0_cdn_usb_clk_lpm",
33 GATE_FLAG_NORMAL, 2, JH7110_OSC),
34 JH7110_GDIV(JH7110_USB0_CLK_STB, "u0_cdn_usb_clk_stb",
35 GATE_FLAG_NORMAL, 4, JH7110_OSC),
36 JH7110_GATE(JH7110_USB0_CLK_APP_125, "u0_cdn_usb_clk_app_125",
37 GATE_FLAG_NORMAL, JH7110_USB_125M),
38 JH7110__DIV(JH7110_USB0_REFCLK, "u0_cdn_usb_refclk", 2, JH7110_OSC),
40 JH7110_GATE(JH7110_PCIE0_CLK_AXI_MST0, "u0_plda_pcie_clk_axi_mst0",
41 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
42 JH7110_GATE(JH7110_PCIE0_CLK_APB, "u0_plda_pcie_clk_apb",
43 GATE_FLAG_NORMAL, JH7110_STG_APB),
44 JH7110_GATE(JH7110_PCIE0_CLK_TL, "u0_plda_pcie_clk_tl",
45 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
46 JH7110_GATE(JH7110_PCIE1_CLK_AXI_MST0, "u1_plda_pcie_clk_axi_mst0",
47 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
48 JH7110_GATE(JH7110_PCIE1_CLK_APB, "u1_plda_pcie_clk_apb",
49 GATE_FLAG_NORMAL, JH7110_STG_APB),
50 JH7110_GATE(JH7110_PCIE1_CLK_TL, "u1_plda_pcie_clk_tl",
51 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
52 JH7110_GATE(JH7110_PCIE01_SLV_DEC_MAINCLK, "u0_pcie01_slv_dec_mainclk",
53 CLK_IGNORE_UNUSED, JH7110_STG_AXIAHB),
55 JH7110_GATE(JH7110_SEC_HCLK, "u0_sec_top_hclk",
56 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
57 JH7110_GATE(JH7110_SEC_MISCAHB_CLK, "u0_sec_top_miscahb_clk",
58 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
60 JH7110_GATE(JH7110_STG_MTRX_GRP0_CLK_MAIN, "u0_stg_mtrx_grp0_clk_main",
61 CLK_IGNORE_UNUSED, JH7110_CPU_BUS),
62 JH7110_GATE(JH7110_STG_MTRX_GRP0_CLK_BUS, "u0_stg_mtrx_grp0_clk_bus",
63 CLK_IGNORE_UNUSED, JH7110_NOCSTG_BUS),
64 JH7110_GATE(JH7110_STG_MTRX_GRP0_CLK_STG, "u0_stg_mtrx_grp0_clk_stg",
65 CLK_IGNORE_UNUSED, JH7110_STG_AXIAHB),
66 JH7110_GATE(JH7110_STG_MTRX_GRP1_CLK_MAIN, "u0_stg_mtrx_grp1_clk_main",
67 CLK_IGNORE_UNUSED, JH7110_CPU_BUS),
68 JH7110_GATE(JH7110_STG_MTRX_GRP1_CLK_BUS, "u0_stg_mtrx_grp1_clk_bus",
69 CLK_IGNORE_UNUSED, JH7110_NOCSTG_BUS),
70 JH7110_GATE(JH7110_STG_MTRX_GRP1_CLK_STG, "u0_stg_mtrx_grp1_clk_stg",
71 CLK_IGNORE_UNUSED, JH7110_STG_AXIAHB),
72 JH7110_GATE(JH7110_STG_MTRX_GRP1_CLK_HIFI, "u0_stg_mtrx_grp1_clk_hifi",
73 CLK_IGNORE_UNUSED, JH7110_HIFI4_AXI),
75 JH7110_GDIV(JH7110_E2_RTC_CLK, "u0_e2_sft7110_rtc_clk",
76 GATE_FLAG_NORMAL, 24, JH7110_OSC),
77 JH7110_GATE(JH7110_E2_CLK_CORE, "u0_e2_sft7110_clk_core",
78 CLK_IGNORE_UNUSED, JH7110_STG_AXIAHB),
79 JH7110_GATE(JH7110_E2_CLK_DBG, "u0_e2_sft7110_clk_dbg",
80 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
82 JH7110_GATE(JH7110_DMA1P_CLK_AXI, "u0_dw_dma1p_8ch_56hs_clk_axi",
83 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
84 JH7110_GATE(JH7110_DMA1P_CLK_AHB, "u0_dw_dma1p_8ch_56hs_clk_ahb",
85 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
88 int __init clk_starfive_jh7110_stg_init(struct platform_device *pdev,
89 struct jh7110_clk_priv *priv)
94 priv->stg_base = devm_platform_ioremap_resource_byname(pdev, "stg");
95 if (IS_ERR(priv->stg_base))
96 return PTR_ERR(priv->stg_base);
98 priv->pll[PLL_OF(JH7110_PCIE0_CLK_AXI_SLV0)] =
99 devm_clk_hw_register_fixed_factor(priv->dev,
100 "u0_plda_pcie_clk_axi_slv0",
101 "u0_plda_pcie_clk_axi_mst0", 0, 1, 1);
102 priv->pll[PLL_OF(JH7110_PCIE0_CLK_AXI_SLV)] =
103 devm_clk_hw_register_fixed_factor(priv->dev,
104 "u0_plda_pcie_clk_axi_slv",
105 "u0_plda_pcie_clk_axi_mst0", 0, 1, 1);
106 priv->pll[PLL_OF(JH7110_PCIE0_CLK_OSC)] =
107 devm_clk_hw_register_fixed_factor(priv->dev,
108 "u0_plda_pcie_clk_osc", "osc", 0, 1, 1);
109 priv->pll[PLL_OF(JH7110_PCIE1_CLK_AXI_SLV0)] =
110 devm_clk_hw_register_fixed_factor(priv->dev,
111 "u1_plda_pcie_clk_axi_slv0",
112 "u1_plda_pcie_clk_axi_mst0", 0, 1, 1);
113 priv->pll[PLL_OF(JH7110_PCIE1_CLK_AXI_SLV)] =
114 devm_clk_hw_register_fixed_factor(priv->dev,
115 "u1_plda_pcie_clk_axi_slv",
116 "u1_plda_pcie_clk_axi_mst0", 0, 1, 1);
117 priv->pll[PLL_OF(JH7110_PCIE1_CLK_OSC)] =
118 devm_clk_hw_register_fixed_factor(priv->dev,
119 "u1_plda_pcie_clk_osc", "osc", 0, 1, 1);
120 priv->pll[PLL_OF(JH7110_E2_IRQ_SYNC_CLK_CORE)] =
121 devm_clk_hw_register_fixed_factor(priv->dev,
122 "u0_e2_sft7110_irq_sync_clk_core",
123 "stg_axiahb", 0, 1, 1);
124 priv->pll[PLL_OF(JH7110_STG_CRG_PCLK)] =
125 devm_clk_hw_register_fixed_factor(priv->dev,
126 "u0_stg_crg_pclk", "stg_apb", 0, 1, 1);
127 priv->pll[PLL_OF(JH7110_STG_SYSCON_PCLK)] =
128 devm_clk_hw_register_fixed_factor(priv->dev,
129 "u0_stg_syscon_pclk", "stg_apb", 0, 1, 1);
131 for (idx = JH7110_CLK_SYS_REG_END; idx < JH7110_CLK_STG_REG_END; idx++) {
132 u32 max = jh7110_clk_stg_data[idx].max;
133 struct clk_parent_data parents[4] = {};
134 struct clk_init_data init = {
135 .name = jh7110_clk_stg_data[idx].name,
136 .ops = starfive_jh7110_clk_ops(max),
137 .parent_data = parents,
138 .num_parents = ((max & JH7110_CLK_MUX_MASK) \
139 >> JH7110_CLK_MUX_SHIFT) + 1,
140 .flags = jh7110_clk_stg_data[idx].flags,
142 struct jh7110_clk *clk = &priv->reg[idx];
145 for (i = 0; i < init.num_parents; i++) {
146 unsigned int pidx = jh7110_clk_stg_data[idx].parents[i];
148 if (pidx < JH7110_CLK_STG_REG_END)
149 parents[i].hw = &priv->reg[pidx].hw;
150 else if ((pidx < JH7110_CLK_STG_END) && \
151 (pidx > JH7110_CLK_SYS_END))
152 parents[i].hw = priv->pll[PLL_OF(pidx)];
153 else if (pidx == JH7110_OSC)
154 parents[i].fw_name = "osc";
155 else if (pidx == JH7110_STG_APB)
156 parents[i].fw_name = "stg_apb";
159 clk->hw.init = &init;
161 clk->max_div = max & JH7110_CLK_DIV_MASK;
162 clk->reg_flags = JH7110_CLK_STG_FLAG;
164 ret = devm_clk_hw_register(priv->dev, &clk->hw);
169 dev_dbg(&pdev->dev,"starfive JH7110 clk_stg init successfully.");