Skip to content

Commit 9991166

Browse files
saschahauerchanwoochoi
authored andcommitted
PM / devfreq: rockchip-dfi: Use free running counter
The DDR_MON counters are free running counters. These are resetted to 0 when starting them over like currently done when reading the current counter values. Resetting the counters becomes a problem with perf support we want to add later, because perf needs counters that are not modified elsewhere. This patch removes resetting the counters and keeps them running instead. That means we no longer use the absolute counter values but instead compare them with the counter values we read last time. Not stopping the counters also has the impact that they are running while we are reading them. We cannot read multiple timers atomically, so the values do not exactly fit together. The effect should be negligible though as the time between two measurements is some orders of magnitude bigger than the time we need to read multiple registers. Link: https://lore.kernel.org/all/[email protected]/ Reviewed-by: Sebastian Reichel <[email protected]> Acked-by: Chanwoo Choi <[email protected]> Signed-off-by: Sascha Hauer <[email protected]> Signed-off-by: Chanwoo Choi <[email protected]>
1 parent 6c29e29 commit 9991166

File tree

1 file changed

+30
-22
lines changed

1 file changed

+30
-22
lines changed

drivers/devfreq/event/rockchip-dfi.c

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,15 @@
3838
#define DDRMON_CH1_COUNT_NUM 0x3c
3939
#define DDRMON_CH1_DFI_ACCESS_NUM 0x40
4040

41-
struct dmc_usage {
41+
struct dmc_count_channel {
4242
u32 access;
4343
u32 total;
4444
};
4545

46+
struct dmc_count {
47+
struct dmc_count_channel c[RK3399_DMC_NUM_CH];
48+
};
49+
4650
/*
4751
* The dfi controller can monitor DDR load. It has an upper and lower threshold
4852
* for the operating points. Whenever the usage leaves these bounds an event is
@@ -51,7 +55,7 @@ struct dmc_usage {
5155
struct rockchip_dfi {
5256
struct devfreq_event_dev *edev;
5357
struct devfreq_event_desc desc;
54-
struct dmc_usage ch_usage[RK3399_DMC_NUM_CH];
58+
struct dmc_count last_event_count;
5559
struct device *dev;
5660
void __iomem *regs;
5761
struct regmap *regmap_pmu;
@@ -85,30 +89,18 @@ static void rockchip_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
8589
writel_relaxed(SOFTWARE_DIS, dfi_regs + DDRMON_CTRL);
8690
}
8791

88-
static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev)
92+
static void rockchip_dfi_read_counters(struct devfreq_event_dev *edev, struct dmc_count *count)
8993
{
9094
struct rockchip_dfi *dfi = devfreq_event_get_drvdata(edev);
91-
u32 tmp, max = 0;
92-
u32 i, busier_ch = 0;
95+
u32 i;
9396
void __iomem *dfi_regs = dfi->regs;
9497

95-
rockchip_dfi_stop_hardware_counter(edev);
96-
97-
/* Find out which channel is busier */
9898
for (i = 0; i < RK3399_DMC_NUM_CH; i++) {
99-
dfi->ch_usage[i].access = readl_relaxed(dfi_regs +
99+
count->c[i].access = readl_relaxed(dfi_regs +
100100
DDRMON_CH0_DFI_ACCESS_NUM + i * 20);
101-
dfi->ch_usage[i].total = readl_relaxed(dfi_regs +
101+
count->c[i].total = readl_relaxed(dfi_regs +
102102
DDRMON_CH0_COUNT_NUM + i * 20);
103-
tmp = dfi->ch_usage[i].access;
104-
if (tmp > max) {
105-
busier_ch = i;
106-
max = tmp;
107-
}
108103
}
109-
rockchip_dfi_start_hardware_counter(edev);
110-
111-
return busier_ch;
112104
}
113105

114106
static int rockchip_dfi_disable(struct devfreq_event_dev *edev)
@@ -145,12 +137,28 @@ static int rockchip_dfi_get_event(struct devfreq_event_dev *edev,
145137
struct devfreq_event_data *edata)
146138
{
147139
struct rockchip_dfi *dfi = devfreq_event_get_drvdata(edev);
148-
int busier_ch;
140+
struct dmc_count count;
141+
struct dmc_count *last = &dfi->last_event_count;
142+
u32 access = 0, total = 0;
143+
int i;
144+
145+
rockchip_dfi_read_counters(edev, &count);
146+
147+
/* We can only report one channel, so find the busiest one */
148+
for (i = 0; i < RK3399_DMC_NUM_CH; i++) {
149+
u32 a = count.c[i].access - last->c[i].access;
150+
u32 t = count.c[i].total - last->c[i].total;
151+
152+
if (a > access) {
153+
access = a;
154+
total = t;
155+
}
156+
}
149157

150-
busier_ch = rockchip_dfi_get_busier_ch(edev);
158+
edata->load_count = access * 4;
159+
edata->total_count = total;
151160

152-
edata->load_count = dfi->ch_usage[busier_ch].access * 4;
153-
edata->total_count = dfi->ch_usage[busier_ch].total;
161+
dfi->last_event_count = count;
154162

155163
return 0;
156164
}

0 commit comments

Comments
 (0)