diff mbox series

[3/5] drm/i915/wopcm: Try to use already locked WOPCM layout

Message ID 20190815171228.31920-4-michal.wajdeczko@intel.com (mailing list archive)
State New, archived
Headers show
Series More WOPCM fixes | expand

Commit Message

Michal Wajdeczko Aug. 15, 2019, 5:12 p.m. UTC
If WOPCM layout is already locked in HW we shouldn't continue
with our own partitioning as it could be likely different and
we will be unable to enforce it and fail. Instead we should try
to reuse what is already programmed, maybe there will be a fit.

This should enable us to reload driver with slightly different
HuC firmware (or even without HuC) without need to reboot.

v2: reordered/rebased

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Michal Winiarski <michal.winiarski@intel.com>
---
 drivers/gpu/drm/i915/intel_wopcm.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

Comments

Daniele Ceraolo Spurio Aug. 16, 2019, 12:14 a.m. UTC | #1
On 8/15/19 10:12 AM, Michal Wajdeczko wrote:
> If WOPCM layout is already locked in HW we shouldn't continue
> with our own partitioning as it could be likely different and
> we will be unable to enforce it and fail. Instead we should try
> to reuse what is already programmed, maybe there will be a fit.
> 
> This should enable us to reload driver with slightly different
> HuC firmware (or even without HuC) without need to reboot.
> 
> v2: reordered/rebased
> 
> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Michal Winiarski <michal.winiarski@intel.com>

Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

Daniele

