Commit caa55235 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 - i915 fixes: a few display regressions
 - vmwgfx: possible loop forever fix
 - nouveau: one userspace interface fix

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/nouveau/core: don't leak oclass type bits to user
  drm/i915: Fix lock dropping in intel_tv_detect()
  drm/i915: handle G45/GM45 pulse detection connected state.
  drm/vmwgfx: Fix a potential infinite spin waiting for fifo idle
  drm/vmwgfx: Fix an incorrect OOM return value
  drm/i915: Remove bogus __init annotation from DMI callbacks
  drm/i915: don't warn if backlight unexpectedly enabled
  drm/i915: Move intel_ddi_set_vc_payload_alloc(false) to haswell_crtc_disable()
  drm/i915: fix plane/cursor handling when runtime suspended
  drm/i915: Ignore VBT backlight presence check on Acer C720 (4005U)
parents b7fece1b 68c78bd6
...@@ -1123,7 +1123,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) ...@@ -1123,7 +1123,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
} }
} }
static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) static int intel_no_opregion_vbt_callback(const struct dmi_system_id *id)
{ {
DRM_DEBUG_KMS("Falling back to manually reading VBT from " DRM_DEBUG_KMS("Falling back to manually reading VBT from "
"VBIOS ROM for %s\n", "VBIOS ROM for %s\n",
......
...@@ -804,7 +804,7 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { ...@@ -804,7 +804,7 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
.destroy = intel_encoder_destroy, .destroy = intel_encoder_destroy,
}; };
static int __init intel_no_crt_dmi_callback(const struct dmi_system_id *id) static int intel_no_crt_dmi_callback(const struct dmi_system_id *id)
{ {
DRM_INFO("Skipping CRT initialization for %s\n", id->ident); DRM_INFO("Skipping CRT initialization for %s\n", id->ident);
return 1; return 1;
......
...@@ -2233,6 +2233,15 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, ...@@ -2233,6 +2233,15 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
if (need_vtd_wa(dev) && alignment < 256 * 1024) if (need_vtd_wa(dev) && alignment < 256 * 1024)
alignment = 256 * 1024; alignment = 256 * 1024;
/*
* Global gtt pte registers are special registers which actually forward
* writes to a chunk of system memory. Which means that there is no risk
* that the register values disappear as soon as we call
* intel_runtime_pm_put(), so it is correct to wrap only the
* pin/unpin/fence and not more.
*/
intel_runtime_pm_get(dev_priv);
dev_priv->mm.interruptible = false; dev_priv->mm.interruptible = false;
ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined);
if (ret) if (ret)
...@@ -2250,12 +2259,14 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, ...@@ -2250,12 +2259,14 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
i915_gem_object_pin_fence(obj); i915_gem_object_pin_fence(obj);
dev_priv->mm.interruptible = true; dev_priv->mm.interruptible = true;
intel_runtime_pm_put(dev_priv);
return 0; return 0;
err_unpin: err_unpin:
i915_gem_object_unpin_from_display_plane(obj); i915_gem_object_unpin_from_display_plane(obj);
err_interruptible: err_interruptible:
dev_priv->mm.interruptible = true; dev_priv->mm.interruptible = true;
intel_runtime_pm_put(dev_priv);
return ret; return ret;
} }
...@@ -4188,10 +4199,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) ...@@ -4188,10 +4199,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
intel_set_pch_fifo_underrun_reporting(dev, pipe, false); intel_set_pch_fifo_underrun_reporting(dev, pipe, false);
intel_disable_pipe(dev_priv, pipe); intel_disable_pipe(dev_priv, pipe);
if (intel_crtc->config.dp_encoder_is_mst)
intel_ddi_set_vc_payload_alloc(crtc, false);
ironlake_pfit_disable(intel_crtc); ironlake_pfit_disable(intel_crtc);
for_each_encoder_on_crtc(dev, crtc, encoder) for_each_encoder_on_crtc(dev, crtc, encoder)
...@@ -4256,6 +4263,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) ...@@ -4256,6 +4263,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false); intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false);
intel_disable_pipe(dev_priv, pipe); intel_disable_pipe(dev_priv, pipe);
if (intel_crtc->config.dp_encoder_is_mst)
intel_ddi_set_vc_payload_alloc(crtc, false);
intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder);
ironlake_pfit_disable(intel_crtc); ironlake_pfit_disable(intel_crtc);
...@@ -8240,6 +8250,15 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, ...@@ -8240,6 +8250,15 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc,
goto fail_locked; goto fail_locked;
} }
/*
* Global gtt pte registers are special registers which actually
* forward writes to a chunk of system memory. Which means that
* there is no risk that the register values disappear as soon
* as we call intel_runtime_pm_put(), so it is correct to wrap
* only the pin/unpin/fence and not more.
*/
intel_runtime_pm_get(dev_priv);
/* Note that the w/a also requires 2 PTE of padding following /* Note that the w/a also requires 2 PTE of padding following
* the bo. We currently fill all unused PTE with the shadow * the bo. We currently fill all unused PTE with the shadow
* page and so we should always have valid PTE following the * page and so we should always have valid PTE following the
...@@ -8252,16 +8271,20 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, ...@@ -8252,16 +8271,20 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc,
ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL); ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL);
if (ret) { if (ret) {
DRM_DEBUG_KMS("failed to move cursor bo into the GTT\n"); DRM_DEBUG_KMS("failed to move cursor bo into the GTT\n");
intel_runtime_pm_put(dev_priv);
goto fail_locked; goto fail_locked;
} }
ret = i915_gem_object_put_fence(obj); ret = i915_gem_object_put_fence(obj);
if (ret) { if (ret) {
DRM_DEBUG_KMS("failed to release fence for cursor"); DRM_DEBUG_KMS("failed to release fence for cursor");
intel_runtime_pm_put(dev_priv);
goto fail_unpin; goto fail_unpin;
} }
addr = i915_gem_obj_ggtt_offset(obj); addr = i915_gem_obj_ggtt_offset(obj);
intel_runtime_pm_put(dev_priv);
} else { } else {
int align = IS_I830(dev) ? 16 * 1024 : 256; int align = IS_I830(dev) ? 16 * 1024 : 256;
ret = i915_gem_object_attach_phys(obj, align); ret = i915_gem_object_attach_phys(obj, align);
...@@ -12481,6 +12504,9 @@ static struct intel_quirk intel_quirks[] = { ...@@ -12481,6 +12504,9 @@ static struct intel_quirk intel_quirks[] = {
/* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */ /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */
{ 0x0a06, 0x1025, 0x0a11, quirk_backlight_present }, { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present },
/* Acer C720 Chromebook (Core i3 4005U) */
{ 0x0a16, 0x1025, 0x0a11, quirk_backlight_present },
/* Toshiba CB35 Chromebook (Celeron 2955U) */ /* Toshiba CB35 Chromebook (Celeron 2955U) */
{ 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present },
......
...@@ -3661,24 +3661,12 @@ ironlake_dp_detect(struct intel_dp *intel_dp) ...@@ -3661,24 +3661,12 @@ ironlake_dp_detect(struct intel_dp *intel_dp)
return intel_dp_detect_dpcd(intel_dp); return intel_dp_detect_dpcd(intel_dp);
} }
static enum drm_connector_status static int g4x_digital_port_connected(struct drm_device *dev,
g4x_dp_detect(struct intel_dp *intel_dp) struct intel_digital_port *intel_dig_port)
{ {
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
uint32_t bit; uint32_t bit;
/* Can't disconnect eDP, but you can close the lid... */
if (is_edp(intel_dp)) {
enum drm_connector_status status;
status = intel_panel_detect(dev);
if (status == connector_status_unknown)
status = connector_status_connected;
return status;
}
if (IS_VALLEYVIEW(dev)) { if (IS_VALLEYVIEW(dev)) {
switch (intel_dig_port->port) { switch (intel_dig_port->port) {
case PORT_B: case PORT_B:
...@@ -3691,7 +3679,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) ...@@ -3691,7 +3679,7 @@ g4x_dp_detect(struct intel_dp *intel_dp)
bit = PORTD_HOTPLUG_LIVE_STATUS_VLV; bit = PORTD_HOTPLUG_LIVE_STATUS_VLV;
break; break;
default: default:
return connector_status_unknown; return -EINVAL;
} }
} else { } else {
switch (intel_dig_port->port) { switch (intel_dig_port->port) {
...@@ -3705,11 +3693,36 @@ g4x_dp_detect(struct intel_dp *intel_dp) ...@@ -3705,11 +3693,36 @@ g4x_dp_detect(struct intel_dp *intel_dp)
bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; bit = PORTD_HOTPLUG_LIVE_STATUS_G4X;
break; break;
default: default:
return connector_status_unknown; return -EINVAL;
} }
} }
if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0) if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0)
return 0;
return 1;
}
static enum drm_connector_status
g4x_dp_detect(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
int ret;
/* Can't disconnect eDP, but you can close the lid... */
if (is_edp(intel_dp)) {
enum drm_connector_status status;
status = intel_panel_detect(dev);
if (status == connector_status_unknown)
status = connector_status_connected;
return status;
}
ret = g4x_digital_port_connected(dev, intel_dig_port);
if (ret == -EINVAL)
return connector_status_unknown;
else if (ret == 0)
return connector_status_disconnected; return connector_status_disconnected;
return intel_dp_detect_dpcd(intel_dp); return intel_dp_detect_dpcd(intel_dp);
...@@ -4066,8 +4079,14 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) ...@@ -4066,8 +4079,14 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
intel_display_power_get(dev_priv, power_domain); intel_display_power_get(dev_priv, power_domain);
if (long_hpd) { if (long_hpd) {
if (!ibx_digital_port_connected(dev_priv, intel_dig_port))
goto mst_fail; if (HAS_PCH_SPLIT(dev)) {
if (!ibx_digital_port_connected(dev_priv, intel_dig_port))
goto mst_fail;
} else {
if (g4x_digital_port_connected(dev, intel_dig_port) != 1)
goto mst_fail;
}
if (!intel_dp_get_dpcd(intel_dp)) { if (!intel_dp_get_dpcd(intel_dp)) {
goto mst_fail; goto mst_fail;
......
...@@ -538,7 +538,7 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = { ...@@ -538,7 +538,7 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
.destroy = intel_encoder_destroy, .destroy = intel_encoder_destroy,
}; };
static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) static int intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
{ {
DRM_INFO("Skipping LVDS initialization for %s\n", id->ident); DRM_INFO("Skipping LVDS initialization for %s\n", id->ident);
return 1; return 1;
......
...@@ -801,7 +801,7 @@ static void pch_enable_backlight(struct intel_connector *connector) ...@@ -801,7 +801,7 @@ static void pch_enable_backlight(struct intel_connector *connector)
cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2); cpu_ctl2 = I915_READ(BLC_PWM_CPU_CTL2);
if (cpu_ctl2 & BLM_PWM_ENABLE) { if (cpu_ctl2 & BLM_PWM_ENABLE) {
WARN(1, "cpu backlight already enabled\n"); DRM_DEBUG_KMS("cpu backlight already enabled\n");
cpu_ctl2 &= ~BLM_PWM_ENABLE; cpu_ctl2 &= ~BLM_PWM_ENABLE;
I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2); I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2);
} }
...@@ -845,7 +845,7 @@ static void i9xx_enable_backlight(struct intel_connector *connector) ...@@ -845,7 +845,7 @@ static void i9xx_enable_backlight(struct intel_connector *connector)
ctl = I915_READ(BLC_PWM_CTL); ctl = I915_READ(BLC_PWM_CTL);
if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) { if (ctl & BACKLIGHT_DUTY_CYCLE_MASK_PNV) {
WARN(1, "backlight already enabled\n"); DRM_DEBUG_KMS("backlight already enabled\n");
I915_WRITE(BLC_PWM_CTL, 0); I915_WRITE(BLC_PWM_CTL, 0);
} }
...@@ -876,7 +876,7 @@ static void i965_enable_backlight(struct intel_connector *connector) ...@@ -876,7 +876,7 @@ static void i965_enable_backlight(struct intel_connector *connector)
ctl2 = I915_READ(BLC_PWM_CTL2); ctl2 = I915_READ(BLC_PWM_CTL2);
if (ctl2 & BLM_PWM_ENABLE) { if (ctl2 & BLM_PWM_ENABLE) {
WARN(1, "backlight already enabled\n"); DRM_DEBUG_KMS("backlight already enabled\n");
ctl2 &= ~BLM_PWM_ENABLE; ctl2 &= ~BLM_PWM_ENABLE;
I915_WRITE(BLC_PWM_CTL2, ctl2); I915_WRITE(BLC_PWM_CTL2, ctl2);
} }
...@@ -910,7 +910,7 @@ static void vlv_enable_backlight(struct intel_connector *connector) ...@@ -910,7 +910,7 @@ static void vlv_enable_backlight(struct intel_connector *connector)
ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe)); ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
if (ctl2 & BLM_PWM_ENABLE) { if (ctl2 & BLM_PWM_ENABLE) {
WARN(1, "backlight already enabled\n"); DRM_DEBUG_KMS("backlight already enabled\n");
ctl2 &= ~BLM_PWM_ENABLE; ctl2 &= ~BLM_PWM_ENABLE;
I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2); I915_WRITE(VLV_BLC_PWM_CTL2(pipe), ctl2);
} }
......
...@@ -1311,6 +1311,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) ...@@ -1311,6 +1311,7 @@ intel_tv_detect(struct drm_connector *connector, bool force)
{ {
struct drm_display_mode mode; struct drm_display_mode mode;
struct intel_tv *intel_tv = intel_attached_tv(connector); struct intel_tv *intel_tv = intel_attached_tv(connector);
enum drm_connector_status status;
int type; int type;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n", DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",
...@@ -1328,16 +1329,19 @@ intel_tv_detect(struct drm_connector *connector, bool force) ...@@ -1328,16 +1329,19 @@ intel_tv_detect(struct drm_connector *connector, bool force)
if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) { if (intel_get_load_detect_pipe(connector, &mode, &tmp, &ctx)) {
type = intel_tv_detect_type(intel_tv, connector); type = intel_tv_detect_type(intel_tv, connector);
intel_release_load_detect_pipe(connector, &tmp); intel_release_load_detect_pipe(connector, &tmp);
status = type < 0 ?
connector_status_disconnected :
connector_status_connected;
} else } else
return connector_status_unknown; status = connector_status_unknown;
drm_modeset_drop_locks(&ctx); drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx); drm_modeset_acquire_fini(&ctx);
} else } else
return connector->status; return connector->status;
if (type < 0) if (status != connector_status_connected)
return connector_status_disconnected; return status;
intel_tv->type = type; intel_tv->type = type;
intel_tv_find_better_format(connector); intel_tv_find_better_format(connector);
......
...@@ -86,7 +86,7 @@ nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size) ...@@ -86,7 +86,7 @@ nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size)
sclass = nv_parent(parent)->sclass; sclass = nv_parent(parent)->sclass;
while (sclass) { while (sclass) {
if (++nr < size) if (++nr < size)
lclass[nr] = sclass->oclass->handle; lclass[nr] = sclass->oclass->handle & 0xffff;
sclass = sclass->sclass; sclass = sclass->sclass;
} }
...@@ -96,7 +96,7 @@ nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size) ...@@ -96,7 +96,7 @@ nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size)
if (engine && (oclass = engine->sclass)) { if (engine && (oclass = engine->sclass)) {
while (oclass->ofuncs) { while (oclass->ofuncs) {
if (++nr < size) if (++nr < size)
lclass[nr] = oclass->handle; lclass[nr] = oclass->handle & 0xffff;
oclass++; oclass++;
} }
} }
......
...@@ -450,11 +450,11 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, ...@@ -450,11 +450,11 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv,
res, res,
id_loc - sw_context->buf_start); id_loc - sw_context->buf_start);
if (unlikely(ret != 0)) if (unlikely(ret != 0))
goto out_err; return ret;
ret = vmw_resource_val_add(sw_context, res, &node); ret = vmw_resource_val_add(sw_context, res, &node);
if (unlikely(ret != 0)) if (unlikely(ret != 0))
goto out_err; return ret;
if (res_type == vmw_res_context && dev_priv->has_mob && if (res_type == vmw_res_context && dev_priv->has_mob &&
node->first_usage) { node->first_usage) {
...@@ -468,13 +468,13 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, ...@@ -468,13 +468,13 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv,
ret = vmw_resource_context_res_add(dev_priv, sw_context, res); ret = vmw_resource_context_res_add(dev_priv, sw_context, res);
if (unlikely(ret != 0)) if (unlikely(ret != 0))
goto out_err; return ret;
node->staged_bindings = node->staged_bindings =
kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL); kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL);
if (node->staged_bindings == NULL) { if (node->staged_bindings == NULL) {
DRM_ERROR("Failed to allocate context binding " DRM_ERROR("Failed to allocate context binding "
"information.\n"); "information.\n");
goto out_err; return -ENOMEM;
} }
INIT_LIST_HEAD(&node->staged_bindings->list); INIT_LIST_HEAD(&node->staged_bindings->list);
} }
...@@ -482,8 +482,7 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv, ...@@ -482,8 +482,7 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv,
if (p_val) if (p_val)
*p_val = node; *p_val = node;
out_err: return 0;
return ret;
} }
......
...@@ -180,8 +180,9 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) ...@@ -180,8 +180,9 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
mutex_lock(&dev_priv->hw_mutex); mutex_lock(&dev_priv->hw_mutex);
vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC);
while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0) while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0)
vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); ;
dev_priv->last_read_seqno = ioread32(fifo_mem + SVGA_FIFO_FENCE); dev_priv->last_read_seqno = ioread32(fifo_mem + SVGA_FIFO_FENCE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment