/* PXP requires both HuC authentication via GSC and GSC proxy initialized */
ready = xe_huc_is_authenticated(>->uc.huc, XE_HUC_AUTH_VIA_GSC) &&
xe_gsc_proxy_init_done(>->uc.gsc);
xe_force_wake_put(gt_to_fw(gt), fw_ref);
return ready;
}
/** *xe_pxp_get_readiness_status-checkwhetherPXPisreadyforuserspaceuse *@pxp:thexe_pxppointer(canbeNULLifPXPisdisabled) * *Returns:0ifPXPisnotreadyyet,1ifitisready,anegativeerrnovalue *ifPXPisnotsupported/enabledorifsomethingwentwronginthe *initializationoftheprerequisites.Notethatthereturnvaluesofthis *functionfollowtheuapi(seedrm_xe_query_pxp_status),sotheycanbeused *directlyinthequeryioctl.
*/ int xe_pxp_get_readiness_status(struct xe_pxp *pxp)
{ int ret = 0;
if (!xe_pxp_is_enabled(pxp)) return -ENODEV;
/* if the GSC or HuC FW are in an error state, PXP will never work */ if (xe_uc_fw_status_to_error(pxp->gt->uc.huc.fw.status) ||
xe_uc_fw_status_to_error(pxp->gt->uc.gsc.fw.status)) return -EIO;
xe_pm_runtime_get(pxp->xe);
/* PXP requires both HuC loaded and GSC proxy initialized */ if (pxp_prerequisites_done(pxp))
ret = 1;
staticvoid pxp_terminate(struct xe_pxp *pxp)
{ int ret = 0; struct xe_device *xe = pxp->xe;
if (!wait_for_completion_timeout(&pxp->activation,
msecs_to_jiffies(PXP_ACTIVATION_TIMEOUT_MS)))
drm_err(&xe->drm, "failed to wait for PXP start before termination\n");
mutex_lock(&pxp->mutex);
if (pxp->status == XE_PXP_ACTIVE)
pxp->key_instance++;
switch (pxp->status) { case XE_PXP_TERMINATION_IN_PROGRESS:
pxp->status = XE_PXP_READY_TO_START; break; case XE_PXP_NEEDS_ADDITIONAL_TERMINATION:
pxp->status = XE_PXP_NEEDS_TERMINATION; break; case XE_PXP_SUSPENDED: /* Nothing to do */ break; default:
drm_err(&pxp->xe->drm, "PXP termination complete while status was %u\n",
pxp->status);
}
/* we only support PXP on single tile devices with a media GT */ if (xe->info.tile_count > 1 || !gt) return0;
/* The GSCCS is required for submissions to the GSC FW */ if (!(gt->info.engine_mask & BIT(XE_HW_ENGINE_GSCCS0))) return0;
/* PXP requires both GSC and HuC firmwares to be available */ if (!xe_uc_fw_is_loadable(>->uc.gsc.fw) ||
!xe_uc_fw_is_loadable(>->uc.huc.fw)) {
drm_info(&xe->drm, "skipping PXP init due to missing FW dependencies"); return0;
}
staticint __pxp_start_arb_session(struct xe_pxp *pxp)
{ int ret; unsignedint fw_ref;
fw_ref = xe_force_wake_get(gt_to_fw(pxp->gt), XE_FW_GT); if (!xe_force_wake_ref_has_domain(fw_ref, XE_FW_GT)) return -EIO;
if (pxp_session_is_in_play(pxp, ARB_SESSION)) {
ret = -EEXIST; goto out_force_wake;
}
ret = xe_pxp_submit_session_init(&pxp->gsc_res, ARB_SESSION); if (ret) {
drm_err(&pxp->xe->drm, "Failed to init PXP arb session: %pe\n", ERR_PTR(ret)); goto out_force_wake;
}
ret = pxp_wait_for_session_state(pxp, ARB_SESSION, true); if (ret) {
drm_err(&pxp->xe->drm, "PXP ARB session failed to go in play%pe\n", ERR_PTR(ret)); goto out_force_wake;
}
drm_dbg(&pxp->xe->drm, "PXP ARB session is active\n");
if (!wait_for_completion_timeout(&pxp->activation,
msecs_to_jiffies(PXP_ACTIVATION_TIMEOUT_MS))) return -ETIMEDOUT;
mutex_lock(&pxp->mutex);
/* If PXP is not already active, turn it on */ switch (pxp->status) { case XE_PXP_ERROR:
ret = -EIO; goto out_unlock; case XE_PXP_ACTIVE: goto out_unlock; case XE_PXP_READY_TO_START:
pxp->status = XE_PXP_START_IN_PROGRESS;
reinit_completion(&pxp->activation); break; case XE_PXP_START_IN_PROGRESS: /* If a start is in progress then the completion must not be done */
XE_WARN_ON(completion_done(&pxp->activation));
restart = true; goto out_unlock; case XE_PXP_NEEDS_TERMINATION:
mark_termination_in_progress(pxp); break; case XE_PXP_TERMINATION_IN_PROGRESS: case XE_PXP_NEEDS_ADDITIONAL_TERMINATION: /* If a termination is in progress then the completion must not be done */
XE_WARN_ON(completion_done(&pxp->termination));
restart = true; goto out_unlock; case XE_PXP_SUSPENDED: default:
drm_err(&pxp->xe->drm, "unexpected state during PXP start: %u\n", pxp->status);
ret = -EIO; goto out_unlock;
}
mutex_unlock(&pxp->mutex);
if (!completion_done(&pxp->termination)) {
ret = pxp_terminate_hw(pxp); if (ret) {
drm_err(&pxp->xe->drm, "PXP termination failed before start\n");
mutex_lock(&pxp->mutex);
pxp->status = XE_PXP_ERROR;
goto out_unlock;
}
goto wait_for_idle;
}
/* All the cases except for start should have exited earlier */
XE_WARN_ON(completion_done(&pxp->activation));
ret = __pxp_start_arb_session(pxp);
mutex_lock(&pxp->mutex);
complete_all(&pxp->activation);
/* *Anyotherprocessshouldwaituntilthestategoesawayfrom *XE_PXP_START_IN_PROGRESS,soifthestateisnotthatsomethingwent *wrong.Markthestatusasneedingterminationandtryagain.
*/ if (pxp->status != XE_PXP_START_IN_PROGRESS) {
drm_err(&pxp->xe->drm, "unexpected state after PXP start: %u\n", pxp->status);
pxp->status = XE_PXP_NEEDS_TERMINATION;
restart = true; goto out_unlock;
}
/* If everything went ok, update the status and add the queue to the list */ if (!ret)
pxp->status = XE_PXP_ACTIVE; else
pxp->status = XE_PXP_ERROR;
/** *xe_pxp_pm_suspend-preparePXPforHWsuspend *@pxp:thexe->pxppointer(itwillbeNULLifPXPisdisabled) * *MakessureallPXPactionshavecompletedandinvalidatesallPXPqueues *andobjectsbeforewegointoasuspendstate. * *Returns:0ifsuccessful,anegativeerrnovalueotherwise.
*/ int xe_pxp_pm_suspend(struct xe_pxp *pxp)
{ bool needs_queue_inval = false; int ret = 0;
if (!xe_pxp_is_enabled(pxp)) return0;
wait_for_activation: if (!wait_for_completion_timeout(&pxp->activation,
msecs_to_jiffies(PXP_ACTIVATION_TIMEOUT_MS)))
ret = -ETIMEDOUT;
mutex_lock(&pxp->mutex);
switch (pxp->status) { case XE_PXP_ERROR: case XE_PXP_READY_TO_START: case XE_PXP_SUSPENDED: case XE_PXP_TERMINATION_IN_PROGRESS: case XE_PXP_NEEDS_ADDITIONAL_TERMINATION: /* *IfPXPisnotrunningthereisnothingtocleanup.Ifthere *isaterminationpendingthennoneedtoissueanotherone.
*/ break; case XE_PXP_START_IN_PROGRESS:
mutex_unlock(&pxp->mutex); goto wait_for_activation; case XE_PXP_NEEDS_TERMINATION: /* If PXP was never used we can skip the cleanup */ if (pxp->key_instance == pxp->last_suspend_key_instance) break;
fallthrough; case XE_PXP_ACTIVE:
pxp->key_instance++;
needs_queue_inval = true; break; default:
drm_err(&pxp->xe->drm, "unexpected state during PXP suspend: %u",
pxp->status);
ret = -EIO; goto out;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.