]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/clk/st/clkgen-pll.c
drivers: clk: st: Support for enable/disable in Clockgen PLLs
[mirror_ubuntu-bionic-kernel.git] / drivers / clk / st / clkgen-pll.c
CommitLineData
b9b8e614
GF
1/*
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>
d5f728ac 19#include <linux/clk.h>
b9b8e614 20#include <linux/clk-provider.h>
fb473862 21#include <linux/iopoll.h>
b9b8e614
GF
22
23#include "clkgen.h"
24
25static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
26
27/*
28 * Common PLL configuration register bits for PLL800 and PLL1600 C65
29 */
30#define C65_MDIV_PLL800_MASK (0xff)
31#define C65_MDIV_PLL1600_MASK (0x7)
32#define C65_NDIV_MASK (0xff)
33#define C65_PDIV_MASK (0x7)
34
35/*
36 * PLL configuration register bits for PLL3200 C32
37 */
38#define C32_NDIV_MASK (0xff)
39#define C32_IDF_MASK (0x7)
40#define C32_ODF_MASK (0x3f)
41#define C32_LDF_MASK (0x7f)
42
43#define C32_MAX_ODFS (4)
44
45struct clkgen_pll_data {
46 struct clkgen_field pdn_status;
fb473862 47 struct clkgen_field pdn_ctrl;
b9b8e614
GF
48 struct clkgen_field locked_status;
49 struct clkgen_field mdiv;
50 struct clkgen_field ndiv;
51 struct clkgen_field pdiv;
52 struct clkgen_field idf;
53 struct clkgen_field ldf;
54 unsigned int num_odfs;
55 struct clkgen_field odf[C32_MAX_ODFS];
56 struct clkgen_field odf_gate[C32_MAX_ODFS];
57 const struct clk_ops *ops;
58};
59
60static const struct clk_ops st_pll1600c65_ops;
61static const struct clk_ops st_pll800c65_ops;
62static const struct clk_ops stm_pll3200c32_ops;
63static const struct clk_ops st_pll1200c32_ops;
64
dc4febef 65static const struct clkgen_pll_data st_pll1600c65_ax = {
b9b8e614 66 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19),
fb473862 67 .pdn_ctrl = CLKGEN_FIELD(0x10, 0x1, 0),
b9b8e614
GF
68 .locked_status = CLKGEN_FIELD(0x0, 0x1, 31),
69 .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK, 0),
70 .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8),
71 .ops = &st_pll1600c65_ops
72};
73
dc4febef 74static const struct clkgen_pll_data st_pll800c65_ax = {
b9b8e614 75 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19),
fb473862 76 .pdn_ctrl = CLKGEN_FIELD(0xC, 0x1, 1),
b9b8e614
GF
77 .locked_status = CLKGEN_FIELD(0x0, 0x1, 31),
78 .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL800_MASK, 0),
79 .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8),
80 .pdiv = CLKGEN_FIELD(0x0, C65_PDIV_MASK, 16),
81 .ops = &st_pll800c65_ops
82};
83
dc4febef 84static const struct clkgen_pll_data st_pll3200c32_a1x_0 = {
b9b8e614 85 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 31),
fb473862 86 .pdn_ctrl = CLKGEN_FIELD(0x18, 0x1, 0),
b9b8e614
GF
87 .locked_status = CLKGEN_FIELD(0x4, 0x1, 31),
88 .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 0x0),
89 .idf = CLKGEN_FIELD(0x4, C32_IDF_MASK, 0x0),
90 .num_odfs = 4,
91 .odf = { CLKGEN_FIELD(0x54, C32_ODF_MASK, 4),
92 CLKGEN_FIELD(0x54, C32_ODF_MASK, 10),
93 CLKGEN_FIELD(0x54, C32_ODF_MASK, 16),
94 CLKGEN_FIELD(0x54, C32_ODF_MASK, 22) },
95 .odf_gate = { CLKGEN_FIELD(0x54, 0x1, 0),
96 CLKGEN_FIELD(0x54, 0x1, 1),
97 CLKGEN_FIELD(0x54, 0x1, 2),
98 CLKGEN_FIELD(0x54, 0x1, 3) },
99 .ops = &stm_pll3200c32_ops,
100};
101
dc4febef 102static const struct clkgen_pll_data st_pll3200c32_a1x_1 = {
b9b8e614 103 .pdn_status = CLKGEN_FIELD(0xC, 0x1, 31),
fb473862 104 .pdn_ctrl = CLKGEN_FIELD(0x18, 0x1, 1),
b9b8e614
GF
105 .locked_status = CLKGEN_FIELD(0x10, 0x1, 31),
106 .ndiv = CLKGEN_FIELD(0xC, C32_NDIV_MASK, 0x0),
107 .idf = CLKGEN_FIELD(0x10, C32_IDF_MASK, 0x0),
108 .num_odfs = 4,
109 .odf = { CLKGEN_FIELD(0x58, C32_ODF_MASK, 4),
110 CLKGEN_FIELD(0x58, C32_ODF_MASK, 10),
111 CLKGEN_FIELD(0x58, C32_ODF_MASK, 16),
112 CLKGEN_FIELD(0x58, C32_ODF_MASK, 22) },
113 .odf_gate = { CLKGEN_FIELD(0x58, 0x1, 0),
114 CLKGEN_FIELD(0x58, 0x1, 1),
115 CLKGEN_FIELD(0x58, 0x1, 2),
116 CLKGEN_FIELD(0x58, 0x1, 3) },
117 .ops = &stm_pll3200c32_ops,
118};
119
ec8d27b4 120/* 415 specific */
dc4febef 121static const struct clkgen_pll_data st_pll3200c32_a9_415 = {
ec8d27b4 122 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
fb473862 123 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
ec8d27b4
GF
124 .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0),
125 .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 9),
126 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 22),
127 .num_odfs = 1,
128 .odf = { CLKGEN_FIELD(0x0, C32_ODF_MASK, 3) },
129 .odf_gate = { CLKGEN_FIELD(0x0, 0x1, 28) },
130 .ops = &stm_pll3200c32_ops,
131};
132
dc4febef 133static const struct clkgen_pll_data st_pll3200c32_ddr_415 = {
ec8d27b4 134 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
fb473862 135 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
ec8d27b4
GF
136 .locked_status = CLKGEN_FIELD(0x100, 0x1, 0),
137 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
138 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
139 .num_odfs = 2,
140 .odf = { CLKGEN_FIELD(0x8, C32_ODF_MASK, 8),
141 CLKGEN_FIELD(0x8, C32_ODF_MASK, 14) },
142 .odf_gate = { CLKGEN_FIELD(0x4, 0x1, 28),
143 CLKGEN_FIELD(0x4, 0x1, 29) },
144 .ops = &stm_pll3200c32_ops,
145};
146
dc4febef 147static const struct clkgen_pll_data st_pll1200c32_gpu_415 = {
fb473862
GF
148 .pdn_status = CLKGEN_FIELD(0x4, 0x1, 0),
149 .pdn_ctrl = CLKGEN_FIELD(0x4, 0x1, 0),
ec8d27b4
GF
150 .locked_status = CLKGEN_FIELD(0x168, 0x1, 0),
151 .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3),
152 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0),
153 .num_odfs = 0,
154 .odf = { CLKGEN_FIELD(0x0, C32_ODF_MASK, 10) },
155 .ops = &st_pll1200c32_ops,
156};
157
158/* 416 specific */
dc4febef 159static const struct clkgen_pll_data st_pll3200c32_a9_416 = {
ec8d27b4 160 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
fb473862 161 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
ec8d27b4
GF
162 .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0),
163 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
164 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
165 .num_odfs = 1,
166 .odf = { CLKGEN_FIELD(0x8, C32_ODF_MASK, 8) },
167 .odf_gate = { CLKGEN_FIELD(0x4, 0x1, 28) },
168 .ops = &stm_pll3200c32_ops,
169};
170
dc4febef 171static const struct clkgen_pll_data st_pll3200c32_ddr_416 = {
ec8d27b4 172 .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0),
fb473862 173 .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0),
ec8d27b4
GF
174 .locked_status = CLKGEN_FIELD(0x10C, 0x1, 0),
175 .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0),
176 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25),
177 .num_odfs = 2,
178 .odf = { CLKGEN_FIELD(0x8, C32_ODF_MASK, 8),
179 CLKGEN_FIELD(0x8, C32_ODF_MASK, 14) },
180 .odf_gate = { CLKGEN_FIELD(0x4, 0x1, 28),
181 CLKGEN_FIELD(0x4, 0x1, 29) },
182 .ops = &stm_pll3200c32_ops,
183};
184
dc4febef 185static const struct clkgen_pll_data st_pll1200c32_gpu_416 = {
ec8d27b4 186 .pdn_status = CLKGEN_FIELD(0x8E4, 0x1, 3),
fb473862 187 .pdn_ctrl = CLKGEN_FIELD(0x8E4, 0x1, 3),
ec8d27b4
GF
188 .locked_status = CLKGEN_FIELD(0x90C, 0x1, 0),
189 .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3),
190 .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0),
191 .num_odfs = 0,
192 .odf = { CLKGEN_FIELD(0x0, C32_ODF_MASK, 10) },
193 .ops = &st_pll1200c32_ops,
194};
195
eee8f783
GF
196static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
197 /* 407 A0 */
198 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
fb473862 199 .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8),
eee8f783
GF
200 .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24),
201 .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16),
202 .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0),
203 .num_odfs = 1,
204 .odf = { CLKGEN_FIELD(0x2b4, C32_ODF_MASK, 0) },
205 .odf_gate = { CLKGEN_FIELD(0x2b4, 0x1, 6) },
206 .ops = &stm_pll3200c32_ops,
207};
208
d34e210e 209static const struct clkgen_pll_data st_pll3200c32_cx_0 = {
51306d56
GF
210 /* 407 C0 PLL0 */
211 .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8),
fb473862 212 .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8),
51306d56
GF
213 .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24),
214 .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16),
215 .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0),
216 .num_odfs = 1,
217 .odf = { CLKGEN_FIELD(0x2b4, C32_ODF_MASK, 0) },
218 .odf_gate = { CLKGEN_FIELD(0x2b4, 0x1, 6) },
219 .ops = &stm_pll3200c32_ops,
220};
221
d34e210e 222static const struct clkgen_pll_data st_pll3200c32_cx_1 = {
51306d56
GF
223 /* 407 C0 PLL1 */
224 .pdn_status = CLKGEN_FIELD(0x2c8, 0x1, 8),
fb473862 225 .pdn_ctrl = CLKGEN_FIELD(0x2c8, 0x1, 8),
51306d56
GF
226 .locked_status = CLKGEN_FIELD(0x2c8, 0x1, 24),
227 .ndiv = CLKGEN_FIELD(0x2cc, C32_NDIV_MASK, 16),
228 .idf = CLKGEN_FIELD(0x2cc, C32_IDF_MASK, 0x0),
229 .num_odfs = 1,
230 .odf = { CLKGEN_FIELD(0x2dc, C32_ODF_MASK, 0) },
231 .odf_gate = { CLKGEN_FIELD(0x2dc, 0x1, 6) },
232 .ops = &stm_pll3200c32_ops,
233};
234
aaa65d77
GF
235static const struct clkgen_pll_data st_pll3200c32_407_a9 = {
236 /* 407 A9 */
237 .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0),
fb473862 238 .pdn_ctrl = CLKGEN_FIELD(0x1a8, 0x1, 0),
aaa65d77
GF
239 .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0),
240 .ndiv = CLKGEN_FIELD(0x1b0, C32_NDIV_MASK, 0),
241 .idf = CLKGEN_FIELD(0x1a8, C32_IDF_MASK, 25),
242 .num_odfs = 1,
243 .odf = { CLKGEN_FIELD(0x1b0, C32_ODF_MASK, 8) },
244 .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) },
245 .ops = &stm_pll3200c32_ops,
246};
247
b9b8e614
GF
248/**
249 * DOC: Clock Generated by PLL, rate set and enabled by bootloader
250 *
251 * Traits of this clock:
252 * prepare - clk_(un)prepare only ensures parent is (un)prepared
253 * enable - clk_enable/disable only ensures parent is enabled
254 * rate - rate is fixed. No clk_set_rate support
255 * parent - fixed parent. No clk_set_parent support
256 */
257
258/**
259 * PLL clock that is integrated in the ClockGenA instances on the STiH415
260 * and STiH416.
261 *
262 * @hw: handle between common and hardware-specific interfaces.
263 * @type: PLL instance type.
264 * @regs_base: base of the PLL configuration register(s).
265 *
266 */
267struct clkgen_pll {
268 struct clk_hw hw;
269 struct clkgen_pll_data *data;
270 void __iomem *regs_base;
271};
272
273#define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw)
274
275static int clkgen_pll_is_locked(struct clk_hw *hw)
276{
277 struct clkgen_pll *pll = to_clkgen_pll(hw);
278 u32 locked = CLKGEN_READ(pll, locked_status);
279
280 return !!locked;
281}
282
283static int clkgen_pll_is_enabled(struct clk_hw *hw)
284{
285 struct clkgen_pll *pll = to_clkgen_pll(hw);
286 u32 poweroff = CLKGEN_READ(pll, pdn_status);
287 return !poweroff;
288}
289
fb473862
GF
290static int clkgen_pll_enable(struct clk_hw *hw)
291{
292 struct clkgen_pll *pll = to_clkgen_pll(hw);
293 void __iomem *base = pll->regs_base;
294 struct clkgen_field *field = &pll->data->locked_status;
295 int ret = 0;
296 u32 reg;
297
298 if (clkgen_pll_is_enabled(hw))
299 return 0;
300
301 CLKGEN_WRITE(pll, pdn_ctrl, 0);
302
303 ret = readl_relaxed_poll_timeout(base + field->offset, reg,
304 !!((reg >> field->shift) & field->mask), 0, 10000);
305
306 if (!ret)
307 pr_debug("%s:%s enabled\n", __clk_get_name(hw->clk), __func__);
308
309 return ret;
310}
311
312static void clkgen_pll_disable(struct clk_hw *hw)
313{
314 struct clkgen_pll *pll = to_clkgen_pll(hw);
315
316 if (!clkgen_pll_is_enabled(hw))
317 return;
318
319 CLKGEN_WRITE(pll, pdn_ctrl, 1);
320
321 pr_debug("%s:%s disabled\n", __clk_get_name(hw->clk), __func__);
322}
323
8e6dd77c 324static unsigned long recalc_stm_pll800c65(struct clk_hw *hw,
b9b8e614
GF
325 unsigned long parent_rate)
326{
327 struct clkgen_pll *pll = to_clkgen_pll(hw);
328 unsigned long mdiv, ndiv, pdiv;
329 unsigned long rate;
330 uint64_t res;
331
332 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
333 return 0;
334
335 pdiv = CLKGEN_READ(pll, pdiv);
336 mdiv = CLKGEN_READ(pll, mdiv);
337 ndiv = CLKGEN_READ(pll, ndiv);
338
339 if (!mdiv)
340 mdiv++; /* mdiv=0 or 1 => MDIV=1 */
341
342 res = (uint64_t)2 * (uint64_t)parent_rate * (uint64_t)ndiv;
343 rate = (unsigned long)div64_u64(res, mdiv * (1 << pdiv));
344
836ee0f7 345 pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
b9b8e614
GF
346
347 return rate;
348
349}
350
8e6dd77c 351static unsigned long recalc_stm_pll1600c65(struct clk_hw *hw,
b9b8e614
GF
352 unsigned long parent_rate)
353{
354 struct clkgen_pll *pll = to_clkgen_pll(hw);
355 unsigned long mdiv, ndiv;
356 unsigned long rate;
357
358 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
359 return 0;
360
361 mdiv = CLKGEN_READ(pll, mdiv);
362 ndiv = CLKGEN_READ(pll, ndiv);
363
364 if (!mdiv)
365 mdiv = 1;
366
367 /* Note: input is divided by 1000 to avoid overflow */
368 rate = ((2 * (parent_rate / 1000) * ndiv) / mdiv) * 1000;
369
836ee0f7 370 pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
b9b8e614
GF
371
372 return rate;
373}
374
8e6dd77c 375static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
b9b8e614
GF
376 unsigned long parent_rate)
377{
378 struct clkgen_pll *pll = to_clkgen_pll(hw);
379 unsigned long ndiv, idf;
380 unsigned long rate = 0;
381
382 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
383 return 0;
384
385 ndiv = CLKGEN_READ(pll, ndiv);
386 idf = CLKGEN_READ(pll, idf);
387
388 if (idf)
389 /* Note: input is divided to avoid overflow */
390 rate = ((2 * (parent_rate/1000) * ndiv) / idf) * 1000;
391
836ee0f7 392 pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
b9b8e614
GF
393
394 return rate;
395}
396
8e6dd77c 397static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
b9b8e614
GF
398 unsigned long parent_rate)
399{
400 struct clkgen_pll *pll = to_clkgen_pll(hw);
401 unsigned long odf, ldf, idf;
402 unsigned long rate;
403
404 if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
405 return 0;
406
407 odf = CLKGEN_READ(pll, odf[0]);
408 ldf = CLKGEN_READ(pll, ldf);
409 idf = CLKGEN_READ(pll, idf);
410
411 if (!idf) /* idf==0 means 1 */
412 idf = 1;
413 if (!odf) /* odf==0 means 1 */
414 odf = 1;
415
416 /* Note: input is divided by 1000 to avoid overflow */
417 rate = (((parent_rate / 1000) * ldf) / (odf * idf)) * 1000;
418
836ee0f7 419 pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
b9b8e614
GF
420
421 return rate;
422}
423
424static const struct clk_ops st_pll1600c65_ops = {
fb473862
GF
425 .enable = clkgen_pll_enable,
426 .disable = clkgen_pll_disable,
b9b8e614
GF
427 .is_enabled = clkgen_pll_is_enabled,
428 .recalc_rate = recalc_stm_pll1600c65,
429};
430
431static const struct clk_ops st_pll800c65_ops = {
fb473862
GF
432 .enable = clkgen_pll_enable,
433 .disable = clkgen_pll_disable,
b9b8e614
GF
434 .is_enabled = clkgen_pll_is_enabled,
435 .recalc_rate = recalc_stm_pll800c65,
436};
437
438static const struct clk_ops stm_pll3200c32_ops = {
fb473862
GF
439 .enable = clkgen_pll_enable,
440 .disable = clkgen_pll_disable,
b9b8e614
GF
441 .is_enabled = clkgen_pll_is_enabled,
442 .recalc_rate = recalc_stm_pll3200c32,
443};
444
445static const struct clk_ops st_pll1200c32_ops = {
fb473862
GF
446 .enable = clkgen_pll_enable,
447 .disable = clkgen_pll_disable,
b9b8e614
GF
448 .is_enabled = clkgen_pll_is_enabled,
449 .recalc_rate = recalc_stm_pll1200c32,
450};
451
452static struct clk * __init clkgen_pll_register(const char *parent_name,
453 struct clkgen_pll_data *pll_data,
454 void __iomem *reg,
455 const char *clk_name)
456{
457 struct clkgen_pll *pll;
458 struct clk *clk;
459 struct clk_init_data init;
460
461 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
462 if (!pll)
463 return ERR_PTR(-ENOMEM);
464
465 init.name = clk_name;
466 init.ops = pll_data->ops;
467
18fee453 468 init.flags = CLK_IS_BASIC | CLK_GET_RATE_NOCACHE;
b9b8e614
GF
469 init.parent_names = &parent_name;
470 init.num_parents = 1;
471
472 pll->data = pll_data;
473 pll->regs_base = reg;
474 pll->hw.init = &init;
475
476 clk = clk_register(NULL, &pll->hw);
477 if (IS_ERR(clk)) {
478 kfree(pll);
479 return clk;
480 }
481
482 pr_debug("%s: parent %s rate %lu\n",
483 __clk_get_name(clk),
484 __clk_get_name(clk_get_parent(clk)),
485 clk_get_rate(clk));
486
487 return clk;
488}
489
490static struct clk * __init clkgen_c65_lsdiv_register(const char *parent_name,
491 const char *clk_name)
492{
493 struct clk *clk;
494
495 clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, 1, 2);
496 if (IS_ERR(clk))
497 return clk;
498
499 pr_debug("%s: parent %s rate %lu\n",
500 __clk_get_name(clk),
501 __clk_get_name(clk_get_parent(clk)),
502 clk_get_rate(clk));
503 return clk;
504}
505
506static void __iomem * __init clkgen_get_register_base(
507 struct device_node *np)
508{
509 struct device_node *pnode;
510 void __iomem *reg = NULL;
511
512 pnode = of_get_parent(np);
513 if (!pnode)
514 return NULL;
515
516 reg = of_iomap(pnode, 0);
517
518 of_node_put(pnode);
519 return reg;
520}
521
522#define CLKGENAx_PLL0_OFFSET 0x0
523#define CLKGENAx_PLL1_OFFSET 0x4
524
525static void __init clkgena_c65_pll_setup(struct device_node *np)
526{
527 const int num_pll_outputs = 3;
528 struct clk_onecell_data *clk_data;
529 const char *parent_name;
530 void __iomem *reg;
531 const char *clk_name;
532
533 parent_name = of_clk_get_parent_name(np, 0);
534 if (!parent_name)
535 return;
536
537 reg = clkgen_get_register_base(np);
538 if (!reg)
539 return;
540
541 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
542 if (!clk_data)
543 return;
544
545 clk_data->clk_num = num_pll_outputs;
546 clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *),
547 GFP_KERNEL);
548
549 if (!clk_data->clks)
550 goto err;
551
552 if (of_property_read_string_index(np, "clock-output-names",
553 0, &clk_name))
554 goto err;
555
556 /*
557 * PLL0 HS (high speed) output
558 */
559 clk_data->clks[0] = clkgen_pll_register(parent_name,
dc4febef
GF
560 (struct clkgen_pll_data *) &st_pll1600c65_ax,
561 reg + CLKGENAx_PLL0_OFFSET, clk_name);
b9b8e614
GF
562
563 if (IS_ERR(clk_data->clks[0]))
564 goto err;
565
566 if (of_property_read_string_index(np, "clock-output-names",
567 1, &clk_name))
568 goto err;
569
570 /*
571 * PLL0 LS (low speed) output, which is a fixed divide by 2 of the
572 * high speed output.
573 */
574 clk_data->clks[1] = clkgen_c65_lsdiv_register(__clk_get_name
575 (clk_data->clks[0]),
576 clk_name);
577
578 if (IS_ERR(clk_data->clks[1]))
579 goto err;
580
581 if (of_property_read_string_index(np, "clock-output-names",
582 2, &clk_name))
583 goto err;
584
585 /*
586 * PLL1 output
587 */
588 clk_data->clks[2] = clkgen_pll_register(parent_name,
dc4febef
GF
589 (struct clkgen_pll_data *) &st_pll800c65_ax,
590 reg + CLKGENAx_PLL1_OFFSET, clk_name);
b9b8e614
GF
591
592 if (IS_ERR(clk_data->clks[2]))
593 goto err;
594
595 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
596 return;
597
598err:
599 kfree(clk_data->clks);
600 kfree(clk_data);
601}
602CLK_OF_DECLARE(clkgena_c65_plls,
603 "st,clkgena-plls-c65", clkgena_c65_pll_setup);
604
605static struct clk * __init clkgen_odf_register(const char *parent_name,
8e6dd77c 606 void __iomem *reg,
b9b8e614
GF
607 struct clkgen_pll_data *pll_data,
608 int odf,
609 spinlock_t *odf_lock,
610 const char *odf_name)
611{
612 struct clk *clk;
613 unsigned long flags;
614 struct clk_gate *gate;
615 struct clk_divider *div;
616
617 flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE;
618
619 gate = kzalloc(sizeof(*gate), GFP_KERNEL);
620 if (!gate)
621 return ERR_PTR(-ENOMEM);
622
623 gate->flags = CLK_GATE_SET_TO_DISABLE;
624 gate->reg = reg + pll_data->odf_gate[odf].offset;
625 gate->bit_idx = pll_data->odf_gate[odf].shift;
626 gate->lock = odf_lock;
627
628 div = kzalloc(sizeof(*div), GFP_KERNEL);
72b1c2c3
VI
629 if (!div) {
630 kfree(gate);
b9b8e614 631 return ERR_PTR(-ENOMEM);
72b1c2c3 632 }
b9b8e614
GF
633
634 div->flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO;
635 div->reg = reg + pll_data->odf[odf].offset;
636 div->shift = pll_data->odf[odf].shift;
637 div->width = fls(pll_data->odf[odf].mask);
638 div->lock = odf_lock;
639
640 clk = clk_register_composite(NULL, odf_name, &parent_name, 1,
641 NULL, NULL,
642 &div->hw, &clk_divider_ops,
643 &gate->hw, &clk_gate_ops,
644 flags);
645 if (IS_ERR(clk))
646 return clk;
647
648 pr_debug("%s: parent %s rate %lu\n",
649 __clk_get_name(clk),
650 __clk_get_name(clk_get_parent(clk)),
651 clk_get_rate(clk));
652 return clk;
653}
654
f375573c 655static const struct of_device_id c32_pll_of_match[] = {
b9b8e614
GF
656 {
657 .compatible = "st,plls-c32-a1x-0",
658 .data = &st_pll3200c32_a1x_0,
659 },
660 {
661 .compatible = "st,plls-c32-a1x-1",
662 .data = &st_pll3200c32_a1x_1,
663 },
ec8d27b4
GF
664 {
665 .compatible = "st,stih415-plls-c32-a9",
666 .data = &st_pll3200c32_a9_415,
667 },
668 {
669 .compatible = "st,stih415-plls-c32-ddr",
670 .data = &st_pll3200c32_ddr_415,
671 },
672 {
673 .compatible = "st,stih416-plls-c32-a9",
674 .data = &st_pll3200c32_a9_416,
675 },
676 {
677 .compatible = "st,stih416-plls-c32-ddr",
678 .data = &st_pll3200c32_ddr_416,
679 },
eee8f783
GF
680 {
681 .compatible = "st,stih407-plls-c32-a0",
682 .data = &st_pll3200c32_407_a0,
683 },
51306d56 684 {
d34e210e
GF
685 .compatible = "st,plls-c32-cx_0",
686 .data = &st_pll3200c32_cx_0,
51306d56
GF
687 },
688 {
d34e210e
GF
689 .compatible = "st,plls-c32-cx_1",
690 .data = &st_pll3200c32_cx_1,
51306d56 691 },
aaa65d77
GF
692 {
693 .compatible = "st,stih407-plls-c32-a9",
694 .data = &st_pll3200c32_407_a9,
695 },
b9b8e614
GF
696 {}
697};
698
699static void __init clkgen_c32_pll_setup(struct device_node *np)
700{
701 const struct of_device_id *match;
702 struct clk *clk;
703 const char *parent_name, *pll_name;
704 void __iomem *pll_base;
705 int num_odfs, odf;
706 struct clk_onecell_data *clk_data;
707 struct clkgen_pll_data *data;
708
709 match = of_match_node(c32_pll_of_match, np);
710 if (!match) {
711 pr_err("%s: No matching data\n", __func__);
712 return;
713 }
714
715 data = (struct clkgen_pll_data *) match->data;
716
717 parent_name = of_clk_get_parent_name(np, 0);
718 if (!parent_name)
719 return;
720
721 pll_base = clkgen_get_register_base(np);
722 if (!pll_base)
723 return;
724
725 clk = clkgen_pll_register(parent_name, data, pll_base, np->name);
726 if (IS_ERR(clk))
727 return;
728
729 pll_name = __clk_get_name(clk);
730
731 num_odfs = data->num_odfs;
732
733 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
734 if (!clk_data)
735 return;
736
737 clk_data->clk_num = num_odfs;
738 clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *),
739 GFP_KERNEL);
740
741 if (!clk_data->clks)
742 goto err;
743
744 for (odf = 0; odf < num_odfs; odf++) {
745 struct clk *clk;
746 const char *clk_name;
747
748 if (of_property_read_string_index(np, "clock-output-names",
749 odf, &clk_name))
750 return;
751
752 clk = clkgen_odf_register(pll_name, pll_base, data,
753 odf, &clkgena_c32_odf_lock, clk_name);
754 if (IS_ERR(clk))
755 goto err;
756
757 clk_data->clks[odf] = clk;
758 }
759
760 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
761 return;
762
763err:
764 kfree(pll_name);
765 kfree(clk_data->clks);
766 kfree(clk_data);
767}
768CLK_OF_DECLARE(clkgen_c32_pll, "st,clkgen-plls-c32", clkgen_c32_pll_setup);
ec8d27b4 769
f375573c 770static const struct of_device_id c32_gpu_pll_of_match[] = {
ec8d27b4
GF
771 {
772 .compatible = "st,stih415-gpu-pll-c32",
773 .data = &st_pll1200c32_gpu_415,
774 },
775 {
776 .compatible = "st,stih416-gpu-pll-c32",
777 .data = &st_pll1200c32_gpu_416,
778 },
70040b35 779 {}
ec8d27b4
GF
780};
781
782static void __init clkgengpu_c32_pll_setup(struct device_node *np)
783{
784 const struct of_device_id *match;
785 struct clk *clk;
786 const char *parent_name;
787 void __iomem *reg;
788 const char *clk_name;
789 struct clkgen_pll_data *data;
790
791 match = of_match_node(c32_gpu_pll_of_match, np);
792 if (!match) {
793 pr_err("%s: No matching data\n", __func__);
794 return;
795 }
796
797 data = (struct clkgen_pll_data *)match->data;
798
799 parent_name = of_clk_get_parent_name(np, 0);
800 if (!parent_name)
801 return;
802
803 reg = clkgen_get_register_base(np);
804 if (!reg)
805 return;
806
807 if (of_property_read_string_index(np, "clock-output-names",
808 0, &clk_name))
809 return;
810
811 /*
812 * PLL 1200MHz output
813 */
814 clk = clkgen_pll_register(parent_name, data, reg, clk_name);
815
816 if (!IS_ERR(clk))
817 of_clk_add_provider(np, of_clk_src_simple_get, clk);
818
819 return;
820}
821CLK_OF_DECLARE(clkgengpu_c32_pll,
822 "st,clkgengpu-pll-c32", clkgengpu_c32_pll_setup);