5e0594fd77
The driver recently switched from handling page flip completion in the
DU vertical blanking handler to the VSP frame end handler to fix a race
condition. This unfortunately resulted in incorrect timestamps in the
vertical blanking events sent to userspace as vertical blanking is now
handled after sending the event.
To fix this we must reverse the order of the two operations. The easiest
way is to handle vertical blanking in the VSP frame end handler before
sending the event. The VSP frame end interrupt occurs approximately 50µs
earlier than the DU frame end interrupt, but this should not cause any
undue harm.
As we need to handle vertical blanking even when page flip completion is
delayed, the VSP driver now needs to call the frame end completion
callback unconditionally, with a new argument to report whether page
flip has completed.
With this new scheme the DU vertical blanking interrupt isn't needed
anymore, so we can stop enabling it.
Fixes: d503a43ac0
("drm: rcar-du: Register a completion callback with VSP1")
Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
63 lines
1.8 KiB
C
63 lines
1.8 KiB
C
/*
|
|
* vsp1.h -- R-Car VSP1 API
|
|
*
|
|
* Copyright (C) 2015 Renesas Electronics Corporation
|
|
*
|
|
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*/
|
|
#ifndef __MEDIA_VSP1_H__
|
|
#define __MEDIA_VSP1_H__
|
|
|
|
#include <linux/scatterlist.h>
|
|
#include <linux/types.h>
|
|
#include <linux/videodev2.h>
|
|
|
|
struct device;
|
|
|
|
int vsp1_du_init(struct device *dev);
|
|
|
|
/**
|
|
* struct vsp1_du_lif_config - VSP LIF configuration
|
|
* @width: output frame width
|
|
* @height: output frame height
|
|
* @callback: frame completion callback function (optional). When a callback
|
|
* is provided, the VSP driver guarantees that it will be called once
|
|
* and only once for each vsp1_du_atomic_flush() call.
|
|
* @callback_data: data to be passed to the frame completion callback
|
|
*/
|
|
struct vsp1_du_lif_config {
|
|
unsigned int width;
|
|
unsigned int height;
|
|
|
|
void (*callback)(void *, bool);
|
|
void *callback_data;
|
|
};
|
|
|
|
int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
|
|
const struct vsp1_du_lif_config *cfg);
|
|
|
|
struct vsp1_du_atomic_config {
|
|
u32 pixelformat;
|
|
unsigned int pitch;
|
|
dma_addr_t mem[3];
|
|
struct v4l2_rect src;
|
|
struct v4l2_rect dst;
|
|
unsigned int alpha;
|
|
unsigned int zpos;
|
|
};
|
|
|
|
void vsp1_du_atomic_begin(struct device *dev, unsigned int pipe_index);
|
|
int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
|
|
unsigned int rpf,
|
|
const struct vsp1_du_atomic_config *cfg);
|
|
void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index);
|
|
int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
|
|
void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
|
|
|
|
#endif /* __MEDIA_VSP1_H__ */
|