aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2013-06-12 09:04:34 -0400
committerMike Turquette <mturquette@linaro.org>2014-01-17 15:34:55 -0500
commitf38b0dd63f0d0cca753bf0997eefdfb23dcc9518 (patch)
tree9945b442a5015de45cefcf9d3d91bcd8c2a28016
parent819b4861c18d602463cfe815041d11fd81002654 (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>
-rw-r--r--Documentation/devicetree/bindings/clock/ti/dpll.txt75
-rw-r--r--arch/arm/mach-omap2/clock.h164
-rw-r--r--arch/arm/mach-omap2/clock3xxx.h2
-rw-r--r--drivers/clk/ti/Makefile1
-rw-r--r--drivers/clk/ti/dpll.c558
-rw-r--r--include/linux/clk/ti.h172
6 files changed, 807 insertions, 165 deletions
diff --git a/Documentation/devicetree/bindings/clock/ti/dpll.txt b/Documentation/devicetree/bindings/clock/ti/dpll.txt
new file mode 100644
index 000000000000..30bfdb7c9f18
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti/dpll.txt
@@ -0,0 +1,75 @@
1Binding for Texas Instruments DPLL clock.
2
3Binding status: Unstable - ABI compatibility may be broken in the future
4
5This binding uses the common clock binding[1]. It assumes a
6register-mapped DPLL with usually two selectable input clocks
7(reference clock and bypass clock), with digital phase locked
8loop logic for multiplying the input clock to a desired output
9clock. This clock also typically supports different operation
10modes (locked, low power stop etc.) This binding has several
11sub-types, which effectively result in slightly different setup
12for the actual DPLL clock.
13
14[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
15
16Required properties:
17- compatible : shall be one of:
18 "ti,omap3-dpll-clock",
19 "ti,omap3-dpll-core-clock",
20 "ti,omap3-dpll-per-clock",
21 "ti,omap3-dpll-per-j-type-clock",
22 "ti,omap4-dpll-clock",
23 "ti,omap4-dpll-x2-clock",
24 "ti,omap4-dpll-core-clock",
25 "ti,omap4-dpll-m4xen-clock",
26 "ti,omap4-dpll-j-type-clock",
27 "ti,am3-dpll-no-gate-clock",
28 "ti,am3-dpll-j-type-clock",
29 "ti,am3-dpll-no-gate-j-type-clock",
30 "ti,am3-dpll-clock",
31 "ti,am3-dpll-core-clock",
32 "ti,am3-dpll-x2-clock",
33
34- #clock-cells : from common clock binding; shall be set to 0.
35- clocks : link phandles of parent clocks, first entry lists reference clock
36 and second entry bypass clock
37- reg : offsets for the register set for controlling the DPLL.
38 Registers are listed in following order:
39 "control" - contains the control register base address
40 "idlest" - contains the idle status register base address
41 "mult-div1" - contains the multiplier / divider register base address
42 "autoidle" - contains the autoidle register base address (optional)
43 ti,am3-* dpll types do not have autoidle register
44
45Optional properties:
46- DPLL mode setting - defining any one or more of the following overrides
47 default setting.
48 - ti,low-power-stop : DPLL supports low power stop mode, gating output
49 - ti,low-power-bypass : DPLL output matches rate of parent bypass clock
50 - ti,lock : DPLL locks in programmed rate
51
52Examples:
53 dpll_core_ck: dpll_core_ck@44e00490 {
54 #clock-cells = <0>;
55 compatible = "ti,omap4-dpll-core-clock";
56 clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
57 reg = <0x490>, <0x45c>, <0x488>, <0x468>;
58 };
59
60 dpll2_ck: dpll2_ck@48004004 {
61 #clock-cells = <0>;
62 compatible = "ti,omap3-dpll-clock";
63 clocks = <&sys_ck>, <&dpll2_fck>;
64 ti,low-power-stop;
65 ti,low-power-bypass;
66 ti,lock;
67 reg = <0x4>, <0x24>, <0x34>, <0x40>;
68 };
69
70 dpll_core_ck: dpll_core_ck@44e00490 {
71 #clock-cells = <0>;
72 compatible = "ti,am3-dpll-core-clock";
73 clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
74 reg = <0x90>, <0x5c>, <0x68>;
75 };
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
25struct omap_clk { 26struct omap_clk {
26 u16 cpu; 27 u16 cpu;
@@ -37,7 +38,6 @@ struct omap_clk {
37 } 38 }
38 39
39struct clockdomain; 40struct 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 */
226struct 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
297struct clk_hw_omap_ops;
298
299struct 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
316struct clk_hw_omap_ops { 181struct 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
359long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
360 unsigned long *parent_rate);
361unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate);
362int omap3_noncore_dpll_enable(struct clk_hw *hw);
363void omap3_noncore_dpll_disable(struct clk_hw *hw);
364int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
365 unsigned long parent_rate);
366u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk); 216u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk);
367void omap3_dpll_allow_idle(struct clk_hw_omap *clk); 217void omap3_dpll_allow_idle(struct clk_hw_omap *clk);
368void omap3_dpll_deny_idle(struct clk_hw_omap *clk); 218void omap3_dpll_deny_idle(struct clk_hw_omap *clk);
369unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
370 unsigned long parent_rate);
371int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk); 219int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk);
372void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk); 220void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk);
373void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk); 221void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk);
374unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
375 unsigned long parent_rate);
376long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
377 unsigned long target_rate,
378 unsigned long *parent_rate);
379 222
380void omap2_init_clk_clkdm(struct clk_hw *clk);
381void __init omap2_clk_disable_clkdm_control(void); 223void __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);
396extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk); 238extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk);
397extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk); 239extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk);
398 240
399u8 omap2_init_dpll_parent(struct clk_hw *hw);
400unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk); 241unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
401 242
402int omap2_dflt_clk_enable(struct clk_hw *hw); 243int omap2_dflt_clk_enable(struct clk_hw *hw);
@@ -408,7 +249,6 @@ void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk,
408void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, 249void 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);
411void omap2_init_clk_hw_omap_clocks(struct clk *clk);
412int omap2_clk_enable_autoidle_all(void); 252int omap2_clk_enable_autoidle_all(void);
413int omap2_clk_disable_autoidle_all(void); 253int omap2_clk_disable_autoidle_all(void);
414int omap2_clk_allow_idle(struct clk *clk); 254int omap2_clk_allow_idle(struct clk *clk);
@@ -433,10 +273,8 @@ extern const struct clksel_rate gfx_l3_rates[];
433extern const struct clksel_rate dsp_ick_rates[]; 273extern const struct clksel_rate dsp_ick_rates[];
434extern struct clk dummy_ck; 274extern struct clk dummy_ck;
435 275
436extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;
437extern const struct clk_hw_omap_ops clkhwops_iclk_wait; 276extern const struct clk_hw_omap_ops clkhwops_iclk_wait;
438extern const struct clk_hw_omap_ops clkhwops_wait; 277extern const struct clk_hw_omap_ops clkhwops_wait;
439extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
440extern const struct clk_hw_omap_ops clkhwops_iclk; 278extern const struct clk_hw_omap_ops clkhwops_iclk;
441extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait; 279extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait;
442extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait; 280extern 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
11int omap3xxx_clk_init(void); 11int omap3xxx_clk_init(void);
12int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,
13 unsigned long parent_rate);
14int omap3_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate, 12int omap3_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate,
15 unsigned long parent_rate); 13 unsigned long parent_rate);
16void omap3_clk_lock_dpll5(void); 14void omap3_clk_lock_dpll5(void);
diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile
index 1825f7f4bdc0..3dbb78dc9fca 100644
--- a/drivers/clk/ti/Makefile
+++ b/drivers/clk/ti/Makefile
@@ -1,3 +1,4 @@
1ifneq ($(CONFIG_OF),) 1ifneq ($(CONFIG_OF),)
2obj-y += clk.o 2obj-y += clk.o
3clk-common = dpll.o
3endif 4endif
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
new file mode 100644
index 000000000000..7e498a44f97d
--- /dev/null
+++ b/drivers/clk/ti/dpll.c
@@ -0,0 +1,558 @@
1/*
2 * OMAP DPLL clock support
3 *
4 * Copyright (C) 2013 Texas Instruments, Inc.
5 *
6 * Tero Kristo <t-kristo@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
13 * kind, whether express or implied; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/clk-provider.h>
19#include <linux/slab.h>
20#include <linux/err.h>
21#include <linux/of.h>
22#include <linux/of_address.h>
23#include <linux/clk/ti.h>
24
25#undef pr_fmt
26#define pr_fmt(fmt) "%s: " fmt, __func__
27
28#define DPLL_HAS_AUTOIDLE 0x1
29
30#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
31 defined(CONFIG_SOC_DRA7XX)
32static const struct clk_ops dpll_m4xen_ck_ops = {
33 .enable = &omap3_noncore_dpll_enable,
34 .disable = &omap3_noncore_dpll_disable,
35 .recalc_rate = &omap4_dpll_regm4xen_recalc,
36 .round_rate = &omap4_dpll_regm4xen_round_rate,
37 .set_rate = &omap3_noncore_dpll_set_rate,
38 .get_parent = &omap2_init_dpll_parent,
39};
40#endif
41
42static const struct clk_ops dpll_core_ck_ops = {
43 .recalc_rate = &omap3_dpll_recalc,
44 .get_parent = &omap2_init_dpll_parent,
45};
46
47#ifdef CONFIG_ARCH_OMAP3
48static const struct clk_ops omap3_dpll_core_ck_ops = {
49 .get_parent = &omap2_init_dpll_parent,
50 .recalc_rate = &omap3_dpll_recalc,
51 .round_rate = &omap2_dpll_round_rate,
52};
53#endif
54
55static const struct clk_ops dpll_ck_ops = {
56 .enable = &omap3_noncore_dpll_enable,
57 .disable = &omap3_noncore_dpll_disable,
58 .recalc_rate = &omap3_dpll_recalc,
59 .round_rate = &omap2_dpll_round_rate,
60 .set_rate = &omap3_noncore_dpll_set_rate,
61 .get_parent = &omap2_init_dpll_parent,
62};
63
64static const struct clk_ops dpll_no_gate_ck_ops = {
65 .recalc_rate = &omap3_dpll_recalc,
66 .get_parent = &omap2_init_dpll_parent,
67 .round_rate = &omap2_dpll_round_rate,
68 .set_rate = &omap3_noncore_dpll_set_rate,
69};
70
71#ifdef CONFIG_ARCH_OMAP3
72static const struct clk_ops omap3_dpll_ck_ops = {
73 .enable = &omap3_noncore_dpll_enable,
74 .disable = &omap3_noncore_dpll_disable,
75 .get_parent = &omap2_init_dpll_parent,
76 .recalc_rate = &omap3_dpll_recalc,
77 .set_rate = &omap3_noncore_dpll_set_rate,
78 .round_rate = &omap2_dpll_round_rate,
79};
80
81static const struct clk_ops omap3_dpll_per_ck_ops = {
82 .enable = &omap3_noncore_dpll_enable,
83 .disable = &omap3_noncore_dpll_disable,
84 .get_parent = &omap2_init_dpll_parent,
85 .recalc_rate = &omap3_dpll_recalc,
86 .set_rate = &omap3_dpll4_set_rate,
87 .round_rate = &omap2_dpll_round_rate,
88};
89#endif
90
91static const struct clk_ops dpll_x2_ck_ops = {
92 .recalc_rate = &omap3_clkoutx2_recalc,
93};
94
95/**
96 * ti_clk_register_dpll - low level registration of a DPLL clock
97 * @hw: hardware clock definition for the clock
98 * @node: device node for the clock
99 *
100 * Finalizes DPLL registration process. In case a failure (clk-ref or
101 * clk-bypass is missing), the clock is added to retry list and
102 * the initialization is retried on later stage.
103 */
104static void __init ti_clk_register_dpll(struct clk_hw *hw,
105 struct device_node *node)
106{
107 struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
108 struct dpll_data *dd = clk_hw->dpll_data;
109 struct clk *clk;
110
111 dd->clk_ref = of_clk_get(node, 0);
112 dd->clk_bypass = of_clk_get(node, 1);
113
114 if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) {
115 pr_debug("clk-ref or clk-bypass missing for %s, retry later\n",
116 node->name);
117 if (!ti_clk_retry_init(node, hw, ti_clk_register_dpll))
118 return;
119
120 goto cleanup;
121 }
122
123 /* register the clock */
124 clk = clk_register(NULL, &clk_hw->hw);
125
126 if (!IS_ERR(clk)) {
127 omap2_init_clk_hw_omap_clocks(clk);
128 of_clk_add_provider(node, of_clk_src_simple_get, clk);
129 kfree(clk_hw->hw.init->parent_names);
130 kfree(clk_hw->hw.init);
131 return;
132 }
133
134cleanup:
135 kfree(clk_hw->dpll_data);
136 kfree(clk_hw->hw.init->parent_names);
137 kfree(clk_hw->hw.init);
138 kfree(clk_hw);
139}
140
141#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
142 defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX)
143/**
144 * ti_clk_register_dpll_x2 - Registers a DPLLx2 clock
145 * @node: device node for this clock
146 * @ops: clk_ops for this clock
147 * @hw_ops: clk_hw_ops for this clock
148 *
149 * Initializes a DPLL x 2 clock from device tree data.
150 */
151static void ti_clk_register_dpll_x2(struct device_node *node,
152 const struct clk_ops *ops,
153 const struct clk_hw_omap_ops *hw_ops)
154{
155 struct clk *clk;
156 struct clk_init_data init = { NULL };
157 struct clk_hw_omap *clk_hw;
158 const char *name = node->name;
159 const char *parent_name;
160
161 parent_name = of_clk_get_parent_name(node, 0);
162 if (!parent_name) {
163 pr_err("%s must have parent\n", node->name);
164 return;
165 }
166
167 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
168 if (!clk_hw)
169 return;
170
171 clk_hw->ops = hw_ops;
172 clk_hw->hw.init = &init;
173
174 init.name = name;
175 init.ops = ops;
176 init.parent_names = &parent_name;
177 init.num_parents = 1;
178
179 /* register the clock */
180 clk = clk_register(NULL, &clk_hw->hw);
181
182 if (IS_ERR(clk)) {
183 kfree(clk_hw);
184 } else {
185 omap2_init_clk_hw_omap_clocks(clk);
186 of_clk_add_provider(node, of_clk_src_simple_get, clk);
187 }
188}
189#endif
190
191/**
192 * of_ti_dpll_setup - Setup function for OMAP DPLL clocks
193 * @node: device node containing the DPLL info
194 * @ops: ops for the DPLL
195 * @ddt: DPLL data template to use
196 * @init_flags: flags for controlling init types
197 *
198 * Initializes a DPLL clock from device tree data.
199 */
200static void __init of_ti_dpll_setup(struct device_node *node,
201 const struct clk_ops *ops,
202 const struct dpll_data *ddt,
203 u8 init_flags)
204{
205 struct clk_hw_omap *clk_hw = NULL;
206 struct clk_init_data *init = NULL;
207 const char **parent_names = NULL;
208 struct dpll_data *dd = NULL;
209 int i;
210 u8 dpll_mode = 0;
211
212 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
213 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
214 init = kzalloc(sizeof(*init), GFP_KERNEL);
215 if (!dd || !clk_hw || !init)
216 goto cleanup;
217
218 memcpy(dd, ddt, sizeof(*dd));
219
220 clk_hw->dpll_data = dd;
221 clk_hw->ops = &clkhwops_omap3_dpll;
222 clk_hw->hw.init = init;
223 clk_hw->flags = MEMMAP_ADDRESSING;
224
225 init->name = node->name;
226 init->ops = ops;
227
228 init->num_parents = of_clk_get_parent_count(node);
229 if (init->num_parents < 1) {
230 pr_err("%s must have parent(s)\n", node->name);
231 goto cleanup;
232 }
233
234 parent_names = kzalloc(sizeof(char *) * init->num_parents, GFP_KERNEL);
235 if (!parent_names)
236 goto cleanup;
237
238 for (i = 0; i < init->num_parents; i++)
239 parent_names[i] = of_clk_get_parent_name(node, i);
240
241 init->parent_names = parent_names;
242
243 dd->control_reg = ti_clk_get_reg_addr(node, 0);
244 dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
245 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
246
247 if (!dd->control_reg || !dd->idlest_reg || !dd->mult_div1_reg)
248 goto cleanup;
249
250 if (init_flags & DPLL_HAS_AUTOIDLE) {
251 dd->autoidle_reg = ti_clk_get_reg_addr(node, 3);
252 if (!dd->autoidle_reg)
253 goto cleanup;
254 }
255
256 if (of_property_read_bool(node, "ti,low-power-stop"))
257 dpll_mode |= 1 << DPLL_LOW_POWER_STOP;
258
259 if (of_property_read_bool(node, "ti,low-power-bypass"))
260 dpll_mode |= 1 << DPLL_LOW_POWER_BYPASS;
261
262 if (of_property_read_bool(node, "ti,lock"))
263 dpll_mode |= 1 << DPLL_LOCKED;
264
265 if (dpll_mode)
266 dd->modes = dpll_mode;
267
268 ti_clk_register_dpll(&clk_hw->hw, node);
269 return;
270
271cleanup:
272 kfree(dd);
273 kfree(parent_names);
274 kfree(init);
275 kfree(clk_hw);
276}
277
278#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
279 defined(CONFIG_SOC_DRA7XX)
280static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node)
281{
282 ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx);
283}
284CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
285 of_ti_omap4_dpll_x2_setup);
286#endif
287
288#ifdef CONFIG_SOC_AM33XX
289static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
290{
291 ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
292}
293CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock",
294 of_ti_am3_dpll_x2_setup);
295#endif
296
297#ifdef CONFIG_ARCH_OMAP3
298static void __init of_ti_omap3_dpll_setup(struct device_node *node)
299{
300 const struct dpll_data dd = {
301 .idlest_mask = 0x1,
302 .enable_mask = 0x7,
303 .autoidle_mask = 0x7,
304 .mult_mask = 0x7ff << 8,
305 .div1_mask = 0x7f,
306 .max_multiplier = 2047,
307 .max_divider = 128,
308 .min_divider = 1,
309 .freqsel_mask = 0xf0,
310 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
311 };
312
313 of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
314}
315CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",
316 of_ti_omap3_dpll_setup);
317
318static void __init of_ti_omap3_core_dpll_setup(struct device_node *node)
319{
320 const struct dpll_data dd = {
321 .idlest_mask = 0x1,
322 .enable_mask = 0x7,
323 .autoidle_mask = 0x7,
324 .mult_mask = 0x7ff << 16,
325 .div1_mask = 0x7f << 8,
326 .max_multiplier = 2047,
327 .max_divider = 128,
328 .min_divider = 1,
329 .freqsel_mask = 0xf0,
330 };
331
332 of_ti_dpll_setup(node, &omap3_dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
333}
334CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock",
335 of_ti_omap3_core_dpll_setup);
336
337static void __init of_ti_omap3_per_dpll_setup(struct device_node *node)
338{
339 const struct dpll_data dd = {
340 .idlest_mask = 0x1 << 1,
341 .enable_mask = 0x7 << 16,
342 .autoidle_mask = 0x7 << 3,
343 .mult_mask = 0x7ff << 8,
344 .div1_mask = 0x7f,
345 .max_multiplier = 2047,
346 .max_divider = 128,
347 .min_divider = 1,
348 .freqsel_mask = 0xf00000,
349 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
350 };
351
352 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
353}
354CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock",
355 of_ti_omap3_per_dpll_setup);
356
357static void __init of_ti_omap3_per_jtype_dpll_setup(struct device_node *node)
358{
359 const struct dpll_data dd = {
360 .idlest_mask = 0x1 << 1,
361 .enable_mask = 0x7 << 16,
362 .autoidle_mask = 0x7 << 3,
363 .mult_mask = 0xfff << 8,
364 .div1_mask = 0x7f,
365 .max_multiplier = 4095,
366 .max_divider = 128,
367 .min_divider = 1,
368 .sddiv_mask = 0xff << 24,
369 .dco_mask = 0xe << 20,
370 .flags = DPLL_J_TYPE,
371 .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
372 };
373
374 of_ti_dpll_setup(node, &omap3_dpll_per_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
375}
376CLK_OF_DECLARE(ti_omap3_per_jtype_dpll_clock, "ti,omap3-dpll-per-j-type-clock",
377 of_ti_omap3_per_jtype_dpll_setup);
378#endif
379
380static void __init of_ti_omap4_dpll_setup(struct device_node *node)
381{
382 const struct dpll_data dd = {
383 .idlest_mask = 0x1,
384 .enable_mask = 0x7,
385 .autoidle_mask = 0x7,
386 .mult_mask = 0x7ff << 8,
387 .div1_mask = 0x7f,
388 .max_multiplier = 2047,
389 .max_divider = 128,
390 .min_divider = 1,
391 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
392 };
393
394 of_ti_dpll_setup(node, &dpll_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
395}
396CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock",
397 of_ti_omap4_dpll_setup);
398
399static void __init of_ti_omap4_core_dpll_setup(struct device_node *node)
400{
401 const struct dpll_data dd = {
402 .idlest_mask = 0x1,
403 .enable_mask = 0x7,
404 .autoidle_mask = 0x7,
405 .mult_mask = 0x7ff << 8,
406 .div1_mask = 0x7f,
407 .max_multiplier = 2047,
408 .max_divider = 128,
409 .min_divider = 1,
410 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
411 };
412
413 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
414}
415CLK_OF_DECLARE(ti_omap4_core_dpll_clock, "ti,omap4-dpll-core-clock",
416 of_ti_omap4_core_dpll_setup);
417
418#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
419 defined(CONFIG_SOC_DRA7XX)
420static void __init of_ti_omap4_m4xen_dpll_setup(struct device_node *node)
421{
422 const struct dpll_data dd = {
423 .idlest_mask = 0x1,
424 .enable_mask = 0x7,
425 .autoidle_mask = 0x7,
426 .mult_mask = 0x7ff << 8,
427 .div1_mask = 0x7f,
428 .max_multiplier = 2047,
429 .max_divider = 128,
430 .min_divider = 1,
431 .m4xen_mask = 0x800,
432 .lpmode_mask = 1 << 10,
433 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
434 };
435
436 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
437}
438CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock",
439 of_ti_omap4_m4xen_dpll_setup);
440
441static void __init of_ti_omap4_jtype_dpll_setup(struct device_node *node)
442{
443 const struct dpll_data dd = {
444 .idlest_mask = 0x1,
445 .enable_mask = 0x7,
446 .autoidle_mask = 0x7,
447 .mult_mask = 0xfff << 8,
448 .div1_mask = 0xff,
449 .max_multiplier = 4095,
450 .max_divider = 256,
451 .min_divider = 1,
452 .sddiv_mask = 0xff << 24,
453 .flags = DPLL_J_TYPE,
454 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
455 };
456
457 of_ti_dpll_setup(node, &dpll_m4xen_ck_ops, &dd, DPLL_HAS_AUTOIDLE);
458}
459CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock",
460 of_ti_omap4_jtype_dpll_setup);
461#endif
462
463static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node)
464{
465 const struct dpll_data dd = {
466 .idlest_mask = 0x1,
467 .enable_mask = 0x7,
468 .autoidle_mask = 0x7,
469 .mult_mask = 0x7ff << 8,
470 .div1_mask = 0x7f,
471 .max_multiplier = 2047,
472 .max_divider = 128,
473 .min_divider = 1,
474 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
475 };
476
477 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0);
478}
479CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock",
480 of_ti_am3_no_gate_dpll_setup);
481
482static void __init of_ti_am3_jtype_dpll_setup(struct device_node *node)
483{
484 const struct dpll_data dd = {
485 .idlest_mask = 0x1,
486 .enable_mask = 0x7,
487 .autoidle_mask = 0x7,
488 .mult_mask = 0x7ff << 8,
489 .div1_mask = 0x7f,
490 .max_multiplier = 4095,
491 .max_divider = 256,
492 .min_divider = 2,
493 .flags = DPLL_J_TYPE,
494 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
495 };
496
497 of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0);
498}
499CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock",
500 of_ti_am3_jtype_dpll_setup);
501
502static void __init of_ti_am3_no_gate_jtype_dpll_setup(struct device_node *node)
503{
504 const struct dpll_data dd = {
505 .idlest_mask = 0x1,
506 .enable_mask = 0x7,
507 .autoidle_mask = 0x7,
508 .mult_mask = 0x7ff << 8,
509 .div1_mask = 0x7f,
510 .max_multiplier = 2047,
511 .max_divider = 128,
512 .min_divider = 1,
513 .flags = DPLL_J_TYPE,
514 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
515 };
516
517 of_ti_dpll_setup(node, &dpll_no_gate_ck_ops, &dd, 0);
518}
519CLK_OF_DECLARE(ti_am3_no_gate_jtype_dpll_clock,
520 "ti,am3-dpll-no-gate-j-type-clock",
521 of_ti_am3_no_gate_jtype_dpll_setup);
522
523static void __init of_ti_am3_dpll_setup(struct device_node *node)
524{
525 const struct dpll_data dd = {
526 .idlest_mask = 0x1,
527 .enable_mask = 0x7,
528 .autoidle_mask = 0x7,
529 .mult_mask = 0x7ff << 8,
530 .div1_mask = 0x7f,
531 .max_multiplier = 2047,
532 .max_divider = 128,
533 .min_divider = 1,
534 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
535 };
536
537 of_ti_dpll_setup(node, &dpll_ck_ops, &dd, 0);
538}
539CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup);
540
541static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
542{
543 const struct dpll_data dd = {
544 .idlest_mask = 0x1,
545 .enable_mask = 0x7,
546 .autoidle_mask = 0x7,
547 .mult_mask = 0x7ff << 8,
548 .div1_mask = 0x7f,
549 .max_multiplier = 2047,
550 .max_divider = 128,
551 .min_divider = 1,
552 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
553 };
554
555 of_ti_dpll_setup(node, &dpll_core_ck_ops, &dd, 0);
556}
557CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",
558 of_ti_am3_core_dpll_setup);
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index c6eded5eea76..3f9de3973582 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -18,6 +18,153 @@
18#include <linux/clkdev.h> 18#include <linux/clkdev.h>
19 19
20/** 20/**
21 * struct dpll_data - DPLL registers and integration data
22 * @mult_div1_reg: register containing the DPLL M and N bitfields
23 * @mult_mask: mask of the DPLL M bitfield in @mult_div1_reg
24 * @div1_mask: mask of the DPLL N bitfield in @mult_div1_reg
25 * @clk_bypass: struct clk pointer to the clock's bypass clock input
26 * @clk_ref: struct clk pointer to the clock's reference clock input
27 * @control_reg: register containing the DPLL mode bitfield
28 * @enable_mask: mask of the DPLL mode bitfield in @control_reg
29 * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate()
30 * @last_rounded_m: cache of the last M result of omap2_dpll_round_rate()
31 * @last_rounded_m4xen: cache of the last M4X result of
32 * omap4_dpll_regm4xen_round_rate()
33 * @last_rounded_lpmode: cache of the last lpmode result of
34 * omap4_dpll_lpmode_recalc()
35 * @max_multiplier: maximum valid non-bypass multiplier value (actual)
36 * @last_rounded_n: cache of the last N result of omap2_dpll_round_rate()
37 * @min_divider: minimum valid non-bypass divider value (actual)
38 * @max_divider: maximum valid non-bypass divider value (actual)
39 * @modes: possible values of @enable_mask
40 * @autoidle_reg: register containing the DPLL autoidle mode bitfield
41 * @idlest_reg: register containing the DPLL idle status bitfield
42 * @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg
43 * @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg
44 * @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg
45 * @lpmode_mask: mask of the DPLL low-power mode bitfield in @control_reg
46 * @m4xen_mask: mask of the DPLL M4X multiplier bitfield in @control_reg
47 * @auto_recal_bit: bitshift of the driftguard enable bit in @control_reg
48 * @recal_en_bit: bitshift of the PRM_IRQENABLE_* bit for recalibration IRQs
49 * @recal_st_bit: bitshift of the PRM_IRQSTATUS_* bit for recalibration IRQs
50 * @flags: DPLL type/features (see below)
51 *
52 * Possible values for @flags:
53 * DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs)
54 *
55 * @freqsel_mask is only used on the OMAP34xx family and AM35xx.
56 *
57 * XXX Some DPLLs have multiple bypass inputs, so it's not technically
58 * correct to only have one @clk_bypass pointer.
59 *
60 * XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m,
61 * @last_rounded_n) should be separated from the runtime-fixed fields
62 * and placed into a different structure, so that the runtime-fixed data
63 * can be placed into read-only space.
64 */
65struct dpll_data {
66 void __iomem *mult_div1_reg;
67 u32 mult_mask;
68 u32 div1_mask;
69 struct clk *clk_bypass;
70 struct clk *clk_ref;
71 void __iomem *control_reg;
72 u32 enable_mask;
73 unsigned long last_rounded_rate;
74 u16 last_rounded_m;
75 u8 last_rounded_m4xen;
76 u8 last_rounded_lpmode;
77 u16 max_multiplier;
78 u8 last_rounded_n;
79 u8 min_divider;
80 u16 max_divider;
81 u8 modes;
82 void __iomem *autoidle_reg;
83 void __iomem *idlest_reg;
84 u32 autoidle_mask;
85 u32 freqsel_mask;
86 u32 idlest_mask;
87 u32 dco_mask;
88 u32 sddiv_mask;
89 u32 lpmode_mask;
90 u32 m4xen_mask;
91 u8 auto_recal_bit;
92 u8 recal_en_bit;
93 u8 recal_st_bit;
94 u8 flags;
95};
96
97struct clk_hw_omap_ops;
98
99/**
100 * struct clk_hw_omap - OMAP struct clk
101 * @node: list_head connecting this clock into the full clock list
102 * @enable_reg: register to write to enable the clock (see @enable_bit)
103 * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
104 * @flags: see "struct clk.flags possibilities" above
105 * @clksel_reg: for clksel clks, register va containing src/divisor select
106 * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
107 * @clksel: for clksel clks, pointer to struct clksel for this clock
108 * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
109 * @clkdm_name: clockdomain name that this clock is contained in
110 * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
111 * @ops: clock ops for this clock
112 */
113struct clk_hw_omap {
114 struct clk_hw hw;
115 struct list_head node;
116 unsigned long fixed_rate;
117 u8 fixed_div;
118 void __iomem *enable_reg;
119 u8 enable_bit;
120 u8 flags;
121 void __iomem *clksel_reg;
122 u32 clksel_mask;
123 const struct clksel *clksel;
124 struct dpll_data *dpll_data;
125 const char *clkdm_name;
126 struct clockdomain *clkdm;
127 const struct clk_hw_omap_ops *ops;
128};
129
130/*
131 * struct clk_hw_omap.flags possibilities
132 *
133 * XXX document the rest of the clock flags here
134 *
135 * ENABLE_REG_32BIT: (OMAP1 only) clock control register must be accessed
136 * with 32bit ops, by default OMAP1 uses 16bit ops.
137 * CLOCK_IDLE_CONTROL: (OMAP1 only) clock has autoidle support.
138 * CLOCK_NO_IDLE_PARENT: (OMAP1 only) when clock is enabled, its parent
139 * clock is put to no-idle mode.
140 * ENABLE_ON_INIT: Clock is enabled on init.
141 * INVERT_ENABLE: By default, clock enable bit behavior is '1' enable, '0'
142 * disable. This inverts the behavior making '0' enable and '1' disable.
143 * CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL
144 * bits share the same register. This flag allows the
145 * omap4_dpllmx*() code to determine which GATE_CTRL bit field
146 * should be used. This is a temporary solution - a better approach
147 * would be to associate clock type-specific data with the clock,
148 * similar to the struct dpll_data approach.
149 * MEMMAP_ADDRESSING: Use memmap addressing to access clock registers.
150 */
151#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */
152#define CLOCK_IDLE_CONTROL (1 << 1)
153#define CLOCK_NO_IDLE_PARENT (1 << 2)
154#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */
155#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */
156#define CLOCK_CLKOUTX2 (1 << 5)
157#define MEMMAP_ADDRESSING (1 << 6)
158
159/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */
160#define DPLL_LOW_POWER_STOP 0x1
161#define DPLL_LOW_POWER_BYPASS 0x5
162#define DPLL_LOCKED 0x7
163
164/* DPLL Type and DCO Selection Flags */
165#define DPLL_J_TYPE 0x1
166
167/**
21 * struct ti_dt_clk - OMAP DT clock alias declarations 168 * struct ti_dt_clk - OMAP DT clock alias declarations
22 * @lk: clock lookup definition 169 * @lk: clock lookup definition
23 * @node_name: clock DT node to map to 170 * @node_name: clock DT node to map to
@@ -68,10 +215,35 @@ struct ti_clk_ll_ops {
68 215
69extern struct ti_clk_ll_ops *ti_clk_ll_ops; 216extern struct ti_clk_ll_ops *ti_clk_ll_ops;
70 217
218#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
219
220void omap2_init_clk_hw_omap_clocks(struct clk *clk);
221int omap3_noncore_dpll_enable(struct clk_hw *hw);
222void omap3_noncore_dpll_disable(struct clk_hw *hw);
223int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
224 unsigned long parent_rate);
225unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
226 unsigned long parent_rate);
227long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
228 unsigned long target_rate,
229 unsigned long *parent_rate);
230u8 omap2_init_dpll_parent(struct clk_hw *hw);
231unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate);
232long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
233 unsigned long *parent_rate);
234void omap2_init_clk_clkdm(struct clk_hw *clk);
235unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
236 unsigned long parent_rate);
237int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,
238 unsigned long parent_rate);
239
71void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index); 240void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
72void ti_dt_clocks_register(struct ti_dt_clk *oclks); 241void ti_dt_clocks_register(struct ti_dt_clk *oclks);
73void ti_dt_clk_init_provider(struct device_node *np, int index); 242void ti_dt_clk_init_provider(struct device_node *np, int index);
74int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw, 243int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
75 ti_of_clk_init_cb_t func); 244 ti_of_clk_init_cb_t func);
76 245
246extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;
247extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
248
77#endif 249#endif