Exynos DRM framework handled page-flip event with custom code.
The patch replaces it with drm-core vblank queue.
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
{
struct decon_context *ctx = dev_id;
u32 val;
- int win;
if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags))
goto out;
val &= VIDINTCON1_INTFRMDONEPEND | VIDINTCON1_INTFRMPEND;
if (val) {
- for (win = ctx->first_win; win < WINDOWS_NR ; win++) {
- struct exynos_drm_plane *plane = &ctx->planes[win];
-
- if (!plane->pending_fb)
- continue;
-
- exynos_drm_crtc_finish_update(ctx->crtc, plane);
- }
-
- /* clear */
writel(val, ctx->addr + DECON_VIDINTCON1);
drm_crtc_handle_vblank(&ctx->crtc->base);
}
{
struct decon_context *ctx = (struct decon_context *)dev_id;
u32 val, clear_bit;
- int win;
val = readl(ctx->regs + VIDINTCON1);
if (!ctx->i80_if) {
drm_crtc_handle_vblank(&ctx->crtc->base);
- for (win = 0 ; win < WINDOWS_NR ; win++) {
- struct exynos_drm_plane *plane = &ctx->planes[win];
-
- if (!plane->pending_fb)
- continue;
-
- exynos_drm_crtc_finish_update(ctx->crtc, plane);
- }
/* set wait vsync event to zero and wake up queue. */
if (atomic_read(&ctx->wait_vsync_event)) {
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
- exynos_crtc->event = crtc->state->event;
-
if (exynos_crtc->ops->atomic_begin)
exynos_crtc->ops->atomic_begin(exynos_crtc);
}
struct drm_crtc_state *old_crtc_state)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
+ struct drm_pending_vblank_event *event;
+ unsigned long flags;
if (exynos_crtc->ops->atomic_flush)
exynos_crtc->ops->atomic_flush(exynos_crtc);
+
+ event = crtc->state->event;
+ if (event) {
+ crtc->state->event = NULL;
+
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ if (drm_crtc_vblank_get(crtc) == 0)
+ drm_crtc_arm_vblank_event(crtc, event);
+ else
+ drm_crtc_send_vblank_event(crtc, event);
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+ }
+
}
static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
exynos_crtc->ops->disable_vblank(exynos_crtc);
}
-void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
- struct exynos_drm_plane *exynos_plane)
-{
- struct drm_crtc *crtc = &exynos_crtc->base;
- unsigned long flags;
-
- exynos_plane->pending_fb = NULL;
-
- spin_lock_irqsave(&crtc->dev->event_lock, flags);
- if (exynos_crtc->event)
- drm_crtc_send_vblank_event(crtc, exynos_crtc->event);
-
- exynos_crtc->event = NULL;
- spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
-}
-
int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
enum exynos_drm_output_type out_type)
{
void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc,
struct drm_file *file)
{
- struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
struct drm_pending_vblank_event *e;
unsigned long flags;
spin_lock_irqsave(&crtc->dev->event_lock, flags);
- e = exynos_crtc->event;
+ e = crtc->state->event;
if (e && e->base.file_priv == file)
- exynos_crtc->event = NULL;
+ crtc->state->event = NULL;
+ else
+ e = NULL;
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
- if (e && e->base.file_priv == file)
+ if (e)
drm_event_cancel_free(crtc->dev, &e->base);
}
struct drm_plane base;
const struct exynos_drm_plane_config *config;
unsigned int index;
- struct drm_framebuffer *pending_fb;
};
#define EXYNOS_DRM_PLANE_CAP_DOUBLE (1 << 0)
struct drm_crtc base;
enum exynos_drm_output_type type;
unsigned int pipe;
- struct drm_pending_vblank_event *event;
const struct exynos_drm_crtc_ops *ops;
void *ctx;
struct exynos_drm_clk *pipe_clk;
static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
{
struct fimd_context *ctx = (struct fimd_context *)dev_id;
- u32 val, clear_bit, start, start_s;
- int win;
+ u32 val, clear_bit;
val = readl(ctx->regs + VIDINTCON1);
if (!ctx->i80_if)
drm_crtc_handle_vblank(&ctx->crtc->base);
- for (win = 0 ; win < WINDOWS_NR ; win++) {
- struct exynos_drm_plane *plane = &ctx->planes[win];
-
- if (!plane->pending_fb)
- continue;
-
- start = readl(ctx->regs + VIDWx_BUF_START(win, 0));
- start_s = readl(ctx->regs + VIDWx_BUF_START_S(win, 0));
- if (start == start_s)
- exynos_drm_crtc_finish_update(ctx->crtc, plane);
- }
-
if (ctx->i80_if) {
/* Exits triggering mode */
atomic_set(&ctx->triggering, 0);
return;
plane->crtc = state->crtc;
- exynos_plane->pending_fb = state->fb;
if (exynos_crtc->ops->update_plane)
exynos_crtc->ops->update_plane(exynos_crtc, exynos_plane);
static void vidi_fake_vblank_timer(unsigned long arg)
{
struct vidi_context *ctx = (void *)arg;
- int win;
if (ctx->pipe < 0)
return;
if (drm_crtc_handle_vblank(&ctx->crtc->base))
mod_timer(&ctx->timer,
jiffies + msecs_to_jiffies(VIDI_REFRESH_TIME) - 1);
-
- for (win = 0 ; win < WINDOWS_NR ; win++) {
- struct exynos_drm_plane *plane = &ctx->planes[win];
-
- if (!plane->pending_fb)
- continue;
-
- exynos_drm_crtc_finish_update(ctx->crtc, plane);
- }
}
static ssize_t vidi_show_connection(struct device *dev,
struct mixer_context *ctx = arg;
struct mixer_resources *res = &ctx->mixer_res;
u32 val, base, shadow;
- int win;
spin_lock(&res->reg_slock);
}
drm_crtc_handle_vblank(&ctx->crtc->base);
- for (win = 0 ; win < MIXER_WIN_NR ; win++) {
- struct exynos_drm_plane *plane = &ctx->planes[win];
-
- if (!plane->pending_fb)
- continue;
-
- exynos_drm_crtc_finish_update(ctx->crtc, plane);
- }
}
out: