Skip to content

Commit

Permalink
Merge tag 'drm-fixes-2019-01-11-1' of git://anongit.freedesktop.org/d…
Browse files Browse the repository at this point in the history
…rm/drm

Pull more drm fixes from Daniel Vetter:
 "Dave sends out his pull, everybody remembers holidays are over :-)

  Since Dave's already in weekend mode and it was quite a few patches I
  figured better to apply all the pulls and forward them to you. Hence
  here 2nd part of bugfixes for -rc2.

  nouveau:
   - backlight fix
   - falcon register access fix
   - fan fix.

  i915:
   - Disable PSR for Apple panels
   - Broxton ERR_PTR error state fix
   - Kabylake VECS workaround fix
   - Unwind failure on pinning the gen7 ppgtt
   - GVT workload request allocation fix

  core:
   - Fix fb-helper to work correctly with SDL 1.2 bugs
   - Fix lockdep warning in the atomic ioctl and setproperty"

* tag 'drm-fixes-2019-01-11-1' of git://anongit.freedesktop.org/drm/drm:
  drm/nouveau/falcon: avoid touching registers if engine is off
  drm/nouveau: Don't disable polling in fallback mode
  drm/nouveau: register backlight on pascal and newer
  drm: Fix documentation generation for DP_DPCD_QUIRK_NO_PSR
  drm/i915: init per-engine WAs for all engines
  drm/i915: Unwind failure on pinning the gen7 ppgtt
  drm/i915: Skip the ERR_PTR error state
  drm/i915: Disable PSR in Apple panels
  gpu/drm: Fix lock held when returning to user space.
  drm/fb-helper: Ignore the value of fb_var_screeninfo.pixclock
  drm/fb-helper: Partially bring back workaround for bugs of SDL 1.2
  drm/i915/gvt: Fix workload request allocation before request add
  • Loading branch information
torvalds committed Jan 12, 2019
2 parents 4b3c31c + e2d3c41 commit 7b5c8f5
Show file tree
Hide file tree
Showing 16 changed files with 192 additions and 102 deletions.
3 changes: 1 addition & 2 deletions drivers/gpu/drm/drm_atomic_uapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1296,12 +1296,11 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
(arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
return -EINVAL;

drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);

state = drm_atomic_state_alloc(dev);
if (!state)
return -ENOMEM;

drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
state->acquire_ctx = &ctx;
state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET);

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/drm_dp_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,8 @@ static const struct dpcd_quirk dpcd_quirk_list[] = {
{ OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_CONSTANT_N) },
/* LG LP140WF6-SPM1 eDP panel */
{ OUI(0x00, 0x22, 0xb9), DEVICE_ID('s', 'i', 'v', 'a', 'r', 'T'), false, BIT(DP_DPCD_QUIRK_CONSTANT_N) },
/* Apple panels need some additional handling to support PSR */
{ OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_NO_PSR) }
};

#undef OUI
Expand Down
133 changes: 79 additions & 54 deletions drivers/gpu/drm/drm_fb_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1621,6 +1621,64 @@ static bool drm_fb_pixel_format_equal(const struct fb_var_screeninfo *var_1,
var_1->transp.msb_right == var_2->transp.msb_right;
}

static void drm_fb_helper_fill_pixel_fmt(struct fb_var_screeninfo *var,
u8 depth)
{
switch (depth) {
case 8:
var->red.offset = 0;
var->green.offset = 0;
var->blue.offset = 0;
var->red.length = 8; /* 8bit DAC */
var->green.length = 8;
var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break;
case 15:
var->red.offset = 10;
var->green.offset = 5;
var->blue.offset = 0;
var->red.length = 5;
var->green.length = 5;
var->blue.length = 5;
var->transp.offset = 15;
var->transp.length = 1;
break;
case 16:
var->red.offset = 11;
var->green.offset = 5;
var->blue.offset = 0;
var->red.length = 5;
var->green.length = 6;
var->blue.length = 5;
var->transp.offset = 0;
break;
case 24:
var->red.offset = 16;
var->green.offset = 8;
var->blue.offset = 0;
var->red.length = 8;
var->green.length = 8;
var->blue.length = 8;
var->transp.offset = 0;
var->transp.length = 0;
break;
case 32:
var->red.offset = 16;
var->green.offset = 8;
var->blue.offset = 0;
var->red.length = 8;
var->green.length = 8;
var->blue.length = 8;
var->transp.offset = 24;
var->transp.length = 8;
break;
default:
break;
}
}

