mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
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
This commit is contained in:
commit
2cc79544bd
8 changed files with 79 additions and 22 deletions
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 @@
|
||||||
#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)
|
||||||
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)
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
|
||||||
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,
|
||||||
{
|
{
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
#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)
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in a new issue