aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSinclair Yeh <syeh@vmware.com>2017-03-23 14:36:05 -0400
committerSinclair Yeh <syeh@vmware.com>2017-03-31 14:12:55 -0400
commitcc5ec459de323fe32514d5f47a4d00460ee30f7b (patch)
tree6d716f263c829457b9ed2618fe99599aa3492df3
parent9c2542a41f559452d570b96239a81038c49becfc (diff)
drm/vmwgfx: Plane atomic state
Add plane state handling functions. We have to keep track of a few plane states so we cannot use the DRM helper for this. Created vmw_plane_state along with functions to reset, duplicate, and destroty it. v2 * Removed cursor clean up special case Signed-off-by: Sinclair Yeh <syeh@vmware.com> Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com> Acked-by: Daniel Vetter <daniel@ffwll.ch>
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c90
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h24
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c13
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c13
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c10
5 files changed, 150 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 18bd8dc46507..ec0506794dbd 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -468,6 +468,96 @@ vmw_du_crtc_destroy_state(struct drm_crtc *crtc,
468} 468}
469 469
470 470
471/**
472 * vmw_du_plane_duplicate_state - duplicate plane state
473 * @plane: drm plane
474 *
475 * Allocates and returns a copy of the plane state (both common and
476 * vmw-specific) for the specified plane.
477 *
478 * Returns: The newly allocated plane state, or NULL on failure.
479 */
480struct drm_plane_state *
481vmw_du_plane_duplicate_state(struct drm_plane *plane)
482{
483 struct drm_plane_state *state;
484 struct vmw_plane_state *vps;
485
486 vps = kmemdup(plane->state, sizeof(*vps), GFP_KERNEL);
487
488 if (!vps)
489 return NULL;
490
491 vps->pinned = 0;
492
493 /* Each ref counted resource needs to be acquired again */
494 if (vps->surf)
495 (void) vmw_surface_reference(vps->surf);
496
497 if (vps->dmabuf)
498 (void) vmw_dmabuf_reference(vps->dmabuf);
499
500 state = &vps->base;
501
502 __drm_atomic_helper_plane_duplicate_state(plane, state);
503
504 return state;
505}
506
507
508/**
509 * vmw_du_plane_reset - creates a blank vmw plane state
510 * @plane: drm plane
511 *
512 * Resets the atomic state for @plane by freeing the state pointer (which might
513 * be NULL, e.g. at driver load time) and allocating a new empty state object.
514 */
515void vmw_du_plane_reset(struct drm_plane *plane)
516{
517 struct vmw_plane_state *vps;
518
519
520 if (plane->state)
521 vmw_du_plane_destroy_state(plane, plane->state);
522
523 vps = kzalloc(sizeof(*vps), GFP_KERNEL);
524
525 if (!vps) {
526 DRM_ERROR("Cannot allocate vmw_plane_state\n");
527 return;
528 }
529
530 plane->state = &vps->base;
531 plane->state->plane = plane;
532 plane->state->rotation = DRM_ROTATE_0;
533}
534
535
536/**
537 * vmw_du_plane_destroy_state - destroy plane state
538 * @plane: DRM plane
539 * @state: state object to destroy
540 *
541 * Destroys the plane state (both common and vmw-specific) for the
542 * specified plane.
543 */
544void
545vmw_du_plane_destroy_state(struct drm_plane *plane,
546 struct drm_plane_state *state)
547{
548 struct vmw_plane_state *vps = vmw_plane_state_to_vps(state);
549
550
551 if (vps->surf)
552 vmw_surface_unreference(&vps->surf);
553
554 if (vps->dmabuf)
555 vmw_dmabuf_unreference(&vps->dmabuf);
556
557 drm_atomic_helper_plane_destroy_state(plane, state);
558}
559
560
471/* 561/*
472 * Generic framebuffer code 562 * Generic framebuffer code
473 */ 563 */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 370f75c95f56..5602c2430719 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -141,6 +141,7 @@ static const uint32_t vmw_cursor_plane_formats[] = {
141 141
142 142
143#define vmw_crtc_state_to_vcs(x) container_of(x, struct vmw_crtc_state, base) 143#define vmw_crtc_state_to_vcs(x) container_of(x, struct vmw_crtc_state, base)
144#define vmw_plane_state_to_vps(x) container_of(x, struct vmw_plane_state, base)
144 145
145 146
146/** 147/**
@@ -153,6 +154,25 @@ struct vmw_crtc_state {
153}; 154};
154 155
155/** 156/**
157 * Derived class for plane state object
158 *
159 * @base DRM plane object
160 * @surf Display surface for STDU
161 * @dmabuf display dmabuf for SOU
162 * @content_fb_type Used by STDU.
163 * @pinned pin count for STDU display surface
164 */
165struct vmw_plane_state {
166 struct drm_plane_state base;
167 struct vmw_surface *surf;
168 struct vmw_dma_buffer *dmabuf;
169
170 int content_fb_type;
171
172 int pinned;
173};
174
175/**
156 * Base class display unit. 176 * Base class display unit.
157 * 177 *
158 * Since the SVGA hw doesn't have a concept of a crtc, encoder or connector 178 * Since the SVGA hw doesn't have a concept of a crtc, encoder or connector
@@ -298,6 +318,10 @@ int vmw_du_cursor_plane_update(struct drm_plane *plane,
298 uint32_t src_x, uint32_t src_y, 318 uint32_t src_x, uint32_t src_y,
299 uint32_t src_w, uint32_t src_h); 319 uint32_t src_w, uint32_t src_h);
300 320
321void vmw_du_plane_reset(struct drm_plane *plane);
322struct drm_plane_state *vmw_du_plane_duplicate_state(struct drm_plane *plane);
323void vmw_du_plane_destroy_state(struct drm_plane *plane,
324 struct drm_plane_state *state);
301void vmw_du_crtc_reset(struct drm_crtc *crtc); 325void vmw_du_crtc_reset(struct drm_crtc *crtc);
302struct drm_crtc_state *vmw_du_crtc_duplicate_state(struct drm_crtc *crtc); 326struct drm_crtc_state *vmw_du_crtc_duplicate_state(struct drm_crtc *crtc);
303void vmw_du_crtc_destroy_state(struct drm_crtc *crtc, 327void vmw_du_crtc_destroy_state(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index 3ee33f0234e4..36cd1fe5fa33 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -325,12 +325,18 @@ static const struct drm_plane_funcs vmw_ldu_plane_funcs = {
325 .update_plane = drm_primary_helper_update, 325 .update_plane = drm_primary_helper_update,
326 .disable_plane = drm_primary_helper_disable, 326 .disable_plane = drm_primary_helper_disable,
327 .destroy = vmw_du_primary_plane_destroy, 327 .destroy = vmw_du_primary_plane_destroy,
328 .reset = vmw_du_plane_reset,
329 .atomic_duplicate_state = vmw_du_plane_duplicate_state,
330 .atomic_destroy_state = vmw_du_plane_destroy_state,
328}; 331};
329 332
330static const struct drm_plane_funcs vmw_ldu_cursor_funcs = { 333static const struct drm_plane_funcs vmw_ldu_cursor_funcs = {
331 .update_plane = vmw_du_cursor_plane_update, 334 .update_plane = vmw_du_cursor_plane_update,
332 .disable_plane = vmw_du_cursor_plane_disable, 335 .disable_plane = vmw_du_cursor_plane_disable,
333 .destroy = vmw_du_cursor_plane_destroy, 336 .destroy = vmw_du_cursor_plane_destroy,
337 .reset = vmw_du_plane_reset,
338 .atomic_duplicate_state = vmw_du_plane_duplicate_state,
339 .atomic_destroy_state = vmw_du_plane_destroy_state,
334}; 340};
335 341
336 342
@@ -340,6 +346,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
340 struct drm_device *dev = dev_priv->dev; 346 struct drm_device *dev = dev_priv->dev;
341 struct drm_connector *connector; 347 struct drm_connector *connector;
342 struct drm_encoder *encoder; 348 struct drm_encoder *encoder;
349 struct drm_plane *primary, *cursor;
343 struct drm_crtc *crtc; 350 struct drm_crtc *crtc;
344 int ret; 351 int ret;
345 352
@@ -351,6 +358,8 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
351 crtc = &ldu->base.crtc; 358 crtc = &ldu->base.crtc;
352 encoder = &ldu->base.encoder; 359 encoder = &ldu->base.encoder;
353 connector = &ldu->base.connector; 360 connector = &ldu->base.connector;
361 primary = &ldu->base.primary;
362 cursor = &ldu->base.cursor;
354 363
355 INIT_LIST_HEAD(&ldu->active); 364 INIT_LIST_HEAD(&ldu->active);
356 365
@@ -366,6 +375,8 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
366 ldu->base.is_implicit = true; 375 ldu->base.is_implicit = true;
367 376
368 /* Initialize primary plane */ 377 /* Initialize primary plane */
378 vmw_du_plane_reset(primary);
379
369 ret = drm_universal_plane_init(dev, &ldu->base.primary, 380 ret = drm_universal_plane_init(dev, &ldu->base.primary,
370 0, &vmw_ldu_plane_funcs, 381 0, &vmw_ldu_plane_funcs,
371 vmw_primary_plane_formats, 382 vmw_primary_plane_formats,
@@ -377,6 +388,8 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
377 } 388 }
378 389
379 /* Initialize cursor plane */ 390 /* Initialize cursor plane */
391 vmw_du_plane_reset(cursor);
392
380 ret = drm_universal_plane_init(dev, &ldu->base.cursor, 393 ret = drm_universal_plane_init(dev, &ldu->base.cursor,
381 0, &vmw_ldu_cursor_funcs, 394 0, &vmw_ldu_cursor_funcs,
382 vmw_cursor_plane_formats, 395 vmw_cursor_plane_formats,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 033e17b966b1..cfba59a8e155 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -506,12 +506,18 @@ static const struct drm_plane_funcs vmw_sou_plane_funcs = {
506 .update_plane = drm_primary_helper_update, 506 .update_plane = drm_primary_helper_update,
507 .disable_plane = drm_primary_helper_disable, 507 .disable_plane = drm_primary_helper_disable,
508 .destroy = vmw_du_primary_plane_destroy, 508 .destroy = vmw_du_primary_plane_destroy,
509 .reset = vmw_du_plane_reset,
510 .atomic_duplicate_state = vmw_du_plane_duplicate_state,
511 .atomic_destroy_state = vmw_du_plane_destroy_state,
509}; 512};
510 513
511static const struct drm_plane_funcs vmw_sou_cursor_funcs = { 514static const struct drm_plane_funcs vmw_sou_cursor_funcs = {
512 .update_plane = vmw_du_cursor_plane_update, 515 .update_plane = vmw_du_cursor_plane_update,
513 .disable_plane = vmw_du_cursor_plane_disable, 516 .disable_plane = vmw_du_cursor_plane_disable,
514 .destroy = vmw_du_cursor_plane_destroy, 517 .destroy = vmw_du_cursor_plane_destroy,
518 .reset = vmw_du_plane_reset,
519 .atomic_duplicate_state = vmw_du_plane_duplicate_state,
520 .atomic_destroy_state = vmw_du_plane_destroy_state,
515}; 521};
516 522
517 523
@@ -521,6 +527,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
521 struct drm_device *dev = dev_priv->dev; 527 struct drm_device *dev = dev_priv->dev;
522 struct drm_connector *connector; 528 struct drm_connector *connector;
523 struct drm_encoder *encoder; 529 struct drm_encoder *encoder;
530 struct drm_plane *primary, *cursor;
524 struct drm_crtc *crtc; 531 struct drm_crtc *crtc;
525 int ret; 532 int ret;
526 533
@@ -532,6 +539,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
532 crtc = &sou->base.crtc; 539 crtc = &sou->base.crtc;
533 encoder = &sou->base.encoder; 540 encoder = &sou->base.encoder;
534 connector = &sou->base.connector; 541 connector = &sou->base.connector;
542 primary = &sou->base.primary;
543 cursor = &sou->base.cursor;
535 544
536 sou->base.active_implicit = false; 545 sou->base.active_implicit = false;
537 sou->base.pref_active = (unit == 0); 546 sou->base.pref_active = (unit == 0);
@@ -546,6 +555,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
546 sou->base.is_implicit = false; 555 sou->base.is_implicit = false;
547 556
548 /* Initialize primary plane */ 557 /* Initialize primary plane */
558 vmw_du_plane_reset(primary);
559
549 ret = drm_universal_plane_init(dev, &sou->base.primary, 560 ret = drm_universal_plane_init(dev, &sou->base.primary,
550 0, &vmw_sou_plane_funcs, 561 0, &vmw_sou_plane_funcs,
551 vmw_primary_plane_formats, 562 vmw_primary_plane_formats,
@@ -557,6 +568,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
557 } 568 }
558 569
559 /* Initialize cursor plane */ 570 /* Initialize cursor plane */
571 vmw_du_plane_reset(cursor);
572
560 ret = drm_universal_plane_init(dev, &sou->base.cursor, 573 ret = drm_universal_plane_init(dev, &sou->base.cursor,
561 0, &vmw_sou_cursor_funcs, 574 0, &vmw_sou_cursor_funcs,
562 vmw_cursor_plane_formats, 575 vmw_cursor_plane_formats,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index 3b8fafe1586e..2a0f550235c0 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -1090,12 +1090,18 @@ static const struct drm_plane_funcs vmw_stdu_plane_funcs = {
1090 .update_plane = drm_primary_helper_update, 1090 .update_plane = drm_primary_helper_update,
1091 .disable_plane = drm_primary_helper_disable, 1091 .disable_plane = drm_primary_helper_disable,
1092 .destroy = vmw_du_primary_plane_destroy, 1092 .destroy = vmw_du_primary_plane_destroy,
1093 .reset = vmw_du_plane_reset,
1094 .atomic_duplicate_state = vmw_du_plane_duplicate_state,
1095 .atomic_destroy_state = vmw_du_plane_destroy_state,
1093}; 1096};
1094 1097
1095static const struct drm_plane_funcs vmw_stdu_cursor_funcs = { 1098static const struct drm_plane_funcs vmw_stdu_cursor_funcs = {
1096 .update_plane = vmw_du_cursor_plane_update, 1099 .update_plane = vmw_du_cursor_plane_update,
1097 .disable_plane = vmw_du_cursor_plane_disable, 1100 .disable_plane = vmw_du_cursor_plane_disable,
1098 .destroy = vmw_du_cursor_plane_destroy, 1101 .destroy = vmw_du_cursor_plane_destroy,
1102 .reset = vmw_du_plane_reset,
1103 .atomic_duplicate_state = vmw_du_plane_duplicate_state,
1104 .atomic_destroy_state = vmw_du_plane_destroy_state,
1099}; 1105};
1100 1106
1101 1107
@@ -1142,6 +1148,8 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
1142 stdu->base.is_implicit = false; 1148 stdu->base.is_implicit = false;
1143 1149
1144 /* Initialize primary plane */ 1150 /* Initialize primary plane */
1151 vmw_du_plane_reset(primary);
1152
1145 ret = drm_universal_plane_init(dev, primary, 1153 ret = drm_universal_plane_init(dev, primary,
1146 0, &vmw_stdu_plane_funcs, 1154 0, &vmw_stdu_plane_funcs,
1147 vmw_primary_plane_formats, 1155 vmw_primary_plane_formats,
@@ -1153,6 +1161,8 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
1153 } 1161 }
1154 1162
1155 /* Initialize cursor plane */ 1163 /* Initialize cursor plane */
1164 vmw_du_plane_reset(cursor);
1165
1156 ret = drm_universal_plane_init(dev, cursor, 1166 ret = drm_universal_plane_init(dev, cursor,
1157 0, &vmw_stdu_cursor_funcs, 1167 0, &vmw_stdu_cursor_funcs,
1158 vmw_cursor_plane_formats, 1168 vmw_cursor_plane_formats,