CHROMIUM: MALI: mediatek: Implement power_runtime_on_callback
Prepare clock and enable regulator in power_runtime_on_callback.
Similarly for power_runtime_off_callback.
Previously they are done in power_on_callback. Each GPU transaction will
turn on/off these, which might be slow.
BUG=b:140543845
TEST=test with CL:1801289 and measure dut-power, graphics_GLBench
Change-Id: I81ce35560b16f7d82e2f3f9fcc88c30f74b98942
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1804031
Reviewed-by: Nick Fan <nick.fan@mediatek.corp-partner.google.com>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
diff --git a/drivers/gpu/arm/midgard/platform/mediatek/mali_kbase_runtime_pm.c b/drivers/gpu/arm/midgard/platform/mediatek/mali_kbase_runtime_pm.c
index d5bbe17..6497053 100644
--- a/drivers/gpu/arm/midgard/platform/mediatek/mali_kbase_runtime_pm.c
+++ b/drivers/gpu/arm/midgard/platform/mediatek/mali_kbase_runtime_pm.c
@@ -67,7 +67,7 @@
static int pm_callback_power_on(struct kbase_device *kbdev)
{
- int error, i;
+ int error;
struct mfg_base *mfg = kbdev->platform_context;
if (mfg->is_powered) {
@@ -75,16 +75,6 @@
return 0;
}
- for (i = 0; i < kbdev->regulator_num; i++) {
- error = regulator_enable(kbdev->regulator[i]);
- if (error < 0) {
- dev_err(kbdev->dev,
- "Power on reg %d failed error = %d\n",
- i, error);
- return error;
- }
- }
-
error = pm_runtime_get_sync(kbdev->dev);
if (error < 0) {
dev_err(kbdev->dev,
@@ -106,7 +96,7 @@
return error;
}
- error = clk_prepare_enable(mfg->clk_main_parent);
+ error = clk_enable(mfg->clk_main_parent);
if (error < 0) {
dev_err(kbdev->dev,
"clk_main_parent clock enable failed (err: %d)\n",
@@ -114,14 +104,14 @@
return error;
}
- error = clk_prepare_enable(mfg->clk_mux);
+ error = clk_enable(mfg->clk_mux);
if (error < 0) {
dev_err(kbdev->dev,
"clk_mux clock enable failed (err: %d)\n", error);
return error;
}
- error = clk_prepare_enable(mfg->subsys_mfg_cg);
+ error = clk_enable(mfg->subsys_mfg_cg);
if (error < 0) {
dev_err(kbdev->dev,
"subsys_mfg_cg clock enable failed (err: %d)\n", error);
@@ -136,7 +126,7 @@
static void pm_callback_power_off(struct kbase_device *kbdev)
{
struct mfg_base *mfg = kbdev->platform_context;
- int error, i;
+ int error;
if (!mfg->is_powered) {
dev_dbg(kbdev->dev, "mali_device is already powered off\n");
@@ -145,11 +135,11 @@
mfg->is_powered = false;
- clk_disable_unprepare(mfg->subsys_mfg_cg);
+ clk_disable(mfg->subsys_mfg_cg);
- clk_disable_unprepare(mfg->clk_mux);
+ clk_disable(mfg->clk_mux);
- clk_disable_unprepare(mfg->clk_main_parent);
+ clk_disable(mfg->clk_main_parent);
pm_runtime_mark_last_busy(&mfg->gpu_core2_dev->dev);
error = pm_runtime_put_autosuspend(&mfg->gpu_core2_dev->dev);
@@ -168,15 +158,6 @@
if (error < 0)
dev_err(kbdev->dev,
"Power off core 0 failed (err: %d)\n", error);
-
- for (i = 0; i < kbdev->regulator_num; i++) {
- error = regulator_disable(kbdev->regulator[i]);
- if (error < 0) {
- dev_err(kbdev->dev,
- "Power off reg %d failed error = %d\n",
- i, error);
- }
- }
}
static int kbase_device_runtime_init(struct kbase_device *kbdev)
@@ -193,14 +174,64 @@
static int pm_callback_runtime_on(struct kbase_device *kbdev)
{
- dev_dbg(kbdev->dev, "%s\n", __func__);
+ struct mfg_base *mfg = kbdev->platform_context;
+ int error, i;
+
+ for (i = 0; i < kbdev->regulator_num; i++) {
+ error = regulator_enable(kbdev->regulator[i]);
+ if (error < 0) {
+ dev_err(kbdev->dev,
+ "Power on reg %d failed error = %d\n",
+ i, error);
+ return error;
+ }
+ }
+
+ error = clk_prepare(mfg->clk_main_parent);
+ if (error < 0) {
+ dev_err(kbdev->dev,
+ "clk_main_parent clock prepare failed (err: %d)\n",
+ error);
+ return error;
+ }
+
+ error = clk_prepare(mfg->clk_mux);
+ if (error < 0) {
+ dev_err(kbdev->dev,
+ "clk_mux clock prepare failed (err: %d)\n", error);
+ return error;
+ }
+
+ error = clk_prepare(mfg->subsys_mfg_cg);
+ if (error < 0) {
+ dev_err(kbdev->dev,
+ "subsys_mfg_cg clock prepare failed (err: %d)\n",
+ error);
+ return error;
+ }
return 0;
}
static void pm_callback_runtime_off(struct kbase_device *kbdev)
{
- dev_dbg(kbdev->dev, "%s\n", __func__);
+ struct mfg_base *mfg = kbdev->platform_context;
+ int error, i;
+
+ clk_unprepare(mfg->subsys_mfg_cg);
+
+ clk_unprepare(mfg->clk_mux);
+
+ clk_unprepare(mfg->clk_main_parent);
+
+ for (i = 0; i < kbdev->regulator_num; i++) {
+ error = regulator_disable(kbdev->regulator[i]);
+ if (error < 0) {
+ dev_err(kbdev->dev,
+ "Power off reg %d failed error = %d\n",
+ i, error);
+ }
+ }
}
static void pm_callback_resume(struct kbase_device *kbdev)