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
2 changed files with 61 additions and 27 deletions
|
@ -674,6 +674,9 @@ struct i915_hw_ppgtt {
|
||||||
};
|
};
|
||||||
|
|
||||||
int (*enable)(struct i915_hw_ppgtt *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 {
|
struct i915_ctx_hang_stats {
|
||||||
|
|
|
@ -72,6 +72,7 @@ static void ppgtt_bind_vma(struct i915_vma *vma,
|
||||||
enum i915_cache_level cache_level,
|
enum i915_cache_level cache_level,
|
||||||
u32 flags);
|
u32 flags);
|
||||||
static void ppgtt_unbind_vma(struct i915_vma *vma);
|
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,
|
static inline gen8_gtt_pte_t gen8_pte_encode(dma_addr_t addr,
|
||||||
enum i915_cache_level level,
|
enum i915_cache_level level,
|
||||||
|
@ -230,37 +231,23 @@ static int gen8_write_pdp(struct intel_ring_buffer *ring, unsigned entry,
|
||||||
return 0;
|
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;
|
int i, ret;
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
||||||
struct intel_ring_buffer *ring;
|
|
||||||
int i, j, ret;
|
|
||||||
|
|
||||||
/* bit of a hack to find the actual last used pd */
|
/* bit of a hack to find the actual last used pd */
|
||||||
int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE;
|
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--) {
|
for (i = used_pd - 1; i >= 0; i--) {
|
||||||
dma_addr_t addr = ppgtt->pd_dma_addr[i];
|
dma_addr_t addr = ppgtt->pd_dma_addr[i];
|
||||||
for_each_ring(ring, dev_priv, j) {
|
ret = gen8_write_pdp(ring, i, addr, synchronous);
|
||||||
ret = gen8_write_pdp(ring, i, addr,
|
if (ret)
|
||||||
i915_reset_in_progress(&dev_priv->gpu_error));
|
return ret;
|
||||||
if (ret)
|
|
||||||
goto err_out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_out:
|
return 0;
|
||||||
for_each_ring(ring, dev_priv, j)
|
|
||||||
I915_WRITE(RING_MODE_GEN7(ring),
|
|
||||||
_MASKED_BIT_DISABLE(GFX_PPGTT_ENABLE));
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
|
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_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT);
|
||||||
ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE;
|
ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE;
|
||||||
ppgtt->enable = gen8_ppgtt_enable;
|
ppgtt->enable = gen8_ppgtt_enable;
|
||||||
|
ppgtt->switch_mm = gen8_mm_switch;
|
||||||
ppgtt->base.clear_range = gen8_ppgtt_clear_range;
|
ppgtt->base.clear_range = gen8_ppgtt_clear_range;
|
||||||
ppgtt->base.insert_entries = gen8_ppgtt_insert_entries;
|
ppgtt->base.insert_entries = gen8_ppgtt_insert_entries;
|
||||||
ppgtt->base.cleanup = gen8_ppgtt_cleanup;
|
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;
|
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)
|
static int gen7_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = ppgtt->base.dev;
|
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;
|
ecochk &= ~ECOCHK_PPGTT_GFDT_IVB;
|
||||||
}
|
}
|
||||||
I915_WRITE(GAM_ECOCHK, ecochk);
|
I915_WRITE(GAM_ECOCHK, ecochk);
|
||||||
/* GFX_MODE is per-ring on gen7+ */
|
|
||||||
|
|
||||||
for_each_ring(ring, dev_priv, i) {
|
for_each_ring(ring, dev_priv, i) {
|
||||||
|
int ret;
|
||||||
|
/* GFX_MODE is per-ring on gen7+ */
|
||||||
I915_WRITE(RING_MODE_GEN7(ring),
|
I915_WRITE(RING_MODE_GEN7(ring),
|
||||||
_MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
|
_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;
|
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));
|
I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
|
||||||
|
|
||||||
for_each_ring(ring, dev_priv, i) {
|
for_each_ring(ring, dev_priv, i) {
|
||||||
I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G);
|
int ret = ppgtt->switch_mm(ppgtt, ring, true);
|
||||||
I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt));
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -688,6 +718,7 @@ alloc:
|
||||||
ppgtt->enable = gen7_ppgtt_enable;
|
ppgtt->enable = gen7_ppgtt_enable;
|
||||||
else
|
else
|
||||||
BUG();
|
BUG();
|
||||||
|
ppgtt->switch_mm = gen6_mm_switch;
|
||||||
ppgtt->base.clear_range = gen6_ppgtt_clear_range;
|
ppgtt->base.clear_range = gen6_ppgtt_clear_range;
|
||||||
ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
|
ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
|
||||||
ppgtt->base.cleanup = gen6_ppgtt_cleanup;
|
ppgtt->base.cleanup = gen6_ppgtt_cleanup;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue