PD#126286 fix soft reset on midgard
authorJiyu Yang <jiyu.yang@amlogic.com>
Tue, 21 Jun 2016 13:20:06 +0000 (21:20 +0800)
committerJiyu Yang <jiyu.yang@amlogic.com>
Fri, 24 Jun 2016 02:46:03 +0000 (10:46 +0800)
The driver will ensure that the GPU is idle
before requesting power down. The power down request
will be made only when all jobs on all slots
have completed (all jobs flush and invalidate
on completion meaning the L2 cache will be empty).
The power down requests of the shader cores,
the tiler and the L2 cache are deferred to the system code
that will disable the clock(TODO) and power-off the whole GPU.

By bypassing the shader cores and core group power down sequences, and power
off the whole GPU instead, allows to this workaround to avoid the beginning of
any spurious transaction.
ter suspend

Change-Id: I048370dc83cb92762217f61b21a0ef3db2da457e

t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_driver.c
t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_internal.h
t83x/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_pm_policy.c
t83x/kernel/drivers/gpu/arm/midgard/mali_kbase_hwaccess_pm.h
t83x/kernel/drivers/gpu/arm/midgard/platform/devicetree/mali_kbase_runtime_pm.c

index 7675c91be2da6ecf6c765e21162059188a152d82..d0fa253b6b560555501b183d243cbd12fb750245 100755 (executable)
 /* Special value to indicate that the JM_CONFIG reg isn't currently used. */
 #define KBASE_JM_CONFIG_UNUSED (1<<31)
 
