Commit a464d618 authored by Rob Clark's avatar Rob Clark Committed by Dave Airlie

drm/tilcdc: use flip-work helper

Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
Tested-by: default avatarDarren Etheridge <detheridge@ti.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent cabaafc7
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <linux/kfifo.h> #include "drm_flip_work.h"
#include "tilcdc_drv.h" #include "tilcdc_drv.h"
#include "tilcdc_regs.h" #include "tilcdc_regs.h"
...@@ -35,21 +35,18 @@ struct tilcdc_crtc { ...@@ -35,21 +35,18 @@ struct tilcdc_crtc {
struct drm_framebuffer *scanout[2]; struct drm_framebuffer *scanout[2];
/* for deferred fb unref's: */ /* for deferred fb unref's: */
DECLARE_KFIFO_PTR(unref_fifo, struct drm_framebuffer *); struct drm_flip_work unref_work;
struct work_struct work;
}; };
#define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
static void unref_worker(struct work_struct *work) static void unref_worker(struct drm_flip_work *work, void *val)
{ {
struct tilcdc_crtc *tilcdc_crtc = struct tilcdc_crtc *tilcdc_crtc =
container_of(work, struct tilcdc_crtc, work); container_of(work, struct tilcdc_crtc, unref_work);
struct drm_device *dev = tilcdc_crtc->base.dev; struct drm_device *dev = tilcdc_crtc->base.dev;
struct drm_framebuffer *fb;
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
while (kfifo_get(&tilcdc_crtc->unref_fifo, &fb)) drm_framebuffer_unreference(val);
drm_framebuffer_unreference(fb);
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
} }
...@@ -68,19 +65,14 @@ static void set_scanout(struct drm_crtc *crtc, int n) ...@@ -68,19 +65,14 @@ static void set_scanout(struct drm_crtc *crtc, int n)
}; };
struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct tilcdc_drm_private *priv = dev->dev_private;
pm_runtime_get_sync(dev->dev); pm_runtime_get_sync(dev->dev);
tilcdc_write(dev, base_reg[n], tilcdc_crtc->start); tilcdc_write(dev, base_reg[n], tilcdc_crtc->start);
tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end); tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end);
if (tilcdc_crtc->scanout[n]) { if (tilcdc_crtc->scanout[n]) {
if (kfifo_put(&tilcdc_crtc->unref_fifo, drm_flip_work_queue(&tilcdc_crtc->unref_work, tilcdc_crtc->scanout[n]);
(const struct drm_framebuffer **)&tilcdc_crtc->scanout[n])) { drm_flip_work_commit(&tilcdc_crtc->unref_work, priv->wq);
struct tilcdc_drm_private *priv = dev->dev_private;
queue_work(priv->wq, &tilcdc_crtc->work);
} else {
dev_err(dev->dev, "unref fifo full!\n");
drm_framebuffer_unreference(tilcdc_crtc->scanout[n]);
}
} }
tilcdc_crtc->scanout[n] = crtc->fb; tilcdc_crtc->scanout[n] = crtc->fb;
drm_framebuffer_reference(tilcdc_crtc->scanout[n]); drm_framebuffer_reference(tilcdc_crtc->scanout[n]);
...@@ -149,8 +141,8 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc) ...@@ -149,8 +141,8 @@ static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
WARN_ON(tilcdc_crtc->dpms == DRM_MODE_DPMS_ON); WARN_ON(tilcdc_crtc->dpms == DRM_MODE_DPMS_ON);
drm_crtc_cleanup(crtc); drm_crtc_cleanup(crtc);
WARN_ON(!kfifo_is_empty(&tilcdc_crtc->unref_fifo)); drm_flip_work_cleanup(&tilcdc_crtc->unref_work);
kfifo_free(&tilcdc_crtc->unref_fifo);
kfree(tilcdc_crtc); kfree(tilcdc_crtc);
} }
...@@ -671,14 +663,13 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) ...@@ -671,14 +663,13 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF; tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF;
init_waitqueue_head(&tilcdc_crtc->frame_done_wq); init_waitqueue_head(&tilcdc_crtc->frame_done_wq);
ret = kfifo_alloc(&tilcdc_crtc->unref_fifo, 16, GFP_KERNEL); ret = drm_flip_work_init(&tilcdc_crtc->unref_work, 16,
"unref", unref_worker);
if (ret) { if (ret) {
dev_err(dev->dev, "could not allocate unref FIFO\n"); dev_err(dev->dev, "could not allocate unref FIFO\n");
goto fail; goto fail;
} }
INIT_WORK(&tilcdc_crtc->work, unref_worker);
ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs);
if (ret < 0) if (ret < 0)
goto fail; goto fail;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment