Skip to content

Commit

Permalink
Merge tag 'drm-intel-fixes-2014-08-08' of git://anongit.freedesktop.o…
Browse files Browse the repository at this point in the history
…rg/drm-intel

Pull intel drm fixes from Daniel Vetter:
 "So I heard that proper pull requests have a revert on top ;-) So here
  we go with my usual mid-merge-window pile of fixes.

[ Ed. This revert thing had better not become the "in" thing ]

   Big fix is the duct-tape for ring init on g4x platforms, we seem to
  have found the magic again to make those machines as happy as before
  (not perfect though unfortunately, but that was never the case).

  Otherwise fixes all over:
   - tune down some overzealous debug output
   - VDD power sequencing fix after resume
   - bunch of dsi fixes for baytrail among them hw state checker
     de-noising
   - bunch of error state capture fixes for bdw
   - misc tiny fixes/workarounds for various platforms

  Last minute rebase was to kick out two patches that shouldn't have
  been in here - they're for the state checker, so 0 functional code
  affected.

  Jani's back from vacation, so he'll take over -fixes from here"

* tag 'drm-intel-fixes-2014-08-08' of git://anongit.freedesktop.org/drm-intel: (21 commits)
  Revert "drm/i915: Enable semaphores on BDW"
  drm/i915: read HEAD register back in init_ring_common() to enforce ordering
  drm/i915: Fix crash when failing to parse MIPI VBT
  drm/i915: Bring GPU Freq to min while suspending.
  drm/i915: Fix DEIER and GTIER collecting for BDW.
  drm/i915: Don't accumulate hangcheck score on forward progress
  drm/i915: Add the WaCsStallBeforeStateCacheInvalidate:bdw workaround.
  drm/i915: Refactor Broadwell PIPE_CONTROL emission into a helper.
  drm/i915: Fix threshold for choosing 32 vs. 64 precisions for VLV DDL values
  drm/i915: Fix drain latency precision multipler for VLV
  drm/i915: Collect gtier properly on HSW.
  drm/i915: Tune down MCH_SSKPD values warning
  drm/i915: Tune done rc6 enabling output
  drm/i915: Don't require dev->struct_mutex in psr_match_conditions
  drm/i915: Fix error state collecting
  drm/i915: fix VDD state tracking after system resume
  drm/i915: Add correct hw/sw config check for DSI encoder
  drm/i915: factor out intel_edp_panel_vdd_sanitize
  drm/i915: wait for all DSI FIFOs to be empty
  drm/i915: work around warning in i915_gem_gtt
  ...
  • Loading branch information
torvalds committed Aug 8, 2014
2 parents a7d7a14 + be71eab commit 889fa78
Show file tree
Hide file tree
Showing 19 changed files with 310 additions and 102 deletions.
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,10 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
if (i915.semaphores >= 0)
return i915.semaphores;

/* Until we get further testing... */
if (IS_GEN8(dev))
return false;

#ifdef CONFIG_INTEL_IOMMU
/* Enable semaphores on SNB when IO remapping is off */
if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped)
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
#define DRIVER_DATE "20140620"
#define DRIVER_DATE "20140725"

