Commit 65983bd6 authored by Dave Airlie's avatar Dave Airlie

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

Daniel writes:
"New stuff for -next. Highlights:
- prep patches for the modeset rework. Note that one of those patches
  touches the fb helper in the common drm code.
- hasw hdmi audio support (Wang Xingchao)
- improved instdone dumping for gen7 (Ben)
- unbound tracking and a few follow-up patches from Chris
- dma_buf->begin/end_cpu_access plus fix for drm/udl (Dave)
- improve mmio error reporting for hsw
- prep patch for WQ_NON_REENTRANT removal (Tejun Heo)
"

* 'for-airlied' of git://people.freedesktop.org/~danvet/drm-intel: (41 commits)
  drm/i915: Remove __GFP_NO_KSWAPD
  drm/i915: disable rc6 on ilk when vt-d is enabled
  drm/i915: Avoid unbinding due to an interrupted pin_and_fence during execbuffer
  drm/i915: Use new INSTDONE registers (Gen7+)
  drm/i915: Add new INSTDONE registers
  drm/i915: Extract reading INSTDONE
  drm/i915: Use a non-blocking wait for set-to-domain ioctl
  drm/i915: Juggle code order to ease flow of the next patch
  drm/i915: Use cpu relocations if the object is in the GTT but not mappable
  drm/i915: Extract general object init routine
  drm/i915: Protect private gem objects from truncate (such as imported dmabuf)
  drm/i915: Only pwrite through the GTT if there is space in the aperture
  i915: use alloc_ordered_workqueue() instead of explicit UNBOUND w/ max_active = 1
  drm/i915: Find unclaimed MMIO writes.
  drm/i915: Add ERR_INT to gen7 error state
  drm/i915: Cantiga+ cannot handle a hsync front porch of 0
  drm/i915: fix reassignment of variable "intel_dp->DP"
  drm/i915: Try harder to allocate an mmap_offset
  drm/i915: Show pin count in debugfs
  drm/i915: Show (count, size) of purgeable objects in i915_gem_objects
  ...
