MALI: bifrost: Add rockchip simple-power-model support

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Change-Id: I721c0f247c81b63a1590c9001ad481837f15f15e
This commit is contained in:
Finley Xiao
2021-01-05 09:51:25 +08:00
parent b080e565a9
commit 6fc2a5c028
6 changed files with 131 additions and 34 deletions

View File

@@ -46,6 +46,7 @@
#define dev_pm_opp_find_freq_ceil opp_find_freq_ceil
#define dev_pm_opp_find_freq_floor opp_find_freq_floor
#endif /* Linux >= 3.13 */
#include <soc/rockchip/rockchip_ipa.h>
#include <soc/rockchip/rockchip_opp_select.h>
#include <soc/rockchip/rockchip_system_monitor.h>
@@ -642,8 +643,22 @@ static void kbase_devfreq_work_term(struct kbase_device *kbdev)
#endif
}
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);
}
static struct devfreq_cooling_power kbase_cooling_power = {
.get_static_power = &kbase_devfreq_get_static_power,
};
int kbase_devfreq_init(struct kbase_device *kbdev)
{
struct devfreq_cooling_power *kbase_dcp = &kbase_cooling_power;
struct device_node *np = kbdev->dev->of_node;
struct devfreq_dev_profile *dp;
struct dev_pm_opp *opp;
@@ -735,22 +750,53 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
kbdev->mdev_info = NULL;
}
#ifdef CONFIG_DEVFREQ_THERMAL
err = kbase_ipa_init(kbdev);
if (err) {
dev_err(kbdev->dev, "IPA initialization failed\n");
goto cooling_failed;
}
if (of_find_compatible_node(kbdev->dev->of_node, NULL,
"simple-power-model")) {
of_property_read_u32(kbdev->dev->of_node,
"dynamic-power-coefficient",
(u32 *)&kbase_dcp->dyn_power_coeff);
kbdev->model_data = rockchip_ipa_power_model_init(kbdev->dev,
"gpu_leakage");
if (IS_ERR_OR_NULL(kbdev->model_data)) {
kbdev->model_data = NULL;
dev_err(kbdev->dev, "failed to initialize power model\n");
} else if (kbdev->model_data->dynamic_coefficient) {
kbase_dcp->dyn_power_coeff =
kbdev->model_data->dynamic_coefficient;
}
if (!kbase_dcp->dyn_power_coeff) {
err = -EINVAL;
dev_err(kbdev->dev, "failed to get dynamic-coefficient\n");
goto cooling_failed;
}
kbdev->devfreq_cooling = of_devfreq_cooling_register_power(
kbdev->dev->of_node,
kbdev->devfreq,
&kbase_ipa_power_model_ops);
if (IS_ERR_OR_NULL(kbdev->devfreq_cooling)) {
err = PTR_ERR(kbdev->devfreq_cooling);
dev_err(kbdev->dev,
"Failed to register cooling device (%d)\n",
err);
goto cooling_failed;
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 cooling_failed;
}
} else {
err = kbase_ipa_init(kbdev);
if (err) {
dev_err(kbdev->dev, "IPA initialization failed\n");
goto cooling_failed;
}
kbdev->devfreq_cooling = of_devfreq_cooling_register_power(
kbdev->dev->of_node,
kbdev->devfreq,
&kbase_ipa_power_model_ops);
if (IS_ERR(kbdev->devfreq_cooling)) {
err = PTR_ERR(kbdev->devfreq_cooling);
dev_err(kbdev->dev,
"Failed to register cooling device (%d)\n",
err);
goto cooling_failed;
}
}
#endif
@@ -782,7 +828,9 @@ void kbase_devfreq_term(struct kbase_device *kbdev)
if (kbdev->devfreq_cooling)
devfreq_cooling_unregister(kbdev->devfreq_cooling);
kbase_ipa_term(kbdev);
if (!kbdev->model_data)
kbase_ipa_term(kbdev);
kfree(kbdev->model_data);
#endif
devfreq_unregister_opp_notifier(kbdev->dev, kbdev->devfreq);

View File

@@ -4455,7 +4455,7 @@ int kbase_device_debugfs_init(struct kbase_device *kbdev)
#ifdef CONFIG_MALI_BIFROST_DEVFREQ
#ifdef CONFIG_DEVFREQ_THERMAL
if (kbdev->devfreq)
if (kbdev->devfreq && !kbdev->model_data)
kbase_ipa_debugfs_init(kbdev);
#endif /* CONFIG_DEVFREQ_THERMAL */
#endif /* CONFIG_MALI_BIFROST_DEVFREQ */

View File

