diff options
Diffstat (limited to 'drivers/gpu/drm/i915/pxp/intel_pxp.c')
-rw-r--r-- | drivers/gpu/drm/i915/pxp/intel_pxp.c | 102 |
1 files changed, 78 insertions, 24 deletions
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c index 9d4c7724e98e..bb2e15329f34 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c @@ -12,7 +12,9 @@ #include "i915_drv.h" #include "intel_pxp.h" +#include "intel_pxp_gsccs.h" #include "intel_pxp_irq.h" +#include "intel_pxp_regs.h" #include "intel_pxp_session.h" #include "intel_pxp_tee.h" #include "intel_pxp_types.h" @@ -60,21 +62,22 @@ bool intel_pxp_is_active(const struct intel_pxp *pxp) return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->arb_is_valid; } -/* KCR register definitions */ -#define KCR_INIT _MMIO(0x320f0) -/* Setting KCR Init bit is required after system boot */ -#define KCR_INIT_ALLOW_DISPLAY_ME_WRITES REG_BIT(14) +static void kcr_pxp_set_status(const struct intel_pxp *pxp, bool enable) +{ + u32 val = enable ? _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES) : + _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES); + + intel_uncore_write(pxp->ctrl_gt->uncore, KCR_INIT(pxp->kcr_base), val); +} -static void kcr_pxp_enable(struct intel_gt *gt) +static void kcr_pxp_enable(const struct intel_pxp *pxp) { - intel_uncore_write(gt->uncore, KCR_INIT, - _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES)); + kcr_pxp_set_status(pxp, true); } -static void kcr_pxp_disable(struct intel_gt *gt) +static void kcr_pxp_disable(const struct intel_pxp *pxp) { - intel_uncore_write(gt->uncore, KCR_INIT, - _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES)); + kcr_pxp_set_status(pxp, false); } static int create_vcs_context(struct intel_pxp *pxp) @@ -126,13 +129,21 @@ static void pxp_init_full(struct intel_pxp *pxp) init_completion(&pxp->termination); complete_all(&pxp->termination); + if (pxp->ctrl_gt->type == GT_MEDIA) + pxp->kcr_base = MTL_KCR_BASE; + else + pxp->kcr_base = GEN12_KCR_BASE; + intel_pxp_session_management_init(pxp); ret = create_vcs_context(pxp); if (ret) return; - ret = intel_pxp_tee_component_init(pxp); + if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) + ret = intel_pxp_gsccs_init(pxp); + else + ret = intel_pxp_tee_component_init(pxp); if (ret) goto out_context; @@ -165,9 +176,12 @@ static struct intel_gt *find_gt_for_required_protected_content(struct drm_i915_p /* * For MTL onwards, PXP-controller-GT needs to have a valid GSC engine * on the media GT. NOTE: if we have a media-tile with a GSC-engine, - * the VDBOX is already present so skip that check + * the VDBOX is already present so skip that check. We also have to + * ensure the GSC and HUC firmware are coming online */ - if (i915->media_gt && HAS_ENGINE(i915->media_gt, GSC0)) + if (i915->media_gt && HAS_ENGINE(i915->media_gt, GSC0) && + intel_uc_fw_is_loadable(&i915->media_gt->uc.gsc.fw) && + intel_uc_fw_is_loadable(&i915->media_gt->uc.huc.fw)) return i915->media_gt; /* @@ -207,7 +221,9 @@ int intel_pxp_init(struct drm_i915_private *i915) if (!i915->pxp) return -ENOMEM; + /* init common info used by all feature-mode usages*/ i915->pxp->ctrl_gt = gt; + mutex_init(&i915->pxp->tee_mutex); /* * If full PXP feature is not available but HuC is loaded by GSC on pre-MTL @@ -229,7 +245,10 @@ void intel_pxp_fini(struct drm_i915_private *i915) i915->pxp->arb_is_valid = false; - intel_pxp_tee_component_fini(i915->pxp); + if (HAS_ENGINE(i915->pxp->ctrl_gt, GSC0)) + intel_pxp_gsccs_fini(i915->pxp); + else + intel_pxp_tee_component_fini(i915->pxp); destroy_vcs_context(i915->pxp); @@ -270,8 +289,18 @@ static bool pxp_component_bound(struct intel_pxp *pxp) return bound; } +int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp) +{ + if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) + return GSCFW_MAX_ROUND_TRIP_LATENCY_MS; + else + return 250; +} + static int __pxp_global_teardown_final(struct intel_pxp *pxp) { + int timeout; + if (!pxp->arb_is_valid) return 0; /* @@ -281,7 +310,9 @@ static int __pxp_global_teardown_final(struct intel_pxp *pxp) intel_pxp_mark_termination_in_progress(pxp); intel_pxp_terminate(pxp, false); - if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(250))) + timeout = intel_pxp_get_backend_timeout_ms(pxp); + + if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(timeout))) return -ETIMEDOUT; return 0; @@ -289,6 +320,8 @@ static int __pxp_global_teardown_final(struct intel_pxp *pxp) static int __pxp_global_teardown_restart(struct intel_pxp *pxp) { + int timeout; + if (pxp->arb_is_valid) return 0; /* @@ -297,7 +330,9 @@ static int __pxp_global_teardown_restart(struct intel_pxp *pxp) */ pxp_queue_termination(pxp); - if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(250))) + timeout = intel_pxp_get_backend_timeout_ms(pxp); + + if (!wait_for_completion_timeout(&pxp->termination, msecs_to_jiffies(timeout))) return -ETIMEDOUT; return 0; @@ -325,6 +360,26 @@ void intel_pxp_end(struct intel_pxp *pxp) } /* + * this helper is used by both intel_pxp_start and by + * the GET_PARAM IOCTL that user space calls. Thus, the + * return values here should match the UAPI spec. + */ +int intel_pxp_get_readiness_status(struct intel_pxp *pxp) +{ + if (!intel_pxp_is_enabled(pxp)) + return -ENODEV; + + if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) { + if (wait_for(intel_pxp_gsccs_is_ready_for_sessions(pxp), 250)) + return 2; + } else { + if (wait_for(pxp_component_bound(pxp), 250)) + return 2; + } + return 1; +} + +/* * the arb session is restarted from the irq work when we receive the * termination completion interrupt */ @@ -332,11 +387,11 @@ int intel_pxp_start(struct intel_pxp *pxp) { int ret = 0; - if (!intel_pxp_is_enabled(pxp)) - return -ENODEV; - - if (wait_for(pxp_component_bound(pxp), 250)) - return -ENXIO; + ret = intel_pxp_get_readiness_status(pxp); + if (ret < 0) + return ret; + else if (ret > 1) + return -EIO; /* per UAPI spec, user may retry later */ mutex_lock(&pxp->arb_mutex); @@ -357,14 +412,13 @@ unlock: void intel_pxp_init_hw(struct intel_pxp *pxp) { - kcr_pxp_enable(pxp->ctrl_gt); + kcr_pxp_enable(pxp); intel_pxp_irq_enable(pxp); } void intel_pxp_fini_hw(struct intel_pxp *pxp) { - kcr_pxp_disable(pxp->ctrl_gt); - + kcr_pxp_disable(pxp); intel_pxp_irq_disable(pxp); } |