1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /**************************************************************************
4 * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
27 #include "vmwgfx_kms.h"
29 #include "vmwgfx_bo.h"
30 #include "vmw_surface_cache.h"
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 #include <drm/drm_edid.h>
40 void vmw_du_cleanup(struct vmw_display_unit *du)
42 struct vmw_private *dev_priv = vmw_priv(du->primary.dev);
43 drm_plane_cleanup(&du->primary);
44 if (vmw_cmd_supported(dev_priv))
45 drm_plane_cleanup(&du->cursor.base);
47 drm_connector_unregister(&du->connector);
48 drm_crtc_cleanup(&du->crtc);
49 drm_encoder_cleanup(&du->encoder);
50 drm_connector_cleanup(&du->connector);
54 * Display Unit Cursor functions
57 static int vmw_du_cursor_plane_unmap_cm(struct vmw_plane_state *vps);
58 static void vmw_cursor_update_mob(struct vmw_private *dev_priv,
59 struct vmw_plane_state *vps,
60 u32 *image, u32 width, u32 height,
61 u32 hotspotX, u32 hotspotY);
63 struct vmw_svga_fifo_cmd_define_cursor {
65 SVGAFifoCmdDefineAlphaCursor cursor;
69 * vmw_send_define_cursor_cmd - queue a define cursor command
70 * @dev_priv: the private driver struct
71 * @image: buffer which holds the cursor image
72 * @width: width of the mouse cursor image
73 * @height: height of the mouse cursor image
74 * @hotspotX: the horizontal position of mouse hotspot
75 * @hotspotY: the vertical position of mouse hotspot
77 static void vmw_send_define_cursor_cmd(struct vmw_private *dev_priv,
78 u32 *image, u32 width, u32 height,
79 u32 hotspotX, u32 hotspotY)
81 struct vmw_svga_fifo_cmd_define_cursor *cmd;
82 const u32 image_size = width * height * sizeof(*image);
83 const u32 cmd_size = sizeof(*cmd) + image_size;
85 /* Try to reserve fifocmd space and swallow any failures;
86 such reservations cannot be left unconsumed for long
87 under the risk of clogging other fifocmd users, so
88 we treat reservations separtely from the way we treat
89 other fallible KMS-atomic resources at prepare_fb */
90 cmd = VMW_CMD_RESERVE(dev_priv, cmd_size);
95 memset(cmd, 0, sizeof(*cmd));
97 memcpy(&cmd[1], image, image_size);
99 cmd->cmd = SVGA_CMD_DEFINE_ALPHA_CURSOR;
101 cmd->cursor.width = width;
102 cmd->cursor.height = height;
103 cmd->cursor.hotspotX = hotspotX;
104 cmd->cursor.hotspotY = hotspotY;
106 vmw_cmd_commit_flush(dev_priv, cmd_size);
110 * vmw_cursor_update_image - update the cursor image on the provided plane
111 * @dev_priv: the private driver struct
112 * @vps: the plane state of the cursor plane
113 * @image: buffer which holds the cursor image
114 * @width: width of the mouse cursor image
115 * @height: height of the mouse cursor image
116 * @hotspotX: the horizontal position of mouse hotspot
117 * @hotspotY: the vertical position of mouse hotspot
119 static void vmw_cursor_update_image(struct vmw_private *dev_priv,
120 struct vmw_plane_state *vps,
121 u32 *image, u32 width, u32 height,
122 u32 hotspotX, u32 hotspotY)
125 vmw_cursor_update_mob(dev_priv, vps, image,
126 vps->base.crtc_w, vps->base.crtc_h,
130 vmw_send_define_cursor_cmd(dev_priv, image, width, height,
136 * vmw_cursor_update_mob - Update cursor vis CursorMob mechanism
138 * Called from inside vmw_du_cursor_plane_atomic_update to actually
139 * make the cursor-image live.
141 * @dev_priv: device to work with
142 * @vps: the plane state of the cursor plane
143 * @image: cursor source data to fill the MOB with
144 * @width: source data width
145 * @height: source data height
146 * @hotspotX: cursor hotspot x
147 * @hotspotY: cursor hotspot Y
149 static void vmw_cursor_update_mob(struct vmw_private *dev_priv,
150 struct vmw_plane_state *vps,
151 u32 *image, u32 width, u32 height,
152 u32 hotspotX, u32 hotspotY)
154 SVGAGBCursorHeader *header;
155 SVGAGBAlphaCursorHeader *alpha_header;
156 const u32 image_size = width * height * sizeof(*image);
158 header = vmw_bo_map_and_cache(vps->cursor.bo);
159 alpha_header = &header->header.alphaHeader;
161 memset(header, 0, sizeof(*header));
163 header->type = SVGA_ALPHA_CURSOR;
164 header->sizeInBytes = image_size;
166 alpha_header->hotspotX = hotspotX;
167 alpha_header->hotspotY = hotspotY;
168 alpha_header->width = width;
169 alpha_header->height = height;
171 memcpy(header + 1, image, image_size);
172 vmw_write(dev_priv, SVGA_REG_CURSOR_MOBID,
173 vps->cursor.bo->tbo.resource->start);
177 static u32 vmw_du_cursor_mob_size(u32 w, u32 h)
179 return w * h * sizeof(u32) + sizeof(SVGAGBCursorHeader);
183 * vmw_du_cursor_plane_acquire_image -- Acquire the image data
184 * @vps: cursor plane state
186 static u32 *vmw_du_cursor_plane_acquire_image(struct vmw_plane_state *vps)
189 if (vps->surf_mapped)
190 return vmw_bo_map_and_cache(vps->surf->res.guest_memory_bo);
191 return vps->surf->snooper.image;
193 return vmw_bo_map_and_cache(vps->bo);
197 static bool vmw_du_cursor_plane_has_changed(struct vmw_plane_state *old_vps,
198 struct vmw_plane_state *new_vps)
205 if (old_vps->base.crtc_w != new_vps->base.crtc_w ||
206 old_vps->base.crtc_h != new_vps->base.crtc_h)
209 if (old_vps->cursor.hotspot_x != new_vps->cursor.hotspot_x ||
210 old_vps->cursor.hotspot_y != new_vps->cursor.hotspot_y)
213 size = new_vps->base.crtc_w * new_vps->base.crtc_h * sizeof(u32);
215 old_image = vmw_du_cursor_plane_acquire_image(old_vps);
216 new_image = vmw_du_cursor_plane_acquire_image(new_vps);
219 if (old_image && new_image)
220 changed = memcmp(old_image, new_image, size) != 0;
225 static void vmw_du_destroy_cursor_mob(struct vmw_bo **vbo)
230 ttm_bo_unpin(&(*vbo)->tbo);
231 vmw_bo_unreference(vbo);
234 static void vmw_du_put_cursor_mob(struct vmw_cursor_plane *vcp,
235 struct vmw_plane_state *vps)
242 vmw_du_cursor_plane_unmap_cm(vps);
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;
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;
264 /* Destroy it if it's not worth caching. */
265 vmw_du_destroy_cursor_mob(&vps->cursor.bo);
268 static int vmw_du_get_cursor_mob(struct vmw_cursor_plane *vcp,
269 struct vmw_plane_state *vps)
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);
274 u32 cursor_max_dim, mob_max_size;
275 struct vmw_fence_obj *fence = NULL;
278 if (!dev_priv->has_mob ||
279 (dev_priv->capabilities2 & SVGA_CAP2_CURSOR_MOB) == 0)
282 mob_max_size = vmw_read(dev_priv, SVGA_REG_MOB_MAX_SIZE);
283 cursor_max_dim = vmw_read(dev_priv, SVGA_REG_CURSOR_MAX_DIMENSION);
285 if (size > mob_max_size || vps->base.crtc_w > cursor_max_dim ||
286 vps->base.crtc_h > cursor_max_dim)
289 if (vps->cursor.bo) {
290 if (vps->cursor.bo->tbo.base.size >= size)
292 vmw_du_put_cursor_mob(vcp, vps);
295 /* Look for an unused mob in the cache. */
296 for (i = 0; i < ARRAY_SIZE(vcp->cursor_mobs); i++) {
297 if (vcp->cursor_mobs[i] &&
298 vcp->cursor_mobs[i]->tbo.base.size >= size) {
299 vps->cursor.bo = vcp->cursor_mobs[i];
300 vcp->cursor_mobs[i] = NULL;
304 /* Create a new mob if we can't find an existing one. */
305 ret = vmw_bo_create_and_populate(dev_priv, size,
312 /* Fence the mob creation so we are guarateed to have the mob */
313 ret = ttm_bo_reserve(&vps->cursor.bo->tbo, false, false, NULL);
317 ret = vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL);
319 ttm_bo_unreserve(&vps->cursor.bo->tbo);
323 dma_fence_wait(&fence->base, false);
324 dma_fence_put(&fence->base);
326 ttm_bo_unreserve(&vps->cursor.bo->tbo);
330 vmw_du_destroy_cursor_mob(&vps->cursor.bo);
335 static void vmw_cursor_update_position(struct vmw_private *dev_priv,
336 bool show, int x, int y)
338 const uint32_t svga_cursor_on = show ? SVGA_CURSOR_ON_SHOW
339 : SVGA_CURSOR_ON_HIDE;
342 spin_lock(&dev_priv->cursor_lock);
343 if (dev_priv->capabilities2 & SVGA_CAP2_EXTRA_REGS) {
344 vmw_write(dev_priv, SVGA_REG_CURSOR4_X, x);
345 vmw_write(dev_priv, SVGA_REG_CURSOR4_Y, y);
346 vmw_write(dev_priv, SVGA_REG_CURSOR4_SCREEN_ID, SVGA3D_INVALID_ID);
347 vmw_write(dev_priv, SVGA_REG_CURSOR4_ON, svga_cursor_on);
348 vmw_write(dev_priv, SVGA_REG_CURSOR4_SUBMIT, 1);
349 } else if (vmw_is_cursor_bypass3_enabled(dev_priv)) {
350 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_ON, svga_cursor_on);
351 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_X, x);
352 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_Y, y);
353 count = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_CURSOR_COUNT);
354 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_COUNT, ++count);
356 vmw_write(dev_priv, SVGA_REG_CURSOR_X, x);
357 vmw_write(dev_priv, SVGA_REG_CURSOR_Y, y);
358 vmw_write(dev_priv, SVGA_REG_CURSOR_ON, svga_cursor_on);
360 spin_unlock(&dev_priv->cursor_lock);
363 void vmw_kms_cursor_snoop(struct vmw_surface *srf,
364 struct ttm_object_file *tfile,
365 struct ttm_buffer_object *bo,
366 SVGA3dCmdHeader *header)
368 struct ttm_bo_kmap_obj map;
369 unsigned long kmap_offset;
370 unsigned long kmap_num;
376 SVGA3dCmdHeader header;
377 SVGA3dCmdSurfaceDMA dma;
380 const struct SVGA3dSurfaceDesc *desc =
381 vmw_surface_get_desc(VMW_CURSOR_SNOOP_FORMAT);
382 const u32 image_pitch = VMW_CURSOR_SNOOP_WIDTH * desc->pitchBytesPerBlock;
384 cmd = container_of(header, struct vmw_dma_cmd, header);
386 /* No snooper installed, nothing to copy */
387 if (!srf->snooper.image)
390 if (cmd->dma.host.face != 0 || cmd->dma.host.mipmap != 0) {
391 DRM_ERROR("face and mipmap for cursors should never != 0\n");
395 if (cmd->header.size < 64) {
396 DRM_ERROR("at least one full copy box must be given\n");
400 box = (SVGA3dCopyBox *)&cmd[1];
401 box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) /
402 sizeof(SVGA3dCopyBox);
404 if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
405 box->x != 0 || box->y != 0 || box->z != 0 ||
406 box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
407 box->d != 1 || box_count != 1 ||
408 box->w > VMW_CURSOR_SNOOP_WIDTH || box->h > VMW_CURSOR_SNOOP_HEIGHT) {
409 /* TODO handle none page aligned offsets */
410 /* TODO handle more dst & src != 0 */
411 /* TODO handle more then one copy */
412 DRM_ERROR("Can't snoop dma request for cursor!\n");
413 DRM_ERROR("(%u, %u, %u) (%u, %u, %u) (%ux%ux%u) %u %u\n",
414 box->srcx, box->srcy, box->srcz,
415 box->x, box->y, box->z,
416 box->w, box->h, box->d, box_count,
417 cmd->dma.guest.ptr.offset);
421 kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
422 kmap_num = (VMW_CURSOR_SNOOP_HEIGHT*image_pitch) >> PAGE_SHIFT;
424 ret = ttm_bo_reserve(bo, true, false, NULL);
425 if (unlikely(ret != 0)) {
426 DRM_ERROR("reserve failed\n");
430 ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
431 if (unlikely(ret != 0))
434 virtual = ttm_kmap_obj_virtual(&map, &is_iomem);
436 if (box->w == VMW_CURSOR_SNOOP_WIDTH && cmd->dma.guest.pitch == image_pitch) {
437 memcpy(srf->snooper.image, virtual,
438 VMW_CURSOR_SNOOP_HEIGHT*image_pitch);
440 /* Image is unsigned pointer. */
441 for (i = 0; i < box->h; i++)
442 memcpy(srf->snooper.image + i * image_pitch,
443 virtual + i * cmd->dma.guest.pitch,
444 box->w * desc->pitchBytesPerBlock);
451 ttm_bo_unreserve(bo);
455 * vmw_kms_legacy_hotspot_clear - Clear legacy hotspots
457 * @dev_priv: Pointer to the device private struct.
459 * Clears all legacy hotspots.
461 void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv)
463 struct drm_device *dev = &dev_priv->drm;
464 struct vmw_display_unit *du;
465 struct drm_crtc *crtc;
467 drm_modeset_lock_all(dev);
468 drm_for_each_crtc(crtc, dev) {
469 du = vmw_crtc_to_du(crtc);
474 drm_modeset_unlock_all(dev);
477 void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
479 struct drm_device *dev = &dev_priv->drm;
480 struct vmw_display_unit *du;
481 struct drm_crtc *crtc;
483 mutex_lock(&dev->mode_config.mutex);
485 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
486 du = vmw_crtc_to_du(crtc);
487 if (!du->cursor_surface ||
488 du->cursor_age == du->cursor_surface->snooper.age ||
489 !du->cursor_surface->snooper.image)
492 du->cursor_age = du->cursor_surface->snooper.age;
493 vmw_send_define_cursor_cmd(dev_priv,
494 du->cursor_surface->snooper.image,
495 VMW_CURSOR_SNOOP_WIDTH,
496 VMW_CURSOR_SNOOP_HEIGHT,
497 du->hotspot_x + du->core_hotspot_x,
498 du->hotspot_y + du->core_hotspot_y);
501 mutex_unlock(&dev->mode_config.mutex);
505 void vmw_du_cursor_plane_destroy(struct drm_plane *plane)
507 struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane);
510 vmw_cursor_update_position(plane->dev->dev_private, false, 0, 0);
512 for (i = 0; i < ARRAY_SIZE(vcp->cursor_mobs); i++)
513 vmw_du_destroy_cursor_mob(&vcp->cursor_mobs[i]);
515 drm_plane_cleanup(plane);
519 void vmw_du_primary_plane_destroy(struct drm_plane *plane)
521 drm_plane_cleanup(plane);
523 /* Planes are static in our case so we don't free it */
528 * vmw_du_plane_unpin_surf - unpins resource associated with a framebuffer surface
530 * @vps: plane state associated with the display surface
531 * @unreference: true if we also want to unreference the display.
533 void vmw_du_plane_unpin_surf(struct vmw_plane_state *vps,
538 vmw_resource_unpin(&vps->surf->res);
544 DRM_ERROR("Surface still pinned\n");
545 vmw_surface_unreference(&vps->surf);
552 * vmw_du_plane_cleanup_fb - Unpins the plane surface
554 * @plane: display plane
555 * @old_state: Contains the FB to clean up
557 * Unpins the framebuffer surface
559 * Returns 0 on success
562 vmw_du_plane_cleanup_fb(struct drm_plane *plane,
563 struct drm_plane_state *old_state)
565 struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
567 vmw_du_plane_unpin_surf(vps, false);
572 * vmw_du_cursor_plane_map_cm - Maps the cursor mobs.
576 * Returns 0 on success
580 vmw_du_cursor_plane_map_cm(struct vmw_plane_state *vps)
583 u32 size = vmw_du_cursor_mob_size(vps->base.crtc_w, vps->base.crtc_h);
584 struct ttm_buffer_object *bo;
589 bo = &vps->cursor.bo->tbo;
591 if (bo->base.size < size)
594 if (vps->cursor.bo->map.virtual)
597 ret = ttm_bo_reserve(bo, false, false, NULL);
598 if (unlikely(ret != 0))
601 vmw_bo_map_and_cache(vps->cursor.bo);
603 ttm_bo_unreserve(bo);
605 if (unlikely(ret != 0))
613 * vmw_du_cursor_plane_unmap_cm - Unmaps the cursor mobs.
615 * @vps: state of the cursor plane
617 * Returns 0 on success
621 vmw_du_cursor_plane_unmap_cm(struct vmw_plane_state *vps)
624 struct vmw_bo *vbo = vps->cursor.bo;
626 if (!vbo || !vbo->map.virtual)
629 ret = ttm_bo_reserve(&vbo->tbo, true, false, NULL);
630 if (likely(ret == 0)) {
632 ttm_bo_unreserve(&vbo->tbo);
640 * vmw_du_cursor_plane_cleanup_fb - Unpins the plane surface
642 * @plane: cursor plane
643 * @old_state: contains the state to clean up
645 * Unmaps all cursor bo mappings and unpins the cursor surface
647 * Returns 0 on success
650 vmw_du_cursor_plane_cleanup_fb(struct drm_plane *plane,
651 struct drm_plane_state *old_state)
653 struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane);
654 struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
656 if (vps->surf_mapped) {
657 vmw_bo_unmap(vps->surf->res.guest_memory_bo);
658 vps->surf_mapped = false;
661 vmw_du_cursor_plane_unmap_cm(vps);
662 vmw_du_put_cursor_mob(vcp, vps);
664 vmw_du_plane_unpin_surf(vps, false);
667 vmw_surface_unreference(&vps->surf);
672 vmw_bo_unreference(&vps->bo);
679 * vmw_du_cursor_plane_prepare_fb - Readies the cursor by referencing it
681 * @plane: display plane
682 * @new_state: info on the new plane state, including the FB
684 * Returns 0 on success
687 vmw_du_cursor_plane_prepare_fb(struct drm_plane *plane,
688 struct drm_plane_state *new_state)
690 struct drm_framebuffer *fb = new_state->fb;
691 struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane);
692 struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
696 if (vps->surf_mapped) {
697 vmw_bo_unmap(vps->surf->res.guest_memory_bo);
698 vps->surf_mapped = false;
700 vmw_surface_unreference(&vps->surf);
705 vmw_bo_unreference(&vps->bo);
710 if (vmw_framebuffer_to_vfb(fb)->bo) {
711 vps->bo = vmw_framebuffer_to_vfbd(fb)->buffer;
712 vmw_bo_reference(vps->bo);
714 vps->surf = vmw_framebuffer_to_vfbs(fb)->surface;
715 vmw_surface_reference(vps->surf);
719 if (!vps->surf && vps->bo) {
720 const u32 size = new_state->crtc_w * new_state->crtc_h * sizeof(u32);
723 * Not using vmw_bo_map_and_cache() helper here as we need to
724 * reserve the ttm_buffer_object first which
725 * vmw_bo_map_and_cache() omits.
727 ret = ttm_bo_reserve(&vps->bo->tbo, true, false, NULL);
729 if (unlikely(ret != 0))
732 ret = ttm_bo_kmap(&vps->bo->tbo, 0, PFN_UP(size), &vps->bo->map);
734 ttm_bo_unreserve(&vps->bo->tbo);
736 if (unlikely(ret != 0))
738 } else if (vps->surf && !vps->bo && vps->surf->res.guest_memory_bo) {
740 WARN_ON(vps->surf->snooper.image);
741 ret = ttm_bo_reserve(&vps->surf->res.guest_memory_bo->tbo, true, false,
743 if (unlikely(ret != 0))
745 vmw_bo_map_and_cache(vps->surf->res.guest_memory_bo);
746 ttm_bo_unreserve(&vps->surf->res.guest_memory_bo->tbo);
747 vps->surf_mapped = true;
750 if (vps->surf || vps->bo) {
751 vmw_du_get_cursor_mob(vcp, vps);
752 vmw_du_cursor_plane_map_cm(vps);
760 vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
761 struct drm_atomic_state *state)
763 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
765 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
767 struct drm_crtc *crtc = new_state->crtc ?: old_state->crtc;
768 struct vmw_private *dev_priv = vmw_priv(crtc->dev);
769 struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
770 struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
771 struct vmw_plane_state *old_vps = vmw_plane_state_to_vps(old_state);
772 s32 hotspot_x, hotspot_y;
774 hotspot_x = du->hotspot_x + new_state->hotspot_x;
775 hotspot_y = du->hotspot_y + new_state->hotspot_y;
777 du->cursor_surface = vps->surf;
778 du->cursor_bo = vps->bo;
780 if (!vps->surf && !vps->bo) {
781 vmw_cursor_update_position(dev_priv, false, 0, 0);
785 vps->cursor.hotspot_x = hotspot_x;
786 vps->cursor.hotspot_y = hotspot_y;
789 du->cursor_age = du->cursor_surface->snooper.age;
792 if (!vmw_du_cursor_plane_has_changed(old_vps, vps)) {
794 * If it hasn't changed, avoid making the device do extra
795 * work by keeping the old cursor active.
797 struct vmw_cursor_plane_state tmp = old_vps->cursor;
798 old_vps->cursor = vps->cursor;
801 void *image = vmw_du_cursor_plane_acquire_image(vps);
803 vmw_cursor_update_image(dev_priv, vps, image,
806 hotspot_x, hotspot_y);
809 du->cursor_x = new_state->crtc_x + du->set_gui_x;
810 du->cursor_y = new_state->crtc_y + du->set_gui_y;
812 vmw_cursor_update_position(dev_priv, true,
813 du->cursor_x + hotspot_x,
814 du->cursor_y + hotspot_y);
816 du->core_hotspot_x = hotspot_x - du->hotspot_x;
817 du->core_hotspot_y = hotspot_y - du->hotspot_y;
822 * vmw_du_primary_plane_atomic_check - check if the new state is okay
824 * @plane: display plane
825 * @state: info on the new plane state, including the FB
827 * Check if the new state is settable given the current state. Other
828 * than what the atomic helper checks, we care about crtc fitting
829 * the FB and maintaining one active framebuffer.
831 * Returns 0 on success
833 int vmw_du_primary_plane_atomic_check(struct drm_plane *plane,
834 struct drm_atomic_state *state)
836 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
838 struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
840 struct drm_crtc_state *crtc_state = NULL;
841 struct drm_framebuffer *new_fb = new_state->fb;
842 struct drm_framebuffer *old_fb = old_state->fb;
846 * Ignore damage clips if the framebuffer attached to the plane's state
847 * has changed since the last plane update (page-flip). In this case, a
848 * full plane update should happen because uploads are done per-buffer.
850 if (old_fb != new_fb)
851 new_state->ignore_damage_clips = true;
854 crtc_state = drm_atomic_get_new_crtc_state(state,
857 ret = drm_atomic_helper_check_plane_state(new_state, crtc_state,
858 DRM_PLANE_NO_SCALING,
859 DRM_PLANE_NO_SCALING,
862 if (!ret && new_fb) {
863 struct drm_crtc *crtc = new_state->crtc;
864 struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
866 vmw_connector_state_to_vcs(du->connector.state);
875 * vmw_du_cursor_plane_atomic_check - check if the new state is okay
877 * @plane: cursor plane
878 * @state: info on the new plane state
880 * This is a chance to fail if the new cursor state does not fit
883 * Returns 0 on success
885 int vmw_du_cursor_plane_atomic_check(struct drm_plane *plane,
886 struct drm_atomic_state *state)
888 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
891 struct drm_crtc_state *crtc_state = NULL;
892 struct vmw_surface *surface = NULL;
893 struct drm_framebuffer *fb = new_state->fb;
896 crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
899 ret = drm_atomic_helper_check_plane_state(new_state, crtc_state,
900 DRM_PLANE_NO_SCALING,
901 DRM_PLANE_NO_SCALING,
910 /* A lot of the code assumes this */
911 if (new_state->crtc_w != 64 || new_state->crtc_h != 64) {
912 DRM_ERROR("Invalid cursor dimensions (%d, %d)\n",
913 new_state->crtc_w, new_state->crtc_h);
917 if (!vmw_framebuffer_to_vfb(fb)->bo) {
918 surface = vmw_framebuffer_to_vfbs(fb)->surface;
923 (!surface->snooper.image && !surface->res.guest_memory_bo)) {
924 DRM_ERROR("surface not suitable for cursor\n");
933 int vmw_du_crtc_atomic_check(struct drm_crtc *crtc,
934 struct drm_atomic_state *state)
936 struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state,
938 struct vmw_display_unit *du = vmw_crtc_to_du(new_state->crtc);
939 int connector_mask = drm_connector_mask(&du->connector);
940 bool has_primary = new_state->plane_mask &
941 drm_plane_mask(crtc->primary);
943 /* We always want to have an active plane with an active CRTC */
944 if (has_primary != new_state->enable)
948 if (new_state->connector_mask != connector_mask &&
949 new_state->connector_mask != 0) {
950 DRM_ERROR("Invalid connectors configuration\n");
955 * Our virtual device does not have a dot clock, so use the logical
956 * clock value as the dot clock.
958 if (new_state->mode.crtc_clock == 0)
959 new_state->adjusted_mode.crtc_clock = new_state->mode.clock;
965 void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc,
966 struct drm_atomic_state *state)
971 void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc,
972 struct drm_atomic_state *state)
978 * vmw_du_crtc_duplicate_state - duplicate crtc state
981 * Allocates and returns a copy of the crtc state (both common and
982 * vmw-specific) for the specified crtc.
984 * Returns: The newly allocated crtc state, or NULL on failure.
986 struct drm_crtc_state *
987 vmw_du_crtc_duplicate_state(struct drm_crtc *crtc)
989 struct drm_crtc_state *state;
990 struct vmw_crtc_state *vcs;
992 if (WARN_ON(!crtc->state))
995 vcs = kmemdup(crtc->state, sizeof(*vcs), GFP_KERNEL);
1002 __drm_atomic_helper_crtc_duplicate_state(crtc, state);
1009 * vmw_du_crtc_reset - creates a blank vmw crtc state
1012 * Resets the atomic state for @crtc by freeing the state pointer (which
1013 * might be NULL, e.g. at driver load time) and allocating a new empty state
1016 void vmw_du_crtc_reset(struct drm_crtc *crtc)
1018 struct vmw_crtc_state *vcs;
1022 __drm_atomic_helper_crtc_destroy_state(crtc->state);
1024 kfree(vmw_crtc_state_to_vcs(crtc->state));
1027 vcs = kzalloc(sizeof(*vcs), GFP_KERNEL);
1030 DRM_ERROR("Cannot allocate vmw_crtc_state\n");
1034 __drm_atomic_helper_crtc_reset(crtc, &vcs->base);
1039 * vmw_du_crtc_destroy_state - destroy crtc state
1041 * @state: state object to destroy
1043 * Destroys the crtc state (both common and vmw-specific) for the
1047 vmw_du_crtc_destroy_state(struct drm_crtc *crtc,
1048 struct drm_crtc_state *state)
1050 drm_atomic_helper_crtc_destroy_state(crtc, state);
1055 * vmw_du_plane_duplicate_state - duplicate plane state
1058 * Allocates and returns a copy of the plane state (both common and
1059 * vmw-specific) for the specified plane.
1061 * Returns: The newly allocated plane state, or NULL on failure.
1063 struct drm_plane_state *
1064 vmw_du_plane_duplicate_state(struct drm_plane *plane)
1066 struct drm_plane_state *state;
1067 struct vmw_plane_state *vps;
1069 vps = kmemdup(plane->state, sizeof(*vps), GFP_KERNEL);
1077 memset(&vps->cursor, 0, sizeof(vps->cursor));
1079 /* Each ref counted resource needs to be acquired again */
1081 (void) vmw_surface_reference(vps->surf);
1084 (void) vmw_bo_reference(vps->bo);
1088 __drm_atomic_helper_plane_duplicate_state(plane, state);
1095 * vmw_du_plane_reset - creates a blank vmw plane state
1098 * Resets the atomic state for @plane by freeing the state pointer (which might
1099 * be NULL, e.g. at driver load time) and allocating a new empty state object.
1101 void vmw_du_plane_reset(struct drm_plane *plane)
1103 struct vmw_plane_state *vps;
1106 vmw_du_plane_destroy_state(plane, plane->state);
1108 vps = kzalloc(sizeof(*vps), GFP_KERNEL);
1111 DRM_ERROR("Cannot allocate vmw_plane_state\n");
1115 __drm_atomic_helper_plane_reset(plane, &vps->base);
1120 * vmw_du_plane_destroy_state - destroy plane state
1122 * @state: state object to destroy
1124 * Destroys the plane state (both common and vmw-specific) for the
1128 vmw_du_plane_destroy_state(struct drm_plane *plane,
1129 struct drm_plane_state *state)
1131 struct vmw_plane_state *vps = vmw_plane_state_to_vps(state);
1133 /* Should have been freed by cleanup_fb */
1135 vmw_surface_unreference(&vps->surf);
1138 vmw_bo_unreference(&vps->bo);
1140 drm_atomic_helper_plane_destroy_state(plane, state);
1145 * vmw_du_connector_duplicate_state - duplicate connector state
1146 * @connector: DRM connector
1148 * Allocates and returns a copy of the connector state (both common and
1149 * vmw-specific) for the specified connector.
1151 * Returns: The newly allocated connector state, or NULL on failure.
1153 struct drm_connector_state *
1154 vmw_du_connector_duplicate_state(struct drm_connector *connector)
1156 struct drm_connector_state *state;
1157 struct vmw_connector_state *vcs;
1159 if (WARN_ON(!connector->state))
1162 vcs = kmemdup(connector->state, sizeof(*vcs), GFP_KERNEL);
1169 __drm_atomic_helper_connector_duplicate_state(connector, state);
1176 * vmw_du_connector_reset - creates a blank vmw connector state
1177 * @connector: DRM connector
1179 * Resets the atomic state for @connector by freeing the state pointer (which
1180 * might be NULL, e.g. at driver load time) and allocating a new empty state
1183 void vmw_du_connector_reset(struct drm_connector *connector)
1185 struct vmw_connector_state *vcs;
1188 if (connector->state) {
1189 __drm_atomic_helper_connector_destroy_state(connector->state);
1191 kfree(vmw_connector_state_to_vcs(connector->state));
1194 vcs = kzalloc(sizeof(*vcs), GFP_KERNEL);
1197 DRM_ERROR("Cannot allocate vmw_connector_state\n");
1201 __drm_atomic_helper_connector_reset(connector, &vcs->base);
1206 * vmw_du_connector_destroy_state - destroy connector state
1207 * @connector: DRM connector
1208 * @state: state object to destroy
1210 * Destroys the connector state (both common and vmw-specific) for the
1214 vmw_du_connector_destroy_state(struct drm_connector *connector,
1215 struct drm_connector_state *state)
1217 drm_atomic_helper_connector_destroy_state(connector, state);
1220 * Generic framebuffer code
1224 * Surface framebuffer code
1227 static void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)
1229 struct vmw_framebuffer_surface *vfbs =
1230 vmw_framebuffer_to_vfbs(framebuffer);
1232 drm_framebuffer_cleanup(framebuffer);
1233 vmw_surface_unreference(&vfbs->surface);
1239 * vmw_kms_readback - Perform a readback from the screen system to
1240 * a buffer-object backed framebuffer.
1242 * @dev_priv: Pointer to the device private structure.
1243 * @file_priv: Pointer to a struct drm_file identifying the caller.
1244 * Must be set to NULL if @user_fence_rep is NULL.
1245 * @vfb: Pointer to the buffer-object backed framebuffer.
1246 * @user_fence_rep: User-space provided structure for fence information.
1247 * Must be set to non-NULL if @file_priv is non-NULL.
1248 * @vclips: Array of clip rects.
1249 * @num_clips: Number of clip rects in @vclips.
1251 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
1254 int vmw_kms_readback(struct vmw_private *dev_priv,
1255 struct drm_file *file_priv,
1256 struct vmw_framebuffer *vfb,
1257 struct drm_vmw_fence_rep __user *user_fence_rep,
1258 struct drm_vmw_rect *vclips,
1261 switch (dev_priv->active_display_unit) {
1262 case vmw_du_screen_object:
1263 return vmw_kms_sou_readback(dev_priv, file_priv, vfb,
1264 user_fence_rep, vclips, num_clips,
1266 case vmw_du_screen_target:
1267 return vmw_kms_stdu_readback(dev_priv, file_priv, vfb,
1268 user_fence_rep, NULL, vclips, num_clips,
1272 "Readback called with invalid display system.\n");
1279 static const struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
1280 .destroy = vmw_framebuffer_surface_destroy,
1281 .dirty = drm_atomic_helper_dirtyfb,
1284 static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
1285 struct vmw_surface *surface,
1286 struct vmw_framebuffer **out,
1287 const struct drm_mode_fb_cmd2
1292 struct drm_device *dev = &dev_priv->drm;
1293 struct vmw_framebuffer_surface *vfbs;
1294 enum SVGA3dSurfaceFormat format;
1297 /* 3D is only supported on HWv8 and newer hosts */
1298 if (dev_priv->active_display_unit == vmw_du_legacy)
1305 if (!drm_any_plane_has_format(&dev_priv->drm,
1306 mode_cmd->pixel_format,
1307 mode_cmd->modifier[0])) {
1308 drm_dbg(&dev_priv->drm,
1309 "unsupported pixel format %p4cc / modifier 0x%llx\n",
1310 &mode_cmd->pixel_format, mode_cmd->modifier[0]);
1314 /* Surface must be marked as a scanout. */
1315 if (unlikely(!surface->metadata.scanout))
1318 if (unlikely(surface->metadata.mip_levels[0] != 1 ||
1319 surface->metadata.num_sizes != 1 ||
1320 surface->metadata.base_size.width < mode_cmd->width ||
1321 surface->metadata.base_size.height < mode_cmd->height ||
1322 surface->metadata.base_size.depth != 1)) {
1323 DRM_ERROR("Incompatible surface dimensions "
1324 "for requested mode.\n");
1328 switch (mode_cmd->pixel_format) {
1329 case DRM_FORMAT_ARGB8888:
1330 format = SVGA3D_A8R8G8B8;
1332 case DRM_FORMAT_XRGB8888:
1333 format = SVGA3D_X8R8G8B8;
1335 case DRM_FORMAT_RGB565:
1336 format = SVGA3D_R5G6B5;
1338 case DRM_FORMAT_XRGB1555:
1339 format = SVGA3D_A1R5G5B5;
1342 DRM_ERROR("Invalid pixel format: %p4cc\n",
1343 &mode_cmd->pixel_format);
1348 * For DX, surface format validation is done when surface->scanout
1351 if (!has_sm4_context(dev_priv) && format != surface->metadata.format) {
1352 DRM_ERROR("Invalid surface format for requested mode.\n");
1356 vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL);
1362 drm_helper_mode_fill_fb_struct(dev, &vfbs->base.base, mode_cmd);
1363 vfbs->surface = vmw_surface_reference(surface);
1364 vfbs->base.user_handle = mode_cmd->handles[0];
1365 vfbs->is_bo_proxy = is_bo_proxy;
1369 ret = drm_framebuffer_init(dev, &vfbs->base.base,
1370 &vmw_framebuffer_surface_funcs);
1377 vmw_surface_unreference(&surface);
1384 * Buffer-object framebuffer code
1387 static int vmw_framebuffer_bo_create_handle(struct drm_framebuffer *fb,
1388 struct drm_file *file_priv,
1389 unsigned int *handle)
1391 struct vmw_framebuffer_bo *vfbd =
1392 vmw_framebuffer_to_vfbd(fb);
1394 return drm_gem_handle_create(file_priv, &vfbd->buffer->tbo.base, handle);
1397 static void vmw_framebuffer_bo_destroy(struct drm_framebuffer *framebuffer)
1399 struct vmw_framebuffer_bo *vfbd =
1400 vmw_framebuffer_to_vfbd(framebuffer);
1402 drm_framebuffer_cleanup(framebuffer);
1403 vmw_bo_unreference(&vfbd->buffer);
1408 static const struct drm_framebuffer_funcs vmw_framebuffer_bo_funcs = {
1409 .create_handle = vmw_framebuffer_bo_create_handle,
1410 .destroy = vmw_framebuffer_bo_destroy,
1411 .dirty = drm_atomic_helper_dirtyfb,
1415 * vmw_create_bo_proxy - create a proxy surface for the buffer object
1418 * @mode_cmd: parameters for the new surface
1419 * @bo_mob: MOB backing the buffer object
1420 * @srf_out: newly created surface
1422 * When the content FB is a buffer object, we create a surface as a proxy to the
1423 * same buffer. This way we can do a surface copy rather than a surface DMA.
1424 * This is a more efficient approach
1427 * 0 on success, error code otherwise
1429 static int vmw_create_bo_proxy(struct drm_device *dev,
1430 const struct drm_mode_fb_cmd2 *mode_cmd,
1431 struct vmw_bo *bo_mob,
1432 struct vmw_surface **srf_out)
1434 struct vmw_surface_metadata metadata = {0};
1436 struct vmw_resource *res;
1437 unsigned int bytes_pp;
1440 switch (mode_cmd->pixel_format) {
1441 case DRM_FORMAT_ARGB8888:
1442 case DRM_FORMAT_XRGB8888:
1443 format = SVGA3D_X8R8G8B8;
1447 case DRM_FORMAT_RGB565:
1448 case DRM_FORMAT_XRGB1555:
1449 format = SVGA3D_R5G6B5;
1459 DRM_ERROR("Invalid framebuffer format %p4cc\n",
1460 &mode_cmd->pixel_format);
1464 metadata.format = format;
1465 metadata.mip_levels[0] = 1;
1466 metadata.num_sizes = 1;
1467 metadata.base_size.width = mode_cmd->pitches[0] / bytes_pp;
1468 metadata.base_size.height = mode_cmd->height;
1469 metadata.base_size.depth = 1;
1470 metadata.scanout = true;
1472 ret = vmw_gb_surface_define(vmw_priv(dev), &metadata, srf_out);
1474 DRM_ERROR("Failed to allocate proxy content buffer\n");
1478 res = &(*srf_out)->res;
1480 /* Reserve and switch the backing mob. */
1481 mutex_lock(&res->dev_priv->cmdbuf_mutex);
1482 (void) vmw_resource_reserve(res, false, true);
1483 vmw_user_bo_unref(&res->guest_memory_bo);
1484 res->guest_memory_bo = vmw_user_bo_ref(bo_mob);
1485 res->guest_memory_offset = 0;
1486 vmw_resource_unreserve(res, false, false, false, NULL, 0);
1487 mutex_unlock(&res->dev_priv->cmdbuf_mutex);
1494 static int vmw_kms_new_framebuffer_bo(struct vmw_private *dev_priv,
1496 struct vmw_framebuffer **out,
1497 const struct drm_mode_fb_cmd2
1501 struct drm_device *dev = &dev_priv->drm;
1502 struct vmw_framebuffer_bo *vfbd;
1503 unsigned int requested_size;
1506 requested_size = mode_cmd->height * mode_cmd->pitches[0];
1507 if (unlikely(requested_size > bo->tbo.base.size)) {
1508 DRM_ERROR("Screen buffer object size is too small "
1509 "for requested mode.\n");
1513 if (!drm_any_plane_has_format(&dev_priv->drm,
1514 mode_cmd->pixel_format,
1515 mode_cmd->modifier[0])) {
1516 drm_dbg(&dev_priv->drm,
1517 "unsupported pixel format %p4cc / modifier 0x%llx\n",
1518 &mode_cmd->pixel_format, mode_cmd->modifier[0]);
1522 vfbd = kzalloc(sizeof(*vfbd), GFP_KERNEL);
1528 vfbd->base.base.obj[0] = &bo->tbo.base;
1529 drm_helper_mode_fill_fb_struct(dev, &vfbd->base.base, mode_cmd);
1530 vfbd->base.bo = true;
1531 vfbd->buffer = vmw_bo_reference(bo);
1532 vfbd->base.user_handle = mode_cmd->handles[0];
1535 ret = drm_framebuffer_init(dev, &vfbd->base.base,
1536 &vmw_framebuffer_bo_funcs);
1543 vmw_bo_unreference(&bo);
1551 * vmw_kms_srf_ok - check if a surface can be created
1553 * @dev_priv: Pointer to device private struct.
1554 * @width: requested width
1555 * @height: requested height
1557 * Surfaces need to be less than texture size
1560 vmw_kms_srf_ok(struct vmw_private *dev_priv, uint32_t width, uint32_t height)
1562 if (width > dev_priv->texture_max_width ||
1563 height > dev_priv->texture_max_height)
1570 * vmw_kms_new_framebuffer - Create a new framebuffer.
1572 * @dev_priv: Pointer to device private struct.
1573 * @bo: Pointer to buffer object to wrap the kms framebuffer around.
1574 * Either @bo or @surface must be NULL.
1575 * @surface: Pointer to a surface to wrap the kms framebuffer around.
1576 * Either @bo or @surface must be NULL.
1577 * @only_2d: No presents will occur to this buffer object based framebuffer.
1578 * This helps the code to do some important optimizations.
1579 * @mode_cmd: Frame-buffer metadata.
1581 struct vmw_framebuffer *
1582 vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
1584 struct vmw_surface *surface,
1586 const struct drm_mode_fb_cmd2 *mode_cmd)
1588 struct vmw_framebuffer *vfb = NULL;
1589 bool is_bo_proxy = false;
1593 * We cannot use the SurfaceDMA command in an non-accelerated VM,
1594 * therefore, wrap the buffer object in a surface so we can use the
1595 * SurfaceCopy command.
1597 if (vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height) &&
1599 mode_cmd->width > 64 && /* Don't create a proxy for cursor */
1600 dev_priv->active_display_unit == vmw_du_screen_target) {
1601 ret = vmw_create_bo_proxy(&dev_priv->drm, mode_cmd,
1604 return ERR_PTR(ret);
1609 /* Create the new framebuffer depending one what we have */
1611 ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
1615 * vmw_create_bo_proxy() adds a reference that is no longer
1619 vmw_surface_unreference(&surface);
1621 ret = vmw_kms_new_framebuffer_bo(dev_priv, bo, &vfb,
1628 return ERR_PTR(ret);
1634 * Generic Kernel modesetting functions
1637 static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
1638 struct drm_file *file_priv,
1639 const struct drm_mode_fb_cmd2 *mode_cmd)
1641 struct vmw_private *dev_priv = vmw_priv(dev);
1642 struct vmw_framebuffer *vfb = NULL;
1643 struct vmw_surface *surface = NULL;
1644 struct vmw_bo *bo = NULL;
1647 /* returns either a bo or surface */
1648 ret = vmw_user_lookup_handle(dev_priv, file_priv,
1649 mode_cmd->handles[0],
1652 DRM_ERROR("Invalid buffer object handle %u (0x%x).\n",
1653 mode_cmd->handles[0], mode_cmd->handles[0]);
1659 !vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)) {
1660 DRM_ERROR("Surface size cannot exceed %dx%d\n",
1661 dev_priv->texture_max_width,
1662 dev_priv->texture_max_height);
1667 vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface,
1668 !(dev_priv->capabilities & SVGA_CAP_3D),
1676 /* vmw_user_lookup_handle takes one ref so does new_fb */
1678 vmw_user_bo_unref(&bo);
1680 vmw_surface_unreference(&surface);
1683 DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
1684 return ERR_PTR(ret);
1691 * vmw_kms_check_display_memory - Validates display memory required for a
1694 * @num_rects: number of drm_rect in rects
1695 * @rects: array of drm_rect representing the topology to validate indexed by
1699 * 0 on success otherwise negative error code
1701 static int vmw_kms_check_display_memory(struct drm_device *dev,
1703 struct drm_rect *rects)
1705 struct vmw_private *dev_priv = vmw_priv(dev);
1706 struct drm_rect bounding_box = {0};
1707 u64 total_pixels = 0, pixel_mem, bb_mem;
1710 for (i = 0; i < num_rects; i++) {
1712 * For STDU only individual screen (screen target) is limited by
1713 * SCREENTARGET_MAX_WIDTH/HEIGHT registers.
1715 if (dev_priv->active_display_unit == vmw_du_screen_target &&
1716 (drm_rect_width(&rects[i]) > dev_priv->stdu_max_width ||
1717 drm_rect_height(&rects[i]) > dev_priv->stdu_max_height)) {
1718 VMW_DEBUG_KMS("Screen size not supported.\n");
1722 /* Bounding box upper left is at (0,0). */
1723 if (rects[i].x2 > bounding_box.x2)
1724 bounding_box.x2 = rects[i].x2;
1726 if (rects[i].y2 > bounding_box.y2)
1727 bounding_box.y2 = rects[i].y2;
1729 total_pixels += (u64) drm_rect_width(&rects[i]) *
1730 (u64) drm_rect_height(&rects[i]);
1733 /* Virtual svga device primary limits are always in 32-bpp. */
1734 pixel_mem = total_pixels * 4;
1737 * For HV10 and below prim_bb_mem is vram size. When
1738 * SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM is not present vram size is
1739 * limit on primary bounding box
1741 if (pixel_mem > dev_priv->max_primary_mem) {
1742 VMW_DEBUG_KMS("Combined output size too large.\n");
1746 /* SVGA_CAP_NO_BB_RESTRICTION is available for STDU only. */
1747 if (dev_priv->active_display_unit != vmw_du_screen_target ||
1748 !(dev_priv->capabilities & SVGA_CAP_NO_BB_RESTRICTION)) {
1749 bb_mem = (u64) bounding_box.x2 * bounding_box.y2 * 4;
1751 if (bb_mem > dev_priv->max_primary_mem) {
1752 VMW_DEBUG_KMS("Topology is beyond supported limits.\n");
1761 * vmw_crtc_state_and_lock - Return new or current crtc state with locked
1763 * @state: The atomic state pointer containing the new atomic state
1766 * This function returns the new crtc state if it's part of the state update.
1767 * Otherwise returns the current crtc state. It also makes sure that the
1768 * crtc mutex is locked.
1770 * Returns: A valid crtc state pointer or NULL. It may also return a
1771 * pointer error, in particular -EDEADLK if locking needs to be rerun.
1773 static struct drm_crtc_state *
1774 vmw_crtc_state_and_lock(struct drm_atomic_state *state, struct drm_crtc *crtc)
1776 struct drm_crtc_state *crtc_state;
1778 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1780 lockdep_assert_held(&crtc->mutex.mutex.base);
1782 int ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
1784 if (ret != 0 && ret != -EALREADY)
1785 return ERR_PTR(ret);
1787 crtc_state = crtc->state;
1794 * vmw_kms_check_implicit - Verify that all implicit display units scan out
1795 * from the same fb after the new state is committed.
1796 * @dev: The drm_device.
1797 * @state: The new state to be checked.
1801 * -EINVAL on invalid state,
1802 * -EDEADLK if modeset locking needs to be rerun.
1804 static int vmw_kms_check_implicit(struct drm_device *dev,
1805 struct drm_atomic_state *state)
1807 struct drm_framebuffer *implicit_fb = NULL;
1808 struct drm_crtc *crtc;
1809 struct drm_crtc_state *crtc_state;
1810 struct drm_plane_state *plane_state;
1812 drm_for_each_crtc(crtc, dev) {
1813 struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
1815 if (!du->is_implicit)
1818 crtc_state = vmw_crtc_state_and_lock(state, crtc);
1819 if (IS_ERR(crtc_state))
1820 return PTR_ERR(crtc_state);
1822 if (!crtc_state || !crtc_state->enable)
1826 * Can't move primary planes across crtcs, so this is OK.
1827 * It also means we don't need to take the plane mutex.
1829 plane_state = du->primary.state;
1830 if (plane_state->crtc != crtc)
1834 implicit_fb = plane_state->fb;
1835 else if (implicit_fb != plane_state->fb)
1843 * vmw_kms_check_topology - Validates topology in drm_atomic_state
1845 * @state: the driver state object
1848 * 0 on success otherwise negative error code
1850 static int vmw_kms_check_topology(struct drm_device *dev,
1851 struct drm_atomic_state *state)
1853 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
1854 struct drm_rect *rects;
1855 struct drm_crtc *crtc;
1859 rects = kcalloc(dev->mode_config.num_crtc, sizeof(struct drm_rect),
1864 drm_for_each_crtc(crtc, dev) {
1865 struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
1866 struct drm_crtc_state *crtc_state;
1868 i = drm_crtc_index(crtc);
1870 crtc_state = vmw_crtc_state_and_lock(state, crtc);
1871 if (IS_ERR(crtc_state)) {
1872 ret = PTR_ERR(crtc_state);
1879 if (crtc_state->enable) {
1880 rects[i].x1 = du->gui_x;
1881 rects[i].y1 = du->gui_y;
1882 rects[i].x2 = du->gui_x + crtc_state->mode.hdisplay;
1883 rects[i].y2 = du->gui_y + crtc_state->mode.vdisplay;
1892 /* Determine change to topology due to new atomic state */
1893 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
1894 new_crtc_state, i) {
1895 struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
1896 struct drm_connector *connector;
1897 struct drm_connector_state *conn_state;
1898 struct vmw_connector_state *vmw_conn_state;
1900 if (!du->pref_active && new_crtc_state->enable) {
1901 VMW_DEBUG_KMS("Enabling a disabled display unit\n");
1907 * For vmwgfx each crtc has only one connector attached and it
1908 * is not changed so don't really need to check the
1909 * crtc->connector_mask and iterate over it.
1911 connector = &du->connector;
1912 conn_state = drm_atomic_get_connector_state(state, connector);
1913 if (IS_ERR(conn_state)) {
1914 ret = PTR_ERR(conn_state);
1918 vmw_conn_state = vmw_connector_state_to_vcs(conn_state);
1919 vmw_conn_state->gui_x = du->gui_x;
1920 vmw_conn_state->gui_y = du->gui_y;
1923 ret = vmw_kms_check_display_memory(dev, dev->mode_config.num_crtc,
1932 * vmw_kms_atomic_check_modeset- validate state object for modeset changes
1935 * @state: the driver state object
1937 * This is a simple wrapper around drm_atomic_helper_check_modeset() for
1938 * us to assign a value to mode->crtc_clock so that
1939 * drm_calc_timestamping_constants() won't throw an error message
1942 * Zero for success or -errno
1945 vmw_kms_atomic_check_modeset(struct drm_device *dev,
1946 struct drm_atomic_state *state)
1948 struct drm_crtc *crtc;
1949 struct drm_crtc_state *crtc_state;
1950 bool need_modeset = false;
1953 ret = drm_atomic_helper_check(dev, state);
1957 ret = vmw_kms_check_implicit(dev, state);
1959 VMW_DEBUG_KMS("Invalid implicit state\n");
1963 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
1964 if (drm_atomic_crtc_needs_modeset(crtc_state))
1965 need_modeset = true;
1969 return vmw_kms_check_topology(dev, state);
1974 static const struct drm_mode_config_funcs vmw_kms_funcs = {
1975 .fb_create = vmw_kms_fb_create,
1976 .atomic_check = vmw_kms_atomic_check_modeset,
1977 .atomic_commit = drm_atomic_helper_commit,
1980 static int vmw_kms_generic_present(struct vmw_private *dev_priv,
1981 struct drm_file *file_priv,
1982 struct vmw_framebuffer *vfb,
1983 struct vmw_surface *surface,
1985 int32_t destX, int32_t destY,
1986 struct drm_vmw_rect *clips,
1989 return vmw_kms_sou_do_surface_dirty(dev_priv, vfb, NULL, clips,
1990 &surface->res, destX, destY,
1991 num_clips, 1, NULL, NULL);
1995 int vmw_kms_present(struct vmw_private *dev_priv,
1996 struct drm_file *file_priv,
1997 struct vmw_framebuffer *vfb,
1998 struct vmw_surface *surface,
2000 int32_t destX, int32_t destY,
2001 struct drm_vmw_rect *clips,
2006 switch (dev_priv->active_display_unit) {
2007 case vmw_du_screen_target:
2008 ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, clips,
2009 &surface->res, destX, destY,
2010 num_clips, 1, NULL, NULL);
2012 case vmw_du_screen_object:
2013 ret = vmw_kms_generic_present(dev_priv, file_priv, vfb, surface,
2014 sid, destX, destY, clips,
2019 "Present called with invalid display system.\n");
2026 vmw_cmd_flush(dev_priv, false);
2032 vmw_kms_create_hotplug_mode_update_property(struct vmw_private *dev_priv)
2034 if (dev_priv->hotplug_mode_update_property)
2037 dev_priv->hotplug_mode_update_property =
2038 drm_property_create_range(&dev_priv->drm,
2039 DRM_MODE_PROP_IMMUTABLE,
2040 "hotplug_mode_update", 0, 1);
2043 int vmw_kms_init(struct vmw_private *dev_priv)
2045 struct drm_device *dev = &dev_priv->drm;
2047 static const char *display_unit_names[] = {
2055 drm_mode_config_init(dev);
2056 dev->mode_config.funcs = &vmw_kms_funcs;
2057 dev->mode_config.min_width = 1;
2058 dev->mode_config.min_height = 1;
2059 dev->mode_config.max_width = dev_priv->texture_max_width;
2060 dev->mode_config.max_height = dev_priv->texture_max_height;
2061 dev->mode_config.preferred_depth = dev_priv->assume_16bpp ? 16 : 32;
2063 drm_mode_create_suggested_offset_properties(dev);
2064 vmw_kms_create_hotplug_mode_update_property(dev_priv);
2066 ret = vmw_kms_stdu_init_display(dev_priv);
2068 ret = vmw_kms_sou_init_display(dev_priv);
2069 if (ret) /* Fallback */
2070 ret = vmw_kms_ldu_init_display(dev_priv);
2072 BUILD_BUG_ON(ARRAY_SIZE(display_unit_names) != (vmw_du_max + 1));
2073 drm_info(&dev_priv->drm, "%s display unit initialized\n",
2074 display_unit_names[dev_priv->active_display_unit]);
2079 int vmw_kms_close(struct vmw_private *dev_priv)
2084 * Docs says we should take the lock before calling this function
2085 * but since it destroys encoders and our destructor calls
2086 * drm_encoder_cleanup which takes the lock we deadlock.
2088 drm_mode_config_cleanup(&dev_priv->drm);
2089 if (dev_priv->active_display_unit == vmw_du_legacy)
2090 ret = vmw_kms_ldu_close_display(dev_priv);
2095 int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
2096 struct drm_file *file_priv)
2098 struct drm_vmw_cursor_bypass_arg *arg = data;
2099 struct vmw_display_unit *du;
2100 struct drm_crtc *crtc;
2103 mutex_lock(&dev->mode_config.mutex);
2104 if (arg->flags & DRM_VMW_CURSOR_BYPASS_ALL) {
2106 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
2107 du = vmw_crtc_to_du(crtc);
2108 du->hotspot_x = arg->xhot;
2109 du->hotspot_y = arg->yhot;
2112 mutex_unlock(&dev->mode_config.mutex);
2116 crtc = drm_crtc_find(dev, file_priv, arg->crtc_id);
2122 du = vmw_crtc_to_du(crtc);
2124 du->hotspot_x = arg->xhot;
2125 du->hotspot_y = arg->yhot;
2128 mutex_unlock(&dev->mode_config.mutex);
2133 int vmw_kms_write_svga(struct vmw_private *vmw_priv,
2134 unsigned width, unsigned height, unsigned pitch,
2135 unsigned bpp, unsigned depth)
2137 if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
2138 vmw_write(vmw_priv, SVGA_REG_PITCHLOCK, pitch);
2139 else if (vmw_fifo_have_pitchlock(vmw_priv))
2140 vmw_fifo_mem_write(vmw_priv, SVGA_FIFO_PITCHLOCK, pitch);
2141 vmw_write(vmw_priv, SVGA_REG_WIDTH, width);
2142 vmw_write(vmw_priv, SVGA_REG_HEIGHT, height);
2143 if ((vmw_priv->capabilities & SVGA_CAP_8BIT_EMULATION) != 0)
2144 vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, bpp);
2146 if (vmw_read(vmw_priv, SVGA_REG_DEPTH) != depth) {
2147 DRM_ERROR("Invalid depth %u for %u bpp, host expects %u\n",
2148 depth, bpp, vmw_read(vmw_priv, SVGA_REG_DEPTH));
2155 bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
2159 return ((u64) pitch * (u64) height) < (u64)
2160 ((dev_priv->active_display_unit == vmw_du_screen_target) ?
2161 dev_priv->max_primary_mem : dev_priv->vram_size);
2165 * vmw_du_update_layout - Update the display unit with topology from resolution
2166 * plugin and generate DRM uevent
2167 * @dev_priv: device private
2168 * @num_rects: number of drm_rect in rects
2169 * @rects: toplogy to update
2171 static int vmw_du_update_layout(struct vmw_private *dev_priv,
2172 unsigned int num_rects, struct drm_rect *rects)
2174 struct drm_device *dev = &dev_priv->drm;
2175 struct vmw_display_unit *du;
2176 struct drm_connector *con;
2177 struct drm_connector_list_iter conn_iter;
2178 struct drm_modeset_acquire_ctx ctx;
2179 struct drm_crtc *crtc;
2182 /* Currently gui_x/y is protected with the crtc mutex */
2183 mutex_lock(&dev->mode_config.mutex);
2184 drm_modeset_acquire_init(&ctx, 0);
2186 drm_for_each_crtc(crtc, dev) {
2187 ret = drm_modeset_lock(&crtc->mutex, &ctx);
2189 if (ret == -EDEADLK) {
2190 drm_modeset_backoff(&ctx);
2197 drm_connector_list_iter_begin(dev, &conn_iter);
2198 drm_for_each_connector_iter(con, &conn_iter) {
2199 du = vmw_connector_to_du(con);
2200 if (num_rects > du->unit) {
2201 du->pref_width = drm_rect_width(&rects[du->unit]);
2202 du->pref_height = drm_rect_height(&rects[du->unit]);
2203 du->pref_active = true;
2204 du->gui_x = rects[du->unit].x1;
2205 du->gui_y = rects[du->unit].y1;
2207 du->pref_width = VMWGFX_MIN_INITIAL_WIDTH;
2208 du->pref_height = VMWGFX_MIN_INITIAL_HEIGHT;
2209 du->pref_active = false;
2214 drm_connector_list_iter_end(&conn_iter);
2216 list_for_each_entry(con, &dev->mode_config.connector_list, head) {
2217 du = vmw_connector_to_du(con);
2218 if (num_rects > du->unit) {
2219 drm_object_property_set_value
2220 (&con->base, dev->mode_config.suggested_x_property,
2222 drm_object_property_set_value
2223 (&con->base, dev->mode_config.suggested_y_property,
2226 drm_object_property_set_value
2227 (&con->base, dev->mode_config.suggested_x_property,
2229 drm_object_property_set_value
2230 (&con->base, dev->mode_config.suggested_y_property,
2233 con->status = vmw_du_connector_detect(con, true);
2236 drm_modeset_drop_locks(&ctx);
2237 drm_modeset_acquire_fini(&ctx);
2238 mutex_unlock(&dev->mode_config.mutex);
2240 drm_sysfs_hotplug_event(dev);
2245 int vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
2246 u16 *r, u16 *g, u16 *b,
2248 struct drm_modeset_acquire_ctx *ctx)
2250 struct vmw_private *dev_priv = vmw_priv(crtc->dev);
2253 for (i = 0; i < size; i++) {
2254 DRM_DEBUG("%d r/g/b = 0x%04x / 0x%04x / 0x%04x\n", i,
2256 vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 0, r[i] >> 8);
2257 vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 1, g[i] >> 8);
2258 vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 2, b[i] >> 8);
2264 int vmw_du_connector_dpms(struct drm_connector *connector, int mode)
2269 enum drm_connector_status
2270 vmw_du_connector_detect(struct drm_connector *connector, bool force)
2272 uint32_t num_displays;
2273 struct drm_device *dev = connector->dev;
2274 struct vmw_private *dev_priv = vmw_priv(dev);
2275 struct vmw_display_unit *du = vmw_connector_to_du(connector);
2277 num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS);
2279 return ((vmw_connector_to_du(connector)->unit < num_displays &&
2281 connector_status_connected : connector_status_disconnected);
2285 * vmw_guess_mode_timing - Provide fake timings for a
2286 * 60Hz vrefresh mode.
2288 * @mode: Pointer to a struct drm_display_mode with hdisplay and vdisplay
2289 * members filled in.
2291 void vmw_guess_mode_timing(struct drm_display_mode *mode)
2293 mode->hsync_start = mode->hdisplay + 50;
2294 mode->hsync_end = mode->hsync_start + 50;
2295 mode->htotal = mode->hsync_end + 50;
2297 mode->vsync_start = mode->vdisplay + 50;
2298 mode->vsync_end = mode->vsync_start + 50;
2299 mode->vtotal = mode->vsync_end + 50;
2301 mode->clock = (u32)mode->htotal * (u32)mode->vtotal / 100 * 6;
2306 * vmw_kms_update_layout_ioctl - Handler for DRM_VMW_UPDATE_LAYOUT ioctl
2307 * @dev: drm device for the ioctl
2308 * @data: data pointer for the ioctl
2309 * @file_priv: drm file for the ioctl call
2311 * Update preferred topology of display unit as per ioctl request. The topology
2312 * is expressed as array of drm_vmw_rect.
2314 * [0 0 640 480] [640 0 800 600] [0 480 640 480]
2317 * The x and y offset (upper left) in drm_vmw_rect cannot be less than 0. Beside
2318 * device limit on topology, x + w and y + h (lower right) cannot be greater
2319 * than INT_MAX. So topology beyond these limits will return with error.
2322 * Zero on success, negative errno on failure.
2324 int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
2325 struct drm_file *file_priv)
2327 struct vmw_private *dev_priv = vmw_priv(dev);
2328 struct drm_mode_config *mode_config = &dev->mode_config;
2329 struct drm_vmw_update_layout_arg *arg =
2330 (struct drm_vmw_update_layout_arg *)data;
2331 void __user *user_rects;
2332 struct drm_vmw_rect *rects;
2333 struct drm_rect *drm_rects;
2334 unsigned rects_size;
2337 if (!arg->num_outputs) {
2338 struct drm_rect def_rect = {0, 0,
2339 VMWGFX_MIN_INITIAL_WIDTH,
2340 VMWGFX_MIN_INITIAL_HEIGHT};
2341 vmw_du_update_layout(dev_priv, 1, &def_rect);
2345 rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
2346 rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect),
2348 if (unlikely(!rects))
2351 user_rects = (void __user *)(unsigned long)arg->rects;
2352 ret = copy_from_user(rects, user_rects, rects_size);
2353 if (unlikely(ret != 0)) {
2354 DRM_ERROR("Failed to get rects.\n");
2359 drm_rects = (struct drm_rect *)rects;
2361 VMW_DEBUG_KMS("Layout count = %u\n", arg->num_outputs);
2362 for (i = 0; i < arg->num_outputs; i++) {
2363 struct drm_vmw_rect curr_rect;
2365 /* Verify user-space for overflow as kernel use drm_rect */
2366 if ((rects[i].x + rects[i].w > INT_MAX) ||
2367 (rects[i].y + rects[i].h > INT_MAX)) {
2372 curr_rect = rects[i];
2373 drm_rects[i].x1 = curr_rect.x;
2374 drm_rects[i].y1 = curr_rect.y;
2375 drm_rects[i].x2 = curr_rect.x + curr_rect.w;
2376 drm_rects[i].y2 = curr_rect.y + curr_rect.h;
2378 VMW_DEBUG_KMS(" x1 = %d y1 = %d x2 = %d y2 = %d\n",
2379 drm_rects[i].x1, drm_rects[i].y1,
2380 drm_rects[i].x2, drm_rects[i].y2);
2383 * Currently this check is limiting the topology within
2384 * mode_config->max (which actually is max texture size
2385 * supported by virtual device). This limit is here to address
2386 * window managers that create a big framebuffer for whole
2389 if (drm_rects[i].x1 < 0 || drm_rects[i].y1 < 0 ||
2390 drm_rects[i].x2 > mode_config->max_width ||
2391 drm_rects[i].y2 > mode_config->max_height) {
2392 VMW_DEBUG_KMS("Invalid layout %d %d %d %d\n",
2393 drm_rects[i].x1, drm_rects[i].y1,
2394 drm_rects[i].x2, drm_rects[i].y2);
2400 ret = vmw_kms_check_display_memory(dev, arg->num_outputs, drm_rects);
2403 vmw_du_update_layout(dev_priv, arg->num_outputs, drm_rects);
2411 * vmw_kms_helper_dirty - Helper to build commands and perform actions based
2412 * on a set of cliprects and a set of display units.
2414 * @dev_priv: Pointer to a device private structure.
2415 * @framebuffer: Pointer to the framebuffer on which to perform the actions.
2416 * @clips: A set of struct drm_clip_rect. Either this os @vclips must be NULL.
2417 * Cliprects are given in framebuffer coordinates.
2418 * @vclips: A set of struct drm_vmw_rect cliprects. Either this or @clips must
2419 * be NULL. Cliprects are given in source coordinates.
2420 * @dest_x: X coordinate offset for the crtc / destination clip rects.
2421 * @dest_y: Y coordinate offset for the crtc / destination clip rects.
2422 * @num_clips: Number of cliprects in the @clips or @vclips array.
2423 * @increment: Integer with which to increment the clip counter when looping.
2424 * Used to skip a predetermined number of clip rects.
2425 * @dirty: Closure structure. See the description of struct vmw_kms_dirty.
2427 int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
2428 struct vmw_framebuffer *framebuffer,
2429 const struct drm_clip_rect *clips,
2430 const struct drm_vmw_rect *vclips,
2431 s32 dest_x, s32 dest_y,
2434 struct vmw_kms_dirty *dirty)
2436 struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
2437 struct drm_crtc *crtc;
2441 dirty->dev_priv = dev_priv;
2443 /* If crtc is passed, no need to iterate over other display units */
2445 units[num_units++] = vmw_crtc_to_du(dirty->crtc);
2447 list_for_each_entry(crtc, &dev_priv->drm.mode_config.crtc_list,
2449 struct drm_plane *plane = crtc->primary;
2451 if (plane->state->fb == &framebuffer->base)
2452 units[num_units++] = vmw_crtc_to_du(crtc);
2456 for (k = 0; k < num_units; k++) {
2457 struct vmw_display_unit *unit = units[k];
2458 s32 crtc_x = unit->crtc.x;
2459 s32 crtc_y = unit->crtc.y;
2460 s32 crtc_width = unit->crtc.mode.hdisplay;
2461 s32 crtc_height = unit->crtc.mode.vdisplay;
2462 const struct drm_clip_rect *clips_ptr = clips;
2463 const struct drm_vmw_rect *vclips_ptr = vclips;
2466 if (dirty->fifo_reserve_size > 0) {
2467 dirty->cmd = VMW_CMD_RESERVE(dev_priv,
2468 dirty->fifo_reserve_size);
2472 memset(dirty->cmd, 0, dirty->fifo_reserve_size);
2474 dirty->num_hits = 0;
2475 for (i = 0; i < num_clips; i++, clips_ptr += increment,
2476 vclips_ptr += increment) {
2481 * Select clip array type. Note that integer type
2482 * in @clips is unsigned short, whereas in @vclips
2486 dirty->fb_x = (s32) clips_ptr->x1;
2487 dirty->fb_y = (s32) clips_ptr->y1;
2488 dirty->unit_x2 = (s32) clips_ptr->x2 + dest_x -
2490 dirty->unit_y2 = (s32) clips_ptr->y2 + dest_y -
2493 dirty->fb_x = vclips_ptr->x;
2494 dirty->fb_y = vclips_ptr->y;
2495 dirty->unit_x2 = dirty->fb_x + vclips_ptr->w +
2497 dirty->unit_y2 = dirty->fb_y + vclips_ptr->h +
2501 dirty->unit_x1 = dirty->fb_x + dest_x - crtc_x;
2502 dirty->unit_y1 = dirty->fb_y + dest_y - crtc_y;
2504 /* Skip this clip if it's outside the crtc region */
2505 if (dirty->unit_x1 >= crtc_width ||
2506 dirty->unit_y1 >= crtc_height ||
2507 dirty->unit_x2 <= 0 || dirty->unit_y2 <= 0)
2510 /* Clip right and bottom to crtc limits */
2511 dirty->unit_x2 = min_t(s32, dirty->unit_x2,
2513 dirty->unit_y2 = min_t(s32, dirty->unit_y2,
2516 /* Clip left and top to crtc limits */
2517 clip_left = min_t(s32, dirty->unit_x1, 0);
2518 clip_top = min_t(s32, dirty->unit_y1, 0);
2519 dirty->unit_x1 -= clip_left;
2520 dirty->unit_y1 -= clip_top;
2521 dirty->fb_x -= clip_left;
2522 dirty->fb_y -= clip_top;
2527 dirty->fifo_commit(dirty);
2534 * vmw_kms_helper_validation_finish - Helper for post KMS command submission
2535 * cleanup and fencing
2536 * @dev_priv: Pointer to the device-private struct
2537 * @file_priv: Pointer identifying the client when user-space fencing is used
2538 * @ctx: Pointer to the validation context
2539 * @out_fence: If non-NULL, returned refcounted fence-pointer
2540 * @user_fence_rep: If non-NULL, pointer to user-space address area
2541 * in which to copy user-space fence info
2543 void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv,
2544 struct drm_file *file_priv,
2545 struct vmw_validation_context *ctx,
2546 struct vmw_fence_obj **out_fence,
2547 struct drm_vmw_fence_rep __user *
2550 struct vmw_fence_obj *fence = NULL;
2551 uint32_t handle = 0;
2554 if (file_priv || user_fence_rep || vmw_validation_has_bos(ctx) ||
2556 ret = vmw_execbuf_fence_commands(file_priv, dev_priv, &fence,
2557 file_priv ? &handle : NULL);
2558 vmw_validation_done(ctx, fence);
2560 vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv),
2561 ret, user_fence_rep, fence,
2566 vmw_fence_obj_unreference(&fence);
2570 * vmw_kms_update_proxy - Helper function to update a proxy surface from
2573 * @res: Pointer to the surface resource
2574 * @clips: Clip rects in framebuffer (surface) space.
2575 * @num_clips: Number of clips in @clips.
2576 * @increment: Integer with which to increment the clip counter when looping.
2577 * Used to skip a predetermined number of clip rects.
2579 * This function makes sure the proxy surface is updated from its backing MOB
2580 * using the region given by @clips. The surface resource @res and its backing
2581 * MOB needs to be reserved and validated on call.
2583 int vmw_kms_update_proxy(struct vmw_resource *res,
2584 const struct drm_clip_rect *clips,
2588 struct vmw_private *dev_priv = res->dev_priv;
2589 struct drm_vmw_size *size = &vmw_res_to_srf(res)->metadata.base_size;
2591 SVGA3dCmdHeader header;
2592 SVGA3dCmdUpdateGBImage body;
2595 size_t copy_size = 0;
2601 cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd) * num_clips);
2605 for (i = 0; i < num_clips; ++i, clips += increment, ++cmd) {
2606 box = &cmd->body.box;
2608 cmd->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE;
2609 cmd->header.size = sizeof(cmd->body);
2610 cmd->body.image.sid = res->id;
2611 cmd->body.image.face = 0;
2612 cmd->body.image.mipmap = 0;
2614 if (clips->x1 > size->width || clips->x2 > size->width ||
2615 clips->y1 > size->height || clips->y2 > size->height) {
2616 DRM_ERROR("Invalid clips outsize of framebuffer.\n");
2623 box->w = clips->x2 - clips->x1;
2624 box->h = clips->y2 - clips->y1;
2627 copy_size += sizeof(*cmd);
2630 vmw_cmd_commit(dev_priv, copy_size);
2636 * vmw_kms_create_implicit_placement_property - Set up the implicit placement
2639 * @dev_priv: Pointer to a device private struct.
2641 * Sets up the implicit placement property unless it's already set up.
2644 vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv)
2646 if (dev_priv->implicit_placement_property)
2649 dev_priv->implicit_placement_property =
2650 drm_property_create_range(&dev_priv->drm,
2651 DRM_MODE_PROP_IMMUTABLE,
2652 "implicit_placement", 0, 1);
2656 * vmw_kms_suspend - Save modesetting state and turn modesetting off.
2658 * @dev: Pointer to the drm device
2659 * Return: 0 on success. Negative error code on failure.
2661 int vmw_kms_suspend(struct drm_device *dev)
2663 struct vmw_private *dev_priv = vmw_priv(dev);
2665 dev_priv->suspend_state = drm_atomic_helper_suspend(dev);
2666 if (IS_ERR(dev_priv->suspend_state)) {
2667 int ret = PTR_ERR(dev_priv->suspend_state);
2669 DRM_ERROR("Failed kms suspend: %d\n", ret);
2670 dev_priv->suspend_state = NULL;
2680 * vmw_kms_resume - Re-enable modesetting and restore state
2682 * @dev: Pointer to the drm device
2683 * Return: 0 on success. Negative error code on failure.
2685 * State is resumed from a previous vmw_kms_suspend(). It's illegal
2686 * to call this function without a previous vmw_kms_suspend().
2688 int vmw_kms_resume(struct drm_device *dev)
2690 struct vmw_private *dev_priv = vmw_priv(dev);
2693 if (WARN_ON(!dev_priv->suspend_state))
2696 ret = drm_atomic_helper_resume(dev, dev_priv->suspend_state);
2697 dev_priv->suspend_state = NULL;
2703 * vmw_kms_lost_device - Notify kms that modesetting capabilities will be lost
2705 * @dev: Pointer to the drm device
2707 void vmw_kms_lost_device(struct drm_device *dev)
2709 drm_atomic_helper_shutdown(dev);
2713 * vmw_du_helper_plane_update - Helper to do plane update on a display unit.
2714 * @update: The closure structure.
2716 * Call this helper after setting callbacks in &vmw_du_update_plane to do plane
2717 * update on display unit.
2719 * Return: 0 on success or a negative error code on failure.
2721 int vmw_du_helper_plane_update(struct vmw_du_update_plane *update)
2723 struct drm_plane_state *state = update->plane->state;
2724 struct drm_plane_state *old_state = update->old_state;
2725 struct drm_atomic_helper_damage_iter iter;
2726 struct drm_rect clip;
2728 DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
2729 uint32_t reserved_size = 0;
2730 uint32_t submit_size = 0;
2731 uint32_t curr_size = 0;
2732 uint32_t num_hits = 0;
2738 * Iterate in advance to check if really need plane update and find the
2739 * number of clips that actually are in plane src for fifo allocation.
2741 drm_atomic_helper_damage_iter_init(&iter, old_state, state);
2742 drm_atomic_for_each_plane_damage(&iter, &clip)
2748 if (update->vfb->bo) {
2749 struct vmw_framebuffer_bo *vfbbo =
2750 container_of(update->vfb, typeof(*vfbbo), base);
2753 * For screen targets we want a mappable bo, for everything else we want
2754 * accelerated i.e. host backed (vram or gmr) bo. If the display unit
2755 * is not screen target then mob's shouldn't be available.
2757 if (update->dev_priv->active_display_unit == vmw_du_screen_target) {
2758 vmw_bo_placement_set(vfbbo->buffer,
2759 VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_GMR,
2760 VMW_BO_DOMAIN_SYS | VMW_BO_DOMAIN_MOB | VMW_BO_DOMAIN_GMR);
2762 WARN_ON(update->dev_priv->has_mob);
2763 vmw_bo_placement_set_default_accelerated(vfbbo->buffer);
2765 ret = vmw_validation_add_bo(&val_ctx, vfbbo->buffer);
2767 struct vmw_framebuffer_surface *vfbs =
2768 container_of(update->vfb, typeof(*vfbs), base);
2770 ret = vmw_validation_add_resource(&val_ctx, &vfbs->surface->res,
2771 0, VMW_RES_DIRTY_NONE, NULL,
2778 ret = vmw_validation_prepare(&val_ctx, update->mutex, update->intr);
2782 reserved_size = update->calc_fifo_size(update, num_hits);
2783 cmd_start = VMW_CMD_RESERVE(update->dev_priv, reserved_size);
2789 cmd_next = cmd_start;
2791 if (update->post_prepare) {
2792 curr_size = update->post_prepare(update, cmd_next);
2793 cmd_next += curr_size;
2794 submit_size += curr_size;
2797 if (update->pre_clip) {
2798 curr_size = update->pre_clip(update, cmd_next, num_hits);
2799 cmd_next += curr_size;
2800 submit_size += curr_size;
2808 drm_atomic_helper_damage_iter_init(&iter, old_state, state);
2809 drm_atomic_for_each_plane_damage(&iter, &clip) {
2810 uint32_t fb_x = clip.x1;
2811 uint32_t fb_y = clip.y1;
2813 vmw_du_translate_to_crtc(state, &clip);
2815 curr_size = update->clip(update, cmd_next, &clip, fb_x,
2817 cmd_next += curr_size;
2818 submit_size += curr_size;
2820 bb.x1 = min_t(int, bb.x1, clip.x1);
2821 bb.y1 = min_t(int, bb.y1, clip.y1);
2822 bb.x2 = max_t(int, bb.x2, clip.x2);
2823 bb.y2 = max_t(int, bb.y2, clip.y2);
2826 curr_size = update->post_clip(update, cmd_next, &bb);
2827 submit_size += curr_size;
2829 if (reserved_size < submit_size)
2832 vmw_cmd_commit(update->dev_priv, submit_size);
2834 vmw_kms_helper_validation_finish(update->dev_priv, NULL, &val_ctx,
2835 update->out_fence, NULL);
2839 vmw_validation_revert(&val_ctx);
2842 vmw_validation_unref_lists(&val_ctx);
2847 * vmw_connector_mode_valid - implements drm_connector_helper_funcs.mode_valid callback
2849 * @connector: the drm connector, part of a DU container
2850 * @mode: drm mode to check
2852 * Returns MODE_OK on success, or a drm_mode_status error code.
2854 enum drm_mode_status vmw_connector_mode_valid(struct drm_connector *connector,
2855 struct drm_display_mode *mode)
2857 struct drm_device *dev = connector->dev;
2858 struct vmw_private *dev_priv = vmw_priv(dev);
2859 u32 max_width = dev_priv->texture_max_width;
2860 u32 max_height = dev_priv->texture_max_height;
2861 u32 assumed_cpp = 4;
2863 if (dev_priv->assume_16bpp)
2866 if (dev_priv->active_display_unit == vmw_du_screen_target) {
2867 max_width = min(dev_priv->stdu_max_width, max_width);
2868 max_height = min(dev_priv->stdu_max_height, max_height);
2871 if (max_width < mode->hdisplay)
2872 return MODE_BAD_HVALUE;
2874 if (max_height < mode->vdisplay)
2875 return MODE_BAD_VVALUE;
2877 if (!vmw_kms_validate_mode_vram(dev_priv,
2878 mode->hdisplay * assumed_cpp,
2886 * vmw_connector_get_modes - implements drm_connector_helper_funcs.get_modes callback
2888 * @connector: the drm connector, part of a DU container
2890 * Returns the number of added modes.
2892 int vmw_connector_get_modes(struct drm_connector *connector)
2894 struct vmw_display_unit *du = vmw_connector_to_du(connector);
2895 struct drm_device *dev = connector->dev;
2896 struct vmw_private *dev_priv = vmw_priv(dev);
2897 struct drm_display_mode *mode = NULL;
2898 struct drm_display_mode prefmode = { DRM_MODE("preferred",
2899 DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
2900 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2901 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
2907 /* Add preferred mode */
2908 mode = drm_mode_duplicate(dev, &prefmode);
2912 mode->hdisplay = du->pref_width;
2913 mode->vdisplay = du->pref_height;
2914 vmw_guess_mode_timing(mode);
2915 drm_mode_set_name(mode);
2917 drm_mode_probed_add(connector, mode);
2918 drm_dbg_kms(dev, "preferred mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
2920 /* Probe connector for all modes not exceeding our geom limits */
2921 max_width = dev_priv->texture_max_width;
2922 max_height = dev_priv->texture_max_height;
2924 if (dev_priv->active_display_unit == vmw_du_screen_target) {
2925 max_width = min(dev_priv->stdu_max_width, max_width);
2926 max_height = min(dev_priv->stdu_max_height, max_height);
2929 num_modes = 1 + drm_add_modes_noedid(connector, max_width, max_height);