Skip to content

Commit ffb5fd5

Browse files
committed
Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-next
More important fixes for 3.9: - error_state improvements to help debug the new scanline wait code added for gen6+ - bug reports started popping up :( patch from Chris Wilson. - fix a panel power sequence confusion between the eDP and lvds detection code resulting in black screens - regression introduce in 3.8 (Jani Nikula) - Chris fixed the root-cause of the ilk relocation vs. evict bug. - Another piece of cargo-culted rc6 lore from Jani, fixes up a regression where a system refused to go into rc6 after suspend sometimes. * 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel: drm/i915: fix FORCEWAKE posting reads drm/i915: Invalidate the relocation presumed_offsets along the slow path drm/i915/eDP: do not write power sequence registers for ghost eDP drm/i915: Record DERRMR, FORCEWAKE and RING_CTL in error-state
2 parents a3f5aed + b514407 commit ffb5fd5

File tree

7 files changed

+84
-20
lines changed

7 files changed

+84
-20
lines changed

drivers/gpu/drm/i915/i915_debugfs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ static void i915_ring_error_state(struct seq_file *m,
641641
seq_printf(m, "%s command stream:\n", ring_str(ring));
642642
seq_printf(m, " HEAD: 0x%08x\n", error->head[ring]);
643643
seq_printf(m, " TAIL: 0x%08x\n", error->tail[ring]);
644+
seq_printf(m, " CTL: 0x%08x\n", error->ctl[ring]);
644645
seq_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]);
645646
seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]);
646647
seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]);
@@ -693,6 +694,8 @@ static int i915_error_state(struct seq_file *m, void *unused)
693694
seq_printf(m, "EIR: 0x%08x\n", error->eir);
694695
seq_printf(m, "IER: 0x%08x\n", error->ier);
695696
seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
697+
seq_printf(m, "FORCEWAKE: 0x%08x\n", error->forcewake);
698+
seq_printf(m, "DERRMR: 0x%08x\n", error->derrmr);
696699
seq_printf(m, "CCID: 0x%08x\n", error->ccid);
697700

698701
for (i = 0; i < dev_priv->num_fence_regs; i++)

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,13 @@ struct drm_i915_error_state {
188188
u32 pgtbl_er;
189189
u32 ier;
190190
u32 ccid;
191+
u32 derrmr;
192+
u32 forcewake;
191193
bool waiting[I915_NUM_RINGS];
192194
u32 pipestat[I915_MAX_PIPES];
193195
u32 tail[I915_NUM_RINGS];
194196
u32 head[I915_NUM_RINGS];
197+
u32 ctl[I915_NUM_RINGS];
195198
u32 ipeir[I915_NUM_RINGS];
196199
u32 ipehr[I915_NUM_RINGS];
197200
u32 instdone[I915_NUM_RINGS];

drivers/gpu/drm/i915/i915_gem_execbuffer.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,8 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
539539
total = 0;
540540
for (i = 0; i < count; i++) {
541541
struct drm_i915_gem_relocation_entry __user *user_relocs;
542+
u64 invalid_offset = (u64)-1;
543+
int j;
542544

543545
user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr;
544546

@@ -549,6 +551,25 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
549551
goto err;
550552
}
551553

554+
/* As we do not update the known relocation offsets after
555+
* relocating (due to the complexities in lock handling),
556+
* we need to mark them as invalid now so that we force the
557+
* relocation processing next time. Just in case the target
558+
* object is evicted and then rebound into its old
559+
* presumed_offset before the next execbuffer - if that
560+
* happened we would make the mistake of assuming that the
561+
* relocations were valid.
562+
*/
563+
for (j = 0; j < exec[i].relocation_count; j++) {
564+
if (copy_to_user(&user_relocs[j].presumed_offset,
565+
&invalid_offset,
566+
sizeof(invalid_offset))) {
567+
ret = -EFAULT;
568+
mutex_lock(&dev->struct_mutex);
569+
goto err;
570+
}
571+
}
572+
552573
reloc_offset[i] = total;
553574
total += exec[i].relocation_count;
554575
}

