Loading drivers/gpu/drm/msm/adreno/adreno_device.c +26 −10 Original line number Diff line number Diff line Loading @@ -155,21 +155,14 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) if (gpu) { int ret; mutex_lock(&dev->struct_mutex); gpu->funcs->pm_resume(gpu); mutex_unlock(&dev->struct_mutex); disable_irq(gpu->irq); ret = gpu->funcs->hw_init(gpu); pm_runtime_get_sync(&pdev->dev); ret = msm_gpu_hw_init(gpu); pm_runtime_put_sync(&pdev->dev); if (ret) { dev_err(dev->dev, "gpu hw init failed: %d\n", ret); gpu->funcs->destroy(gpu); gpu = NULL; } else { enable_irq(gpu->irq); /* give inactive pm a chance to kick in: */ msm_gpu_retire(gpu); } } Loading Loading @@ -296,12 +289,35 @@ static const struct of_device_id dt_match[] = { {} }; #ifdef CONFIG_PM static int adreno_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct msm_gpu *gpu = platform_get_drvdata(pdev); return gpu->funcs->pm_resume(gpu); } static int adreno_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct msm_gpu *gpu = platform_get_drvdata(pdev); return gpu->funcs->pm_suspend(gpu); } #endif static const struct dev_pm_ops adreno_pm_ops = { SET_RUNTIME_PM_OPS(adreno_suspend, adreno_resume, NULL) }; static struct platform_driver adreno_driver = { .probe = adreno_probe, .remove = adreno_remove, .driver = { .name = "adreno", .of_match_table = dt_match, .pm = &adreno_pm_ops, }, }; Loading drivers/gpu/drm/msm/adreno/adreno_gpu.c +8 −3 Original line number Diff line number Diff line Loading @@ -115,6 +115,9 @@ void adreno_recover(struct msm_gpu *gpu) struct drm_device *dev = gpu->dev; int ret; // XXX pm-runtime?? we *need* the device to be off after this // so maybe continuing to call ->pm_suspend/resume() is better? gpu->funcs->pm_suspend(gpu); /* reset ringbuffer: */ Loading @@ -127,13 +130,11 @@ void adreno_recover(struct msm_gpu *gpu) gpu->funcs->pm_resume(gpu); disable_irq(gpu->irq); ret = gpu->funcs->hw_init(gpu); ret = msm_gpu_hw_init(gpu); if (ret) { dev_err(dev->dev, "gpu hw init failed: %d\n", ret); /* hmm, oh well? */ } enable_irq(gpu->irq); } void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, Loading Loading @@ -365,6 +366,10 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, if (ret) return ret; pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev); if (ret) { dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n", Loading drivers/gpu/drm/msm/msm_debugfs.c +2 −2 Original line number Diff line number Diff line Loading @@ -28,9 +28,9 @@ static int msm_gpu_show(struct drm_device *dev, struct seq_file *m) if (gpu) { seq_printf(m, "%s Status:\n", gpu->name); gpu->funcs->pm_resume(gpu); pm_runtime_get_sync(&gpu->pdev->dev); gpu->funcs->show(gpu, m); gpu->funcs->pm_suspend(gpu); pm_runtime_put_sync(&gpu->pdev->dev); } return 0; Loading drivers/gpu/drm/msm/msm_drv.c +2 −0 Original line number Diff line number Diff line Loading @@ -265,6 +265,8 @@ static int msm_drm_uninit(struct device *dev) if (gpu) { mutex_lock(&ddev->struct_mutex); // XXX what do we do here? //pm_runtime_enable(&pdev->dev); gpu->funcs->pm_suspend(gpu); mutex_unlock(&ddev->struct_mutex); gpu->funcs->destroy(gpu); Loading drivers/gpu/drm/msm/msm_gpu.c +27 −72 Original line number Diff line number Diff line Loading @@ -152,18 +152,9 @@ static int disable_axi(struct msm_gpu *gpu) int msm_gpu_pm_resume(struct msm_gpu *gpu) { struct drm_device *dev = gpu->dev; int ret; DBG("%s: active_cnt=%d", gpu->name, gpu->active_cnt); WARN_ON(!mutex_is_locked(&dev->struct_mutex)); if (gpu->active_cnt++ > 0) return 0; if (WARN_ON(gpu->active_cnt <= 0)) return -EINVAL; DBG("%s", gpu->name); ret = enable_pwrrail(gpu); if (ret) Loading @@ -177,23 +168,16 @@ int msm_gpu_pm_resume(struct msm_gpu *gpu) if (ret) return ret; gpu->needs_hw_init = true; return 0; } int msm_gpu_pm_suspend(struct msm_gpu *gpu) { struct drm_device *dev = gpu->dev; int ret; DBG("%s: active_cnt=%d", gpu->name, gpu->active_cnt); WARN_ON(!mutex_is_locked(&dev->struct_mutex)); if (--gpu->active_cnt > 0) return 0; if (WARN_ON(gpu->active_cnt < 0)) return -EINVAL; DBG("%s", gpu->name); ret = disable_axi(gpu); if (ret) Loading @@ -210,53 +194,20 @@ int msm_gpu_pm_suspend(struct msm_gpu *gpu) return 0; } /* * Inactivity detection (for suspend): */ static void inactive_worker(struct work_struct *work) { struct msm_gpu *gpu = container_of(work, struct msm_gpu, inactive_work); struct drm_device *dev = gpu->dev; if (gpu->inactive) return; DBG("%s: inactive!\n", gpu->name); mutex_lock(&dev->struct_mutex); if (!(msm_gpu_active(gpu) || gpu->inactive)) { disable_axi(gpu); disable_clk(gpu); gpu->inactive = true; } mutex_unlock(&dev->struct_mutex); } static void inactive_handler(unsigned long data) int msm_gpu_hw_init(struct msm_gpu *gpu) { struct msm_gpu *gpu = (struct msm_gpu *)data; struct msm_drm_private *priv = gpu->dev->dev_private; int ret; queue_work(priv->wq, &gpu->inactive_work); } if (!gpu->needs_hw_init) return 0; /* cancel inactive timer and make sure we are awake: */ static void inactive_cancel(struct msm_gpu *gpu) { DBG("%s", gpu->name); del_timer(&gpu->inactive_timer); if (gpu->inactive) { enable_clk(gpu); enable_axi(gpu); gpu->inactive = false; } } disable_irq(gpu->irq); ret = gpu->funcs->hw_init(gpu); if (!ret) gpu->needs_hw_init = false; enable_irq(gpu->irq); static void inactive_start(struct msm_gpu *gpu) { DBG("%s", gpu->name); mod_timer(&gpu->inactive_timer, round_jiffies_up(jiffies + DRM_MSM_INACTIVE_JIFFIES)); return ret; } /* Loading Loading @@ -296,8 +247,9 @@ static void recover_worker(struct work_struct *work) /* retire completed submits, plus the one that hung: */ retire_submits(gpu); inactive_cancel(gpu); pm_runtime_get_sync(&gpu->pdev->dev); gpu->funcs->recover(gpu); pm_runtime_put_sync(&gpu->pdev->dev); /* replay the remaining submits after the one that hung: */ list_for_each_entry(submit, &gpu->submit_list, node) { Loading Loading @@ -400,6 +352,8 @@ void msm_gpu_perfcntr_start(struct msm_gpu *gpu) { unsigned long flags; pm_runtime_get_sync(&gpu->pdev->dev); spin_lock_irqsave(&gpu->perf_lock, flags); /* we could dynamically enable/disable perfcntr registers too.. */ gpu->last_sample.active = msm_gpu_active(gpu); Loading @@ -413,6 +367,7 @@ void msm_gpu_perfcntr_start(struct msm_gpu *gpu) void msm_gpu_perfcntr_stop(struct msm_gpu *gpu) { gpu->perfcntr_active = false; pm_runtime_put_sync(&gpu->pdev->dev); } /* returns -errno or # of cntrs sampled */ Loading Loading @@ -458,6 +413,8 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) drm_gem_object_unreference(&msm_obj->base); } pm_runtime_mark_last_busy(&gpu->pdev->dev); pm_runtime_put_autosuspend(&gpu->pdev->dev); msm_gem_submit_free(submit); } Loading Loading @@ -492,9 +449,6 @@ static void retire_worker(struct work_struct *work) mutex_lock(&dev->struct_mutex); retire_submits(gpu); mutex_unlock(&dev->struct_mutex); if (!msm_gpu_active(gpu)) inactive_start(gpu); } /* call from irq handler to schedule work to retire bo's */ Loading @@ -515,7 +469,9 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, WARN_ON(!mutex_is_locked(&dev->struct_mutex)); inactive_cancel(gpu); pm_runtime_get_sync(&gpu->pdev->dev); msm_gpu_hw_init(gpu); list_add_tail(&submit->node, &gpu->submit_list); Loading Loading @@ -576,7 +532,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, gpu->dev = drm; gpu->funcs = funcs; gpu->name = name; gpu->inactive = true; gpu->fctx = msm_fence_context_alloc(drm, name); if (IS_ERR(gpu->fctx)) { ret = PTR_ERR(gpu->fctx); Loading @@ -586,13 +541,10 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, INIT_LIST_HEAD(&gpu->active_list); INIT_WORK(&gpu->retire_work, retire_worker); INIT_WORK(&gpu->inactive_work, inactive_worker); INIT_WORK(&gpu->recover_work, recover_worker); INIT_LIST_HEAD(&gpu->submit_list); setup_timer(&gpu->inactive_timer, inactive_handler, (unsigned long)gpu); setup_timer(&gpu->hangcheck_timer, hangcheck_handler, (unsigned long)gpu); Loading Loading @@ -684,6 +636,9 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, goto fail; } gpu->pdev = pdev; platform_set_drvdata(pdev, gpu); bs_init(gpu); return 0; Loading Loading
drivers/gpu/drm/msm/adreno/adreno_device.c +26 −10 Original line number Diff line number Diff line Loading @@ -155,21 +155,14 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) if (gpu) { int ret; mutex_lock(&dev->struct_mutex); gpu->funcs->pm_resume(gpu); mutex_unlock(&dev->struct_mutex); disable_irq(gpu->irq); ret = gpu->funcs->hw_init(gpu); pm_runtime_get_sync(&pdev->dev); ret = msm_gpu_hw_init(gpu); pm_runtime_put_sync(&pdev->dev); if (ret) { dev_err(dev->dev, "gpu hw init failed: %d\n", ret); gpu->funcs->destroy(gpu); gpu = NULL; } else { enable_irq(gpu->irq); /* give inactive pm a chance to kick in: */ msm_gpu_retire(gpu); } } Loading Loading @@ -296,12 +289,35 @@ static const struct of_device_id dt_match[] = { {} }; #ifdef CONFIG_PM static int adreno_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct msm_gpu *gpu = platform_get_drvdata(pdev); return gpu->funcs->pm_resume(gpu); } static int adreno_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct msm_gpu *gpu = platform_get_drvdata(pdev); return gpu->funcs->pm_suspend(gpu); } #endif static const struct dev_pm_ops adreno_pm_ops = { SET_RUNTIME_PM_OPS(adreno_suspend, adreno_resume, NULL) }; static struct platform_driver adreno_driver = { .probe = adreno_probe, .remove = adreno_remove, .driver = { .name = "adreno", .of_match_table = dt_match, .pm = &adreno_pm_ops, }, }; Loading
drivers/gpu/drm/msm/adreno/adreno_gpu.c +8 −3 Original line number Diff line number Diff line Loading @@ -115,6 +115,9 @@ void adreno_recover(struct msm_gpu *gpu) struct drm_device *dev = gpu->dev; int ret; // XXX pm-runtime?? we *need* the device to be off after this // so maybe continuing to call ->pm_suspend/resume() is better? gpu->funcs->pm_suspend(gpu); /* reset ringbuffer: */ Loading @@ -127,13 +130,11 @@ void adreno_recover(struct msm_gpu *gpu) gpu->funcs->pm_resume(gpu); disable_irq(gpu->irq); ret = gpu->funcs->hw_init(gpu); ret = msm_gpu_hw_init(gpu); if (ret) { dev_err(dev->dev, "gpu hw init failed: %d\n", ret); /* hmm, oh well? */ } enable_irq(gpu->irq); } void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, Loading Loading @@ -365,6 +366,10 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, if (ret) return ret; pm_runtime_set_autosuspend_delay(&pdev->dev, DRM_MSM_INACTIVE_PERIOD); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = request_firmware(&adreno_gpu->pm4, adreno_gpu->info->pm4fw, drm->dev); if (ret) { dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n", Loading
drivers/gpu/drm/msm/msm_debugfs.c +2 −2 Original line number Diff line number Diff line Loading @@ -28,9 +28,9 @@ static int msm_gpu_show(struct drm_device *dev, struct seq_file *m) if (gpu) { seq_printf(m, "%s Status:\n", gpu->name); gpu->funcs->pm_resume(gpu); pm_runtime_get_sync(&gpu->pdev->dev); gpu->funcs->show(gpu, m); gpu->funcs->pm_suspend(gpu); pm_runtime_put_sync(&gpu->pdev->dev); } return 0; Loading
drivers/gpu/drm/msm/msm_drv.c +2 −0 Original line number Diff line number Diff line Loading @@ -265,6 +265,8 @@ static int msm_drm_uninit(struct device *dev) if (gpu) { mutex_lock(&ddev->struct_mutex); // XXX what do we do here? //pm_runtime_enable(&pdev->dev); gpu->funcs->pm_suspend(gpu); mutex_unlock(&ddev->struct_mutex); gpu->funcs->destroy(gpu); Loading
drivers/gpu/drm/msm/msm_gpu.c +27 −72 Original line number Diff line number Diff line Loading @@ -152,18 +152,9 @@ static int disable_axi(struct msm_gpu *gpu) int msm_gpu_pm_resume(struct msm_gpu *gpu) { struct drm_device *dev = gpu->dev; int ret; DBG("%s: active_cnt=%d", gpu->name, gpu->active_cnt); WARN_ON(!mutex_is_locked(&dev->struct_mutex)); if (gpu->active_cnt++ > 0) return 0; if (WARN_ON(gpu->active_cnt <= 0)) return -EINVAL; DBG("%s", gpu->name); ret = enable_pwrrail(gpu); if (ret) Loading @@ -177,23 +168,16 @@ int msm_gpu_pm_resume(struct msm_gpu *gpu) if (ret) return ret; gpu->needs_hw_init = true; return 0; } int msm_gpu_pm_suspend(struct msm_gpu *gpu) { struct drm_device *dev = gpu->dev; int ret; DBG("%s: active_cnt=%d", gpu->name, gpu->active_cnt); WARN_ON(!mutex_is_locked(&dev->struct_mutex)); if (--gpu->active_cnt > 0) return 0; if (WARN_ON(gpu->active_cnt < 0)) return -EINVAL; DBG("%s", gpu->name); ret = disable_axi(gpu); if (ret) Loading @@ -210,53 +194,20 @@ int msm_gpu_pm_suspend(struct msm_gpu *gpu) return 0; } /* * Inactivity detection (for suspend): */ static void inactive_worker(struct work_struct *work) { struct msm_gpu *gpu = container_of(work, struct msm_gpu, inactive_work); struct drm_device *dev = gpu->dev; if (gpu->inactive) return; DBG("%s: inactive!\n", gpu->name); mutex_lock(&dev->struct_mutex); if (!(msm_gpu_active(gpu) || gpu->inactive)) { disable_axi(gpu); disable_clk(gpu); gpu->inactive = true; } mutex_unlock(&dev->struct_mutex); } static void inactive_handler(unsigned long data) int msm_gpu_hw_init(struct msm_gpu *gpu) { struct msm_gpu *gpu = (struct msm_gpu *)data; struct msm_drm_private *priv = gpu->dev->dev_private; int ret; queue_work(priv->wq, &gpu->inactive_work); } if (!gpu->needs_hw_init) return 0; /* cancel inactive timer and make sure we are awake: */ static void inactive_cancel(struct msm_gpu *gpu) { DBG("%s", gpu->name); del_timer(&gpu->inactive_timer); if (gpu->inactive) { enable_clk(gpu); enable_axi(gpu); gpu->inactive = false; } } disable_irq(gpu->irq); ret = gpu->funcs->hw_init(gpu); if (!ret) gpu->needs_hw_init = false; enable_irq(gpu->irq); static void inactive_start(struct msm_gpu *gpu) { DBG("%s", gpu->name); mod_timer(&gpu->inactive_timer, round_jiffies_up(jiffies + DRM_MSM_INACTIVE_JIFFIES)); return ret; } /* Loading Loading @@ -296,8 +247,9 @@ static void recover_worker(struct work_struct *work) /* retire completed submits, plus the one that hung: */ retire_submits(gpu); inactive_cancel(gpu); pm_runtime_get_sync(&gpu->pdev->dev); gpu->funcs->recover(gpu); pm_runtime_put_sync(&gpu->pdev->dev); /* replay the remaining submits after the one that hung: */ list_for_each_entry(submit, &gpu->submit_list, node) { Loading Loading @@ -400,6 +352,8 @@ void msm_gpu_perfcntr_start(struct msm_gpu *gpu) { unsigned long flags; pm_runtime_get_sync(&gpu->pdev->dev); spin_lock_irqsave(&gpu->perf_lock, flags); /* we could dynamically enable/disable perfcntr registers too.. */ gpu->last_sample.active = msm_gpu_active(gpu); Loading @@ -413,6 +367,7 @@ void msm_gpu_perfcntr_start(struct msm_gpu *gpu) void msm_gpu_perfcntr_stop(struct msm_gpu *gpu) { gpu->perfcntr_active = false; pm_runtime_put_sync(&gpu->pdev->dev); } /* returns -errno or # of cntrs sampled */ Loading Loading @@ -458,6 +413,8 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) drm_gem_object_unreference(&msm_obj->base); } pm_runtime_mark_last_busy(&gpu->pdev->dev); pm_runtime_put_autosuspend(&gpu->pdev->dev); msm_gem_submit_free(submit); } Loading Loading @@ -492,9 +449,6 @@ static void retire_worker(struct work_struct *work) mutex_lock(&dev->struct_mutex); retire_submits(gpu); mutex_unlock(&dev->struct_mutex); if (!msm_gpu_active(gpu)) inactive_start(gpu); } /* call from irq handler to schedule work to retire bo's */ Loading @@ -515,7 +469,9 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, WARN_ON(!mutex_is_locked(&dev->struct_mutex)); inactive_cancel(gpu); pm_runtime_get_sync(&gpu->pdev->dev); msm_gpu_hw_init(gpu); list_add_tail(&submit->node, &gpu->submit_list); Loading Loading @@ -576,7 +532,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, gpu->dev = drm; gpu->funcs = funcs; gpu->name = name; gpu->inactive = true; gpu->fctx = msm_fence_context_alloc(drm, name); if (IS_ERR(gpu->fctx)) { ret = PTR_ERR(gpu->fctx); Loading @@ -586,13 +541,10 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, INIT_LIST_HEAD(&gpu->active_list); INIT_WORK(&gpu->retire_work, retire_worker); INIT_WORK(&gpu->inactive_work, inactive_worker); INIT_WORK(&gpu->recover_work, recover_worker); INIT_LIST_HEAD(&gpu->submit_list); setup_timer(&gpu->inactive_timer, inactive_handler, (unsigned long)gpu); setup_timer(&gpu->hangcheck_timer, hangcheck_handler, (unsigned long)gpu); Loading Loading @@ -684,6 +636,9 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, goto fail; } gpu->pdev = pdev; platform_set_drvdata(pdev, gpu); bs_init(gpu); return 0; Loading