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