blob: 48ce16484ec2a414b111bd6acac03d8ad4cd32ef [file] [log] [blame]
Ryder Lee0bd7dc72018-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 Glasscd93d622020-05-10 11:40:13 -060010#include <linux/bitops.h>
Ryder Lee0bd7dc72018-11-15 10:07:54 +080011#define CLK_XTAL 0
12#define MHZ (1000 * 1000)
13
Weijie Gao7fb33e92022-09-09 19:59:59 +080014/* flags in struct mtk_clk_tree */
15
16/* clk id == 0 doesn't mean it's xtal clk */
17#define CLK_BYPASS_XTAL BIT(0)
18
Ryder Lee0bd7dc72018-11-15 10:07:54 +080019#define HAVE_RST_BAR BIT(0)
20#define CLK_DOMAIN_SCPSYS BIT(0)
mingming leef62168d2019-12-31 11:29:21 +080021#define CLK_MUX_SETCLR_UPD BIT(1)
Ryder Lee0bd7dc72018-11-15 10:07:54 +080022
23#define CLK_GATE_SETCLR BIT(0)
24#define CLK_GATE_SETCLR_INV BIT(1)
25#define CLK_GATE_NO_SETCLR BIT(2)
26#define CLK_GATE_NO_SETCLR_INV BIT(3)
27#define CLK_GATE_MASK GENMASK(3, 0)
28
29#define CLK_PARENT_APMIXED BIT(4)
30#define CLK_PARENT_TOPCKGEN BIT(5)
Weijie Gao570b0842022-09-09 20:00:04 +080031#define CLK_PARENT_INFRASYS BIT(6)
Weijie Gaoad832b92022-09-09 20:00:07 +080032#define CLK_PARENT_XTAL BIT(7)
33#define CLK_PARENT_MASK GENMASK(7, 4)
Ryder Lee0bd7dc72018-11-15 10:07:54 +080034
Ryder Lee2d88b5a2019-07-29 22:17:48 +080035#define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34
Weijie Gao2dca3cc2018-12-20 16:12:52 +080036
Ryder Lee0bd7dc72018-11-15 10:07:54 +080037/* struct mtk_pll_data - hardware-specific PLLs data */
38struct mtk_pll_data {
39 const int id;
40 u32 reg;
41 u32 pwr_reg;
42 u32 en_mask;
43 u32 pd_reg;
44 int pd_shift;
45 u32 flags;
46 u32 rst_bar_mask;
47 u64 fmax;
mingming lee0670adb2019-12-31 11:29:22 +080048 u64 fmin;
Ryder Lee0bd7dc72018-11-15 10:07:54 +080049 int pcwbits;
mingming lee0670adb2019-12-31 11:29:22 +080050 int pcwibits;
Ryder Lee0bd7dc72018-11-15 10:07:54 +080051 u32 pcw_reg;
52 int pcw_shift;
mingming lee0670adb2019-12-31 11:29:22 +080053 u32 pcw_chg_reg;
Ryder Lee0bd7dc72018-11-15 10:07:54 +080054};
55
56/**
57 * struct mtk_fixed_clk - fixed clocks
58 *
59 * @id: index of clocks
60 * @parent: index of parnet clocks
61 * @rate: fixed rate
62 */
63struct mtk_fixed_clk {
64 const int id;
65 const int parent;
66 unsigned long rate;
67};
68
69#define FIXED_CLK(_id, _parent, _rate) { \
70 .id = _id, \
71 .parent = _parent, \
72 .rate = _rate, \
73 }
74
75/**
76 * struct mtk_fixed_factor - fixed multiplier and divider clocks
77 *
78 * @id: index of clocks
79 * @parent: index of parnet clocks
80 * @mult: multiplier
81 * @div: divider
82 * @flag: hardware-specific flags
83 */
84struct mtk_fixed_factor {
85 const int id;
86 const int parent;
87 u32 mult;
88 u32 div;
89 u32 flags;
90};
91
92#define FACTOR(_id, _parent, _mult, _div, _flags) { \
93 .id = _id, \
94 .parent = _parent, \
95 .mult = _mult, \
96 .div = _div, \
97 .flags = _flags, \
98 }
99
100/**
101 * struct mtk_composite - aggregate clock of mux, divider and gate clocks
102 *
103 * @id: index of clocks
104 * @parent: index of parnet clocks
105 * @mux_reg: hardware-specific mux register
106 * @gate_reg: hardware-specific gate register
107 * @mux_mask: mask to the mux bit field
108 * @mux_shift: shift to the mux bit field
109 * @gate_shift: shift to the gate bit field
110 * @num_parents: number of parent clocks
111 * @flags: hardware-specific flags
112 */
113struct mtk_composite {
114 const int id;
115 const int *parent;
116 u32 mux_reg;
mingming leef62168d2019-12-31 11:29:21 +0800117 u32 mux_set_reg;
118 u32 mux_clr_reg;
119 u32 upd_reg;
Ryder Lee0bd7dc72018-11-15 10:07:54 +0800120 u32 gate_reg;
121 u32 mux_mask;
122 signed char mux_shift;
mingming leef62168d2019-12-31 11:29:21 +0800123 signed char upd_shift;
Ryder Lee0bd7dc72018-11-15 10:07:54 +0800124 signed char gate_shift;
125 signed char num_parents;
126 u16 flags;
127};
128
129#define MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, \
130 _flags) { \
131 .id = _id, \
132 .mux_reg = _reg, \
133 .mux_shift = _shift, \
134 .mux_mask = BIT(_width) - 1, \
135 .gate_reg = _reg, \
136 .gate_shift = _gate, \
137 .parent = _parents, \
138 .num_parents = ARRAY_SIZE(_parents), \
139 .flags = _flags, \
140 }
141
142#define MUX_GATE(_id, _parents, _reg, _shift, _width, _gate) \
143 MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, 0)
144
145#define MUX(_id, _parents, _reg, _shift, _width) { \
146 .id = _id, \
147 .mux_reg = _reg, \
148 .mux_shift = _shift, \
149 .mux_mask = BIT(_width) - 1, \
150 .gate_shift = -1, \
151 .parent = _parents, \
152 .num_parents = ARRAY_SIZE(_parents), \
153 .flags = 0, \
154 }
155
mingming leef62168d2019-12-31 11:29:21 +0800156#define MUX_CLR_SET_UPD_FLAGS(_id, _parents, _mux_ofs, _mux_set_ofs,\
157 _mux_clr_ofs, _shift, _width, _gate, \
158 _upd_ofs, _upd, _flags) { \
159 .id = _id, \
160 .mux_reg = _mux_ofs, \
161 .mux_set_reg = _mux_set_ofs, \
162 .mux_clr_reg = _mux_clr_ofs, \
163 .upd_reg = _upd_ofs, \
164 .upd_shift = _upd, \
165 .mux_shift = _shift, \
166 .mux_mask = BIT(_width) - 1, \
167 .gate_reg = _mux_ofs, \
168 .gate_shift = _gate, \
169 .parent = _parents, \
170 .num_parents = ARRAY_SIZE(_parents), \
171 .flags = _flags, \
172 }
173
Ryder Lee0bd7dc72018-11-15 10:07:54 +0800174struct mtk_gate_regs {
175 u32 sta_ofs;
176 u32 clr_ofs;
177 u32 set_ofs;
178};
179
180/**
181 * struct mtk_gate - gate clocks
182 *
183 * @id: index of gate clocks
184 * @parent: index of parnet clocks
185 * @regs: hardware-specific mux register
186 * @shift: shift to the gate bit field
187 * @flags: hardware-specific flags
188 */
189struct mtk_gate {
190 const int id;
191 const int parent;
192 const struct mtk_gate_regs *regs;
193 int shift;
194 u32 flags;
195};
196
197/* struct mtk_clk_tree - clock tree */
198struct mtk_clk_tree {
199 unsigned long xtal_rate;
200 unsigned long xtal2_rate;
201 const int fdivs_offs;
202 const int muxes_offs;
203 const struct mtk_pll_data *plls;
204 const struct mtk_fixed_clk *fclks;
205 const struct mtk_fixed_factor *fdivs;
206 const struct mtk_composite *muxes;
Weijie Gao7fb33e92022-09-09 19:59:59 +0800207 u32 flags;
Ryder Lee0bd7dc72018-11-15 10:07:54 +0800208};
209
210struct mtk_clk_priv {
Weijie Gao98a8bbb2022-09-09 20:00:01 +0800211 struct udevice *parent;
Ryder Lee0bd7dc72018-11-15 10:07:54 +0800212 void __iomem *base;
213 const struct mtk_clk_tree *tree;
214};
215
216struct mtk_cg_priv {
Weijie Gao98a8bbb2022-09-09 20:00:01 +0800217 struct udevice *parent;
Ryder Lee0bd7dc72018-11-15 10:07:54 +0800218 void __iomem *base;
219 const struct mtk_clk_tree *tree;
220 const struct mtk_gate *gates;
221};
222
223extern const struct clk_ops mtk_clk_apmixedsys_ops;
224extern const struct clk_ops mtk_clk_topckgen_ops;
Weijie Gao570b0842022-09-09 20:00:04 +0800225extern const struct clk_ops mtk_clk_infrasys_ops;
Ryder Lee0bd7dc72018-11-15 10:07:54 +0800226extern const struct clk_ops mtk_clk_gate_ops;
227
228int mtk_common_clk_init(struct udevice *dev,
229 const struct mtk_clk_tree *tree);
230int mtk_common_clk_gate_init(struct udevice *dev,
231 const struct mtk_clk_tree *tree,
232 const struct mtk_gate *gates);
233
234#endif /* __DRV_CLK_MTK_H */