All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v2 15/15] drm/i915: Try to relocate the BIOS fb to the start of ggtt
Date: Thu, 11 Jan 2024 15:42:36 +0200	[thread overview]
Message-ID: <ZZ_wTKBVTO3VTvbE@intel.com> (raw)
In-Reply-To: <287a84e9-29c1-40a5-ad8c-f29bc9a0aab2@intel.com>

On Wed, Jan 10, 2024 at 11:11:10AM +0100, Andrzej Hajda wrote:
> On 15.12.2023 11:59, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > On MTL the GOP (for whatever reason) likes to bind its framebuffer
> > high up in the ggtt address space. This can conflict with whatever
> > ggtt_reserve_guc_top() is trying to do, and the result is that
> > ggtt_reserve_guc_top() fails and then we proceed to explode when
> > trying to tear down the driver. Thus far I haven't analyzed what
> > causes the actual fireworks, but it's not super important as even
> > if it didn't explode we'd still fail the driver load and the user
> > would be left with an unusable GPU.
> > 
> > To remedy this (without having to figure out exactly what
> > ggtt_reserve_guc_top() is trying to achieve) we can attempt to
> > relocate the BIOS framebuffer to a lower ggtt address. We can do
> > this at this early point in driver init because nothing else is
> > supposed to be clobbering the ggtt yet. So we simply change where
> > in the ggtt we pin the vma, the original PTEs will be left as is,
> > and the new PTEs will get written with the same dma addresses.
> > The plane will keep on scanning out from the original PTEs until
> > we are done with the whole process, and at that point we rewrite
> > the plane's surface address register to point at the new ggtt
> > address.
> > 
> > Since we don't need a specific ggtt address for the plane
> > (apart from needing it to land in the mappable region for
> > normal stolen objects) we'll just try to pin it without a fixed
> > offset first. It should end up at the lowest available address
> > (which really should be 0 at this point in the driver init).
> > If that fails we'll fall back to just pinning it exactly to the
> > origianal address.
> > 
> > To make sure we don't accidentlally pin it partially over the
> > original ggtt range (as that would corrupt the original PTEs)
> > we reserve the original range temporarily during this process.
> > 
> > Cc: Paz Zcharya <pazz@chromium.org>
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >   drivers/gpu/drm/i915/display/i9xx_plane.c     | 30 ++++++++++
> >   drivers/gpu/drm/i915/display/i9xx_plane.h     |  7 +++
> >   drivers/gpu/drm/i915/display/intel_display.c  |  5 ++
> >   .../gpu/drm/i915/display/intel_display_core.h |  2 +
> >   .../drm/i915/display/intel_plane_initial.c    | 57 ++++++++++++++++++-
> >   .../drm/i915/display/skl_universal_plane.c    | 28 +++++++++
> >   .../drm/i915/display/skl_universal_plane.h    |  2 +
> >   7 files changed, 128 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
> > index 91f2bc405cba..0279c8aabdd1 100644
> > --- a/drivers/gpu/drm/i915/display/i9xx_plane.c
> > +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
> > @@ -1060,3 +1060,33 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
> >   
> >   	plane_config->fb = intel_fb;
> >   }
> > +
> > +bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
> > +				     const struct intel_initial_plane_config *plane_config)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
> > +	const struct intel_plane_state *plane_state =
> > +		to_intel_plane_state(plane->base.state);
> > +	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> > +	u32 base;
> > +
> > +	if (!plane_state->uapi.visible)
> > +		return false;
> > +
> > +	base = intel_plane_ggtt_offset(plane_state);
> > +
> > +	/*
> > +	 * We may have moved the surface to a different
> > +	 * part of ggtt, make the plane aware of that.
> > +	 */
> > +	if (plane_config->base == base)
> > +		return false;
> > +
> > +	if (DISPLAY_VER(dev_priv) >= 4)
> > +		intel_de_write(dev_priv, DSPSURF(i9xx_plane), base);
> > +	else
> > +		intel_de_write(dev_priv, DSPADDR(i9xx_plane), base);
> 
> It seems skl_fixup_initial_plane_config is the same, except 
> intel_de_write part. Couldn't we merge both functions into one and just 
> add another elseif branch here? Maybe abstracting out somehow surface 
> registers writes? Just loose ideas.
> However I wouldn't be surprised if there is good reason to keep it as is.

