1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #ifndef __TEGRA_CLK_H
7*4882a593Smuzhiyun #define __TEGRA_CLK_H
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <linux/clk-provider.h>
10*4882a593Smuzhiyun #include <linux/clkdev.h>
11*4882a593Smuzhiyun #include <linux/delay.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #define CLK_OUT_ENB_L 0x010
14*4882a593Smuzhiyun #define CLK_OUT_ENB_H 0x014
15*4882a593Smuzhiyun #define CLK_OUT_ENB_U 0x018
16*4882a593Smuzhiyun #define CLK_OUT_ENB_V 0x360
17*4882a593Smuzhiyun #define CLK_OUT_ENB_W 0x364
18*4882a593Smuzhiyun #define CLK_OUT_ENB_X 0x280
19*4882a593Smuzhiyun #define CLK_OUT_ENB_Y 0x298
20*4882a593Smuzhiyun #define CLK_ENB_PLLP_OUT_CPU BIT(31)
21*4882a593Smuzhiyun #define CLK_OUT_ENB_SET_L 0x320
22*4882a593Smuzhiyun #define CLK_OUT_ENB_CLR_L 0x324
23*4882a593Smuzhiyun #define CLK_OUT_ENB_SET_H 0x328
24*4882a593Smuzhiyun #define CLK_OUT_ENB_CLR_H 0x32c
25*4882a593Smuzhiyun #define CLK_OUT_ENB_SET_U 0x330
26*4882a593Smuzhiyun #define CLK_OUT_ENB_CLR_U 0x334
27*4882a593Smuzhiyun #define CLK_OUT_ENB_SET_V 0x440
28*4882a593Smuzhiyun #define CLK_OUT_ENB_CLR_V 0x444
29*4882a593Smuzhiyun #define CLK_OUT_ENB_SET_W 0x448
30*4882a593Smuzhiyun #define CLK_OUT_ENB_CLR_W 0x44c
31*4882a593Smuzhiyun #define CLK_OUT_ENB_SET_X 0x284
32*4882a593Smuzhiyun #define CLK_OUT_ENB_CLR_X 0x288
33*4882a593Smuzhiyun #define CLK_OUT_ENB_SET_Y 0x29c
34*4882a593Smuzhiyun #define CLK_OUT_ENB_CLR_Y 0x2a0
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #define RST_DEVICES_L 0x004
37*4882a593Smuzhiyun #define RST_DEVICES_H 0x008
38*4882a593Smuzhiyun #define RST_DEVICES_U 0x00C
39*4882a593Smuzhiyun #define RST_DEVICES_V 0x358
40*4882a593Smuzhiyun #define RST_DEVICES_W 0x35C
41*4882a593Smuzhiyun #define RST_DEVICES_X 0x28C
42*4882a593Smuzhiyun #define RST_DEVICES_Y 0x2a4
43*4882a593Smuzhiyun #define RST_DEVICES_SET_L 0x300
44*4882a593Smuzhiyun #define RST_DEVICES_CLR_L 0x304
45*4882a593Smuzhiyun #define RST_DEVICES_SET_H 0x308
46*4882a593Smuzhiyun #define RST_DEVICES_CLR_H 0x30c
47*4882a593Smuzhiyun #define RST_DEVICES_SET_U 0x310
48*4882a593Smuzhiyun #define RST_DEVICES_CLR_U 0x314
49*4882a593Smuzhiyun #define RST_DEVICES_SET_V 0x430
50*4882a593Smuzhiyun #define RST_DEVICES_CLR_V 0x434
51*4882a593Smuzhiyun #define RST_DEVICES_SET_W 0x438
52*4882a593Smuzhiyun #define RST_DEVICES_CLR_W 0x43c
53*4882a593Smuzhiyun #define RST_DEVICES_SET_X 0x290
54*4882a593Smuzhiyun #define RST_DEVICES_CLR_X 0x294
55*4882a593Smuzhiyun #define RST_DEVICES_SET_Y 0x2a8
56*4882a593Smuzhiyun #define RST_DEVICES_CLR_Y 0x2ac
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun /*
59*4882a593Smuzhiyun * Tegra CLK_OUT_ENB registers have some undefined bits which are not used and
60*4882a593Smuzhiyun * any accidental write of 1 to these bits can cause PSLVERR.
61*4882a593Smuzhiyun * So below are the valid mask defines for each CLK_OUT_ENB register used to
62*4882a593Smuzhiyun * turn ON only the valid clocks.
63*4882a593Smuzhiyun */
64*4882a593Smuzhiyun #define TEGRA210_CLK_ENB_VLD_MSK_L 0xdcd7dff9
65*4882a593Smuzhiyun #define TEGRA210_CLK_ENB_VLD_MSK_H 0x87d1f3e7
66*4882a593Smuzhiyun #define TEGRA210_CLK_ENB_VLD_MSK_U 0xf3fed3fa
67*4882a593Smuzhiyun #define TEGRA210_CLK_ENB_VLD_MSK_V 0xffc18cfb
68*4882a593Smuzhiyun #define TEGRA210_CLK_ENB_VLD_MSK_W 0x793fb7ff
69*4882a593Smuzhiyun #define TEGRA210_CLK_ENB_VLD_MSK_X 0x3fe66fff
70*4882a593Smuzhiyun #define TEGRA210_CLK_ENB_VLD_MSK_Y 0xfc1fc7ff
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /**
73*4882a593Smuzhiyun * struct tegra_clk_sync_source - external clock source from codec
74*4882a593Smuzhiyun *
75*4882a593Smuzhiyun * @hw: handle between common and hardware-specific interfaces
76*4882a593Smuzhiyun * @rate: input frequency from source
77*4882a593Smuzhiyun * @max_rate: max rate allowed
78*4882a593Smuzhiyun */
79*4882a593Smuzhiyun struct tegra_clk_sync_source {
80*4882a593Smuzhiyun struct clk_hw hw;
81*4882a593Smuzhiyun unsigned long rate;
82*4882a593Smuzhiyun unsigned long max_rate;
83*4882a593Smuzhiyun };
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun #define to_clk_sync_source(_hw) \
86*4882a593Smuzhiyun container_of(_hw, struct tegra_clk_sync_source, hw)
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun extern const struct clk_ops tegra_clk_sync_source_ops;
89*4882a593Smuzhiyun extern int *periph_clk_enb_refcnt;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun struct clk *tegra_clk_register_sync_source(const char *name,
92*4882a593Smuzhiyun unsigned long max_rate);
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun /**
95*4882a593Smuzhiyun * struct tegra_clk_frac_div - fractional divider clock
96*4882a593Smuzhiyun *
97*4882a593Smuzhiyun * @hw: handle between common and hardware-specific interfaces
98*4882a593Smuzhiyun * @reg: register containing divider
99*4882a593Smuzhiyun * @flags: hardware-specific flags
100*4882a593Smuzhiyun * @shift: shift to the divider bit field
101*4882a593Smuzhiyun * @width: width of the divider bit field
102*4882a593Smuzhiyun * @frac_width: width of the fractional bit field
103*4882a593Smuzhiyun * @lock: register lock
104*4882a593Smuzhiyun *
105*4882a593Smuzhiyun * Flags:
106*4882a593Smuzhiyun * TEGRA_DIVIDER_ROUND_UP - This flags indicates to round up the divider value.
107*4882a593Smuzhiyun * TEGRA_DIVIDER_FIXED - Fixed rate PLL dividers has addition override bit, this
108*4882a593Smuzhiyun * flag indicates that this divider is for fixed rate PLL.
109*4882a593Smuzhiyun * TEGRA_DIVIDER_INT - Some modules can not cope with the duty cycle when
110*4882a593Smuzhiyun * fraction bit is set. This flags indicates to calculate divider for which
111*4882a593Smuzhiyun * fracton bit will be zero.
112*4882a593Smuzhiyun * TEGRA_DIVIDER_UART - UART module divider has additional enable bit which is
113*4882a593Smuzhiyun * set when divider value is not 0. This flags indicates that the divider
114*4882a593Smuzhiyun * is for UART module.
115*4882a593Smuzhiyun */
116*4882a593Smuzhiyun struct tegra_clk_frac_div {
117*4882a593Smuzhiyun struct clk_hw hw;
118*4882a593Smuzhiyun void __iomem *reg;
119*4882a593Smuzhiyun u8 flags;
120*4882a593Smuzhiyun u8 shift;
121*4882a593Smuzhiyun u8 width;
122*4882a593Smuzhiyun u8 frac_width;
123*4882a593Smuzhiyun spinlock_t *lock;
124*4882a593Smuzhiyun };
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun #define to_clk_frac_div(_hw) container_of(_hw, struct tegra_clk_frac_div, hw)
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun #define TEGRA_DIVIDER_ROUND_UP BIT(0)
129*4882a593Smuzhiyun #define TEGRA_DIVIDER_FIXED BIT(1)
130*4882a593Smuzhiyun #define TEGRA_DIVIDER_INT BIT(2)
131*4882a593Smuzhiyun #define TEGRA_DIVIDER_UART BIT(3)
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun extern const struct clk_ops tegra_clk_frac_div_ops;
134*4882a593Smuzhiyun struct clk *tegra_clk_register_divider(const char *name,
135*4882a593Smuzhiyun const char *parent_name, void __iomem *reg,
136*4882a593Smuzhiyun unsigned long flags, u8 clk_divider_flags, u8 shift, u8 width,
137*4882a593Smuzhiyun u8 frac_width, spinlock_t *lock);
138*4882a593Smuzhiyun struct clk *tegra_clk_register_mc(const char *name, const char *parent_name,
139*4882a593Smuzhiyun void __iomem *reg, spinlock_t *lock);
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun /*
142*4882a593Smuzhiyun * Tegra PLL:
143*4882a593Smuzhiyun *
144*4882a593Smuzhiyun * In general, there are 3 requirements for each PLL
145*4882a593Smuzhiyun * that SW needs to be comply with.
146*4882a593Smuzhiyun * (1) Input frequency range (REF).
147*4882a593Smuzhiyun * (2) Comparison frequency range (CF). CF = REF/DIVM.
148*4882a593Smuzhiyun * (3) VCO frequency range (VCO). VCO = CF * DIVN.
149*4882a593Smuzhiyun *
150*4882a593Smuzhiyun * The final PLL output frequency (FO) = VCO >> DIVP.
151*4882a593Smuzhiyun */
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun /**
154*4882a593Smuzhiyun * struct tegra_clk_pll_freq_table - PLL frequecy table
155*4882a593Smuzhiyun *
156*4882a593Smuzhiyun * @input_rate: input rate from source
157*4882a593Smuzhiyun * @output_rate: output rate from PLL for the input rate
158*4882a593Smuzhiyun * @n: feedback divider
159*4882a593Smuzhiyun * @m: input divider
160*4882a593Smuzhiyun * @p: post divider
161*4882a593Smuzhiyun * @cpcon: charge pump current
162*4882a593Smuzhiyun * @sdm_data: fraction divider setting (0 = disabled)
163*4882a593Smuzhiyun */
164*4882a593Smuzhiyun struct tegra_clk_pll_freq_table {
165*4882a593Smuzhiyun unsigned long input_rate;
166*4882a593Smuzhiyun unsigned long output_rate;
167*4882a593Smuzhiyun u32 n;
168*4882a593Smuzhiyun u32 m;
169*4882a593Smuzhiyun u8 p;
170*4882a593Smuzhiyun u8 cpcon;
171*4882a593Smuzhiyun u16 sdm_data;
172*4882a593Smuzhiyun };
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun /**
175*4882a593Smuzhiyun * struct pdiv_map - map post divider to hw value
176*4882a593Smuzhiyun *
177*4882a593Smuzhiyun * @pdiv: post divider
178*4882a593Smuzhiyun * @hw_val: value to be written to the PLL hw
179*4882a593Smuzhiyun */
180*4882a593Smuzhiyun struct pdiv_map {
181*4882a593Smuzhiyun u8 pdiv;
182*4882a593Smuzhiyun u8 hw_val;
183*4882a593Smuzhiyun };
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun /**
186*4882a593Smuzhiyun * struct div_nmp - offset and width of m,n and p fields
187*4882a593Smuzhiyun *
188*4882a593Smuzhiyun * @divn_shift: shift to the feedback divider bit field
189*4882a593Smuzhiyun * @divn_width: width of the feedback divider bit field
190*4882a593Smuzhiyun * @divm_shift: shift to the input divider bit field
191*4882a593Smuzhiyun * @divm_width: width of the input divider bit field
192*4882a593Smuzhiyun * @divp_shift: shift to the post divider bit field
193*4882a593Smuzhiyun * @divp_width: width of the post divider bit field
194*4882a593Smuzhiyun * @override_divn_shift: shift to the feedback divider bitfield in override reg
195*4882a593Smuzhiyun * @override_divm_shift: shift to the input divider bitfield in override reg
196*4882a593Smuzhiyun * @override_divp_shift: shift to the post divider bitfield in override reg
197*4882a593Smuzhiyun */
198*4882a593Smuzhiyun struct div_nmp {
199*4882a593Smuzhiyun u8 divn_shift;
200*4882a593Smuzhiyun u8 divn_width;
201*4882a593Smuzhiyun u8 divm_shift;
202*4882a593Smuzhiyun u8 divm_width;
203*4882a593Smuzhiyun u8 divp_shift;
204*4882a593Smuzhiyun u8 divp_width;
205*4882a593Smuzhiyun u8 override_divn_shift;
206*4882a593Smuzhiyun u8 override_divm_shift;
207*4882a593Smuzhiyun u8 override_divp_shift;
208*4882a593Smuzhiyun };
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun #define MAX_PLL_MISC_REG_COUNT 6
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun struct tegra_clk_pll;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun /**
215*4882a593Smuzhiyun * struct tegra_clk_pll_params - PLL parameters
216*4882a593Smuzhiyun *
217*4882a593Smuzhiyun * @input_min: Minimum input frequency
218*4882a593Smuzhiyun * @input_max: Maximum input frequency
219*4882a593Smuzhiyun * @cf_min: Minimum comparison frequency
220*4882a593Smuzhiyun * @cf_max: Maximum comparison frequency
221*4882a593Smuzhiyun * @vco_min: Minimum VCO frequency
222*4882a593Smuzhiyun * @vco_max: Maximum VCO frequency
223*4882a593Smuzhiyun * @base_reg: PLL base reg offset
224*4882a593Smuzhiyun * @misc_reg: PLL misc reg offset
225*4882a593Smuzhiyun * @lock_reg: PLL lock reg offset
226*4882a593Smuzhiyun * @lock_mask: Bitmask for PLL lock status
227*4882a593Smuzhiyun * @lock_enable_bit_idx: Bit index to enable PLL lock
228*4882a593Smuzhiyun * @iddq_reg: PLL IDDQ register offset
229*4882a593Smuzhiyun * @iddq_bit_idx: Bit index to enable PLL IDDQ
230*4882a593Smuzhiyun * @reset_reg: Register offset of where RESET bit is
231*4882a593Smuzhiyun * @reset_bit_idx: Shift of reset bit in reset_reg
232*4882a593Smuzhiyun * @sdm_din_reg: Register offset where SDM settings are
233*4882a593Smuzhiyun * @sdm_din_mask: Mask of SDM divider bits
234*4882a593Smuzhiyun * @sdm_ctrl_reg: Register offset where SDM enable is
235*4882a593Smuzhiyun * @sdm_ctrl_en_mask: Mask of SDM enable bit
236*4882a593Smuzhiyun * @ssc_ctrl_reg: Register offset where SSC settings are
237*4882a593Smuzhiyun * @ssc_ctrl_en_mask: Mask of SSC enable bit
238*4882a593Smuzhiyun * @aux_reg: AUX register offset
239*4882a593Smuzhiyun * @dyn_ramp_reg: Dynamic ramp control register offset
240*4882a593Smuzhiyun * @ext_misc_reg: Miscellaneous control register offsets
241*4882a593Smuzhiyun * @pmc_divnm_reg: n, m divider PMC override register offset (PLLM)
242*4882a593Smuzhiyun * @pmc_divp_reg: p divider PMC override register offset (PLLM)
243*4882a593Smuzhiyun * @flags: PLL flags
244*4882a593Smuzhiyun * @stepa_shift: Dynamic ramp step A field shift
245*4882a593Smuzhiyun * @stepb_shift: Dynamic ramp step B field shift
246*4882a593Smuzhiyun * @lock_delay: Delay in us if PLL lock is not used
247*4882a593Smuzhiyun * @max_p: maximum value for the p divider
248*4882a593Smuzhiyun * @defaults_set: Boolean signaling all reg defaults for PLL set.
249*4882a593Smuzhiyun * @pdiv_tohw: mapping of p divider to register values
250*4882a593Smuzhiyun * @div_nmp: offsets and widths on n, m and p fields
251*4882a593Smuzhiyun * @freq_table: array of frequencies supported by PLL
252*4882a593Smuzhiyun * @fixed_rate: PLL rate if it is fixed
253*4882a593Smuzhiyun * @mdiv_default: Default value for fixed mdiv for this PLL
254*4882a593Smuzhiyun * @round_p_to_pdiv: Callback used to round p to the closed pdiv
255*4882a593Smuzhiyun * @set_gain: Callback to adjust N div for SDM enabled
256*4882a593Smuzhiyun * PLL's based on fractional divider value.
257*4882a593Smuzhiyun * @calc_rate: Callback used to change how out of table
258*4882a593Smuzhiyun * rates (dividers and multipler) are calculated.
259*4882a593Smuzhiyun * @adjust_vco: Callback to adjust the programming range of the
260*4882a593Smuzhiyun * divider range (if SDM is present)
261*4882a593Smuzhiyun * @set_defaults: Callback which will try to initialize PLL
262*4882a593Smuzhiyun * registers to sane default values. This is first
263*4882a593Smuzhiyun * tried during PLL registration, but if the PLL
264*4882a593Smuzhiyun * is already enabled, it will be done the first
265*4882a593Smuzhiyun * time the rate is changed while the PLL is
266*4882a593Smuzhiyun * disabled.
267*4882a593Smuzhiyun * @dyn_ramp: Callback which can be used to define a custom
268*4882a593Smuzhiyun * dynamic ramp function for a given PLL.
269*4882a593Smuzhiyun * @pre_rate_change: Callback which is invoked just before changing
270*4882a593Smuzhiyun * PLL's rate.
271*4882a593Smuzhiyun * @post_rate_change: Callback which is invoked right after changing
272*4882a593Smuzhiyun * PLL's rate.
273*4882a593Smuzhiyun *
274*4882a593Smuzhiyun * Flags:
275*4882a593Smuzhiyun * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for
276*4882a593Smuzhiyun * PLL locking. If not set it will use lock_delay value to wait.
277*4882a593Smuzhiyun * TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs
278*4882a593Smuzhiyun * to be programmed to change output frequency of the PLL.
279*4882a593Smuzhiyun * TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs
280*4882a593Smuzhiyun * to be programmed to change output frequency of the PLL.
281*4882a593Smuzhiyun * TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs
282*4882a593Smuzhiyun * to be programmed to change output frequency of the PLL.
283*4882a593Smuzhiyun * TEGRA_PLLU - PLLU has inverted post divider. This flags indicated
284*4882a593Smuzhiyun * that it is PLLU and invert post divider value.
285*4882a593Smuzhiyun * TEGRA_PLLM - PLLM has additional override settings in PMC. This
286*4882a593Smuzhiyun * flag indicates that it is PLLM and use override settings.
287*4882a593Smuzhiyun * TEGRA_PLL_FIXED - We are not supposed to change output frequency
288*4882a593Smuzhiyun * of some plls.
289*4882a593Smuzhiyun * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
290*4882a593Smuzhiyun * TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the
291*4882a593Smuzhiyun * base register.
292*4882a593Smuzhiyun * TEGRA_PLL_BYPASS - PLL has bypass bit
293*4882a593Smuzhiyun * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
294*4882a593Smuzhiyun * TEGRA_MDIV_NEW - Switch to new method for calculating fixed mdiv
295*4882a593Smuzhiyun * it may be more accurate (especially if SDM present)
296*4882a593Smuzhiyun * TEGRA_PLLMB - PLLMB has should be treated similar to PLLM. This
297*4882a593Smuzhiyun * flag indicated that it is PLLMB.
298*4882a593Smuzhiyun * TEGRA_PLL_VCO_OUT - Used to indicate that the PLL has a VCO output
299*4882a593Smuzhiyun */
300*4882a593Smuzhiyun struct tegra_clk_pll_params {
301*4882a593Smuzhiyun unsigned long input_min;
302*4882a593Smuzhiyun unsigned long input_max;
303*4882a593Smuzhiyun unsigned long cf_min;
304*4882a593Smuzhiyun unsigned long cf_max;
305*4882a593Smuzhiyun unsigned long vco_min;
306*4882a593Smuzhiyun unsigned long vco_max;
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun u32 base_reg;
309*4882a593Smuzhiyun u32 misc_reg;
310*4882a593Smuzhiyun u32 lock_reg;
311*4882a593Smuzhiyun u32 lock_mask;
312*4882a593Smuzhiyun u32 lock_enable_bit_idx;
313*4882a593Smuzhiyun u32 iddq_reg;
314*4882a593Smuzhiyun u32 iddq_bit_idx;
315*4882a593Smuzhiyun u32 reset_reg;
316*4882a593Smuzhiyun u32 reset_bit_idx;
317*4882a593Smuzhiyun u32 sdm_din_reg;
318*4882a593Smuzhiyun u32 sdm_din_mask;
319*4882a593Smuzhiyun u32 sdm_ctrl_reg;
320*4882a593Smuzhiyun u32 sdm_ctrl_en_mask;
321*4882a593Smuzhiyun u32 ssc_ctrl_reg;
322*4882a593Smuzhiyun u32 ssc_ctrl_en_mask;
323*4882a593Smuzhiyun u32 aux_reg;
324*4882a593Smuzhiyun u32 dyn_ramp_reg;
325*4882a593Smuzhiyun u32 ext_misc_reg[MAX_PLL_MISC_REG_COUNT];
326*4882a593Smuzhiyun u32 pmc_divnm_reg;
327*4882a593Smuzhiyun u32 pmc_divp_reg;
328*4882a593Smuzhiyun u32 flags;
329*4882a593Smuzhiyun int stepa_shift;
330*4882a593Smuzhiyun int stepb_shift;
331*4882a593Smuzhiyun int lock_delay;
332*4882a593Smuzhiyun int max_p;
333*4882a593Smuzhiyun bool defaults_set;
334*4882a593Smuzhiyun const struct pdiv_map *pdiv_tohw;
335*4882a593Smuzhiyun struct div_nmp *div_nmp;
336*4882a593Smuzhiyun struct tegra_clk_pll_freq_table *freq_table;
337*4882a593Smuzhiyun unsigned long fixed_rate;
338*4882a593Smuzhiyun u16 mdiv_default;
339*4882a593Smuzhiyun u32 (*round_p_to_pdiv)(u32 p, u32 *pdiv);
340*4882a593Smuzhiyun void (*set_gain)(struct tegra_clk_pll_freq_table *cfg);
341*4882a593Smuzhiyun int (*calc_rate)(struct clk_hw *hw,
342*4882a593Smuzhiyun struct tegra_clk_pll_freq_table *cfg,
343*4882a593Smuzhiyun unsigned long rate, unsigned long parent_rate);
344*4882a593Smuzhiyun unsigned long (*adjust_vco)(struct tegra_clk_pll_params *pll_params,
345*4882a593Smuzhiyun unsigned long parent_rate);
346*4882a593Smuzhiyun void (*set_defaults)(struct tegra_clk_pll *pll);
347*4882a593Smuzhiyun int (*dyn_ramp)(struct tegra_clk_pll *pll,
348*4882a593Smuzhiyun struct tegra_clk_pll_freq_table *cfg);
349*4882a593Smuzhiyun int (*pre_rate_change)(void);
350*4882a593Smuzhiyun void (*post_rate_change)(void);
351*4882a593Smuzhiyun };
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun #define TEGRA_PLL_USE_LOCK BIT(0)
354*4882a593Smuzhiyun #define TEGRA_PLL_HAS_CPCON BIT(1)
355*4882a593Smuzhiyun #define TEGRA_PLL_SET_LFCON BIT(2)
356*4882a593Smuzhiyun #define TEGRA_PLL_SET_DCCON BIT(3)
357*4882a593Smuzhiyun #define TEGRA_PLLU BIT(4)
358*4882a593Smuzhiyun #define TEGRA_PLLM BIT(5)
359*4882a593Smuzhiyun #define TEGRA_PLL_FIXED BIT(6)
360*4882a593Smuzhiyun #define TEGRA_PLLE_CONFIGURE BIT(7)
361*4882a593Smuzhiyun #define TEGRA_PLL_LOCK_MISC BIT(8)
362*4882a593Smuzhiyun #define TEGRA_PLL_BYPASS BIT(9)
363*4882a593Smuzhiyun #define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
364*4882a593Smuzhiyun #define TEGRA_MDIV_NEW BIT(11)
365*4882a593Smuzhiyun #define TEGRA_PLLMB BIT(12)
366*4882a593Smuzhiyun #define TEGRA_PLL_VCO_OUT BIT(13)
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun /**
369*4882a593Smuzhiyun * struct tegra_clk_pll - Tegra PLL clock
370*4882a593Smuzhiyun *
371*4882a593Smuzhiyun * @hw: handle between common and hardware-specifix interfaces
372*4882a593Smuzhiyun * @clk_base: address of CAR controller
373*4882a593Smuzhiyun * @pmc: address of PMC, required to read override bits
374*4882a593Smuzhiyun * @lock: register lock
375*4882a593Smuzhiyun * @params: PLL parameters
376*4882a593Smuzhiyun */
377*4882a593Smuzhiyun struct tegra_clk_pll {
378*4882a593Smuzhiyun struct clk_hw hw;
379*4882a593Smuzhiyun void __iomem *clk_base;
380*4882a593Smuzhiyun void __iomem *pmc;
381*4882a593Smuzhiyun spinlock_t *lock;
382*4882a593Smuzhiyun struct tegra_clk_pll_params *params;
383*4882a593Smuzhiyun };
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun #define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun /**
388*4882a593Smuzhiyun * struct tegra_audio_clk_info - Tegra Audio Clk Information
389*4882a593Smuzhiyun *
390*4882a593Smuzhiyun * @name: name for the audio pll
391*4882a593Smuzhiyun * @pll_params: pll_params for audio pll
392*4882a593Smuzhiyun * @clk_id: clk_ids for the audio pll
393*4882a593Smuzhiyun * @parent: name of the parent of the audio pll
394*4882a593Smuzhiyun */
395*4882a593Smuzhiyun struct tegra_audio_clk_info {
396*4882a593Smuzhiyun char *name;
397*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params;
398*4882a593Smuzhiyun int clk_id;
399*4882a593Smuzhiyun char *parent;
400*4882a593Smuzhiyun };
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun extern const struct clk_ops tegra_clk_pll_ops;
403*4882a593Smuzhiyun extern const struct clk_ops tegra_clk_plle_ops;
404*4882a593Smuzhiyun struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
405*4882a593Smuzhiyun void __iomem *clk_base, void __iomem *pmc,
406*4882a593Smuzhiyun unsigned long flags, struct tegra_clk_pll_params *pll_params,
407*4882a593Smuzhiyun spinlock_t *lock);
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
410*4882a593Smuzhiyun void __iomem *clk_base, void __iomem *pmc,
411*4882a593Smuzhiyun unsigned long flags, struct tegra_clk_pll_params *pll_params,
412*4882a593Smuzhiyun spinlock_t *lock);
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
415*4882a593Smuzhiyun void __iomem *clk_base, void __iomem *pmc,
416*4882a593Smuzhiyun unsigned long flags,
417*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
418*4882a593Smuzhiyun spinlock_t *lock);
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
421*4882a593Smuzhiyun void __iomem *clk_base, void __iomem *pmc,
422*4882a593Smuzhiyun unsigned long flags,
423*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
424*4882a593Smuzhiyun spinlock_t *lock);
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
427*4882a593Smuzhiyun void __iomem *clk_base, void __iomem *pmc,
428*4882a593Smuzhiyun unsigned long flags,
429*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
430*4882a593Smuzhiyun spinlock_t *lock);
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
433*4882a593Smuzhiyun void __iomem *clk_base, void __iomem *pmc,
434*4882a593Smuzhiyun unsigned long flags,
435*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
436*4882a593Smuzhiyun spinlock_t *lock, unsigned long parent_rate);
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun struct clk *tegra_clk_register_pllre_tegra210(const char *name,
439*4882a593Smuzhiyun const char *parent_name, void __iomem *clk_base,
440*4882a593Smuzhiyun void __iomem *pmc, unsigned long flags,
441*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
442*4882a593Smuzhiyun spinlock_t *lock, unsigned long parent_rate);
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun struct clk *tegra_clk_register_plle_tegra114(const char *name,
445*4882a593Smuzhiyun const char *parent_name,
446*4882a593Smuzhiyun void __iomem *clk_base, unsigned long flags,
447*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
448*4882a593Smuzhiyun spinlock_t *lock);
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun struct clk *tegra_clk_register_plle_tegra210(const char *name,
451*4882a593Smuzhiyun const char *parent_name,
452*4882a593Smuzhiyun void __iomem *clk_base, unsigned long flags,
453*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
454*4882a593Smuzhiyun spinlock_t *lock);
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun struct clk *tegra_clk_register_pllc_tegra210(const char *name,
457*4882a593Smuzhiyun const char *parent_name, void __iomem *clk_base,
458*4882a593Smuzhiyun void __iomem *pmc, unsigned long flags,
459*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
460*4882a593Smuzhiyun spinlock_t *lock);
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun struct clk *tegra_clk_register_pllss_tegra210(const char *name,
463*4882a593Smuzhiyun const char *parent_name, void __iomem *clk_base,
464*4882a593Smuzhiyun unsigned long flags,
465*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
466*4882a593Smuzhiyun spinlock_t *lock);
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
469*4882a593Smuzhiyun void __iomem *clk_base, unsigned long flags,
470*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
471*4882a593Smuzhiyun spinlock_t *lock);
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun struct clk *tegra_clk_register_pllmb(const char *name, const char *parent_name,
474*4882a593Smuzhiyun void __iomem *clk_base, void __iomem *pmc,
475*4882a593Smuzhiyun unsigned long flags,
476*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
477*4882a593Smuzhiyun spinlock_t *lock);
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun struct clk *tegra_clk_register_pllu(const char *name, const char *parent_name,
480*4882a593Smuzhiyun void __iomem *clk_base, unsigned long flags,
481*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
482*4882a593Smuzhiyun spinlock_t *lock);
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun struct clk *tegra_clk_register_pllu_tegra114(const char *name,
485*4882a593Smuzhiyun const char *parent_name,
486*4882a593Smuzhiyun void __iomem *clk_base, unsigned long flags,
487*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
488*4882a593Smuzhiyun spinlock_t *lock);
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun struct clk *tegra_clk_register_pllu_tegra210(const char *name,
491*4882a593Smuzhiyun const char *parent_name,
492*4882a593Smuzhiyun void __iomem *clk_base, unsigned long flags,
493*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params,
494*4882a593Smuzhiyun spinlock_t *lock);
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun /**
497*4882a593Smuzhiyun * struct tegra_clk_pll_out - PLL divider down clock
498*4882a593Smuzhiyun *
499*4882a593Smuzhiyun * @hw: handle between common and hardware-specific interfaces
500*4882a593Smuzhiyun * @reg: register containing the PLL divider
501*4882a593Smuzhiyun * @enb_bit_idx: bit to enable/disable PLL divider
502*4882a593Smuzhiyun * @rst_bit_idx: bit to reset PLL divider
503*4882a593Smuzhiyun * @lock: register lock
504*4882a593Smuzhiyun * @flags: hardware-specific flags
505*4882a593Smuzhiyun */
506*4882a593Smuzhiyun struct tegra_clk_pll_out {
507*4882a593Smuzhiyun struct clk_hw hw;
508*4882a593Smuzhiyun void __iomem *reg;
509*4882a593Smuzhiyun u8 enb_bit_idx;
510*4882a593Smuzhiyun u8 rst_bit_idx;
511*4882a593Smuzhiyun spinlock_t *lock;
512*4882a593Smuzhiyun u8 flags;
513*4882a593Smuzhiyun };
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun #define to_clk_pll_out(_hw) container_of(_hw, struct tegra_clk_pll_out, hw)
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun extern const struct clk_ops tegra_clk_pll_out_ops;
518*4882a593Smuzhiyun struct clk *tegra_clk_register_pll_out(const char *name,
519*4882a593Smuzhiyun const char *parent_name, void __iomem *reg, u8 enb_bit_idx,
520*4882a593Smuzhiyun u8 rst_bit_idx, unsigned long flags, u8 pll_div_flags,
521*4882a593Smuzhiyun spinlock_t *lock);
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun /**
524*4882a593Smuzhiyun * struct tegra_clk_periph_regs - Registers controlling peripheral clock
525*4882a593Smuzhiyun *
526*4882a593Smuzhiyun * @enb_reg: read the enable status
527*4882a593Smuzhiyun * @enb_set_reg: write 1 to enable clock
528*4882a593Smuzhiyun * @enb_clr_reg: write 1 to disable clock
529*4882a593Smuzhiyun * @rst_reg: read the reset status
530*4882a593Smuzhiyun * @rst_set_reg: write 1 to assert the reset of peripheral
531*4882a593Smuzhiyun * @rst_clr_reg: write 1 to deassert the reset of peripheral
532*4882a593Smuzhiyun */
533*4882a593Smuzhiyun struct tegra_clk_periph_regs {
534*4882a593Smuzhiyun u32 enb_reg;
535*4882a593Smuzhiyun u32 enb_set_reg;
536*4882a593Smuzhiyun u32 enb_clr_reg;
537*4882a593Smuzhiyun u32 rst_reg;
538*4882a593Smuzhiyun u32 rst_set_reg;
539*4882a593Smuzhiyun u32 rst_clr_reg;
540*4882a593Smuzhiyun };
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun /**
543*4882a593Smuzhiyun * struct tegra_clk_periph_gate - peripheral gate clock
544*4882a593Smuzhiyun *
545*4882a593Smuzhiyun * @magic: magic number to validate type
546*4882a593Smuzhiyun * @hw: handle between common and hardware-specific interfaces
547*4882a593Smuzhiyun * @clk_base: address of CAR controller
548*4882a593Smuzhiyun * @regs: Registers to control the peripheral
549*4882a593Smuzhiyun * @flags: hardware-specific flags
550*4882a593Smuzhiyun * @clk_num: Clock number
551*4882a593Smuzhiyun * @enable_refcnt: array to maintain reference count of the clock
552*4882a593Smuzhiyun *
553*4882a593Smuzhiyun * Flags:
554*4882a593Smuzhiyun * TEGRA_PERIPH_NO_RESET - This flag indicates that reset is not allowed
555*4882a593Smuzhiyun * for this module.
556*4882a593Smuzhiyun * TEGRA_PERIPH_MANUAL_RESET - This flag indicates not to reset module
557*4882a593Smuzhiyun * after clock enable and driver for the module is responsible for
558*4882a593Smuzhiyun * doing reset.
559*4882a593Smuzhiyun * TEGRA_PERIPH_ON_APB - If peripheral is in the APB bus then read the
560*4882a593Smuzhiyun * bus to flush the write operation in apb bus. This flag indicates
561*4882a593Smuzhiyun * that this peripheral is in apb bus.
562*4882a593Smuzhiyun * TEGRA_PERIPH_WAR_1005168 - Apply workaround for Tegra114 MSENC bug
563*4882a593Smuzhiyun */
564*4882a593Smuzhiyun struct tegra_clk_periph_gate {
565*4882a593Smuzhiyun u32 magic;
566*4882a593Smuzhiyun struct clk_hw hw;
567*4882a593Smuzhiyun void __iomem *clk_base;
568*4882a593Smuzhiyun u8 flags;
569*4882a593Smuzhiyun int clk_num;
570*4882a593Smuzhiyun int *enable_refcnt;
571*4882a593Smuzhiyun const struct tegra_clk_periph_regs *regs;
572*4882a593Smuzhiyun };
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun #define to_clk_periph_gate(_hw) \
575*4882a593Smuzhiyun container_of(_hw, struct tegra_clk_periph_gate, hw)
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun #define TEGRA_CLK_PERIPH_GATE_MAGIC 0x17760309
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun #define TEGRA_PERIPH_NO_RESET BIT(0)
580*4882a593Smuzhiyun #define TEGRA_PERIPH_MANUAL_RESET BIT(1)
581*4882a593Smuzhiyun #define TEGRA_PERIPH_ON_APB BIT(2)
582*4882a593Smuzhiyun #define TEGRA_PERIPH_WAR_1005168 BIT(3)
583*4882a593Smuzhiyun #define TEGRA_PERIPH_NO_DIV BIT(4)
584*4882a593Smuzhiyun #define TEGRA_PERIPH_NO_GATE BIT(5)
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun extern const struct clk_ops tegra_clk_periph_gate_ops;
587*4882a593Smuzhiyun struct clk *tegra_clk_register_periph_gate(const char *name,
588*4882a593Smuzhiyun const char *parent_name, u8 gate_flags, void __iomem *clk_base,
589*4882a593Smuzhiyun unsigned long flags, int clk_num, int *enable_refcnt);
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun struct tegra_clk_periph_fixed {
592*4882a593Smuzhiyun struct clk_hw hw;
593*4882a593Smuzhiyun void __iomem *base;
594*4882a593Smuzhiyun const struct tegra_clk_periph_regs *regs;
595*4882a593Smuzhiyun unsigned int mul;
596*4882a593Smuzhiyun unsigned int div;
597*4882a593Smuzhiyun unsigned int num;
598*4882a593Smuzhiyun };
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun struct clk *tegra_clk_register_periph_fixed(const char *name,
601*4882a593Smuzhiyun const char *parent,
602*4882a593Smuzhiyun unsigned long flags,
603*4882a593Smuzhiyun void __iomem *base,
604*4882a593Smuzhiyun unsigned int mul,
605*4882a593Smuzhiyun unsigned int div,
606*4882a593Smuzhiyun unsigned int num);
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun /**
609*4882a593Smuzhiyun * struct clk-periph - peripheral clock
610*4882a593Smuzhiyun *
611*4882a593Smuzhiyun * @magic: magic number to validate type
612*4882a593Smuzhiyun * @hw: handle between common and hardware-specific interfaces
613*4882a593Smuzhiyun * @mux: mux clock
614*4882a593Smuzhiyun * @divider: divider clock
615*4882a593Smuzhiyun * @gate: gate clock
616*4882a593Smuzhiyun * @mux_ops: mux clock ops
617*4882a593Smuzhiyun * @div_ops: divider clock ops
618*4882a593Smuzhiyun * @gate_ops: gate clock ops
619*4882a593Smuzhiyun */
620*4882a593Smuzhiyun struct tegra_clk_periph {
621*4882a593Smuzhiyun u32 magic;
622*4882a593Smuzhiyun struct clk_hw hw;
623*4882a593Smuzhiyun struct clk_mux mux;
624*4882a593Smuzhiyun struct tegra_clk_frac_div divider;
625*4882a593Smuzhiyun struct tegra_clk_periph_gate gate;
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun const struct clk_ops *mux_ops;
628*4882a593Smuzhiyun const struct clk_ops *div_ops;
629*4882a593Smuzhiyun const struct clk_ops *gate_ops;
630*4882a593Smuzhiyun };
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun #define to_clk_periph(_hw) container_of(_hw, struct tegra_clk_periph, hw)
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun #define TEGRA_CLK_PERIPH_MAGIC 0x18221223
635*4882a593Smuzhiyun
636*4882a593Smuzhiyun extern const struct clk_ops tegra_clk_periph_ops;
637*4882a593Smuzhiyun struct clk *tegra_clk_register_periph(const char *name,
638*4882a593Smuzhiyun const char * const *parent_names, int num_parents,
639*4882a593Smuzhiyun struct tegra_clk_periph *periph, void __iomem *clk_base,
640*4882a593Smuzhiyun u32 offset, unsigned long flags);
641*4882a593Smuzhiyun struct clk *tegra_clk_register_periph_nodiv(const char *name,
642*4882a593Smuzhiyun const char * const *parent_names, int num_parents,
643*4882a593Smuzhiyun struct tegra_clk_periph *periph, void __iomem *clk_base,
644*4882a593Smuzhiyun u32 offset);
645*4882a593Smuzhiyun
646*4882a593Smuzhiyun #define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \
647*4882a593Smuzhiyun _div_shift, _div_width, _div_frac_width, \
648*4882a593Smuzhiyun _div_flags, _clk_num,\
649*4882a593Smuzhiyun _gate_flags, _table, _lock) \
650*4882a593Smuzhiyun { \
651*4882a593Smuzhiyun .mux = { \
652*4882a593Smuzhiyun .flags = _mux_flags, \
653*4882a593Smuzhiyun .shift = _mux_shift, \
654*4882a593Smuzhiyun .mask = _mux_mask, \
655*4882a593Smuzhiyun .table = _table, \
656*4882a593Smuzhiyun .lock = _lock, \
657*4882a593Smuzhiyun }, \
658*4882a593Smuzhiyun .divider = { \
659*4882a593Smuzhiyun .flags = _div_flags, \
660*4882a593Smuzhiyun .shift = _div_shift, \
661*4882a593Smuzhiyun .width = _div_width, \
662*4882a593Smuzhiyun .frac_width = _div_frac_width, \
663*4882a593Smuzhiyun .lock = _lock, \
664*4882a593Smuzhiyun }, \
665*4882a593Smuzhiyun .gate = { \
666*4882a593Smuzhiyun .flags = _gate_flags, \
667*4882a593Smuzhiyun .clk_num = _clk_num, \
668*4882a593Smuzhiyun }, \
669*4882a593Smuzhiyun .mux_ops = &clk_mux_ops, \
670*4882a593Smuzhiyun .div_ops = &tegra_clk_frac_div_ops, \
671*4882a593Smuzhiyun .gate_ops = &tegra_clk_periph_gate_ops, \
672*4882a593Smuzhiyun }
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun struct tegra_periph_init_data {
675*4882a593Smuzhiyun const char *name;
676*4882a593Smuzhiyun int clk_id;
677*4882a593Smuzhiyun union {
678*4882a593Smuzhiyun const char *const *parent_names;
679*4882a593Smuzhiyun const char *parent_name;
680*4882a593Smuzhiyun } p;
681*4882a593Smuzhiyun int num_parents;
682*4882a593Smuzhiyun struct tegra_clk_periph periph;
683*4882a593Smuzhiyun u32 offset;
684*4882a593Smuzhiyun const char *con_id;
685*4882a593Smuzhiyun const char *dev_id;
686*4882a593Smuzhiyun unsigned long flags;
687*4882a593Smuzhiyun };
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
690*4882a593Smuzhiyun _mux_shift, _mux_mask, _mux_flags, _div_shift, \
691*4882a593Smuzhiyun _div_width, _div_frac_width, _div_flags, \
692*4882a593Smuzhiyun _clk_num, _gate_flags, _clk_id, _table, \
693*4882a593Smuzhiyun _flags, _lock) \
694*4882a593Smuzhiyun { \
695*4882a593Smuzhiyun .name = _name, \
696*4882a593Smuzhiyun .clk_id = _clk_id, \
697*4882a593Smuzhiyun .p.parent_names = _parent_names, \
698*4882a593Smuzhiyun .num_parents = ARRAY_SIZE(_parent_names), \
699*4882a593Smuzhiyun .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, \
700*4882a593Smuzhiyun _mux_flags, _div_shift, \
701*4882a593Smuzhiyun _div_width, _div_frac_width, \
702*4882a593Smuzhiyun _div_flags, _clk_num, \
703*4882a593Smuzhiyun _gate_flags, _table, _lock), \
704*4882a593Smuzhiyun .offset = _offset, \
705*4882a593Smuzhiyun .con_id = _con_id, \
706*4882a593Smuzhiyun .dev_id = _dev_id, \
707*4882a593Smuzhiyun .flags = _flags \
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun
710*4882a593Smuzhiyun #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\
711*4882a593Smuzhiyun _mux_shift, _mux_width, _mux_flags, _div_shift, \
712*4882a593Smuzhiyun _div_width, _div_frac_width, _div_flags, \
713*4882a593Smuzhiyun _clk_num, _gate_flags, _clk_id) \
714*4882a593Smuzhiyun TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
715*4882a593Smuzhiyun _mux_shift, BIT(_mux_width) - 1, _mux_flags, \
716*4882a593Smuzhiyun _div_shift, _div_width, _div_frac_width, _div_flags, \
717*4882a593Smuzhiyun _clk_num, _gate_flags, _clk_id,\
718*4882a593Smuzhiyun NULL, 0, NULL)
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun struct clk *tegra_clk_register_periph_data(void __iomem *clk_base,
721*4882a593Smuzhiyun struct tegra_periph_init_data *init);
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun /**
724*4882a593Smuzhiyun * struct clk_super_mux - super clock
725*4882a593Smuzhiyun *
726*4882a593Smuzhiyun * @hw: handle between common and hardware-specific interfaces
727*4882a593Smuzhiyun * @reg: register controlling multiplexer
728*4882a593Smuzhiyun * @width: width of the multiplexer bit field
729*4882a593Smuzhiyun * @flags: hardware-specific flags
730*4882a593Smuzhiyun * @div2_index: bit controlling divide-by-2
731*4882a593Smuzhiyun * @pllx_index: PLLX index in the parent list
732*4882a593Smuzhiyun * @lock: register lock
733*4882a593Smuzhiyun *
734*4882a593Smuzhiyun * Flags:
735*4882a593Smuzhiyun * TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates
736*4882a593Smuzhiyun * that this is LP cluster clock.
737*4882a593Smuzhiyun * TEGRA210_CPU_CLK - This flag is used to identify CPU cluster for gen5
738*4882a593Smuzhiyun * super mux parent using PLLP branches. To use PLLP branches to CPU, need
739*4882a593Smuzhiyun * to configure additional bit PLLP_OUT_CPU in the clock registers.
740*4882a593Smuzhiyun * TEGRA20_SUPER_CLK - Tegra20 doesn't have a dedicated divider for Super
741*4882a593Smuzhiyun * clocks, it only has a clock-skipper.
742*4882a593Smuzhiyun */
743*4882a593Smuzhiyun struct tegra_clk_super_mux {
744*4882a593Smuzhiyun struct clk_hw hw;
745*4882a593Smuzhiyun void __iomem *reg;
746*4882a593Smuzhiyun struct tegra_clk_frac_div frac_div;
747*4882a593Smuzhiyun const struct clk_ops *div_ops;
748*4882a593Smuzhiyun u8 width;
749*4882a593Smuzhiyun u8 flags;
750*4882a593Smuzhiyun u8 div2_index;
751*4882a593Smuzhiyun u8 pllx_index;
752*4882a593Smuzhiyun spinlock_t *lock;
753*4882a593Smuzhiyun };
754*4882a593Smuzhiyun
755*4882a593Smuzhiyun #define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw)
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun #define TEGRA_DIVIDER_2 BIT(0)
758*4882a593Smuzhiyun #define TEGRA210_CPU_CLK BIT(1)
759*4882a593Smuzhiyun #define TEGRA20_SUPER_CLK BIT(2)
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun extern const struct clk_ops tegra_clk_super_ops;
762*4882a593Smuzhiyun struct clk *tegra_clk_register_super_mux(const char *name,
763*4882a593Smuzhiyun const char **parent_names, u8 num_parents,
764*4882a593Smuzhiyun unsigned long flags, void __iomem *reg, u8 clk_super_flags,
765*4882a593Smuzhiyun u8 width, u8 pllx_index, u8 div2_index, spinlock_t *lock);
766*4882a593Smuzhiyun struct clk *tegra_clk_register_super_clk(const char *name,
767*4882a593Smuzhiyun const char * const *parent_names, u8 num_parents,
768*4882a593Smuzhiyun unsigned long flags, void __iomem *reg, u8 clk_super_flags,
769*4882a593Smuzhiyun spinlock_t *lock);
770*4882a593Smuzhiyun struct clk *tegra_clk_register_super_cclk(const char *name,
771*4882a593Smuzhiyun const char * const *parent_names, u8 num_parents,
772*4882a593Smuzhiyun unsigned long flags, void __iomem *reg, u8 clk_super_flags,
773*4882a593Smuzhiyun spinlock_t *lock);
774*4882a593Smuzhiyun int tegra_cclk_pre_pllx_rate_change(void);
775*4882a593Smuzhiyun void tegra_cclk_post_pllx_rate_change(void);
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun /**
778*4882a593Smuzhiyun * struct tegra_sdmmc_mux - switch divider with Low Jitter inputs for SDMMC
779*4882a593Smuzhiyun *
780*4882a593Smuzhiyun * @hw: handle between common and hardware-specific interfaces
781*4882a593Smuzhiyun * @reg: register controlling mux and divider
782*4882a593Smuzhiyun * @flags: hardware-specific flags
783*4882a593Smuzhiyun * @lock: optional register lock
784*4882a593Smuzhiyun * @gate: gate clock
785*4882a593Smuzhiyun * @gate_ops: gate clock ops
786*4882a593Smuzhiyun */
787*4882a593Smuzhiyun struct tegra_sdmmc_mux {
788*4882a593Smuzhiyun struct clk_hw hw;
789*4882a593Smuzhiyun void __iomem *reg;
790*4882a593Smuzhiyun spinlock_t *lock;
791*4882a593Smuzhiyun const struct clk_ops *gate_ops;
792*4882a593Smuzhiyun struct tegra_clk_periph_gate gate;
793*4882a593Smuzhiyun u8 div_flags;
794*4882a593Smuzhiyun };
795*4882a593Smuzhiyun
796*4882a593Smuzhiyun #define to_clk_sdmmc_mux(_hw) container_of(_hw, struct tegra_sdmmc_mux, hw)
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun struct clk *tegra_clk_register_sdmmc_mux_div(const char *name,
799*4882a593Smuzhiyun void __iomem *clk_base, u32 offset, u32 clk_num, u8 div_flags,
800*4882a593Smuzhiyun unsigned long flags, void *lock);
801*4882a593Smuzhiyun
802*4882a593Smuzhiyun /**
803*4882a593Smuzhiyun * struct clk_init_table - clock initialization table
804*4882a593Smuzhiyun * @clk_id: clock id as mentioned in device tree bindings
805*4882a593Smuzhiyun * @parent_id: parent clock id as mentioned in device tree bindings
806*4882a593Smuzhiyun * @rate: rate to set
807*4882a593Smuzhiyun * @state: enable/disable
808*4882a593Smuzhiyun */
809*4882a593Smuzhiyun struct tegra_clk_init_table {
810*4882a593Smuzhiyun unsigned int clk_id;
811*4882a593Smuzhiyun unsigned int parent_id;
812*4882a593Smuzhiyun unsigned long rate;
813*4882a593Smuzhiyun int state;
814*4882a593Smuzhiyun };
815*4882a593Smuzhiyun
816*4882a593Smuzhiyun /**
817*4882a593Smuzhiyun * struct clk_duplicate - duplicate clocks
818*4882a593Smuzhiyun * @clk_id: clock id as mentioned in device tree bindings
819*4882a593Smuzhiyun * @lookup: duplicate lookup entry for the clock
820*4882a593Smuzhiyun */
821*4882a593Smuzhiyun struct tegra_clk_duplicate {
822*4882a593Smuzhiyun int clk_id;
823*4882a593Smuzhiyun struct clk_lookup lookup;
824*4882a593Smuzhiyun };
825*4882a593Smuzhiyun
826*4882a593Smuzhiyun #define TEGRA_CLK_DUPLICATE(_clk_id, _dev, _con) \
827*4882a593Smuzhiyun { \
828*4882a593Smuzhiyun .clk_id = _clk_id, \
829*4882a593Smuzhiyun .lookup = { \
830*4882a593Smuzhiyun .dev_id = _dev, \
831*4882a593Smuzhiyun .con_id = _con, \
832*4882a593Smuzhiyun }, \
833*4882a593Smuzhiyun }
834*4882a593Smuzhiyun
835*4882a593Smuzhiyun struct tegra_clk {
836*4882a593Smuzhiyun int dt_id;
837*4882a593Smuzhiyun bool present;
838*4882a593Smuzhiyun };
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun struct tegra_devclk {
841*4882a593Smuzhiyun int dt_id;
842*4882a593Smuzhiyun char *dev_id;
843*4882a593Smuzhiyun char *con_id;
844*4882a593Smuzhiyun };
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun void tegra_init_special_resets(unsigned int num, int (*assert)(unsigned long),
847*4882a593Smuzhiyun int (*deassert)(unsigned long));
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun void tegra_init_from_table(struct tegra_clk_init_table *tbl,
850*4882a593Smuzhiyun struct clk *clks[], int clk_max);
851*4882a593Smuzhiyun
852*4882a593Smuzhiyun void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
853*4882a593Smuzhiyun struct clk *clks[], int clk_max);
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun const struct tegra_clk_periph_regs *get_reg_bank(int clkid);
856*4882a593Smuzhiyun struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks);
857*4882a593Smuzhiyun
858*4882a593Smuzhiyun struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk);
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun void tegra_add_of_provider(struct device_node *np, void *clk_src_onecell_get);
861*4882a593Smuzhiyun void tegra_register_devclks(struct tegra_devclk *dev_clks, int num);
862*4882a593Smuzhiyun
863*4882a593Smuzhiyun void tegra_audio_clk_init(void __iomem *clk_base,
864*4882a593Smuzhiyun void __iomem *pmc_base, struct tegra_clk *tegra_clks,
865*4882a593Smuzhiyun struct tegra_audio_clk_info *audio_info,
866*4882a593Smuzhiyun unsigned int num_plls, unsigned long sync_max_rate);
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base,
869*4882a593Smuzhiyun struct tegra_clk *tegra_clks,
870*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params);
871*4882a593Smuzhiyun
872*4882a593Smuzhiyun void tegra_fixed_clk_init(struct tegra_clk *tegra_clks);
873*4882a593Smuzhiyun int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
874*4882a593Smuzhiyun unsigned long *input_freqs, unsigned int num,
875*4882a593Smuzhiyun unsigned int clk_m_div, unsigned long *osc_freq,
876*4882a593Smuzhiyun unsigned long *pll_ref_freq);
877*4882a593Smuzhiyun void tegra_super_clk_gen4_init(void __iomem *clk_base,
878*4882a593Smuzhiyun void __iomem *pmc_base, struct tegra_clk *tegra_clks,
879*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params);
880*4882a593Smuzhiyun void tegra_super_clk_gen5_init(void __iomem *clk_base,
881*4882a593Smuzhiyun void __iomem *pmc_base, struct tegra_clk *tegra_clks,
882*4882a593Smuzhiyun struct tegra_clk_pll_params *pll_params);
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun #ifdef CONFIG_TEGRA124_EMC
885*4882a593Smuzhiyun struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
886*4882a593Smuzhiyun spinlock_t *lock);
887*4882a593Smuzhiyun #else
tegra_clk_register_emc(void __iomem * base,struct device_node * np,spinlock_t * lock)888*4882a593Smuzhiyun static inline struct clk *tegra_clk_register_emc(void __iomem *base,
889*4882a593Smuzhiyun struct device_node *np,
890*4882a593Smuzhiyun spinlock_t *lock)
891*4882a593Smuzhiyun {
892*4882a593Smuzhiyun return NULL;
893*4882a593Smuzhiyun }
894*4882a593Smuzhiyun #endif
895*4882a593Smuzhiyun
896*4882a593Smuzhiyun void tegra114_clock_tune_cpu_trimmers_high(void);
897*4882a593Smuzhiyun void tegra114_clock_tune_cpu_trimmers_low(void);
898*4882a593Smuzhiyun void tegra114_clock_tune_cpu_trimmers_init(void);
899*4882a593Smuzhiyun void tegra114_clock_assert_dfll_dvco_reset(void);
900*4882a593Smuzhiyun void tegra114_clock_deassert_dfll_dvco_reset(void);
901*4882a593Smuzhiyun
902*4882a593Smuzhiyun typedef void (*tegra_clk_apply_init_table_func)(void);
903*4882a593Smuzhiyun extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
904*4882a593Smuzhiyun int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll);
905*4882a593Smuzhiyun u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate);
906*4882a593Smuzhiyun int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
907*4882a593Smuzhiyun int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
908*4882a593Smuzhiyun u8 frac_width, u8 flags);
909*4882a593Smuzhiyun void tegra_clk_osc_resume(void __iomem *clk_base);
910*4882a593Smuzhiyun void tegra_clk_set_pllp_out_cpu(bool enable);
911*4882a593Smuzhiyun void tegra_clk_periph_suspend(void);
912*4882a593Smuzhiyun void tegra_clk_periph_resume(void);
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun
915*4882a593Smuzhiyun /* Combined read fence with delay */
916*4882a593Smuzhiyun #define fence_udelay(delay, reg) \
917*4882a593Smuzhiyun do { \
918*4882a593Smuzhiyun readl(reg); \
919*4882a593Smuzhiyun udelay(delay); \
920*4882a593Smuzhiyun } while (0)
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw);
923*4882a593Smuzhiyun struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter);
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun struct clk *tegra210_clk_register_emc(struct device_node *np,
926*4882a593Smuzhiyun void __iomem *regs);
927*4882a593Smuzhiyun
928*4882a593Smuzhiyun #endif /* TEGRA_CLK_H */
929