diff --git a/src/gallium/drivers/iris/i915/iris_batch.c b/src/gallium/drivers/iris/i915/iris_batch.c index 9a3f27443be..b923bfefba5 100644 --- a/src/gallium/drivers/iris/i915/iris_batch.c +++ b/src/gallium/drivers/iris/i915/iris_batch.c @@ -101,6 +101,14 @@ iris_create_hw_context(struct iris_bufmgr *bufmgr, bool protected) uint32_t ctx_id; if (protected) { + /* User explicitly requested for PXP so wait for the kernel + firmware + * dependencies to complete to avoid a premature PXP context-create failure. + */ + if (!intel_gem_wait_on_get_param(iris_bufmgr_get_fd(bufmgr), + I915_PARAM_PXP_STATUS, 1, + 8000)) + DBG("unable to wait for pxp-readiness\n"); + if (!intel_gem_create_context_ext(iris_bufmgr_get_fd(bufmgr), INTEL_GEM_CREATE_CONTEXT_EXT_PROTECTED_FLAG, &ctx_id)) { @@ -169,9 +177,18 @@ iris_create_engines_context(struct iris_context *ice) engine_classes[IRIS_BATCH_COMPUTE] = INTEL_ENGINE_CLASS_COMPUTE; enum intel_gem_create_context_flags flags = 0; - if (ice->protected) + if (ice->protected) { flags |= INTEL_GEM_CREATE_CONTEXT_EXT_PROTECTED_FLAG; + /* User explicitly requested for PXP so wait for the kernel + firmware + * dependencies to complete to avoid a premature PXP context-create failure. + */ + if (!intel_gem_wait_on_get_param(fd, + I915_PARAM_PXP_STATUS, 1, + 8000)) + DBG("unable to wait for pxp-readiness\n"); + } + uint32_t engines_ctx; if (!intel_gem_create_context_engines(fd, flags, engines_info, num_batches, engine_classes, &engines_ctx)) { diff --git a/src/intel/common/i915/intel_gem.c b/src/intel/common/i915/intel_gem.c index b380e57b679..797b85b610d 100644 --- a/src/intel/common/i915/intel_gem.c +++ b/src/intel/common/i915/intel_gem.c @@ -235,10 +235,20 @@ i915_gem_create_context_ext(int fd, bool i915_gem_supports_protected_context(int fd) { + int val = 0; uint32_t ctx_id; - bool ret = i915_gem_create_context_ext(fd, - INTEL_GEM_CREATE_CONTEXT_EXT_PROTECTED_FLAG, - &ctx_id); + bool ret; + + errno = 0; + if (!i915_gem_get_param(fd, I915_PARAM_PXP_STATUS, &val) && (errno == ENODEV)) + return false; + else + return (val > 0); + + /* failed without ENODEV, so older kernels require a creation test */ + ret = i915_gem_create_context_ext(fd, + INTEL_GEM_CREATE_CONTEXT_EXT_PROTECTED_FLAG, + &ctx_id); if (!ret) return ret; diff --git a/src/intel/common/intel_gem.c b/src/intel/common/intel_gem.c index b697d2f4b81..14dd76ee1ff 100644 --- a/src/intel/common/intel_gem.c +++ b/src/intel/common/intel_gem.c @@ -27,6 +27,8 @@ #include "i915/intel_gem.h" #include "xe/intel_gem.h" +#include "util/os_time.h" + bool intel_gem_supports_syncobj_wait(int fd) { @@ -135,6 +137,26 @@ intel_gem_supports_protected_context(int fd, enum intel_kmd_type kmd_type) } } +bool +intel_gem_wait_on_get_param(int fd, uint32_t param, int target_val, + uint32_t timeout_ms) +{ + int64_t start_time = os_time_get(); + int64_t end_time = start_time + (timeout_ms * 1000); + int val = -1; + + errno = 0; + do { + if (!intel_gem_get_param(fd, param, &val)) + break; + } while (val != target_val && !os_time_timeout(start_time, end_time, os_time_get())); + + if (errno || val != target_val) + return false; + + return true; +} + bool intel_gem_get_param(int fd, uint32_t param, int *value) { diff --git a/src/intel/common/intel_gem.h b/src/intel/common/intel_gem.h index b5ffc2326fc..da752841c60 100644 --- a/src/intel/common/intel_gem.h +++ b/src/intel/common/intel_gem.h @@ -187,6 +187,8 @@ bool intel_gem_get_context_param(int fd, uint32_t context, uint32_t param, uint64_t *value); bool intel_gem_get_param(int fd, uint32_t param, int *value); +bool intel_gem_wait_on_get_param(int fd, uint32_t param, int target_val, + uint32_t timeout_ms); #ifdef __cplusplus }