soc: rockchip: Add rockchip system monitor support

Change-Id: I4cb7fafcb33fda0212b5ad1f6eebd44503556336
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
This commit is contained in:
Finley Xiao 2019-06-11 14:33:15 +08:00 committed by Tao Huang
parent a7bddb708d
commit b99f359494
4 changed files with 90 additions and 86 deletions

View File

@ -78,4 +78,10 @@ config ROCKCHIP_SUSPEND_MODE
help
Say Y here if you want to set the suspend mode to the ATF.
config ROCKCHIP_SYSTEM_MONITOR
bool "Rockchip system monitor support"
default y
help
Say y here to enable rockchip system monitor support.
endif

View File

@ -11,7 +11,7 @@ obj-$(CONFIG_ROCKCHIP_IPA) += rockchip_ipa.o
obj-$(CONFIG_ROCKCHIP_OPP) += rockchip_opp_select.o
obj-$(CONFIG_ROCKCHIP_PVTM) += rockchip_pvtm.o
obj-$(CONFIG_ROCKCHIP_SUSPEND_MODE) += rockchip_pm_config.o
obj-$(CONFIG_ROCKCHIP_SYSTEM_MONITOR) += rockchip_system_monitor.o
obj-y += rk_vendor_storage.o
obj-y += rockchip-system-status.o
obj-$(CONFIG_RK_FLASH) += flash_vendor_storage.o

View File

