diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 01feb48af333..39d43a01d846 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
@@ -29,6 +29,25 @@ | |||
29 | #include "drmP.h" | 29 | #include "drmP.h" |
30 | #include "ttm/ttm_placement.h" | 30 | #include "ttm/ttm_placement.h" |
31 | 31 | ||
32 | bool vmw_fifo_have_3d(struct vmw_private *dev_priv) | ||
33 | { | ||
34 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; | ||
35 | uint32_t fifo_min, hwversion; | ||
36 | |||
37 | fifo_min = ioread32(fifo_mem + SVGA_FIFO_MIN); | ||
38 | if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int)) | ||
39 | return false; | ||
40 | |||
41 | hwversion = ioread32(fifo_mem + SVGA_FIFO_3D_HWVERSION); | ||
42 | if (hwversion == 0) | ||
43 | return false; | ||
44 | |||
45 | if (hwversion < SVGA3D_HWVERSION_WS65_B1) | ||
46 | return false; | ||
47 | |||
48 | return true; | ||
49 | } | ||
50 | |||
32 | int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | 51 | int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) |
33 | { | 52 | { |
34 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; | 53 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
@@ -55,6 +74,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
55 | fifo->reserved_size = 0; | 74 | fifo->reserved_size = 0; |
56 | fifo->using_bounce_buffer = false; | 75 | fifo->using_bounce_buffer = false; |
57 | 76 | ||
77 | mutex_init(&fifo->fifo_mutex); | ||
58 | init_rwsem(&fifo->rwsem); | 78 | init_rwsem(&fifo->rwsem); |
59 | 79 | ||
60 | /* | 80 | /* |
@@ -98,8 +118,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
98 | (unsigned int) min, | 118 | (unsigned int) min, |
99 | (unsigned int) fifo->capabilities); | 119 | (unsigned int) fifo->capabilities); |
100 | 120 | ||
101 | dev_priv->fence_seq = (uint32_t) -100; | 121 | atomic_set(&dev_priv->fence_seq, dev_priv->last_read_sequence); |
102 | dev_priv->last_read_sequence = (uint32_t) -100; | ||
103 | iowrite32(dev_priv->last_read_sequence, fifo_mem + SVGA_FIFO_FENCE); | 122 | iowrite32(dev_priv->last_read_sequence, fifo_mem + SVGA_FIFO_FENCE); |
104 | 123 | ||
105 | return vmw_fifo_send_fence(dev_priv, &dummy); | 124 | return vmw_fifo_send_fence(dev_priv, &dummy); |
@@ -265,7 +284,7 @@ void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes) | |||
265 | uint32_t reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE; | 284 | uint32_t reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE; |
266 | int ret; | 285 | int ret; |
267 | 286 | ||
268 | down_write(&fifo_state->rwsem); | 287 | mutex_lock(&fifo_state->fifo_mutex); |
269 | max = ioread32(fifo_mem + SVGA_FIFO_MAX); | 288 | max = ioread32(fifo_mem + SVGA_FIFO_MAX); |
270 | min = ioread32(fifo_mem + SVGA_FIFO_MIN); | 289 | min = ioread32(fifo_mem + SVGA_FIFO_MIN); |
271 | next_cmd = ioread32(fifo_mem + SVGA_FIFO_NEXT_CMD); | 290 | next_cmd = ioread32(fifo_mem + SVGA_FIFO_NEXT_CMD); |
@@ -333,7 +352,7 @@ void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes) | |||
333 | } | 352 | } |
334 | out_err: | 353 | out_err: |
335 | fifo_state->reserved_size = 0; | 354 | fifo_state->reserved_size = 0; |
336 | up_write(&fifo_state->rwsem); | 355 | mutex_unlock(&fifo_state->fifo_mutex); |
337 | return NULL; | 356 | return NULL; |
338 | } | 357 | } |
339 | 358 | ||
@@ -408,6 +427,7 @@ void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes) | |||
408 | 427 | ||
409 | } | 428 | } |
410 | 429 | ||
430 | down_write(&fifo_state->rwsem); | ||
411 | if (fifo_state->using_bounce_buffer || reserveable) { | 431 | if (fifo_state->using_bounce_buffer || reserveable) { |
412 | next_cmd += bytes; | 432 | next_cmd += bytes; |
413 | if (next_cmd >= max) | 433 | if (next_cmd >= max) |
@@ -419,8 +439,9 @@ void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes) | |||
419 | if (reserveable) | 439 | if (reserveable) |
420 | iowrite32(0, fifo_mem + SVGA_FIFO_RESERVED); | 440 | iowrite32(0, fifo_mem + SVGA_FIFO_RESERVED); |
421 | mb(); | 441 | mb(); |
422 | vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); | ||
423 | up_write(&fifo_state->rwsem); | 442 | up_write(&fifo_state->rwsem); |
443 | vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); | ||
444 | mutex_unlock(&fifo_state->fifo_mutex); | ||
424 | } | 445 | } |
425 | 446 | ||
426 | int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence) | 447 | int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence) |
@@ -433,9 +454,7 @@ int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence) | |||
433 | 454 | ||
434 | fm = vmw_fifo_reserve(dev_priv, bytes); | 455 | fm = vmw_fifo_reserve(dev_priv, bytes); |
435 | if (unlikely(fm == NULL)) { | 456 | if (unlikely(fm == NULL)) { |
436 | down_write(&fifo_state->rwsem); | 457 | *sequence = atomic_read(&dev_priv->fence_seq); |
437 | *sequence = dev_priv->fence_seq; | ||
438 | up_write(&fifo_state->rwsem); | ||
439 | ret = -ENOMEM; | 458 | ret = -ENOMEM; |
440 | (void)vmw_fallback_wait(dev_priv, false, true, *sequence, | 459 | (void)vmw_fallback_wait(dev_priv, false, true, *sequence, |
441 | false, 3*HZ); | 460 | false, 3*HZ); |
@@ -443,7 +462,7 @@ int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence) | |||
443 | } | 462 | } |
444 | 463 | ||
445 | do { | 464 | do { |
446 | *sequence = dev_priv->fence_seq++; | 465 | *sequence = atomic_add_return(1, &dev_priv->fence_seq); |
447 | } while (*sequence == 0); | 466 | } while (*sequence == 0); |
448 | 467 | ||
449 | if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE)) { | 468 | if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE)) { |