It's just that we generally want to keep the skl+ vs. pre-skl
low level plane code separate. There are enough differences between
them, so separate code is probably less messy than trying to share
it. And I don't think the common parts between this and its counterpart
are significant enough to really go against that.

> 
> Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
> 
> Regards
> Andrzej
> 
> > +
> > +	return true;
> > +}
> > diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.h b/drivers/gpu/drm/i915/display/i9xx_plane.h
> > index b3d724a144cb..0ca12d1e6839 100644
> > --- a/drivers/gpu/drm/i915/display/i9xx_plane.h
> > +++ b/drivers/gpu/drm/i915/display/i9xx_plane.h
> > @@ -26,6 +26,8 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe);
> >   
> >   void i9xx_get_initial_plane_config(struct intel_crtc *crtc,
> >   				   struct intel_initial_plane_config *plane_config);
> > +bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
> > +				     const struct intel_initial_plane_config *plane_config);
> >   #else
> >   static inline unsigned int i965_plane_max_stride(struct intel_plane *plane,
> >   						 u32 pixel_format, u64 modifier,
> > @@ -46,6 +48,11 @@ static inline void i9xx_get_initial_plane_config(struct intel_crtc *crtc,
> >   						 struct intel_initial_plane_config *plane_config)
> >   {
> >   }
> > +static inline bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
> > +						   const struct intel_initial_plane_config *plane_config)
> > +{
> > +	return false;
> > +}
> >   #endif
> >   
> >   #endif
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index d955957b7d18..92b4a894c9b9 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -7820,6 +7820,7 @@ static const struct intel_display_funcs skl_display_funcs = {
> >   	.crtc_disable = hsw_crtc_disable,
> >   	.commit_modeset_enables = skl_commit_modeset_enables,
> >   	.get_initial_plane_config = skl_get_initial_plane_config,
> > +	.fixup_initial_plane_config = skl_fixup_initial_plane_config,
> >   };
> >   
> >   static const struct intel_display_funcs ddi_display_funcs = {
> > @@ -7828,6 +7829,7 @@ static const struct intel_display_funcs ddi_display_funcs = {
> >   	.crtc_disable = hsw_crtc_disable,
> >   	.commit_modeset_enables = intel_commit_modeset_enables,
> >   	.get_initial_plane_config = i9xx_get_initial_plane_config,
> > +	.fixup_initial_plane_config = i9xx_fixup_initial_plane_config,
> >   };
> >   
> >   static const struct intel_display_funcs pch_split_display_funcs = {
> > @@ -7836,6 +7838,7 @@ static const struct intel_display_funcs pch_split_display_funcs = {
> >   	.crtc_disable = ilk_crtc_disable,
> >   	.commit_modeset_enables = intel_commit_modeset_enables,
> >   	.get_initial_plane_config = i9xx_get_initial_plane_config,
> > +	.fixup_initial_plane_config = i9xx_fixup_initial_plane_config,
> >   };
> >   
> >   static const struct intel_display_funcs vlv_display_funcs = {
> > @@ -7844,6 +7847,7 @@ static const struct intel_display_funcs vlv_display_funcs = {
> >   	.crtc_disable = i9xx_crtc_disable,
> >   	.commit_modeset_enables = intel_commit_modeset_enables,
> >   	.get_initial_plane_config = i9xx_get_initial_plane_config,
> > +	.fixup_initial_plane_config = i9xx_fixup_initial_plane_config,
> >   };
> >   
> >   static const struct intel_display_funcs i9xx_display_funcs = {
> > @@ -7852,6 +7856,7 @@ static const struct intel_display_funcs i9xx_display_funcs = {
> >   	.crtc_disable = i9xx_crtc_disable,
> >   	.commit_modeset_enables = intel_commit_modeset_enables,
> >   	.get_initial_plane_config = i9xx_get_initial_plane_config,
> > +	.fixup_initial_plane_config = i9xx_fixup_initial_plane_config,
> >   };
> >   
> >   /**
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h
> > index 7e82b87e9cde..3f17328ff690 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_core.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_core.h
> > @@ -64,6 +64,8 @@ struct intel_display_funcs {
> >   				struct intel_crtc_state *);
> >   	void (*get_initial_plane_config)(struct intel_crtc *,
> >   					 struct intel_initial_plane_config *);
> > +	bool (*fixup_initial_plane_config)(struct intel_crtc *crtc,
> > +					   const struct intel_initial_plane_config *plane_config);
> >   	void (*crtc_enable)(struct intel_atomic_state *state,
> >   			    struct intel_crtc *crtc);
> >   	void (*crtc_disable)(struct intel_atomic_state *state,
> > diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c
> > index 82ab98985a09..72f509f8bc63 100644
> > --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c
> > +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c
> > @@ -3,9 +3,11 @@
> >    * Copyright © 2021 Intel Corporation
> >    */
> >   
> > +#include "gem/i915_gem_lmem.h"
> >   #include "gem/i915_gem_region.h"
> >   #include "i915_drv.h"
> >   #include "intel_atomic_plane.h"
> > +#include "intel_crtc.h"
> >   #include "intel_display.h"
> >   #include "intel_display_types.h"
> >   #include "intel_fb.h"
> > @@ -138,6 +140,7 @@ initial_plane_vma(struct drm_i915_private *i915,
> >   {
> >   	struct intel_memory_region *mem;
> >   	struct drm_i915_gem_object *obj;
> > +	struct drm_mm_node orig_mm = {};
> >   	struct i915_vma *vma;
> >   	resource_size_t phys_base;
> >   	u32 base, size;
> > @@ -195,23 +198,68 @@ initial_plane_vma(struct drm_i915_private *i915,
> >   		goto err_obj;
> >   	}
> >   
> > +	/*
> > +	 * MTL GOP likes to place the framebuffer high up in ggtt,
> > +	 * which can cause problems for ggtt_reserve_guc_top().
> > +	 * Try to pin it to a low ggtt address instead to avoid that.
> > +	 */
> > +	base = 0;
> > +
> > +	if (base != plane_config->base) {
> > +		struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
> > +		int ret;
> > +
> > +		/*
> > +		 * Make sure the original and new locations
> > +		 * can't overlap. That would corrupt the original
> > +		 * PTEs which are still being used for scanout.
> > +		 */
> > +		ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &orig_mm,
> > +					   size, plane_config->base,
> > +					   I915_COLOR_UNEVICTABLE, PIN_NOEVICT);
> > +		if (ret)
> > +			goto err_obj;
> > +	}
> > +
> >   	vma = i915_vma_instance(obj, &to_gt(i915)->ggtt->vm, NULL);
> >   	if (IS_ERR(vma))
> >   		goto err_obj;
> >   
> > -	pinctl = PIN_GLOBAL | PIN_OFFSET_FIXED | base;
> > -	if (HAS_GMCH(i915))
> > +retry:
> > +	pinctl = PIN_GLOBAL;
> > +	if (base == plane_config->base)
> > +		pinctl |= PIN_OFFSET_FIXED | base;
> > +	if (!i915_gem_object_is_lmem(obj))
> >   		pinctl |= PIN_MAPPABLE;
> > -	if (i915_vma_pin(vma, 0, 0, pinctl))
> > +	if (i915_vma_pin(vma, 0, 0, pinctl)) {
> > +		if (drm_mm_node_allocated(&orig_mm)) {
> > +			drm_mm_remove_node(&orig_mm);
> > +			/*
> > +			 * Try again, but this time pin
> > +			 * it to its original location.
> > +			 */
> > +			base = plane_config->base;
> > +			goto retry;
> > +		}
> >   		goto err_obj;
> > +	}
> >   
> >   	if (i915_gem_object_is_tiled(obj) &&
> >   	    !i915_vma_is_map_and_fenceable(vma))
> >   		goto err_obj;
> >   
> > +	if (drm_mm_node_allocated(&orig_mm))
> > +		drm_mm_remove_node(&orig_mm);
> > +
> > +	drm_dbg_kms(&i915->drm,
> > +		    "Initial plane fb bound to 0x%x in the ggtt (original 0x%x)\n",
> > +		    i915_ggtt_offset(vma), plane_config->base);
> > +
> >   	return vma;
> >   
> >   err_obj:
> > +	if (drm_mm_node_allocated(&orig_mm))
> > +		drm_mm_remove_node(&orig_mm);
> >   	i915_gem_object_put(obj);
> >   	return NULL;
> >   }
> > @@ -386,6 +434,9 @@ void intel_initial_plane_config(struct drm_i915_private *i915)
> >   		 */
> >   		intel_find_initial_plane_obj(crtc, plane_configs);
> >   
> > +		if (i915->display.funcs.display->fixup_initial_plane_config(crtc, plane_config))
> > +			intel_crtc_wait_for_next_vblank(crtc);
> > +
> >   		plane_config_fini(plane_config);
> >   	}
> >   }
> > diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > index 511dc1544854..392d93e97bf8 100644
> > --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> > @@ -2624,3 +2624,31 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
> >   error:
> >   	kfree(intel_fb);
> >   }
> > +
> > +bool skl_fixup_initial_plane_config(struct intel_crtc *crtc,
> > +				    const struct intel_initial_plane_config *plane_config)
> > +{
> > +	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
> > +	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
> > +	const struct intel_plane_state *plane_state =
> > +		to_intel_plane_state(plane->base.state);
> > +	enum plane_id plane_id = plane->id;
> > +	enum pipe pipe = crtc->pipe;
> > +	u32 base;
> > +
> > +	if (!plane_state->uapi.visible)
> > +		return false;
> > +
> > +	base = intel_plane_ggtt_offset(plane_state);
> > +
> > +	/*
> > +	 * We may have moved the surface to a different
> > +	 * part of ggtt, make the plane aware of that.
> > +	 */
> > +	if (plane_config->base == base)
> > +		return false;
> > +
> > +	intel_de_write(i915, PLANE_SURF(pipe, plane_id), base);
> > +
> > +	return true;
> > +}
> > diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.h b/drivers/gpu/drm/i915/display/skl_universal_plane.h
> > index be64c201f9b3..e92e00c01b29 100644
> > --- a/drivers/gpu/drm/i915/display/skl_universal_plane.h
> > +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.h
> > @@ -22,6 +22,8 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
> >   
> >   void skl_get_initial_plane_config(struct intel_crtc *crtc,
> >   				  struct intel_initial_plane_config *plane_config);
> > +bool skl_fixup_initial_plane_config(struct intel_crtc *crtc,
> > +				    const struct intel_initial_plane_config *plane_config);
> >   
> >   int skl_format_to_fourcc(int format, bool rgb_order, bool alpha);
> >   

-- 
Ville Syrjälä
Intel

  reply	other threads:[~2024-01-11 13:42 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-15 10:59 [PATCH v2 00/15] drm/i915: (stolen) memory region related fixes Ville Syrjala
2023-12-15 10:59 ` [PATCH v2 01/15] drm/i915: Use struct resource for memory region IO as well Ville Syrjala
2023-12-15 10:59 ` [PATCH v2 02/15] drm/i915: Print memory region info during probe Ville Syrjala
2023-12-15 10:59 ` [PATCH v2 03/15] drm/i915: Remove ad-hoc lmem/stolen debugs Ville Syrjala
2023-12-15 10:59 ` [PATCH v2 04/15] drm/i915: Bypass LMEMBAR/GTTMMADR for MTL stolen memory access Ville Syrjala
2023-12-15 21:58   ` Sripada, Radhakrishna
2024-01-10  9:13   ` Andrzej Hajda
2024-01-10 10:49   ` Nirmoy Das
2024-01-10 11:48     ` Nirmoy Das
2024-01-12 15:12     ` Ville Syrjälä
2024-01-12 16:31       ` Nirmoy Das
2024-01-12 16:55         ` Ville Syrjälä
2023-12-15 10:59 ` [PATCH v2 05/15] drm/i915: Disable the "binder" Ville Syrjala
2024-01-10 10:28   ` Andrzej Hajda
2023-12-15 10:59 ` [PATCH v2 06/15] drm/i915: Rename the DSM/GSM registers Ville Syrjala
2023-12-15 13:56   ` Andrzej Hajda
2023-12-15 10:59 ` [PATCH v2 07/15] drm/i915: Fix PTE decode during initial plane readout Ville Syrjala
2023-12-18 12:36   ` Andrzej Hajda
2023-12-15 10:59 ` [PATCH v2 08/15] drm/i915: Fix region start " Ville Syrjala
2023-12-18 13:00   ` Andrzej Hajda
2023-12-19  0:01     ` Ville Syrjälä
2024-01-12 14:53       ` Ville Syrjälä
2023-12-15 10:59 ` [PATCH v2 09/15] drm/i915: Fix MTL " Ville Syrjala
2023-12-19 10:58   ` Andrzej Hajda
2024-01-12 14:52     ` Ville Syrjälä
2023-12-15 10:59 ` [PATCH v2 10/15] drm/i915: s/phys_base/dma_addr/ Ville Syrjala
2023-12-19 10:55   ` Andrzej Hajda
2023-12-15 10:59 ` [PATCH v2 11/15] drm/i915: Split the smem and lmem plane readout apart Ville Syrjala
2023-12-19 10:55   ` Andrzej Hajda
2023-12-19 12:47     ` Ville Syrjälä
2023-12-15 10:59 ` [PATCH v2 12/15] drm/i915: Simplify intel_initial_plane_config() calling convention Ville Syrjala
2023-12-19 10:59   ` Andrzej Hajda
2024-01-13  0:55   ` kernel test robot
2024-01-13  6:27   ` kernel test robot
2023-12-15 10:59 ` [PATCH v2 13/15] drm/i915/fbdev: Fix smem_start for LMEMBAR stolen objects Ville Syrjala
2024-01-10  9:12   ` Andrzej Hajda
2023-12-15 10:59 ` [PATCH v2 14/15] drm/i915: Tweak BIOS fb reuse check Ville Syrjala
2024-01-10  9:36   ` Andrzej Hajda
2023-12-15 10:59 ` [PATCH v2 15/15] drm/i915: Try to relocate the BIOS fb to the start of ggtt Ville Syrjala
2024-01-10 10:11   ` Andrzej Hajda
2024-01-11 13:42     ` Ville Syrjälä [this message]
2024-01-11 14:06   ` [PATCH v3 " Ville Syrjala
2023-12-15 15:45 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: (stolen) memory region related fixes (rev3) Patchwork
2023-12-15 15:45 ` ✗ Fi.CI.SPARSE: " Patchwork
2023-12-15 16:02 ` ✗ Fi.CI.BAT: failure " Patchwork
2024-01-11 17:08 ` ✗ Fi.CI.CHECKPATCH: warning for drm/i915: (stolen) memory region related fixes (rev5) Patchwork
2024-01-11 17:08 ` ✗ Fi.CI.SPARSE: " Patchwork
2024-01-11 17:22 ` ✓ Fi.CI.BAT: success " Patchwork
2024-01-11 22:46 ` ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZZ_wTKBVTO3VTvbE@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=andrzej.hajda@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.