Skip to content

Commit

Permalink
Merge tag 'drm-intel-next-fixes-2016-10-11' of git://anongit.freedesk…
Browse files Browse the repository at this point in the history
…top.org/drm-intel into drm-next

A big bunch of i915 fixes for drm-next / v4.9 merge window, with more
than half of them also cc: stable. We also continue to have more Fixes:
annotations for our fixes, which should help the backporters and
archeologists.

* tag 'drm-intel-next-fixes-2016-10-11' of git://anongit.freedesktop.org/drm-intel: (27 commits)
  drm/i915: Fix conflict resolution from backmerge of v4.8-rc8 to drm-next
  drm/i915/guc: Unwind GuC workqueue reservation if request construction fails
  drm/i915: Reset the breadcrumbs IRQ more carefully
  drm/i915: Force relocations via cpu if we run out of idle aperture
  drm/i915: Distinguish last emitted request from last submitted request
  drm/i915: Allow DP to work w/o EDID
  drm/i915: Move long hpd handling into the hotplug work
  drm/i915/execlists: Reinitialise context image after GPU hang
  drm/i915: Use correct index for backtracking HUNG semaphores
  drm/i915: Unalias obj->phys_handle and obj->userptr
  drm/i915: Just clear the mmiodebug before a register access
  drm/i915/gen9: only add the planes actually affected by ddb changes
  drm/i915: Allow PCH DPLL sharing regardless of DPLL_SDVO_HIGH_SPEED
  drm/i915/bxt: Fix HDMI DPLL configuration
  drm/i915/gen9: fix the watermark res_blocks value
  drm/i915/gen9: fix plane_blocks_per_line on watermarks calculations
  drm/i915/gen9: minimum scanlines for Y tile is not always 4
  drm/i915/gen9: fix the WaWmMemoryReadLatency implementation
  drm/i915/kbl: KBL also needs to run the SAGV code
  drm/i915: introduce intel_has_sagv()
  ...
  • Loading branch information
Dave Airlie committed Oct 11, 2016
2 parents b898578 + 105f1a6 commit 28da9ed
Show file tree
Hide file tree
Showing 20 changed files with 432 additions and 247 deletions.
21 changes: 11 additions & 10 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1786,15 +1786,6 @@ void i915_reset(struct drm_i915_private *dev_priv)
goto error;
}

/*
* rps/rc6 re-init is necessary to restore state lost after the
* reset and the re-install of gt irqs. Skip for ironlake per
* previous concerns that it doesn't respond well to some forms
* of re-init after reset.
*/
intel_sanitize_gt_powersave(dev_priv);
intel_autoenable_gt_powersave(dev_priv);

wakeup:
wake_up_bit(&error->flags, I915_RESET_IN_PROGRESS);
return;
Expand Down Expand Up @@ -1872,7 +1863,17 @@ static int i915_pm_resume(struct device *kdev)
/* freeze: before creating the hibernation_image */
static int i915_pm_freeze(struct device *kdev)
{
return i915_pm_suspend(kdev);
int ret;

ret = i915_pm_suspend(kdev);
if (ret)
return ret;

ret = i915_gem_freeze(kdev_to_i915(kdev));
if (ret)
return ret;

return 0;
}

static int i915_pm_freeze_late(struct device *kdev)
Expand Down
35 changes: 17 additions & 18 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1984,11 +1984,11 @@ struct drm_i915_private {
struct vlv_s0ix_state vlv_s0ix_state;

enum {
I915_SKL_SAGV_UNKNOWN = 0,
I915_SKL_SAGV_DISABLED,
I915_SKL_SAGV_ENABLED,
I915_SKL_SAGV_NOT_CONTROLLED
} skl_sagv_status;
I915_SAGV_UNKNOWN = 0,
I915_SAGV_DISABLED,
I915_SAGV_ENABLED,
I915_SAGV_NOT_CONTROLLED
} sagv_status;

struct {
/*
Expand Down Expand Up @@ -2276,21 +2276,19 @@ struct drm_i915_gem_object {
/** Record of address bit 17 of each page at last unbind. */
unsigned long *bit_17;

union {
/** for phy allocated objects */
struct drm_dma_handle *phys_handle;

struct i915_gem_userptr {
uintptr_t ptr;
unsigned read_only :1;
unsigned workers :4;
struct i915_gem_userptr {
uintptr_t ptr;
unsigned read_only :1;
unsigned workers :4;
#define I915_GEM_USERPTR_MAX_WORKERS 15

struct i915_mm_struct *mm;
struct i915_mmu_object *mmu_object;
struct work_struct *work;
} userptr;
};
struct i915_mm_struct *mm;
struct i915_mmu_object *mmu_object;
struct work_struct *work;
} userptr;

/** for phys allocated objects */
struct drm_dma_handle *phys_handle;
};

static inline struct drm_i915_gem_object *
Expand Down Expand Up @@ -3076,6 +3074,7 @@ int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
void i915_gem_load_init(struct drm_device *dev);
void i915_gem_load_cleanup(struct drm_device *dev);
void i915_gem_load_init_fences(struct drm_i915_private *dev_priv);
int i915_gem_freeze(struct drm_i915_private *dev_priv);
int i915_gem_freeze_late(struct drm_i915_private *dev_priv);