parents 93bb70e0 d7c3b937
...@@ -1230,7 +1230,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) ...@@ -1230,7 +1230,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
struct drm_device *dev = fb_helper->dev; struct drm_device *dev = fb_helper->dev;
struct drm_fb_helper_crtc **crtcs; struct drm_fb_helper_crtc **crtcs;
struct drm_display_mode **modes; struct drm_display_mode **modes;
struct drm_encoder *encoder;
struct drm_mode_set *modeset; struct drm_mode_set *modeset;
bool *enabled; bool *enabled;
int width, height; int width, height;
...@@ -1241,11 +1240,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) ...@@ -1241,11 +1240,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
width = dev->mode_config.max_width; width = dev->mode_config.max_width;
height = dev->mode_config.max_height; height = dev->mode_config.max_height;
/* clean out all the encoder/crtc combos */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
encoder->crtc = NULL;
}
crtcs = kcalloc(dev->mode_config.num_connector, crtcs = kcalloc(dev->mode_config.num_connector,
sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL); sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
modes = kcalloc(dev->mode_config.num_connector, modes = kcalloc(dev->mode_config.num_connector,
......
...@@ -58,13 +58,12 @@ struct intel_dvo_dev_ops { ...@@ -58,13 +58,12 @@ struct intel_dvo_dev_ops {
void (*create_resources)(struct intel_dvo_device *dvo); void (*create_resources)(struct intel_dvo_device *dvo);
/* /*
* Turn on/off output or set intermediate power levels if available. * Turn on/off output.
* *
* Unsupported intermediate modes drop to the lower power setting. * Because none of our dvo drivers support an intermediate power levels,
* If the mode is DPMSModeOff, the output must be disabled, * we don't expose this in the interfac.
* as the DPLL may be disabled afterwards.
*/ */
void (*dpms)(struct intel_dvo_device *dvo, int mode); void (*dpms)(struct intel_dvo_device *dvo, bool enable);
/* /*
* Callback for testing a video mode for a given output. * Callback for testing a video mode for a given output.
......
...@@ -163,7 +163,7 @@ struct ch7017_priv { ...@@ -163,7 +163,7 @@ struct ch7017_priv {
}; };
static void ch7017_dump_regs(struct intel_dvo_device *dvo); static void ch7017_dump_regs(struct intel_dvo_device *dvo);
static void ch7017_dpms(struct intel_dvo_device *dvo, int mode); static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable);
static bool ch7017_read(struct intel_dvo_device *dvo, u8 addr, u8 *val) static bool ch7017_read(struct intel_dvo_device *dvo, u8 addr, u8 *val)
{ {
...@@ -309,7 +309,7 @@ static void ch7017_mode_set(struct intel_dvo_device *dvo, ...@@ -309,7 +309,7 @@ static void ch7017_mode_set(struct intel_dvo_device *dvo,
lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED | lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED |
(mode->hdisplay & 0x0700) >> 8; (mode->hdisplay & 0x0700) >> 8;
ch7017_dpms(dvo, DRM_MODE_DPMS_OFF); ch7017_dpms(dvo, false);
ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT,
horizontal_active_pixel_input); horizontal_active_pixel_input);
ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT, ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT,
...@@ -331,7 +331,7 @@ static void ch7017_mode_set(struct intel_dvo_device *dvo, ...@@ -331,7 +331,7 @@ static void ch7017_mode_set(struct intel_dvo_device *dvo,
} }
/* set the CH7017 power state */ /* set the CH7017 power state */
static void ch7017_dpms(struct intel_dvo_device *dvo, int mode) static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable)
{ {
uint8_t val; uint8_t val;
...@@ -345,7 +345,7 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode) ...@@ -345,7 +345,7 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode)
CH7017_DAC3_POWER_DOWN | CH7017_DAC3_POWER_DOWN |
CH7017_TV_POWER_DOWN_EN); CH7017_TV_POWER_DOWN_EN);
if (mode == DRM_MODE_DPMS_ON) { if (enable) {
/* Turn on the LVDS */ /* Turn on the LVDS */
ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, ch7017_write(dvo, CH7017_LVDS_POWER_DOWN,
val & ~CH7017_LVDS_POWER_DOWN_EN); val & ~CH7017_LVDS_POWER_DOWN_EN);
......
...@@ -289,9 +289,9 @@ static void ch7xxx_mode_set(struct intel_dvo_device *dvo, ...@@ -289,9 +289,9 @@ static void ch7xxx_mode_set(struct intel_dvo_device *dvo,
} }
/* set the CH7xxx power state */ /* set the CH7xxx power state */
static void ch7xxx_dpms(struct intel_dvo_device *dvo, int mode) static void ch7xxx_dpms(struct intel_dvo_device *dvo, bool enable)
{ {
if (mode == DRM_MODE_DPMS_ON) if (enable)
ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP); ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
else else
ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD); ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD);
......
...@@ -288,7 +288,7 @@ static enum drm_mode_status ivch_mode_valid(struct intel_dvo_device *dvo, ...@@ -288,7 +288,7 @@ static enum drm_mode_status ivch_mode_valid(struct intel_dvo_device *dvo,
} }
/** Sets the power state of the panel connected to the ivch */ /** Sets the power state of the panel connected to the ivch */
static void ivch_dpms(struct intel_dvo_device *dvo, int mode) static void ivch_dpms(struct intel_dvo_device *dvo, bool enable)
{ {
int i; int i;
uint16_t vr01, vr30, backlight; uint16_t vr01, vr30, backlight;
...@@ -297,13 +297,13 @@ static void ivch_dpms(struct intel_dvo_device *dvo, int mode) ...@@ -297,13 +297,13 @@ static void ivch_dpms(struct intel_dvo_device *dvo, int mode)
if (!ivch_read(dvo, VR01, &vr01)) if (!ivch_read(dvo, VR01, &vr01))
return; return;
if (mode == DRM_MODE_DPMS_ON) if (enable)
backlight = 1; backlight = 1;
else else
backlight = 0; backlight = 0;
ivch_write(dvo, VR80, backlight); ivch_write(dvo, VR80, backlight);
if (mode == DRM_MODE_DPMS_ON) if (enable)
vr01 |= VR01_LCD_ENABLE | VR01_DVO_ENABLE; vr01 |= VR01_LCD_ENABLE | VR01_DVO_ENABLE;
else else
vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE); vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
...@@ -315,7 +315,7 @@ static void ivch_dpms(struct intel_dvo_device *dvo, int mode) ...@@ -315,7 +315,7 @@ static void ivch_dpms(struct intel_dvo_device *dvo, int mode)
if (!ivch_read(dvo, VR30, &vr30)) if (!ivch_read(dvo, VR30, &vr30))
break; break;
if (((vr30 & VR30_PANEL_ON) != 0) == (mode == DRM_MODE_DPMS_ON)) if (((vr30 & VR30_PANEL_ON) != 0) == enable)
break; break;
udelay(1000); udelay(1000);
} }
......
...@@ -74,11 +74,6 @@ struct ns2501_priv { ...@@ -74,11 +74,6 @@ struct ns2501_priv {
#define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr)) #define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr))
/*
* Include the PLL launcher prototype
*/
extern void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe);
/* /*
* For reasons unclear to me, the ns2501 at least on the Fujitsu/Siemens * For reasons unclear to me, the ns2501 at least on the Fujitsu/Siemens
* laptops does not react on the i2c bus unless * laptops does not react on the i2c bus unless
...@@ -113,8 +108,6 @@ static void enable_dvo(struct intel_dvo_device *dvo) ...@@ -113,8 +108,6 @@ static void enable_dvo(struct intel_dvo_device *dvo)
I915_WRITE(DVOC_SRCDIM, 0x400300); // 1024x768 I915_WRITE(DVOC_SRCDIM, 0x400300); // 1024x768
I915_WRITE(FW_BLC, 0x1080304); I915_WRITE(FW_BLC, 0x1080304);
intel_enable_pll(dev_priv, 0);
I915_WRITE(DVOC, 0x90004084); I915_WRITE(DVOC, 0x90004084);
} }
...@@ -500,19 +493,19 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo, ...@@ -500,19 +493,19 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo,
} }
/* set the NS2501 power state */ /* set the NS2501 power state */
static void ns2501_dpms(struct intel_dvo_device *dvo, int mode) static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
{ {
bool ok; bool ok;
bool restore = false; bool restore = false;
struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv); struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
unsigned char ch; unsigned char ch;
DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to %d\n", DRM_DEBUG_KMS("%s: Trying set the dpms of the DVO to %i\n",
__FUNCTION__, mode); __FUNCTION__, enable);
ch = ns->reg_8_shadow; ch = ns->reg_8_shadow;
if (mode == DRM_MODE_DPMS_ON) if (enable)
ch |= NS2501_8_PD; ch |= NS2501_8_PD;
else else
ch &= ~NS2501_8_PD; ch &= ~NS2501_8_PD;
...@@ -526,12 +519,10 @@ static void ns2501_dpms(struct intel_dvo_device *dvo, int mode) ...@@ -526,12 +519,10 @@ static void ns2501_dpms(struct intel_dvo_device *dvo, int mode)
ok &= ns2501_writeb(dvo, NS2501_REG8, ch); ok &= ns2501_writeb(dvo, NS2501_REG8, ch);
ok &= ok &=
ns2501_writeb(dvo, 0x34, ns2501_writeb(dvo, 0x34,
(mode == enable ? 0x03 : 0x00);
DRM_MODE_DPMS_ON) ? (0x03) : (0x00));
ok &= ok &=
ns2501_writeb(dvo, 0x35, ns2501_writeb(dvo, 0x35,
(mode == enable ? 0xff : 0x00);
DRM_MODE_DPMS_ON) ? (0xff) : (0x00));
if (!ok) { if (!ok) {
if (restore) if (restore)
restore_dvo(dvo); restore_dvo(dvo);
......
...@@ -208,7 +208,7 @@ static void sil164_mode_set(struct intel_dvo_device *dvo, ...@@ -208,7 +208,7 @@ static void sil164_mode_set(struct intel_dvo_device *dvo,
} }
/* set the SIL164 power state */ /* set the SIL164 power state */
static void sil164_dpms(struct intel_dvo_device *dvo, int mode) static void sil164_dpms(struct intel_dvo_device *dvo, bool enable)
{ {
int ret; int ret;
unsigned char ch; unsigned char ch;
...@@ -217,7 +217,7 @@ static void sil164_dpms(struct intel_dvo_device *dvo, int mode) ...@@ -217,7 +217,7 @@ static void sil164_dpms(struct intel_dvo_device *dvo, int mode)
if (ret == false) if (ret == false)
return; return;
if (mode == DRM_MODE_DPMS_ON) if (enable)
ch |= SIL164_8_PD; ch |= SIL164_8_PD;
else else
ch &= ~SIL164_8_PD; ch &= ~SIL164_8_PD;
......
...@@ -234,14 +234,14 @@ static void tfp410_mode_set(struct intel_dvo_device *dvo, ...@@ -234,14 +234,14 @@ static void tfp410_mode_set(struct intel_dvo_device *dvo,
} }
/* set the tfp410 power state */ /* set the tfp410 power state */
static void tfp410_dpms(struct intel_dvo_device *dvo, int mode) static void tfp410_dpms(struct intel_dvo_device *dvo, bool enable)
{ {
uint8_t ctl1; uint8_t ctl1;
if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1)) if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
return; return;
if (mode == DRM_MODE_DPMS_ON) if (enable)
ctl1 |= TFP410_CTL_1_PD; ctl1 |= TFP410_CTL_1_PD;
else else
ctl1 &= ~TFP410_CTL_1_PD; ctl1 &= ~TFP410_CTL_1_PD;
......
...@@ -118,6 +118,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) ...@@ -118,6 +118,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
if (obj->base.name) if (obj->base.name)
seq_printf(m, " (name: %d)", obj->base.name); seq_printf(m, " (name: %d)", obj->base.name);
if (obj->pin_count)
seq_printf(m, " (pinned x %d)", obj->pin_count);
if (obj->fence_reg != I915_FENCE_REG_NONE) if (obj->fence_reg != I915_FENCE_REG_NONE)
seq_printf(m, " (fence: %d)", obj->fence_reg); seq_printf(m, " (fence: %d)", obj->fence_reg);
if (obj->gtt_space != NULL) if (obj->gtt_space != NULL)
...@@ -197,8 +199,8 @@ static int i915_gem_object_info(struct seq_file *m, void* data) ...@@ -197,8 +199,8 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 count, mappable_count; u32 count, mappable_count, purgeable_count;
size_t size, mappable_size; size_t size, mappable_size, purgeable_size;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
int ret; int ret;
...@@ -211,7 +213,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data) ...@@ -211,7 +213,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
dev_priv->mm.object_memory); dev_priv->mm.object_memory);
size = count = mappable_size = mappable_count = 0; size = count = mappable_size = mappable_count = 0;
count_objects(&dev_priv->mm.gtt_list, gtt_list); count_objects(&dev_priv->mm.bound_list, gtt_list);
seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n", seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n",
count, mappable_count, size, mappable_size); count, mappable_count, size, mappable_size);
...@@ -225,8 +227,16 @@ static int i915_gem_object_info(struct seq_file *m, void* data) ...@@ -225,8 +227,16 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
seq_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n", seq_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n",
count, mappable_count, size, mappable_size); count, mappable_count, size, mappable_size);
size = count = purgeable_size = purgeable_count = 0;
list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list) {
size += obj->base.size, ++count;
if (obj->madv == I915_MADV_DONTNEED)
purgeable_size += obj->base.size, ++purgeable_count;
}
seq_printf(m, "%u unbound objects, %zu bytes\n", count, size);
size = count = mappable_size = mappable_count = 0; size = count = mappable_size = mappable_count = 0;
list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
if (obj->fault_mappable) { if (obj->fault_mappable) {
size += obj->gtt_space->size; size += obj->gtt_space->size;
++count; ++count;
...@@ -235,7 +245,13 @@ static int i915_gem_object_info(struct seq_file *m, void* data) ...@@ -235,7 +245,13 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
mappable_size += obj->gtt_space->size; mappable_size += obj->gtt_space->size;
++mappable_count; ++mappable_count;
} }
if (obj->madv == I915_MADV_DONTNEED) {
purgeable_size += obj->base.size;
++purgeable_count;
} }
}
seq_printf(m, "%u purgeable objects, %zu bytes\n",
purgeable_count, purgeable_size);
seq_printf(m, "%u pinned mappable objects, %zu bytes\n", seq_printf(m, "%u pinned mappable objects, %zu bytes\n",
mappable_count, mappable_size); mappable_count, mappable_size);
seq_printf(m, "%u fault mappable objects, %zu bytes\n", seq_printf(m, "%u fault mappable objects, %zu bytes\n",
...@@ -264,7 +280,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void* data) ...@@ -264,7 +280,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void* data)
return ret; return ret;
total_obj_size = total_gtt_size = count = 0; total_obj_size = total_gtt_size = count = 0;
list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
if (list == PINNED_LIST && obj->pin_count == 0) if (list == PINNED_LIST && obj->pin_count == 0)
continue; continue;
...@@ -526,7 +542,8 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) ...@@ -526,7 +542,8 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
for (i = 0; i < dev_priv->num_fence_regs; i++) { for (i = 0; i < dev_priv->num_fence_regs; i++) {
struct drm_i915_gem_object *obj = dev_priv->fence_regs[i].obj; struct drm_i915_gem_object *obj = dev_priv->fence_regs[i].obj;
seq_printf(m, "Fenced object[%2d] = ", i); seq_printf(m, "Fence %d, pin count = %d, object = ",
i, dev_priv->fence_regs[i].pin_count);
if (obj == NULL) if (obj == NULL)
seq_printf(m, "unused"); seq_printf(m, "unused");
else else
...@@ -645,10 +662,9 @@ static void i915_ring_error_state(struct seq_file *m, ...@@ -645,10 +662,9 @@ static void i915_ring_error_state(struct seq_file *m,
seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]);
seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]);
seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]);
if (ring == RCS && INTEL_INFO(dev)->gen >= 4) { if (ring == RCS && INTEL_INFO(dev)->gen >= 4)
seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1);
seq_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); seq_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr);
}
if (INTEL_INFO(dev)->gen >= 4) if (INTEL_INFO(dev)->gen >= 4)
seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]);
seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]);
...@@ -697,11 +713,17 @@ static int i915_error_state(struct seq_file *m, void *unused) ...@@ -697,11 +713,17 @@ static int i915_error_state(struct seq_file *m, void *unused)
for (i = 0; i < dev_priv->num_fence_regs; i++) for (i = 0; i < dev_priv->num_fence_regs; i++)
seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]);
for (i = 0; i < ARRAY_SIZE(error->extra_instdone); i++)
seq_printf(m, " INSTDONE_%d: 0x%08x\n", i, error->extra_instdone[i]);
if (INTEL_INFO(dev)->gen >= 6) { if (INTEL_INFO(dev)->gen >= 6) {
seq_printf(m, "ERROR: 0x%08x\n", error->error); seq_printf(m, "ERROR: 0x%08x\n", error->error);
seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg);
} }
if (INTEL_INFO(dev)->gen == 7)
seq_printf(m, "ERR_INT: 0x%08x\n", error->err_int);
for_each_ring(ring, dev_priv, i) for_each_ring(ring, dev_priv, i)
i915_ring_error_state(m, dev, error, i); i915_ring_error_state(m, dev, error, i);
......
...@@ -235,10 +235,10 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) ...@@ -235,10 +235,10 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
} }
} }
dev_priv->cpp = init->cpp; dev_priv->dri1.cpp = init->cpp;
dev_priv->back_offset = init->back_offset; dev_priv->dri1.back_offset = init->back_offset;
dev_priv->front_offset = init->front_offset; dev_priv->dri1.front_offset = init->front_offset;
dev_priv->current_page = 0; dev_priv->dri1.current_page = 0;
if (master_priv->sarea_priv) if (master_priv->sarea_priv)
master_priv->sarea_priv->pf_current_page = 0; master_priv->sarea_priv->pf_current_page = 0;
...@@ -575,7 +575,7 @@ static int i915_dispatch_flip(struct drm_device * dev) ...@@ -575,7 +575,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n", DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n",
__func__, __func__,
dev_priv->current_page, dev_priv->dri1.current_page,
master_priv->sarea_priv->pf_current_page); master_priv->sarea_priv->pf_current_page);
i915_kernel_lost_context(dev); i915_kernel_lost_context(dev);
...@@ -589,12 +589,12 @@ static int i915_dispatch_flip(struct drm_device * dev) ...@@ -589,12 +589,12 @@ static int i915_dispatch_flip(struct drm_device * dev)
OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
OUT_RING(0); OUT_RING(0);
if (dev_priv->current_page == 0) { if (dev_priv->dri1.current_page == 0) {
OUT_RING(dev_priv->back_offset); OUT_RING(dev_priv->dri1.back_offset);
dev_priv->current_page = 1; dev_priv->dri1.current_page = 1;
} else { } else {
OUT_RING(dev_priv->front_offset); OUT_RING(dev_priv->dri1.front_offset);
dev_priv->current_page = 0; dev_priv->dri1.current_page = 0;
} }
OUT_RING(0); OUT_RING(0);
...@@ -613,7 +613,7 @@ static int i915_dispatch_flip(struct drm_device * dev) ...@@ -613,7 +613,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
ADVANCE_LP_RING(); ADVANCE_LP_RING();
} }
master_priv->sarea_priv->pf_current_page = dev_priv->current_page; master_priv->sarea_priv->pf_current_page = dev_priv->dri1.current_page;
return 0; return 0;
} }
...@@ -1012,6 +1012,9 @@ static int i915_getparam(struct drm_device *dev, void *data, ...@@ -1012,6 +1012,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_SEMAPHORES: case I915_PARAM_HAS_SEMAPHORES:
value = i915_semaphore_is_enabled(dev); value = i915_semaphore_is_enabled(dev);
break; break;
case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
value = 1;
break;
default: default:
DRM_DEBUG_DRIVER("Unknown parameter %d\n", DRM_DEBUG_DRIVER("Unknown parameter %d\n",
param->param); param->param);
...@@ -1555,11 +1558,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -1555,11 +1558,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
* *
* All tasks on the workqueue are expected to acquire the dev mutex * All tasks on the workqueue are expected to acquire the dev mutex
* so there is no point in running more than one instance of the * so there is no point in running more than one instance of the
* workqueue at any time: max_active = 1 and NON_REENTRANT. * workqueue at any time. Use an ordered one.
*/ */
dev_priv->wq = alloc_workqueue("i915", dev_priv->wq = alloc_ordered_workqueue("i915", 0);
WQ_UNBOUND | WQ_NON_REENTRANT,
1);
if (dev_priv->wq == NULL) { if (dev_priv->wq == NULL) {
DRM_ERROR("Failed to create our workqueue.\n"); DRM_ERROR("Failed to create our workqueue.\n");
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -1174,6 +1174,10 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ ...@@ -1174,6 +1174,10 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
if (unlikely(__fifo_ret)) { \ if (unlikely(__fifo_ret)) { \
gen6_gt_check_fifodbg(dev_priv); \ gen6_gt_check_fifodbg(dev_priv); \
} \ } \
if (IS_HASWELL(dev_priv->dev) && (I915_READ_NOTRACE(GEN7_ERR_INT) & ERR_INT_MMIO_UNCLAIMED)) { \
DRM_ERROR("Unclaimed write to %x\n", reg); \
writel(ERR_INT_MMIO_UNCLAIMED, dev_priv->regs + GEN7_ERR_INT); \
} \
} }
__i915_write(8, b) __i915_write(8, b)
__i915_write(16, w) __i915_write(16, w)
......
...@@ -196,9 +196,10 @@ struct drm_i915_error_state { ...@@ -196,9 +196,10 @@ struct drm_i915_error_state {
u32 cpu_ring_head[I915_NUM_RINGS]; u32 cpu_ring_head[I915_NUM_RINGS];
u32 cpu_ring_tail[I915_NUM_RINGS]; u32 cpu_ring_tail[I915_NUM_RINGS];
u32 error; /* gen6+ */ u32 error; /* gen6+ */
u32 err_int; /* gen7 */
u32 instpm[I915_NUM_RINGS]; u32 instpm[I915_NUM_RINGS];
u32 instps[I915_NUM_RINGS]; u32 instps[I915_NUM_RINGS];
u32 instdone1; u32 extra_instdone[I915_NUM_INSTDONE_REG];
u32 seqno[I915_NUM_RINGS]; u32 seqno[I915_NUM_RINGS];
u64 bbaddr; u64 bbaddr;
u32 fault_reg[I915_NUM_RINGS]; u32 fault_reg[I915_NUM_RINGS];
...@@ -428,12 +429,6 @@ typedef struct drm_i915_private { ...@@ -428,12 +429,6 @@ typedef struct drm_i915_private {
struct resource mch_res; struct resource mch_res;
unsigned int cpp;
int back_offset;
int front_offset;
int current_page;
int page_flipping;
atomic_t irq_received; atomic_t irq_received;
/* protects the irq masks */ /* protects the irq masks */
...@@ -451,7 +446,6 @@ typedef struct drm_i915_private { ...@@ -451,7 +446,6 @@ typedef struct drm_i915_private {
u32 hotplug_supported_mask; u32 hotplug_supported_mask;
struct work_struct hotplug_work; struct work_struct hotplug_work;
unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
int num_pipe; int num_pipe;
int num_pch_pll; int num_pch_pll;
...@@ -460,8 +454,7 @@ typedef struct drm_i915_private { ...@@ -460,8 +454,7 @@ typedef struct drm_i915_private {
struct timer_list hangcheck_timer; struct timer_list hangcheck_timer;
int hangcheck_count; int hangcheck_count;
uint32_t last_acthd[I915_NUM_RINGS]; uint32_t last_acthd[I915_NUM_RINGS];
uint32_t last_instdone; uint32_t prev_instdone[I915_NUM_INSTDONE_REG];
uint32_t last_instdone1;
unsigned int stop_rings; unsigned int stop_rings;
...@@ -692,7 +685,13 @@ typedef struct drm_i915_private { ...@@ -692,7 +685,13 @@ typedef struct drm_i915_private {
struct drm_mm gtt_space; struct drm_mm gtt_space;
/** List of all objects in gtt_space. Used to restore gtt /** List of all objects in gtt_space. Used to restore gtt
* mappings on resume */ * mappings on resume */
struct list_head gtt_list; struct list_head bound_list;
/**
* List of objects which are not bound to the GTT (thus
* are idle and not used by the GPU) but still have
* (presumably uncached) pages still attached.
*/
struct list_head unbound_list;
/** Usable portion of the GTT for GEM */ /** Usable portion of the GTT for GEM */
unsigned long gtt_start; unsigned long gtt_start;
...@@ -790,6 +789,12 @@ typedef struct drm_i915_private { ...@@ -790,6 +789,12 @@ typedef struct drm_i915_private {
struct { struct {
unsigned allow_batchbuffer : 1; unsigned allow_batchbuffer : 1;
u32 __iomem *gfx_hws_cpu_addr; u32 __iomem *gfx_hws_cpu_addr;
unsigned int cpp;
int back_offset;
int front_offset;
int current_page;
int page_flipping;
} dri1; } dri1;
/* Kernel Modesetting */ /* Kernel Modesetting */
...@@ -1296,19 +1301,20 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data, ...@@ -1296,19 +1301,20 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
void i915_gem_load(struct drm_device *dev); void i915_gem_load(struct drm_device *dev);
int i915_gem_init_object(struct drm_gem_object *obj); int i915_gem_init_object(struct drm_gem_object *obj);
void i915_gem_object_init(struct drm_i915_gem_object *obj);
struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
size_t size); size_t size);
void i915_gem_free_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj);
int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
uint32_t alignment, uint32_t alignment,
bool map_and_fenceable); bool map_and_fenceable,
bool nonblocking);
void i915_gem_object_unpin(struct drm_i915_gem_object *obj); void i915_gem_object_unpin(struct drm_i915_gem_object *obj);
int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj); int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj);
void i915_gem_release_mmap(struct drm_i915_gem_object *obj); void i915_gem_release_mmap(struct drm_i915_gem_object *obj);
void i915_gem_lastclose(struct drm_device *dev); void i915_gem_lastclose(struct drm_device *dev);
int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, int __must_check i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj);
gfp_t gfpmask);
int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
int i915_gem_object_sync(struct drm_i915_gem_object *obj, int i915_gem_object_sync(struct drm_i915_gem_object *obj,
struct intel_ring_buffer *to); struct intel_ring_buffer *to);
...@@ -1449,8 +1455,9 @@ void i915_gem_init_global_gtt(struct drm_device *dev, ...@@ -1449,8 +1455,9 @@ void i915_gem_init_global_gtt(struct drm_device *dev,
int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size, int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size,
unsigned alignment, unsigned alignment,
unsigned cache_level, unsigned cache_level,
bool mappable); bool mappable,
int i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only); bool nonblock);
int i915_gem_evict_everything(struct drm_device *dev);
/* i915_gem_stolen.c */ /* i915_gem_stolen.c */
int i915_gem_init_stolen(struct drm_device *dev); int i915_gem_init_stolen(struct drm_device *dev);
......
This diff is collapsed.
...@@ -221,7 +221,7 @@ static int create_default_context(struct drm_i915_private *dev_priv) ...@@ -221,7 +221,7 @@ static int create_default_context(struct drm_i915_private *dev_priv)
* default context. * default context.
*/ */
dev_priv->ring[RCS].default_context = ctx; 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, false);
if (ret) if (ret)
goto err_destroy; goto err_destroy;
...@@ -374,7 +374,7 @@ static int do_switch(struct i915_hw_context *to) ...@@ -374,7 +374,7 @@ static int do_switch(struct i915_hw_context *to)
if (from_obj == to->obj) if (from_obj == to->obj)
return 0; return 0;
ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false); ret = i915_gem_object_pin(to->obj, CONTEXT_ALIGN, false, false);
if (ret) if (ret)
return ret; return ret;
......
...@@ -33,7 +33,7 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme ...@@ -33,7 +33,7 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
struct drm_i915_gem_object *obj = attachment->dmabuf->priv; struct drm_i915_gem_object *obj = attachment->dmabuf->priv;
struct drm_device *dev = obj->base.dev; struct drm_device *dev = obj->base.dev;
int npages = obj->base.size / PAGE_SIZE; int npages = obj->base.size / PAGE_SIZE;
struct sg_table *sg = NULL; struct sg_table *sg;
int ret; int ret;
int nents; int nents;
...@@ -41,9 +41,9 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme ...@@ -41,9 +41,9 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
if (ret) if (ret)
return ERR_PTR(ret); return ERR_PTR(ret);
if (!obj->pages) { ret = i915_gem_object_get_pages_gtt(obj);
ret = i915_gem_object_get_pages_gtt(obj, __GFP_NORETRY | __GFP_NOWARN); if (ret) {
if (ret) sg = ERR_PTR(ret);
goto out; goto out;
} }
...@@ -89,13 +89,11 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf) ...@@ -89,13 +89,11 @@ static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
goto out_unlock; goto out_unlock;
} }
if (!obj->pages) { ret = i915_gem_object_get_pages_gtt(obj);
ret = i915_gem_object_get_pages_gtt(obj, __GFP_NORETRY | __GFP_NOWARN);
if (ret) { if (ret) {
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
}
obj->dma_buf_vmapping = vmap(obj->pages, obj->base.size / PAGE_SIZE, 0, PAGE_KERNEL); obj->dma_buf_vmapping = vmap(obj->pages, obj->base.size / PAGE_SIZE, 0, PAGE_KERNEL);
if (!obj->dma_buf_vmapping) { if (!obj->dma_buf_vmapping) {
...@@ -151,6 +149,22 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct * ...@@ -151,6 +149,22 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *
return -EINVAL; return -EINVAL;
} }
static int i915_gem_begin_cpu_access(struct dma_buf *dma_buf, size_t start, size_t length, enum dma_data_direction direction)
{
struct drm_i915_gem_object *obj = dma_buf->priv;
struct drm_device *dev = obj->base.dev;
int ret;
bool write = (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE);
ret = i915_mutex_lock_interruptible(dev);
if (ret)
return ret;
ret = i915_gem_object_set_to_cpu_domain(obj, write);
mutex_unlock(&dev->struct_mutex);
return ret;
}
static const struct dma_buf_ops i915_dmabuf_ops = { static const struct dma_buf_ops i915_dmabuf_ops = {
.map_dma_buf = i915_gem_map_dma_buf, .map_dma_buf = i915_gem_map_dma_buf,
.unmap_dma_buf = i915_gem_unmap_dma_buf, .unmap_dma_buf = i915_gem_unmap_dma_buf,
...@@ -162,6 +176,7 @@ static const struct dma_buf_ops i915_dmabuf_ops = { ...@@ -162,6 +176,7 @@ static const struct dma_buf_ops i915_dmabuf_ops = {
.mmap = i915_gem_dmabuf_mmap, .mmap = i915_gem_dmabuf_mmap,
.vmap = i915_gem_dmabuf_vmap, .vmap = i915_gem_dmabuf_vmap,
.vunmap = i915_gem_dmabuf_vunmap, .vunmap = i915_gem_dmabuf_vunmap,
.begin_cpu_access = i915_gem_begin_cpu_access,
}; };
struct dma_buf *i915_gem_prime_export(struct drm_device *dev, struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
......
...@@ -45,7 +45,7 @@ mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) ...@@ -45,7 +45,7 @@ mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind)
int int
i915_gem_evict_something(struct drm_device *dev, int min_size, i915_gem_evict_something(struct drm_device *dev, int min_size,
unsigned alignment, unsigned cache_level, unsigned alignment, unsigned cache_level,
bool mappable) bool mappable, bool nonblocking)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
struct list_head eviction_list, unwind_list; struct list_head eviction_list, unwind_list;
...@@ -92,12 +92,16 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, ...@@ -92,12 +92,16 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
goto found; goto found;
} }
if (nonblocking)
goto none;
/* Now merge in the soon-to-be-expired objects... */ /* Now merge in the soon-to-be-expired objects... */
list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) {
if (mark_free(obj, &unwind_list)) if (mark_free(obj, &unwind_list))
goto found; goto found;
} }
none:
/* Nothing found, clean up and bail out! */ /* Nothing found, clean up and bail out! */
while (!list_empty(&unwind_list)) { while (!list_empty(&unwind_list)) {
obj = list_first_entry(&unwind_list, obj = list_first_entry(&unwind_list,
...@@ -148,7 +152,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, ...@@ -148,7 +152,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
} }
int int
i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only) i915_gem_evict_everything(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj, *next; struct drm_i915_gem_object *obj, *next;
...@@ -160,7 +164,7 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only) ...@@ -160,7 +164,7 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only)
if (lists_empty) if (lists_empty)
return -ENOSPC; return -ENOSPC;
trace_i915_gem_evict_everything(dev, purgeable_only); trace_i915_gem_evict_everything(dev);
/* The gpu_idle will flush everything in the write domain to the /* The gpu_idle will flush everything in the write domain to the
* active list. Then we must move everything off the active list * active list. Then we must move everything off the active list
...@@ -174,12 +178,9 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only) ...@@ -174,12 +178,9 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only)
/* Having flushed everything, unbind() should never raise an error */ /* Having flushed everything, unbind() should never raise an error */
list_for_each_entry_safe(obj, next, list_for_each_entry_safe(obj, next,
&dev_priv->mm.inactive_list, mm_list) { &dev_priv->mm.inactive_list, mm_list)
if (!purgeable_only || obj->madv != I915_MADV_WILLNEED) {
if (obj->pin_count == 0) if (obj->pin_count == 0)
WARN_ON(i915_gem_object_unbind(obj)); WARN_ON(i915_gem_object_unbind(obj));
}
}
return 0; return 0;
} }
...@@ -95,6 +95,7 @@ eb_destroy(struct eb_objects *eb) ...@@ -95,6 +95,7 @@ eb_destroy(struct eb_objects *eb)
static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) static inline int use_cpu_reloc(struct drm_i915_gem_object *obj)
{ {
return (obj->base.write_domain == I915_GEM_DOMAIN_CPU || return (obj->base.write_domain == I915_GEM_DOMAIN_CPU ||
!obj->map_and_fenceable ||
obj->cache_level != I915_CACHE_NONE); obj->cache_level != I915_CACHE_NONE);
} }
...@@ -330,7 +331,8 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, ...@@ -330,7 +331,8 @@ i915_gem_execbuffer_relocate(struct drm_device *dev,
return ret; return ret;
} }
#define __EXEC_OBJECT_HAS_FENCE (1<<31) #define __EXEC_OBJECT_HAS_PIN (1<<31)
#define __EXEC_OBJECT_HAS_FENCE (1<<30)
static int static int
need_reloc_mappable(struct drm_i915_gem_object *obj) need_reloc_mappable(struct drm_i915_gem_object *obj)
...@@ -340,9 +342,10 @@ need_reloc_mappable(struct drm_i915_gem_object *obj) ...@@ -340,9 +342,10 @@ need_reloc_mappable(struct drm_i915_gem_object *obj)
} }
static int static int
pin_and_fence_object(struct drm_i915_gem_object *obj, i915_gem_execbuffer_reserve_object(struct drm_i915_gem_object *obj,
struct intel_ring_buffer *ring) struct intel_ring_buffer *ring)
{ {
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
bool need_fence, need_mappable; bool need_fence, need_mappable;
...@@ -354,15 +357,17 @@ pin_and_fence_object(struct drm_i915_gem_object *obj, ...@@ -354,15 +357,17 @@ pin_and_fence_object(struct drm_i915_gem_object *obj,
obj->tiling_mode != I915_TILING_NONE; obj->tiling_mode != I915_TILING_NONE;
need_mappable = need_fence || need_reloc_mappable(obj); need_mappable = need_fence || need_reloc_mappable(obj);
ret = i915_gem_object_pin(obj, entry->alignment, need_mappable); ret = i915_gem_object_pin(obj, entry->alignment, need_mappable, false);
if (ret) if (ret)
return ret; return ret;
entry->flags |= __EXEC_OBJECT_HAS_PIN;
if (has_fenced_gpu_access) { if (has_fenced_gpu_access) {
if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
ret = i915_gem_object_get_fence(obj); ret = i915_gem_object_get_fence(obj);
if (ret) if (ret)
goto err_unpin; return ret;
if (i915_gem_object_pin_fence(obj)) if (i915_gem_object_pin_fence(obj))
entry->flags |= __EXEC_OBJECT_HAS_FENCE; entry->flags |= __EXEC_OBJECT_HAS_FENCE;
...@@ -371,12 +376,35 @@ pin_and_fence_object(struct drm_i915_gem_object *obj, ...@@ -371,12 +376,35 @@ pin_and_fence_object(struct drm_i915_gem_object *obj,
} }
} }
/* Ensure ppgtt mapping exists if needed */
if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) {
i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
obj, obj->cache_level);
obj->has_aliasing_ppgtt_mapping = 1;
}
entry->offset = obj->gtt_offset; entry->offset = obj->gtt_offset;
return 0; return 0;
}
static void
i915_gem_execbuffer_unreserve_object(struct drm_i915_gem_object *obj)
{
struct drm_i915_gem_exec_object2 *entry;
if (!obj->gtt_space)
return;
entry = obj->exec_entry;
if (entry->flags & __EXEC_OBJECT_HAS_FENCE)
i915_gem_object_unpin_fence(obj);
err_unpin: if (entry->flags & __EXEC_OBJECT_HAS_PIN)
i915_gem_object_unpin(obj); i915_gem_object_unpin(obj);
return ret;
entry->flags &= ~(__EXEC_OBJECT_HAS_FENCE | __EXEC_OBJECT_HAS_PIN);
} }
static int static int
...@@ -384,11 +412,10 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, ...@@ -384,11 +412,10 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
struct drm_file *file, struct drm_file *file,
struct list_head *objects) struct list_head *objects)
{ {
drm_i915_private_t *dev_priv = ring->dev->dev_private;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
int ret, retry;
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
struct list_head ordered_objects; struct list_head ordered_objects;
bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
int retry;
INIT_LIST_HEAD(&ordered_objects); INIT_LIST_HEAD(&ordered_objects);
while (!list_empty(objects)) { while (!list_empty(objects)) {
...@@ -426,12 +453,12 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, ...@@ -426,12 +453,12 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
* 2. Bind new objects. * 2. Bind new objects.
* 3. Decrement pin count. * 3. Decrement pin count.
* *
* This avoid unnecessary unbinding of later objects in order to makr * This avoid unnecessary unbinding of later objects in order to make
* room for the earlier objects *unless* we need to defragment. * room for the earlier objects *unless* we need to defragment.
*/ */
retry = 0; retry = 0;
do { do {
ret = 0; int ret = 0;
/* Unbind any ill-fitting objects or pin. */ /* Unbind any ill-fitting objects or pin. */
list_for_each_entry(obj, objects, exec_list) { list_for_each_entry(obj, objects, exec_list) {
...@@ -451,7 +478,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, ...@@ -451,7 +478,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
(need_mappable && !obj->map_and_fenceable)) (need_mappable && !obj->map_and_fenceable))
ret = i915_gem_object_unbind(obj); ret = i915_gem_object_unbind(obj);
else else
ret = pin_and_fence_object(obj, ring); ret = i915_gem_execbuffer_reserve_object(obj, ring);
if (ret) if (ret)
goto err; goto err;
} }
...@@ -461,77 +488,22 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, ...@@ -461,77 +488,22 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
if (obj->gtt_space) if (obj->gtt_space)
continue; continue;
ret = pin_and_fence_object(obj, ring); ret = i915_gem_execbuffer_reserve_object(obj, ring);
if (ret) { if (ret)
int ret_ignore; goto err;
/* This can potentially raise a harmless
* -EINVAL if we failed to bind in the above
* call. It cannot raise -EINTR since we know
* that the bo is freshly bound and so will
* not need to be flushed or waited upon.
*/
ret_ignore = i915_gem_object_unbind(obj);
(void)ret_ignore;
WARN_ON(obj->gtt_space);
break;
}
}
/* Decrement pin count for bound objects */
list_for_each_entry(obj, objects, exec_list) {
struct drm_i915_gem_exec_object2 *entry;
if (!obj->gtt_space)
continue;
entry = obj->exec_entry;
if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
i915_gem_object_unpin_fence(obj);
entry->flags &= ~__EXEC_OBJECT_HAS_FENCE;
} }
i915_gem_object_unpin(obj); err: /* Decrement pin count for bound objects */
list_for_each_entry(obj, objects, exec_list)
/* ... and ensure ppgtt mapping exist if needed. */ i915_gem_execbuffer_unreserve_object(obj);
if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) {
i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt,
obj, obj->cache_level);
obj->has_aliasing_ppgtt_mapping = 1;
}
}
if (ret != -ENOSPC || retry > 1) if (ret != -ENOSPC || retry++)
return ret; return ret;
/* First attempt, just clear anything that is purgeable. ret = i915_gem_evict_everything(ring->dev);
* Second attempt, clear the entire GTT.
*/
ret = i915_gem_evict_everything(ring->dev, retry == 0);
if (ret) if (ret)
return ret; return ret;
retry++;
} while (1); } while (1);
err:
list_for_each_entry_continue_reverse(obj, objects, exec_list) {
struct drm_i915_gem_exec_object2 *entry;
if (!obj->gtt_space)
continue;
entry = obj->exec_entry;
if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
i915_gem_object_unpin_fence(obj);
entry->flags &= ~__EXEC_OBJECT_HAS_FENCE;
}
i915_gem_object_unpin(obj);
}
return ret;
} }
static int static int
......
...@@ -351,7 +351,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) ...@@ -351,7 +351,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
intel_gtt_clear_range(dev_priv->mm.gtt_start / PAGE_SIZE, intel_gtt_clear_range(dev_priv->mm.gtt_start / PAGE_SIZE,
(dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE); (dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE);
list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) {
i915_gem_clflush_object(obj); i915_gem_clflush_object(obj);
i915_gem_gtt_bind_object(obj, obj->cache_level); i915_gem_gtt_bind_object(obj, obj->cache_level);
} }
......
...@@ -1070,6 +1070,36 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, ...@@ -1070,6 +1070,36 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
return NULL; return NULL;
} }
/* NB: please notice the memset */
static void i915_get_extra_instdone(struct drm_device *dev,
uint32_t *instdone)
{
struct drm_i915_private *dev_priv = dev->dev_private;
memset(instdone, 0, sizeof(*instdone) * I915_NUM_INSTDONE_REG);
switch(INTEL_INFO(dev)->gen) {
case 2:
case 3:
instdone[0] = I915_READ(INSTDONE);
break;
case 4:
case 5:
case 6:
instdone[0] = I915_READ(INSTDONE_I965);
instdone[1] = I915_READ(INSTDONE1);
break;
default:
WARN_ONCE(1, "Unsupported platform\n");
case 7:
instdone[0] = I915_READ(GEN7_INSTDONE_1);
instdone[1] = I915_READ(GEN7_SC_INSTDONE);
instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE);
instdone[3] = I915_READ(GEN7_ROW_INSTDONE);
break;
}
}
static void i915_record_ring_state(struct drm_device *dev, static void i915_record_ring_state(struct drm_device *dev,
struct drm_i915_error_state *error, struct drm_i915_error_state *error,
struct intel_ring_buffer *ring) struct intel_ring_buffer *ring)
...@@ -1091,10 +1121,8 @@ static void i915_record_ring_state(struct drm_device *dev, ...@@ -1091,10 +1121,8 @@ static void i915_record_ring_state(struct drm_device *dev,
error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base));
error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base));
error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base));
if (ring->id == RCS) { if (ring->id == RCS)
error->instdone1 = I915_READ(INSTDONE1);
error->bbaddr = I915_READ64(BB_ADDR); error->bbaddr = I915_READ64(BB_ADDR);
}
} else { } else {
error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX); error->faddr[ring->id] = I915_READ(DMA_FADD_I8XX);
error->ipeir[ring->id] = I915_READ(IPEIR); error->ipeir[ring->id] = I915_READ(IPEIR);
...@@ -1210,6 +1238,11 @@ static void i915_capture_error_state(struct drm_device *dev) ...@@ -1210,6 +1238,11 @@ static void i915_capture_error_state(struct drm_device *dev)
error->done_reg = I915_READ(DONE_REG); error->done_reg = I915_READ(DONE_REG);
} }
if (INTEL_INFO(dev)->gen == 7)
error->err_int = I915_READ(GEN7_ERR_INT);
i915_get_extra_instdone(dev, error->extra_instdone);
i915_gem_record_fences(dev, error); i915_gem_record_fences(dev, error);
i915_gem_record_rings(dev, error); i915_gem_record_rings(dev, error);
...@@ -1221,7 +1254,7 @@ static void i915_capture_error_state(struct drm_device *dev) ...@@ -1221,7 +1254,7 @@ static void i915_capture_error_state(struct drm_device *dev)
list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list)
i++; i++;
error->active_bo_count = i; error->active_bo_count = i;
list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
if (obj->pin_count) if (obj->pin_count)
i++; i++;
error->pinned_bo_count = i - error->active_bo_count; error->pinned_bo_count = i - error->active_bo_count;
...@@ -1246,7 +1279,7 @@ static void i915_capture_error_state(struct drm_device *dev) ...@@ -1246,7 +1279,7 @@ static void i915_capture_error_state(struct drm_device *dev)
error->pinned_bo_count = error->pinned_bo_count =
capture_pinned_bo(error->pinned_bo, capture_pinned_bo(error->pinned_bo,
error->pinned_bo_count, error->pinned_bo_count,
&dev_priv->mm.gtt_list); &dev_priv->mm.bound_list);
do_gettimeofday(&error->time); do_gettimeofday(&error->time);
...@@ -1285,24 +1318,26 @@ void i915_destroy_error_state(struct drm_device *dev) ...@@ -1285,24 +1318,26 @@ void i915_destroy_error_state(struct drm_device *dev)
static void i915_report_and_clear_eir(struct drm_device *dev) static void i915_report_and_clear_eir(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t instdone[I915_NUM_INSTDONE_REG];
u32 eir = I915_READ(EIR); u32 eir = I915_READ(EIR);
int pipe; int pipe, i;
if (!eir) if (!eir)
return; return;
pr_err("render error detected, EIR: 0x%08x\n", eir); pr_err("render error detected, EIR: 0x%08x\n", eir);
i915_get_extra_instdone(dev, instdone);
if (IS_G4X(dev)) { if (IS_G4X(dev)) {
if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) { if (eir & (GM45_ERROR_MEM_PRIV | GM45_ERROR_CP_PRIV)) {
u32 ipeir = I915_READ(IPEIR_I965); u32 ipeir = I915_READ(IPEIR_I965);
pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965)); pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965));
pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965)); pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965));
pr_err(" INSTDONE: 0x%08x\n", for (i = 0; i < ARRAY_SIZE(instdone); i++)
I915_READ(INSTDONE_I965)); pr_err(" INSTDONE_%d: 0x%08x\n", i, instdone[i]);
pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS)); pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS));
pr_err(" INSTDONE1: 0x%08x\n", I915_READ(INSTDONE1));
pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965)); pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965));
I915_WRITE(IPEIR_I965, ipeir); I915_WRITE(IPEIR_I965, ipeir);
POSTING_READ(IPEIR_I965); POSTING_READ(IPEIR_I965);
...@@ -1336,12 +1371,13 @@ static void i915_report_and_clear_eir(struct drm_device *dev) ...@@ -1336,12 +1371,13 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
if (eir & I915_ERROR_INSTRUCTION) { if (eir & I915_ERROR_INSTRUCTION) {
pr_err("instruction error\n"); pr_err("instruction error\n");
pr_err(" INSTPM: 0x%08x\n", I915_READ(INSTPM)); pr_err(" INSTPM: 0x%08x\n", I915_READ(INSTPM));
for (i = 0; i < ARRAY_SIZE(instdone); i++)
pr_err(" INSTDONE_%d: 0x%08x\n", i, instdone[i]);
if (INTEL_INFO(dev)->gen < 4) { if (INTEL_INFO(dev)->gen < 4) {
u32 ipeir = I915_READ(IPEIR); u32 ipeir = I915_READ(IPEIR);
pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR)); pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR));
pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR)); pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR));
pr_err(" INSTDONE: 0x%08x\n", I915_READ(INSTDONE));
pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD)); pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD));
I915_WRITE(IPEIR, ipeir); I915_WRITE(IPEIR, ipeir);
POSTING_READ(IPEIR); POSTING_READ(IPEIR);
...@@ -1350,10 +1386,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) ...@@ -1350,10 +1386,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965)); pr_err(" IPEIR: 0x%08x\n", I915_READ(IPEIR_I965));
pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965)); pr_err(" IPEHR: 0x%08x\n", I915_READ(IPEHR_I965));
pr_err(" INSTDONE: 0x%08x\n",
I915_READ(INSTDONE_I965));
pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS)); pr_err(" INSTPS: 0x%08x\n", I915_READ(INSTPS));
pr_err(" INSTDONE1: 0x%08x\n", I915_READ(INSTDONE1));
pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965)); pr_err(" ACTHD: 0x%08x\n", I915_READ(ACTHD_I965));
I915_WRITE(IPEIR_I965, ipeir); I915_WRITE(IPEIR_I965, ipeir);
POSTING_READ(IPEIR_I965); POSTING_READ(IPEIR_I965);
...@@ -1668,7 +1701,7 @@ void i915_hangcheck_elapsed(unsigned long data) ...@@ -1668,7 +1701,7 @@ void i915_hangcheck_elapsed(unsigned long data)
{ {
struct drm_device *dev = (struct drm_device *)data; struct drm_device *dev = (struct drm_device *)data;
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
uint32_t acthd[I915_NUM_RINGS], instdone, instdone1; uint32_t acthd[I915_NUM_RINGS], instdone[I915_NUM_INSTDONE_REG];
struct intel_ring_buffer *ring; struct intel_ring_buffer *ring;
bool err = false, idle; bool err = false, idle;
int i; int i;
...@@ -1696,25 +1729,16 @@ void i915_hangcheck_elapsed(unsigned long data) ...@@ -1696,25 +1729,16 @@ void i915_hangcheck_elapsed(unsigned long data)
return; return;
} }
if (INTEL_INFO(dev)->gen < 4) { i915_get_extra_instdone(dev, instdone);
instdone = I915_READ(INSTDONE);
instdone1 = 0;
} else {
instdone = I915_READ(INSTDONE_I965);
instdone1 = I915_READ(INSTDONE1);
}
if (memcmp(dev_priv->last_acthd, acthd, sizeof(acthd)) == 0 && if (memcmp(dev_priv->last_acthd, acthd, sizeof(acthd)) == 0 &&
dev_priv->last_instdone == instdone && memcmp(dev_priv->prev_instdone, instdone, sizeof(instdone)) == 0) {
dev_priv->last_instdone1 == instdone1) {
if (i915_hangcheck_hung(dev)) if (i915_hangcheck_hung(dev))
return; return;
} else { } else {
dev_priv->hangcheck_count = 0; dev_priv->hangcheck_count = 0;
memcpy(dev_priv->last_acthd, acthd, sizeof(acthd)); memcpy(dev_priv->last_acthd, acthd, sizeof(acthd));
dev_priv->last_instdone = instdone; memcpy(dev_priv->prev_instdone, instdone, sizeof(instdone));
dev_priv->last_instdone1 = instdone1;
} }
repeat: repeat:
......
...@@ -479,6 +479,11 @@ ...@@ -479,6 +479,11 @@
#define IPEIR_I965 0x02064 #define IPEIR_I965 0x02064
#define IPEHR_I965 0x02068 #define IPEHR_I965 0x02068
#define INSTDONE_I965 0x0206c #define INSTDONE_I965 0x0206c
#define GEN7_INSTDONE_1 0x0206c
#define GEN7_SC_INSTDONE 0x07100
#define GEN7_SAMPLER_INSTDONE 0x0e160
#define GEN7_ROW_INSTDONE 0x0e164
#define I915_NUM_INSTDONE_REG 4
#define RING_IPEIR(base) ((base)+0x64) #define RING_IPEIR(base) ((base)+0x64)
#define RING_IPEHR(base) ((base)+0x68) #define RING_IPEHR(base) ((base)+0x68)
#define RING_INSTDONE(base) ((base)+0x6c) #define RING_INSTDONE(base) ((base)+0x6c)
...@@ -501,6 +506,8 @@ ...@@ -501,6 +506,8 @@
#define DMA_FADD_I8XX 0x020d0 #define DMA_FADD_I8XX 0x020d0
#define ERROR_GEN6 0x040a0 #define ERROR_GEN6 0x040a0
#define GEN7_ERR_INT 0x44040
#define ERR_INT_MMIO_UNCLAIMED (1<<13)
/* GM45+ chicken bits -- debug workaround bits that may be required /* GM45+ chicken bits -- debug workaround bits that may be required
* for various sorts of correct behavior. The top 16 bits of each are * for various sorts of correct behavior. The top 16 bits of each are
...@@ -4248,7 +4255,15 @@ ...@@ -4248,7 +4255,15 @@
#define G4X_HDMIW_HDMIEDID 0x6210C #define G4X_HDMIW_HDMIEDID 0x6210C
#define IBX_HDMIW_HDMIEDID_A 0xE2050 #define IBX_HDMIW_HDMIEDID_A 0xE2050
#define IBX_HDMIW_HDMIEDID_B 0xE2150
#define IBX_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \
IBX_HDMIW_HDMIEDID_A, \
IBX_HDMIW_HDMIEDID_B)
#define IBX_AUD_CNTL_ST_A 0xE20B4 #define IBX_AUD_CNTL_ST_A 0xE20B4
#define IBX_AUD_CNTL_ST_B 0xE21B4
#define IBX_AUD_CNTL_ST(pipe) _PIPE(pipe, \
IBX_AUD_CNTL_ST_A, \
IBX_AUD_CNTL_ST_B)
#define IBX_ELD_BUFFER_SIZE (0x1f << 10) #define IBX_ELD_BUFFER_SIZE (0x1f << 10)
#define IBX_ELD_ADDRESS (0x1f << 5) #define IBX_ELD_ADDRESS (0x1f << 5)
#define IBX_ELD_ACK (1 << 4) #define IBX_ELD_ACK (1 << 4)
...@@ -4257,7 +4272,15 @@ ...@@ -4257,7 +4272,15 @@
#define IBX_CP_READYB (1 << 1) #define IBX_CP_READYB (1 << 1)
#define CPT_HDMIW_HDMIEDID_A 0xE5050 #define CPT_HDMIW_HDMIEDID_A 0xE5050
#define CPT_HDMIW_HDMIEDID_B 0xE5150
#define CPT_HDMIW_HDMIEDID(pipe) _PIPE(pipe, \
CPT_HDMIW_HDMIEDID_A, \
CPT_HDMIW_HDMIEDID_B)
#define CPT_AUD_CNTL_ST_A 0xE50B4 #define CPT_AUD_CNTL_ST_A 0xE50B4
#define CPT_AUD_CNTL_ST_B 0xE51B4
#define CPT_AUD_CNTL_ST(pipe) _PIPE(pipe, \
CPT_AUD_CNTL_ST_A, \
CPT_AUD_CNTL_ST_B)
#define CPT_AUD_CNTRL_ST2 0xE50C0 #define CPT_AUD_CNTRL_ST2 0xE50C0
/* These are the 4 32-bit write offset registers for each stream /* These are the 4 32-bit write offset registers for each stream
...@@ -4267,7 +4290,15 @@ ...@@ -4267,7 +4290,15 @@
#define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4) #define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4)
#define IBX_AUD_CONFIG_A 0xe2000 #define IBX_AUD_CONFIG_A 0xe2000
#define IBX_AUD_CONFIG_B 0xe2100
#define IBX_AUD_CFG(pipe) _PIPE(pipe, \
IBX_AUD_CONFIG_A, \
IBX_AUD_CONFIG_B)
#define CPT_AUD_CONFIG_A 0xe5000 #define CPT_AUD_CONFIG_A 0xe5000
#define CPT_AUD_CONFIG_B 0xe5100
#define CPT_AUD_CFG(pipe) _PIPE(pipe, \
CPT_AUD_CONFIG_A, \
CPT_AUD_CONFIG_B)
#define AUD_CONFIG_N_VALUE_INDEX (1 << 29) #define AUD_CONFIG_N_VALUE_INDEX (1 << 29)
#define AUD_CONFIG_N_PROG_ENABLE (1 << 28) #define AUD_CONFIG_N_PROG_ENABLE (1 << 28)
#define AUD_CONFIG_UPPER_N_SHIFT 20 #define AUD_CONFIG_UPPER_N_SHIFT 20
...@@ -4278,6 +4309,54 @@ ...@@ -4278,6 +4309,54 @@
#define AUD_CONFIG_PIXEL_CLOCK_HDMI (0xf << 16) #define AUD_CONFIG_PIXEL_CLOCK_HDMI (0xf << 16)
#define AUD_CONFIG_DISABLE_NCTS (1 << 3) #define AUD_CONFIG_DISABLE_NCTS (1 << 3)
/* HSW Audio */
#define HSW_AUD_CONFIG_A 0x65000 /* Audio Configuration Transcoder A */
#define HSW_AUD_CONFIG_B 0x65100 /* Audio Configuration Transcoder B */
#define HSW_AUD_CFG(pipe) _PIPE(pipe, \
HSW_AUD_CONFIG_A, \
HSW_AUD_CONFIG_B)
#define HSW_AUD_MISC_CTRL_A 0x65010 /* Audio Misc Control Convert 1 */
#define HSW_AUD_MISC_CTRL_B 0x65110 /* Audio Misc Control Convert 2 */
#define HSW_AUD_MISC_CTRL(pipe) _PIPE(pipe, \
HSW_AUD_MISC_CTRL_A, \
HSW_AUD_MISC_CTRL_B)
#define HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4 /* Audio DIP and ELD Control State Transcoder A */
#define HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4 /* Audio DIP and ELD Control State Transcoder B */
#define HSW_AUD_DIP_ELD_CTRL(pipe) _PIPE(pipe, \
HSW_AUD_DIP_ELD_CTRL_ST_A, \
HSW_AUD_DIP_ELD_CTRL_ST_B)
/* Audio Digital Converter */
#define HSW_AUD_DIG_CNVT_1 0x65080 /* Audio Converter 1 */
#define HSW_AUD_DIG_CNVT_2 0x65180 /* Audio Converter 1 */
#define AUD_DIG_CNVT(pipe) _PIPE(pipe, \
HSW_AUD_DIG_CNVT_1, \
HSW_AUD_DIG_CNVT_2)
#define DIP_PORT_SEL_MASK 0x3
#define HSW_AUD_EDID_DATA_A 0x65050
#define HSW_AUD_EDID_DATA_B 0x65150
#define HSW_AUD_EDID_DATA(pipe) _PIPE(pipe, \
HSW_AUD_EDID_DATA_A, \
HSW_AUD_EDID_DATA_B)
#define HSW_AUD_PIPE_CONV_CFG 0x6507c /* Audio pipe and converter configs */
#define HSW_AUD_PIN_ELD_CP_VLD 0x650c0 /* Audio ELD and CP Ready Status */
#define AUDIO_INACTIVE_C (1<<11)
#define AUDIO_INACTIVE_B (1<<7)
#define AUDIO_INACTIVE_A (1<<3)
#define AUDIO_OUTPUT_ENABLE_A (1<<2)
#define AUDIO_OUTPUT_ENABLE_B (1<<6)
#define AUDIO_OUTPUT_ENABLE_C (1<<10)
#define AUDIO_ELD_VALID_A (1<<0)
#define AUDIO_ELD_VALID_B (1<<4)
#define AUDIO_ELD_VALID_C (1<<8)
#define AUDIO_CP_READY_A (1<<1)
#define AUDIO_CP_READY_B (1<<5)
#define AUDIO_CP_READY_C (1<<9)
/* HSW Power Wells */ /* HSW Power Wells */
#define HSW_PWR_WELL_CTL1 0x45400 /* BIOS */ #define HSW_PWR_WELL_CTL1 0x45400 /* BIOS */
#define HSW_PWR_WELL_CTL2 0x45404 /* Driver */ #define HSW_PWR_WELL_CTL2 0x45404 /* Driver */
......
...@@ -214,22 +214,18 @@ TRACE_EVENT(i915_gem_evict, ...@@ -214,22 +214,18 @@ TRACE_EVENT(i915_gem_evict,
); );
TRACE_EVENT(i915_gem_evict_everything, TRACE_EVENT(i915_gem_evict_everything,
TP_PROTO(struct drm_device *dev, bool purgeable), TP_PROTO(struct drm_device *dev),
TP_ARGS(dev, purgeable), TP_ARGS(dev),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(u32, dev) __field(u32, dev)
__field(bool, purgeable)
), ),
TP_fast_assign( TP_fast_assign(
__entry->dev = dev->primary->index; __entry->dev = dev->primary->index;
__entry->purgeable = purgeable;
), ),
TP_printk("dev=%d%s", TP_printk("dev=%d", __entry->dev)
__entry->dev,
__entry->purgeable ? ", purgeable only" : "")
); );
TRACE_EVENT(i915_gem_ring_dispatch, TRACE_EVENT(i915_gem_ring_dispatch,
......
...@@ -547,14 +547,12 @@ intel_crt_detect(struct drm_connector *connector, bool force) ...@@ -547,14 +547,12 @@ intel_crt_detect(struct drm_connector *connector, bool force)
return connector->status; return connector->status;
/* for pre-945g platforms use load detect */ /* for pre-945g platforms use load detect */
if (intel_get_load_detect_pipe(&crt->base, connector, NULL, if (intel_get_load_detect_pipe(connector, NULL, &tmp)) {
&tmp)) {
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(&crt->base, connector, intel_release_load_detect_pipe(connector, &tmp);
&tmp);
} else } else
status = connector_status_unknown; status = connector_status_unknown;
...@@ -694,7 +692,7 @@ void intel_crt_init(struct drm_device *dev) ...@@ -694,7 +692,7 @@ void intel_crt_init(struct drm_device *dev)
if (IS_HASWELL(dev)) if (IS_HASWELL(dev))
crt->base.crtc_mask = (1 << 0); crt->base.crtc_mask = (1 << 0);
else else
crt->base.crtc_mask = (1 << 0) | (1 << 1); crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
if (IS_GEN2(dev)) if (IS_GEN2(dev))
connector->interlace_allowed = 0; connector->interlace_allowed = 0;
......
...@@ -713,8 +713,12 @@ void intel_ddi_mode_set(struct drm_encoder *encoder, ...@@ -713,8 +713,12 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
/* Proper support for digital audio needs a new logic and a new set /* Proper support for digital audio needs a new logic and a new set
* of registers, so we leave it for future patch bombing. * of registers, so we leave it for future patch bombing.
*/ */
DRM_DEBUG_DRIVER("HDMI audio on pipe %c not yet supported on DDI\n", DRM_DEBUG_DRIVER("HDMI audio on pipe %c on DDI\n",
pipe_name(intel_crtc->pipe)); pipe_name(intel_crtc->pipe));
/* write eld */
DRM_DEBUG_DRIVER("HDMI audio: write eld information\n");
intel_write_eld(encoder, adjusted_mode);
} }
/* Enable PIPE_DDI_FUNC_CTL for the pipe to work in HDMI mode */ /* Enable PIPE_DDI_FUNC_CTL for the pipe to work in HDMI mode */
......
This diff is collapsed.
...@@ -850,10 +850,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, ...@@ -850,10 +850,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
* supposed to be read-only. * supposed to be read-only.
*/ */
intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED; intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED;
intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
/* Handle DP bits in common between all three register formats */ /* Handle DP bits in common between all three register formats */
intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0;
switch (intel_dp->lane_count) { switch (intel_dp->lane_count) {
......
...@@ -435,12 +435,10 @@ struct intel_load_detect_pipe { ...@@ -435,12 +435,10 @@ struct intel_load_detect_pipe {
bool load_detect_temp; bool load_detect_temp;
int dpms_mode; int dpms_mode;
}; };
extern bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, extern bool intel_get_load_detect_pipe(struct drm_connector *connector,
struct drm_connector *connector,
struct drm_display_mode *mode, struct drm_display_mode *mode,
struct intel_load_detect_pipe *old); struct intel_load_detect_pipe *old);
extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, extern void intel_release_load_detect_pipe(struct drm_connector *connector,
struct drm_connector *connector,
struct intel_load_detect_pipe *old); struct intel_load_detect_pipe *old);
extern void intelfb_restore(void); extern void intelfb_restore(void);
......
...@@ -115,9 +115,9 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) ...@@ -115,9 +115,9 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
if (mode == DRM_MODE_DPMS_ON) { if (mode == DRM_MODE_DPMS_ON) {
I915_WRITE(dvo_reg, temp | DVO_ENABLE); I915_WRITE(dvo_reg, temp | DVO_ENABLE);
I915_READ(dvo_reg); I915_READ(dvo_reg);
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
} else { } else {
intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
I915_READ(dvo_reg); I915_READ(dvo_reg);
} }
......
...@@ -235,54 +235,6 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, ...@@ -235,54 +235,6 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
return 0; return 0;
} }
/* Workaround for i830 bug where pipe a must be enable to change control regs */
static int
i830_activate_pipe_a(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_crtc *crtc;
struct drm_crtc_helper_funcs *crtc_funcs;
struct drm_display_mode vesa_640x480 = {
DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
752, 800, 0, 480, 489, 492, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
}, *mode;
crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[0]);
if (crtc->dpms_mode == DRM_MODE_DPMS_ON)
return 0;
/* most i8xx have pipe a forced on, so don't trust dpms mode */
if (I915_READ(_PIPEACONF) & PIPECONF_ENABLE)
return 0;
crtc_funcs = crtc->base.helper_private;
if (crtc_funcs->dpms == NULL)
return 0;
DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n");
mode = drm_mode_duplicate(dev, &vesa_640x480);
if (!drm_crtc_helper_set_mode(&crtc->base, mode,
crtc->base.x, crtc->base.y,
crtc->base.fb))
return 0;
crtc_funcs->dpms(&crtc->base, DRM_MODE_DPMS_ON);
return 1;
}
static void
i830_deactivate_pipe_a(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
}
/* overlay needs to be disable in OCMD reg */ /* overlay needs to be disable in OCMD reg */
static int intel_overlay_on(struct intel_overlay *overlay) static int intel_overlay_on(struct intel_overlay *overlay)
{ {
...@@ -290,17 +242,12 @@ static int intel_overlay_on(struct intel_overlay *overlay) ...@@ -290,17 +242,12 @@ static int intel_overlay_on(struct intel_overlay *overlay)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
struct drm_i915_gem_request *request; struct drm_i915_gem_request *request;
int pipe_a_quirk = 0;
int ret; int ret;
BUG_ON(overlay->active); BUG_ON(overlay->active);
overlay->active = 1; overlay->active = 1;
if (IS_I830(dev)) { WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
pipe_a_quirk = i830_activate_pipe_a(dev);
if (pipe_a_quirk < 0)
return pipe_a_quirk;
}
request = kzalloc(sizeof(*request), GFP_KERNEL); request = kzalloc(sizeof(*request), GFP_KERNEL);
if (request == NULL) { if (request == NULL) {
...@@ -322,9 +269,6 @@ static int intel_overlay_on(struct intel_overlay *overlay) ...@@ -322,9 +269,6 @@ static int intel_overlay_on(struct intel_overlay *overlay)
ret = intel_overlay_do_wait_request(overlay, request, NULL); ret = intel_overlay_do_wait_request(overlay, request, NULL);
out: out:
if (pipe_a_quirk)
i830_deactivate_pipe_a(dev);
return ret; return ret;
} }
...@@ -1439,7 +1383,7 @@ void intel_setup_overlay(struct drm_device *dev) ...@@ -1439,7 +1383,7 @@ void intel_setup_overlay(struct drm_device *dev)
} }
overlay->flip_addr = reg_bo->phys_obj->handle->busaddr; overlay->flip_addr = reg_bo->phys_obj->handle->busaddr;
} else { } else {
ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true); ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true, false);
if (ret) { if (ret) {
DRM_ERROR("failed to pin overlay register bo\n"); DRM_ERROR("failed to pin overlay register bo\n");
goto out_free_bo; goto out_free_bo;
......
...@@ -2138,7 +2138,7 @@ intel_alloc_context_page(struct drm_device *dev) ...@@ -2138,7 +2138,7 @@ intel_alloc_context_page(struct drm_device *dev)
return NULL; return NULL;
} }
ret = i915_gem_object_pin(ctx, 4096, true); ret = i915_gem_object_pin(ctx, 4096, true, false);
if (ret) { if (ret) {
DRM_ERROR("failed to pin power context: %d\n", ret); DRM_ERROR("failed to pin power context: %d\n", ret);
goto err_unref; goto err_unref;
...@@ -2372,6 +2372,11 @@ int intel_enable_rc6(const struct drm_device *dev) ...@@ -2372,6 +2372,11 @@ int intel_enable_rc6(const struct drm_device *dev)
return i915_enable_rc6; return i915_enable_rc6;
if (INTEL_INFO(dev)->gen == 5) { if (INTEL_INFO(dev)->gen == 5) {
#ifdef CONFIG_INTEL_IOMMU
/* Disable rc6 on ilk if VT-d is on. */
if (intel_iommu_gfx_mapped)
return false;
#endif
DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n"); DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n");
return INTEL_RC6_ENABLE; return INTEL_RC6_ENABLE;
} }
......
...@@ -391,7 +391,7 @@ init_pipe_control(struct intel_ring_buffer *ring) ...@@ -391,7 +391,7 @@ init_pipe_control(struct intel_ring_buffer *ring)
i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
ret = i915_gem_object_pin(obj, 4096, true); ret = i915_gem_object_pin(obj, 4096, true, false);
if (ret) if (ret)
goto err_unref; goto err_unref;
...@@ -979,7 +979,7 @@ static int init_status_page(struct intel_ring_buffer *ring) ...@@ -979,7 +979,7 @@ static int init_status_page(struct intel_ring_buffer *ring)
i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); i915_gem_object_set_cache_level(obj, I915_CACHE_LLC);
ret = i915_gem_object_pin(obj, 4096, true); ret = i915_gem_object_pin(obj, 4096, true, false);
if (ret != 0) { if (ret != 0) {
goto err_unref; goto err_unref;
} }
...@@ -1036,7 +1036,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, ...@@ -1036,7 +1036,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
ring->obj = obj; ring->obj = obj;
ret = i915_gem_object_pin(obj, PAGE_SIZE, true); ret = i915_gem_object_pin(obj, PAGE_SIZE, true, false);
if (ret) if (ret)
goto err_unref; goto err_unref;
......
...@@ -1303,12 +1303,9 @@ intel_tv_detect(struct drm_connector *connector, bool force) ...@@ -1303,12 +1303,9 @@ intel_tv_detect(struct drm_connector *connector, bool force)
if (force) { if (force) {
struct intel_load_detect_pipe tmp; struct intel_load_detect_pipe tmp;
if (intel_get_load_detect_pipe(&intel_tv->base, connector, if (intel_get_load_detect_pipe(connector, &mode, &tmp)) {
&mode, &tmp)) {
type = intel_tv_detect_type(intel_tv, connector); type = intel_tv_detect_type(intel_tv, connector);
intel_release_load_detect_pipe(&intel_tv->base, intel_release_load_detect_pipe(connector, &tmp);
connector,
&tmp);
} else } else
return connector_status_unknown; return connector_status_unknown;
} else } else
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/dma-buf.h>
#include "drmP.h" #include "drmP.h"
#include "drm.h" #include "drm.h"
...@@ -377,16 +378,33 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, ...@@ -377,16 +378,33 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb,
{ {
struct udl_framebuffer *ufb = to_udl_fb(fb); struct udl_framebuffer *ufb = to_udl_fb(fb);
int i; int i;
int ret = 0;
if (!ufb->active_16) if (!ufb->active_16)
return 0; return 0;
if (ufb->obj->base.import_attach) {
ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf,
0, ufb->obj->base.size,
DMA_FROM_DEVICE);
if (ret)
return ret;
}
for (i = 0; i < num_clips; i++) { for (i = 0; i < num_clips; i++) {
udl_handle_damage(ufb, clips[i].x1, clips[i].y1, ret = udl_handle_damage(ufb, clips[i].x1, clips[i].y1,
clips[i].x2 - clips[i].x1, clips[i].x2 - clips[i].x1,
clips[i].y2 - clips[i].y1); clips[i].y2 - clips[i].y1);
if (ret)
break;
} }
return 0;
if (ufb->obj->base.import_attach) {
dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf,
0, ufb->obj->base.size,
DMA_FROM_DEVICE);
}
return ret;
} }
static void udl_user_framebuffer_destroy(struct drm_framebuffer *fb) static void udl_user_framebuffer_destroy(struct drm_framebuffer *fb)
......
...@@ -181,11 +181,6 @@ int udl_gem_vmap(struct udl_gem_object *obj) ...@@ -181,11 +181,6 @@ int udl_gem_vmap(struct udl_gem_object *obj)
int ret; int ret;
if (obj->base.import_attach) { if (obj->base.import_attach) {
ret = dma_buf_begin_cpu_access(obj->base.import_attach->dmabuf,
0, obj->base.size, DMA_BIDIRECTIONAL);
if (ret)
return -EINVAL;
obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf); obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf);
if (!obj->vmapping) if (!obj->vmapping)
return -ENOMEM; return -ENOMEM;
...@@ -206,8 +201,6 @@ void udl_gem_vunmap(struct udl_gem_object *obj) ...@@ -206,8 +201,6 @@ void udl_gem_vunmap(struct udl_gem_object *obj)
{ {
if (obj->base.import_attach) { if (obj->base.import_attach) {
dma_buf_vunmap(obj->base.import_attach->dmabuf, obj->vmapping); dma_buf_vunmap(obj->base.import_attach->dmabuf, obj->vmapping);
dma_buf_end_cpu_access(obj->base.import_attach->dmabuf, 0,
obj->base.size, DMA_BIDIRECTIONAL);
return; return;
} }
......
...@@ -312,6 +312,7 @@ typedef struct drm_i915_irq_wait { ...@@ -312,6 +312,7 @@ typedef struct drm_i915_irq_wait {
#define I915_PARAM_HAS_ALIASING_PPGTT 18 #define I915_PARAM_HAS_ALIASING_PPGTT 18
#define I915_PARAM_HAS_WAIT_TIMEOUT 19 #define I915_PARAM_HAS_WAIT_TIMEOUT 19
#define I915_PARAM_HAS_SEMAPHORES 20 #define I915_PARAM_HAS_SEMAPHORES 20
#define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21
typedef struct drm_i915_getparam { typedef struct drm_i915_getparam {
int param; int param;
......
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