mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
MALI: bifrost: Use new APIs for devfreq
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com> Change-Id: Ifd0262cbff997a752f81aa4941763c12bde741cf
This commit is contained in:
@@ -49,7 +49,7 @@ static struct monitor_dev_profile mali_mdevp = {
|
||||
.type = MONITOR_TYPE_DEV,
|
||||
.low_temp_adjust = rockchip_monitor_dev_low_temp_adjust,
|
||||
.high_temp_adjust = rockchip_monitor_dev_high_temp_adjust,
|
||||
.update_volt = rockchip_monitor_check_rate_volt,
|
||||
.check_rate_volt = rockchip_monitor_check_rate_volt,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -127,132 +127,15 @@ void kbase_devfreq_opp_translate(struct kbase_device *kbdev, unsigned long freq,
|
||||
}
|
||||
}
|
||||
|
||||
int kbase_devfreq_opp_helper(struct dev_pm_set_opp_data *data)
|
||||
{
|
||||
struct device *dev = data->dev;
|
||||
struct dev_pm_opp_supply *old_supply_vdd = &data->old_opp.supplies[0];
|
||||
struct dev_pm_opp_supply *new_supply_vdd = &data->new_opp.supplies[0];
|
||||
struct regulator *vdd_reg = data->regulators[0];
|
||||
struct dev_pm_opp_supply *old_supply_mem;
|
||||
struct dev_pm_opp_supply *new_supply_mem;
|
||||
struct regulator *mem_reg;
|
||||
struct clk *clk = data->clk;
|
||||
struct kbase_device *kbdev = dev_get_drvdata(dev);
|
||||
struct rockchip_opp_info *opp_info = &kbdev->opp_info;
|
||||
unsigned long old_freq = data->old_opp.rate;
|
||||
unsigned long new_freq = data->new_opp.rate;
|
||||
unsigned int reg_count = data->regulator_count;
|
||||
bool is_set_rm = true;
|
||||
bool is_set_clk = true;
|
||||
u32 target_rm = UINT_MAX;
|
||||
int ret = 0;
|
||||
|
||||
if (reg_count > 1) {
|
||||
old_supply_mem = &data->old_opp.supplies[1];
|
||||
new_supply_mem = &data->new_opp.supplies[1];
|
||||
mem_reg = data->regulators[1];
|
||||
}
|
||||
|
||||
if (!pm_runtime_active(dev)) {
|
||||
is_set_rm = false;
|
||||
if (opp_info->scmi_clk)
|
||||
is_set_clk = false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
if (reg_count > 1) {
|
||||
ret = regulator_set_voltage(mem_reg,
|
||||
new_supply_mem->u_volt,
|
||||
INT_MAX);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to set volt %lu uV for mem reg\n",
|
||||
new_supply_mem->u_volt);
|
||||
goto restore_voltage;
|
||||
}
|
||||
}
|
||||
ret = regulator_set_voltage(vdd_reg, new_supply_vdd->u_volt,
|
||||
INT_MAX);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to set volt %lu uV for vdd reg\n",
|
||||
new_supply_vdd->u_volt);
|
||||
goto restore_voltage;
|
||||
}
|
||||
rockchip_set_read_margin(dev, opp_info, target_rm, is_set_rm);
|
||||
if (is_set_clk && clk_set_rate(clk, new_freq)) {
|
||||
ret = -EINVAL;
|
||||
dev_err(dev, "failed to set clk rate\n");
|
||||
goto restore_rm;
|
||||
}
|
||||
/* Scaling down? Scale voltage after frequency */
|
||||
} 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)) {
|
||||
ret = -EINVAL;
|
||||
dev_err(dev, "failed to set clk rate\n");
|
||||
goto restore_rm;
|
||||
}
|
||||
ret = regulator_set_voltage(vdd_reg, new_supply_vdd->u_volt,
|
||||
INT_MAX);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to set volt %lu uV for vdd reg\n",
|
||||
new_supply_vdd->u_volt);
|
||||
goto restore_freq;
|
||||
}
|
||||
if (reg_count > 1) {
|
||||
ret = regulator_set_voltage(mem_reg,
|
||||
new_supply_mem->u_volt,
|
||||
INT_MAX);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to set volt %lu uV for mem reg\n",
|
||||
new_supply_mem->u_volt);
|
||||
goto restore_voltage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
|
||||
|
||||
return 0;
|
||||
|
||||
restore_freq:
|
||||
if (is_set_clk && clk_set_rate(clk, old_freq))
|
||||
dev_err(dev, "failed to restore old-freq %lu Hz\n", old_freq);
|
||||
restore_rm:
|
||||
rockchip_get_read_margin(dev, opp_info, old_supply_vdd->u_volt,
|
||||
&target_rm);
|
||||
rockchip_set_read_margin(dev, opp_info, opp_info->target_rm, is_set_rm);
|
||||
restore_voltage:
|
||||
if (reg_count > 1 && old_supply_mem->u_volt)
|
||||
regulator_set_voltage(mem_reg, old_supply_mem->u_volt, INT_MAX);
|
||||
regulator_set_voltage(vdd_reg, old_supply_vdd->u_volt, INT_MAX);
|
||||
clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
kbase_devfreq_target(struct device *dev, unsigned long *freq, u32 flags)
|
||||
{
|
||||
struct kbase_device *kbdev = dev_get_drvdata(dev);
|
||||
struct rockchip_opp_info *opp_info = &kbdev->opp_info;
|
||||
struct dev_pm_opp *opp;
|
||||
int ret = 0;
|
||||
|
||||
if (!mali_mdevp.is_checked)
|
||||
if (!opp_info->is_rate_volt_checked)
|
||||
return -EINVAL;
|
||||
|
||||
opp = devfreq_recommended_opp(dev, freq, flags);
|
||||
@@ -262,13 +145,18 @@ kbase_devfreq_target(struct device *dev, unsigned long *freq, u32 flags)
|
||||
|
||||
if (*freq == kbdev->current_nominal_freq)
|
||||
return 0;
|
||||
rockchip_monitor_volt_adjust_lock(kbdev->mdev_info);
|
||||
|
||||
rockchip_opp_dvfs_lock(opp_info);
|
||||
if (pm_runtime_active(dev))
|
||||
opp_info->is_runtime_active = true;
|
||||
else
|
||||
opp_info->is_runtime_active = false;
|
||||
ret = dev_pm_opp_set_rate(dev, *freq);
|
||||
if (!ret) {
|
||||
kbdev->current_nominal_freq = *freq;
|
||||
KBASE_TLSTREAM_AUX_DEVFREQ_TARGET(kbdev, (u64)*freq);
|
||||
}
|
||||
rockchip_monitor_volt_adjust_unlock(kbdev->mdev_info);
|
||||
rockchip_opp_dvfs_unlock(opp_info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -671,23 +559,13 @@ static void kbase_devfreq_work_term(struct kbase_device *kbdev)
|
||||
destroy_workqueue(workq);
|
||||
}
|
||||
|
||||
static unsigned long kbase_devfreq_get_static_power(struct devfreq *devfreq,
|
||||
unsigned long voltage)
|
||||
{
|
||||
struct device *dev = devfreq->dev.parent;
|
||||
struct kbase_device *kbdev = dev_get_drvdata(dev);
|
||||
|
||||
return rockchip_ipa_get_static_power(kbdev->model_data, voltage);
|
||||
}
|
||||
|
||||
int kbase_devfreq_init(struct kbase_device *kbdev)
|
||||
{
|
||||
struct devfreq_cooling_power *kbase_dcp = &kbdev->dfc_power;
|
||||
struct device_node *np = kbdev->dev->of_node;
|
||||
struct device_node *model_node;
|
||||
struct devfreq_dev_profile *dp;
|
||||
int err;
|
||||
struct dev_pm_opp *opp;
|
||||
unsigned int dyn_power_coeff = 0;
|
||||
unsigned int i;
|
||||
bool free_devfreq_freq_table = true;
|
||||
|
||||
@@ -703,8 +581,6 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
|
||||
else
|
||||
kbdev->current_freqs[i] = 0;
|
||||
}
|
||||
if (strstr(__clk_get_name(kbdev->clocks[0]), "scmi"))
|
||||
kbdev->opp_info.scmi_clk = kbdev->clocks[0];
|
||||
kbdev->current_nominal_freq = kbdev->current_freqs[0];
|
||||
|
||||
opp = devfreq_recommended_opp(kbdev->dev, &kbdev->current_nominal_freq, 0);
|
||||
@@ -729,6 +605,12 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
|
||||
kbdev->gpu_props.props.core_props.gpu_freq_khz_max =
|
||||
dp->freq_table[0] / 1000;
|
||||
};
|
||||
#if IS_ENABLED(CONFIG_DEVFREQ_THERMAL)
|
||||
of_property_read_u32(kbdev->dev->of_node, "dynamic-power-coefficient",
|
||||
&dyn_power_coeff);
|
||||
if (dyn_power_coeff)
|
||||
dp->is_cooling_device = true;
|
||||
#endif
|
||||
err = kbase_devfreq_init_core_mask_table(kbdev);
|
||||
if (err)
|
||||
goto init_core_mask_table_failed;
|
||||
@@ -770,59 +652,21 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
|
||||
|
||||
mali_mdevp.data = kbdev->devfreq;
|
||||
mali_mdevp.opp_info = &kbdev->opp_info;
|
||||
kbdev->mdev_info = rockchip_system_monitor_register(kbdev->dev,
|
||||
&mali_mdevp);
|
||||
kbdev->mdev_info = rockchip_system_monitor_register(kbdev->dev, &mali_mdevp);
|
||||
if (IS_ERR(kbdev->mdev_info)) {
|
||||
dev_dbg(kbdev->dev, "without system monitor\n");
|
||||
kbdev->mdev_info = NULL;
|
||||
mali_mdevp.is_checked = true;
|
||||
}
|
||||
kbdev->opp_info.is_rate_volt_checked = true;
|
||||
#if IS_ENABLED(CONFIG_DEVFREQ_THERMAL)
|
||||
of_property_read_u32(kbdev->dev->of_node, "dynamic-power-coefficient",
|
||||
(u32 *)&kbase_dcp->dyn_power_coeff);
|
||||
model_node = of_get_compatible_child(kbdev->dev->of_node,
|
||||
"simple-power-model");
|
||||
if (model_node) {
|
||||
of_node_put(model_node);
|
||||
kbdev->model_data =
|
||||
rockchip_ipa_power_model_init(kbdev->dev,
|
||||
"gpu_leakage");
|
||||
if (IS_ERR_OR_NULL(kbdev->model_data)) {
|
||||
kbdev->model_data = NULL;
|
||||
if (kbase_dcp->dyn_power_coeff)
|
||||
dev_info(kbdev->dev,
|
||||
"only calculate dynamic power\n");
|
||||
else
|
||||
dev_err(kbdev->dev,
|
||||
"failed to initialize power model\n");
|
||||
} else {
|
||||
kbase_dcp->get_static_power =
|
||||
kbase_devfreq_get_static_power;
|
||||
if (kbdev->model_data->dynamic_coefficient)
|
||||
kbase_dcp->dyn_power_coeff =
|
||||
kbdev->model_data->dynamic_coefficient;
|
||||
}
|
||||
}
|
||||
|
||||
if (kbase_dcp->dyn_power_coeff) {
|
||||
kbdev->devfreq_cooling =
|
||||
of_devfreq_cooling_register_power(kbdev->dev->of_node,
|
||||
kbdev->devfreq,
|
||||
kbase_dcp);
|
||||
if (IS_ERR(kbdev->devfreq_cooling)) {
|
||||
err = PTR_ERR(kbdev->devfreq_cooling);
|
||||
dev_err(kbdev->dev, "failed to register cooling device\n");
|
||||
goto ipa_init_failed;
|
||||
}
|
||||
} else {
|
||||
if (!dp->is_cooling_device) {
|
||||
err = kbase_ipa_init(kbdev);
|
||||
if (err) {
|
||||
dev_err(kbdev->dev, "IPA initialization failed\n");
|
||||
goto ipa_init_failed;
|
||||
}
|
||||
|
||||
kbdev->devfreq_cooling = of_devfreq_cooling_register_power(
|
||||
kbdev->dev->of_node,
|
||||
kbdev->devfreq_cooling = devfreq_cooling_em_register(
|
||||
kbdev->devfreq,
|
||||
&kbase_ipa_power_model_ops);
|
||||
if (IS_ERR(kbdev->devfreq_cooling)) {
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
int kbase_devfreq_init(struct kbase_device *kbdev);
|
||||
|
||||
void kbase_devfreq_term(struct kbase_device *kbdev);
|
||||
int kbase_devfreq_opp_helper(struct dev_pm_set_opp_data *data);
|
||||
|
||||
/**
|
||||
* kbase_devfreq_force_freq - Set GPU frequency on L2 power on/off.
|
||||
|
||||
@@ -168,13 +168,6 @@ static const struct mali_kbase_capability_def kbase_caps_table[MALI_KBASE_NUM_CA
|
||||
static struct mutex kbase_probe_mutex;
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_MALI_BIFROST_DEVFREQ
|
||||
static inline int kbase_devfreq_opp_helper(struct dev_pm_set_opp_data *data)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* mali_kbase_supports_cap - Query whether a kbase capability is supported
|
||||
*
|
||||
@@ -4597,39 +4590,6 @@ int power_control_init(struct kbase_device *kbdev)
|
||||
* from completing its initialization.
|
||||
*/
|
||||
#if defined(CONFIG_PM_OPP)
|
||||
#if defined(CONFIG_REGULATOR)
|
||||
#if (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE)
|
||||
if (kbdev->nr_regulators > 0) {
|
||||
kbdev->token = dev_pm_opp_set_regulators(kbdev->dev, regulator_names);
|
||||
|
||||
if (kbdev->token < 0) {
|
||||
err = kbdev->token;
|
||||
goto regulators_probe_defer;
|
||||
}
|
||||
|
||||
}
|
||||
#elif (KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE)
|
||||
if (kbdev->nr_regulators > 0) {
|
||||
kbdev->opp_table =
|
||||
dev_pm_opp_set_regulators(kbdev->dev, regulator_names,
|
||||
kbdev->nr_regulators);
|
||||
if (IS_ERR(kbdev->opp_table)) {
|
||||
dev_err(kbdev->dev, "Failed to set regulators\n");
|
||||
return 0;
|
||||
}
|
||||
kbdev->opp_table =
|
||||
dev_pm_opp_register_set_opp_helper(kbdev->dev,
|
||||
kbase_devfreq_opp_helper);
|
||||
if (IS_ERR(kbdev->opp_table)) {
|
||||
dev_pm_opp_put_regulators(kbdev->opp_table);
|
||||
kbdev->opp_table = NULL;
|
||||
dev_err(kbdev->dev, "Failed to set opp helper\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE) */
|
||||
#endif /* CONFIG_REGULATOR */
|
||||
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
err = kbase_platform_rk_init_opp_table(kbdev);
|
||||
if (err)
|
||||
@@ -4668,18 +4628,11 @@ void power_control_term(struct kbase_device *kbdev)
|
||||
unsigned int i;
|
||||
|
||||
#if defined(CONFIG_PM_OPP)
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
kbase_platform_rk_uninit_opp_table(kbdev);
|
||||
#else
|
||||
dev_pm_opp_of_remove_table(kbdev->dev);
|
||||
#if defined(CONFIG_REGULATOR)
|
||||
#if (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE)
|
||||
if (kbdev->token > -EPERM) {
|
||||
dev_pm_opp_unregister_set_opp_helper(kbdev->opp_table);
|
||||
dev_pm_opp_put_regulators(kbdev->token);
|
||||
}
|
||||
#elif (KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE)
|
||||
if (!IS_ERR_OR_NULL(kbdev->opp_table))
|
||||
dev_pm_opp_put_regulators(kbdev->opp_table);
|
||||
#endif /* (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE) */
|
||||
#endif /* CONFIG_REGULATOR */
|
||||
#endif
|
||||
#endif /* CONFIG_PM_OPP */
|
||||
|
||||
for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) {
|
||||
@@ -4991,8 +4944,7 @@ static struct dentry *init_debugfs(struct kbase_device *kbdev)
|
||||
|
||||
#ifdef CONFIG_MALI_BIFROST_DEVFREQ
|
||||
#if IS_ENABLED(CONFIG_DEVFREQ_THERMAL)
|
||||
if (kbdev->devfreq && !kbdev->model_data &&
|
||||
!kbdev->dfc_power.dyn_power_coeff)
|
||||
if (kbdev->devfreq && kbdev->devfreq_cooling)
|
||||
kbase_ipa_debugfs_init(kbdev);
|
||||
#endif /* CONFIG_DEVFREQ_THERMAL */
|
||||
#endif /* CONFIG_MALI_BIFROST_DEVFREQ */
|
||||
@@ -5543,10 +5495,6 @@ static int kbase_platform_device_probe(struct platform_device *pdev)
|
||||
|
||||
kbdev->dev = &pdev->dev;
|
||||
|
||||
#if (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE)
|
||||
kbdev->token = -EPERM;
|
||||
#endif /* (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE) */
|
||||
|
||||
dev_set_drvdata(kbdev->dev, kbdev);
|
||||
#if (KERNEL_VERSION(5, 3, 0) <= LINUX_VERSION_CODE)
|
||||
mutex_lock(&kbase_probe_mutex);
|
||||
|
||||
@@ -1072,11 +1072,6 @@ struct kbase_device {
|
||||
#if IS_ENABLED(CONFIG_REGULATOR)
|
||||
struct regulator *regulators[BASE_MAX_NR_CLOCKS_REGULATORS];
|
||||
unsigned int nr_regulators;
|
||||
#if (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE)
|
||||
int token;
|
||||
#elif (KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE)
|
||||
struct opp_table *opp_table;
|
||||
#endif /* (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE) */
|
||||
#endif /* CONFIG_REGULATOR */
|
||||
char devname[DEVNAME_SIZE];
|
||||
u32 id;
|
||||
|
||||
@@ -90,4 +90,5 @@ extern struct kbase_platform_funcs_conf platform_funcs;
|
||||
extern struct kbase_clk_rate_trace_op_conf clk_rate_trace_ops;
|
||||
|
||||
int kbase_platform_rk_init_opp_table(struct kbase_device *kbdev);
|
||||
void kbase_platform_rk_uninit_opp_table(struct kbase_device *kbdev);
|
||||
int kbase_platform_rk_enable_regulator(struct kbase_device *kbdev);
|
||||
|
||||
@@ -94,6 +94,7 @@ static void rk_pm_power_off_delay_work(struct work_struct *work)
|
||||
struct rk_context *platform =
|
||||
container_of(to_delayed_work(work), struct rk_context, work);
|
||||
struct kbase_device *kbdev = platform->kbdev;
|
||||
struct rockchip_opp_info *opp_info = &kbdev->opp_info;
|
||||
|
||||
mutex_lock(&platform->lock);
|
||||
|
||||
@@ -103,12 +104,12 @@ static void rk_pm_power_off_delay_work(struct work_struct *work)
|
||||
return;
|
||||
}
|
||||
|
||||
rockchip_monitor_volt_adjust_lock(kbdev->mdev_info);
|
||||
rockchip_opp_dvfs_lock(opp_info);
|
||||
if (pm_runtime_enabled(kbdev->dev)) {
|
||||
D("to put_sync_suspend mali_dev.");
|
||||
pm_runtime_put_sync_suspend(kbdev->dev);
|
||||
}
|
||||
rockchip_monitor_volt_adjust_unlock(kbdev->mdev_info);
|
||||
rockchip_opp_dvfs_unlock(opp_info);
|
||||
|
||||
rk_pm_disable_clk(kbdev);
|
||||
|
||||
@@ -208,7 +209,7 @@ static int rk_pm_callback_runtime_on(struct kbase_device *kbdev)
|
||||
if (!kbdev->current_nominal_freq)
|
||||
return 0;
|
||||
|
||||
ret = clk_bulk_prepare_enable(opp_info->num_clks, opp_info->clks);
|
||||
ret = clk_bulk_prepare_enable(opp_info->nclocks, opp_info->clocks);
|
||||
if (ret) {
|
||||
dev_err(kbdev->dev, "failed to enable opp clks\n");
|
||||
return ret;
|
||||
@@ -216,12 +217,11 @@ static int rk_pm_callback_runtime_on(struct kbase_device *kbdev)
|
||||
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))
|
||||
if (opp_info->is_scmi_clk) {
|
||||
if (clk_set_rate(opp_info->clk, kbdev->current_nominal_freq))
|
||||
dev_err(kbdev->dev, "failed to restore clk rate\n");
|
||||
}
|
||||
clk_bulk_disable_unprepare(opp_info->num_clks, opp_info->clks);
|
||||
clk_bulk_disable_unprepare(opp_info->nclocks, opp_info->clocks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -230,8 +230,8 @@ static void rk_pm_callback_runtime_off(struct kbase_device *kbdev)
|
||||
{
|
||||
struct rockchip_opp_info *opp_info = &kbdev->opp_info;
|
||||
|
||||
if (opp_info->scmi_clk) {
|
||||
if (clk_set_rate(opp_info->scmi_clk, POWER_DOWN_FREQ))
|
||||
if (opp_info->is_scmi_clk) {
|
||||
if (clk_set_rate(opp_info->clk, POWER_DOWN_FREQ))
|
||||
dev_err(kbdev->dev, "failed to set power down rate\n");
|
||||
}
|
||||
opp_info->current_rm = UINT_MAX;
|
||||
@@ -242,6 +242,7 @@ static int rk_pm_callback_power_on(struct kbase_device *kbdev)
|
||||
int ret = 1; /* Assume GPU has been powered off */
|
||||
int err = 0;
|
||||
struct rk_context *platform = get_rk_context(kbdev);
|
||||
struct rockchip_opp_info *opp_info = &kbdev->opp_info;
|
||||
|
||||
cancel_delayed_work_sync(&platform->work);
|
||||
|
||||
@@ -271,7 +272,7 @@ static int rk_pm_callback_power_on(struct kbase_device *kbdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
rockchip_monitor_volt_adjust_lock(kbdev->mdev_info);
|
||||
rockchip_opp_dvfs_lock(opp_info);
|
||||
/* 若 mali_dev 的 runtime_pm 是 enabled 的, 则... */
|
||||
if (pm_runtime_enabled(kbdev->dev)) {
|
||||
D("to resume mali_dev syncly.");
|
||||
@@ -280,6 +281,7 @@ static int rk_pm_callback_power_on(struct kbase_device *kbdev)
|
||||
*/
|
||||
err = pm_runtime_get_sync(kbdev->dev);
|
||||
if (err < 0) {
|
||||
rockchip_opp_dvfs_unlock(opp_info);
|
||||
E("failed to runtime resume device: %d.", err);
|
||||
ret = err;
|
||||
goto out;
|
||||
@@ -288,7 +290,7 @@ static int rk_pm_callback_power_on(struct kbase_device *kbdev)
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
rockchip_monitor_volt_adjust_unlock(kbdev->mdev_info);
|
||||
rockchip_opp_dvfs_unlock(opp_info);
|
||||
|
||||
platform->is_powered = true;
|
||||
wake_lock(&platform->wake_lock);
|
||||
@@ -547,12 +549,11 @@ static int rk3588_gpu_get_soc_info(struct device *dev, struct device_node *np,
|
||||
}
|
||||
|
||||
static int rk3588_gpu_set_soc_info(struct device *dev, struct device_node *np,
|
||||
int bin, int process, int volt_sel)
|
||||
struct rockchip_opp_info *opp_info)
|
||||
{
|
||||
struct opp_table *opp_table;
|
||||
u32 supported_hw[2];
|
||||
int bin = opp_info->bin;
|
||||
|
||||
if (volt_sel < 0)
|
||||
if (opp_info->volt_sel < 0)
|
||||
return 0;
|
||||
if (bin < 0)
|
||||
bin = 0;
|
||||
@@ -561,14 +562,9 @@ static int rk3588_gpu_set_soc_info(struct device *dev, struct device_node *np,
|
||||
return 0;
|
||||
|
||||
/* SoC Version */
|
||||
supported_hw[0] = BIT(bin);
|
||||
opp_info->supported_hw[0] = BIT(bin);
|
||||
/* Speed Grade */
|
||||
supported_hw[1] = BIT(volt_sel);
|
||||
opp_table = dev_pm_opp_set_supported_hw(dev, supported_hw, 2);
|
||||
if (IS_ERR(opp_table)) {
|
||||
dev_err(dev, "failed to set supported opp\n");
|
||||
return PTR_ERR(opp_table);
|
||||
}
|
||||
opp_info->supported_hw[1] = BIT(opp_info->volt_sel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -608,10 +604,38 @@ static int rk3588_gpu_set_read_margin(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpu_opp_config_regulators(struct device *dev,
|
||||
struct dev_pm_opp *old_opp,
|
||||
struct dev_pm_opp *new_opp,
|
||||
struct regulator **regulators,
|
||||
unsigned int count)
|
||||
{
|
||||
struct kbase_device *kbdev = dev_get_drvdata(dev);
|
||||
|
||||
return rockchip_opp_config_regulators(dev, old_opp, new_opp, regulators,
|
||||
count, &kbdev->opp_info);
|
||||
}
|
||||
|
||||
static int gpu_opp_config_clks(struct device *dev, struct opp_table *opp_table,
|
||||
struct dev_pm_opp *opp, void *data,
|
||||
bool scaling_down)
|
||||
{
|
||||
struct kbase_device *kbdev = dev_get_drvdata(dev);
|
||||
|
||||
return rockchip_opp_config_clks(dev, opp_table, opp, data, scaling_down,
|
||||
&kbdev->opp_info);
|
||||
}
|
||||
|
||||
static const struct rockchip_opp_data rk3588_gpu_opp_data = {
|
||||
.get_soc_info = rk3588_gpu_get_soc_info,
|
||||
.set_soc_info = rk3588_gpu_set_soc_info,
|
||||
.set_read_margin = rk3588_gpu_set_read_margin,
|
||||
.config_regulators = gpu_opp_config_regulators,
|
||||
.config_clks = gpu_opp_config_clks,
|
||||
};
|
||||
|
||||
static const struct rockchip_opp_data rockchip_gpu_opp_data = {
|
||||
.config_clks = gpu_opp_config_clks,
|
||||
};
|
||||
|
||||
static const struct of_device_id rockchip_mali_of_match[] = {
|
||||
@@ -624,10 +648,18 @@ static const struct of_device_id rockchip_mali_of_match[] = {
|
||||
|
||||
int kbase_platform_rk_init_opp_table(struct kbase_device *kbdev)
|
||||
{
|
||||
struct rockchip_opp_info *info = &kbdev->opp_info;
|
||||
|
||||
info->data = &rockchip_gpu_opp_data;
|
||||
rockchip_get_opp_data(rockchip_mali_of_match, &kbdev->opp_info);
|
||||
|
||||
return rockchip_init_opp_table(kbdev->dev, &kbdev->opp_info,
|
||||
"gpu_leakage", "mali");
|
||||
"clk_mali", "mali");
|
||||
}
|
||||
|
||||
void kbase_platform_rk_uninit_opp_table(struct kbase_device *kbdev)
|
||||
{
|
||||
rockchip_uninit_opp_table(kbdev->dev, &kbdev->opp_info);
|
||||
}
|
||||
|
||||
int kbase_platform_rk_enable_regulator(struct kbase_device *kbdev)
|
||||
|
||||
Reference in New Issue
Block a user