Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Tero Kristo and committed by
Mike Turquette
f38b0dd6 819b4861

+807 -165
+75
Documentation/devicetree/bindings/clock/ti/dpll.txt
··· 1 + Binding for Texas Instruments DPLL clock. 2 + 3 + Binding status: Unstable - ABI compatibility may be broken in the future 4 + 5 + This binding uses the common clock binding[1]. It assumes a 6 + register-mapped DPLL with usually two selectable input clocks 7 + (reference clock and bypass clock), with digital phase locked 8 + loop logic for multiplying the input clock to a desired output 9 + clock. This clock also typically supports different operation 10 + modes (locked, low power stop etc.) This binding has several 11 + sub-types, which effectively result in slightly different setup 12 + for the actual DPLL clock. 13 + 14 + [1] Documentation/devicetree/bindings/clock/clock-bindings.txt 15 + 16 + Required 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 + 45 + Optional 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 + 52 + Examples: 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 + };
+1 -163
arch/arm/mach-omap2/clock.h
··· 21 21 22 22 #include <linux/clkdev.h> 23 23 #include <linux/clk-provider.h> 24 + #include <linux/clk/ti.h> 24 25 25 26 struct omap_clk { 26 27 u16 cpu; ··· 38 37 } 39 38 40 39 struct clockdomain; 41 - #define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw) 42 40 43 41 #define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \ 44 42 static struct clk _name = { \ ··· 178 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 181 struct clk_hw_omap_ops { 317 182 void (*find_idlest)(struct clk_hw_omap *oclk, 318 183 void __iomem **idlest_reg, ··· 213 348 #define OMAP4XXX_EN_DPLL_FRBYPASS 0x6 214 349 #define OMAP4XXX_EN_DPLL_LOCKED 0x7 215 350 216 - /* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */ 217 - #define DPLL_LOW_POWER_STOP 0x1 218 - #define DPLL_LOW_POWER_BYPASS 0x5 219 - #define DPLL_LOCKED 0x7 220 - 221 - /* DPLL Type and DCO Selection Flags */ 222 - #define DPLL_J_TYPE 0x1 223 - 224 - long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, 225 - unsigned long *parent_rate); 226 - unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate); 227 - int omap3_noncore_dpll_enable(struct clk_hw *hw); 228 - void omap3_noncore_dpll_disable(struct clk_hw *hw); 229 - int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, 230 - unsigned long parent_rate); 231 351 u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk); 232 352 void omap3_dpll_allow_idle(struct clk_hw_omap *clk); 233 353 void omap3_dpll_deny_idle(struct clk_hw_omap *clk); 234 - unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, 235 - unsigned long parent_rate); 236 354 int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk); 237 355 void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk); 238 356 void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk); 239 - unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, 240 - unsigned long parent_rate); 241 - long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, 242 - unsigned long target_rate, 243 - unsigned long *parent_rate); 244 357 245 - void omap2_init_clk_clkdm(struct clk_hw *clk); 246 358 void __init omap2_clk_disable_clkdm_control(void); 247 359 248 360 /* clkt_clksel.c public functions */ ··· 238 396 extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk); 239 397 extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk); 240 398 241 - u8 omap2_init_dpll_parent(struct clk_hw *hw); 242 399 unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk); 243 400 244 401 int omap2_dflt_clk_enable(struct clk_hw *hw); ··· 249 408 void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, 250 409 void __iomem **idlest_reg, 251 410 u8 *idlest_bit, u8 *idlest_val); 252 - void omap2_init_clk_hw_omap_clocks(struct clk *clk); 253 411 int omap2_clk_enable_autoidle_all(void); 254 412 int omap2_clk_disable_autoidle_all(void); 255 413 int omap2_clk_allow_idle(struct clk *clk); ··· 273 433 extern const struct clksel_rate dsp_ick_rates[]; 274 434 extern struct clk dummy_ck; 275 435 276 - extern const struct clk_hw_omap_ops clkhwops_omap3_dpll; 277 436 extern const struct clk_hw_omap_ops clkhwops_iclk_wait; 278 437 extern const struct clk_hw_omap_ops clkhwops_wait; 279 - extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; 280 438 extern const struct clk_hw_omap_ops clkhwops_iclk; 281 439 extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait; 282 440 extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait;
-2
arch/arm/mach-omap2/clock3xxx.h
··· 9 9 #define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H 10 10 11 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 12 int omap3_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate, 15 13 unsigned long parent_rate); 16 14 void omap3_clk_lock_dpll5(void);
+1
drivers/clk/ti/Makefile
··· 1 1 ifneq ($(CONFIG_OF),) 2 2 obj-y += clk.o 3 + clk-common = dpll.o 3 4 endif
+558
drivers/clk/ti/dpll.c
··· 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) 32 + static 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 + 42 + static 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 48 + static 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 + 55 + static 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 + 64 + static 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 72 + static 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 + 81 + static 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 + 91 + static 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 + */ 104 + static 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 + 134 + cleanup: 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 + */ 151 + static 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 + */ 200 + static 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 + 271 + cleanup: 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) 280 + static 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 + } 284 + CLK_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 289 + static 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 + } 293 + CLK_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 298 + static 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 + } 315 + CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock", 316 + of_ti_omap3_dpll_setup); 317 + 318 + static 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 + } 334 + CLK_OF_DECLARE(ti_omap3_core_dpll_clock, "ti,omap3-dpll-core-clock", 335 + of_ti_omap3_core_dpll_setup); 336 + 337 + static 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 + } 354 + CLK_OF_DECLARE(ti_omap3_per_dpll_clock, "ti,omap3-dpll-per-clock", 355 + of_ti_omap3_per_dpll_setup); 356 + 357 + static 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 + } 376 + CLK_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 + 380 + static 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 + } 396 + CLK_OF_DECLARE(ti_omap4_dpll_clock, "ti,omap4-dpll-clock", 397 + of_ti_omap4_dpll_setup); 398 + 399 + static 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 + } 415 + CLK_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) 420 + static 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 + } 438 + CLK_OF_DECLARE(ti_omap4_m4xen_dpll_clock, "ti,omap4-dpll-m4xen-clock", 439 + of_ti_omap4_m4xen_dpll_setup); 440 + 441 + static 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 + } 459 + CLK_OF_DECLARE(ti_omap4_jtype_dpll_clock, "ti,omap4-dpll-j-type-clock", 460 + of_ti_omap4_jtype_dpll_setup); 461 + #endif 462 + 463 + static 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 + } 479 + CLK_OF_DECLARE(ti_am3_no_gate_dpll_clock, "ti,am3-dpll-no-gate-clock", 480 + of_ti_am3_no_gate_dpll_setup); 481 + 482 + static 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 + } 499 + CLK_OF_DECLARE(ti_am3_jtype_dpll_clock, "ti,am3-dpll-j-type-clock", 500 + of_ti_am3_jtype_dpll_setup); 501 + 502 + static 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 + } 519 + CLK_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 + 523 + static 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 + } 539 + CLK_OF_DECLARE(ti_am3_dpll_clock, "ti,am3-dpll-clock", of_ti_am3_dpll_setup); 540 + 541 + static 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 + } 557 + CLK_OF_DECLARE(ti_am3_core_dpll_clock, "ti,am3-dpll-core-clock", 558 + of_ti_am3_core_dpll_setup);
+172
include/linux/clk/ti.h
··· 18 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 + */ 65 + struct 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 + 97 + struct 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 + */ 113 + struct 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 168 * struct ti_dt_clk - OMAP DT clock alias declarations 22 169 * @lk: clock lookup definition 23 170 * @node_name: clock DT node to map to ··· 215 68 216 69 extern struct ti_clk_ll_ops *ti_clk_ll_ops; 217 70 71 + #define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw) 72 + 73 + void omap2_init_clk_hw_omap_clocks(struct clk *clk); 74 + int omap3_noncore_dpll_enable(struct clk_hw *hw); 75 + void omap3_noncore_dpll_disable(struct clk_hw *hw); 76 + int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, 77 + unsigned long parent_rate); 78 + unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw, 79 + unsigned long parent_rate); 80 + long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw, 81 + unsigned long target_rate, 82 + unsigned long *parent_rate); 83 + u8 omap2_init_dpll_parent(struct clk_hw *hw); 84 + unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate); 85 + long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, 86 + unsigned long *parent_rate); 87 + void omap2_init_clk_clkdm(struct clk_hw *clk); 88 + unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, 89 + unsigned long parent_rate); 90 + int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate, 91 + unsigned long parent_rate); 92 + 218 93 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index); 219 94 void ti_dt_clocks_register(struct ti_dt_clk *oclks); 220 95 void ti_dt_clk_init_provider(struct device_node *np, int index); 221 96 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw, 222 97 ti_of_clk_init_cb_t func); 98 + 99 + extern const struct clk_hw_omap_ops clkhwops_omap3_dpll; 100 + extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx; 223 101 224 102 #endif