mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 14:42:37 +02:00
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:
parent
a7bddb708d
commit
b99f359494
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user