mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
PM / devfreq: bw_hwmon: Add support for specifying count factor
Not all bandwidth monitors count in units of 1MB. Add a DT property that indicates the number of bytes the monitor counts in so we can properly scale the count we read from the hardware to reflect the traffic. By default, we will assume 1MB units if the property doesn't exist. Change-Id: I1b581b2fffda04ba151df6e87221628368ff5b17 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
This commit is contained in:
parent
40c5693a21
commit
f6615037dc
@ -23,6 +23,7 @@ Required properties:
|
||||
Optional properties:
|
||||
- qcom,byte-mid-match: Byte count MID match value
|
||||
- qcom,byte-mid-mask: Byte count MID mask value
|
||||
- qcom,count-unit: Number of bytes monitor counts in
|
||||
|
||||
Example:
|
||||
qcom,cpu-bwmon {
|
||||
@ -35,4 +36,5 @@ Example:
|
||||
qcom,hw-timer-hz = <19200000>;
|
||||
qcom,byte-mid-match = <0x1e00>;
|
||||
qcom,byte-mid-mask = <0x1e00>;
|
||||
qcom,count-unit = <0x100000>;
|
||||
};
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/sizes.h>
|
||||
#include "governor_bw_hwmon.h"
|
||||
|
||||
#define GLB_INT_STATUS(m) ((m)->global_base + 0x100)
|
||||
@ -104,6 +106,8 @@ struct bwmon {
|
||||
u32 throttle_adj;
|
||||
u32 sample_size_ms;
|
||||
u32 intr_status;
|
||||
u8 count_shift;
|
||||
u32 thres_lim;
|
||||
u32 byte_mask;
|
||||
u32 byte_match;
|
||||
};
|
||||
@ -418,11 +422,18 @@ static u32 calc_zone_counts(struct bw_hwmon *hw)
|
||||
return zone_counts;
|
||||
}
|
||||
|
||||
static unsigned int mbps_to_mb(unsigned long mbps, unsigned int ms)
|
||||
#define MB_SHIFT 20
|
||||
|
||||
static u32 mbps_to_count(unsigned long mbps, unsigned int ms, u8 shift)
|
||||
{
|
||||
mbps *= ms;
|
||||
mbps = DIV_ROUND_UP(mbps, MSEC_PER_SEC);
|
||||
return mbps;
|
||||
|
||||
if (shift > MB_SHIFT)
|
||||
mbps >>= shift - MB_SHIFT;
|
||||
else
|
||||
mbps <<= MB_SHIFT - shift;
|
||||
|
||||
return DIV_ROUND_UP(mbps, MSEC_PER_SEC);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -430,9 +441,10 @@ static unsigned int mbps_to_mb(unsigned long mbps, unsigned int ms)
|
||||
* Zone 0: byte count < THRES_LO
|
||||
* Zone 1: THRES_LO < byte count < THRES_MED
|
||||
* Zone 2: THRES_MED < byte count < THRES_HI
|
||||
* Zone 3: byte count > THRES_HI
|
||||
* Zone 3: THRES_LIM > byte count > THRES_HI
|
||||
*/
|
||||
#define THRES_LIM 0x7FFU
|
||||
#define THRES_LIM(shift) (0xFFFFFFFF >> shift)
|
||||
|
||||
static __always_inline
|
||||
void set_zone_thres(struct bwmon *m, unsigned int sample_ms,
|
||||
enum mon_reg_type type)
|
||||
@ -441,14 +453,14 @@ void set_zone_thres(struct bwmon *m, unsigned int sample_ms,
|
||||
u32 hi, med, lo;
|
||||
u32 zone_cnt_thres = calc_zone_counts(hw);
|
||||
|
||||
hi = mbps_to_mb(hw->up_wake_mbps, sample_ms);
|
||||
med = mbps_to_mb(hw->down_wake_mbps, sample_ms);
|
||||
hi = mbps_to_count(hw->up_wake_mbps, sample_ms, m->count_shift);
|
||||
med = mbps_to_count(hw->down_wake_mbps, sample_ms, m->count_shift);
|
||||
lo = 0;
|
||||
|
||||
if (unlikely((hi > THRES_LIM) || (med > hi) || (lo > med))) {
|
||||
if (unlikely((hi > m->thres_lim) || (med > hi) || (lo > med))) {
|
||||
pr_warn("Zone thres larger than hw limit: hi:%u med:%u lo:%u\n",
|
||||
hi, med, lo);
|
||||
hi = min(hi, THRES_LIM);
|
||||
hi = min(hi, m->thres_lim);
|
||||
med = min(med, hi - 1);
|
||||
lo = min(lo, med-1);
|
||||
}
|
||||
@ -580,7 +592,7 @@ unsigned long mon_get_zone_stats(struct bwmon *m, enum mon_reg_type type)
|
||||
|
||||
zone = get_zone(m, type);
|
||||
count = get_zone_count(m, zone, type);
|
||||
count *= SZ_1M;
|
||||
count <<= m->count_shift;
|
||||
|
||||
dev_dbg(m->dev, "Zone%d Max byte count: %08lx\n", zone, count);
|
||||
|
||||
@ -992,7 +1004,7 @@ static int bimc_bwmon_driver_probe(struct platform_device *pdev)
|
||||
struct resource *res;
|
||||
struct bwmon *m;
|
||||
int ret;
|
||||
u32 data;
|
||||
u32 data, count_unit;
|
||||
|
||||
m = devm_kzalloc(dev, sizeof(*m), GFP_KERNEL);
|
||||
if (!m)
|
||||
@ -1057,6 +1069,11 @@ static int bimc_bwmon_driver_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
if (of_property_read_u32(dev->of_node, "qcom,count-unit", &count_unit))
|
||||
count_unit = SZ_1M;
|
||||
m->count_shift = order_base_2(count_unit);
|
||||
m->thres_lim = THRES_LIM(m->count_shift);
|
||||
|
||||
switch (m->spec->reg_type) {
|
||||
case MON3:
|
||||
m->hw.start_hwmon = start_bw_hwmon3;
|
||||
|
Loading…
x
Reference in New Issue
Block a user