drm/i915: Extract mm switching to function
In order to do the full context switch with address space, it's convenient to have a way to switch the address space. We already have this in our code - just pull it out to be called by the context switch code later. v2: Rebased on BDW support. Required adding BDW. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
b4a74e3adf
commit
eeb9488e75
@ -674,6 +674,9 @@ struct i915_hw_ppgtt {
|
||||
};
|
||||
|
||||
int (*enable)(struct i915_hw_ppgtt *ppgtt);
|
||||
int (*switch_mm)(struct i915_hw_ppgtt *ppgtt,
|
||||
struct intel_ring_buffer *ring,
|
||||
bool synchronous);
|
||||
};
|
||||
|
||||
struct i915_ctx_hang_stats {
|
||||
|
@ -72,6 +72,7 @@ static void ppgtt_bind_vma(struct i915_vma *vma,
|
||||
enum i915_cache_level cache_level,
|
||||
u32 flags);
|
||||
static void ppgtt_unbind_vma(struct i915_vma *vma);
|
||||
static int gen8_ppgtt_enable(struct i915_hw_ppgtt *ppgtt);
|
||||
|
||||
static inline gen8_gtt_pte_t gen8_pte_encode(dma_addr_t addr,
|
||||
enum i915_cache_level level,
|
||||
@ -230,37 +231,23 @@ static int gen8_write_pdp(struct intel_ring_buffer *ring, unsigned entry,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gen8_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
|
||||
static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
|
||||
struct intel_ring_buffer *ring,
|
||||
bool synchronous)
|
||||
{
|
||||
struct drm_device *dev = ppgtt->base.dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_ring_buffer *ring;
|
||||
int i, j, ret;
|
||||
int i, ret;
|
||||
|
||||
/* bit of a hack to find the actual last used pd */
|
||||
int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE;
|
||||
|
||||
for_each_ring(ring, dev_priv, j) {
|
||||
I915_WRITE(RING_MODE_GEN7(ring),
|
||||
_MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
|
||||
}
|
||||
|
||||
for (i = used_pd - 1; i >= 0; i--) {
|
||||
dma_addr_t addr = ppgtt->pd_dma_addr[i];
|
||||
for_each_ring(ring, dev_priv, j) {
|
||||
ret = gen8_write_pdp(ring, i, addr,
|
||||
i915_reset_in_progress(&dev_priv->gpu_error));
|
||||
if (ret)
|
||||
goto err_out;
|
||||
}
|
||||
ret = gen8_write_pdp(ring, i, addr, synchronous);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
for_each_ring(ring, dev_priv, j)
|
||||
I915_WRITE(RING_MODE_GEN7(ring),
|
||||
_MASKED_BIT_DISABLE(GFX_PPGTT_ENABLE));
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
|
||||
@ -397,6 +384,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size)
|
||||
ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT);
|
||||
ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE;
|
||||
ppgtt->enable = gen8_ppgtt_enable;
|
||||
ppgtt->switch_mm = gen8_mm_switch;
|
||||
ppgtt->base.clear_range = gen8_ppgtt_clear_range;
|
||||
ppgtt->base.insert_entries = gen8_ppgtt_insert_entries;
|
||||
ppgtt->base.cleanup = gen8_ppgtt_cleanup;
|
||||
@ -498,6 +486,45 @@ static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt)
|
||||
return (ppgtt->pd_offset / 64) << 16;
|
||||
}
|
||||
|
||||
static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt,
|
||||
struct intel_ring_buffer *ring,
|
||||
bool synchronous)
|
||||
{
|
||||
struct drm_device *dev = ppgtt->base.dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G);
|
||||
I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt));
|
||||
|
||||
POSTING_READ(RING_PP_DIR_DCLV(ring));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gen8_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
|
||||
{
|
||||
struct drm_device *dev = ppgtt->base.dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_ring_buffer *ring;
|
||||
int j, ret;
|
||||
|
||||
for_each_ring(ring, dev_priv, j) {
|
||||
I915_WRITE(RING_MODE_GEN7(ring),
|
||||
_MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
|
||||
ret = ppgtt->switch_mm(ppgtt, ring, true);
|
||||
if (ret)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
for_each_ring(ring, dev_priv, j)
|
||||
I915_WRITE(RING_MODE_GEN7(ring),
|
||||
_MASKED_BIT_DISABLE(GFX_PPGTT_ENABLE));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gen7_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
|
||||
{
|
||||
struct drm_device *dev = ppgtt->base.dev;
|
||||
@ -519,14 +546,16 @@ static int gen7_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
|
||||
ecochk &= ~ECOCHK_PPGTT_GFDT_IVB;
|
||||
}
|
||||
I915_WRITE(GAM_ECOCHK, ecochk);
|
||||
/* GFX_MODE is per-ring on gen7+ */
|
||||
|
||||
for_each_ring(ring, dev_priv, i) {
|
||||
int ret;
|
||||
/* GFX_MODE is per-ring on gen7+ */
|
||||
I915_WRITE(RING_MODE_GEN7(ring),
|
||||
_MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
|
||||
ret = ppgtt->switch_mm(ppgtt, ring, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G);
|
||||
I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -554,8 +583,9 @@ static int gen6_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
|
||||
I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
|
||||
|
||||
for_each_ring(ring, dev_priv, i) {
|
||||
I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G);
|
||||
I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt));
|
||||
int ret = ppgtt->switch_mm(ppgtt, ring, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -688,6 +718,7 @@ alloc:
|
||||
ppgtt->enable = gen7_ppgtt_enable;
|
||||
else
|
||||
BUG();
|
||||
ppgtt->switch_mm = gen6_mm_switch;
|
||||
ppgtt->base.clear_range = gen6_ppgtt_clear_range;
|
||||
ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
|
||||
ppgtt->base.cleanup = gen6_ppgtt_cleanup;
|
||||
|
Loading…
Reference in New Issue
Block a user