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