By tracking the iomapping on the VMA itself, we can share that area between multiple users. Also by only revoking the iomapping upon unbinding from the mappable portion of the GGTT, we can keep that iomap across multiple invocations (e.g. execlists context pinning). Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem.c | 5 +++++ drivers/gpu/drm/i915/i915_gem_gtt.c | 33 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_gtt.h | 4 ++++ drivers/gpu/drm/i915/intel_fbdev.c | 8 +++----- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0c4e8e1aeeff..5bb21b20c36a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2699,6 +2699,11 @@ int i915_vma_unbind(struct i915_vma *vma) if (ret) return ret; + if (vma->iomap) { + iounmap(vma->iomap); + vma->iomap = NULL; + } + vma->map_and_fenceable = false; } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index b8af904ad12c..3fcf2fd73453 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3575,3 +3575,36 @@ int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level, return 0; } + +void *i915_vma_iomap(struct drm_i915_private *dev_priv, + struct i915_vma *vma) +{ + if (WARN_ON(!vma->map_and_fenceable)) + return ERR_PTR(-ENODEV); + + GEM_BUG_ON(!vma->is_ggtt); + GEM_BUG_ON((vma->bound & GLOBAL_BIND) == 0); + + if (vma->iomap == NULL) { + u32 base = dev_priv->gtt.mappable_base + vma->node.start; + void *ptr; + + ptr = ioremap_wc(base, vma->size); + if (ptr == NULL) { + int ret; + + /* Too many areas already allocated? */ + ret = i915_gem_evict_vm(vma->vm, true); + if (ret) + return ERR_PTR(ret); + + ptr = ioremap_wc(base, vma->size); + if (ptr == NULL) + return ERR_PTR(-ENOMEM); + } + + vma->iomap = ptr; + } + + return vma->iomap; +} diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 6b0f557982d5..0e0570e13a68 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -181,6 +181,7 @@ struct i915_vma { struct drm_mm_node node; struct drm_i915_gem_object *obj; struct i915_address_space *vm; + void *iomap; u64 size; struct i915_gem_active last_read[I915_NUM_RINGS]; @@ -579,4 +580,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev); int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj); void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj); + +void *i915_vma_iomap(struct drm_i915_private *dev_priv, + struct i915_vma *vma); #endif diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 7decbca25dbb..8e7c341951fd 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -248,12 +248,10 @@ static int intelfb_create(struct drm_fb_helper *helper, info->fix.smem_start = dev->mode_config.fb_base + vma->node.start; info->fix.smem_len = vma->node.size; - info->screen_base = - ioremap_wc(dev_priv->gtt.mappable_base + vma->node.start, - vma->node.size); - if (!info->screen_base) { + info->screen_base = i915_vma_iomap(dev_priv, vma); + if (IS_ERR(info->screen_base)) { DRM_ERROR("Failed to remap framebuffer into virtual memory\n"); - ret = -ENOSPC; + ret = PTR_ERR(info->screen_base); goto out_destroy_fbi; } info->screen_size = vma->node.size; -- 2.7.0.rc3 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx