diff options
author | Sinclair Yeh <syeh@vmware.com> | 2017-03-23 14:36:05 -0400 |
---|---|---|
committer | Sinclair Yeh <syeh@vmware.com> | 2017-03-31 14:12:55 -0400 |
commit | cc5ec459de323fe32514d5f47a4d00460ee30f7b (patch) | |
tree | 6d716f263c829457b9ed2618fe99599aa3492df3 | |
parent | 9c2542a41f559452d570b96239a81038c49becfc (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.c | 90 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 10 |
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 | */ | ||
480 | struct drm_plane_state * | ||
481 | vmw_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 | */ | ||
515 | void 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 | */ | ||
544 | void | ||
545 | vmw_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 | */ | ||
165 | struct 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 | ||
321 | void vmw_du_plane_reset(struct drm_plane *plane); | ||
322 | struct drm_plane_state *vmw_du_plane_duplicate_state(struct drm_plane *plane); | ||
323 | void vmw_du_plane_destroy_state(struct drm_plane *plane, | ||
324 | struct drm_plane_state *state); | ||
301 | void vmw_du_crtc_reset(struct drm_crtc *crtc); | 325 | void vmw_du_crtc_reset(struct drm_crtc *crtc); |
302 | struct drm_crtc_state *vmw_du_crtc_duplicate_state(struct drm_crtc *crtc); | 326 | struct drm_crtc_state *vmw_du_crtc_duplicate_state(struct drm_crtc *crtc); |
303 | void vmw_du_crtc_destroy_state(struct drm_crtc *crtc, | 327 | void 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 | ||
330 | static const struct drm_plane_funcs vmw_ldu_cursor_funcs = { | 333 | static 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 | ||
511 | static const struct drm_plane_funcs vmw_sou_cursor_funcs = { | 514 | static 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 | ||
1095 | static const struct drm_plane_funcs vmw_stdu_cursor_funcs = { | 1098 | static 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, |