]>
Commit | Line | Data |
---|---|---|
5fe225c1 RJ |
1 | /* |
2 | * Copyright (C) 2014 Broadcom Corporation | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License as | |
6 | * published by the Free Software Foundation version 2. | |
7 | * | |
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | |
9 | * kind, whether express or implied; without even the implied warranty | |
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | */ | |
13 | ||
14 | #ifndef _CLK_IPROC_H | |
15 | #define _CLK_IPROC_H | |
16 | ||
17 | #include <linux/kernel.h> | |
18 | #include <linux/list.h> | |
19 | #include <linux/spinlock.h> | |
20 | #include <linux/slab.h> | |
21 | #include <linux/device.h> | |
22 | #include <linux/of.h> | |
23 | #include <linux/clk-provider.h> | |
24 | ||
25 | #define IPROC_CLK_NAME_LEN 25 | |
26 | #define IPROC_CLK_INVALID_OFFSET 0xffffffff | |
27 | #define bit_mask(width) ((1 << (width)) - 1) | |
28 | ||
29 | /* clocks that should not be disabled at runtime */ | |
30 | #define IPROC_CLK_AON BIT(0) | |
31 | ||
32 | /* PLL that requires gating through ASIU */ | |
33 | #define IPROC_CLK_PLL_ASIU BIT(1) | |
34 | ||
35 | /* PLL that has fractional part of the NDIV */ | |
36 | #define IPROC_CLK_PLL_HAS_NDIV_FRAC BIT(2) | |
37 | ||
38 | /* | |
39 | * Some of the iProc PLL/clocks may have an ASIC bug that requires read back | |
40 | * of the same register following the write to flush the write transaction into | |
41 | * the intended register | |
42 | */ | |
43 | #define IPROC_CLK_NEEDS_READ_BACK BIT(3) | |
44 | ||
45 | /* | |
46 | * Some PLLs require the PLL SW override bit to be set before changes can be | |
47 | * applied to the PLL | |
48 | */ | |
49 | #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4) | |
50 | ||
01b6722f JM |
51 | /* |
52 | * Some PLLs use a different way to control clock power, via the PWRDWN bit in | |
53 | * the PLL control register | |
54 | */ | |
55 | #define IPROC_CLK_EMBED_PWRCTRL BIT(5) | |
56 | ||
40c8bec3 JM |
57 | /* |
58 | * Some PLLs have separate registers for Status and Control. Identify this to | |
59 | * let the driver know if additional registers need to be used | |
60 | */ | |
61 | #define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6) | |
62 | ||
bcd8be13 SR |
63 | /* |
64 | * Some PLLs have an additional divide by 2 in master clock calculation; | |
65 | * MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know | |
66 | * of modified calculations | |
67 | */ | |
68 | #define IPROC_CLK_MCLK_DIV_BY_2 BIT(7) | |
69 | ||
70 | /* | |
71 | * Some PLLs provide a look up table for the leaf clock frequencies and | |
72 | * auto calculates VCO frequency parameters based on the provided leaf | |
73 | * clock frequencies. They have a user mode that allows the divider | |
74 | * controls to be determined by the user | |
75 | */ | |
76 | #define IPROC_CLK_PLL_USER_MODE_ON BIT(8) | |
77 | ||
78 | /* | |
79 | * Some PLLs have an active low reset | |
80 | */ | |
81 | #define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9) | |
82 | ||
5fe225c1 RJ |
83 | /* |
84 | * Parameters for VCO frequency configuration | |
85 | * | |
86 | * VCO frequency = | |
87 | * ((ndiv_int + ndiv_frac / 2^20) * (ref freqeuncy / pdiv) | |
88 | */ | |
89 | struct iproc_pll_vco_param { | |
90 | unsigned long rate; | |
91 | unsigned int ndiv_int; | |
92 | unsigned int ndiv_frac; | |
93 | unsigned int pdiv; | |
94 | }; | |
95 | ||
96 | struct iproc_clk_reg_op { | |
97 | unsigned int offset; | |
98 | unsigned int shift; | |
99 | unsigned int width; | |
100 | }; | |
101 | ||
102 | /* | |
103 | * Clock gating control at the top ASIU level | |
104 | */ | |
105 | struct iproc_asiu_gate { | |
106 | unsigned int offset; | |
107 | unsigned int en_shift; | |
108 | }; | |
109 | ||
110 | /* | |
111 | * Control of powering on/off of a PLL | |
112 | * | |
113 | * Before powering off a PLL, input isolation (ISO) needs to be enabled | |
114 | */ | |
115 | struct iproc_pll_aon_pwr_ctrl { | |
116 | unsigned int offset; | |
117 | unsigned int pwr_width; | |
118 | unsigned int pwr_shift; | |
119 | unsigned int iso_shift; | |
120 | }; | |
121 | ||
122 | /* | |
f713c6bf | 123 | * Control of the PLL reset |
5fe225c1 RJ |
124 | */ |
125 | struct iproc_pll_reset_ctrl { | |
126 | unsigned int offset; | |
127 | unsigned int reset_shift; | |
128 | unsigned int p_reset_shift; | |
f713c6bf JM |
129 | }; |
130 | ||
131 | /* | |
132 | * Control of the Ki, Kp, and Ka parameters | |
133 | */ | |
134 | struct iproc_pll_dig_filter_ctrl { | |
135 | unsigned int offset; | |
5fe225c1 RJ |
136 | unsigned int ki_shift; |
137 | unsigned int ki_width; | |
138 | unsigned int kp_shift; | |
139 | unsigned int kp_width; | |
140 | unsigned int ka_shift; | |
141 | unsigned int ka_width; | |
142 | }; | |
143 | ||
144 | /* | |
145 | * To enable SW control of the PLL | |
146 | */ | |
147 | struct iproc_pll_sw_ctrl { | |
148 | unsigned int offset; | |
149 | unsigned int shift; | |
150 | }; | |
151 | ||
152 | struct iproc_pll_vco_ctrl { | |
153 | unsigned int u_offset; | |
154 | unsigned int l_offset; | |
155 | }; | |
156 | ||
157 | /* | |
158 | * Main PLL control parameters | |
159 | */ | |
160 | struct iproc_pll_ctrl { | |
161 | unsigned long flags; | |
162 | struct iproc_pll_aon_pwr_ctrl aon; | |
163 | struct iproc_asiu_gate asiu; | |
164 | struct iproc_pll_reset_ctrl reset; | |
f713c6bf | 165 | struct iproc_pll_dig_filter_ctrl dig_filter; |
5fe225c1 RJ |
166 | struct iproc_pll_sw_ctrl sw_ctrl; |
167 | struct iproc_clk_reg_op ndiv_int; | |
168 | struct iproc_clk_reg_op ndiv_frac; | |
169 | struct iproc_clk_reg_op pdiv; | |
170 | struct iproc_pll_vco_ctrl vco_ctrl; | |
171 | struct iproc_clk_reg_op status; | |
bcd8be13 | 172 | struct iproc_clk_reg_op macro_mode; |
5fe225c1 RJ |
173 | }; |
174 | ||
175 | /* | |
176 | * Controls enabling/disabling a PLL derived clock | |
177 | */ | |
178 | struct iproc_clk_enable_ctrl { | |
179 | unsigned int offset; | |
180 | unsigned int enable_shift; | |
181 | unsigned int hold_shift; | |
182 | unsigned int bypass_shift; | |
183 | }; | |
184 | ||
185 | /* | |
186 | * Main clock control parameters for clocks derived from the PLLs | |
187 | */ | |
188 | struct iproc_clk_ctrl { | |
189 | unsigned int channel; | |
190 | unsigned long flags; | |
191 | struct iproc_clk_enable_ctrl enable; | |
192 | struct iproc_clk_reg_op mdiv; | |
193 | }; | |
194 | ||
195 | /* | |
196 | * Divisor of the ASIU clocks | |
197 | */ | |
198 | struct iproc_asiu_div { | |
199 | unsigned int offset; | |
200 | unsigned int en_shift; | |
201 | unsigned int high_shift; | |
202 | unsigned int high_width; | |
203 | unsigned int low_shift; | |
204 | unsigned int low_width; | |
205 | }; | |
206 | ||
df416e56 RJ |
207 | void iproc_armpll_setup(struct device_node *node); |
208 | void iproc_pll_clk_setup(struct device_node *node, | |
209 | const struct iproc_pll_ctrl *pll_ctrl, | |
210 | const struct iproc_pll_vco_param *vco, | |
211 | unsigned int num_vco_entries, | |
212 | const struct iproc_clk_ctrl *clk_ctrl, | |
213 | unsigned int num_clks); | |
214 | void iproc_asiu_setup(struct device_node *node, | |
215 | const struct iproc_asiu_div *div, | |
216 | const struct iproc_asiu_gate *gate, | |
217 | unsigned int num_clks); | |
5fe225c1 RJ |
218 | |
219 | #endif /* _CLK_IPROC_H */ |