aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/ti/dpll.c
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2015-01-29 15:24:28 -0500
committerMichael Turquette <mturquette@linaro.org>2015-01-30 13:55:09 -0500
commited405a2350646a940966f471ae705fa2d81eee65 (patch)
treee35f9ce7fa7d0bb91f90580093a2b0e488d6c4a7 /drivers/clk/ti/dpll.c
parentd96f774b25386a7a71c799bbf55b69c27129e454 (diff)
clk: ti: dpll: add support for legacy DPLL init
Legacy clock data is initialized slightly differently compared to DT clocks, thus add support for this. Signed-off-by: Tero Kristo <t-kristo@ti.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Michael Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk/ti/dpll.c')
-rw-r--r--drivers/clk/ti/dpll.c119
1 files changed, 108 insertions, 11 deletions
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 85ac0dd501de..47ebff772b13 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -21,6 +21,7 @@
21#include <linux/of.h> 21#include <linux/of.h>
22#include <linux/of_address.h> 22#include <linux/of_address.h>
23#include <linux/clk/ti.h> 23#include <linux/clk/ti.h>
24#include "clock.h"
24 25
25#undef pr_fmt 26#undef pr_fmt
26#define pr_fmt(fmt) "%s: " fmt, __func__ 27#define pr_fmt(fmt) "%s: " fmt, __func__
@@ -130,7 +131,7 @@ static const struct clk_ops dpll_x2_ck_ops = {
130}; 131};
131 132
132/** 133/**
133 * ti_clk_register_dpll - low level registration of a DPLL clock 134 * _register_dpll - low level registration of a DPLL clock
134 * @hw: hardware clock definition for the clock 135 * @hw: hardware clock definition for the clock
135 * @node: device node for the clock 136 * @node: device node for the clock
136 * 137 *
@@ -138,8 +139,8 @@ static const struct clk_ops dpll_x2_ck_ops = {
138 * clk-bypass is missing), the clock is added to retry list and 139 * clk-bypass is missing), the clock is added to retry list and
139 * the initialization is retried on later stage. 140 * the initialization is retried on later stage.
140 */ 141 */
141static void __init ti_clk_register_dpll(struct clk_hw *hw, 142static void __init _register_dpll(struct clk_hw *hw,
142 struct device_node *node) 143 struct device_node *node)
143{ 144{
144 struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw); 145 struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw);
145 struct dpll_data *dd = clk_hw->dpll_data; 146 struct dpll_data *dd = clk_hw->dpll_data;
@@ -151,7 +152,7 @@ static void __init ti_clk_register_dpll(struct clk_hw *hw,
151 if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) { 152 if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) {
152 pr_debug("clk-ref or clk-bypass missing for %s, retry later\n", 153 pr_debug("clk-ref or clk-bypass missing for %s, retry later\n",
153 node->name); 154 node->name);
154 if (!ti_clk_retry_init(node, hw, ti_clk_register_dpll)) 155 if (!ti_clk_retry_init(node, hw, _register_dpll))
155 return; 156 return;
156 157
157 goto cleanup; 158 goto cleanup;
@@ -175,20 +176,116 @@ cleanup:
175 kfree(clk_hw); 176 kfree(clk_hw);
176} 177}
177 178
179void __iomem *_get_reg(u8 module, u16 offset)
180{
181 u32 reg;
182 struct clk_omap_reg *reg_setup;
183
184 reg_setup = (struct clk_omap_reg *)&reg;
185
186 reg_setup->index = module;
187 reg_setup->offset = offset;
188
189 return (void __iomem *)reg;
190}
191
192struct clk *ti_clk_register_dpll(struct ti_clk *setup)
193{
194 struct clk_hw_omap *clk_hw;
195 struct clk_init_data init = { NULL };
196 struct dpll_data *dd;
197 struct clk *clk;
198 struct ti_clk_dpll *dpll;
199 const struct clk_ops *ops = &omap3_dpll_ck_ops;
200 struct clk *clk_ref;
201 struct clk *clk_bypass;
202
203 dpll = setup->data;
204
205 if (dpll->num_parents < 2)
206 return ERR_PTR(-EINVAL);
207
208 clk_ref = clk_get_sys(NULL, dpll->parents[0]);
209 clk_bypass = clk_get_sys(NULL, dpll->parents[1]);
210
211 if (IS_ERR_OR_NULL(clk_ref) || IS_ERR_OR_NULL(clk_bypass))
212 return ERR_PTR(-EAGAIN);
213
214 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
215 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
216 if (!dd || !clk_hw) {
217 clk = ERR_PTR(-ENOMEM);
218 goto cleanup;
219 }
220
221 clk_hw->dpll_data = dd;
222 clk_hw->ops = &clkhwops_omap3_dpll;
223 clk_hw->hw.init = &init;
224 clk_hw->flags = MEMMAP_ADDRESSING;
225
226 init.name = setup->name;
227 init.ops = ops;
228
229 init.num_parents = dpll->num_parents;
230 init.parent_names = dpll->parents;
231
232 dd->control_reg = _get_reg(dpll->module, dpll->control_reg);
233 dd->idlest_reg = _get_reg(dpll->module, dpll->idlest_reg);
234 dd->mult_div1_reg = _get_reg(dpll->module, dpll->mult_div1_reg);
235 dd->autoidle_reg = _get_reg(dpll->module, dpll->autoidle_reg);
236
237 dd->modes = dpll->modes;
238 dd->div1_mask = dpll->div1_mask;
239 dd->idlest_mask = dpll->idlest_mask;
240 dd->mult_mask = dpll->mult_mask;
241 dd->autoidle_mask = dpll->autoidle_mask;
242 dd->enable_mask = dpll->enable_mask;
243 dd->sddiv_mask = dpll->sddiv_mask;
244 dd->dco_mask = dpll->dco_mask;
245 dd->max_divider = dpll->max_divider;
246 dd->min_divider = dpll->min_divider;
247 dd->max_multiplier = dpll->max_multiplier;
248 dd->auto_recal_bit = dpll->auto_recal_bit;
249 dd->recal_en_bit = dpll->recal_en_bit;
250 dd->recal_st_bit = dpll->recal_st_bit;
251
252 dd->clk_ref = clk_ref;
253 dd->clk_bypass = clk_bypass;
254
255 if (dpll->flags & CLKF_CORE)
256 ops = &omap3_dpll_core_ck_ops;
257
258 if (dpll->flags & CLKF_PER)
259 ops = &omap3_dpll_per_ck_ops;
260
261 if (dpll->flags & CLKF_J_TYPE)
262 dd->flags |= DPLL_J_TYPE;
263
264 clk = clk_register(NULL, &clk_hw->hw);
265
266 if (!IS_ERR(clk))
267 return clk;
268
269cleanup:
270 kfree(dd);
271 kfree(clk_hw);
272 return clk;
273}
274
178#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ 275#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
179 defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \ 276 defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM33XX) || \
180 defined(CONFIG_SOC_AM43XX) 277 defined(CONFIG_SOC_AM43XX)
181/** 278/**
182 * ti_clk_register_dpll_x2 - Registers a DPLLx2 clock 279 * _register_dpll_x2 - Registers a DPLLx2 clock
183 * @node: device node for this clock 280 * @node: device node for this clock
184 * @ops: clk_ops for this clock 281 * @ops: clk_ops for this clock
185 * @hw_ops: clk_hw_ops for this clock 282 * @hw_ops: clk_hw_ops for this clock
186 * 283 *
187 * Initializes a DPLL x 2 clock from device tree data. 284 * Initializes a DPLL x 2 clock from device tree data.
188 */ 285 */
189static void ti_clk_register_dpll_x2(struct device_node *node, 286static void _register_dpll_x2(struct device_node *node,
190 const struct clk_ops *ops, 287 const struct clk_ops *ops,
191 const struct clk_hw_omap_ops *hw_ops) 288 const struct clk_hw_omap_ops *hw_ops)
192{ 289{
193 struct clk *clk; 290 struct clk *clk;
194 struct clk_init_data init = { NULL }; 291 struct clk_init_data init = { NULL };
@@ -318,7 +415,7 @@ static void __init of_ti_dpll_setup(struct device_node *node,
318 if (dpll_mode) 415 if (dpll_mode)
319 dd->modes = dpll_mode; 416 dd->modes = dpll_mode;
320 417
321 ti_clk_register_dpll(&clk_hw->hw, node); 418 _register_dpll(&clk_hw->hw, node);
322 return; 419 return;
323 420
324cleanup: 421cleanup:
@@ -332,7 +429,7 @@ cleanup:
332 defined(CONFIG_SOC_DRA7XX) 429 defined(CONFIG_SOC_DRA7XX)
333static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node) 430static void __init of_ti_omap4_dpll_x2_setup(struct device_node *node)
334{ 431{
335 ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx); 432 _register_dpll_x2(node, &dpll_x2_ck_ops, &clkhwops_omap4_dpllmx);
336} 433}
337CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock", 434CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
338 of_ti_omap4_dpll_x2_setup); 435 of_ti_omap4_dpll_x2_setup);
@@ -341,7 +438,7 @@ CLK_OF_DECLARE(ti_omap4_dpll_x2_clock, "ti,omap4-dpll-x2-clock",
341#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) 438#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
342static void __init of_ti_am3_dpll_x2_setup(struct device_node *node) 439static void __init of_ti_am3_dpll_x2_setup(struct device_node *node)
343{ 440{
344 ti_clk_register_dpll_x2(node, &dpll_x2_ck_ops, NULL); 441 _register_dpll_x2(node, &dpll_x2_ck_ops, NULL);
345} 442}
346CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock", 443CLK_OF_DECLARE(ti_am3_dpll_x2_clock, "ti,am3-dpll-x2-clock",
347 of_ti_am3_dpll_x2_setup); 444 of_ti_am3_dpll_x2_setup);