Skip to content

Commit 30c60ba

Browse files
committed
Merge tag 'vmwgfx-drm-fixes-5.18-2022-05-13' of https://gitlab.freedesktop.org/zack/vmwgfx into drm-fixes
vmwgfx fixes for: - Black screen due to fences using FIFO checks on SVGA3 - Random black screens on boot due to uninitialized drm_mode_fb_cmd2 - Hangs on SVGA3 due to command buffers being used with gbobjects Signed-off-by: Dave Airlie <airlied@redhat.com> From: Zack Rusin <zackr@vmware.com> Link: https://patchwork.freedesktop.org/patch/msgid/a1d32799e4c74b8540216376d7576bb783ca07ba.camel@vmware.com
2 parents 5005e98 + 21d1d19 commit 30c60ba

6 files changed

Lines changed: 61 additions & 24 deletions

File tree

drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ int vmw_cmd_send_fence(struct vmw_private *dev_priv, uint32_t *seqno)
528528
*seqno = atomic_add_return(1, &dev_priv->marker_seq);
529529
} while (*seqno == 0);
530530

531-
if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE)) {
531+
if (!vmw_has_fences(dev_priv)) {
532532

533533
/*
534534
* Don't request hardware to send a fence. The
@@ -675,11 +675,14 @@ int vmw_cmd_emit_dummy_query(struct vmw_private *dev_priv,
675675
*/
676676
bool vmw_cmd_supported(struct vmw_private *vmw)
677677
{
678-
if ((vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS |
679-
SVGA_CAP_CMD_BUFFERS_2)) != 0)
680-
return true;
678+
bool has_cmdbufs =
679+
(vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS |
680+
SVGA_CAP_CMD_BUFFERS_2)) != 0;
681+
if (vmw_is_svga_v3(vmw))
682+
return (has_cmdbufs &&
683+
(vmw->capabilities & SVGA_CAP_GBOBJECTS) != 0);
681684
/*
682685
* We have FIFO cmd's
683686
*/
684-
return vmw->fifo_mem != NULL;
687+
return has_cmdbufs || vmw->fifo_mem != NULL;
685688
}

drivers/gpu/drm/vmwgfx/vmwgfx_drv.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,4 +1679,12 @@ static inline void vmw_irq_status_write(struct vmw_private *vmw,
16791679
outl(status, vmw->io_start + SVGA_IRQSTATUS_PORT);
16801680
}
16811681

1682+
static inline bool vmw_has_fences(struct vmw_private *vmw)
1683+
{
1684+
if ((vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS |
1685+
SVGA_CAP_CMD_BUFFERS_2)) != 0)
1686+
return true;
1687+
return (vmw_fifo_caps(vmw) & SVGA_FIFO_CAP_FENCE) != 0;
1688+
}
1689+
16821690
#endif

drivers/gpu/drm/vmwgfx/vmwgfx_fb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
483483

484484
static int vmw_fb_kms_framebuffer(struct fb_info *info)
485485
{
486-
struct drm_mode_fb_cmd2 mode_cmd;
486+
struct drm_mode_fb_cmd2 mode_cmd = {0};
487487
struct vmw_fb_par *par = info->par;
488488
struct fb_var_screeninfo *var = &info->var;
489489
struct drm_framebuffer *cur_fb;

drivers/gpu/drm/vmwgfx/vmwgfx_fence.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,22 @@ fman_from_fence(struct vmw_fence_obj *fence)
8282
return container_of(fence->base.lock, struct vmw_fence_manager, lock);
8383
}
8484

