diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2018-08-06 21:52:26 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-08-06 21:52:26 -0700 |
| commit | 42570c93eca94652aa82f2c880004789606bbbe7 (patch) | |
| tree | a79cfbd21c96558e14f8578545faa2e7e11b157f | |
| parent | 7f6b5aa038fa25267e78b90b4eca57d4119fdb79 (diff) | |
| parent | fcff8d4b117e1d31da5b2cf2f0684ecb72cd5e94 (diff) | |
Merge "msm: kgsl: unload/reload zap shader"
| -rw-r--r-- | drivers/gpu/msm/adreno.c | 25 | ||||
| -rw-r--r-- | drivers/gpu/msm/adreno.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/msm/adreno_a5xx.c | 19 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl.c | 28 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl_device.h | 6 |
5 files changed, 66 insertions, 13 deletions
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 7af2af483f10..9cb65033ed13 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -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 = { diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 9ea50007ec38..1f598bf3d9f8 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -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 *); }; /** diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index 4daf1fad6ee1..e3381bca2586 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -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, }; diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 4eed26b64577..02f0cb7eb16c 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -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, }; diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 57d4fe4d9120..078109af99fe 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -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 { |
