mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 14:42:37 +02:00
soc: rockchip_system_monitor: Set intermediate rate before change read margin
Improve stability when change read margin. Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com> Change-Id: If283af8895eead5ec8f86cf7f03eca28fc1d2a45
This commit is contained in:
parent
1f40ab6977
commit
816f5aea02
|
|
@ -842,7 +842,7 @@ static void rockchip_low_temp_adjust(struct monitor_dev_info *info,
|
|||
info->is_low_temp = is_low;
|
||||
|
||||
if (devp->update_volt)
|
||||
devp->update_volt(info, false);
|
||||
devp->update_volt(info);
|
||||
}
|
||||
|
||||
static void rockchip_high_temp_adjust(struct monitor_dev_info *info,
|
||||
|
|
@ -1090,21 +1090,32 @@ void rockchip_monitor_volt_adjust_unlock(struct monitor_dev_info *info)
|
|||
}
|
||||
EXPORT_SYMBOL(rockchip_monitor_volt_adjust_unlock);
|
||||
|
||||
static int rockchip_monitor_set_read_margin(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info,
|
||||
u32 rm)
|
||||
static int rockchip_monitor_enable_opp_clk(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (opp_info && opp_info->data && opp_info->data->set_read_margin) {
|
||||
if (pm_runtime_active(dev))
|
||||
opp_info->data->set_read_margin(dev, opp_info, rm);
|
||||
if (!opp_info)
|
||||
return 0;
|
||||
|
||||
ret = clk_bulk_prepare_enable(opp_info->num_clks, opp_info->clks);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable opp clks\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rockchip_monitor_check_rate_volt(struct monitor_dev_info *info,
|
||||
bool is_set_clk)
|
||||
static void rockchip_monitor_disable_opp_clk(struct device *dev,
|
||||
struct rockchip_opp_info *opp_info)
|
||||
{
|
||||
if (!opp_info)
|
||||
return;
|
||||
|
||||
clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
|
||||
}
|
||||
int rockchip_monitor_check_rate_volt(struct monitor_dev_info *info)
|
||||
{
|
||||
struct device *dev = info->dev;
|
||||
struct regulator *vdd_reg = NULL;
|
||||
|
|
@ -1114,20 +1125,14 @@ int rockchip_monitor_check_rate_volt(struct monitor_dev_info *info,
|
|||
unsigned long old_rate, new_rate, new_volt, new_mem_volt;
|
||||
int old_volt, old_mem_volt;
|
||||
u32 target_rm = UINT_MAX;
|
||||
bool is_set_clk = true;
|
||||
bool is_set_rm = false;
|
||||
int ret = 0;
|
||||
|
||||
if (!info->regulators || !info->clk)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&info->volt_adjust_mutex);
|
||||
if (opp_info) {
|
||||
ret = clk_bulk_prepare_enable(opp_info->num_clks,
|
||||
opp_info->clks);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable opp clks\n");
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
vdd_reg = info->regulators[0];
|
||||
old_rate = clk_get_rate(info->clk);
|
||||
|
|
@ -1168,10 +1173,24 @@ int rockchip_monitor_check_rate_volt(struct monitor_dev_info *info,
|
|||
if (!new_volt || (info->regulator_count > 1 && !new_mem_volt))
|
||||
goto unlock;
|
||||
|
||||
if (opp_info && opp_info->data && opp_info->data->set_read_margin) {
|
||||
is_set_rm = true;
|
||||
if (info->devp->type == MONITOR_TPYE_DEV) {
|
||||
if (!pm_runtime_active(dev)) {
|
||||
is_set_rm = false;
|
||||
if (opp_info->scmi_clk)
|
||||
is_set_clk = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
rockchip_monitor_enable_opp_clk(dev, opp_info);
|
||||
rockchip_get_read_margin(dev, opp_info, new_volt, &target_rm);
|
||||
|
||||
dev_dbg(dev, "%s: %lu Hz --> %lu Hz\n", __func__, old_rate, new_rate);
|
||||
if (new_rate >= old_rate) {
|
||||
rockchip_set_intermediate_rate(dev, opp_info, info->clk,
|
||||
old_rate, new_rate,
|
||||
true, is_set_clk);
|
||||
if (info->regulator_count > 1) {
|
||||
ret = regulator_set_voltage(mem_reg, new_mem_volt,
|
||||
INT_MAX);
|
||||
|
|
@ -1187,19 +1206,22 @@ int rockchip_monitor_check_rate_volt(struct monitor_dev_info *info,
|
|||
__func__, new_volt);
|
||||
goto restore_voltage;
|
||||
}
|
||||
rockchip_monitor_set_read_margin(dev, opp_info, target_rm);
|
||||
if (new_rate == old_rate)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (is_set_clk && clk_set_rate(info->clk, new_rate)) {
|
||||
dev_err(dev, "%s: failed to set clock rate: %lu\n",
|
||||
__func__, new_rate);
|
||||
goto restore_rm;
|
||||
}
|
||||
|
||||
if (new_rate < old_rate) {
|
||||
rockchip_monitor_set_read_margin(dev, opp_info, target_rm);
|
||||
rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm);
|
||||
if (is_set_clk && clk_set_rate(info->clk, new_rate)) {
|
||||
dev_err(dev, "%s: failed to set clock rate: %lu\n",
|
||||
__func__, new_rate);
|
||||
goto restore_rm;
|
||||
}
|
||||
} else {
|
||||
rockchip_set_intermediate_rate(dev, opp_info, info->clk,
|
||||
old_rate, new_rate,
|
||||
false, is_set_clk);
|
||||
rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm);
|
||||
if (is_set_clk && clk_set_rate(info->clk, new_rate)) {
|
||||
dev_err(dev, "%s: failed to set clock rate: %lu\n",
|
||||
__func__, new_rate);
|
||||
goto restore_rm;
|
||||
}
|
||||
ret = regulator_set_voltage(vdd_reg, new_volt,
|
||||
INT_MAX);
|
||||
if (ret) {
|
||||
|
|
@ -1225,14 +1247,13 @@ int rockchip_monitor_check_rate_volt(struct monitor_dev_info *info,
|
|||
__func__, old_rate);
|
||||
restore_rm:
|
||||
rockchip_get_read_margin(dev, opp_info, old_volt, &target_rm);
|
||||
rockchip_monitor_set_read_margin(dev, opp_info, target_rm);
|
||||
rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm);
|
||||
restore_voltage:
|
||||
if (info->regulator_count > 1)
|
||||
regulator_set_voltage(mem_reg, old_mem_volt, INT_MAX);
|
||||
regulator_set_voltage(vdd_reg, old_volt, INT_MAX);
|
||||
disable_clk:
|
||||
if (opp_info)
|
||||
clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
|
||||
rockchip_monitor_disable_opp_clk(dev, opp_info);
|
||||
unlock:
|
||||
mutex_unlock(&info->volt_adjust_mutex);
|
||||
|
||||
|
|
@ -1259,14 +1280,14 @@ rockchip_system_monitor_register(struct device *dev,
|
|||
|
||||
rockchip_system_monitor_parse_supplies(dev, info);
|
||||
if (monitor_device_parse_dt(dev, info)) {
|
||||
rockchip_monitor_check_rate_volt(info, true);
|
||||
rockchip_monitor_check_rate_volt(info);
|
||||
kfree(info);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
rockchip_system_monitor_early_regulator_init(info);
|
||||
rockchip_system_monitor_wide_temp_init(info);
|
||||
rockchip_monitor_check_rate_volt(info, true);
|
||||
rockchip_monitor_check_rate_volt(info);
|
||||
devp->is_checked = true;
|
||||
rockchip_system_monitor_freq_qos_requset(info);
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ struct monitor_dev_profile {
|
|||
bool is_checked;
|
||||
int (*low_temp_adjust)(struct monitor_dev_info *info, bool is_low);
|
||||
int (*high_temp_adjust)(struct monitor_dev_info *info, bool is_low);
|
||||
int (*update_volt)(struct monitor_dev_info *info, bool is_set_clk);
|
||||
int (*update_volt)(struct monitor_dev_info *info);
|
||||
struct cpumask allowed_cpus;
|
||||
struct rockchip_opp_info *opp_info;
|
||||
};
|
||||
|
|
@ -133,8 +133,7 @@ int rockchip_monitor_cpu_high_temp_adjust(struct monitor_dev_info *info,
|
|||
bool is_high);
|
||||
void rockchip_monitor_volt_adjust_lock(struct monitor_dev_info *info);
|
||||
void rockchip_monitor_volt_adjust_unlock(struct monitor_dev_info *info);
|
||||
int rockchip_monitor_check_rate_volt(struct monitor_dev_info *info,
|
||||
bool is_set_clk);
|
||||
int rockchip_monitor_check_rate_volt(struct monitor_dev_info *info);
|
||||
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,
|
||||
|
|
@ -177,7 +176,7 @@ rockchip_monitor_volt_adjust_unlock(struct monitor_dev_info *info)
|
|||
}
|
||||
|
||||
static inline int
|
||||
rockchip_monitor_check_rate_volt(struct monitor_dev_info *info, bool is_set_clk)
|
||||
rockchip_monitor_check_rate_volt(struct monitor_dev_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user