summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/pxp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/pxp')
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp.c48
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp.h2
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h4
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c14
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h10
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_pm.c18
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_pm.h5
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_tee.c18
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_types.h9
9 files changed, 93 insertions, 35 deletions
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index bb2e15329f34..dc327cf40b5a 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -162,8 +162,8 @@ static struct intel_gt *find_gt_for_required_teelink(struct drm_i915_private *i9
* for HuC authentication. For now, its limited to DG2.
*/
if (IS_ENABLED(CONFIG_INTEL_MEI_PXP) && IS_ENABLED(CONFIG_INTEL_MEI_GSC) &&
- intel_huc_is_loaded_by_gsc(&i915->gt0.uc.huc) && intel_uc_uses_huc(&i915->gt0.uc))
- return &i915->gt0;
+ intel_huc_is_loaded_by_gsc(&to_gt(i915)->uc.huc) && intel_uc_uses_huc(&to_gt(i915)->uc))
+ return to_gt(i915);
return NULL;
}
@@ -188,8 +188,8 @@ static struct intel_gt *find_gt_for_required_protected_content(struct drm_i915_p
* Else we rely on mei-pxp module but only on legacy platforms
* prior to having separate media GTs and has a valid VDBOX.
*/
- if (IS_ENABLED(CONFIG_INTEL_MEI_PXP) && !i915->media_gt && VDBOX_MASK(&i915->gt0))
- return &i915->gt0;
+ if (IS_ENABLED(CONFIG_INTEL_MEI_PXP) && !i915->media_gt && VDBOX_MASK(to_gt(i915)))
+ return to_gt(i915);
return NULL;
}
@@ -359,22 +359,46 @@ void intel_pxp_end(struct intel_pxp *pxp)
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
}
+static bool pxp_required_fw_failed(struct intel_pxp *pxp)
+{
+ if (__intel_uc_fw_status(&pxp->ctrl_gt->uc.huc.fw) == INTEL_UC_FIRMWARE_LOAD_FAIL)
+ return true;
+ if (HAS_ENGINE(pxp->ctrl_gt, GSC0) &&
+ __intel_uc_fw_status(&pxp->ctrl_gt->uc.gsc.fw) == INTEL_UC_FIRMWARE_LOAD_FAIL)
+ return true;
+
+ return false;
+}
+
+static bool pxp_fw_dependencies_completed(struct intel_pxp *pxp)
+{
+ if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
+ return intel_pxp_gsccs_is_ready_for_sessions(pxp);
+
+ return pxp_component_bound(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)
+int intel_pxp_get_readiness_status(struct intel_pxp *pxp, int timeout_ms)
{
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))
+ if (pxp_required_fw_failed(pxp))
+ return -ENODEV;
+
+ if (pxp->platform_cfg_is_bad)
+ return -ENODEV;
+
+ if (timeout_ms) {
+ if (wait_for(pxp_fw_dependencies_completed(pxp), timeout_ms))
return 2;
+ } else if (!pxp_fw_dependencies_completed(pxp)) {
+ return 2;
}
return 1;
}
@@ -383,11 +407,13 @@ int intel_pxp_get_readiness_status(struct intel_pxp *pxp)
* the arb session is restarted from the irq work when we receive the
* termination completion interrupt
*/
+#define PXP_READINESS_TIMEOUT 250
+
int intel_pxp_start(struct intel_pxp *pxp)
{
int ret = 0;
- ret = intel_pxp_get_readiness_status(pxp);
+ ret = intel_pxp_get_readiness_status(pxp, PXP_READINESS_TIMEOUT);
if (ret < 0)
return ret;
else if (ret > 1)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 17254c3f1267..d9372f6f7797 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -26,7 +26,7 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id);
-int intel_pxp_get_readiness_status(struct intel_pxp *pxp);
+int intel_pxp_get_readiness_status(struct intel_pxp *pxp, int timeout_ms);
int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp);
int intel_pxp_start(struct intel_pxp *pxp);
void intel_pxp_end(struct intel_pxp *pxp);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
index 0165d38fbead..329b4fcdc040 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_43.h
@@ -14,8 +14,8 @@
#define PXP43_CMDID_NEW_HUC_AUTH 0x0000003F /* MTL+ */
#define PXP43_CMDID_INIT_SESSION 0x00000036
-/* PXP-Packet sizes for MTL's GSCCS-HECI instruction */
-#define PXP43_MAX_HECI_INOUT_SIZE (SZ_32K)
+/* PXP-Packet sizes for MTL's GSCCS-HECI instruction is spec'd at 65K before page alignment*/
+#define PXP43_MAX_HECI_INOUT_SIZE (PAGE_ALIGN(SZ_64K + SZ_1K))
/* PXP-Packet size for MTL's NEW_HUC_AUTH instruction */
#define PXP43_HUC_AUTH_INOUT_SIZE (SZ_4K)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
index f13890ec7db1..27402ecf0457 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
@@ -6,6 +6,7 @@
#include "gem/i915_gem_internal.h"
#include "gt/intel_context.h"
+#include "gt/intel_gt.h"
#include "gt/uc/intel_gsc_fw.h"
#include "gt/uc/intel_gsc_uc_heci_cmd_submit.h"
@@ -17,12 +18,13 @@
#include "intel_pxp_types.h"
static bool
-is_fw_err_platform_config(u32 type)
+is_fw_err_platform_config(struct intel_pxp *pxp, u32 type)
{
switch (type) {
case PXP_STATUS_ERROR_API_VERSION:
case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+ pxp->platform_cfg_is_bad = true;
return true;
default:
break;
@@ -110,7 +112,7 @@ gsccs_send_message(struct intel_pxp *pxp,
ret = intel_gsc_uc_heci_cmd_submit_nonpriv(&gt->uc.gsc,
exec_res->ce, &pkt, exec_res->bb_vaddr,
- GSC_REPLY_LATENCY_MS);
+ GSC_HECI_REPLY_LATENCY_MS);
if (ret) {
drm_err(&i915->drm, "failed to send gsc PXP msg (%d)\n", ret);
goto unlock;
@@ -197,7 +199,7 @@ bool intel_pxp_gsccs_is_ready_for_sessions(struct intel_pxp *pxp)
* are out of order) will suffice.
*/
if (intel_huc_is_authenticated(&pxp->ctrl_gt->uc.huc, INTEL_HUC_AUTH_BY_GSC) &&
- intel_gsc_uc_fw_proxy_init_done(&pxp->ctrl_gt->uc.gsc))
+ intel_gsc_uc_fw_proxy_init_done(&pxp->ctrl_gt->uc.gsc, true))
return true;
return false;
@@ -225,7 +227,7 @@ int intel_pxp_gsccs_create_session(struct intel_pxp *pxp,
if (ret) {
drm_err(&i915->drm, "Failed to init session %d, ret=[%d]\n", arb_session_id, ret);
} else if (msg_out.header.status != 0) {
- if (is_fw_err_platform_config(msg_out.header.status)) {
+ if (is_fw_err_platform_config(pxp, msg_out.header.status)) {
drm_info_once(&i915->drm,
"PXP init-session-%d failed due to BIOS/SOC:0x%08x:%s\n",
arb_session_id, msg_out.header.status,
@@ -268,7 +270,7 @@ void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 session_id)
drm_err(&i915->drm, "Failed to inv-stream-key-%u, ret=[%d]\n",
session_id, ret);
} else if (msg_out.header.status != 0) {
- if (is_fw_err_platform_config(msg_out.header.status)) {
+ if (is_fw_err_platform_config(pxp, msg_out.header.status)) {
drm_info_once(&i915->drm,
"PXP inv-stream-key-%u failed due to BIOS/SOC :0x%08x:%s\n",
session_id, msg_out.header.status,
@@ -336,7 +338,7 @@ gsccs_create_buffer(struct intel_gt *gt,
}
/* return a virtual pointer */
- *map = i915_gem_object_pin_map_unlocked(obj, i915_coherent_map_type(i915, obj, true));
+ *map = i915_gem_object_pin_map_unlocked(obj, intel_gt_coherent_map_type(gt, obj, true));
if (IS_ERR(*map)) {
drm_err(&i915->drm, "Failed to map gsccs backend %s.\n", bufname);
err = PTR_ERR(*map);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
index 298ad38e6c7d..9aae779c4da3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
@@ -8,16 +8,14 @@
#include <linux/types.h>
+#include "gt/uc/intel_gsc_uc_heci_cmd_submit.h"
+
struct intel_pxp;
-#define GSC_REPLY_LATENCY_MS 210
-/*
- * Max FW response time is 200ms, to which we add 10ms to account for overhead
- * such as request preparation, GuC submission to hw and pipeline completion times.
- */
#define GSC_PENDING_RETRY_MAXCOUNT 40
#define GSC_PENDING_RETRY_PAUSE_MS 50
-#define GSCFW_MAX_ROUND_TRIP_LATENCY_MS (GSC_PENDING_RETRY_MAXCOUNT * GSC_PENDING_RETRY_PAUSE_MS)
+#define GSCFW_MAX_ROUND_TRIP_LATENCY_MS (GSC_HECI_REPLY_LATENCY_MS + \
+ (GSC_PENDING_RETRY_MAXCOUNT * GSC_PENDING_RETRY_PAUSE_MS))
#ifdef CONFIG_DRM_I915_PXP
void intel_pxp_gsccs_fini(struct intel_pxp *pxp);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
index 1a04067f61fc..6dfd24918953 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -34,8 +34,10 @@ void intel_pxp_suspend(struct intel_pxp *pxp)
}
}
-void intel_pxp_resume_complete(struct intel_pxp *pxp)
+static void _pxp_resume(struct intel_pxp *pxp, bool take_wakeref)
{
+ intel_wakeref_t wakeref;
+
if (!intel_pxp_is_enabled(pxp))
return;
@@ -48,7 +50,21 @@ void intel_pxp_resume_complete(struct intel_pxp *pxp)
if (!HAS_ENGINE(pxp->ctrl_gt, GSC0) && !pxp->pxp_component)
return;
+ if (take_wakeref)
+ wakeref = intel_runtime_pm_get(&pxp->ctrl_gt->i915->runtime_pm);
intel_pxp_init_hw(pxp);
+ if (take_wakeref)
+ intel_runtime_pm_put(&pxp->ctrl_gt->i915->runtime_pm, wakeref);
+}
+
+void intel_pxp_resume_complete(struct intel_pxp *pxp)
+{
+ _pxp_resume(pxp, true);
+}
+
+void intel_pxp_runtime_resume(struct intel_pxp *pxp)
+{
+ _pxp_resume(pxp, false);
}
void intel_pxp_runtime_suspend(struct intel_pxp *pxp)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
index 06b46f535b42..8695889b8380 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
@@ -13,6 +13,7 @@ void intel_pxp_suspend_prepare(struct intel_pxp *pxp);
void intel_pxp_suspend(struct intel_pxp *pxp);
void intel_pxp_resume_complete(struct intel_pxp *pxp);
void intel_pxp_runtime_suspend(struct intel_pxp *pxp);
+void intel_pxp_runtime_resume(struct intel_pxp *pxp);
#else
static inline void intel_pxp_suspend_prepare(struct intel_pxp *pxp)
{
@@ -29,9 +30,9 @@ static inline void intel_pxp_resume_complete(struct intel_pxp *pxp)
static inline void intel_pxp_runtime_suspend(struct intel_pxp *pxp)
{
}
-#endif
+
static inline void intel_pxp_runtime_resume(struct intel_pxp *pxp)
{
- intel_pxp_resume_complete(pxp);
}
+#endif
#endif /* __INTEL_PXP_PM_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 1ce07d7e8769..bb58fa9579b8 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -9,8 +9,10 @@
#include <drm/i915_component.h>
#include "gem/i915_gem_lmem.h"
+#include "gt/intel_gt_print.h"
#include "i915_drv.h"
+#include "gt/intel_gt.h"
#include "intel_pxp.h"
#include "intel_pxp_cmd_interface_42.h"
@@ -20,12 +22,13 @@
#include "intel_pxp_types.h"
static bool
-is_fw_err_platform_config(u32 type)
+is_fw_err_platform_config(struct intel_pxp *pxp, u32 type)
{
switch (type) {
case PXP_STATUS_ERROR_API_VERSION:
case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
case PXP_STATUS_PLATFCONFIG_KF1_BAD:
+ pxp->platform_cfg_is_bad = true;
return true;
default:
break;
@@ -154,7 +157,8 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
{
struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
struct intel_pxp *pxp = i915->pxp;
- struct intel_uc *uc = &pxp->ctrl_gt->uc;
+ struct intel_gt *gt = pxp->ctrl_gt;
+ struct intel_uc *uc = &gt->uc;
intel_wakeref_t wakeref;
int ret = 0;
@@ -174,7 +178,7 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
/* load huc via pxp */
ret = intel_huc_fw_load_and_auth_via_gsc(&uc->huc);
if (ret < 0)
- drm_err(&i915->drm, "failed to load huc via gsc %d\n", ret);
+ gt_probe_error(gt, "failed to load huc via gsc %d\n", ret);
}
}
@@ -245,7 +249,9 @@ static int alloc_streaming_command(struct intel_pxp *pxp)
}
/* map the lmem into the virtual memory pointer */
- cmd = i915_gem_object_pin_map_unlocked(obj, i915_coherent_map_type(i915, obj, true));
+ cmd = i915_gem_object_pin_map_unlocked(obj,
+ intel_gt_coherent_map_type(pxp->ctrl_gt,
+ obj, true));
if (IS_ERR(cmd)) {
drm_err(&i915->drm, "Failed to map gsc message page!\n");
err = PTR_ERR(cmd);
@@ -339,7 +345,7 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
if (ret) {
drm_err(&i915->drm, "Failed to send tee msg init arb session, ret=[%d]\n", ret);
} else if (msg_out.header.status != 0) {
- if (is_fw_err_platform_config(msg_out.header.status)) {
+ if (is_fw_err_platform_config(pxp, msg_out.header.status)) {
drm_info_once(&i915->drm,
"PXP init-arb-session-%d failed due to BIOS/SOC:0x%08x:%s\n",
arb_session_id, msg_out.header.status,
@@ -387,7 +393,7 @@ try_again:
drm_err(&i915->drm, "Failed to send tee msg for inv-stream-key-%u, ret=[%d]\n",
session_id, ret);
} else if (msg_out.header.status != 0) {
- if (is_fw_err_platform_config(msg_out.header.status)) {
+ if (is_fw_err_platform_config(pxp, msg_out.header.status)) {
drm_info_once(&i915->drm,
"PXP inv-stream-key-%u failed due to BIOS/SOC :0x%08x:%s\n",
session_id, msg_out.header.status,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 1a8765866b8b..7e11fa8034b2 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -27,6 +27,15 @@ struct intel_pxp {
struct intel_gt *ctrl_gt;
/**
+ * @platform_cfg_is_bad: used to track if any prior arb session creation resulted
+ * in a failure that was caused by a platform configuration issue, meaning that
+ * failure will not get resolved without a change to the platform (not kernel)
+ * such as BIOS configuration, firwmware update, etc. This bool gets reflected when
+ * GET_PARAM:I915_PARAM_PXP_STATUS is called.
+ */
+ bool platform_cfg_is_bad;
+
+ /**
* @kcr_base: base mmio offset for the KCR engine which is different on legacy platforms
* vs newer platforms where the KCR is inside the media-tile.
*/