drivers/gpu/drm/i915/i915_irq.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,7 @@ static void i915_record_ring_state(struct drm_device *dev,
11571157
error->acthd[ring->id] = intel_ring_get_active_head(ring);
11581158
error->head[ring->id] = I915_READ_HEAD(ring);
11591159
error->tail[ring->id] = I915_READ_TAIL(ring);
1160+
error->ctl[ring->id] = I915_READ_CTL(ring);
11601161

11611162
error->cpu_ring_head[ring->id] = ring->head;
11621163
error->cpu_ring_tail[ring->id] = ring->tail;
@@ -1251,6 +1252,16 @@ static void i915_capture_error_state(struct drm_device *dev)
12511252
else
12521253
error->ier = I915_READ(IER);
12531254

1255+
if (INTEL_INFO(dev)->gen >= 6)
1256+
error->derrmr = I915_READ(DERRMR);
1257+
1258+
if (IS_VALLEYVIEW(dev))
1259+
error->forcewake = I915_READ(FORCEWAKE_VLV);
1260+
else if (INTEL_INFO(dev)->gen >= 7)
1261+
error->forcewake = I915_READ(FORCEWAKE_MT);
1262+
else if (INTEL_INFO(dev)->gen == 6)
1263+
error->forcewake = I915_READ(FORCEWAKE);
1264+
12541265
for_each_pipe(pipe)
12551266
error->pipestat[pipe] = I915_READ(PIPESTAT(pipe));
12561267

drivers/gpu/drm/i915/i915_reg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,8 @@
512512
#define GEN7_ERR_INT 0x44040
513513
#define ERR_INT_MMIO_UNCLAIMED (1<<13)
514514

515+
#define DERRMR 0x44050
516+
515517
/* GM45+ chicken bits -- debug workaround bits that may be required
516518
* for various sorts of correct behavior. The top 16 bits of each are
517519
* the enables for writing to the corresponding low bit.

drivers/gpu/drm/i915/intel_dp.c

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2579,7 +2579,8 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
25792579

25802580
static void
25812581
intel_dp_init_panel_power_sequencer(struct drm_device *dev,
2582-
struct intel_dp *intel_dp)
2582+
struct intel_dp *intel_dp,
2583+
struct edp_power_seq *out)
25832584
{
25842585
struct drm_i915_private *dev_priv = dev->dev_private;
25852586
struct edp_power_seq cur, vbt, spec, final;
@@ -2650,16 +2651,35 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
26502651
intel_dp->panel_power_cycle_delay = get_delay(t11_t12);
26512652
#undef get_delay
26522653

2654+
DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n",
2655+
intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay,
2656+
intel_dp->panel_power_cycle_delay);
2657+
2658+
DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
2659+
intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
2660+
2661+
if (out)
2662+
*out = final;
2663+
}
2664+
2665+
static void
2666+
intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
2667+
struct intel_dp *intel_dp,
2668+
struct edp_power_seq *seq)
2669+
{
2670+
struct drm_i915_private *dev_priv = dev->dev_private;
2671+
u32 pp_on, pp_off, pp_div;
2672+
26532673
/* And finally store the new values in the power sequencer. */
2654-
pp_on = (final.t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) |
2655-
(final.t8 << PANEL_LIGHT_ON_DELAY_SHIFT);
2656-
pp_off = (final.t9 << PANEL_LIGHT_OFF_DELAY_SHIFT) |
2657-
(final.t10 << PANEL_POWER_DOWN_DELAY_SHIFT);
2674+
pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) |
2675+
(seq->t8 << PANEL_LIGHT_ON_DELAY_SHIFT);
2676+
pp_off = (seq->t9 << PANEL_LIGHT_OFF_DELAY_SHIFT) |
2677+
(seq->t10 << PANEL_POWER_DOWN_DELAY_SHIFT);
26582678
/* Compute the divisor for the pp clock, simply match the Bspec
26592679
* formula. */
26602680
pp_div = ((100 * intel_pch_rawclk(dev))/2 - 1)
26612681
<< PP_REFERENCE_DIVIDER_SHIFT;
2662-
pp_div |= (DIV_ROUND_UP(final.t11_t12, 1000)
2682+
pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000)
26632683
<< PANEL_POWER_CYCLE_DELAY_SHIFT);
26642684

