From 1c055e55a242a33e574e48be530e06770a210dcd Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 19 Feb 2024 03:26:26 +0000
Subject: [PATCH] add r8169 read mac form eeprom

---
 kernel/drivers/devfreq/event/rockchip-dfi.c |  149 +++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 117 insertions(+), 32 deletions(-)

diff --git a/kernel/drivers/devfreq/event/rockchip-dfi.c b/kernel/drivers/devfreq/event/rockchip-dfi.c
index d407f45..e65e489 100644
--- a/kernel/drivers/devfreq/event/rockchip-dfi.c
+++ b/kernel/drivers/devfreq/event/rockchip-dfi.c
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
  * Author: Lin Huang <hl@rock-chips.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
  */
 
 #include <linux/clk.h>
@@ -26,8 +18,12 @@
 #include <linux/list.h>
 #include <linux/of.h>
 
+#include <soc/rockchip/rk3399_grf.h>
+
 #define PX30_PMUGRF_OS_REG2		0x208
 #define PX30_PMUGRF_OS_REG3		0x20c
+
+#define RK3588_PMUGRF_OS_REG(n)		(0x200 + (n) * 4)
 
 #define RK3128_GRF_SOC_CON0		0x140
 #define RK3128_GRF_OS_REG1		0x1cc
@@ -60,14 +56,18 @@
 #define RK3528_PMUGRF_OS_REG18		0x248
 #define RK3528_PMUGRF_OS_REG19		0x24c
 
-#define MAX_DMC_NUM_CH			2
+#define MAX_DMC_NUM_CH			4
 #define READ_DRAMTYPE_INFO(n)		(((n) >> 13) & 0x7)
 #define READ_CH_INFO(n)			(((n) >> 28) & 0x3)
 #define READ_DRAMTYPE_INFO_V3(n, m)	((((n) >> 13) & 0x7) | ((((m) >> 12) & 0x3) << 3))
 #define READ_SYSREG_VERSION(m)		(((m) >> 28) & 0xf)
+#define READ_LP5_BANK_MODE(m)		(((m) >> 1) & 0x3)
+#define READ_LP5_CKR(m)			(((m) >> 0) & 0x1)
 /* DDRMON_CTRL */
 #define DDRMON_CTRL			0x04
-#define CLR_DDRMON_CTRL			(0x3f0000 << 0)
+#define CLR_DDRMON_CTRL			(0xffff0000 << 0)
+#define LPDDR5_BANK_MODE(m)		((0x30000 | ((m) & 0x3)) << 7)
+#define LPDDR5_EN			(0x10001 << 6)
 #define DDR4_EN				(0x10001 << 5)
 #define LPDDR4_EN			(0x10001 << 4)
 #define HARDWARE_EN			(0x10001 << 3)
@@ -91,12 +91,14 @@
 	LPDDR3 = 6,
 	LPDDR4 = 7,
 	LPDDR4X = 8,
+	LPDDR5 = 9,
+	DDR5 = 10,
 	UNUSED = 0xFF
 };
 
 struct dmc_usage {
-	u32 access;
-	u32 total;
+	u64 access;
+	u64 total;
 };
 
 /*
@@ -115,7 +117,13 @@
 	struct regmap *regmap_pmugrf;
 	struct clk *clk;
 	u32 dram_type;
+	u32 mon_idx;
 	u32 count_rate;
+	u32 dram_dynamic_info_reg;
+	/* 0: BG mode, 1: 16 Bank mode, 2: 8 bank mode */
+	u32 lp5_bank_mode;
+	/* 0: clk:dqs = 1:2, 1: 1:4 */
+	u32 lp5_ckr;
 	/*
 	 * available mask, 1: available, 0: not available
 	 * each bit represent a channel
@@ -352,28 +360,56 @@
 {
 	struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
 	void __iomem *dfi_regs = info->regs;
+	u32 mon_idx = 0, val_6 = 0;
+	u32 i;
 
-	/* clear DDRMON_CTRL setting */
-	writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL);
+	if (info->mon_idx)
+		mon_idx = info->mon_idx;
 
-	/* set ddr type to dfi */
-	if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2)
-		writel_relaxed(LPDDR2_3_EN, dfi_regs + DDRMON_CTRL);
-	else if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
-		writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL);
-	else if (info->dram_type == DDR4)
-		writel_relaxed(DDR4_EN, dfi_regs + DDRMON_CTRL);
+	if (info->dram_dynamic_info_reg)
+		regmap_read(info->regmap_pmugrf, info->dram_dynamic_info_reg, &val_6);
 
