OSDN Git Service

msm: kgsl: unload/reload zap shader
authorThomas Yun <wyun@codeaurora.org>
Tue, 17 Jul 2018 18:07:39 +0000 (14:07 -0400)
committerGerrit - the friendly Code Review server <code-review@localhost>
Fri, 27 Jul 2018 18:35:17 +0000 (11:35 -0700)
Unload zap shader during device hibernation and reload it
during resume otherwise scm calls during post hibernation
GPU initialization will fail as there is possibility that
TZ driver is not aware of the hibernation.

Change-Id: I1f62fb97cbc8e6c3e3536d4d5260a543ca15b685
Signed-off-by: Suprith Malligere Shankaregowda <supgow@codeaurora.org>
Signed-off-by: Thomas Yun <wyun@codeaurora.org>
drivers/gpu/msm/adreno.c
drivers/gpu/msm/adreno.h
drivers/gpu/msm/adreno_a5xx.c
drivers/gpu/msm/kgsl.c
drivers/gpu/msm/kgsl_device.h

index 7af2af4..9cb6503 100644 (file)
@@ -2800,6 +2800,27 @@ static void adreno_gpu_model(struct kgsl_device *device, char *str,
                         ADRENO_CHIPID_PATCH(adreno_dev->chipid) + 1);
 }
 
