1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /**************************************************************************
3  *
4  * Copyright 2009-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 #include "vmwgfx_kms.h"
28 
29 #include "vmwgfx_bo.h"
30 #include "vmw_surface_cache.h"
31 
32 #include <drm/drm_atomic.h>
33 #include <drm/drm_atomic_helper.h>
34 #include <drm/drm_damage_helper.h>
35 #include <drm/drm_fourcc.h>
36 #include <drm/drm_rect.h>
37 #include <drm/drm_sysfs.h>
38 
vmw_du_cleanup(struct vmw_display_unit * du)39 void vmw_du_cleanup(struct vmw_display_unit *du)
40 {
41 	struct vmw_private *dev_priv = vmw_priv(du->primary.dev);
42 	drm_plane_cleanup(&du->primary);
43 	if (vmw_cmd_supported(dev_priv))
44 		drm_plane_cleanup(&du->cursor.base);
45 
46 	drm_connector_unregister(&du->connector);
47 	drm_crtc_cleanup(&du->crtc);
48 	drm_encoder_cleanup(&du->encoder);
49 	drm_connector_cleanup(&du->connector);
50 }
51 
52 /*
53  * Display Unit Cursor functions
54  */
55 
56 static int vmw_du_cursor_plane_unmap_cm(struct vmw_plane_state *vps);
57 static void vmw_cursor_update_mob(struct vmw_private *dev_priv,
58 				  struct vmw_plane_state *vps,
59 				  u32 *image, u32 width, u32 height,
60 				  u32 hotspotX, u32 hotspotY);
61 
62 struct vmw_svga_fifo_cmd_define_cursor {
63 	u32 cmd;
64 	SVGAFifoCmdDefineAlphaCursor cursor;
65 };
66 
67 /**
68  * vmw_send_define_cursor_cmd - queue a define cursor command
69  * @dev_priv: the private driver struct
70  * @image: buffer which holds the cursor image
71  * @width: width of the mouse cursor image
72  * @height: height of the mouse cursor image
73  * @hotspotX: the horizontal position of mouse hotspot
74  * @hotspotY: the vertical position of mouse hotspot
75  */
vmw_send_define_cursor_cmd(struct vmw_private * dev_priv,u32 * image,u32 width,u32 height,u32 hotspotX,u32 hotspotY)76 static void vmw_send_define_cursor_cmd(struct vmw_private *dev_priv,
77 				       u32 *image, u32 width, u32 height,
78 				       u32 hotspotX, u32 hotspotY)
79 {
80 	struct vmw_svga_fifo_cmd_define_cursor *cmd;
81 	const u32 image_size = width * height * sizeof(*image);
82 	const u32 cmd_size = sizeof(*cmd) + image_size;
83 
84 	/* Try to reserve fifocmd space and swallow any failures;
85 	   such reservations cannot be left unconsumed for long
86 	   under the risk of clogging other fifocmd users, so
87 	   we treat reservations separtely from the way we treat
88 	   other fallible KMS-atomic resources at prepare_fb */
89 	cmd = VMW_CMD_RESERVE(dev_priv, cmd_size);
90 
91 	if (unlikely(!cmd))
92 		return;
93 
94 	memset(cmd, 0, sizeof(*cmd));
95 
96 	memcpy(&cmd[1], image, image_size);
97 
98 	cmd->cmd = SVGA_CMD_DEFINE_ALPHA_CURSOR;
99 	cmd->cursor.id = 0;
100 	cmd->cursor.width = width;
101 	cmd->cursor.height = height;
102 	cmd->cursor.hotspotX = hotspotX;
103 	cmd->cursor.hotspotY = hotspotY;
104 
105 	vmw_cmd_commit_flush(dev_priv, cmd_size);
106 }
107 
108 /**
109  * vmw_cursor_update_image - update the cursor image on the provided plane
110  * @dev_priv: the private driver struct
111  * @vps: the plane state of the cursor plane
112  * @image: buffer which holds the cursor image
113  * @width: width of the mouse cursor image
114  * @height: height of the mouse cursor image
115  * @hotspotX: the horizontal position of mouse hotspot
116  * @hotspotY: the vertical position of mouse hotspot
117  */
vmw_cursor_update_image(struct vmw_private * dev_priv,struct vmw_plane_state * vps,u32 * image,u32 width,u32 height,u32 hotspotX,u32 hotspotY)118 static void vmw_cursor_update_image(struct vmw_private *dev_priv,
119 				    struct vmw_plane_state *vps,
120 				    u32 *image, u32 width, u32 height,
121 				    u32 hotspotX, u32 hotspotY)
122 {
123 	if (vps->cursor.bo)
124 		vmw_cursor_update_mob(dev_priv, vps, image,
125 				      vps->base.crtc_w, vps->base.crtc_h,
126 				      hotspotX, hotspotY);
127 
128 	else
129 		vmw_send_define_cursor_cmd(dev_priv, image, width, height,
130 					   hotspotX, hotspotY);
131 }
132 
133 
134 /**
135  * vmw_cursor_update_mob - Update cursor vis CursorMob mechanism
136  *
137  * Called from inside vmw_du_cursor_plane_atomic_update to actually
138  * make the cursor-image live.
139  *
140  * @dev_priv: device to work with
141  * @vps: the plane state of the cursor plane
142  * @image: cursor source data to fill the MOB with
143  * @width: source data width
144  * @height: source data height
145  * @hotspotX: cursor hotspot x
146  * @hotspotY: cursor hotspot Y
147  */
vmw_cursor_update_mob(struct vmw_private * dev_priv,struct vmw_plane_state * vps,u32 * image,u32 width,u32 height,u32 hotspotX,u32 hotspotY)148 static void vmw_cursor_update_mob(struct vmw_private *dev_priv,
149 				  struct vmw_plane_state *vps,
150 				  u32 *image, u32 width, u32 height,
151 				  u32 hotspotX, u32 hotspotY)
152 {
153 	SVGAGBCursorHeader *header;
154 	SVGAGBAlphaCursorHeader *alpha_header;
155 	const u32 image_size = width * height * sizeof(*image);
156 
157 	header = vmw_bo_map_and_cache(vps->cursor.bo);
158 	alpha_header = &header->header.alphaHeader;
159 
160 	memset(header, 0, sizeof(*header));
161 
162 	header->type = SVGA_ALPHA_CURSOR;
163 	header->sizeInBytes = image_size;
164 
165 	alpha_header->hotspotX = hotspotX;
166 	alpha_header->hotspotY = hotspotY;
167 	alpha_header->width = width;
168 	alpha_header->height = height;
169 
170 	memcpy(header + 1, image, image_size);
171 	vmw_write(dev_priv, SVGA_REG_CURSOR_MOBID,
172 		  vps->cursor.bo->tbo.resource->start);
173 }
174 
175 
vmw_du_cursor_mob_size(u32 w,u32 h)176 static u32 vmw_du_cursor_mob_size(u32 w, u32 h)
177 {
178 	return w * h * sizeof(u32) + sizeof(SVGAGBCursorHeader);
179 }
180 
181 /**
182  * vmw_du_cursor_plane_acquire_image -- Acquire the image data
183  * @vps: cursor plane state
184  */
vmw_du_cursor_plane_acquire_image(struct vmw_plane_state * vps)185 static u32 *vmw_du_cursor_plane_acquire_image(struct vmw_plane_state *vps)
186 {
187 	bool is_iomem;
188 	if (vps->surf) {
189 		if (vps->surf_mapped)
190 			return vmw_bo_map_and_cache(vps->surf->res.guest_memory_bo);
191 		return vps->surf->snooper.image;
192 	} else if (vps->bo)
193 		return ttm_kmap_obj_virtual(&vps->bo->map, &is_iomem);
194 	return NULL;
195 }
196 
vmw_du_cursor_plane_has_changed(struct vmw_plane_state * old_vps,struct vmw_plane_state * new_vps)197 static bool vmw_du_cursor_plane_has_changed(struct vmw_plane_state *old_vps,
198 					    struct vmw_plane_state *new_vps)
199 {
200 	void *old_image;
201 	void *new_image;
202 	u32 size;
203 	bool changed;
204 
205 	if (old_vps->base.crtc_w != new_vps->base.crtc_w ||
206 	    old_vps->base.crtc_h != new_vps->base.crtc_h)
207 	    return true;
208 
209 	if (old_vps->cursor.hotspot_x != new_vps->cursor.hotspot_x ||
210 	    old_vps->cursor.hotspot_y != new_vps->cursor.hotspot_y)
211 	    return true;
212 
213 	size = new_vps->base.crtc_w * new_vps->base.crtc_h * sizeof(u32);
214 
215 	old_image = vmw_du_cursor_plane_acquire_image(old_vps);
216 	new_image = vmw_du_cursor_plane_acquire_image(new_vps);
217 
218 	changed = false;
219 	if (old_image && new_image)
220 		changed = memcmp(old_image, new_image, size) != 0;
221 
222 	return changed;
223 }
224 
vmw_du_destroy_cursor_mob(struct vmw_bo ** vbo)225 static void vmw_du_destroy_cursor_mob(struct vmw_bo **vbo)
226 {
227 	if (!(*vbo))
228 		return;
229 
230 	ttm_bo_unpin(&(*vbo)->tbo);
231 	vmw_bo_unreference(vbo);
232 }
233 
vmw_du_put_cursor_mob(struct vmw_cursor_plane * vcp,struct vmw_plane_state * vps)234 static void vmw_du_put_cursor_mob(struct vmw_cursor_plane *vcp,
235 				  struct vmw_plane_state *vps)
236 {
237 	u32 i;
238 
239 	if (!vps->cursor.bo)
240 		return;
241 
242 	vmw_du_cursor_plane_unmap_cm(vps);
243 
244 	/* Look for a free slot to return this mob to the cache. */
245 	for (i = 0; i < ARRAY_SIZE(vcp->cursor_mobs); i++) {
246 		if (!vcp->cursor_mobs[i]) {
247 			vcp->cursor_mobs[i] = vps->cursor.bo;
248 			vps->cursor.bo = NULL;
249 			return;
250 		}
251 	}
252 
253 	/* Cache is full: See if this mob is bigger than an existing mob. */
254 	for (i = 0; i < ARRAY_SIZE(vcp->cursor_mobs); i++) {
255 		if (vcp->cursor_mobs[i]->tbo.base.size <
256 		    vps->cursor.bo->tbo.base.size) {
257 			vmw_du_destroy_cursor_mob(&vcp->cursor_mobs[i]);
258 			vcp->cursor_mobs[i] = vps->cursor.bo;
259 			vps->cursor.bo = NULL;
260 			return;
261 		}
262 	}
263 
264 	/* Destroy it if it's not worth caching. */
265 	vmw_du_destroy_cursor_mob(&vps->cursor.bo);
266 }
267 
vmw_du_get_cursor_mob(struct vmw_cursor_plane * vcp,struct vmw_plane_state * vps)268 static int vmw_du_get_cursor_mob(struct vmw_cursor_plane *vcp,
269 				 struct vmw_plane_state *vps)
270 {
271 	struct vmw_private *dev_priv = vcp->base.dev->dev_private;
272 	u32 size = vmw_du_cursor_mob_size(vps->base.crtc_w, vps->base.crtc_h);
273 	u32 i;
274 	u32 cursor_max_dim, mob_max_size;
275 	int ret;
276 
277 	if (!dev_priv->has_mob ||
278 	    (dev_priv->capabilities2 & SVGA_CAP2_CURSOR_MOB) == 0)
279 		return -EINVAL;
280 
281 	mob_max_size = vmw_read(dev_priv, SVGA_REG_MOB_MAX_SIZE);
282 	cursor_max_dim = vmw_read(dev_priv, SVGA_REG_CURSOR_MAX_DIMENSION);
283 
284 	if (size > mob_max_size || vps->base.crtc_w > cursor_max_dim ||
285 	    vps->base.crtc_h > cursor_max_dim)
286 		return -EINVAL;
287 
288 	if (vps->cursor.bo) {
289 		if (vps->cursor.bo->tbo.base.size >= size)
290 			return 0;
291 		vmw_du_put_cursor_mob(vcp, vps);
292 	}
293 
294 	/* Look for an unused mob in the cache. */
295 	for (i = 0; i < ARRAY_SIZE(vcp->cursor_mobs); i++) {
296 		if (vcp->cursor_mobs[i] &&
297 		    vcp->cursor_mobs[i]->tbo.base.size >= size) {
298 			vps->cursor.bo = vcp->cursor_mobs[i];
299 			vcp->cursor_mobs[i] = NULL;
300 			return 0;
301 		}
302 	}
303 	/* Create a new mob if we can't find an existing one. */
304 	ret = vmw_bo_create_and_populate(dev_priv, size,
305 					 VMW_BO_DOMAIN_MOB,
306 					 &vps->cursor.bo);
307 
308 	if (ret != 0)
309 		return ret;
310 
311 	/* Fence the mob creation so we are guarateed to have the mob */
312 	ret = ttm_bo_reserve(&vps->cursor.bo->tbo, false, false, NULL);
313 	if (ret != 0)
314 		goto teardown;
315 
316 	vmw_bo_fence_single(&vps->cursor.bo->tbo, NULL);
317 	ttm_bo_unreserve(&vps->cursor.bo->tbo);
318 	return 0;
319 
320 teardown:
321 	vmw_du_destroy_cursor_mob(&vps->cursor.bo);
322 	return ret;
323 }
324 
325 
vmw_cursor_update_position(struct vmw_private * dev_priv,bool show,int x,int y)326 static void vmw_cursor_update_position(struct vmw_private *dev_priv,
327 				       bool show, int x, int y)
328 {
329 	const uint32_t svga_cursor_on = show ? SVGA_CURSOR_ON_SHOW
330 					     : SVGA_CURSOR_ON_HIDE;
331 	uint32_t count;
332 
333 	spin_lock(&dev_priv->cursor_lock);
334 	if (dev_priv->capabilities2 & SVGA_CAP2_EXTRA_REGS) {
335 		vmw_write(dev_priv, SVGA_REG_CURSOR4_X, x);
336 		vmw_write(dev_priv, SVGA_REG_CURSOR4_Y, y);
337 		vmw_write(dev_priv, SVGA_REG_CURSOR4_SCREEN_ID, SVGA3D_INVALID_ID);
338 		vmw_write(dev_priv, SVGA_REG_CURSOR4_ON, svga_cursor_on);
339 		vmw_write(dev_priv, SVGA_REG_CURSOR4_SUBMIT, 1);
340 	} else if (vmw_is_cursor_bypass3_enabled(dev_priv)) {
341 		vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_ON, svga_cursor_on);
342 		vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_X, x);
343 		vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_Y, y);
344 		count = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_CURSOR_COUNT);
345 		vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_COUNT, ++count);
346 	} else {
347 		vmw_write(dev_priv, SVGA_REG_CURSOR_X, x);
348 		vmw_write(dev_priv, SVGA_REG_CURSOR_Y, y);
349 		vmw_write(dev_priv, SVGA_REG_CURSOR_ON, svga_cursor_on);
350 	}
351 	spin_unlock(&dev_priv->cursor_lock);
352 }
353 
vmw_kms_cursor_snoop(struct vmw_surface * srf,struct ttm_object_file * tfile,struct ttm_buffer_object * bo,SVGA3dCmdHeader * header)354 void vmw_kms_cursor_snoop(struct vmw_surface *srf,
355 			  struct ttm_object_file *tfile,
356 			  struct ttm_buffer_object *bo,
357 			  SVGA3dCmdHeader *header)
358 {
359 	struct ttm_bo_kmap_obj map;
360 	unsigned long kmap_offset;
361 	unsigned long kmap_num;
362 	SVGA3dCopyBox *box;
363 	unsigned box_count;
364 	void *virtual;
365 	bool is_iomem;
366 	struct vmw_dma_cmd {
367 		SVGA3dCmdHeader header;
368 		SVGA3dCmdSurfaceDMA dma;
369 	} *cmd;
370 	int i, ret;
371 	const struct SVGA3dSurfaceDesc *desc =
372 		vmw_surface_get_desc(VMW_CURSOR_SNOOP_FORMAT);
373 	const u32 image_pitch = VMW_CURSOR_SNOOP_WIDTH * desc->pitchBytesPerBlock;
374 
375 	cmd = container_of(header, struct vmw_dma_cmd, header);
376 
377 	/* No snooper installed, nothing to copy */
378 	if (!srf->snooper.image)
379 		return;
380 
381 	if (cmd->dma.host.face != 0 || cmd->dma.host.mipmap != 0) {
382 		DRM_ERROR("face and mipmap for cursors should never != 0\n");
383 		return;
384 	}
385 
386 	if (cmd->header.size < 64) {
387 		DRM_ERROR("at least one full copy box must be given\n");
388 		return;
389 	}
390 
391 	box = (SVGA3dCopyBox *)&cmd[1];
392 	box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) /
393 			sizeof(SVGA3dCopyBox);
394 
395 	if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
396 	    box->x != 0    || box->y != 0    || box->z != 0    ||
397 	    box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
398 	    box->d != 1    || box_count != 1 ||
399 	    box->w > VMW_CURSOR_SNOOP_WIDTH || box->h > VMW_CURSOR_SNOOP_HEIGHT) {
400 		/* TODO handle none page aligned offsets */
401 		/* TODO handle more dst & src != 0 */
402 		/* TODO handle more then one copy */
403 		DRM_ERROR("Can't snoop dma request for cursor!\n");
404 		DRM_ERROR("(%u, %u, %u) (%u, %u, %u) (%ux%ux%u) %u %u\n",
405 			  box->srcx, box->srcy, box->srcz,
406 			  box->x, box->y, box->z,
407 			  box->w, box->h, box->d, box_count,
408 			  cmd->dma.guest.ptr.offset);
409 		return;
410 	}
411 
412 	kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
413 	kmap_num = (VMW_CURSOR_SNOOP_HEIGHT*image_pitch) >> PAGE_SHIFT;
414 
415 	ret = ttm_bo_reserve(bo, true, false, NULL);
416 	if (unlikely(ret != 0)) {
417 		DRM_ERROR("reserve failed\n");
418 		return;
419 	}
420 
421 	ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
422 	if (unlikely(ret != 0))
423 		goto err_unreserve;
424 
425 	virtual = ttm_kmap_obj_virtual(&map, &is_iomem);
426 
427 	if (box->w == VMW_CURSOR_SNOOP_WIDTH && cmd->dma.guest.pitch == image_pitch) {
428 		memcpy(srf->snooper.image, virtual,
429 		       VMW_CURSOR_SNOOP_HEIGHT*image_pitch);
430 	} else {
431 		/* Image is unsigned pointer. */
432 		for (i = 0; i < box->h; i++)
433 			memcpy(srf->snooper.image + i * image_pitch,
434 			       virtual + i * cmd->dma.guest.pitch,
435 			       box->w * desc->pitchBytesPerBlock);
436 	}
437 
438 	srf->snooper.age++;
439 
440 	ttm_bo_kunmap(&map);
441 err_unreserve:
442 	ttm_bo_unreserve(bo);
443 }
444 
445 /**
446  * vmw_kms_legacy_hotspot_clear - Clear legacy hotspots
447  *
448  * @dev_priv: Pointer to the device private struct.
449  *
450  * Clears all legacy hotspots.
451  */
vmw_kms_legacy_hotspot_clear(struct vmw_private * dev_priv)452 void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv)
453 {
454 	struct drm_device *dev = &dev_priv->drm;
455 	struct vmw_display_unit *du;
456 	struct drm_crtc *crtc;
457 
458 	drm_modeset_lock_all(dev);
459 	drm_for_each_crtc(crtc, dev) {
460 		du = vmw_crtc_to_du(crtc);
461 
462 		du->hotspot_x = 0;
463 		du->hotspot_y = 0;
464 	}
465 	drm_modeset_unlock_all(dev);
466 }
467 
vmw_kms_cursor_post_execbuf(struct vmw_private * dev_priv)468 void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
469 {
470 	struct drm_device *dev = &dev_priv->drm;
471 	struct vmw_display_unit *du;
472 	struct drm_crtc *crtc;
473 
474 	mutex_lock(&dev->mode_config.mutex);
475 
476 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
477 		du = vmw_crtc_to_du(crtc);
478 		if (!du->cursor_surface ||
479 		    du->cursor_age == du->cursor_surface->snooper.age ||
480 		    !du->cursor_surface->snooper.image)
481 			continue;
482 
483 		du->cursor_age = du->cursor_surface->snooper.age;
484 		vmw_send_define_cursor_cmd(dev_priv,
485 					   du->cursor_surface->snooper.image,
486 					   VMW_CURSOR_SNOOP_WIDTH,
487 					   VMW_CURSOR_SNOOP_HEIGHT,
488 					   du->hotspot_x + du->core_hotspot_x,
489 					   du->hotspot_y + du->core_hotspot_y);
490 	}
491 
492 	mutex_unlock(&dev->mode_config.mutex);
493 }
494 
495 
vmw_du_cursor_plane_destroy(struct drm_plane * plane)496 void vmw_du_cursor_plane_destroy(struct drm_plane *plane)
497 {
498 	struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane);
499 	u32 i;
500 
501 	vmw_cursor_update_position(plane->dev->dev_private, false, 0, 0);
502 
503 	for (i = 0; i < ARRAY_SIZE(vcp->cursor_mobs); i++)
504 		vmw_du_destroy_cursor_mob(&vcp->cursor_mobs[i]);
505 
506 	drm_plane_cleanup(plane);
507 }
508 
509 
vmw_du_primary_plane_destroy(struct drm_plane * plane)510 void vmw_du_primary_plane_destroy(struct drm_plane *plane)
511 {
512 	drm_plane_cleanup(plane);
513 
514 	/* Planes are static in our case so we don't free it */
515 }
516 
517 
518 /**
519  * vmw_du_plane_unpin_surf - unpins resource associated with a framebuffer surface
520  *
521  * @vps: plane state associated with the display surface
522  * @unreference: true if we also want to unreference the display.
523  */
vmw_du_plane_unpin_surf(struct vmw_plane_state * vps,bool unreference)524 void vmw_du_plane_unpin_surf(struct vmw_plane_state *vps,
525 			     bool unreference)
526 {
527 	if (vps->surf) {
528 		if (vps->pinned) {
529 			vmw_resource_unpin(&vps->surf->res);
530 			vps->pinned--;
531 		}
532 
533 		if (unreference) {
534 			if (vps->pinned)
535 				DRM_ERROR("Surface still pinned\n");
536 			vmw_surface_unreference(&vps->surf);
537 		}
538 	}
539 }
540 
541 
542 /**
543  * vmw_du_plane_cleanup_fb - Unpins the plane surface
544  *
545  * @plane:  display plane
546  * @old_state: Contains the FB to clean up
547  *
548  * Unpins the framebuffer surface
549  *
550  * Returns 0 on success
551  */
552 void
vmw_du_plane_cleanup_fb(struct drm_plane * plane,struct drm_plane_state * old_state)553 vmw_du_plane_cleanup_fb(struct drm_plane *plane,
554 			struct drm_plane_state *old_state)
555 {
556 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
557 
558 	vmw_du_plane_unpin_surf(vps, false);
559 }
560 
561 
562 /**
563  * vmw_du_cursor_plane_map_cm - Maps the cursor mobs.
564  *
565  * @vps: plane_state
566  *
567  * Returns 0 on success
568  */
569 
570 static int
vmw_du_cursor_plane_map_cm(struct vmw_plane_state * vps)571 vmw_du_cursor_plane_map_cm(struct vmw_plane_state *vps)
572 {
573 	int ret;
574 	u32 size = vmw_du_cursor_mob_size(vps->base.crtc_w, vps->base.crtc_h);
575 	struct ttm_buffer_object *bo;
576 
577 	if (!vps->cursor.bo)
578 		return -EINVAL;
579 
580 	bo = &vps->cursor.bo->tbo;
581 
582 	if (bo->base.size < size)
583 		return -EINVAL;
584 
585 	if (vps->cursor.bo->map.virtual)
586 		return 0;
587 
588 	ret = ttm_bo_reserve(bo, false, false, NULL);
589 	if (unlikely(ret != 0))
590 		return -ENOMEM;
591 
592 	vmw_bo_map_and_cache(vps->cursor.bo);
593 
594 	ttm_bo_unreserve(bo);
595 
596 	if (unlikely(ret != 0))
597 		return -ENOMEM;
598 
599 	return 0;
600 }
601 
602 
603 /**
604  * vmw_du_cursor_plane_unmap_cm - Unmaps the cursor mobs.
605  *
606  * @vps: state of the cursor plane
607  *
608  * Returns 0 on success
609  */
610 
611 static int
vmw_du_cursor_plane_unmap_cm(struct vmw_plane_state * vps)612 vmw_du_cursor_plane_unmap_cm(struct vmw_plane_state *vps)
613 {
614 	int ret = 0;
615 	struct vmw_bo *vbo = vps->cursor.bo;
616 
617 	if (!vbo || !vbo->map.virtual)
618 		return 0;
619 
620 	ret = ttm_bo_reserve(&vbo->tbo, true, false, NULL);
621 	if (likely(ret == 0)) {
622 		vmw_bo_unmap(vbo);
623 		ttm_bo_unreserve(&vbo->tbo);
624 	}
625 
626 	return ret;
627 }
628 
629 
630 /**
631  * vmw_du_cursor_plane_cleanup_fb - Unpins the plane surface
632  *
633  * @plane: cursor plane
634  * @old_state: contains the state to clean up
635  *
636  * Unmaps all cursor bo mappings and unpins the cursor surface
637  *
638  * Returns 0 on success
639  */
640 void
vmw_du_cursor_plane_cleanup_fb(struct drm_plane * plane,struct drm_plane_state * old_state)641 vmw_du_cursor_plane_cleanup_fb(struct drm_plane *plane,
642 			       struct drm_plane_state *old_state)
643 {
644 	struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane);
645 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
646 	bool is_iomem;
647 
648 	if (vps->surf_mapped) {
649 		vmw_bo_unmap(vps->surf->res.guest_memory_bo);
650 		vps->surf_mapped = false;
651 	}
652 
653 	if (vps->bo && ttm_kmap_obj_virtual(&vps->bo->map, &is_iomem)) {
654 		const int ret = ttm_bo_reserve(&vps->bo->tbo, true, false, NULL);
655 
656 		if (likely(ret == 0)) {
657 			ttm_bo_kunmap(&vps->bo->map);
658 			ttm_bo_unreserve(&vps->bo->tbo);
659 		}
660 	}
661 
662 	vmw_du_cursor_plane_unmap_cm(vps);
663 	vmw_du_put_cursor_mob(vcp, vps);
664 
665 	vmw_du_plane_unpin_surf(vps, false);
666 
667 	if (vps->surf) {
668 		vmw_surface_unreference(&vps->surf);
669 		vps->surf = NULL;
670 	}
671 
672 	if (vps->bo) {
673 		vmw_bo_unreference(&vps->bo);
674 		vps->bo = NULL;
675 	}
676 }
677 
678 
679 /**
680  * vmw_du_cursor_plane_prepare_fb - Readies the cursor by referencing it
681  *
682  * @plane:  display plane
683  * @new_state: info on the new plane state, including the FB
684  *
685  * Returns 0 on success
686  */
687 int
vmw_du_cursor_plane_prepare_fb(struct drm_plane * plane,struct drm_plane_state * new_state)688 vmw_du_cursor_plane_prepare_fb(struct drm_plane *plane,
689 			       struct drm_plane_state *new_state)
690 {
691 	struct drm_framebuffer *fb = new_state->fb;
692 	struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane);
693 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
694 	int ret = 0;
695 
696 	if (vps->surf) {
697 		vmw_surface_unreference(&vps->surf);
698 		vps->surf = NULL;
699 	}
700 
701 	if (vps->bo) {
702 		vmw_bo_unreference(&vps->bo);
703 		vps->bo = NULL;
704 	}
705 
706 	if (fb) {
707 		if (vmw_framebuffer_to_vfb(fb)->bo) {
708 			vps->bo = vmw_framebuffer_to_vfbd(fb)->buffer;
709 			vmw_bo_reference(vps->bo);
710 		} else {
711 			vps->surf = vmw_framebuffer_to_vfbs(fb)->surface;
712 			vmw_surface_reference(vps->surf);
713 		}
714 	}
715 
716 	if (!vps->surf && vps->bo) {
717 		const u32 size = new_state->crtc_w * new_state->crtc_h * sizeof(u32);
718 
719 		/*
720 		 * Not using vmw_bo_map_and_cache() helper here as we need to
721 		 * reserve the ttm_buffer_object first which
722 		 * vmw_bo_map_and_cache() omits.
723 		 */
724 		ret = ttm_bo_reserve(&vps->bo->tbo, true, false, NULL);
725 
726 		if (unlikely(ret != 0))
727 			return -ENOMEM;
728 
729 		ret = ttm_bo_kmap(&vps->bo->tbo, 0, PFN_UP(size), &vps->bo->map);
730 
731 		ttm_bo_unreserve(&vps->bo->tbo);
732 
733 		if (unlikely(ret != 0))
734 			return -ENOMEM;
735 	} else if (vps->surf && !vps->bo && vps->surf->res.guest_memory_bo) {
736 
737 		WARN_ON(vps->surf->snooper.image);
738 		ret = ttm_bo_reserve(&vps->surf->res.guest_memory_bo->tbo, true, false,
739 				     NULL);
740 		if (unlikely(ret != 0))
741 			return -ENOMEM;
742 		vmw_bo_map_and_cache(vps->surf->res.guest_memory_bo);
743 		ttm_bo_unreserve(&vps->surf->res.guest_memory_bo->tbo);
744 		vps->surf_mapped = true;
745 	}
746 
747 	if (vps->surf || vps->bo) {
748 		vmw_du_get_cursor_mob(vcp, vps);
749 		vmw_du_cursor_plane_map_cm(vps);
750 	}
751 
752 	return 0;
753 }
754 
755 
756 void
vmw_du_cursor_plane_atomic_update(struct drm_plane * plane,struct drm_atomic_state * state)757 vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
758 				  struct drm_atomic_state *state)
759 {
760 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
761 									   plane);
762 	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
763 									   plane);
764 	struct drm_crtc *crtc = new_state->crtc ?: old_state->crtc;
765 	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
766 	struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
767 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
768 	struct vmw_plane_state *old_vps = vmw_plane_state_to_vps(old_state);
769 	s32 hotspot_x, hotspot_y;
770 
771 	hotspot_x = du->hotspot_x;
772 	hotspot_y = du->hotspot_y;
773 
774 	if (new_state->fb) {
775 		hotspot_x += new_state->fb->hot_x;
776 		hotspot_y += new_state->fb->hot_y;
777 	}
778 
779 	du->cursor_surface = vps->surf;
780 	du->cursor_bo = vps->bo;
781 
782 	if (!vps->surf && !vps->bo) {
783 		vmw_cursor_update_position(dev_priv, false, 0, 0);
784 		return;
785 	}
786 
787 	vps->cursor.hotspot_x = hotspot_x;
788 	vps->cursor.hotspot_y = hotspot_y;
789 
790 	if (vps->surf) {
791 		du->cursor_age = du->cursor_surface->snooper.age;
792 	}
793 
794 	if (!vmw_du_cursor_plane_has_changed(old_vps, vps)) {
795 		/*
796 		 * If it hasn't changed, avoid making the device do extra
797 		 * work by keeping the old cursor active.
798 		 */
799 		struct vmw_cursor_plane_state tmp = old_vps->cursor;
800 		old_vps->cursor = vps->cursor;
801 		vps->cursor = tmp;
802 	} else {
803 		void *image = vmw_du_cursor_plane_acquire_image(vps);
804 		if (image)
805 			vmw_cursor_update_image(dev_priv, vps, image,
806 						new_state->crtc_w,
807 						new_state->crtc_h,
808 						hotspot_x, hotspot_y);
809 	}
810 
811 	du->cursor_x = new_state->crtc_x + du->set_gui_x;
812 	du->cursor_y = new_state->crtc_y + du->set_gui_y;
813 
814 	vmw_cursor_update_position(dev_priv, true,
815 				   du->cursor_x + hotspot_x,
816 				   du->cursor_y + hotspot_y);
817 
818 	du->core_hotspot_x = hotspot_x - du->hotspot_x;
819 	du->core_hotspot_y = hotspot_y - du->hotspot_y;
820 }
821 
822 
823 /**
824  * vmw_du_primary_plane_atomic_check - check if the new state is okay
825  *
826  * @plane: display plane
827  * @state: info on the new plane state, including the FB
828  *
829  * Check if the new state is settable given the current state.  Other
830  * than what the atomic helper checks, we care about crtc fitting
831  * the FB and maintaining one active framebuffer.
832  *
833  * Returns 0 on success
834  */
vmw_du_primary_plane_atomic_check(struct drm_plane * plane,struct drm_atomic_state * state)835 int vmw_du_primary_plane_atomic_check(struct drm_plane *plane,
836 				      struct drm_atomic_state *state)
837 {
838 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
839 									   plane);
840 	struct drm_crtc_state *crtc_state = NULL;
841 	struct drm_framebuffer *new_fb = new_state->fb;
842 	int ret;
843 
844 	if (new_state->crtc)
845 		crtc_state = drm_atomic_get_new_crtc_state(state,
846 							   new_state->crtc);
847 
848 	ret = drm_atomic_helper_check_plane_state(new_state, crtc_state,
849 						  DRM_PLANE_NO_SCALING,
850 						  DRM_PLANE_NO_SCALING,
851 						  false, true);
852 
853 	if (!ret && new_fb) {
854 		struct drm_crtc *crtc = new_state->crtc;
855 		struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
856 
857 		vmw_connector_state_to_vcs(du->connector.state);
858 	}
859 
860 
861 	return ret;
862 }
863 
864 
865 /**
866  * vmw_du_cursor_plane_atomic_check - check if the new state is okay
867  *
868  * @plane: cursor plane
869  * @state: info on the new plane state
870  *
871  * This is a chance to fail if the new cursor state does not fit
872  * our requirements.
873  *
874  * Returns 0 on success
875  */
vmw_du_cursor_plane_atomic_check(struct drm_plane * plane,struct drm_atomic_state * state)876 int vmw_du_cursor_plane_atomic_check(struct drm_plane *plane,
877 				     struct drm_atomic_state *state)
878 {
879 	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
880 									   plane);
881 	int ret = 0;
882 	struct drm_crtc_state *crtc_state = NULL;
883 	struct vmw_surface *surface = NULL;
884 	struct drm_framebuffer *fb = new_state->fb;
885 
886 	if (new_state->crtc)
887 		crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
888 							   new_state->crtc);
889 
890 	ret = drm_atomic_helper_check_plane_state(new_state, crtc_state,
891 						  DRM_PLANE_NO_SCALING,
892 						  DRM_PLANE_NO_SCALING,
893 						  true, true);
894 	if (ret)
895 		return ret;
896 
897 	/* Turning off */
898 	if (!fb)
899 		return 0;
900 
901 	/* A lot of the code assumes this */
902 	if (new_state->crtc_w != 64 || new_state->crtc_h != 64) {
903 		DRM_ERROR("Invalid cursor dimensions (%d, %d)\n",
904 			  new_state->crtc_w, new_state->crtc_h);
905 		return -EINVAL;
906 	}
907 
908 	if (!vmw_framebuffer_to_vfb(fb)->bo) {
909 		surface = vmw_framebuffer_to_vfbs(fb)->surface;
910 
911 		WARN_ON(!surface);
912 
913 		if (!surface ||
914 		    (!surface->snooper.image && !surface->res.guest_memory_bo)) {
915 			DRM_ERROR("surface not suitable for cursor\n");
916 			return -EINVAL;
917 		}
918 	}
919 
920 	return 0;
921 }
922 
923 
vmw_du_crtc_atomic_check(struct drm_crtc * crtc,struct drm_atomic_state * state)924 int vmw_du_crtc_atomic_check(struct drm_crtc *crtc,
925 			     struct drm_atomic_state *state)
926 {
927 	struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state,
928 									 crtc);
929 	struct vmw_display_unit *du = vmw_crtc_to_du(new_state->crtc);
930 	int connector_mask = drm_connector_mask(&du->connector);
931 	bool has_primary = new_state->plane_mask &
932 			   drm_plane_mask(crtc->primary);
933 
934 	/* We always want to have an active plane with an active CRTC */
935 	if (has_primary != new_state->enable)
936 		return -EINVAL;
937 
938 
939 	if (new_state->connector_mask != connector_mask &&
940 	    new_state->connector_mask != 0) {
941 		DRM_ERROR("Invalid connectors configuration\n");
942 		return -EINVAL;
943 	}
944 
945 	/*
946 	 * Our virtual device does not have a dot clock, so use the logical
947 	 * clock value as the dot clock.
948 	 */
949 	if (new_state->mode.crtc_clock == 0)
950 		new_state->adjusted_mode.crtc_clock = new_state->mode.clock;
951 
952 	return 0;
953 }
954 
955 
vmw_du_crtc_atomic_begin(struct drm_crtc * crtc,struct drm_atomic_state * state)956 void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc,
957 			      struct drm_atomic_state *state)
958 {
959 }
960 
961 
vmw_du_crtc_atomic_flush(struct drm_crtc * crtc,struct drm_atomic_state * state)962 void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc,
963 			      struct drm_atomic_state *state)
964 {
965 }
966 
967 
968 /**
969  * vmw_du_crtc_duplicate_state - duplicate crtc state
970  * @crtc: DRM crtc
971  *
972  * Allocates and returns a copy of the crtc state (both common and
973  * vmw-specific) for the specified crtc.
974  *
975  * Returns: The newly allocated crtc state, or NULL on failure.
976  */
977 struct drm_crtc_state *
vmw_du_crtc_duplicate_state(struct drm_crtc * crtc)978 vmw_du_crtc_duplicate_state(struct drm_crtc *crtc)
979 {
980 	struct drm_crtc_state *state;
981 	struct vmw_crtc_state *vcs;
982 
983 	if (WARN_ON(!crtc->state))
984 		return NULL;
985 
986 	vcs = kmemdup(crtc->state, sizeof(*vcs), GFP_KERNEL);
987 
988 	if (!vcs)
989 		return NULL;
990 
991 	state = &vcs->base;
992 
993 	__drm_atomic_helper_crtc_duplicate_state(crtc, state);
994 
995 	return state;
996 }
997 
998 
999 /**
1000  * vmw_du_crtc_reset - creates a blank vmw crtc state
1001  * @crtc: DRM crtc
1002  *
1003  * Resets the atomic state for @crtc by freeing the state pointer (which
1004  * might be NULL, e.g. at driver load time) and allocating a new empty state
1005  * object.
1006  */
vmw_du_crtc_reset(struct drm_crtc * crtc)1007 void vmw_du_crtc_reset(struct drm_crtc *crtc)
1008 {
1009 	struct vmw_crtc_state *vcs;
1010 
1011 
1012 	if (crtc->state) {
1013 		__drm_atomic_helper_crtc_destroy_state(crtc->state);
1014 
1015 		kfree(vmw_crtc_state_to_vcs(crtc->state));
1016 	}
1017 
1018 	vcs = kzalloc(sizeof(*vcs), GFP_KERNEL);
1019 
1020 	if (!vcs) {
1021 		DRM_ERROR("Cannot allocate vmw_crtc_state\n");
1022 		return;
1023 	}
1024 
1025 	__drm_atomic_helper_crtc_reset(crtc, &vcs->base);
1026 }
1027 
1028 
1029 /**
1030  * vmw_du_crtc_destroy_state - destroy crtc state
1031  * @crtc: DRM crtc
1032  * @state: state object to destroy
1033  *
1034  * Destroys the crtc state (both common and vmw-specific) for the
1035  * specified plane.
1036  */
1037 void
vmw_du_crtc_destroy_state(struct drm_crtc * crtc,struct drm_crtc_state * state)1038 vmw_du_crtc_destroy_state(struct drm_crtc *crtc,
1039 			  struct drm_crtc_state *state)
1040 {
1041 	drm_atomic_helper_crtc_destroy_state(crtc, state);
1042 }
1043 
1044 
1045 /**
1046  * vmw_du_plane_duplicate_state - duplicate plane state
1047  * @plane: drm plane
1048  *
1049  * Allocates and returns a copy of the plane state (both common and
1050  * vmw-specific) for the specified plane.
1051  *
1052  * Returns: The newly allocated plane state, or NULL on failure.
1053  */
1054 struct drm_plane_state *
vmw_du_plane_duplicate_state(struct drm_plane * plane)1055 vmw_du_plane_duplicate_state(struct drm_plane *plane)
1056 {
1057 	struct drm_plane_state *state;
1058 	struct vmw_plane_state *vps;
1059 
1060 	vps = kmemdup(plane->state, sizeof(*vps), GFP_KERNEL);
1061 
1062 	if (!vps)
1063 		return NULL;
1064 
1065 	vps->pinned = 0;
1066 	vps->cpp = 0;
1067 
1068 	memset(&vps->cursor, 0, sizeof(vps->cursor));
1069 
1070 	/* Each ref counted resource needs to be acquired again */
1071 	if (vps->surf)
1072 		(void) vmw_surface_reference(vps->surf);
1073 
1074 	if (vps->bo)
1075 		(void) vmw_bo_reference(vps->bo);
1076 
1077 	state = &vps->base;
1078 
1079 	__drm_atomic_helper_plane_duplicate_state(plane, state);
1080 
1081 	return state;
1082 }
1083 
1084 
1085 /**
1086  * vmw_du_plane_reset - creates a blank vmw plane state
1087  * @plane: drm plane
1088  *
1089  * Resets the atomic state for @plane by freeing the state pointer (which might
1090  * be NULL, e.g. at driver load time) and allocating a new empty state object.
1091  */
vmw_du_plane_reset(struct drm_plane * plane)1092 void vmw_du_plane_reset(struct drm_plane *plane)
1093 {
1094 	struct vmw_plane_state *vps;
1095 
1096 	if (plane->state)
1097 		vmw_du_plane_destroy_state(plane, plane->state);
1098 
1099 	vps = kzalloc(sizeof(*vps), GFP_KERNEL);
1100 
1101 	if (!vps) {
1102 		DRM_ERROR("Cannot allocate vmw_plane_state\n");
1103 		return;
1104 	}
1105 
1106 	__drm_atomic_helper_plane_reset(plane, &vps->base);
1107 }
1108 
1109 
1110 /**
1111  * vmw_du_plane_destroy_state - destroy plane state
1112  * @plane: DRM plane
1113  * @state: state object to destroy
1114  *
1115  * Destroys the plane state (both common and vmw-specific) for the
1116  * specified plane.
1117  */
1118 void
vmw_du_plane_destroy_state(struct drm_plane * plane,struct drm_plane_state * state)1119 vmw_du_plane_destroy_state(struct drm_plane *plane,
1120 			   struct drm_plane_state *state)
1121 {
1122 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(state);
1123 
1124 	/* Should have been freed by cleanup_fb */
1125 	if (vps->surf)
1126 		vmw_surface_unreference(&vps->surf);
1127 
1128 	if (vps->bo)
1129 		vmw_bo_unreference(&vps->bo);
1130 
1131 	drm_atomic_helper_plane_destroy_state(plane, state);
1132 }
1133 
1134 
1135 /**
1136  * vmw_du_connector_duplicate_state - duplicate connector state
1137  * @connector: DRM connector
1138  *
1139  * Allocates and returns a copy of the connector state (both common and
1140  * vmw-specific) for the specified connector.
1141  *
1142  * Returns: The newly allocated connector state, or NULL on failure.
1143  */
1144 struct drm_connector_state *
vmw_du_connector_duplicate_state(struct drm_connector * connector)1145 vmw_du_connector_duplicate_state(struct drm_connector *connector)
1146 {
1147 	struct drm_connector_state *state;
1148 	struct vmw_connector_state *vcs;
1149 
1150 	if (WARN_ON(!connector->state))
1151 		return NULL;
1152 
1153 	vcs = kmemdup(connector->state, sizeof(*vcs), GFP_KERNEL);
1154 
1155 	if (!vcs)
1156 		return NULL;
1157 
1158 	state = &vcs->base;
1159 
1160 	__drm_atomic_helper_connector_duplicate_state(connector, state);
1161 
1162 	return state;
1163 }
1164 
1165 
1166 /**
1167  * vmw_du_connector_reset - creates a blank vmw connector state
1168  * @connector: DRM connector
1169  *
1170  * Resets the atomic state for @connector by freeing the state pointer (which
1171  * might be NULL, e.g. at driver load time) and allocating a new empty state
1172  * object.
1173  */
vmw_du_connector_reset(struct drm_connector * connector)1174 void vmw_du_connector_reset(struct drm_connector *connector)
1175 {
1176 	struct vmw_connector_state *vcs;
1177 
1178 
1179 	if (connector->state) {
1180 		__drm_atomic_helper_connector_destroy_state(connector->state);
1181 
1182 		kfree(vmw_connector_state_to_vcs(connector->state));
1183 	}
1184 
1185 	vcs = kzalloc(sizeof(*vcs), GFP_KERNEL);
1186 
1187 	if (!vcs) {
1188 		DRM_ERROR("Cannot allocate vmw_connector_state\n");
1189 		return;
1190 	}
1191 
1192 	__drm_atomic_helper_connector_reset(connector, &vcs->base);
1193 }
1194 
1195 
1196 /**
1197  * vmw_du_connector_destroy_state - destroy connector state
1198  * @connector: DRM connector
1199  * @state: state object to destroy
1200  *
1201  * Destroys the connector state (both common and vmw-specific) for the
1202  * specified plane.
1203  */
1204 void
vmw_du_connector_destroy_state(struct drm_connector * connector,struct drm_connector_state * state)1205 vmw_du_connector_destroy_state(struct drm_connector *connector,
1206 			  struct drm_connector_state *state)
1207 {
1208 	drm_atomic_helper_connector_destroy_state(connector, state);
1209 }
1210 /*
1211  * Generic framebuffer code
1212  */
1213 
1214 /*
1215  * Surface framebuffer code
1216  */
1217 
vmw_framebuffer_surface_destroy(struct drm_framebuffer * framebuffer)1218 static void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)
1219 {
1220 	struct vmw_framebuffer_surface *vfbs =
1221 		vmw_framebuffer_to_vfbs(framebuffer);
1222 
1223 	drm_framebuffer_cleanup(framebuffer);
1224 	vmw_surface_unreference(&vfbs->surface);
1225 
1226 	kfree(vfbs);
1227 }
1228 
1229 /**
1230  * vmw_kms_readback - Perform a readback from the screen system to
1231  * a buffer-object backed framebuffer.
1232  *
1233  * @dev_priv: Pointer to the device private structure.
1234  * @file_priv: Pointer to a struct drm_file identifying the caller.
1235  * Must be set to NULL if @user_fence_rep is NULL.
1236  * @vfb: Pointer to the buffer-object backed framebuffer.
1237  * @user_fence_rep: User-space provided structure for fence information.
1238  * Must be set to non-NULL if @file_priv is non-NULL.
1239  * @vclips: Array of clip rects.
1240  * @num_clips: Number of clip rects in @vclips.
1241  *
1242  * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
1243  * interrupted.
1244  */
vmw_kms_readback(struct vmw_private * dev_priv,struct drm_file * file_priv,struct vmw_framebuffer * vfb,struct drm_vmw_fence_rep __user * user_fence_rep,struct drm_vmw_rect * vclips,uint32_t num_clips)1245 int vmw_kms_readback(struct vmw_private *dev_priv,
1246 		     struct drm_file *file_priv,
1247 		     struct vmw_framebuffer *vfb,
1248 		     struct drm_vmw_fence_rep __user *user_fence_rep,
1249 		     struct drm_vmw_rect *vclips,
1250 		     uint32_t num_clips)
1251 {
1252 	switch (dev_priv->active_display_unit) {
1253 	case vmw_du_screen_object:
1254 		return vmw_kms_sou_readback(dev_priv, file_priv, vfb,
1255 					    user_fence_rep, vclips, num_clips,
1256 					    NULL);
1257 	case vmw_du_screen_target:
1258 		return vmw_kms_stdu_readback(dev_priv, file_priv, vfb,
1259 					     user_fence_rep, NULL, vclips, num_clips,
1260 					     1, NULL);
1261 	default:
1262 		WARN_ONCE(true,
1263 			  "Readback called with invalid display system.\n");
1264 }
1265 
1266 	return -ENOSYS;
1267 }
1268 
1269 
1270 static const struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
1271 	.destroy = vmw_framebuffer_surface_destroy,
1272 	.dirty = drm_atomic_helper_dirtyfb,
1273 };
1274 
vmw_kms_new_framebuffer_surface(struct vmw_private * dev_priv,struct vmw_surface * surface,struct vmw_framebuffer ** out,const struct drm_mode_fb_cmd2 * mode_cmd,bool is_bo_proxy)1275 static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
1276 					   struct vmw_surface *surface,
1277 					   struct vmw_framebuffer **out,
1278 					   const struct drm_mode_fb_cmd2
1279 					   *mode_cmd,
1280 					   bool is_bo_proxy)
1281 
1282 {
1283 	struct drm_device *dev = &dev_priv->drm;
1284 	struct vmw_framebuffer_surface *vfbs;
1285 	enum SVGA3dSurfaceFormat format;
1286 	int ret;
1287 
1288 	/* 3D is only supported on HWv8 and newer hosts */
1289 	if (dev_priv->active_display_unit == vmw_du_legacy)
1290 		return -ENOSYS;
1291 
1292 	/*
1293 	 * Sanity checks.
1294 	 */
1295 
1296 	if (!drm_any_plane_has_format(&dev_priv->drm,
1297 				      mode_cmd->pixel_format,
1298 				      mode_cmd->modifier[0])) {
1299 		drm_dbg(&dev_priv->drm,
1300 			"unsupported pixel format %p4cc / modifier 0x%llx\n",
1301 			&mode_cmd->pixel_format, mode_cmd->modifier[0]);
1302 		return -EINVAL;
1303 	}
1304 
1305 	/* Surface must be marked as a scanout. */
1306 	if (unlikely(!surface->metadata.scanout))
1307 		return -EINVAL;
1308 
1309 	if (unlikely(surface->metadata.mip_levels[0] != 1 ||
1310 		     surface->metadata.num_sizes != 1 ||
1311 		     surface->metadata.base_size.width < mode_cmd->width ||
1312 		     surface->metadata.base_size.height < mode_cmd->height ||
1313 		     surface->metadata.base_size.depth != 1)) {
1314 		DRM_ERROR("Incompatible surface dimensions "
1315 			  "for requested mode.\n");
1316 		return -EINVAL;
1317 	}
1318 
1319 	switch (mode_cmd->pixel_format) {
1320 	case DRM_FORMAT_ARGB8888:
1321 		format = SVGA3D_A8R8G8B8;
1322 		break;
1323 	case DRM_FORMAT_XRGB8888:
1324 		format = SVGA3D_X8R8G8B8;
1325 		break;
1326 	case DRM_FORMAT_RGB565:
1327 		format = SVGA3D_R5G6B5;
1328 		break;
1329 	case DRM_FORMAT_XRGB1555:
1330 		format = SVGA3D_A1R5G5B5;
1331 		break;
1332 	default:
1333 		DRM_ERROR("Invalid pixel format: %p4cc\n",
1334 			  &mode_cmd->pixel_format);
1335 		return -EINVAL;
1336 	}
1337 
1338 	/*
1339 	 * For DX, surface format validation is done when surface->scanout
1340 	 * is set.
1341 	 */
1342 	if (!has_sm4_context(dev_priv) && format != surface->metadata.format) {
1343 		DRM_ERROR("Invalid surface format for requested mode.\n");
1344 		return -EINVAL;
1345 	}
1346 
1347 	vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL);
1348 	if (!vfbs) {
1349 		ret = -ENOMEM;
1350 		goto out_err1;
1351 	}
1352 
1353 	drm_helper_mode_fill_fb_struct(dev, &vfbs->base.base, mode_cmd);
1354 	vfbs->surface = vmw_surface_reference(surface);
1355 	vfbs->base.user_handle = mode_cmd->handles[0];
1356 	vfbs->is_bo_proxy = is_bo_proxy;
1357 
1358 	*out = &vfbs->base;
1359 
1360 	ret = drm_framebuffer_init(dev, &vfbs->base.base,
1361 				   &vmw_framebuffer_surface_funcs);
1362 	if (ret)
1363 		goto out_err2;
1364 
1365 	return 0;
1366 
1367 out_err2:
1368 	vmw_surface_unreference(&surface);
1369 	kfree(vfbs);
1370 out_err1:
1371 	return ret;
1372 }
1373 
1374 /*
1375  * Buffer-object framebuffer code
1376  */
1377 
vmw_framebuffer_bo_create_handle(struct drm_framebuffer * fb,struct drm_file * file_priv,unsigned int * handle)1378 static int vmw_framebuffer_bo_create_handle(struct drm_framebuffer *fb,
1379 					    struct drm_file *file_priv,
1380 					    unsigned int *handle)
1381 {
1382 	struct vmw_framebuffer_bo *vfbd =
1383 			vmw_framebuffer_to_vfbd(fb);
1384 
1385 	return drm_gem_handle_create(file_priv, &vfbd->buffer->tbo.base, handle);
1386 }
1387 
vmw_framebuffer_bo_destroy(struct drm_framebuffer * framebuffer)1388 static void vmw_framebuffer_bo_destroy(struct drm_framebuffer *framebuffer)
1389 {
1390 	struct vmw_framebuffer_bo *vfbd =
1391 		vmw_framebuffer_to_vfbd(framebuffer);
1392 
1393 	drm_framebuffer_cleanup(framebuffer);
1394 	vmw_bo_unreference(&vfbd->buffer);
1395 
1396 	kfree(vfbd);
1397 }
1398 
1399 static const struct drm_framebuffer_funcs vmw_framebuffer_bo_funcs = {
1400 	.create_handle = vmw_framebuffer_bo_create_handle,
1401 	.destroy = vmw_framebuffer_bo_destroy,
1402 	.dirty = drm_atomic_helper_dirtyfb,
1403 };
1404 
1405 /**
1406  * vmw_create_bo_proxy - create a proxy surface for the buffer object
1407  *
1408  * @dev: DRM device
1409  * @mode_cmd: parameters for the new surface
1410  * @bo_mob: MOB backing the buffer object
1411  * @srf_out: newly created surface
1412  *
1413  * When the content FB is a buffer object, we create a surface as a proxy to the
1414  * same buffer.  This way we can do a surface copy rather than a surface DMA.
1415  * This is a more efficient approach
1416  *
1417  * RETURNS:
1418  * 0 on success, error code otherwise
1419  */
vmw_create_bo_proxy(struct drm_device * dev,const struct drm_mode_fb_cmd2 * mode_cmd,struct vmw_bo * bo_mob,struct vmw_surface ** srf_out)1420 static int vmw_create_bo_proxy(struct drm_device *dev,
1421 			       const struct drm_mode_fb_cmd2 *mode_cmd,
1422 			       struct vmw_bo *bo_mob,
1423 			       struct vmw_surface **srf_out)
1424 {
1425 	struct vmw_surface_metadata metadata = {0};
1426 	uint32_t format;
1427 	struct vmw_resource *res;
1428 	unsigned int bytes_pp;
1429 	int ret;
1430 
1431 	switch (mode_cmd->pixel_format) {
1432 	case DRM_FORMAT_ARGB8888:
1433 	case DRM_FORMAT_XRGB8888:
1434 		format = SVGA3D_X8R8G8B8;
1435 		bytes_pp = 4;
1436 		break;
1437 
1438 	case DRM_FORMAT_RGB565:
1439 	case DRM_FORMAT_XRGB1555:
1440 		format = SVGA3D_R5G6B5;
1441 		bytes_pp = 2;
1442 		break;
1443 
1444 	case 8:
1445 		format = SVGA3D_P8;
1446 		bytes_pp = 1;
1447 		break;
1448 
1449 	default:
1450 		DRM_ERROR("Invalid framebuffer format %p4cc\n",
1451 			  &mode_cmd->pixel_format);
1452 		return -EINVAL;
1453 	}
1454 
1455 	metadata.format = format;
1456 	metadata.mip_levels[0] = 1;
1457 	metadata.num_sizes = 1;
1458 	metadata.base_size.width = mode_cmd->pitches[0] / bytes_pp;
1459 	metadata.base_size.height =  mode_cmd->height;
1460 	metadata.base_size.depth = 1;
1461 	metadata.scanout = true;
1462 
1463 	ret = vmw_gb_surface_define(vmw_priv(dev), &metadata, srf_out);
1464 	if (ret) {
1465 		DRM_ERROR("Failed to allocate proxy content buffer\n");
1466 		return ret;
1467 	}
1468 
1469 	res = &(*srf_out)->res;
1470 
1471 	/* Reserve and switch the backing mob. */
1472 	mutex_lock(&res->dev_priv->cmdbuf_mutex);
1473 	(void) vmw_resource_reserve(res, false, true);
1474 	vmw_user_bo_unref(&res->guest_memory_bo);
1475 	res->guest_memory_bo = vmw_user_bo_ref(bo_mob);
1476 	res->guest_memory_offset = 0;
1477 	vmw_resource_unreserve(res, false, false, false, NULL, 0);
1478 	mutex_unlock(&res->dev_priv->cmdbuf_mutex);
1479 
1480 	return 0;
1481 }
1482 
1483 
1484 
vmw_kms_new_framebuffer_bo(struct vmw_private * dev_priv,struct vmw_bo * bo,struct vmw_framebuffer ** out,const struct drm_mode_fb_cmd2 * mode_cmd)1485 static int vmw_kms_new_framebuffer_bo(struct vmw_private *dev_priv,
1486 				      struct vmw_bo *bo,
1487 				      struct vmw_framebuffer **out,
1488 				      const struct drm_mode_fb_cmd2
1489 				      *mode_cmd)
1490 
1491 {
1492 	struct drm_device *dev = &dev_priv->drm;
1493 	struct vmw_framebuffer_bo *vfbd;
1494 	unsigned int requested_size;
1495 	int ret;
1496 
1497 	requested_size = mode_cmd->height * mode_cmd->pitches[0];
1498 	if (unlikely(requested_size > bo->tbo.base.size)) {
1499 		DRM_ERROR("Screen buffer object size is too small "
1500 			  "for requested mode.\n");
1501 		return -EINVAL;
1502 	}
1503 
1504 	if (!drm_any_plane_has_format(&dev_priv->drm,
1505 				      mode_cmd->pixel_format,
1506 				      mode_cmd->modifier[0])) {
1507 		drm_dbg(&dev_priv->drm,
1508 			"unsupported pixel format %p4cc / modifier 0x%llx\n",
1509 			&mode_cmd->pixel_format, mode_cmd->modifier[0]);
1510 		return -EINVAL;
1511 	}
1512 
1513 	vfbd = kzalloc(sizeof(*vfbd), GFP_KERNEL);
1514 	if (!vfbd) {
1515 		ret = -ENOMEM;
1516 		goto out_err1;
1517 	}
1518 
1519 	vfbd->base.base.obj[0] = &bo->tbo.base;
1520 	drm_helper_mode_fill_fb_struct(dev, &vfbd->base.base, mode_cmd);
1521 	vfbd->base.bo = true;
1522 	vfbd->buffer = vmw_bo_reference(bo);
1523 	vfbd->base.user_handle = mode_cmd->handles[0];
1524 	*out = &vfbd->base;
1525 
1526 	ret = drm_framebuffer_init(dev, &vfbd->base.base,
1527 				   &vmw_framebuffer_bo_funcs);
1528 	if (ret)
1529 		goto out_err2;
1530 
1531 	return 0;
1532 
1533 out_err2:
1534 	vmw_bo_unreference(&bo);
1535 	kfree(vfbd);
1536 out_err1:
1537 	return ret;
1538 }
1539 
1540 
1541 /**
1542  * vmw_kms_srf_ok - check if a surface can be created
1543  *
1544  * @dev_priv: Pointer to device private struct.
1545  * @width: requested width
1546  * @height: requested height
1547  *
1548  * Surfaces need to be less than texture size
1549  */
1550 static bool
vmw_kms_srf_ok(struct vmw_private * dev_priv,uint32_t width,uint32_t height)1551 vmw_kms_srf_ok(struct vmw_private *dev_priv, uint32_t width, uint32_t height)
1552 {
1553 	if (width  > dev_priv->texture_max_width ||
1554 	    height > dev_priv->texture_max_height)
1555 		return false;
1556 
1557 	return true;
1558 }
1559 
1560 /**
1561  * vmw_kms_new_framebuffer - Create a new framebuffer.
1562  *
1563  * @dev_priv: Pointer to device private struct.
1564  * @bo: Pointer to buffer object to wrap the kms framebuffer around.
1565  * Either @bo or @surface must be NULL.
1566  * @surface: Pointer to a surface to wrap the kms framebuffer around.
1567  * Either @bo or @surface must be NULL.
1568  * @only_2d: No presents will occur to this buffer object based framebuffer.
1569  * This helps the code to do some important optimizations.
1570  * @mode_cmd: Frame-buffer metadata.
1571  */
1572 struct vmw_framebuffer *
vmw_kms_new_framebuffer(struct vmw_private * dev_priv,struct vmw_bo * bo,struct vmw_surface * surface,bool only_2d,const struct drm_mode_fb_cmd2 * mode_cmd)1573 vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
1574 			struct vmw_bo *bo,
1575 			struct vmw_surface *surface,
1576 			bool only_2d,
1577 			const struct drm_mode_fb_cmd2 *mode_cmd)
1578 {
1579 	struct vmw_framebuffer *vfb = NULL;
1580 	bool is_bo_proxy = false;
1581 	int ret;
1582 
1583 	/*
1584 	 * We cannot use the SurfaceDMA command in an non-accelerated VM,
1585 	 * therefore, wrap the buffer object in a surface so we can use the
1586 	 * SurfaceCopy command.
1587 	 */
1588 	if (vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)  &&
1589 	    bo && only_2d &&
1590 	    mode_cmd->width > 64 &&  /* Don't create a proxy for cursor */
1591 	    dev_priv->active_display_unit == vmw_du_screen_target) {
1592 		ret = vmw_create_bo_proxy(&dev_priv->drm, mode_cmd,
1593 					  bo, &surface);
1594 		if (ret)
1595 			return ERR_PTR(ret);
1596 
1597 		is_bo_proxy = true;
1598 	}
1599 
1600 	/* Create the new framebuffer depending one what we have */
1601 	if (surface) {
1602 		ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
1603 						      mode_cmd,
1604 						      is_bo_proxy);
1605 		/*
1606 		 * vmw_create_bo_proxy() adds a reference that is no longer
1607 		 * needed
1608 		 */
1609 		if (is_bo_proxy)
1610 			vmw_surface_unreference(&surface);
1611 	} else if (bo) {
1612 		ret = vmw_kms_new_framebuffer_bo(dev_priv, bo, &vfb,
1613 						 mode_cmd);
1614 	} else {
1615 		BUG();
1616 	}
1617 
1618 	if (ret)
1619 		return ERR_PTR(ret);
1620 
1621 	return vfb;
1622 }
1623 
1624 /*
1625  * Generic Kernel modesetting functions
1626  */
1627 
vmw_kms_fb_create(struct drm_device * dev,struct drm_file * file_priv,const struct drm_mode_fb_cmd2 * mode_cmd)1628 static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
1629 						 struct drm_file *file_priv,
1630 						 const struct drm_mode_fb_cmd2 *mode_cmd)
1631 {
1632 	struct vmw_private *dev_priv = vmw_priv(dev);
1633 	struct vmw_framebuffer *vfb = NULL;
1634 	struct vmw_surface *surface = NULL;
1635 	struct vmw_bo *bo = NULL;
1636 	int ret;
1637 
1638 	/* returns either a bo or surface */
1639 	ret = vmw_user_lookup_handle(dev_priv, file_priv,
1640 				     mode_cmd->handles[0],
1641 				     &surface, &bo);
1642 	if (ret) {
1643 		DRM_ERROR("Invalid buffer object handle %u (0x%x).\n",
1644 			  mode_cmd->handles[0], mode_cmd->handles[0]);
1645 		goto err_out;
1646 	}
1647 
1648 
1649 	if (!bo &&
1650 	    !vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)) {
1651 		DRM_ERROR("Surface size cannot exceed %dx%d\n",
1652 			dev_priv->texture_max_width,
1653 			dev_priv->texture_max_height);
1654 		goto err_out;
1655 	}
1656 
1657 
1658 	vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface,
1659 				      !(dev_priv->capabilities & SVGA_CAP_3D),
1660 				      mode_cmd);
1661 	if (IS_ERR(vfb)) {
1662 		ret = PTR_ERR(vfb);
1663 		goto err_out;
1664 	}
1665 
1666 err_out:
1667 	/* vmw_user_lookup_handle takes one ref so does new_fb */
1668 	if (bo)
1669 		vmw_user_bo_unref(&bo);
1670 	if (surface)
1671 		vmw_surface_unreference(&surface);
1672 
1673 	if (ret) {
1674 		DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
1675 		return ERR_PTR(ret);
1676 	}
1677 
1678 	return &vfb->base;
1679 }
1680 
1681 /**
1682  * vmw_kms_check_display_memory - Validates display memory required for a
1683  * topology
1684  * @dev: DRM device
1685  * @num_rects: number of drm_rect in rects
1686  * @rects: array of drm_rect representing the topology to validate indexed by
1687  * crtc index.
1688  *
1689  * Returns:
1690  * 0 on success otherwise negative error code
1691  */
vmw_kms_check_display_memory(struct drm_device * dev,uint32_t num_rects,struct drm_rect * rects)1692 static int vmw_kms_check_display_memory(struct drm_device *dev,
1693 					uint32_t num_rects,
1694 					struct drm_rect *rects)
1695 {
1696 	struct vmw_private *dev_priv = vmw_priv(dev);
1697 	struct drm_rect bounding_box = {0};
1698 	u64 total_pixels = 0, pixel_mem, bb_mem;
1699 	int i;
1700 
1701 	for (i = 0; i < num_rects; i++) {
1702 		/*
1703 		 * For STDU only individual screen (screen target) is limited by
1704 		 * SCREENTARGET_MAX_WIDTH/HEIGHT registers.
1705 		 */
1706 		if (dev_priv->active_display_unit == vmw_du_screen_target &&
1707 		    (drm_rect_width(&rects[i]) > dev_priv->stdu_max_width ||
1708 		     drm_rect_height(&rects[i]) > dev_priv->stdu_max_height)) {
1709 			VMW_DEBUG_KMS("Screen size not supported.\n");
1710 			return -EINVAL;
1711 		}
1712 
1713 		/* Bounding box upper left is at (0,0). */
1714 		if (rects[i].x2 > bounding_box.x2)
1715 			bounding_box.x2 = rects[i].x2;
1716 
1717 		if (rects[i].y2 > bounding_box.y2)
1718 			bounding_box.y2 = rects[i].y2;
1719 
1720 		total_pixels += (u64) drm_rect_width(&rects[i]) *
1721 			(u64) drm_rect_height(&rects[i]);
1722 	}
1723 
1724 	/* Virtual svga device primary limits are always in 32-bpp. */
1725 	pixel_mem = total_pixels * 4;
1726 
1727 	/*
1728 	 * For HV10 and below prim_bb_mem is vram size. When
1729 	 * SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM is not present vram size is
1730 	 * limit on primary bounding box
1731 	 */
1732 	if (pixel_mem > dev_priv->max_primary_mem) {
1733 		VMW_DEBUG_KMS("Combined output size too large.\n");
1734 		return -EINVAL;
1735 	}
1736 
1737 	/* SVGA_CAP_NO_BB_RESTRICTION is available for STDU only. */
1738 	if (dev_priv->active_display_unit != vmw_du_screen_target ||
1739 	    !(dev_priv->capabilities & SVGA_CAP_NO_BB_RESTRICTION)) {
1740 		bb_mem = (u64) bounding_box.x2 * bounding_box.y2 * 4;
1741 
1742 		if (bb_mem > dev_priv->max_primary_mem) {
1743 			VMW_DEBUG_KMS("Topology is beyond supported limits.\n");
1744 			return -EINVAL;
1745 		}
1746 	}
1747 
1748 	return 0;
1749 }
1750 
1751 /**
1752  * vmw_crtc_state_and_lock - Return new or current crtc state with locked
1753  * crtc mutex
1754  * @state: The atomic state pointer containing the new atomic state
1755  * @crtc: The crtc
1756  *
1757  * This function returns the new crtc state if it's part of the state update.
1758  * Otherwise returns the current crtc state. It also makes sure that the
1759  * crtc mutex is locked.
1760  *
1761  * Returns: A valid crtc state pointer or NULL. It may also return a
1762  * pointer error, in particular -EDEADLK if locking needs to be rerun.
1763  */
1764 static struct drm_crtc_state *
vmw_crtc_state_and_lock(struct drm_atomic_state * state,struct drm_crtc * crtc)1765 vmw_crtc_state_and_lock(struct drm_atomic_state *state, struct drm_crtc *crtc)
1766 {
1767 	struct drm_crtc_state *crtc_state;
1768 
1769 	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1770 	if (crtc_state) {
1771 		lockdep_assert_held(&crtc->mutex.mutex.base);
1772 	} else {
1773 		int ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
1774 
1775 		if (ret != 0 && ret != -EALREADY)
1776 			return ERR_PTR(ret);
1777 
1778 		crtc_state = crtc->state;
1779 	}
1780 
1781 	return crtc_state;
1782 }
1783 
1784 /**
1785  * vmw_kms_check_implicit - Verify that all implicit display units scan out
1786  * from the same fb after the new state is committed.
1787  * @dev: The drm_device.
1788  * @state: The new state to be checked.
1789  *
1790  * Returns:
1791  *   Zero on success,
1792  *   -EINVAL on invalid state,
1793  *   -EDEADLK if modeset locking needs to be rerun.
1794  */
vmw_kms_check_implicit(struct drm_device * dev,struct drm_atomic_state * state)1795 static int vmw_kms_check_implicit(struct drm_device *dev,
1796 				  struct drm_atomic_state *state)
1797 {
1798 	struct drm_framebuffer *implicit_fb = NULL;
1799 	struct drm_crtc *crtc;
1800 	struct drm_crtc_state *crtc_state;
1801 	struct drm_plane_state *plane_state;
1802 
1803 	drm_for_each_crtc(crtc, dev) {
1804 		struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
1805 
1806 		if (!du->is_implicit)
1807 			continue;
1808 
1809 		crtc_state = vmw_crtc_state_and_lock(state, crtc);
1810 		if (IS_ERR(crtc_state))
1811 			return PTR_ERR(crtc_state);
1812 
1813 		if (!crtc_state || !crtc_state->enable)
1814 			continue;
1815 
1816 		/*
1817 		 * Can't move primary planes across crtcs, so this is OK.
1818 		 * It also means we don't need to take the plane mutex.
1819 		 */
1820 		plane_state = du->primary.state;
1821 		if (plane_state->crtc != crtc)
1822 			continue;
1823 
1824 		if (!implicit_fb)
1825 			implicit_fb = plane_state->fb;
1826 		else if (implicit_fb != plane_state->fb)
1827 			return -EINVAL;
1828 	}
1829 
1830 	return 0;
1831 }
1832 
1833 /**
1834  * vmw_kms_check_topology - Validates topology in drm_atomic_state
1835  * @dev: DRM device
1836  * @state: the driver state object
1837  *
1838  * Returns:
1839  * 0 on success otherwise negative error code
1840  */
vmw_kms_check_topology(struct drm_device * dev,struct drm_atomic_state * state)1841 static int vmw_kms_check_topology(struct drm_device *dev,
1842 				  struct drm_atomic_state *state)
1843 {
1844 	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
1845 	struct drm_rect *rects;
1846 	struct drm_crtc *crtc;
1847 	uint32_t i;
1848 	int ret = 0;
1849 
1850 	rects = kcalloc(dev->mode_config.num_crtc, sizeof(struct drm_rect),
1851 			GFP_KERNEL);
1852 	if (!rects)
1853 		return -ENOMEM;
1854 
1855 	drm_for_each_crtc(crtc, dev) {
1856 		struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
1857 		struct drm_crtc_state *crtc_state;
1858 
1859 		i = drm_crtc_index(crtc);
1860 
1861 		crtc_state = vmw_crtc_state_and_lock(state, crtc);
1862 		if (IS_ERR(crtc_state)) {
1863 			ret = PTR_ERR(crtc_state);
1864 			goto clean;
1865 		}
1866 
1867 		if (!crtc_state)
1868 			continue;
1869 
1870 		if (crtc_state->enable) {
1871 			rects[i].x1 = du->gui_x;
1872 			rects[i].y1 = du->gui_y;
1873 			rects[i].x2 = du->gui_x + crtc_state->mode.hdisplay;
1874 			rects[i].y2 = du->gui_y + crtc_state->mode.vdisplay;
1875 		} else {
1876 			rects[i].x1 = 0;
1877 			rects[i].y1 = 0;
1878 			rects[i].x2 = 0;
1879 			rects[i].y2 = 0;
1880 		}
1881 	}
1882 
1883 	/* Determine change to topology due to new atomic state */
1884 	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
1885 				      new_crtc_state, i) {
1886 		struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
1887 		struct drm_connector *connector;
1888 		struct drm_connector_state *conn_state;
1889 		struct vmw_connector_state *vmw_conn_state;
1890 
1891 		if (!du->pref_active && new_crtc_state->enable) {
1892 			VMW_DEBUG_KMS("Enabling a disabled display unit\n");
1893 			ret = -EINVAL;
1894 			goto clean;
1895 		}
1896 
1897 		/*
1898 		 * For vmwgfx each crtc has only one connector attached and it
1899 		 * is not changed so don't really need to check the
1900 		 * crtc->connector_mask and iterate over it.
1901 		 */
1902 		connector = &du->connector;
1903 		conn_state = drm_atomic_get_connector_state(state, connector);
1904 		if (IS_ERR(conn_state)) {
1905 			ret = PTR_ERR(conn_state);
1906 			goto clean;
1907 		}
1908 
1909 		vmw_conn_state = vmw_connector_state_to_vcs(conn_state);
1910 		vmw_conn_state->gui_x = du->gui_x;
1911 		vmw_conn_state->gui_y = du->gui_y;
1912 	}
1913 
1914 	ret = vmw_kms_check_display_memory(dev, dev->mode_config.num_crtc,
1915 					   rects);
1916 
1917 clean:
1918 	kfree(rects);
1919 	return ret;
1920 }
1921 
1922 /**
1923  * vmw_kms_atomic_check_modeset- validate state object for modeset changes
1924  *
1925  * @dev: DRM device
1926  * @state: the driver state object
1927  *
1928  * This is a simple wrapper around drm_atomic_helper_check_modeset() for
1929  * us to assign a value to mode->crtc_clock so that
1930  * drm_calc_timestamping_constants() won't throw an error message
1931  *
1932  * Returns:
1933  * Zero for success or -errno
1934  */
1935 static int
vmw_kms_atomic_check_modeset(struct drm_device * dev,struct drm_atomic_state * state)1936 vmw_kms_atomic_check_modeset(struct drm_device *dev,
1937 			     struct drm_atomic_state *state)
1938 {
1939 	struct drm_crtc *crtc;
1940 	struct drm_crtc_state *crtc_state;
1941 	bool need_modeset = false;
1942 	int i, ret;
1943 
1944 	ret = drm_atomic_helper_check(dev, state);
1945 	if (ret)
1946 		return ret;
1947 
1948 	ret = vmw_kms_check_implicit(dev, state);
1949 	if (ret) {
1950 		VMW_DEBUG_KMS("Invalid implicit state\n");
1951 		return ret;
1952 	}
1953 
1954 	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
1955 		if (drm_atomic_crtc_needs_modeset(crtc_state))
1956 			need_modeset = true;
1957 	}
1958 
1959 	if (need_modeset)
1960 		return vmw_kms_check_topology(dev, state);
1961 
1962 	return ret;
1963 }
1964 
1965 static const struct drm_mode_config_funcs vmw_kms_funcs = {
1966 	.fb_create = vmw_kms_fb_create,
1967 	.atomic_check = vmw_kms_atomic_check_modeset,
1968 	.atomic_commit = drm_atomic_helper_commit,
1969 };
1970 
vmw_kms_generic_present(struct vmw_private * dev_priv,struct drm_file * file_priv,struct vmw_framebuffer * vfb,struct vmw_surface * surface,uint32_t sid,int32_t destX,int32_t destY,struct drm_vmw_rect * clips,uint32_t num_clips)1971 static int vmw_kms_generic_present(struct vmw_private *dev_priv,
1972 				   struct drm_file *file_priv,
1973 				   struct vmw_framebuffer *vfb,
1974 				   struct vmw_surface *surface,
1975 				   uint32_t sid,
1976 				   int32_t destX, int32_t destY,
1977 				   struct drm_vmw_rect *clips,
1978 				   uint32_t num_clips)
1979 {
1980 	return vmw_kms_sou_do_surface_dirty(dev_priv, vfb, NULL, clips,
1981 					    &surface->res, destX, destY,
1982 					    num_clips, 1, NULL, NULL);
1983 }
1984 
1985 
vmw_kms_present(struct vmw_private * dev_priv,struct drm_file * file_priv,struct vmw_framebuffer * vfb,struct vmw_surface * surface,uint32_t sid,int32_t destX,int32_t destY,struct drm_vmw_rect * clips,uint32_t num_clips)1986 int vmw_kms_present(struct vmw_private *dev_priv,
1987 		    struct drm_file *file_priv,
1988 		    struct vmw_framebuffer *vfb,
1989 		    struct vmw_surface *surface,
1990 		    uint32_t sid,
1991 		    int32_t destX, int32_t destY,
1992 		    struct drm_vmw_rect *clips,
1993 		    uint32_t num_clips)
1994 {
1995 	int ret;
1996 
1997 	switch (dev_priv->active_display_unit) {
1998 	case vmw_du_screen_target:
1999 		ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, clips,
2000 						 &surface->res, destX, destY,
2001 						 num_clips, 1, NULL, NULL);
2002 		break;
2003 	case vmw_du_screen_object:
2004 		ret = vmw_kms_generic_present(dev_priv, file_priv, vfb, surface,
2005 					      sid, destX, destY, clips,
2006 					      num_clips);
2007 		break;
2008 	default:
2009 		WARN_ONCE(true,
2010 			  "Present called with invalid display system.\n");
2011 		ret = -ENOSYS;
2012 		break;
2013 	}
2014 	if (ret)
2015 		return ret;
2016 
2017 	vmw_cmd_flush(dev_priv, false);
2018 
2019 	return 0;
2020 }
2021 
2022 static void
vmw_kms_create_hotplug_mode_update_property(struct vmw_private * dev_priv)2023 vmw_kms_create_hotplug_mode_update_property(struct vmw_private *dev_priv)
2024 {
2025 	if (dev_priv->hotplug_mode_update_property)
2026 		return;
2027 
2028 	dev_priv->hotplug_mode_update_property =
2029 		drm_property_create_range(&dev_priv->drm,
2030 					  DRM_MODE_PROP_IMMUTABLE,
2031 					  "hotplug_mode_update", 0, 1);
2032 }
2033 
vmw_kms_init(struct vmw_private * dev_priv)2034 int vmw_kms_init(struct vmw_private *dev_priv)
2035 {
2036 	struct drm_device *dev = &dev_priv->drm;
2037 	int ret;
2038 	static const char *display_unit_names[] = {
2039 		"Invalid",
2040 		"Legacy",
2041 		"Screen Object",
2042 		"Screen Target",
2043 		"Invalid (max)"
2044 	};
2045 
2046 	drm_mode_config_init(dev);
2047 	dev->mode_config.funcs = &vmw_kms_funcs;
2048 	dev->mode_config.min_width = 1;
2049 	dev->mode_config.min_height = 1;
2050 	dev->mode_config.max_width = dev_priv->texture_max_width;
2051 	dev->mode_config.max_height = dev_priv->texture_max_height;
2052 	dev->mode_config.preferred_depth = dev_priv->assume_16bpp ? 16 : 32;
2053 
2054 	drm_mode_create_suggested_offset_properties(dev);
2055 	vmw_kms_create_hotplug_mode_update_property(dev_priv);
2056 
2057 	ret = vmw_kms_stdu_init_display(dev_priv);
2058 	if (ret) {
2059 		ret = vmw_kms_sou_init_display(dev_priv);
2060 		if (ret) /* Fallback */
2061 			ret = vmw_kms_ldu_init_display(dev_priv);
2062 	}
2063 	BUILD_BUG_ON(ARRAY_SIZE(display_unit_names) != (vmw_du_max + 1));
2064 	drm_info(&dev_priv->drm, "%s display unit initialized\n",
2065 		 display_unit_names[dev_priv->active_display_unit]);
2066 
2067 	return ret;
2068 }
2069 
vmw_kms_close(struct vmw_private * dev_priv)2070 int vmw_kms_close(struct vmw_private *dev_priv)
2071 {
2072 	int ret = 0;
2073 
2074 	/*
2075 	 * Docs says we should take the lock before calling this function
2076 	 * but since it destroys encoders and our destructor calls
2077 	 * drm_encoder_cleanup which takes the lock we deadlock.
2078 	 */
2079 	drm_mode_config_cleanup(&dev_priv->drm);
2080 	if (dev_priv->active_display_unit == vmw_du_legacy)
2081 		ret = vmw_kms_ldu_close_display(dev_priv);
2082 
2083 	return ret;
2084 }
2085 
vmw_kms_cursor_bypass_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)2086 int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
2087 				struct drm_file *file_priv)
2088 {
2089 	struct drm_vmw_cursor_bypass_arg *arg = data;
2090 	struct vmw_display_unit *du;
2091 	struct drm_crtc *crtc;
2092 	int ret = 0;
2093 
2094 	mutex_lock(&dev->mode_config.mutex);
2095 	if (arg->flags & DRM_VMW_CURSOR_BYPASS_ALL) {
2096 
2097 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
2098 			du = vmw_crtc_to_du(crtc);
2099 			du->hotspot_x = arg->xhot;
2100 			du->hotspot_y = arg->yhot;
2101 		}
2102 
2103 		mutex_unlock(&dev->mode_config.mutex);
2104 		return 0;
2105 	}
2106 
2107 	crtc = drm_crtc_find(dev, file_priv, arg->crtc_id);
2108 	if (!crtc) {
2109 		ret = -ENOENT;
2110 		goto out;
2111 	}
2112 
2113 	du = vmw_crtc_to_du(crtc);
2114 
2115 	du->hotspot_x = arg->xhot;
2116 	du->hotspot_y = arg->yhot;
2117 
2118 out:
2119 	mutex_unlock(&dev->mode_config.mutex);
2120 
2121 	return ret;
2122 }
2123 
vmw_kms_write_svga(struct vmw_private * vmw_priv,unsigned width,unsigned height,unsigned pitch,unsigned bpp,unsigned depth)2124 int vmw_kms_write_svga(struct vmw_private *vmw_priv,
2125 			unsigned width, unsigned height, unsigned pitch,
2126 			unsigned bpp, unsigned depth)
2127 {
2128 	if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
2129 		vmw_write(vmw_priv, SVGA_REG_PITCHLOCK, pitch);
2130 	else if (vmw_fifo_have_pitchlock(vmw_priv))
2131 		vmw_fifo_mem_write(vmw_priv, SVGA_FIFO_PITCHLOCK, pitch);
2132 	vmw_write(vmw_priv, SVGA_REG_WIDTH, width);
2133 	vmw_write(vmw_priv, SVGA_REG_HEIGHT, height);
2134 	if ((vmw_priv->capabilities & SVGA_CAP_8BIT_EMULATION) != 0)
2135 		vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, bpp);
2136 
2137 	if (vmw_read(vmw_priv, SVGA_REG_DEPTH) != depth) {
2138 		DRM_ERROR("Invalid depth %u for %u bpp, host expects %u\n",
2139 			  depth, bpp, vmw_read(vmw_priv, SVGA_REG_DEPTH));
2140 		return -EINVAL;
2141 	}
2142 
2143 	return 0;
2144 }
2145 
vmw_kms_validate_mode_vram(struct vmw_private * dev_priv,uint32_t pitch,uint32_t height)2146 bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
2147 				uint32_t pitch,
2148 				uint32_t height)
2149 {
2150 	return ((u64) pitch * (u64) height) < (u64)
2151 		((dev_priv->active_display_unit == vmw_du_screen_target) ?
2152 		 dev_priv->max_primary_mem : dev_priv->vram_size);
2153 }
2154 
2155 /**
2156  * vmw_du_update_layout - Update the display unit with topology from resolution
2157  * plugin and generate DRM uevent
2158  * @dev_priv: device private
2159  * @num_rects: number of drm_rect in rects
2160  * @rects: toplogy to update
2161  */
vmw_du_update_layout(struct vmw_private * dev_priv,unsigned int num_rects,struct drm_rect * rects)2162 static int vmw_du_update_layout(struct vmw_private *dev_priv,
2163 				unsigned int num_rects, struct drm_rect *rects)
2164 {
2165 	struct drm_device *dev = &dev_priv->drm;
2166 	struct vmw_display_unit *du;
2167 	struct drm_connector *con;
2168 	struct drm_connector_list_iter conn_iter;
2169 	struct drm_modeset_acquire_ctx ctx;
2170 	struct drm_crtc *crtc;
2171 	int ret;
2172 
2173 	/* Currently gui_x/y is protected with the crtc mutex */
2174 	mutex_lock(&dev->mode_config.mutex);
2175 	drm_modeset_acquire_init(&ctx, 0);
2176 retry:
2177 	drm_for_each_crtc(crtc, dev) {
2178 		ret = drm_modeset_lock(&crtc->mutex, &ctx);
2179 		if (ret < 0) {
2180 			if (ret == -EDEADLK) {
2181 				drm_modeset_backoff(&ctx);
2182 				goto retry;
2183 		}
2184 			goto out_fini;
2185 		}
2186 	}
2187 
2188 	drm_connector_list_iter_begin(dev, &conn_iter);
2189 	drm_for_each_connector_iter(con, &conn_iter) {
2190 		du = vmw_connector_to_du(con);
2191 		if (num_rects > du->unit) {
2192 			du->pref_width = drm_rect_width(&rects[du->unit]);
2193 			du->pref_height = drm_rect_height(&rects[du->unit]);
2194 			du->pref_active = true;
2195 			du->gui_x = rects[du->unit].x1;
2196 			du->gui_y = rects[du->unit].y1;
2197 		} else {
2198 			du->pref_width  = VMWGFX_MIN_INITIAL_WIDTH;
2199 			du->pref_height = VMWGFX_MIN_INITIAL_HEIGHT;
2200 			du->pref_active = false;
2201 			du->gui_x = 0;
2202 			du->gui_y = 0;
2203 		}
2204 	}
2205 	drm_connector_list_iter_end(&conn_iter);
2206 
2207 	list_for_each_entry(con, &dev->mode_config.connector_list, head) {
2208 		du = vmw_connector_to_du(con);
2209 		if (num_rects > du->unit) {
2210 			drm_object_property_set_value
2211 			  (&con->base, dev->mode_config.suggested_x_property,
2212 			   du->gui_x);
2213 			drm_object_property_set_value
2214 			  (&con->base, dev->mode_config.suggested_y_property,
2215 			   du->gui_y);
2216 		} else {
2217 			drm_object_property_set_value
2218 			  (&con->base, dev->mode_config.suggested_x_property,
2219 			   0);
2220 			drm_object_property_set_value
2221 			  (&con->base, dev->mode_config.suggested_y_property,
2222 			   0);
2223 		}
2224 		con->status = vmw_du_connector_detect(con, true);
2225 	}
2226 out_fini:
2227 	drm_modeset_drop_locks(&ctx);
2228 	drm_modeset_acquire_fini(&ctx);
2229 	mutex_unlock(&dev->mode_config.mutex);
2230 
2231 	drm_sysfs_hotplug_event(dev);
2232 
2233 	return 0;
2234 }
2235 
vmw_du_crtc_gamma_set(struct drm_crtc * crtc,u16 * r,u16 * g,u16 * b,uint32_t size,struct drm_modeset_acquire_ctx * ctx)2236 int vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
2237 			  u16 *r, u16 *g, u16 *b,
2238 			  uint32_t size,
2239 			  struct drm_modeset_acquire_ctx *ctx)
2240 {
2241 	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
2242 	int i;
2243 
2244 	for (i = 0; i < size; i++) {
2245 		DRM_DEBUG("%d r/g/b = 0x%04x / 0x%04x / 0x%04x\n", i,
2246 			  r[i], g[i], b[i]);
2247 		vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 0, r[i] >> 8);
2248 		vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 1, g[i] >> 8);
2249 		vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 2, b[i] >> 8);
2250 	}
2251 
2252 	return 0;
2253 }
2254 
vmw_du_connector_dpms(struct drm_connector * connector,int mode)2255 int vmw_du_connector_dpms(struct drm_connector *connector, int mode)
2256 {
2257 	return 0;
2258 }
2259 
2260 enum drm_connector_status
vmw_du_connector_detect(struct drm_connector * connector,bool force)2261 vmw_du_connector_detect(struct drm_connector *connector, bool force)
2262 {
2263 	uint32_t num_displays;
2264 	struct drm_device *dev = connector->dev;
2265 	struct vmw_private *dev_priv = vmw_priv(dev);
2266 	struct vmw_display_unit *du = vmw_connector_to_du(connector);
2267 
2268 	num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS);
2269 
2270 	return ((vmw_connector_to_du(connector)->unit < num_displays &&
2271 		 du->pref_active) ?
2272 		connector_status_connected : connector_status_disconnected);
2273 }
2274 
2275 static struct drm_display_mode vmw_kms_connector_builtin[] = {
2276 	/* 640x480@60Hz */
2277 	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
2278 		   752, 800, 0, 480, 489, 492, 525, 0,
2279 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
2280 	/* 800x600@60Hz */
2281 	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
2282 		   968, 1056, 0, 600, 601, 605, 628, 0,
2283 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
2284 	/* 1024x768@60Hz */
2285 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
2286 		   1184, 1344, 0, 768, 771, 777, 806, 0,
2287 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
2288 	/* 1152x864@75Hz */
2289 	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
2290 		   1344, 1600, 0, 864, 865, 868, 900, 0,
2291 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
2292 	/* 1280x720@60Hz */
2293 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74500, 1280, 1344,
2294 		   1472, 1664, 0, 720, 723, 728, 748, 0,
2295 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2296 	/* 1280x768@60Hz */
2297 	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
2298 		   1472, 1664, 0, 768, 771, 778, 798, 0,
2299 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2300 	/* 1280x800@60Hz */
2301 	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
2302 		   1480, 1680, 0, 800, 803, 809, 831, 0,
2303 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
2304 	/* 1280x960@60Hz */
2305 	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
2306 		   1488, 1800, 0, 960, 961, 964, 1000, 0,
2307 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
2308 	/* 1280x1024@60Hz */
2309 	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
2310 		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
2311 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
2312 	/* 1360x768@60Hz */
2313 	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
2314 		   1536, 1792, 0, 768, 771, 777, 795, 0,
2315 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
2316 	/* 1440x1050@60Hz */
2317 	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
2318 		   1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
2319 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2320 	/* 1440x900@60Hz */
2321 	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
2322 		   1672, 1904, 0, 900, 903, 909, 934, 0,
2323 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2324 	/* 1600x1200@60Hz */
2325 	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
2326 		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
2327 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
2328 	/* 1680x1050@60Hz */
2329 	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
2330 		   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
2331 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2332 	/* 1792x1344@60Hz */
2333 	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
2334 		   2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
2335 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2336 	/* 1853x1392@60Hz */
2337 	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
2338 		   2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
2339 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2340 	/* 1920x1080@60Hz */
2341 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 173000, 1920, 2048,
2342 		   2248, 2576, 0, 1080, 1083, 1088, 1120, 0,
2343 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2344 	/* 1920x1200@60Hz */
2345 	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
2346 		   2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
2347 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2348 	/* 1920x1440@60Hz */
2349 	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
2350 		   2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
2351 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2352 	/* 2560x1440@60Hz */
2353 	{ DRM_MODE("2560x1440", DRM_MODE_TYPE_DRIVER, 241500, 2560, 2608,
2354 		   2640, 2720, 0, 1440, 1443, 1448, 1481, 0,
2355 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
2356 	/* 2560x1600@60Hz */
2357 	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
2358 		   3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
2359 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
2360 	/* 2880x1800@60Hz */
2361 	{ DRM_MODE("2880x1800", DRM_MODE_TYPE_DRIVER, 337500, 2880, 2928,
2362 		   2960, 3040, 0, 1800, 1803, 1809, 1852, 0,
2363 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
2364 	/* 3840x2160@60Hz */
2365 	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 533000, 3840, 3888,
2366 		   3920, 4000, 0, 2160, 2163, 2168, 2222, 0,
2367 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
2368 	/* 3840x2400@60Hz */
2369 	{ DRM_MODE("3840x2400", DRM_MODE_TYPE_DRIVER, 592250, 3840, 3888,
2370 		   3920, 4000, 0, 2400, 2403, 2409, 2469, 0,
2371 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
2372 	/* Terminate */
2373 	{ DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) },
2374 };
2375 
2376 /**
2377  * vmw_guess_mode_timing - Provide fake timings for a
2378  * 60Hz vrefresh mode.
2379  *
2380  * @mode: Pointer to a struct drm_display_mode with hdisplay and vdisplay
2381  * members filled in.
2382  */
vmw_guess_mode_timing(struct drm_display_mode * mode)2383 void vmw_guess_mode_timing(struct drm_display_mode *mode)
2384 {
2385 	mode->hsync_start = mode->hdisplay + 50;
2386 	mode->hsync_end = mode->hsync_start + 50;
2387 	mode->htotal = mode->hsync_end + 50;
2388 
2389 	mode->vsync_start = mode->vdisplay + 50;
2390 	mode->vsync_end = mode->vsync_start + 50;
2391 	mode->vtotal = mode->vsync_end + 50;
2392 
2393 	mode->clock = (u32)mode->htotal * (u32)mode->vtotal / 100 * 6;
2394 }
2395 
2396 
vmw_du_connector_fill_modes(struct drm_connector * connector,uint32_t max_width,uint32_t max_height)2397 int vmw_du_connector_fill_modes(struct drm_connector *connector,
2398 				uint32_t max_width, uint32_t max_height)
2399 {
2400 	struct vmw_display_unit *du = vmw_connector_to_du(connector);
2401 	struct drm_device *dev = connector->dev;
2402 	struct vmw_private *dev_priv = vmw_priv(dev);
2403 	struct drm_display_mode *mode = NULL;
2404 	struct drm_display_mode *bmode;
2405 	struct drm_display_mode prefmode = { DRM_MODE("preferred",
2406 		DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
2407 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2408 		DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
2409 	};
2410 	int i;
2411 	u32 assumed_bpp = 4;
2412 
2413 	if (dev_priv->assume_16bpp)
2414 		assumed_bpp = 2;
2415 
2416 	max_width  = min(max_width,  dev_priv->texture_max_width);
2417 	max_height = min(max_height, dev_priv->texture_max_height);
2418 
2419 	/*
2420 	 * For STDU extra limit for a mode on SVGA_REG_SCREENTARGET_MAX_WIDTH/
2421 	 * HEIGHT registers.
2422 	 */
2423 	if (dev_priv->active_display_unit == vmw_du_screen_target) {
2424 		max_width  = min(max_width,  dev_priv->stdu_max_width);
2425 		max_height = min(max_height, dev_priv->stdu_max_height);
2426 	}
2427 
2428 	/* Add preferred mode */
2429 	mode = drm_mode_duplicate(dev, &prefmode);
2430 	if (!mode)
2431 		return 0;
2432 	mode->hdisplay = du->pref_width;
2433 	mode->vdisplay = du->pref_height;
2434 	vmw_guess_mode_timing(mode);
2435 	drm_mode_set_name(mode);
2436 
2437 	if (vmw_kms_validate_mode_vram(dev_priv,
2438 					mode->hdisplay * assumed_bpp,
2439 					mode->vdisplay)) {
2440 		drm_mode_probed_add(connector, mode);
2441 	} else {
2442 		drm_mode_destroy(dev, mode);
2443 		mode = NULL;
2444 	}
2445 
2446 	if (du->pref_mode) {
2447 		list_del_init(&du->pref_mode->head);
2448 		drm_mode_destroy(dev, du->pref_mode);
2449 	}
2450 
2451 	/* mode might be null here, this is intended */
2452 	du->pref_mode = mode;
2453 
2454 	for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) {
2455 		bmode = &vmw_kms_connector_builtin[i];
2456 		if (bmode->hdisplay > max_width ||
2457 		    bmode->vdisplay > max_height)
2458 			continue;
2459 
2460 		if (!vmw_kms_validate_mode_vram(dev_priv,
2461 						bmode->hdisplay * assumed_bpp,
2462 						bmode->vdisplay))
2463 			continue;
2464 
2465 		mode = drm_mode_duplicate(dev, bmode);
2466 		if (!mode)
2467 			return 0;
2468 
2469 		drm_mode_probed_add(connector, mode);
2470 	}
2471 
2472 	drm_connector_list_update(connector);
2473 	/* Move the prefered mode first, help apps pick the right mode. */
2474 	drm_mode_sort(&connector->modes);
2475 
2476 	return 1;
2477 }
2478 
2479 /**
2480  * vmw_kms_update_layout_ioctl - Handler for DRM_VMW_UPDATE_LAYOUT ioctl
2481  * @dev: drm device for the ioctl
2482  * @data: data pointer for the ioctl
2483  * @file_priv: drm file for the ioctl call
2484  *
2485  * Update preferred topology of display unit as per ioctl request. The topology
2486  * is expressed as array of drm_vmw_rect.
2487  * e.g.
2488  * [0 0 640 480] [640 0 800 600] [0 480 640 480]
2489  *
2490  * NOTE:
2491  * The x and y offset (upper left) in drm_vmw_rect cannot be less than 0. Beside
2492  * device limit on topology, x + w and y + h (lower right) cannot be greater
2493  * than INT_MAX. So topology beyond these limits will return with error.
2494  *
2495  * Returns:
2496  * Zero on success, negative errno on failure.
2497  */
vmw_kms_update_layout_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)2498 int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
2499 				struct drm_file *file_priv)
2500 {
2501 	struct vmw_private *dev_priv = vmw_priv(dev);
2502 	struct drm_mode_config *mode_config = &dev->mode_config;
2503 	struct drm_vmw_update_layout_arg *arg =
2504 		(struct drm_vmw_update_layout_arg *)data;
2505 	void __user *user_rects;
2506 	struct drm_vmw_rect *rects;
2507 	struct drm_rect *drm_rects;
2508 	unsigned rects_size;
2509 	int ret, i;
2510 
2511 	if (!arg->num_outputs) {
2512 		struct drm_rect def_rect = {0, 0,
2513 					    VMWGFX_MIN_INITIAL_WIDTH,
2514 					    VMWGFX_MIN_INITIAL_HEIGHT};
2515 		vmw_du_update_layout(dev_priv, 1, &def_rect);
2516 		return 0;
2517 	}
2518 
2519 	rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
2520 	rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect),
2521 			GFP_KERNEL);
2522 	if (unlikely(!rects))
2523 		return -ENOMEM;
2524 
2525 	user_rects = (void __user *)(unsigned long)arg->rects;
2526 	ret = copy_from_user(rects, user_rects, rects_size);
2527 	if (unlikely(ret != 0)) {
2528 		DRM_ERROR("Failed to get rects.\n");
2529 		ret = -EFAULT;
2530 		goto out_free;
2531 	}
2532 
2533 	drm_rects = (struct drm_rect *)rects;
2534 
2535 	VMW_DEBUG_KMS("Layout count = %u\n", arg->num_outputs);
2536 	for (i = 0; i < arg->num_outputs; i++) {
2537 		struct drm_vmw_rect curr_rect;
2538 
2539 		/* Verify user-space for overflow as kernel use drm_rect */
2540 		if ((rects[i].x + rects[i].w > INT_MAX) ||
2541 		    (rects[i].y + rects[i].h > INT_MAX)) {
2542 			ret = -ERANGE;
2543 			goto out_free;
2544 		}
2545 
2546 		curr_rect = rects[i];
2547 		drm_rects[i].x1 = curr_rect.x;
2548 		drm_rects[i].y1 = curr_rect.y;
2549 		drm_rects[i].x2 = curr_rect.x + curr_rect.w;
2550 		drm_rects[i].y2 = curr_rect.y + curr_rect.h;
2551 
2552 		VMW_DEBUG_KMS("  x1 = %d y1 = %d x2 = %d y2 = %d\n",
2553 			      drm_rects[i].x1, drm_rects[i].y1,
2554 			      drm_rects[i].x2, drm_rects[i].y2);
2555 
2556 		/*
2557 		 * Currently this check is limiting the topology within
2558 		 * mode_config->max (which actually is max texture size
2559 		 * supported by virtual device). This limit is here to address
2560 		 * window managers that create a big framebuffer for whole
2561 		 * topology.
2562 		 */
2563 		if (drm_rects[i].x1 < 0 ||  drm_rects[i].y1 < 0 ||
2564 		    drm_rects[i].x2 > mode_config->max_width ||
2565 		    drm_rects[i].y2 > mode_config->max_height) {
2566 			VMW_DEBUG_KMS("Invalid layout %d %d %d %d\n",
2567 				      drm_rects[i].x1, drm_rects[i].y1,
2568 				      drm_rects[i].x2, drm_rects[i].y2);
2569 			ret = -EINVAL;
2570 			goto out_free;
2571 		}
2572 	}
2573 
2574 	ret = vmw_kms_check_display_memory(dev, arg->num_outputs, drm_rects);
2575 
2576 	if (ret == 0)
2577 		vmw_du_update_layout(dev_priv, arg->num_outputs, drm_rects);
2578 
2579 out_free:
2580 	kfree(rects);
2581 	return ret;
2582 }
2583 
2584 /**
2585  * vmw_kms_helper_dirty - Helper to build commands and perform actions based
2586  * on a set of cliprects and a set of display units.
2587  *
2588  * @dev_priv: Pointer to a device private structure.
2589  * @framebuffer: Pointer to the framebuffer on which to perform the actions.
2590  * @clips: A set of struct drm_clip_rect. Either this os @vclips must be NULL.
2591  * Cliprects are given in framebuffer coordinates.
2592  * @vclips: A set of struct drm_vmw_rect cliprects. Either this or @clips must
2593  * be NULL. Cliprects are given in source coordinates.
2594  * @dest_x: X coordinate offset for the crtc / destination clip rects.
2595  * @dest_y: Y coordinate offset for the crtc / destination clip rects.
2596  * @num_clips: Number of cliprects in the @clips or @vclips array.
2597  * @increment: Integer with which to increment the clip counter when looping.
2598  * Used to skip a predetermined number of clip rects.
2599  * @dirty: Closure structure. See the description of struct vmw_kms_dirty.
2600  */
vmw_kms_helper_dirty(struct vmw_private * dev_priv,struct vmw_framebuffer * framebuffer,const struct drm_clip_rect * clips,const struct drm_vmw_rect * vclips,s32 dest_x,s32 dest_y,int num_clips,int increment,struct vmw_kms_dirty * dirty)2601 int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
2602 			 struct vmw_framebuffer *framebuffer,
2603 			 const struct drm_clip_rect *clips,
2604 			 const struct drm_vmw_rect *vclips,
2605 			 s32 dest_x, s32 dest_y,
2606 			 int num_clips,
2607 			 int increment,
2608 			 struct vmw_kms_dirty *dirty)
2609 {
2610 	struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
2611 	struct drm_crtc *crtc;
2612 	u32 num_units = 0;
2613 	u32 i, k;
2614 
2615 	dirty->dev_priv = dev_priv;
2616 
2617 	/* If crtc is passed, no need to iterate over other display units */
2618 	if (dirty->crtc) {
2619 		units[num_units++] = vmw_crtc_to_du(dirty->crtc);
2620 	} else {
2621 		list_for_each_entry(crtc, &dev_priv->drm.mode_config.crtc_list,
2622 				    head) {
2623 			struct drm_plane *plane = crtc->primary;
2624 
2625 			if (plane->state->fb == &framebuffer->base)
2626 				units[num_units++] = vmw_crtc_to_du(crtc);
2627 		}
2628 	}
2629 
2630 	for (k = 0; k < num_units; k++) {
2631 		struct vmw_display_unit *unit = units[k];
2632 		s32 crtc_x = unit->crtc.x;
2633 		s32 crtc_y = unit->crtc.y;
2634 		s32 crtc_width = unit->crtc.mode.hdisplay;
2635 		s32 crtc_height = unit->crtc.mode.vdisplay;
2636 		const struct drm_clip_rect *clips_ptr = clips;
2637 		const struct drm_vmw_rect *vclips_ptr = vclips;
2638 
2639 		dirty->unit = unit;
2640 		if (dirty->fifo_reserve_size > 0) {
2641 			dirty->cmd = VMW_CMD_RESERVE(dev_priv,
2642 						      dirty->fifo_reserve_size);
2643 			if (!dirty->cmd)
2644 				return -ENOMEM;
2645 
2646 			memset(dirty->cmd, 0, dirty->fifo_reserve_size);
2647 		}
2648 		dirty->num_hits = 0;
2649 		for (i = 0; i < num_clips; i++, clips_ptr += increment,
2650 		       vclips_ptr += increment) {
2651 			s32 clip_left;
2652 			s32 clip_top;
2653 
2654 			/*
2655 			 * Select clip array type. Note that integer type
2656 			 * in @clips is unsigned short, whereas in @vclips
2657 			 * it's 32-bit.
2658 			 */
2659 			if (clips) {
2660 				dirty->fb_x = (s32) clips_ptr->x1;
2661 				dirty->fb_y = (s32) clips_ptr->y1;
2662 				dirty->unit_x2 = (s32) clips_ptr->x2 + dest_x -
2663 					crtc_x;
2664 				dirty->unit_y2 = (s32) clips_ptr->y2 + dest_y -
2665 					crtc_y;
2666 			} else {
2667 				dirty->fb_x = vclips_ptr->x;
2668 				dirty->fb_y = vclips_ptr->y;
2669 				dirty->unit_x2 = dirty->fb_x + vclips_ptr->w +
2670 					dest_x - crtc_x;
2671 				dirty->unit_y2 = dirty->fb_y + vclips_ptr->h +
2672 					dest_y - crtc_y;
2673 			}
2674 
2675 			dirty->unit_x1 = dirty->fb_x + dest_x - crtc_x;
2676 			dirty->unit_y1 = dirty->fb_y + dest_y - crtc_y;
2677 
2678 			/* Skip this clip if it's outside the crtc region */
2679 			if (dirty->unit_x1 >= crtc_width ||
2680 			    dirty->unit_y1 >= crtc_height ||
2681 			    dirty->unit_x2 <= 0 || dirty->unit_y2 <= 0)
2682 				continue;
2683 
2684 			/* Clip right and bottom to crtc limits */
2685 			dirty->unit_x2 = min_t(s32, dirty->unit_x2,
2686 					       crtc_width);
2687 			dirty->unit_y2 = min_t(s32, dirty->unit_y2,
2688 					       crtc_height);
2689 
2690 			/* Clip left and top to crtc limits */
2691 			clip_left = min_t(s32, dirty->unit_x1, 0);
2692 			clip_top = min_t(s32, dirty->unit_y1, 0);
2693 			dirty->unit_x1 -= clip_left;
2694 			dirty->unit_y1 -= clip_top;
2695 			dirty->fb_x -= clip_left;
2696 			dirty->fb_y -= clip_top;
2697 
2698 			dirty->clip(dirty);
2699 		}
2700 
2701 		dirty->fifo_commit(dirty);
2702 	}
2703 
2704 	return 0;
2705 }
2706 
2707 /**
2708  * vmw_kms_helper_validation_finish - Helper for post KMS command submission
2709  * cleanup and fencing
2710  * @dev_priv: Pointer to the device-private struct
2711  * @file_priv: Pointer identifying the client when user-space fencing is used
2712  * @ctx: Pointer to the validation context
2713  * @out_fence: If non-NULL, returned refcounted fence-pointer
2714  * @user_fence_rep: If non-NULL, pointer to user-space address area
2715  * in which to copy user-space fence info
2716  */
vmw_kms_helper_validation_finish(struct vmw_private * dev_priv,struct drm_file * file_priv,struct vmw_validation_context * ctx,struct vmw_fence_obj ** out_fence,struct drm_vmw_fence_rep __user * user_fence_rep)2717 void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv,
2718 				      struct drm_file *file_priv,
2719 				      struct vmw_validation_context *ctx,
2720 				      struct vmw_fence_obj **out_fence,
2721 				      struct drm_vmw_fence_rep __user *
2722 				      user_fence_rep)
2723 {
2724 	struct vmw_fence_obj *fence = NULL;
2725 	uint32_t handle = 0;
2726 	int ret = 0;
2727 
2728 	if (file_priv || user_fence_rep || vmw_validation_has_bos(ctx) ||
2729 	    out_fence)
2730 		ret = vmw_execbuf_fence_commands(file_priv, dev_priv, &fence,
2731 						 file_priv ? &handle : NULL);
2732 	vmw_validation_done(ctx, fence);
2733 	if (file_priv)
2734 		vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv),
2735 					    ret, user_fence_rep, fence,
2736 					    handle, -1);
2737 	if (out_fence)
2738 		*out_fence = fence;
2739 	else
2740 		vmw_fence_obj_unreference(&fence);
2741 }
2742 
2743 /**
2744  * vmw_kms_update_proxy - Helper function to update a proxy surface from
2745  * its backing MOB.
2746  *
2747  * @res: Pointer to the surface resource
2748  * @clips: Clip rects in framebuffer (surface) space.
2749  * @num_clips: Number of clips in @clips.
2750  * @increment: Integer with which to increment the clip counter when looping.
2751  * Used to skip a predetermined number of clip rects.
2752  *
2753  * This function makes sure the proxy surface is updated from its backing MOB
2754  * using the region given by @clips. The surface resource @res and its backing
2755  * MOB needs to be reserved and validated on call.
2756  */
vmw_kms_update_proxy(struct vmw_resource * res,const struct drm_clip_rect * clips,unsigned num_clips,int increment)2757 int vmw_kms_update_proxy(struct vmw_resource *res,
2758 			 const struct drm_clip_rect *clips,
2759 			 unsigned num_clips,
2760 			 int increment)
2761 {
2762 	struct vmw_private *dev_priv = res->dev_priv;
2763 	struct drm_vmw_size *size = &vmw_res_to_srf(res)->metadata.base_size;
2764 	struct {
2765 		SVGA3dCmdHeader header;
2766 		SVGA3dCmdUpdateGBImage body;
2767 	} *cmd;
2768 	SVGA3dBox *box;
2769 	size_t copy_size = 0;
2770 	int i;
2771 
2772 	if (!clips)
2773 		return 0;
2774 
2775 	cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd) * num_clips);
2776 	if (!cmd)
2777 		return -ENOMEM;
2778 
2779 	for (i = 0; i < num_clips; ++i, clips += increment, ++cmd) {
2780 		box = &cmd->body.box;
2781 
2782 		cmd->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE;
2783 		cmd->header.size = sizeof(cmd->body);
2784 		cmd->body.image.sid = res->id;
2785 		cmd->body.image.face = 0;
2786 		cmd->body.image.mipmap = 0;
2787 
2788 		if (clips->x1 > size->width || clips->x2 > size->width ||
2789 		    clips->y1 > size->height || clips->y2 > size->height) {
2790 			DRM_ERROR("Invalid clips outsize of framebuffer.\n");
2791 			return -EINVAL;
2792 		}
2793 
2794 		box->x = clips->x1;
2795 		box->y = clips->y1;
2796 		box->z = 0;
2797 		box->w = clips->x2 - clips->x1;
2798 		box->h = clips->y2 - clips->y1;
2799 		box->d = 1;
2800 
2801 		copy_size += sizeof(*cmd);
2802 	}
2803 
2804 	vmw_cmd_commit(dev_priv, copy_size);
2805 
2806 	return 0;
2807 }
2808 
2809 /**
2810  * vmw_kms_create_implicit_placement_property - Set up the implicit placement
2811  * property.
2812  *
2813  * @dev_priv: Pointer to a device private struct.
2814  *
2815  * Sets up the implicit placement property unless it's already set up.
2816  */
2817 void
vmw_kms_create_implicit_placement_property(struct vmw_private * dev_priv)2818 vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv)
2819 {
2820 	if (dev_priv->implicit_placement_property)
2821 		return;
2822 
2823 	dev_priv->implicit_placement_property =
2824 		drm_property_create_range(&dev_priv->drm,
2825 					  DRM_MODE_PROP_IMMUTABLE,
2826 					  "implicit_placement", 0, 1);
2827 }
2828 
2829 /**
2830  * vmw_kms_suspend - Save modesetting state and turn modesetting off.
2831  *
2832  * @dev: Pointer to the drm device
2833  * Return: 0 on success. Negative error code on failure.
2834  */
vmw_kms_suspend(struct drm_device * dev)2835 int vmw_kms_suspend(struct drm_device *dev)
2836 {
2837 	struct vmw_private *dev_priv = vmw_priv(dev);
2838 
2839 	dev_priv->suspend_state = drm_atomic_helper_suspend(dev);
2840 	if (IS_ERR(dev_priv->suspend_state)) {
2841 		int ret = PTR_ERR(dev_priv->suspend_state);
2842 
2843 		DRM_ERROR("Failed kms suspend: %d\n", ret);
2844 		dev_priv->suspend_state = NULL;
2845 
2846 		return ret;
2847 	}
2848 
2849 	return 0;
2850 }
2851 
2852 
2853 /**
2854  * vmw_kms_resume - Re-enable modesetting and restore state
2855  *
2856  * @dev: Pointer to the drm device
2857  * Return: 0 on success. Negative error code on failure.
2858  *
2859  * State is resumed from a previous vmw_kms_suspend(). It's illegal
2860  * to call this function without a previous vmw_kms_suspend().
2861  */
vmw_kms_resume(struct drm_device * dev)2862 int vmw_kms_resume(struct drm_device *dev)
2863 {
2864 	struct vmw_private *dev_priv = vmw_priv(dev);
2865 	int ret;
2866 
2867 	if (WARN_ON(!dev_priv->suspend_state))
2868 		return 0;
2869 
2870 	ret = drm_atomic_helper_resume(dev, dev_priv->suspend_state);
2871 	dev_priv->suspend_state = NULL;
2872 
2873 	return ret;
2874 }
2875 
2876 /**
2877  * vmw_kms_lost_device - Notify kms that modesetting capabilities will be lost
2878  *
2879  * @dev: Pointer to the drm device
2880  */
vmw_kms_lost_device(struct drm_device * dev)2881 void vmw_kms_lost_device(struct drm_device *dev)
2882 {
2883 	drm_atomic_helper_shutdown(dev);
2884 }
2885 
2886 /**
2887  * vmw_du_helper_plane_update - Helper to do plane update on a display unit.
2888  * @update: The closure structure.
2889  *
2890  * Call this helper after setting callbacks in &vmw_du_update_plane to do plane
2891  * update on display unit.
2892  *
2893  * Return: 0 on success or a negative error code on failure.
2894  */
vmw_du_helper_plane_update(struct vmw_du_update_plane * update)2895 int vmw_du_helper_plane_update(struct vmw_du_update_plane *update)
2896 {
2897 	struct drm_plane_state *state = update->plane->state;
2898 	struct drm_plane_state *old_state = update->old_state;
2899 	struct drm_atomic_helper_damage_iter iter;
2900 	struct drm_rect clip;
2901 	struct drm_rect bb;
2902 	DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
2903 	uint32_t reserved_size = 0;
2904 	uint32_t submit_size = 0;
2905 	uint32_t curr_size = 0;
2906 	uint32_t num_hits = 0;
2907 	void *cmd_start;
2908 	char *cmd_next;
2909 	int ret;
2910 
2911 	/*
2912 	 * Iterate in advance to check if really need plane update and find the
2913 	 * number of clips that actually are in plane src for fifo allocation.
2914 	 */
2915 	drm_atomic_helper_damage_iter_init(&iter, old_state, state);
2916 	drm_atomic_for_each_plane_damage(&iter, &clip)
2917 		num_hits++;
2918 
2919 	if (num_hits == 0)
2920 		return 0;
2921 
2922 	if (update->vfb->bo) {
2923 		struct vmw_framebuffer_bo *vfbbo =
2924 			container_of(update->vfb, typeof(*vfbbo), base);
2925 
2926 		/*
2927 		 * For screen targets we want a mappable bo, for everything else we want
2928 		 * accelerated i.e. host backed (vram or gmr) bo. If the display unit
2929 		 * is not screen target then mob's shouldn't be available.
2930 		 */
2931 		if (update->dev_priv->active_display_unit == vmw_du_screen_target) {
2932 			vmw_bo_placement_set(vfbbo->buffer,
2933 					     VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_GMR,
2934 					     VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_GMR);
2935 		} else {
2936 			WARN_ON(update->dev_priv->has_mob);
2937 			vmw_bo_placement_set_default_accelerated(vfbbo->buffer);
2938 		}
2939 		ret = vmw_validation_add_bo(&val_ctx, vfbbo->buffer);
2940 	} else {
2941 		struct vmw_framebuffer_surface *vfbs =
2942 			container_of(update->vfb, typeof(*vfbs), base);
2943 
2944 		ret = vmw_validation_add_resource(&val_ctx, &vfbs->surface->res,
2945 						  0, VMW_RES_DIRTY_NONE, NULL,
2946 						  NULL);
2947 	}
2948 
2949 	if (ret)
2950 		return ret;
2951 
2952 	ret = vmw_validation_prepare(&val_ctx, update->mutex, update->intr);
2953 	if (ret)
2954 		goto out_unref;
2955 
2956 	reserved_size = update->calc_fifo_size(update, num_hits);
2957 	cmd_start = VMW_CMD_RESERVE(update->dev_priv, reserved_size);
2958 	if (!cmd_start) {
2959 		ret = -ENOMEM;
2960 		goto out_revert;
2961 	}
2962 
2963 	cmd_next = cmd_start;
2964 
2965 	if (update->post_prepare) {
2966 		curr_size = update->post_prepare(update, cmd_next);
2967 		cmd_next += curr_size;
2968 		submit_size += curr_size;
2969 	}
2970 
2971 	if (update->pre_clip) {
2972 		curr_size = update->pre_clip(update, cmd_next, num_hits);
2973 		cmd_next += curr_size;
2974 		submit_size += curr_size;
2975 	}
2976 
2977 	bb.x1 = INT_MAX;
2978 	bb.y1 = INT_MAX;
2979 	bb.x2 = INT_MIN;
2980 	bb.y2 = INT_MIN;
2981 
2982 	drm_atomic_helper_damage_iter_init(&iter, old_state, state);
2983 	drm_atomic_for_each_plane_damage(&iter, &clip) {
2984 		uint32_t fb_x = clip.x1;
2985 		uint32_t fb_y = clip.y1;
2986 
2987 		vmw_du_translate_to_crtc(state, &clip);
2988 		if (update->clip) {
2989 			curr_size = update->clip(update, cmd_next, &clip, fb_x,
2990 						 fb_y);
2991 			cmd_next += curr_size;
2992 			submit_size += curr_size;
2993 		}
2994 		bb.x1 = min_t(int, bb.x1, clip.x1);
2995 		bb.y1 = min_t(int, bb.y1, clip.y1);
2996 		bb.x2 = max_t(int, bb.x2, clip.x2);
2997 		bb.y2 = max_t(int, bb.y2, clip.y2);
2998 	}
2999 
3000 	curr_size = update->post_clip(update, cmd_next, &bb);
3001 	submit_size += curr_size;
3002 
3003 	if (reserved_size < submit_size)
3004 		submit_size = 0;
3005 
3006 	vmw_cmd_commit(update->dev_priv, submit_size);
3007 
3008 	vmw_kms_helper_validation_finish(update->dev_priv, NULL, &val_ctx,
3009 					 update->out_fence, NULL);
3010 	return ret;
3011 
3012 out_revert:
3013 	vmw_validation_revert(&val_ctx);
3014 
3015 out_unref:
3016 	vmw_validation_unref_lists(&val_ctx);
3017 	return ret;
3018 }
3019