hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/clk/rockchip/clk-pll.c
....@@ -1,19 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (c) 2014 MundoReader S.L.
34 * Author: Heiko Stuebner <heiko@sntech.de>
45 *
56 * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
67 * Author: Xing Zheng <zhengxing@rock-chips.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- * GNU General Public License for more details.
178 */
189
1910 #include <asm/div64.h>
....@@ -122,6 +113,7 @@
122113
123114 return 0;
124115 }
116
+EXPORT_SYMBOL(rockchip_pll_clk_adaptive_scaling);
125117
126118 int rockchip_pll_clk_rate_to_scale(struct clk *clk, unsigned long rate)
127119 {
....@@ -145,6 +137,7 @@
145137
146138 return -EINVAL;
147139 }
140
+EXPORT_SYMBOL(rockchip_pll_clk_rate_to_scale);
148141
149142 int rockchip_pll_clk_scale_to_rate(struct clk *clk, unsigned int scale)
150143 {
....@@ -168,6 +161,7 @@
168161
169162 return -EINVAL;
170163 }
164
+EXPORT_SYMBOL(rockchip_pll_clk_scale_to_rate);
171165
172166 static struct rockchip_pll_rate_table *rk_pll_rate_table_get(void)
173167 {
....@@ -338,6 +332,109 @@
338332 return rate_table;
339333 }
340334
335
+static u32
336
+rockchip_rk3588_pll_frac_get(u32 m, u32 p, u32 s, u64 fin_hz, u64 fvco)
337
+{
338
+ u64 fref, fout, ffrac;
339
+ u32 k = 0;
340
+
341
+ fref = fin_hz / p;
342
+ ffrac = fvco - (m * fref);
343
+ fout = ffrac * 65536;
344
+ k = fout / fref;
345
+ if (k > 32767) {
346
+ fref = fin_hz / p;
347
+ ffrac = ((m + 1) * fref) - fvco;
348
+ fout = ffrac * 65536;
349
+ k = ((fout * 10 / fref) + 7) / 10;
350
+ if (k > 32767)
351
+ k = 0;
352
+ else
353
+ k = ~k + 1;
354
+ }
355
+ return k;
356
+}
357
+
358
+static struct rockchip_pll_rate_table *
359
+rockchip_rk3588_pll_frac_by_auto(unsigned long fin_hz, unsigned long fout_hz)
360
+{
361
+ struct rockchip_pll_rate_table *rate_table = rk_pll_rate_table_get();
362
+ u64 fvco_min = 2250 * MHZ, fvco_max = 4500 * MHZ;
363
+ u32 p, m, s, k;
364
+ u64 fvco;
365
+
366
+ for (s = 0; s <= 6; s++) {
367
+ fvco = (u64)fout_hz << s;
368
+ if (fvco < fvco_min || fvco > fvco_max)
369
+ continue;
370
+ for (p = 1; p <= 4; p++) {
371
+ for (m = 64; m <= 1023; m++) {
372
+ if ((fvco >= m * fin_hz / p) && (fvco < (m + 1) * fin_hz / p)) {
373
+ k = rockchip_rk3588_pll_frac_get(m, p, s,
374
+ (u64)fin_hz,
375
+ fvco);
376
+ if (!k)
377
+ continue;
378
+ rate_table->p = p;
379
+ rate_table->s = s;
380
+ rate_table->k = k;
381
+ if (k > 32767)
382
+ rate_table->m = m + 1;
383
+ else
384
+ rate_table->m = m;
385
+ return rate_table;
386
+ }
387
+ }
388
+ }
389
+ }
390
+ return NULL;
391
+}
392
+
393
+static struct rockchip_pll_rate_table *
394
+rockchip_rk3588_pll_clk_set_by_auto(struct rockchip_clk_pll *pll,
395
+ unsigned long fin_hz,
396
+ unsigned long fout_hz)
397
+{
398
+ struct rockchip_pll_rate_table *rate_table = rk_pll_rate_table_get();
399
+ u64 fvco_min = 2250 * MHZ, fvco_max = 4500 * MHZ;
400
+ u64 fout_min = 37 * MHZ, fout_max = 4500 * MHZ;
401
+ u32 p, m, s;
402
+ u64 fvco;
403
+
404
+ if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
405
+ return NULL;
406
+
407
+ if (fout_hz > fout_max || fout_hz < fout_min)
408
+ return NULL;
409
+
410
+ if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
411
+ for (s = 0; s <= 6; s++) {
412
+ fvco = (u64)fout_hz << s;
413
+ if (fvco < fvco_min || fvco > fvco_max)
414
+ continue;
415
+ for (p = 2; p <= 4; p++) {
416
+ for (m = 64; m <= 1023; m++) {
417
+ if (fvco == m * fin_hz / p) {
418
+ rate_table->p = p;
419
+ rate_table->m = m;
420
+ rate_table->s = s;
421
+ rate_table->k = 0;
422
+ return rate_table;
423
+ }
424
+ }
425
+ }
426
+ }
427
+ pr_err("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
428
+ } else {
429
+ rate_table = rockchip_rk3588_pll_frac_by_auto(fin_hz, fout_hz);
430
+ if (!rate_table)
431
+ pr_err("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
432
+ else
433
+ return rate_table;
434
+ }
435
+ return NULL;
436
+}
437
+
341438 static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
342439 struct rockchip_clk_pll *pll, unsigned long rate)
343440 {
....@@ -358,6 +455,8 @@
358455
359456 if (pll->type == pll_rk3066)
360457 return rockchip_rk3066_pll_clk_set_by_auto(pll, 24 * MHZ, rate);
458
+ else if (pll->type == pll_rk3588 || pll->type == pll_rk3588_core)
459
+ return rockchip_rk3588_pll_clk_set_by_auto(pll, 24 * MHZ, rate);
361460 else
362461 return rockchip_pll_clk_set_by_auto(pll, 24 * MHZ, rate);
363462 }
....@@ -591,10 +690,14 @@
591690 static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
592691 {
593692 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
693
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
694
+ struct clk_mux *pll_mux = &pll->pll_mux;
594695
595696 writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
596697 pll->reg_base + RK3036_PLLCON(1));
597698 rockchip_rk3036_pll_wait_lock(pll);
699
+
700
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
598701
599702 return 0;
600703 }
....@@ -602,6 +705,10 @@
602705 static void rockchip_rk3036_pll_disable(struct clk_hw *hw)
603706 {
604707 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
708
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
709
+ struct clk_mux *pll_mux = &pll->pll_mux;
710
+
711
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
605712
606713 writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN,
607714 RK3036_PLLCON1_PWRDOWN, 0),
....@@ -616,7 +723,7 @@
616723 return !(pllcon & RK3036_PLLCON1_PWRDOWN);
617724 }
618725
619
-static void rockchip_rk3036_pll_init(struct clk_hw *hw)
726
+static int rockchip_rk3036_pll_init(struct clk_hw *hw)
620727 {
621728 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
622729 const struct rockchip_pll_rate_table *rate;
....@@ -624,14 +731,14 @@
624731 unsigned long drate;
625732
626733 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
627
- return;
734
+ return 0;
628735
629736 drate = clk_hw_get_rate(hw);
630737 rate = rockchip_get_pll_settings(pll, drate);
631738
632739 /* when no rate setting for the current rate, rely on clk_set_rate */
633740 if (!rate)
634
- return;
741
+ return 0;
635742
636743 rockchip_rk3036_pll_get_params(pll, &cur);
637744
....@@ -653,13 +760,15 @@
653760 if (!parent) {
654761 pr_warn("%s: parent of %s not available\n",
655762 __func__, __clk_get_name(hw->clk));
656
- return;
763
+ return 0;
657764 }
658765
659766 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
660767 __func__, __clk_get_name(hw->clk));
661768 rockchip_rk3036_pll_set_params(pll, rate);
662769 }
770
+
771
+ return 0;
663772 }
664773
665774 static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
....@@ -865,7 +974,7 @@
865974 return !(pllcon & RK3066_PLLCON3_PWRDOWN);
866975 }
867976
868
-static void rockchip_rk3066_pll_init(struct clk_hw *hw)
977
+static int rockchip_rk3066_pll_init(struct clk_hw *hw)
869978 {
870979 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
871980 const struct rockchip_pll_rate_table *rate;
....@@ -873,14 +982,14 @@
873982 unsigned long drate;
874983
875984 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
876
- return;
985
+ return 0;
877986
878987 drate = clk_hw_get_rate(hw);
879988 rate = rockchip_get_pll_settings(pll, drate);
880989
881990 /* when no rate setting for the current rate, rely on clk_set_rate */
882991 if (!rate)
883
- return;
992
+ return 0;
884993
885994 rockchip_rk3066_pll_get_params(pll, &cur);
886995
....@@ -893,6 +1002,8 @@
8931002 __func__, clk_hw_get_name(hw));
8941003 rockchip_rk3066_pll_set_params(pll, rate);
8951004 }
1005
+
1006
+ return 0;
8961007 }
8971008
8981009 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
....@@ -1131,7 +1242,7 @@
11311242 return !(pllcon & RK3399_PLLCON3_PWRDOWN);
11321243 }
11331244
1134
-static void rockchip_rk3399_pll_init(struct clk_hw *hw)
1245
+static int rockchip_rk3399_pll_init(struct clk_hw *hw)
11351246 {
11361247 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
11371248 const struct rockchip_pll_rate_table *rate;
....@@ -1139,14 +1250,14 @@
11391250 unsigned long drate;
11401251
11411252 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
1142
- return;
1253
+ return 0;
11431254
11441255 drate = clk_hw_get_rate(hw);
11451256 rate = rockchip_get_pll_settings(pll, drate);
11461257
11471258 /* when no rate setting for the current rate, rely on clk_set_rate */
11481259 if (!rate)
1149
- return;
1260
+ return 0;
11501261
11511262 rockchip_rk3399_pll_get_params(pll, &cur);
11521263
....@@ -1168,13 +1279,15 @@
11681279 if (!parent) {
11691280 pr_warn("%s: parent of %s not available\n",
11701281 __func__, __clk_get_name(hw->clk));
1171
- return;
1282
+ return 0;
11721283 }
11731284
11741285 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
11751286 __func__, __clk_get_name(hw->clk));
11761287 rockchip_rk3399_pll_set_params(pll, rate);
11771288 }
1289
+
1290
+ return 0;
11781291 }
11791292
11801293 static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
....@@ -1194,12 +1307,269 @@
11941307 .init = rockchip_rk3399_pll_init,
11951308 };
11961309
1310
+/**
1311
+ * PLL used in RK3588
1312
+ */
1313
+
1314
+#define RK3588_PLLCON(i) (i * 0x4)
1315
+#define RK3588_PLLCON0_M_MASK 0x3ff
1316
+#define RK3588_PLLCON0_M_SHIFT 0
1317
+#define RK3588_PLLCON1_P_MASK 0x3f
1318
+#define RK3588_PLLCON1_P_SHIFT 0
1319
+#define RK3588_PLLCON1_S_MASK 0x7
1320
+#define RK3588_PLLCON1_S_SHIFT 6
1321
+#define RK3588_PLLCON2_K_MASK 0xffff
1322
+#define RK3588_PLLCON2_K_SHIFT 0
1323
+#define RK3588_PLLCON1_PWRDOWN BIT(13)
1324
+#define RK3588_PLLCON6_LOCK_STATUS BIT(15)
1325
+
1326
+static int rockchip_rk3588_pll_wait_lock(struct rockchip_clk_pll *pll)
1327
+{
1328
+ u32 pllcon;
1329
+ int ret;
1330
+
1331
+ /*
1332
+ * Lock time typical 250, max 500 input clock cycles @24MHz
1333
+ * So define a very safe maximum of 1000us, meaning 24000 cycles.
1334
+ */
1335
+ ret = readl_relaxed_poll_timeout(pll->reg_base + RK3588_PLLCON(6),
1336
+ pllcon,
1337
+ pllcon & RK3588_PLLCON6_LOCK_STATUS,
1338
+ 0, 1000);
1339
+ if (ret)
1340
+ pr_err("%s: timeout waiting for pll to lock\n", __func__);
1341
+
1342
+ return ret;
1343
+}
1344
+
1345
+static long rockchip_rk3588_pll_round_rate(struct clk_hw *hw,
1346
+ unsigned long drate, unsigned long *prate)
1347
+{
1348
+ if ((drate < 37 * MHZ) || (drate > 4500 * MHZ))
1349
+ return -EINVAL;
1350
+ else
1351
+ return drate;
1352
+}
1353
+
1354
+static void rockchip_rk3588_pll_get_params(struct rockchip_clk_pll *pll,
1355
+ struct rockchip_pll_rate_table *rate)
1356
+{
1357
+ u32 pllcon;
1358
+
1359
+ pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(0));
1360
+ rate->m = ((pllcon >> RK3588_PLLCON0_M_SHIFT)
1361
+ & RK3588_PLLCON0_M_MASK);
1362
+
1363
+ pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(1));
1364
+ rate->p = ((pllcon >> RK3588_PLLCON1_P_SHIFT)
1365
+ & RK3588_PLLCON1_P_MASK);
1366
+ rate->s = ((pllcon >> RK3588_PLLCON1_S_SHIFT)
1367
+ & RK3588_PLLCON1_S_MASK);
1368
+
1369
+ pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(2));
1370
+ rate->k = ((pllcon >> RK3588_PLLCON2_K_SHIFT)
1371
+ & RK3588_PLLCON2_K_MASK);
1372
+}
1373
+
1374
+static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw,
1375
+ unsigned long prate)
1376
+{
1377
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1378
+ struct rockchip_pll_rate_table cur;
1379
+ u64 rate64 = prate, postdiv;
1380
+
1381
+ if (pll->sel && pll->scaling)
1382
+ return pll->scaling;
1383
+
1384
+ rockchip_rk3588_pll_get_params(pll, &cur);
1385
+ if (cur.p == 0)
1386
+ return prate;
1387
+
1388
+ rate64 *= cur.m;
1389
+ do_div(rate64, cur.p);
1390
+
1391
+ if (cur.k & BIT(15)) {
1392
+ /* fractional mode */
1393
+ u64 frac_rate64;
1394
+
1395
+ cur.k = (~(cur.k - 1)) & RK3588_PLLCON2_K_MASK;
1396
+ frac_rate64 = prate * cur.k;
1397
+ postdiv = cur.p;
1398
+ postdiv *= 65536;
1399
+ do_div(frac_rate64, postdiv);
1400
+ rate64 -= frac_rate64;
1401
+ } else {
1402
+ /* fractional mode */
1403
+ u64 frac_rate64 = prate * cur.k;
1404
+
1405
+ postdiv = cur.p;
1406
+ postdiv *= 65536;
1407
+ do_div(frac_rate64, postdiv);
1408
+ rate64 += frac_rate64;
1409
+ }
1410
+ rate64 = rate64 >> cur.s;
1411
+
1412
+ return (unsigned long)rate64;
1413
+}
1414
+
1415
+static int rockchip_rk3588_pll_set_params(struct rockchip_clk_pll *pll,
1416
+ const struct rockchip_pll_rate_table *rate)
1417
+{
1418
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
1419
+ struct clk_mux *pll_mux = &pll->pll_mux;
1420
+ struct rockchip_pll_rate_table cur;
1421
+ int rate_change_remuxed = 0;
1422
+ int cur_parent;
1423
+ int ret;
1424
+
1425
+ pr_debug("%s: rate settings for %lu p: %d, m: %d, s: %d, k: %d\n",
1426
+ __func__, rate->rate, rate->p, rate->m, rate->s, rate->k);
1427
+
1428
+ rockchip_rk3588_pll_get_params(pll, &cur);
1429
+ cur.rate = 0;
1430
+
1431
+ if (pll->type == pll_rk3588) {
1432
+ cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
1433
+ if (cur_parent == PLL_MODE_NORM) {
1434
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
1435
+ rate_change_remuxed = 1;
1436
+ }
1437
+ }
1438
+
1439
+ /* set pll power down */
1440
+ writel(HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN,
1441
+ RK3588_PLLCON1_PWRDOWN, 0),
1442
+ pll->reg_base + RK3588_PLLCON(1));
1443
+
1444
+ /* update pll values */
1445
+ writel_relaxed(HIWORD_UPDATE(rate->m, RK3588_PLLCON0_M_MASK,
1446
+ RK3588_PLLCON0_M_SHIFT),
1447
+ pll->reg_base + RK3588_PLLCON(0));
1448
+
1449
+ writel_relaxed(HIWORD_UPDATE(rate->p, RK3588_PLLCON1_P_MASK,
1450
+ RK3588_PLLCON1_P_SHIFT) |
1451
+ HIWORD_UPDATE(rate->s, RK3588_PLLCON1_S_MASK,
1452
+ RK3588_PLLCON1_S_SHIFT),
1453
+ pll->reg_base + RK3588_PLLCON(1));
1454
+
1455
+ writel_relaxed(HIWORD_UPDATE(rate->k, RK3588_PLLCON2_K_MASK,
1456
+ RK3588_PLLCON2_K_SHIFT),
1457
+ pll->reg_base + RK3588_PLLCON(2));
1458
+
1459
+ /* set pll power up */
1460
+ writel(HIWORD_UPDATE(0,
1461
+ RK3588_PLLCON1_PWRDOWN, 0),
1462
+ pll->reg_base + RK3588_PLLCON(1));
1463
+
1464
+ /* wait for the pll to lock */
1465
+ ret = rockchip_rk3588_pll_wait_lock(pll);
1466
+ if (ret) {
1467
+ pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
1468
+ __func__);
1469
+ rockchip_rk3588_pll_set_params(pll, &cur);
1470
+ }
1471
+
1472
+ if ((pll->type == pll_rk3588) && rate_change_remuxed)
1473
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
1474
+
1475
+ return ret;
1476
+}
1477
+
1478
+static int rockchip_rk3588_pll_set_rate(struct clk_hw *hw, unsigned long drate,
1479
+ unsigned long prate)
1480
+{
1481
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1482
+ const struct rockchip_pll_rate_table *rate;
1483
+ unsigned long old_rate = rockchip_rk3588_pll_recalc_rate(hw, prate);
1484
+ int ret;
1485
+
1486
+ pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
1487
+ __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
1488
+
1489
+ /* Get required rate settings from table */
1490
+ rate = rockchip_get_pll_settings(pll, drate);
1491
+ if (!rate) {
1492
+ pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1493
+ drate, __clk_get_name(hw->clk));
1494
+ return -EINVAL;
1495
+ }
1496
+
1497
+ ret = rockchip_rk3588_pll_set_params(pll, rate);
1498
+ if (ret)
1499
+ pll->scaling = 0;
1500
+
1501
+ return ret;
1502
+}
1503
+
1504
+static int rockchip_rk3588_pll_enable(struct clk_hw *hw)
1505
+{
1506
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1507
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
1508
+ struct clk_mux *pll_mux = &pll->pll_mux;
1509
+
1510
+ writel(HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0),
1511
+ pll->reg_base + RK3588_PLLCON(1));
1512
+ rockchip_rk3588_pll_wait_lock(pll);
1513
+
1514
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
1515
+
1516
+ return 0;
1517
+}
1518
+
1519
+static void rockchip_rk3588_pll_disable(struct clk_hw *hw)
1520
+{
1521
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1522
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
1523
+ struct clk_mux *pll_mux = &pll->pll_mux;
1524
+
1525
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
1526
+
1527
+ writel(HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN,
1528
+ RK3588_PLLCON1_PWRDOWN, 0),
1529
+ pll->reg_base + RK3588_PLLCON(1));
1530
+}
1531
+
1532
+static int rockchip_rk3588_pll_is_enabled(struct clk_hw *hw)
1533
+{
1534
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1535
+ u32 pllcon = readl(pll->reg_base + RK3588_PLLCON(1));
1536
+
1537
+ return !(pllcon & RK3588_PLLCON1_PWRDOWN);
1538
+}
1539
+
1540
+static int rockchip_rk3588_pll_init(struct clk_hw *hw)
1541
+{
1542
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1543
+
1544
+ if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
1545
+ return 0;
1546
+
1547
+ return 0;
1548
+}
1549
+
1550
+static const struct clk_ops rockchip_rk3588_pll_clk_norate_ops = {
1551
+ .recalc_rate = rockchip_rk3588_pll_recalc_rate,
1552
+ .enable = rockchip_rk3588_pll_enable,
1553
+ .disable = rockchip_rk3588_pll_disable,
1554
+ .is_enabled = rockchip_rk3588_pll_is_enabled,
1555
+};
1556
+
1557
+static const struct clk_ops rockchip_rk3588_pll_clk_ops = {
1558
+ .recalc_rate = rockchip_rk3588_pll_recalc_rate,
1559
+ .round_rate = rockchip_rk3588_pll_round_rate,
1560
+ .set_rate = rockchip_rk3588_pll_set_rate,
1561
+ .enable = rockchip_rk3588_pll_enable,
1562
+ .disable = rockchip_rk3588_pll_disable,
1563
+ .is_enabled = rockchip_rk3588_pll_is_enabled,
1564
+ .init = rockchip_rk3588_pll_init,
1565
+};
1566
+
11971567 #ifdef CONFIG_ROCKCHIP_CLK_COMPENSATION
11981568 int rockchip_pll_clk_compensation(struct clk *clk, int ppm)
11991569 {
12001570 struct clk *parent = clk_get_parent(clk);
12011571 struct rockchip_clk_pll *pll;
1202
- static u32 frac, fbdiv;
1572
+ static u32 frac, fbdiv, s, p;
12031573 bool negative;
12041574 u32 pllcon, pllcon0, pllcon2, fbdiv_mask, frac_mask, frac_shift;
12051575 u64 fracdiv, m, n;
....@@ -1236,6 +1606,13 @@
12361606 frac_mask = RK3399_PLLCON2_FRAC_MASK;
12371607 frac_shift = RK3399_PLLCON2_FRAC_SHIFT;
12381608 break;
1609
+ case pll_rk3588:
1610
+ pllcon0 = RK3588_PLLCON(0);
1611
+ pllcon2 = RK3588_PLLCON(2);
1612
+ fbdiv_mask = RK3588_PLLCON0_M_MASK;
1613
+ frac_mask = RK3588_PLLCON2_K_MASK;
1614
+ frac_shift = RK3588_PLLCON2_K_SHIFT;
1615
+ break;
12391616 default:
12401617 return -EINVAL;
12411618 }
....@@ -1243,29 +1620,101 @@
12431620 negative = !!(ppm & BIT(31));
12441621 ppm = negative ? ~ppm + 1 : ppm;
12451622
1246
- if (!frac) {
1247
- frac = readl_relaxed(pll->reg_base + pllcon2) & frac_mask;
1248
- fbdiv = readl_relaxed(pll->reg_base + pllcon0) & fbdiv_mask;
1249
- }
1623
+ switch (pll->type) {
1624
+ case pll_rk3036:
1625
+ case pll_rk3328:
1626
+ case pll_rk3066:
1627
+ case pll_rk3399:
1628
+ /*
1629
+ * delta frac frac ppm
1630
+ * -------------- = (fbdiv + ----------) * ---------
1631
+ * 1 << 24 1 << 24 1000000
1632
+ *
1633
+ */
1634
+ if (!frac) {
1635
+ frac = readl_relaxed(pll->reg_base + pllcon2) & frac_mask;
1636
+ fbdiv = readl_relaxed(pll->reg_base + pllcon0) & fbdiv_mask;
1637
+ }
1638
+ m = div64_u64((uint64_t)frac * ppm, 1000000);
1639
+ n = div64_u64((uint64_t)ppm << 24, 1000000) * fbdiv;
12501640
1251
- /*
1252
- * delta frac frac ppm
1253
- * -------------- = (fbdiv + ----------) * ---------
1254
- * 1 << 24 1 << 24 1000000
1255
- *
1256
- */
1257
- m = div64_u64((uint64_t)frac * ppm, 1000000);
1258
- n = div64_u64((uint64_t)ppm << 24, 1000000) * fbdiv;
1641
+ fracdiv = negative ? frac - (m + n) : frac + (m + n);
12591642
1260
- fracdiv = negative ? frac - (m + n) : frac + (m + n);
1643
+ if (!frac || fracdiv > frac_mask)
1644
+ return -EINVAL;
12611645
1262
- if (!frac || fracdiv > frac_mask)
1646
+ pllcon = readl_relaxed(pll->reg_base + pllcon2);
1647
+ pllcon &= ~(frac_mask << frac_shift);
1648
+ pllcon |= fracdiv << frac_shift;
1649
+ writel_relaxed(pllcon, pll->reg_base + pllcon2);
1650
+ break;
1651
+ case pll_rk3588:
1652
+ if (!fbdiv) {
1653
+ frac = readl_relaxed(pll->reg_base + pllcon2) & frac_mask;
1654
+ fbdiv = readl_relaxed(pll->reg_base + pllcon0) & fbdiv_mask;
1655
+ }
1656
+ if (!frac) {
1657
+ pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(1));
1658
+ s = ((pllcon >> RK3588_PLLCON1_S_SHIFT)
1659
+ & RK3588_PLLCON1_S_MASK);
1660
+ p = ((pllcon >> RK3588_PLLCON1_P_SHIFT)
1661
+ & RK3588_PLLCON1_P_MASK);
1662
+ m = div64_u64((uint64_t)clk_get_rate(clk) * ppm, 24000000);
1663
+ n = div64_u64((uint64_t)m * 65536 * p * (1 << s), 1000000);
1664
+
1665
+ if (n > 32767)
1666
+ return -EINVAL;
1667
+ fracdiv = negative ? ~n + 1 : n;
1668
+ } else if (frac & BIT(15)) {
1669
+ frac = (~(frac - 1)) & RK3588_PLLCON2_K_MASK;
1670
+ m = div64_u64((uint64_t)frac * ppm, 100000);
1671
+ n = div64_u64((uint64_t)ppm * 65536 * fbdiv, 100000);
1672
+ if (negative) {
1673
+ fracdiv = frac + (div64_u64(m + n, 10));
1674
+ if (fracdiv > 32767)
1675
+ return -EINVAL;
1676
+ fracdiv = ~fracdiv + 1;
1677
+ } else {
1678
+ s = div64_u64(m + n, 10);
1679
+ if (frac >= s) {
1680
+ fracdiv = frac - s;
1681
+ if (fracdiv > 32767)
1682
+ return -EINVAL;
1683
+ fracdiv = ~fracdiv + 1;
1684
+ } else {
1685
+ fracdiv = s - frac;
1686
+ if (fracdiv > 32767)
1687
+ return -EINVAL;
1688
+ }
1689
+ }
1690
+ } else {
1691
+ m = div64_u64((uint64_t)frac * ppm, 100000);
1692
+ n = div64_u64((uint64_t)ppm * 65536 * fbdiv, 100000);
1693
+ if (!negative) {
1694
+ fracdiv = frac + (div64_u64(m + n, 10));
1695
+ if (fracdiv > 32767)
1696
+ return -EINVAL;
1697
+ } else {
1698
+ s = div64_u64(m + n, 10);
1699
+ if (frac >= s) {
1700
+ fracdiv = frac - s;
1701
+ if (fracdiv > 32767)
1702
+ return -EINVAL;
1703
+ } else {
1704
+ fracdiv = s - frac;
1705
+ if (fracdiv > 32767)
1706
+ return -EINVAL;
1707
+ fracdiv = ~fracdiv + 1;
1708
+ }
1709
+ }
1710
+ }
1711
+
1712
+ writel_relaxed(HIWORD_UPDATE(fracdiv, frac_mask, frac_shift),
1713
+ pll->reg_base + pllcon2);
1714
+ break;
1715
+ default:
12631716 return -EINVAL;
1264
-
1265
- pllcon = readl_relaxed(pll->reg_base + pllcon2);
1266
- pllcon &= ~(frac_mask << frac_shift);
1267
- pllcon |= fracdiv << frac_shift;
1268
- writel_relaxed(pllcon, pll->reg_base + pllcon2);
1717
+ }
12691718
12701719 return 0;
12711720 }
....@@ -1285,7 +1734,7 @@
12851734 unsigned long flags, u8 clk_pll_flags)
12861735 {
12871736 const char *pll_parents[3];
1288
- struct clk_init_data init = {};
1737
+ struct clk_init_data init;
12891738 struct rockchip_clk_pll *pll;
12901739 struct clk_mux *pll_mux;
12911740 struct clk *pll_clk, *mux_clk;
....@@ -1316,12 +1765,7 @@
13161765 pll_mux->flags = 0;
13171766 pll_mux->lock = &ctx->lock;
13181767 pll_mux->hw.init = &init;
1319
-
1320
- if (pll_type == pll_rk3036 ||
1321
- pll_type == pll_rk3066 ||
1322
- pll_type == pll_rk3328 ||
1323
- pll_type == pll_rk3399)
1324
- pll_mux->flags |= CLK_MUX_HIWORD_MASK;
1768
+ pll_mux->flags |= CLK_MUX_HIWORD_MASK;
13251769
13261770 /* the actual muxing is xin24m, pll-output, xin32k */
13271771 pll_parents[0] = parent_names[0];
....@@ -1345,8 +1789,11 @@
13451789 init.name = pll_name;
13461790
13471791 #ifndef CONFIG_ROCKCHIP_LOW_PERFORMANCE
1348
- /* keep all plls untouched for now */
1349
- init.flags = flags | CLK_IGNORE_UNUSED;
1792
+ if (clk_pll_flags & ROCKCHIP_PLL_ALLOW_POWER_DOWN)
1793
+ init.flags = flags;
1794
+ else
1795
+ /* keep all plls untouched for now */
1796
+ init.flags = flags | CLK_IGNORE_UNUSED;
13501797 #else
13511798 init.flags = flags;
13521799 #endif
....@@ -1374,7 +1821,7 @@
13741821 switch (pll_type) {
13751822 case pll_rk3036:
13761823 case pll_rk3328:
1377
- if (!pll->rate_table || IS_ERR(ctx->grf))
1824
+ if (!pll->rate_table)
13781825 init.ops = &rockchip_rk3036_pll_clk_norate_ops;
13791826 else
13801827 init.ops = &rockchip_rk3036_pll_clk_ops;
....@@ -1393,6 +1840,16 @@
13931840 init.ops = &rockchip_rk3399_pll_clk_norate_ops;
13941841 else
13951842 init.ops = &rockchip_rk3399_pll_clk_ops;
1843
+ break;
1844
+#endif
1845
+#ifdef CONFIG_ROCKCHIP_PLL_RK3588
1846
+ case pll_rk3588:
1847
+ case pll_rk3588_core:
1848
+ if (!pll->rate_table)
1849
+ init.ops = &rockchip_rk3588_pll_clk_norate_ops;
1850
+ else
1851
+ init.ops = &rockchip_rk3588_pll_clk_ops;
1852
+ init.flags = flags;
13961853 break;
13971854 #endif
13981855 default:
....@@ -1419,6 +1876,7 @@
14191876 return mux_clk;
14201877
14211878 err_pll:
1879
+ kfree(pll->rate_table);
14221880 clk_unregister(mux_clk);
14231881 mux_clk = pll_clk;
14241882 err_mux:
....@@ -1619,6 +2077,7 @@
16192077 #ifdef CONFIG_DEBUG_FS
16202078 #include <linux/debugfs.h>
16212079
2080
+#ifndef MODULE
16222081 static int boost_summary_show(struct seq_file *s, void *data)
16232082 {
16242083 struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private;
....@@ -1736,5 +2195,6 @@
17362195 return 0;
17372196 }
17382197 late_initcall(boost_debug_init);
2198
+#endif /* MODULE */
17392199 #endif /* CONFIG_DEBUG_FS */
17402200 #endif /* CONFIG_ROCKCHIP_CLK_BOOST */