blob: 09d15d86dc9a316d3465369995c0b78fe6512eb1 [file] [log] [blame]
Kongyang Liu80bf1f72024-06-11 17:41:14 +08001/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
4 *
5 */
6
7#ifndef __CLK_SOPHGO_IP_H__
8#define __CLK_SOPHGO_IP_H__
9
10#include <clk.h>
11
12#include "clk-common.h"
13
14struct cv1800b_mmux_parent_info {
15 const char *name;
16 u8 clk_sel;
17 u8 index;
18};
19
20struct cv1800b_clk_gate {
21 struct clk clk;
22 const char *name;
23 const char *parent_name;
24 void __iomem *base;
25 struct cv1800b_clk_regbit gate;
26};
27
28struct cv1800b_clk_div {
29 struct clk clk;
30 const char *name;
31 const char *parent_name;
32 void __iomem *base;
33 struct cv1800b_clk_regbit gate;
34 struct cv1800b_clk_regfield div;
35 int div_init;
36};
37
38struct cv1800b_clk_bypass_div {
39 struct cv1800b_clk_div div;
40 struct cv1800b_clk_regbit bypass;
41};
42
43struct cv1800b_clk_fixed_div {
44 struct clk clk;
45 const char *name;
46 const char *parent_name;
47 void __iomem *base;
48 struct cv1800b_clk_regbit gate;
49 int div;
50};
51
52struct cv1800b_clk_bypass_fixed_div {
53 struct cv1800b_clk_fixed_div div;
54 struct cv1800b_clk_regbit bypass;
55};
56
57struct cv1800b_clk_mux {
58 struct clk clk;
59 const char *name;
60 const char * const *parent_names;
61 u8 num_parents;
62 void __iomem *base;
63 struct cv1800b_clk_regbit gate;
64 struct cv1800b_clk_regfield div;
65 int div_init;
66 struct cv1800b_clk_regfield mux;
67};
68
69struct cv1800b_clk_bypass_mux {
70 struct cv1800b_clk_mux mux;
71 struct cv1800b_clk_regbit bypass;
72};
73
74struct cv1800b_clk_mmux {
75 struct clk clk;
76 const char *name;
77 const struct cv1800b_mmux_parent_info *parent_infos;
78 u8 num_parents;
79 void __iomem *base;
80 struct cv1800b_clk_regbit gate;
81 struct cv1800b_clk_regfield div[2];
82 int div_init[2];
83 struct cv1800b_clk_regfield mux[2];
84 struct cv1800b_clk_regbit bypass;
85 struct cv1800b_clk_regbit clk_sel;
86};
87
88struct cv1800b_clk_audio {
89 struct clk clk;
90 const char *name;
91 const char *parent_name;
92 void __iomem *base;
93 struct cv1800b_clk_regbit src_en;
94 struct cv1800b_clk_regbit output_en;
95 struct cv1800b_clk_regbit div_en;
96 struct cv1800b_clk_regbit div_up;
97 struct cv1800b_clk_regfield m;
98 struct cv1800b_clk_regfield n;
99};
100
101#define CV1800B_GATE(_id, _name, _parent, \
102 _gate_offset, _gate_shift, \
103 _flags) \
104 { \
105 .clk = { \
106 .id = CV1800B_CLK_ID_TRANSFORM(_id), \
107 .flags = _flags, \
108 }, \
109 .name = _name, \
110 .parent_name = _parent, \
111 .gate = CV1800B_CLK_REGBIT(_gate_offset, _gate_shift), \
112 }
113
114#define CV1800B_DIV(_id, _name, _parent, \
115 _gate_offset, _gate_shift, \
116 _div_offset, _div_shift, _div_width, \
117 _div_init, _flags) \
118 { \
119 .clk = { \
120 .id = CV1800B_CLK_ID_TRANSFORM(_id), \
121 .flags = _flags, \
122 }, \
123 .name = _name, \
124 .parent_name = _parent, \
125 .gate = CV1800B_CLK_REGBIT(_gate_offset, _gate_shift), \
126 .div = CV1800B_CLK_REGFIELD(_div_offset, _div_shift, \
127 _div_width), \
128 .div_init = _div_init, \
129 }
130
131#define CV1800B_BYPASS_DIV(_id, _name, _parent, \
132 _gate_offset, _gate_shift, \
133 _div_offset, _div_shift, \
134 _div_width, _div_init, \
135 _bypass_offset, _bypass_shift, \
136 _flags) \
137 { \
138 .div = CV1800B_DIV(_id, _name, _parent, \
139 _gate_offset, _gate_shift, \
140 _div_offset, _div_shift, _div_width, \
141 _div_init, _flags), \
142 .bypass = CV1800B_CLK_REGBIT(_bypass_offset, \
143 _bypass_shift), \
144 }
145
146#define CV1800B_FIXED_DIV(_id, _name, _parent, \
147 _gate_offset, _gate_shift, \
148 _div, _flags) \
149 { \
150 .clk = { \
151 .id = CV1800B_CLK_ID_TRANSFORM(_id), \
152 .flags = _flags, \
153 }, \
154 .name = _name, \
155 .parent_name = _parent, \
156 .gate = CV1800B_CLK_REGBIT(_gate_offset, _gate_shift), \
157 .div = _div, \
158 }
159
160#define CV1800B_BYPASS_FIXED_DIV(_id, _name, _parent, \
161 _gate_offset, _gate_shift, \
162 _div, \
163 _bypass_offset, _bypass_shift, \
164 _flags) \
165 { \
166 .div = CV1800B_FIXED_DIV(_id, _name, _parent, \
167 _gate_offset, _gate_shift, \
168 _div, _flags), \
169 .bypass = CV1800B_CLK_REGBIT(_bypass_offset, \
170 _bypass_shift) \
171 }
172
173#define CV1800B_MUX(_id, _name, _parents, \
174 _gate_offset, _gate_shift, \
175 _div_offset, _div_shift, _div_width, _div_init, \
176 _mux_offset, _mux_shift, _mux_width, \
177 _flags) \
178 { \
179 .clk = { \
180 .id = CV1800B_CLK_ID_TRANSFORM(_id), \
181 .flags = _flags, \
182 }, \
183 .name = _name, \
184 .parent_names = _parents, \
185 .num_parents = ARRAY_SIZE(_parents), \
186 .gate = CV1800B_CLK_REGBIT(_gate_offset, _gate_shift), \
187 .div = CV1800B_CLK_REGFIELD(_div_offset, _div_shift, \
188 _div_width), \
189 .div_init = _div_init, \
190 .mux = CV1800B_CLK_REGFIELD(_mux_offset, _mux_shift, \
191 _mux_width), \
192 }
193
194#define CV1800B_BYPASS_MUX(_id, _name, _parents, \
195 _gate_offset, _gate_shift, \
196 _div_offset, _div_shift, \
197 _div_width, _div_init, \
198 _mux_offset, _mux_shift, _mux_width, \
199 _bypass_offset, _bypass_shift, \
200 _flags) \
201 { \
202 .mux = CV1800B_MUX(_id, _name, _parents, \
203 _gate_offset, _gate_shift, \
204 _div_offset, _div_shift, \
205 _div_width, _div_init, \
206 _mux_offset, _mux_shift, _mux_width, \
207 _flags), \
208 .bypass = CV1800B_CLK_REGBIT(_bypass_offset, \
209 _bypass_shift), \
210 }
211
212#define CV1800B_MMUX(_id, _name, _parents, \
213 _gate_offset, _gate_shift, \
214 _div0_offset, _div0_shift, _div0_width, _div0_init,\
215 _div1_offset, _div1_shift, _div1_width, _div1_init,\
216 _mux0_offset, _mux0_shift, _mux0_width, \
217 _mux1_offset, _mux1_shift, _mux1_width, \
218 _bypass_offset, _bypass_shift, \
219 _clk_sel_offset, _clk_sel_shift, \
220 _flags) \
221 { \
222 .clk = { \
223 .id = CV1800B_CLK_ID_TRANSFORM(_id), \
224 .flags = _flags, \
225 }, \
226 .name = _name, \
227 .parent_infos = _parents, \
228 .num_parents = ARRAY_SIZE(_parents), \
229 .gate = CV1800B_CLK_REGBIT(_gate_offset, _gate_shift), \
230 .div = { \
231 CV1800B_CLK_REGFIELD(_div0_offset, _div0_shift, \
232 _div0_width), \
233 CV1800B_CLK_REGFIELD(_div1_offset, _div1_shift, \
234 _div1_width), \
235 }, \
236 .div_init = { _div0_init, _div1_init }, \
237 .mux = { \
238 CV1800B_CLK_REGFIELD(_mux0_offset, _mux0_shift, \
239 _mux0_width), \
240 CV1800B_CLK_REGFIELD(_mux1_offset, _mux1_shift, \
241 _mux1_width), \
242 }, \
243 .bypass = CV1800B_CLK_REGBIT(_bypass_offset, \
244 _bypass_shift), \
245 .clk_sel = CV1800B_CLK_REGBIT(_clk_sel_offset, \
246 _clk_sel_shift), \
247 }
248
249#define CV1800B_AUDIO(_id, _name, _parent, \
250 _src_en_offset, _src_en_shift, \
251 _output_en_offset, _output_en_shift, \
252 _div_en_offset, _div_en_shift, \
253 _div_up_offset, _div_up_shift, \
254 _m_offset, _m_shift, _m_width, \
255 _n_offset, _n_shift, _n_width, \
256 _flags) \
257 { \
258 .clk = { \
259 .id = CV1800B_CLK_ID_TRANSFORM(_id), \
260 .flags = _flags, \
261 }, \
262 .name = _name, \
263 .parent_name = _parent, \
264 .src_en = CV1800B_CLK_REGBIT(_src_en_offset, \
265 _src_en_shift), \
266 .output_en = CV1800B_CLK_REGBIT(_output_en_offset, \
267 _output_en_shift), \
268 .div_en = CV1800B_CLK_REGBIT(_div_en_offset, \
269 _div_en_shift), \
270 .div_up = CV1800B_CLK_REGBIT(_div_up_offset, \
271 _div_up_shift), \
272 .m = CV1800B_CLK_REGFIELD(_m_offset, _m_shift, \
273 _m_width), \
274 .n = CV1800B_CLK_REGFIELD(_n_offset, _n_shift, \
275 _n_width), \
276 }
277
278extern const struct clk_ops cv1800b_clk_gate_ops;
279extern const struct clk_ops cv1800b_clk_div_ops;
280extern const struct clk_ops cv1800b_clk_bypass_div_ops;
281extern const struct clk_ops cv1800b_clk_fixed_div_ops;
282extern const struct clk_ops cv1800b_clk_bypass_fixed_div_ops;
283extern const struct clk_ops cv1800b_clk_mux_ops;
284extern const struct clk_ops cv1800b_clk_bypass_mux_ops;
285extern const struct clk_ops cv1800b_clk_mmux_ops;
286extern const struct clk_ops cv1800b_clk_audio_ops;
287
288#endif /* __CLK_SOPHGO_IP_H__ */