All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anshuman Gupta <anshuman.gupta@intel.com>
To: Jani Nikula <jani.nikula@intel.com>
Cc: intel-gfx@lists.freedesktop.org, lucas.demarchi@intel.com,
	rodrigo.vivi@intel.com
Subject: Re: [Intel-gfx] [PATCH v3 2/6] drm/i915/opregion: Abstract opregion function
Date: Fri, 1 Apr 2022 18:56:50 +0530	[thread overview]
Message-ID: <20220401132647.GC22062@intel.com> (raw)
In-Reply-To: <87o826nt9u.fsf@intel.com>

On 2022-03-16 at 11:25:33 +0200, Jani Nikula wrote:
> On Sun, 20 Feb 2022, Anshuman Gupta <anshuman.gupta@intel.com> wrote:
> > Abstract opregion operations like get opregion base, get rvda and
> > opregion cleanup in form of i915_opregion_ops.
> > This will be required to converge igfx and dgfx opregion.
> >
> > v2:
> > - Keep only function pointer abstraction stuff. [Jani]
> > - Add alloc_rvda error handling.
> >
> > v3:
> > - Added necessary credit to Manasi for static analysis fix around
> >   drm_WARN_ON(&i915->drm, !opregion->asls || !opregion->header)
> >
> > Cc: Jani Nikula <jani.nikula@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Cc: Badal Nilawar <badal.nilawar@intel.com>
> > Cc: Uma Shankar <uma.shankar@intel.com>
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_opregion.c | 179 +++++++++++++-----
> >  drivers/gpu/drm/i915/display/intel_opregion.h |   3 +
> >  2 files changed, 134 insertions(+), 48 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c
> > index 9b56064ddb5d..94eb7c23fcb4 100644
> > --- a/drivers/gpu/drm/i915/display/intel_opregion.c
> > +++ b/drivers/gpu/drm/i915/display/intel_opregion.c
> > @@ -138,6 +138,13 @@ struct opregion_asle_ext {
> >  	u8 rsvd[764];
> >  } __packed;
> >  
> > +struct i915_opregion_func {
> > +	void *(*alloc_opregion)(struct drm_i915_private *i915);
> > +	void *(*alloc_rvda)(struct drm_i915_private *i915);
> > +	void (*free_rvda)(struct drm_i915_private *i915);
> > +	void (*free_opregion)(struct drm_i915_private *i915);
> > +};
> > +
> >  /* Driver readiness indicator */
> >  #define ASLE_ARDY_READY		(1 << 0)
> >  #define ASLE_ARDY_NOT_READY	(0 << 0)
> > @@ -876,10 +883,7 @@ static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv)
> >  static int intel_opregion_setup(struct drm_i915_private *dev_priv)
> >  {
> >  	struct intel_opregion *opregion = &dev_priv->opregion;
> > -	struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
> > -	u32 asls, mboxes;
> > -	char buf[sizeof(OPREGION_SIGNATURE)];
> > -	int err = 0;
> > +	u32 mboxes;
> >  	void *base;
> >  	const void *vbt;
> >  	u32 vbt_size;
> > @@ -890,27 +894,12 @@ static int intel_opregion_setup(struct drm_i915_private *dev_priv)
> >  	BUILD_BUG_ON(sizeof(struct opregion_asle) != 0x100);
> >  	BUILD_BUG_ON(sizeof(struct opregion_asle_ext) != 0x400);
> >  
> > -	pci_read_config_dword(pdev, ASLS, &asls);
> > -	drm_dbg(&dev_priv->drm, "graphic opregion physical addr: 0x%x\n",
> > -		asls);
> > -	if (asls == 0) {
> > -		drm_dbg(&dev_priv->drm, "ACPI OpRegion not supported!\n");
> > -		return -ENOTSUPP;
> > -	}
> > -
> >  	INIT_WORK(&opregion->asle_work, asle_work);
> >  
> > -	base = memremap(asls, OPREGION_SIZE, MEMREMAP_WB);
> > -	if (!base)
> > -		return -ENOMEM;
> > +	base = opregion->opregion_func->alloc_opregion(dev_priv);
> > +	if (IS_ERR(base))
> > +		return PTR_ERR(base);
> >  
> > -	memcpy(buf, base, sizeof(buf));
> > -
> > -	if (memcmp(buf, OPREGION_SIGNATURE, 16)) {
> > -		drm_dbg(&dev_priv->drm, "opregion signature mismatch\n");
> > -		err = -EINVAL;
> > -		goto err_out;
> > -	}
> >  	opregion->header = base;
> >  	opregion->lid_state = base + ACPI_CLID;
> >  
> > @@ -970,23 +959,10 @@ static int intel_opregion_setup(struct drm_i915_private *dev_priv)
> >  
> >  	if (opregion->header->over.major >= 2 && opregion->asle &&
> >  	    opregion->asle->rvda && opregion->asle->rvds) {
> > -		resource_size_t rvda = opregion->asle->rvda;
> > -
> > -		/*
> > -		 * opregion 2.0: rvda is the physical VBT address.
> > -		 *
> > -		 * opregion 2.1+: rvda is unsigned, relative offset from
> > -		 * opregion base, and should never point within opregion.
> > -		 */
> > -		if (opregion->header->over.major > 2 ||
> > -		    opregion->header->over.minor >= 1) {
> > -			drm_WARN_ON(&dev_priv->drm, rvda < OPREGION_SIZE);
> > -
> > -			rvda += asls;
> > -		}
> >  
> > -		opregion->rvda = memremap(rvda, opregion->asle->rvds,
> > -					  MEMREMAP_WB);
> > +		opregion->rvda = opregion->opregion_func->alloc_rvda(dev_priv);
> 
> It's a basic principle of interfaces to do corresponding things at the
> same abstraction level.
> 
> Now, you set opregion->rvda at the level that calls ->alloc_rvda,
> however ->free_rvda accesses opregion->rvda directly.
> 
> Similarly for ->alloc_opregion and ->free_opregion.
Thanks for review comment.
Could you please shed light to make same abstraction level.
	free_rvda(void *rvda)
	{
		IS_ERR(rvda)
			return;
		if (rvda) {
			 memunmap(opregion->rvda);
			 rvda = NULL;
		}	
	}
I could think above kind of approach to address abstraction level
Please guide me if that is corrects.
> 
> > +		if (IS_ERR(opregion->rvda))
> > +			goto mbox4_vbt;
> >  
> >  		vbt = opregion->rvda;
> >  		vbt_size = opregion->asle->rvds;
> > @@ -999,11 +975,12 @@ static int intel_opregion_setup(struct drm_i915_private *dev_priv)
> >  		} else {
> >  			drm_dbg_kms(&dev_priv->drm,
> >  				    "Invalid VBT in ACPI OpRegion (RVDA)\n");
> > -			memunmap(opregion->rvda);
> > -			opregion->rvda = NULL;
> > +			opregion->opregion_func->free_rvda(dev_priv);
> >  		}
> >  	}
> >  
> > +mbox4_vbt:
> > +
> >  	vbt = base + OPREGION_VBT_OFFSET;
> >  	/*
> >  	 * The VBT specification says that if the ASLE ext mailbox is not used
> > @@ -1028,9 +1005,6 @@ static int intel_opregion_setup(struct drm_i915_private *dev_priv)
> >  out:
> >  	return 0;
> >  
> > -err_out:
> > -	memunmap(base);
> > -	return err;
> >  }
> >  
> >  static int intel_use_opregion_panel_type_callback(const struct dmi_system_id *id)
> > @@ -1215,11 +1189,9 @@ void intel_opregion_unregister(struct drm_i915_private *i915)
> >  	}
> >  
> >  	/* just clear all opregion memory pointers now */
> > -	memunmap(opregion->header);
> > -	if (opregion->rvda) {
> > -		memunmap(opregion->rvda);
> > -		opregion->rvda = NULL;
> > -	}
> > +	opregion->opregion_func->free_rvda(i915);
> > +	opregion->opregion_func->free_opregion(i915);
> > +
> >  	if (opregion->vbt_firmware) {
> >  		kfree(opregion->vbt_firmware);
> >  		opregion->vbt_firmware = NULL;
> > @@ -1233,6 +1205,113 @@ void intel_opregion_unregister(struct drm_i915_private *i915)
> >  	opregion->lid_state = NULL;
> >  }
> >  
> > +static int
> > +intel_opregion_get_asls(struct drm_i915_private *i915)
> 
> You'd expect a function named "get asls" to return asls.
will fix this.
> 
> > +{
> > +	struct intel_opregion *opregion = &i915->opregion;
> > +	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
> > +	u32 asls;
> > +
> > +	pci_read_config_dword(pdev, ASLS, &asls);
> > +	drm_dbg(&i915->drm, "graphic opregion physical addr: 0x%x\n",
> > +		asls);
> > +	if (asls == 0) {
> > +		drm_dbg(&i915->drm, "ACPI OpRegion not supported!\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	opregion->asls = asls;
> > +
> > +	return 0;
> > +}
> > +
> > +static void *intel_igfx_alloc_opregion(struct drm_i915_private *i915)
> > +{
> > +	struct intel_opregion *opregion = &i915->opregion;
> > +	char buf[sizeof(OPREGION_SIGNATURE)];
> > +	int err = 0;
> > +	void *base;
> > +
> > +	err = intel_opregion_get_asls(i915);
> > +	if (err)
> > +		return ERR_PTR(err);
> > +
> > +	base = memremap(opregion->asls, OPREGION_SIZE, MEMREMAP_WB);
> > +	if (!base)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	memcpy(buf, base, sizeof(buf));
> > +
> > +	if (memcmp(buf, OPREGION_SIGNATURE, 16)) {
> > +		drm_dbg(&i915->drm, "opregion signature mismatch\n");
> > +		err = -EINVAL;
> > +		goto err_out;
> > +	}
> > +
> > +	return base;
> > +
> > +err_out:
> > +	memunmap(base);
> > +
> > +	return ERR_PTR(err);
> > +}
> > +
> > +static void *intel_igfx_alloc_rvda(struct drm_i915_private *i915)
> > +{
> > +	struct intel_opregion *opregion = &i915->opregion;
> > +	resource_size_t rvda;
> > +	void *opreg_rvda;
> > +
> > +	if(drm_WARN_ON(&i915->drm, !opregion->asls || !opregion->header))
>           ^
> 
> Missing space.
Will fix this.
Thanks,
Anshuman.
> 
> > +		return ERR_PTR(-ENODEV);
> > +
> > +	rvda = opregion->asle->rvda;
> > +
> > +	/*
> > +	 * opregion 2.0: rvda is the physical VBT address.
> > +	 *
> > +	 * opregion 2.1+: rvda is unsigned, relative offset from
> > +	 * opregion base, and should never point within opregion.
> > +	 */
> > +	if (opregion->header->over.major > 2 ||
> > +	    opregion->header->over.minor >= 1) {
> > +		drm_WARN_ON(&i915->drm, rvda < OPREGION_SIZE);
> > +
> > +		rvda += opregion->asls;
> > +	}
> > +
> > +	opreg_rvda = memremap(rvda, opregion->asle->rvds, MEMREMAP_WB);
> > +	if (!opreg_rvda)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	return opreg_rvda;
> > +}
> > +
> > +static void intel_igfx_free_rvda(struct drm_i915_private *i915)
> > +{
> > +	struct intel_opregion *opregion = &i915->opregion;
> > +
> > +	if (opregion->rvda) {
> > +		memunmap(opregion->rvda);
> > +		opregion->rvda = NULL;
> > +	}
> > +}
> > +
> > +static void intel_igfx_free_opregion(struct drm_i915_private *i915)
> > +{
> > +	struct intel_opregion *opregion = &i915->opregion;
> > +
> > +	if (opregion->header)
> > +		memunmap(opregion->header);
> > +}
> > +
> > +static const struct i915_opregion_func igfx_opregion_func = {
> > +	.alloc_opregion = intel_igfx_alloc_opregion,
> > +	.alloc_rvda = intel_igfx_alloc_rvda,
> > +	.free_rvda = intel_igfx_free_rvda,
> > +	.free_opregion = intel_igfx_free_opregion,
> > +};
> > +
> >  /**
> >   * intel_opregion_init() - Init ACPI opregion.
> >   * @i915 i915 device priv data.
> > @@ -1240,5 +1319,9 @@ void intel_opregion_unregister(struct drm_i915_private *i915)
> >   */
> >  int intel_opregion_init(struct drm_i915_private *i915)
> >  {
> > +	struct intel_opregion *opregion = &i915->opregion;
> > +
> > +	opregion->opregion_func = &igfx_opregion_func;
> > +
> >  	return intel_opregion_setup(i915);
> >  }
> > diff --git a/drivers/gpu/drm/i915/display/intel_opregion.h b/drivers/gpu/drm/i915/display/intel_opregion.h
> > index 744d53c804e2..7500c396b74d 100644
> > --- a/drivers/gpu/drm/i915/display/intel_opregion.h
> > +++ b/drivers/gpu/drm/i915/display/intel_opregion.h
> > @@ -37,6 +37,7 @@ struct opregion_acpi;
> >  struct opregion_swsci;
> >  struct opregion_asle;
> >  struct opregion_asle_ext;
> > +struct i915_opregion_func;
> >  
> >  struct intel_opregion {
> >  	struct opregion_header *header;
> > @@ -46,6 +47,8 @@ struct intel_opregion {
> >  	u32 swsci_sbcb_sub_functions;
> >  	struct opregion_asle *asle;
> >  	struct opregion_asle_ext *asle_ext;
> > +	const struct i915_opregion_func *opregion_func;
> > +	resource_size_t asls;
> >  	void *rvda;
> >  	void *vbt_firmware;
> >  	const void *vbt;
> 
> -- 
> Jani Nikula, Intel Open Source Graphics Center

  reply	other threads:[~2022-04-01 13:26 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-20 16:37 [Intel-gfx] [PATCH v3 0/6] DGFX OpRegion Anshuman Gupta
2022-02-20 16:37 ` [Intel-gfx] [PATCH v3 1/6] drm/i915/opregion: Add intel_opregion_init() wrapper Anshuman Gupta
2022-02-20 16:37 ` [Intel-gfx] [PATCH v3 2/6] drm/i915/opregion: Abstract opregion function Anshuman Gupta
2022-03-16  9:25   ` Jani Nikula
2022-04-01 13:26     ` Anshuman Gupta [this message]
2022-03-16  9:26   ` Jani Nikula
2022-02-20 16:37 ` [Intel-gfx] [PATCH v3 3/6] drm/i915/opregion: Add dgfx opregion func Anshuman Gupta
2022-02-20 16:37 ` [Intel-gfx] [PATCH v3 4/6] drm/i915/opregion: Cond dgfx opregion func registration Anshuman Gupta
2022-03-16  9:30   ` Jani Nikula
2022-02-20 16:37 ` [Intel-gfx] [PATCH v3 5/6] drm/i915/dgfx: OPROM OpRegion Setup Anshuman Gupta
2022-02-20 16:37 ` [Intel-gfx] [PATCH v3 6/6] drm/i915/dgfx: Get VBT from rvda Anshuman Gupta
2022-02-20 17:00 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for DGFX OpRegion (rev3) Patchwork
2022-02-20 17:01 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-02-20 17:24 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-02-20 18:49 ` [Intel-gfx] ✓ 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=20220401132647.GC22062@intel.com \
    --to=anshuman.gupta@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jani.nikula@intel.com \
    --cc=lucas.demarchi@intel.com \
    --cc=rodrigo.vivi@intel.com \
    /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.