1 // SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause
2 /*
3  *  Copyright (C) 2016 Atmel Corporation,
4  *		       Songjun Wu <songjun.wu@atmel.com>,
5  *		       Nicolas Ferre <nicolas.ferre@atmel.com>
6  *  Copyright (C) 2017 Free Electrons,
7  *		       Quentin Schulz <quentin.schulz@free-electrons.com>
8  *
9  * The Sama5d2 SoC has two audio PLLs (PMC and PAD) that shares the same parent
10  * (FRAC). FRAC can output between 620 and 700MHz and only multiply the rate of
11  * its own parent. PMC and PAD can then divide the FRAC rate to best match the
12  * asked rate.
13  *
14  * Traits of FRAC clock:
15  * enable - clk_enable writes nd, fracr parameters and enables PLL
16  * rate - rate is adjustable.
17  *        clk->rate = parent->rate * ((nd + 1) + (fracr / 2^22))
18  * parent - fixed parent.  No clk_set_parent support
19  *
20  * Traits of PMC clock:
21  * enable - clk_enable writes qdpmc, and enables PMC output
22  * rate - rate is adjustable.
23  *        clk->rate = parent->rate / (qdpmc + 1)
24  * parent - fixed parent.  No clk_set_parent support
25  *
26  * Traits of PAD clock:
27  * enable - clk_enable writes divisors and enables PAD output
28  * rate - rate is adjustable.
29  *        clk->rate = parent->rate / (qdaudio * div))
30  * parent - fixed parent.  No clk_set_parent support
31  */
32 
33 #include <io.h>
34 #include <kernel/delay.h>
35 #include <kernel/panic.h>
36 #include <mm/core_memprot.h>
37 #include <string.h>
38 #include <types_ext.h>
39 
40 #include "at91_clk.h"
41 
42 #define AUDIO_PLL_DIV_FRAC	BIT(22)
43 #define AUDIO_PLL_ND_MAX	(AT91_PMC_AUDIO_PLL_ND_MASK >> \
44 					AT91_PMC_AUDIO_PLL_ND_OFFSET)
45 
46 #define AUDIO_PLL_QDPAD(qd, div) \
47 				((AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV(qd) & \
48 				  AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MASK) | \
49 				 (AT91_PMC_AUDIO_PLL_QDPAD_DIV(div) & \
50 				  AT91_PMC_AUDIO_PLL_QDPAD_DIV_MASK))
51 
52 #define AUDIO_PLL_QDPMC_MAX		(AT91_PMC_AUDIO_PLL_QDPMC_MASK >> \
53 						AT91_PMC_AUDIO_PLL_QDPMC_OFFSET)
54 
55 #define AUDIO_PLL_FOUT_MIN	620000000UL
56 #define AUDIO_PLL_FOUT_MAX	700000000UL
57 
58 struct clk_audio_frac {
59 	vaddr_t base;
60 	uint32_t fracr;
61 	uint8_t nd;
62 };
63 
64 struct clk_audio_pad {
65 	vaddr_t base;
66 	uint8_t qdaudio;
67 	uint8_t div;
68 };
69 
70 struct clk_audio_pmc {
71 	vaddr_t base;
72 	uint8_t qdpmc;
73 };
74 
clk_audio_pll_frac_enable(struct clk * clk)75 static TEE_Result clk_audio_pll_frac_enable(struct clk *clk)
76 {
77 	struct clk_audio_frac *frac = clk->priv;
78 
79 	io_clrbits32(frac->base + AT91_PMC_AUDIO_PLL0,
80 		     AT91_PMC_AUDIO_PLL_RESETN);
81 	io_setbits32(frac->base + AT91_PMC_AUDIO_PLL0,
82 		     AT91_PMC_AUDIO_PLL_RESETN);
83 	io_clrsetbits32(frac->base + AT91_PMC_AUDIO_PLL1,
84 			AT91_PMC_AUDIO_PLL_FRACR_MASK, frac->fracr);
85 
86 	/*
87 	 * reset and enable have to be done in 2 separated writes
88 	 * for AT91_PMC_AUDIO_PLL0
89 	 */
90 	io_clrsetbits32(frac->base + AT91_PMC_AUDIO_PLL0,
91 			AT91_PMC_AUDIO_PLL_PLLEN |
92 			AT91_PMC_AUDIO_PLL_ND_MASK,
93 			AT91_PMC_AUDIO_PLL_PLLEN |
94 			AT91_PMC_AUDIO_PLL_ND(frac->nd));
95 
96 	return TEE_SUCCESS;
97 }
98 
clk_audio_pll_pad_enable(struct clk * clk)99 static TEE_Result clk_audio_pll_pad_enable(struct clk *clk)
100 {
101 	struct clk_audio_pad *apad_ck = clk->priv;
102 
103 	io_clrsetbits32(apad_ck->base + AT91_PMC_AUDIO_PLL1,
104 			AT91_PMC_AUDIO_PLL_QDPAD_MASK,
105 			AUDIO_PLL_QDPAD(apad_ck->qdaudio, apad_ck->div));
106 	io_clrsetbits32(apad_ck->base + AT91_PMC_AUDIO_PLL0,
107 			AT91_PMC_AUDIO_PLL_PADEN, AT91_PMC_AUDIO_PLL_PADEN);
108 
109 	return TEE_SUCCESS;
110 }
111 
clk_audio_pll_pmc_enable(struct clk * clk)112 static TEE_Result clk_audio_pll_pmc_enable(struct clk *clk)
113 {
114 	struct clk_audio_pmc *apmc_ck = clk->priv;
115 
116 	io_clrsetbits32(apmc_ck->base + AT91_PMC_AUDIO_PLL0,
117 			AT91_PMC_AUDIO_PLL_PMCEN |
118 			AT91_PMC_AUDIO_PLL_QDPMC_MASK,
119 			AT91_PMC_AUDIO_PLL_PMCEN |
120 			AT91_PMC_AUDIO_PLL_QDPMC(apmc_ck->qdpmc));
121 	return TEE_SUCCESS;
122 }
123 
clk_audio_pll_frac_disable(struct clk * clk)124 static void clk_audio_pll_frac_disable(struct clk *clk)
125 {
126 	struct clk_audio_frac *frac = clk->priv;
127 
128 	io_clrbits32(frac->base + AT91_PMC_AUDIO_PLL0,
129 		     AT91_PMC_AUDIO_PLL_PLLEN);
130 	/* Requires 2 separated writes */
131 	io_clrbits32(frac->base + AT91_PMC_AUDIO_PLL0,
132 		     AT91_PMC_AUDIO_PLL_RESETN);
133 }
134 
clk_audio_pll_pad_disable(struct clk * clk)135 static void clk_audio_pll_pad_disable(struct clk *clk)
136 {
137 	struct clk_audio_pad *apad_ck = clk->priv;
138 
139 	io_clrbits32(apad_ck->base + AT91_PMC_AUDIO_PLL0,
140 		     AT91_PMC_AUDIO_PLL_PADEN);
141 }
142 
clk_audio_pll_pmc_disable(struct clk * clk)143 static void clk_audio_pll_pmc_disable(struct clk *clk)
144 {
145 	struct clk_audio_pmc *apmc_ck = clk->priv;
146 
147 	io_clrbits32(apmc_ck->base + AT91_PMC_AUDIO_PLL0,
148 		     AT91_PMC_AUDIO_PLL_PMCEN);
149 }
150 
clk_audio_pll_fout(unsigned long parent_rate,unsigned long nd,unsigned long fracr)151 static unsigned long clk_audio_pll_fout(unsigned long parent_rate,
152 					unsigned long nd, unsigned long fracr)
153 {
154 	unsigned long long fr = (unsigned long long)parent_rate * fracr;
155 
156 	fr = UDIV_ROUND_NEAREST(fr, AUDIO_PLL_DIV_FRAC);
157 
158 	return parent_rate * (nd + 1) + fr;
159 }
160 
clk_audio_pll_frac_get_rate(struct clk * clk,unsigned long parent_rate)161 static unsigned long clk_audio_pll_frac_get_rate(struct clk *clk,
162 						 unsigned long parent_rate)
163 {
164 	struct clk_audio_frac *frac = clk->priv;
165 
166 	return clk_audio_pll_fout(parent_rate, frac->nd, frac->fracr);
167 }
168 
clk_audio_pll_pad_get_rate(struct clk * clk,unsigned long parent_rate)169 static unsigned long clk_audio_pll_pad_get_rate(struct clk *clk,
170 						unsigned long parent_rate)
171 {
172 	struct clk_audio_pad *apad_ck = clk->priv;
173 	unsigned long apad_rate = 0;
174 
175 	if (apad_ck->qdaudio && apad_ck->div)
176 		apad_rate = parent_rate / (apad_ck->qdaudio * apad_ck->div);
177 
178 	return apad_rate;
179 }
180 
clk_audio_pll_pmc_get_rate(struct clk * clk,unsigned long parent_rate)181 static unsigned long clk_audio_pll_pmc_get_rate(struct clk *clk,
182 						unsigned long parent_rate)
183 {
184 	struct clk_audio_pmc *apmc_ck = clk->priv;
185 
186 	return parent_rate / (apmc_ck->qdpmc + 1);
187 }
188 
clk_audio_pll_frac_compute_frac(unsigned long rate,unsigned long parent_rate,unsigned long * nd,unsigned long * fracr)189 static TEE_Result clk_audio_pll_frac_compute_frac(unsigned long rate,
190 						  unsigned long parent_rate,
191 						  unsigned long *nd,
192 						  unsigned long *fracr)
193 {
194 	unsigned long long tmp = 0;
195 	unsigned long long rem = 0;
196 
197 	if (!rate || !parent_rate)
198 		return TEE_ERROR_BAD_PARAMETERS;
199 
200 	tmp = rate;
201 	rem = tmp % parent_rate;
202 	tmp /= parent_rate;
203 	if (!tmp || tmp >= AUDIO_PLL_ND_MAX)
204 		return TEE_ERROR_BAD_PARAMETERS;
205 
206 	*nd = tmp - 1;
207 
208 	tmp = rem * AUDIO_PLL_DIV_FRAC;
209 	tmp = UDIV_ROUND_NEAREST(tmp, parent_rate);
210 	if (tmp > AT91_PMC_AUDIO_PLL_FRACR_MASK)
211 		return TEE_ERROR_BAD_PARAMETERS;
212 
213 	/* we can cast here as we verified the bounds just above */
214 	*fracr = (unsigned long)tmp;
215 
216 	return TEE_SUCCESS;
217 }
218 
clk_audio_pll_frac_set_rate(struct clk * clk,unsigned long rate,unsigned long parent_rate)219 static TEE_Result clk_audio_pll_frac_set_rate(struct clk *clk,
220 					      unsigned long rate,
221 					      unsigned long parent_rate)
222 {
223 	struct clk_audio_frac *frac = clk->priv;
224 	unsigned long fracr = 0;
225 	unsigned long nd = 0;
226 	TEE_Result res = TEE_ERROR_GENERIC;
227 
228 	if (rate < AUDIO_PLL_FOUT_MIN || rate > AUDIO_PLL_FOUT_MAX)
229 		return TEE_ERROR_BAD_PARAMETERS;
230 
231 	res = clk_audio_pll_frac_compute_frac(rate, parent_rate, &nd, &fracr);
232 	if (res)
233 		return res;
234 
235 	frac->nd = nd;
236 	frac->fracr = fracr;
237 
238 	return TEE_SUCCESS;
239 }
240 
clk_audio_pll_pad_set_rate(struct clk * clk,unsigned long rate,unsigned long parent_rate)241 static TEE_Result clk_audio_pll_pad_set_rate(struct clk *clk,
242 					     unsigned long rate,
243 					     unsigned long parent_rate)
244 {
245 	struct clk_audio_pad *apad_ck = clk->priv;
246 	uint8_t tmp_div = 1;
247 
248 	if (!rate)
249 		return TEE_ERROR_BAD_PARAMETERS;
250 
251 	tmp_div = parent_rate / rate;
252 	if (tmp_div % 3 == 0) {
253 		apad_ck->qdaudio = tmp_div / 3;
254 		apad_ck->div = 3;
255 	} else {
256 		apad_ck->qdaudio = tmp_div / 2;
257 		apad_ck->div = 2;
258 	}
259 
260 	return TEE_SUCCESS;
261 }
262 
clk_audio_pll_pmc_set_rate(struct clk * clk,unsigned long rate,unsigned long parent_rate)263 static TEE_Result clk_audio_pll_pmc_set_rate(struct clk *clk,
264 					     unsigned long rate,
265 					     unsigned long parent_rate)
266 {
267 	struct clk_audio_pmc *apmc_ck = clk->priv;
268 
269 	if (!rate)
270 		return TEE_ERROR_BAD_PARAMETERS;
271 
272 	apmc_ck->qdpmc = parent_rate / rate - 1;
273 
274 	return TEE_SUCCESS;
275 }
276 
277 static const struct clk_ops audio_pll_frac_ops = {
278 	.enable = clk_audio_pll_frac_enable,
279 	.disable = clk_audio_pll_frac_disable,
280 	.get_rate = clk_audio_pll_frac_get_rate,
281 	.set_rate = clk_audio_pll_frac_set_rate,
282 };
283 
284 static const struct clk_ops audio_pll_pad_ops = {
285 	.enable = clk_audio_pll_pad_enable,
286 	.disable = clk_audio_pll_pad_disable,
287 	.get_rate = clk_audio_pll_pad_get_rate,
288 	.set_rate = clk_audio_pll_pad_set_rate,
289 };
290 
291 static const struct clk_ops audio_pll_pmc_ops = {
292 	.enable = clk_audio_pll_pmc_enable,
293 	.disable = clk_audio_pll_pmc_disable,
294 	.get_rate = clk_audio_pll_pmc_get_rate,
295 	.set_rate = clk_audio_pll_pmc_set_rate,
296 };
297 
298 struct clk *
at91_clk_register_audio_pll_frac(struct pmc_data * pmc,const char * name,struct clk * parent)299 at91_clk_register_audio_pll_frac(struct pmc_data *pmc, const char *name,
300 				 struct clk *parent)
301 {
302 	struct clk_audio_frac *frac_ck = NULL;
303 	struct clk *clk = NULL;
304 
305 	clk = clk_alloc(name, &audio_pll_frac_ops, &parent, 1);
306 	if (!clk)
307 		return NULL;
308 
309 	frac_ck = calloc(1, sizeof(*frac_ck));
310 	if (!frac_ck) {
311 		clk_free(clk);
312 		return NULL;
313 	}
314 
315 	clk->flags = CLK_SET_RATE_GATE;
316 
317 	frac_ck->base = pmc->base;
318 
319 	clk->priv = frac_ck;
320 	if (clk_register(clk)) {
321 		clk_free(clk);
322 		free(frac_ck);
323 		return NULL;
324 	}
325 
326 	return clk;
327 }
328 
329 struct clk *
at91_clk_register_audio_pll_pad(struct pmc_data * pmc,const char * name,struct clk * parent)330 at91_clk_register_audio_pll_pad(struct pmc_data *pmc, const char *name,
331 				struct clk *parent)
332 {
333 	struct clk_audio_pad *apad_ck = NULL;
334 	struct clk *clk = NULL;
335 
336 	clk = clk_alloc(name, &audio_pll_pad_ops, &parent, 1);
337 	if (!clk)
338 		return NULL;
339 
340 	apad_ck = calloc(1, sizeof(*apad_ck));
341 	if (!apad_ck) {
342 		clk_free(clk);
343 		return NULL;
344 	}
345 
346 	clk->flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
347 
348 	apad_ck->base = pmc->base;
349 
350 	clk->priv = apad_ck;
351 	if (clk_register(clk)) {
352 		clk_free(clk);
353 		free(apad_ck);
354 		return NULL;
355 	}
356 
357 	return clk;
358 }
359 
360 struct clk *
at91_clk_register_audio_pll_pmc(struct pmc_data * pmc,const char * name,struct clk * parent)361 at91_clk_register_audio_pll_pmc(struct pmc_data *pmc, const char *name,
362 				struct clk *parent)
363 {
364 	struct clk_audio_pmc *apmc_ck = NULL;
365 	struct clk *clk = NULL;
366 
367 	clk = clk_alloc(name, &audio_pll_pmc_ops, &parent, 1);
368 	if (!clk)
369 		return NULL;
370 
371 	apmc_ck = calloc(1, sizeof(*apmc_ck));
372 	if (!apmc_ck) {
373 		clk_free(clk);
374 		return NULL;
375 	}
376 
377 	clk->flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
378 
379 	apmc_ck->base = pmc->base;
380 
381 	clk->priv = apmc_ck;
382 
383 	if (clk_register(clk)) {
384 		clk_free(clk);
385 		free(apmc_ck);
386 		return NULL;
387 	}
388 
389 	return clk;
390 }
391