void *i915_gem_object_alloc(struct drm_device *dev);
Expand Down
27 changes: 23 additions & 4 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2616,8 +2616,6 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
list_for_each_entry_continue(request, &engine->request_list, link)
if (request->ctx == incomplete_ctx)
reset_request(request);

engine->i915->gt.active_engines &= ~intel_engine_flag(engine);
}

void i915_gem_reset(struct drm_i915_private *dev_priv)
Expand All @@ -2628,9 +2626,15 @@ void i915_gem_reset(struct drm_i915_private *dev_priv)

for_each_engine(engine, dev_priv)
i915_gem_reset_engine(engine);
mod_delayed_work(dev_priv->wq, &dev_priv->gt.idle_work, 0);

i915_gem_restore_fences(&dev_priv->drm);

if (dev_priv->gt.awake) {
intel_sanitize_gt_powersave(dev_priv);
intel_enable_gt_powersave(dev_priv);
if (INTEL_GEN(dev_priv) >= 6)
gen6_rps_busy(dev_priv);
}
}

static void nop_submit_request(struct drm_i915_gem_request *request)
Expand Down Expand Up @@ -4589,6 +4593,19 @@ void i915_gem_load_cleanup(struct drm_device *dev)
rcu_barrier();
}

int i915_gem_freeze(struct drm_i915_private *dev_priv)
{
intel_runtime_pm_get(dev_priv);

mutex_lock(&dev_priv->drm.struct_mutex);
i915_gem_shrink_all(dev_priv);
mutex_unlock(&dev_priv->drm.struct_mutex);

intel_runtime_pm_put(dev_priv);

return 0;
}

int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
{
struct drm_i915_gem_object *obj;
Expand All @@ -4612,14 +4629,16 @@ int i915_gem_freeze_late(struct drm_i915_private *dev_priv)
* the objects as well.
*/

i915_gem_shrink_all(dev_priv);
mutex_lock(&dev_priv->drm.struct_mutex);
i915_gem_shrink(dev_priv, -1UL, I915_SHRINK_UNBOUND);

for (p = phases; *p; p++) {
list_for_each_entry(obj, *p, global_list) {
obj->base.read_domains = I915_GEM_DOMAIN_CPU;
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
}
}
mutex_unlock(&dev_priv->drm.struct_mutex);

return 0;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/i915/i915_gem_execbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,8 @@ static void *reloc_iomap(struct drm_i915_gem_object *obj,
0, ggtt->mappable_end,
DRM_MM_SEARCH_DEFAULT,
DRM_MM_CREATE_DEFAULT);
if (ret)
return ERR_PTR(ret);
if (ret) /* no inactive aperture space, use cpu reloc */
return NULL;
} else {
ret = i915_vma_put_fence(vma);
if (ret) {
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/i915/i915_gem_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)

switch (state) {
case FENCE_COMPLETE:
request->engine->last_submitted_seqno = request->fence.seqno;
request->engine->submit_request(request);
break;

Expand Down Expand Up @@ -641,8 +642,8 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
&request->submitq);

request->emitted_jiffies = jiffies;
request->previous_seqno = engine->last_submitted_seqno;
engine->last_submitted_seqno = request->fence.seqno;
request->previous_seqno = engine->last_pending_seqno;
engine->last_pending_seqno = request->fence.seqno;
i915_gem_active_set(&engine->last_request, request);
list_add_tail(&request->link, &engine->request_list);
list_add_tail(&request->ring_link, &ring->request_list);
Expand Down
12 changes: 12 additions & 0 deletions drivers/gpu/drm/i915/i915_guc_submission.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,18 @@ int i915_guc_wq_reserve(struct drm_i915_gem_request *request)
return ret;
}

void i915_guc_wq_unreserve(struct drm_i915_gem_request *request)
{
const size_t wqi_size = sizeof(struct guc_wq_item);
struct i915_guc_client *gc = request->i915->guc.execbuf_client;

GEM_BUG_ON(READ_ONCE(gc->wq_rsvd) < wqi_size);

spin_lock(&gc->wq_lock);
gc->wq_rsvd -= wqi_size;
spin_unlock(&gc->wq_lock);
}

/* Construct a Work Item and append it to the GuC's Work Queue */
static void guc_wq_item_append(struct i915_guc_client *gc,
struct drm_i915_gem_request *rq)
Expand Down
14 changes: 10 additions & 4 deletions drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv)

void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv)
{
if (READ_ONCE(dev_priv->rps.interrupts_enabled))
return;

spin_lock_irq(&dev_priv->irq_lock);
WARN_ON_ONCE(dev_priv->rps.pm_iir);
WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events);
Expand All @@ -368,6 +371,9 @@ u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask)

