diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_drv.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 276 |
1 files changed, 231 insertions, 45 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 96949b93d920..13afddc1f034 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -82,16 +82,27 @@ | |||
82 | #define DRM_IOCTL_VMW_EXECBUF \ | 82 | #define DRM_IOCTL_VMW_EXECBUF \ |
83 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_EXECBUF, \ | 83 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_EXECBUF, \ |
84 | struct drm_vmw_execbuf_arg) | 84 | struct drm_vmw_execbuf_arg) |
85 | #define DRM_IOCTL_VMW_FIFO_DEBUG \ | 85 | #define DRM_IOCTL_VMW_GET_3D_CAP \ |
86 | DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FIFO_DEBUG, \ | 86 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_GET_3D_CAP, \ |
87 | struct drm_vmw_fifo_debug_arg) | 87 | struct drm_vmw_get_3d_cap_arg) |
88 | #define DRM_IOCTL_VMW_FENCE_WAIT \ | 88 | #define DRM_IOCTL_VMW_FENCE_WAIT \ |
89 | DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_WAIT, \ | 89 | DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_WAIT, \ |
90 | struct drm_vmw_fence_wait_arg) | 90 | struct drm_vmw_fence_wait_arg) |
91 | #define DRM_IOCTL_VMW_UPDATE_LAYOUT \ | 91 | #define DRM_IOCTL_VMW_FENCE_SIGNALED \ |
92 | DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT, \ | 92 | DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_SIGNALED, \ |
93 | struct drm_vmw_update_layout_arg) | 93 | struct drm_vmw_fence_signaled_arg) |
94 | 94 | #define DRM_IOCTL_VMW_FENCE_UNREF \ | |
95 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_FENCE_UNREF, \ | ||
96 | struct drm_vmw_fence_arg) | ||
97 | #define DRM_IOCTL_VMW_FENCE_EVENT \ | ||
98 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_FENCE_EVENT, \ | ||
99 | struct drm_vmw_fence_event_arg) | ||
100 | #define DRM_IOCTL_VMW_PRESENT \ | ||
101 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT, \ | ||
102 | struct drm_vmw_present_arg) | ||
103 | #define DRM_IOCTL_VMW_PRESENT_READBACK \ | ||
104 | DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT_READBACK, \ | ||
105 | struct drm_vmw_present_readback_arg) | ||
95 | 106 | ||
96 | /** | 107 | /** |
97 | * The core DRM version of this macro doesn't account for | 108 | * The core DRM version of this macro doesn't account for |
@@ -135,12 +146,25 @@ static struct drm_ioctl_desc vmw_ioctls[] = { | |||
135 | DRM_AUTH | DRM_UNLOCKED), | 146 | DRM_AUTH | DRM_UNLOCKED), |
136 | VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl, | 147 | VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl, |
137 | DRM_AUTH | DRM_UNLOCKED), | 148 | DRM_AUTH | DRM_UNLOCKED), |
138 | VMW_IOCTL_DEF(VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, | 149 | VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_obj_wait_ioctl, |
139 | DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), | 150 | DRM_AUTH | DRM_UNLOCKED), |
140 | VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_wait_ioctl, | 151 | VMW_IOCTL_DEF(VMW_FENCE_SIGNALED, |
152 | vmw_fence_obj_signaled_ioctl, | ||
153 | DRM_AUTH | DRM_UNLOCKED), | ||
154 | VMW_IOCTL_DEF(VMW_FENCE_UNREF, vmw_fence_obj_unref_ioctl, | ||
155 | DRM_AUTH | DRM_UNLOCKED), | ||
156 | VMW_IOCTL_DEF(VMW_FENCE_EVENT, | ||
157 | vmw_fence_event_ioctl, | ||
158 | DRM_AUTH | DRM_UNLOCKED), | ||
159 | VMW_IOCTL_DEF(VMW_GET_3D_CAP, vmw_get_cap_3d_ioctl, | ||
141 | DRM_AUTH | DRM_UNLOCKED), | 160 | DRM_AUTH | DRM_UNLOCKED), |
142 | VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, | 161 | |
143 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED) | 162 | /* these allow direct access to the framebuffers mark as master only */ |
163 | VMW_IOCTL_DEF(VMW_PRESENT, vmw_present_ioctl, | ||
164 | DRM_MASTER | DRM_AUTH | DRM_UNLOCKED), | ||
165 | VMW_IOCTL_DEF(VMW_PRESENT_READBACK, | ||
166 | vmw_present_readback_ioctl, | ||
167 | DRM_MASTER | DRM_AUTH | DRM_UNLOCKED), | ||
144 | }; | 168 | }; |
145 | 169 | ||
146 | static struct pci_device_id vmw_pci_id_list[] = { | 170 | static struct pci_device_id vmw_pci_id_list[] = { |
@@ -189,8 +213,78 @@ static void vmw_print_capabilities(uint32_t capabilities) | |||
189 | DRM_INFO(" GMR.\n"); | 213 | DRM_INFO(" GMR.\n"); |
190 | if (capabilities & SVGA_CAP_TRACES) | 214 | if (capabilities & SVGA_CAP_TRACES) |
191 | DRM_INFO(" Traces.\n"); | 215 | DRM_INFO(" Traces.\n"); |
216 | if (capabilities & SVGA_CAP_GMR2) | ||
217 | DRM_INFO(" GMR2.\n"); | ||
218 | if (capabilities & SVGA_CAP_SCREEN_OBJECT_2) | ||
219 | DRM_INFO(" Screen Object 2.\n"); | ||
220 | } | ||
221 | |||
222 | |||
223 | /** | ||
224 | * vmw_execbuf_prepare_dummy_query - Initialize a query result structure at | ||
225 | * the start of a buffer object. | ||
226 | * | ||
227 | * @dev_priv: The device private structure. | ||
228 | * | ||
229 | * This function will idle the buffer using an uninterruptible wait, then | ||
230 | * map the first page and initialize a pending occlusion query result structure, | ||
231 | * Finally it will unmap the buffer. | ||
232 | * | ||
233 | * TODO: Since we're only mapping a single page, we should optimize the map | ||
234 | * to use kmap_atomic / iomap_atomic. | ||
235 | */ | ||
236 | static void vmw_dummy_query_bo_prepare(struct vmw_private *dev_priv) | ||
237 | { | ||
238 | struct ttm_bo_kmap_obj map; | ||
239 | volatile SVGA3dQueryResult *result; | ||
240 | bool dummy; | ||
241 | int ret; | ||
242 | struct ttm_bo_device *bdev = &dev_priv->bdev; | ||
243 | struct ttm_buffer_object *bo = dev_priv->dummy_query_bo; | ||
244 | |||
245 | ttm_bo_reserve(bo, false, false, false, 0); | ||
246 | spin_lock(&bdev->fence_lock); | ||
247 | ret = ttm_bo_wait(bo, false, false, false); | ||
248 | spin_unlock(&bdev->fence_lock); | ||
249 | if (unlikely(ret != 0)) | ||
250 | (void) vmw_fallback_wait(dev_priv, false, true, 0, false, | ||
251 | 10*HZ); | ||
252 | |||
253 | ret = ttm_bo_kmap(bo, 0, 1, &map); | ||
254 | if (likely(ret == 0)) { | ||
255 | result = ttm_kmap_obj_virtual(&map, &dummy); | ||
256 | result->totalSize = sizeof(*result); | ||
257 | result->state = SVGA3D_QUERYSTATE_PENDING; | ||
258 | result->result32 = 0xff; | ||
259 | ttm_bo_kunmap(&map); | ||
260 | } else | ||
261 | DRM_ERROR("Dummy query buffer map failed.\n"); | ||
262 | ttm_bo_unreserve(bo); | ||
263 | } | ||
264 | |||
265 | |||
266 | /** | ||
267 | * vmw_dummy_query_bo_create - create a bo to hold a dummy query result | ||
268 | * | ||
269 | * @dev_priv: A device private structure. | ||
270 | * | ||
271 | * This function creates a small buffer object that holds the query | ||
272 | * result for dummy queries emitted as query barriers. | ||
273 | * No interruptible waits are done within this function. | ||
274 | * | ||
275 | * Returns an error if bo creation fails. | ||
276 | */ | ||
277 | static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) | ||
278 | { | ||
279 | return ttm_bo_create(&dev_priv->bdev, | ||
280 | PAGE_SIZE, | ||
281 | ttm_bo_type_device, | ||
282 | &vmw_vram_sys_placement, | ||
283 | 0, 0, false, NULL, | ||
284 | &dev_priv->dummy_query_bo); | ||
192 | } | 285 | } |
193 | 286 | ||
287 | |||
194 | static int vmw_request_device(struct vmw_private *dev_priv) | 288 | static int vmw_request_device(struct vmw_private *dev_priv) |
195 | { | 289 | { |
196 | int ret; | 290 | int ret; |
@@ -200,16 +294,42 @@ static int vmw_request_device(struct vmw_private *dev_priv) | |||
200 | DRM_ERROR("Unable to initialize FIFO.\n"); | 294 | DRM_ERROR("Unable to initialize FIFO.\n"); |
201 | return ret; | 295 | return ret; |
202 | } | 296 | } |
297 | vmw_fence_fifo_up(dev_priv->fman); | ||
298 | ret = vmw_dummy_query_bo_create(dev_priv); | ||
299 | if (unlikely(ret != 0)) | ||
300 | goto out_no_query_bo; | ||
301 | vmw_dummy_query_bo_prepare(dev_priv); | ||
203 | 302 | ||
204 | return 0; | 303 | return 0; |
304 | |||
305 | out_no_query_bo: | ||
306 | vmw_fence_fifo_down(dev_priv->fman); | ||
307 | vmw_fifo_release(dev_priv, &dev_priv->fifo); | ||
308 | return ret; | ||
205 | } | 309 | } |
206 | 310 | ||
207 | static void vmw_release_device(struct vmw_private *dev_priv) | 311 | static void vmw_release_device(struct vmw_private *dev_priv) |
208 | { | 312 | { |
313 | /* | ||
314 | * Previous destructions should've released | ||
315 | * the pinned bo. | ||
316 | */ | ||
317 | |||
318 | BUG_ON(dev_priv->pinned_bo != NULL); | ||
319 | |||
320 | ttm_bo_unref(&dev_priv->dummy_query_bo); | ||
321 | vmw_fence_fifo_down(dev_priv->fman); | ||
209 | vmw_fifo_release(dev_priv, &dev_priv->fifo); | 322 | vmw_fifo_release(dev_priv, &dev_priv->fifo); |
210 | } | 323 | } |
211 | 324 | ||
212 | int vmw_3d_resource_inc(struct vmw_private *dev_priv) | 325 | /** |
326 | * Increase the 3d resource refcount. | ||
327 | * If the count was prevously zero, initialize the fifo, switching to svga | ||
328 | * mode. Note that the master holds a ref as well, and may request an | ||
329 | * explicit switch to svga mode if fb is not running, using @unhide_svga. | ||
330 | */ | ||
331 | int vmw_3d_resource_inc(struct vmw_private *dev_priv, | ||
332 | bool unhide_svga) | ||
213 | { | 333 | { |
214 | int ret = 0; | 334 | int ret = 0; |
215 | 335 | ||
@@ -218,19 +338,42 @@ int vmw_3d_resource_inc(struct vmw_private *dev_priv) | |||
218 | ret = vmw_request_device(dev_priv); | 338 | ret = vmw_request_device(dev_priv); |
219 | if (unlikely(ret != 0)) | 339 | if (unlikely(ret != 0)) |
220 | --dev_priv->num_3d_resources; | 340 | --dev_priv->num_3d_resources; |
341 | } else if (unhide_svga) { | ||
342 | mutex_lock(&dev_priv->hw_mutex); | ||
343 | vmw_write(dev_priv, SVGA_REG_ENABLE, | ||
344 | vmw_read(dev_priv, SVGA_REG_ENABLE) & | ||
345 | ~SVGA_REG_ENABLE_HIDE); | ||
346 | mutex_unlock(&dev_priv->hw_mutex); | ||
221 | } | 347 | } |
348 | |||
222 | mutex_unlock(&dev_priv->release_mutex); | 349 | mutex_unlock(&dev_priv->release_mutex); |
223 | return ret; | 350 | return ret; |
224 | } | 351 | } |
225 | 352 | ||
226 | 353 | /** | |
227 | void vmw_3d_resource_dec(struct vmw_private *dev_priv) | 354 | * Decrease the 3d resource refcount. |
355 | * If the count reaches zero, disable the fifo, switching to vga mode. | ||
356 | * Note that the master holds a refcount as well, and may request an | ||
357 | * explicit switch to vga mode when it releases its refcount to account | ||
358 | * for the situation of an X server vt switch to VGA with 3d resources | ||
359 | * active. | ||
360 | */ | ||
361 | void vmw_3d_resource_dec(struct vmw_private *dev_priv, | ||
362 | bool hide_svga) | ||
228 | { | 363 | { |
229 | int32_t n3d; | 364 | int32_t n3d; |
230 | 365 | ||
231 | mutex_lock(&dev_priv->release_mutex); | 366 | mutex_lock(&dev_priv->release_mutex); |
232 | if (unlikely(--dev_priv->num_3d_resources == 0)) | 367 | if (unlikely(--dev_priv->num_3d_resources == 0)) |
233 | vmw_release_device(dev_priv); | 368 | vmw_release_device(dev_priv); |
369 | else if (hide_svga) { | ||
370 | mutex_lock(&dev_priv->hw_mutex); | ||
371 | vmw_write(dev_priv, SVGA_REG_ENABLE, | ||
372 | vmw_read(dev_priv, SVGA_REG_ENABLE) | | ||
373 | SVGA_REG_ENABLE_HIDE); | ||
374 | mutex_unlock(&dev_priv->hw_mutex); | ||
375 | } | ||
376 | |||
234 | n3d = (int32_t) dev_priv->num_3d_resources; | 377 | n3d = (int32_t) dev_priv->num_3d_resources; |
235 | mutex_unlock(&dev_priv->release_mutex); | 378 | mutex_unlock(&dev_priv->release_mutex); |
236 | 379 | ||
@@ -252,7 +395,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
252 | 395 | ||
253 | dev_priv->dev = dev; | 396 | dev_priv->dev = dev; |
254 | dev_priv->vmw_chipset = chipset; | 397 | dev_priv->vmw_chipset = chipset; |
255 | dev_priv->last_read_sequence = (uint32_t) -100; | 398 | dev_priv->last_read_seqno = (uint32_t) -100; |
256 | mutex_init(&dev_priv->hw_mutex); | 399 | mutex_init(&dev_priv->hw_mutex); |
257 | mutex_init(&dev_priv->cmdbuf_mutex); | 400 | mutex_init(&dev_priv->cmdbuf_mutex); |
258 | mutex_init(&dev_priv->release_mutex); | 401 | mutex_init(&dev_priv->release_mutex); |
@@ -263,8 +406,10 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
263 | mutex_init(&dev_priv->init_mutex); | 406 | mutex_init(&dev_priv->init_mutex); |
264 | init_waitqueue_head(&dev_priv->fence_queue); | 407 | init_waitqueue_head(&dev_priv->fence_queue); |
265 | init_waitqueue_head(&dev_priv->fifo_queue); | 408 | init_waitqueue_head(&dev_priv->fifo_queue); |
266 | atomic_set(&dev_priv->fence_queue_waiters, 0); | 409 | dev_priv->fence_queue_waiters = 0; |
267 | atomic_set(&dev_priv->fifo_queue_waiters, 0); | 410 | atomic_set(&dev_priv->fifo_queue_waiters, 0); |
411 | INIT_LIST_HEAD(&dev_priv->surface_lru); | ||
412 | dev_priv->used_memory_size = 0; | ||
268 | 413 | ||
269 | dev_priv->io_start = pci_resource_start(dev->pdev, 0); | 414 | dev_priv->io_start = pci_resource_start(dev->pdev, 0); |
270 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); | 415 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); |
@@ -285,6 +430,10 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
285 | 430 | ||
286 | dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES); | 431 | dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES); |
287 | 432 | ||
433 | dev_priv->vram_size = vmw_read(dev_priv, SVGA_REG_VRAM_SIZE); | ||
434 | dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE); | ||
435 | dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH); | ||
436 | dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT); | ||
288 | if (dev_priv->capabilities & SVGA_CAP_GMR) { | 437 | if (dev_priv->capabilities & SVGA_CAP_GMR) { |
289 | dev_priv->max_gmr_descriptors = | 438 | dev_priv->max_gmr_descriptors = |
290 | vmw_read(dev_priv, | 439 | vmw_read(dev_priv, |
@@ -292,11 +441,19 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
292 | dev_priv->max_gmr_ids = | 441 | dev_priv->max_gmr_ids = |
293 | vmw_read(dev_priv, SVGA_REG_GMR_MAX_IDS); | 442 | vmw_read(dev_priv, SVGA_REG_GMR_MAX_IDS); |
294 | } | 443 | } |
295 | 444 | if (dev_priv->capabilities & SVGA_CAP_GMR2) { | |
296 | dev_priv->vram_size = vmw_read(dev_priv, SVGA_REG_VRAM_SIZE); | 445 | dev_priv->max_gmr_pages = |
297 | dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE); | 446 | vmw_read(dev_priv, SVGA_REG_GMRS_MAX_PAGES); |
298 | dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH); | 447 | dev_priv->memory_size = |
299 | dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT); | 448 | vmw_read(dev_priv, SVGA_REG_MEMORY_SIZE); |
449 | dev_priv->memory_size -= dev_priv->vram_size; | ||
450 | } else { | ||
451 | /* | ||
452 | * An arbitrary limit of 512MiB on surface | ||
453 | * memory. But all HWV8 hardware supports GMR2. | ||
454 | */ | ||
455 | dev_priv->memory_size = 512*1024*1024; | ||
456 | } | ||
300 | 457 | ||
301 | mutex_unlock(&dev_priv->hw_mutex); | 458 | mutex_unlock(&dev_priv->hw_mutex); |
302 | 459 | ||
@@ -308,6 +465,12 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
308 | DRM_INFO("Max GMR descriptors is %u\n", | 465 | DRM_INFO("Max GMR descriptors is %u\n", |
309 | (unsigned)dev_priv->max_gmr_descriptors); | 466 | (unsigned)dev_priv->max_gmr_descriptors); |
310 | } | 467 | } |
468 | if (dev_priv->capabilities & SVGA_CAP_GMR2) { | ||
469 | DRM_INFO("Max number of GMR pages is %u\n", | ||
470 | (unsigned)dev_priv->max_gmr_pages); | ||
471 | DRM_INFO("Max dedicated hypervisor surface memory is %u kiB\n", | ||
472 | (unsigned)dev_priv->memory_size / 1024); | ||
473 | } | ||
311 | DRM_INFO("VRAM at 0x%08x size is %u kiB\n", | 474 | DRM_INFO("VRAM at 0x%08x size is %u kiB\n", |
312 | dev_priv->vram_start, dev_priv->vram_size / 1024); | 475 | dev_priv->vram_start, dev_priv->vram_size / 1024); |
313 | DRM_INFO("MMIO at 0x%08x size is %u kiB\n", | 476 | DRM_INFO("MMIO at 0x%08x size is %u kiB\n", |
@@ -394,22 +557,34 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
394 | goto out_no_device; | 557 | goto out_no_device; |
395 | } | 558 | } |
396 | } | 559 | } |
560 | |||
561 | dev_priv->fman = vmw_fence_manager_init(dev_priv); | ||
562 | if (unlikely(dev_priv->fman == NULL)) | ||
563 | goto out_no_fman; | ||
564 | |||
565 | /* Need to start the fifo to check if we can do screen objects */ | ||
566 | ret = vmw_3d_resource_inc(dev_priv, true); | ||
567 | if (unlikely(ret != 0)) | ||
568 | goto out_no_fifo; | ||
569 | vmw_kms_save_vga(dev_priv); | ||
570 | |||
571 | /* Start kms and overlay systems, needs fifo. */ | ||
397 | ret = vmw_kms_init(dev_priv); | 572 | ret = vmw_kms_init(dev_priv); |
398 | if (unlikely(ret != 0)) | 573 | if (unlikely(ret != 0)) |
399 | goto out_no_kms; | 574 | goto out_no_kms; |
400 | vmw_overlay_init(dev_priv); | 575 | vmw_overlay_init(dev_priv); |
576 | |||
577 | /* 3D Depends on Screen Objects being used. */ | ||
578 | DRM_INFO("Detected %sdevice 3D availability.\n", | ||
579 | vmw_fifo_have_3d(dev_priv) ? | ||
580 | "" : "no "); | ||
581 | |||
582 | /* We might be done with the fifo now */ | ||
401 | if (dev_priv->enable_fb) { | 583 | if (dev_priv->enable_fb) { |
402 | ret = vmw_3d_resource_inc(dev_priv); | ||
403 | if (unlikely(ret != 0)) | ||
404 | goto out_no_fifo; | ||
405 | vmw_kms_save_vga(dev_priv); | ||
406 | vmw_fb_init(dev_priv); | 584 | vmw_fb_init(dev_priv); |
407 | DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? | ||
408 | "Detected device 3D availability.\n" : | ||
409 | "Detected no device 3D availability.\n"); | ||
410 | } else { | 585 | } else { |
411 | DRM_INFO("Delayed 3D detection since we're not " | 586 | vmw_kms_restore_vga(dev_priv); |
412 | "running the device in SVGA mode yet.\n"); | 587 | vmw_3d_resource_dec(dev_priv, true); |
413 | } | 588 | } |
414 | 589 | ||
415 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | 590 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { |
@@ -426,15 +601,19 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
426 | return 0; | 601 | return 0; |
427 | 602 | ||
428 | out_no_irq: | 603 | out_no_irq: |
429 | if (dev_priv->enable_fb) { | 604 | if (dev_priv->enable_fb) |
430 | vmw_fb_close(dev_priv); | 605 | vmw_fb_close(dev_priv); |
431 | vmw_kms_restore_vga(dev_priv); | ||
432 | vmw_3d_resource_dec(dev_priv); | ||
433 | } | ||
434 | out_no_fifo: | ||
435 | vmw_overlay_close(dev_priv); | 606 | vmw_overlay_close(dev_priv); |
436 | vmw_kms_close(dev_priv); | 607 | vmw_kms_close(dev_priv); |
437 | out_no_kms: | 608 | out_no_kms: |
609 | /* We still have a 3D resource reference held */ | ||
610 | if (dev_priv->enable_fb) { | ||
611 | vmw_kms_restore_vga(dev_priv); | ||
612 | vmw_3d_resource_dec(dev_priv, false); | ||
613 | } | ||
614 | out_no_fifo: | ||
615 | vmw_fence_manager_takedown(dev_priv->fman); | ||
616 | out_no_fman: | ||
438 | if (dev_priv->stealth) | 617 | if (dev_priv->stealth) |
439 | pci_release_region(dev->pdev, 2); | 618 | pci_release_region(dev->pdev, 2); |
440 | else | 619 | else |
@@ -467,15 +646,18 @@ static int vmw_driver_unload(struct drm_device *dev) | |||
467 | 646 | ||
468 | unregister_pm_notifier(&dev_priv->pm_nb); | 647 | unregister_pm_notifier(&dev_priv->pm_nb); |
469 | 648 | ||
649 | if (dev_priv->ctx.cmd_bounce) | ||
650 | vfree(dev_priv->ctx.cmd_bounce); | ||
470 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | 651 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) |
471 | drm_irq_uninstall(dev_priv->dev); | 652 | drm_irq_uninstall(dev_priv->dev); |
472 | if (dev_priv->enable_fb) { | 653 | if (dev_priv->enable_fb) { |
473 | vmw_fb_close(dev_priv); | 654 | vmw_fb_close(dev_priv); |
474 | vmw_kms_restore_vga(dev_priv); | 655 | vmw_kms_restore_vga(dev_priv); |
475 | vmw_3d_resource_dec(dev_priv); | 656 | vmw_3d_resource_dec(dev_priv, false); |
476 | } | 657 | } |
477 | vmw_kms_close(dev_priv); | 658 | vmw_kms_close(dev_priv); |
478 | vmw_overlay_close(dev_priv); | 659 | vmw_overlay_close(dev_priv); |
660 | vmw_fence_manager_takedown(dev_priv->fman); | ||
479 | if (dev_priv->stealth) | 661 | if (dev_priv->stealth) |
480 | pci_release_region(dev->pdev, 2); | 662 | pci_release_region(dev->pdev, 2); |
481 | else | 663 | else |
@@ -646,7 +828,7 @@ static int vmw_master_set(struct drm_device *dev, | |||
646 | int ret = 0; | 828 | int ret = 0; |
647 | 829 | ||
648 | if (!dev_priv->enable_fb) { | 830 | if (!dev_priv->enable_fb) { |
649 | ret = vmw_3d_resource_inc(dev_priv); | 831 | ret = vmw_3d_resource_inc(dev_priv, true); |
650 | if (unlikely(ret != 0)) | 832 | if (unlikely(ret != 0)) |
651 | return ret; | 833 | return ret; |
652 | vmw_kms_save_vga(dev_priv); | 834 | vmw_kms_save_vga(dev_priv); |
@@ -688,7 +870,7 @@ out_no_active_lock: | |||
688 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | 870 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); |
689 | mutex_unlock(&dev_priv->hw_mutex); | 871 | mutex_unlock(&dev_priv->hw_mutex); |
690 | vmw_kms_restore_vga(dev_priv); | 872 | vmw_kms_restore_vga(dev_priv); |
691 | vmw_3d_resource_dec(dev_priv); | 873 | vmw_3d_resource_dec(dev_priv, true); |
692 | } | 874 | } |
693 | return ret; | 875 | return ret; |
694 | } | 876 | } |
@@ -709,7 +891,7 @@ static void vmw_master_drop(struct drm_device *dev, | |||
709 | 891 | ||
710 | vmw_fp->locked_master = drm_master_get(file_priv->master); | 892 | vmw_fp->locked_master = drm_master_get(file_priv->master); |
711 | ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile); | 893 | ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile); |
712 | vmw_kms_idle_workqueues(vmaster); | 894 | vmw_execbuf_release_pinned_bo(dev_priv, false, 0); |
713 | 895 | ||
714 | if (unlikely((ret != 0))) { | 896 | if (unlikely((ret != 0))) { |
715 | DRM_ERROR("Unable to lock TTM at VT switch.\n"); | 897 | DRM_ERROR("Unable to lock TTM at VT switch.\n"); |
@@ -726,7 +908,7 @@ static void vmw_master_drop(struct drm_device *dev, | |||
726 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | 908 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); |
727 | mutex_unlock(&dev_priv->hw_mutex); | 909 | mutex_unlock(&dev_priv->hw_mutex); |
728 | vmw_kms_restore_vga(dev_priv); | 910 | vmw_kms_restore_vga(dev_priv); |
729 | vmw_3d_resource_dec(dev_priv); | 911 | vmw_3d_resource_dec(dev_priv, true); |
730 | } | 912 | } |
731 | 913 | ||
732 | dev_priv->active_master = &dev_priv->fbdev_master; | 914 | dev_priv->active_master = &dev_priv->fbdev_master; |
@@ -761,6 +943,7 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, | |||
761 | * This empties VRAM and unbinds all GMR bindings. | 943 | * This empties VRAM and unbinds all GMR bindings. |
762 | * Buffer contents is moved to swappable memory. | 944 | * Buffer contents is moved to swappable memory. |
763 | */ | 945 | */ |
946 | vmw_execbuf_release_pinned_bo(dev_priv, false, 0); | ||
764 | ttm_bo_swapout_all(&dev_priv->bdev); | 947 | ttm_bo_swapout_all(&dev_priv->bdev); |
765 | 948 | ||
766 | break; | 949 | break; |
@@ -835,7 +1018,7 @@ static int vmw_pm_prepare(struct device *kdev) | |||
835 | */ | 1018 | */ |
836 | dev_priv->suspended = true; | 1019 | dev_priv->suspended = true; |
837 | if (dev_priv->enable_fb) | 1020 | if (dev_priv->enable_fb) |
838 | vmw_3d_resource_dec(dev_priv); | 1021 | vmw_3d_resource_dec(dev_priv, true); |
839 | 1022 | ||
840 | if (dev_priv->num_3d_resources != 0) { | 1023 | if (dev_priv->num_3d_resources != 0) { |
841 | 1024 | ||
@@ -843,7 +1026,7 @@ static int vmw_pm_prepare(struct device *kdev) | |||
843 | "while 3D resources are active.\n"); | 1026 | "while 3D resources are active.\n"); |
844 | 1027 | ||
845 | if (dev_priv->enable_fb) | 1028 | if (dev_priv->enable_fb) |
846 | vmw_3d_resource_inc(dev_priv); | 1029 | vmw_3d_resource_inc(dev_priv, true); |
847 | dev_priv->suspended = false; | 1030 | dev_priv->suspended = false; |
848 | return -EBUSY; | 1031 | return -EBUSY; |
849 | } | 1032 | } |
@@ -862,7 +1045,7 @@ static void vmw_pm_complete(struct device *kdev) | |||
862 | * start fifo. | 1045 | * start fifo. |
863 | */ | 1046 | */ |
864 | if (dev_priv->enable_fb) | 1047 | if (dev_priv->enable_fb) |
865 | vmw_3d_resource_inc(dev_priv); | 1048 | vmw_3d_resource_inc(dev_priv, false); |
866 | 1049 | ||
867 | dev_priv->suspended = false; | 1050 | dev_priv->suspended = false; |
868 | } | 1051 | } |
@@ -886,6 +1069,8 @@ static struct drm_driver driver = { | |||
886 | .irq_uninstall = vmw_irq_uninstall, | 1069 | .irq_uninstall = vmw_irq_uninstall, |
887 | .irq_handler = vmw_irq_handler, | 1070 | .irq_handler = vmw_irq_handler, |
888 | .get_vblank_counter = vmw_get_vblank_counter, | 1071 | .get_vblank_counter = vmw_get_vblank_counter, |
1072 | .enable_vblank = vmw_enable_vblank, | ||
1073 | .disable_vblank = vmw_disable_vblank, | ||
889 | .reclaim_buffers_locked = NULL, | 1074 | .reclaim_buffers_locked = NULL, |
890 | .ioctls = vmw_ioctls, | 1075 | .ioctls = vmw_ioctls, |
891 | .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), | 1076 | .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), |
@@ -902,7 +1087,8 @@ static struct drm_driver driver = { | |||
902 | .release = drm_release, | 1087 | .release = drm_release, |
903 | .unlocked_ioctl = vmw_unlocked_ioctl, | 1088 | .unlocked_ioctl = vmw_unlocked_ioctl, |
904 | .mmap = vmw_mmap, | 1089 | .mmap = vmw_mmap, |
905 | .poll = drm_poll, | 1090 | .poll = vmw_fops_poll, |
1091 | .read = vmw_fops_read, | ||
906 | .fasync = drm_fasync, | 1092 | .fasync = drm_fasync, |
907 | #if defined(CONFIG_COMPAT) | 1093 | #if defined(CONFIG_COMPAT) |
908 | .compat_ioctl = drm_compat_ioctl, | 1094 | .compat_ioctl = drm_compat_ioctl, |