1// 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>
6 *		Xingyu Wu <xingyu.wu@starfivetech.com>
7 */
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
20#include "clk.h"
21
22#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)
28
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))
32
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);
236	struct clk *pclk;
237
238	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_CPU_ROOT),
239	       starfive_clk_mux(priv->reg, "cpu_root",
240				OFFSET(JH7110_SYSCLK_CPU_ROOT), 1,
241				cpu_root_sels, ARRAY_SIZE(cpu_root_sels)));
242	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_CPU_CORE),
243	       starfive_clk_divider(priv->reg,
244				    "cpu_core", "cpu_root",
245				    OFFSET(JH7110_SYSCLK_CPU_CORE), 3));
246	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_CPU_BUS),
247	       starfive_clk_divider(priv->reg,
248				    "cpu_bus", "cpu_core",
249				    OFFSET(JH7110_SYSCLK_CPU_BUS), 2));
250	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_PERH_ROOT),
251	       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));
255	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_BUS_ROOT),
256	       starfive_clk_mux(priv->reg, "bus_root",
257				OFFSET(JH7110_SYSCLK_BUS_ROOT), 1,
258				bus_root_sels,	ARRAY_SIZE(bus_root_sels)));
259	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_NOCSTG_BUS),
260	       starfive_clk_divider(priv->reg,
261				    "nocstg_bus", "bus_root",
262				    OFFSET(JH7110_SYSCLK_NOCSTG_BUS), 3));
263	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_AXI_CFG0),
264	       starfive_clk_divider(priv->reg,
265				    "axi_cfg0", "bus_root",
266				    OFFSET(JH7110_SYSCLK_AXI_CFG0), 2));
267	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_STG_AXIAHB),
268	       starfive_clk_divider(priv->reg,
269				    "stg_axiahb", "axi_cfg0",
270				    OFFSET(JH7110_SYSCLK_STG_AXIAHB), 2));
271	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_AHB0),
272	       starfive_clk_gate(priv->reg,
273				 "ahb0", "stg_axiahb",
274				 OFFSET(JH7110_SYSCLK_AHB0)));
275	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_AHB1),
276	       starfive_clk_gate(priv->reg,
277				 "ahb1", "stg_axiahb",
278				 OFFSET(JH7110_SYSCLK_AHB1)));
279	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_APB_BUS),
280	       starfive_clk_divider(priv->reg,
281				    "apb_bus", "stg_axiahb",
282				    OFFSET(JH7110_SYSCLK_APB_BUS), 4));
283	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_APB0),
284	       starfive_clk_gate(priv->reg,
285				 "apb0", "apb_bus",
286				 OFFSET(JH7110_SYSCLK_APB0)));
287	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_AHB),
288	       starfive_clk_gate(priv->reg,
289				 "qspi_ahb", "ahb1",
290				 OFFSET(JH7110_SYSCLK_QSPI_AHB)));
291	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_APB),
292	       starfive_clk_gate(priv->reg,
293				 "qspi_apb", "apb_bus",
294				 OFFSET(JH7110_SYSCLK_QSPI_APB)));
295	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_REF_SRC),
296	       starfive_clk_divider(priv->reg,
297				    "qspi_ref_src", "pll0_out",
298				    OFFSET(JH7110_SYSCLK_QSPI_REF_SRC), 5));
299	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_QSPI_REF),
300	       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));
304	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO0_AHB),
305	       starfive_clk_gate(priv->reg,
306				 "sdio0_ahb", "ahb0",
307				 OFFSET(JH7110_SYSCLK_SDIO0_AHB)));
308	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO1_AHB),
309	       starfive_clk_gate(priv->reg,
310				 "sdio1_ahb", "ahb0",
311				 OFFSET(JH7110_SYSCLK_SDIO1_AHB)));
312	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO0_SDCARD),
313	       starfive_clk_fix_parent_composite(priv->reg,
314						 "sdio0_sdcard", "axi_cfg0",
315						 OFFSET(JH7110_SYSCLK_SDIO0_SDCARD), 0, 1, 4));
316	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_SDIO1_SDCARD),
317	       starfive_clk_fix_parent_composite(priv->reg,
318						 "sdio1_sdcard", "axi_cfg0",
319						 OFFSET(JH7110_SYSCLK_SDIO1_SDCARD), 0, 1, 4));
320	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_USB_125M),
321	       starfive_clk_divider(priv->reg,
322				    "usb_125m", "pll0_out",
323				    OFFSET(JH7110_SYSCLK_USB_125M), 4));
324	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_NOC_BUS_STG_AXI),
325	       starfive_clk_gate(priv->reg,
326				 "noc_bus_stg_axi", "nocstg_bus",
327				 OFFSET(JH7110_SYSCLK_NOC_BUS_STG_AXI)));
328	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_AHB),
329	       starfive_clk_gate(priv->reg,
330				 "gmac1_ahb", "ahb0",
331				 OFFSET(JH7110_SYSCLK_GMAC1_AHB)));
332	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_AXI),
333	       starfive_clk_gate(priv->reg,
334				 "gmac1_axi", "stg_axiahb",
335				 OFFSET(JH7110_SYSCLK_GMAC1_AXI)));
336	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC_SRC),
337	       starfive_clk_divider(priv->reg,
338				    "gmac_src", "pll0_out",
339				    OFFSET(JH7110_SYSCLK_GMAC_SRC), 3));
340	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_GTXCLK),
341	       starfive_clk_divider(priv->reg,
342				    "gmac1_gtxclk", "pll0_out",
343				    OFFSET(JH7110_SYSCLK_GMAC1_GTXCLK), 4));
344	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_GTXC),
345	       starfive_clk_gate(priv->reg,
346				 "gmac1_gtxc", "gmac1_gtxclk",
347				 OFFSET(JH7110_SYSCLK_GMAC1_GTXC)));
348	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_RMII_RTX),
349	       starfive_clk_divider(priv->reg,
350				    "gmac1_rmii_rtx", "gmac1-rmii-refin-clock",
351				    OFFSET(JH7110_SYSCLK_GMAC1_RMII_RTX), 5));
352	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_PTP),
353	       starfive_clk_gate_divider(priv->reg,
354					 "gmac1_ptp", "gmac_src",
355					 OFFSET(JH7110_SYSCLK_GMAC1_PTP), 5));
356	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_RX),
357	       starfive_clk_mux(priv->reg, "gmac1_rx",
358				OFFSET(JH7110_SYSCLK_GMAC1_RX), 1,
359				gmac1_rx_sels,	ARRAY_SIZE(gmac1_rx_sels)));
360	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_TX),
361	       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));
365	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC1_TX_INV),
366	       starfive_clk_inv(priv->reg,
367				"gmac1_tx_inv", "gmac1_tx",
368				OFFSET(JH7110_SYSCLK_GMAC1_TX_INV)));
369	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC0_GTXCLK),
370	       starfive_clk_gate_divider(priv->reg,
371					 "gmac0_gtxclk", "pll0_out",
372					 OFFSET(JH7110_SYSCLK_GMAC0_GTXCLK), 4));
373	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC0_PTP),
374	       starfive_clk_gate_divider(priv->reg,
375					 "gmac0_ptp", "gmac_src",
376					 OFFSET(JH7110_SYSCLK_GMAC0_PTP), 5));
377	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_GMAC0_GTXC),
378	       starfive_clk_gate(priv->reg,
379				 "gmac0_gtxc", "gmac0_gtxclk",
380				 OFFSET(JH7110_SYSCLK_GMAC0_GTXC)));
381	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART0_APB),
382	       starfive_clk_gate(priv->reg,
383				 "uart0_apb", "apb0",
384				 OFFSET(JH7110_SYSCLK_UART0_APB)));
385	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART0_CORE),
386	       starfive_clk_gate(priv->reg,
387				 "uart0_core", "oscillator",
388				 OFFSET(JH7110_SYSCLK_UART0_CORE)));
389	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART1_APB),
390	       starfive_clk_gate(priv->reg,
391				 "uart1_apb", "apb0",
392				 OFFSET(JH7110_SYSCLK_UART1_APB)));
393	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART1_CORE),
394	       starfive_clk_gate(priv->reg,
395				 "uart1_core", "oscillator",
396				 OFFSET(JH7110_SYSCLK_UART1_CORE)));
397	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART2_APB),
398	       starfive_clk_gate(priv->reg,
399				 "uart2_apb", "apb0",
400				 OFFSET(JH7110_SYSCLK_UART2_APB)));
401	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART2_CORE),
402	       starfive_clk_gate(priv->reg,
403				 "uart2_core", "oscillator",
404				 OFFSET(JH7110_SYSCLK_UART2_CORE)));
405	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART3_APB),
406	       starfive_clk_gate(priv->reg,
407				 "uart3_apb", "apb0",
408				 OFFSET(JH7110_SYSCLK_UART3_APB)));
409	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART3_CORE),
410	       starfive_clk_gate_divider(priv->reg,
411					 "uart3_core", "perh_root",
412					 OFFSET(JH7110_SYSCLK_UART3_CORE), 8));
413	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART4_APB),
414	       starfive_clk_gate(priv->reg,
415				 "uart4_apb", "apb0",
416				 OFFSET(JH7110_SYSCLK_UART4_APB)));
417	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART4_CORE),
418	       starfive_clk_gate_divider(priv->reg,
419					 "uart4_core", "perh_root",
420					 OFFSET(JH7110_SYSCLK_UART4_CORE), 8));
421	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART5_APB),
422	       starfive_clk_gate(priv->reg,
423				 "uart5_apb", "apb0",
424				 OFFSET(JH7110_SYSCLK_UART5_APB)));
425	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_UART5_CORE),
426	       starfive_clk_gate_divider(priv->reg,
427					 "uart5_core", "perh_root",
428					 OFFSET(JH7110_SYSCLK_UART5_CORE), 8));
429	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_I2C2_APB),
430	       starfive_clk_gate(priv->reg,
431				 "i2c2_apb", "apb0",
432				 OFFSET(JH7110_SYSCLK_I2C2_APB)));
433	clk_dm(JH7110_SYS_ID_TRANS(JH7110_SYSCLK_I2C5_APB),
434	       starfive_clk_gate(priv->reg,
435				 "i2c5_apb", "apb0",
436				 OFFSET(JH7110_SYSCLK_I2C5_APB)));
437	/* 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)));
446
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
458	clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_OSC_DIV4),
459	       starfive_clk_divider(priv->reg,
460				    "osc_div4", "oscillator",
461				    OFFSET(JH7110_AONCLK_OSC_DIV4), 5));
462	clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_APB_FUNC),
463	       starfive_clk_mux(priv->reg, "apb_func",
464				OFFSET(JH7110_AONCLK_APB_FUNC), 1,
465				apb_func_sels,	ARRAY_SIZE(apb_func_sels)));
466	clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_AHB),
467	       starfive_clk_gate(priv->reg,
468				 "gmac0_ahb", "stg_axiahb",
469				 OFFSET(JH7110_AONCLK_GMAC0_AHB)));
470	clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_AXI),
471	       starfive_clk_gate(priv->reg,
472				 "gmac0_axi", "stg_axiahb",
473				 OFFSET(JH7110_AONCLK_GMAC0_AXI)));
474	clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_RMII_RTX),
475	       starfive_clk_divider(priv->reg,
476				    "gmac0_rmii_rtx", "gmac0-rmii-refin-clock",
477				    OFFSET(JH7110_AONCLK_GMAC0_RMII_RTX), 5));
478	clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_TX),
479	       starfive_clk_composite(priv->reg,
480				      "gmac0_tx", gmac0_tx_sels,
481				      ARRAY_SIZE(gmac0_tx_sels),
482				      OFFSET(JH7110_AONCLK_GMAC0_TX), 1, 1, 0));
483	clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_GMAC0_TX_INV),
484	       starfive_clk_inv(priv->reg,
485				"gmac0_tx_inv", "gmac0_tx",
486				OFFSET(JH7110_AONCLK_GMAC0_TX_INV)));
487	clk_dm(JH7110_AON_ID_TRANS(JH7110_AONCLK_OTPC_APB),
488	       starfive_clk_gate(priv->reg,
489				 "otpc_apb", "apb_bus",
490				 OFFSET(JH7110_AONCLK_OTPC_APB)));
491
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
499	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_APB),
500	       starfive_clk_gate(priv->reg,
501				 "usb_apb", "apb_bus",
502				 OFFSET(JH7110_STGCLK_USB_APB)));
503	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_UTMI_APB),
504	       starfive_clk_gate(priv->reg,
505				 "usb_utmi_apb", "apb_bus",
506				 OFFSET(JH7110_STGCLK_USB_UTMI_APB)));
507	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_AXI),
508	       starfive_clk_gate(priv->reg,
509				 "usb_axi", "stg_axiahb",
510				 OFFSET(JH7110_STGCLK_USB_AXI)));
511	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_LPM),
512	       starfive_clk_gate_divider(priv->reg,
513					 "usb_lpm", "oscillator",
514					 OFFSET(JH7110_STGCLK_USB_LPM), 2));
515	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_STB),
516	       starfive_clk_gate_divider(priv->reg,
517					 "usb_stb", "oscillator",
518					 OFFSET(JH7110_STGCLK_USB_STB), 3));
519	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_APP_125),
520	       starfive_clk_gate(priv->reg,
521				 "usb_app_125", "usb_125m",
522				 OFFSET(JH7110_STGCLK_USB_APP_125)));
523	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_USB_REFCLK),
524	       starfive_clk_divider(priv->reg, "usb_refclk", "oscillator",
525				    OFFSET(JH7110_STGCLK_USB_REFCLK), 2));
526	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE0_AXI),
527	       starfive_clk_gate(priv->reg,
528				 "pcie0_axi", "stg_axiahb",
529				 OFFSET(JH7110_STGCLK_PCIE0_AXI)));
530	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE0_APB),
531	       starfive_clk_gate(priv->reg,
532				 "pcie0_apb", "apb_bus",
533				 OFFSET(JH7110_STGCLK_PCIE0_APB)));
534	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE0_TL),
535	       starfive_clk_gate(priv->reg,
536				 "pcie0_tl", "stg_axiahb",
537				 OFFSET(JH7110_STGCLK_PCIE0_TL)));
538	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE1_AXI),
539	       starfive_clk_gate(priv->reg,
540				 "pcie1_axi", "stg_axiahb",
541				 OFFSET(JH7110_STGCLK_PCIE1_AXI)));
542	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE1_APB),
543	       starfive_clk_gate(priv->reg,
544				 "pcie1_apb", "apb_bus",
545				 OFFSET(JH7110_STGCLK_PCIE1_APB)));
546	clk_dm(JH7110_STG_ID_TRANS(JH7110_STGCLK_PCIE1_TL),
547	       starfive_clk_gate(priv->reg,
548				 "pcie1_tl", "stg_axiahb",
549				 OFFSET(JH7110_STGCLK_PCIE1_TL)));
550
551	/* 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
561	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
584static 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[] = {
630	{ .compatible = "starfive,jh7110-syscrg",
631	  .data = (ulong)&jh7110_syscrg_init
632	},
633	{ }
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[] = {
649	{ .compatible = "starfive,jh7110-aoncrg",
650	  .data = (ulong)&jh7110_aoncrg_init
651	},
652	{ }
653};
654
655JH7110_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",
678	.id = UCLASS_CLK,
679	.of_match = jh7110_stg_clk_of_match,
680	.probe = jh7110_clk_probe,
681	.ops = &jh7110_stg_clk_ops,
682	.priv_auto = sizeof(struct jh7110_clk_priv),
683	.bind = jh7110_clk_bind,
684};
685