Commit 4407cc02 authored by Laurent Pinchart's avatar Laurent Pinchart

drm: rcar-du: Switch plane set_property to atomic helpers

Allow setting up plane properties atomically using the plane
set_property atomic helper. The properties are now stored in the plane
state (requiring subclassing it) and applied when updating the planes.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
parent d5746642
...@@ -193,7 +193,12 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc, ...@@ -193,7 +193,12 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
rcdu->dpad0_source = rcrtc->index; rcdu->dpad0_source = rcrtc->index;
} }
void rcar_du_crtc_update_planes(struct drm_crtc *crtc) static unsigned int plane_zpos(struct rcar_du_plane *plane)
{
return to_rcar_du_plane_state(plane->plane.state)->zpos;
}
static void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
{ {
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES]; struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES];
...@@ -212,7 +217,7 @@ void rcar_du_crtc_update_planes(struct drm_crtc *crtc) ...@@ -212,7 +217,7 @@ void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
/* Insert the plane in the sorted planes array. */ /* Insert the plane in the sorted planes array. */
for (j = num_planes++; j > 0; --j) { for (j = num_planes++; j > 0; --j) {
if (planes[j-1]->zpos <= plane->zpos) if (plane_zpos(planes[j-1]) <= plane_zpos(plane))
break; break;
planes[j] = planes[j-1]; planes[j] = planes[j-1];
} }
......
...@@ -62,6 +62,5 @@ void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc); ...@@ -62,6 +62,5 @@ void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc);
void rcar_du_crtc_route_output(struct drm_crtc *crtc, void rcar_du_crtc_route_output(struct drm_crtc *crtc,
enum rcar_du_output output); enum rcar_du_output output);
void rcar_du_crtc_update_planes(struct drm_crtc *crtc);
#endif /* __RCAR_DU_CRTC_H__ */ #endif /* __RCAR_DU_CRTC_H__ */
...@@ -201,6 +201,8 @@ static void rcar_du_plane_compute_base(struct rcar_du_plane *plane, ...@@ -201,6 +201,8 @@ static void rcar_du_plane_compute_base(struct rcar_du_plane *plane,
static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane,
unsigned int index) unsigned int index)
{ {
struct rcar_du_plane_state *state =
to_rcar_du_plane_state(plane->plane.state);
struct rcar_du_group *rgrp = plane->group; struct rcar_du_group *rgrp = plane->group;
u32 colorkey; u32 colorkey;
u32 pnmr; u32 pnmr;
...@@ -218,7 +220,7 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, ...@@ -218,7 +220,7 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane,
rcar_du_plane_write(rgrp, index, PnALPHAR, PnALPHAR_ABIT_0); rcar_du_plane_write(rgrp, index, PnALPHAR, PnALPHAR_ABIT_0);
else else
rcar_du_plane_write(rgrp, index, PnALPHAR, rcar_du_plane_write(rgrp, index, PnALPHAR,
PnALPHAR_ABIT_X | plane->alpha); PnALPHAR_ABIT_X | state->alpha);
pnmr = PnMR_BM_MD | plane->format->pnmr; pnmr = PnMR_BM_MD | plane->format->pnmr;
...@@ -226,7 +228,7 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, ...@@ -226,7 +228,7 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane,
* PnMR_SPIM_TP_OFF bit set in their pnmr field, disabling color keying * PnMR_SPIM_TP_OFF bit set in their pnmr field, disabling color keying
* automatically. * automatically.
*/ */
if ((plane->colorkey & RCAR_DU_COLORKEY_MASK) == RCAR_DU_COLORKEY_NONE) if ((state->colorkey & RCAR_DU_COLORKEY_MASK) == RCAR_DU_COLORKEY_NONE)
pnmr |= PnMR_SPIM_TP_OFF; pnmr |= PnMR_SPIM_TP_OFF;
/* For packed YUV formats we need to select the U/V order. */ /* For packed YUV formats we need to select the U/V order. */
...@@ -237,24 +239,24 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, ...@@ -237,24 +239,24 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane,
switch (plane->format->fourcc) { switch (plane->format->fourcc) {
case DRM_FORMAT_RGB565: case DRM_FORMAT_RGB565:
colorkey = ((plane->colorkey & 0xf80000) >> 8) colorkey = ((state->colorkey & 0xf80000) >> 8)
| ((plane->colorkey & 0x00fc00) >> 5) | ((state->colorkey & 0x00fc00) >> 5)
| ((plane->colorkey & 0x0000f8) >> 3); | ((state->colorkey & 0x0000f8) >> 3);
rcar_du_plane_write(rgrp, index, PnTC2R, colorkey); rcar_du_plane_write(rgrp, index, PnTC2R, colorkey);
break; break;
case DRM_FORMAT_ARGB1555: case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_XRGB1555: case DRM_FORMAT_XRGB1555:
colorkey = ((plane->colorkey & 0xf80000) >> 9) colorkey = ((state->colorkey & 0xf80000) >> 9)
| ((plane->colorkey & 0x00f800) >> 6) | ((state->colorkey & 0x00f800) >> 6)
| ((plane->colorkey & 0x0000f8) >> 3); | ((state->colorkey & 0x0000f8) >> 3);
rcar_du_plane_write(rgrp, index, PnTC2R, colorkey); rcar_du_plane_write(rgrp, index, PnTC2R, colorkey);
break; break;
case DRM_FORMAT_XRGB8888: case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_ARGB8888: case DRM_FORMAT_ARGB8888:
rcar_du_plane_write(rgrp, index, PnTC3R, rcar_du_plane_write(rgrp, index, PnTC3R,
PnTC3R_CODE | (plane->colorkey & 0xffffff)); PnTC3R_CODE | (state->colorkey & 0xffffff));
break; break;
} }
} }
...@@ -414,65 +416,87 @@ static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = { ...@@ -414,65 +416,87 @@ static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = {
.atomic_update = rcar_du_plane_atomic_update, .atomic_update = rcar_du_plane_atomic_update,
}; };
/* Both the .set_property and the .update_plane operations are called with the static void rcar_du_plane_reset(struct drm_plane *plane)
* mode_config lock held. There is this no need to explicitly protect access to
* the alpha and colorkey fields and the mode register.
*/
static void rcar_du_plane_set_alpha(struct rcar_du_plane *plane, u32 alpha)
{ {
if (plane->alpha == alpha) struct rcar_du_plane_state *state;
return;
if (plane->state && plane->state->fb)
drm_framebuffer_unreference(plane->state->fb);
plane->alpha = alpha; kfree(plane->state);
if (!plane->enabled || plane->format->fourcc != DRM_FORMAT_XRGB1555) plane->state = NULL;
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (state == NULL)
return; return;
rcar_du_plane_setup_mode(plane, plane->hwindex); state->alpha = 255;
state->colorkey = RCAR_DU_COLORKEY_NONE;
state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
plane->state = &state->state;
plane->state->plane = plane;
} }
static void rcar_du_plane_set_colorkey(struct rcar_du_plane *plane, static struct drm_plane_state *
u32 colorkey) rcar_du_plane_atomic_duplicate_state(struct drm_plane *plane)
{ {
if (plane->colorkey == colorkey) struct rcar_du_plane_state *state;
return; struct rcar_du_plane_state *copy;
plane->colorkey = colorkey; state = to_rcar_du_plane_state(plane->state);
if (!plane->enabled) copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
return; if (copy == NULL)
return NULL;
if (copy->state.fb)
drm_framebuffer_reference(copy->state.fb);
rcar_du_plane_setup_mode(plane, plane->hwindex); return &copy->state;
} }
static void rcar_du_plane_set_zpos(struct rcar_du_plane *plane, static void rcar_du_plane_atomic_destroy_state(struct drm_plane *plane,
unsigned int zpos) struct drm_plane_state *state)
{ {
mutex_lock(&plane->group->planes.lock); kfree(to_rcar_du_plane_state(state));
if (plane->zpos == zpos) }
goto done;
plane->zpos = zpos; static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
if (!plane->enabled) struct drm_plane_state *state,
goto done; struct drm_property *property,
uint64_t val)
{
struct rcar_du_plane_state *rstate = to_rcar_du_plane_state(state);
struct rcar_du_plane *rplane = to_rcar_plane(plane);
struct rcar_du_group *rgrp = rplane->group;
rcar_du_crtc_update_planes(plane->crtc); if (property == rgrp->planes.alpha)
rstate->alpha = val;
else if (property == rgrp->planes.colorkey)
rstate->colorkey = val;
else if (property == rgrp->planes.zpos)
rstate->zpos = val;
else
return -EINVAL;
done: return 0;
mutex_unlock(&plane->group->planes.lock);
} }
static int rcar_du_plane_set_property(struct drm_plane *plane, static int rcar_du_plane_atomic_get_property(struct drm_plane *plane,
struct drm_property *property, const struct drm_plane_state *state, struct drm_property *property,
uint64_t value) uint64_t *val)
{ {
const struct rcar_du_plane_state *rstate =
container_of(state, const struct rcar_du_plane_state, state);
struct rcar_du_plane *rplane = to_rcar_plane(plane); struct rcar_du_plane *rplane = to_rcar_plane(plane);
struct rcar_du_group *rgrp = rplane->group; struct rcar_du_group *rgrp = rplane->group;
if (property == rgrp->planes.alpha) if (property == rgrp->planes.alpha)
rcar_du_plane_set_alpha(rplane, value); *val = rstate->alpha;
else if (property == rgrp->planes.colorkey) else if (property == rgrp->planes.colorkey)
rcar_du_plane_set_colorkey(rplane, value); *val = rstate->colorkey;
else if (property == rgrp->planes.zpos) else if (property == rgrp->planes.zpos)
rcar_du_plane_set_zpos(rplane, value); *val = rstate->zpos;
else else
return -EINVAL; return -EINVAL;
...@@ -482,11 +506,13 @@ static int rcar_du_plane_set_property(struct drm_plane *plane, ...@@ -482,11 +506,13 @@ static int rcar_du_plane_set_property(struct drm_plane *plane,
static const struct drm_plane_funcs rcar_du_plane_funcs = { static const struct drm_plane_funcs rcar_du_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane, .update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane, .disable_plane = drm_atomic_helper_disable_plane,
.reset = drm_atomic_helper_plane_reset, .reset = rcar_du_plane_reset,
.set_property = rcar_du_plane_set_property, .set_property = drm_atomic_helper_plane_set_property,
.destroy = drm_plane_cleanup, .destroy = drm_plane_cleanup,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state, .atomic_destroy_state = rcar_du_plane_atomic_destroy_state,
.atomic_set_property = rcar_du_plane_atomic_set_property,
.atomic_get_property = rcar_du_plane_atomic_get_property,
}; };
static const uint32_t formats[] = { static const uint32_t formats[] = {
...@@ -551,9 +577,6 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp) ...@@ -551,9 +577,6 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
plane->group = rgrp; plane->group = rgrp;
plane->hwindex = -1; plane->hwindex = -1;
plane->alpha = 255;
plane->colorkey = RCAR_DU_COLORKEY_NONE;
plane->zpos = type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs, ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
&rcar_du_plane_funcs, formats, &rcar_du_plane_funcs, formats,
......
...@@ -39,9 +39,6 @@ struct rcar_du_plane { ...@@ -39,9 +39,6 @@ struct rcar_du_plane {
bool enabled; bool enabled;
int hwindex; /* 0-based, -1 means unused */ int hwindex; /* 0-based, -1 means unused */
unsigned int alpha;
unsigned int colorkey;
unsigned int zpos;
const struct rcar_du_format_info *format; const struct rcar_du_format_info *format;
...@@ -59,6 +56,20 @@ struct rcar_du_planes { ...@@ -59,6 +56,20 @@ struct rcar_du_planes {
struct drm_property *zpos; struct drm_property *zpos;
}; };
struct rcar_du_plane_state {
struct drm_plane_state state;
unsigned int alpha;
unsigned int colorkey;
unsigned int zpos;
};
static inline struct rcar_du_plane_state *
to_rcar_du_plane_state(struct drm_plane_state *state)
{
return container_of(state, struct rcar_du_plane_state, state);
}
int rcar_du_planes_init(struct rcar_du_group *rgrp); int rcar_du_planes_init(struct rcar_du_group *rgrp);
void rcar_du_plane_setup(struct rcar_du_plane *plane); void rcar_du_plane_setup(struct rcar_du_plane *plane);
......
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