Intel-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jani Nikula <jani.nikula@intel.com>
To: Anshuman Gupta <anshuman.gupta@intel.com>,
	intel-gfx@lists.freedesktop.org
Cc: lucas.demarchi@intel.com, rodrigo.vivi@intel.com
Subject: Re: [Intel-gfx] [PATCH v3 2/6] drm/i915/opregion: Abstract opregion function
Date: Wed, 16 Mar 2022 11:25:33 +0200	[thread overview]
Message-ID: <87o826nt9u.fsf@intel.com> (raw)
In-Reply-To: <20220220163730.5021-3-anshuman.gupta@intel.com>

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.

> +		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.

> +{
> +	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.

> +		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-03-16  9:25 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 [this message]
2022-04-01 13:26     ` Anshuman Gupta
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=87o826nt9u.fsf@intel.com \
    --to=jani.nikula@intel.com \
    --cc=anshuman.gupta@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox