blob: d4ef4f47977668b456448458f85f503e7601efce [file] [log] [blame]
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +01001/*
2 * Copyright (C) 2014 STMicroelectronics (R&D) Limited
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 */
10
11/*
12 * Authors:
13 * Stephen Gallimore <stephen.gallimore@st.com>,
14 * Pankaj Dev <pankaj.dev@st.com>.
15 */
16
17#include <linux/slab.h>
18#include <linux/of_address.h>
19#include <linux/clk-provider.h>
20
21#include "clkgen.h"
22
23static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
24
25/*
26 * Common PLL configuration register bits for PLL800 and PLL1600 C65
27 */
28#define C65_MDIV_PLL800_MASK (0xff)
29#define C65_MDIV_PLL1600_MASK (0x7)
30#define C65_NDIV_MASK (0xff)
31#define C65_PDIV_MASK (0x7)
32
33/*
34 * PLL configuration register bits for PLL3200 C32
35 */
36#define C32_NDIV_MASK (0xff)
37#define C32_IDF_MASK (0x7)
38#define C32_ODF_MASK (0x3f)
39#define C32_LDF_MASK (0x7f)
40
41#define C32_MAX_ODFS (4)
42
43struct clkgen_pll_data {
44 struct clkgen_field pdn_status;
45 struct clkgen_field locked_status;
46 struct clkgen_field mdiv;
47 struct clkgen_field ndiv;
48 struct clkgen_field pdiv;
49 struct clkgen_field idf;
50 struct clkgen_field ldf;
51 unsigned int num_odfs;
52 struct clkgen_field odf[C32_MAX_ODFS];
53 struct clkgen_field odf_gate[C32_MAX_ODFS];
54 const struct clk_ops *ops;
55};
56
57static const struct clk_ops st_pll1600c65_ops;
58static const struct clk_ops st_pll800c65_ops;
59static const struct clk_ops stm_pll3200c32_ops;
60static const struct clk_ops st_pll1200c32_ops;
61
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +020062static const struct clkgen_pll_data st_pll1600c65_ax = {
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +010063 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19),
64 .locked_status = CLKGEN_FIELD(0x0, 0x1, 31),
65 .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK, 0),
66 .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8),
67 .ops = &st_pll1600c65_ops
68};
69
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +020070static const struct clkgen_pll_data st_pll800c65_ax = {
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +010071 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19),
72 .locked_status = CLKGEN_FIELD(0x0, 0x1, 31),
73 .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL800_MASK, 0),
74 .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8),
75 .pdiv = CLKGEN_FIELD(0x0, C65_PDIV_MASK, 16),
76 .ops = &st_pll800c65_ops
77};
78
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +020079static const struct clkgen_pll_data st_pll3200c32_a1x_0 = {
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +010080 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 31),
81 .locked_status = CLKGEN_FIELD(0x4, 0x1, 31),
82 .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 0x0),
83 .idf = CLKGEN_FIELD(0x4, C32_IDF_MASK, 0x0),
84 .num_odfs = 4,
85 .odf = { CLKGEN_FIELD(0x54, C32_ODF_MASK, 4),
86 CLKGEN_FIELD(0x54, C32_ODF_MASK, 10),
87 CLKGEN_FIELD(0x54, C32_ODF_MASK, 16),
88 CLKGEN_FIELD(0x54, C32_ODF_MASK, 22) },
89 .odf_gate = { CLKGEN_FIELD(0x54, 0x1, 0),
90 CLKGEN_FIELD(0x54, 0x1, 1),
91 CLKGEN_FIELD(0x54, 0x1, 2),
92 CLKGEN_FIELD(0x54, 0x1, 3) },
93 .ops = &stm_pll3200c32_ops,
94};
95
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +020096static const struct clkgen_pll_data st_pll3200c32_a1x_1 = {
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +010097 .pdn_status = CLKGEN_FIELD(0xC, 0x1, 31),
98 .locked_status = CLKGEN_FIELD(0x10, 0x1, 31),
99 .ndiv = CLKGEN_FIELD(0xC, C32_NDIV_MASK, 0x0),
100 .idf = CLKGEN_FIELD(0x10, C32_IDF_MASK, 0x0),
101 .num_odfs = 4,
102 .odf = { CLKGEN_FIELD(0x58, C32_ODF_MASK, 4),
103 CLKGEN_FIELD(0x58, C32_ODF_MASK, 10),
104 CLKGEN_FIELD(0x58, C32_ODF_MASK, 16),
105 CLKGEN_FIELD(0x58, C32_ODF_MASK, 22) },
106 .odf_gate = { CLKGEN_FIELD(0x58, 0x1, 0),
107 CLKGEN_FIELD(0x58, 0x1, 1),
108 CLKGEN_FIELD(0x58, 0x1, 2),
109 CLKGEN_FIELD(0x58, 0x1, 3) },
110 .ops = &stm_pll3200c32_ops,
111};
112
Gabriel FERNANDEZec8d27b2014-02-27 16:24:18 +0100113/* 415 specific */
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +0200114static const struct clkgen_pll_data st_pll3200c32_a9_415 = {
Gabriel FERNANDEZec8d27b2014-02-27 16:24:18 +0100115 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
116 .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0),
117 .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 9),
118 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 22),
119 .num_odfs = 1,
120 .odf = { CLKGEN_FIELD(0x0, C32_ODF_MASK, 3) },
121 .odf_gate = { CLKGEN_FIELD(0x0, 0x1, 28) },
122 .ops = &stm_pll3200c32_ops,
123};
124
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +0200125static const struct clkgen_pll_data st_pll3200c32_ddr_415 = {
Gabriel FERNANDEZec8d27b2014-02-27 16:24:18 +0100126 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
127 .locked_status = CLKGEN_FIELD(0x100, 0x1, 0),
128 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
129 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
130 .num_odfs = 2,
131 .odf = { CLKGEN_FIELD(0x8, C32_ODF_MASK, 8),
132 CLKGEN_FIELD(0x8, C32_ODF_MASK, 14) },
133 .odf_gate = { CLKGEN_FIELD(0x4, 0x1, 28),
134 CLKGEN_FIELD(0x4, 0x1, 29) },
135 .ops = &stm_pll3200c32_ops,
136};
137
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +0200138static const struct clkgen_pll_data st_pll1200c32_gpu_415 = {
Gabriel FERNANDEZec8d27b2014-02-27 16:24:18 +0100139 .pdn_status = CLKGEN_FIELD(0x144, 0x1, 3),
140 .locked_status = CLKGEN_FIELD(0x168, 0x1, 0),
141 .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3),
142 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0),
143 .num_odfs = 0,
144 .odf = { CLKGEN_FIELD(0x0, C32_ODF_MASK, 10) },
145 .ops = &st_pll1200c32_ops,
146};
147
148/* 416 specific */
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +0200149static const struct clkgen_pll_data st_pll3200c32_a9_416 = {
Gabriel FERNANDEZec8d27b2014-02-27 16:24:18 +0100150 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
151 .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0),
152 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
153 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
154 .num_odfs = 1,
155 .odf = { CLKGEN_FIELD(0x8, C32_ODF_MASK, 8) },
156 .odf_gate = { CLKGEN_FIELD(0x4, 0x1, 28) },
157 .ops = &stm_pll3200c32_ops,
158};
159
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +0200160static const struct clkgen_pll_data st_pll3200c32_ddr_416 = {
Gabriel FERNANDEZec8d27b2014-02-27 16:24:18 +0100161 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
162 .locked_status = CLKGEN_FIELD(0x10C, 0x1, 0),
163 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
164 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
165 .num_odfs = 2,
166 .odf = { CLKGEN_FIELD(0x8, C32_ODF_MASK, 8),
167 CLKGEN_FIELD(0x8, C32_ODF_MASK, 14) },
168 .odf_gate = { CLKGEN_FIELD(0x4, 0x1, 28),
169 CLKGEN_FIELD(0x4, 0x1, 29) },
170 .ops = &stm_pll3200c32_ops,
171};
172
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +0200173static const struct clkgen_pll_data st_pll1200c32_gpu_416 = {
Gabriel FERNANDEZec8d27b2014-02-27 16:24:18 +0100174 .pdn_status = CLKGEN_FIELD(0x8E4, 0x1, 3),
175 .locked_status = CLKGEN_FIELD(0x90C, 0x1, 0),
176 .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3),
177 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0),
178 .num_odfs = 0,
179 .odf = { CLKGEN_FIELD(0x0, C32_ODF_MASK, 10) },
180 .ops = &st_pll1200c32_ops,
181};
182
Gabriel FERNANDEZeee8f782014-07-15 17:20:24 +0200183static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
184 /* 407 A0 */
185 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
186 .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24),
187 .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16),
188 .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0),
189 .num_odfs = 1,
190 .odf = { CLKGEN_FIELD(0x2b4, C32_ODF_MASK, 0) },
191 .odf_gate = { CLKGEN_FIELD(0x2b4, 0x1, 6) },
192 .ops = &stm_pll3200c32_ops,
193};
194
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +0100195/**
196 * DOC: Clock Generated by PLL, rate set and enabled by bootloader
197 *
198 * Traits of this clock:
199 * prepare - clk_(un)prepare only ensures parent is (un)prepared
200 * enable - clk_enable/disable only ensures parent is enabled
201 * rate - rate is fixed. No clk_set_rate support
202 * parent - fixed parent. No clk_set_parent support
203 */
204
205/**
206 * PLL clock that is integrated in the ClockGenA instances on the STiH415
207 * and STiH416.
208 *
209 * @hw: handle between common and hardware-specific interfaces.
210 * @type: PLL instance type.
211 * @regs_base: base of the PLL configuration register(s).
212 *
213 */
214struct clkgen_pll {
215 struct clk_hw hw;
216 struct clkgen_pll_data *data;
217 void __iomem *regs_base;
218};
219
220#define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw)
221
222static int clkgen_pll_is_locked(struct clk_hw *hw)
223{
224 struct clkgen_pll *pll = to_clkgen_pll(hw);
225 u32 locked = CLKGEN_READ(pll, locked_status);
226
227 return !!locked;
228}
229
230static int clkgen_pll_is_enabled(struct clk_hw *hw)
231{
232 struct clkgen_pll *pll = to_clkgen_pll(hw);
233 u32 poweroff = CLKGEN_READ(pll, pdn_status);
234 return !poweroff;
235}
236
237unsigned long recalc_stm_pll800c65(struct clk_hw *hw,
238 unsigned long parent_rate)
239{
240 struct clkgen_pll *pll = to_clkgen_pll(hw);
241 unsigned long mdiv, ndiv, pdiv;
242 unsigned long rate;
243 uint64_t res;
244
245 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
246 return 0;
247
248 pdiv = CLKGEN_READ(pll, pdiv);
249 mdiv = CLKGEN_READ(pll, mdiv);
250 ndiv = CLKGEN_READ(pll, ndiv);
251
252 if (!mdiv)
253 mdiv++; /* mdiv=0 or 1 => MDIV=1 */
254
255 res = (uint64_t)2 * (uint64_t)parent_rate * (uint64_t)ndiv;
256 rate = (unsigned long)div64_u64(res, mdiv * (1 << pdiv));
257
258 pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
259
260 return rate;
261
262}
263
264unsigned long recalc_stm_pll1600c65(struct clk_hw *hw,
265 unsigned long parent_rate)
266{
267 struct clkgen_pll *pll = to_clkgen_pll(hw);
268 unsigned long mdiv, ndiv;
269 unsigned long rate;
270
271 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
272 return 0;
273
274 mdiv = CLKGEN_READ(pll, mdiv);
275 ndiv = CLKGEN_READ(pll, ndiv);
276
277 if (!mdiv)
278 mdiv = 1;
279
280 /* Note: input is divided by 1000 to avoid overflow */
281 rate = ((2 * (parent_rate / 1000) * ndiv) / mdiv) * 1000;
282
283 pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
284
285 return rate;
286}
287
288unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
289 unsigned long parent_rate)
290{
291 struct clkgen_pll *pll = to_clkgen_pll(hw);
292 unsigned long ndiv, idf;
293 unsigned long rate = 0;
294
295 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
296 return 0;
297
298 ndiv = CLKGEN_READ(pll, ndiv);
299 idf = CLKGEN_READ(pll, idf);
300
301 if (idf)
302 /* Note: input is divided to avoid overflow */
303 rate = ((2 * (parent_rate/1000) * ndiv) / idf) * 1000;
304
305 pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
306
307 return rate;
308}
309
310unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
311 unsigned long parent_rate)
312{
313 struct clkgen_pll *pll = to_clkgen_pll(hw);
314 unsigned long odf, ldf, idf;
315 unsigned long rate;
316
317 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
318 return 0;
319
320 odf = CLKGEN_READ(pll, odf[0]);
321 ldf = CLKGEN_READ(pll, ldf);
322 idf = CLKGEN_READ(pll, idf);
323
324 if (!idf) /* idf==0 means 1 */
325 idf = 1;
326 if (!odf) /* odf==0 means 1 */
327 odf = 1;
328
329 /* Note: input is divided by 1000 to avoid overflow */
330 rate = (((parent_rate / 1000) * ldf) / (odf * idf)) * 1000;
331
332 pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
333
334 return rate;
335}
336
337static const struct clk_ops st_pll1600c65_ops = {
338 .is_enabled = clkgen_pll_is_enabled,
339 .recalc_rate = recalc_stm_pll1600c65,
340};
341
342static const struct clk_ops st_pll800c65_ops = {
343 .is_enabled = clkgen_pll_is_enabled,
344 .recalc_rate = recalc_stm_pll800c65,
345};
346
347static const struct clk_ops stm_pll3200c32_ops = {
348 .is_enabled = clkgen_pll_is_enabled,
349 .recalc_rate = recalc_stm_pll3200c32,
350};
351
352static const struct clk_ops st_pll1200c32_ops = {
353 .is_enabled = clkgen_pll_is_enabled,
354 .recalc_rate = recalc_stm_pll1200c32,
355};
356
357static struct clk * __init clkgen_pll_register(const char *parent_name,
358 struct clkgen_pll_data *pll_data,
359 void __iomem *reg,
360 const char *clk_name)
361{
362 struct clkgen_pll *pll;
363 struct clk *clk;
364 struct clk_init_data init;
365
366 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
367 if (!pll)
368 return ERR_PTR(-ENOMEM);
369
370 init.name = clk_name;
371 init.ops = pll_data->ops;
372
373 init.flags = CLK_IS_BASIC;
374 init.parent_names = &parent_name;
375 init.num_parents = 1;
376
377 pll->data = pll_data;
378 pll->regs_base = reg;
379 pll->hw.init = &init;
380
381 clk = clk_register(NULL, &pll->hw);
382 if (IS_ERR(clk)) {
383 kfree(pll);
384 return clk;
385 }
386
387 pr_debug("%s: parent %s rate %lu\n",
388 __clk_get_name(clk),
389 __clk_get_name(clk_get_parent(clk)),
390 clk_get_rate(clk));
391
392 return clk;
393}
394
395static struct clk * __init clkgen_c65_lsdiv_register(const char *parent_name,
396 const char *clk_name)
397{
398 struct clk *clk;
399
400 clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, 1, 2);
401 if (IS_ERR(clk))
402 return clk;
403
404 pr_debug("%s: parent %s rate %lu\n",
405 __clk_get_name(clk),
406 __clk_get_name(clk_get_parent(clk)),
407 clk_get_rate(clk));
408 return clk;
409}
410
411static void __iomem * __init clkgen_get_register_base(
412 struct device_node *np)
413{
414 struct device_node *pnode;
415 void __iomem *reg = NULL;
416
417 pnode = of_get_parent(np);
418 if (!pnode)
419 return NULL;
420
421 reg = of_iomap(pnode, 0);
422
423 of_node_put(pnode);
424 return reg;
425}
426
427#define CLKGENAx_PLL0_OFFSET 0x0
428#define CLKGENAx_PLL1_OFFSET 0x4
429
430static void __init clkgena_c65_pll_setup(struct device_node *np)
431{
432 const int num_pll_outputs = 3;
433 struct clk_onecell_data *clk_data;
434 const char *parent_name;
435 void __iomem *reg;
436 const char *clk_name;
437
438 parent_name = of_clk_get_parent_name(np, 0);
439 if (!parent_name)
440 return;
441
442 reg = clkgen_get_register_base(np);
443 if (!reg)
444 return;
445
446 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
447 if (!clk_data)
448 return;
449
450 clk_data->clk_num = num_pll_outputs;
451 clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *),
452 GFP_KERNEL);
453
454 if (!clk_data->clks)
455 goto err;
456
457 if (of_property_read_string_index(np, "clock-output-names",
458 0, &clk_name))
459 goto err;
460
461 /*
462 * PLL0 HS (high speed) output
463 */
464 clk_data->clks[0] = clkgen_pll_register(parent_name,
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +0200465 (struct clkgen_pll_data *) &st_pll1600c65_ax,
466 reg + CLKGENAx_PLL0_OFFSET, clk_name);
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +0100467
468 if (IS_ERR(clk_data->clks[0]))
469 goto err;
470
471 if (of_property_read_string_index(np, "clock-output-names",
472 1, &clk_name))
473 goto err;
474
475 /*
476 * PLL0 LS (low speed) output, which is a fixed divide by 2 of the
477 * high speed output.
478 */
479 clk_data->clks[1] = clkgen_c65_lsdiv_register(__clk_get_name
480 (clk_data->clks[0]),
481 clk_name);
482
483 if (IS_ERR(clk_data->clks[1]))
484 goto err;
485
486 if (of_property_read_string_index(np, "clock-output-names",
487 2, &clk_name))
488 goto err;
489
490 /*
491 * PLL1 output
492 */
493 clk_data->clks[2] = clkgen_pll_register(parent_name,
Gabriel FERNANDEZdc4febe2014-07-15 17:20:19 +0200494 (struct clkgen_pll_data *) &st_pll800c65_ax,
495 reg + CLKGENAx_PLL1_OFFSET, clk_name);
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +0100496
497 if (IS_ERR(clk_data->clks[2]))
498 goto err;
499
500 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
501 return;
502
503err:
504 kfree(clk_data->clks);
505 kfree(clk_data);
506}
507CLK_OF_DECLARE(clkgena_c65_plls,
508 "st,clkgena-plls-c65", clkgena_c65_pll_setup);
509
510static struct clk * __init clkgen_odf_register(const char *parent_name,
511 void * __iomem reg,
512 struct clkgen_pll_data *pll_data,
513 int odf,
514 spinlock_t *odf_lock,
515 const char *odf_name)
516{
517 struct clk *clk;
518 unsigned long flags;
519 struct clk_gate *gate;
520 struct clk_divider *div;
521
522 flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE;
523
524 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
525 if (!gate)
526 return ERR_PTR(-ENOMEM);
527
528 gate->flags = CLK_GATE_SET_TO_DISABLE;
529 gate->reg = reg + pll_data->odf_gate[odf].offset;
530 gate->bit_idx = pll_data->odf_gate[odf].shift;
531 gate->lock = odf_lock;
532
533 div = kzalloc(sizeof(*div), GFP_KERNEL);
Valentin Ilie72b1c2c2014-04-22 16:15:54 +0300534 if (!div) {
535 kfree(gate);
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +0100536 return ERR_PTR(-ENOMEM);
Valentin Ilie72b1c2c2014-04-22 16:15:54 +0300537 }
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +0100538
539 div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
540 div->reg = reg + pll_data->odf[odf].offset;
541 div->shift = pll_data->odf[odf].shift;
542 div->width = fls(pll_data->odf[odf].mask);
543 div->lock = odf_lock;
544
545 clk = clk_register_composite(NULL, odf_name, &parent_name, 1,
546 NULL, NULL,
547 &div->hw, &clk_divider_ops,
548 &gate->hw, &clk_gate_ops,
549 flags);
550 if (IS_ERR(clk))
551 return clk;
552
553 pr_debug("%s: parent %s rate %lu\n",
554 __clk_get_name(clk),
555 __clk_get_name(clk_get_parent(clk)),
556 clk_get_rate(clk));
557 return clk;
558}
559
560static struct of_device_id c32_pll_of_match[] = {
561 {
562 .compatible = "st,plls-c32-a1x-0",
563 .data = &st_pll3200c32_a1x_0,
564 },
565 {
566 .compatible = "st,plls-c32-a1x-1",
567 .data = &st_pll3200c32_a1x_1,
568 },
Gabriel FERNANDEZec8d27b2014-02-27 16:24:18 +0100569 {
570 .compatible = "st,stih415-plls-c32-a9",
571 .data = &st_pll3200c32_a9_415,
572 },
573 {
574 .compatible = "st,stih415-plls-c32-ddr",
575 .data = &st_pll3200c32_ddr_415,
576 },
577 {
578 .compatible = "st,stih416-plls-c32-a9",
579 .data = &st_pll3200c32_a9_416,
580 },
581 {
582 .compatible = "st,stih416-plls-c32-ddr",
583 .data = &st_pll3200c32_ddr_416,
584 },
Gabriel FERNANDEZeee8f782014-07-15 17:20:24 +0200585 {
586 .compatible = "st,stih407-plls-c32-a0",
587 .data = &st_pll3200c32_407_a0,
588 },
Gabriel FERNANDEZb9b8e612014-02-27 16:24:15 +0100589 {}
590};
591
592static void __init clkgen_c32_pll_setup(struct device_node *np)
593{
594 const struct of_device_id *match;
595 struct clk *clk;
596 const char *parent_name, *pll_name;
597 void __iomem *pll_base;
598 int num_odfs, odf;
599 struct clk_onecell_data *clk_data;
600 struct clkgen_pll_data *data;
601
602 match = of_match_node(c32_pll_of_match, np);
603 if (!match) {
604 pr_err("%s: No matching data\n", __func__);
605 return;
606 }
607
608 data = (struct clkgen_pll_data *) match->data;
609
610 parent_name = of_clk_get_parent_name(np, 0);
611 if (!parent_name)
612 return;
613
614 pll_base = clkgen_get_register_base(np);
615 if (!pll_base)
616 return;
617
618 clk = clkgen_pll_register(parent_name, data, pll_base, np->name);
619 if (IS_ERR(clk))
620 return;
621
622 pll_name = __clk_get_name(clk);
623
624 num_odfs = data->num_odfs;
625
626 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
627 if (!clk_data)
628 return;
629
630 clk_data->clk_num = num_odfs;
631 clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *),
632 GFP_KERNEL);
633
634 if (!clk_data->clks)
635 goto err;
636
637 for (odf = 0; odf < num_odfs; odf++) {
638 struct clk *clk;
639 const char *clk_name;
640
641 if (of_property_read_string_index(np, "clock-output-names",
642 odf, &clk_name))
643 return;
644
645 clk = clkgen_odf_register(pll_name, pll_base, data,
646 odf, &clkgena_c32_odf_lock, clk_name);
647 if (IS_ERR(clk))
648 goto err;
649
650 clk_data->clks[odf] = clk;
651 }
652
653 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
654 return;
655
656err:
657 kfree(pll_name);
658 kfree(clk_data->clks);
659 kfree(clk_data);
660}
661CLK_OF_DECLARE(clkgen_c32_pll, "st,clkgen-plls-c32", clkgen_c32_pll_setup);
Gabriel FERNANDEZec8d27b2014-02-27 16:24:18 +0100662
663static struct of_device_id c32_gpu_pll_of_match[] = {
664 {
665 .compatible = "st,stih415-gpu-pll-c32",
666 .data = &st_pll1200c32_gpu_415,
667 },
668 {
669 .compatible = "st,stih416-gpu-pll-c32",
670 .data = &st_pll1200c32_gpu_416,
671 },
Stephen Boyd70040b32014-05-23 17:16:50 -0700672 {}
Gabriel FERNANDEZec8d27b2014-02-27 16:24:18 +0100673};
674
675static void __init clkgengpu_c32_pll_setup(struct device_node *np)
676{
677 const struct of_device_id *match;
678 struct clk *clk;
679 const char *parent_name;
680 void __iomem *reg;
681 const char *clk_name;
682 struct clkgen_pll_data *data;
683
684 match = of_match_node(c32_gpu_pll_of_match, np);
685 if (!match) {
686 pr_err("%s: No matching data\n", __func__);
687 return;
688 }
689
690 data = (struct clkgen_pll_data *)match->data;
691
692 parent_name = of_clk_get_parent_name(np, 0);
693 if (!parent_name)
694 return;
695
696 reg = clkgen_get_register_base(np);
697 if (!reg)
698 return;
699
700 if (of_property_read_string_index(np, "clock-output-names",
701 0, &clk_name))
702 return;
703
704 /*
705 * PLL 1200MHz output
706 */
707 clk = clkgen_pll_register(parent_name, data, reg, clk_name);
708
709 if (!IS_ERR(clk))
710 of_clk_add_provider(np, of_clk_src_simple_get, clk);
711
712 return;
713}
714CLK_OF_DECLARE(clkgengpu_c32_pll,
715 "st,clkgengpu-pll-c32", clkgengpu_c32_pll_setup);