mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-07 13:13:57 +08:00
drm/i915: Split early global GTT initialisation
Initialising the global GTT is tricky as we wish to use the drm_mm range manager during the modesetting initialisation (to capture stolen allocations from the BIOS) before we actually enable GEM. To overcome this, we currently setup the drm_mm first and then carefully rebind them. v2: Fixup after rebasing v3: GGTT initialisation needs to be split around kicking out conflicts v4: Restore an old UMS BUG_ON(mappable > total) as a DRM_ERROR plus fixup of probe results. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1470293567-10811-4-git-send-email-chris@chris-wilson.co.uk
This commit is contained in:
parent
97d6d7ab68
commit
f6b9d5cabd
@ -993,8 +993,6 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv)
|
||||
static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
uint32_t aperture_size;
|
||||
int ret;
|
||||
|
||||
if (i915_inject_load_failure())
|
||||
@ -1044,7 +1042,6 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 965GM sometimes incorrectly writes to hardware status page (HWS)
|
||||
* using 32bit addressing, overwriting memory if HWS is located
|
||||
* above 4GB.
|
||||
@ -1063,19 +1060,6 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
}
|
||||
|
||||
aperture_size = ggtt->mappable_end;
|
||||
|
||||
ggtt->mappable =
|
||||
io_mapping_create_wc(ggtt->mappable_base,
|
||||
aperture_size);
|
||||
if (!ggtt->mappable) {
|
||||
ret = -EIO;
|
||||
goto out_ggtt;
|
||||
}
|
||||
|
||||
ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base,
|
||||
aperture_size);
|
||||
|
||||
pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY,
|
||||
PM_QOS_DEFAULT_VALUE);
|
||||
|
||||
@ -1116,14 +1100,11 @@ out_ggtt:
|
||||
static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
|
||||
if (dev->pdev->msi_enabled)
|
||||
pci_disable_msi(dev->pdev);
|
||||
|
||||
pm_qos_remove_request(&dev_priv->pm_qos);
|
||||
arch_phys_wc_del(ggtt->mtrr);
|
||||
io_mapping_free(ggtt->mappable);
|
||||
i915_ggtt_cleanup_hw(dev_priv);
|
||||
}
|
||||
|
||||
|
@ -4543,7 +4543,10 @@ int i915_gem_init(struct drm_device *dev)
|
||||
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
|
||||
|
||||
i915_gem_init_userptr(dev_priv);
|
||||
i915_gem_init_ggtt(dev_priv);
|
||||
|
||||
ret = i915_gem_init_ggtt(dev_priv);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
ret = i915_gem_context_init(dev);
|
||||
if (ret)
|
||||
@ -4634,7 +4637,6 @@ i915_gem_load_init(struct drm_device *dev)
|
||||
SLAB_HWCACHE_ALIGN,
|
||||
NULL);
|
||||
|
||||
INIT_LIST_HEAD(&dev_priv->vm_list);
|
||||
INIT_LIST_HEAD(&dev_priv->context_list);
|
||||
INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
|
||||
INIT_LIST_HEAD(&dev_priv->mm.bound_list);
|
||||
|
@ -2745,10 +2745,7 @@ static void i915_gtt_color_adjust(struct drm_mm_node *node,
|
||||
*end -= 4096;
|
||||
}
|
||||
|
||||
static int i915_gem_setup_global_gtt(struct drm_i915_private *dev_priv,
|
||||
u64 start,
|
||||
u64 mappable_end,
|
||||
u64 end)
|
||||
int i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
/* Let GEM Manage all of the aperture.
|
||||
*
|
||||
@ -2760,46 +2757,14 @@ static int i915_gem_setup_global_gtt(struct drm_i915_private *dev_priv,
|
||||
* of the aperture.
|
||||
*/
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
struct drm_mm_node *entry;
|
||||
struct drm_i915_gem_object *obj;
|
||||
unsigned long hole_start, hole_end;
|
||||
struct drm_mm_node *entry;
|
||||
int ret;
|
||||
|
||||
BUG_ON(mappable_end > end);
|
||||
|
||||
ggtt->base.start = start;
|
||||
|
||||
/* Subtract the guard page before address space initialization to
|
||||
* shrink the range used by drm_mm */
|
||||
ggtt->base.total = end - start - PAGE_SIZE;
|
||||
i915_address_space_init(&ggtt->base, dev_priv);
|
||||
ggtt->base.total += PAGE_SIZE;
|
||||
|
||||
ret = intel_vgt_balloon(dev_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!HAS_LLC(dev_priv))
|
||||
ggtt->base.mm.color_adjust = i915_gtt_color_adjust;
|
||||
|
||||
/* Mark any preallocated objects as occupied */
|
||||
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
|
||||
struct i915_vma *vma = i915_gem_obj_to_vma(obj, &ggtt->base);
|
||||
|
||||
DRM_DEBUG_KMS("reserving preallocated space: %llx + %zx\n",
|
||||
i915_gem_obj_ggtt_offset(obj), obj->base.size);
|
||||
|
||||
WARN_ON(i915_gem_obj_ggtt_bound(obj));
|
||||
ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node);
|
||||
if (ret) {
|
||||
DRM_DEBUG_KMS("Reservation failed: %i\n", ret);
|
||||
return ret;
|
||||
}
|
||||
vma->bound |= GLOBAL_BIND;
|
||||
__i915_vma_set_map_and_fenceable(vma);
|
||||
list_add_tail(&vma->vm_link, &ggtt->base.inactive_list);
|
||||
}
|
||||
|
||||
/* Clear any non-preallocated blocks */
|
||||
drm_mm_for_each_hole(entry, &ggtt->base.mm, hole_start, hole_end) {
|
||||
DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n",
|
||||
@ -2809,7 +2774,9 @@ static int i915_gem_setup_global_gtt(struct drm_i915_private *dev_priv,
|
||||
}
|
||||
|
||||
/* And finally clear the reserved guard page */
|
||||
ggtt->base.clear_range(&ggtt->base, end - PAGE_SIZE, PAGE_SIZE, true);
|
||||
ggtt->base.clear_range(&ggtt->base,
|
||||
ggtt->base.total - PAGE_SIZE, PAGE_SIZE,
|
||||
true);
|
||||
|
||||
if (USES_PPGTT(dev_priv) && !USES_FULL_PPGTT(dev_priv)) {
|
||||
struct i915_hw_ppgtt *ppgtt;
|
||||
@ -2847,18 +2814,6 @@ static int i915_gem_setup_global_gtt(struct drm_i915_private *dev_priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* i915_gem_init_ggtt - Initialize GEM for Global GTT
|
||||
* @dev_priv: i915 device
|
||||
*/
|
||||
void i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
|
||||
i915_gem_setup_global_gtt(dev_priv,
|
||||
0, ggtt->mappable_end, ggtt->base.total);
|
||||
}
|
||||
|
||||
/**
|
||||
* i915_ggtt_cleanup_hw - Clean up GGTT hardware initialization
|
||||
* @dev_priv: i915 device
|
||||
@ -2883,6 +2838,9 @@ void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
|
||||
ggtt->base.cleanup(&ggtt->base);
|
||||
|
||||
arch_phys_wc_del(ggtt->mtrr);
|
||||
io_mapping_free(ggtt->mappable);
|
||||
}
|
||||
|
||||
static unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl)
|
||||
@ -3243,12 +3201,19 @@ int i915_ggtt_probe_hw(struct drm_i915_private *dev_priv)
|
||||
|
||||
if ((ggtt->base.total - 1) >> 32) {
|
||||
DRM_ERROR("We never expected a Global GTT with more than 32bits"
|
||||
"of address space! Found %lldM!\n",
|
||||
" of address space! Found %lldM!\n",
|
||||
ggtt->base.total >> 20);
|
||||
ggtt->base.total = 1ULL << 32;
|
||||
ggtt->mappable_end = min(ggtt->mappable_end, ggtt->base.total);
|
||||
}
|
||||
|
||||
if (ggtt->mappable_end > ggtt->base.total) {
|
||||
DRM_ERROR("mappable aperture extends past end of GGTT,"
|
||||
" aperture=%llx, total=%llx\n",
|
||||
ggtt->mappable_end, ggtt->base.total);
|
||||
ggtt->mappable_end = ggtt->base.total;
|
||||
}
|
||||
|
||||
/* GMADR is the PCI mmio aperture into the global GTT. */
|
||||
DRM_INFO("Memory usable by graphics device = %lluM\n",
|
||||
ggtt->base.total >> 20);
|
||||
@ -3271,6 +3236,26 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
int ret;
|
||||
|
||||
INIT_LIST_HEAD(&dev_priv->vm_list);
|
||||
|
||||
/* Subtract the guard page before address space initialization to
|
||||
* shrink the range used by drm_mm.
|
||||
*/
|
||||
ggtt->base.total -= PAGE_SIZE;
|
||||
i915_address_space_init(&ggtt->base, dev_priv);
|
||||
ggtt->base.total += PAGE_SIZE;
|
||||
if (!HAS_LLC(dev_priv))
|
||||
ggtt->base.mm.color_adjust = i915_gtt_color_adjust;
|
||||
|
||||
ggtt->mappable =
|
||||
io_mapping_create_wc(ggtt->mappable_base, ggtt->mappable_end);
|
||||
if (!ggtt->mappable) {
|
||||
ret = -EIO;
|
||||
goto out_gtt_cleanup;
|
||||
}
|
||||
|
||||
ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base, ggtt->mappable_end);
|
||||
|
||||
/*
|
||||
* Initialise stolen early so that we may reserve preallocated
|
||||
* objects for the BIOS to KMS transition.
|
||||
|
@ -524,7 +524,7 @@ i915_page_dir_dma_addr(const struct i915_hw_ppgtt *ppgtt, const unsigned n)
|
||||
int i915_ggtt_probe_hw(struct drm_i915_private *dev_priv);
|
||||
int i915_ggtt_init_hw(struct drm_i915_private *dev_priv);
|
||||
int i915_ggtt_enable_hw(struct drm_i915_private *dev_priv);
|
||||
void i915_gem_init_ggtt(struct drm_i915_private *dev_priv);
|
||||
int i915_gem_init_ggtt(struct drm_i915_private *dev_priv);
|
||||
void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv);
|
||||
|
||||
int i915_ppgtt_init_hw(struct drm_device *dev);
|
||||
|
@ -698,18 +698,17 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
|
||||
*/
|
||||
vma->node.start = gtt_offset;
|
||||
vma->node.size = size;
|
||||
if (drm_mm_initialized(&ggtt->base.mm)) {
|
||||
ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node);
|
||||
if (ret) {
|
||||
DRM_DEBUG_KMS("failed to allocate stolen GTT space\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
vma->bound |= GLOBAL_BIND;
|
||||
__i915_vma_set_map_and_fenceable(vma);
|
||||
list_add_tail(&vma->vm_link, &ggtt->base.inactive_list);
|
||||
ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node);
|
||||
if (ret) {
|
||||
DRM_DEBUG_KMS("failed to allocate stolen GTT space\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
vma->bound |= GLOBAL_BIND;
|
||||
__i915_vma_set_map_and_fenceable(vma);
|
||||
list_add_tail(&vma->vm_link, &ggtt->base.inactive_list);
|
||||
|
||||
list_add_tail(&obj->global_list, &dev_priv->mm.bound_list);
|
||||
i915_gem_object_pin_pages(obj);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user