aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2015-02-22 19:36:31 -0500
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2015-03-03 09:16:23 -0500
commit4407cc02c9251b0ce6bad3718211353a7dba93ef (patch)
tree63bf492797632e4d679aae3fd75bf9d66c4f3197
parentd5746642f480c134e8e76a3104b987c08f790283 (diff)
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: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c9
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.h1
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c125
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.h17
4 files changed, 95 insertions, 57 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 2a1119b52c2a..faa46ed23a62 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -193,7 +193,12 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc,
193 rcdu->dpad0_source = rcrtc->index; 193 rcdu->dpad0_source = rcrtc->index;
194} 194}
195 195
196void rcar_du_crtc_update_planes(struct drm_crtc *crtc) 196static unsigned int plane_zpos(struct rcar_du_plane *plane)
197{
198 return to_rcar_du_plane_state(plane->plane.state)->zpos;
199}
200
201static void rcar_du_crtc_update_planes(struct drm_crtc *crtc)
197{ 202{
198 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); 203 struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
199 struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES]; 204 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 217
213 /* Insert the plane in the sorted planes array. */ 218 /* Insert the plane in the sorted planes array. */
214 for (j = num_planes++; j > 0; --j) { 219 for (j = num_planes++; j > 0; --j) {
215 if (planes[j-1]->zpos <= plane->zpos) 220 if (plane_zpos(planes[j-1]) <= plane_zpos(plane))
216 break; 221 break;
217 planes[j] = planes[j-1]; 222 planes[j] = planes[j-1];
218 } 223 }
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index f50fbafd609f..0a3dcca58fd7 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -62,6 +62,5 @@ void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc);
62 62
63void rcar_du_crtc_route_output(struct drm_crtc *crtc, 63void rcar_du_crtc_route_output(struct drm_crtc *crtc,
64 enum rcar_du_output output); 64 enum rcar_du_output output);
65void rcar_du_crtc_update_planes(struct drm_crtc *crtc);
66 65
67#endif /* __RCAR_DU_CRTC_H__ */ 66#endif /* __RCAR_DU_CRTC_H__ */
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 9176ac451438..7e0e2731ea27 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -201,6 +201,8 @@ static void rcar_du_plane_compute_base(struct rcar_du_plane *plane,
201static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, 201static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane,
202 unsigned int index) 202 unsigned int index)
203{ 203{
204 struct rcar_du_plane_state *state =
205 to_rcar_du_plane_state(plane->plane.state);
204 struct rcar_du_group *rgrp = plane->group; 206 struct rcar_du_group *rgrp = plane->group;
205 u32 colorkey; 207 u32 colorkey;
206 u32 pnmr; 208 u32 pnmr;
@@ -218,7 +220,7 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane,
218 rcar_du_plane_write(rgrp, index, PnALPHAR, PnALPHAR_ABIT_0); 220 rcar_du_plane_write(rgrp, index, PnALPHAR, PnALPHAR_ABIT_0);
219 else 221 else
220 rcar_du_plane_write(rgrp, index, PnALPHAR, 222 rcar_du_plane_write(rgrp, index, PnALPHAR,
221 PnALPHAR_ABIT_X | plane->alpha); 223 PnALPHAR_ABIT_X | state->alpha);
222 224
223 pnmr = PnMR_BM_MD | plane->format->pnmr; 225 pnmr = PnMR_BM_MD | plane->format->pnmr;
224 226
@@ -226,7 +228,7 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane,
226 * PnMR_SPIM_TP_OFF bit set in their pnmr field, disabling color keying 228 * PnMR_SPIM_TP_OFF bit set in their pnmr field, disabling color keying
227 * automatically. 229 * automatically.
228 */ 230 */
229 if ((plane->colorkey & RCAR_DU_COLORKEY_MASK) == RCAR_DU_COLORKEY_NONE) 231 if ((state->colorkey & RCAR_DU_COLORKEY_MASK) == RCAR_DU_COLORKEY_NONE)
230 pnmr |= PnMR_SPIM_TP_OFF; 232 pnmr |= PnMR_SPIM_TP_OFF;
231 233
232 /* For packed YUV formats we need to select the U/V order. */ 234 /* 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 239
238 switch (plane->format->fourcc) { 240 switch (plane->format->fourcc) {
239 case DRM_FORMAT_RGB565: 241 case DRM_FORMAT_RGB565:
240 colorkey = ((plane->colorkey & 0xf80000) >> 8) 242 colorkey = ((state->colorkey & 0xf80000) >> 8)
241 | ((plane->colorkey & 0x00fc00) >> 5) 243 | ((state->colorkey & 0x00fc00) >> 5)
242 | ((plane->colorkey & 0x0000f8) >> 3); 244 | ((state->colorkey & 0x0000f8) >> 3);
243 rcar_du_plane_write(rgrp, index, PnTC2R, colorkey); 245 rcar_du_plane_write(rgrp, index, PnTC2R, colorkey);
244 break; 246 break;
245 247
246 case DRM_FORMAT_ARGB1555: 248 case DRM_FORMAT_ARGB1555:
247 case DRM_FORMAT_XRGB1555: 249 case DRM_FORMAT_XRGB1555:
248 colorkey = ((plane->colorkey & 0xf80000) >> 9) 250 colorkey = ((state->colorkey & 0xf80000) >> 9)
249 | ((plane->colorkey & 0x00f800) >> 6) 251 | ((state->colorkey & 0x00f800) >> 6)
250 | ((plane->colorkey & 0x0000f8) >> 3); 252 | ((state->colorkey & 0x0000f8) >> 3);
251 rcar_du_plane_write(rgrp, index, PnTC2R, colorkey); 253 rcar_du_plane_write(rgrp, index, PnTC2R, colorkey);
252 break; 254 break;
253 255
254 case DRM_FORMAT_XRGB8888: 256 case DRM_FORMAT_XRGB8888:
255 case DRM_FORMAT_ARGB8888: 257 case DRM_FORMAT_ARGB8888:
256 rcar_du_plane_write(rgrp, index, PnTC3R, 258 rcar_du_plane_write(rgrp, index, PnTC3R,
257 PnTC3R_CODE | (plane->colorkey & 0xffffff)); 259 PnTC3R_CODE | (state->colorkey & 0xffffff));
258 break; 260 break;
259 } 261 }
260} 262}
@@ -414,65 +416,87 @@ static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = {
414 .atomic_update = rcar_du_plane_atomic_update, 416 .atomic_update = rcar_du_plane_atomic_update,
415}; 417};
416 418
417/* Both the .set_property and the .update_plane operations are called with the 419static void rcar_du_plane_reset(struct drm_plane *plane)
418 * mode_config lock held. There is this no need to explicitly protect access to
419 * the alpha and colorkey fields and the mode register.
420 */
421static void rcar_du_plane_set_alpha(struct rcar_du_plane *plane, u32 alpha)
422{ 420{
423 if (plane->alpha == alpha) 421 struct rcar_du_plane_state *state;
424 return; 422
423 if (plane->state && plane->state->fb)
424 drm_framebuffer_unreference(plane->state->fb);
425 425
426 plane->alpha = alpha; 426 kfree(plane->state);
427 if (!plane->enabled || plane->format->fourcc != DRM_FORMAT_XRGB1555) 427 plane->state = NULL;
428
429 state = kzalloc(sizeof(*state), GFP_KERNEL);
430 if (state == NULL)
428 return; 431 return;
429 432
430 rcar_du_plane_setup_mode(plane, plane->hwindex); 433 state->alpha = 255;
434 state->colorkey = RCAR_DU_COLORKEY_NONE;
435 state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
436
437 plane->state = &state->state;
438 plane->state->plane = plane;
431} 439}
432 440
433static void rcar_du_plane_set_colorkey(struct rcar_du_plane *plane, 441static struct drm_plane_state *
434 u32 colorkey) 442rcar_du_plane_atomic_duplicate_state(struct drm_plane *plane)
435{ 443{
436 if (plane->colorkey == colorkey) 444 struct rcar_du_plane_state *state;
437 return; 445 struct rcar_du_plane_state *copy;
438 446
439 plane->colorkey = colorkey; 447 state = to_rcar_du_plane_state(plane->state);
440 if (!plane->enabled) 448 copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
441 return; 449 if (copy == NULL)
450 return NULL;
451
452 if (copy->state.fb)
453 drm_framebuffer_reference(copy->state.fb);
442 454
443 rcar_du_plane_setup_mode(plane, plane->hwindex); 455 return &copy->state;
444} 456}
445 457
446static void rcar_du_plane_set_zpos(struct rcar_du_plane *plane, 458static void rcar_du_plane_atomic_destroy_state(struct drm_plane *plane,
447 unsigned int zpos) 459 struct drm_plane_state *state)
448{ 460{
449 mutex_lock(&plane->group->planes.lock); 461 kfree(to_rcar_du_plane_state(state));
450 if (plane->zpos == zpos) 462}
451 goto done;
452 463
453 plane->zpos = zpos; 464static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
454 if (!plane->enabled) 465 struct drm_plane_state *state,
455 goto done; 466 struct drm_property *property,
467 uint64_t val)
468{
469 struct rcar_du_plane_state *rstate = to_rcar_du_plane_state(state);
470 struct rcar_du_plane *rplane = to_rcar_plane(plane);
471 struct rcar_du_group *rgrp = rplane->group;
456 472
457 rcar_du_crtc_update_planes(plane->crtc); 473 if (property == rgrp->planes.alpha)
474 rstate->alpha = val;
475 else if (property == rgrp->planes.colorkey)
476 rstate->colorkey = val;
477 else if (property == rgrp->planes.zpos)
478 rstate->zpos = val;
479 else
480 return -EINVAL;
458 481
459done: 482 return 0;
460 mutex_unlock(&plane->group->planes.lock);
461} 483}
462 484
463static int rcar_du_plane_set_property(struct drm_plane *plane, 485static int rcar_du_plane_atomic_get_property(struct drm_plane *plane,
464 struct drm_property *property, 486 const struct drm_plane_state *state, struct drm_property *property,
465 uint64_t value) 487 uint64_t *val)
466{ 488{
489 const struct rcar_du_plane_state *rstate =
490 container_of(state, const struct rcar_du_plane_state, state);
467 struct rcar_du_plane *rplane = to_rcar_plane(plane); 491 struct rcar_du_plane *rplane = to_rcar_plane(plane);
468 struct rcar_du_group *rgrp = rplane->group; 492 struct rcar_du_group *rgrp = rplane->group;
469 493
470 if (property == rgrp->planes.alpha) 494 if (property == rgrp->planes.alpha)
471 rcar_du_plane_set_alpha(rplane, value); 495 *val = rstate->alpha;
472 else if (property == rgrp->planes.colorkey) 496 else if (property == rgrp->planes.colorkey)
473 rcar_du_plane_set_colorkey(rplane, value); 497 *val = rstate->colorkey;
474 else if (property == rgrp->planes.zpos) 498 else if (property == rgrp->planes.zpos)
475 rcar_du_plane_set_zpos(rplane, value); 499 *val = rstate->zpos;
476 else 500 else
477 return -EINVAL; 501 return -EINVAL;
478 502
@@ -482,11 +506,13 @@ static int rcar_du_plane_set_property(struct drm_plane *plane,
482static const struct drm_plane_funcs rcar_du_plane_funcs = { 506static const struct drm_plane_funcs rcar_du_plane_funcs = {
483 .update_plane = drm_atomic_helper_update_plane, 507 .update_plane = drm_atomic_helper_update_plane,
484 .disable_plane = drm_atomic_helper_disable_plane, 508 .disable_plane = drm_atomic_helper_disable_plane,
485 .reset = drm_atomic_helper_plane_reset, 509 .reset = rcar_du_plane_reset,
486 .set_property = rcar_du_plane_set_property, 510 .set_property = drm_atomic_helper_plane_set_property,
487 .destroy = drm_plane_cleanup, 511 .destroy = drm_plane_cleanup,
488 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 512 .atomic_duplicate_state = rcar_du_plane_atomic_duplicate_state,
489 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 513 .atomic_destroy_state = rcar_du_plane_atomic_destroy_state,
514 .atomic_set_property = rcar_du_plane_atomic_set_property,
515 .atomic_get_property = rcar_du_plane_atomic_get_property,
490}; 516};
491 517
492static const uint32_t formats[] = { 518static const uint32_t formats[] = {
@@ -551,9 +577,6 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
551 577
552 plane->group = rgrp; 578 plane->group = rgrp;
553 plane->hwindex = -1; 579 plane->hwindex = -1;
554 plane->alpha = 255;
555 plane->colorkey = RCAR_DU_COLORKEY_NONE;
556 plane->zpos = type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
557 580
558 ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs, 581 ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
559 &rcar_du_plane_funcs, formats, 582 &rcar_du_plane_funcs, formats,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
index 9b77a638863f..d291e85896ef 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
@@ -39,9 +39,6 @@ struct rcar_du_plane {
39 bool enabled; 39 bool enabled;
40 40
41 int hwindex; /* 0-based, -1 means unused */ 41 int hwindex; /* 0-based, -1 means unused */
42 unsigned int alpha;
43 unsigned int colorkey;
44 unsigned int zpos;
45 42
46 const struct rcar_du_format_info *format; 43 const struct rcar_du_format_info *format;
47 44
@@ -59,6 +56,20 @@ struct rcar_du_planes {
59 struct drm_property *zpos; 56 struct drm_property *zpos;
60}; 57};
61 58
59struct rcar_du_plane_state {
60 struct drm_plane_state state;
61
62 unsigned int alpha;
63 unsigned int colorkey;
64 unsigned int zpos;
65};
66
67static inline struct rcar_du_plane_state *
68to_rcar_du_plane_state(struct drm_plane_state *state)
69{
70 return container_of(state, struct rcar_du_plane_state, state);
71}
72
62int rcar_du_planes_init(struct rcar_du_group *rgrp); 73int rcar_du_planes_init(struct rcar_du_group *rgrp);
63 74
64void rcar_du_plane_setup(struct rcar_du_plane *plane); 75void rcar_du_plane_setup(struct rcar_du_plane *plane);