immortalwrt/target/linux/rockchip/patches-6.1/804-05-PM-devfreq-event-make-dfi-more-extension.patch
Tianling Shen 496436c0e0 rockchip: 6.1: copy patches, config from 5.15
Copy patches and config from 5.15 kernel version.

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
2023-05-23 12:48:31 +08:00

185 lines
5.7 KiB
Diff

From 0873229b2495f356d84a0182e50c5ea27ae46816 Mon Sep 17 00:00:00 2001
From: CanYang He <hcy@rock-chips.com>
Date: Sat, 23 Dec 2017 14:51:38 +0800
Subject: [PATCH] PM / devfreq: event: make dfi more extension
after modify, rockchip_dfi_ops can apply to other platform use such
version ddr monitor. regardless of channel count, only one channel
of rk3288,rk3399,rk3328 can work. and regardless of monitor clk,
some platform like rk3328 monitor clk is always on.
Change-Id: Ia1c02a89116546ded385c5a6a3e36d020d66b7f3
Signed-off-by: CanYang He <hcy@rock-chips.com>
---
drivers/devfreq/event/rockchip-dfi.c | 63 ++++++++++++++++++----------
1 file changed, 40 insertions(+), 23 deletions(-)
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -31,7 +31,6 @@
#define RK3288_PMU_SYS_REG2 0x9c
#define RK3288_GRF_SOC_CON4 0x254
#define RK3288_GRF_SOC_STATUS(n) (0x280 + (n) * 4)
-#define READ_DRAMTYPE_INFO(n) (((n) >> 13) & 0x7)
#define RK3288_DFI_EN (0x30003 << 14)
#define RK3288_DFI_DIS (0x30000 << 14)
#define RK3288_LPDDR_SEL (0x10001 << 13)
@@ -46,7 +45,9 @@
#define RK3368_DFI_EN (0x30003 << 5)
#define RK3368_DFI_DIS (0x30000 << 5)
-#define RK3399_DMC_NUM_CH 2
+#define MAX_DMC_NUM_CH 2
+#define READ_DRAMTYPE_INFO(n) (((n) >> 13) & 0x7)
+#define READ_CH_INFO(n) (((n) >> 28) & 0x3)
/* DDRMON_CTRL */
#define DDRMON_CTRL 0x04
@@ -63,6 +64,9 @@
#define DDRMON_CH1_COUNT_NUM 0x3c
#define DDRMON_CH1_DFI_ACCESS_NUM 0x40
+/* pmu grf */
+#define PMUGRF_OS_REG2 0x308
+
enum {
DDR3 = 3,
LPDDR3 = 6,
@@ -83,12 +87,18 @@ struct dmc_usage {
struct rockchip_dfi {
struct devfreq_event_dev *edev;
struct devfreq_event_desc *desc;
- struct dmc_usage ch_usage[RK3399_DMC_NUM_CH];
+ struct dmc_usage ch_usage[MAX_DMC_NUM_CH];
struct device *dev;
void __iomem *regs;
struct regmap *regmap_pmu;
struct regmap *regmap_grf;
struct clk *clk;
+ u32 dram_type;
+ /*
+ * available mask, 1: available, 0: not available
+ * each bit represent a channel
+ */
+ u32 ch_msk;
};
static void rk3128_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
@@ -203,7 +213,9 @@ static int rk3288_dfi_get_busier_ch(stru
rk3288_dfi_stop_hardware_counter(edev);
/* Find out which channel is busier */
- for (i = 0; i < RK3399_DMC_NUM_CH; i++) {
+ for (i = 0; i < MAX_DMC_NUM_CH; i++) {
+ if (!(info->ch_msk & BIT(i)))
+ continue;
regmap_read(info->regmap_grf,
RK3288_GRF_SOC_STATUS(11 + i * 4), &wr_count);
regmap_read(info->regmap_grf,
@@ -318,21 +330,14 @@ static void rockchip_dfi_start_hardware_
{
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
void __iomem *dfi_regs = info->regs;
- u32 val;
- u32 ddr_type;
-
- /* get ddr type */
- regmap_read(info->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
- ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
- RK3399_PMUGRF_DDRTYPE_MASK;
/* clear DDRMON_CTRL setting */
writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL);
/* set ddr type to dfi */
- if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR3)
+ if (info->dram_type == LPDDR3)
writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL);
- else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR4)
+ else if (info->dram_type == LPDDR4)
writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL);
/* enable count, use software mode */
@@ -357,7 +362,9 @@ static int rockchip_dfi_get_busier_ch(st
rockchip_dfi_stop_hardware_counter(edev);
/* Find out which channel is busier */
- for (i = 0; i < RK3399_DMC_NUM_CH; i++) {
+ for (i = 0; i < MAX_DMC_NUM_CH; i++) {
+ if (!(info->ch_msk & BIT(i)))
+ continue;
info->ch_usage[i].access = readl_relaxed(dfi_regs +
DDRMON_CH0_DFI_ACCESS_NUM + i * 20) * 4;
info->ch_usage[i].total = readl_relaxed(dfi_regs +
@@ -378,7 +385,8 @@ static int rockchip_dfi_disable(struct d
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
rockchip_dfi_stop_hardware_counter(edev);
- clk_disable_unprepare(info->clk);
+ if (info->clk)
+ clk_disable_unprepare(info->clk);
return 0;
}
@@ -388,10 +396,13 @@ static int rockchip_dfi_enable(struct de
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
int ret;
- ret = clk_prepare_enable(info->clk);
- if (ret) {
- dev_err(&edev->dev, "failed to enable dfi clk: %d\n", ret);
- return ret;
+ if (info->clk) {
+ ret = clk_prepare_enable(info->clk);
+ if (ret) {
+ dev_err(&edev->dev, "failed to enable dfi clk: %d\n",
+ ret);
+ return ret;
+ }
}
rockchip_dfi_start_hardware_counter(edev);
@@ -450,7 +461,7 @@ static __init int rk3288_dfi_init(struct
struct devfreq_event_desc *desc)
{
struct device_node *np = pdev->dev.of_node, *node;
- u32 dram_type;
+ u32 val;
node = of_parse_phandle(np, "rockchip,pmu", 0);
if (node) {
@@ -466,10 +477,11 @@ static __init int rk3288_dfi_init(struct
return PTR_ERR(data->regmap_grf);
}
- regmap_read(data->regmap_pmu, RK3288_PMU_SYS_REG2, &dram_type);
- dram_type = READ_DRAMTYPE_INFO(dram_type);
+ regmap_read(data->regmap_pmu, RK3288_PMU_SYS_REG2, &val);
+ data->dram_type = READ_DRAMTYPE_INFO(val);
+ data->ch_msk = READ_CH_INFO(val);
- if (dram_type == DDR3)
+ if (data->dram_type == DDR3)
regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4,
RK3288_DDR3_SEL);
else
@@ -505,6 +517,7 @@ static __init int rockchip_dfi_init(stru
{
struct device *dev = &pdev->dev;
struct device_node *np = pdev->dev.of_node, *node;
+ u32 val;
data->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->regs))
@@ -525,6 +538,10 @@ static __init int rockchip_dfi_init(stru
return PTR_ERR(data->regmap_pmu);
}
+ regmap_read(data->regmap_pmu, PMUGRF_OS_REG2, &val);
+ data->dram_type = READ_DRAMTYPE_INFO(val);
+ data->ch_msk = READ_CH_INFO(val);
+
desc->ops = &rockchip_dfi_ops;
return 0;