drm/exynos: move finish page flip to a common place
This patch implements the exynos_drm_crtc_finish_pageflip in exynos_drm_crtc.c. This avoids the duplication of same code in mixer, fimd and vidi. Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com> Signed-off-by: Stephane Marchesin <marcheu@chromium.org> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
@@ -393,3 +393,33 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)
|
|||||||
exynos_drm_fn_encoder(private->crtc[crtc], &crtc,
|
exynos_drm_fn_encoder(private->crtc[crtc], &crtc,
|
||||||
exynos_drm_disable_vblank);
|
exynos_drm_disable_vblank);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc)
|
||||||
|
{
|
||||||
|
struct exynos_drm_private *dev_priv = dev->dev_private;
|
||||||
|
struct drm_pending_vblank_event *e, *t;
|
||||||
|
struct timeval now;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
DRM_DEBUG_KMS("%s\n", __FILE__);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev->event_lock, flags);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
|
||||||
|
base.link) {
|
||||||
|
/* if event's pipe isn't same as crtc then ignore it. */
|
||||||
|
if (crtc != e->pipe)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
do_gettimeofday(&now);
|
||||||
|
e->event.sequence = 0;
|
||||||
|
e->event.tv_sec = now.tv_sec;
|
||||||
|
e->event.tv_usec = now.tv_usec;
|
||||||
|
|
||||||
|
list_move_tail(&e->base.link, &e->base.file_priv->event_list);
|
||||||
|
wake_up_interruptible(&e->base.file_priv->event_wait);
|
||||||
|
drm_vblank_put(dev, crtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||||
|
}
|
||||||
|
@@ -18,5 +18,6 @@
|
|||||||
int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr);
|
int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr);
|
||||||
int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc);
|
int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc);
|
||||||
void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc);
|
void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc);
|
||||||
|
void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -663,34 +663,6 @@ static struct exynos_drm_manager fimd_manager = {
|
|||||||
.display_ops = &fimd_display_ops,
|
.display_ops = &fimd_display_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc)
|
|
||||||
{
|
|
||||||
struct exynos_drm_private *dev_priv = drm_dev->dev_private;
|
|
||||||
struct drm_pending_vblank_event *e, *t;
|
|
||||||
struct timeval now;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&drm_dev->event_lock, flags);
|
|
||||||
|
|
||||||
list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
|
|
||||||
base.link) {
|
|
||||||
/* if event's pipe isn't same as crtc then ignore it. */
|
|
||||||
if (crtc != e->pipe)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
do_gettimeofday(&now);
|
|
||||||
e->event.sequence = 0;
|
|
||||||
e->event.tv_sec = now.tv_sec;
|
|
||||||
e->event.tv_usec = now.tv_usec;
|
|
||||||
|
|
||||||
list_move_tail(&e->base.link, &e->base.file_priv->event_list);
|
|
||||||
wake_up_interruptible(&e->base.file_priv->event_wait);
|
|
||||||
drm_vblank_put(drm_dev, crtc);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&drm_dev->event_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
|
static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct fimd_context *ctx = (struct fimd_context *)dev_id;
|
struct fimd_context *ctx = (struct fimd_context *)dev_id;
|
||||||
@@ -710,7 +682,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
drm_handle_vblank(drm_dev, manager->pipe);
|
drm_handle_vblank(drm_dev, manager->pipe);
|
||||||
fimd_finish_pageflip(drm_dev, manager->pipe);
|
exynos_drm_crtc_finish_pageflip(drm_dev, manager->pipe);
|
||||||
|
|
||||||
/* set wait vsync event to zero and wake up queue. */
|
/* set wait vsync event to zero and wake up queue. */
|
||||||
if (atomic_read(&ctx->wait_vsync_event)) {
|
if (atomic_read(&ctx->wait_vsync_event)) {
|
||||||
|
@@ -372,34 +372,6 @@ static struct exynos_drm_manager vidi_manager = {
|
|||||||
.display_ops = &vidi_display_ops,
|
.display_ops = &vidi_display_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc)
|
|
||||||
{
|
|
||||||
struct exynos_drm_private *dev_priv = drm_dev->dev_private;
|
|
||||||
struct drm_pending_vblank_event *e, *t;
|
|
||||||
struct timeval now;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&drm_dev->event_lock, flags);
|
|
||||||
|
|
||||||
list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
|
|
||||||
base.link) {
|
|
||||||
/* if event's pipe isn't same as crtc then ignore it. */
|
|
||||||
if (crtc != e->pipe)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
do_gettimeofday(&now);
|
|
||||||
e->event.sequence = 0;
|
|
||||||
e->event.tv_sec = now.tv_sec;
|
|
||||||
e->event.tv_usec = now.tv_usec;
|
|
||||||
|
|
||||||
list_move_tail(&e->base.link, &e->base.file_priv->event_list);
|
|
||||||
wake_up_interruptible(&e->base.file_priv->event_wait);
|
|
||||||
drm_vblank_put(drm_dev, crtc);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&drm_dev->event_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vidi_fake_vblank_handler(struct work_struct *work)
|
static void vidi_fake_vblank_handler(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct vidi_context *ctx = container_of(work, struct vidi_context,
|
struct vidi_context *ctx = container_of(work, struct vidi_context,
|
||||||
@@ -424,7 +396,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work)
|
|||||||
|
|
||||||
mutex_unlock(&ctx->lock);
|
mutex_unlock(&ctx->lock);
|
||||||
|
|
||||||
vidi_finish_pageflip(subdrv->drm_dev, manager->pipe);
|
exynos_drm_crtc_finish_pageflip(subdrv->drm_dev, manager->pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
|
static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include <drm/exynos_drm.h>
|
#include <drm/exynos_drm.h>
|
||||||
|
|
||||||
#include "exynos_drm_drv.h"
|
#include "exynos_drm_drv.h"
|
||||||
|
#include "exynos_drm_crtc.h"
|
||||||
#include "exynos_drm_hdmi.h"
|
#include "exynos_drm_hdmi.h"
|
||||||
#include "exynos_drm_iommu.h"
|
#include "exynos_drm_iommu.h"
|
||||||
|
|
||||||
@@ -949,35 +950,6 @@ static struct exynos_mixer_ops mixer_ops = {
|
|||||||
.win_disable = mixer_win_disable,
|
.win_disable = mixer_win_disable,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* for pageflip event */
|
|
||||||
static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc)
|
|
||||||
{
|
|
||||||
struct exynos_drm_private *dev_priv = drm_dev->dev_private;
|
|
||||||
struct drm_pending_vblank_event *e, *t;
|
|
||||||
struct timeval now;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&drm_dev->event_lock, flags);
|
|
||||||
|
|
||||||
list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
|
|
||||||
base.link) {
|
|
||||||
/* if event's pipe isn't same as crtc then ignore it. */
|
|
||||||
if (crtc != e->pipe)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
do_gettimeofday(&now);
|
|
||||||
e->event.sequence = 0;
|
|
||||||
e->event.tv_sec = now.tv_sec;
|
|
||||||
e->event.tv_usec = now.tv_usec;
|
|
||||||
|
|
||||||
list_move_tail(&e->base.link, &e->base.file_priv->event_list);
|
|
||||||
wake_up_interruptible(&e->base.file_priv->event_wait);
|
|
||||||
drm_vblank_put(drm_dev, crtc);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&drm_dev->event_lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t mixer_irq_handler(int irq, void *arg)
|
static irqreturn_t mixer_irq_handler(int irq, void *arg)
|
||||||
{
|
{
|
||||||
struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
|
struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
|
||||||
@@ -1006,7 +978,8 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe);
|
drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe);
|
||||||
mixer_finish_pageflip(drm_hdmi_ctx->drm_dev, ctx->pipe);
|
exynos_drm_crtc_finish_pageflip(drm_hdmi_ctx->drm_dev,
|
||||||
|
ctx->pipe);
|
||||||
|
|
||||||
/* set wait vsync event to zero and wake up queue. */
|
/* set wait vsync event to zero and wake up queue. */
|
||||||
if (atomic_read(&ctx->wait_vsync_event)) {
|
if (atomic_read(&ctx->wait_vsync_event)) {
|
||||||
|
Reference in New Issue
Block a user