hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
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,66 @@
338332 return rate_table;
339333 }
340334
335
+static struct rockchip_pll_rate_table *
336
+rockchip_rk3588_pll_clk_set_by_auto(struct rockchip_clk_pll *pll,
337
+ unsigned long fin_hz,
338
+ unsigned long fout_hz)
339
+{
340
+ struct rockchip_pll_rate_table *rate_table = rk_pll_rate_table_get();
341
+ u64 fvco_min = 2250 * MHZ, fvco_max = 4500 * MHZ;
342
+ u64 fout_min = 37 * MHZ, fout_max = 4500 * MHZ;
343
+ u32 p, m, s;
344
+ u64 fvco, fref, fout, ffrac;
345
+
346
+ if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
347
+ return NULL;
348
+
349
+ if (fout_hz > fout_max || fout_hz < fout_min)
350
+ return NULL;
351
+
352
+ if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) {
353
+ for (s = 0; s <= 6; s++) {
354
+ fvco = (u64)fout_hz << s;
355
+ if (fvco < fvco_min || fvco > fvco_max)
356
+ continue;
357
+ for (p = 2; p <= 4; p++) {
358
+ for (m = 64; m <= 1023; m++) {
359
+ if (fvco == m * fin_hz / p) {
360
+ rate_table->p = p;
361
+ rate_table->m = m;
362
+ rate_table->s = s;
363
+ rate_table->k = 0;
364
+ return rate_table;
365
+ }
366
+ }
367
+ }
368
+ }
369
+ pr_err("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
370
+ } else {
371
+ for (s = 0; s <= 6; s++) {
372
+ fvco = (u64)fout_hz << s;
373
+ if (fvco < fvco_min || fvco > fvco_max)
374
+ continue;
375
+ for (p = 1; p <= 4; p++) {
376
+ for (m = 64; m <= 1023; m++) {
377
+ if ((fvco >= m * fin_hz / p) && (fvco < (m + 1) * fin_hz / p)) {
378
+ rate_table->p = p;
379
+ rate_table->m = m;
380
+ rate_table->s = s;
381
+ fref = fin_hz / p;
382
+ ffrac = fvco - (m * fref);
383
+ fout = ffrac * 65536;
384
+ rate_table->k = fout / fref;
385
+ return rate_table;
386
+ }
387
+ }
388
+ }
389
+ }
390
+ pr_err("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
391
+ }
392
+ return NULL;
393
+}
394
+
341395 static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
342396 struct rockchip_clk_pll *pll, unsigned long rate)
343397 {
....@@ -358,6 +412,8 @@
358412
359413 if (pll->type == pll_rk3066)
360414 return rockchip_rk3066_pll_clk_set_by_auto(pll, 24 * MHZ, rate);
415
+ else if (pll->type == pll_rk3588 || pll->type == pll_rk3588_core)
416
+ return rockchip_rk3588_pll_clk_set_by_auto(pll, 24 * MHZ, rate);
361417 else
362418 return rockchip_pll_clk_set_by_auto(pll, 24 * MHZ, rate);
363419 }
....@@ -591,10 +647,14 @@
591647 static int rockchip_rk3036_pll_enable(struct clk_hw *hw)
592648 {
593649 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
650
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
651
+ struct clk_mux *pll_mux = &pll->pll_mux;
594652
595653 writel(HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0),
596654 pll->reg_base + RK3036_PLLCON(1));
597655 rockchip_rk3036_pll_wait_lock(pll);
656
+
657
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
598658
599659 return 0;
600660 }
....@@ -602,6 +662,10 @@
602662 static void rockchip_rk3036_pll_disable(struct clk_hw *hw)
603663 {
604664 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
665
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
666
+ struct clk_mux *pll_mux = &pll->pll_mux;
667
+
668
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
605669
606670 writel(HIWORD_UPDATE(RK3036_PLLCON1_PWRDOWN,
607671 RK3036_PLLCON1_PWRDOWN, 0),
....@@ -616,7 +680,7 @@
616680 return !(pllcon & RK3036_PLLCON1_PWRDOWN);
617681 }
618682
619
-static void rockchip_rk3036_pll_init(struct clk_hw *hw)
683
+static int rockchip_rk3036_pll_init(struct clk_hw *hw)
620684 {
621685 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
622686 const struct rockchip_pll_rate_table *rate;
....@@ -624,14 +688,14 @@
624688 unsigned long drate;
625689
626690 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
627
- return;
691
+ return 0;
628692
629693 drate = clk_hw_get_rate(hw);
630694 rate = rockchip_get_pll_settings(pll, drate);
631695
632696 /* when no rate setting for the current rate, rely on clk_set_rate */
633697 if (!rate)
634
- return;
698
+ return 0;
635699
636700 rockchip_rk3036_pll_get_params(pll, &cur);
637701
....@@ -653,13 +717,15 @@
653717 if (!parent) {
654718 pr_warn("%s: parent of %s not available\n",
655719 __func__, __clk_get_name(hw->clk));
656
- return;
720
+ return 0;
657721 }
658722
659723 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
660724 __func__, __clk_get_name(hw->clk));
661725 rockchip_rk3036_pll_set_params(pll, rate);
662726 }
727
+
728
+ return 0;
663729 }
664730
665731 static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
....@@ -865,7 +931,7 @@
865931 return !(pllcon & RK3066_PLLCON3_PWRDOWN);
866932 }
867933
868
-static void rockchip_rk3066_pll_init(struct clk_hw *hw)
934
+static int rockchip_rk3066_pll_init(struct clk_hw *hw)
869935 {
870936 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
871937 const struct rockchip_pll_rate_table *rate;
....@@ -873,14 +939,14 @@
873939 unsigned long drate;
874940
875941 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
876
- return;
942
+ return 0;
877943
878944 drate = clk_hw_get_rate(hw);
879945 rate = rockchip_get_pll_settings(pll, drate);
880946
881947 /* when no rate setting for the current rate, rely on clk_set_rate */
882948 if (!rate)
883
- return;
949
+ return 0;
884950
885951 rockchip_rk3066_pll_get_params(pll, &cur);
886952
....@@ -893,6 +959,8 @@
893959 __func__, clk_hw_get_name(hw));
894960 rockchip_rk3066_pll_set_params(pll, rate);
895961 }
962
+
963
+ return 0;
896964 }
897965
898966 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
....@@ -1131,7 +1199,7 @@
11311199 return !(pllcon & RK3399_PLLCON3_PWRDOWN);
11321200 }
11331201
1134
-static void rockchip_rk3399_pll_init(struct clk_hw *hw)
1202
+static int rockchip_rk3399_pll_init(struct clk_hw *hw)
11351203 {
11361204 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
11371205 const struct rockchip_pll_rate_table *rate;
....@@ -1139,14 +1207,14 @@
11391207 unsigned long drate;
11401208
11411209 if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
1142
- return;
1210
+ return 0;
11431211
11441212 drate = clk_hw_get_rate(hw);
11451213 rate = rockchip_get_pll_settings(pll, drate);
11461214
11471215 /* when no rate setting for the current rate, rely on clk_set_rate */
11481216 if (!rate)
1149
- return;
1217
+ return 0;
11501218
11511219 rockchip_rk3399_pll_get_params(pll, &cur);
11521220
....@@ -1168,13 +1236,15 @@
11681236 if (!parent) {
11691237 pr_warn("%s: parent of %s not available\n",
11701238 __func__, __clk_get_name(hw->clk));
1171
- return;
1239
+ return 0;
11721240 }
11731241
11741242 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
11751243 __func__, __clk_get_name(hw->clk));
11761244 rockchip_rk3399_pll_set_params(pll, rate);
11771245 }
1246
+
1247
+ return 0;
11781248 }
11791249
11801250 static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
....@@ -1192,6 +1262,253 @@
11921262 .disable = rockchip_rk3399_pll_disable,
11931263 .is_enabled = rockchip_rk3399_pll_is_enabled,
11941264 .init = rockchip_rk3399_pll_init,
1265
+};
1266
+
1267
+/**
1268
+ * PLL used in RK3588
1269
+ */
1270
+
1271
+#define RK3588_PLLCON(i) (i * 0x4)
1272
+#define RK3588_PLLCON0_M_MASK 0x3ff
1273
+#define RK3588_PLLCON0_M_SHIFT 0
1274
+#define RK3588_PLLCON1_P_MASK 0x3f
1275
+#define RK3588_PLLCON1_P_SHIFT 0
1276
+#define RK3588_PLLCON1_S_MASK 0x7
1277
+#define RK3588_PLLCON1_S_SHIFT 6
1278
+#define RK3588_PLLCON2_K_MASK 0xffff
1279
+#define RK3588_PLLCON2_K_SHIFT 0
1280
+#define RK3588_PLLCON1_PWRDOWN BIT(13)
1281
+#define RK3588_PLLCON6_LOCK_STATUS BIT(15)
1282
+
1283
+static int rockchip_rk3588_pll_wait_lock(struct rockchip_clk_pll *pll)
1284
+{
1285
+ u32 pllcon;
1286
+ int ret;
1287
+
1288
+ /*
1289
+ * Lock time typical 250, max 500 input clock cycles @24MHz
1290
+ * So define a very safe maximum of 1000us, meaning 24000 cycles.
1291
+ */
1292
+ ret = readl_relaxed_poll_timeout(pll->reg_base + RK3588_PLLCON(6),
1293
+ pllcon,
1294
+ pllcon & RK3588_PLLCON6_LOCK_STATUS,
1295
+ 0, 1000);
1296
+ if (ret)
1297
+ pr_err("%s: timeout waiting for pll to lock\n", __func__);
1298
+
1299
+ return ret;
1300
+}
1301
+
1302
+static long rockchip_rk3588_pll_round_rate(struct clk_hw *hw,
1303
+ unsigned long drate, unsigned long *prate)
1304
+{
1305
+ if ((drate < 37 * MHZ) || (drate > 4500 * MHZ))
1306
+ return -EINVAL;
1307
+ else
1308
+ return drate;
1309
+}
1310
+
1311
+static void rockchip_rk3588_pll_get_params(struct rockchip_clk_pll *pll,
1312
+ struct rockchip_pll_rate_table *rate)
1313
+{
1314
+ u32 pllcon;
1315
+
1316
+ pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(0));
1317
+ rate->m = ((pllcon >> RK3588_PLLCON0_M_SHIFT)
1318
+ & RK3588_PLLCON0_M_MASK);
1319
+
1320
+ pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(1));
1321
+ rate->p = ((pllcon >> RK3588_PLLCON1_P_SHIFT)
1322
+ & RK3588_PLLCON1_P_MASK);
1323
+ rate->s = ((pllcon >> RK3588_PLLCON1_S_SHIFT)
1324
+ & RK3588_PLLCON1_S_MASK);
1325
+
1326
+ pllcon = readl_relaxed(pll->reg_base + RK3588_PLLCON(2));
1327
+ rate->k = ((pllcon >> RK3588_PLLCON2_K_SHIFT)
1328
+ & RK3588_PLLCON2_K_MASK);
1329
+}
1330
+
1331
+static unsigned long rockchip_rk3588_pll_recalc_rate(struct clk_hw *hw,
1332
+ unsigned long prate)
1333
+{
1334
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1335
+ struct rockchip_pll_rate_table cur;
1336
+ u64 rate64 = prate, postdiv;
1337
+
1338
+ if (pll->sel && pll->scaling)
1339
+ return pll->scaling;
1340
+
1341
+ rockchip_rk3588_pll_get_params(pll, &cur);
1342
+ if (cur.p == 0)
1343
+ return prate;
1344
+
1345
+ rate64 *= cur.m;
1346
+ do_div(rate64, cur.p);
1347
+
1348
+ if (cur.k) {
1349
+ /* fractional mode */
1350
+ u64 frac_rate64 = prate * cur.k;
1351
+
1352
+ postdiv = cur.p;
1353
+ postdiv *= 65536;
1354
+ do_div(frac_rate64, postdiv);
1355
+ rate64 += frac_rate64;
1356
+ }
1357
+ rate64 = rate64 >> cur.s;
1358
+
1359
+ return (unsigned long)rate64;
1360
+}
1361
+
1362
+static int rockchip_rk3588_pll_set_params(struct rockchip_clk_pll *pll,
1363
+ const struct rockchip_pll_rate_table *rate)
1364
+{
1365
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
1366
+ struct clk_mux *pll_mux = &pll->pll_mux;
1367
+ struct rockchip_pll_rate_table cur;
1368
+ int rate_change_remuxed = 0;
1369
+ int cur_parent;
1370
+ int ret;
1371
+
1372
+ pr_debug("%s: rate settings for %lu p: %d, m: %d, s: %d, k: %d\n",
1373
+ __func__, rate->rate, rate->p, rate->m, rate->s, rate->k);
1374
+
1375
+ rockchip_rk3588_pll_get_params(pll, &cur);
1376
+ cur.rate = 0;
1377
+
1378
+ if (pll->type == pll_rk3588) {
1379
+ cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
1380
+ if (cur_parent == PLL_MODE_NORM) {
1381
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
1382
+ rate_change_remuxed = 1;
1383
+ }
1384
+ }
1385
+
1386
+ /* set pll power down */
1387
+ writel(HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN,
1388
+ RK3588_PLLCON1_PWRDOWN, 0),
1389
+ pll->reg_base + RK3588_PLLCON(1));
1390
+
1391
+ /* update pll values */
1392
+ writel_relaxed(HIWORD_UPDATE(rate->m, RK3588_PLLCON0_M_MASK,
1393
+ RK3588_PLLCON0_M_SHIFT),
1394
+ pll->reg_base + RK3588_PLLCON(0));
1395
+
1396
+ writel_relaxed(HIWORD_UPDATE(rate->p, RK3588_PLLCON1_P_MASK,
1397
+ RK3588_PLLCON1_P_SHIFT) |
1398
+ HIWORD_UPDATE(rate->s, RK3588_PLLCON1_S_MASK,
1399
+ RK3588_PLLCON1_S_SHIFT),
1400
+ pll->reg_base + RK3588_PLLCON(1));
1401
+
1402
+ writel_relaxed(HIWORD_UPDATE(rate->k, RK3588_PLLCON2_K_MASK,
1403
+ RK3588_PLLCON2_K_SHIFT),
1404
+ pll->reg_base + RK3588_PLLCON(2));
1405
+
1406
+ /* set pll power up */
1407
+ writel(HIWORD_UPDATE(0,
1408
+ RK3588_PLLCON1_PWRDOWN, 0),
1409
+ pll->reg_base + RK3588_PLLCON(1));
1410
+
1411
+ /* wait for the pll to lock */
1412
+ ret = rockchip_rk3588_pll_wait_lock(pll);
1413
+ if (ret) {
1414
+ pr_warn("%s: pll update unsuccessful, trying to restore old params\n",
1415
+ __func__);
1416
+ rockchip_rk3588_pll_set_params(pll, &cur);
1417
+ }
1418
+
1419
+ if ((pll->type == pll_rk3588) && rate_change_remuxed)
1420
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
1421
+
1422
+ return ret;
1423
+}
1424
+
1425
+static int rockchip_rk3588_pll_set_rate(struct clk_hw *hw, unsigned long drate,
1426
+ unsigned long prate)
1427
+{
1428
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1429
+ const struct rockchip_pll_rate_table *rate;
1430
+ unsigned long old_rate = rockchip_rk3588_pll_recalc_rate(hw, prate);
1431
+ int ret;
1432
+
1433
+ pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
1434
+ __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
1435
+
1436
+ /* Get required rate settings from table */
1437
+ rate = rockchip_get_pll_settings(pll, drate);
1438
+ if (!rate) {
1439
+ pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
1440
+ drate, __clk_get_name(hw->clk));
1441
+ return -EINVAL;
1442
+ }
1443
+
1444
+ ret = rockchip_rk3588_pll_set_params(pll, rate);
1445
+ if (ret)
1446
+ pll->scaling = 0;
1447
+
1448
+ return ret;
1449
+}
1450
+
1451
+static int rockchip_rk3588_pll_enable(struct clk_hw *hw)
1452
+{
1453
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1454
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
1455
+ struct clk_mux *pll_mux = &pll->pll_mux;
1456
+
1457
+ writel(HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0),
1458
+ pll->reg_base + RK3588_PLLCON(1));
1459
+ rockchip_rk3588_pll_wait_lock(pll);
1460
+
1461
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
1462
+
1463
+ return 0;
1464
+}
1465
+
1466
+static void rockchip_rk3588_pll_disable(struct clk_hw *hw)
1467
+{
1468
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1469
+ const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
1470
+ struct clk_mux *pll_mux = &pll->pll_mux;
1471
+
1472
+ pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
1473
+
1474
+ writel(HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN,
1475
+ RK3588_PLLCON1_PWRDOWN, 0),
1476
+ pll->reg_base + RK3588_PLLCON(1));
1477
+}
1478
+
1479
+static int rockchip_rk3588_pll_is_enabled(struct clk_hw *hw)
1480
+{
1481
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1482
+ u32 pllcon = readl(pll->reg_base + RK3588_PLLCON(1));
1483
+
1484
+ return !(pllcon & RK3588_PLLCON1_PWRDOWN);
1485
+}
1486
+
1487
+static int rockchip_rk3588_pll_init(struct clk_hw *hw)
1488
+{
1489
+ struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
1490
+
1491
+ if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
1492
+ return 0;
1493
+
1494
+ return 0;
1495
+}
1496
+
1497
+static const struct clk_ops rockchip_rk3588_pll_clk_norate_ops = {
1498
+ .recalc_rate = rockchip_rk3588_pll_recalc_rate,
1499
+ .enable = rockchip_rk3588_pll_enable,
1500
+ .disable = rockchip_rk3588_pll_disable,
1501
+ .is_enabled = rockchip_rk3588_pll_is_enabled,
1502
+};
1503
+
1504
+static const struct clk_ops rockchip_rk3588_pll_clk_ops = {
1505
+ .recalc_rate = rockchip_rk3588_pll_recalc_rate,
1506
+ .round_rate = rockchip_rk3588_pll_round_rate,
1507
+ .set_rate = rockchip_rk3588_pll_set_rate,
1508
+ .enable = rockchip_rk3588_pll_enable,
1509
+ .disable = rockchip_rk3588_pll_disable,
1510
+ .is_enabled = rockchip_rk3588_pll_is_enabled,
1511
+ .init = rockchip_rk3588_pll_init,
11951512 };
11961513
11971514 #ifdef CONFIG_ROCKCHIP_CLK_COMPENSATION
....@@ -1236,6 +1553,13 @@
12361553 frac_mask = RK3399_PLLCON2_FRAC_MASK;
12371554 frac_shift = RK3399_PLLCON2_FRAC_SHIFT;
12381555 break;
1556
+ case pll_rk3588:
1557
+ pllcon0 = RK3588_PLLCON(0);
1558
+ pllcon2 = RK3588_PLLCON(2);
1559
+ fbdiv_mask = RK3588_PLLCON0_M_MASK;
1560
+ frac_mask = RK3588_PLLCON2_K_MASK;
1561
+ frac_shift = RK3588_PLLCON2_K_SHIFT;
1562
+ break;
12391563 default:
12401564 return -EINVAL;
12411565 }
....@@ -1248,24 +1572,45 @@
12481572 fbdiv = readl_relaxed(pll->reg_base + pllcon0) & fbdiv_mask;
12491573 }
12501574
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;
1575
+ switch (pll->type) {
1576
+ case pll_rk3036:
1577
+ case pll_rk3328:
1578
+ case pll_rk3066:
1579
+ case pll_rk3399:
1580
+ /*
1581
+ * delta frac frac ppm
1582
+ * -------------- = (fbdiv + ----------) * ---------
1583
+ * 1 << 24 1 << 24 1000000
1584
+ *
1585
+ */
1586
+ m = div64_u64((uint64_t)frac * ppm, 1000000);
1587
+ n = div64_u64((uint64_t)ppm << 24, 1000000) * fbdiv;
12591588
1260
- fracdiv = negative ? frac - (m + n) : frac + (m + n);
1589
+ fracdiv = negative ? frac - (m + n) : frac + (m + n);
12611590
1262
- if (!frac || fracdiv > frac_mask)
1591
+ if (!frac || fracdiv > frac_mask)
1592
+ return -EINVAL;
1593
+
1594
+ pllcon = readl_relaxed(pll->reg_base + pllcon2);
1595
+ pllcon &= ~(frac_mask << frac_shift);
1596
+ pllcon |= fracdiv << frac_shift;
1597
+ writel_relaxed(pllcon, pll->reg_base + pllcon2);
1598
+ break;
1599
+ case pll_rk3588:
1600
+ m = div64_u64((uint64_t)frac * ppm, 100000);
1601
+ n = div64_u64((uint64_t)ppm * 65535 * fbdiv, 100000);
1602
+
1603
+ fracdiv = negative ? frac - (div64_u64(m + n, 10)) : frac + (div64_u64(m + n, 10));
1604
+
1605
+ if (!frac || fracdiv > frac_mask)
1606
+ return -EINVAL;
1607
+
1608
+ writel_relaxed(HIWORD_UPDATE(fracdiv, frac_mask, frac_shift),
1609
+ pll->reg_base + pllcon2);
1610
+ break;
1611
+ default:
12631612 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);
1613
+ }
12691614
12701615 return 0;
12711616 }
....@@ -1285,7 +1630,7 @@
12851630 unsigned long flags, u8 clk_pll_flags)
12861631 {
12871632 const char *pll_parents[3];
1288
- struct clk_init_data init = {};
1633
+ struct clk_init_data init;
12891634 struct rockchip_clk_pll *pll;
12901635 struct clk_mux *pll_mux;
12911636 struct clk *pll_clk, *mux_clk;
....@@ -1316,12 +1661,7 @@
13161661 pll_mux->flags = 0;
13171662 pll_mux->lock = &ctx->lock;
13181663 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;
1664
+ pll_mux->flags |= CLK_MUX_HIWORD_MASK;
13251665
13261666 /* the actual muxing is xin24m, pll-output, xin32k */
13271667 pll_parents[0] = parent_names[0];
....@@ -1345,8 +1685,11 @@
13451685 init.name = pll_name;
13461686
13471687 #ifndef CONFIG_ROCKCHIP_LOW_PERFORMANCE
1348
- /* keep all plls untouched for now */
1349
- init.flags = flags | CLK_IGNORE_UNUSED;
1688
+ if (clk_pll_flags & ROCKCHIP_PLL_ALLOW_POWER_DOWN)
1689
+ init.flags = flags;
1690
+ else
1691
+ /* keep all plls untouched for now */
1692
+ init.flags = flags | CLK_IGNORE_UNUSED;
13501693 #else
13511694 init.flags = flags;
13521695 #endif
....@@ -1374,7 +1717,7 @@
13741717 switch (pll_type) {
13751718 case pll_rk3036:
13761719 case pll_rk3328:
1377
- if (!pll->rate_table || IS_ERR(ctx->grf))
1720
+ if (!pll->rate_table)
13781721 init.ops = &rockchip_rk3036_pll_clk_norate_ops;
13791722 else
13801723 init.ops = &rockchip_rk3036_pll_clk_ops;
....@@ -1393,6 +1736,16 @@
13931736 init.ops = &rockchip_rk3399_pll_clk_norate_ops;
13941737 else
13951738 init.ops = &rockchip_rk3399_pll_clk_ops;
1739
+ break;
1740
+#endif
1741
+#ifdef CONFIG_ROCKCHIP_PLL_RK3588
1742
+ case pll_rk3588:
1743
+ case pll_rk3588_core:
1744
+ if (!pll->rate_table)
1745
+ init.ops = &rockchip_rk3588_pll_clk_norate_ops;
1746
+ else
1747
+ init.ops = &rockchip_rk3588_pll_clk_ops;
1748
+ init.flags = flags;
13961749 break;
13971750 #endif
13981751 default:
....@@ -1619,6 +1972,7 @@
16191972 #ifdef CONFIG_DEBUG_FS
16201973 #include <linux/debugfs.h>
16211974
1975
+#ifndef MODULE
16221976 static int boost_summary_show(struct seq_file *s, void *data)
16231977 {
16241978 struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private;
....@@ -1736,5 +2090,6 @@
17362090 return 0;
17372091 }
17382092 late_initcall(boost_debug_init);
2093
+#endif /* MODULE */
17392094 #endif /* CONFIG_DEBUG_FS */
17402095 #endif /* CONFIG_ROCKCHIP_CLK_BOOST */