blob: c448ed024aa99b7dd1b7b8606eaa15fa1c0417b0 [file] [log] [blame]
developer2186c982018-11-15 10:07:54 +08001/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2018 MediaTek Inc.
4 * Author: Ryder Lee <ryder.lee@mediatek.com>
5 */
6
7#ifndef __DRV_CLK_MTK_H
8#define __DRV_CLK_MTK_H
9
Simon Glass4dcacfc2020-05-10 11:40:13 -060010#include <linux/bitops.h>
developer2186c982018-11-15 10:07:54 +080011#define CLK_XTAL 0
12#define MHZ (1000 * 1000)
13
developer2dc4caa2022-09-09 19:59:59 +080014/* flags in struct mtk_clk_tree */
15
Christian Marangia4143eb2024-06-28 19:40:50 +020016/* 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 */
developer2dc4caa2022-09-09 19:59:59 +080021#define CLK_BYPASS_XTAL BIT(0)
22
developer2186c982018-11-15 10:07:54 +080023#define HAVE_RST_BAR BIT(0)
24#define CLK_DOMAIN_SCPSYS BIT(0)
developerba560c72019-12-31 11:29:21 +080025#define CLK_MUX_SETCLR_UPD BIT(1)
developer2186c982018-11-15 10:07:54 +080026
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)
developerad5b0752022-09-09 20:00:04 +080035#define CLK_PARENT_INFRASYS BIT(6)
developerf724f112022-09-09 20:00:07 +080036#define CLK_PARENT_XTAL BIT(7)
Christian Marangia4143eb2024-06-28 19:40:50 +020037/*
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
developer2186c982018-11-15 10:07:54 +080048
developera588d152019-07-29 22:17:48 +080049#define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34
developer02259452018-12-20 16:12:52 +080050
developer2186c982018-11-15 10:07:54 +080051/* struct mtk_pll_data - hardware-specific PLLs data */
52struct 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;
developer0b5e5f12019-12-31 11:29:22 +080062 u64 fmin;
developer2186c982018-11-15 10:07:54 +080063 int pcwbits;
developer0b5e5f12019-12-31 11:29:22 +080064 int pcwibits;
developer2186c982018-11-15 10:07:54 +080065 u32 pcw_reg;
66 int pcw_shift;
developer0b5e5f12019-12-31 11:29:22 +080067 u32 pcw_chg_reg;
developer2186c982018-11-15 10:07:54 +080068};
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 */
77struct 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 */
98struct 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/**
Christian Marangia4143eb2024-06-28 19:40:50 +0200115 * 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 */
122struct 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/**
developer2186c982018-11-15 10:07:54 +0800133 * struct mtk_composite - aggregate clock of mux, divider and gate clocks
134 *
135 * @id: index of clocks
136 * @parent: index of parnet clocks
Christian Marangia4143eb2024-06-28 19:40:50 +0200137 * @parent: index of parnet clocks
138 * @parent_flags: table of parent clocks with flags
developer2186c982018-11-15 10:07:54 +0800139 * @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 */
147struct mtk_composite {
148 const int id;
Christian Marangia4143eb2024-06-28 19:40:50 +0200149 union {
150 const int *parent;
151 const struct mtk_parent *parent_flags;
152 };
developer2186c982018-11-15 10:07:54 +0800153 u32 mux_reg;
developerba560c72019-12-31 11:29:21 +0800154 u32 mux_set_reg;
155 u32 mux_clr_reg;
156 u32 upd_reg;
developer2186c982018-11-15 10:07:54 +0800157 u32 gate_reg;
158 u32 mux_mask;
159 signed char mux_shift;
developerba560c72019-12-31 11:29:21 +0800160 signed char upd_shift;
developer2186c982018-11-15 10:07:54 +0800161 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(_id, _parents, _reg, _shift, _width) { \
183 .id = _id, \
184 .mux_reg = _reg, \
185 .mux_shift = _shift, \
186 .mux_mask = BIT(_width) - 1, \
187 .gate_shift = -1, \
188 .parent = _parents, \
189 .num_parents = ARRAY_SIZE(_parents), \
190 .flags = 0, \
191 }
192
developerba560c72019-12-31 11:29:21 +0800193#define MUX_CLR_SET_UPD_FLAGS(_id, _parents, _mux_ofs, _mux_set_ofs,\
194 _mux_clr_ofs, _shift, _width, _gate, \
195 _upd_ofs, _upd, _flags) { \
196 .id = _id, \
197 .mux_reg = _mux_ofs, \
198 .mux_set_reg = _mux_set_ofs, \
199 .mux_clr_reg = _mux_clr_ofs, \
200 .upd_reg = _upd_ofs, \
201 .upd_shift = _upd, \
202 .mux_shift = _shift, \
203 .mux_mask = BIT(_width) - 1, \
204 .gate_reg = _mux_ofs, \
205 .gate_shift = _gate, \
206 .parent = _parents, \
207 .num_parents = ARRAY_SIZE(_parents), \
208 .flags = _flags, \
209 }
210
developer2186c982018-11-15 10:07:54 +0800211struct mtk_gate_regs {
212 u32 sta_ofs;
213 u32 clr_ofs;
214 u32 set_ofs;
215};
216
217/**
218 * struct mtk_gate - gate clocks
219 *
220 * @id: index of gate clocks
221 * @parent: index of parnet clocks
222 * @regs: hardware-specific mux register
223 * @shift: shift to the gate bit field
224 * @flags: hardware-specific flags
225 */
226struct mtk_gate {
227 const int id;
228 const int parent;
229 const struct mtk_gate_regs *regs;
230 int shift;
231 u32 flags;
232};
233
234/* struct mtk_clk_tree - clock tree */
235struct mtk_clk_tree {
236 unsigned long xtal_rate;
237 unsigned long xtal2_rate;
Christian Marangi29771ad2024-06-28 19:40:54 +0200238 /*
239 * Clock ID offset are remapped with an auxiliary table.
240 * Enable this by defining .id_offs_map.
241 * This is needed for upstream linux kernel <soc>-clk.h that
242 * have mixed clk ID and doesn't have clear distinction between
243 * ID for factor, mux and gates.
244 */
245 const int *id_offs_map; /* optional, table clk.h to driver ID */
developer2186c982018-11-15 10:07:54 +0800246 const int fdivs_offs;
247 const int muxes_offs;
Christian Marangibaa244c2024-06-28 19:40:48 +0200248 const int gates_offs;
developer2186c982018-11-15 10:07:54 +0800249 const struct mtk_pll_data *plls;
250 const struct mtk_fixed_clk *fclks;
251 const struct mtk_fixed_factor *fdivs;
252 const struct mtk_composite *muxes;
Christian Marangibaa244c2024-06-28 19:40:48 +0200253 const struct mtk_gate *gates;
developer2dc4caa2022-09-09 19:59:59 +0800254 u32 flags;
developer2186c982018-11-15 10:07:54 +0800255};
256
257struct mtk_clk_priv {
developerfd47f762022-09-09 20:00:01 +0800258 struct udevice *parent;
developer2186c982018-11-15 10:07:54 +0800259 void __iomem *base;
260 const struct mtk_clk_tree *tree;
261};
262
263struct mtk_cg_priv {
developerfd47f762022-09-09 20:00:01 +0800264 struct udevice *parent;
developer2186c982018-11-15 10:07:54 +0800265 void __iomem *base;
266 const struct mtk_clk_tree *tree;
267 const struct mtk_gate *gates;
268};
269
270extern const struct clk_ops mtk_clk_apmixedsys_ops;
271extern const struct clk_ops mtk_clk_topckgen_ops;
developerad5b0752022-09-09 20:00:04 +0800272extern const struct clk_ops mtk_clk_infrasys_ops;
developer2186c982018-11-15 10:07:54 +0800273extern const struct clk_ops mtk_clk_gate_ops;
274
275int mtk_common_clk_init(struct udevice *dev,
276 const struct mtk_clk_tree *tree);
Christian Marangie03d0802024-06-28 19:40:53 +0200277int mtk_common_clk_infrasys_init(struct udevice *dev,
278 const struct mtk_clk_tree *tree);
developer2186c982018-11-15 10:07:54 +0800279int mtk_common_clk_gate_init(struct udevice *dev,
280 const struct mtk_clk_tree *tree,
281 const struct mtk_gate *gates);
282
283#endif /* __DRV_CLK_MTK_H */