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