Commit 2cc79544 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-next

A bunch of fixes, nothing truely horrible:
- Fix PCH irq handling race which resulted in missed gmbus/dp aux irqs
  and subsequent fallout (Paulo)
- Fixup off-by-one in our hsw id table (Kenneth)
- Fixup ilk rc6 support (disabled by default), regression introduced in
  3.8
- g4x plane w/a from Egbert Eich
- gen2/3/4 dpms suspend/standy fixes for VGA outputs from Patrik Jakobsson
- Workaround dying ivb machines with less aggressive rc6 values (Stéphane
  Marchesin)

* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel:
  drm/i915: Turn off hsync and vsync on ADPA when disabling crt
  drm/i915: Fix incorrect definition of ADPA HSYNC and VSYNC bits
  drm/i915: also disable south interrupts when handling them
  drm/i915: enable irqs earlier when resuming
  drm/i915: Increase the RC6p threshold.
  DRM/i915: On G45 enable cursor plane briefly after enabling the display plane.
  drm/i915: Fix Haswell/CRW PCI IDs.
  drm/i915: Don't clobber crtc->fb when queue_flip fails
  drm/i915: wait_event_timeout's timeout is in jiffies
  drm/i915: Fix missing variable initilization
parents 64e38a8c f40ebd6b
...@@ -379,15 +379,15 @@ static const struct pci_device_id pciidlist[] = { /* aka */ ...@@ -379,15 +379,15 @@ static const struct pci_device_id pciidlist[] = { /* aka */
INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */
INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */
INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */ INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */
INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */ INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */
INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */
INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */ INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */
INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */ INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */
INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */ INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */
INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */ INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */
INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */ INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */
INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */ INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */
INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */
INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */
INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info),
INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info),
...@@ -495,6 +495,7 @@ static int i915_drm_freeze(struct drm_device *dev) ...@@ -495,6 +495,7 @@ static int i915_drm_freeze(struct drm_device *dev)
intel_modeset_disable(dev); intel_modeset_disable(dev);
drm_irq_uninstall(dev); drm_irq_uninstall(dev);
dev_priv->enable_hotplug_processing = false;
} }
i915_save_state(dev); i915_save_state(dev);
...@@ -568,10 +569,20 @@ static int __i915_drm_thaw(struct drm_device *dev) ...@@ -568,10 +569,20 @@ static int __i915_drm_thaw(struct drm_device *dev)
error = i915_gem_init_hw(dev); error = i915_gem_init_hw(dev);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
/* We need working interrupts for modeset enabling ... */
drm_irq_install(dev);
intel_modeset_init_hw(dev); intel_modeset_init_hw(dev);
intel_modeset_setup_hw_state(dev, false); intel_modeset_setup_hw_state(dev, false);
drm_irq_install(dev);
/*
* ... but also need to make sure that hotplug processing
* doesn't cause havoc. Like in the driver load code we don't
* bother with the tiny race here where we might loose hotplug
* notifications.
* */
intel_hpd_init(dev); intel_hpd_init(dev);
dev_priv->enable_hotplug_processing = true;
} }
intel_opregion_init(dev); intel_opregion_init(dev);
......
...@@ -701,7 +701,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) ...@@ -701,7 +701,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
{ {
struct drm_device *dev = (struct drm_device *) arg; struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
u32 de_iir, gt_iir, de_ier, pm_iir; u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier;
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
int i; int i;
...@@ -711,6 +711,15 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) ...@@ -711,6 +711,15 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
de_ier = I915_READ(DEIER); de_ier = I915_READ(DEIER);
I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
/* Disable south interrupts. We'll only write to SDEIIR once, so further
* interrupts will will be stored on its back queue, and then we'll be
* able to process them after we restore SDEIER (as soon as we restore
* it, we'll get an interrupt if SDEIIR still has something to process
* due to its back queue). */
sde_ier = I915_READ(SDEIER);
I915_WRITE(SDEIER, 0);
POSTING_READ(SDEIER);
gt_iir = I915_READ(GTIIR); gt_iir = I915_READ(GTIIR);
if (gt_iir) { if (gt_iir) {
snb_gt_irq_handler(dev, dev_priv, gt_iir); snb_gt_irq_handler(dev, dev_priv, gt_iir);
...@@ -759,6 +768,8 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) ...@@ -759,6 +768,8 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
I915_WRITE(DEIER, de_ier); I915_WRITE(DEIER, de_ier);
POSTING_READ(DEIER); POSTING_READ(DEIER);
I915_WRITE(SDEIER, sde_ier);
POSTING_READ(SDEIER);
return ret; return ret;
} }
...@@ -778,7 +789,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) ...@@ -778,7 +789,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
struct drm_device *dev = (struct drm_device *) arg; struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE; int ret = IRQ_NONE;
u32 de_iir, gt_iir, de_ier, pm_iir; u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier;
atomic_inc(&dev_priv->irq_received); atomic_inc(&dev_priv->irq_received);
...@@ -787,6 +798,15 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) ...@@ -787,6 +798,15 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
POSTING_READ(DEIER); POSTING_READ(DEIER);
/* Disable south interrupts. We'll only write to SDEIIR once, so further
* interrupts will will be stored on its back queue, and then we'll be
* able to process them after we restore SDEIER (as soon as we restore
* it, we'll get an interrupt if SDEIIR still has something to process
* due to its back queue). */
sde_ier = I915_READ(SDEIER);
I915_WRITE(SDEIER, 0);
POSTING_READ(SDEIER);
de_iir = I915_READ(DEIIR); de_iir = I915_READ(DEIIR);
gt_iir = I915_READ(GTIIR); gt_iir = I915_READ(GTIIR);
pm_iir = I915_READ(GEN6_PMIIR); pm_iir = I915_READ(GEN6_PMIIR);
...@@ -849,6 +869,8 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) ...@@ -849,6 +869,8 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
done: done:
I915_WRITE(DEIER, de_ier); I915_WRITE(DEIER, de_ier);
POSTING_READ(DEIER); POSTING_READ(DEIER);
I915_WRITE(SDEIER, sde_ier);
POSTING_READ(SDEIER);
return ret; return ret;
} }
......
...@@ -1613,9 +1613,9 @@ ...@@ -1613,9 +1613,9 @@
#define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) #define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16)
#define ADPA_USE_VGA_HVPOLARITY (1<<15) #define ADPA_USE_VGA_HVPOLARITY (1<<15)
#define ADPA_SETS_HVPOLARITY 0 #define ADPA_SETS_HVPOLARITY 0
#define ADPA_VSYNC_CNTL_DISABLE (1<<11) #define ADPA_VSYNC_CNTL_DISABLE (1<<10)
#define ADPA_VSYNC_CNTL_ENABLE 0 #define ADPA_VSYNC_CNTL_ENABLE 0
#define ADPA_HSYNC_CNTL_DISABLE (1<<10) #define ADPA_HSYNC_CNTL_DISABLE (1<<11)
#define ADPA_HSYNC_CNTL_ENABLE 0 #define ADPA_HSYNC_CNTL_ENABLE 0
#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) #define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
#define ADPA_VSYNC_ACTIVE_LOW 0 #define ADPA_VSYNC_ACTIVE_LOW 0
......
...@@ -88,7 +88,7 @@ static void intel_disable_crt(struct intel_encoder *encoder) ...@@ -88,7 +88,7 @@ static void intel_disable_crt(struct intel_encoder *encoder)
u32 temp; u32 temp;
temp = I915_READ(crt->adpa_reg); temp = I915_READ(crt->adpa_reg);
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
temp &= ~ADPA_DAC_ENABLE; temp &= ~ADPA_DAC_ENABLE;
I915_WRITE(crt->adpa_reg, temp); I915_WRITE(crt->adpa_reg, temp);
} }
......
...@@ -1391,8 +1391,8 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder) ...@@ -1391,8 +1391,8 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
struct intel_dp *intel_dp = &intel_dig_port->dp; struct intel_dp *intel_dp = &intel_dig_port->dp;
struct drm_i915_private *dev_priv = encoder->dev->dev_private; struct drm_i915_private *dev_priv = encoder->dev->dev_private;
enum port port = intel_dig_port->port; enum port port = intel_dig_port->port;
bool wait;
uint32_t val; uint32_t val;
bool wait = false;
if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) { if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
val = I915_READ(DDI_BUF_CTL(port)); val = I915_READ(DDI_BUF_CTL(port));
......
...@@ -3604,6 +3604,30 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) ...@@ -3604,6 +3604,30 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
*/ */
} }
/**
* i9xx_fixup_plane - ugly workaround for G45 to fire up the hardware
* cursor plane briefly if not already running after enabling the display
* plane.
* This workaround avoids occasional blank screens when self refresh is
* enabled.
*/
static void
g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe)
{
u32 cntl = I915_READ(CURCNTR(pipe));
if ((cntl & CURSOR_MODE) == 0) {
u32 fw_bcl_self = I915_READ(FW_BLC_SELF);
I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN);
I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX);
intel_wait_for_vblank(dev_priv->dev, pipe);
I915_WRITE(CURCNTR(pipe), cntl);
I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
I915_WRITE(FW_BLC_SELF, fw_bcl_self);
}
}
static void i9xx_crtc_enable(struct drm_crtc *crtc) static void i9xx_crtc_enable(struct drm_crtc *crtc)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
...@@ -3629,6 +3653,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) ...@@ -3629,6 +3653,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
intel_enable_pipe(dev_priv, pipe, false); intel_enable_pipe(dev_priv, pipe, false);
intel_enable_plane(dev_priv, plane, pipe); intel_enable_plane(dev_priv, plane, pipe);
if (IS_G4X(dev))
g4x_fixup_plane(dev_priv, pipe);
intel_crtc_load_lut(crtc); intel_crtc_load_lut(crtc);
intel_update_fbc(dev); intel_update_fbc(dev);
...@@ -7256,8 +7282,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -7256,8 +7282,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_framebuffer *intel_fb; struct drm_framebuffer *old_fb = crtc->fb;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_unpin_work *work; struct intel_unpin_work *work;
unsigned long flags; unsigned long flags;
...@@ -7282,8 +7308,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -7282,8 +7308,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
work->event = event; work->event = event;
work->crtc = crtc; work->crtc = crtc;
intel_fb = to_intel_framebuffer(crtc->fb); work->old_fb_obj = to_intel_framebuffer(old_fb)->obj;
work->old_fb_obj = intel_fb->obj;
INIT_WORK(&work->work, intel_unpin_work_fn); INIT_WORK(&work->work, intel_unpin_work_fn);
ret = drm_vblank_get(dev, intel_crtc->pipe); ret = drm_vblank_get(dev, intel_crtc->pipe);
...@@ -7303,9 +7328,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -7303,9 +7328,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
intel_crtc->unpin_work = work; intel_crtc->unpin_work = work;
spin_unlock_irqrestore(&dev->event_lock, flags); spin_unlock_irqrestore(&dev->event_lock, flags);
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;
if (atomic_read(&intel_crtc->unpin_work_count) >= 2) if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
flush_workqueue(dev_priv->wq); flush_workqueue(dev_priv->wq);
...@@ -7340,6 +7362,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -7340,6 +7362,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
cleanup_pending: cleanup_pending:
atomic_dec(&intel_crtc->unpin_work_count); atomic_dec(&intel_crtc->unpin_work_count);
crtc->fb = old_fb;
drm_gem_object_unreference(&work->old_fb_obj->base); drm_gem_object_unreference(&work->old_fb_obj->base);
drm_gem_object_unreference(&obj->base); drm_gem_object_unreference(&obj->base);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
......
...@@ -353,7 +353,8 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) ...@@ -353,7 +353,8 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq)
#define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0) #define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0)
if (has_aux_irq) if (has_aux_irq)
done = wait_event_timeout(dev_priv->gmbus_wait_queue, C, 10); done = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
msecs_to_jiffies(10));
else else
done = wait_for_atomic(C, 10) == 0; done = wait_for_atomic(C, 10) == 0;
if (!done) if (!done)
......
...@@ -2574,7 +2574,7 @@ static void gen6_enable_rps(struct drm_device *dev) ...@@ -2574,7 +2574,7 @@ static void gen6_enable_rps(struct drm_device *dev)
I915_WRITE(GEN6_RC_SLEEP, 0); I915_WRITE(GEN6_RC_SLEEP, 0);
I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
I915_WRITE(GEN6_RC6_THRESHOLD, 50000); I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); I915_WRITE(GEN6_RC6p_THRESHOLD, 150000);
I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
/* Check if we are enabling RC6 */ /* Check if we are enabling RC6 */
......
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