Re: [PATCH v2 3/3] drm/i915/dmc: allocate dmc structure dynamically

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Feb 17, 2023 at 12:04:14PM +0200, Jani Nikula wrote:
> On Thu, 16 Feb 2023, Imre Deak <imre.deak@xxxxxxxxx> wrote:
> > On Thu, Feb 16, 2023 at 06:17:39PM +0200, Jani Nikula wrote:
> >> sizeof(struct intel_dmc) > 1024 bytes, allocated on all platforms as
> >> part of struct drm_i915_private, whether they have DMC or not.
> >> 
> >> Allocate struct intel_dmc dynamically, and hide all the dmc details
> >> behind an opaque pointer in intel_dmc.c.
> >> 
> >> Care must be taken to take into account all cases: DMC not supported on
> >> the platform, DMC supported but not initialized, and DMC initialized but
> >> not loaded. For the second case, we need to move the wakeref out of
> >> struct intel_dmc.
> >> 
> >> Cc: Imre Deak <imre.deak@xxxxxxxxx>
> >> Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx>
> >> ---
> >>  .../gpu/drm/i915/display/intel_display_core.h |  8 ++-
> >>  drivers/gpu/drm/i915/display/intel_dmc.c      | 50 +++++++++++++++++--
> >>  drivers/gpu/drm/i915/display/intel_dmc.h      | 34 +------------
> >>  .../drm/i915/display/intel_modeset_setup.c    |  1 +
> >>  4 files changed, 53 insertions(+), 40 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h
> >> index b870f7f47f2b..ff51149c5fcb 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_display_core.h
> >> +++ b/drivers/gpu/drm/i915/display/intel_display_core.h
> >> @@ -19,7 +19,6 @@
> >>  #include "intel_cdclk.h"
> >>  #include "intel_display_limits.h"
> >>  #include "intel_display_power.h"
> >> -#include "intel_dmc.h"
> >>  #include "intel_dpll_mgr.h"
> >>  #include "intel_fbc.h"
> >>  #include "intel_global_state.h"
> >> @@ -40,6 +39,7 @@ struct intel_cdclk_vals;
> >>  struct intel_color_funcs;
> >>  struct intel_crtc;
> >>  struct intel_crtc_state;
> >> +struct intel_dmc;
> >>  struct intel_dpll_funcs;
> >>  struct intel_dpll_mgr;
> >>  struct intel_fbdev;
> >> @@ -340,6 +340,11 @@ struct intel_display {
> >>  		spinlock_t phy_lock;
> >>  	} dkl;
> >>  
> >> +	struct {
> >> +		struct intel_dmc *dmc;
> >> +		intel_wakeref_t wakeref;
> >> +	} dmc;
> >> +
> >>  	struct {
> >>  		/* VLV/CHV/BXT/GLK DSI MMIO register base address */
> >>  		u32 mmio_base;
> >> @@ -467,7 +472,6 @@ struct intel_display {
> >>  
> >>  	/* Grouping using named structs. Keep sorted. */
> >>  	struct intel_audio audio;
> >> -	struct intel_dmc dmc;
> >>  	struct intel_dpll dpll;
> >>  	struct intel_fbc *fbc[I915_MAX_FBCS];
> >>  	struct intel_frontbuffer_tracking fb_tracking;
> >> diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
> >> index 1d156ac2eb4c..8428d08e0c3d 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_dmc.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_dmc.c
> >> @@ -38,9 +38,37 @@
> >>   * low-power state and comes back to normal.
> >>   */
> >>  
> >> +enum intel_dmc_id {
> >> +	DMC_FW_MAIN = 0,
> >> +	DMC_FW_PIPEA,
> >> +	DMC_FW_PIPEB,
> >> +	DMC_FW_PIPEC,
> >> +	DMC_FW_PIPED,
> >> +	DMC_FW_MAX
> >> +};
> >> +
> >> +struct intel_dmc {
> >> +	struct drm_i915_private *i915;
> >> +	struct work_struct work;
> >> +	const char *fw_path;
> >> +	u32 max_fw_size; /* bytes */
> >> +	u32 version;
> >> +	struct dmc_fw_info {
> >> +		u32 mmio_count;
> >> +		i915_reg_t mmioaddr[20];
> >> +		u32 mmiodata[20];
> >> +		u32 dmc_offset;
> >> +		u32 start_mmioaddr;
> >> +		u32 dmc_fw_size; /*dwords */
> >> +		u32 *payload;
> >> +		bool present;
> >> +	} dmc_info[DMC_FW_MAX];
> >> +};
> >> +
> >> +/* Note: This may be NULL. */
> >>  static struct intel_dmc *i915_to_dmc(struct drm_i915_private *i915)
> >>  {
> >> -	return &i915->display.dmc;
> >> +	return i915->display.dmc.dmc;
> >>  }
> >>  
> >>  #define DMC_VERSION(major, minor)	((major) << 16 | (minor))
> >> @@ -937,7 +965,10 @@ void intel_dmc_init(struct drm_i915_private *dev_priv)
> >>  	if (!HAS_DMC(dev_priv))
> >>  		return;
> >>  
> >> -	dmc = i915_to_dmc(dev_priv);
> >> +	dmc = kzalloc(sizeof(*dmc), GFP_KERNEL);
> >> +	if (!dmc)
> >> +		return;
> >
> > Couldn't driver loading fail in this case instead (simplifying the
> > dmc==NULL checks elsewhere)?
> 
> We could fail driver load, yes, but it still wouldn't simplify the NULL
> checks because you could use i915.dmc_firmware_path="" to disable the
> firmware, and what's the point in keeping the 1k memory allocated in
> that case?

Right, only noticed the same later. But that's only a debug feature so
could be acceptable trade-off for simplicity imo; also the supported but
non-initialized state wouldn't be needed then either.

It's not a big deal and the check is local to intel_dmc.c, so either way
on the patchset:
Reviewed-by: Imre Deak <imre.deak@xxxxxxxxx>

(Querying the DMC FW presence in IGT needs to be fixed before merging.)

> BR,
> Jani.
> 
> 
> >
> >> +
> >>  	dmc->i915 = dev_priv;
> >>  
> >>  	INIT_WORK(&dmc->work, dmc_load_work_fn);
> >> @@ -991,10 +1022,9 @@ void intel_dmc_init(struct drm_i915_private *dev_priv)
> >>  
> >>  	if (dev_priv->params.dmc_firmware_path) {
> >>  		if (strlen(dev_priv->params.dmc_firmware_path) == 0) {
> >> -			dmc->fw_path = NULL;
> >>  			drm_info(&dev_priv->drm,
> >>  				 "Disabling DMC firmware and runtime PM\n");
> >> -			return;
> >> +			goto out;
> >>  		}
> >>  
> >>  		dmc->fw_path = dev_priv->params.dmc_firmware_path;
> >> @@ -1003,11 +1033,18 @@ void intel_dmc_init(struct drm_i915_private *dev_priv)
> >>  	if (!dmc->fw_path) {
> >>  		drm_dbg_kms(&dev_priv->drm,
> >>  			    "No known DMC firmware for platform, disabling runtime PM\n");
> >> -		return;
> >> +		goto out;
> >>  	}
> >>  
> >> +	dev_priv->display.dmc.dmc = dmc;
> >> +
> >>  	drm_dbg_kms(&dev_priv->drm, "Loading %s\n", dmc->fw_path);
> >>  	schedule_work(&dmc->work);
> >> +
> >> +	return;
> >> +
> >> +out:
> >> +	kfree(dmc);
> >>  }
> >>  
> >>  /**
> >> @@ -1074,6 +1111,9 @@ void intel_dmc_fini(struct drm_i915_private *dev_priv)
> >>  	if (dmc) {
> >>  		for_each_dmc_id(dmc_id)
> >>  			kfree(dmc->dmc_info[dmc_id].payload);
> >> +
> >> +		kfree(dmc);
> >> +		dev_priv->display.dmc.dmc = NULL;
> >>  	}
> >>  }
> >>  
> >> diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h
> >> index b74635497aa7..fd607afff2ef 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_dmc.h
> >> +++ b/drivers/gpu/drm/i915/display/intel_dmc.h
> >> @@ -6,44 +6,12 @@
> >>  #ifndef __INTEL_DMC_H__
> >>  #define __INTEL_DMC_H__
> >>  
> >> -#include "i915_reg_defs.h"
> >> -#include "intel_wakeref.h"
> >> -#include <linux/workqueue.h>
> >> +#include <linux/types.h>
> >>  
> >>  struct drm_i915_error_state_buf;
> >>  struct drm_i915_private;
> >> -
> >>  enum pipe;
> >>  
> >> -enum intel_dmc_id {
> >> -	DMC_FW_MAIN = 0,
> >> -	DMC_FW_PIPEA,
> >> -	DMC_FW_PIPEB,
> >> -	DMC_FW_PIPEC,
> >> -	DMC_FW_PIPED,
> >> -	DMC_FW_MAX
> >> -};
> >> -
> >> -struct intel_dmc {
> >> -	struct drm_i915_private *i915;
> >> -	struct work_struct work;
> >> -	const char *fw_path;
> >> -	u32 max_fw_size; /* bytes */
> >> -	u32 version;
> >> -	struct dmc_fw_info {
> >> -		u32 mmio_count;
> >> -		i915_reg_t mmioaddr[20];
> >> -		u32 mmiodata[20];
> >> -		u32 dmc_offset;
> >> -		u32 start_mmioaddr;
> >> -		u32 dmc_fw_size; /*dwords */
> >> -		u32 *payload;
> >> -		bool present;
> >> -	} dmc_info[DMC_FW_MAX];
> >> -
> >> -	intel_wakeref_t wakeref;
> >> -};
> >> -
> >>  void intel_dmc_init(struct drm_i915_private *i915);
> >>  void intel_dmc_load_program(struct drm_i915_private *i915);
> >>  void intel_dmc_disable_program(struct drm_i915_private *i915);
> >> diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
> >> index 5359b9663a07..42bfd56fcbe4 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
> >> @@ -22,6 +22,7 @@
> >>  #include "intel_display.h"
> >>  #include "intel_display_power.h"
> >>  #include "intel_display_types.h"
> >> +#include "intel_dmc.h"
> >>  #include "intel_modeset_setup.h"
> >>  #include "intel_pch_display.h"
> >>  #include "intel_pm.h"
> >> -- 
> >> 2.34.1
> >> 
> 
> -- 
> Jani Nikula, Intel Open Source Graphics Center



[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux