From e3e12f52b214121840b44c91de5b3e5af5d3eb84 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 06 Nov 2023 03:04:41 +0000
Subject: [PATCH] rk3568 rt init

---
 kernel/drivers/gpu/arm/mali400/mali/platform/rk/rk.c |  206 +++++++++++++++++++++++++++++++++------------------
 1 files changed, 134 insertions(+), 72 deletions(-)

diff --git a/kernel/drivers/gpu/arm/mali400/mali/platform/rk/rk.c b/kernel/drivers/gpu/arm/mali400/mali/platform/rk/rk.c
index 9a012fd..4c6e7f9 100644
--- a/kernel/drivers/gpu/arm/mali400/mali/platform/rk/rk.c
+++ b/kernel/drivers/gpu/arm/mali400/mali/platform/rk/rk.c
@@ -34,7 +34,10 @@
 #include <linux/dma-mapping.h>
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
 #include <linux/rockchip/cpu.h>
+#include <soc/rockchip/rockchip_ipa.h>
 #include <soc/rockchip/rockchip_opp_select.h>
 
 #include <linux/mali/mali_utgard.h>
@@ -47,6 +50,7 @@
 
 /*---------------------------------------------------------------------------*/
 
+#define RK3528_GPU_SD_SLP_HAST	0x10024
 #define DEFAULT_UTILISATION_PERIOD_IN_MS (100)
 
 /*
@@ -55,6 +59,7 @@
 struct rk_context {
 	/* mali device. */
 	struct device *dev;
+	struct regmap *grf;
 	/* is the GPU powered on?  */
 	bool is_powered;
 	/* debug only, the period in ms to count gpu_utilisation. */
@@ -183,6 +188,10 @@
 	}
 
 	platform->dev = dev;
+	platform->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+							"rockchip,grf");
+	if (IS_ERR(platform->grf))
+		platform->grf = NULL;
 	platform->is_powered = false;
 
 	platform->utilisation_period = DEFAULT_UTILISATION_PERIOD_IN_MS;
@@ -232,73 +241,7 @@
 static u32 static_coefficient;
 static s32 ts[4];
 static struct thermal_zone_device *gpu_tz;