> ---
>   drivers/gpu/drm/i915/intel_wopcm.c | 29 +++++++++++++++++++++++++++--
>   1 file changed, 27 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/intel_wopcm.c
> index 3ac05055bb08..ea02efb653a7 100644
> --- a/drivers/gpu/drm/i915/intel_wopcm.c
> +++ b/drivers/gpu/drm/i915/intel_wopcm.c
> @@ -212,6 +212,21 @@ static inline bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
>   				     huc_fw_size);
>   }
>   
> +static bool __wopcm_regs_locked(struct intel_uncore *uncore,
> +				u32 *guc_wopcm_base, u32 *guc_wopcm_size)
> +{
> +	u32 reg_base = intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET);
> +	u32 reg_size = intel_uncore_read(uncore, GUC_WOPCM_SIZE);
> +
> +	if (!(reg_size & GUC_WOPCM_SIZE_LOCKED) ||
> +	    !(reg_base & GUC_WOPCM_OFFSET_VALID))
> +		return false;
> +
> +	*guc_wopcm_base = reg_base & GUC_WOPCM_OFFSET_MASK;
> +	*guc_wopcm_size = reg_size & GUC_WOPCM_SIZE_MASK;
> +	return true;
> +}
> +
>   /**
>    * intel_wopcm_init() - Initialize the WOPCM structure.
>    * @wopcm: pointer to intel_wopcm.
> @@ -225,8 +240,9 @@ static inline bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
>   void intel_wopcm_init(struct intel_wopcm *wopcm)
>   {
>   	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
> -	u32 guc_fw_size = intel_uc_fw_get_upload_size(&i915->gt.uc.guc.fw);
> -	u32 huc_fw_size = intel_uc_fw_get_upload_size(&i915->gt.uc.huc.fw);
> +	struct intel_gt *gt = &i915->gt;
> +	u32 guc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.guc.fw);
> +	u32 huc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.huc.fw);
>   	u32 ctx_rsvd = context_reserved_size(i915);
>   	u32 guc_wopcm_base;
>   	u32 guc_wopcm_size;
> @@ -244,6 +260,14 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
>   	if (i915_inject_probe_failure(i915))
>   		return;
>   
> +	if (__wopcm_regs_locked(gt->uncore, &guc_wopcm_base, &guc_wopcm_size)) {
> +		DRM_DEV_DEBUG_DRIVER(i915->drm.dev,
> +				     "GuC WOPCM is already locked [%uK, %uK)\n",
> +				     guc_wopcm_base / SZ_1K,
> +				     guc_wopcm_size / SZ_1K);
> +		goto check;
> +	}
> +
>   	guc_wopcm_base = ALIGN(huc_fw_size + WOPCM_RESERVED_SIZE,
>   			       GUC_WOPCM_OFFSET_ALIGNMENT);
>   	guc_wopcm_base = max(wopcm->size - ctx_rsvd, guc_wopcm_base);
> @@ -254,6 +278,7 @@ void intel_wopcm_init(struct intel_wopcm *wopcm)
>   			     "Calculated GuC WOPCM Region: [%uKiB, %uKiB)\n",
>   			     guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K);
>   
> +check:
>   	if (__check_layout(i915, wopcm->size, guc_wopcm_base, guc_wopcm_size,
>   			   guc_fw_size, huc_fw_size)) {
>   		wopcm->guc.base = guc_wopcm_base;
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/intel_wopcm.c b/drivers/gpu/drm/i915/intel_wopcm.c
index 3ac05055bb08..ea02efb653a7 100644
--- a/drivers/gpu/drm/i915/intel_wopcm.c
+++ b/drivers/gpu/drm/i915/intel_wopcm.c
@@ -212,6 +212,21 @@  static inline bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
 				     huc_fw_size);
 }
 
+static bool __wopcm_regs_locked(struct intel_uncore *uncore,
+				u32 *guc_wopcm_base, u32 *guc_wopcm_size)
+{
+	u32 reg_base = intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET);
+	u32 reg_size = intel_uncore_read(uncore, GUC_WOPCM_SIZE);
+
+	if (!(reg_size & GUC_WOPCM_SIZE_LOCKED) ||
+	    !(reg_base & GUC_WOPCM_OFFSET_VALID))
+		return false;
+
+	*guc_wopcm_base = reg_base & GUC_WOPCM_OFFSET_MASK;
+	*guc_wopcm_size = reg_size & GUC_WOPCM_SIZE_MASK;
+	return true;
+}
+
 /**
  * intel_wopcm_init() - Initialize the WOPCM structure.
  * @wopcm: pointer to intel_wopcm.
@@ -225,8 +240,9 @@  static inline bool __check_layout(struct drm_i915_private *i915, u32 wopcm_size,
 void intel_wopcm_init(struct intel_wopcm *wopcm)
 {
 	struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
-	u32 guc_fw_size = intel_uc_fw_get_upload_size(&i915->gt.uc.guc.fw);
-	u32 huc_fw_size = intel_uc_fw_get_upload_size(&i915->gt.uc.huc.fw);
+	struct intel_gt *gt = &i915->gt;
+	u32 guc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.guc.fw);
+	u32 huc_fw_size = intel_uc_fw_get_upload_size(&gt->uc.huc.fw);
 	u32 ctx_rsvd = context_reserved_size(i915);
 	u32 guc_wopcm_base;
 	u32 guc_wopcm_size;
@@ -244,6 +260,14 @@  void intel_wopcm_init(struct intel_wopcm *wopcm)
 	if (i915_inject_probe_failure(i915))
 		return;
 
+	if (__wopcm_regs_locked(gt->uncore, &guc_wopcm_base, &guc_wopcm_size)) {
+		DRM_DEV_DEBUG_DRIVER(i915->drm.dev,
+				     "GuC WOPCM is already locked [%uK, %uK)\n",
+				     guc_wopcm_base / SZ_1K,
+				     guc_wopcm_size / SZ_1K);
+		goto check;
+	}
+
 	guc_wopcm_base = ALIGN(huc_fw_size + WOPCM_RESERVED_SIZE,
 			       GUC_WOPCM_OFFSET_ALIGNMENT);
 	guc_wopcm_base = max(wopcm->size - ctx_rsvd, guc_wopcm_base);
@@ -254,6 +278,7 @@  void intel_wopcm_init(struct intel_wopcm *wopcm)
 			     "Calculated GuC WOPCM Region: [%uKiB, %uKiB)\n",
 			     guc_wopcm_base / SZ_1K, guc_wopcm_size / SZ_1K);
 
+check:
 	if (__check_layout(i915, wopcm->size, guc_wopcm_base, guc_wopcm_size,
 			   guc_fw_size, huc_fw_size)) {
 		wopcm->guc.base = guc_wopcm_base;