Commit 12f0e670 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-2012-07-06' of...

Merge tag 'drm-intel-next-2012-07-06' of git://people.freedesktop.org/~danvet/drm-intel into drm-next

Daniel writes:
New pull for -next. Highlights:
- rc6/turbo support for hsw (Eugeni)
- improve corner-case of the reset handling code - gpu reset handling
  should be rock-solid now
- support for fb offset > 4096 pixels on gen4+ (yeah, you need some fairly
  big screens to hit that)
- the "Flush Me Harder" patch to fix the gen6+ fallout from disabling the
  flushing_list
- no more /dev/agpgart on gen6+!
- HAS_PCH_xxx improvements from Paulo
- a few minor bits&pieces all over, most of it in thew hsw code

* tag 'drm-intel-next-2012-07-06' of git://people.freedesktop.org/~danvet/drm-intel: (40 commits)
  drm/i915: program FDI_RX TP and FDI delays
  drm/i915: introduce for_each_encoder_on_crtc
  drm/i915: adjust framebuffer base address on gen4+
  drm/i915: introduce crtc->dspaddr_offset
  drm/i915: Reject page flips with changed format/offset/pitch
  drm/i915: Zero initialize mode_cmd
  drm/i915: don't return a spurious -EIO from intel_ring_begin
  drm/i915: properly SIGBUS on I/O errors
  drm/i915: don't hang userspace when the gpu reset is stuck
  drm/i915: non-interruptible sleeps can't handle -EAGAIN
  drm/i915: don't trylock in the gpu reset code
  drm/i915: fix PIPE_DDI_PORT_MASK
  drm/i915: prevent bogus intel_update_fbc notifications
  drm/i915: re-initialize DDI buffer translations after resume
  drm/i915: don't ironlake_init_pch_refclk() on LPT
  drm/i915: get rid of dev_priv->info->has_pch_split
  drm/i915: add PCH_NONE to enum intel_pch
  drm/i915: prefer wide & slow to fast & narrow in DP configs
  drm/i915: fix up ilk rc6 disabling confusion
  drm/i915: move force wake support into intel_pm
  ...