/**
* drm_fb_helper_check_var - implementation for &fb_ops.fb_check_var
* @var: screeninfo to check
Expand All @@ -1632,9 +1690,14 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
struct drm_fb_helper *fb_helper = info->par;
struct drm_framebuffer *fb = fb_helper->fb;

if (var->pixclock != 0 || in_dbg_master())
if (in_dbg_master())
return -EINVAL;

if (var->pixclock != 0) {
DRM_DEBUG("fbdev emulation doesn't support changing the pixel clock, value of pixclock is ignored\n");
var->pixclock = 0;
}

if ((drm_format_info_block_width(fb->format, 0) > 1) ||
(drm_format_info_block_height(fb->format, 0) > 1))
return -EINVAL;
Expand All @@ -1654,6 +1717,20 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
return -EINVAL;
}

/*
* Workaround for SDL 1.2, which is known to be setting all pixel format
* fields values to zero in some cases. We treat this situation as a
* kind of "use some reasonable autodetected values".
*/
if (!var->red.offset && !var->green.offset &&
!var->blue.offset && !var->transp.offset &&
!var->red.length && !var->green.length &&
!var->blue.length && !var->transp.length &&
!var->red.msb_right && !var->green.msb_right &&
!var->blue.msb_right && !var->transp.msb_right) {
drm_fb_helper_fill_pixel_fmt(var, fb->format->depth);
}

/*
* drm fbdev emulation doesn't support changing the pixel format at all,
* so reject all pixel format changing requests.
Expand Down Expand Up @@ -1967,59 +2044,7 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
info->var.yoffset = 0;
info->var.activate = FB_ACTIVATE_NOW;

switch (fb->format->depth) {
case 8:
info->var.red.offset = 0;
info->var.green.offset = 0;
info->var.blue.offset = 0;
info->var.red.length = 8; /* 8bit DAC */
info->var.green.length = 8;
info->var.blue.length = 8;
info->var.transp.offset = 0;
info->var.transp.length = 0;
break;
case 15:
info->var.red.offset = 10;
info->var.green.offset = 5;
info->var.blue.offset = 0;
info->var.red.length = 5;
info->var.green.length = 5;
info->var.blue.length = 5;
info->var.transp.offset = 15;
info->var.transp.length = 1;
break;
case 16:
info->var.red.offset = 11;
info->var.green.offset = 5;
info->var.blue.offset = 0;
info->var.red.length = 5;
info->var.green.length = 6;
info->var.blue.length = 5;
info->var.transp.offset = 0;
break;
case 24:
info->var.red.offset = 16;
info->var.green.offset = 8;
info->var.blue.offset = 0;
info->var.red.length = 8;
info->var.green.length = 8;
info->var.blue.length = 8;
info->var.transp.offset = 0;
info->var.transp.length = 0;
break;
case 32:
info->var.red.offset = 16;
info->var.green.offset = 8;
info->var.blue.offset = 0;
info->var.red.length = 8;
info->var.green.length = 8;
info->var.blue.length = 8;
info->var.transp.offset = 24;
info->var.transp.length = 8;
break;
default:
break;
}
drm_fb_helper_fill_pixel_fmt(&info->var, fb->format->depth);