85+
static u32 vmw_fence_goal_read(struct vmw_private *vmw)
86+
{
87+
if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
88+
return vmw_read(vmw, SVGA_REG_FENCE_GOAL);
89+
else
90+
return vmw_fifo_mem_read(vmw, SVGA_FIFO_FENCE_GOAL);
91+
}
92+
93+
static void vmw_fence_goal_write(struct vmw_private *vmw, u32 value)
94+
{
95+
if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
96+
vmw_write(vmw, SVGA_REG_FENCE_GOAL, value);
97+
else
98+
vmw_fifo_mem_write(vmw, SVGA_FIFO_FENCE_GOAL, value);
99+
}
100+
85101
/*
86102
* Note on fencing subsystem usage of irqs:
87103
* Typically the vmw_fences_update function is called
@@ -392,17 +408,16 @@ static bool vmw_fence_goal_new_locked(struct vmw_fence_manager *fman,
392408
if (likely(!fman->seqno_valid))
393409
return false;
394410

395-
goal_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE_GOAL);
411+
goal_seqno = vmw_fence_goal_read(fman->dev_priv);
396412
if (likely(passed_seqno - goal_seqno >= VMW_FENCE_WRAP))
397413
return false;
398414

399415
fman->seqno_valid = false;
400416
list_for_each_entry(fence, &fman->fence_list, head) {
401417
if (!list_empty(&fence->seq_passed_actions)) {
402418
fman->seqno_valid = true;
403-
vmw_fifo_mem_write(fman->dev_priv,
404-
SVGA_FIFO_FENCE_GOAL,
405-
fence->base.seqno);
419+
vmw_fence_goal_write(fman->dev_priv,
420+
fence->base.seqno);
406421
break;
407422
}
408423
}
@@ -434,13 +449,12 @@ static bool vmw_fence_goal_check_locked(struct vmw_fence_obj *fence)
434449
if (dma_fence_is_signaled_locked(&fence->base))
435450
return false;
436451

437-
goal_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE_GOAL);
452+
goal_seqno = vmw_fence_goal_read(fman->dev_priv);
438453
if (likely(fman->seqno_valid &&
439454
goal_seqno - fence->base.seqno < VMW_FENCE_WRAP))
440455
return false;
441456

442-
vmw_fifo_mem_write(fman->dev_priv, SVGA_FIFO_FENCE_GOAL,
443-
fence->base.seqno);
457+
vmw_fence_goal_write(fman->dev_priv, fence->base.seqno);
444458
fman->seqno_valid = true;
445459

446460
return true;

drivers/gpu/drm/vmwgfx/vmwgfx_irq.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@
3232

3333
#define VMW_FENCE_WRAP (1 << 24)
3434

35+
static u32 vmw_irqflag_fence_goal(struct vmw_private *vmw)
36+
{
37+
if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0)
38+
return SVGA_IRQFLAG_REG_FENCE_GOAL;
39+
else
40+
return SVGA_IRQFLAG_FENCE_GOAL;
41+
}
42+
3543
/**
3644
* vmw_thread_fn - Deferred (process context) irq handler
3745
*
@@ -96,7 +104,7 @@ static irqreturn_t vmw_irq_handler(int irq, void *arg)
96104
wake_up_all(&dev_priv->fifo_queue);
97105

98106
if ((masked_status & (SVGA_IRQFLAG_ANY_FENCE |
99-
SVGA_IRQFLAG_FENCE_GOAL)) &&
107+
vmw_irqflag_fence_goal(dev_priv))) &&
100108
!test_and_set_bit(VMW_IRQTHREAD_FENCE, dev_priv->irqthread_pending))
101109
ret = IRQ_WAKE_THREAD;
102110

@@ -137,8 +145,7 @@ bool vmw_seqno_passed(struct vmw_private *dev_priv,
137145
if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP))
138146
return true;
139147

140-
if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE) &&
141-
vmw_fifo_idle(dev_priv, seqno))
148+
if (!vmw_has_fences(dev_priv) && vmw_fifo_idle(dev_priv, seqno))
142149
return true;
143150

144151
/**
@@ -160,6 +167,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv,
160167
unsigned long timeout)
161168
{
162169
struct vmw_fifo_state *fifo_state = dev_priv->fifo;
170+
bool fifo_down = false;
163171

164172
uint32_t count = 0;
165173
uint32_t signal_seq;
@@ -176,12 +184,14 @@ int vmw_fallback_wait(struct vmw_private *dev_priv,
176184
*/
177185

178186
if (fifo_idle) {
179-
down_read(&fifo_state->rwsem);
180187
if (dev_priv->cman) {
181188
ret = vmw_cmdbuf_idle(dev_priv->cman, interruptible,
182189
10*HZ);
183190
if (ret)
184191
goto out_err;
192+
} else if (fifo_state) {
193+
down_read(&fifo_state->rwsem);
194+
fifo_down = true;
185195
}
186196
}
187197

@@ -218,12 +228,12 @@ int vmw_fallback_wait(struct vmw_private *dev_priv,
218228
}
219229
}
220230
finish_wait(&dev_priv->fence_queue, &__wait);
221-
if (ret == 0 && fifo_idle)
231+
if (ret == 0 && fifo_idle && fifo_state)
222232
vmw_fence_write(dev_priv, signal_seq);
223233

224234
wake_up_all(&dev_priv->fence_queue);
225235
out_err:
226-
if (fifo_idle)
236+
if (fifo_down)
227237
up_read(&fifo_state->rwsem);
228238

229239
return ret;
@@ -266,13 +276,13 @@ void vmw_seqno_waiter_remove(struct vmw_private *dev_priv)
266276

267277
void vmw_goal_waiter_add(struct vmw_private *dev_priv)
268278
{
269-
vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_FENCE_GOAL,
279+
vmw_generic_waiter_add(dev_priv, vmw_irqflag_fence_goal(dev_priv),
270280
&dev_priv->goal_queue_waiters);
271281
}
272282

273283
void vmw_goal_waiter_remove(struct vmw_private *dev_priv)
274284
{
275-
vmw_generic_waiter_remove(dev_priv, SVGA_IRQFLAG_FENCE_GOAL,
285+
vmw_generic_waiter_remove(dev_priv, vmw_irqflag_fence_goal(dev_priv),
276286
&dev_priv->goal_queue_waiters);
277287
}
278288

drivers/gpu/drm/vmwgfx/vmwgfx_kms.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,6 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
13441344
ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
13451345
mode_cmd,
13461346
is_bo_proxy);
1347-
13481347
/*
13491348
* vmw_create_bo_proxy() adds a reference that is no longer
13501349
* needed
@@ -1385,13 +1384,16 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
13851384
ret = vmw_user_lookup_handle(dev_priv, file_priv,
13861385
mode_cmd->handles[0],
13871386
&surface, &bo);
1388-
if (ret)
1387+
if (ret) {
1388+
DRM_ERROR("Invalid buffer object handle %u (0x%x).\n",
1389+
mode_cmd->handles[0], mode_cmd->handles[0]);
13891390
goto err_out;
1391+
}
13901392

13911393

13921394
if (!bo &&
13931395
!vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)) {
1394-
DRM_ERROR("Surface size cannot exceed %dx%d",
1396+
DRM_ERROR("Surface size cannot exceed %dx%d\n",
13951397
dev_priv->texture_max_width,
13961398
dev_priv->texture_max_height);
13971399
goto err_out;

0 commit comments

Comments
 (0)