-
-static int power_model_simple_init(struct platform_device *pdev)
-{
-	struct device_node *power_model_node;
-	const char *tz_name;
-	u32 static_power, dynamic_power;
-	u32 voltage, voltage_squared, voltage_cubed, frequency;
-
-	power_model_node = of_get_child_by_name(pdev->dev.of_node,
-			"power_model");
-	if (!power_model_node) {
-		dev_err(&pdev->dev, "could not find power_model node\n");
-		return -ENODEV;
-	}
-	if (!of_device_is_compatible(power_model_node,
-			"arm,mali-simple-power-model")) {
-		dev_err(&pdev->dev, "power_model incompatible with simple power model\n");
-		return -ENODEV;
-	}
-
-	if (of_property_read_string(power_model_node, "thermal-zone",
-			&tz_name)) {
-		dev_err(&pdev->dev, "ts in power_model not available\n");
-		return -EINVAL;
-	}
-
-	gpu_tz = thermal_zone_get_zone_by_name(tz_name);
-	if (IS_ERR(gpu_tz)) {
-		pr_warn_ratelimited("Error getting gpu thermal zone '%s'(%ld), not yet ready?\n",
-				tz_name,
-				PTR_ERR(gpu_tz));
-		gpu_tz = NULL;
-	}
-
-	if (of_property_read_u32(power_model_node, "static-power",
-			&static_power)) {
-		dev_err(&pdev->dev, "static-power in power_model not available\n");
-		return -EINVAL;
-	}
-	if (of_property_read_u32(power_model_node, "dynamic-power",
-			&dynamic_power)) {
-		dev_err(&pdev->dev, "dynamic-power in power_model not available\n");
-		return -EINVAL;
-	}
-	if (of_property_read_u32(power_model_node, "voltage",
-			&voltage)) {
-		dev_err(&pdev->dev, "voltage in power_model not available\n");
-		return -EINVAL;
-	}
-	if (of_property_read_u32(power_model_node, "frequency",
-			&frequency)) {
-		dev_err(&pdev->dev, "frequency in power_model not available\n");
-		return -EINVAL;
-	}
-	voltage_squared = (voltage * voltage) / 1000;
-	voltage_cubed = voltage * voltage * voltage;
-	static_coefficient = (static_power << 20) / (voltage_cubed >> 10);
-	dynamic_coefficient = (((dynamic_power * 1000) / voltage_squared)
-			* 1000) / frequency;
-
-	if (of_property_read_u32_array(power_model_node, "ts", (u32 *)ts, 4)) {
-		dev_err(&pdev->dev, "ts in power_model not available\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
+static struct ipa_power_model_data *model_data;
 
 /* Calculate gpu static power example for reference */
 static unsigned long rk_model_static_power(struct devfreq *devfreq,
@@ -360,10 +303,107 @@
 	return dynamic_power;
 }
 
-struct devfreq_cooling_power rk_cooling_ops = {
+static struct devfreq_cooling_power rk_cooling_ops = {
 	.get_static_power = rk_model_static_power,
 	.get_dynamic_power = rk_model_dynamic_power,
 };
+
+static unsigned long mali_devfreq_get_static_power(struct devfreq *devfreq,
+						   unsigned long voltage)
+{
+	return rockchip_ipa_get_static_power(model_data, voltage);
+}
+
+static int power_model_simple_init(struct platform_device *pdev)
+{
+	struct device_node *power_model_node;
+	const char *tz_name;
+	u32 static_power, dynamic_power;
+	u32 voltage, voltage_squared, voltage_cubed, frequency;
+
+	if (of_find_compatible_node(pdev->dev.of_node, NULL, "simple-power-model")) {
+		of_property_read_u32(pdev->dev.of_node,
+				     "dynamic-power-coefficient",
+				     (u32 *)&rk_cooling_ops.dyn_power_coeff);
+		model_data = rockchip_ipa_power_model_init(&pdev->dev,
+							   "gpu_leakage");
+		if (IS_ERR_OR_NULL(model_data)) {
+			model_data = NULL;
+			dev_err(&pdev->dev, "failed to initialize power model\n");
+		} else if (model_data->dynamic_coefficient) {
+			rk_cooling_ops.dyn_power_coeff =
+			model_data->dynamic_coefficient;
+			rk_cooling_ops.get_dynamic_power = NULL;
+			rk_cooling_ops.get_static_power = mali_devfreq_get_static_power;
+		}
+		if (!rk_cooling_ops.dyn_power_coeff) {
+			dev_err(&pdev->dev, "failed to get dynamic-coefficient\n");
+			return -EINVAL;
+		}
+
+		return 0;
+	}
+
+	power_model_node = of_get_child_by_name(pdev->dev.of_node,
+			"power_model");
+	if (!power_model_node) {
+		dev_err(&pdev->dev, "could not find power_model node\n");
+		return -ENODEV;
+	}
+	if (!of_device_is_compatible(power_model_node,
+			"arm,mali-simple-power-model")) {
+		dev_err(&pdev->dev, "power_model incompatible with simple power model\n");
+		return -ENODEV;
+	}
+
+	if (of_property_read_string(power_model_node, "thermal-zone",
+			&tz_name)) {
+		dev_err(&pdev->dev, "ts in power_model not available\n");
+		return -EINVAL;
+	}
+
+	gpu_tz = thermal_zone_get_zone_by_name(tz_name);
+	if (IS_ERR(gpu_tz)) {
+		pr_warn_ratelimited("Error getting gpu thermal zone '%s'(%ld), not yet ready?\n",
+				tz_name,
+				PTR_ERR(gpu_tz));
+		gpu_tz = NULL;
+	}
+
+	if (of_property_read_u32(power_model_node, "static-power",
+			&static_power)) {
+		dev_err(&pdev->dev, "static-power in power_model not available\n");
+		return -EINVAL;
+	}
+	if (of_property_read_u32(power_model_node, "dynamic-power",
+			&dynamic_power)) {
+		dev_err(&pdev->dev, "dynamic-power in power_model not available\n");
+		return -EINVAL;
+	}
+	if (of_property_read_u32(power_model_node, "voltage",
+			&voltage)) {
+		dev_err(&pdev->dev, "voltage in power_model not available\n");
+		return -EINVAL;
+	}
+	if (of_property_read_u32(power_model_node, "frequency",
+			&frequency)) {
+		dev_err(&pdev->dev, "frequency in power_model not available\n");
+		return -EINVAL;
+	}
+	voltage_squared = (voltage * voltage) / 1000;
+	voltage_cubed = voltage * voltage * voltage;
+	static_coefficient = (static_power << 20) / (voltage_cubed >> 10);
+	dynamic_coefficient = (((dynamic_power * 1000) / voltage_squared)
+			* 1000) / frequency;
+
+	if (of_property_read_u32_array(power_model_node, "ts", (u32 *)ts, 4)) {
+		dev_err(&pdev->dev, "ts in power_model not available\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 #endif
 
 /*---------------------------------------------------------------------------*/
@@ -376,8 +416,7 @@
 #if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_HAVE_CLK)
 	struct mali_device *mdev = dev_get_drvdata(dev);
 
-	if (mdev->clock)
-		ret = clk_enable(mdev->clock);
+	ret = clk_bulk_enable(mdev->num_clks, mdev->clks);
 #endif
 	return ret;
 }
@@ -387,8 +426,7 @@
 #if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_HAVE_CLK)
 	struct mali_device *mdev = dev_get_drvdata(dev);
 
-	if (mdev->clock)
-		clk_disable(mdev->clock);
+	clk_bulk_disable(mdev->num_clks, mdev->clks);
 #endif
 }
 
@@ -432,6 +470,18 @@
 			goto fail_to_enable_regulator;
 		}
 
+		if (cpu_is_rk3528()) {
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_HAVE_CLK)
+			struct mali_device *mdev = dev_get_drvdata(dev);
+
+			clk_set_rate(mdev->clock, mdev->current_freq);
+#endif
+			if (platform->grf)
+				regmap_write(platform->grf,
+					     RK3528_GPU_SD_SLP_HAST,
+					     0xffff0000);
+		}
+
 		platform->is_powered = true;
 	}
 
@@ -449,6 +499,18 @@
 	struct rk_context *platform = s_rk_context;
 
 	if (platform->is_powered) {
+		if (cpu_is_rk3528()) {
+#if defined(CONFIG_MALI_DEVFREQ) && defined(CONFIG_HAVE_CLK)
+			struct mali_device *mdev = dev_get_drvdata(dev);
+
+			//use normal pll 200M for gpu when suspend
+			clk_set_rate(mdev->clock, 200000000);
+#endif
+			if (platform->grf)
+				regmap_write(platform->grf,
+					     RK3528_GPU_SD_SLP_HAST,
+					     0xfffffffd);
+		}
 		rk_platform_disable_clk_gpu(dev);
 		rk_platform_disable_gpu_regulator(dev);
 

--
Gitblit v1.6.2