summaryrefslogtreecommitdiffstats
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.c40
-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.c17
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h10
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_huc.c4
-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.c29
-rw-r--r--drivers/gpu/drm/i915/pxp/intel_pxp_types.h9
10 files changed, 98 insertions, 40 deletions
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 38ec754d0..dc327cf40 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -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 17254c3f1..d9372f6f7 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 0165d38fb..329b4fcdc 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 2a600184a..75df959b0 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c
@@ -18,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;
@@ -111,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;
@@ -208,8 +209,8 @@ int intel_pxp_gsccs_create_session(struct intel_pxp *pxp,
int arb_session_id)
{
struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
- struct pxp43_create_arb_in msg_in = {0};
- struct pxp43_create_arb_out msg_out = {0};
+ struct pxp43_create_arb_in msg_in = {};
+ struct pxp43_create_arb_out msg_out = {};
int ret;
msg_in.header.api_version = PXP_APIVER(4, 3);
@@ -226,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,
@@ -246,8 +247,8 @@ int intel_pxp_gsccs_create_session(struct intel_pxp *pxp,
void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 session_id)
{
struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
- struct pxp42_inv_stream_key_in msg_in = {0};
- struct pxp42_inv_stream_key_out msg_out = {0};
+ struct pxp42_inv_stream_key_in msg_in = {};
+ struct pxp42_inv_stream_key_out msg_out = {};
int ret = 0;
/*
@@ -269,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,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h b/drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.h
index 298ad38e6..9aae779c4 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_huc.c b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c
index 5eedce916..0e609547b 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c
@@ -18,8 +18,8 @@ int intel_pxp_huc_load_and_auth(struct intel_pxp *pxp)
{
struct intel_gt *gt;
struct intel_huc *huc;
- struct pxp43_start_huc_auth_in huc_in = {0};
- struct pxp43_huc_auth_out huc_out = {0};
+ struct pxp43_start_huc_auth_in huc_in = {};
+ struct pxp43_huc_auth_out huc_out = {};
dma_addr_t huc_phys_addr;
u8 client_id = 0;
u8 fence_id = 0;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
index 1a04067f6..6dfd24918 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 06b46f535..8695889b8 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 80bb00189..b00d6c280 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -9,6 +9,7 @@
#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"
@@ -20,13 +21,16 @@
#include "intel_pxp_tee.h"
#include "intel_pxp_types.h"
+#define PXP_TRANSPORT_TIMEOUT_MS 5000 /* 5 sec */
+
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;
@@ -71,13 +75,15 @@ static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
goto unlock;
}
- ret = pxp_component->ops->send(pxp_component->tee_dev, msg_in, msg_in_size);
+ ret = pxp_component->ops->send(pxp_component->tee_dev, msg_in, msg_in_size,
+ PXP_TRANSPORT_TIMEOUT_MS);
if (ret) {
drm_err(&i915->drm, "Failed to send PXP TEE message\n");
goto unlock;
}
- ret = pxp_component->ops->recv(pxp_component->tee_dev, msg_out, msg_out_max_size);
+ ret = pxp_component->ops->recv(pxp_component->tee_dev, msg_out, msg_out_max_size,
+ PXP_TRANSPORT_TIMEOUT_MS);
if (ret < 0) {
drm_err(&i915->drm, "Failed to receive PXP TEE message\n");
goto unlock;
@@ -155,7 +161,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;
@@ -175,7 +182,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);
}
}
@@ -324,8 +331,8 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
int arb_session_id)
{
struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
- struct pxp42_create_arb_in msg_in = {0};
- struct pxp42_create_arb_out msg_out = {0};
+ struct pxp42_create_arb_in msg_in = {};
+ struct pxp42_create_arb_out msg_out = {};
int ret;
msg_in.header.api_version = PXP_APIVER(4, 2);
@@ -342,7 +349,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,
@@ -362,8 +369,8 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 session_id)
{
struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
- struct pxp42_inv_stream_key_in msg_in = {0};
- struct pxp42_inv_stream_key_out msg_out = {0};
+ struct pxp42_inv_stream_key_in msg_in = {};
+ struct pxp42_inv_stream_key_out msg_out = {};
int ret, trials = 0;
try_again:
@@ -390,7 +397,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 1a8765866..7e11fa803 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.
*/