parents 74da01dc 4acf5186
...@@ -903,17 +903,6 @@ static struct pci_device_id agp_intel_pci_table[] = { ...@@ -903,17 +903,6 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB),
ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB),
ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB),
ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB),
ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB),
ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB),
ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_HB),
ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_HB),
ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB),
ID(PCI_DEVICE_ID_INTEL_VALLEYVIEW_HB),
ID(PCI_DEVICE_ID_INTEL_HASWELL_HB),
ID(PCI_DEVICE_ID_INTEL_HASWELL_M_HB),
ID(PCI_DEVICE_ID_INTEL_HASWELL_S_HB),
ID(PCI_DEVICE_ID_INTEL_HASWELL_E_HB),
{ } { }
}; };
......
...@@ -1414,7 +1414,7 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) ...@@ -1414,7 +1414,7 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
if (!ap) if (!ap)
return; return;
ap->ranges[0].base = dev_priv->dev->agp->base; ap->ranges[0].base = dev_priv->mm.gtt->gma_bus_addr;
ap->ranges[0].size = ap->ranges[0].size =
dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
primary = primary =
...@@ -1547,7 +1547,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -1547,7 +1547,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_mtrrfree; goto out_mtrrfree;
} }
/* This must be called before any calls to HAS_PCH_* */
intel_detect_pch(dev);
intel_irq_init(dev); intel_irq_init(dev);
intel_gt_init(dev);
/* Try to make sure MCHBAR is enabled before poking at it */ /* Try to make sure MCHBAR is enabled before poking at it */
intel_setup_mchbar(dev); intel_setup_mchbar(dev);
...@@ -1580,7 +1584,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -1580,7 +1584,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!IS_I945G(dev) && !IS_I945GM(dev)) if (!IS_I945G(dev) && !IS_I945GM(dev))
pci_enable_msi(dev->pdev); pci_enable_msi(dev->pdev);
spin_lock_init(&dev_priv->gt_lock);
spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->irq_lock);
spin_lock_init(&dev_priv->error_lock); spin_lock_init(&dev_priv->error_lock);
spin_lock_init(&dev_priv->rps_lock); spin_lock_init(&dev_priv->rps_lock);
...@@ -1599,8 +1602,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -1599,8 +1602,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
/* Start out suspended */ /* Start out suspended */
dev_priv->mm.suspended = 1; dev_priv->mm.suspended = 1;
intel_detect_pch(dev);
if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (drm_core_check_feature(dev, DRIVER_MODESET)) {
ret = i915_load_modeset_init(dev); ret = i915_load_modeset_init(dev);
if (ret < 0) { if (ret < 0) {
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "drm.h" #include "drm.h"
#include "i915_drm.h" #include "i915_drm.h"
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h" #include "intel_drv.h"
#include <linux/console.h> #include <linux/console.h>
...@@ -215,7 +216,6 @@ static const struct intel_device_info intel_ironlake_d_info = { ...@@ -215,7 +216,6 @@ static const struct intel_device_info intel_ironlake_d_info = {
.gen = 5, .gen = 5,
.need_gfx_hws = 1, .has_hotplug = 1, .need_gfx_hws = 1, .has_hotplug = 1,
.has_bsd_ring = 1, .has_bsd_ring = 1,
.has_pch_split = 1,
}; };
static const struct intel_device_info intel_ironlake_m_info = { static const struct intel_device_info intel_ironlake_m_info = {
...@@ -223,7 +223,6 @@ static const struct intel_device_info intel_ironlake_m_info = { ...@@ -223,7 +223,6 @@ static const struct intel_device_info intel_ironlake_m_info = {
.need_gfx_hws = 1, .has_hotplug = 1, .need_gfx_hws = 1, .has_hotplug = 1,
.has_fbc = 1, .has_fbc = 1,
.has_bsd_ring = 1, .has_bsd_ring = 1,
.has_pch_split = 1,
}; };
static const struct intel_device_info intel_sandybridge_d_info = { static const struct intel_device_info intel_sandybridge_d_info = {
...@@ -232,7 +231,6 @@ static const struct intel_device_info intel_sandybridge_d_info = { ...@@ -232,7 +231,6 @@ static const struct intel_device_info intel_sandybridge_d_info = {
.has_bsd_ring = 1, .has_bsd_ring = 1,
.has_blt_ring = 1, .has_blt_ring = 1,
.has_llc = 1, .has_llc = 1,
.has_pch_split = 1,
.has_force_wake = 1, .has_force_wake = 1,
}; };
...@@ -243,7 +241,6 @@ static const struct intel_device_info intel_sandybridge_m_info = { ...@@ -243,7 +241,6 @@ static const struct intel_device_info intel_sandybridge_m_info = {
.has_bsd_ring = 1, .has_bsd_ring = 1,
.has_blt_ring = 1, .has_blt_ring = 1,
.has_llc = 1, .has_llc = 1,
.has_pch_split = 1,
.has_force_wake = 1, .has_force_wake = 1,
}; };
...@@ -253,7 +250,6 @@ static const struct intel_device_info intel_ivybridge_d_info = { ...@@ -253,7 +250,6 @@ static const struct intel_device_info intel_ivybridge_d_info = {
.has_bsd_ring = 1, .has_bsd_ring = 1,
.has_blt_ring = 1, .has_blt_ring = 1,
.has_llc = 1, .has_llc = 1,
.has_pch_split = 1,
.has_force_wake = 1, .has_force_wake = 1,
}; };
...@@ -264,7 +260,6 @@ static const struct intel_device_info intel_ivybridge_m_info = { ...@@ -264,7 +260,6 @@ static const struct intel_device_info intel_ivybridge_m_info = {
.has_bsd_ring = 1, .has_bsd_ring = 1,
.has_blt_ring = 1, .has_blt_ring = 1,
.has_llc = 1, .has_llc = 1,
.has_pch_split = 1,
.has_force_wake = 1, .has_force_wake = 1,
}; };
...@@ -292,7 +287,6 @@ static const struct intel_device_info intel_haswell_d_info = { ...@@ -292,7 +287,6 @@ static const struct intel_device_info intel_haswell_d_info = {
.has_bsd_ring = 1, .has_bsd_ring = 1,
.has_blt_ring = 1, .has_blt_ring = 1,
.has_llc = 1, .has_llc = 1,
.has_pch_split = 1,
.has_force_wake = 1, .has_force_wake = 1,
}; };
...@@ -302,7 +296,6 @@ static const struct intel_device_info intel_haswell_m_info = { ...@@ -302,7 +296,6 @@ static const struct intel_device_info intel_haswell_m_info = {
.has_bsd_ring = 1, .has_bsd_ring = 1,
.has_blt_ring = 1, .has_blt_ring = 1,
.has_llc = 1, .has_llc = 1,
.has_pch_split = 1,
.has_force_wake = 1, .has_force_wake = 1,
}; };
...@@ -432,135 +425,6 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) ...@@ -432,135 +425,6 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
return 1; return 1;
} }
void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
int count;
count = 0;
while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
udelay(10);
I915_WRITE_NOTRACE(FORCEWAKE, 1);
POSTING_READ(FORCEWAKE);
count = 0;
while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0)
udelay(10);
}
void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
{
int count;
count = 0;
while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
udelay(10);
I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1));
POSTING_READ(FORCEWAKE_MT);
count = 0;
while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
udelay(10);
}
/*
* Generally this is called implicitly by the register read function. However,
* if some sequence requires the GT to not power down then this function should
* be called at the beginning of the sequence followed by a call to
* gen6_gt_force_wake_put() at the end of the sequence.
*/
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
if (dev_priv->forcewake_count++ == 0)
dev_priv->display.force_wake_get(dev_priv);
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}
static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
{
u32 gtfifodbg;
gtfifodbg = I915_READ_NOTRACE(GTFIFODBG);
if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK,
"MMIO read or write has been dropped %x\n", gtfifodbg))
I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK);
}
void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE, 0);
/* The below doubles as a POSTING_READ */
gen6_gt_check_fifodbg(dev_priv);
}
void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1));
/* The below doubles as a POSTING_READ */
gen6_gt_check_fifodbg(dev_priv);
}
/*
* see gen6_gt_force_wake_get()
*/
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
if (--dev_priv->forcewake_count == 0)
dev_priv->display.force_wake_put(dev_priv);
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}
int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
{
int ret = 0;
if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
int loop = 500;
u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
udelay(10);
fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
}
if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
++ret;
dev_priv->gt_fifo_count = fifo;
}
dev_priv->gt_fifo_count--;
return ret;
}
void vlv_force_wake_get(struct drm_i915_private *dev_priv)
{
int count;
count = 0;
/* Already awake? */
if ((I915_READ(0x130094) & 0xa1) == 0xa1)
return;
I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffffffff);
POSTING_READ(FORCEWAKE_VLV);
count = 0;
while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK_VLV) & 1) == 0)
udelay(10);
}
void vlv_force_wake_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE_VLV, 0xffff0000);
/* FIXME: confirm VLV behavior with Punit folks */
POSTING_READ(FORCEWAKE_VLV);
}
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;
...@@ -640,7 +504,7 @@ static int i915_drm_thaw(struct drm_device *dev) ...@@ -640,7 +504,7 @@ static int i915_drm_thaw(struct drm_device *dev)
/* KMS EnterVT equivalent */ /* KMS EnterVT equivalent */
if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (drm_core_check_feature(dev, DRIVER_MODESET)) {
if (HAS_PCH_SPLIT(dev)) if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
ironlake_init_pch_refclk(dev); ironlake_init_pch_refclk(dev);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
...@@ -797,9 +661,9 @@ static int gen6_do_reset(struct drm_device *dev) ...@@ -797,9 +661,9 @@ static int gen6_do_reset(struct drm_device *dev)
/* If reset with a user forcewake, try to restore, otherwise turn it off */ /* If reset with a user forcewake, try to restore, otherwise turn it off */
if (dev_priv->forcewake_count) if (dev_priv->forcewake_count)
dev_priv->display.force_wake_get(dev_priv); dev_priv->gt.force_wake_get(dev_priv);
else else
dev_priv->display.force_wake_put(dev_priv); dev_priv->gt.force_wake_put(dev_priv);
/* Restore fifo count */ /* Restore fifo count */
dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
...@@ -866,8 +730,7 @@ int i915_reset(struct drm_device *dev) ...@@ -866,8 +730,7 @@ int i915_reset(struct drm_device *dev)
if (!i915_try_reset) if (!i915_try_reset)
return 0; return 0;
if (!mutex_trylock(&dev->struct_mutex)) mutex_lock(&dev->struct_mutex);
return -EBUSY;
i915_gem_reset(dev); i915_gem_reset(dev);
...@@ -930,10 +793,12 @@ int i915_reset(struct drm_device *dev) ...@@ -930,10 +793,12 @@ int i915_reset(struct drm_device *dev)
return 0; return 0;
} }
static int __devinit static int __devinit
i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{ {
struct intel_device_info *intel_info =
(struct intel_device_info *) ent->driver_data;
/* Only bind to function 0 of the device. Early generations /* Only bind to function 0 of the device. Early generations
* used function 1 as a placeholder for multi-head. This causes * used function 1 as a placeholder for multi-head. This causes
* us confusion instead, especially on the systems where both * us confusion instead, especially on the systems where both
...@@ -942,6 +807,18 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -942,6 +807,18 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (PCI_FUNC(pdev->devfn)) if (PCI_FUNC(pdev->devfn))
return -ENODEV; return -ENODEV;
/* We've managed to ship a kms-enabled ddx that shipped with an XvMC
* implementation for gen3 (and only gen3) that used legacy drm maps
* (gasp!) to share buffers between X and the client. Hence we need to
* keep around the fake agp stuff for gen3, even when kms is enabled. */
if (intel_info->gen != 3) {
driver.driver_features &=
~(DRIVER_USE_AGP | DRIVER_REQUIRE_AGP);
} else if (!intel_agp_enabled) {
DRM_ERROR("drm/i915 can't work without intel_agp module!\n");
return -ENODEV;
}
return drm_get_pci_dev(pdev, ent, &driver); return drm_get_pci_dev(pdev, ent, &driver);
} }
...@@ -1102,11 +979,6 @@ static struct pci_driver i915_pci_driver = { ...@@ -1102,11 +979,6 @@ static struct pci_driver i915_pci_driver = {
static int __init i915_init(void) static int __init i915_init(void)
{ {
if (!intel_agp_enabled) {
DRM_ERROR("drm/i915 can't work without intel_agp module!\n");
return -ENODEV;
}
driver.num_ioctls = i915_max_ioctl; driver.num_ioctls = i915_max_ioctl;
/* /*
...@@ -1239,10 +1111,10 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ ...@@ -1239,10 +1111,10 @@ u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
unsigned long irqflags; \ unsigned long irqflags; \
spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
if (dev_priv->forcewake_count == 0) \ if (dev_priv->forcewake_count == 0) \
dev_priv->display.force_wake_get(dev_priv); \ dev_priv->gt.force_wake_get(dev_priv); \
val = read##y(dev_priv->regs + reg); \ val = read##y(dev_priv->regs + reg); \
if (dev_priv->forcewake_count == 0) \ if (dev_priv->forcewake_count == 0) \
dev_priv->display.force_wake_put(dev_priv); \ dev_priv->gt.force_wake_put(dev_priv); \
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
} else if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \ } else if (IS_VALLEYVIEW(dev_priv->dev) && IS_DISPLAYREG(reg)) { \
val = read##y(dev_priv->regs + reg + 0x180000); \ val = read##y(dev_priv->regs + reg + 0x180000); \
......
...@@ -79,6 +79,10 @@ enum port { ...@@ -79,6 +79,10 @@ enum port {
#define for_each_pipe(p) for ((p) = 0; (p) < dev_priv->num_pipe; (p)++) #define for_each_pipe(p) for ((p) = 0; (p) < dev_priv->num_pipe; (p)++)
#define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \
list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \
if ((intel_encoder)->base.crtc == (__crtc))
struct intel_pch_pll { struct intel_pch_pll {
int refcount; /* count of number of CRTCs sharing this PLL */ int refcount; /* count of number of CRTCs sharing this PLL */
int active; /* count of number of active CRTCs (i.e. DPMS on) */ int active; /* count of number of active CRTCs (i.e. DPMS on) */
...@@ -262,8 +266,6 @@ struct drm_i915_display_funcs { ...@@ -262,8 +266,6 @@ struct drm_i915_display_funcs {
struct drm_i915_gem_object *obj); struct drm_i915_gem_object *obj);
int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int x, int y); int x, int y);
void (*force_wake_get)(struct drm_i915_private *dev_priv);
void (*force_wake_put)(struct drm_i915_private *dev_priv);
/* clock updates for mode set */ /* clock updates for mode set */
/* cursor updates */ /* cursor updates */
/* render clock increase/decrease */ /* render clock increase/decrease */
...@@ -271,6 +273,11 @@ struct drm_i915_display_funcs { ...@@ -271,6 +273,11 @@ struct drm_i915_display_funcs {
/* pll clock increase/decrease */ /* pll clock increase/decrease */
}; };
struct drm_i915_gt_funcs {
void (*force_wake_get)(struct drm_i915_private *dev_priv);
void (*force_wake_put)(struct drm_i915_private *dev_priv);
};
struct intel_device_info { struct intel_device_info {
u8 gen; u8 gen;
u8 is_mobile:1; u8 is_mobile:1;
...@@ -285,7 +292,6 @@ struct intel_device_info { ...@@ -285,7 +292,6 @@ struct intel_device_info {
u8 is_crestline:1; u8 is_crestline:1;
u8 is_ivybridge:1; u8 is_ivybridge:1;
u8 is_valleyview:1; u8 is_valleyview:1;
u8 has_pch_split:1;
u8 has_force_wake:1; u8 has_force_wake:1;
u8 is_haswell:1; u8 is_haswell:1;
u8 has_fbc:1; u8 has_fbc:1;
...@@ -333,6 +339,7 @@ enum no_fbc_reason { ...@@ -333,6 +339,7 @@ enum no_fbc_reason {
}; };
enum intel_pch { enum intel_pch {
PCH_NONE = 0, /* No PCH present */
PCH_IBX, /* Ibexpeak PCH */ PCH_IBX, /* Ibexpeak PCH */
PCH_CPT, /* Cougarpoint PCH */ PCH_CPT, /* Cougarpoint PCH */
PCH_LPT, /* Lynxpoint PCH */ PCH_LPT, /* Lynxpoint PCH */
...@@ -362,6 +369,8 @@ typedef struct drm_i915_private { ...@@ -362,6 +369,8 @@ typedef struct drm_i915_private {
int relative_constants_mode; int relative_constants_mode;
void __iomem *regs; void __iomem *regs;
struct drm_i915_gt_funcs gt;
/** gt_fifo_count and the subsequent register write are synchronized /** gt_fifo_count and the subsequent register write are synchronized
* with dev->struct_mutex. */ * with dev->struct_mutex. */
unsigned gt_fifo_count; unsigned gt_fifo_count;
...@@ -1115,13 +1124,13 @@ struct drm_i915_file_private { ...@@ -1115,13 +1124,13 @@ struct drm_i915_file_private {
#define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr)
#define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc)
#define HAS_PCH_SPLIT(dev) (INTEL_INFO(dev)->has_pch_split)
#define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5) #define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5)
#define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type)
#define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT) #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT)
#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX)
#define HAS_PCH_SPLIT(dev) (INTEL_PCH_TYPE(dev) != PCH_NONE)
#define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake) #define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake)
...@@ -1200,6 +1209,7 @@ void i915_hangcheck_elapsed(unsigned long data); ...@@ -1200,6 +1209,7 @@ void i915_hangcheck_elapsed(unsigned long data);
void i915_handle_error(struct drm_device *dev, bool wedged); void i915_handle_error(struct drm_device *dev, bool wedged);
extern void intel_irq_init(struct drm_device *dev); extern void intel_irq_init(struct drm_device *dev);
extern void intel_gt_init(struct drm_device *dev);
void i915_error_state_free(struct kref *error_ref); void i915_error_state_free(struct kref *error_ref);
...@@ -1330,6 +1340,8 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) ...@@ -1330,6 +1340,8 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj)
void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_retire_requests(struct drm_device *dev);
void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring); void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring);
int __must_check i915_gem_check_wedge(struct drm_i915_private *dev_priv,
bool interruptible);
void i915_gem_reset(struct drm_device *dev); void i915_gem_reset(struct drm_device *dev);
void i915_gem_clflush_object(struct drm_i915_gem_object *obj); void i915_gem_clflush_object(struct drm_i915_gem_object *obj);
...@@ -1510,20 +1522,12 @@ extern bool intel_fbc_enabled(struct drm_device *dev); ...@@ -1510,20 +1522,12 @@ extern bool intel_fbc_enabled(struct drm_device *dev);
extern void intel_disable_fbc(struct drm_device *dev); extern void intel_disable_fbc(struct drm_device *dev);
extern bool ironlake_set_drps(struct drm_device *dev, u8 val); extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
extern void ironlake_init_pch_refclk(struct drm_device *dev); extern void ironlake_init_pch_refclk(struct drm_device *dev);
extern void ironlake_enable_rc6(struct drm_device *dev);
extern void gen6_set_rps(struct drm_device *dev, u8 val); extern void gen6_set_rps(struct drm_device *dev, u8 val);
extern void intel_detect_pch(struct drm_device *dev); extern void intel_detect_pch(struct drm_device *dev);
extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
extern int intel_enable_rc6(const struct drm_device *dev); extern int intel_enable_rc6(const struct drm_device *dev);
extern bool i915_semaphore_is_enabled(struct drm_device *dev); extern bool i915_semaphore_is_enabled(struct drm_device *dev);
extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv);
extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv);
extern void vlv_force_wake_get(struct drm_i915_private *dev_priv);
extern void vlv_force_wake_put(struct drm_i915_private *dev_priv);
/* overlay */ /* overlay */
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
......
...@@ -96,9 +96,18 @@ i915_gem_wait_for_error(struct drm_device *dev) ...@@ -96,9 +96,18 @@ i915_gem_wait_for_error(struct drm_device *dev)
if (!atomic_read(&dev_priv->mm.wedged)) if (!atomic_read(&dev_priv->mm.wedged))
return 0; return 0;
ret = wait_for_completion_interruptible(x); /*
if (ret) * Only wait 10 seconds for the gpu reset to complete to avoid hanging
* userspace. If it takes that long something really bad is going on and
* we should simply try to bail out and fail as gracefully as possible.
*/
ret = wait_for_completion_interruptible_timeout(x, 10*HZ);
if (ret == 0) {
DRM_ERROR("Timed out waiting for the gpu reset to complete\n");
return -EIO;
} else if (ret < 0) {
return ret; return ret;
}
if (atomic_read(&dev_priv->mm.wedged)) { if (atomic_read(&dev_priv->mm.wedged)) {
/* GPU is hung, bump the completion count to account for /* GPU is hung, bump the completion count to account for
...@@ -1132,6 +1141,11 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -1132,6 +1141,11 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
out: out:
switch (ret) { switch (ret) {
case -EIO: case -EIO:
/* If this -EIO is due to a gpu hang, give the reset code a
* chance to clean up the mess. Otherwise return the proper
* SIGBUS. */
if (!atomic_read(&dev_priv->mm.wedged))
return VM_FAULT_SIGBUS;
case -EAGAIN: case -EAGAIN:
/* Give the error handler a chance to run and move the /* Give the error handler a chance to run and move the
* objects off the GPU active list. Next time we service the * objects off the GPU active list. Next time we service the
...@@ -1863,11 +1877,10 @@ i915_gem_retire_work_handler(struct work_struct *work) ...@@ -1863,11 +1877,10 @@ i915_gem_retire_work_handler(struct work_struct *work)
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
} }
static int int
i915_gem_check_wedge(struct drm_i915_private *dev_priv) i915_gem_check_wedge(struct drm_i915_private *dev_priv,
bool interruptible)
{ {
BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
if (atomic_read(&dev_priv->mm.wedged)) { if (atomic_read(&dev_priv->mm.wedged)) {
struct completion *x = &dev_priv->error_completion; struct completion *x = &dev_priv->error_completion;
bool recovery_complete; bool recovery_complete;
...@@ -1878,7 +1891,16 @@ i915_gem_check_wedge(struct drm_i915_private *dev_priv) ...@@ -1878,7 +1891,16 @@ i915_gem_check_wedge(struct drm_i915_private *dev_priv)
recovery_complete = x->done > 0; recovery_complete = x->done > 0;
spin_unlock_irqrestore(&x->wait.lock, flags); spin_unlock_irqrestore(&x->wait.lock, flags);
return recovery_complete ? -EIO : -EAGAIN; /* Non-interruptible callers can't handle -EAGAIN, hence return
* -EIO unconditionally for these. */
if (!interruptible)
return -EIO;
/* Recovery complete, but still wedged means reset failure. */
if (recovery_complete)
return -EIO;
return -EAGAIN;
} }
return 0; return 0;
...@@ -1932,6 +1954,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, ...@@ -1932,6 +1954,7 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
unsigned long timeout_jiffies; unsigned long timeout_jiffies;
long end; long end;
bool wait_forever = true; bool wait_forever = true;
int ret;
if (i915_seqno_passed(ring->get_seqno(ring), seqno)) if (i915_seqno_passed(ring->get_seqno(ring), seqno))
return 0; return 0;
...@@ -1963,8 +1986,9 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, ...@@ -1963,8 +1986,9 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno,
end = wait_event_timeout(ring->irq_queue, EXIT_COND, end = wait_event_timeout(ring->irq_queue, EXIT_COND,
timeout_jiffies); timeout_jiffies);
if (atomic_read(&dev_priv->mm.wedged)) ret = i915_gem_check_wedge(dev_priv, interruptible);
end = -EAGAIN; if (ret)
end = ret;
} while (end == 0 && wait_forever); } while (end == 0 && wait_forever);
getrawmonotonic(&now); getrawmonotonic(&now);
...@@ -2004,7 +2028,7 @@ i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno) ...@@ -2004,7 +2028,7 @@ i915_wait_seqno(struct intel_ring_buffer *ring, uint32_t seqno)
BUG_ON(seqno == 0); BUG_ON(seqno == 0);
ret = i915_gem_check_wedge(dev_priv); ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible);
if (ret) if (ret)
return ret; return ret;
......
...@@ -136,37 +136,36 @@ static void do_destroy(struct i915_hw_context *ctx) ...@@ -136,37 +136,36 @@ static void do_destroy(struct i915_hw_context *ctx)
kfree(ctx); kfree(ctx);
} }
static int static struct i915_hw_context *
create_hw_context(struct drm_device *dev, create_hw_context(struct drm_device *dev,
struct drm_i915_file_private *file_priv, struct drm_i915_file_private *file_priv)
struct i915_hw_context **ctx_out)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_hw_context *ctx;
int ret, id; int ret, id;
*ctx_out = kzalloc(sizeof(struct drm_i915_file_private), GFP_KERNEL); ctx = kzalloc(sizeof(struct drm_i915_file_private), GFP_KERNEL);
if (*ctx_out == NULL) if (ctx == NULL)
return -ENOMEM; return ERR_PTR(-ENOMEM);
(*ctx_out)->obj = i915_gem_alloc_object(dev, ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
dev_priv->hw_context_size); if (ctx->obj == NULL) {
if ((*ctx_out)->obj == NULL) { kfree(ctx);
kfree(*ctx_out);
DRM_DEBUG_DRIVER("Context object allocated failed\n"); DRM_DEBUG_DRIVER("Context object allocated failed\n");
return -ENOMEM; return ERR_PTR(-ENOMEM);
} }
/* The ring associated with the context object is handled by the normal /* The ring associated with the context object is handled by the normal
* object tracking code. We give an initial ring value simple to pass an * object tracking code. We give an initial ring value simple to pass an
* assertion in the context switch code. * assertion in the context switch code.
*/ */
(*ctx_out)->ring = &dev_priv->ring[RCS]; ctx->ring = &dev_priv->ring[RCS];
/* Default context will never have a file_priv */ /* Default context will never have a file_priv */
if (file_priv == NULL) if (file_priv == NULL)
return 0; return ctx;
(*ctx_out)->file_priv = file_priv; ctx->file_priv = file_priv;
again: again:
if (idr_pre_get(&file_priv->context_idr, GFP_KERNEL) == 0) { if (idr_pre_get(&file_priv->context_idr, GFP_KERNEL) == 0) {
...@@ -175,21 +174,21 @@ create_hw_context(struct drm_device *dev, ...@@ -175,21 +174,21 @@ create_hw_context(struct drm_device *dev,
goto err_out; goto err_out;
} }
ret = idr_get_new_above(&file_priv->context_idr, *ctx_out, ret = idr_get_new_above(&file_priv->context_idr, ctx,
DEFAULT_CONTEXT_ID + 1, &id); DEFAULT_CONTEXT_ID + 1, &id);
if (ret == 0) if (ret == 0)
(*ctx_out)->id = id; ctx->id = id;
if (ret == -EAGAIN) if (ret == -EAGAIN)
goto again; goto again;
else if (ret) else if (ret)
goto err_out; goto err_out;
return 0; return ctx;
err_out: err_out:
do_destroy(*ctx_out); do_destroy(ctx);
return ret; return ERR_PTR(ret);
} }
static inline bool is_default_context(struct i915_hw_context *ctx) static inline bool is_default_context(struct i915_hw_context *ctx)
...@@ -209,10 +208,9 @@ static int create_default_context(struct drm_i915_private *dev_priv) ...@@ -209,10 +208,9 @@ static int create_default_context(struct drm_i915_private *dev_priv)
BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
ret = create_hw_context(dev_priv->dev, NULL, ctx = create_hw_context(dev_priv->dev, NULL);
&dev_priv->ring[RCS].default_context); if (IS_ERR(ctx))
if (ret) return PTR_ERR(ctx);
return ret;
/* We may need to do things with the shrinker which require us to /* We may need to do things with the shrinker which require us to
* immediately switch back to the default context. This can cause a * immediately switch back to the default context. This can cause a
...@@ -220,7 +218,7 @@ static int create_default_context(struct drm_i915_private *dev_priv) ...@@ -220,7 +218,7 @@ static int create_default_context(struct drm_i915_private *dev_priv)
* may not be available. To avoid this we always pin the * may not be available. To avoid this we always pin the
* default context. * default context.
*/ */
ctx = dev_priv->ring[RCS].default_context; dev_priv->ring[RCS].default_context = ctx;
ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false); ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false);
if (ret) { if (ret) {
do_destroy(ctx); do_destroy(ctx);
...@@ -496,13 +494,13 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, ...@@ -496,13 +494,13 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
if (ret) if (ret)
return ret; return ret;
ret = create_hw_context(dev, file_priv, &ctx); ctx = create_hw_context(dev, file_priv);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
args->ctx_id = ctx->id; args->ctx_id = ctx->id;
DRM_DEBUG_DRIVER("HW context %d created\n", args->ctx_id); DRM_DEBUG_DRIVER("HW context %d created\n", args->ctx_id);
return ret; return PTR_RET(ctx);
} }
int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
......
...@@ -1458,6 +1458,10 @@ ...@@ -1458,6 +1458,10 @@
#define DDRMPLL1 0X12c20 #define DDRMPLL1 0X12c20
#define PEG_BAND_GAP_DATA 0x14d68 #define PEG_BAND_GAP_DATA 0x14d68
#define GEN6_GT_THREAD_STATUS_REG 0x13805c
#define GEN6_GT_THREAD_STATUS_CORE_MASK 0x7
#define GEN6_GT_THREAD_STATUS_CORE_MASK_HSW (0x7 | (0x07 << 16))
#define GEN6_GT_PERF_STATUS 0x145948 #define GEN6_GT_PERF_STATUS 0x145948
#define GEN6_RP_STATE_LIMITS 0x145994 #define GEN6_RP_STATE_LIMITS 0x145994
#define GEN6_RP_STATE_CAP 0x145998 #define GEN6_RP_STATE_CAP 0x145998
...@@ -2975,13 +2979,14 @@ ...@@ -2975,13 +2979,14 @@
#define DSPSIZE(plane) _PIPE(plane, _DSPASIZE, _DSPBSIZE) #define DSPSIZE(plane) _PIPE(plane, _DSPASIZE, _DSPBSIZE)
#define DSPSURF(plane) _PIPE(plane, _DSPASURF, _DSPBSURF) #define DSPSURF(plane) _PIPE(plane, _DSPASURF, _DSPBSURF)
#define DSPTILEOFF(plane) _PIPE(plane, _DSPATILEOFF, _DSPBTILEOFF) #define DSPTILEOFF(plane) _PIPE(plane, _DSPATILEOFF, _DSPBTILEOFF)
#define DSPLINOFF(plane) DSPADDR(plane)
/* Display/Sprite base address macros */ /* Display/Sprite base address macros */
#define DISP_BASEADDR_MASK (0xfffff000) #define DISP_BASEADDR_MASK (0xfffff000)
#define I915_LO_DISPBASE(val) (val & ~DISP_BASEADDR_MASK) #define I915_LO_DISPBASE(val) (val & ~DISP_BASEADDR_MASK)
#define I915_HI_DISPBASE(val) (val & DISP_BASEADDR_MASK) #define I915_HI_DISPBASE(val) (val & DISP_BASEADDR_MASK)
#define I915_MODIFY_DISPBASE(reg, gfx_addr) \ #define I915_MODIFY_DISPBASE(reg, gfx_addr) \
(I915_WRITE(reg, gfx_addr | I915_LO_DISPBASE(I915_READ(reg)))) (I915_WRITE((reg), (gfx_addr) | I915_LO_DISPBASE(I915_READ(reg))))
/* VBIOS flags */ /* VBIOS flags */
#define SWF00 0x71410 #define SWF00 0x71410
...@@ -3849,6 +3854,9 @@ ...@@ -3849,6 +3854,9 @@
#define _FDI_RXA_TUSIZE2 0xf0038 #define _FDI_RXA_TUSIZE2 0xf0038
#define _FDI_RXB_TUSIZE1 0xf1030 #define _FDI_RXB_TUSIZE1 0xf1030
#define _FDI_RXB_TUSIZE2 0xf1038 #define _FDI_RXB_TUSIZE2 0xf1038
#define FDI_RX_TP1_TO_TP2_48 (2<<20)
#define FDI_RX_TP1_TO_TP2_64 (3<<20)
#define FDI_RX_FDI_DELAY_90 (0x90<<0)
#define FDI_RX_MISC(pipe) _PIPE(pipe, _FDI_RXA_MISC, _FDI_RXB_MISC) #define FDI_RX_MISC(pipe) _PIPE(pipe, _FDI_RXA_MISC, _FDI_RXB_MISC)
#define FDI_RX_TUSIZE1(pipe) _PIPE(pipe, _FDI_RXA_TUSIZE1, _FDI_RXB_TUSIZE1) #define FDI_RX_TUSIZE1(pipe) _PIPE(pipe, _FDI_RXA_TUSIZE1, _FDI_RXB_TUSIZE1)
#define FDI_RX_TUSIZE2(pipe) _PIPE(pipe, _FDI_RXA_TUSIZE2, _FDI_RXB_TUSIZE2) #define FDI_RX_TUSIZE2(pipe) _PIPE(pipe, _FDI_RXA_TUSIZE2, _FDI_RXB_TUSIZE2)
...@@ -4067,6 +4075,7 @@ ...@@ -4067,6 +4075,7 @@
#define FORCEWAKE 0xA18C #define FORCEWAKE 0xA18C
#define FORCEWAKE_VLV 0x1300b0 #define FORCEWAKE_VLV 0x1300b0
#define FORCEWAKE_ACK_VLV 0x1300b4 #define FORCEWAKE_ACK_VLV 0x1300b4
#define FORCEWAKE_ACK_HSW 0x130044
#define FORCEWAKE_ACK 0x130090 #define FORCEWAKE_ACK 0x130090
#define FORCEWAKE_MT 0xa188 /* multi-threaded */ #define FORCEWAKE_MT 0xa188 /* multi-threaded */
#define FORCEWAKE_MT_ACK 0x130040 #define FORCEWAKE_MT_ACK 0x130040
...@@ -4127,6 +4136,7 @@ ...@@ -4127,6 +4136,7 @@
#define GEN6_RP_UP_IDLE_MIN (0x1<<3) #define GEN6_RP_UP_IDLE_MIN (0x1<<3)
#define GEN6_RP_UP_BUSY_AVG (0x2<<3) #define GEN6_RP_UP_BUSY_AVG (0x2<<3)
#define GEN6_RP_UP_BUSY_CONT (0x4<<3) #define GEN6_RP_UP_BUSY_CONT (0x4<<3)
#define GEN7_RP_DOWN_IDLE_AVG (0x2<<0)
#define GEN6_RP_DOWN_IDLE_CONT (0x1<<0) #define GEN6_RP_DOWN_IDLE_CONT (0x1<<0)
#define GEN6_RP_UP_THRESHOLD 0xA02C #define GEN6_RP_UP_THRESHOLD 0xA02C
#define GEN6_RP_DOWN_THRESHOLD 0xA030 #define GEN6_RP_DOWN_THRESHOLD 0xA030
...@@ -4277,7 +4287,7 @@ ...@@ -4277,7 +4287,7 @@
PIPE_DDI_FUNC_CTL_B) PIPE_DDI_FUNC_CTL_B)
#define PIPE_DDI_FUNC_ENABLE (1<<31) #define PIPE_DDI_FUNC_ENABLE (1<<31)
/* Those bits are ignored by pipe EDP since it can only connect to DDI A */ /* Those bits are ignored by pipe EDP since it can only connect to DDI A */
#define PIPE_DDI_PORT_MASK (0xf<<28) #define PIPE_DDI_PORT_MASK (7<<28)
#define PIPE_DDI_SELECT_PORT(x) ((x)<<28) #define PIPE_DDI_SELECT_PORT(x) ((x)<<28)
#define PIPE_DDI_MODE_SELECT_HDMI (0<<24) #define PIPE_DDI_MODE_SELECT_HDMI (0<<24)
#define PIPE_DDI_MODE_SELECT_DVI (1<<24) #define PIPE_DDI_MODE_SELECT_DVI (1<<24)
...@@ -4435,7 +4445,7 @@ ...@@ -4435,7 +4445,7 @@
#define PIPE_WM_LINETIME_B 0x45274 #define PIPE_WM_LINETIME_B 0x45274
#define PIPE_WM_LINETIME(pipe) _PIPE(pipe, \ #define PIPE_WM_LINETIME(pipe) _PIPE(pipe, \
PIPE_WM_LINETIME_A, \ PIPE_WM_LINETIME_A, \
PIPE_WM_LINETIME_A) PIPE_WM_LINETIME_B)
#define PIPE_WM_LINETIME_MASK (0x1ff) #define PIPE_WM_LINETIME_MASK (0x1ff)
#define PIPE_WM_LINETIME_TIME(x) ((x)) #define PIPE_WM_LINETIME_TIME(x) ((x))
#define PIPE_WM_LINETIME_IPS_LINETIME_MASK (0x1ff<<16) #define PIPE_WM_LINETIME_IPS_LINETIME_MASK (0x1ff<<16)
...@@ -4447,4 +4457,9 @@ ...@@ -4447,4 +4457,9 @@
#define SFUSE_STRAP_DDIC_DETECTED (1<<1) #define SFUSE_STRAP_DDIC_DETECTED (1<<1)
#define SFUSE_STRAP_DDID_DETECTED (1<<0) #define SFUSE_STRAP_DDID_DETECTED (1<<0)
#define WM_DBG 0x45280
#define WM_DBG_DISALLOW_MULTIPLE_LP (1<<0)
#define WM_DBG_DISALLOW_MAXFIFO (1<<1)
#define WM_DBG_DISALLOW_SPRITE (1<<2)
#endif /* _I915_REG_H_ */ #endif /* _I915_REG_H_ */
...@@ -825,10 +825,7 @@ int i915_save_state(struct drm_device *dev) ...@@ -825,10 +825,7 @@ int i915_save_state(struct drm_device *dev)
dev_priv->saveIMR = I915_READ(IMR); dev_priv->saveIMR = I915_READ(IMR);
} }
if (IS_IRONLAKE_M(dev)) intel_disable_gt_powersave(dev);
ironlake_disable_drps(dev);
if (INTEL_INFO(dev)->gen >= 6)
gen6_disable_rps(dev);
/* Cache mode state */ /* Cache mode state */
dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
......
...@@ -170,6 +170,15 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) ...@@ -170,6 +170,15 @@ void hsw_fdi_link_train(struct drm_crtc *crtc)
udelay(600); udelay(600);
/* We need to program FDI_RX_MISC with the default TP1 to TP2
* values before enabling the receiver, and configure the delay
* for the FDI timing generator to 90h. Luckily, all the other
* bits are supposed to be zeroed, so we can write those values
* directly.
*/
I915_WRITE(FDI_RX_MISC(pipe), FDI_RX_TP1_TO_TP2_48 |
FDI_RX_FDI_DELAY_90);
/* Enable CPU FDI Receiver with auto-training */ /* Enable CPU FDI Receiver with auto-training */
reg = FDI_RX_CTL(pipe); reg = FDI_RX_CTL(pipe);
I915_WRITE(reg, I915_WRITE(reg,
......
This diff is collapsed.
...@@ -733,8 +733,8 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, ...@@ -733,8 +733,8 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp); mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) {
for (clock = 0; clock <= max_clock; clock++) { for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
if (mode_rate <= link_avail) { if (mode_rate <= link_avail) {
...@@ -793,8 +793,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, ...@@ -793,8 +793,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *encoder;
struct drm_encoder *encoder;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
int lane_count = 4; int lane_count = 4;
...@@ -804,13 +803,9 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, ...@@ -804,13 +803,9 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
/* /*
* Find the lane count in the intel_encoder private * Find the lane count in the intel_encoder private
*/ */
list_for_each_entry(encoder, &mode_config->encoder_list, head) { for_each_encoder_on_crtc(dev, crtc, encoder) {
struct intel_dp *intel_dp; struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
if (encoder->crtc != crtc)
continue;
intel_dp = enc_to_intel_dp(encoder);
if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
intel_dp->base.type == INTEL_OUTPUT_EDP) intel_dp->base.type == INTEL_OUTPUT_EDP)
{ {
...@@ -2404,16 +2399,11 @@ int ...@@ -2404,16 +2399,11 @@ int
intel_trans_dp_port_sel(struct drm_crtc *crtc) intel_trans_dp_port_sel(struct drm_crtc *crtc)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *encoder;
struct drm_encoder *encoder;
list_for_each_entry(encoder, &mode_config->encoder_list, head) { for_each_encoder_on_crtc(dev, crtc, encoder) {
struct intel_dp *intel_dp; struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
if (encoder->crtc != crtc)
continue;
intel_dp = enc_to_intel_dp(encoder);
if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT ||
intel_dp->base.type == INTEL_OUTPUT_EDP) intel_dp->base.type == INTEL_OUTPUT_EDP)
return intel_dp->output_reg; return intel_dp->output_reg;
......
...@@ -177,6 +177,11 @@ struct intel_crtc { ...@@ -177,6 +177,11 @@ struct intel_crtc {
struct intel_unpin_work *unpin_work; struct intel_unpin_work *unpin_work;
int fdi_lanes; int fdi_lanes;
/* Display surface base address adjustement for pageflips. Note that on
* gen4+ this only adjusts up to a tile, offsets within a tile are
* handled in the hw itself (with the TILEOFF register). */
unsigned long dspaddr_offset;
struct drm_i915_gem_object *cursor_bo; struct drm_i915_gem_object *cursor_bo;
uint32_t cursor_addr; uint32_t cursor_addr;
int16_t cursor_x, cursor_y; int16_t cursor_x, cursor_y;
...@@ -425,9 +430,6 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, ...@@ -425,9 +430,6 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, int regno); u16 *blue, int regno);
extern void intel_enable_clock_gating(struct drm_device *dev); extern void intel_enable_clock_gating(struct drm_device *dev);
extern void ironlake_disable_rc6(struct drm_device *dev);
extern void ironlake_enable_drps(struct drm_device *dev);
extern void ironlake_disable_drps(struct drm_device *dev);
extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
struct drm_i915_gem_object *obj, struct drm_i915_gem_object *obj,
...@@ -494,10 +496,10 @@ extern void intel_update_fbc(struct drm_device *dev); ...@@ -494,10 +496,10 @@ extern void intel_update_fbc(struct drm_device *dev);
extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv); extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
extern void intel_gpu_ips_teardown(void); extern void intel_gpu_ips_teardown(void);
extern void gen6_enable_rps(struct drm_i915_private *dev_priv); extern void intel_enable_gt_powersave(struct drm_device *dev);
extern void gen6_update_ring_freq(struct drm_i915_private *dev_priv); extern void intel_disable_gt_powersave(struct drm_device *dev);
extern void gen6_disable_rps(struct drm_device *dev); extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv);
extern void intel_init_emon(struct drm_device *dev); extern void ironlake_teardown_rc6(struct drm_device *dev);
extern void intel_ddi_dpms(struct drm_encoder *encoder, int mode); extern void intel_ddi_dpms(struct drm_encoder *encoder, int mode);
extern void intel_ddi_mode_set(struct drm_encoder *encoder, extern void intel_ddi_mode_set(struct drm_encoder *encoder,
......
...@@ -65,7 +65,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, ...@@ -65,7 +65,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct fb_info *info; struct fb_info *info;
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
struct drm_mode_fb_cmd2 mode_cmd; struct drm_mode_fb_cmd2 mode_cmd = {};
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
struct device *device = &dev->pdev->dev; struct device *device = &dev->pdev->dev;
int size, ret; int size, ret;
......
...@@ -236,7 +236,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -236,7 +236,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
struct intel_lvds *intel_lvds = to_intel_lvds(encoder); struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
struct drm_encoder *tmp_encoder; struct intel_encoder *tmp_encoder;
u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
int pipe; int pipe;
...@@ -247,8 +247,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -247,8 +247,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
} }
/* Should never happen!! */ /* Should never happen!! */
list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { for_each_encoder_on_crtc(dev, encoder->crtc, tmp_encoder) {
if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { if (&tmp_encoder->base != encoder) {
DRM_ERROR("Can't enable LVDS and another " DRM_ERROR("Can't enable LVDS and another "
"encoder on the same pipe\n"); "encoder on the same pipe\n");
return false; return false;
......
This diff is collapsed.
...@@ -219,7 +219,9 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, ...@@ -219,7 +219,9 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring,
int ret; int ret;
/* Force SNB workarounds for PIPE_CONTROL flushes */ /* Force SNB workarounds for PIPE_CONTROL flushes */
intel_emit_post_sync_nonzero_flush(ring); ret = intel_emit_post_sync_nonzero_flush(ring);
if (ret)
return ret;
/* Just flush everything. Experiments have shown that reducing the /* Just flush everything. Experiments have shown that reducing the
* number of bits based on the write domains has little performance * number of bits based on the write domains has little performance
...@@ -233,6 +235,12 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, ...@@ -233,6 +235,12 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring,
flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
/*
* Ensure that any following seqno writes only happen when the render
* cache is indeed flushed (but only if the caller actually wants that).
*/
if (flush_domains)
flags |= PIPE_CONTROL_CS_STALL;
ret = intel_ring_begin(ring, 6); ret = intel_ring_begin(ring, 6);
if (ret) if (ret)
...@@ -1109,20 +1117,9 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) ...@@ -1109,20 +1117,9 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring)
static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno) static int intel_ring_wait_seqno(struct intel_ring_buffer *ring, u32 seqno)
{ {
struct drm_i915_private *dev_priv = ring->dev->dev_private;
bool was_interruptible;
int ret; int ret;
/* XXX As we have not yet audited all the paths to check that
* they are ready for ERESTARTSYS from intel_ring_begin, do not
* allow us to be interruptible by a signal.
*/
was_interruptible = dev_priv->mm.interruptible;
dev_priv->mm.interruptible = false;
ret = i915_wait_seqno(ring, seqno); ret = i915_wait_seqno(ring, seqno);
dev_priv->mm.interruptible = was_interruptible;
if (!ret) if (!ret)
i915_gem_retire_requests_ring(ring); i915_gem_retire_requests_ring(ring);
...@@ -1220,8 +1217,10 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) ...@@ -1220,8 +1217,10 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
} }
msleep(1); msleep(1);
if (atomic_read(&dev_priv->mm.wedged))
return -EAGAIN; ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible);
if (ret)
return ret;
} while (!time_after(jiffies, end)); } while (!time_after(jiffies, end));
trace_i915_ring_wait_end(ring); trace_i915_ring_wait_end(ring);
return -EBUSY; return -EBUSY;
...@@ -1230,12 +1229,13 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) ...@@ -1230,12 +1229,13 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
int intel_ring_begin(struct intel_ring_buffer *ring, int intel_ring_begin(struct intel_ring_buffer *ring,
int num_dwords) int num_dwords)
{ {
struct drm_i915_private *dev_priv = ring->dev->dev_private; drm_i915_private_t *dev_priv = ring->dev->dev_private;
int n = 4*num_dwords; int n = 4*num_dwords;
int ret; int ret;
if (unlikely(atomic_read(&dev_priv->mm.wedged))) ret = i915_gem_check_wedge(dev_priv, dev_priv->mm.interruptible);
return -EIO; if (ret)
return ret;
if (unlikely(ring->tail + n > ring->effective_size)) { if (unlikely(ring->tail + n > ring->effective_size)) {
ret = intel_wrap_ring_buffer(ring); ret = intel_wrap_ring_buffer(ring);
......
...@@ -56,6 +56,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, ...@@ -56,6 +56,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
sprctl &= ~SPRITE_PIXFORMAT_MASK; sprctl &= ~SPRITE_PIXFORMAT_MASK;
sprctl &= ~SPRITE_RGB_ORDER_RGBX; sprctl &= ~SPRITE_RGB_ORDER_RGBX;
sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
sprctl &= ~SPRITE_TILED;
switch (fb->pixel_format) { switch (fb->pixel_format) {
case DRM_FORMAT_XBGR8888: case DRM_FORMAT_XBGR8888:
...@@ -84,7 +85,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, ...@@ -84,7 +85,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
break; break;
default: default:
DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n"); DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
sprctl |= DVS_FORMAT_RGBX888; sprctl |= SPRITE_FORMAT_RGBX888;
pixel_size = 4; pixel_size = 4;
break; break;
} }
...@@ -690,6 +691,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) ...@@ -690,6 +691,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe)
break; break;
default: default:
kfree(intel_plane);
return -ENODEV; return -ENODEV;
} }
...@@ -704,4 +706,3 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) ...@@ -704,4 +706,3 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe)
return ret; return ret;
} }
...@@ -895,20 +895,16 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, ...@@ -895,20 +895,16 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct drm_mode_config *drm_config = &dev->mode_config;
struct intel_tv *intel_tv = enc_to_intel_tv(encoder); struct intel_tv *intel_tv = enc_to_intel_tv(encoder);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv);
struct drm_encoder *other_encoder; struct intel_encoder *other_encoder;
if (!tv_mode) if (!tv_mode)
return false; return false;
/* FIXME: lock encoder list */ for_each_encoder_on_crtc(dev, encoder->crtc, other_encoder)
list_for_each_entry(other_encoder, &drm_config->encoder_list, head) { if (&other_encoder->base != encoder)
if (other_encoder != encoder &&
other_encoder->crtc == encoder->crtc)
return false; return false;
}
adjusted_mode->clock = tv_mode->clock; adjusted_mode->clock = tv_mode->clock;
return true; return true;
......
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