xref: /linux/drivers/clk/meson/meson-clkc-utils.h (revision 522ba450b56fff29f868b1552bdc2965f55de7ed)
1 /* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
2 /*
3  * Copyright (c) 2023 Neil Armstrong <neil.armstrong@linaro.org>
4  */
5 
6 #ifndef __MESON_CLKC_UTILS_H__
7 #define __MESON_CLKC_UTILS_H__
8 
9 #include <linux/of_device.h>
10 #include <linux/clk-provider.h>
11 
12 struct platform_device;
13 
14 struct meson_clk_hw_data {
15 	struct clk_hw	**hws;
16 	unsigned int	num;
17 };
18 
19 struct clk_hw *meson_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_data);
20 
21 struct meson_clkc_data {
22 	const struct reg_sequence	*init_regs;
23 	unsigned int			init_count;
24 	struct meson_clk_hw_data	hw_clks;
25 };
26 
27 int meson_clkc_syscon_probe(struct platform_device *pdev);
28 int meson_clkc_mmio_probe(struct platform_device *pdev);
29 
30 #define __MESON_PCLK(_name, _reg, _bit, _ops, _pdata, _flags)		\
31 struct clk_regmap _name = {						\
32 	.data = &(struct clk_regmap_gate_data) {			\
33 		.offset = (_reg),					\
34 		.bit_idx = (_bit),					\
35 	},								\
36 	.hw.init = &(struct clk_init_data) {				\
37 		.name = #_name,						\
38 		.ops = _ops,						\
39 		.parent_data = (_pdata),				\
40 		.num_parents = 1,					\
41 		.flags = (_flags),					\
42 	},								\
43 }
44 
45 #define MESON_PCLK(_name, _reg, _bit, _pdata, _flags)			\
46 	__MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pdata, _flags)
47 
48 #define MESON_PCLK_RO(_name, _reg, _bit, _pdata, _flags)		\
49 	__MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pdata, _flags)
50 
51 /* Helpers for the usual sel/div/gate composite clocks */
52 #define MESON_COMP_SEL(_prefix, _name, _reg, _shift, _mask, _pdata,	\
53 		       _table, _dflags, _iflags)			\
54 struct clk_regmap _prefix##_name##_sel = {				\
55 	.data = &(struct clk_regmap_mux_data) {				\
56 		.offset = (_reg),					\
57 		.mask = (_mask),					\
58 		.shift = (_shift),					\
59 		.flags = (_dflags),					\
60 		.table = (_table),					\
61 	},								\
62 	.hw.init = &(struct clk_init_data){				\
63 		.name = #_name "_sel",					\
64 		.ops = &clk_regmap_mux_ops,				\
65 		.parent_data = _pdata,					\
66 		.num_parents = ARRAY_SIZE(_pdata),			\
67 		.flags = (_iflags),					\
68 	},								\
69 }
70 
71 #define MESON_COMP_DIV(_prefix, _name, _reg, _shift, _width,		\
72 		       _dflags, _iflags)				\
73 struct clk_regmap _prefix##_name##_div = {				\
74 	.data = &(struct clk_regmap_div_data) {				\
75 		.offset = (_reg),					\
76 		.shift = (_shift),					\
77 		.width = (_width),					\
78 		.flags = (_dflags),					\
79 	},								\
80 	.hw.init = &(struct clk_init_data) {				\
81 		.name = #_name "_div",					\
82 		.ops = &clk_regmap_divider_ops,				\
83 		.parent_hws = (const struct clk_hw *[]) {		\
84 			&_prefix##_name##_sel.hw			\
85 		},							\
86 		.num_parents = 1,					\
87 		.flags = (_iflags),					\
88 	},								\
89 }
90 
91 #define MESON_COMP_GATE(_prefix, _name, _reg, _bit, _iflags)		\
92 struct clk_regmap _prefix##_name = {					\
93 	.data = &(struct clk_regmap_gate_data) {			\
94 		.offset = (_reg),					\
95 		.bit_idx = (_bit),					\
96 	},								\
97 	.hw.init = &(struct clk_init_data) {				\
98 		.name = #_name,						\
99 		.ops = &clk_regmap_gate_ops,				\
100 		.parent_hws = (const struct clk_hw *[]) {		\
101 			&_prefix##_name##_div.hw			\
102 		},							\
103 		.num_parents = 1,					\
104 		.flags = (_iflags),					\
105 	},								\
106 }
107 
108 #endif
109