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)
19 static const struct jh7110_clk_data jh7110_clk_stg_data[] __initconst = {
21 JH7110_GATE(JH7110_HIFI4_CLK_CORE, "u0_hifi4_clk_core",
22 GATE_FLAG_NORMAL, JH7110_HIFI4_CORE),
24 JH7110_GATE(JH7110_USB0_CLK_USB_APB, "u0_cdn_usb_clk_usb_apb",
25 GATE_FLAG_NORMAL, JH7110_STG_APB),
26 JH7110_GATE(JH7110_USB0_CLK_UTMI_APB, "u0_cdn_usb_clk_utmi_apb",
27 GATE_FLAG_NORMAL, JH7110_STG_APB),
28 JH7110_GATE(JH7110_USB0_CLK_AXI, "u0_cdn_usb_clk_axi",
29 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
30 JH7110_GDIV(JH7110_USB0_CLK_LPM, "u0_cdn_usb_clk_lpm",
31 GATE_FLAG_NORMAL, 2, JH7110_OSC),
32 JH7110_GDIV(JH7110_USB0_CLK_STB, "u0_cdn_usb_clk_stb",
33 GATE_FLAG_NORMAL, 4, JH7110_OSC),
34 JH7110_GATE(JH7110_USB0_CLK_APP_125, "u0_cdn_usb_clk_app_125",
35 GATE_FLAG_NORMAL, JH7110_USB_125M),
36 JH7110__DIV(JH7110_USB0_REFCLK, "u0_cdn_usb_refclk", 2, JH7110_OSC),
38 JH7110_GATE(JH7110_PCIE0_CLK_AXI_MST0, "u0_plda_pcie_clk_axi_mst0",
39 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
40 JH7110_GATE(JH7110_PCIE0_CLK_APB, "u0_plda_pcie_clk_apb",
41 GATE_FLAG_NORMAL, JH7110_STG_APB),
42 JH7110_GATE(JH7110_PCIE0_CLK_TL, "u0_plda_pcie_clk_tl",
43 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
44 JH7110_GATE(JH7110_PCIE1_CLK_AXI_MST0, "u1_plda_pcie_clk_axi_mst0",
45 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
46 JH7110_GATE(JH7110_PCIE1_CLK_APB, "u1_plda_pcie_clk_apb",
47 GATE_FLAG_NORMAL, JH7110_STG_APB),
48 JH7110_GATE(JH7110_PCIE1_CLK_TL, "u1_plda_pcie_clk_tl",
49 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
50 JH7110_GATE(JH7110_PCIE01_SLV_DEC_MAINCLK, "u0_pcie01_slv_dec_mainclk",
51 CLK_IGNORE_UNUSED, JH7110_STG_AXIAHB),
53 JH7110_GATE(JH7110_SEC_HCLK, "u0_sec_top_hclk",
54 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
55 JH7110_GATE(JH7110_SEC_MISCAHB_CLK, "u0_sec_top_miscahb_clk",
56 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
58 JH7110_GATE(JH7110_STG_MTRX_GRP0_CLK_MAIN, "u0_stg_mtrx_grp0_clk_main",
59 CLK_IGNORE_UNUSED, JH7110_CPU_BUS),
60 JH7110_GATE(JH7110_STG_MTRX_GRP0_CLK_BUS, "u0_stg_mtrx_grp0_clk_bus",
61 CLK_IGNORE_UNUSED, JH7110_NOCSTG_BUS),
62 JH7110_GATE(JH7110_STG_MTRX_GRP0_CLK_STG, "u0_stg_mtrx_grp0_clk_stg",
63 CLK_IGNORE_UNUSED, JH7110_STG_AXIAHB),
64 JH7110_GATE(JH7110_STG_MTRX_GRP1_CLK_MAIN, "u0_stg_mtrx_grp1_clk_main",
65 CLK_IGNORE_UNUSED, JH7110_CPU_BUS),
66 JH7110_GATE(JH7110_STG_MTRX_GRP1_CLK_BUS, "u0_stg_mtrx_grp1_clk_bus",
67 CLK_IGNORE_UNUSED, JH7110_NOCSTG_BUS),
68 JH7110_GATE(JH7110_STG_MTRX_GRP1_CLK_STG, "u0_stg_mtrx_grp1_clk_stg",
69 CLK_IGNORE_UNUSED, JH7110_STG_AXIAHB),
70 JH7110_GATE(JH7110_STG_MTRX_GRP1_CLK_HIFI, "u0_stg_mtrx_grp1_clk_hifi",
71 CLK_IGNORE_UNUSED, JH7110_HIFI4_AXI),
73 JH7110_GDIV(JH7110_E2_RTC_CLK, "u0_e2_sft7110_rtc_clk",
74 GATE_FLAG_NORMAL, 24, JH7110_OSC),
75 JH7110_GATE(JH7110_E2_CLK_CORE, "u0_e2_sft7110_clk_core",
76 CLK_IGNORE_UNUSED, JH7110_STG_AXIAHB),
77 JH7110_GATE(JH7110_E2_CLK_DBG, "u0_e2_sft7110_clk_dbg",
78 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
80 JH7110_GATE(JH7110_DMA1P_CLK_AXI, "u0_dw_dma1p_8ch_56hs_clk_axi",
81 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
82 JH7110_GATE(JH7110_DMA1P_CLK_AHB, "u0_dw_dma1p_8ch_56hs_clk_ahb",
83 GATE_FLAG_NORMAL, JH7110_STG_AXIAHB),
86 int __init clk_starfive_jh7110_stg_init(struct platform_device *pdev,
87 struct jh7110_clk_priv *priv)
92 priv->stg_base = devm_platform_ioremap_resource_byname(pdev, "stg");
93 if (IS_ERR(priv->stg_base))
94 return PTR_ERR(priv->stg_base);
96 priv->pll[PLL_OF(JH7110_PCIE0_CLK_AXI_SLV0)] =
97 devm_clk_hw_register_fixed_factor(priv->dev,
98 "u0_plda_pcie_clk_axi_slv0",
99 "u0_plda_pcie_clk_axi_mst0", 0, 1, 1);
100 priv->pll[PLL_OF(JH7110_PCIE0_CLK_AXI_SLV)] =
101 devm_clk_hw_register_fixed_factor(priv->dev,
102 "u0_plda_pcie_clk_axi_slv",
103 "u0_plda_pcie_clk_axi_mst0", 0, 1, 1);
104 priv->pll[PLL_OF(JH7110_PCIE0_CLK_OSC)] =
105 devm_clk_hw_register_fixed_factor(priv->dev,
106 "u0_plda_pcie_clk_osc", "osc", 0, 1, 1);
107 priv->pll[PLL_OF(JH7110_PCIE1_CLK_AXI_SLV0)] =
108 devm_clk_hw_register_fixed_factor(priv->dev,
109 "u1_plda_pcie_clk_axi_slv0",
110 "u1_plda_pcie_clk_axi_mst0", 0, 1, 1);
111 priv->pll[PLL_OF(JH7110_PCIE1_CLK_AXI_SLV)] =
112 devm_clk_hw_register_fixed_factor(priv->dev,
113 "u1_plda_pcie_clk_axi_slv",
114 "u1_plda_pcie_clk_axi_mst0", 0, 1, 1);
115 priv->pll[PLL_OF(JH7110_PCIE1_CLK_OSC)] =
116 devm_clk_hw_register_fixed_factor(priv->dev,
117 "u1_plda_pcie_clk_osc", "osc", 0, 1, 1);
118 priv->pll[PLL_OF(JH7110_E2_IRQ_SYNC_CLK_CORE)] =
119 devm_clk_hw_register_fixed_factor(priv->dev,
120 "u0_e2_sft7110_irq_sync_clk_core",
121 "stg_axiahb", 0, 1, 1);
122 priv->pll[PLL_OF(JH7110_STG_CRG_PCLK)] =
123 devm_clk_hw_register_fixed_factor(priv->dev,
124 "u0_stg_crg_pclk", "stg_apb", 0, 1, 1);
125 priv->pll[PLL_OF(JH7110_STG_SYSCON_PCLK)] =
126 devm_clk_hw_register_fixed_factor(priv->dev,
127 "u0_stg_syscon_pclk", "stg_apb", 0, 1, 1);
128 priv->pll[PLL_OF(JH7110_STG_APB)] =
129 devm_clk_hw_register_fixed_factor(priv->dev,
130 "stg_apb", "apb_bus", 0, 1, 1);
132 for (idx = JH7110_CLK_SYS_REG_END; idx < JH7110_CLK_STG_REG_END; idx++) {
133 u32 max = jh7110_clk_stg_data[idx].max;
134 struct clk_parent_data parents[4] = {};
135 struct clk_init_data init = {
136 .name = jh7110_clk_stg_data[idx].name,
137 .ops = starfive_jh7110_clk_ops(max),
138 .parent_data = parents,
139 .num_parents = ((max & JH7110_CLK_MUX_MASK) >>
140 JH7110_CLK_MUX_SHIFT) + 1,
141 .flags = jh7110_clk_stg_data[idx].flags,
143 struct jh7110_clk *clk = &priv->reg[idx];
146 for (i = 0; i < init.num_parents; i++) {
147 unsigned int pidx = jh7110_clk_stg_data[idx].parents[i];
149 if (pidx < JH7110_CLK_REG_END )
150 parents[i].hw = &priv->reg[pidx].hw;
151 else if ((pidx < JH7110_CLK_STG_END) &&
152 (pidx > (JH7110_CLK_SYS_END - 1)))
153 parents[i].hw = priv->pll[PLL_OF(pidx)];
154 else if (pidx == JH7110_OSC)
155 parents[i].fw_name = "osc";
158 clk->hw.init = &init;
160 clk->max_div = max & JH7110_CLK_DIV_MASK;
161 clk->reg_flags = JH7110_CLK_STG_FLAG;
163 ret = devm_clk_hw_register(priv->dev, &clk->hw);
168 dev_dbg(&pdev->dev, "starfive JH7110 clk_stg init successfully.");