+static void adreno_suspend_device(struct kgsl_device *device,
+                               pm_message_t pm_state)
+{
+       struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+       struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
+       int pm_event = pm_state.event;
+
+       adreno_dispatcher_halt(device);
+
+       if ((pm_event == PM_EVENT_FREEZE) ||
+               (pm_event == PM_EVENT_QUIESCE) ||
+               (pm_event == PM_EVENT_HIBERNATE))
+               if (gpudev->zap_shader_unload != NULL)
+                       gpudev->zap_shader_unload(adreno_dev);
+}
+
+static void adreno_resume_device(struct kgsl_device *device)
+{
+       adreno_dispatcher_unhalt(device);
+}
+
 static const struct kgsl_functable adreno_functable = {
        /* Mandatory functions */
        .regread = adreno_regread,
@@ -2839,8 +2860,8 @@ static const struct kgsl_functable adreno_functable = {
        .clk_set_options = adreno_clk_set_options,
        .gpu_model = adreno_gpu_model,
        .stop_fault_timer = adreno_dispatcher_stop_fault_timer,
-       .dispatcher_halt = adreno_dispatcher_halt,
-       .dispatcher_unhalt = adreno_dispatcher_unhalt,
+       .suspend_device = adreno_suspend_device,
+       .resume_device = adreno_resume_device,
 };
 
 static struct platform_driver adreno_platform_driver = {
index 9ea5000..1f598bf 100644 (file)
@@ -794,6 +794,7 @@ struct adreno_gpudev {
        void (*enable_64bit)(struct adreno_device *);
        void (*clk_set_options)(struct adreno_device *,
                                const char *, struct clk *, bool on);
+       void (*zap_shader_unload)(struct adreno_device *);
 };
 
 /**
index 4daf1fa..e3381bc 100644 (file)
@@ -31,6 +31,7 @@
 #include "adreno_a5xx_packets.h"
 
 static int zap_ucode_loaded;
+static void *zap_handle_ptr;
 static int critical_packet_constructed;
 
 static struct kgsl_memdesc crit_pkts;
@@ -2236,7 +2237,6 @@ static int a5xx_switch_to_unsecure_mode(struct adreno_device *adreno_dev,
  */
 static int a5xx_microcode_load(struct adreno_device *adreno_dev)
 {
-       void *ptr;
        struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
        uint64_t gpuaddr;
 
@@ -2276,11 +2276,12 @@ static int a5xx_microcode_load(struct adreno_device *adreno_dev)
 
        /* Load the zap shader firmware through PIL if its available */
        if (adreno_dev->gpucore->zap_name && !zap_ucode_loaded) {
-               ptr = subsystem_get(adreno_dev->gpucore->zap_name);
+               zap_handle_ptr = subsystem_get(adreno_dev->gpucore->zap_name);
 
                /* Return error if the zap shader cannot be loaded */
-               if (IS_ERR_OR_NULL(ptr))
-                       return (ptr == NULL) ? -ENODEV : PTR_ERR(ptr);
+               if (IS_ERR_OR_NULL(zap_handle_ptr))
+                       return (zap_handle_ptr == NULL) ?
+                                       -ENODEV : PTR_ERR(zap_handle_ptr);
 
                zap_ucode_loaded = 1;
        }
@@ -2288,6 +2289,15 @@ static int a5xx_microcode_load(struct adreno_device *adreno_dev)
        return 0;
 }
 
+static void a5xx_zap_shader_unload(struct adreno_device *adreno_dev)
+{
+       if (!IS_ERR_OR_NULL(zap_handle_ptr)) {
+               subsystem_put(zap_handle_ptr);
+               zap_handle_ptr = NULL;
+               zap_ucode_loaded = 0;
+       }
+}
+
 static int _me_init_ucode_workarounds(struct adreno_device *adreno_dev)
 {
        switch (ADRENO_GPUREV(adreno_dev)) {
@@ -3698,4 +3708,5 @@ struct adreno_gpudev adreno_a5xx_gpudev = {
        .preemption_schedule = a5xx_preemption_schedule,
        .enable_64bit = a5xx_enable_64bit,
        .clk_set_options = a5xx_clk_set_options,
+       .zap_shader_unload = a5xx_zap_shader_unload,
 };
index 4eed26b..02f0cb7 100644 (file)
@@ -746,7 +746,7 @@ static int kgsl_suspend_device(struct kgsl_device *device, pm_message_t state)
        mutex_lock(&device->mutex);
        status = kgsl_pwrctrl_change_state(device, KGSL_STATE_SUSPEND);
        if (status == 0)
-               device->ftbl->dispatcher_halt(device);
+               device->ftbl->suspend_device(device, state);
        mutex_unlock(&device->mutex);
 
        return status;
@@ -759,7 +759,7 @@ static int kgsl_resume_device(struct kgsl_device *device)
 
        mutex_lock(&device->mutex);
        if (device->state == KGSL_STATE_SUSPEND) {
-               device->ftbl->dispatcher_unhalt(device);
+               device->ftbl->resume_device(device);
                kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);
        } else if (device->state != KGSL_STATE_INIT) {
                /*
@@ -782,10 +782,23 @@ static int kgsl_resume_device(struct kgsl_device *device)
 
 static int kgsl_suspend(struct device *dev)
 {
+       struct kgsl_device *device = dev_get_drvdata(dev);
+
+       return kgsl_suspend_device(device, PMSG_SUSPEND);
+}
+
+static int kgsl_freeze(struct device *dev)
+{
+       struct kgsl_device *device = dev_get_drvdata(dev);
+
+       return kgsl_suspend_device(device, PMSG_FREEZE);
+}
 
-       pm_message_t arg = {0};
+static int kgsl_poweroff(struct device *dev)
+{
        struct kgsl_device *device = dev_get_drvdata(dev);
-       return kgsl_suspend_device(device, arg);
+
+       return kgsl_suspend_device(device, PMSG_HIBERNATE);
 }
 
 static int kgsl_resume(struct device *dev)
@@ -805,7 +818,12 @@ static int kgsl_runtime_resume(struct device *dev)
 }
 
 const struct dev_pm_ops kgsl_pm_ops = {
-       SET_SYSTEM_SLEEP_PM_OPS(kgsl_suspend, kgsl_resume)
+       .suspend = kgsl_suspend,
+       .resume = kgsl_resume,
+       .freeze = kgsl_freeze,
+       .thaw = kgsl_resume,
+       .poweroff = kgsl_poweroff,
+       .restore = kgsl_resume,
        .runtime_suspend = kgsl_runtime_suspend,
        .runtime_resume = kgsl_runtime_resume,
 };
index 57d4fe4..078109a 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/slab.h>
 #include <linux/idr.h>
+#include <linux/pm.h>
 #include <linux/pm_qos.h>
 #include <linux/sched.h>
 
@@ -171,8 +172,9 @@ struct kgsl_functable {
        void (*gpu_model)(struct kgsl_device *device, char *str,
                size_t bufsz);
        void (*stop_fault_timer)(struct kgsl_device *device);
-       void (*dispatcher_halt)(struct kgsl_device *device);
-       void (*dispatcher_unhalt)(struct kgsl_device *device);
+       void (*suspend_device)(struct kgsl_device *device,
+               pm_message_t pm_state);
+       void (*resume_device)(struct kgsl_device *device);
 };
 
 struct kgsl_ioctl {