-/**
- * enum kbasep_pm_action - Actions that can be performed on a core.
- *
- * This enumeration is private to the file. Its values are set to allow
- * core_type_to_reg() function, which decodes this enumeration, to be simpler
- * and more efficient.
- *
- * @ACTION_PRESENT: The cores that are present
- * @ACTION_READY: The cores that are ready
- * @ACTION_PWRON: Power on the cores specified
- * @ACTION_PWROFF: Power off the cores specified
- * @ACTION_PWRTRANS: The cores that are transitioning
- * @ACTION_PWRACTIVE: The cores that are active
- */
-enum kbasep_pm_action {
-       ACTION_PRESENT = 0,
-       ACTION_READY = (SHADER_READY_LO - SHADER_PRESENT_LO),
-       ACTION_PWRON = (SHADER_PWRON_LO - SHADER_PRESENT_LO),
-       ACTION_PWROFF = (SHADER_PWROFF_LO - SHADER_PRESENT_LO),
-       ACTION_PWRTRANS = (SHADER_PWRTRANS_LO - SHADER_PRESENT_LO),
-       ACTION_PWRACTIVE = (SHADER_PWRACTIVE_LO - SHADER_PRESENT_LO)
-};
-
 static u64 kbase_pm_get_state(
                struct kbase_device *kbdev,
                enum kbase_pm_core_type core_type,
@@ -143,7 +120,7 @@ static void mali_cci_flush_l2(struct kbase_device *kbdev)
  * @cores:     A bit mask of cores to perform the action on (low 32 bits)
  * @action:    The action to perform on the cores
  */
-static void kbase_pm_invoke(struct kbase_device *kbdev,
+void kbase_pm_invoke(struct kbase_device *kbdev,
                                        enum kbase_pm_core_type core_type,
                                        u64 cores,
                                        enum kbasep_pm_action action)
@@ -223,6 +200,8 @@ static void kbase_pm_invoke(struct kbase_device *kbdev,
                kbase_reg_write(kbdev, GPU_CONTROL_REG(reg + 4), hi, NULL);
 }
 
+KBASE_EXPORT_TEST_API(kbase_pm_invoke);
+
 /**
  * kbase_pm_get_state - Get information about a core set
  *
@@ -485,7 +464,7 @@ static bool kbase_pm_transition_core_type(struct kbase_device *kbdev,
 
        /* Perform transitions if any */
        kbase_pm_invoke(kbdev, type, powerup, ACTION_PWRON);
-       kbase_pm_invoke(kbdev, type, powerdown, ACTION_PWROFF);
+       //kbase_pm_invoke(kbdev, type, powerdown, ACTION_PWROFF);
 
        /* Recalculate cores transitioning on, and re-evaluate our state */
        powering_on_trans |= powerup;
index aa51b8cdef8fc3bfced5d0ca1b6ca01367a0308f..477bea7706073fe82957204ec341c7271969859d 100755 (executable)
 #include "mali_kbase_pm_policy.h"
 
 
+/**
+ * enum kbasep_pm_action - Actions that can be performed on a core.
+ *
+ * This enumeration is private to the file. Its values are set to allow
+ * core_type_to_reg() function, which decodes this enumeration, to be simpler
+ * and more efficient.
+ *
+ * @ACTION_PRESENT: The cores that are present
+ * @ACTION_READY: The cores that are ready
+ * @ACTION_PWRON: Power on the cores specified
+ * @ACTION_PWROFF: Power off the cores specified
+ * @ACTION_PWRTRANS: The cores that are transitioning
+ * @ACTION_PWRACTIVE: The cores that are active
+ */
+enum kbasep_pm_action {
+       ACTION_PRESENT = 0,
+       ACTION_READY = (SHADER_READY_LO - SHADER_PRESENT_LO),
+       ACTION_PWRON = (SHADER_PWRON_LO - SHADER_PRESENT_LO),
+       ACTION_PWROFF = (SHADER_PWROFF_LO - SHADER_PRESENT_LO),
+       ACTION_PWRTRANS = (SHADER_PWRTRANS_LO - SHADER_PRESENT_LO),
+       ACTION_PWRACTIVE = (SHADER_PWRACTIVE_LO - SHADER_PRESENT_LO)
+};
+
+
+
 /**
  * kbase_pm_dev_idle - The GPU is idle.
  *
@@ -277,6 +302,24 @@ void kbase_pm_update_cores_state(struct kbase_device *kbdev);
  */
 void kbase_pm_cancel_deferred_poweroff(struct kbase_device *kbdev);
 
+/**
+ * kbase_pm_invoke - Invokes an action on a core set
+ *
+ * This function performs the action given by @action on a set of cores of a
+ * type given by @core_type. It is a static function used by
+ * kbase_pm_transition_core_type()
+ *
+ * @kbdev:     The kbase device structure of the device
+ * @core_type: The type of core that the action should be performed on
+ * @cores:     A bit mask of cores to perform the action on (low 32 bits)
+ * @action:    The action to perform on the cores
+ */
+
+void kbase_pm_invoke(struct kbase_device *kbdev,
+                                       enum kbase_pm_core_type core_type,
+                                       u64 cores,
+                                       enum kbasep_pm_action action);
+
 /**
  * kbasep_pm_read_present_cores - Read the bitmasks of present cores.
  *
index 343436fc353dd7e9e47409ae21300034ad9fc168..90648c720f1bbf10e3d51e8a3f8889469610df10 100755 (executable)
@@ -554,6 +554,35 @@ const struct kbase_pm_policy *kbase_pm_get_policy(struct kbase_device *kbdev)
 
 KBASE_EXPORT_TEST_API(kbase_pm_get_policy);
 
+int set_policy_by_name(struct kbase_device *kbdev, const char *name)
+{
+       const struct kbase_pm_policy *new_policy = NULL;
+       const struct kbase_pm_policy *const *policy_list;
+       int policy_count;
+       int i;
+
+       policy_count = kbase_pm_list_policies(&policy_list);
+
+       for (i = 0; i < policy_count; i++) {
+               if (sysfs_streq(policy_list[i]->name, name)) {
+                       new_policy = policy_list[i];
+                       break;
+               }
+       }
+
+       if (!new_policy) {
+               printk("power_policy: policy not found\n");
+               return -EINVAL;
+       }
+       trace_printk("policy name=%s\n", name);
+
+       kbase_pm_set_policy(kbdev, new_policy);
+
+       return 0;
+}
+
+KBASE_EXPORT_TEST_API(set_policy_by_name);
+
 void kbase_pm_set_policy(struct kbase_device *kbdev,
                                const struct kbase_pm_policy *new_policy)
 {
index 71c7d495c40ab924f6ec9fe01ffd2fd9d1263fd2..bae7c0d23742803364fb9c759fc072ee76e16f01 100755 (executable)
@@ -183,6 +183,7 @@ kbase_pm_ca_list_policies(const struct kbase_pm_ca_policy * const **policies);
  * @return The current policy
  */
 const struct kbase_pm_policy *kbase_pm_get_policy(struct kbase_device *kbdev);
+int set_policy_by_name(struct kbase_device *kbdev, const char *name);
 
 /**
  * Change the policy to the one specified.
index 62f974c7bf54984925951a4c3bffa16e59fafc5f..3b3f095855d87288271c1ef9af049e76893052f3 100755 (executable)
 
 #include <mali_kbase.h>
 #include <mali_kbase_defs.h>
+#include <backend/gpu/mali_kbase_device_internal.h>
+#include <backend/gpu/mali_kbase_pm_internal.h>
 #include <linux/pm_runtime.h>
 #include <linux/suspend.h>
 #include <linux/delay.h>
 #include <linux/io.h>
-#include <backend/gpu/mali_kbase_device_internal.h>
 
 void *reg_base_hiubus = NULL;
 u32  override_value_aml = 0;
 static int first = 1;
 
-extern u64 kbase_pm_get_ready_cores(struct kbase_device *kbdev, enum kbase_pm_core_type type);
 static void  Mali_pwr_on_with_kdev ( struct kbase_device *kbdev, uint32_t  mask)
 {
     uint32_t    part1_done;
@@ -163,12 +163,24 @@ ret:
 
 static void pm_callback_power_off(struct kbase_device *kbdev)
 {
-       dev_dbg(kbdev->dev, "pm_callback_power_off\n");
     //printk("%s, %d\n", __FILE__, __LINE__);
 #if 0
     iounmap(reg_base_hiubus);
     reg_base_hiubus = NULL;
 #endif
+       u64 core_ready  = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_SHADER);
+       u64 l2_ready    = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_L2);
+       u64 tiler_ready = kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_TILER);
+
+       dev_dbg(kbdev->dev, "pm_callback_power_off\n");
+       if (core_ready)
+               kbase_pm_invoke(kbdev, KBASE_PM_CORE_SHADER, core_ready, ACTION_PWROFF);
+
+       if (l2_ready)
+               kbase_pm_invoke(kbdev, KBASE_PM_CORE_L2, l2_ready, ACTION_PWROFF);
+
+       if (tiler_ready)
+               kbase_pm_invoke(kbdev, KBASE_PM_CORE_TILER, tiler_ready, ACTION_PWROFF);
 
        pm_runtime_put_autosuspend(kbdev->dev);
 }