@@ -997,6 +997,7 @@ struct kbase_device {
int num_opps;
struct kbasep_pm_metrics last_devfreq_metrics;
struct monitor_dev_info *mdev_info;
struct ipa_power_model_data *model_data;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
struct kbase_devfreq_queue_info devfreq_queue;
#endif

View File

@@ -43,6 +43,7 @@
#define dev_pm_opp_find_freq_floor opp_find_freq_floor
#endif /* Linux >= 3.13 */
#include <soc/rockchip/rockchip_ipa.h>
#include <soc/rockchip/rockchip_opp_select.h>
#include <soc/rockchip/rockchip_system_monitor.h>
@@ -321,6 +322,19 @@ static int kbase_devfreq_init_core_mask_table(struct kbase_device *kbdev)
return 0;
}
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);
}
static struct devfreq_cooling_power kbase_cooling_power = {
.get_static_power = &kbase_devfreq_get_static_power,
};
int kbase_devfreq_init(struct kbase_device *kbdev)
{
struct device_node *np = kbdev->dev->of_node;
@@ -388,22 +402,53 @@ int kbase_devfreq_init(struct kbase_device *kbdev)
kbdev->mdev_info = NULL;
}
#ifdef CONFIG_DEVFREQ_THERMAL
err = kbase_ipa_init(kbdev);
if (err) {
dev_err(kbdev->dev, "IPA initialization failed\n");
goto cooling_failed;
}
if (of_find_compatible_node(kbdev->dev->of_node, NULL,
"simple-power-model")) {
of_property_read_u32(kbdev->dev->of_node,
"dynamic-power-coefficient",
(u32 *)&kbase_dcp->dyn_power_coeff);
kbdev->model_data = rockchip_ipa_power_model_init(kbdev->dev,
"gpu_leakage");
if (IS_ERR_OR_NULL(kbdev->model_data)) {
kbdev->model_data = NULL;
dev_err(kbdev->dev, "failed to initialize power model\n");
} else if (kbdev->model_data->dynamic_coefficient) {
kbase_dcp->dyn_power_coeff =
kbdev->model_data->dynamic_coefficient;
}
if (!kbase_dcp->dyn_power_coeff) {
dev_err(kbdev->dev, "failed to get dynamic-coefficient\n");
err = -EINVAL;
goto cooling_failed;
}
kbdev->devfreq_cooling = of_devfreq_cooling_register_power(
kbdev->dev->of_node,
kbdev->devfreq,
&kbase_ipa_power_model_ops);
if (IS_ERR_OR_NULL(kbdev->devfreq_cooling)) {
err = PTR_ERR(kbdev->devfreq_cooling);
dev_err(kbdev->dev,
"Failed to register cooling device (%d)\n",
err);
goto cooling_failed;
kbdev->devfreq_cooling =
of_devfreq_cooling_register_power(kbdev->dev->of_node,
kbdev->devfreq,
kbase_dcp);
if (IS_ERR(kbdev->devfreq_cooling)) {
dev_err(kbdev->dev, "failed to register cooling device\n");
err = PTR_ERR(kbdev->devfreq_cooling);
goto cooling_failed;
}
} else {
err = kbase_ipa_init(kbdev);
if (err) {
dev_err(kbdev->dev, "IPA initialization failed\n");
goto cooling_failed;
}
kbdev->devfreq_cooling = of_devfreq_cooling_register_power(
kbdev->dev->of_node,
kbdev->devfreq,
&kbase_ipa_power_model_ops);
if (IS_ERR(kbdev->devfreq_cooling)) {
err = PTR_ERR(kbdev->devfreq_cooling);
dev_err(kbdev->dev,
"Failed to register cooling device (%d)\n",
err);
goto cooling_failed;
}
}
#endif
@@ -433,7 +478,9 @@ void kbase_devfreq_term(struct kbase_device *kbdev)
if (kbdev->devfreq_cooling)
devfreq_cooling_unregister(kbdev->devfreq_cooling);
kbase_ipa_term(kbdev);
if (!kbdev->model_data)
kbase_ipa_term(kbdev);
kfree(kbdev->model_data);
#endif
devfreq_unregister_opp_notifier(kbdev->dev, kbdev->devfreq);

View File

@@ -4135,7 +4135,7 @@ static int kbase_device_debugfs_init(struct kbase_device *kbdev)
#ifdef CONFIG_MALI_BIFROST_DEVFREQ
#ifdef CONFIG_DEVFREQ_THERMAL
if (kbdev->inited_subsys & inited_devfreq)
if ((kbdev->inited_subsys & inited_devfreq) && !kbdev->model_data)
kbase_ipa_debugfs_init(kbdev);
#endif /* CONFIG_DEVFREQ_THERMAL */
#endif /* CONFIG_MALI_BIFROST_DEVFREQ */

View File

@@ -1127,6 +1127,7 @@ struct kbase_device {
struct kbase_devfreq_opp *opp_table;
int num_opps;
struct monitor_dev_info *mdev_info;
struct ipa_power_model_data *model_data;
#ifdef CONFIG_DEVFREQ_THERMAL
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
struct devfreq_cooling_device *devfreq_cooling;