info->var.xres = fb_width;
info->var.yres = fb_height;
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/drm_mode_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,11 +459,11 @@ static int set_property_atomic(struct drm_mode_object *obj,
struct drm_modeset_acquire_ctx ctx;
int ret;

drm_modeset_acquire_init(&ctx, 0);

state = drm_atomic_state_alloc(dev);
if (!state)
return -ENOMEM;

drm_modeset_acquire_init(&ctx, 0);
state->acquire_ctx = &ctx;
retry:
if (prop == state->dev->mode_config.dpms_property) {
Expand Down
64 changes: 42 additions & 22 deletions drivers/gpu/drm/i915/gvt/scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,33 @@ static int set_context_ppgtt_from_shadow(struct intel_vgpu_workload *workload,
return 0;
}

static int
intel_gvt_workload_req_alloc(struct intel_vgpu_workload *workload)
{
struct intel_vgpu *vgpu = workload->vgpu;
struct intel_vgpu_submission *s = &vgpu->submission;
struct i915_gem_context *shadow_ctx = s->shadow_ctx;
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
struct intel_engine_cs *engine = dev_priv->engine[workload->ring_id];
struct i915_request *rq;
int ret = 0;

lockdep_assert_held(&dev_priv->drm.struct_mutex);

if (workload->req)
goto out;

rq = i915_request_alloc(engine, shadow_ctx);
if (IS_ERR(rq)) {
gvt_vgpu_err("fail to allocate gem request\n");
ret = PTR_ERR(rq);
goto out;
}
workload->req = i915_request_get(rq);
out:
return ret;
}

/**
* intel_gvt_scan_and_shadow_workload - audit the workload by scanning and
* shadow it as well, include ringbuffer,wa_ctx and ctx.
Expand All @@ -372,12 +399,11 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
struct intel_engine_cs *engine = dev_priv->engine[workload->ring_id];
struct intel_context *ce;
struct i915_request *rq;
int ret;

lockdep_assert_held(&dev_priv->drm.struct_mutex);

if (workload->req)
if (workload->shadow)
return 0;

ret = set_context_ppgtt_from_shadow(workload, shadow_ctx);
Expand Down Expand Up @@ -417,22 +443,8 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
goto err_shadow;
}

rq = i915_request_alloc(engine, shadow_ctx);
if (IS_ERR(rq)) {
gvt_vgpu_err("fail to allocate gem request\n");
ret = PTR_ERR(rq);
goto err_shadow;
}
workload->req = i915_request_get(rq);

ret = populate_shadow_context(workload);
if (ret)
goto err_req;

workload->shadow = true;
return 0;
err_req:
rq = fetch_and_zero(&workload->req);
i915_request_put(rq);
err_shadow:
release_shadow_wa_ctx(&workload->wa_ctx);
err_unpin:
Expand Down Expand Up @@ -671,23 +683,31 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
mutex_lock(&vgpu->vgpu_lock);
mutex_lock(&dev_priv->drm.struct_mutex);

ret = intel_gvt_workload_req_alloc(workload);
if (ret)
goto err_req;

ret = intel_gvt_scan_and_shadow_workload(workload);
if (ret)
goto out;

ret = prepare_workload(workload);
ret = populate_shadow_context(workload);
if (ret) {
release_shadow_wa_ctx(&workload->wa_ctx);
goto out;
}

ret = prepare_workload(workload);
out:
if (ret)
workload->status = ret;

if (!IS_ERR_OR_NULL(workload->req)) {
gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
ring_id, workload->req);
i915_request_add(workload->req);
workload->dispatched = true;
}

err_req:
if (ret)
workload->status = ret;
mutex_unlock(&dev_priv->drm.struct_mutex);
mutex_unlock(&vgpu->vgpu_lock);
return ret;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/gvt/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct intel_vgpu_workload {
struct i915_request *req;
/* if this workload has been dispatched to i915? */
bool dispatched;
bool shadow; /* if workload has done shadow of guest request */
int status;

struct intel_vgpu_mm *shadow_mm;
Expand Down
12 changes: 9 additions & 3 deletions drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -984,8 +984,8 @@ static int i915_gpu_info_open(struct inode *inode, struct file *file)
intel_runtime_pm_get(i915);
gpu = i915_capture_gpu_state(i915);
intel_runtime_pm_put(i915);
if (!gpu)
return -ENOMEM;
if (IS_ERR(gpu))
return PTR_ERR(gpu);

file->private_data = gpu;
return 0;
Expand Down Expand Up @@ -1018,7 +1018,13 @@ i915_error_state_write(struct file *filp,

static int i915_error_state_open(struct inode *inode, struct file *file)
{
file->private_data = i915_first_error_state(inode->i_private);
struct i915_gpu_state *error;

error = i915_first_error_state(inode->i_private);
if (IS_ERR(error))
return PTR_ERR(error);

file->private_data = error;
return 0;
}

Expand Down
15 changes: 12 additions & 3 deletions drivers/gpu/drm/i915/i915_gem_gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2075,6 +2075,7 @@ static struct i915_vma *pd_vma_create(struct gen6_hw_ppgtt *ppgtt, int size)
int gen6_ppgtt_pin(struct i915_hw_ppgtt *base)
{
struct gen6_hw_ppgtt *ppgtt = to_gen6_ppgtt(base);
int err;

/*
* Workaround the limited maximum vma->pin_count and the aliasing_ppgtt
Expand All @@ -2090,9 +2091,17 @@ int gen6_ppgtt_pin(struct i915_hw_ppgtt *base)
* allocator works in address space sizes, so it's multiplied by page
* size. We allocate at the top of the GTT to avoid fragmentation.
*/
return i915_vma_pin(ppgtt->vma,
0, GEN6_PD_ALIGN,
PIN_GLOBAL | PIN_HIGH);
err = i915_vma_pin(ppgtt->vma,
0, GEN6_PD_ALIGN,
PIN_GLOBAL | PIN_HIGH);
if (err)
goto unpin;

return 0;

unpin:
ppgtt->pin_count = 0;
return err;
}

void gen6_ppgtt_unpin(struct i915_hw_ppgtt *base)
Expand Down
Loading

0 comments on commit 7b5c8f5

Please sign in to comment.