26652685
/* Haswell doesn't have any port selection bits for the panel
@@ -2675,14 +2695,6 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
26752695
I915_WRITE(PCH_PP_OFF_DELAYS, pp_off);
26762696
I915_WRITE(PCH_PP_DIVISOR, pp_div);
26772697

2678-
2679-
DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n",
2680-
intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay,
2681-
intel_dp->panel_power_cycle_delay);
2682-
2683-
DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n",
2684-
intel_dp->backlight_on_delay, intel_dp->backlight_off_delay);
2685-
26862698
DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n",
26872699
I915_READ(PCH_PP_ON_DELAYS),
26882700
I915_READ(PCH_PP_OFF_DELAYS),
@@ -2699,6 +2711,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
26992711
struct drm_device *dev = intel_encoder->base.dev;
27002712
struct drm_i915_private *dev_priv = dev->dev_private;
27012713
struct drm_display_mode *fixed_mode = NULL;
2714+
struct edp_power_seq power_seq = { 0 };
27022715
enum port port = intel_dig_port->port;
27032716
const char *name = NULL;
27042717
int type;
@@ -2771,7 +2784,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
27712784
}
27722785

27732786
if (is_edp(intel_dp))
2774-
intel_dp_init_panel_power_sequencer(dev, intel_dp);
2787+
intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);
27752788

27762789
intel_dp_i2c_init(intel_dp, intel_connector, name);
27772790

@@ -2798,6 +2811,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
27982811
return;
27992812
}
28002813

2814+
/* We now know it's not a ghost, init power sequence regs. */
2815+
intel_dp_init_panel_power_sequencer_registers(dev, intel_dp,
2816+
&power_seq);
2817+
28012818
ironlake_edp_panel_vdd_on(intel_dp);
28022819
edid = drm_get_edid(connector, &intel_dp->adapter);
28032820
if (edid) {

drivers/gpu/drm/i915/intel_pm.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4250,7 +4250,8 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
42504250
static void __gen6_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
42514251
{
42524252
I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff));
4253-
POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */
4253+
/* something from same cacheline, but !FORCEWAKE_MT */
4254+
POSTING_READ(ECOBUS);
42544255
}
42554256

42564257
static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
@@ -4267,7 +4268,8 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
42674268
DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
42684269

42694270
I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
4270-
POSTING_READ(ECOBUS); /* something from same cacheline, but !FORCEWAKE */
4271+
/* something from same cacheline, but !FORCEWAKE_MT */
4272+
POSTING_READ(ECOBUS);
42714273

42724274
if (wait_for_atomic((I915_READ_NOTRACE(forcewake_ack) & 1),
42734275
FORCEWAKE_ACK_TIMEOUT_MS))
@@ -4304,14 +4306,16 @@ void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
43044306
static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
43054307
{
43064308
I915_WRITE_NOTRACE(FORCEWAKE, 0);
4307-
/* gen6_gt_check_fifodbg doubles as the POSTING_READ */
4309+
/* something from same cacheline, but !FORCEWAKE */
4310+
POSTING_READ(ECOBUS);
43084311
gen6_gt_check_fifodbg(dev_priv);
43094312
}
43104313

43114314
static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
43124315
{
43134316
I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
4314-
/* gen6_gt_check_fifodbg doubles as the POSTING_READ */
4317+
/* something from same cacheline, but !FORCEWAKE_MT */
4318+
POSTING_READ(ECOBUS);
43154319
gen6_gt_check_fifodbg(dev_priv);
43164320
}
43174321

@@ -4351,6 +4355,8 @@ int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
43514355
static void vlv_force_wake_reset(struct drm_i915_private *dev_priv)
43524356
{
43534357
I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(0xffff));
4358+
/* something from same cacheline, but !FORCEWAKE_VLV */
4359+
POSTING_READ(FORCEWAKE_ACK_VLV);
43544360
}
43554361

43564362
static void vlv_force_wake_get(struct drm_i915_private *dev_priv)
@@ -4371,7 +4377,8 @@ static void vlv_force_wake_get(struct drm_i915_private *dev_priv)
43714377
static void vlv_force_wake_put(struct drm_i915_private *dev_priv)
43724378
{
43734379
I915_WRITE_NOTRACE(FORCEWAKE_VLV, _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
4374-
/* The below doubles as a POSTING_READ */
4380+
/* something from same cacheline, but !FORCEWAKE_VLV */
4381+
POSTING_READ(FORCEWAKE_ACK_VLV);
43754382
gen6_gt_check_fifodbg(dev_priv);
43764383
}
43774384

0 commit comments

Comments
 (0)