On Thu, 27 Feb 2014, Chris Wilson <ch...@chris-wilson.co.uk> wrote:
> On Mon, Feb 24, 2014 at 09:22:31PM +0200, Jani Nikula wrote:
>> I'm going to need a Reviewed-by and preferrably a Tested-by on this.
>
> I really didn't like this patch because requesting a region other than
> the one we use is morally equivalent to not requesting a region at all.
> The approach I would prefer is to only use the requested resource as our
> available stolen region, like in the attached.

I would need the reviewed- and tested-bys on this one instead then.

I'm keeping Akash's patch in -fixes for now as I've already pushed it
there. Frankly, I'm inclined to queuing that one for 3.14 and fixing
this right for 3.15, as it's a broken BIOS we're talking about, but I
could be convinced otherwise. Particularly with the r-b and t-b.

BR,
Jani.


> -Chris
>
> -- 
> Chris Wilson, Intel Open Source Technology Centre
> From e5230c7bf7186699f1b83dcbff5a45a3267c9941 Mon Sep 17 00:00:00 2001
> From: Chris Wilson <ch...@chris-wilson.co.uk>
> Date: Wed, 26 Feb 2014 18:01:42 +0000
> Subject: [PATCH] drm/i915: Trim stolen region for reserved pages and
>  conflicting BIOS setups
>
> On a few systems we have to reserve regions inside the stolen portion
> for use by the BIOS - we have to trim that out of our own allocation. In
> some cases, the BIOS will have reduced the reserved region in the e820
> map and so we have to adjust our own region request to suit. Either way,
> we need to only use the resource that we successfully reserve for
> ourselves - rather than claim one region and use another.
>
> v2: Fix resource request bounds to be inclusive. (Jani)
>
> Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/i915_drv.h        |  2 +-
>  drivers/gpu/drm/i915/i915_gem_stolen.c | 64 
> ++++++++++++++++++++++------------
>  drivers/gpu/drm/i915/intel_pm.c        |  9 +++--
>  3 files changed, 49 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 655a45c981fd..eb31c456eb35 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1099,7 +1099,7 @@ struct i915_gem_mm {
>       struct list_head unbound_list;
>  
>       /** Usable portion of the GTT for GEM */
> -     unsigned long stolen_base; /* limited to low memory (32-bit) */
> +     struct resource *stolen_region; /* limited to low memory (32-bit) */
>  
>       /** PPGTT used for aliasing the PPGTT with the GTT */
>       struct i915_hw_ppgtt *aliasing_ppgtt;
> diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c 
> b/drivers/gpu/drm/i915/i915_gem_stolen.c
> index adc5c91f6946..984ada1b0084 100644
> --- a/drivers/gpu/drm/i915/i915_gem_stolen.c
> +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
> @@ -45,10 +45,11 @@
>   * for is a boon.
>   */
>  
> -static unsigned long i915_stolen_to_physical(struct drm_device *dev)
> +static struct resource *i915_stolen_to_physical(struct drm_device *dev)
>  {
>       struct drm_i915_private *dev_priv = dev->dev_private;
>       struct resource *r;
> +     unsigned long start, end;
>       u32 base;
>  
>       /* Almost universally we can find the Graphics Base of Stolen Memory
> @@ -184,15 +185,38 @@ static unsigned long i915_stolen_to_physical(struct 
> drm_device *dev)
>        * kernel. So if the region is already marked as busy, something
>        * is seriously wrong.
>        */
> -     r = devm_request_mem_region(dev->dev, base, dev_priv->gtt.stolen_size,
> +     start = base + PAGE_SIZE; /* leave the first page alone! */
> +
> +     end = base + dev_priv->gtt.stolen_size - 1;
> +     if (IS_VALLEYVIEW(dev))
> +             end -= 1024*1024; /* top 1M on VLV/BYT is reserved */
> +
> +     r = devm_request_mem_region(dev->dev, start, end-start,
>                                   "Graphics Stolen Memory");
>       if (r == NULL) {
> -             DRM_ERROR("conflict detected with stolen region: [0x%08x - 
> 0x%08x]\n",
> -                       base, base + (uint32_t)dev_priv->gtt.stolen_size);
> -             base = 0;
> +             /* Weird. BIOS has not reserved the whole region for us,
> +              * try something smaller.
> +              */
> +             do {
> +                     start += PAGE_SIZE;
> +                     end -= PAGE_SIZE;
> +                     if (start < end)
> +                             break;
> +
> +                     r = devm_request_mem_region(dev->dev, start, end-start,
> +                                                 "Graphics Stolen Memory");
> +             } while (r == NULL);
> +
> +             if (r == NULL)
> +                     DRM_ERROR("conflicting resource reservations detected 
> with stolen region: [0x%08x - 0x%08x]\n",
> +                               base, base + 
> (uint32_t)dev_priv->gtt.stolen_size - 1);
> +             else
> +                     DRM_INFO("conflict detected with stolen region [0x%08x 
> - 0x%08x], reducing to [0x%08lx - 0x%08lx]\n",
> +                              base, base + 
> (uint32_t)dev_priv->gtt.stolen_size - 1,
> +                              start, end);
>       }
>  
> -     return base;
> +     return r;
>  }
>  
>  static int i915_setup_compression(struct drm_device *dev, int size)
> @@ -232,9 +256,9 @@ static int i915_setup_compression(struct drm_device *dev, 
> int size)
>               dev_priv->fbc.compressed_llb = compressed_llb;
>  
>               I915_WRITE(FBC_CFB_BASE,
> -                        dev_priv->mm.stolen_base + compressed_fb->start);
> +                        dev_priv->mm.stolen_region->start + 
> compressed_fb->start);
>               I915_WRITE(FBC_LL_BASE,
> -                        dev_priv->mm.stolen_base + compressed_llb->start);
> +                        dev_priv->mm.stolen_region->start + 
> compressed_llb->start);
>       }
>  
>       dev_priv->fbc.compressed_fb = compressed_fb;
> @@ -304,28 +328,22 @@ void i915_gem_cleanup_stolen(struct drm_device *dev)
>  int i915_gem_init_stolen(struct drm_device *dev)
>  {
>       struct drm_i915_private *dev_priv = dev->dev_private;
> -     int bios_reserved = 0;
> +     struct resource *r;
>  
>       if (dev_priv->gtt.stolen_size == 0)
>               return 0;
>  
> -     dev_priv->mm.stolen_base = i915_stolen_to_physical(dev);
> -     if (dev_priv->mm.stolen_base == 0)
> +     r = i915_stolen_to_physical(dev);
> +     if (r == NULL)
>               return 0;
>  
> -     DRM_DEBUG_KMS("found %zd bytes of stolen memory at %08lx\n",
> -                   dev_priv->gtt.stolen_size, dev_priv->mm.stolen_base);
> -
> -     if (IS_VALLEYVIEW(dev))
> -             bios_reserved = 1024*1024; /* top 1M on VLV/BYT */
> -
> -     if (WARN_ON(bios_reserved > dev_priv->gtt.stolen_size))
> -             return 0;
> +     DRM_DEBUG_KMS("found %ld bytes of stolen memory at %08lx\n",
> +                   (long)resource_size(r), (long)r->start);
>  
>       /* Basic memrange allocator for stolen space */
> -     drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size -
> -                 bios_reserved);
> +     drm_mm_init(&dev_priv->mm.stolen, 0, resource_size(r));
>  
> +     dev_priv->mm.stolen_region = r;
>       return 0;
>  }
>  
> @@ -338,7 +356,7 @@ i915_pages_create_for_stolen(struct drm_device *dev,
>       struct scatterlist *sg;
>  
>       DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size);
> -     BUG_ON(offset > dev_priv->gtt.stolen_size - size);
> +     BUG_ON(offset > resource_size(dev_priv->mm.stolen_region) - size);
>  
>       /* We hide that we have no struct page backing our stolen object
>        * by wrapping the contiguous physical allocation with a fake
> @@ -358,7 +376,7 @@ i915_pages_create_for_stolen(struct drm_device *dev,
>       sg->offset = 0;
>       sg->length = size;
>  
> -     sg_dma_address(sg) = (dma_addr_t)dev_priv->mm.stolen_base + offset;
> +     sg_dma_address(sg) = (dma_addr_t)dev_priv->mm.stolen_region->start + 
> offset;
>       sg_dma_len(sg) = size;
>  
>       return st;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 3419ddae32c6..ac0cff40d5ec 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3564,12 +3564,17 @@ static void valleyview_setup_pctx(struct drm_device 
> *dev)
>       u32 pcbr;
>       int pctx_size = 24*1024;
>  
> +     if (dev_priv->mm.stolen_region == NULL) {
> +             DRM_DEBUG("stolen space not reserved, unable to setup power 
> saving context");
> +             return;
> +     }
> +
>       pcbr = I915_READ(VLV_PCBR);
>       if (pcbr) {
>               /* BIOS set it up already, grab the pre-alloc'd space */
>               int pcbr_offset;
>  
> -             pcbr_offset = (pcbr & (~4095)) - dev_priv->mm.stolen_base;
> +             pcbr_offset = (pcbr & (~4095)) - 
> dev_priv->mm.stolen_region->start;
>               pctx = 
> i915_gem_object_create_stolen_for_preallocated(dev_priv->dev,
>                                                                     
> pcbr_offset,
>                                                                     
> I915_GTT_OFFSET_NONE,
> @@ -3591,7 +3596,7 @@ static void valleyview_setup_pctx(struct drm_device 
> *dev)
>               return;
>       }
>  
> -     pctx_paddr = dev_priv->mm.stolen_base + pctx->stolen->start;
> +     pctx_paddr = dev_priv->mm.stolen_region->start + pctx->stolen->start;
>       I915_WRITE(VLV_PCBR, pctx_paddr);
>  
>  out:
> -- 
> 1.9.0
>

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to