hc
2024-02-19 1c055e55a242a33e574e48be530e06770a210dcd
kernel/drivers/devfreq/event/rockchip-dfi.c
....@@ -1,15 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
34 * Author: Lin Huang <hl@rock-chips.com>
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope it will be useful, but WITHOUT
10
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
- * more details.
135 */
146
157 #include <linux/clk.h>
....@@ -26,8 +18,12 @@
2618 #include <linux/list.h>
2719 #include <linux/of.h>
2820
21
+#include <soc/rockchip/rk3399_grf.h>
22
+
2923 #define PX30_PMUGRF_OS_REG2 0x208
3024 #define PX30_PMUGRF_OS_REG3 0x20c
25
+
26
+#define RK3588_PMUGRF_OS_REG(n) (0x200 + (n) * 4)
3127
3228 #define RK3128_GRF_SOC_CON0 0x140
3329 #define RK3128_GRF_OS_REG1 0x1cc
....@@ -56,14 +52,22 @@
5652 #define RK3368_DFI_EN (0x30003 << 5)
5753 #define RK3368_DFI_DIS (0x30000 << 5)
5854
59
-#define MAX_DMC_NUM_CH 2
55
+#define RK3528_PMUGRF_OFFSET 0x70000
56
+#define RK3528_PMUGRF_OS_REG18 0x248
57
+#define RK3528_PMUGRF_OS_REG19 0x24c
58
+
59
+#define MAX_DMC_NUM_CH 4
6060 #define READ_DRAMTYPE_INFO(n) (((n) >> 13) & 0x7)
6161 #define READ_CH_INFO(n) (((n) >> 28) & 0x3)
6262 #define READ_DRAMTYPE_INFO_V3(n, m) ((((n) >> 13) & 0x7) | ((((m) >> 12) & 0x3) << 3))
6363 #define READ_SYSREG_VERSION(m) (((m) >> 28) & 0xf)
64
+#define READ_LP5_BANK_MODE(m) (((m) >> 1) & 0x3)
65
+#define READ_LP5_CKR(m) (((m) >> 0) & 0x1)
6466 /* DDRMON_CTRL */
6567 #define DDRMON_CTRL 0x04
66
-#define CLR_DDRMON_CTRL (0x3f0000 << 0)
68
+#define CLR_DDRMON_CTRL (0xffff0000 << 0)
69
+#define LPDDR5_BANK_MODE(m) ((0x30000 | ((m) & 0x3)) << 7)
70
+#define LPDDR5_EN (0x10001 << 6)
6771 #define DDR4_EN (0x10001 << 5)
6872 #define LPDDR4_EN (0x10001 << 4)
6973 #define HARDWARE_EN (0x10001 << 3)
....@@ -87,12 +91,14 @@
8791 LPDDR3 = 6,
8892 LPDDR4 = 7,
8993 LPDDR4X = 8,
94
+ LPDDR5 = 9,
95
+ DDR5 = 10,
9096 UNUSED = 0xFF
9197 };
9298
9399 struct dmc_usage {
94
- u32 access;
95
- u32 total;
100
+ u64 access;
101
+ u64 total;
96102 };
97103
98104 /*
....@@ -111,6 +117,13 @@
111117 struct regmap *regmap_pmugrf;
112118 struct clk *clk;
113119 u32 dram_type;
120
+ u32 mon_idx;
121
+ u32 count_rate;
122
+ u32 dram_dynamic_info_reg;
123
+ /* 0: BG mode, 1: 16 Bank mode, 2: 8 bank mode */
124
+ u32 lp5_bank_mode;
125
+ /* 0: clk:dqs = 1:2, 1: 1:4 */
126
+ u32 lp5_ckr;
114127 /*
115128 * available mask, 1: available, 0: not available
116129 * each bit represent a channel
....@@ -347,28 +360,56 @@
347360 {
348361 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
349362 void __iomem *dfi_regs = info->regs;
363
+ u32 mon_idx = 0, val_6 = 0;
364
+ u32 i;
350365
351
- /* clear DDRMON_CTRL setting */
352
- writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL);
366
+ if (info->mon_idx)
367
+ mon_idx = info->mon_idx;
353368
354
- /* set ddr type to dfi */
355
- if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2)
356
- writel_relaxed(LPDDR2_3_EN, dfi_regs + DDRMON_CTRL);
357
- else if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
358
- writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL);
359
- else if (info->dram_type == DDR4)
360
- writel_relaxed(DDR4_EN, dfi_regs + DDRMON_CTRL);
369
+ if (info->dram_dynamic_info_reg)
370
+ regmap_read(info->regmap_pmugrf, info->dram_dynamic_info_reg, &val_6);
361371
362
- /* enable count, use software mode */
363
- writel_relaxed(SOFTWARE_EN, dfi_regs + DDRMON_CTRL);
372
+ if (info->dram_type == LPDDR5) {
373
+ info->lp5_bank_mode = READ_LP5_BANK_MODE(val_6);
374
+ info->lp5_ckr = READ_LP5_CKR(val_6);
375
+ }
376
+
377
+ for (i = 0; i < MAX_DMC_NUM_CH; i++) {
378
+ if (!(info->ch_msk & BIT(i)))
379
+ continue;
380
+ /* clear DDRMON_CTRL setting */
381
+ writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + i * mon_idx + DDRMON_CTRL);
382
+
383
+ /* set ddr type to dfi */
384
+ if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2)
385
+ writel_relaxed(LPDDR2_3_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
386
+ else if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
387
+ writel_relaxed(LPDDR4_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
388
+ else if (info->dram_type == DDR4)
389
+ writel_relaxed(DDR4_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
390
+ else if (info->dram_type == LPDDR5)
391
+ writel_relaxed(LPDDR5_EN | LPDDR5_BANK_MODE(info->lp5_bank_mode),
392
+ dfi_regs + i * mon_idx + DDRMON_CTRL);
393
+
394
+ /* enable count, use software mode */
395
+ writel_relaxed(SOFTWARE_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
396
+ }
364397 }
365398
366399 static void rockchip_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
367400 {
368401 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
369402 void __iomem *dfi_regs = info->regs;
403
+ u32 mon_idx = 0, i;
370404
371
- writel_relaxed(SOFTWARE_DIS, dfi_regs + DDRMON_CTRL);
405
+ if (info->mon_idx)
406
+ mon_idx = info->mon_idx;
407
+
408
+ for (i = 0; i < MAX_DMC_NUM_CH; i++) {
409
+ if (!(info->ch_msk & BIT(i)))
410
+ continue;
411
+ writel_relaxed(SOFTWARE_DIS, dfi_regs + i * mon_idx + DDRMON_CTRL);
412
+ }
372413 }
373414
374415 static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev)
....@@ -377,22 +418,31 @@
377418 u32 tmp, max = 0;
378419 u32 i, busier_ch = 0;
379420 void __iomem *dfi_regs = info->regs;
421
+ u32 mon_idx = 0x20, count_rate = 1;
380422
381423 rockchip_dfi_stop_hardware_counter(edev);
424
+
425
+ if (info->mon_idx)
426
+ mon_idx = info->mon_idx;
427
+ if (info->count_rate)
428
+ count_rate = info->count_rate;
382429
383430 /* Find out which channel is busier */
384431 for (i = 0; i < MAX_DMC_NUM_CH; i++) {
385432 if (!(info->ch_msk & BIT(i)))
386433 continue;
387434
435
+ /* rk3588 counter is dfi clk rate */
388436 info->ch_usage[i].total = readl_relaxed(dfi_regs +
389
- DDRMON_CH0_COUNT_NUM + i * 20);
437
+ DDRMON_CH0_COUNT_NUM + i * mon_idx) * count_rate;
390438
391
- /* LPDDR4 and LPDDR4X BL = 16,other DDR type BL = 8 */
439
+ /* LPDDR5 LPDDR4 and LPDDR4X BL = 16,other DDR type BL = 8 */
392440 tmp = readl_relaxed(dfi_regs +
393
- DDRMON_CH0_DFI_ACCESS_NUM + i * 20);
441
+ DDRMON_CH0_DFI_ACCESS_NUM + i * mon_idx);
394442 if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
395443 tmp *= 8;
444
+ else if (info->dram_type == LPDDR5)
445
+ tmp *= 16 / (4 << info->lp5_ckr);
396446 else
397447 tmp *= 4;
398448 info->ch_usage[i].access = tmp;
....@@ -464,6 +514,45 @@
464514 .get_event = rockchip_dfi_get_event,
465515 .set_event = rockchip_dfi_set_event,
466516 };
517
+
518
+static __maybe_unused __init int rk3588_dfi_init(struct platform_device *pdev,
519
+ struct rockchip_dfi *data,
520
+ struct devfreq_event_desc *desc)
521
+{
522
+ struct device_node *np = pdev->dev.of_node;
523
+ struct resource *res;
524
+ u32 val_2, val_3, val_4;
525
+
526
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
527
+ data->regs = devm_ioremap_resource(&pdev->dev, res);
528
+ if (IS_ERR(data->regs))
529
+ return PTR_ERR(data->regs);
530
+
531
+ data->regmap_pmugrf = syscon_regmap_lookup_by_phandle(np, "rockchip,pmu_grf");
532
+ if (IS_ERR(data->regmap_pmugrf))
533
+ return PTR_ERR(data->regmap_pmugrf);
534
+
535
+ regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(2), &val_2);
536
+ regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(3), &val_3);
537
+ regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(4), &val_4);
538
+ if (READ_SYSREG_VERSION(val_3) >= 0x3)
539
+ data->dram_type = READ_DRAMTYPE_INFO_V3(val_2, val_3);
540
+ else
541
+ data->dram_type = READ_DRAMTYPE_INFO(val_2);
542
+
543
+ data->mon_idx = 0x4000;
544
+ if (data->dram_type == LPDDR5)
545
+ data->count_rate = 1;
546
+ else
547
+ data->count_rate = 2;
548
+ data->dram_dynamic_info_reg = RK3588_PMUGRF_OS_REG(6);
549
+ data->ch_msk = READ_CH_INFO(val_2) | READ_CH_INFO(val_4) << 2;
550
+ data->clk = NULL;
551
+
552
+ desc->ops = &rockchip_dfi_ops;
553
+
554
+ return 0;
555
+}
467556
468557 static __maybe_unused __init int px30_dfi_init(struct platform_device *pdev,
469558 struct rockchip_dfi *data,
....@@ -577,12 +666,10 @@
577666 struct devfreq_event_desc *desc)
578667 {
579668 struct device *dev = &pdev->dev;
580
- struct resource *res;
581669 struct device_node *np = pdev->dev.of_node, *node;
582670 u32 val;
583671
584
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
585
- data->regs = devm_ioremap_resource(&pdev->dev, res);
672
+ data->regs = devm_platform_ioremap_resource(pdev, 0);
586673 if (IS_ERR(data->regs))
587674 return PTR_ERR(data->regs);
588675
....@@ -596,6 +683,7 @@
596683 node = of_parse_phandle(np, "rockchip,pmu", 0);
597684 if (node) {
598685 data->regmap_pmu = syscon_node_to_regmap(node);
686
+ of_node_put(node);
599687 if (IS_ERR(data->regmap_pmu))
600688 return PTR_ERR(data->regmap_pmu);
601689 }
....@@ -639,6 +727,41 @@
639727 return 0;
640728 }
641729
730
+static __maybe_unused __init int rk3528_dfi_init(struct platform_device *pdev,
731
+ struct rockchip_dfi *data,
732
+ struct devfreq_event_desc *desc)
733
+{
734
+ struct device_node *np = pdev->dev.of_node, *node;
735
+ struct resource *res;
736
+ u32 val_18, val_19;
737
+
738
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
739
+ data->regs = devm_ioremap_resource(&pdev->dev, res);
740
+ if (IS_ERR(data->regs))
741
+ return PTR_ERR(data->regs);
742
+
743
+ node = of_parse_phandle(np, "rockchip,grf", 0);
744
+ if (node) {
745
+ data->regmap_grf = syscon_node_to_regmap(node);
746
+ if (IS_ERR(data->regmap_grf))
747
+ return PTR_ERR(data->regmap_grf);
748
+ }
749
+
750
+ regmap_read(data->regmap_grf, RK3528_PMUGRF_OFFSET + RK3528_PMUGRF_OS_REG18, &val_18);
751
+ regmap_read(data->regmap_grf, RK3528_PMUGRF_OFFSET + RK3528_PMUGRF_OS_REG19, &val_19);
752
+ if (READ_SYSREG_VERSION(val_19) >= 0x3)
753
+ data->dram_type = READ_DRAMTYPE_INFO_V3(val_18, val_19);
754
+ else
755
+ data->dram_type = READ_DRAMTYPE_INFO(val_18);
756
+ data->count_rate = 2;
757
+ data->ch_msk = 1;
758
+ data->clk = NULL;
759
+
760
+ desc->ops = &rockchip_dfi_ops;
761
+
762
+ return 0;
763
+}
764
+
642765 static const struct of_device_id rockchip_dfi_id_match[] = {
643766 #ifdef CONFIG_CPU_PX30
644767 { .compatible = "rockchip,px30-dfi", .data = px30_dfi_init },
....@@ -661,9 +784,18 @@
661784 #ifdef CONFIG_CPU_RK3399
662785 { .compatible = "rockchip,rk3399-dfi", .data = rockchip_dfi_init },
663786 #endif
787
+#ifdef CONFIG_CPU_RK3528
788
+ { .compatible = "rockchip,rk3528-dfi", .data = rk3528_dfi_init },
789
+#endif
790
+#ifdef CONFIG_CPU_RK3562
791
+ { .compatible = "rockchip,rk3562-dfi", .data = px30_dfi_init },
792
+#endif
664793 #ifdef CONFIG_CPU_RK3568
665794 { .compatible = "rockchip,rk3568-dfi", .data = px30_dfi_init },
666795 #endif
796
+#ifdef CONFIG_CPU_RK3588
797
+ { .compatible = "rockchip,rk3588-dfi", .data = rk3588_dfi_init },
798
+#endif
667799 #ifdef CONFIG_CPU_RV1126
668800 { .compatible = "rockchip,rv1126-dfi", .data = px30_dfi_init },
669801 #endif