diff options
author | Tero Kristo <t-kristo@ti.com> | 2013-06-12 09:04:34 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2014-01-17 15:34:55 -0500 |
commit | f38b0dd63f0d0cca753bf0997eefdfb23dcc9518 (patch) | |
tree | 9945b442a5015de45cefcf9d3d91bcd8c2a28016 /arch | |
parent | 819b4861c18d602463cfe815041d11fd81002654 (diff) |
CLK: TI: Add DPLL clock support
The OMAP clock driver now supports DPLL clock type. This patch also
adds support for DT DPLL nodes.
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/clock.h | 164 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock3xxx.h | 2 |
2 files changed, 1 insertions, 165 deletions
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 82916cc82c92..b345f3ea8617 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <linux/clkdev.h> | 22 | #include <linux/clkdev.h> |
23 | #include <linux/clk-provider.h> | 23 | #include <linux/clk-provider.h> |
24 | #include <linux/clk/ti.h> | ||
24 | 25 | ||
25 | struct omap_clk { | 26 | struct omap_clk { |
26 | u16 cpu; | 27 | u16 cpu; |
@@ -37,7 +38,6 @@ struct omap_clk { | |||
37 | } | 38 | } |
38 | 39 | ||
39 | struct clockdomain; | 40 | struct clockdomain; |
40 | #define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw) | ||
41 | 41 | ||
42 | #define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \ | 42 | #define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \ |
43 | static struct clk _name = { \ | 43 | static struct clk _name = { \ |
@@ -178,141 +178,6 @@ struct clksel { | |||
178 | const struct clksel_rate *rates; | 178 | const struct clksel_rate *rates; |
179 | }; | 179 | }; |
180 | 180 | ||
181 | /** | ||
182 | * struct dpll_data - DPLL registers and integration data | ||
183 | * @mult_div1_reg: register containing the DPLL M and N bitfields | ||
184 | * @mult_mask: mask of the DPLL M bitfield in @mult_div1_reg | ||
185 | * @div1_mask: mask of the DPLL N bitfield in @mult_div1_reg | ||
186 | * @clk_bypass: struct clk pointer to the clock's bypass clock input | ||
187 | * @clk_ref: struct clk pointer to the clock's reference clock input | ||
188 | * @control_reg: register containing the DPLL mode bitfield | ||
189 | * @enable_mask: mask of the DPLL mode bitfield in @control_reg | ||
190 | * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate() | ||
191 | * @last_rounded_m: cache of the last M result of omap2_dpll_round_rate() | ||
192 | * @last_rounded_m4xen: cache of the last M4X result of | ||
193 | * omap4_dpll_regm4xen_round_rate() | ||
194 | * @last_rounded_lpmode: cache of the last lpmode result of | ||
195 | * omap4_dpll_lpmode_recalc() | ||
196 | * @max_multiplier: maximum valid non-bypass multiplier value (actual) | ||
197 | * @last_rounded_n: cache of the last N result of omap2_dpll_round_rate() | ||
198 | * @min_divider: minimum valid non-bypass divider value (actual) | ||
199 | * @max_divider: maximum valid non-bypass divider value (actual) | ||
200 | * @modes: possible values of @enable_mask | ||
201 | * @autoidle_reg: register containing the DPLL autoidle mode bitfield | ||
202 | * @idlest_reg: register containing the DPLL idle status bitfield | ||
203 | * @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg | ||
204 | * @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg | ||
205 | * @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg | ||
206 | * @lpmode_mask: mask of the DPLL low-power mode bitfield in @control_reg | ||
207 | * @m4xen_mask: mask of the DPLL M4X multiplier bitfield in @control_reg | ||
208 | * @auto_recal_bit: bitshift of the driftguard enable bit in @control_reg | ||
209 | * @recal_en_bit: bitshift of the PRM_IRQENABLE_* bit for recalibration IRQs | ||
210 | * @recal_st_bit: bitshift of the PRM_IRQSTATUS_* bit for recalibration IRQs | ||
211 | * @flags: DPLL type/features (see below) | ||
212 | * | ||
213 | * Possible values for @flags: | ||
214 | * DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs) | ||
215 | * | ||
216 | * @freqsel_mask is only used on the OMAP34xx family and AM35xx. | ||
217 | * | ||
218 | * XXX Some DPLLs have multiple bypass inputs, so it's not technically | ||
219 | * correct to only have one @clk_bypass pointer. | ||
220 | * | ||
221 | * XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m, | ||
222 | * @last_rounded_n) should be separated from the runtime-fixed fields | ||
223 | * and placed into a different structure, so that the runtime-fixed data | ||
224 | * can be placed into read-only space. | ||
225 | */ | ||
226 | struct dpll_data { | ||
227 | void __iomem *mult_div1_reg; | ||
228 | u32 mult_mask; | ||
229 | u32 div1_mask; | ||
230 | struct clk *clk_bypass; | ||
231 | struct clk *clk_ref; | ||
232 | void __iomem *control_reg; | ||
233 | u32 enable_mask; | ||
234 | unsigned long last_rounded_rate; | ||
235 | u16 last_rounded_m; | ||
236 | u8 last_rounded_m4xen; | ||
237 | u8 last_rounded_lpmode; | ||
238 | u16 max_multiplier; | ||
239 | u8 last_rounded_n; | ||
240 | u8 min_divider; | ||
241 | u16 max_divider; | ||
242 | u8 modes; | ||
243 | void __iomem *autoidle_reg; | ||
244 | void __iomem *idlest_reg; | ||
245 | u32 autoidle_mask; | ||
246 | u32 freqsel_mask; | ||
247 | u32 idlest_mask; | ||
248 | u32 dco_mask; | ||
249 | u32 sddiv_mask; | ||
250 | u32 lpmode_mask; | ||
251 | u32 m4xen_mask; | ||
252 | u8 auto_recal_bit; | ||
253 | u8 recal_en_bit; | ||
254 | u8 recal_st_bit; | ||
255 | u8 flags; | ||
256 | }; | ||
257 | |||
258 | /* | ||
259 | * struct clk.flags possibilities | ||
260 | * | ||
261 | * XXX document the rest of the clock flags here | ||
262 | * | ||
263 | * CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL | ||
264 | * bits share the same register. This flag allows the | ||
265 | * omap4_dpllmx*() code to determine which GATE_CTRL bit field | ||
266 | * should be used. This is a temporary solution - a better approach | ||
267 | * would be to associate clock type-specific data with the clock, | ||
268 | * similar to the struct dpll_data approach. | ||
269 | */ | ||
270 | #define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */ | ||
271 | #define CLOCK_IDLE_CONTROL (1 << 1) | ||
272 | #define CLOCK_NO_IDLE_PARENT (1 << 2) | ||
273 | #define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */ | ||
274 | #define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */ | ||
275 | #define CLOCK_CLKOUTX2 (1 << 5) | ||
276 | |||
277 | /** | ||
278 | * struct clk_hw_omap - OMAP struct clk | ||
279 | * @node: list_head connecting this clock into the full clock list | ||
280 | * @enable_reg: register to write to enable the clock (see @enable_bit) | ||
281 | * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg) | ||
282 | * @flags: see "struct clk.flags possibilities" above | ||
283 | * @clksel_reg: for clksel clks, register va containing src/divisor select | ||
284 | * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector | ||
285 | * @clksel: for clksel clks, pointer to struct clksel for this clock | ||
286 | * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock | ||
287 | * @clkdm_name: clockdomain name that this clock is contained in | ||
288 | * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime | ||
289 | * @rate_offset: bitshift for rate selection bitfield (OMAP1 only) | ||
290 | * @src_offset: bitshift for source selection bitfield (OMAP1 only) | ||
291 | * | ||
292 | * XXX @rate_offset, @src_offset should probably be removed and OMAP1 | ||
293 | * clock code converted to use clksel. | ||
294 | * | ||
295 | */ | ||
296 | |||
297 | struct clk_hw_omap_ops; | ||
298 | |||
299 | struct clk_hw_omap { | ||
300 | struct clk_hw hw; | ||
301 | struct list_head node; | ||
302 | unsigned long fixed_rate; | ||
303 | u8 fixed_div; | ||
304 | void __iomem *enable_reg; | ||
305 | u8 enable_bit; | ||
306 | u8 flags; | ||
307 | void __iomem *clksel_reg; | ||
308 | u32 clksel_mask; | ||
309 | const struct clksel *clksel; | ||
310 | struct dpll_data *dpll_data; | ||
311 | const char *clkdm_name; | ||
312 | struct clockdomain *clkdm; | ||
313 | const struct clk_hw_omap_ops *ops; | ||
314 | }; | ||
315 | |||
316 | struct clk_hw_omap_ops { | 181 | struct clk_hw_omap_ops { |
317 | void (*find_idlest)(struct clk_hw_omap *oclk, | 182 | void (*find_idlest)(struct clk_hw_omap *oclk, |
318 | void __iomem **idlest_reg, | 183 | void __iomem **idlest_reg, |
@@ -348,36 +213,13 @@ unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw, | |||
348 | #define OMAP4XXX_EN_DPLL_FRBYPASS 0x6 | 213 | #define OMAP4XXX_EN_DPLL_FRBYPASS 0x6 |
349 | #define OMAP4XXX_EN_DPLL_LOCKED 0x7 | 214 | #define OMAP4XXX_EN_DPLL_LOCKED 0x7 |
350 | 215 | ||
351 | /* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */ | ||
352 | #define DPLL_LOW_POWER_STOP 0x1 | ||
353 | #define DPLL_LOW_POWER_BYPASS 0x5 | ||
354 | #define DPLL_LOCKED 0x7 | ||
355 | |||
356 | /* DPLL Type and DCO Selection Flags */ | ||
357 | #define DPLL_J_TYPE 0x1 | ||
358 | |||
359 | long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, | ||
360 | unsigned long *parent_rate); | ||
361 | unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate); | ||
362 | int omap3_noncore_dpll_enable(struct clk_hw *hw); | ||
363 | void omap3_noncore_dpll_disable(struct clk_hw *hw); | ||
364 | int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, | ||
365 | unsigned long parent_rate); | ||
366 | u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk); | 216 | u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk); |
367 | void omap3_dpll_allow_idle(struct clk_hw_omap *clk); | 217 | void omap3_dpll_allow_idle(struct clk_hw_omap *clk); |
368 | void omap3_dpll_deny_idle(struct clk_hw_omap *clk); | 218 | void omap3_dpll_deny_idle(struct clk_hw_omap *clk); |
369 | unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, | ||
370 | unsigned long parent_rate); | ||
371 | int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk); | 219 | int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk); |
372 | void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk); | 220 | void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk); |
373 | void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk); | 221 | void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk); |
374 | unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, | ||
375 | unsigned long parent_rate); | ||
376 | long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, | ||
377 | unsigned long target_rate, | ||
378 | unsigned long *parent_rate); | ||
379 | 222 | ||
380 | void omap2_init_clk_clkdm(struct clk_hw *clk); | ||
381 | void __init omap2_clk_disable_clkdm_control(void); | 223 | void __init omap2_clk_disable_clkdm_control(void); |
382 | 224 | ||
383 | /* clkt_clksel.c public functions */ | 225 | /* clkt_clksel.c public functions */ |
@@ -396,7 +238,6 @@ int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val); | |||
396 | extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk); | 238 | extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk); |
397 | extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk); | 239 | extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk); |
398 | 240 | ||
399 | u8 omap2_init_dpll_parent(struct clk_hw *hw); | ||
400 | unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk); | 241 | unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk); |
401 | 242 | ||
402 | int omap2_dflt_clk_enable(struct clk_hw *hw); | 243 | int omap2_dflt_clk_enable(struct clk_hw *hw); |
@@ -408,7 +249,6 @@ void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk, | |||
408 | void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, | 249 | void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, |
409 | void __iomem **idlest_reg, | 250 | void __iomem **idlest_reg, |
410 | u8 *idlest_bit, u8 *idlest_val); | 251 | u8 *idlest_bit, u8 *idlest_val); |
411 | void omap2_init_clk_hw_omap_clocks(struct clk *clk); | ||
412 | int omap2_clk_enable_autoidle_all(void); | 252 | int omap2_clk_enable_autoidle_all(void); |
413 | int omap2_clk_disable_autoidle_all(void); | 253 | int omap2_clk_disable_autoidle_all(void); |
414 | int omap2_clk_allow_idle(struct clk *clk); | 254 | int omap2_clk_allow_idle(struct clk *clk); |
@@ -433,10 +273,8 @@ extern const struct clksel_rate gfx_l3_rates[]; | |||
433 | extern const struct clksel_rate dsp_ick_rates[]; | 273 | extern const struct clksel_rate dsp_ick_rates[]; |
434 | extern struct clk dummy_ck; | 274 | extern struct clk dummy_ck; |
435 | 275 | ||
436 | extern const struct clk_hw_omap_ops clkhwops_omap3_dpll; | ||
437 | extern const struct clk_hw_omap_ops clkhwops_iclk_wait; | 276 | extern const struct clk_hw_omap_ops clkhwops_iclk_wait; |
438 | extern const struct clk_hw_omap_ops clkhwops_wait; | 277 | extern const struct clk_hw_omap_ops clkhwops_wait; |
439 | extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; | ||
440 | extern const struct clk_hw_omap_ops clkhwops_iclk; | 278 | extern const struct clk_hw_omap_ops clkhwops_iclk; |
441 | extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait; | 279 | extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait; |
442 | extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait; | 280 | extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait; |
diff --git a/arch/arm/mach-omap2/clock3xxx.h b/arch/arm/mach-omap2/clock3xxx.h index 8cd4b0a882ae..dab90e281aeb 100644 --- a/arch/arm/mach-omap2/clock3xxx.h +++ b/arch/arm/mach-omap2/clock3xxx.h | |||
@@ -9,8 +9,6 @@ | |||
9 | #define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H | 9 | #define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H |
10 | 10 | ||
11 | int omap3xxx_clk_init(void); | 11 | int omap3xxx_clk_init(void); |
12 | int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, | ||
13 | unsigned long parent_rate); | ||
14 | int omap3_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate, | 12 | int omap3_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate, |
15 | unsigned long parent_rate); | 13 | unsigned long parent_rate); |
16 | void omap3_clk_lock_dpll5(void); | 14 | void omap3_clk_lock_dpll5(void); |