]> Git Repo - J-u-boot.git/blob - drivers/clk/mediatek/clk-mtk.h
Merge patch series "Bug-fixes for a few boards"
[J-u-boot.git] / drivers / clk / mediatek / clk-mtk.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2018 MediaTek Inc.
4  * Author: Ryder Lee <[email protected]>
5  */
6
7 #ifndef __DRV_CLK_MTK_H
8 #define __DRV_CLK_MTK_H
9
10 #include <linux/bitops.h>
11 #define CLK_XTAL                        0
12 #define MHZ                             (1000 * 1000)
13
14 /* flags in struct mtk_clk_tree */
15
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
19  * relevant parent.
20  */
21 #define CLK_BYPASS_XTAL                 BIT(0)
22
23 #define HAVE_RST_BAR                    BIT(0)
24 #define CLK_DOMAIN_SCPSYS               BIT(0)
25 #define CLK_MUX_SETCLR_UPD              BIT(1)
26
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)
32
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)
37 /*
38  * For CLK_PARENT_MIXED to correctly work, is required to
39  * define in clk_tree flags the clk type using the alias.
40  */
41 #define CLK_PARENT_MIXED                BIT(8)
42 #define CLK_PARENT_MASK                 GENMASK(8, 4)
43
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
48
49 #define ETHSYS_HIFSYS_RST_CTRL_OFS      0x34
50
51 /* struct mtk_pll_data - hardware-specific PLLs data */
52 struct mtk_pll_data {
53         const int id;
54         u32 reg;
55         u32 pwr_reg;
56         u32 en_mask;
57         u32 pd_reg;
58         int pd_shift;
59         u32 flags;
60         u32 rst_bar_mask;
61         u64 fmax;
62         u64 fmin;
63         int pcwbits;
64         int pcwibits;
65         u32 pcw_reg;
66         int pcw_shift;
67         u32 pcw_chg_reg;
68 };
69
70 /**
71  * struct mtk_fixed_clk - fixed clocks
72  *
73  * @id:         index of clocks
74  * @parent:     index of parnet clocks
75  * @rate:       fixed rate
76  */
77 struct mtk_fixed_clk {
78         const int id;
79         const int parent;
80         unsigned long rate;
81 };
82
83 #define FIXED_CLK(_id, _parent, _rate) {                \
84                 .id = _id,                              \
85                 .parent = _parent,                      \
86                 .rate = _rate,                          \
87         }
88
89 /**
90  * struct mtk_fixed_factor - fixed multiplier and divider clocks
91  *
92  * @id:         index of clocks
93  * @parent:     index of parnet clocks
94  * @mult:       multiplier
95  * @div:        divider
96  * @flag:       hardware-specific flags
97  */
98 struct mtk_fixed_factor {
99         const int id;
100         const int parent;
101         u32 mult;
102         u32 div;
103         u32 flags;
104 };
105
106 #define FACTOR(_id, _parent, _mult, _div, _flags) {     \
107                 .id = _id,                              \
108                 .parent = _parent,                      \
109                 .mult = _mult,                          \
110                 .div = _div,                            \
111                 .flags = _flags,                        \
112         }
113
114 /**
115  * struct mtk_parent -  clock parent with flags. Needed for MUX that
116  *                      parent with mixed infracfg and topckgen.
117  *
118  * @id:                 index of parent clocks
119  * @flags:              hardware-specific flags (parent location,
120  *                      infracfg, topckgen, APMIXED, xtal ...)
121  */
122 struct mtk_parent {
123         const int id;
124         u16 flags;
125 };
126
127 #define PARENT(_id, _flags) {                           \
128                 .id = _id,                              \
129                 .flags = _flags,                        \
130         }
131
132 /**
133  * struct mtk_composite - aggregate clock of mux, divider and gate clocks
134  *
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
146  */
147 struct mtk_composite {
148         const int id;
149         union {
150                 const int *parent;
151                 const struct mtk_parent *parent_flags;
152         };
153         u32 mux_reg;
154         u32 mux_set_reg;
155         u32 mux_clr_reg;
156         u32 upd_reg;
157         u32 gate_reg;
158         u32 mux_mask;
159         signed char mux_shift;
160         signed char upd_shift;
161         signed char gate_shift;
162         signed char num_parents;
163         u16 flags;
164 };
165
166 #define MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate,      \
167                        _flags) {                                        \
168                 .id = _id,                                              \
169                 .mux_reg = _reg,                                        \
170                 .mux_shift = _shift,                                    \
171                 .mux_mask = BIT(_width) - 1,                            \
172                 .gate_reg = _reg,                                       \
173                 .gate_shift = _gate,                                    \
174                 .parent = _parents,                                     \
175                 .num_parents = ARRAY_SIZE(_parents),                    \
176                 .flags = _flags,                                        \
177         }
178
179 #define MUX_GATE(_id, _parents, _reg, _shift, _width, _gate)            \
180         MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, 0)
181
182 #define MUX_MIXED_FLAGS(_id, _parents, _reg, _shift, _width, _flags) {  \
183                 .id = _id,                                              \
184                 .mux_reg = _reg,                                        \
185                 .mux_shift = _shift,                                    \
186                 .mux_mask = BIT(_width) - 1,                            \
187                 .gate_shift = -1,                                       \
188                 .parent_flags = _parents,                               \
189                 .num_parents = ARRAY_SIZE(_parents),                    \
190                 .flags = CLK_PARENT_MIXED | (_flags),                   \
191         }
192 #define MUX_MIXED(_id, _parents, _reg, _shift, _width)                  \
193         MUX_MIXED_FLAGS(_id, _parents, _reg, _shift, _width, 0)
194
195 #define MUX_FLAGS(_id, _parents, _reg, _shift, _width, _flags) {        \
196                 .id = _id,                                              \
197                 .mux_reg = _reg,                                        \
198                 .mux_shift = _shift,                                    \
199                 .mux_mask = BIT(_width) - 1,                            \
200                 .gate_shift = -1,                                       \
201                 .parent = _parents,                                     \
202                 .num_parents = ARRAY_SIZE(_parents),                    \
203                 .flags = _flags,                                        \
204         }
205 #define MUX(_id, _parents, _reg, _shift, _width)                        \
206         MUX_FLAGS(_id, _parents, _reg, _shift, _width, 0)
207
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) {                       \
211                 .id = _id,                                              \
212                 .mux_reg = _mux_ofs,                                    \
213                 .mux_set_reg = _mux_set_ofs,                    \
214                 .mux_clr_reg = _mux_clr_ofs,                    \
215                 .upd_reg = _upd_ofs,                                    \
216                 .upd_shift = _upd,                                      \
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),                    \
223                 .flags = _flags,                                        \
224         }
225
226 struct mtk_gate_regs {
227         u32 sta_ofs;
228         u32 clr_ofs;
229         u32 set_ofs;
230 };
231
232 /**
233  * struct mtk_gate - gate clocks
234  *
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
240  */
241 struct mtk_gate {
242         const int id;
243         const int parent;
244         const struct mtk_gate_regs *regs;
245         int shift;
246         u32 flags;
247 };
248
249 /* struct mtk_clk_tree - clock tree */
250 struct mtk_clk_tree {
251         unsigned long xtal_rate;
252         unsigned long xtal2_rate;
253         /*
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.
259          */
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;
269         u32 flags;
270 };
271
272 struct mtk_clk_priv {
273         struct udevice *parent;
274         void __iomem *base;
275         const struct mtk_clk_tree *tree;
276 };
277
278 struct mtk_cg_priv {
279         struct udevice *parent;
280         void __iomem *base;
281         const struct mtk_clk_tree *tree;
282         const struct mtk_gate *gates;
283 };
284
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;
289
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);
297
298 #endif /* __DRV_CLK_MTK_H */
This page took 0.076882 seconds and 4 git commands to generate.