xref: /linux/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c (revision e511e08a9f496948b13aac50610f2d17335f56c3)
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /******************************************************************************
3  *
4  * COPYRIGHT (C) 2014-2023 VMware, Inc., Palo Alto, CA., USA
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  ******************************************************************************/
27 
28 #include "vmwgfx_bo.h"
29 #include "vmwgfx_kms.h"
30 #include "vmwgfx_vkms.h"
31 #include "vmw_surface_cache.h"
32 
33 #include <drm/drm_atomic.h>
34 #include <drm/drm_atomic_helper.h>
35 #include <drm/drm_damage_helper.h>
36 #include <drm/drm_fourcc.h>
37 #include <drm/drm_vblank.h>
38 
39 #define vmw_crtc_to_stdu(x) \
40 	container_of(x, struct vmw_screen_target_display_unit, base.crtc)
41 #define vmw_encoder_to_stdu(x) \
42 	container_of(x, struct vmw_screen_target_display_unit, base.encoder)
43 #define vmw_connector_to_stdu(x) \
44 	container_of(x, struct vmw_screen_target_display_unit, base.connector)
45 
46 
47 
48 enum stdu_content_type {
49 	SAME_AS_DISPLAY = 0,
50 	SEPARATE_SURFACE,
51 	SEPARATE_BO
52 };
53 
54 /**
55  * struct vmw_stdu_dirty - closure structure for the update functions
56  *
57  * @base: The base type we derive from. Used by vmw_kms_helper_dirty().
58  * @left: Left side of bounding box.
59  * @right: Right side of bounding box.
60  * @top: Top side of bounding box.
61  * @bottom: Bottom side of bounding box.
62  * @fb_left: Left side of the framebuffer/content bounding box
63  * @fb_top: Top of the framebuffer/content bounding box
64  * @pitch: framebuffer pitch (stride)
65  * @buf: buffer object when DMA-ing between buffer and screen targets.
66  * @sid: Surface ID when copying between surface and screen targets.
67  */
68 struct vmw_stdu_dirty {
69 	struct vmw_kms_dirty base;
70 	s32 left, right, top, bottom;
71 	s32 fb_left, fb_top;
72 	u32 pitch;
73 	union {
74 		struct vmw_bo *buf;
75 		u32 sid;
76 	};
77 };
78 
79 /*
80  * SVGA commands that are used by this code. Please see the device headers
81  * for explanation.
82  */
83 struct vmw_stdu_update {
84 	SVGA3dCmdHeader header;
85 	SVGA3dCmdUpdateGBScreenTarget body;
86 };
87 
88 struct vmw_stdu_dma {
89 	SVGA3dCmdHeader     header;
90 	SVGA3dCmdSurfaceDMA body;
91 };
92 
93 struct vmw_stdu_surface_copy {
94 	SVGA3dCmdHeader      header;
95 	SVGA3dCmdSurfaceCopy body;
96 };
97 
98 struct vmw_stdu_update_gb_image {
99 	SVGA3dCmdHeader header;
100 	SVGA3dCmdUpdateGBImage body;
101 };
102 
103 /**
104  * struct vmw_screen_target_display_unit - conglomerated STDU structure
105  *
106  * @base: VMW specific DU structure
107  * @display_srf: surface to be displayed.  The dimension of this will always
108  *               match the display mode.  If the display mode matches
109  *               content_vfbs dimensions, then this is a pointer into the
110  *               corresponding field in content_vfbs.  If not, then this
111  *               is a separate buffer to which content_vfbs will blit to.
112  * @content_fb_type: content_fb type
113  * @display_width:  display width
114  * @display_height: display height
115  * @defined:     true if the current display unit has been initialized
116  * @cpp:         Bytes per pixel
117  */
118 struct vmw_screen_target_display_unit {
119 	struct vmw_display_unit base;
120 	struct vmw_surface *display_srf;
121 	enum stdu_content_type content_fb_type;
122 	s32 display_width, display_height;
123 
124 	bool defined;
125 
126 	/* For CPU Blit */
127 	unsigned int cpp;
128 };
129 
130 
131 
132 static void vmw_stdu_destroy(struct vmw_screen_target_display_unit *stdu);
133 
134 
135 
136 /******************************************************************************
137  * Screen Target Display Unit CRTC Functions
138  *****************************************************************************/
139 
140 /**
141  * vmw_stdu_crtc_destroy - cleans up the STDU
142  *
143  * @crtc: used to get a reference to the containing STDU
144  */
145 static void vmw_stdu_crtc_destroy(struct drm_crtc *crtc)
146 {
147 	vmw_stdu_destroy(vmw_crtc_to_stdu(crtc));
148 }
149 
150 /**
151  * vmw_stdu_define_st - Defines a Screen Target
152  *
153  * @dev_priv:  VMW DRM device
154  * @stdu: display unit to create a Screen Target for
155  * @mode: The mode to set.
156  * @crtc_x: X coordinate of screen target relative to framebuffer origin.
157  * @crtc_y: Y coordinate of screen target relative to framebuffer origin.
158  *
159  * Creates a STDU that we can used later.  This function is called whenever the
160  * framebuffer size changes.
161  *
162  * RETURNs:
163  * 0 on success, error code on failure
164  */
165 static int vmw_stdu_define_st(struct vmw_private *dev_priv,
166 			      struct vmw_screen_target_display_unit *stdu,
167 			      struct drm_display_mode *mode,
168 			      int crtc_x, int crtc_y)
169 {
170 	struct {
171 		SVGA3dCmdHeader header;
172 		SVGA3dCmdDefineGBScreenTarget body;
173 	} *cmd;
174 
175 	cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
176 	if (unlikely(cmd == NULL))
177 		return -ENOMEM;
178 
179 	cmd->header.id   = SVGA_3D_CMD_DEFINE_GB_SCREENTARGET;
180 	cmd->header.size = sizeof(cmd->body);
181 
182 	cmd->body.stid   = stdu->base.unit;
183 	cmd->body.width  = mode->hdisplay;
184 	cmd->body.height = mode->vdisplay;
185 	cmd->body.flags  = (0 == cmd->body.stid) ? SVGA_STFLAG_PRIMARY : 0;
186 	cmd->body.dpi    = 0;
187 	cmd->body.xRoot  = crtc_x;
188 	cmd->body.yRoot  = crtc_y;
189 
190 	stdu->base.set_gui_x = cmd->body.xRoot;
191 	stdu->base.set_gui_y = cmd->body.yRoot;
192 
193 	vmw_cmd_commit(dev_priv, sizeof(*cmd));
194 
195 	stdu->defined = true;
196 	stdu->display_width  = mode->hdisplay;
197 	stdu->display_height = mode->vdisplay;
198 
199 	return 0;
200 }
201 
202 
203 
204 /**
205  * vmw_stdu_bind_st - Binds a surface to a Screen Target
206  *
207  * @dev_priv: VMW DRM device
208  * @stdu: display unit affected
209  * @res: Buffer to bind to the screen target.  Set to NULL to blank screen.
210  *
211  * Binding a surface to a Screen Target the same as flipping
212  *
213  * Returns: %0 on success or -errno code on failure
214  */
215 static int vmw_stdu_bind_st(struct vmw_private *dev_priv,
216 			    struct vmw_screen_target_display_unit *stdu,
217 			    const struct vmw_resource *res)
218 {
219 	SVGA3dSurfaceImageId image;
220 
221 	struct {
222 		SVGA3dCmdHeader header;
223 		SVGA3dCmdBindGBScreenTarget body;
224 	} *cmd;
225 
226 
227 	if (!stdu->defined) {
228 		DRM_ERROR("No screen target defined\n");
229 		return -EINVAL;
230 	}
231 
232 	/* Set up image using information in vfb */
233 	memset(&image, 0, sizeof(image));
234 	image.sid = res ? res->id : SVGA3D_INVALID_ID;
235 
236 	cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
237 	if (unlikely(cmd == NULL))
238 		return -ENOMEM;
239 
240 	cmd->header.id   = SVGA_3D_CMD_BIND_GB_SCREENTARGET;
241 	cmd->header.size = sizeof(cmd->body);
242 
243 	cmd->body.stid   = stdu->base.unit;
244 	cmd->body.image  = image;
245 
246 	vmw_cmd_commit(dev_priv, sizeof(*cmd));
247 
248 	return 0;
249 }
250 
251 /**
252  * vmw_stdu_populate_update - populate an UPDATE_GB_SCREENTARGET command with a
253  * bounding box.
254  *
255  * @cmd: Pointer to command stream.
256  * @unit: Screen target unit.
257  * @left: Left side of bounding box.
258  * @right: Right side of bounding box.
259  * @top: Top side of bounding box.
260  * @bottom: Bottom side of bounding box.
261  */
262 static void vmw_stdu_populate_update(void *cmd, int unit,
263 				     s32 left, s32 right, s32 top, s32 bottom)
264 {
265 	struct vmw_stdu_update *update = cmd;
266 
267 	update->header.id   = SVGA_3D_CMD_UPDATE_GB_SCREENTARGET;
268 	update->header.size = sizeof(update->body);
269 
270 	update->body.stid   = unit;
271 	update->body.rect.x = left;
272 	update->body.rect.y = top;
273 	update->body.rect.w = right - left;
274 	update->body.rect.h = bottom - top;
275 }
276 
277 /**
278  * vmw_stdu_update_st - Full update of a Screen Target
279  *
280  * @dev_priv: VMW DRM device
281  * @stdu: display unit affected
282  *
283  * This function needs to be called whenever the content of a screen
284  * target has changed completely. Typically as a result of a backing
285  * surface change.
286  *
287  * RETURNS:
288  * 0 on success, error code on failure
289  */
290 static int vmw_stdu_update_st(struct vmw_private *dev_priv,
291 			      struct vmw_screen_target_display_unit *stdu)
292 {
293 	struct vmw_stdu_update *cmd;
294 
295 	if (!stdu->defined) {
296 		DRM_ERROR("No screen target defined");
297 		return -EINVAL;
298 	}
299 
300 	cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
301 	if (unlikely(cmd == NULL))
302 		return -ENOMEM;
303 
304 	vmw_stdu_populate_update(cmd, stdu->base.unit,
305 				 0, stdu->display_width,
306 				 0, stdu->display_height);
307 
308 	vmw_cmd_commit(dev_priv, sizeof(*cmd));
309 
310 	return 0;
311 }
312 
313 
314 
315 /**
316  * vmw_stdu_destroy_st - Destroy a Screen Target
317  *
318  * @dev_priv:  VMW DRM device
319  * @stdu: display unit to destroy
320  *
321  * Returns: %0 on success, negative error code on failure. -ERESTARTSYS if
322  * interrupted.
323  */
324 static int vmw_stdu_destroy_st(struct vmw_private *dev_priv,
325 			       struct vmw_screen_target_display_unit *stdu)
326 {
327 	int    ret;
328 
329 	struct {
330 		SVGA3dCmdHeader header;
331 		SVGA3dCmdDestroyGBScreenTarget body;
332 	} *cmd;
333 
334 
335 	/* Nothing to do if not successfully defined */
336 	if (unlikely(!stdu->defined))
337 		return 0;
338 
339 	cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
340 	if (unlikely(cmd == NULL))
341 		return -ENOMEM;
342 
343 	cmd->header.id   = SVGA_3D_CMD_DESTROY_GB_SCREENTARGET;
344 	cmd->header.size = sizeof(cmd->body);
345 
346 	cmd->body.stid   = stdu->base.unit;
347 
348 	vmw_cmd_commit(dev_priv, sizeof(*cmd));
349 
350 	/* Force sync */
351 	ret = vmw_fallback_wait(dev_priv, false, true, 0, false, 3*HZ);
352 	if (unlikely(ret != 0))
353 		DRM_ERROR("Failed to sync with HW");
354 
355 	stdu->defined = false;
356 	stdu->display_width  = 0;
357 	stdu->display_height = 0;
358 
359 	return ret;
360 }
361 
362 
363 /**
364  * vmw_stdu_crtc_mode_set_nofb - Updates screen target size
365  *
366  * @crtc: CRTC associated with the screen target
367  *
368  * This function defines/destroys a screen target
369  *
370  */
371 static void vmw_stdu_crtc_mode_set_nofb(struct drm_crtc *crtc)
372 {
373 	struct vmw_private *dev_priv;
374 	struct vmw_screen_target_display_unit *stdu;
375 	struct drm_connector_state *conn_state;
376 	struct vmw_connector_state *vmw_conn_state;
377 	int x, y, ret;
378 
379 	stdu = vmw_crtc_to_stdu(crtc);
380 	dev_priv = vmw_priv(crtc->dev);
381 	conn_state = stdu->base.connector.state;
382 	vmw_conn_state = vmw_connector_state_to_vcs(conn_state);
383 
384 	if (stdu->defined) {
385 		ret = vmw_stdu_bind_st(dev_priv, stdu, NULL);
386 		if (ret)
387 			DRM_ERROR("Failed to blank CRTC\n");
388 
389 		(void) vmw_stdu_update_st(dev_priv, stdu);
390 
391 		ret = vmw_stdu_destroy_st(dev_priv, stdu);
392 		if (ret)
393 			DRM_ERROR("Failed to destroy Screen Target\n");
394 
395 		stdu->content_fb_type = SAME_AS_DISPLAY;
396 	}
397 
398 	if (!crtc->state->enable)
399 		return;
400 
401 	x = vmw_conn_state->gui_x;
402 	y = vmw_conn_state->gui_y;
403 
404 	vmw_svga_enable(dev_priv);
405 	ret = vmw_stdu_define_st(dev_priv, stdu, &crtc->mode, x, y);
406 
407 	if (ret)
408 		DRM_ERROR("Failed to define Screen Target of size %dx%d\n",
409 			  crtc->x, crtc->y);
410 }
411 
412 static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc,
413 					 struct drm_atomic_state *state)
414 {
415 	struct vmw_private *dev_priv;
416 	struct vmw_screen_target_display_unit *stdu;
417 	int ret;
418 
419 	if (!crtc) {
420 		DRM_ERROR("CRTC is NULL\n");
421 		return;
422 	}
423 
424 	stdu     = vmw_crtc_to_stdu(crtc);
425 	dev_priv = vmw_priv(crtc->dev);
426 
427 	if (dev_priv->vkms_enabled)
428 		drm_crtc_vblank_off(crtc);
429 
430 	if (stdu->defined) {
431 		ret = vmw_stdu_bind_st(dev_priv, stdu, NULL);
432 		if (ret)
433 			DRM_ERROR("Failed to blank CRTC\n");
434 
435 		(void) vmw_stdu_update_st(dev_priv, stdu);
436 
437 		ret = vmw_stdu_destroy_st(dev_priv, stdu);
438 		if (ret)
439 			DRM_ERROR("Failed to destroy Screen Target\n");
440 
441 		stdu->content_fb_type = SAME_AS_DISPLAY;
442 	}
443 }
444 
445 /**
446  * vmw_stdu_bo_cpu_clip - Callback to encode a CPU blit
447  *
448  * @dirty: The closure structure.
449  *
450  * This function calculates the bounding box for all the incoming clips.
451  */
452 static void vmw_stdu_bo_cpu_clip(struct vmw_kms_dirty *dirty)
453 {
454 	struct vmw_stdu_dirty *ddirty =
455 		container_of(dirty, struct vmw_stdu_dirty, base);
456 
457 	dirty->num_hits = 1;
458 
459 	/* Calculate destination bounding box */
460 	ddirty->left = min_t(s32, ddirty->left, dirty->unit_x1);
461 	ddirty->top = min_t(s32, ddirty->top, dirty->unit_y1);
462 	ddirty->right = max_t(s32, ddirty->right, dirty->unit_x2);
463 	ddirty->bottom = max_t(s32, ddirty->bottom, dirty->unit_y2);
464 
465 	/*
466 	 * Calculate content bounding box.  We only need the top-left
467 	 * coordinate because width and height will be the same as the
468 	 * destination bounding box above
469 	 */
470 	ddirty->fb_left = min_t(s32, ddirty->fb_left, dirty->fb_x);
471 	ddirty->fb_top  = min_t(s32, ddirty->fb_top, dirty->fb_y);
472 }
473 
474 
475 /**
476  * vmw_stdu_bo_cpu_commit - Callback to do a CPU blit from buffer object
477  *
478  * @dirty: The closure structure.
479  *
480  * For the special case when we cannot create a proxy surface in a
481  * 2D VM, we have to do a CPU blit ourselves.
482  */
483 static void vmw_stdu_bo_cpu_commit(struct vmw_kms_dirty *dirty)
484 {
485 	struct vmw_stdu_dirty *ddirty =
486 		container_of(dirty, struct vmw_stdu_dirty, base);
487 	struct vmw_screen_target_display_unit *stdu =
488 		container_of(dirty->unit, typeof(*stdu), base);
489 	s32 width, height;
490 	s32 src_pitch, dst_pitch;
491 	struct ttm_buffer_object *src_bo, *dst_bo;
492 	u32 src_offset, dst_offset;
493 	struct vmw_diff_cpy diff = VMW_CPU_BLIT_DIFF_INITIALIZER(stdu->cpp);
494 
495 	if (!dirty->num_hits)
496 		return;
497 
498 	width = ddirty->right - ddirty->left;
499 	height = ddirty->bottom - ddirty->top;
500 
501 	if (width == 0 || height == 0)
502 		return;
503 
504 	/* Assume we are blitting from Guest (bo) to Host (display_srf) */
505 	src_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp;
506 	src_bo = &stdu->display_srf->res.guest_memory_bo->tbo;
507 	src_offset = ddirty->top * src_pitch + ddirty->left * stdu->cpp;
508 
509 	dst_pitch = ddirty->pitch;
510 	dst_bo = &ddirty->buf->tbo;
511 	dst_offset = ddirty->fb_top * dst_pitch + ddirty->fb_left * stdu->cpp;
512 
513 	(void) vmw_bo_cpu_blit(dst_bo, dst_offset, dst_pitch,
514 			       src_bo, src_offset, src_pitch,
515 			       width * stdu->cpp, height, &diff);
516 }
517 
518 /**
519  * vmw_kms_stdu_readback - Perform a readback from a buffer-object backed
520  * framebuffer and the screen target system.
521  *
522  * @dev_priv: Pointer to the device private structure.
523  * @file_priv: Pointer to a struct drm-file identifying the caller. May be
524  * set to NULL, but then @user_fence_rep must also be set to NULL.
525  * @vfb: Pointer to the buffer-object backed framebuffer.
526  * @user_fence_rep: User-space provided structure for fence information.
527  * @clips: Array of clip rects. Either @clips or @vclips must be NULL.
528  * @vclips: Alternate array of clip rects. Either @clips or @vclips must
529  * be NULL.
530  * @num_clips: Number of clip rects in @clips or @vclips.
531  * @increment: Increment to use when looping over @clips or @vclips.
532  * @crtc: If crtc is passed, perform stdu dma on that crtc only.
533  *
534  * If DMA-ing till the screen target system, the function will also notify
535  * the screen target system that a bounding box of the cliprects has been
536  * updated.
537  *
538  * Returns: %0 on success, negative error code on failure. -ERESTARTSYS if
539  * interrupted.
540  */
541 int vmw_kms_stdu_readback(struct vmw_private *dev_priv,
542 			  struct drm_file *file_priv,
543 			  struct vmw_framebuffer *vfb,
544 			  struct drm_vmw_fence_rep __user *user_fence_rep,
545 			  struct drm_clip_rect *clips,
546 			  struct drm_vmw_rect *vclips,
547 			  uint32_t num_clips,
548 			  int increment,
549 			  struct drm_crtc *crtc)
550 {
551 	struct vmw_bo *buf =
552 		container_of(vfb, struct vmw_framebuffer_bo, base)->buffer;
553 	struct vmw_stdu_dirty ddirty;
554 	int ret;
555 	DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
556 
557 	/*
558 	 * The GMR domain might seem confusing because it might seem like it should
559 	 * never happen with screen targets but e.g. the xorg vmware driver issues
560 	 * CMD_SURFACE_DMA for various pixmap updates which might transition our bo to
561 	 * a GMR. Instead of forcing another transition we can optimize the readback
562 	 * by reading directly from the GMR.
563 	 */
564 	vmw_bo_placement_set(buf,
565 			     VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_GMR,
566 			     VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_GMR);
567 	ret = vmw_validation_add_bo(&val_ctx, buf);
568 	if (ret)
569 		return ret;
570 
571 	ret = vmw_validation_prepare(&val_ctx, NULL, true);
572 	if (ret)
573 		goto out_unref;
574 
575 	ddirty.left = ddirty.top = S32_MAX;
576 	ddirty.right = ddirty.bottom = S32_MIN;
577 	ddirty.fb_left = ddirty.fb_top = S32_MAX;
578 	ddirty.pitch = vfb->base.pitches[0];
579 	ddirty.buf = buf;
580 
581 	ddirty.base.fifo_commit = vmw_stdu_bo_cpu_commit;
582 	ddirty.base.clip = vmw_stdu_bo_cpu_clip;
583 	ddirty.base.fifo_reserve_size = 0;
584 
585 	ddirty.base.crtc = crtc;
586 
587 	ret = vmw_kms_helper_dirty(dev_priv, vfb, clips, vclips,
588 				   0, 0, num_clips, increment, &ddirty.base);
589 
590 	vmw_kms_helper_validation_finish(dev_priv, file_priv, &val_ctx, NULL,
591 					 user_fence_rep);
592 	return ret;
593 
594 out_unref:
595 	vmw_validation_unref_lists(&val_ctx);
596 	return ret;
597 }
598 
599 /**
600  * vmw_kms_stdu_surface_clip - Callback to encode a surface copy command cliprect
601  *
602  * @dirty: The closure structure.
603  *
604  * Encodes a surface copy command cliprect and updates the bounding box
605  * for the copy.
606  */
607 static void vmw_kms_stdu_surface_clip(struct vmw_kms_dirty *dirty)
608 {
609 	struct vmw_stdu_dirty *sdirty =
610 		container_of(dirty, struct vmw_stdu_dirty, base);
611 	struct vmw_stdu_surface_copy *cmd = dirty->cmd;
612 	struct vmw_screen_target_display_unit *stdu =
613 		container_of(dirty->unit, typeof(*stdu), base);
614 
615 	if (sdirty->sid != stdu->display_srf->res.id) {
616 		struct SVGA3dCopyBox *blit = (struct SVGA3dCopyBox *) &cmd[1];
617 
618 		blit += dirty->num_hits;
619 		blit->srcx = dirty->fb_x;
620 		blit->srcy = dirty->fb_y;
621 		blit->x = dirty->unit_x1;
622 		blit->y = dirty->unit_y1;
623 		blit->d = 1;
624 		blit->w = dirty->unit_x2 - dirty->unit_x1;
625 		blit->h = dirty->unit_y2 - dirty->unit_y1;
626 	}
627 
628 	dirty->num_hits++;
629 
630 	/* Destination bounding box */
631 	sdirty->left = min_t(s32, sdirty->left, dirty->unit_x1);
632 	sdirty->top = min_t(s32, sdirty->top, dirty->unit_y1);
633 	sdirty->right = max_t(s32, sdirty->right, dirty->unit_x2);
634 	sdirty->bottom = max_t(s32, sdirty->bottom, dirty->unit_y2);
635 }
636 
637 /**
638  * vmw_kms_stdu_surface_fifo_commit - Callback to fill in and submit a surface
639  * copy command.
640  *
641  * @dirty: The closure structure.
642  *
643  * Fills in the missing fields in a surface copy command, and encodes a screen
644  * target update command.
645  */
646 static void vmw_kms_stdu_surface_fifo_commit(struct vmw_kms_dirty *dirty)
647 {
648 	struct vmw_stdu_dirty *sdirty =
649 		container_of(dirty, struct vmw_stdu_dirty, base);
650 	struct vmw_screen_target_display_unit *stdu =
651 		container_of(dirty->unit, typeof(*stdu), base);
652 	struct vmw_stdu_surface_copy *cmd = dirty->cmd;
653 	struct vmw_stdu_update *update;
654 	size_t blit_size = sizeof(SVGA3dCopyBox) * dirty->num_hits;
655 	size_t commit_size;
656 
657 	if (!dirty->num_hits) {
658 		vmw_cmd_commit(dirty->dev_priv, 0);
659 		return;
660 	}
661 
662 	if (sdirty->sid != stdu->display_srf->res.id) {
663 		struct SVGA3dCopyBox *blit = (struct SVGA3dCopyBox *) &cmd[1];
664 
665 		cmd->header.id = SVGA_3D_CMD_SURFACE_COPY;
666 		cmd->header.size = sizeof(cmd->body) + blit_size;
667 		cmd->body.src.sid = sdirty->sid;
668 		cmd->body.dest.sid = stdu->display_srf->res.id;
669 		update = (struct vmw_stdu_update *) &blit[dirty->num_hits];
670 		commit_size = sizeof(*cmd) + blit_size + sizeof(*update);
671 		stdu->display_srf->res.res_dirty = true;
672 	} else {
673 		update = dirty->cmd;
674 		commit_size = sizeof(*update);
675 	}
676 
677 	vmw_stdu_populate_update(update, stdu->base.unit, sdirty->left,
678 				 sdirty->right, sdirty->top, sdirty->bottom);
679 
680 	vmw_cmd_commit(dirty->dev_priv, commit_size);
681 
682 	sdirty->left = sdirty->top = S32_MAX;
683 	sdirty->right = sdirty->bottom = S32_MIN;
684 }
685 
686 /**
687  * vmw_kms_stdu_surface_dirty - Dirty part of a surface backed framebuffer
688  *
689  * @dev_priv: Pointer to the device private structure.
690  * @framebuffer: Pointer to the surface-buffer backed framebuffer.
691  * @clips: Array of clip rects. Either @clips or @vclips must be NULL.
692  * @vclips: Alternate array of clip rects. Either @clips or @vclips must
693  * be NULL.
694  * @srf: Pointer to surface to blit from. If NULL, the surface attached
695  * to @framebuffer will be used.
696  * @dest_x: X coordinate offset to align @srf with framebuffer coordinates.
697  * @dest_y: Y coordinate offset to align @srf with framebuffer coordinates.
698  * @num_clips: Number of clip rects in @clips.
699  * @inc: Increment to use when looping over @clips.
700  * @out_fence: If non-NULL, will return a ref-counted pointer to a
701  * struct vmw_fence_obj. The returned fence pointer may be NULL in which
702  * case the device has already synchronized.
703  * @crtc: If crtc is passed, perform surface dirty on that crtc only.
704  *
705  * Returns: %0 on success, negative error code on failure. -ERESTARTSYS if
706  * interrupted.
707  */
708 int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
709 			       struct vmw_framebuffer *framebuffer,
710 			       struct drm_clip_rect *clips,
711 			       struct drm_vmw_rect *vclips,
712 			       struct vmw_resource *srf,
713 			       s32 dest_x,
714 			       s32 dest_y,
715 			       unsigned num_clips, int inc,
716 			       struct vmw_fence_obj **out_fence,
717 			       struct drm_crtc *crtc)
718 {
719 	struct vmw_framebuffer_surface *vfbs =
720 		container_of(framebuffer, typeof(*vfbs), base);
721 	struct vmw_stdu_dirty sdirty;
722 	DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
723 	int ret;
724 
725 	if (!srf)
726 		srf = &vfbs->surface->res;
727 
728 	ret = vmw_validation_add_resource(&val_ctx, srf, 0, VMW_RES_DIRTY_NONE,
729 					  NULL, NULL);
730 	if (ret)
731 		return ret;
732 
733 	ret = vmw_validation_prepare(&val_ctx, &dev_priv->cmdbuf_mutex, true);
734 	if (ret)
735 		goto out_unref;
736 
737 	if (vfbs->is_bo_proxy) {
738 		ret = vmw_kms_update_proxy(srf, clips, num_clips, inc);
739 		if (ret)
740 			goto out_finish;
741 	}
742 
743 	sdirty.base.fifo_commit = vmw_kms_stdu_surface_fifo_commit;
744 	sdirty.base.clip = vmw_kms_stdu_surface_clip;
745 	sdirty.base.fifo_reserve_size = sizeof(struct vmw_stdu_surface_copy) +
746 		sizeof(SVGA3dCopyBox) * num_clips +
747 		sizeof(struct vmw_stdu_update);
748 	sdirty.base.crtc = crtc;
749 	sdirty.sid = srf->id;
750 	sdirty.left = sdirty.top = S32_MAX;
751 	sdirty.right = sdirty.bottom = S32_MIN;
752 
753 	ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips,
754 				   dest_x, dest_y, num_clips, inc,
755 				   &sdirty.base);
756 out_finish:
757 	vmw_kms_helper_validation_finish(dev_priv, NULL, &val_ctx, out_fence,
758 					 NULL);
759 
760 	return ret;
761 
762 out_unref:
763 	vmw_validation_unref_lists(&val_ctx);
764 	return ret;
765 }
766 
767 /*
768  *  Screen Target CRTC dispatch table
769  */
770 static const struct drm_crtc_funcs vmw_stdu_crtc_funcs = {
771 	.gamma_set = vmw_du_crtc_gamma_set,
772 	.destroy = vmw_stdu_crtc_destroy,
773 	.reset = vmw_du_crtc_reset,
774 	.atomic_duplicate_state = vmw_du_crtc_duplicate_state,
775 	.atomic_destroy_state = vmw_du_crtc_destroy_state,
776 	.set_config = drm_atomic_helper_set_config,
777 	.page_flip = drm_atomic_helper_page_flip,
778 	.enable_vblank		= vmw_vkms_enable_vblank,
779 	.disable_vblank		= vmw_vkms_disable_vblank,
780 	.get_vblank_timestamp	= vmw_vkms_get_vblank_timestamp,
781 	.get_crc_sources	= vmw_vkms_get_crc_sources,
782 	.set_crc_source		= vmw_vkms_set_crc_source,
783 	.verify_crc_source	= vmw_vkms_verify_crc_source,
784 };
785 
786 
787 
788 /******************************************************************************
789  * Screen Target Display Unit Encoder Functions
790  *****************************************************************************/
791 
792 /**
793  * vmw_stdu_encoder_destroy - cleans up the STDU
794  *
795  * @encoder: used the get the containing STDU
796  *
797  * vmwgfx cleans up crtc/encoder/connector all at the same time so technically
798  * this can be a no-op.  Nevertheless, it doesn't hurt of have this in case
799  * the common KMS code changes and somehow vmw_stdu_crtc_destroy() doesn't
800  * get called.
801  */
802 static void vmw_stdu_encoder_destroy(struct drm_encoder *encoder)
803 {
804 	vmw_stdu_destroy(vmw_encoder_to_stdu(encoder));
805 }
806 
807 static const struct drm_encoder_funcs vmw_stdu_encoder_funcs = {
808 	.destroy = vmw_stdu_encoder_destroy,
809 };
810 
811 
812 
813 /******************************************************************************
814  * Screen Target Display Unit Connector Functions
815  *****************************************************************************/
816 
817 /**
818  * vmw_stdu_connector_destroy - cleans up the STDU
819  *
820  * @connector: used to get the containing STDU
821  *
822  * vmwgfx cleans up crtc/encoder/connector all at the same time so technically
823  * this can be a no-op.  Nevertheless, it doesn't hurt of have this in case
824  * the common KMS code changes and somehow vmw_stdu_crtc_destroy() doesn't
825  * get called.
826  */
827 static void vmw_stdu_connector_destroy(struct drm_connector *connector)
828 {
829 	vmw_stdu_destroy(vmw_connector_to_stdu(connector));
830 }
831 
832 
833 
834 static const struct drm_connector_funcs vmw_stdu_connector_funcs = {
835 	.dpms = vmw_du_connector_dpms,
836 	.detect = vmw_du_connector_detect,
837 	.fill_modes = drm_helper_probe_single_connector_modes,
838 	.destroy = vmw_stdu_connector_destroy,
839 	.reset = vmw_du_connector_reset,
840 	.atomic_duplicate_state = vmw_du_connector_duplicate_state,
841 	.atomic_destroy_state = vmw_du_connector_destroy_state,
842 };
843 
844 
845 static const struct
846 drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = {
847 	.get_modes = vmw_connector_get_modes,
848 	.mode_valid = vmw_connector_mode_valid
849 };
850 
851 
852 
853 /******************************************************************************
854  * Screen Target Display Plane Functions
855  *****************************************************************************/
856 
857 
858 
859 /**
860  * vmw_stdu_primary_plane_cleanup_fb - Unpins the display surface
861  *
862  * @plane:  display plane
863  * @old_state: Contains the FB to clean up
864  *
865  * Unpins the display surface
866  *
867  * Returns 0 on success
868  */
869 static void
870 vmw_stdu_primary_plane_cleanup_fb(struct drm_plane *plane,
871 				  struct drm_plane_state *old_state)
872 {
873 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
874 
875 	if (vps->surf)
876 		WARN_ON(!vps->pinned);
877 
878 	vmw_du_plane_cleanup_fb(plane, old_state);
879 
880 	vps->content_fb_type = SAME_AS_DISPLAY;
881 	vps->cpp = 0;
882 }
883 
884 
885 
886 /**
887  * vmw_stdu_primary_plane_prepare_fb - Readies the display surface
888  *
889  * @plane:  display plane
890  * @new_state: info on the new plane state, including the FB
891  *
892  * This function allocates a new display surface if the content is
893  * backed by a buffer object.  The display surface is pinned here, and it'll
894  * be unpinned in .cleanup_fb()
895  *
896  * Returns: %0 on success
897  */
898 static int
899 vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane,
900 				  struct drm_plane_state *new_state)
901 {
902 	struct vmw_private *dev_priv = vmw_priv(plane->dev);
903 	struct drm_framebuffer *new_fb = new_state->fb;
904 	struct vmw_framebuffer *vfb;
905 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
906 	enum stdu_content_type new_content_type;
907 	struct vmw_framebuffer_surface *new_vfbs;
908 	uint32_t hdisplay = new_state->crtc_w, vdisplay = new_state->crtc_h;
909 	int ret;
910 
911 	/* No FB to prepare */
912 	if (!new_fb) {
913 		if (vps->surf) {
914 			WARN_ON(vps->pinned != 0);
915 			vmw_surface_unreference(&vps->surf);
916 		}
917 
918 		return 0;
919 	}
920 
921 	vfb = vmw_framebuffer_to_vfb(new_fb);
922 	new_vfbs = (vfb->bo) ? NULL : vmw_framebuffer_to_vfbs(new_fb);
923 
924 	if (new_vfbs &&
925 	    new_vfbs->surface->metadata.base_size.width == hdisplay &&
926 	    new_vfbs->surface->metadata.base_size.height == vdisplay)
927 		new_content_type = SAME_AS_DISPLAY;
928 	else if (vfb->bo)
929 		new_content_type = SEPARATE_BO;
930 	else
931 		new_content_type = SEPARATE_SURFACE;
932 
933 	if (new_content_type != SAME_AS_DISPLAY) {
934 		struct vmw_surface_metadata metadata = {0};
935 
936 		/*
937 		 * If content buffer is a buffer object, then we have to
938 		 * construct surface info
939 		 */
940 		if (new_content_type == SEPARATE_BO) {
941 
942 			switch (new_fb->format->cpp[0]*8) {
943 			case 32:
944 				metadata.format = SVGA3D_X8R8G8B8;
945 				break;
946 
947 			case 16:
948 				metadata.format = SVGA3D_R5G6B5;
949 				break;
950 
951 			case 8:
952 				metadata.format = SVGA3D_P8;
953 				break;
954 
955 			default:
956 				DRM_ERROR("Invalid format\n");
957 				return -EINVAL;
958 			}
959 
960 			metadata.mip_levels[0] = 1;
961 			metadata.num_sizes = 1;
962 			metadata.scanout = true;
963 		} else {
964 			metadata = new_vfbs->surface->metadata;
965 		}
966 
967 		metadata.base_size.width = hdisplay;
968 		metadata.base_size.height = vdisplay;
969 		metadata.base_size.depth = 1;
970 
971 		if (vps->surf) {
972 			struct drm_vmw_size cur_base_size =
973 				vps->surf->metadata.base_size;
974 
975 			if (cur_base_size.width != metadata.base_size.width ||
976 			    cur_base_size.height != metadata.base_size.height ||
977 			    vps->surf->metadata.format != metadata.format) {
978 				WARN_ON(vps->pinned != 0);
979 				vmw_surface_unreference(&vps->surf);
980 			}
981 
982 		}
983 
984 		if (!vps->surf) {
985 			ret = vmw_gb_surface_define(dev_priv, &metadata,
986 						    &vps->surf);
987 			if (ret != 0) {
988 				DRM_ERROR("Couldn't allocate STDU surface.\n");
989 				return ret;
990 			}
991 		}
992 	} else {
993 		/*
994 		 * prepare_fb and clean_fb should only take care of pinning
995 		 * and unpinning.  References are tracked by state objects.
996 		 * The only time we add a reference in prepare_fb is if the
997 		 * state object doesn't have a reference to begin with
998 		 */
999 		if (vps->surf) {
1000 			WARN_ON(vps->pinned != 0);
1001 			vmw_surface_unreference(&vps->surf);
1002 		}
1003 
1004 		vps->surf = vmw_surface_reference(new_vfbs->surface);
1005 	}
1006 
1007 	if (vps->surf) {
1008 
1009 		/* Pin new surface before flipping */
1010 		ret = vmw_resource_pin(&vps->surf->res, false);
1011 		if (ret)
1012 			goto out_srf_unref;
1013 
1014 		vps->pinned++;
1015 	}
1016 
1017 	vps->content_fb_type = new_content_type;
1018 
1019 	/*
1020 	 * This should only happen if the buffer object is too large to create a
1021 	 * proxy surface for.
1022 	 */
1023 	if (vps->content_fb_type == SEPARATE_BO)
1024 		vps->cpp = new_fb->pitches[0] / new_fb->width;
1025 
1026 	return 0;
1027 
1028 out_srf_unref:
1029 	vmw_surface_unreference(&vps->surf);
1030 	return ret;
1031 }
1032 
1033 static uint32_t vmw_stdu_bo_fifo_size_cpu(struct vmw_du_update_plane *update,
1034 					  uint32_t num_hits)
1035 {
1036 	return sizeof(struct vmw_stdu_update_gb_image) +
1037 		sizeof(struct vmw_stdu_update);
1038 }
1039 
1040 static uint32_t vmw_stdu_bo_pre_clip_cpu(struct vmw_du_update_plane  *update,
1041 					 void *cmd, uint32_t num_hits)
1042 {
1043 	struct vmw_du_update_plane_buffer *bo_update =
1044 		container_of(update, typeof(*bo_update), base);
1045 
1046 	bo_update->fb_left = INT_MAX;
1047 	bo_update->fb_top = INT_MAX;
1048 
1049 	return 0;
1050 }
1051 
1052 static uint32_t vmw_stdu_bo_clip_cpu(struct vmw_du_update_plane  *update,
1053 				     void *cmd, struct drm_rect *clip,
1054 				     uint32_t fb_x, uint32_t fb_y)
1055 {
1056 	struct vmw_du_update_plane_buffer *bo_update =
1057 		container_of(update, typeof(*bo_update), base);
1058 
1059 	bo_update->fb_left = min_t(int, bo_update->fb_left, fb_x);
1060 	bo_update->fb_top = min_t(int, bo_update->fb_top, fb_y);
1061 
1062 	return 0;
1063 }
1064 
1065 static uint32_t
1066 vmw_stdu_bo_populate_update_cpu(struct vmw_du_update_plane  *update, void *cmd,
1067 				struct drm_rect *bb)
1068 {
1069 	struct vmw_du_update_plane_buffer *bo_update;
1070 	struct vmw_screen_target_display_unit *stdu;
1071 	struct vmw_framebuffer_bo *vfbbo;
1072 	struct vmw_diff_cpy diff = VMW_CPU_BLIT_DIFF_INITIALIZER(0);
1073 	struct vmw_stdu_update_gb_image *cmd_img = cmd;
1074 	struct vmw_stdu_update *cmd_update;
1075 	struct ttm_buffer_object *src_bo, *dst_bo;
1076 	u32 src_offset, dst_offset;
1077 	s32 src_pitch, dst_pitch;
1078 	s32 width, height;
1079 
1080 	bo_update = container_of(update, typeof(*bo_update), base);
1081 	stdu = container_of(update->du, typeof(*stdu), base);
1082 	vfbbo = container_of(update->vfb, typeof(*vfbbo), base);
1083 
1084 	width = bb->x2 - bb->x1;
1085 	height = bb->y2 - bb->y1;
1086 
1087 	diff.cpp = stdu->cpp;
1088 
1089 	dst_bo = &stdu->display_srf->res.guest_memory_bo->tbo;
1090 	dst_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp;
1091 	dst_offset = bb->y1 * dst_pitch + bb->x1 * stdu->cpp;
1092 
1093 	src_bo = &vfbbo->buffer->tbo;
1094 	src_pitch = update->vfb->base.pitches[0];
1095 	src_offset = bo_update->fb_top * src_pitch + bo_update->fb_left *
1096 		stdu->cpp;
1097 
1098 	(void) vmw_bo_cpu_blit(dst_bo, dst_offset, dst_pitch, src_bo,
1099 			       src_offset, src_pitch, width * stdu->cpp, height,
1100 			       &diff);
1101 
1102 	if (drm_rect_visible(&diff.rect)) {
1103 		SVGA3dBox *box = &cmd_img->body.box;
1104 
1105 		cmd_img->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE;
1106 		cmd_img->header.size = sizeof(cmd_img->body);
1107 		cmd_img->body.image.sid = stdu->display_srf->res.id;
1108 		cmd_img->body.image.face = 0;
1109 		cmd_img->body.image.mipmap = 0;
1110 
1111 		box->x = diff.rect.x1;
1112 		box->y = diff.rect.y1;
1113 		box->z = 0;
1114 		box->w = drm_rect_width(&diff.rect);
1115 		box->h = drm_rect_height(&diff.rect);
1116 		box->d = 1;
1117 
1118 		cmd_update = (struct vmw_stdu_update *)&cmd_img[1];
1119 		vmw_stdu_populate_update(cmd_update, stdu->base.unit,
1120 					 diff.rect.x1, diff.rect.x2,
1121 					 diff.rect.y1, diff.rect.y2);
1122 
1123 		return sizeof(*cmd_img) + sizeof(*cmd_update);
1124 	}
1125 
1126 	return 0;
1127 }
1128 
1129 /**
1130  * vmw_stdu_plane_update_bo - Update display unit for bo backed fb.
1131  * @dev_priv: device private.
1132  * @plane: plane state.
1133  * @old_state: old plane state.
1134  * @vfb: framebuffer which is blitted to display unit.
1135  * @out_fence: If non-NULL, will return a ref-counted pointer to vmw_fence_obj.
1136  *             The returned fence pointer may be NULL in which case the device
1137  *             has already synchronized.
1138  *
1139  * Return: 0 on success or a negative error code on failure.
1140  */
1141 static int vmw_stdu_plane_update_bo(struct vmw_private *dev_priv,
1142 				    struct drm_plane *plane,
1143 				    struct drm_plane_state *old_state,
1144 				    struct vmw_framebuffer *vfb,
1145 				    struct vmw_fence_obj **out_fence)
1146 {
1147 	struct vmw_du_update_plane_buffer bo_update;
1148 
1149 	memset(&bo_update, 0, sizeof(struct vmw_du_update_plane_buffer));
1150 	bo_update.base.plane = plane;
1151 	bo_update.base.old_state = old_state;
1152 	bo_update.base.dev_priv = dev_priv;
1153 	bo_update.base.du = vmw_crtc_to_du(plane->state->crtc);
1154 	bo_update.base.vfb = vfb;
1155 	bo_update.base.out_fence = out_fence;
1156 	bo_update.base.mutex = NULL;
1157 	bo_update.base.intr = false;
1158 
1159 	bo_update.base.calc_fifo_size = vmw_stdu_bo_fifo_size_cpu;
1160 	bo_update.base.pre_clip = vmw_stdu_bo_pre_clip_cpu;
1161 	bo_update.base.clip = vmw_stdu_bo_clip_cpu;
1162 	bo_update.base.post_clip = vmw_stdu_bo_populate_update_cpu;
1163 
1164 	return vmw_du_helper_plane_update(&bo_update.base);
1165 }
1166 
1167 static uint32_t
1168 vmw_stdu_surface_fifo_size_same_display(struct vmw_du_update_plane *update,
1169 					uint32_t num_hits)
1170 {
1171 	struct vmw_framebuffer_surface *vfbs;
1172 	uint32_t size = 0;
1173 
1174 	vfbs = container_of(update->vfb, typeof(*vfbs), base);
1175 
1176 	if (vfbs->is_bo_proxy)
1177 		size += sizeof(struct vmw_stdu_update_gb_image) * num_hits;
1178 
1179 	size += sizeof(struct vmw_stdu_update);
1180 
1181 	return size;
1182 }
1183 
1184 static uint32_t vmw_stdu_surface_fifo_size(struct vmw_du_update_plane *update,
1185 					   uint32_t num_hits)
1186 {
1187 	struct vmw_framebuffer_surface *vfbs;
1188 	uint32_t size = 0;
1189 
1190 	vfbs = container_of(update->vfb, typeof(*vfbs), base);
1191 
1192 	if (vfbs->is_bo_proxy)
1193 		size += sizeof(struct vmw_stdu_update_gb_image) * num_hits;
1194 
1195 	size += sizeof(struct vmw_stdu_surface_copy) + sizeof(SVGA3dCopyBox) *
1196 		num_hits + sizeof(struct vmw_stdu_update);
1197 
1198 	return size;
1199 }
1200 
1201 static uint32_t
1202 vmw_stdu_surface_update_proxy(struct vmw_du_update_plane *update, void *cmd)
1203 {
1204 	struct vmw_framebuffer_surface *vfbs;
1205 	struct drm_plane_state *state = update->plane->state;
1206 	struct drm_plane_state *old_state = update->old_state;
1207 	struct vmw_stdu_update_gb_image *cmd_update = cmd;
1208 	struct drm_atomic_helper_damage_iter iter;
1209 	struct drm_rect clip;
1210 	uint32_t copy_size = 0;
1211 
1212 	vfbs = container_of(update->vfb, typeof(*vfbs), base);
1213 
1214 	/*
1215 	 * proxy surface is special where a buffer object type fb is wrapped
1216 	 * in a surface and need an update gb image command to sync with device.
1217 	 */
1218 	drm_atomic_helper_damage_iter_init(&iter, old_state, state);
1219 	drm_atomic_for_each_plane_damage(&iter, &clip) {
1220 		SVGA3dBox *box = &cmd_update->body.box;
1221 
1222 		cmd_update->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE;
1223 		cmd_update->header.size = sizeof(cmd_update->body);
1224 		cmd_update->body.image.sid = vfbs->surface->res.id;
1225 		cmd_update->body.image.face = 0;
1226 		cmd_update->body.image.mipmap = 0;
1227 
1228 		box->x = clip.x1;
1229 		box->y = clip.y1;
1230 		box->z = 0;
1231 		box->w = drm_rect_width(&clip);
1232 		box->h = drm_rect_height(&clip);
1233 		box->d = 1;
1234 
1235 		copy_size += sizeof(*cmd_update);
1236 		cmd_update++;
1237 	}
1238 
1239 	return copy_size;
1240 }
1241 
1242 static uint32_t
1243 vmw_stdu_surface_populate_copy(struct vmw_du_update_plane  *update, void *cmd,
1244 			       uint32_t num_hits)
1245 {
1246 	struct vmw_screen_target_display_unit *stdu;
1247 	struct vmw_framebuffer_surface *vfbs;
1248 	struct vmw_stdu_surface_copy *cmd_copy = cmd;
1249 
1250 	stdu = container_of(update->du, typeof(*stdu), base);
1251 	vfbs = container_of(update->vfb, typeof(*vfbs), base);
1252 
1253 	cmd_copy->header.id = SVGA_3D_CMD_SURFACE_COPY;
1254 	cmd_copy->header.size = sizeof(cmd_copy->body) + sizeof(SVGA3dCopyBox) *
1255 		num_hits;
1256 	cmd_copy->body.src.sid = vfbs->surface->res.id;
1257 	cmd_copy->body.dest.sid = stdu->display_srf->res.id;
1258 
1259 	return sizeof(*cmd_copy);
1260 }
1261 
1262 static uint32_t
1263 vmw_stdu_surface_populate_clip(struct vmw_du_update_plane  *update, void *cmd,
1264 			       struct drm_rect *clip, uint32_t fb_x,
1265 			       uint32_t fb_y)
1266 {
1267 	struct SVGA3dCopyBox *box = cmd;
1268 
1269 	box->srcx = fb_x;
1270 	box->srcy = fb_y;
1271 	box->srcz = 0;
1272 	box->x = clip->x1;
1273 	box->y = clip->y1;
1274 	box->z = 0;
1275 	box->w = drm_rect_width(clip);
1276 	box->h = drm_rect_height(clip);
1277 	box->d = 1;
1278 
1279 	return sizeof(*box);
1280 }
1281 
1282 static uint32_t
1283 vmw_stdu_surface_populate_update(struct vmw_du_update_plane  *update, void *cmd,
1284 				 struct drm_rect *bb)
1285 {
1286 	vmw_stdu_populate_update(cmd, update->du->unit, bb->x1, bb->x2, bb->y1,
1287 				 bb->y2);
1288 
1289 	return sizeof(struct vmw_stdu_update);
1290 }
1291 
1292 /**
1293  * vmw_stdu_plane_update_surface - Update display unit for surface backed fb
1294  * @dev_priv: Device private
1295  * @plane: Plane state
1296  * @old_state: Old plane state
1297  * @vfb: Framebuffer which is blitted to display unit
1298  * @out_fence: If non-NULL, will return a ref-counted pointer to vmw_fence_obj.
1299  *             The returned fence pointer may be NULL in which case the device
1300  *             has already synchronized.
1301  *
1302  * Return: 0 on success or a negative error code on failure.
1303  */
1304 static int vmw_stdu_plane_update_surface(struct vmw_private *dev_priv,
1305 					 struct drm_plane *plane,
1306 					 struct drm_plane_state *old_state,
1307 					 struct vmw_framebuffer *vfb,
1308 					 struct vmw_fence_obj **out_fence)
1309 {
1310 	struct vmw_du_update_plane srf_update;
1311 	struct vmw_screen_target_display_unit *stdu;
1312 	struct vmw_framebuffer_surface *vfbs;
1313 
1314 	stdu = vmw_crtc_to_stdu(plane->state->crtc);
1315 	vfbs = container_of(vfb, typeof(*vfbs), base);
1316 
1317 	memset(&srf_update, 0, sizeof(struct vmw_du_update_plane));
1318 	srf_update.plane = plane;
1319 	srf_update.old_state = old_state;
1320 	srf_update.dev_priv = dev_priv;
1321 	srf_update.du = vmw_crtc_to_du(plane->state->crtc);
1322 	srf_update.vfb = vfb;
1323 	srf_update.out_fence = out_fence;
1324 	srf_update.mutex = &dev_priv->cmdbuf_mutex;
1325 	srf_update.intr = true;
1326 
1327 	if (vfbs->is_bo_proxy)
1328 		srf_update.post_prepare = vmw_stdu_surface_update_proxy;
1329 
1330 	if (vfbs->surface->res.id != stdu->display_srf->res.id) {
1331 		srf_update.calc_fifo_size = vmw_stdu_surface_fifo_size;
1332 		srf_update.pre_clip = vmw_stdu_surface_populate_copy;
1333 		srf_update.clip = vmw_stdu_surface_populate_clip;
1334 	} else {
1335 		srf_update.calc_fifo_size =
1336 			vmw_stdu_surface_fifo_size_same_display;
1337 	}
1338 
1339 	srf_update.post_clip = vmw_stdu_surface_populate_update;
1340 
1341 	return vmw_du_helper_plane_update(&srf_update);
1342 }
1343 
1344 /**
1345  * vmw_stdu_primary_plane_atomic_update - formally switches STDU to new plane
1346  * @plane: display plane
1347  * @state: Only used to get crtc info
1348  *
1349  * Formally update stdu->display_srf to the new plane, and bind the new
1350  * plane STDU.  This function is called during the commit phase when
1351  * all the preparation have been done and all the configurations have
1352  * been checked.
1353  */
1354 static void
1355 vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane,
1356 				     struct drm_atomic_state *state)
1357 {
1358 	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
1359 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
1360 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
1361 	struct drm_crtc *crtc = new_state->crtc;
1362 	struct vmw_screen_target_display_unit *stdu;
1363 	struct vmw_fence_obj *fence = NULL;
1364 	struct vmw_private *dev_priv;
1365 	int ret;
1366 
1367 	/* If case of device error, maintain consistent atomic state */
1368 	if (crtc && new_state->fb) {
1369 		struct vmw_framebuffer *vfb =
1370 			vmw_framebuffer_to_vfb(new_state->fb);
1371 		stdu = vmw_crtc_to_stdu(crtc);
1372 		dev_priv = vmw_priv(crtc->dev);
1373 
1374 		stdu->display_srf = vps->surf;
1375 		stdu->content_fb_type = vps->content_fb_type;
1376 		stdu->cpp = vps->cpp;
1377 
1378 		ret = vmw_stdu_bind_st(dev_priv, stdu, &stdu->display_srf->res);
1379 		if (ret)
1380 			DRM_ERROR("Failed to bind surface to STDU.\n");
1381 
1382 		if (vfb->bo)
1383 			ret = vmw_stdu_plane_update_bo(dev_priv, plane,
1384 						       old_state, vfb, &fence);
1385 		else
1386 			ret = vmw_stdu_plane_update_surface(dev_priv, plane,
1387 							    old_state, vfb,
1388 							    &fence);
1389 		if (ret)
1390 			DRM_ERROR("Failed to update STDU.\n");
1391 	} else {
1392 		crtc = old_state->crtc;
1393 		stdu = vmw_crtc_to_stdu(crtc);
1394 		dev_priv = vmw_priv(crtc->dev);
1395 
1396 		/* Blank STDU when fb and crtc are NULL */
1397 		if (!stdu->defined)
1398 			return;
1399 
1400 		ret = vmw_stdu_bind_st(dev_priv, stdu, NULL);
1401 		if (ret)
1402 			DRM_ERROR("Failed to blank STDU\n");
1403 
1404 		ret = vmw_stdu_update_st(dev_priv, stdu);
1405 		if (ret)
1406 			DRM_ERROR("Failed to update STDU.\n");
1407 
1408 		return;
1409 	}
1410 
1411 	if (fence)
1412 		vmw_fence_obj_unreference(&fence);
1413 }
1414 
1415 static void
1416 vmw_stdu_crtc_atomic_flush(struct drm_crtc *crtc,
1417 			   struct drm_atomic_state *state)
1418 {
1419 	struct vmw_private *vmw = vmw_priv(crtc->dev);
1420 	struct vmw_screen_target_display_unit *stdu = vmw_crtc_to_stdu(crtc);
1421 
1422 	if (vmw->vkms_enabled)
1423 		vmw_vkms_set_crc_surface(crtc, stdu->display_srf);
1424 	vmw_vkms_crtc_atomic_flush(crtc, state);
1425 }
1426 
1427 static const struct drm_plane_funcs vmw_stdu_plane_funcs = {
1428 	.update_plane = drm_atomic_helper_update_plane,
1429 	.disable_plane = drm_atomic_helper_disable_plane,
1430 	.destroy = vmw_du_primary_plane_destroy,
1431 	.reset = vmw_du_plane_reset,
1432 	.atomic_duplicate_state = vmw_du_plane_duplicate_state,
1433 	.atomic_destroy_state = vmw_du_plane_destroy_state,
1434 };
1435 
1436 static const struct drm_plane_funcs vmw_stdu_cursor_funcs = {
1437 	.update_plane = drm_atomic_helper_update_plane,
1438 	.disable_plane = drm_atomic_helper_disable_plane,
1439 	.destroy = vmw_du_cursor_plane_destroy,
1440 	.reset = vmw_du_plane_reset,
1441 	.atomic_duplicate_state = vmw_du_plane_duplicate_state,
1442 	.atomic_destroy_state = vmw_du_plane_destroy_state,
1443 };
1444 
1445 
1446 /*
1447  * Atomic Helpers
1448  */
1449 static const struct
1450 drm_plane_helper_funcs vmw_stdu_cursor_plane_helper_funcs = {
1451 	.atomic_check = vmw_du_cursor_plane_atomic_check,
1452 	.atomic_update = vmw_du_cursor_plane_atomic_update,
1453 	.prepare_fb = vmw_du_cursor_plane_prepare_fb,
1454 	.cleanup_fb = vmw_du_cursor_plane_cleanup_fb,
1455 };
1456 
1457 static const struct
1458 drm_plane_helper_funcs vmw_stdu_primary_plane_helper_funcs = {
1459 	.atomic_check = vmw_du_primary_plane_atomic_check,
1460 	.atomic_update = vmw_stdu_primary_plane_atomic_update,
1461 	.prepare_fb = vmw_stdu_primary_plane_prepare_fb,
1462 	.cleanup_fb = vmw_stdu_primary_plane_cleanup_fb,
1463 };
1464 
1465 static const struct drm_crtc_helper_funcs vmw_stdu_crtc_helper_funcs = {
1466 	.mode_set_nofb = vmw_stdu_crtc_mode_set_nofb,
1467 	.atomic_check = vmw_du_crtc_atomic_check,
1468 	.atomic_begin = vmw_du_crtc_atomic_begin,
1469 	.atomic_flush = vmw_stdu_crtc_atomic_flush,
1470 	.atomic_enable = vmw_vkms_crtc_atomic_enable,
1471 	.atomic_disable = vmw_stdu_crtc_atomic_disable,
1472 };
1473 
1474 
1475 /**
1476  * vmw_stdu_init - Sets up a Screen Target Display Unit
1477  *
1478  * @dev_priv: VMW DRM device
1479  * @unit: unit number range from 0 to VMWGFX_NUM_DISPLAY_UNITS
1480  *
1481  * This function is called once per CRTC, and allocates one Screen Target
1482  * display unit to represent that CRTC.  Since the SVGA device does not separate
1483  * out encoder and connector, they are represented as part of the STDU as well.
1484  *
1485  * Returns: %0 on success or -errno code on failure
1486  */
1487 static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
1488 {
1489 	struct vmw_screen_target_display_unit *stdu;
1490 	struct drm_device *dev = &dev_priv->drm;
1491 	struct drm_connector *connector;
1492 	struct drm_encoder *encoder;
1493 	struct drm_plane *primary;
1494 	struct vmw_cursor_plane *cursor;
1495 	struct drm_crtc *crtc;
1496 	int    ret;
1497 
1498 	stdu = kzalloc(sizeof(*stdu), GFP_KERNEL);
1499 	if (!stdu)
1500 		return -ENOMEM;
1501 
1502 	stdu->base.unit = unit;
1503 	crtc = &stdu->base.crtc;
1504 	encoder = &stdu->base.encoder;
1505 	connector = &stdu->base.connector;
1506 	primary = &stdu->base.primary;
1507 	cursor = &stdu->base.cursor;
1508 
1509 	stdu->base.pref_active = (unit == 0);
1510 	stdu->base.pref_width  = dev_priv->initial_width;
1511 	stdu->base.pref_height = dev_priv->initial_height;
1512 	stdu->base.is_implicit = false;
1513 
1514 	/* Initialize primary plane */
1515 	ret = drm_universal_plane_init(dev, primary,
1516 				       0, &vmw_stdu_plane_funcs,
1517 				       vmw_primary_plane_formats,
1518 				       ARRAY_SIZE(vmw_primary_plane_formats),
1519 				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
1520 	if (ret) {
1521 		DRM_ERROR("Failed to initialize primary plane");
1522 		goto err_free;
1523 	}
1524 
1525 	drm_plane_helper_add(primary, &vmw_stdu_primary_plane_helper_funcs);
1526 	drm_plane_enable_fb_damage_clips(primary);
1527 
1528 	/* Initialize cursor plane */
1529 	ret = drm_universal_plane_init(dev, &cursor->base,
1530 			0, &vmw_stdu_cursor_funcs,
1531 			vmw_cursor_plane_formats,
1532 			ARRAY_SIZE(vmw_cursor_plane_formats),
1533 			NULL, DRM_PLANE_TYPE_CURSOR, NULL);
1534 	if (ret) {
1535 		DRM_ERROR("Failed to initialize cursor plane");
1536 		drm_plane_cleanup(&stdu->base.primary);
1537 		goto err_free;
1538 	}
1539 
1540 	drm_plane_helper_add(&cursor->base, &vmw_stdu_cursor_plane_helper_funcs);
1541 
1542 	ret = drm_connector_init(dev, connector, &vmw_stdu_connector_funcs,
1543 				 DRM_MODE_CONNECTOR_VIRTUAL);
1544 	if (ret) {
1545 		DRM_ERROR("Failed to initialize connector\n");
1546 		goto err_free;
1547 	}
1548 
1549 	drm_connector_helper_add(connector, &vmw_stdu_connector_helper_funcs);
1550 	connector->status = vmw_du_connector_detect(connector, false);
1551 
1552 	ret = drm_encoder_init(dev, encoder, &vmw_stdu_encoder_funcs,
1553 			       DRM_MODE_ENCODER_VIRTUAL, NULL);
1554 	if (ret) {
1555 		DRM_ERROR("Failed to initialize encoder\n");
1556 		goto err_free_connector;
1557 	}
1558 
1559 	(void) drm_connector_attach_encoder(connector, encoder);
1560 	encoder->possible_crtcs = (1 << unit);
1561 	encoder->possible_clones = 0;
1562 
1563 	ret = drm_connector_register(connector);
1564 	if (ret) {
1565 		DRM_ERROR("Failed to register connector\n");
1566 		goto err_free_encoder;
1567 	}
1568 
1569 	ret = drm_crtc_init_with_planes(dev, crtc, primary,
1570 					&cursor->base,
1571 					&vmw_stdu_crtc_funcs, NULL);
1572 	if (ret) {
1573 		DRM_ERROR("Failed to initialize CRTC\n");
1574 		goto err_free_unregister;
1575 	}
1576 
1577 	drm_crtc_helper_add(crtc, &vmw_stdu_crtc_helper_funcs);
1578 
1579 	drm_mode_crtc_set_gamma_size(crtc, 256);
1580 
1581 	drm_object_attach_property(&connector->base,
1582 				   dev_priv->hotplug_mode_update_property, 1);
1583 	drm_object_attach_property(&connector->base,
1584 				   dev->mode_config.suggested_x_property, 0);
1585 	drm_object_attach_property(&connector->base,
1586 				   dev->mode_config.suggested_y_property, 0);
1587 
1588 	vmw_du_init(&stdu->base);
1589 
1590 	return 0;
1591 
1592 err_free_unregister:
1593 	drm_connector_unregister(connector);
1594 err_free_encoder:
1595 	drm_encoder_cleanup(encoder);
1596 err_free_connector:
1597 	drm_connector_cleanup(connector);
1598 err_free:
1599 	kfree(stdu);
1600 	return ret;
1601 }
1602 
1603 
1604 
1605 /**
1606  *  vmw_stdu_destroy - Cleans up a vmw_screen_target_display_unit
1607  *
1608  *  @stdu:  Screen Target Display Unit to be destroyed
1609  *
1610  *  Clean up after vmw_stdu_init
1611  */
1612 static void vmw_stdu_destroy(struct vmw_screen_target_display_unit *stdu)
1613 {
1614 	vmw_du_cleanup(&stdu->base);
1615 	kfree(stdu);
1616 }
1617 
1618 
1619 
1620 /******************************************************************************
1621  * Screen Target Display KMS Functions
1622  *
1623  * These functions are called by the common KMS code in vmwgfx_kms.c
1624  *****************************************************************************/
1625 
1626 /**
1627  * vmw_kms_stdu_init_display - Initializes a Screen Target based display
1628  *
1629  * @dev_priv: VMW DRM device
1630  *
1631  * This function initialize a Screen Target based display device.  It checks
1632  * the capability bits to make sure the underlying hardware can support
1633  * screen targets, and then creates the maximum number of CRTCs, a.k.a Display
1634  * Units, as supported by the display hardware.
1635  *
1636  * RETURNS:
1637  * 0 on success, error code otherwise
1638  */
1639 int vmw_kms_stdu_init_display(struct vmw_private *dev_priv)
1640 {
1641 	struct drm_device *dev = &dev_priv->drm;
1642 	int i, ret;
1643 
1644 
1645 	/* Do nothing if there's no support for MOBs */
1646 	if (!dev_priv->has_mob)
1647 		return -ENOSYS;
1648 
1649 	if (!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS))
1650 		return -ENOSYS;
1651 
1652 	dev_priv->active_display_unit = vmw_du_screen_target;
1653 
1654 	for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i) {
1655 		ret = vmw_stdu_init(dev_priv, i);
1656 
1657 		if (unlikely(ret != 0)) {
1658 			drm_err(&dev_priv->drm,
1659 				"Failed to initialize STDU %d", i);
1660 			return ret;
1661 		}
1662 	}
1663 
1664 	drm_mode_config_reset(dev);
1665 
1666 	return 0;
1667 }
1668