blob: 191da75d7ba2c3fe02f14e2db6bda08db9e46982 [file] [log] [blame]
Yanhong Wang5a85d052023-03-29 11:42:13 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2022-23 StarFive Technology Co., Ltd.
4 *
5 * Author: Yanhong Wang <yanhong.wang@starfivetech.com>
Xingyu Wu751e4402023-07-07 18:50:07 +08006 * Xingyu Wu <xingyu.wu@starfivetech.com>
Yanhong Wang5a85d052023-03-29 11:42:13 +08007 */
8
Yanhong Wang5a85d052023-03-29 11:42:13 +08009#include <clk.h>
10#include <clk-uclass.h>
11#include <dm.h>
12#include <dm/device.h>
13#include <dm/devres.h>
14#include <dm/lists.h>
15#include <dt-bindings/clock/starfive,jh7110-crg.h>
16#include <log.h>
17#include <linux/clk-provider.h>
18
Xingyu Wua3897e62023-07-07 18:50:11 +080019#include "clk.h"
20
Yanhong Wang5a85d052023-03-29 11:42:13 +080021#define STARFIVE_CLK_ENABLE_SHIFT 31 /* [31] */
22#define STARFIVE_CLK_INVERT_SHIFT 30 /* [30] */
23#define STARFIVE_CLK_MUX_SHIFT 24 /* [29:24] */
24#define STARFIVE_CLK_DIV_SHIFT 0 /* [23:0] */
25
26#define OFFSET(id) ((id) * 4)
Xingyu Wua3897e62023-07-07 18:50:11 +080027
28#define JH7110_SYS_ID_TRANS(id) ((id) + JH7110_PLLCLK_END + JH7110_EXTCLK_END)
29#define JH7110_AON_ID_TRANS(id) ((id) + JH7110_SYS_ID_TRANS(JH7110_SYSCLK_END))
30#define JH7110_STG_ID_TRANS(id) ((id) + JH7110_AON_ID_TRANS(JH7110_AONCLK_END))
Yanhong Wang5a85d052023-03-29 11:42:13 +080031
32typedef int (*jh1710_init_fn)(struct udevice *dev);
33
34struct jh7110_clk_priv {
35 void __iomem *reg;
36 jh1710_init_fn init;
37};
38
39static const char *cpu_root_sels[2] = {
40 [0] = "oscillator",
41 [1] = "pll0_out",
42};
43
44static const char *perh_root_sels[2] = {
45 [0] = "pll0_out",
46 [1] = "pll2_out",
47};
48
49static const char *bus_root_sels[2] = {
50 [0] = "oscillator",
51 [1] = "pll2_out",
52};
53
54static const char *qspi_ref_sels[2] = {
55 [0] = "oscillator",
56 [1] = "qspi_ref_src",
57};
58
59static const char *gmac1_tx_sels[2] = {
60 [0] = "gmac1_gtxclk",
61 [1] = "gmac1_rmii_rtx",
62};
63
64static const char *gmac0_tx_sels[2] = {
65 [0] = "gmac0_gtxclk",
66 [1] = "gmac0_rmii_rtx",
67};
68
69static const char *apb_func_sels[2] = {
70 [0] = "osc_div4",
71 [1] = "oscillator",
72};
73
74static const char *gmac1_rx_sels[2] = {
75 [0] = "gmac1-rgmii-rxin-clock",
76 [1] = "gmac1_rmii_rtx",
77};
78
79static struct clk *starfive_clk_mux(void __iomem *reg,
80 const char *name,
81 unsigned int offset,
82 u8 width,
83 const char * const *parent_names,
84 u8 num_parents)
85{
86 return clk_register_mux(NULL, name, parent_names, num_parents, 0,
87 reg + offset, STARFIVE_CLK_MUX_SHIFT,
88 width, 0);
89}
90
91static struct clk *starfive_clk_gate(void __iomem *reg,
92 const char *name,
93 const char *parent_name,
94 unsigned int offset)
95{
96 return clk_register_gate(NULL, name, parent_name, 0, reg + offset,
97 STARFIVE_CLK_ENABLE_SHIFT, 0, NULL);
98}
99
100static struct clk *starfive_clk_inv(void __iomem *reg,
101 const char *name,
102 const char *parent_name,
103 unsigned int offset)
104{
105 return clk_register_gate(NULL, name, parent_name, 0, reg + offset,
106 STARFIVE_CLK_INVERT_SHIFT, 0, NULL);
107}
108
109static struct clk *starfive_clk_divider(void __iomem *reg,
110 const char *name,
111 const char *parent_name,
112 unsigned int offset,
113 u8 width)
114{
115 return clk_register_divider(NULL, name, parent_name, 0, reg + offset,
116 0, width, CLK_DIVIDER_ONE_BASED);
117}
118
119static struct clk *starfive_clk_composite(void __iomem *reg,
120 const char *name,
121 const char * const *parent_names,
122 unsigned int num_parents,
123 unsigned int offset,
124 unsigned int mux_width,
125 unsigned int gate_width,
126 unsigned int div_width)
127{
128 struct clk *clk = ERR_PTR(-ENOMEM);
129 struct clk_divider *div = NULL;
130 struct clk_gate *gate = NULL;
131 struct clk_mux *mux = NULL;
132 int mask_arry[4] = {0x1, 0x3, 0x7, 0xF};
133 int mask;
134
135 if (mux_width) {
136 if (mux_width > 4)
137 goto fail;
138 else
139 mask = mask_arry[mux_width - 1];
140
141 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
142 if (!mux)
143 goto fail;
144
145 mux->reg = reg + offset;
146 mux->mask = mask;
147 mux->shift = STARFIVE_CLK_MUX_SHIFT;
148 mux->num_parents = num_parents;
149 mux->flags = 0;
150 mux->parent_names = parent_names;
151 }
152
153 if (gate_width) {
154 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
155
156 if (!gate)
157 goto fail;
158
159 gate->reg = reg + offset;
160 gate->bit_idx = STARFIVE_CLK_ENABLE_SHIFT;
161 gate->flags = 0;
162 }
163
164 if (div_width) {
165 div = kzalloc(sizeof(*div), GFP_KERNEL);
166 if (!div)
167 goto fail;
168
169 div->reg = reg + offset;
170
171 if (offset == OFFSET(JH7110_SYSCLK_UART3_CORE) ||
172 offset == OFFSET(JH7110_SYSCLK_UART4_CORE) ||
173 offset == OFFSET(JH7110_SYSCLK_UART5_CORE)) {
174 div->shift = 8;
175 div->width = 8;
176 } else {
177 div->shift = STARFIVE_CLK_DIV_SHIFT;
178 div->width = div_width;
179 }
180 div->flags = CLK_DIVIDER_ONE_BASED;
181 div->table = NULL;
182 }
183
184 clk = clk_register_composite(NULL, name,
185 parent_names, num_parents,
186 &mux->clk, &clk_mux_ops,
187 &div->clk, &clk_divider_ops,
188 &gate->clk, &clk_gate_ops, 0);
189
190 if (IS_ERR(clk))
191 goto fail;
192
193 return clk;
194
195fail:
196 kfree(gate);
197 kfree(div);
198 kfree(mux);
199 return ERR_CAST(clk);
200}
201
202static struct clk *starfive_clk_fix_parent_composite(void __iomem *reg,
203 const char *name,
204 const char *parent_names,
205 unsigned int offset,
206 unsigned int mux_width,
207 unsigned int gate_width,
208 unsigned int div_width)
209{
210 const char * const *parents;
211
212 parents = &parent_names;
213
214 return starfive_clk_composite(reg, name, parents, 1, offset,
215 mux_width, gate_width, div_width);
216}
217
218static struct clk *starfive_clk_gate_divider(void __iomem *reg,
219 const char *name,
220 const char *parent,
221 unsigned int offset,
222 unsigned int width)
223{
224 const char * const *parent_names;
225
226 parent_names = &parent;
227
228 return starfive_clk_composite(reg, name, parent_names, 1,
229 offset, 0, 1, width);
230}
231
232static int jh7110_syscrg_init(struct udevice *dev)
233{
234 struct jh7110_clk_priv *priv = dev_get_priv(dev);
Yanhong Wang5a85d052023-03-29 11:42:13 +0800235 struct clk *pclk;
Yanhong Wang5a85d052023-03-29 11:42:13 +0800236
Xingyu Wua3897e62023-07-07 18:50:11 +0800237 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_CPU_ROOT),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800238 starfive_clk_mux(priv->reg, "cpu_root",
239 OFFSET(JH7110_SYSCLK_CPU_ROOT), 1,
240 cpu_root_sels, ARRAY_SIZE(cpu_root_sels)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800241 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_CPU_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800242 starfive_clk_divider(priv->reg,
243 "cpu_core", "cpu_root",
244 OFFSET(JH7110_SYSCLK_CPU_CORE), 3));
Xingyu Wua3897e62023-07-07 18:50:11 +0800245 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_CPU_BUS),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800246 starfive_clk_divider(priv->reg,
247 "cpu_bus", "cpu_core",
248 OFFSET(JH7110_SYSCLK_CPU_BUS), 2));
Xingyu Wua3897e62023-07-07 18:50:11 +0800249 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_PERH_ROOT),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800250 starfive_clk_composite(priv->reg,
251 "perh_root",
252 perh_root_sels, ARRAY_SIZE(perh_root_sels),
253 OFFSET(JH7110_SYSCLK_PERH_ROOT), 1, 0, 2));
Xingyu Wua3897e62023-07-07 18:50:11 +0800254 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_BUS_ROOT),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800255 starfive_clk_mux(priv->reg, "bus_root",
256 OFFSET(JH7110_SYSCLK_BUS_ROOT), 1,
257 bus_root_sels, ARRAY_SIZE(bus_root_sels)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800258 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_NOCSTG_BUS),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800259 starfive_clk_divider(priv->reg,
260 "nocstg_bus", "bus_root",
261 OFFSET(JH7110_SYSCLK_NOCSTG_BUS), 3));
Xingyu Wua3897e62023-07-07 18:50:11 +0800262 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_AXI_CFG0),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800263 starfive_clk_divider(priv->reg,
264 "axi_cfg0", "bus_root",
265 OFFSET(JH7110_SYSCLK_AXI_CFG0), 2));
Xingyu Wua3897e62023-07-07 18:50:11 +0800266 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_STG_AXIAHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800267 starfive_clk_divider(priv->reg,
268 "stg_axiahb", "axi_cfg0",
269 OFFSET(JH7110_SYSCLK_STG_AXIAHB), 2));
Xingyu Wua3897e62023-07-07 18:50:11 +0800270 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_AHB0),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800271 starfive_clk_gate(priv->reg,
272 "ahb0", "stg_axiahb",
273 OFFSET(JH7110_SYSCLK_AHB0)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800274 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_AHB1),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800275 starfive_clk_gate(priv->reg,
276 "ahb1", "stg_axiahb",
277 OFFSET(JH7110_SYSCLK_AHB1)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800278 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_APB_BUS),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800279 starfive_clk_divider(priv->reg,
280 "apb_bus", "stg_axiahb",
281 OFFSET(JH7110_SYSCLK_APB_BUS), 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800282 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_APB0),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800283 starfive_clk_gate(priv->reg,
284 "apb0", "apb_bus",
285 OFFSET(JH7110_SYSCLK_APB0)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800286 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_AHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800287 starfive_clk_gate(priv->reg,
288 "qspi_ahb", "ahb1",
289 OFFSET(JH7110_SYSCLK_QSPI_AHB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800290 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800291 starfive_clk_gate(priv->reg,
292 "qspi_apb", "apb_bus",
293 OFFSET(JH7110_SYSCLK_QSPI_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800294 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_REF_SRC),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800295 starfive_clk_divider(priv->reg,
296 "qspi_ref_src", "pll0_out",
297 OFFSET(JH7110_SYSCLK_QSPI_REF_SRC), 5));
Xingyu Wua3897e62023-07-07 18:50:11 +0800298 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_REF),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800299 starfive_clk_composite(priv->reg,
300 "qspi_ref",
301 qspi_ref_sels, ARRAY_SIZE(qspi_ref_sels),
302 OFFSET(JH7110_SYSCLK_QSPI_REF), 1, 1, 0));
Xingyu Wua3897e62023-07-07 18:50:11 +0800303 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO0_AHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800304 starfive_clk_gate(priv->reg,
305 "sdio0_ahb", "ahb0",
306 OFFSET(JH7110_SYSCLK_SDIO0_AHB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800307 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO1_AHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800308 starfive_clk_gate(priv->reg,
309 "sdio1_ahb", "ahb0",
310 OFFSET(JH7110_SYSCLK_SDIO1_AHB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800311 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO0_SDCARD),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800312 starfive_clk_fix_parent_composite(priv->reg,
313 "sdio0_sdcard", "axi_cfg0",
314 OFFSET(JH7110_SYSCLK_SDIO0_SDCARD), 0, 1, 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800315 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO1_SDCARD),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800316 starfive_clk_fix_parent_composite(priv->reg,
317 "sdio1_sdcard", "axi_cfg0",
318 OFFSET(JH7110_SYSCLK_SDIO1_SDCARD), 0, 1, 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800319 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_USB_125M),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800320 starfive_clk_divider(priv->reg,
321 "usb_125m", "pll0_out",
322 OFFSET(JH7110_SYSCLK_USB_125M), 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800323 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_NOC_BUS_STG_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800324 starfive_clk_gate(priv->reg,
325 "noc_bus_stg_axi", "nocstg_bus",
326 OFFSET(JH7110_SYSCLK_NOC_BUS_STG_AXI)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800327 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_AHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800328 starfive_clk_gate(priv->reg,
329 "gmac1_ahb", "ahb0",
330 OFFSET(JH7110_SYSCLK_GMAC1_AHB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800331 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800332 starfive_clk_gate(priv->reg,
333 "gmac1_axi", "stg_axiahb",
334 OFFSET(JH7110_SYSCLK_GMAC1_AXI)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800335 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC_SRC),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800336 starfive_clk_divider(priv->reg,
337 "gmac_src", "pll0_out",
338 OFFSET(JH7110_SYSCLK_GMAC_SRC), 3));
Xingyu Wua3897e62023-07-07 18:50:11 +0800339 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_GTXCLK),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800340 starfive_clk_divider(priv->reg,
341 "gmac1_gtxclk", "pll0_out",
342 OFFSET(JH7110_SYSCLK_GMAC1_GTXCLK), 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800343 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_GTXC),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800344 starfive_clk_gate(priv->reg,
345 "gmac1_gtxc", "gmac1_gtxclk",
346 OFFSET(JH7110_SYSCLK_GMAC1_GTXC)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800347 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_RMII_RTX),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800348 starfive_clk_divider(priv->reg,
349 "gmac1_rmii_rtx", "gmac1-rmii-refin-clock",
350 OFFSET(JH7110_SYSCLK_GMAC1_RMII_RTX), 5));
Xingyu Wua3897e62023-07-07 18:50:11 +0800351 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_PTP),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800352 starfive_clk_gate_divider(priv->reg,
353 "gmac1_ptp", "gmac_src",
354 OFFSET(JH7110_SYSCLK_GMAC1_PTP), 5));
Xingyu Wua3897e62023-07-07 18:50:11 +0800355 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_RX),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800356 starfive_clk_mux(priv->reg, "gmac1_rx",
357 OFFSET(JH7110_SYSCLK_GMAC1_RX), 1,
358 gmac1_rx_sels, ARRAY_SIZE(gmac1_rx_sels)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800359 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_TX),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800360 starfive_clk_composite(priv->reg,
361 "gmac1_tx",
362 gmac1_tx_sels, ARRAY_SIZE(gmac1_tx_sels),
363 OFFSET(JH7110_SYSCLK_GMAC1_TX), 1, 1, 0));
Xingyu Wua3897e62023-07-07 18:50:11 +0800364 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_TX_INV),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800365 starfive_clk_inv(priv->reg,
366 "gmac1_tx_inv", "gmac1_tx",
367 OFFSET(JH7110_SYSCLK_GMAC1_TX_INV)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800368 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC0_GTXCLK),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800369 starfive_clk_gate_divider(priv->reg,
370 "gmac0_gtxclk", "pll0_out",
371 OFFSET(JH7110_SYSCLK_GMAC0_GTXCLK), 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800372 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC0_PTP),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800373 starfive_clk_gate_divider(priv->reg,
374 "gmac0_ptp", "gmac_src",
375 OFFSET(JH7110_SYSCLK_GMAC0_PTP), 5));
Xingyu Wua3897e62023-07-07 18:50:11 +0800376 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC0_GTXC),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800377 starfive_clk_gate(priv->reg,
378 "gmac0_gtxc", "gmac0_gtxclk",
379 OFFSET(JH7110_SYSCLK_GMAC0_GTXC)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800380 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART0_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800381 starfive_clk_gate(priv->reg,
382 "uart0_apb", "apb0",
383 OFFSET(JH7110_SYSCLK_UART0_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800384 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART0_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800385 starfive_clk_gate(priv->reg,
386 "uart0_core", "oscillator",
387 OFFSET(JH7110_SYSCLK_UART0_CORE)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800388 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART1_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800389 starfive_clk_gate(priv->reg,
390 "uart1_apb", "apb0",
391 OFFSET(JH7110_SYSCLK_UART1_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800392 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART1_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800393 starfive_clk_gate(priv->reg,
394 "uart1_core", "oscillator",
395 OFFSET(JH7110_SYSCLK_UART1_CORE)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800396 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART2_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800397 starfive_clk_gate(priv->reg,
398 "uart2_apb", "apb0",
399 OFFSET(JH7110_SYSCLK_UART2_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800400 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART2_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800401 starfive_clk_gate(priv->reg,
402 "uart2_core", "oscillator",
403 OFFSET(JH7110_SYSCLK_UART2_CORE)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800404 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART3_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800405 starfive_clk_gate(priv->reg,
406 "uart3_apb", "apb0",
407 OFFSET(JH7110_SYSCLK_UART3_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800408 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART3_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800409 starfive_clk_gate_divider(priv->reg,
410 "uart3_core", "perh_root",
411 OFFSET(JH7110_SYSCLK_UART3_CORE), 8));
Xingyu Wua3897e62023-07-07 18:50:11 +0800412 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART4_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800413 starfive_clk_gate(priv->reg,
414 "uart4_apb", "apb0",
415 OFFSET(JH7110_SYSCLK_UART4_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800416 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART4_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800417 starfive_clk_gate_divider(priv->reg,
418 "uart4_core", "perh_root",
419 OFFSET(JH7110_SYSCLK_UART4_CORE), 8));
Xingyu Wua3897e62023-07-07 18:50:11 +0800420 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART5_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800421 starfive_clk_gate(priv->reg,
422 "uart5_apb", "apb0",
423 OFFSET(JH7110_SYSCLK_UART5_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800424 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART5_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800425 starfive_clk_gate_divider(priv->reg,
426 "uart5_core", "perh_root",
427 OFFSET(JH7110_SYSCLK_UART5_CORE), 8));
Xingyu Wua3897e62023-07-07 18:50:11 +0800428 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_I2C2_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800429 starfive_clk_gate(priv->reg,
430 "i2c2_apb", "apb0",
431 OFFSET(JH7110_SYSCLK_I2C2_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800432 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_I2C5_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800433 starfive_clk_gate(priv->reg,
434 "i2c5_apb", "apb0",
435 OFFSET(JH7110_SYSCLK_I2C5_APB)));
Chanho Park020e1b02023-11-06 08:13:15 +0900436 /* Watchdog clocks */
437 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_WDT_APB),
438 starfive_clk_gate(priv->reg,
439 "wdt_apb", "apb0",
440 OFFSET(JH7110_SYSCLK_WDT_APB)));
441 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_WDT_CORE),
442 starfive_clk_gate(priv->reg,
443 "wdt_core", "oscillator",
444 OFFSET(JH7110_SYSCLK_WDT_CORE)));
Yanhong Wang5a85d052023-03-29 11:42:13 +0800445
446 /* enable noc_bus_stg_axi clock */
447 if (!clk_get_by_id(JH7110_SYSCLK_NOC_BUS_STG_AXI, &pclk))
448 clk_enable(pclk);
449
450 return 0;
451}
452
453static int jh7110_aoncrg_init(struct udevice *dev)
454{
455 struct jh7110_clk_priv *priv = dev_get_priv(dev);
456
Xingyu Wua3897e62023-07-07 18:50:11 +0800457 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_OSC_DIV4),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800458 starfive_clk_divider(priv->reg,
459 "osc_div4", "oscillator",
Xingyu Wua3897e62023-07-07 18:50:11 +0800460 OFFSET(JH7110_AONCLK_OSC_DIV4), 5));
461 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_APB_FUNC),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800462 starfive_clk_mux(priv->reg, "apb_func",
Xingyu Wua3897e62023-07-07 18:50:11 +0800463 OFFSET(JH7110_AONCLK_APB_FUNC), 1,
Yanhong Wang5a85d052023-03-29 11:42:13 +0800464 apb_func_sels, ARRAY_SIZE(apb_func_sels)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800465 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_AHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800466 starfive_clk_gate(priv->reg,
467 "gmac0_ahb", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800468 OFFSET(JH7110_AONCLK_GMAC0_AHB)));
469 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800470 starfive_clk_gate(priv->reg,
471 "gmac0_axi", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800472 OFFSET(JH7110_AONCLK_GMAC0_AXI)));
473 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_RMII_RTX),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800474 starfive_clk_divider(priv->reg,
475 "gmac0_rmii_rtx", "gmac0-rmii-refin-clock",
Xingyu Wua3897e62023-07-07 18:50:11 +0800476 OFFSET(JH7110_AONCLK_GMAC0_RMII_RTX), 5));
477 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_TX),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800478 starfive_clk_composite(priv->reg,
479 "gmac0_tx", gmac0_tx_sels,
480 ARRAY_SIZE(gmac0_tx_sels),
Xingyu Wua3897e62023-07-07 18:50:11 +0800481 OFFSET(JH7110_AONCLK_GMAC0_TX), 1, 1, 0));
482 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_TX_INV),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800483 starfive_clk_inv(priv->reg,
484 "gmac0_tx_inv", "gmac0_tx",
Xingyu Wua3897e62023-07-07 18:50:11 +0800485 OFFSET(JH7110_AONCLK_GMAC0_TX_INV)));
486 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_OTPC_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800487 starfive_clk_gate(priv->reg,
488 "otpc_apb", "apb_bus",
Xingyu Wua3897e62023-07-07 18:50:11 +0800489 OFFSET(JH7110_AONCLK_OTPC_APB)));
Yanhong Wang5a85d052023-03-29 11:42:13 +0800490
491 return 0;
492}
493
494static int jh7110_stgcrg_init(struct udevice *dev)
495{
496 struct jh7110_clk_priv *priv = dev_get_priv(dev);
497
Xingyu Wua3897e62023-07-07 18:50:11 +0800498 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800499 starfive_clk_gate(priv->reg,
500 "usb_apb", "apb_bus",
Xingyu Wua3897e62023-07-07 18:50:11 +0800501 OFFSET(JH7110_STGCLK_USB_APB)));
502 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_UTMI_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800503 starfive_clk_gate(priv->reg,
504 "usb_utmi_apb", "apb_bus",
Xingyu Wua3897e62023-07-07 18:50:11 +0800505 OFFSET(JH7110_STGCLK_USB_UTMI_APB)));
506 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800507 starfive_clk_gate(priv->reg,
508 "usb_axi", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800509 OFFSET(JH7110_STGCLK_USB_AXI)));
510 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_LPM),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800511 starfive_clk_gate_divider(priv->reg,
512 "usb_lpm", "oscillator",
Xingyu Wua3897e62023-07-07 18:50:11 +0800513 OFFSET(JH7110_STGCLK_USB_LPM), 2));
514 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_STB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800515 starfive_clk_gate_divider(priv->reg,
516 "usb_stb", "oscillator",
Xingyu Wua3897e62023-07-07 18:50:11 +0800517 OFFSET(JH7110_STGCLK_USB_STB), 3));
518 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_APP_125),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800519 starfive_clk_gate(priv->reg,
520 "usb_app_125", "usb_125m",
Xingyu Wua3897e62023-07-07 18:50:11 +0800521 OFFSET(JH7110_STGCLK_USB_APP_125)));
522 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_REFCLK),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800523 starfive_clk_divider(priv->reg, "usb_refclk", "oscillator",
Xingyu Wua3897e62023-07-07 18:50:11 +0800524 OFFSET(JH7110_STGCLK_USB_REFCLK), 2));
525 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE0_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800526 starfive_clk_gate(priv->reg,
527 "pcie0_axi", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800528 OFFSET(JH7110_STGCLK_PCIE0_AXI)));
529 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE0_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800530 starfive_clk_gate(priv->reg,
531 "pcie0_apb", "apb_bus",
Xingyu Wua3897e62023-07-07 18:50:11 +0800532 OFFSET(JH7110_STGCLK_PCIE0_APB)));
533 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE0_TL),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800534 starfive_clk_gate(priv->reg,
535 "pcie0_tl", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800536 OFFSET(JH7110_STGCLK_PCIE0_TL)));
537 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE1_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800538 starfive_clk_gate(priv->reg,
539 "pcie1_axi", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800540 OFFSET(JH7110_STGCLK_PCIE1_AXI)));
541 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE1_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800542 starfive_clk_gate(priv->reg,
543 "pcie1_apb", "apb_bus",
Xingyu Wua3897e62023-07-07 18:50:11 +0800544 OFFSET(JH7110_STGCLK_PCIE1_APB)));
545 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE1_TL),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800546 starfive_clk_gate(priv->reg,
547 "pcie1_tl", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800548 OFFSET(JH7110_STGCLK_PCIE1_TL)));
Yanhong Wang5a85d052023-03-29 11:42:13 +0800549
Chanho Parkab81cc72023-11-01 21:16:49 +0900550 /* Security clocks */
551 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_SEC_HCLK),
552 starfive_clk_gate(priv->reg,
553 "sec_ahb", "stg_axiahb",
554 OFFSET(JH7110_STGCLK_SEC_HCLK)));
555 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_SEC_MISCAHB),
556 starfive_clk_gate(priv->reg,
557 "sec_misc_ahb", "stg_axiahb",
558 OFFSET(JH7110_STGCLK_SEC_MISCAHB)));
559
Yanhong Wang5a85d052023-03-29 11:42:13 +0800560 return 0;
561}
562
563static int jh7110_clk_probe(struct udevice *dev)
564{
565 struct jh7110_clk_priv *priv = dev_get_priv(dev);
566
567 priv->init = (jh1710_init_fn)dev_get_driver_data(dev);
568 priv->reg = (void __iomem *)dev_read_addr_ptr(dev);
569
570 if (priv->init)
571 return priv->init(dev);
572
573 return 0;
574}
575
576static int jh7110_clk_bind(struct udevice *dev)
577{
578 /* The reset driver does not have a device node, so bind it here */
579 return device_bind_driver_to_node(dev, "jh7110_reset", dev->name,
580 dev_ofnode(dev), NULL);
581}
582
Xingyu Wua3897e62023-07-07 18:50:11 +0800583static int jh7110_sys_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
584{
585 if (args->args_count > 1) {
586 debug("Invalid args_count: %d\n", args->args_count);
587 return -EINVAL;
588 }
589
590 if (args->args_count)
591 clk->id = JH7110_SYS_ID_TRANS(args->args[0]);
592 else
593 clk->id = 0;
594
595 return 0;
596}
597
598static int jh7110_aon_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
599{
600 if (args->args_count > 1) {
601 debug("Invalid args_count: %d\n", args->args_count);
602 return -EINVAL;
603 }
604
605 if (args->args_count)
606 clk->id = JH7110_AON_ID_TRANS(args->args[0]);
607 else
608 clk->id = 0;
609
610 return 0;
611}
612
613static int jh7110_stg_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
614{
615 if (args->args_count > 1) {
616 debug("Invalid args_count: %d\n", args->args_count);
617 return -EINVAL;
618 }
619
620 if (args->args_count)
621 clk->id = JH7110_STG_ID_TRANS(args->args[0]);
622 else
623 clk->id = 0;
624
625 return 0;
626}
627
628static const struct udevice_id jh7110_sys_clk_of_match[] = {
Yanhong Wang5a85d052023-03-29 11:42:13 +0800629 { .compatible = "starfive,jh7110-syscrg",
630 .data = (ulong)&jh7110_syscrg_init
631 },
Xingyu Wua3897e62023-07-07 18:50:11 +0800632 { }
633};
634
635JH7110_CLK_OPS(sys);
636
637U_BOOT_DRIVER(jh7110_sys_clk) = {
638 .name = "jh7110_sys_clk",
639 .id = UCLASS_CLK,
640 .of_match = jh7110_sys_clk_of_match,
641 .probe = jh7110_clk_probe,
642 .ops = &jh7110_sys_clk_ops,
643 .priv_auto = sizeof(struct jh7110_clk_priv),
644 .bind = jh7110_clk_bind,
645};
646
647static const struct udevice_id jh7110_aon_clk_of_match[] = {
Yanhong Wang5a85d052023-03-29 11:42:13 +0800648 { .compatible = "starfive,jh7110-aoncrg",
649 .data = (ulong)&jh7110_aoncrg_init
650 },
651 { }
652};
653
Xingyu Wua3897e62023-07-07 18:50:11 +0800654JH7110_CLK_OPS(aon);
655
656U_BOOT_DRIVER(jh7110_aon_clk) = {
657 .name = "jh7110_aon_clk",
658 .id = UCLASS_CLK,
659 .of_match = jh7110_aon_clk_of_match,
660 .probe = jh7110_clk_probe,
661 .ops = &jh7110_aon_clk_ops,
662 .priv_auto = sizeof(struct jh7110_clk_priv),
663 .bind = jh7110_clk_bind,
664};
665
666static const struct udevice_id jh7110_stg_clk_of_match[] = {
667 { .compatible = "starfive,jh7110-stgcrg",
668 .data = (ulong)&jh7110_stgcrg_init
669 },
670 { }
671};
672
673JH7110_CLK_OPS(stg);
674
675U_BOOT_DRIVER(jh7110_stg_clk) = {
676 .name = "jh7110_stg_clk",
Yanhong Wang5a85d052023-03-29 11:42:13 +0800677 .id = UCLASS_CLK,
Xingyu Wua3897e62023-07-07 18:50:11 +0800678 .of_match = jh7110_stg_clk_of_match,
Yanhong Wang5a85d052023-03-29 11:42:13 +0800679 .probe = jh7110_clk_probe,
Xingyu Wua3897e62023-07-07 18:50:11 +0800680 .ops = &jh7110_stg_clk_ops,
Yanhong Wang5a85d052023-03-29 11:42:13 +0800681 .priv_auto = sizeof(struct jh7110_clk_priv),
Xingyu Wua3897e62023-07-07 18:50:11 +0800682 .bind = jh7110_clk_bind,
Yanhong Wang5a85d052023-03-29 11:42:13 +0800683};