enum pipe {
INVALID_PIPE = -1,
Expand Down Expand Up @@ -314,6 +314,7 @@ struct drm_i915_error_state {
u32 eir;
u32 pgtbl_er;
u32 ier;
u32 gtier[4];
u32 ccid;
u32 derrmr;
u32 forcewake;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -4545,7 +4545,7 @@ i915_gem_suspend(struct drm_device *dev)

del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
cancel_delayed_work_sync(&dev_priv->mm.retire_work);
cancel_delayed_work_sync(&dev_priv->mm.idle_work);
flush_delayed_work(&dev_priv->mm.idle_work);

return 0;

Expand Down
11 changes: 6 additions & 5 deletions drivers/gpu/drm/i915/i915_gem_gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1415,7 +1415,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
(gen8_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry;
int i = 0;
struct sg_page_iter sg_iter;
dma_addr_t addr = 0;
dma_addr_t addr = 0; /* shut up gcc */

for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
addr = sg_dma_address(sg_iter.sg) +
Expand Down Expand Up @@ -1461,7 +1461,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
(gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry;
int i = 0;
struct sg_page_iter sg_iter;
dma_addr_t addr;
dma_addr_t addr = 0;

for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
addr = sg_page_iter_dma_address(&sg_iter);
Expand All @@ -1475,9 +1475,10 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
* of NUMA access patterns. Therefore, even with the way we assume
* hardware should work, we must keep this posting read for paranoia.
*/
if (i != 0)
WARN_ON(readl(&gtt_entries[i-1]) !=
vm->pte_encode(addr, level, true, flags));
if (i != 0) {
unsigned long gtt = readl(&gtt_entries[i-1]);
WARN_ON(gtt != vm->pte_encode(addr, level, true, flags));
}

/* This next bit makes the above posting read even more important. We
* want to flush the TLBs only after we're certain all the PTE updates
Expand Down
35 changes: 24 additions & 11 deletions drivers/gpu/drm/i915/i915_gpu_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ static const char *hangcheck_action_to_str(enum intel_ring_hangcheck_action a)
return "wait";
case HANGCHECK_ACTIVE:
return "active";
case HANGCHECK_ACTIVE_LOOP:
return "active (loop)";
case HANGCHECK_KICK:
return "kick";
case HANGCHECK_HUNG:
Expand Down Expand Up @@ -359,6 +361,12 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
err_printf(m, "PCI ID: 0x%04x\n", dev->pdev->device);
err_printf(m, "EIR: 0x%08x\n", error->eir);
err_printf(m, "IER: 0x%08x\n", error->ier);
if (INTEL_INFO(dev)->gen >= 8) {
for (i = 0; i < 4; i++)
err_printf(m, "GTIER gt %d: 0x%08x\n", i,
error->gtier[i]);
} else if (HAS_PCH_SPLIT(dev) || IS_VALLEYVIEW(dev))
err_printf(m, "GTIER: 0x%08x\n", error->gtier[0]);
err_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
err_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake);
err_printf(m, "DERRMR: 0x%08x\n", error->derrmr);
Expand Down Expand Up @@ -784,7 +792,8 @@ static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv,
if (ring == to)
continue;

signal_offset = (GEN8_SIGNAL_OFFSET(ring, i) & PAGE_MASK) / 4;
signal_offset = (GEN8_SIGNAL_OFFSET(ring, i) & (PAGE_SIZE - 1))
/ 4;
tmp = error->semaphore_obj->pages[0];
idx = intel_ring_sync_index(ring, to);

Expand Down Expand Up @@ -1091,6 +1100,7 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv,
struct drm_i915_error_state *error)
{
struct drm_device *dev = dev_priv->dev;
int i;

/* General organization
* 1. Registers specific to a single generation
Expand All @@ -1102,7 +1112,8 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv,

/* 1: Registers specific to a single generation */
if (IS_VALLEYVIEW(dev)) {
error->ier = I915_READ(GTIER) | I915_READ(VLV_IER);
error->gtier[0] = I915_READ(GTIER);
error->ier = I915_READ(VLV_IER);
error->forcewake = I915_READ(FORCEWAKE_VLV);
}

Expand Down Expand Up @@ -1135,16 +1146,18 @@ static void i915_capture_reg_state(struct drm_i915_private *dev_priv,
if (HAS_HW_CONTEXTS(dev))
error->ccid = I915_READ(CCID);

if (HAS_PCH_SPLIT(dev))
error->ier = I915_READ(DEIER) | I915_READ(GTIER);
else {
if (IS_GEN2(dev))
error->ier = I915_READ16(IER);
else
error->ier = I915_READ(IER);
if (INTEL_INFO(dev)->gen >= 8) {
error->ier = I915_READ(GEN8_DE_MISC_IER);
for (i = 0; i < 4; i++)
error->gtier[i] = I915_READ(GEN8_GT_IER(i));
} else if (HAS_PCH_SPLIT(dev)) {
error->ier = I915_READ(DEIER);
error->gtier[0] = I915_READ(GTIER);
} else if (IS_GEN2(dev)) {
error->ier = I915_READ16(IER);
} else if (!IS_VALLEYVIEW(dev)) {
error->ier = I915_READ(IER);
}

/* 4: Everything else */
error->eir = I915_READ(EIR);
error->pgtbl_er = I915_READ(PGTBL_ER);

Expand Down
15 changes: 12 additions & 3 deletions drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -3189,8 +3189,14 @@ ring_stuck(struct intel_engine_cs *ring, u64 acthd)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 tmp;

if (ring->hangcheck.acthd != acthd)
return HANGCHECK_ACTIVE;
if (acthd != ring->hangcheck.acthd) {
if (acthd > ring->hangcheck.max_acthd) {
ring->hangcheck.max_acthd = acthd;
return HANGCHECK_ACTIVE;
}

return HANGCHECK_ACTIVE_LOOP;
}

if (IS_GEN2(dev))
return HANGCHECK_HUNG;
Expand Down Expand Up @@ -3301,8 +3307,9 @@ static void i915_hangcheck_elapsed(unsigned long data)
switch (ring->hangcheck.action) {
case HANGCHECK_IDLE:
case HANGCHECK_WAIT:
break;
case HANGCHECK_ACTIVE:
break;
case HANGCHECK_ACTIVE_LOOP:
ring->hangcheck.score += BUSY;
break;
case HANGCHECK_KICK:
Expand All @@ -3322,6 +3329,8 @@ static void i915_hangcheck_elapsed(unsigned long data)
*/
if (ring->hangcheck.score > 0)
ring->hangcheck.score--;

ring->hangcheck.acthd = ring->hangcheck.max_acthd = 0;
}

ring->hangcheck.seqno = seqno;
Expand Down
50 changes: 25 additions & 25 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -3863,47 +3863,47 @@ enum punit_power_well {

/* drain latency register values*/
#define DRAIN_LATENCY_PRECISION_32 32
#define DRAIN_LATENCY_PRECISION_16 16
#define DRAIN_LATENCY_PRECISION_64 64
#define VLV_DDL1 (VLV_DISPLAY_BASE + 0x70050)
#define DDL_CURSORA_PRECISION_32 (1<<31)
#define DDL_CURSORA_PRECISION_16 (0<<31)
#define DDL_CURSORA_PRECISION_64 (1<<31)
#define DDL_CURSORA_PRECISION_32 (0<<31)
#define DDL_CURSORA_SHIFT 24
#define DDL_SPRITEB_PRECISION_32 (1<<23)
#define DDL_SPRITEB_PRECISION_16 (0<<23)
#define DDL_SPRITEB_PRECISION_64 (1<<23)
#define DDL_SPRITEB_PRECISION_32 (0<<23)
#define DDL_SPRITEB_SHIFT 16
#define DDL_SPRITEA_PRECISION_32 (1<<15)
#define DDL_SPRITEA_PRECISION_16 (0<<15)
#define DDL_SPRITEA_PRECISION_64 (1<<15)
#define DDL_SPRITEA_PRECISION_32 (0<<15)
#define DDL_SPRITEA_SHIFT 8
#define DDL_PLANEA_PRECISION_32 (1<<7)
#define DDL_PLANEA_PRECISION_16 (0<<7)
#define DDL_PLANEA_PRECISION_64 (1<<7)
#define DDL_PLANEA_PRECISION_32 (0<<7)
#define DDL_PLANEA_SHIFT 0

#define VLV_DDL2 (VLV_DISPLAY_BASE + 0x70054)
#define DDL_CURSORB_PRECISION_32 (1<<31)
#define DDL_CURSORB_PRECISION_16 (0<<31)
#define DDL_CURSORB_PRECISION_64 (1<<31)
#define DDL_CURSORB_PRECISION_32 (0<<31)
#define DDL_CURSORB_SHIFT 24
#define DDL_SPRITED_PRECISION_32 (1<<23)
#define DDL_SPRITED_PRECISION_16 (0<<23)
#define DDL_SPRITED_PRECISION_64 (1<<23)
#define DDL_SPRITED_PRECISION_32 (0<<23)
#define DDL_SPRITED_SHIFT 16
#define DDL_SPRITEC_PRECISION_32 (1<<15)
#define DDL_SPRITEC_PRECISION_16 (0<<15)
#define DDL_SPRITEC_PRECISION_64 (1<<15)
#define DDL_SPRITEC_PRECISION_32 (0<<15)
#define DDL_SPRITEC_SHIFT 8
#define DDL_PLANEB_PRECISION_32 (1<<7)
#define DDL_PLANEB_PRECISION_16 (0<<7)
#define DDL_PLANEB_PRECISION_64 (1<<7)
#define DDL_PLANEB_PRECISION_32 (0<<7)
#define DDL_PLANEB_SHIFT 0

#define VLV_DDL3 (VLV_DISPLAY_BASE + 0x70058)
#define DDL_CURSORC_PRECISION_32 (1<<31)
#define DDL_CURSORC_PRECISION_16 (0<<31)
#define DDL_CURSORC_PRECISION_64 (1<<31)
#define DDL_CURSORC_PRECISION_32 (0<<31)
#define DDL_CURSORC_SHIFT 24
#define DDL_SPRITEF_PRECISION_32 (1<<23)
#define DDL_SPRITEF_PRECISION_16 (0<<23)
#define DDL_SPRITEF_PRECISION_64 (1<<23)
#define DDL_SPRITEF_PRECISION_32 (0<<23)
#define DDL_SPRITEF_SHIFT 16
#define DDL_SPRITEE_PRECISION_32 (1<<15)
#define DDL_SPRITEE_PRECISION_16 (0<<15)
#define DDL_SPRITEE_PRECISION_64 (1<<15)
#define DDL_SPRITEE_PRECISION_32 (0<<15)
#define DDL_SPRITEE_SHIFT 8
#define DDL_PLANEC_PRECISION_32 (1<<7)
#define DDL_PLANEC_PRECISION_16 (0<<7)
#define DDL_PLANEC_PRECISION_64 (1<<7)
#define DDL_PLANEC_PRECISION_32 (0<<7)
#define DDL_PLANEC_SHIFT 0

/* FIFO watermark sizes etc */
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/intel_bios.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ parse_mipi(struct drm_i915_private *dev_priv, struct bdb_header *bdb)

/* error during parsing so set all pointers to null
* because of partial parsing */
memset(dev_priv->vbt.dsi.sequence, 0, MIPI_SEQ_MAX);
memset(dev_priv->vbt.dsi.sequence, 0, sizeof(dev_priv->vbt.dsi.sequence));
}

static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -6161,6 +6161,10 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc,
u32 mdiv;
int refclk = 100000;

/* In case of MIPI DPLL will not even be used */
if (!(pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE))
return;

mutex_lock(&dev_priv->dpio_lock);
mdiv = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW3(pipe));
mutex_unlock(&dev_priv->dpio_lock);
Expand Down
67 changes: 49 additions & 18 deletions drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,19 @@ static void edp_panel_vdd_work(struct work_struct *__work)
drm_modeset_unlock(&dev->mode_config.connection_mutex);
}

static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp)
{
unsigned long delay;

/*
* Queue the timer to fire a long time from now (relative to the power
* down delay) to keep the panel power up across a sequence of
* operations.
*/
delay = msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5);
schedule_delayed_work(&intel_dp->panel_vdd_work, delay);
}

static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
{
if (!is_edp(intel_dp))
Expand All @@ -1294,17 +1307,10 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)

intel_dp->want_panel_vdd = false;

if (sync) {
if (sync)
edp_panel_vdd_off_sync(intel_dp);
} else {
/*
* Queue the timer to fire a long
* time from now (relative to the power down delay)
* to keep the panel power up across a sequence of operations
*/
schedule_delayed_work(&intel_dp->panel_vdd_work,
msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5));
}
else
edp_panel_vdd_schedule_off(intel_dp);
}

