Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/clk/at91/clk-sam9x60-pll.c
26292 views
1
// SPDX-License-Identifier: GPL-2.0+
2
/*
3
* Copyright (C) 2019 Microchip Technology Inc.
4
*
5
*/
6
7
#include <linux/bitfield.h>
8
#include <linux/clk.h>
9
#include <linux/clk-provider.h>
10
#include <linux/clkdev.h>
11
#include <linux/clk/at91_pmc.h>
12
#include <linux/of.h>
13
#include <linux/mfd/syscon.h>
14
#include <linux/regmap.h>
15
16
#include "pmc.h"
17
18
#define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
19
#define PMC_PLL_CTRL1_MUL_MSK GENMASK(31, 24)
20
#define PMC_PLL_CTRL1_FRACR_MSK GENMASK(21, 0)
21
22
#define PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
23
#define UPLL_DIV 2
24
#define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
25
26
#define PLL_MAX_ID 9
27
28
struct sam9x60_pll_core {
29
struct regmap *regmap;
30
spinlock_t *lock;
31
const struct clk_pll_characteristics *characteristics;
32
const struct clk_pll_layout *layout;
33
struct clk_hw hw;
34
u8 id;
35
};
36
37
struct sam9x60_frac {
38
struct sam9x60_pll_core core;
39
struct at91_clk_pms pms;
40
u32 frac;
41
u16 mul;
42
};
43
44
struct sam9x60_div {
45
struct sam9x60_pll_core core;
46
struct at91_clk_pms pms;
47
u8 div;
48
u8 safe_div;
49
};
50
51
#define to_sam9x60_pll_core(hw) container_of(hw, struct sam9x60_pll_core, hw)
52
#define to_sam9x60_frac(core) container_of(core, struct sam9x60_frac, core)
53
#define to_sam9x60_div(core) container_of(core, struct sam9x60_div, core)
54
55
static struct sam9x60_div *notifier_div;
56
57
static inline bool sam9x60_pll_ready(struct regmap *regmap, int id)
58
{
59
unsigned int status;
60
61
regmap_read(regmap, AT91_PMC_PLL_ISR0, &status);
62
63
return !!(status & BIT(id));
64
}
65
66
static bool sam9x60_frac_pll_ready(struct regmap *regmap, u8 id)
67
{
68
return sam9x60_pll_ready(regmap, id);
69
}
70
71
static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw,
72
unsigned long parent_rate)
73
{
74
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
75
struct sam9x60_frac *frac = to_sam9x60_frac(core);
76
unsigned long freq;
77
78
freq = parent_rate * (frac->mul + 1) +
79
DIV_ROUND_CLOSEST_ULL((u64)parent_rate * frac->frac, (1 << 22));
80
81
if (core->layout->div2)
82
freq >>= 1;
83
84
return freq;
85
}
86
87
static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core)
88
{
89
struct sam9x60_frac *frac = to_sam9x60_frac(core);
90
struct regmap *regmap = core->regmap;
91
unsigned int val, cfrac, cmul;
92
unsigned long flags;
93
94
spin_lock_irqsave(core->lock, flags);
95
96
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
97
AT91_PMC_PLL_UPDT_ID_MSK, core->id);
98
regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
99
cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift;
100
cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
101
102
if (sam9x60_frac_pll_ready(regmap, core->id) &&
103
(cmul == frac->mul && cfrac == frac->frac))
104
goto unlock;
105
106
/* Recommended value for PMC_PLL_ACR */
107
if (core->characteristics->upll)
108
val = AT91_PMC_PLL_ACR_DEFAULT_UPLL;
109
else
110
val = AT91_PMC_PLL_ACR_DEFAULT_PLLA;
111
regmap_write(regmap, AT91_PMC_PLL_ACR, val);
112
113
regmap_write(regmap, AT91_PMC_PLL_CTRL1,
114
(frac->mul << core->layout->mul_shift) |
115
(frac->frac << core->layout->frac_shift));
116
117
if (core->characteristics->upll) {
118
/* Enable the UTMI internal bandgap */
119
val |= AT91_PMC_PLL_ACR_UTMIBG;
120
regmap_write(regmap, AT91_PMC_PLL_ACR, val);
121
122
udelay(10);
123
124
/* Enable the UTMI internal regulator */
125
val |= AT91_PMC_PLL_ACR_UTMIVR;
126
regmap_write(regmap, AT91_PMC_PLL_ACR, val);
127
128
udelay(10);
129
}
130
131
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
132
AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
133
AT91_PMC_PLL_UPDT_UPDATE | core->id);
134
135
regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
136
AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL,
137
AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL);
138
139
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
140
AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
141
AT91_PMC_PLL_UPDT_UPDATE | core->id);
142
143
while (!sam9x60_pll_ready(regmap, core->id))
144
cpu_relax();
145
146
unlock:
147
spin_unlock_irqrestore(core->lock, flags);
148
149
return 0;
150
}
151
152
static int sam9x60_frac_pll_prepare(struct clk_hw *hw)
153
{
154
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
155
156
return sam9x60_frac_pll_set(core);
157
}
158
159
static void sam9x60_frac_pll_unprepare(struct clk_hw *hw)
160
{
161
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
162
struct regmap *regmap = core->regmap;
163
unsigned long flags;
164
165
spin_lock_irqsave(core->lock, flags);
166
167
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
168
AT91_PMC_PLL_UPDT_ID_MSK, core->id);
169
170
regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, AT91_PMC_PLL_CTRL0_ENPLL, 0);
171
172
if (core->characteristics->upll)
173
regmap_update_bits(regmap, AT91_PMC_PLL_ACR,
174
AT91_PMC_PLL_ACR_UTMIBG | AT91_PMC_PLL_ACR_UTMIVR, 0);
175
176
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
177
AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
178
AT91_PMC_PLL_UPDT_UPDATE | core->id);
179
180
spin_unlock_irqrestore(core->lock, flags);
181
}
182
183
static int sam9x60_frac_pll_is_prepared(struct clk_hw *hw)
184
{
185
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
186
187
return sam9x60_pll_ready(core->regmap, core->id);
188
}
189
190
static long sam9x60_frac_pll_compute_mul_frac(struct sam9x60_pll_core *core,
191
unsigned long rate,
192
unsigned long parent_rate,
193
bool update)
194
{
195
struct sam9x60_frac *frac = to_sam9x60_frac(core);
196
unsigned long tmprate, remainder;
197
unsigned long nmul = 0;
198
unsigned long nfrac = 0;
199
200
if (rate < core->characteristics->core_output[0].min ||
201
rate > core->characteristics->core_output[0].max)
202
return -ERANGE;
203
204
/*
205
* Calculate the multiplier associated with the current
206
* divider that provide the closest rate to the requested one.
207
*/
208
nmul = mult_frac(rate, 1, parent_rate);
209
tmprate = mult_frac(parent_rate, nmul, 1);
210
remainder = rate - tmprate;
211
212
if (remainder) {
213
nfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * (1 << 22),
214
parent_rate);
215
216
tmprate += DIV_ROUND_CLOSEST_ULL((u64)nfrac * parent_rate,
217
(1 << 22));
218
}
219
220
/* Check if resulted rate is a valid. */
221
if (tmprate < core->characteristics->core_output[0].min ||
222
tmprate > core->characteristics->core_output[0].max)
223
return -ERANGE;
224
225
if (update) {
226
frac->mul = nmul - 1;
227
frac->frac = nfrac;
228
}
229
230
return tmprate;
231
}
232
233
static long sam9x60_frac_pll_round_rate(struct clk_hw *hw, unsigned long rate,
234
unsigned long *parent_rate)
235
{
236
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
237
238
return sam9x60_frac_pll_compute_mul_frac(core, rate, *parent_rate, false);
239
}
240
241
static int sam9x60_frac_pll_set_rate(struct clk_hw *hw, unsigned long rate,
242
unsigned long parent_rate)
243
{
244
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
245
246
return sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true);
247
}
248
249
static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate,
250
unsigned long parent_rate)
251
{
252
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
253
struct sam9x60_frac *frac = to_sam9x60_frac(core);
254
struct regmap *regmap = core->regmap;
255
unsigned long irqflags;
256
unsigned int val, cfrac, cmul;
257
long ret;
258
259
ret = sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true);
260
if (ret <= 0)
261
return ret;
262
263
spin_lock_irqsave(core->lock, irqflags);
264
265
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
266
core->id);
267
regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
268
cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift;
269
cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift;
270
271
if (cmul == frac->mul && cfrac == frac->frac)
272
goto unlock;
273
274
regmap_write(regmap, AT91_PMC_PLL_CTRL1,
275
(frac->mul << core->layout->mul_shift) |
276
(frac->frac << core->layout->frac_shift));
277
278
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
279
AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
280
AT91_PMC_PLL_UPDT_UPDATE | core->id);
281
282
regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
283
AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL,
284
AT91_PMC_PLL_CTRL0_ENLOCK |
285
AT91_PMC_PLL_CTRL0_ENPLL);
286
287
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
288
AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
289
AT91_PMC_PLL_UPDT_UPDATE | core->id);
290
291
while (!sam9x60_pll_ready(regmap, core->id))
292
cpu_relax();
293
294
unlock:
295
spin_unlock_irqrestore(core->lock, irqflags);
296
297
return ret;
298
}
299
300
static int sam9x60_frac_pll_save_context(struct clk_hw *hw)
301
{
302
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
303
struct sam9x60_frac *frac = to_sam9x60_frac(core);
304
305
frac->pms.status = sam9x60_pll_ready(core->regmap, core->id);
306
307
return 0;
308
}
309
310
static void sam9x60_frac_pll_restore_context(struct clk_hw *hw)
311
{
312
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
313
struct sam9x60_frac *frac = to_sam9x60_frac(core);
314
315
if (frac->pms.status)
316
sam9x60_frac_pll_set(core);
317
}
318
319
static const struct clk_ops sam9x60_frac_pll_ops = {
320
.prepare = sam9x60_frac_pll_prepare,
321
.unprepare = sam9x60_frac_pll_unprepare,
322
.is_prepared = sam9x60_frac_pll_is_prepared,
323
.recalc_rate = sam9x60_frac_pll_recalc_rate,
324
.round_rate = sam9x60_frac_pll_round_rate,
325
.set_rate = sam9x60_frac_pll_set_rate,
326
.save_context = sam9x60_frac_pll_save_context,
327
.restore_context = sam9x60_frac_pll_restore_context,
328
};
329
330
static const struct clk_ops sam9x60_frac_pll_ops_chg = {
331
.prepare = sam9x60_frac_pll_prepare,
332
.unprepare = sam9x60_frac_pll_unprepare,
333
.is_prepared = sam9x60_frac_pll_is_prepared,
334
.recalc_rate = sam9x60_frac_pll_recalc_rate,
335
.round_rate = sam9x60_frac_pll_round_rate,
336
.set_rate = sam9x60_frac_pll_set_rate_chg,
337
.save_context = sam9x60_frac_pll_save_context,
338
.restore_context = sam9x60_frac_pll_restore_context,
339
};
340
341
/* This function should be called with spinlock acquired. */
342
static void sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, u32 div,
343
bool enable)
344
{
345
struct regmap *regmap = core->regmap;
346
u32 ena_msk = enable ? core->layout->endiv_mask : 0;
347
u32 ena_val = enable ? (1 << core->layout->endiv_shift) : 0;
348
349
regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
350
core->layout->div_mask | ena_msk,
351
(div << core->layout->div_shift) | ena_val);
352
353
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
354
AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
355
AT91_PMC_PLL_UPDT_UPDATE | core->id);
356
357
while (!sam9x60_pll_ready(regmap, core->id))
358
cpu_relax();
359
}
360
361
static int sam9x60_div_pll_set(struct sam9x60_pll_core *core)
362
{
363
struct sam9x60_div *div = to_sam9x60_div(core);
364
struct regmap *regmap = core->regmap;
365
unsigned long flags;
366
unsigned int val, cdiv;
367
368
spin_lock_irqsave(core->lock, flags);
369
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
370
AT91_PMC_PLL_UPDT_ID_MSK, core->id);
371
regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
372
cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
373
374
/* Stop if enabled an nothing changed. */
375
if (!!(val & core->layout->endiv_mask) && cdiv == div->div)
376
goto unlock;
377
378
sam9x60_div_pll_set_div(core, div->div, 1);
379
380
unlock:
381
spin_unlock_irqrestore(core->lock, flags);
382
383
return 0;
384
}
385
386
static int sam9x60_div_pll_prepare(struct clk_hw *hw)
387
{
388
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
389
390
return sam9x60_div_pll_set(core);
391
}
392
393
static void sam9x60_div_pll_unprepare(struct clk_hw *hw)
394
{
395
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
396
struct regmap *regmap = core->regmap;
397
unsigned long flags;
398
399
spin_lock_irqsave(core->lock, flags);
400
401
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
402
AT91_PMC_PLL_UPDT_ID_MSK, core->id);
403
404
regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0,
405
core->layout->endiv_mask, 0);
406
407
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
408
AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK,
409
AT91_PMC_PLL_UPDT_UPDATE | core->id);
410
411
spin_unlock_irqrestore(core->lock, flags);
412
}
413
414
static int sam9x60_div_pll_is_prepared(struct clk_hw *hw)
415
{
416
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
417
struct regmap *regmap = core->regmap;
418
unsigned long flags;
419
unsigned int val;
420
421
spin_lock_irqsave(core->lock, flags);
422
423
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
424
AT91_PMC_PLL_UPDT_ID_MSK, core->id);
425
regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
426
427
spin_unlock_irqrestore(core->lock, flags);
428
429
return !!(val & core->layout->endiv_mask);
430
}
431
432
static unsigned long sam9x60_div_pll_recalc_rate(struct clk_hw *hw,
433
unsigned long parent_rate)
434
{
435
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
436
struct sam9x60_div *div = to_sam9x60_div(core);
437
438
return DIV_ROUND_CLOSEST_ULL(parent_rate, (div->div + 1));
439
}
440
441
static unsigned long sam9x60_fixed_div_pll_recalc_rate(struct clk_hw *hw,
442
unsigned long parent_rate)
443
{
444
return parent_rate >> 1;
445
}
446
447
static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
448
unsigned long *parent_rate,
449
unsigned long rate)
450
{
451
const struct clk_pll_characteristics *characteristics =
452
core->characteristics;
453
struct clk_hw *parent = clk_hw_get_parent(&core->hw);
454
unsigned long tmp_rate, tmp_parent_rate, tmp_diff;
455
long best_diff = -1, best_rate = -EINVAL;
456
u32 divid;
457
458
if (!rate)
459
return 0;
460
461
if (rate < characteristics->output[0].min ||
462
rate > characteristics->output[0].max)
463
return -ERANGE;
464
465
for (divid = 1; divid < core->layout->div_mask; divid++) {
466
tmp_parent_rate = clk_hw_round_rate(parent, rate * divid);
467
if (!tmp_parent_rate)
468
continue;
469
470
tmp_rate = DIV_ROUND_CLOSEST_ULL(tmp_parent_rate, divid);
471
tmp_diff = abs(rate - tmp_rate);
472
473
if (best_diff < 0 || best_diff > tmp_diff) {
474
*parent_rate = tmp_parent_rate;
475
best_rate = tmp_rate;
476
best_diff = tmp_diff;
477
}
478
479
if (!best_diff)
480
break;
481
}
482
483
if (best_rate < characteristics->output[0].min ||
484
best_rate > characteristics->output[0].max)
485
return -ERANGE;
486
487
return best_rate;
488
}
489
490
static long sam9x60_div_pll_round_rate(struct clk_hw *hw, unsigned long rate,
491
unsigned long *parent_rate)
492
{
493
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
494
495
return sam9x60_div_pll_compute_div(core, parent_rate, rate);
496
}
497
498
static int sam9x60_div_pll_set_rate(struct clk_hw *hw, unsigned long rate,
499
unsigned long parent_rate)
500
{
501
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
502
struct sam9x60_div *div = to_sam9x60_div(core);
503
504
div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1;
505
506
return 0;
507
}
508
509
static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate,
510
unsigned long parent_rate)
511
{
512
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
513
struct sam9x60_div *div = to_sam9x60_div(core);
514
struct regmap *regmap = core->regmap;
515
unsigned long irqflags;
516
unsigned int val, cdiv;
517
518
div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1;
519
520
spin_lock_irqsave(core->lock, irqflags);
521
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
522
core->id);
523
regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
524
cdiv = (val & core->layout->div_mask) >> core->layout->div_shift;
525
526
/* Stop if nothing changed. */
527
if (cdiv == div->div)
528
goto unlock;
529
530
sam9x60_div_pll_set_div(core, div->div, 0);
531
532
unlock:
533
spin_unlock_irqrestore(core->lock, irqflags);
534
535
return 0;
536
}
537
538
static int sam9x60_div_pll_save_context(struct clk_hw *hw)
539
{
540
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
541
struct sam9x60_div *div = to_sam9x60_div(core);
542
543
div->pms.status = sam9x60_div_pll_is_prepared(hw);
544
545
return 0;
546
}
547
548
static void sam9x60_div_pll_restore_context(struct clk_hw *hw)
549
{
550
struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw);
551
struct sam9x60_div *div = to_sam9x60_div(core);
552
553
if (div->pms.status)
554
sam9x60_div_pll_set(core);
555
}
556
557
static int sam9x60_div_pll_notifier_fn(struct notifier_block *notifier,
558
unsigned long code, void *data)
559
{
560
struct sam9x60_div *div = notifier_div;
561
struct sam9x60_pll_core core = div->core;
562
struct regmap *regmap = core.regmap;
563
unsigned long irqflags;
564
u32 val, cdiv;
565
int ret = NOTIFY_DONE;
566
567
if (code != PRE_RATE_CHANGE)
568
return ret;
569
570
/*
571
* We switch to safe divider to avoid overclocking of other domains
572
* feed by us while the frac PLL (our parent) is changed.
573
*/
574
div->div = div->safe_div;
575
576
spin_lock_irqsave(core.lock, irqflags);
577
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK,
578
core.id);
579
regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
580
cdiv = (val & core.layout->div_mask) >> core.layout->div_shift;
581
582
/* Stop if nothing changed. */
583
if (cdiv == div->safe_div)
584
goto unlock;
585
586
sam9x60_div_pll_set_div(&core, div->div, 0);
587
ret = NOTIFY_OK;
588
589
unlock:
590
spin_unlock_irqrestore(core.lock, irqflags);
591
592
return ret;
593
}
594
595
static struct notifier_block sam9x60_div_pll_notifier = {
596
.notifier_call = sam9x60_div_pll_notifier_fn,
597
};
598
599
static const struct clk_ops sam9x60_div_pll_ops = {
600
.prepare = sam9x60_div_pll_prepare,
601
.unprepare = sam9x60_div_pll_unprepare,
602
.is_prepared = sam9x60_div_pll_is_prepared,
603
.recalc_rate = sam9x60_div_pll_recalc_rate,
604
.round_rate = sam9x60_div_pll_round_rate,
605
.set_rate = sam9x60_div_pll_set_rate,
606
.save_context = sam9x60_div_pll_save_context,
607
.restore_context = sam9x60_div_pll_restore_context,
608
};
609
610
static const struct clk_ops sam9x60_div_pll_ops_chg = {
611
.prepare = sam9x60_div_pll_prepare,
612
.unprepare = sam9x60_div_pll_unprepare,
613
.is_prepared = sam9x60_div_pll_is_prepared,
614
.recalc_rate = sam9x60_div_pll_recalc_rate,
615
.round_rate = sam9x60_div_pll_round_rate,
616
.set_rate = sam9x60_div_pll_set_rate_chg,
617
.save_context = sam9x60_div_pll_save_context,
618
.restore_context = sam9x60_div_pll_restore_context,
619
};
620
621
static const struct clk_ops sam9x60_fixed_div_pll_ops = {
622
.prepare = sam9x60_div_pll_prepare,
623
.unprepare = sam9x60_div_pll_unprepare,
624
.is_prepared = sam9x60_div_pll_is_prepared,
625
.recalc_rate = sam9x60_fixed_div_pll_recalc_rate,
626
.round_rate = sam9x60_div_pll_round_rate,
627
.save_context = sam9x60_div_pll_save_context,
628
.restore_context = sam9x60_div_pll_restore_context,
629
};
630
631
struct clk_hw * __init
632
sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock,
633
const char *name, const char *parent_name,
634
struct clk_hw *parent_hw, u8 id,
635
const struct clk_pll_characteristics *characteristics,
636
const struct clk_pll_layout *layout, u32 flags)
637
{
638
struct sam9x60_frac *frac;
639
struct clk_hw *hw;
640
struct clk_init_data init = {};
641
unsigned long parent_rate, irqflags;
642
unsigned int val;
643
int ret;
644
645
if (id > PLL_MAX_ID || !lock || !parent_hw)
646
return ERR_PTR(-EINVAL);
647
648
frac = kzalloc(sizeof(*frac), GFP_KERNEL);
649
if (!frac)
650
return ERR_PTR(-ENOMEM);
651
652
init.name = name;
653
if (parent_name)
654
init.parent_names = &parent_name;
655
else
656
init.parent_hws = (const struct clk_hw **)&parent_hw;
657
init.num_parents = 1;
658
if (flags & CLK_SET_RATE_GATE)
659
init.ops = &sam9x60_frac_pll_ops;
660
else
661
init.ops = &sam9x60_frac_pll_ops_chg;
662
663
init.flags = flags;
664
665
frac->core.id = id;
666
frac->core.hw.init = &init;
667
frac->core.characteristics = characteristics;
668
frac->core.layout = layout;
669
frac->core.regmap = regmap;
670
frac->core.lock = lock;
671
672
spin_lock_irqsave(frac->core.lock, irqflags);
673
if (sam9x60_pll_ready(regmap, id)) {
674
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
675
AT91_PMC_PLL_UPDT_ID_MSK, id);
676
regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val);
677
frac->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val);
678
frac->frac = FIELD_GET(PMC_PLL_CTRL1_FRACR_MSK, val);
679
} else {
680
/*
681
* This means the PLL is not setup by bootloaders. In this
682
* case we need to set the minimum rate for it. Otherwise
683
* a clock child of this PLL may be enabled before setting
684
* its rate leading to enabling this PLL with unsupported
685
* rate. This will lead to PLL not being locked at all.
686
*/
687
parent_rate = clk_hw_get_rate(parent_hw);
688
if (!parent_rate) {
689
hw = ERR_PTR(-EINVAL);
690
goto free;
691
}
692
693
ret = sam9x60_frac_pll_compute_mul_frac(&frac->core,
694
characteristics->core_output[0].min,
695
parent_rate, true);
696
if (ret < 0) {
697
hw = ERR_PTR(ret);
698
goto free;
699
}
700
}
701
spin_unlock_irqrestore(frac->core.lock, irqflags);
702
703
hw = &frac->core.hw;
704
ret = clk_hw_register(NULL, hw);
705
if (ret) {
706
kfree(frac);
707
hw = ERR_PTR(ret);
708
}
709
710
return hw;
711
712
free:
713
spin_unlock_irqrestore(frac->core.lock, irqflags);
714
kfree(frac);
715
return hw;
716
}
717
718
struct clk_hw * __init
719
sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock,
720
const char *name, const char *parent_name,
721
struct clk_hw *parent_hw, u8 id,
722
const struct clk_pll_characteristics *characteristics,
723
const struct clk_pll_layout *layout, u32 flags,
724
u32 safe_div)
725
{
726
struct sam9x60_div *div;
727
struct clk_hw *hw;
728
struct clk_init_data init = {};
729
unsigned long irqflags;
730
unsigned int val;
731
int ret;
732
733
/* We only support one changeable PLL. */
734
if (id > PLL_MAX_ID || !lock || (safe_div && notifier_div))
735
return ERR_PTR(-EINVAL);
736
737
if (safe_div >= PLL_DIV_MAX)
738
safe_div = PLL_DIV_MAX - 1;
739
740
div = kzalloc(sizeof(*div), GFP_KERNEL);
741
if (!div)
742
return ERR_PTR(-ENOMEM);
743
744
init.name = name;
745
if (parent_hw)
746
init.parent_hws = (const struct clk_hw **)&parent_hw;
747
else
748
init.parent_names = &parent_name;
749
init.num_parents = 1;
750
751
if (layout->div2)
752
init.ops = &sam9x60_fixed_div_pll_ops;
753
else if (flags & CLK_SET_RATE_GATE)
754
init.ops = &sam9x60_div_pll_ops;
755
else
756
init.ops = &sam9x60_div_pll_ops_chg;
757
758
init.flags = flags;
759
760
div->core.id = id;
761
div->core.hw.init = &init;
762
div->core.characteristics = characteristics;
763
div->core.layout = layout;
764
div->core.regmap = regmap;
765
div->core.lock = lock;
766
div->safe_div = safe_div;
767
768
spin_lock_irqsave(div->core.lock, irqflags);
769
770
regmap_update_bits(regmap, AT91_PMC_PLL_UPDT,
771
AT91_PMC_PLL_UPDT_ID_MSK, id);
772
regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val);
773
div->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val);
774
775
spin_unlock_irqrestore(div->core.lock, irqflags);
776
777
hw = &div->core.hw;
778
ret = clk_hw_register(NULL, hw);
779
if (ret) {
780
kfree(div);
781
hw = ERR_PTR(ret);
782
} else if (div->safe_div) {
783
notifier_div = div;
784
clk_notifier_register(hw->clk, &sam9x60_div_pll_notifier);
785
}
786
787
return hw;
788
}
789
790
791