summaryrefslogtreecommitdiff
path: root/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c')
-rwxr-xr-x[-rw-r--r--]drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c236
1 files changed, 43 insertions, 193 deletions
diff --git a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c
index bcf7971a5fdb..9514daf42a8a 100644..100755
--- a/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c
+++ b/drivers/gpu/arm/midgard/platform/rk/mali_kbase_config_rk.c
@@ -14,12 +14,9 @@
#include <mali_kbase.h>
#include <mali_kbase_defs.h>
#include <mali_kbase_config.h>
-#include <backend/gpu/mali_kbase_pm_internal.h>
#include <linux/pm_runtime.h>
#include <linux/suspend.h>
-#include <linux/of.h>
-#include <linux/delay.h>
#include "mali_kbase_rk.h"
@@ -42,54 +39,18 @@
/*---------------------------------------------------------------------------*/
-#ifdef CONFIG_REGULATOR
static int rk_pm_enable_regulator(struct kbase_device *kbdev);
+
static void rk_pm_disable_regulator(struct kbase_device *kbdev);
-#else
-static inline int rk_pm_enable_regulator(struct kbase_device *kbdev)
-{
- return 0;
-}
-static inline void rk_pm_disable_regulator(struct kbase_device *kbdev)
-{
-}
-#endif
static int rk_pm_enable_clk(struct kbase_device *kbdev);
static void rk_pm_disable_clk(struct kbase_device *kbdev);
-static int kbase_platform_rk_create_sysfs_files(struct device *dev);
-
-static void kbase_platform_rk_remove_sysfs_files(struct device *dev);
-
/*---------------------------------------------------------------------------*/
-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;
-
- if (!platform->is_powered) {
- D("mali_dev is already powered off.");
- return;
- }
-
- if (pm_runtime_enabled(kbdev->dev)) {
- D("to put_sync_suspend mali_dev.");
- pm_runtime_put_sync_suspend(kbdev->dev);
- }
-
- rk_pm_disable_regulator(kbdev);
-
- platform->is_powered = false;
- KBASE_TIMELINE_GPU_POWER(kbdev, 0);
-}
-
static int kbase_platform_rk_init(struct kbase_device *kbdev)
{
- int ret = 0;
struct rk_context *platform;
platform = kzalloc(sizeof(*platform), GFP_KERNEL);
@@ -99,49 +60,14 @@ static int kbase_platform_rk_init(struct kbase_device *kbdev)
}
platform->is_powered = false;
- platform->kbdev = kbdev;
-
- platform->delay_ms = 200;
- if (of_property_read_u32(kbdev->dev->of_node, "power-off-delay-ms",
- &platform->delay_ms))
- W("power-off-delay-ms not available.");
-
- platform->power_off_wq = create_freezable_workqueue("gpu_power_off_wq");
- if (!platform->power_off_wq) {
- E("couldn't create workqueue");
- return -ENOMEM;
- }
- INIT_DEFERRABLE_WORK(&platform->work, rk_pm_power_off_delay_work);
- platform->utilisation_period = DEFAULT_UTILISATION_PERIOD_IN_MS;
-
- ret = kbase_platform_rk_create_sysfs_files(kbdev->dev);
- if (ret) {
- E("fail to create sysfs_files. ret = %d.", ret);
- goto EXIT;
- }
kbdev->platform_context = (void *)platform;
- pm_runtime_enable(kbdev->dev);
-EXIT:
- return ret;
+ return 0;
}
static void kbase_platform_rk_term(struct kbase_device *kbdev)
{
- struct rk_context *platform =
- (struct rk_context *)kbdev->platform_context;
-
- pm_runtime_disable(kbdev->dev);
- kbdev->platform_context = NULL;
-
- if (platform) {
- destroy_workqueue(platform->power_off_wq);
- platform->is_powered = false;
- platform->kbdev = NULL;
- kfree(platform);
- }
- kbase_platform_rk_remove_sysfs_files(kbdev->dev);
}
struct kbase_platform_funcs_conf platform_funcs = {
@@ -164,21 +90,16 @@ 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);
-
- cancel_delayed_work_sync(&platform->work);
-
- err = rk_pm_enable_clk(kbdev);
- if (err) {
- E("failed to enable clk: %d", err);
- return err;
- }
+ struct rk_context *platform;
+ platform = (struct rk_context *)kbdev->platform_context;
if (platform->is_powered) {
- D("mali_device is already powered.");
+ W("mali_device is already powered.");
return 0;
}
+ D("powering on.");
+
/* we must enable vdd_gpu before pd_gpu_in_chip. */
err = rk_pm_enable_regulator(kbdev);
if (err) {
@@ -202,6 +123,12 @@ static int rk_pm_callback_power_on(struct kbase_device *kbdev)
}
}
+ err = rk_pm_enable_clk(kbdev); /* clk is not relative to pd. */
+ if (err) {
+ E("failed to enable clk: %d", err);
+ return err;
+ }
+
platform->is_powered = true;
KBASE_TIMELINE_GPU_POWER(kbdev, 1);
@@ -210,20 +137,47 @@ static int rk_pm_callback_power_on(struct kbase_device *kbdev)
static void rk_pm_callback_power_off(struct kbase_device *kbdev)
{
- struct rk_context *platform = get_rk_context(kbdev);
+ struct rk_context *platform =
+ (struct rk_context *)kbdev->platform_context;
+
+ if (!platform->is_powered) {
+ W("mali_dev is already powered off.");
+ return;
+ }
+
+ D("powering off.");
+
+ platform->is_powered = false;
+ KBASE_TIMELINE_GPU_POWER(kbdev, 0);
rk_pm_disable_clk(kbdev);
- queue_delayed_work(platform->power_off_wq, &platform->work,
- msecs_to_jiffies(platform->delay_ms));
+
+ if (pm_runtime_enabled(kbdev->dev)) {
+ pm_runtime_mark_last_busy(kbdev->dev);
+ D("to put_sync_suspend mali_dev.");
+ pm_runtime_put_sync_suspend(kbdev->dev);
+ }
+
+ rk_pm_disable_regulator(kbdev);
}
int rk_kbase_device_runtime_init(struct kbase_device *kbdev)
{
+ pm_runtime_set_autosuspend_delay(kbdev->dev, 200);
+ pm_runtime_use_autosuspend(kbdev->dev);
+
+ /* no need to call pm_runtime_set_active here. */
+
+ D("to enable pm_runtime.");
+ pm_runtime_enable(kbdev->dev);
+
return 0;
}
void rk_kbase_device_runtime_disable(struct kbase_device *kbdev)
{
+ D("to disable pm_runtime.");
+ pm_runtime_disable(kbdev->dev);
}
struct kbase_pm_callback_conf pm_callbacks = {
@@ -250,15 +204,6 @@ int kbase_platform_early_init(void)
/*---------------------------------------------------------------------------*/
-void kbase_platform_rk_shutdown(struct kbase_device *kbdev)
-{
- I("to make vdd_gpu enabled for turning off pd_gpu in pm_framework.");
- rk_pm_enable_regulator(kbdev);
-}
-
-/*---------------------------------------------------------------------------*/
-
-#ifdef CONFIG_REGULATOR
static int rk_pm_enable_regulator(struct kbase_device *kbdev)
{
int ret = 0;
@@ -289,7 +234,6 @@ static void rk_pm_disable_regulator(struct kbase_device *kbdev)
D("to disable regulator.");
regulator_disable(kbdev->regulator);
}
-#endif
static int rk_pm_enable_clk(struct kbase_device *kbdev)
{
@@ -317,97 +261,3 @@ static void rk_pm_disable_clk(struct kbase_device *kbdev)
}
}
-/*---------------------------------------------------------------------------*/
-
-static ssize_t utilisation_period_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct kbase_device *kbdev = dev_get_drvdata(dev);
- struct rk_context *platform = get_rk_context(kbdev);
- ssize_t ret = 0;
-
- ret += snprintf(buf, PAGE_SIZE, "%u\n", platform->utilisation_period);
-
- return ret;
-}
-
-static ssize_t utilisation_period_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t count)
-{
- struct kbase_device *kbdev = dev_get_drvdata(dev);
- struct rk_context *platform = get_rk_context(kbdev);
- int ret = 0;
-
- ret = kstrtouint(buf, 0, &platform->utilisation_period);
- if (ret) {
- E("invalid input period : %s.", buf);
- return ret;
- }
- D("set utilisation_period to '%d'.", platform->utilisation_period);
-
- return count;
-}
-
-static ssize_t utilisation_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct kbase_device *kbdev = dev_get_drvdata(dev);
- struct rk_context *platform = get_rk_context(kbdev);
- ssize_t ret = 0;
- unsigned long period_in_us = platform->utilisation_period * 1000;
- unsigned long total_time;
- unsigned long busy_time;
- unsigned long utilisation;
-
- kbase_pm_reset_dvfs_utilisation(kbdev);
- usleep_range(period_in_us, period_in_us + 100);
- kbase_pm_get_dvfs_utilisation(kbdev, &total_time, &busy_time);
- /* 'devfreq_dev_profile' instance registered to devfreq
- * also uses kbase_pm_reset_dvfs_utilisation
- * and kbase_pm_get_dvfs_utilisation.
- * it's better to cat this file when DVFS is disabled.
- */
- D("total_time : %lu, busy_time : %lu.", total_time, busy_time);
-
- utilisation = busy_time * 100 / total_time;
- ret += snprintf(buf, PAGE_SIZE, "%ld\n", utilisation);
-
- return ret;
-}
-
-static DEVICE_ATTR_RW(utilisation_period);
-static DEVICE_ATTR_RO(utilisation);
-
-static int kbase_platform_rk_create_sysfs_files(struct device *dev)
-{
- int ret = 0;
-
- ret = device_create_file(dev, &dev_attr_utilisation_period);
- if (ret) {
- E("fail to create sysfs file 'utilisation_period'.");
- goto out;
- }
-
- ret = device_create_file(dev, &dev_attr_utilisation);
- if (ret) {
- E("fail to create sysfs file 'utilisation'.");
- goto remove_utilisation_period;
- }
-
- return 0;
-
-remove_utilisation_period:
- device_remove_file(dev, &dev_attr_utilisation_period);
-out:
- return ret;
-}
-
-static void kbase_platform_rk_remove_sysfs_files(struct device *dev)
-{
- device_remove_file(dev, &dev_attr_utilisation_period);
- device_remove_file(dev, &dev_attr_utilisation);
-}