void intel_edp_panel_on(struct intel_dp *intel_dp)
Expand Down Expand Up @@ -1800,7 +1806,6 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);

lockdep_assert_held(&dev_priv->psr.lock);
lockdep_assert_held(&dev->struct_mutex);
WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
WARN_ON(!drm_modeset_is_locked(&crtc->mutex));

Expand Down Expand Up @@ -3998,6 +4003,11 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
kfree(intel_dig_port);
}

static void intel_dp_encoder_reset(struct drm_encoder *encoder)
{
intel_edp_panel_vdd_sanitize(to_intel_encoder(encoder));
}

static const struct drm_connector_funcs intel_dp_connector_funcs = {
.dpms = intel_connector_dpms,
.detect = intel_dp_detect,
Expand All @@ -4013,6 +4023,7 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs =
};

static const struct drm_encoder_funcs intel_dp_enc_funcs = {
.reset = intel_dp_encoder_reset,
.destroy = intel_dp_encoder_destroy,
};

Expand Down Expand Up @@ -4445,6 +4456,32 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port,
return downclock_mode;
}

void intel_edp_panel_vdd_sanitize(struct intel_encoder *intel_encoder)
{
struct drm_device *dev = intel_encoder->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp *intel_dp;
enum intel_display_power_domain power_domain;

if (intel_encoder->type != INTEL_OUTPUT_EDP)
return;

intel_dp = enc_to_intel_dp(&intel_encoder->base);
if (!edp_have_panel_vdd(intel_dp))
return;
/*
* The VDD bit needs a power domain reference, so if the bit is
* already enabled when we boot or resume, grab this reference and
* schedule a vdd off, so we don't hold on to the reference
* indefinitely.
*/
DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n");
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);

edp_panel_vdd_schedule_off(intel_dp);
}

static bool intel_edp_init_connector(struct intel_dp *intel_dp,
struct intel_connector *intel_connector,
struct edp_power_seq *power_seq)
Expand All @@ -4465,13 +4502,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
if (!is_edp(intel_dp))
return true;

/* The VDD bit needs a power domain reference, so if the bit is already
* enabled when we boot, grab this reference. */
if (edp_have_panel_vdd(intel_dp)) {
enum intel_display_power_domain power_domain;
power_domain = intel_display_port_power_domain(intel_encoder);
intel_display_power_get(dev_priv, power_domain);
}
intel_edp_panel_vdd_sanitize(intel_encoder);

/* Cache DPCD and EDID for edp. */
intel_edp_panel_vdd_on(intel_dp);
Expand Down
Loading

0 comments on commit 889fa78

Please sign in to comment.