void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv)
{
if (!READ_ONCE(dev_priv->rps.interrupts_enabled))
return;

spin_lock_irq(&dev_priv->irq_lock);
dev_priv->rps.interrupts_enabled = false;

Expand Down Expand Up @@ -2816,7 +2822,7 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr,
if (engine == signaller)
continue;

if (offset == signaller->semaphore.signal_ggtt[engine->id])
if (offset == signaller->semaphore.signal_ggtt[engine->hw_id])
return signaller;
}
} else {
Expand All @@ -2826,13 +2832,13 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *engine, u32 ipehr,
if(engine == signaller)
continue;

if (sync_bits == signaller->semaphore.mbox.wait[engine->id])
if (sync_bits == signaller->semaphore.mbox.wait[engine->hw_id])
return signaller;
}
}

DRM_DEBUG_DRIVER("No signaller ring found for ring %i, ipehr 0x%08x, offset 0x%016llx\n",
engine->id, ipehr, offset);
DRM_DEBUG_DRIVER("No signaller ring found for %s, ipehr 0x%08x, offset 0x%016llx\n",
engine->name, ipehr, offset);

return ERR_PTR(-ENODEV);
}
Expand Down
33 changes: 31 additions & 2 deletions drivers/gpu/drm/i915/intel_breadcrumbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -578,15 +578,44 @@ int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine)
return 0;
}

static void cancel_fake_irq(struct intel_engine_cs *engine)
{
struct intel_breadcrumbs *b = &engine->breadcrumbs;

del_timer_sync(&b->hangcheck);
del_timer_sync(&b->fake_irq);
clear_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings);
}

void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
{
struct intel_breadcrumbs *b = &engine->breadcrumbs;

cancel_fake_irq(engine);
spin_lock(&b->lock);

__intel_breadcrumbs_disable_irq(b);
if (intel_engine_has_waiter(engine)) {
b->timeout = wait_timeout();
__intel_breadcrumbs_enable_irq(b);
if (READ_ONCE(b->irq_posted))
wake_up_process(b->first_wait->tsk);
} else {
/* sanitize the IMR and unmask any auxiliary interrupts */
irq_disable(engine);
}

spin_unlock(&b->lock);
}

void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
{
struct intel_breadcrumbs *b = &engine->breadcrumbs;

if (!IS_ERR_OR_NULL(b->signaler))
kthread_stop(b->signaler);

del_timer_sync(&b->hangcheck);
del_timer_sync(&b->fake_irq);
cancel_fake_irq(engine);
}

unsigned int intel_kick_waiters(struct drm_i915_private *i915)
Expand Down
30 changes: 25 additions & 5 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -3408,6 +3408,8 @@ static void skylake_update_primary_plane(struct drm_plane *plane,
dst_w--;
dst_h--;

intel_crtc->dspaddr_offset = surf_addr;

intel_crtc->adjusted_x = src_x;
intel_crtc->adjusted_y = src_y;

Expand Down Expand Up @@ -3629,6 +3631,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
intel_runtime_pm_disable_interrupts(dev_priv);
intel_runtime_pm_enable_interrupts(dev_priv);

intel_pps_unlock_regs_wa(dev_priv);
intel_modeset_init_hw(dev);

spin_lock_irq(&dev_priv->irq_lock);
Expand Down Expand Up @@ -9509,6 +9512,24 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc,
if (intel_crtc_has_dp_encoder(crtc_state))
dpll |= DPLL_SDVO_HIGH_SPEED;

/*
* The high speed IO clock is only really required for
* SDVO/HDMI/DP, but we also enable it for CRT to make it
* possible to share the DPLL between CRT and HDMI. Enabling
* the clock needlessly does no real harm, except use up a
* bit of power potentially.
*
* We'll limit this to IVB with 3 pipes, since it has only two
* DPLLs and so DPLL sharing is the only way to get three pipes
* driving PCH ports at the same time. On SNB we could do this,
* and potentially avoid enabling the second DPLL, but it's not
* clear if it''s a win or loss power wise. No point in doing
* this on ILK at all since it has a fixed DPLL<->pipe mapping.
*/
if (INTEL_INFO(dev_priv)->num_pipes == 3 &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG))
dpll |= DPLL_SDVO_HIGH_SPEED;

/* compute bitmask from p1 value */
dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
/* also FPA1 */
Expand Down Expand Up @@ -14364,8 +14385,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
* SKL workaround: bspec recommends we disable the SAGV when we
* have more then one pipe enabled
*/
if (IS_SKYLAKE(dev_priv) && !skl_can_enable_sagv(state))
skl_disable_sagv(dev_priv);
if (!intel_can_enable_sagv(state))
intel_disable_sagv(dev_priv);

intel_modeset_verify_disabled(dev);
}
Expand Down Expand Up @@ -14422,9 +14443,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state);
}

if (IS_SKYLAKE(dev_priv) && intel_state->modeset &&
skl_can_enable_sagv(state))
skl_enable_sagv(dev_priv);
if (intel_state->modeset && intel_can_enable_sagv(state))
intel_enable_sagv(dev_priv);

drm_atomic_helper_commit_hw_done(state);

Expand Down
Loading

0 comments on commit 28da9ed

Please sign in to comment.