soc: rockchip: ipa: Add support to calculate static coefficient

On some platforms, the mathematical model of leakage-static power
curve is quadratic equation and the leakage has a range between a
minimum and maximum.

Change-Id: I1d5101b5e5897256e32fffab4210033214e7a532
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
This commit is contained in:
Finley Xiao 2020-01-15 17:04:51 +08:00 committed by Tao Huang
parent 2dc8014581
commit 2bb51f79eb
3 changed files with 63 additions and 26 deletions

View File

@ -12,6 +12,31 @@
#define FALLBACK_STATIC_TEMPERATURE 55000
static void calculate_static_coefficient(struct ipa_power_model_data *data)
{
s32 *ls = data->ls;
u32 lkg = data->leakage;
u32 ref_lkg = data->ref_leakage;
u32 min = data->lkg_range[0], max = data->lkg_range[1];
u32 static_coeff = data->static_coefficient;
u32 lkg_scaling_factor;
/* leakage=0, use static_coefficient in devicetree */
if (!lkg)
return;
if (ref_lkg) {
data->static_coefficient = static_coeff * lkg / ref_lkg;
return;
}
if (lkg < min)
lkg = min;
if (lkg > max)
lkg = max;
/* As ts have beed multiplied by 1000 in devicetree */
lkg_scaling_factor = (ls[2] * lkg * lkg + ls[1] * lkg + ls[0]) / 1000;
data->static_coefficient = static_coeff * lkg_scaling_factor / 100;
}
/**
* rockchip_ipa_power_model_init() - initialise ipa power model parameter
* @dev: device for which we do this operation
@ -69,8 +94,23 @@ struct ipa_power_model_data *rockchip_ipa_power_model_init(struct device *dev,
goto err;
}
rockchip_of_get_leakage(dev, lkg_name, &model_data->leakage);
of_property_read_u32(model_node, "ref-leakage",
&model_data->ref_leakage);
if (!of_property_read_u32(model_node, "ref-leakage",
&model_data->ref_leakage))
goto cal_static_coeff;
if (of_property_read_u32_array(model_node, "leakage-range",
(u32 *)model_data->lkg_range, 2)) {
dev_err(dev, "leakage-range isn't available\n");
ret = -EINVAL;
goto err;
}
if (of_property_read_u32_array(model_node, "ls",
(u32 *)model_data->ls, 3)) {
dev_err(dev, "ls isn't available\n");
ret = -EINVAL;
goto err;
}
cal_static_coeff:
calculate_static_coefficient(model_data);
return model_data;
err:
@ -146,7 +186,7 @@ rockchip_ipa_get_static_power(struct ipa_power_model_data *data,
unsigned long voltage_mv)
{
u32 temp_scaling_factor, volt_scaling_factor, static_power;
u64 coeff_big;
u64 power_big;
int temp;
int ret;
@ -158,21 +198,19 @@ rockchip_ipa_get_static_power(struct ipa_power_model_data *data,
}
temp_scaling_factor = calculate_temp_scaling_factor(data->ts, temp);
coeff_big = (u64)data->static_coefficient * (u64)temp_scaling_factor;
static_power = div_u64(coeff_big, 1000000);
volt_scaling_factor = calculate_volt_scaling_factor((u32)voltage_mv);
coeff_big = (u64)static_power * (u64)volt_scaling_factor;
static_power = div_u64(coeff_big, 1000000);
if (data->leakage && data->ref_leakage)
static_power = static_power * data->leakage /
data->ref_leakage;
trace_thermal_power_get_static_power(data->static_coefficient, temp,
power_big = (u64)data->static_coefficient * (u64)temp_scaling_factor;
static_power = div_u64(power_big, 1000000);
power_big = (u64)static_power * (u64)volt_scaling_factor;
static_power = div_u64(power_big, 1000000);
trace_thermal_power_get_static_power(data->leakage,
data->static_coefficient,
temp,
temp_scaling_factor,
(u32)voltage_mv,
volt_scaling_factor,
data->leakage, data->ref_leakage,
static_power);
return static_power;

View File

@ -8,10 +8,12 @@
struct ipa_power_model_data {
u32 static_coefficient;
u32 dynamic_coefficient;
s32 ts[4];
s32 ts[4]; /* temperature scaling factor */
struct thermal_zone_device *tz;
u32 leakage;
u32 ref_leakage;
u32 lkg_range[2]; /* min leakage and max leakage */
s32 ls[3]; /* leakage scaling factor */
};
#ifdef CONFIG_ROCKCHIP_IPA

View File

@ -93,39 +93,36 @@ TRACE_EVENT(thermal_zone_trip,
#ifdef CONFIG_ROCKCHIP_IPA
TRACE_EVENT(thermal_power_get_static_power,
TP_PROTO(u32 coefficient, s32 temp, u32 temp_scaling_factor, u32 volt,
u32 volt_scaling_factor, u32 leakage, u32 ref_leakage,
TP_PROTO(u32 leakage, u32 coefficient, s32 temp,
u32 temp_scaling_factor, u32 volt, u32 volt_scaling_factor,
u32 static_power),
TP_ARGS(coefficient, temp, temp_scaling_factor, volt,
volt_scaling_factor, leakage, ref_leakage, static_power),
TP_ARGS(leakage, coefficient, temp, temp_scaling_factor, volt,
volt_scaling_factor, static_power),
TP_STRUCT__entry(
__field(u32, leakage)
__field(u32, coefficient)
__field(s32, temp)
__field(u32, temp_scaling_factor)
__field(u32, volt)
__field(u32, volt_scaling_factor)
__field(u32, leakage)
__field(u32, ref_leakage)
__field(u32, static_power)
),
TP_fast_assign(
__entry->leakage = leakage;
__entry->coefficient = coefficient;
__entry->temp = temp;
__entry->temp_scaling_factor = temp_scaling_factor;
__entry->volt = volt;
__entry->volt_scaling_factor = volt_scaling_factor;
__entry->leakage = leakage;
__entry->ref_leakage = ref_leakage;
__entry->static_power = static_power;
),
TP_printk("c=%u t=%d ts=%u v=%u vs=%u lkg=%u ref_lkg=%u static_power=%u",
__entry->coefficient, __entry->temp,
TP_printk("lkg=%u c=%u t=%d ts=%u v=%u vs=%u static_power=%u",
__entry->leakage, __entry->coefficient, __entry->temp,
__entry->temp_scaling_factor, __entry->volt,
__entry->volt_scaling_factor, __entry->leakage,
__entry->ref_leakage, __entry->static_power)
__entry->volt_scaling_factor, __entry->static_power)
);
#endif /* CONFIG_ROCKCHIP_IPA */