Commit 20a984c2 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-fixes-2014-08-21' of git://anongit.freedesktop.org/drm-intel

Display fixes from Ville and Imre, all cc: stable.

* tag 'drm-intel-fixes-2014-08-21' of git://anongit.freedesktop.org/drm-intel:
  drm/i915: don't try to retrain a DP link on an inactive CRTC
  drm/i915: make sure VDD is turned off during system suspend
  drm/i915: cancel hotplug and dig_port work during suspend and unload
  drm/i915: fix HPD IRQ reenable work cancelation
  drm/i915: take display port power domain in DP HPD handler
  drm/i915: Don't try to enable cursor from setplane when crtc is disabled
  drm/i915: Skip load detect when intel_crtc->new_enable==true
  drm/i915: Fix locking for intel_enable_pipe_a()
parents c3735aeb 1a125d8a
...@@ -494,6 +494,36 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) ...@@ -494,6 +494,36 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
return true; return true;
} }
void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
{
spin_lock_irq(&dev_priv->irq_lock);
dev_priv->long_hpd_port_mask = 0;
dev_priv->short_hpd_port_mask = 0;
dev_priv->hpd_event_bits = 0;
spin_unlock_irq(&dev_priv->irq_lock);
cancel_work_sync(&dev_priv->dig_port_work);
cancel_work_sync(&dev_priv->hotplug_work);
cancel_delayed_work_sync(&dev_priv->hotplug_reenable_work);
}
static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
struct drm_encoder *encoder;
drm_modeset_lock_all(dev);
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
if (intel_encoder->suspend)
intel_encoder->suspend(intel_encoder);
}
drm_modeset_unlock_all(dev);
}
static int i915_drm_freeze(struct drm_device *dev) static int i915_drm_freeze(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -538,6 +568,9 @@ static int i915_drm_freeze(struct drm_device *dev) ...@@ -538,6 +568,9 @@ static int i915_drm_freeze(struct drm_device *dev)
flush_delayed_work(&dev_priv->rps.delayed_resume_work); flush_delayed_work(&dev_priv->rps.delayed_resume_work);
intel_runtime_pm_disable_interrupts(dev); intel_runtime_pm_disable_interrupts(dev);
intel_hpd_cancel_work(dev_priv);
intel_suspend_encoders(dev_priv);
intel_suspend_gt_powersave(dev); intel_suspend_gt_powersave(dev);
......
...@@ -1458,7 +1458,7 @@ struct drm_i915_private { ...@@ -1458,7 +1458,7 @@ struct drm_i915_private {
} hpd_mark; } hpd_mark;
} hpd_stats[HPD_NUM_PINS]; } hpd_stats[HPD_NUM_PINS];
u32 hpd_event_bits; u32 hpd_event_bits;
struct timer_list hotplug_reenable_timer; struct delayed_work hotplug_reenable_work;
struct i915_fbc fbc; struct i915_fbc fbc;
struct i915_drrs drrs; struct i915_drrs drrs;
...@@ -2178,6 +2178,7 @@ extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); ...@@ -2178,6 +2178,7 @@ extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); extern void i915_update_gfx_val(struct drm_i915_private *dev_priv);
int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on); int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on);
void intel_hpd_cancel_work(struct drm_i915_private *dev_priv);
extern void intel_console_resume(struct work_struct *work); extern void intel_console_resume(struct work_struct *work);
......
...@@ -1189,8 +1189,8 @@ static void i915_hotplug_work_func(struct work_struct *work) ...@@ -1189,8 +1189,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
* some connectors */ * some connectors */
if (hpd_disabled) { if (hpd_disabled) {
drm_kms_helper_poll_enable(dev); drm_kms_helper_poll_enable(dev);
mod_timer(&dev_priv->hotplug_reenable_timer, mod_delayed_work(system_wq, &dev_priv->hotplug_reenable_work,
jiffies + msecs_to_jiffies(I915_REENABLE_HOTPLUG_DELAY)); msecs_to_jiffies(I915_REENABLE_HOTPLUG_DELAY));
} }
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
...@@ -1213,11 +1213,6 @@ static void i915_hotplug_work_func(struct work_struct *work) ...@@ -1213,11 +1213,6 @@ static void i915_hotplug_work_func(struct work_struct *work)
drm_kms_helper_hotplug_event(dev); drm_kms_helper_hotplug_event(dev);
} }
static void intel_hpd_irq_uninstall(struct drm_i915_private *dev_priv)
{
del_timer_sync(&dev_priv->hotplug_reenable_timer);
}
static void ironlake_rps_change_irq_handler(struct drm_device *dev) static void ironlake_rps_change_irq_handler(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -3892,8 +3887,6 @@ static void gen8_irq_uninstall(struct drm_device *dev) ...@@ -3892,8 +3887,6 @@ static void gen8_irq_uninstall(struct drm_device *dev)
if (!dev_priv) if (!dev_priv)
return; return;
intel_hpd_irq_uninstall(dev_priv);
gen8_irq_reset(dev); gen8_irq_reset(dev);
} }
...@@ -3908,8 +3901,6 @@ static void valleyview_irq_uninstall(struct drm_device *dev) ...@@ -3908,8 +3901,6 @@ static void valleyview_irq_uninstall(struct drm_device *dev)
I915_WRITE(VLV_MASTER_IER, 0); I915_WRITE(VLV_MASTER_IER, 0);
intel_hpd_irq_uninstall(dev_priv);
for_each_pipe(pipe) for_each_pipe(pipe)
I915_WRITE(PIPESTAT(pipe), 0xffff); I915_WRITE(PIPESTAT(pipe), 0xffff);
...@@ -3988,8 +3979,6 @@ static void ironlake_irq_uninstall(struct drm_device *dev) ...@@ -3988,8 +3979,6 @@ static void ironlake_irq_uninstall(struct drm_device *dev)
if (!dev_priv) if (!dev_priv)
return; return;
intel_hpd_irq_uninstall(dev_priv);
ironlake_irq_reset(dev); ironlake_irq_reset(dev);
} }
...@@ -4360,8 +4349,6 @@ static void i915_irq_uninstall(struct drm_device * dev) ...@@ -4360,8 +4349,6 @@ static void i915_irq_uninstall(struct drm_device * dev)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int pipe; int pipe;
intel_hpd_irq_uninstall(dev_priv);
if (I915_HAS_HOTPLUG(dev)) { if (I915_HAS_HOTPLUG(dev)) {
I915_WRITE(PORT_HOTPLUG_EN, 0); I915_WRITE(PORT_HOTPLUG_EN, 0);
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
...@@ -4598,8 +4585,6 @@ static void i965_irq_uninstall(struct drm_device * dev) ...@@ -4598,8 +4585,6 @@ static void i965_irq_uninstall(struct drm_device * dev)
if (!dev_priv) if (!dev_priv)
return; return;
intel_hpd_irq_uninstall(dev_priv);
I915_WRITE(PORT_HOTPLUG_EN, 0); I915_WRITE(PORT_HOTPLUG_EN, 0);
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
...@@ -4615,14 +4600,18 @@ static void i965_irq_uninstall(struct drm_device * dev) ...@@ -4615,14 +4600,18 @@ static void i965_irq_uninstall(struct drm_device * dev)
I915_WRITE(IIR, I915_READ(IIR)); I915_WRITE(IIR, I915_READ(IIR));
} }
static void intel_hpd_irq_reenable(unsigned long data) static void intel_hpd_irq_reenable(struct work_struct *work)
{ {
struct drm_i915_private *dev_priv = (struct drm_i915_private *)data; struct drm_i915_private *dev_priv =
container_of(work, typeof(*dev_priv),
hotplug_reenable_work.work);
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
struct drm_mode_config *mode_config = &dev->mode_config; struct drm_mode_config *mode_config = &dev->mode_config;
unsigned long irqflags; unsigned long irqflags;
int i; int i;
intel_runtime_pm_get(dev_priv);
spin_lock_irqsave(&dev_priv->irq_lock, irqflags); spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
for (i = (HPD_NONE + 1); i < HPD_NUM_PINS; i++) { for (i = (HPD_NONE + 1); i < HPD_NUM_PINS; i++) {
struct drm_connector *connector; struct drm_connector *connector;
...@@ -4648,6 +4637,8 @@ static void intel_hpd_irq_reenable(unsigned long data) ...@@ -4648,6 +4637,8 @@ static void intel_hpd_irq_reenable(unsigned long data)
if (dev_priv->display.hpd_irq_setup) if (dev_priv->display.hpd_irq_setup)
dev_priv->display.hpd_irq_setup(dev); dev_priv->display.hpd_irq_setup(dev);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
intel_runtime_pm_put(dev_priv);
} }
void intel_irq_init(struct drm_device *dev) void intel_irq_init(struct drm_device *dev)
...@@ -4670,8 +4661,8 @@ void intel_irq_init(struct drm_device *dev) ...@@ -4670,8 +4661,8 @@ void intel_irq_init(struct drm_device *dev)
setup_timer(&dev_priv->gpu_error.hangcheck_timer, setup_timer(&dev_priv->gpu_error.hangcheck_timer,
i915_hangcheck_elapsed, i915_hangcheck_elapsed,
(unsigned long) dev); (unsigned long) dev);
setup_timer(&dev_priv->hotplug_reenable_timer, intel_hpd_irq_reenable, INIT_DELAYED_WORK(&dev_priv->hotplug_reenable_work,
(unsigned long) dev_priv); intel_hpd_irq_reenable);
pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
......
...@@ -699,16 +699,21 @@ intel_crt_detect(struct drm_connector *connector, bool force) ...@@ -699,16 +699,21 @@ intel_crt_detect(struct drm_connector *connector, bool force)
goto out; goto out;
} }
drm_modeset_acquire_init(&ctx, 0);
/* for pre-945g platforms use load detect */ /* for pre-945g platforms use load detect */
if (intel_get_load_detect_pipe(connector, NULL, &tmp, &ctx)) { if (intel_get_load_detect_pipe(connector, NULL, &tmp, &ctx)) {
if (intel_crt_detect_ddc(connector)) if (intel_crt_detect_ddc(connector))
status = connector_status_connected; status = connector_status_connected;
else else
status = intel_crt_load_detect(crt); status = intel_crt_load_detect(crt);
intel_release_load_detect_pipe(connector, &tmp, &ctx); intel_release_load_detect_pipe(connector, &tmp);
} else } else
status = connector_status_unknown; status = connector_status_unknown;
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
out: out:
intel_display_power_put(dev_priv, power_domain); intel_display_power_put(dev_priv, power_domain);
return status; return status;
......
...@@ -8462,8 +8462,6 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, ...@@ -8462,8 +8462,6 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
connector->base.id, connector->name, connector->base.id, connector->name,
encoder->base.id, encoder->name); encoder->base.id, encoder->name);
drm_modeset_acquire_init(ctx, 0);
retry: retry:
ret = drm_modeset_lock(&config->connection_mutex, ctx); ret = drm_modeset_lock(&config->connection_mutex, ctx);
if (ret) if (ret)
...@@ -8502,10 +8500,14 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, ...@@ -8502,10 +8500,14 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
i++; i++;
if (!(encoder->possible_crtcs & (1 << i))) if (!(encoder->possible_crtcs & (1 << i)))
continue; continue;
if (!possible_crtc->enabled) { if (possible_crtc->enabled)
crtc = possible_crtc; continue;
break; /* This can occur when applying the pipe A quirk on resume. */
} if (to_intel_crtc(possible_crtc)->new_enabled)
continue;
crtc = possible_crtc;
break;
} }
/* /*
...@@ -8574,15 +8576,11 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, ...@@ -8574,15 +8576,11 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
goto retry; goto retry;
} }
drm_modeset_drop_locks(ctx);
drm_modeset_acquire_fini(ctx);
return false; return false;
} }
void intel_release_load_detect_pipe(struct drm_connector *connector, void intel_release_load_detect_pipe(struct drm_connector *connector,
struct intel_load_detect_pipe *old, struct intel_load_detect_pipe *old)
struct drm_modeset_acquire_ctx *ctx)
{ {
struct intel_encoder *intel_encoder = struct intel_encoder *intel_encoder =
intel_attached_encoder(connector); intel_attached_encoder(connector);
...@@ -8606,17 +8604,12 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, ...@@ -8606,17 +8604,12 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
drm_framebuffer_unreference(old->release_fb); drm_framebuffer_unreference(old->release_fb);
} }
goto unlock;
return; return;
} }
/* Switch crtc and encoder back off if necessary */ /* Switch crtc and encoder back off if necessary */
if (old->dpms_mode != DRM_MODE_DPMS_ON) if (old->dpms_mode != DRM_MODE_DPMS_ON)
connector->funcs->dpms(connector, old->dpms_mode); connector->funcs->dpms(connector, old->dpms_mode);
unlock:
drm_modeset_drop_locks(ctx);
drm_modeset_acquire_fini(ctx);
} }
static int i9xx_pll_refclk(struct drm_device *dev, static int i9xx_pll_refclk(struct drm_device *dev,
...@@ -11700,8 +11693,8 @@ intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -11700,8 +11693,8 @@ intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
}; };
const struct drm_rect clip = { const struct drm_rect clip = {
/* integer pixels */ /* integer pixels */
.x2 = intel_crtc->config.pipe_src_w, .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
.y2 = intel_crtc->config.pipe_src_h, .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
}; };
bool visible; bool visible;
int ret; int ret;
...@@ -12659,7 +12652,7 @@ static void intel_enable_pipe_a(struct drm_device *dev) ...@@ -12659,7 +12652,7 @@ static void intel_enable_pipe_a(struct drm_device *dev)
struct intel_connector *connector; struct intel_connector *connector;
struct drm_connector *crt = NULL; struct drm_connector *crt = NULL;
struct intel_load_detect_pipe load_detect_temp; struct intel_load_detect_pipe load_detect_temp;
struct drm_modeset_acquire_ctx ctx; struct drm_modeset_acquire_ctx *ctx = dev->mode_config.acquire_ctx;
/* We can't just switch on the pipe A, we need to set things up with a /* We can't just switch on the pipe A, we need to set things up with a
* proper mode and output configuration. As a gross hack, enable pipe A * proper mode and output configuration. As a gross hack, enable pipe A
...@@ -12676,10 +12669,8 @@ static void intel_enable_pipe_a(struct drm_device *dev) ...@@ -12676,10 +12669,8 @@ static void intel_enable_pipe_a(struct drm_device *dev)
if (!crt) if (!crt)
return; return;
if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp, &ctx)) if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp, ctx))
intel_release_load_detect_pipe(crt, &load_detect_temp, &ctx); intel_release_load_detect_pipe(crt, &load_detect_temp);
} }
static bool static bool
...@@ -13112,7 +13103,7 @@ void intel_modeset_cleanup(struct drm_device *dev) ...@@ -13112,7 +13103,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
* experience fancy races otherwise. * experience fancy races otherwise.
*/ */
drm_irq_uninstall(dev); drm_irq_uninstall(dev);
cancel_work_sync(&dev_priv->hotplug_work); intel_hpd_cancel_work(dev_priv);
dev_priv->pm._irqs_disabled = true; dev_priv->pm._irqs_disabled = true;
/* /*
......
...@@ -3553,6 +3553,9 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) ...@@ -3553,6 +3553,9 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
if (WARN_ON(!intel_encoder->base.crtc)) if (WARN_ON(!intel_encoder->base.crtc))
return; return;
if (!to_intel_crtc(intel_encoder->base.crtc)->active)
return;
/* Try to read receiver status if the link appears to be up */ /* Try to read receiver status if the link appears to be up */
if (!intel_dp_get_link_status(intel_dp, link_status)) { if (!intel_dp_get_link_status(intel_dp, link_status)) {
return; return;
...@@ -4003,6 +4006,16 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) ...@@ -4003,6 +4006,16 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
kfree(intel_dig_port); kfree(intel_dig_port);
} }
static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder)
{
struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base);
if (!is_edp(intel_dp))
return;
edp_panel_vdd_off_sync(intel_dp);
}
static void intel_dp_encoder_reset(struct drm_encoder *encoder) static void intel_dp_encoder_reset(struct drm_encoder *encoder)
{ {
intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder)); intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder));
...@@ -4037,15 +4050,21 @@ bool ...@@ -4037,15 +4050,21 @@ bool
intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
{ {
struct intel_dp *intel_dp = &intel_dig_port->dp; struct intel_dp *intel_dp = &intel_dig_port->dp;
struct intel_encoder *intel_encoder = &intel_dig_port->base;
struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int ret; enum intel_display_power_domain power_domain;
bool ret = true;
if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) if (intel_dig_port->base.type != INTEL_OUTPUT_EDP)
intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT;
DRM_DEBUG_KMS("got hpd irq on port %d - %s\n", intel_dig_port->port, DRM_DEBUG_KMS("got hpd irq on port %d - %s\n", intel_dig_port->port,
long_hpd ? "long" : "short"); long_hpd ? "long" : "short");
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
if (long_hpd) { if (long_hpd) {
if (!ibx_digital_port_connected(dev_priv, intel_dig_port)) if (!ibx_digital_port_connected(dev_priv, intel_dig_port))
goto mst_fail; goto mst_fail;
...@@ -4061,8 +4080,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) ...@@ -4061,8 +4080,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
} else { } else {
if (intel_dp->is_mst) { if (intel_dp->is_mst) {
ret = intel_dp_check_mst_status(intel_dp); if (intel_dp_check_mst_status(intel_dp) == -EINVAL)
if (ret == -EINVAL)
goto mst_fail; goto mst_fail;
} }
...@@ -4076,7 +4094,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) ...@@ -4076,7 +4094,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
drm_modeset_unlock(&dev->mode_config.connection_mutex); drm_modeset_unlock(&dev->mode_config.connection_mutex);
} }
} }
return false; ret = false;
goto put_power;
mst_fail: mst_fail:
/* if we were in MST mode, and device is not there get out of MST mode */ /* if we were in MST mode, and device is not there get out of MST mode */
if (intel_dp->is_mst) { if (intel_dp->is_mst) {
...@@ -4084,7 +4103,10 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) ...@@ -4084,7 +4103,10 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
intel_dp->is_mst = false; intel_dp->is_mst = false;
drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
} }
return true; put_power:
intel_display_power_put(dev_priv, power_domain);
return ret;
} }
/* Return which DP Port should be selected for Transcoder DP control */ /* Return which DP Port should be selected for Transcoder DP control */
...@@ -4722,6 +4744,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) ...@@ -4722,6 +4744,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
intel_encoder->disable = intel_disable_dp; intel_encoder->disable = intel_disable_dp;
intel_encoder->get_hw_state = intel_dp_get_hw_state; intel_encoder->get_hw_state = intel_dp_get_hw_state;
intel_encoder->get_config = intel_dp_get_config; intel_encoder->get_config = intel_dp_get_config;
intel_encoder->suspend = intel_dp_encoder_suspend;
if (IS_CHERRYVIEW(dev)) { if (IS_CHERRYVIEW(dev)) {
intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable; intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
intel_encoder->pre_enable = chv_pre_enable_dp; intel_encoder->pre_enable = chv_pre_enable_dp;
......
...@@ -153,6 +153,12 @@ struct intel_encoder { ...@@ -153,6 +153,12 @@ struct intel_encoder {
* be set correctly before calling this function. */ * be set correctly before calling this function. */
void (*get_config)(struct intel_encoder *, void (*get_config)(struct intel_encoder *,
struct intel_crtc_config *pipe_config); struct intel_crtc_config *pipe_config);
/*
* Called during system suspend after all pending requests for the
* encoder are flushed (for example for DP AUX transactions) and
* device interrupts are disabled.
*/
void (*suspend)(struct intel_encoder *);
int crtc_mask; int crtc_mask;
enum hpd_pin hpd_pin; enum hpd_pin hpd_pin;
}; };
...@@ -830,8 +836,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, ...@@ -830,8 +836,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
struct intel_load_detect_pipe *old, struct intel_load_detect_pipe *old,
struct drm_modeset_acquire_ctx *ctx); struct drm_modeset_acquire_ctx *ctx);
void intel_release_load_detect_pipe(struct drm_connector *connector, void intel_release_load_detect_pipe(struct drm_connector *connector,
struct intel_load_detect_pipe *old, struct intel_load_detect_pipe *old);
struct drm_modeset_acquire_ctx *ctx);
int intel_pin_and_fence_fb_obj(struct drm_device *dev, int intel_pin_and_fence_fb_obj(struct drm_device *dev,
struct drm_i915_gem_object *obj, struct drm_i915_gem_object *obj,
struct intel_engine_cs *pipelined); struct intel_engine_cs *pipelined);
......
...@@ -1323,11 +1323,16 @@ intel_tv_detect(struct drm_connector *connector, bool force) ...@@ -1323,11 +1323,16 @@ intel_tv_detect(struct drm_connector *connector, bool force)
struct intel_load_detect_pipe tmp; struct intel_load_detect_pipe tmp;
struct drm_modeset_acquire_ctx ctx; struct drm_modeset_acquire_ctx ctx;
drm_modeset_acquire_init(&ctx, 0);
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, &ctx); intel_release_load_detect_pipe(connector, &tmp);
} else } else
return connector_status_unknown; return connector_status_unknown;
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
} else } else
return connector->status; return connector->status;
......
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