-	/* enable count, use software mode */
-	writel_relaxed(SOFTWARE_EN, dfi_regs + DDRMON_CTRL);
+	if (info->dram_type == LPDDR5) {
+		info->lp5_bank_mode = READ_LP5_BANK_MODE(val_6);
+		info->lp5_ckr = READ_LP5_CKR(val_6);
+	}
+
+	for (i = 0; i < MAX_DMC_NUM_CH; i++) {
+		if (!(info->ch_msk & BIT(i)))
+			continue;
+		/* clear DDRMON_CTRL setting */
+		writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + i * mon_idx + DDRMON_CTRL);
+
+		/* set ddr type to dfi */
+		if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2)
+			writel_relaxed(LPDDR2_3_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
+		else if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
+			writel_relaxed(LPDDR4_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
+		else if (info->dram_type == DDR4)
+			writel_relaxed(DDR4_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
+		else if (info->dram_type == LPDDR5)
+			writel_relaxed(LPDDR5_EN | LPDDR5_BANK_MODE(info->lp5_bank_mode),
+				       dfi_regs + i * mon_idx + DDRMON_CTRL);
+
+		/* enable count, use software mode */
+		writel_relaxed(SOFTWARE_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
+	}
 }
 
 static void rockchip_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
 {
 	struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
 	void __iomem *dfi_regs = info->regs;
+	u32 mon_idx = 0, i;
 
-	writel_relaxed(SOFTWARE_DIS, dfi_regs + DDRMON_CTRL);
+	if (info->mon_idx)
+		mon_idx = info->mon_idx;
+
+	for (i = 0; i < MAX_DMC_NUM_CH; i++) {
+		if (!(info->ch_msk & BIT(i)))
+			continue;
+		writel_relaxed(SOFTWARE_DIS, dfi_regs + i * mon_idx + DDRMON_CTRL);
+	}
 }
 
 static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev)
@@ -382,10 +418,12 @@
 	u32 tmp, max = 0;
 	u32 i, busier_ch = 0;
 	void __iomem *dfi_regs = info->regs;
-	u32 count_rate = 1;
+	u32 mon_idx = 0x20, count_rate = 1;
 
 	rockchip_dfi_stop_hardware_counter(edev);
 
+	if (info->mon_idx)
+		mon_idx = info->mon_idx;
 	if (info->count_rate)
 		count_rate = info->count_rate;
 
@@ -394,14 +432,17 @@
 		if (!(info->ch_msk & BIT(i)))
 			continue;
 
+		/* rk3588 counter is dfi clk rate */
 		info->ch_usage[i].total = readl_relaxed(dfi_regs +
-				DDRMON_CH0_COUNT_NUM + i * 20) * count_rate;
+				DDRMON_CH0_COUNT_NUM + i * mon_idx) * count_rate;
 
-		/* LPDDR4 and LPDDR4X BL = 16,other DDR type BL = 8 */
+		/* LPDDR5 LPDDR4 and LPDDR4X BL = 16,other DDR type BL = 8 */
 		tmp = readl_relaxed(dfi_regs +
-				DDRMON_CH0_DFI_ACCESS_NUM + i * 20);
+				DDRMON_CH0_DFI_ACCESS_NUM + i * mon_idx);
 		if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
 			tmp *= 8;
+		else if (info->dram_type == LPDDR5)
+			tmp *= 16 / (4 << info->lp5_ckr);
 		else
 			tmp *= 4;
 		info->ch_usage[i].access = tmp;
@@ -473,6 +514,45 @@
 	.get_event = rockchip_dfi_get_event,
 	.set_event = rockchip_dfi_set_event,
 };
+
+static __maybe_unused __init int rk3588_dfi_init(struct platform_device *pdev,
+						 struct rockchip_dfi *data,
+						 struct devfreq_event_desc *desc)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *res;
+	u32 val_2, val_3, val_4;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	data->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(data->regs))
+		return PTR_ERR(data->regs);
+
+	data->regmap_pmugrf = syscon_regmap_lookup_by_phandle(np, "rockchip,pmu_grf");
+	if (IS_ERR(data->regmap_pmugrf))
+		return PTR_ERR(data->regmap_pmugrf);
+
+	regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(2), &val_2);
+	regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(3), &val_3);
+	regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(4), &val_4);
+	if (READ_SYSREG_VERSION(val_3) >= 0x3)
+		data->dram_type = READ_DRAMTYPE_INFO_V3(val_2, val_3);
+	else
+		data->dram_type = READ_DRAMTYPE_INFO(val_2);
+
+	data->mon_idx = 0x4000;
+	if (data->dram_type == LPDDR5)
+		data->count_rate = 1;
+	else
+		data->count_rate = 2;
+	data->dram_dynamic_info_reg = RK3588_PMUGRF_OS_REG(6);
+	data->ch_msk = READ_CH_INFO(val_2) | READ_CH_INFO(val_4) << 2;
+	data->clk = NULL;
+
+	desc->ops = &rockchip_dfi_ops;
+
+	return 0;
+}
 
 static __maybe_unused __init int px30_dfi_init(struct platform_device *pdev,
 					       struct rockchip_dfi *data,
@@ -586,12 +666,10 @@
 						   struct devfreq_event_desc *desc)
 {
 	struct device *dev = &pdev->dev;
-	struct resource *res;
 	struct device_node *np = pdev->dev.of_node, *node;
 	u32 val;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	data->regs = devm_ioremap_resource(&pdev->dev, res);
+	data->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->regs))
 		return PTR_ERR(data->regs);
 
@@ -605,6 +683,7 @@
 	node = of_parse_phandle(np, "rockchip,pmu", 0);
 	if (node) {
 		data->regmap_pmu = syscon_node_to_regmap(node);
+		of_node_put(node);
 		if (IS_ERR(data->regmap_pmu))
 			return PTR_ERR(data->regmap_pmu);
 	}
@@ -708,9 +787,15 @@
 #ifdef CONFIG_CPU_RK3528
 	{ .compatible = "rockchip,rk3528-dfi", .data = rk3528_dfi_init },
 #endif
+#ifdef CONFIG_CPU_RK3562
+	{ .compatible = "rockchip,rk3562-dfi", .data = px30_dfi_init },
+#endif
 #ifdef CONFIG_CPU_RK3568
 	{ .compatible = "rockchip,rk3568-dfi", .data = px30_dfi_init },
 #endif
+#ifdef CONFIG_CPU_RK3588
+	{ .compatible = "rockchip,rk3588-dfi", .data = rk3588_dfi_init },
+#endif
 #ifdef CONFIG_CPU_RV1126
 	{ .compatible = "rockchip,rv1126-dfi", .data = px30_dfi_init },
 #endif

--
Gitblit v1.6.2