diff --git a/drivers/soc/rockchip/rockchip_ipa.c b/drivers/soc/rockchip/rockchip_ipa.c index b748e734bc03..59f0cb74b13c 100644 --- a/drivers/soc/rockchip/rockchip_ipa.c +++ b/drivers/soc/rockchip/rockchip_ipa.c @@ -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; diff --git a/include/soc/rockchip/rockchip_ipa.h b/include/soc/rockchip/rockchip_ipa.h index 896bc7cc760b..e3605bb2a448 100644 --- a/include/soc/rockchip/rockchip_ipa.h +++ b/include/soc/rockchip/rockchip_ipa.h @@ -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 diff --git a/include/trace/events/thermal.h b/include/trace/events/thermal.h index a0948a304c2d..07b5aa9fcc29 100644 --- a/include/trace/events/thermal.h +++ b/include/trace/events/thermal.h @@ -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 */