diff mbox series

[v3,7/7] drm/i915: fixup the initial fb base on DGFX

Message ID 20220314112837.352931-8-matthew.auld@intel.com (mailing list archive)
State New, archived
Headers show
Series Some more bits for small BAR enabling | expand

Commit Message

Matthew Auld March 14, 2022, 11:28 a.m. UTC
On integrated it looks like the GGTT base should always 1:1 maps to
somewhere within DSM. On discrete the base seems to be pre-programmed with
a normal lmem address, and is not 1:1 mapped with the base address. On
such devices probe the lmem address directly from the PTE.

v2(Ville):
  - The base is actually the pre-programmed GGTT address, which is then
    meant to 1:1 map to somewhere inside dsm. In the case of dgpu the
    base looks to just be some offset within lmem, but this also happens
    to be the exact dsm start, on dg1. Therefore we should only need to
    fudge the physical address, before allocating from stolen.
  - Bail if it's not located in dsm.
v3:
  - Scratch that. There doesn't seem to be any relationship with the
    base and PTE address, on at least DG1. Let's instead just grab the
    lmem address from the PTE itself.

Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Nirmoy Das <nirmoy.das@linux.intel.com>
---
 .../drm/i915/display/intel_plane_initial.c    | 50 ++++++++++++++++---
 1 file changed, 44 insertions(+), 6 deletions(-)

Comments

Nirmoy Das March 15, 2022, 11:08 a.m. UTC | #1
|This seems more natural to me than the previous version. Acked-by: 
Nirmoy Das <nirmoy.das@linux.intel.com> |

Nirmoy

