From eb26be047e7625624333002d6564938f7cbba9f5 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Thu, 17 Feb 2022 12:28:47 +0800 Subject: [PATCH] MALI: bifrost: Set intermediate rate before change read margin Improve stability when change read margin. Signed-off-by: Finley Xiao Change-Id: I0ddb1d00c670cbc8e4c64f999382f1420a86c537 --- .../bifrost/backend/gpu/mali_kbase_devfreq.c | 48 ++++++++----------- .../platform/rk/mali_kbase_config_rk.c | 6 +-- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c b/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c index 7d315fbaaf27..ab1b2fb1d8e8 100644 --- a/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c +++ b/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c @@ -127,19 +127,6 @@ void kbase_devfreq_opp_translate(struct kbase_device *kbdev, unsigned long freq, } } -static int kbase_devfreq_set_read_margin(struct device *dev, - struct rockchip_opp_info *opp_info, - u32 rm, - bool is_set_rm) -{ - if (opp_info->data && opp_info->data->set_read_margin) { - if (is_set_rm) - opp_info->data->set_read_margin(dev, opp_info, rm); - } - - return 0; -} - int kbase_devfreq_opp_helper(struct dev_pm_set_opp_data *data) { struct device *dev = data->dev; @@ -173,8 +160,12 @@ int kbase_devfreq_opp_helper(struct dev_pm_set_opp_data *data) rockchip_get_read_margin(dev, opp_info, new_supply_vdd->u_volt, &target_rm); + /* Change frequency */ + dev_dbg(dev, "switching OPP: %lu Hz --> %lu Hz\n", old_freq, new_freq); /* Scaling up? Scale voltage before frequency */ if (new_freq >= old_freq) { + rockchip_set_intermediate_rate(dev, opp_info, clk, old_freq, + new_freq, true, is_set_clk); ret = regulator_set_voltage(mem_reg, new_supply_mem->u_volt, INT_MAX); if (ret) { @@ -189,21 +180,20 @@ int kbase_devfreq_opp_helper(struct dev_pm_set_opp_data *data) new_supply_vdd->u_volt); goto restore_voltage; } - kbase_devfreq_set_read_margin(dev, opp_info, target_rm, - is_set_rm); - } - - /* Change frequency */ - dev_dbg(dev, "switching OPP: %lu Hz --> %lu Hz\n", old_freq, new_freq); - if (is_set_clk && clk_set_rate(clk, new_freq)) { - dev_err(dev, "failed to set clk rate: %d\n", ret); - goto restore_rm; - } - + rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm); + if (is_set_clk && clk_set_rate(clk, new_freq)) { + dev_err(dev, "failed to set clk rate: %d\n", ret); + goto restore_rm; + } /* Scaling down? Scale voltage after frequency */ - if (new_freq < old_freq) { - kbase_devfreq_set_read_margin(dev, opp_info, target_rm, - is_set_rm); + } else { + rockchip_set_intermediate_rate(dev, opp_info, clk, old_freq, + new_freq, false, is_set_clk); + rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm); + if (is_set_clk && clk_set_rate(clk, new_freq)) { + dev_err(dev, "failed to set clk rate: %d\n", ret); + goto restore_rm; + } ret = regulator_set_voltage(vdd_reg, new_supply_vdd->u_volt, INT_MAX); if (ret) { @@ -230,7 +220,7 @@ restore_freq: restore_rm: rockchip_get_read_margin(dev, opp_info, old_supply_vdd->u_volt, &target_rm); - kbase_devfreq_set_read_margin(dev, opp_info, target_rm, is_set_rm); + rockchip_set_read_margin(dev, opp_info, opp_info->target_rm, is_set_rm); restore_voltage: regulator_set_voltage(mem_reg, old_supply_mem->u_volt, INT_MAX); regulator_set_voltage(vdd_reg, old_supply_vdd->u_volt, INT_MAX); @@ -254,6 +244,8 @@ kbase_devfreq_target(struct device *dev, unsigned long *freq, u32 flags) return PTR_ERR(opp); dev_pm_opp_put(opp); + if (*freq == kbdev->current_nominal_freq) + return 0; rockchip_monitor_volt_adjust_lock(kbdev->mdev_info); ret = dev_pm_opp_set_rate(dev, *freq); if (!ret) { diff --git a/drivers/gpu/arm/bifrost/platform/rk/mali_kbase_config_rk.c b/drivers/gpu/arm/bifrost/platform/rk/mali_kbase_config_rk.c index 13ddea1873d4..53c5a86d016e 100755 --- a/drivers/gpu/arm/bifrost/platform/rk/mali_kbase_config_rk.c +++ b/drivers/gpu/arm/bifrost/platform/rk/mali_kbase_config_rk.c @@ -202,14 +202,14 @@ static int rk_pm_callback_runtime_on(struct kbase_device *kbdev) dev_err(kbdev->dev, "failed to enable opp clks\n"); return ret; } + if (opp_info->data && opp_info->data->set_read_margin) + opp_info->data->set_read_margin(kbdev->dev, opp_info, + opp_info->target_rm); if (opp_info->scmi_clk) { if (clk_set_rate(opp_info->scmi_clk, kbdev->current_nominal_freq)) dev_err(kbdev->dev, "failed to restore clk rate\n"); } - if (opp_info->data && opp_info->data->set_read_margin) - opp_info->data->set_read_margin(kbdev->dev, opp_info, - opp_info->target_rm); clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks); return 0;