1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Copyright 2018 NXP.
4 *
5 * This driver supports the SCCG plls found in the imx8m SOCs
6 *
7 * Documentation for this SCCG pll can be found at:
8 *   https://www.nxp.com/docs/en/reference-manual/IMX8MDQLQRM.pdf#page=834
9 */
10
11#include <linux/clk-provider.h>
12#include <linux/err.h>
13#include <linux/export.h>
14#include <linux/io.h>
15#include <linux/iopoll.h>
16#include <linux/slab.h>
17#include <linux/bitfield.h>
18
19#include "clk.h"
20
21/* PLL CFGs */
22#define PLL_CFG0		0x0
23#define PLL_CFG1		0x4
24#define PLL_CFG2		0x8
25
26#define PLL_DIVF1_MASK		GENMASK(18, 13)
27#define PLL_DIVF2_MASK		GENMASK(12, 7)
28#define PLL_DIVR1_MASK		GENMASK(27, 25)
29#define PLL_DIVR2_MASK		GENMASK(24, 19)
30#define PLL_DIVQ_MASK           GENMASK(6, 1)
31#define PLL_REF_MASK		GENMASK(2, 0)
32
33#define PLL_LOCK_MASK		BIT(31)
34#define PLL_PD_MASK		BIT(7)
35
36/* These are the specification limits for the SSCG PLL */
37#define PLL_REF_MIN_FREQ		25000000UL
38#define PLL_REF_MAX_FREQ		235000000UL
39
40#define PLL_STAGE1_MIN_FREQ		1600000000UL
41#define PLL_STAGE1_MAX_FREQ		2400000000UL
42
43#define PLL_STAGE1_REF_MIN_FREQ		25000000UL
44#define PLL_STAGE1_REF_MAX_FREQ		54000000UL
45
46#define PLL_STAGE2_MIN_FREQ		1200000000UL
47#define PLL_STAGE2_MAX_FREQ		2400000000UL
48
49#define PLL_STAGE2_REF_MIN_FREQ		54000000UL
50#define PLL_STAGE2_REF_MAX_FREQ		75000000UL
51
52#define PLL_OUT_MIN_FREQ		20000000UL
53#define PLL_OUT_MAX_FREQ		1200000000UL
54
55#define PLL_DIVR1_MAX			7
56#define PLL_DIVR2_MAX			63
57#define PLL_DIVF1_MAX			63
58#define PLL_DIVF2_MAX			63
59#define PLL_DIVQ_MAX			63
60
61#define PLL_BYPASS_NONE			0x0
62#define PLL_BYPASS1			0x2
63#define PLL_BYPASS2			0x1
64
65#define SSCG_PLL_BYPASS1_MASK           BIT(5)
66#define SSCG_PLL_BYPASS2_MASK           BIT(4)
67#define SSCG_PLL_BYPASS_MASK		GENMASK(5, 4)
68
69#define PLL_SCCG_LOCK_TIMEOUT		70
70
71struct clk_sscg_pll_setup {
72	int divr1, divf1;
73	int divr2, divf2;
74	int divq;
75	int bypass;
76	uint64_t vco1;
77	uint64_t vco2;
78	uint64_t fout;
79	uint64_t ref;
80	uint64_t ref_div1;
81	uint64_t ref_div2;
82	uint64_t fout_request;
83	int fout_error;
84};
85
86struct clk_sscg_pll {
87	struct clk_hw	hw;
88	const struct clk_ops  ops;
89	void __iomem *base;
90	struct clk_sscg_pll_setup setup;
91	u8 parent;
92	u8 bypass1;
93	u8 bypass2;
94};
95
96#define to_clk_sscg_pll(_hw) container_of(_hw, struct clk_sscg_pll, hw)
97
98static int clk_sscg_pll_wait_lock(struct clk_sscg_pll *pll)
99{
100	u32 val;
101
102	val = readl_relaxed(pll->base + PLL_CFG0);
103
104	/* don't wait for lock if all plls are bypassed */
105	if (!(val & SSCG_PLL_BYPASS2_MASK))
106		return readl_poll_timeout(pll->base, val, val & PLL_LOCK_MASK,
107						0, PLL_SCCG_LOCK_TIMEOUT);
108
109	return 0;
110}
111
112static int clk_sscg_pll2_check_match(struct clk_sscg_pll_setup *setup,
113					struct clk_sscg_pll_setup *temp_setup)
114{
115	int new_diff = temp_setup->fout - temp_setup->fout_request;
116	int diff = temp_setup->fout_error;
117
118	if (abs(diff) > abs(new_diff)) {
119		temp_setup->fout_error = new_diff;
120		memcpy(setup, temp_setup, sizeof(struct clk_sscg_pll_setup));
121
122		if (temp_setup->fout_request == temp_setup->fout)
123			return 0;
124	}
125	return -1;
126}
127
128static int clk_sscg_divq_lookup(struct clk_sscg_pll_setup *setup,
129				struct clk_sscg_pll_setup *temp_setup)
130{
131	int ret = -EINVAL;
132
133	for (temp_setup->divq = 0; temp_setup->divq <= PLL_DIVQ_MAX;
134	     temp_setup->divq++) {
135		temp_setup->vco2 = temp_setup->vco1;
136		do_div(temp_setup->vco2, temp_setup->divr2 + 1);
137		temp_setup->vco2 *= 2;
138		temp_setup->vco2 *= temp_setup->divf2 + 1;
139		if (temp_setup->vco2 >= PLL_STAGE2_MIN_FREQ &&
140				temp_setup->vco2 <= PLL_STAGE2_MAX_FREQ) {
141			temp_setup->fout = temp_setup->vco2;
142			do_div(temp_setup->fout, 2 * (temp_setup->divq + 1));
143
144			ret = clk_sscg_pll2_check_match(setup, temp_setup);
145			if (!ret) {
146				temp_setup->bypass = PLL_BYPASS1;
147				return ret;
148			}
149		}
150	}
151
152	return ret;
153}
154
155static int clk_sscg_divf2_lookup(struct clk_sscg_pll_setup *setup,
156					struct clk_sscg_pll_setup *temp_setup)
157{
158	int ret = -EINVAL;
159
160	for (temp_setup->divf2 = 0; temp_setup->divf2 <= PLL_DIVF2_MAX;
161	     temp_setup->divf2++) {
162		ret = clk_sscg_divq_lookup(setup, temp_setup);
163		if (!ret)
164			return ret;
165	}
166
167	return ret;
168}
169
170static int clk_sscg_divr2_lookup(struct clk_sscg_pll_setup *setup,
171				struct clk_sscg_pll_setup *temp_setup)
172{
173	int ret = -EINVAL;
174
175	for (temp_setup->divr2 = 0; temp_setup->divr2 <= PLL_DIVR2_MAX;
176	     temp_setup->divr2++) {
177		temp_setup->ref_div2 = temp_setup->vco1;
178		do_div(temp_setup->ref_div2, temp_setup->divr2 + 1);
179		if (temp_setup->ref_div2 >= PLL_STAGE2_REF_MIN_FREQ &&
180		    temp_setup->ref_div2 <= PLL_STAGE2_REF_MAX_FREQ) {
181			ret = clk_sscg_divf2_lookup(setup, temp_setup);
182			if (!ret)
183				return ret;
184		}
185	}
186
187	return ret;
188}
189
190static int clk_sscg_pll2_find_setup(struct clk_sscg_pll_setup *setup,
191					struct clk_sscg_pll_setup *temp_setup,
192					uint64_t ref)
193{
194	int ret;
195
196	if (ref < PLL_STAGE1_MIN_FREQ || ref > PLL_STAGE1_MAX_FREQ)
197		return -EINVAL;
198
199	temp_setup->vco1 = ref;
200
201	ret = clk_sscg_divr2_lookup(setup, temp_setup);
202	return ret;
203}
204
205static int clk_sscg_divf1_lookup(struct clk_sscg_pll_setup *setup,
206				struct clk_sscg_pll_setup *temp_setup)
207{
208	int ret = -EINVAL;
209
210	for (temp_setup->divf1 = 0; temp_setup->divf1 <= PLL_DIVF1_MAX;
211	     temp_setup->divf1++) {
212		uint64_t vco1 = temp_setup->ref;
213
214		do_div(vco1, temp_setup->divr1 + 1);
215		vco1 *= 2;
216		vco1 *= temp_setup->divf1 + 1;
217
218		ret = clk_sscg_pll2_find_setup(setup, temp_setup, vco1);
219		if (!ret) {
220			temp_setup->bypass = PLL_BYPASS_NONE;
221			return ret;
222		}
223	}
224
225	return ret;
226}
227
228static int clk_sscg_divr1_lookup(struct clk_sscg_pll_setup *setup,
229				struct clk_sscg_pll_setup *temp_setup)
230{
231	int ret = -EINVAL;
232
233	for (temp_setup->divr1 = 0; temp_setup->divr1 <= PLL_DIVR1_MAX;
234	     temp_setup->divr1++) {
235		temp_setup->ref_div1 = temp_setup->ref;
236		do_div(temp_setup->ref_div1, temp_setup->divr1 + 1);
237		if (temp_setup->ref_div1 >= PLL_STAGE1_REF_MIN_FREQ &&
238		    temp_setup->ref_div1 <= PLL_STAGE1_REF_MAX_FREQ) {
239			ret = clk_sscg_divf1_lookup(setup, temp_setup);
240			if (!ret)
241				return ret;
242		}
243	}
244
245	return ret;
246}
247
248static int clk_sscg_pll1_find_setup(struct clk_sscg_pll_setup *setup,
249					struct clk_sscg_pll_setup *temp_setup,
250					uint64_t ref)
251{
252	int ret;
253
254	if (ref < PLL_REF_MIN_FREQ || ref > PLL_REF_MAX_FREQ)
255		return -EINVAL;
256
257	temp_setup->ref = ref;
258
259	ret = clk_sscg_divr1_lookup(setup, temp_setup);
260
261	return ret;
262}
263
264static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup,
265					uint64_t prate,
266					uint64_t rate, int try_bypass)
267{
268	struct clk_sscg_pll_setup temp_setup;
269	int ret = -EINVAL;
270
271	memset(&temp_setup, 0, sizeof(struct clk_sscg_pll_setup));
272	memset(setup, 0, sizeof(struct clk_sscg_pll_setup));
273
274	temp_setup.fout_error = PLL_OUT_MAX_FREQ;
275	temp_setup.fout_request = rate;
276
277	switch (try_bypass) {
278	case PLL_BYPASS2:
279		if (prate == rate) {
280			setup->bypass = PLL_BYPASS2;
281			setup->fout = rate;
282			ret = 0;
283		}
284		break;
285	case PLL_BYPASS1:
286		ret = clk_sscg_pll2_find_setup(setup, &temp_setup, prate);
287		break;
288	case PLL_BYPASS_NONE:
289		ret = clk_sscg_pll1_find_setup(setup, &temp_setup, prate);
290		break;
291	}
292
293	return ret;
294}
295
296static int clk_sscg_pll_is_prepared(struct clk_hw *hw)
297{
298	struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
299
300	u32 val = readl_relaxed(pll->base + PLL_CFG0);
301
302	return (val & PLL_PD_MASK) ? 0 : 1;
303}
304
305static int clk_sscg_pll_prepare(struct clk_hw *hw)
306{
307	struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
308	u32 val;
309
310	val = readl_relaxed(pll->base + PLL_CFG0);
311	val &= ~PLL_PD_MASK;
312	writel_relaxed(val, pll->base + PLL_CFG0);
313
314	return clk_sscg_pll_wait_lock(pll);
315}
316
317static void clk_sscg_pll_unprepare(struct clk_hw *hw)
318{
319	struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
320	u32 val;
321
322	val = readl_relaxed(pll->base + PLL_CFG0);
323	val |= PLL_PD_MASK;
324	writel_relaxed(val, pll->base + PLL_CFG0);
325}
326
327static unsigned long clk_sscg_pll_recalc_rate(struct clk_hw *hw,
328					 unsigned long parent_rate)
329{
330	struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
331	u32 val, divr1, divf1, divr2, divf2, divq;
332	u64 temp64;
333
334	val = readl_relaxed(pll->base + PLL_CFG2);
335	divr1 = FIELD_GET(PLL_DIVR1_MASK, val);
336	divr2 = FIELD_GET(PLL_DIVR2_MASK, val);
337	divf1 = FIELD_GET(PLL_DIVF1_MASK, val);
338	divf2 = FIELD_GET(PLL_DIVF2_MASK, val);
339	divq = FIELD_GET(PLL_DIVQ_MASK, val);
340
341	temp64 = parent_rate;
342
343	val = readl(pll->base + PLL_CFG0);
344	if (val & SSCG_PLL_BYPASS2_MASK) {
345		temp64 = parent_rate;
346	} else if (val & SSCG_PLL_BYPASS1_MASK) {
347		temp64 *= divf2;
348		do_div(temp64, (divr2 + 1) * (divq + 1));
349	} else {
350		temp64 *= 2;
351		temp64 *= (divf1 + 1) * (divf2 + 1);
352		do_div(temp64, (divr1 + 1) * (divr2 + 1) * (divq + 1));
353	}
354
355	return temp64;
356}
357
358static int clk_sscg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
359			    unsigned long parent_rate)
360{
361	struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
362	struct clk_sscg_pll_setup *setup = &pll->setup;
363	u32 val;
364
365	/* set bypass here too since the parent might be the same */
366	val = readl(pll->base + PLL_CFG0);
367	val &= ~SSCG_PLL_BYPASS_MASK;
368	val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, setup->bypass);
369	writel(val, pll->base + PLL_CFG0);
370
371	val = readl_relaxed(pll->base + PLL_CFG2);
372	val &= ~(PLL_DIVF1_MASK | PLL_DIVF2_MASK);
373	val &= ~(PLL_DIVR1_MASK | PLL_DIVR2_MASK | PLL_DIVQ_MASK);
374	val |= FIELD_PREP(PLL_DIVF1_MASK, setup->divf1);
375	val |= FIELD_PREP(PLL_DIVF2_MASK, setup->divf2);
376	val |= FIELD_PREP(PLL_DIVR1_MASK, setup->divr1);
377	val |= FIELD_PREP(PLL_DIVR2_MASK, setup->divr2);
378	val |= FIELD_PREP(PLL_DIVQ_MASK, setup->divq);
379	writel_relaxed(val, pll->base + PLL_CFG2);
380
381	return clk_sscg_pll_wait_lock(pll);
382}
383
384static u8 clk_sscg_pll_get_parent(struct clk_hw *hw)
385{
386	struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
387	u32 val;
388	u8 ret = pll->parent;
389
390	val = readl(pll->base + PLL_CFG0);
391	if (val & SSCG_PLL_BYPASS2_MASK)
392		ret = pll->bypass2;
393	else if (val & SSCG_PLL_BYPASS1_MASK)
394		ret = pll->bypass1;
395	return ret;
396}
397
398static int clk_sscg_pll_set_parent(struct clk_hw *hw, u8 index)
399{
400	struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
401	u32 val;
402
403	val = readl(pll->base + PLL_CFG0);
404	val &= ~SSCG_PLL_BYPASS_MASK;
405	val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass);
406	writel(val, pll->base + PLL_CFG0);
407
408	return clk_sscg_pll_wait_lock(pll);
409}
410
411static int __clk_sscg_pll_determine_rate(struct clk_hw *hw,
412					struct clk_rate_request *req,
413					uint64_t min,
414					uint64_t max,
415					uint64_t rate,
416					int bypass)
417{
418	struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
419	struct clk_sscg_pll_setup *setup = &pll->setup;
420	struct clk_hw *parent_hw = NULL;
421	int bypass_parent_index;
422	int ret;
423
424	req->max_rate = max;
425	req->min_rate = min;
426
427	switch (bypass) {
428	case PLL_BYPASS2:
429		bypass_parent_index = pll->bypass2;
430		break;
431	case PLL_BYPASS1:
432		bypass_parent_index = pll->bypass1;
433		break;
434	default:
435		bypass_parent_index = pll->parent;
436		break;
437	}
438
439	parent_hw = clk_hw_get_parent_by_index(hw, bypass_parent_index);
440	ret = __clk_determine_rate(parent_hw, req);
441	if (!ret) {
442		ret = clk_sscg_pll_find_setup(setup, req->rate,
443						rate, bypass);
444	}
445
446	req->best_parent_hw = parent_hw;
447	req->best_parent_rate = req->rate;
448	req->rate = setup->fout;
449
450	return ret;
451}
452
453static int clk_sscg_pll_determine_rate(struct clk_hw *hw,
454				       struct clk_rate_request *req)
455{
456	struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
457	struct clk_sscg_pll_setup *setup = &pll->setup;
458	uint64_t rate = req->rate;
459	uint64_t min = req->min_rate;
460	uint64_t max = req->max_rate;
461	int ret;
462
463	if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ)
464		return -EINVAL;
465
466	ret = __clk_sscg_pll_determine_rate(hw, req, req->rate, req->rate,
467						rate, PLL_BYPASS2);
468	if (!ret)
469		return ret;
470
471	ret = __clk_sscg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ,
472						PLL_STAGE1_REF_MAX_FREQ, rate,
473						PLL_BYPASS1);
474	if (!ret)
475		return ret;
476
477	ret = __clk_sscg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ,
478						PLL_REF_MAX_FREQ, rate,
479						PLL_BYPASS_NONE);
480	if (!ret)
481		return ret;
482
483	if (setup->fout >= min && setup->fout <= max)
484		ret = 0;
485
486	return ret;
487}
488
489static const struct clk_ops clk_sscg_pll_ops = {
490	.prepare	= clk_sscg_pll_prepare,
491	.unprepare	= clk_sscg_pll_unprepare,
492	.is_prepared	= clk_sscg_pll_is_prepared,
493	.recalc_rate	= clk_sscg_pll_recalc_rate,
494	.set_rate	= clk_sscg_pll_set_rate,
495	.set_parent	= clk_sscg_pll_set_parent,
496	.get_parent	= clk_sscg_pll_get_parent,
497	.determine_rate	= clk_sscg_pll_determine_rate,
498};
499
500struct clk_hw *imx_clk_hw_sscg_pll(const char *name,
501				const char * const *parent_names,
502				u8 num_parents,
503				u8 parent, u8 bypass1, u8 bypass2,
504				void __iomem *base,
505				unsigned long flags)
506{
507	struct clk_sscg_pll *pll;
508	struct clk_init_data init;
509	struct clk_hw *hw;
510	int ret;
511
512	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
513	if (!pll)
514		return ERR_PTR(-ENOMEM);
515
516	pll->parent = parent;
517	pll->bypass1 = bypass1;
518	pll->bypass2 = bypass2;
519
520	pll->base = base;
521	init.name = name;
522	init.ops = &clk_sscg_pll_ops;
523
524	init.flags = flags;
525	init.parent_names = parent_names;
526	init.num_parents = num_parents;
527
528	pll->hw.init = &init;
529
530	hw = &pll->hw;
531
532	ret = clk_hw_register(NULL, hw);
533	if (ret) {
534		kfree(pll);
535		return ERR_PTR(ret);
536	}
537
538	return hw;
539}
540EXPORT_SYMBOL_GPL(imx_clk_hw_sscg_pll);
541