aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/clock/ti/dpll.txt9
-rw-r--r--arch/arm/mach-omap2/clock.h1
-rw-r--r--arch/arm/mach-omap2/clock2xxx.h4
-rw-r--r--drivers/clk/ti/dpll.c78
-rw-r--r--include/linux/clk/ti.h6
5 files changed, 82 insertions, 16 deletions
diff --git a/Documentation/devicetree/bindings/clock/ti/dpll.txt b/Documentation/devicetree/bindings/clock/ti/dpll.txt
index 30bfdb7c9f18..50a1a427608f 100644
--- a/Documentation/devicetree/bindings/clock/ti/dpll.txt
+++ b/Documentation/devicetree/bindings/clock/ti/dpll.txt
@@ -30,6 +30,7 @@ Required properties:
30 "ti,am3-dpll-clock", 30 "ti,am3-dpll-clock",
31 "ti,am3-dpll-core-clock", 31 "ti,am3-dpll-core-clock",
32 "ti,am3-dpll-x2-clock", 32 "ti,am3-dpll-x2-clock",
33 "ti,omap2-dpll-core-clock",
33 34
34- #clock-cells : from common clock binding; shall be set to 0. 35- #clock-cells : from common clock binding; shall be set to 0.
35- clocks : link phandles of parent clocks, first entry lists reference clock 36- clocks : link phandles of parent clocks, first entry lists reference clock
@@ -41,6 +42,7 @@ Required properties:
41 "mult-div1" - contains the multiplier / divider register base address 42 "mult-div1" - contains the multiplier / divider register base address
42 "autoidle" - contains the autoidle register base address (optional) 43 "autoidle" - contains the autoidle register base address (optional)
43 ti,am3-* dpll types do not have autoidle register 44 ti,am3-* dpll types do not have autoidle register
45 ti,omap2-* dpll type does not support idlest / autoidle registers
44 46
45Optional properties: 47Optional properties:
46- DPLL mode setting - defining any one or more of the following overrides 48- DPLL mode setting - defining any one or more of the following overrides
@@ -73,3 +75,10 @@ Examples:
73 clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; 75 clocks = <&sys_clkin_ck>, <&sys_clkin_ck>;
74 reg = <0x90>, <0x5c>, <0x68>; 76 reg = <0x90>, <0x5c>, <0x68>;
75 }; 77 };
78
79 dpll_ck: dpll_ck {
80 #clock-cells = <0>;
81 compatible = "ti,omap2-dpll-core-clock";
82 clocks = <&sys_ck>, <&sys_ck>;
83 reg = <0x0500>, <0x0540>;
84 };
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index bda767a9dea8..f6e9904d7a75 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -279,7 +279,6 @@ extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait;
279extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; 279extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait;
280extern const struct clk_hw_omap_ops clkhwops_apll54; 280extern const struct clk_hw_omap_ops clkhwops_apll54;
281extern const struct clk_hw_omap_ops clkhwops_apll96; 281extern const struct clk_hw_omap_ops clkhwops_apll96;
282extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll;
283extern const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait; 282extern const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait;
284 283
285/* clksel_rate blocks shared between OMAP44xx and AM33xx */ 284/* clksel_rate blocks shared between OMAP44xx and AM33xx */
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index 539dc08afbba..45f41a411603 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -21,10 +21,6 @@ unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
21 unsigned long parent_rate); 21 unsigned long parent_rate);
22unsigned long omap2_osc_clk_recalc(struct clk_hw *clk, 22unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,
23 unsigned long parent_rate); 23 unsigned long parent_rate);
24unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
25 unsigned long parent_rate);
26int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
27 unsigned long parent_rate);
28void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw); 24void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
29unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw, 25unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
30 unsigned long parent_rate); 26 unsigned long parent_rate);
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index dda262db42ea..34e233990212 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -35,21 +35,18 @@ static const struct clk_ops dpll_m4xen_ck_ops = {
35 .set_rate = &omap3_noncore_dpll_set_rate, 35 .set_rate = &omap3_noncore_dpll_set_rate,
36 .get_parent = &omap2_init_dpll_parent, 36 .get_parent = &omap2_init_dpll_parent,
37}; 37};
38#else
39static const struct clk_ops dpll_m4xen_ck_ops = {};
38#endif 40#endif
39 41
42#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) || \
43 defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) || \
44 defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
40static const struct clk_ops dpll_core_ck_ops = { 45static const struct clk_ops dpll_core_ck_ops = {
41 .recalc_rate = &omap3_dpll_recalc, 46 .recalc_rate = &omap3_dpll_recalc,
42 .get_parent = &omap2_init_dpll_parent, 47 .get_parent = &omap2_init_dpll_parent,
43}; 48};
44 49
45#ifdef CONFIG_ARCH_OMAP3
46static const struct clk_ops omap3_dpll_core_ck_ops = {
47 .get_parent = &omap2_init_dpll_parent,
48 .recalc_rate = &omap3_dpll_recalc,
49 .round_rate = &omap2_dpll_round_rate,
50};
51#endif
52
53static const struct clk_ops dpll_ck_ops = { 50static const struct clk_ops dpll_ck_ops = {
54 .enable = &omap3_noncore_dpll_enable, 51 .enable = &omap3_noncore_dpll_enable,
55 .disable = &omap3_noncore_dpll_disable, 52 .disable = &omap3_noncore_dpll_disable,
@@ -65,6 +62,33 @@ static const struct clk_ops dpll_no_gate_ck_ops = {
65 .round_rate = &omap2_dpll_round_rate, 62 .round_rate = &omap2_dpll_round_rate,
66 .set_rate = &omap3_noncore_dpll_set_rate, 63 .set_rate = &omap3_noncore_dpll_set_rate,
67}; 64};
65#else
66static const struct clk_ops dpll_core_ck_ops = {};
67static const struct clk_ops dpll_ck_ops = {};
68static const struct clk_ops dpll_no_gate_ck_ops = {};
69const struct clk_hw_omap_ops clkhwops_omap3_dpll = {};
70#endif
71
72#ifdef CONFIG_ARCH_OMAP2
73static const struct clk_ops omap2_dpll_core_ck_ops = {
74 .get_parent = &omap2_init_dpll_parent,
75 .recalc_rate = &omap2_dpllcore_recalc,
76 .round_rate = &omap2_dpll_round_rate,
77 .set_rate = &omap2_reprogram_dpllcore,
78};
79#else
80static const struct clk_ops omap2_dpll_core_ck_ops = {};
81#endif
82
83#ifdef CONFIG_ARCH_OMAP3
84static const struct clk_ops omap3_dpll_core_ck_ops = {
85 .get_parent = &omap2_init_dpll_parent,
86 .recalc_rate = &omap3_dpll_recalc,
87 .round_rate = &omap2_dpll_round_rate,
88};
89#else
90static const struct clk_ops omap3_dpll_core_ck_ops = {};
91#endif
68 92
69#ifdef CONFIG_ARCH_OMAP3 93#ifdef CONFIG_ARCH_OMAP3
70static const struct clk_ops omap3_dpll_ck_ops = { 94static const struct clk_ops omap3_dpll_ck_ops = {
@@ -237,10 +261,27 @@ static void __init of_ti_dpll_setup(struct device_node *node,
237 init->parent_names = parent_names; 261 init->parent_names = parent_names;
238 262
239 dd->control_reg = ti_clk_get_reg_addr(node, 0); 263 dd->control_reg = ti_clk_get_reg_addr(node, 0);
240 dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
241 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
242 264
243 if (!dd->control_reg || !dd->idlest_reg || !dd->mult_div1_reg) 265 /*
266 * Special case for OMAP2 DPLL, register order is different due to
267 * missing idlest_reg, also clkhwops is different. Detected from
268 * missing idlest_mask.
269 */
270 if (!dd->idlest_mask) {
271 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 1);
272#ifdef CONFIG_ARCH_OMAP2
273 clk_hw->ops = &clkhwops_omap2xxx_dpll;
274 omap2xxx_clkt_dpllcore_init(&clk_hw->hw);
275#endif
276 } else {
277 dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
278 if (!dd->idlest_reg)
279 goto cleanup;
280
281 dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
282 }
283
284 if (!dd->control_reg || !dd->mult_div1_reg)
244 goto cleanup; 285 goto cleanup;
245 286
246 if (dd->autoidle_mask) { 287 if (dd->autoidle_mask) {
@@ -547,3 +588,18 @@ static void __init of_ti_am3_core_dpll_setup(struct device_node *node)
547} 588}
548CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock", 589CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock",
549 of_ti_am3_core_dpll_setup); 590 of_ti_am3_core_dpll_setup);
591
592static void __init of_ti_omap2_core_dpll_setup(struct device_node *node)
593{
594 const struct dpll_data dd = {
595 .enable_mask = 0x3,
596 .mult_mask = 0x3ff << 12,
597 .div1_mask = 0xf << 8,
598 .max_divider = 16,
599 .min_divider = 1,
600 };
601
602 of_ti_dpll_setup(node, &omap2_dpll_core_ck_ops, &dd);
603}
604CLK_OF_DECLARE(ti_omap2_core_dpll_clock, "ti,omap2-dpll-core-clock",
605 of_ti_omap2_core_dpll_setup);
diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
index 4a21a872dbbd..753878c6fa52 100644
--- a/include/linux/clk/ti.h
+++ b/include/linux/clk/ti.h
@@ -259,6 +259,11 @@ int omap2_dflt_clk_enable(struct clk_hw *hw);
259void omap2_dflt_clk_disable(struct clk_hw *hw); 259void omap2_dflt_clk_disable(struct clk_hw *hw);
260int omap2_dflt_clk_is_enabled(struct clk_hw *hw); 260int omap2_dflt_clk_is_enabled(struct clk_hw *hw);
261void omap3_clk_lock_dpll5(void); 261void omap3_clk_lock_dpll5(void);
262unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
263 unsigned long parent_rate);
264int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
265 unsigned long parent_rate);
266void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
262 267
263void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index); 268void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
264void ti_dt_clocks_register(struct ti_dt_clk *oclks); 269void ti_dt_clocks_register(struct ti_dt_clk *oclks);
@@ -287,6 +292,7 @@ static inline void of_ti_clk_allow_autoidle_all(void) { }
287static inline void of_ti_clk_deny_autoidle_all(void) { } 292static inline void of_ti_clk_deny_autoidle_all(void) { }
288#endif 293#endif
289 294
295extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll;
290extern const struct clk_hw_omap_ops clkhwops_omap3_dpll; 296extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;
291extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; 297extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
292extern const struct clk_hw_omap_ops clkhwops_wait; 298extern const struct clk_hw_omap_ops clkhwops_wait;