aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tilcdc
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2013-08-07 13:41:20 -0400
committerDave Airlie <airlied@redhat.com>2013-08-18 20:33:36 -0400
commita464d618c715b7a850f7459754d9d155f5e60538 (patch)
tree78edb8216877a677fd51c5d335394cf5fe9c41f1 /drivers/gpu/drm/tilcdc
parentcabaafc78935521c5abc7ec72278dbaa5400c995 (diff)
drm/tilcdc: use flip-work helper
Signed-off-by: Rob Clark <robdclark@gmail.com> Tested-by: Darren Etheridge <detheridge@ti.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_crtc.c33
1 files changed, 12 insertions, 21 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 6d0524095fe3..fe4726628906 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -15,7 +15,7 @@
15 * this program. If not, see <http://www.gnu.org/licenses/>. 15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18#include <linux/kfifo.h> 18#include "drm_flip_work.h"
19 19
20#include "tilcdc_drv.h" 20#include "tilcdc_drv.h"
21#include "tilcdc_regs.h" 21#include "tilcdc_regs.h"
@@ -35,21 +35,18 @@ struct tilcdc_crtc {
35 struct drm_framebuffer *scanout[2]; 35 struct drm_framebuffer *scanout[2];
36 36
37 /* for deferred fb unref's: */ 37 /* for deferred fb unref's: */
38 DECLARE_KFIFO_PTR(unref_fifo, struct drm_framebuffer *); 38 struct drm_flip_work unref_work;
39 struct work_struct work;
40}; 39};
41#define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) 40#define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
42 41
43static void unref_worker(struct work_struct *work) 42static void unref_worker(struct drm_flip_work *work, void *val)
44{ 43{
45 struct tilcdc_crtc *tilcdc_crtc = 44 struct tilcdc_crtc *tilcdc_crtc =
46 container_of(work, struct tilcdc_crtc, work); 45 container_of(work, struct tilcdc_crtc, unref_work);
47 struct drm_device *dev = tilcdc_crtc->base.dev; 46 struct drm_device *dev = tilcdc_crtc->base.dev;
48 struct drm_framebuffer *fb;
49 47
50 mutex_lock(&dev->mode_config.mutex); 48 mutex_lock(&dev->mode_config.mutex);
51 while (kfifo_get(&tilcdc_crtc->unref_fifo, &fb)) 49 drm_framebuffer_unreference(val);
52 drm_framebuffer_unreference(fb);
53 mutex_unlock(&dev->mode_config.mutex); 50 mutex_unlock(&dev->mode_config.mutex);
54} 51}
55 52
@@ -68,19 +65,14 @@ static void set_scanout(struct drm_crtc *crtc, int n)
68 }; 65 };
69 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 66 struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
70 struct drm_device *dev = crtc->dev; 67 struct drm_device *dev = crtc->dev;
68 struct tilcdc_drm_private *priv = dev->dev_private;
71 69
72 pm_runtime_get_sync(dev->dev); 70 pm_runtime_get_sync(dev->dev);
73 tilcdc_write(dev, base_reg[n], tilcdc_crtc->start); 71 tilcdc_write(dev, base_reg[n], tilcdc_crtc->start);
74 tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end); 72 tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end);
75 if (tilcdc_crtc->scanout[n]) { 73 if (tilcdc_crtc->scanout[n]) {
76 if (kfifo_put(&tilcdc_crtc->unref_fifo, 74 drm_flip_work_queue(&tilcdc_crtc->unref_work, tilcdc_crtc->scanout[n]);
77 (const struct drm_framebuffer **)&tilcdc_crtc->scanout[n])) { 75 drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq);
78 struct tilcdc_drm_private *priv = dev->dev_private;
79 queue_work(priv->wq, &tilcdc_crtc->work);
80 } else {
81 dev_err(dev->dev, "unref fifo full!\n");
82 drm_framebuffer_unreference(tilcdc_crtc->scanout[n]);
83 }
84 } 76 }
85 tilcdc_crtc->scanout[n] = crtc->fb; 77 tilcdc_crtc->scanout[n] = crtc->fb;
86 drm_framebuffer_reference(tilcdc_crtc->scanout[n]); 78 drm_framebuffer_reference(tilcdc_crtc->scanout[n]);
@@ -149,8 +141,8 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
149 WARN_ON(tilcdc_crtc->dpms == DRM_MODE_DPMS_ON); 141 WARN_ON(tilcdc_crtc->dpms == DRM_MODE_DPMS_ON);
150 142
151 drm_crtc_cleanup(crtc); 143 drm_crtc_cleanup(crtc);
152 WARN_ON(!kfifo_is_empty(&tilcdc_crtc->unref_fifo)); 144 drm_flip_work_cleanup(&tilcdc_crtc->unref_work);
153 kfifo_free(&tilcdc_crtc->unref_fifo); 145
154 kfree(tilcdc_crtc); 146 kfree(tilcdc_crtc);
155} 147}
156 148
@@ -671,14 +663,13 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
671 tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF; 663 tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF;
672 init_waitqueue_head(&tilcdc_crtc->frame_done_wq); 664 init_waitqueue_head(&tilcdc_crtc->frame_done_wq);
673 665
674 ret = kfifo_alloc(&tilcdc_crtc->unref_fifo, 16, GFP_KERNEL); 666 ret = drm_flip_work_init(&tilcdc_crtc->unref_work, 16,
667 "unref", unref_worker);
675 if (ret) { 668 if (ret) {
676 dev_err(dev->dev, "could not allocate unref FIFO\n"); 669 dev_err(dev->dev, "could not allocate unref FIFO\n");
677 goto fail; 670 goto fail;
678 } 671 }
679 672
680 INIT_WORK(&tilcdc_crtc->work, unref_worker);
681
682 ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); 673 ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs);
683 if (ret < 0) 674 if (ret < 0)
684 goto fail; 675 goto fail;