diff options
-rw-r--r-- | Documentation/devicetree/bindings/clock/ti/dpll.txt | 9 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock2xxx.h | 4 | ||||
-rw-r--r-- | drivers/clk/ti/dpll.c | 78 | ||||
-rw-r--r-- | include/linux/clk/ti.h | 6 |
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 | ||
45 | Optional properties: | 47 | Optional 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; | |||
279 | extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; | 279 | extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; |
280 | extern const struct clk_hw_omap_ops clkhwops_apll54; | 280 | extern const struct clk_hw_omap_ops clkhwops_apll54; |
281 | extern const struct clk_hw_omap_ops clkhwops_apll96; | 281 | extern const struct clk_hw_omap_ops clkhwops_apll96; |
282 | extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll; | ||
283 | extern const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait; | 282 | extern 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); |
22 | unsigned long omap2_osc_clk_recalc(struct clk_hw *clk, | 22 | unsigned long omap2_osc_clk_recalc(struct clk_hw *clk, |
23 | unsigned long parent_rate); | 23 | unsigned long parent_rate); |
24 | unsigned long omap2_dpllcore_recalc(struct clk_hw *hw, | ||
25 | unsigned long parent_rate); | ||
26 | int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate, | ||
27 | unsigned long parent_rate); | ||
28 | void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw); | 24 | void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw); |
29 | unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw, | 25 | unsigned 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 | ||
39 | static 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) | ||
40 | static const struct clk_ops dpll_core_ck_ops = { | 45 | static 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 | ||
46 | static 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 | |||
53 | static const struct clk_ops dpll_ck_ops = { | 50 | static 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 | ||
66 | static const struct clk_ops dpll_core_ck_ops = {}; | ||
67 | static const struct clk_ops dpll_ck_ops = {}; | ||
68 | static const struct clk_ops dpll_no_gate_ck_ops = {}; | ||
69 | const struct clk_hw_omap_ops clkhwops_omap3_dpll = {}; | ||
70 | #endif | ||
71 | |||
72 | #ifdef CONFIG_ARCH_OMAP2 | ||
73 | static 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 | ||
80 | static const struct clk_ops omap2_dpll_core_ck_ops = {}; | ||
81 | #endif | ||
82 | |||
83 | #ifdef CONFIG_ARCH_OMAP3 | ||
84 | static 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 | ||
90 | static const struct clk_ops omap3_dpll_core_ck_ops = {}; | ||
91 | #endif | ||
68 | 92 | ||
69 | #ifdef CONFIG_ARCH_OMAP3 | 93 | #ifdef CONFIG_ARCH_OMAP3 |
70 | static const struct clk_ops omap3_dpll_ck_ops = { | 94 | static 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 | } |
548 | CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock", | 589 | CLK_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 | |||
592 | static 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 | } | ||
604 | CLK_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); | |||
259 | void omap2_dflt_clk_disable(struct clk_hw *hw); | 259 | void omap2_dflt_clk_disable(struct clk_hw *hw); |
260 | int omap2_dflt_clk_is_enabled(struct clk_hw *hw); | 260 | int omap2_dflt_clk_is_enabled(struct clk_hw *hw); |
261 | void omap3_clk_lock_dpll5(void); | 261 | void omap3_clk_lock_dpll5(void); |
262 | unsigned long omap2_dpllcore_recalc(struct clk_hw *hw, | ||
263 | unsigned long parent_rate); | ||
264 | int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate, | ||
265 | unsigned long parent_rate); | ||
266 | void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw); | ||
262 | 267 | ||
263 | void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index); | 268 | void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index); |
264 | void ti_dt_clocks_register(struct ti_dt_clk *oclks); | 269 | void ti_dt_clocks_register(struct ti_dt_clk *oclks); |
@@ -287,6 +292,7 @@ static inline void of_ti_clk_allow_autoidle_all(void) { } | |||
287 | static inline void of_ti_clk_deny_autoidle_all(void) { } | 292 | static inline void of_ti_clk_deny_autoidle_all(void) { } |
288 | #endif | 293 | #endif |
289 | 294 | ||
295 | extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll; | ||
290 | extern const struct clk_hw_omap_ops clkhwops_omap3_dpll; | 296 | extern const struct clk_hw_omap_ops clkhwops_omap3_dpll; |
291 | extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; | 297 | extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; |
292 | extern const struct clk_hw_omap_ops clkhwops_wait; | 298 | extern const struct clk_hw_omap_ops clkhwops_wait; |