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; |
