aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0468-drm-vc4-Use-runtime-PM-to-power-cycle-the-device-whe.patch
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas <noltari@gmail.com>2016-09-10 14:54:26 +0200
committerÁlvaro Fernández Rojas <noltari@gmail.com>2016-09-10 14:54:26 +0200
commit2b1c6b21b5e6c82ebb55d7fb7df90e60e88cbb14 (patch)
treeba6d48b4fec219d07110f5d55afc19bc309d2bdb /target/linux/brcm2708/patches-4.4/0468-drm-vc4-Use-runtime-PM-to-power-cycle-the-device-whe.patch
parentac08cb06f6734ebf73ed855cbc836c566f80eaca (diff)
downloadupstream-2b1c6b21b5e6c82ebb55d7fb7df90e60e88cbb14.tar.gz
upstream-2b1c6b21b5e6c82ebb55d7fb7df90e60e88cbb14.tar.bz2
upstream-2b1c6b21b5e6c82ebb55d7fb7df90e60e88cbb14.zip
brcm2708: update linux 4.4 patches to latest version
As usual these patches were extracted and rebased from the raspberry pi repo: https://github.com/raspberrypi/linux/tree/rpi-4.4.y Also adds support for Raspberry Pi Compute Module 3 (untested). Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0468-drm-vc4-Use-runtime-PM-to-power-cycle-the-device-whe.patch')
-rw-r--r--target/linux/brcm2708/patches-4.4/0468-drm-vc4-Use-runtime-PM-to-power-cycle-the-device-whe.patch102
1 files changed, 102 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0468-drm-vc4-Use-runtime-PM-to-power-cycle-the-device-whe.patch b/target/linux/brcm2708/patches-4.4/0468-drm-vc4-Use-runtime-PM-to-power-cycle-the-device-whe.patch
new file mode 100644
index 0000000000..d771261a19
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.4/0468-drm-vc4-Use-runtime-PM-to-power-cycle-the-device-whe.patch
@@ -0,0 +1,102 @@
+From e70d1a5fdbb7277490c273533ce535977326c6a5 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Mon, 8 Feb 2016 12:59:02 -0800
+Subject: [PATCH] drm/vc4: Use runtime PM to power cycle the device when the
+ GPU hangs.
+
+This gets us functional GPU reset again, like we had until a refactor
+at merge time. Tested with a little patch to stuff in a broken binner
+job every 100 frames.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+(cherry picked from commit 36cb6253f9383fd9a59ee7b8458c6232ef48577c)
+---
+ drivers/gpu/drm/vc4/vc4_drv.h | 6 +++++-
+ drivers/gpu/drm/vc4/vc4_gem.c | 26 +++++++++++++++++++++-----
+ 2 files changed, 26 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -104,6 +104,11 @@ struct vc4_dev {
+ struct vc4_bo *overflow_mem;
+ struct work_struct overflow_mem_work;
+
++ int power_refcount;
++
++ /* Mutex controlling the power refcount. */
++ struct mutex power_lock;
++
+ struct {
+ struct timer_list timer;
+ struct work_struct reset_work;
+@@ -495,7 +500,6 @@ void vc4_plane_async_set_fb(struct drm_p
+ extern struct platform_driver vc4_v3d_driver;
+ int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused);
+ int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused);
+-int vc4_v3d_set_power(struct vc4_dev *vc4, bool on);
+
+ /* vc4_validate.c */
+ int
+--- a/drivers/gpu/drm/vc4/vc4_gem.c
++++ b/drivers/gpu/drm/vc4/vc4_gem.c
+@@ -261,8 +261,16 @@ vc4_reset(struct drm_device *dev)
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+ DRM_INFO("Resetting GPU.\n");
+- vc4_v3d_set_power(vc4, false);
+- vc4_v3d_set_power(vc4, true);
++
++ mutex_lock(&vc4->power_lock);
++ if (vc4->power_refcount) {
++ /* Power the device off and back on the by dropping the
++ * reference on runtime PM.
++ */
++ pm_runtime_put_sync_suspend(&vc4->v3d->pdev->dev);
++ pm_runtime_get_sync(&vc4->v3d->pdev->dev);
++ }
++ mutex_unlock(&vc4->power_lock);
+
+ vc4_irq_reset(dev);
+
+@@ -709,7 +717,10 @@ vc4_complete_exec(struct drm_device *dev
+ }
+ mutex_unlock(&dev->struct_mutex);
+
+- pm_runtime_put(&vc4->v3d->pdev->dev);
++ mutex_lock(&vc4->power_lock);
++ if (--vc4->power_refcount == 0)
++ pm_runtime_put(&vc4->v3d->pdev->dev);
++ mutex_unlock(&vc4->power_lock);
+
+ kfree(exec);
+ }
+@@ -851,7 +862,7 @@ vc4_submit_cl_ioctl(struct drm_device *d
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct drm_vc4_submit_cl *args = data;
+ struct vc4_exec_info *exec;
+- int ret;
++ int ret = 0;
+
+ if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) {
+ DRM_ERROR("Unknown flags: 0x%02x\n", args->flags);
+@@ -864,7 +875,10 @@ vc4_submit_cl_ioctl(struct drm_device *d
+ return -ENOMEM;
+ }
+
+- ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
++ mutex_lock(&vc4->power_lock);
++ if (vc4->power_refcount++ == 0)
++ ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
++ mutex_unlock(&vc4->power_lock);
+ if (ret < 0) {
+ kfree(exec);
+ return ret;
+@@ -925,6 +939,8 @@ vc4_gem_init(struct drm_device *dev)
+ (unsigned long)dev);
+
+ INIT_WORK(&vc4->job_done_work, vc4_job_done_work);
++
++ mutex_init(&vc4->power_lock);
+ }
+
+ void