#define DDRMON_CH1_COUNT_NUM           0x3c
 #define DDRMON_CH1_DFI_ACCESS_NUM      0x40
 
-struct dmc_usage {
+struct dmc_count_channel {
        u32 access;
        u32 total;
 };
 
+struct dmc_count {
+       struct dmc_count_channel c[RK3399_DMC_NUM_CH];
+};
+
 /*
  * The dfi controller can monitor DDR load. It has an upper and lower threshold
  * for the operating points. Whenever the usage leaves these bounds an event is
 struct rockchip_dfi {
        struct devfreq_event_dev *edev;
        struct devfreq_event_desc desc;
-       struct dmc_usage ch_usage[RK3399_DMC_NUM_CH];
+       struct dmc_count last_event_count;
        struct device *dev;
        void __iomem *regs;
        struct regmap *regmap_pmu;
        writel_relaxed(SOFTWARE_DIS, dfi_regs + DDRMON_CTRL);
 }
 
-static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev)
+static void rockchip_dfi_read_counters(struct devfreq_event_dev *edev, struct dmc_count *count)
 {
        struct rockchip_dfi *dfi = devfreq_event_get_drvdata(edev);
-       u32 tmp, max = 0;
-       u32 i, busier_ch = 0;
+       u32 i;
        void __iomem *dfi_regs = dfi->regs;
 
-       rockchip_dfi_stop_hardware_counter(edev);
-
-       /* Find out which channel is busier */
        for (i = 0; i < RK3399_DMC_NUM_CH; i++) {
-               dfi->ch_usage[i].access = readl_relaxed(dfi_regs +
+               count->c[i].access = readl_relaxed(dfi_regs +
                                DDRMON_CH0_DFI_ACCESS_NUM + i * 20);
-               dfi->ch_usage[i].total = readl_relaxed(dfi_regs +
+               count->c[i].total = readl_relaxed(dfi_regs +
                                DDRMON_CH0_COUNT_NUM + i * 20);
-               tmp = dfi->ch_usage[i].access;
-               if (tmp > max) {
-                       busier_ch = i;
-                       max = tmp;
-               }
        }
-       rockchip_dfi_start_hardware_counter(edev);
-
-       return busier_ch;
 }
 
 static int rockchip_dfi_disable(struct devfreq_event_dev *edev)
                                  struct devfreq_event_data *edata)
 {
        struct rockchip_dfi *dfi = devfreq_event_get_drvdata(edev);
-       int busier_ch;
+       struct dmc_count count;
+       struct dmc_count *last = &dfi->last_event_count;
+       u32 access = 0, total = 0;
+       int i;
+
+       rockchip_dfi_read_counters(edev, &count);
+
+       /* We can only report one channel, so find the busiest one */
+       for (i = 0; i < RK3399_DMC_NUM_CH; i++) {
+               u32 a = count.c[i].access - last->c[i].access;
+               u32 t = count.c[i].total - last->c[i].total;
+
+               if (a > access) {
+                       access = a;
+                       total = t;
+               }
+       }
 
-       busier_ch = rockchip_dfi_get_busier_ch(edev);
+       edata->load_count = access * 4;
+       edata->total_count = total;
 
-       edata->load_count = dfi->ch_usage[busier_ch].access * 4;
-       edata->total_count = dfi->ch_usage[busier_ch].total;
+       dfi->last_event_count = count;
 
        return 0;
 }