On 14/03/2022 12:28, Matthew Auld wrote:
> On integrated it looks like the GGTT base should always 1:1 maps to
> somewhere within DSM. On discrete the base seems to be pre-programmed with
> a normal lmem address, and is not 1:1 mapped with the base address. On
> such devices probe the lmem address directly from the PTE.
>
> v2(Ville):
>    - The base is actually the pre-programmed GGTT address, which is then
>      meant to 1:1 map to somewhere inside dsm. In the case of dgpu the
>      base looks to just be some offset within lmem, but this also happens
>      to be the exact dsm start, on dg1. Therefore we should only need to
>      fudge the physical address, before allocating from stolen.
>    - Bail if it's not located in dsm.
> v3:
>    - Scratch that. There doesn't seem to be any relationship with the
>      base and PTE address, on at least DG1. Let's instead just grab the
>      lmem address from the PTE itself.
>
> Signed-off-by: Matthew Auld<matthew.auld@intel.com>
> Cc: Thomas Hellström<thomas.hellstrom@linux.intel.com>
> Cc: Ville Syrjälä<ville.syrjala@linux.intel.com>
> Cc: Nirmoy Das<nirmoy.das@linux.intel.com>
> ---
>   .../drm/i915/display/intel_plane_initial.c    | 50 ++++++++++++++++---
>   1 file changed, 44 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c
> index f797fcef18fc..7979929bb632 100644
> --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c
> +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c
> @@ -47,17 +47,55 @@ static struct i915_vma *
>   initial_plane_vma(struct drm_i915_private *i915,
>   		  struct intel_initial_plane_config *plane_config)
>   {
> -	struct intel_memory_region *mem = i915->mm.stolen_region;
> +	struct intel_memory_region *mem;
>   	struct drm_i915_gem_object *obj;
>   	struct i915_vma *vma;
> +	resource_size_t phys_base;
>   	u32 base, size;
>   	u64 pinctl;
>   
> -	if (!mem || plane_config->size == 0)
> +	if (plane_config->size == 0)
> +		return NULL;
> +
> +	base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT);
> +	if (IS_DGFX(i915)) {
> +		gen8_pte_t __iomem *gte = to_gt(i915)->ggtt->gsm;
> +		gen8_pte_t pte;
> +
> +		gte += base / I915_GTT_PAGE_SIZE;
> +
> +		pte = ioread64(gte);
> +		if (!(pte & GEN12_GGTT_PTE_LM)) {
> +			drm_err(&i915->drm,
> +				"Initial plane programming missing PTE_LM bit\n");
> +			return NULL;
> +		}
> +
> +		phys_base = pte & I915_GTT_PAGE_MASK;
> +		mem = i915->mm.regions[INTEL_REGION_LMEM];
> +
> +		/*
> +		 * We don't currently expect this to ever be placed in the
> +		 * stolen portion.
> +		 */
> +		if (phys_base >= resource_size(&mem->region)) {
> +			drm_err(&i915->drm,
> +				"Initial plane programming using invalid range, phys_base=%pa\n",
> +				&phys_base);
> +			return NULL;
> +		}
> +
> +		drm_dbg(&i915->drm,
> +			"Using phys_base=%pa, based on initial plane programming\n",
> +			&phys_base);
> +	} else {
> +		phys_base = base;
> +		mem = i915->mm.stolen_region;
> +	}
> +
> +	if (!mem)
>   		return NULL;
>   
> -	base = round_down(plane_config->base,
> -			  I915_GTT_MIN_ALIGNMENT);
>   	size = round_up(plane_config->base + plane_config->size,
>   			mem->min_page_size);
>   	size -= base;
> @@ -68,11 +106,11 @@ initial_plane_vma(struct drm_i915_private *i915,
>   	 * features.
>   	 */
>   	if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) &&
> +	    mem == i915->mm.stolen_region &&
>   	    size * 2 > i915->stolen_usable_size)
>   		return NULL;
>   
> -	obj = i915_gem_object_create_region_at(i915->mm.stolen_region,
> -					       base, size, 0);
> +	obj = i915_gem_object_create_region_at(mem, phys_base, size, 0);
>   	if (IS_ERR(obj))
>   		return NULL;
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c
index f797fcef18fc..7979929bb632 100644
--- a/drivers/gpu/drm/i915/display/intel_plane_initial.c
+++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c
@@ -47,17 +47,55 @@  static struct i915_vma *
 initial_plane_vma(struct drm_i915_private *i915,
 		  struct intel_initial_plane_config *plane_config)
 {
-	struct intel_memory_region *mem = i915->mm.stolen_region;
+	struct intel_memory_region *mem;
 	struct drm_i915_gem_object *obj;
 	struct i915_vma *vma;
+	resource_size_t phys_base;
 	u32 base, size;
 	u64 pinctl;
 
-	if (!mem || plane_config->size == 0)
+	if (plane_config->size == 0)
+		return NULL;
+
+	base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT);
+	if (IS_DGFX(i915)) {
+		gen8_pte_t __iomem *gte = to_gt(i915)->ggtt->gsm;
+		gen8_pte_t pte;
+
+		gte += base / I915_GTT_PAGE_SIZE;
+
+		pte = ioread64(gte);
+		if (!(pte & GEN12_GGTT_PTE_LM)) {
+			drm_err(&i915->drm,
+				"Initial plane programming missing PTE_LM bit\n");
+			return NULL;
+		}
+
+		phys_base = pte & I915_GTT_PAGE_MASK;
+		mem = i915->mm.regions[INTEL_REGION_LMEM];
+
+		/*
+		 * We don't currently expect this to ever be placed in the
+		 * stolen portion.
+		 */
+		if (phys_base >= resource_size(&mem->region)) {
+			drm_err(&i915->drm,
+				"Initial plane programming using invalid range, phys_base=%pa\n",
+				&phys_base);
+			return NULL;
+		}
+
+		drm_dbg(&i915->drm,
+			"Using phys_base=%pa, based on initial plane programming\n",
+			&phys_base);
+	} else {
+		phys_base = base;
+		mem = i915->mm.stolen_region;
+	}
+
+	if (!mem)
 		return NULL;
 
-	base = round_down(plane_config->base,
-			  I915_GTT_MIN_ALIGNMENT);
 	size = round_up(plane_config->base + plane_config->size,
 			mem->min_page_size);
 	size -= base;
@@ -68,11 +106,11 @@  initial_plane_vma(struct drm_i915_private *i915,
 	 * features.
 	 */
 	if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) &&
+	    mem == i915->mm.stolen_region &&
 	    size * 2 > i915->stolen_usable_size)
 		return NULL;
 
-	obj = i915_gem_object_create_region_at(i915->mm.stolen_region,
-					       base, size, 0);
+	obj = i915_gem_object_create_region_at(mem, phys_base, size, 0);
 	if (IS_ERR(obj))
 		return NULL;