@ -24,7 +24,7 @@
#include <soc/rockchip/rockchip_system_monitor.h>
#include <soc/rockchip/rockchip-system-status.h>
#include "../../base/power/opp/opp.h"
#include "../../opp/opp.h"
#include "../../devfreq/governor.h"
#define CPU_REBOOT_FREQ 816000 /* kHz */
@ -446,77 +446,70 @@ static int rockchip_get_low_temp_volt(struct monitor_dev_info *info,
static int rockchip_init_temp_opp_table(struct monitor_dev_info *info)
{
struct device *dev = info->dev;
struct opp_table *opp_table;
struct dev_pm_opp *opp;
int delta_volt = 0;
int i, max_count, ret = 0;
unsigned long rate;
int i = 0, max_count;
unsigned long low_limit = 0, high_limit = 0;
bool reach_max_volt = false;
bool reach_high_temp_max_volt = false;
max_count = dev_pm_opp_get_opp_count(dev);
if (max_count <= 0) {
ret = max_count ? max_count : -ENODATA;
goto out;
}
if (max_count <= 0)
return max_count ? max_count : -ENODATA;
info->opp_table = kzalloc(sizeof(*info->opp_table) * max_count,
GFP_KERNEL);
if (!info->opp_table) {
ret = -ENOMEM;
goto out;
if (!info->opp_table)
return -ENOMEM;
opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table) {
kfree(info->opp_table);
return -ENOMEM;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
rcu_read_lock();
#endif
for (i = 0, rate = 0; i < max_count; i++, rate++) {
/* find next rate */
opp = dev_pm_opp_find_freq_ceil(dev, &rate);
if (IS_ERR(opp)) {
ret = PTR_ERR(opp);
kfree(info->opp_table);
goto unlock;
}
mutex_lock(&opp_table->lock);
list_for_each_entry(opp, &opp_table->opp_list, node) {
info->opp_table[i].rate = opp->rate;
info->opp_table[i].volt = opp->u_volt;
info->opp_table[i].max_volt = opp->u_volt_max;
info->opp_table[i].volt = opp->supplies[0].u_volt;
info->opp_table[i].max_volt = opp->supplies[0].u_volt_max;
if (opp->u_volt <= info->high_temp_max_volt) {
if (opp->supplies[0].u_volt <= info->high_temp_max_volt) {
if (!reach_high_temp_max_volt)
info->high_limit = opp->rate;
if (opp->u_volt == info->high_temp_max_volt)
high_limit = opp->rate;
if (opp->supplies[0].u_volt == info->high_temp_max_volt)
reach_high_temp_max_volt = true;
}
if (rockchip_get_low_temp_volt(info, opp->rate, &delta_volt))
delta_volt = 0;
if ((opp->u_volt + delta_volt) <= info->max_volt) {
if ((opp->supplies[0].u_volt + delta_volt) <= info->max_volt) {
info->opp_table[i].low_temp_volt =
opp->u_volt + delta_volt;
opp->supplies[0].u_volt + delta_volt;
if (info->opp_table[i].low_temp_volt <
info->low_temp_min_volt)
info->opp_table[i].low_temp_volt =
info->low_temp_min_volt;
if (!reach_max_volt)
info->low_limit = opp->rate;
low_limit = opp->rate;
if (info->opp_table[i].low_temp_volt == info->max_volt)
reach_max_volt = true;
} else {
info->opp_table[i].low_temp_volt = info->max_volt;
}
if (low_limit && low_limit != opp->rate)
info->low_limit = low_limit;
if (high_limit && high_limit != opp->rate)
info->high_limit = high_limit;
dev_dbg(dev, "rate=%lu, volt=%lu, low_temp_volt=%lu\n",
info->opp_table[i].rate, info->opp_table[i].volt,
info->opp_table[i].low_temp_volt);
i++;
}
if (info->low_limit == opp->rate)
info->low_limit = 0;
if (info->high_limit == opp->rate)
info->high_limit = 0;
unlock:
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
rcu_read_unlock();
#endif
out:
return ret;
mutex_unlock(&opp_table->lock);
dev_pm_opp_put_opp_table(opp_table);
return 0;
}
static int monitor_device_parse_wide_temp_config(struct device_node *np,
@ -771,44 +764,37 @@ static int rockchip_adjust_low_temp_opp_volt(struct monitor_dev_info *info,
bool is_low_temp)
{
struct device *dev = info->dev;
struct opp_table *opp_table;
struct dev_pm_opp *opp;
unsigned long rate;
int i, count, ret = 0;
int i = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
rcu_read_lock();
#endif
count = dev_pm_opp_get_opp_count(dev);
if (count <= 0) {
ret = count ? count : -ENODATA;
goto out;
}
opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table)
return -ENOMEM;
for (i = 0, rate = 0; i < count; i++, rate++) {
/* find next rate */
opp = dev_pm_opp_find_freq_ceil(dev, &rate);
if (IS_ERR(opp)) {
ret = PTR_ERR(opp);
goto out;
}
mutex_lock(&opp_table->lock);
list_for_each_entry(opp, &opp_table->opp_list, node) {
if (is_low_temp) {
if (opp->u_volt_max < info->opp_table[i].low_temp_volt)
opp->u_volt_max =
if (opp->supplies[0].u_volt_max <
info->opp_table[i].low_temp_volt)
opp->supplies[0].u_volt_max =
info->opp_table[i].low_temp_volt;
opp->u_volt = info->opp_table[i].low_temp_volt;
opp->u_volt_min = opp->u_volt;
opp->supplies[0].u_volt =
info->opp_table[i].low_temp_volt;
opp->supplies[0].u_volt_min = opp->supplies[0].u_volt;
} else {
opp->u_volt_min = info->opp_table[i].volt;
opp->u_volt = opp->u_volt_min;
opp->u_volt_max = info->opp_table[i].max_volt;
opp->supplies[0].u_volt_min = info->opp_table[i].volt;
opp->supplies[0].u_volt = opp->supplies[0].u_volt_min;
opp->supplies[0].u_volt_max =
info->opp_table[i].max_volt;
}
i++;
}
mutex_unlock(&opp_table->lock);
out:
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
rcu_read_unlock();
#endif
return ret;
dev_pm_opp_put_opp_table(opp_table);
return 0;
}
static void rockchip_low_temp_adjust(struct monitor_dev_info *info,
@ -841,8 +827,19 @@ static void rockchip_high_temp_adjust(struct monitor_dev_info *info,
info->is_high_temp = is_high;
}
int rockchip_monitor_suspend_low_temp_adjust(struct monitor_dev_info *info)
int rockchip_monitor_suspend_low_temp_adjust(int cpu)
{
struct monitor_dev_info *info = NULL, *tmp;
list_for_each_entry(tmp, &monitor_dev_list, node) {
if (tmp->devp->type != MONITOR_TPYE_CPU)
continue;
if (cpumask_test_cpu(cpu, &tmp->devp->allowed_cpus)) {
info = tmp;
break;
}
}
if (!info || !info->is_low_temp_enabled)
return 0;
@ -921,11 +918,15 @@ static int system_monitor_devfreq_notifier_call(struct notifier_block *nb,
static int monitor_set_freq_table(struct device *dev,
struct monitor_dev_info *info)
{
struct opp_table *opp_table;
struct dev_pm_opp *opp;
unsigned long freq, *freq_table;
unsigned int i;
unsigned long *freq_table;
int count;
opp_table = dev_pm_opp_get_opp_table(dev);
if (!opp_table)
return -ENOMEM;
/* Initialize the freq_table from OPP table */
count = dev_pm_opp_get_opp_count(dev);
if (count <= 0)
@ -938,18 +939,16 @@ static int monitor_set_freq_table(struct device *dev,
return -ENOMEM;
}
rcu_read_lock();
for (i = 0, freq = ULONG_MAX; i < info->max_state; i++, freq--) {
opp = dev_pm_opp_find_freq_floor(dev, &freq);
if (IS_ERR(opp)) {
kfree(freq_table);
info->max_state = 0;
rcu_read_unlock();
return PTR_ERR(opp);
mutex_lock(&opp_table->lock);
list_for_each_entry(opp, &opp_table->opp_list, node) {
if (opp->available) {
count--;
freq_table[count] = opp->rate;
}
freq_table[i] = freq;
}
rcu_read_unlock();
mutex_unlock(&opp_table->lock);
dev_pm_opp_put_opp_table(opp_table);
info->freq_table = freq_table;

View File

@ -120,7 +120,7 @@ int rockchip_monitor_dev_low_temp_adjust(struct monitor_dev_info *info,
bool is_low);
int rockchip_monitor_dev_high_temp_adjust(struct monitor_dev_info *info,
bool is_high);
int rockchip_monitor_suspend_low_temp_adjust(struct monitor_dev_info *info);
int rockchip_monitor_suspend_low_temp_adjust(int cpu);
int
rockchip_system_monitor_adjust_cdev_state(struct thermal_cooling_device *cdev,
int temp, unsigned long *state);
@ -163,8 +163,7 @@ rockchip_monitor_dev_high_temp_adjust(struct monitor_dev_info *info,
return 0;
};
static inline int
rockchip_monitor_suspend_low_temp_adjust(struct monitor_dev_info *info)
static inline int rockchip_monitor_suspend_low_temp_adjust(in cpu)
{
return 0;
};