Commit af8ad962 authored by Laurent Pinchart's avatar Laurent Pinchart

drm: rcar-du: Add VSP1 support to the planes allocator

The R8A7790 DU can source frames directly from the VSP1 devices VSPD0
and VSPD1. VSPD0 feeds DU0/1 plane 0, and VSPD1 feeds either DU2 plane 0
or DU0/1 plane 1.

Allocate the correct fixed plane when sourcing frames from VSPD0 or
VSPD1, and allocate planes in reverse index order otherwise to ensure
maximum availability of planes 0 and 1.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
parent 2f13c529
...@@ -244,11 +244,41 @@ static unsigned int rcar_du_plane_hwmask(struct rcar_du_plane_state *state) ...@@ -244,11 +244,41 @@ static unsigned int rcar_du_plane_hwmask(struct rcar_du_plane_state *state)
return mask; return mask;
} }
static int rcar_du_plane_hwalloc(unsigned int num_planes, unsigned int free) /*
* The R8A7790 DU can source frames directly from the VSP1 devices VSPD0 and
* VSPD1. VSPD0 feeds DU0/1 plane 0, and VSPD1 feeds either DU2 plane 0 or
* DU0/1 plane 1.
*
* Allocate the correct fixed plane when sourcing frames from VSPD0 or VSPD1,
* and allocate planes in reverse index order otherwise to ensure maximum
* availability of planes 0 and 1.
*
* The caller is responsible for ensuring that the requested source is
* compatible with the DU revision.
*/
static int rcar_du_plane_hwalloc(struct rcar_du_plane *plane,
struct rcar_du_plane_state *state,
unsigned int free)
{ {
unsigned int i; unsigned int num_planes = state->format->planes;
int fixed = -1;
int i;
if (state->source == RCAR_DU_PLANE_VSPD0) {
/* VSPD0 feeds plane 0 on DU0/1. */
if (plane->group->index != 0)
return -EINVAL;
fixed = 0;
} else if (state->source == RCAR_DU_PLANE_VSPD1) {
/* VSPD1 feeds plane 1 on DU0/1 or plane 0 on DU2. */
fixed = plane->group->index == 0 ? 1 : 0;
}
if (fixed >= 0)
return free & (1 << fixed) ? fixed : -EBUSY;
for (i = 0; i < RCAR_DU_NUM_HW_PLANES; ++i) { for (i = RCAR_DU_NUM_HW_PLANES - 1; i >= 0; --i) {
if (!(free & (1 << i))) if (!(free & (1 << i)))
continue; continue;
...@@ -256,7 +286,7 @@ static int rcar_du_plane_hwalloc(unsigned int num_planes, unsigned int free) ...@@ -256,7 +286,7 @@ static int rcar_du_plane_hwalloc(unsigned int num_planes, unsigned int free)
break; break;
} }
return i == RCAR_DU_NUM_HW_PLANES ? -EBUSY : i; return i < 0 ? -EBUSY : i;
} }
static int rcar_du_atomic_check(struct drm_device *dev, static int rcar_du_atomic_check(struct drm_device *dev,
...@@ -413,10 +443,10 @@ static int rcar_du_atomic_check(struct drm_device *dev, ...@@ -413,10 +443,10 @@ static int rcar_du_atomic_check(struct drm_device *dev,
: ~plane->group->dptsr_planes; : ~plane->group->dptsr_planes;
free = group_free_planes[plane->group->index]; free = group_free_planes[plane->group->index];
idx = rcar_du_plane_hwalloc(plane_state->format->planes, idx = rcar_du_plane_hwalloc(plane, plane_state,
free & crtc_planes); free & crtc_planes);
if (idx < 0) if (idx < 0)
idx = rcar_du_plane_hwalloc(plane_state->format->planes, idx = rcar_du_plane_hwalloc(plane, plane_state,
free); free);
if (idx < 0) { if (idx < 0) {
dev_dbg(rcdu->dev, "%s: no available hardware plane\n", dev_dbg(rcdu->dev, "%s: no available hardware plane\n",
......
...@@ -309,6 +309,7 @@ static void rcar_du_plane_reset(struct drm_plane *plane) ...@@ -309,6 +309,7 @@ static void rcar_du_plane_reset(struct drm_plane *plane)
return; return;
state->hwindex = -1; state->hwindex = -1;
state->source = RCAR_DU_PLANE_MEMORY;
state->alpha = 255; state->alpha = 255;
state->colorkey = RCAR_DU_COLORKEY_NONE; state->colorkey = RCAR_DU_COLORKEY_NONE;
state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1; state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
......
...@@ -28,6 +28,12 @@ struct rcar_du_group; ...@@ -28,6 +28,12 @@ struct rcar_du_group;
#define RCAR_DU_NUM_KMS_PLANES 9 #define RCAR_DU_NUM_KMS_PLANES 9
#define RCAR_DU_NUM_HW_PLANES 8 #define RCAR_DU_NUM_HW_PLANES 8
enum rcar_du_plane_source {
RCAR_DU_PLANE_MEMORY,
RCAR_DU_PLANE_VSPD0,
RCAR_DU_PLANE_VSPD1,
};
struct rcar_du_plane { struct rcar_du_plane {
struct drm_plane plane; struct drm_plane plane;
struct rcar_du_group *group; struct rcar_du_group *group;
...@@ -52,6 +58,7 @@ struct rcar_du_plane_state { ...@@ -52,6 +58,7 @@ struct rcar_du_plane_state {
const struct rcar_du_format_info *format; const struct rcar_du_format_info *format;
int hwindex; int hwindex;
enum rcar_du_plane_source source;
unsigned int alpha; unsigned int alpha;
unsigned int colorkey; unsigned int colorkey;
......
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