From bb86d1b9c220c676e7d54f044dc109115ef47c26 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 22 Nov 2010 08:07:02 +0000 Subject: [PATCH] --- yaml --- r: 228716 b: refs/heads/master c: c724e8a9407683a8a2ee8eb00b972badf237bbe1 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/i915/i915_debugfs.c | 63 +++++---- trunk/drivers/gpu/drm/i915/i915_drv.h | 4 +- trunk/drivers/gpu/drm/i915/i915_irq.c | 87 ++++++++---- trunk/drivers/gpu/drm/i915/intel_crt.c | 159 +++++++++------------- 5 files changed, 164 insertions(+), 151 deletions(-) diff --git a/[refs] b/[refs] index 15c867ed8212..57d2d09cf018 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8b5abbe0683f285e1311c4cc29c79da07d18d0af +refs/heads/master: c724e8a9407683a8a2ee8eb00b972badf237bbe1 diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index 4c8fae9baaad..24a88ac63212 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -609,6 +609,36 @@ static const char *purgeable_flag(int purgeable) return purgeable ? " purgeable" : ""; } +static void print_error_buffers(struct seq_file *m, + const char *name, + struct drm_i915_error_buffer *err, + int count) +{ + seq_printf(m, "%s [%d]:\n", name, count); + + while (count--) { + seq_printf(m, " %08x %8zd %04x %04x %08x%s%s%s%s%s", + err->gtt_offset, + err->size, + err->read_domains, + err->write_domain, + err->seqno, + pin_flag(err->pinned), + tiling_flag(err->tiling), + dirty_flag(err->dirty), + purgeable_flag(err->purgeable), + ring_str(err->ring)); + + if (err->name) + seq_printf(m, " (name: %d)", err->name); + if (err->fence_reg != I915_FENCE_REG_NONE) + seq_printf(m, " (fence: %d)", err->fence_reg); + + seq_printf(m, "\n"); + err++; + } +} + static int i915_error_state(struct seq_file *m, void *unused) { struct drm_info_node *node = (struct drm_info_node *) m->private; @@ -658,30 +688,15 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); seq_printf(m, " seqno: 0x%08x\n", error->seqno); - if (error->active_bo_count) { - seq_printf(m, "Buffers [%d]:\n", error->active_bo_count); - - for (i = 0; i < error->active_bo_count; i++) { - seq_printf(m, " %08x %8zd %08x %08x %08x%s%s%s%s %s", - error->active_bo[i].gtt_offset, - error->active_bo[i].size, - error->active_bo[i].read_domains, - error->active_bo[i].write_domain, - error->active_bo[i].seqno, - pin_flag(error->active_bo[i].pinned), - tiling_flag(error->active_bo[i].tiling), - dirty_flag(error->active_bo[i].dirty), - purgeable_flag(error->active_bo[i].purgeable), - ring_str(error->active_bo[i].ring)); - - if (error->active_bo[i].name) - seq_printf(m, " (name: %d)", error->active_bo[i].name); - if (error->active_bo[i].fence_reg != I915_FENCE_REG_NONE) - seq_printf(m, " (fence: %d)", error->active_bo[i].fence_reg); - - seq_printf(m, "\n"); - } - } + if (error->active_bo) + print_error_buffers(m, "Active", + error->active_bo, + error->active_bo_count); + + if (error->pinned_bo) + print_error_buffers(m, "Pinned", + error->pinned_bo, + error->pinned_bo_count); for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) { if (error->batchbuffer[i]) { diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 73a41f7ab8c6..826c7237409b 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -184,8 +184,8 @@ struct drm_i915_error_state { u32 dirty:1; u32 purgeable:1; u32 ring:4; - } *active_bo; - u32 active_bo_count; + } *active_bo, *pinned_bo; + u32 active_bo_count, pinned_bo_count; struct intel_overlay_error_state *overlay; }; diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index ef3503733ebb..bbcd5da89ba5 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -552,6 +552,40 @@ i915_ringbuffer_last_batch(struct drm_device *dev, return bbaddr; } +static u32 capture_bo_list(struct drm_i915_error_buffer *err, + int count, + struct list_head *head) +{ + struct drm_i915_gem_object *obj; + int i = 0; + + list_for_each_entry(obj, head, mm_list) { + err->size = obj->base.size; + err->name = obj->base.name; + err->seqno = obj->last_rendering_seqno; + err->gtt_offset = obj->gtt_offset; + err->read_domains = obj->base.read_domains; + err->write_domain = obj->base.write_domain; + err->fence_reg = obj->fence_reg; + err->pinned = 0; + if (obj->pin_count > 0) + err->pinned = 1; + if (obj->user_pin_count > 0) + err->pinned = -1; + err->tiling = obj->tiling_mode; + err->dirty = obj->dirty; + err->purgeable = obj->madv != I915_MADV_WILLNEED; + err->ring = obj->ring->id; + + if (++i == count) + break; + + err++; + } + + return i; +} + /** * i915_capture_error_state - capture an error record for later analysis * @dev: drm device @@ -700,42 +734,35 @@ static void i915_capture_error_state(struct drm_device *dev) error->ringbuffer = i915_error_object_create(dev, dev_priv->render_ring.gem_object); - /* Record buffers on the active list. */ + /* Record buffers on the active and pinned lists. */ error->active_bo = NULL; - error->active_bo_count = 0; + error->pinned_bo = NULL; - if (count) + error->active_bo_count = count; + list_for_each_entry(obj_priv, &dev_priv->mm.pinned_list, mm_list) + count++; + error->pinned_bo_count = count - error->active_bo_count; + + if (count) { error->active_bo = kmalloc(sizeof(*error->active_bo)*count, GFP_ATOMIC); - - if (error->active_bo) { - int i = 0; - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { - struct drm_gem_object *obj = &obj_priv->base; - - error->active_bo[i].size = obj->size; - error->active_bo[i].name = obj->name; - error->active_bo[i].seqno = obj_priv->last_rendering_seqno; - error->active_bo[i].gtt_offset = obj_priv->gtt_offset; - error->active_bo[i].read_domains = obj->read_domains; - error->active_bo[i].write_domain = obj->write_domain; - error->active_bo[i].fence_reg = obj_priv->fence_reg; - error->active_bo[i].pinned = 0; - if (obj_priv->pin_count > 0) - error->active_bo[i].pinned = 1; - if (obj_priv->user_pin_count > 0) - error->active_bo[i].pinned = -1; - error->active_bo[i].tiling = obj_priv->tiling_mode; - error->active_bo[i].dirty = obj_priv->dirty; - error->active_bo[i].purgeable = obj_priv->madv != I915_MADV_WILLNEED; - error->active_bo[i].ring = obj_priv->ring->id; - - if (++i == count) - break; - } - error->active_bo_count = i; + if (error->active_bo) + error->pinned_bo = + error->active_bo + error->active_bo_count; } + if (error->active_bo) + error->active_bo_count = + capture_bo_list(error->active_bo, + error->active_bo_count, + &dev_priv->mm.active_list); + + if (error->pinned_bo) + error->pinned_bo_count = + capture_bo_list(error->pinned_bo, + error->pinned_bo_count, + &dev_priv->mm.pinned_list); + do_gettimeofday(&error->time); error->overlay = intel_overlay_capture_error_state(dev); diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index 8df574316063..c55c77043357 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -34,25 +34,6 @@ #include "i915_drm.h" #include "i915_drv.h" -/* Here's the desired hotplug mode */ -#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \ - ADPA_CRT_HOTPLUG_WARMUP_10MS | \ - ADPA_CRT_HOTPLUG_SAMPLE_4S | \ - ADPA_CRT_HOTPLUG_VOLTAGE_50 | \ - ADPA_CRT_HOTPLUG_VOLREF_325MV | \ - ADPA_CRT_HOTPLUG_ENABLE) - -struct intel_crt { - struct intel_encoder base; - bool force_hotplug_required; -}; - -static struct intel_crt *intel_attached_crt(struct drm_connector *connector) -{ - return container_of(intel_attached_encoder(connector), - struct intel_crt, base); -} - static void intel_crt_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; @@ -148,7 +129,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); } - adpa = ADPA_HOTPLUG_BITS; + adpa = 0; if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) adpa |= ADPA_HSYNC_ACTIVE_HIGH; if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) @@ -176,44 +157,53 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct intel_crt *crt = intel_attached_crt(connector); struct drm_i915_private *dev_priv = dev->dev_private; - u32 adpa; + u32 adpa, temp; bool ret; + bool turn_off_dac = false; - /* The first time through, trigger an explicit detection cycle */ - if (crt->force_hotplug_required) { - bool turn_off_dac = HAS_PCH_SPLIT(dev); - u32 save_adpa; + temp = adpa = I915_READ(PCH_ADPA); - crt->force_hotplug_required = 0; - - save_adpa = adpa = I915_READ(PCH_ADPA); - DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); - - adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; - if (turn_off_dac) - adpa &= ~ADPA_DAC_ENABLE; - - I915_WRITE(PCH_ADPA, adpa); - - if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, - 1000)) - DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); - - if (turn_off_dac) { - I915_WRITE(PCH_ADPA, save_adpa); - POSTING_READ(PCH_ADPA); - } + if (HAS_PCH_SPLIT(dev)) + turn_off_dac = true; + + adpa &= ~ADPA_CRT_HOTPLUG_MASK; + if (turn_off_dac) + adpa &= ~ADPA_DAC_ENABLE; + + /* disable HPD first */ + I915_WRITE(PCH_ADPA, adpa); + (void)I915_READ(PCH_ADPA); + + adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | + ADPA_CRT_HOTPLUG_WARMUP_10MS | + ADPA_CRT_HOTPLUG_SAMPLE_4S | + ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */ + ADPA_CRT_HOTPLUG_VOLREF_325MV | + ADPA_CRT_HOTPLUG_ENABLE | + ADPA_CRT_HOTPLUG_FORCE_TRIGGER); + + DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); + I915_WRITE(PCH_ADPA, adpa); + + if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, + 1000)) + DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); + + if (turn_off_dac) { + /* Make sure hotplug is enabled */ + I915_WRITE(PCH_ADPA, temp | ADPA_CRT_HOTPLUG_ENABLE); + (void)I915_READ(PCH_ADPA); } /* Check the status to see if both blue and green are on now */ adpa = I915_READ(PCH_ADPA); - if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) + adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK; + if ((adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR) || + (adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO)) ret = true; else ret = false; - DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret); return ret; } @@ -287,12 +277,13 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus) return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1; } -static bool intel_crt_detect_ddc(struct intel_crt *crt) +static bool intel_crt_detect_ddc(struct drm_encoder *encoder) { - struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; + struct intel_encoder *intel_encoder = to_intel_encoder(encoder); + struct drm_i915_private *dev_priv = encoder->dev->dev_private; /* CRT should always be at 0, but check anyway */ - if (crt->base.type != INTEL_OUTPUT_ANALOG) + if (intel_encoder->type != INTEL_OUTPUT_ANALOG) return false; if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) { @@ -300,7 +291,7 @@ static bool intel_crt_detect_ddc(struct intel_crt *crt) return true; } - if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { + if (intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin)) { DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); return true; } @@ -309,9 +300,9 @@ static bool intel_crt_detect_ddc(struct intel_crt *crt) } static enum drm_connector_status -intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt) +intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder) { - struct drm_encoder *encoder = &crt->base.base; + struct drm_encoder *encoder = &intel_encoder->base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -443,7 +434,7 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; - struct intel_crt *crt = intel_attached_crt(connector); + struct intel_encoder *encoder = intel_attached_encoder(connector); struct drm_crtc *crtc; int dpms_mode; enum drm_connector_status status; @@ -452,31 +443,28 @@ intel_crt_detect(struct drm_connector *connector, bool force) if (intel_crt_detect_hotplug(connector)) { DRM_DEBUG_KMS("CRT detected via hotplug\n"); return connector_status_connected; - } else { - DRM_DEBUG_KMS("CRT not detected via hotplug\n"); + } else return connector_status_disconnected; - } } - if (intel_crt_detect_ddc(crt)) + if (intel_crt_detect_ddc(&encoder->base)) return connector_status_connected; if (!force) return connector->status; /* for pre-945g platforms use load detect */ - crtc = crt->base.base.crtc; - if (crtc && crtc->enabled) { - status = intel_crt_load_detect(crtc, crt); + if (encoder->base.crtc && encoder->base.crtc->enabled) { + status = intel_crt_load_detect(encoder->base.crtc, encoder); } else { - crtc = intel_get_load_detect_pipe(&crt->base, connector, + crtc = intel_get_load_detect_pipe(encoder, connector, NULL, &dpms_mode); if (crtc) { - if (intel_crt_detect_ddc(crt)) + if (intel_crt_detect_ddc(&encoder->base)) status = connector_status_connected; else - status = intel_crt_load_detect(crtc, crt); - intel_release_load_detect_pipe(&crt->base, + status = intel_crt_load_detect(crtc, encoder); + intel_release_load_detect_pipe(encoder, connector, dpms_mode); } else status = connector_status_unknown; @@ -548,17 +536,17 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { void intel_crt_init(struct drm_device *dev) { struct drm_connector *connector; - struct intel_crt *crt; + struct intel_encoder *intel_encoder; struct intel_connector *intel_connector; struct drm_i915_private *dev_priv = dev->dev_private; - crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); - if (!crt) + intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL); + if (!intel_encoder) return; intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); if (!intel_connector) { - kfree(crt); + kfree(intel_encoder); return; } @@ -566,20 +554,20 @@ void intel_crt_init(struct drm_device *dev) drm_connector_init(dev, &intel_connector->base, &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); - drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs, + drm_encoder_init(dev, &intel_encoder->base, &intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC); - intel_connector_attach_encoder(intel_connector, &crt->base); + intel_connector_attach_encoder(intel_connector, intel_encoder); - crt->base.type = INTEL_OUTPUT_ANALOG; - crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT | - 1 << INTEL_ANALOG_CLONE_BIT | - 1 << INTEL_SDVO_LVDS_CLONE_BIT); - crt->base.crtc_mask = (1 << 0) | (1 << 1); + intel_encoder->type = INTEL_OUTPUT_ANALOG; + intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | + (1 << INTEL_ANALOG_CLONE_BIT) | + (1 << INTEL_SDVO_LVDS_CLONE_BIT); + intel_encoder->crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = 1; connector->doublescan_allowed = 0; - drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs); + drm_encoder_helper_add(&intel_encoder->base, &intel_crt_helper_funcs); drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); drm_sysfs_connector_add(connector); @@ -589,22 +577,5 @@ void intel_crt_init(struct drm_device *dev) else connector->polled = DRM_CONNECTOR_POLL_CONNECT; - /* - * Configure the automatic hotplug detection stuff - */ - crt->force_hotplug_required = 0; - if (HAS_PCH_SPLIT(dev)) { - u32 adpa; - - adpa = I915_READ(PCH_ADPA); - adpa &= ~ADPA_CRT_HOTPLUG_MASK; - adpa |= ADPA_HOTPLUG_BITS; - I915_WRITE(PCH_ADPA, adpa); - POSTING_READ(PCH_ADPA); - - DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa); - crt->force_hotplug_required = 1; - } - dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; }