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)