1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Copyright (C) 2018 MediaTek Inc.
7 #ifndef __DRV_CLK_MTK_H
8 #define __DRV_CLK_MTK_H
10 #include <linux/bitops.h>
12 #define MHZ (1000 * 1000)
14 /* flags in struct mtk_clk_tree */
16 /* clk id == 0 doesn't mean it's xtal clk
17 * This doesn't apply when CLK_PARENT_MIXED is defined.
18 * With CLK_PARENT_MIXED declare CLK_PARENT_XTAL for the
21 #define CLK_BYPASS_XTAL BIT(0)
23 #define HAVE_RST_BAR BIT(0)
24 #define CLK_DOMAIN_SCPSYS BIT(0)
25 #define CLK_MUX_SETCLR_UPD BIT(1)
27 #define CLK_GATE_SETCLR BIT(0)
28 #define CLK_GATE_SETCLR_INV BIT(1)
29 #define CLK_GATE_NO_SETCLR BIT(2)
30 #define CLK_GATE_NO_SETCLR_INV BIT(3)
31 #define CLK_GATE_MASK GENMASK(3, 0)
33 #define CLK_PARENT_APMIXED BIT(4)
34 #define CLK_PARENT_TOPCKGEN BIT(5)
35 #define CLK_PARENT_INFRASYS BIT(6)
36 #define CLK_PARENT_XTAL BIT(7)
38 * For CLK_PARENT_MIXED to correctly work, is required to
39 * define in clk_tree flags the clk type using the alias.
41 #define CLK_PARENT_MIXED BIT(8)
42 #define CLK_PARENT_MASK GENMASK(8, 4)
44 /* alias to reference clk type */
45 #define CLK_APMIXED CLK_PARENT_APMIXED
46 #define CLK_TOPCKGEN CLK_PARENT_TOPCKGEN
47 #define CLK_INFRASYS CLK_PARENT_INFRASYS
49 #define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34
51 /* struct mtk_pll_data - hardware-specific PLLs data */
71 * struct mtk_fixed_clk - fixed clocks
73 * @id: index of clocks
74 * @parent: index of parnet clocks
77 struct mtk_fixed_clk {
83 #define FIXED_CLK(_id, _parent, _rate) { \
90 * struct mtk_fixed_factor - fixed multiplier and divider clocks
92 * @id: index of clocks
93 * @parent: index of parnet clocks
96 * @flag: hardware-specific flags
98 struct mtk_fixed_factor {
106 #define FACTOR(_id, _parent, _mult, _div, _flags) { \
115 * struct mtk_parent - clock parent with flags. Needed for MUX that
116 * parent with mixed infracfg and topckgen.
118 * @id: index of parent clocks
119 * @flags: hardware-specific flags (parent location,
120 * infracfg, topckgen, APMIXED, xtal ...)
127 #define PARENT(_id, _flags) { \
133 * struct mtk_composite - aggregate clock of mux, divider and gate clocks
135 * @id: index of clocks
136 * @parent: index of parnet clocks
137 * @parent: index of parnet clocks
138 * @parent_flags: table of parent clocks with flags
139 * @mux_reg: hardware-specific mux register
140 * @gate_reg: hardware-specific gate register
141 * @mux_mask: mask to the mux bit field
142 * @mux_shift: shift to the mux bit field
143 * @gate_shift: shift to the gate bit field
144 * @num_parents: number of parent clocks
145 * @flags: hardware-specific flags
147 struct mtk_composite {
151 const struct mtk_parent *parent_flags;
159 signed char mux_shift;
160 signed char upd_shift;
161 signed char gate_shift;
162 signed char num_parents;
166 #define MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, \
170 .mux_shift = _shift, \
171 .mux_mask = BIT(_width) - 1, \
173 .gate_shift = _gate, \
174 .parent = _parents, \
175 .num_parents = ARRAY_SIZE(_parents), \
179 #define MUX_GATE(_id, _parents, _reg, _shift, _width, _gate) \
180 MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, 0)
182 #define MUX_MIXED_FLAGS(_id, _parents, _reg, _shift, _width, _flags) { \
185 .mux_shift = _shift, \
186 .mux_mask = BIT(_width) - 1, \
188 .parent_flags = _parents, \
189 .num_parents = ARRAY_SIZE(_parents), \
190 .flags = CLK_PARENT_MIXED | (_flags), \
192 #define MUX_MIXED(_id, _parents, _reg, _shift, _width) \
193 MUX_MIXED_FLAGS(_id, _parents, _reg, _shift, _width, 0)
195 #define MUX_FLAGS(_id, _parents, _reg, _shift, _width, _flags) { \
198 .mux_shift = _shift, \
199 .mux_mask = BIT(_width) - 1, \
201 .parent = _parents, \
202 .num_parents = ARRAY_SIZE(_parents), \
205 #define MUX(_id, _parents, _reg, _shift, _width) \
206 MUX_FLAGS(_id, _parents, _reg, _shift, _width, 0)
208 #define MUX_CLR_SET_UPD_FLAGS(_id, _parents, _mux_ofs, _mux_set_ofs,\
209 _mux_clr_ofs, _shift, _width, _gate, \
210 _upd_ofs, _upd, _flags) { \
212 .mux_reg = _mux_ofs, \
213 .mux_set_reg = _mux_set_ofs, \
214 .mux_clr_reg = _mux_clr_ofs, \
215 .upd_reg = _upd_ofs, \
217 .mux_shift = _shift, \
218 .mux_mask = BIT(_width) - 1, \
219 .gate_reg = _mux_ofs, \
220 .gate_shift = _gate, \
221 .parent = _parents, \
222 .num_parents = ARRAY_SIZE(_parents), \
226 struct mtk_gate_regs {
233 * struct mtk_gate - gate clocks
235 * @id: index of gate clocks
236 * @parent: index of parnet clocks
237 * @regs: hardware-specific mux register
238 * @shift: shift to the gate bit field
239 * @flags: hardware-specific flags
244 const struct mtk_gate_regs *regs;
249 /* struct mtk_clk_tree - clock tree */
250 struct mtk_clk_tree {
251 unsigned long xtal_rate;
252 unsigned long xtal2_rate;
254 * Clock ID offset are remapped with an auxiliary table.
255 * Enable this by defining .id_offs_map.
256 * This is needed for upstream linux kernel <soc>-clk.h that
257 * have mixed clk ID and doesn't have clear distinction between
258 * ID for factor, mux and gates.
260 const int *id_offs_map; /* optional, table clk.h to driver ID */
261 const int fdivs_offs;
262 const int muxes_offs;
263 const int gates_offs;
264 const struct mtk_pll_data *plls;
265 const struct mtk_fixed_clk *fclks;
266 const struct mtk_fixed_factor *fdivs;
267 const struct mtk_composite *muxes;
268 const struct mtk_gate *gates;
272 struct mtk_clk_priv {
273 struct udevice *parent;
275 const struct mtk_clk_tree *tree;
279 struct udevice *parent;
281 const struct mtk_clk_tree *tree;
282 const struct mtk_gate *gates;
285 extern const struct clk_ops mtk_clk_apmixedsys_ops;
286 extern const struct clk_ops mtk_clk_topckgen_ops;
287 extern const struct clk_ops mtk_clk_infrasys_ops;
288 extern const struct clk_ops mtk_clk_gate_ops;
290 int mtk_common_clk_init(struct udevice *dev,
291 const struct mtk_clk_tree *tree);
292 int mtk_common_clk_infrasys_init(struct udevice *dev,
293 const struct mtk_clk_tree *tree);
294 int mtk_common_clk_gate_init(struct udevice *dev,
295 const struct mtk_clk_tree *tree,
296 const struct mtk_gate *gates);
298 #endif /* __DRV_CLK_MTK_H */