blob: a38694809a0068fbf55191ed872f5bb7bd81e995 [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
9#include <common.h>
10#include <clk.h>
11#include <clk-uclass.h>
12#include <dm.h>
13#include <dm/device.h>
14#include <dm/devres.h>
15#include <dm/lists.h>
16#include <dt-bindings/clock/starfive,jh7110-crg.h>
17#include <log.h>
18#include <linux/clk-provider.h>
19
Xingyu Wua3897e62023-07-07 18:50:11 +080020#include "clk.h"
21
Yanhong Wang5a85d052023-03-29 11:42:13 +080022#define STARFIVE_CLK_ENABLE_SHIFT 31 /* [31] */
23#define STARFIVE_CLK_INVERT_SHIFT 30 /* [30] */
24#define STARFIVE_CLK_MUX_SHIFT 24 /* [29:24] */
25#define STARFIVE_CLK_DIV_SHIFT 0 /* [23:0] */
26
27#define OFFSET(id) ((id) * 4)
Xingyu Wua3897e62023-07-07 18:50:11 +080028
29#define JH7110_SYS_ID_TRANS(id) ((id) + JH7110_PLLCLK_END + JH7110_EXTCLK_END)
30#define JH7110_AON_ID_TRANS(id) ((id) + JH7110_SYS_ID_TRANS(JH7110_SYSCLK_END))
31#define JH7110_STG_ID_TRANS(id) ((id) + JH7110_AON_ID_TRANS(JH7110_AONCLK_END))
Yanhong Wang5a85d052023-03-29 11:42:13 +080032
33typedef int (*jh1710_init_fn)(struct udevice *dev);
34
35struct jh7110_clk_priv {
36 void __iomem *reg;
37 jh1710_init_fn init;
38};
39
40static const char *cpu_root_sels[2] = {
41 [0] = "oscillator",
42 [1] = "pll0_out",
43};
44
45static const char *perh_root_sels[2] = {
46 [0] = "pll0_out",
47 [1] = "pll2_out",
48};
49
50static const char *bus_root_sels[2] = {
51 [0] = "oscillator",
52 [1] = "pll2_out",
53};
54
55static const char *qspi_ref_sels[2] = {
56 [0] = "oscillator",
57 [1] = "qspi_ref_src",
58};
59
60static const char *gmac1_tx_sels[2] = {
61 [0] = "gmac1_gtxclk",
62 [1] = "gmac1_rmii_rtx",
63};
64
65static const char *gmac0_tx_sels[2] = {
66 [0] = "gmac0_gtxclk",
67 [1] = "gmac0_rmii_rtx",
68};
69
70static const char *apb_func_sels[2] = {
71 [0] = "osc_div4",
72 [1] = "oscillator",
73};
74
75static const char *gmac1_rx_sels[2] = {
76 [0] = "gmac1-rgmii-rxin-clock",
77 [1] = "gmac1_rmii_rtx",
78};
79
80static struct clk *starfive_clk_mux(void __iomem *reg,
81 const char *name,
82 unsigned int offset,
83 u8 width,
84 const char * const *parent_names,
85 u8 num_parents)
86{
87 return clk_register_mux(NULL, name, parent_names, num_parents, 0,
88 reg + offset, STARFIVE_CLK_MUX_SHIFT,
89 width, 0);
90}
91
92static struct clk *starfive_clk_gate(void __iomem *reg,
93 const char *name,
94 const char *parent_name,
95 unsigned int offset)
96{
97 return clk_register_gate(NULL, name, parent_name, 0, reg + offset,
98 STARFIVE_CLK_ENABLE_SHIFT, 0, NULL);
99}
100
101static struct clk *starfive_clk_inv(void __iomem *reg,
102 const char *name,
103 const char *parent_name,
104 unsigned int offset)
105{
106 return clk_register_gate(NULL, name, parent_name, 0, reg + offset,
107 STARFIVE_CLK_INVERT_SHIFT, 0, NULL);
108}
109
110static struct clk *starfive_clk_divider(void __iomem *reg,
111 const char *name,
112 const char *parent_name,
113 unsigned int offset,
114 u8 width)
115{
116 return clk_register_divider(NULL, name, parent_name, 0, reg + offset,
117 0, width, CLK_DIVIDER_ONE_BASED);
118}
119
120static struct clk *starfive_clk_composite(void __iomem *reg,
121 const char *name,
122 const char * const *parent_names,
123 unsigned int num_parents,
124 unsigned int offset,
125 unsigned int mux_width,
126 unsigned int gate_width,
127 unsigned int div_width)
128{
129 struct clk *clk = ERR_PTR(-ENOMEM);
130 struct clk_divider *div = NULL;
131 struct clk_gate *gate = NULL;
132 struct clk_mux *mux = NULL;
133 int mask_arry[4] = {0x1, 0x3, 0x7, 0xF};
134 int mask;
135
136 if (mux_width) {
137 if (mux_width > 4)
138 goto fail;
139 else
140 mask = mask_arry[mux_width - 1];
141
142 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
143 if (!mux)
144 goto fail;
145
146 mux->reg = reg + offset;
147 mux->mask = mask;
148 mux->shift = STARFIVE_CLK_MUX_SHIFT;
149 mux->num_parents = num_parents;
150 mux->flags = 0;
151 mux->parent_names = parent_names;
152 }
153
154 if (gate_width) {
155 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
156
157 if (!gate)
158 goto fail;
159
160 gate->reg = reg + offset;
161 gate->bit_idx = STARFIVE_CLK_ENABLE_SHIFT;
162 gate->flags = 0;
163 }
164
165 if (div_width) {
166 div = kzalloc(sizeof(*div), GFP_KERNEL);
167 if (!div)
168 goto fail;
169
170 div->reg = reg + offset;
171
172 if (offset == OFFSET(JH7110_SYSCLK_UART3_CORE) ||
173 offset == OFFSET(JH7110_SYSCLK_UART4_CORE) ||
174 offset == OFFSET(JH7110_SYSCLK_UART5_CORE)) {
175 div->shift = 8;
176 div->width = 8;
177 } else {
178 div->shift = STARFIVE_CLK_DIV_SHIFT;
179 div->width = div_width;
180 }
181 div->flags = CLK_DIVIDER_ONE_BASED;
182 div->table = NULL;
183 }
184
185 clk = clk_register_composite(NULL, name,
186 parent_names, num_parents,
187 &mux->clk, &clk_mux_ops,
188 &div->clk, &clk_divider_ops,
189 &gate->clk, &clk_gate_ops, 0);
190
191 if (IS_ERR(clk))
192 goto fail;
193
194 return clk;
195
196fail:
197 kfree(gate);
198 kfree(div);
199 kfree(mux);
200 return ERR_CAST(clk);
201}
202
203static struct clk *starfive_clk_fix_parent_composite(void __iomem *reg,
204 const char *name,
205 const char *parent_names,
206 unsigned int offset,
207 unsigned int mux_width,
208 unsigned int gate_width,
209 unsigned int div_width)
210{
211 const char * const *parents;
212
213 parents = &parent_names;
214
215 return starfive_clk_composite(reg, name, parents, 1, offset,
216 mux_width, gate_width, div_width);
217}
218
219static struct clk *starfive_clk_gate_divider(void __iomem *reg,
220 const char *name,
221 const char *parent,
222 unsigned int offset,
223 unsigned int width)
224{
225 const char * const *parent_names;
226
227 parent_names = &parent;
228
229 return starfive_clk_composite(reg, name, parent_names, 1,
230 offset, 0, 1, width);
231}
232
233static int jh7110_syscrg_init(struct udevice *dev)
234{
235 struct jh7110_clk_priv *priv = dev_get_priv(dev);
Yanhong Wang5a85d052023-03-29 11:42:13 +0800236 struct clk *pclk;
Yanhong Wang5a85d052023-03-29 11:42:13 +0800237
Xingyu Wua3897e62023-07-07 18:50:11 +0800238 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_CPU_ROOT),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800239 starfive_clk_mux(priv->reg, "cpu_root",
240 OFFSET(JH7110_SYSCLK_CPU_ROOT), 1,
241 cpu_root_sels, ARRAY_SIZE(cpu_root_sels)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800242 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_CPU_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800243 starfive_clk_divider(priv->reg,
244 "cpu_core", "cpu_root",
245 OFFSET(JH7110_SYSCLK_CPU_CORE), 3));
Xingyu Wua3897e62023-07-07 18:50:11 +0800246 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_CPU_BUS),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800247 starfive_clk_divider(priv->reg,
248 "cpu_bus", "cpu_core",
249 OFFSET(JH7110_SYSCLK_CPU_BUS), 2));
Xingyu Wua3897e62023-07-07 18:50:11 +0800250 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_PERH_ROOT),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800251 starfive_clk_composite(priv->reg,
252 "perh_root",
253 perh_root_sels, ARRAY_SIZE(perh_root_sels),
254 OFFSET(JH7110_SYSCLK_PERH_ROOT), 1, 0, 2));
Xingyu Wua3897e62023-07-07 18:50:11 +0800255 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_BUS_ROOT),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800256 starfive_clk_mux(priv->reg, "bus_root",
257 OFFSET(JH7110_SYSCLK_BUS_ROOT), 1,
258 bus_root_sels, ARRAY_SIZE(bus_root_sels)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800259 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_NOCSTG_BUS),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800260 starfive_clk_divider(priv->reg,
261 "nocstg_bus", "bus_root",
262 OFFSET(JH7110_SYSCLK_NOCSTG_BUS), 3));
Xingyu Wua3897e62023-07-07 18:50:11 +0800263 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_AXI_CFG0),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800264 starfive_clk_divider(priv->reg,
265 "axi_cfg0", "bus_root",
266 OFFSET(JH7110_SYSCLK_AXI_CFG0), 2));
Xingyu Wua3897e62023-07-07 18:50:11 +0800267 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_STG_AXIAHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800268 starfive_clk_divider(priv->reg,
269 "stg_axiahb", "axi_cfg0",
270 OFFSET(JH7110_SYSCLK_STG_AXIAHB), 2));
Xingyu Wua3897e62023-07-07 18:50:11 +0800271 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_AHB0),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800272 starfive_clk_gate(priv->reg,
273 "ahb0", "stg_axiahb",
274 OFFSET(JH7110_SYSCLK_AHB0)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800275 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_AHB1),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800276 starfive_clk_gate(priv->reg,
277 "ahb1", "stg_axiahb",
278 OFFSET(JH7110_SYSCLK_AHB1)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800279 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_APB_BUS),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800280 starfive_clk_divider(priv->reg,
281 "apb_bus", "stg_axiahb",
282 OFFSET(JH7110_SYSCLK_APB_BUS), 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800283 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_APB0),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800284 starfive_clk_gate(priv->reg,
285 "apb0", "apb_bus",
286 OFFSET(JH7110_SYSCLK_APB0)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800287 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_AHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800288 starfive_clk_gate(priv->reg,
289 "qspi_ahb", "ahb1",
290 OFFSET(JH7110_SYSCLK_QSPI_AHB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800291 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800292 starfive_clk_gate(priv->reg,
293 "qspi_apb", "apb_bus",
294 OFFSET(JH7110_SYSCLK_QSPI_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800295 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_REF_SRC),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800296 starfive_clk_divider(priv->reg,
297 "qspi_ref_src", "pll0_out",
298 OFFSET(JH7110_SYSCLK_QSPI_REF_SRC), 5));
Xingyu Wua3897e62023-07-07 18:50:11 +0800299 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_REF),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800300 starfive_clk_composite(priv->reg,
301 "qspi_ref",
302 qspi_ref_sels, ARRAY_SIZE(qspi_ref_sels),
303 OFFSET(JH7110_SYSCLK_QSPI_REF), 1, 1, 0));
Xingyu Wua3897e62023-07-07 18:50:11 +0800304 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO0_AHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800305 starfive_clk_gate(priv->reg,
306 "sdio0_ahb", "ahb0",
307 OFFSET(JH7110_SYSCLK_SDIO0_AHB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800308 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO1_AHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800309 starfive_clk_gate(priv->reg,
310 "sdio1_ahb", "ahb0",
311 OFFSET(JH7110_SYSCLK_SDIO1_AHB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800312 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO0_SDCARD),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800313 starfive_clk_fix_parent_composite(priv->reg,
314 "sdio0_sdcard", "axi_cfg0",
315 OFFSET(JH7110_SYSCLK_SDIO0_SDCARD), 0, 1, 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800316 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO1_SDCARD),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800317 starfive_clk_fix_parent_composite(priv->reg,
318 "sdio1_sdcard", "axi_cfg0",
319 OFFSET(JH7110_SYSCLK_SDIO1_SDCARD), 0, 1, 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800320 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_USB_125M),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800321 starfive_clk_divider(priv->reg,
322 "usb_125m", "pll0_out",
323 OFFSET(JH7110_SYSCLK_USB_125M), 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800324 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_NOC_BUS_STG_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800325 starfive_clk_gate(priv->reg,
326 "noc_bus_stg_axi", "nocstg_bus",
327 OFFSET(JH7110_SYSCLK_NOC_BUS_STG_AXI)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800328 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_AHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800329 starfive_clk_gate(priv->reg,
330 "gmac1_ahb", "ahb0",
331 OFFSET(JH7110_SYSCLK_GMAC1_AHB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800332 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800333 starfive_clk_gate(priv->reg,
334 "gmac1_axi", "stg_axiahb",
335 OFFSET(JH7110_SYSCLK_GMAC1_AXI)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800336 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC_SRC),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800337 starfive_clk_divider(priv->reg,
338 "gmac_src", "pll0_out",
339 OFFSET(JH7110_SYSCLK_GMAC_SRC), 3));
Xingyu Wua3897e62023-07-07 18:50:11 +0800340 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_GTXCLK),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800341 starfive_clk_divider(priv->reg,
342 "gmac1_gtxclk", "pll0_out",
343 OFFSET(JH7110_SYSCLK_GMAC1_GTXCLK), 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800344 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_GTXC),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800345 starfive_clk_gate(priv->reg,
346 "gmac1_gtxc", "gmac1_gtxclk",
347 OFFSET(JH7110_SYSCLK_GMAC1_GTXC)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800348 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_RMII_RTX),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800349 starfive_clk_divider(priv->reg,
350 "gmac1_rmii_rtx", "gmac1-rmii-refin-clock",
351 OFFSET(JH7110_SYSCLK_GMAC1_RMII_RTX), 5));
Xingyu Wua3897e62023-07-07 18:50:11 +0800352 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_PTP),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800353 starfive_clk_gate_divider(priv->reg,
354 "gmac1_ptp", "gmac_src",
355 OFFSET(JH7110_SYSCLK_GMAC1_PTP), 5));
Xingyu Wua3897e62023-07-07 18:50:11 +0800356 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_RX),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800357 starfive_clk_mux(priv->reg, "gmac1_rx",
358 OFFSET(JH7110_SYSCLK_GMAC1_RX), 1,
359 gmac1_rx_sels, ARRAY_SIZE(gmac1_rx_sels)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800360 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_TX),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800361 starfive_clk_composite(priv->reg,
362 "gmac1_tx",
363 gmac1_tx_sels, ARRAY_SIZE(gmac1_tx_sels),
364 OFFSET(JH7110_SYSCLK_GMAC1_TX), 1, 1, 0));
Xingyu Wua3897e62023-07-07 18:50:11 +0800365 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_TX_INV),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800366 starfive_clk_inv(priv->reg,
367 "gmac1_tx_inv", "gmac1_tx",
368 OFFSET(JH7110_SYSCLK_GMAC1_TX_INV)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800369 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC0_GTXCLK),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800370 starfive_clk_gate_divider(priv->reg,
371 "gmac0_gtxclk", "pll0_out",
372 OFFSET(JH7110_SYSCLK_GMAC0_GTXCLK), 4));
Xingyu Wua3897e62023-07-07 18:50:11 +0800373 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC0_PTP),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800374 starfive_clk_gate_divider(priv->reg,
375 "gmac0_ptp", "gmac_src",
376 OFFSET(JH7110_SYSCLK_GMAC0_PTP), 5));
Xingyu Wua3897e62023-07-07 18:50:11 +0800377 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC0_GTXC),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800378 starfive_clk_gate(priv->reg,
379 "gmac0_gtxc", "gmac0_gtxclk",
380 OFFSET(JH7110_SYSCLK_GMAC0_GTXC)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800381 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART0_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800382 starfive_clk_gate(priv->reg,
383 "uart0_apb", "apb0",
384 OFFSET(JH7110_SYSCLK_UART0_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800385 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART0_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800386 starfive_clk_gate(priv->reg,
387 "uart0_core", "oscillator",
388 OFFSET(JH7110_SYSCLK_UART0_CORE)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800389 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART1_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800390 starfive_clk_gate(priv->reg,
391 "uart1_apb", "apb0",
392 OFFSET(JH7110_SYSCLK_UART1_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800393 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART1_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800394 starfive_clk_gate(priv->reg,
395 "uart1_core", "oscillator",
396 OFFSET(JH7110_SYSCLK_UART1_CORE)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800397 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART2_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800398 starfive_clk_gate(priv->reg,
399 "uart2_apb", "apb0",
400 OFFSET(JH7110_SYSCLK_UART2_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800401 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART2_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800402 starfive_clk_gate(priv->reg,
403 "uart2_core", "oscillator",
404 OFFSET(JH7110_SYSCLK_UART2_CORE)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800405 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART3_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800406 starfive_clk_gate(priv->reg,
407 "uart3_apb", "apb0",
408 OFFSET(JH7110_SYSCLK_UART3_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800409 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART3_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800410 starfive_clk_gate_divider(priv->reg,
411 "uart3_core", "perh_root",
412 OFFSET(JH7110_SYSCLK_UART3_CORE), 8));
Xingyu Wua3897e62023-07-07 18:50:11 +0800413 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART4_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800414 starfive_clk_gate(priv->reg,
415 "uart4_apb", "apb0",
416 OFFSET(JH7110_SYSCLK_UART4_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800417 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART4_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800418 starfive_clk_gate_divider(priv->reg,
419 "uart4_core", "perh_root",
420 OFFSET(JH7110_SYSCLK_UART4_CORE), 8));
Xingyu Wua3897e62023-07-07 18:50:11 +0800421 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART5_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800422 starfive_clk_gate(priv->reg,
423 "uart5_apb", "apb0",
424 OFFSET(JH7110_SYSCLK_UART5_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800425 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART5_CORE),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800426 starfive_clk_gate_divider(priv->reg,
427 "uart5_core", "perh_root",
428 OFFSET(JH7110_SYSCLK_UART5_CORE), 8));
Xingyu Wua3897e62023-07-07 18:50:11 +0800429 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_I2C2_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800430 starfive_clk_gate(priv->reg,
431 "i2c2_apb", "apb0",
432 OFFSET(JH7110_SYSCLK_I2C2_APB)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800433 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_I2C5_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800434 starfive_clk_gate(priv->reg,
435 "i2c5_apb", "apb0",
436 OFFSET(JH7110_SYSCLK_I2C5_APB)));
Chanho Park020e1b02023-11-06 08:13:15 +0900437 /* Watchdog clocks */
438 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_WDT_APB),
439 starfive_clk_gate(priv->reg,
440 "wdt_apb", "apb0",
441 OFFSET(JH7110_SYSCLK_WDT_APB)));
442 clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_WDT_CORE),
443 starfive_clk_gate(priv->reg,
444 "wdt_core", "oscillator",
445 OFFSET(JH7110_SYSCLK_WDT_CORE)));
Yanhong Wang5a85d052023-03-29 11:42:13 +0800446
447 /* enable noc_bus_stg_axi clock */
448 if (!clk_get_by_id(JH7110_SYSCLK_NOC_BUS_STG_AXI, &pclk))
449 clk_enable(pclk);
450
451 return 0;
452}
453
454static int jh7110_aoncrg_init(struct udevice *dev)
455{
456 struct jh7110_clk_priv *priv = dev_get_priv(dev);
457
Xingyu Wua3897e62023-07-07 18:50:11 +0800458 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_OSC_DIV4),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800459 starfive_clk_divider(priv->reg,
460 "osc_div4", "oscillator",
Xingyu Wua3897e62023-07-07 18:50:11 +0800461 OFFSET(JH7110_AONCLK_OSC_DIV4), 5));
462 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_APB_FUNC),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800463 starfive_clk_mux(priv->reg, "apb_func",
Xingyu Wua3897e62023-07-07 18:50:11 +0800464 OFFSET(JH7110_AONCLK_APB_FUNC), 1,
Yanhong Wang5a85d052023-03-29 11:42:13 +0800465 apb_func_sels, ARRAY_SIZE(apb_func_sels)));
Xingyu Wua3897e62023-07-07 18:50:11 +0800466 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_AHB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800467 starfive_clk_gate(priv->reg,
468 "gmac0_ahb", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800469 OFFSET(JH7110_AONCLK_GMAC0_AHB)));
470 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800471 starfive_clk_gate(priv->reg,
472 "gmac0_axi", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800473 OFFSET(JH7110_AONCLK_GMAC0_AXI)));
474 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_RMII_RTX),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800475 starfive_clk_divider(priv->reg,
476 "gmac0_rmii_rtx", "gmac0-rmii-refin-clock",
Xingyu Wua3897e62023-07-07 18:50:11 +0800477 OFFSET(JH7110_AONCLK_GMAC0_RMII_RTX), 5));
478 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_TX),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800479 starfive_clk_composite(priv->reg,
480 "gmac0_tx", gmac0_tx_sels,
481 ARRAY_SIZE(gmac0_tx_sels),
Xingyu Wua3897e62023-07-07 18:50:11 +0800482 OFFSET(JH7110_AONCLK_GMAC0_TX), 1, 1, 0));
483 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_TX_INV),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800484 starfive_clk_inv(priv->reg,
485 "gmac0_tx_inv", "gmac0_tx",
Xingyu Wua3897e62023-07-07 18:50:11 +0800486 OFFSET(JH7110_AONCLK_GMAC0_TX_INV)));
487 clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_OTPC_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800488 starfive_clk_gate(priv->reg,
489 "otpc_apb", "apb_bus",
Xingyu Wua3897e62023-07-07 18:50:11 +0800490 OFFSET(JH7110_AONCLK_OTPC_APB)));
Yanhong Wang5a85d052023-03-29 11:42:13 +0800491
492 return 0;
493}
494
495static int jh7110_stgcrg_init(struct udevice *dev)
496{
497 struct jh7110_clk_priv *priv = dev_get_priv(dev);
498
Xingyu Wua3897e62023-07-07 18:50:11 +0800499 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800500 starfive_clk_gate(priv->reg,
501 "usb_apb", "apb_bus",
Xingyu Wua3897e62023-07-07 18:50:11 +0800502 OFFSET(JH7110_STGCLK_USB_APB)));
503 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_UTMI_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800504 starfive_clk_gate(priv->reg,
505 "usb_utmi_apb", "apb_bus",
Xingyu Wua3897e62023-07-07 18:50:11 +0800506 OFFSET(JH7110_STGCLK_USB_UTMI_APB)));
507 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800508 starfive_clk_gate(priv->reg,
509 "usb_axi", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800510 OFFSET(JH7110_STGCLK_USB_AXI)));
511 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_LPM),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800512 starfive_clk_gate_divider(priv->reg,
513 "usb_lpm", "oscillator",
Xingyu Wua3897e62023-07-07 18:50:11 +0800514 OFFSET(JH7110_STGCLK_USB_LPM), 2));
515 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_STB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800516 starfive_clk_gate_divider(priv->reg,
517 "usb_stb", "oscillator",
Xingyu Wua3897e62023-07-07 18:50:11 +0800518 OFFSET(JH7110_STGCLK_USB_STB), 3));
519 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_APP_125),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800520 starfive_clk_gate(priv->reg,
521 "usb_app_125", "usb_125m",
Xingyu Wua3897e62023-07-07 18:50:11 +0800522 OFFSET(JH7110_STGCLK_USB_APP_125)));
523 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_REFCLK),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800524 starfive_clk_divider(priv->reg, "usb_refclk", "oscillator",
Xingyu Wua3897e62023-07-07 18:50:11 +0800525 OFFSET(JH7110_STGCLK_USB_REFCLK), 2));
526 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE0_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800527 starfive_clk_gate(priv->reg,
528 "pcie0_axi", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800529 OFFSET(JH7110_STGCLK_PCIE0_AXI)));
530 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE0_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800531 starfive_clk_gate(priv->reg,
532 "pcie0_apb", "apb_bus",
Xingyu Wua3897e62023-07-07 18:50:11 +0800533 OFFSET(JH7110_STGCLK_PCIE0_APB)));
534 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE0_TL),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800535 starfive_clk_gate(priv->reg,
536 "pcie0_tl", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800537 OFFSET(JH7110_STGCLK_PCIE0_TL)));
538 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE1_AXI),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800539 starfive_clk_gate(priv->reg,
540 "pcie1_axi", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800541 OFFSET(JH7110_STGCLK_PCIE1_AXI)));
542 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE1_APB),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800543 starfive_clk_gate(priv->reg,
544 "pcie1_apb", "apb_bus",
Xingyu Wua3897e62023-07-07 18:50:11 +0800545 OFFSET(JH7110_STGCLK_PCIE1_APB)));
546 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE1_TL),
Yanhong Wang5a85d052023-03-29 11:42:13 +0800547 starfive_clk_gate(priv->reg,
548 "pcie1_tl", "stg_axiahb",
Xingyu Wua3897e62023-07-07 18:50:11 +0800549 OFFSET(JH7110_STGCLK_PCIE1_TL)));
Yanhong Wang5a85d052023-03-29 11:42:13 +0800550
Chanho Parkab81cc72023-11-01 21:16:49 +0900551 /* Security clocks */
552 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_SEC_HCLK),
553 starfive_clk_gate(priv->reg,
554 "sec_ahb", "stg_axiahb",
555 OFFSET(JH7110_STGCLK_SEC_HCLK)));
556 clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_SEC_MISCAHB),
557 starfive_clk_gate(priv->reg,
558 "sec_misc_ahb", "stg_axiahb",
559 OFFSET(JH7110_STGCLK_SEC_MISCAHB)));
560
Yanhong Wang5a85d052023-03-29 11:42:13 +0800561 return 0;
562}
563
564static int jh7110_clk_probe(struct udevice *dev)
565{
566 struct jh7110_clk_priv *priv = dev_get_priv(dev);
567
568 priv->init = (jh1710_init_fn)dev_get_driver_data(dev);
569 priv->reg = (void __iomem *)dev_read_addr_ptr(dev);
570
571 if (priv->init)
572 return priv->init(dev);
573
574 return 0;
575}
576
577static int jh7110_clk_bind(struct udevice *dev)
578{
579 /* The reset driver does not have a device node, so bind it here */
580 return device_bind_driver_to_node(dev, "jh7110_reset", dev->name,
581 dev_ofnode(dev), NULL);
582}
583
Xingyu Wua3897e62023-07-07 18:50:11 +0800584static int jh7110_sys_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
585{
586 if (args->args_count > 1) {
587 debug("Invalid args_count: %d\n", args->args_count);
588 return -EINVAL;
589 }
590
591 if (args->args_count)
592 clk->id = JH7110_SYS_ID_TRANS(args->args[0]);
593 else
594 clk->id = 0;
595
596 return 0;
597}
598
599static int jh7110_aon_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
600{
601 if (args->args_count > 1) {
602 debug("Invalid args_count: %d\n", args->args_count);
603 return -EINVAL;
604 }
605
606 if (args->args_count)
607 clk->id = JH7110_AON_ID_TRANS(args->args[0]);
608 else
609 clk->id = 0;
610
611 return 0;
612}
613
614static int jh7110_stg_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
615{
616 if (args->args_count > 1) {
617 debug("Invalid args_count: %d\n", args->args_count);
618 return -EINVAL;
619 }
620
621 if (args->args_count)
622 clk->id = JH7110_STG_ID_TRANS(args->args[0]);
623 else
624 clk->id = 0;
625
626 return 0;
627}
628
629static const struct udevice_id jh7110_sys_clk_of_match[] = {
Yanhong Wang5a85d052023-03-29 11:42:13 +0800630 { .compatible = "starfive,jh7110-syscrg",
631 .data = (ulong)&jh7110_syscrg_init
632 },
Xingyu Wua3897e62023-07-07 18:50:11 +0800633 { }
634};
635
636JH7110_CLK_OPS(sys);
637
638U_BOOT_DRIVER(jh7110_sys_clk) = {
639 .name = "jh7110_sys_clk",
640 .id = UCLASS_CLK,
641 .of_match = jh7110_sys_clk_of_match,
642 .probe = jh7110_clk_probe,
643 .ops = &jh7110_sys_clk_ops,
644 .priv_auto = sizeof(struct jh7110_clk_priv),
645 .bind = jh7110_clk_bind,
646};
647
648static const struct udevice_id jh7110_aon_clk_of_match[] = {
Yanhong Wang5a85d052023-03-29 11:42:13 +0800649 { .compatible = "starfive,jh7110-aoncrg",
650 .data = (ulong)&jh7110_aoncrg_init
651 },
652 { }
653};
654
Xingyu Wua3897e62023-07-07 18:50:11 +0800655JH7110_CLK_OPS(aon);
656
657U_BOOT_DRIVER(jh7110_aon_clk) = {
658 .name = "jh7110_aon_clk",
659 .id = UCLASS_CLK,
660 .of_match = jh7110_aon_clk_of_match,
661 .probe = jh7110_clk_probe,
662 .ops = &jh7110_aon_clk_ops,
663 .priv_auto = sizeof(struct jh7110_clk_priv),
664 .bind = jh7110_clk_bind,
665};
666
667static const struct udevice_id jh7110_stg_clk_of_match[] = {
668 { .compatible = "starfive,jh7110-stgcrg",
669 .data = (ulong)&jh7110_stgcrg_init
670 },
671 { }
672};
673
674JH7110_CLK_OPS(stg);
675
676U_BOOT_DRIVER(jh7110_stg_clk) = {
677 .name = "jh7110_stg_clk",
Yanhong Wang5a85d052023-03-29 11:42:13 +0800678 .id = UCLASS_CLK,
Xingyu Wua3897e62023-07-07 18:50:11 +0800679 .of_match = jh7110_stg_clk_of_match,
Yanhong Wang5a85d052023-03-29 11:42:13 +0800680 .probe = jh7110_clk_probe,
Xingyu Wua3897e62023-07-07 18:50:11 +0800681 .ops = &jh7110_stg_clk_ops,
Yanhong Wang5a85d052023-03-29 11:42:13 +0800682 .priv_auto = sizeof(struct jh7110_clk_priv),
Xingyu Wua3897e62023-07-07 18:50:11 +0800683 .bind = jh7110_clk_bind,
Yanhong Wang5a85d052023-03-29 11:42:13 +0800684};