[Intel-gfx] [PATCH v3 07/14] drm/i915/gt: Add intel_gt_mcr_wait_for_reg_fw()

Balasubramani Vivekanandan balasubramani.vivekanandan at intel.com
Mon Oct 17 16:52:54 UTC 2022


On 14.10.2022 16:02, Matt Roper wrote:
> Xe_HP has some MCR registers that need to be polled for completion of
> operations like TLB invalidation.  Those registers are in the GAM range,
> which rolls up the status from each unit into the 'primary' instance's
> value.  This makes it useful to have a dedicated 'wait for register'
> function that handles this on MCR registers, similar to the
> __intel_wait_for_register_fw() function we already have for regular
> registers.
> 
> Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
> ---
>  drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 55 ++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/gt/intel_gt_mcr.h |  7 ++++
>  2 files changed, 62 insertions(+)

Reviewed-by: Balasubramani Vivekanandan <balasubramani.vivekanandan at intel.com>

Regards,
Bala
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> index 4dc360f4e344..1ed9bc4dccfd 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
> @@ -568,3 +568,58 @@ void intel_gt_mcr_get_ss_steering(struct intel_gt *gt, unsigned int dss,
>  		return;
>  	}
>  }
> +
> +/**
> + * intel_gt_mcr_wait_for_reg_fw - wait until MCR register matches expected state
> + * @gt: GT structure
> + * @reg: the register to read
> + * @mask: mask to apply to register value
> + * @value: value to wait for
> + * @fast_timeout_us: fast timeout in microsecond for atomic/tight wait
> + * @slow_timeout_ms: slow timeout in millisecond
> + *
> + * This routine waits until the target register @reg contains the expected
> + * @value after applying the @mask, i.e. it waits until ::
> + *
> + *     (intel_gt_mcr_read_any_fw(gt, reg) & mask) == value
> + *
> + * Otherwise, the wait will timeout after @slow_timeout_ms milliseconds.
> + * For atomic context @slow_timeout_ms must be zero and @fast_timeout_us
> + * must be not larger than 20,0000 microseconds.
> + *
> + * This function is basically an MCR-friendly version of
> + * __intel_wait_for_register_fw().  Generally this function will only be used
> + * on GAM registers which are a bit special --- although they're MCR registers,
> + * reads (e.g., waiting for status updates) are always directed to the primary
> + * instance.
> + *
> + * Note that this routine assumes the caller holds forcewake asserted, it is
> + * not suitable for very long waits.
> + *
> + * Return: 0 if the register matches the desired condition, or -ETIMEDOUT.
> + */
> +int intel_gt_mcr_wait_for_reg_fw(struct intel_gt *gt,
> +				 i915_reg_t reg,
> +				 u32 mask,
> +				 u32 value,
> +				 unsigned int fast_timeout_us,
> +				 unsigned int slow_timeout_ms)
> +{
> +	u32 reg_value = 0;
> +#define done (((reg_value = intel_gt_mcr_read_any_fw(gt, reg)) & mask) == value)
> +	int ret;
> +
> +	/* Catch any overuse of this function */
> +	might_sleep_if(slow_timeout_ms);
> +	GEM_BUG_ON(fast_timeout_us > 20000);
> +	GEM_BUG_ON(!fast_timeout_us && !slow_timeout_ms);
> +
> +	ret = -ETIMEDOUT;
> +	if (fast_timeout_us && fast_timeout_us <= 20000)
> +		ret = _wait_for_atomic(done, fast_timeout_us, 0);
> +	if (ret && slow_timeout_ms)
> +		ret = wait_for(done, slow_timeout_ms);
> +
> +	return ret;
> +#undef done
> +}
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.h b/drivers/gpu/drm/i915/gt/intel_gt_mcr.h
> index 781b267478db..548f922cd9fa 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.h
> @@ -37,6 +37,13 @@ void intel_gt_mcr_report_steering(struct drm_printer *p, struct intel_gt *gt,
>  void intel_gt_mcr_get_ss_steering(struct intel_gt *gt, unsigned int dss,
>  				  unsigned int *group, unsigned int *instance);
>  
> +int intel_gt_mcr_wait_for_reg_fw(struct intel_gt *gt,
> +				 i915_reg_t reg,
> +				 u32 mask,
> +				 u32 value,
> +				 unsigned int fast_timeout_us,
> +				 unsigned int slow_timeout_ms);
> +
>  /*
>   * Helper for for_each_ss_steering loop.  On pre-Xe_HP platforms, subslice
>   * presence is determined by using the group/instance as direct lookups in the
> -- 
> 2.37.3
> 


More information about the Intel-gfx mailing list