Re: [PATCH] drm/i915/gt/uc: Evaluate GuC priority within locks

2024-06-07 Thread Daniele Ceraolo Spurio




On 6/5/2024 5:17 PM, Andi Shyti wrote:

The ce->guc_state.lock was made to protect guc_prio, which
indicates the GuC priority level.

But at the begnning of the function we perform some sanity check
of guc_prio outside its protected section. Move them within the
locked region.

Use this occasion to expand the if statement to make it clearer.

Fixes: ee242ca704d3 ("drm/i915/guc: Implement GuC priority management")
Signed-off-by: Andi Shyti 
Cc: Matthew Brost 
Cc:  # v5.15+
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 15 +++
  1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 0eaa1064242c..1181043bc5e9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4267,13 +4267,18 @@ static void guc_bump_inflight_request_prio(struct 
i915_request *rq,
u8 new_guc_prio = map_i915_prio_to_guc_prio(prio);
  
  	/* Short circuit function */

-   if (prio < I915_PRIORITY_NORMAL ||
-   rq->guc_prio == GUC_PRIO_FINI ||
-   (rq->guc_prio != GUC_PRIO_INIT &&
-!new_guc_prio_higher(rq->guc_prio, new_guc_prio)))
+   if (prio < I915_PRIORITY_NORMAL)
return;
  


My understanding was that those checks are purposely done outside of the 
lock to avoid taking it when not needed and that the early exit is not 
racy. In particular:


- GUC_PRIO_FINI is the end state for the priority, so if we're there 
that's not changing anymore and therefore the lock is not required.


- the priority only goes up with the bumping, so if 
new_guc_prio_higher() is false that's not going to be changed by a 
different thread running at the same time and increasing the priority 
even more.


I think there is still a possible race is if new_guc_prio_higher() is 
true when we check it outside the lock but then changes before we 
execute the protected chunk inside, so a fix would still be required for 
that.


All this said, I don't really have anything against moving the whole 
thing inside the lock since this isn't on a critical path, just wanted 
to point out that it's not all strictly required.


One nit on the code below.


spin_lock(>guc_state.lock);
+
+   if (rq->guc_prio == GUC_PRIO_FINI)
+   goto exit;
+
+   if (rq->guc_prio != GUC_PRIO_INIT &&
+   !new_guc_prio_higher(rq->guc_prio, new_guc_prio))
+   goto exit;
+
if (rq->guc_prio != GUC_PRIO_FINI) {


You're now checking for rq->guc_prio == GUC_PRIO_FINI inside the lock, 
so no need to check it again here as it can't have changed.


Daniele


if (rq->guc_prio != GUC_PRIO_INIT)
sub_context_inflight_prio(ce, rq->guc_prio);
@@ -4281,6 +4286,8 @@ static void guc_bump_inflight_request_prio(struct 
i915_request *rq,
add_context_inflight_prio(ce, rq->guc_prio);
update_context_prio(ce);
}
+
+exit:
spin_unlock(>guc_state.lock);
  }
  




Re: [PATCH 0/3] LNL GSC FW support

2024-04-15 Thread Daniele Ceraolo Spurio

Ooops, wrong mailing list, please ignore. I'll re-send it to intel-xe.

Daniele

On 4/15/2024 4:17 PM, Daniele Ceraolo Spurio wrote:

The flow is the same as MTL, so the only things we need to add are the
GSCCS and FW definitions.
Due to the FW not being in its final state yet, we can't push it to
linux-firmware yet so it needs to be in the xe-for-ci branch. Also, due
to lack of mei support, a second patch for xe-for-ci has been added to
avoid attempting to use the GSC proxy until the mei patch is there.

I haven't yet added the gitlab links for the xe-for-ci patches because
the mei patch is expected to be published soon and therefore the patch
to skip the GSC proxy init might end up unneeded. I'll add the links in
if we decide to go with the series as-is.

Cc: Lucas De Marchi 

Daniele Ceraolo Spurio (3):
   drm/xe/gsc: define GSCCS for LNL
   drm/xe/gsc: Skip GSC proxy init
   drm/xe/gsc: define GSC FW for LNL

  drivers/gpu/drm/xe/xe_gsc_proxy.c | 9 +
  drivers/gpu/drm/xe/xe_pci.c   | 3 ++-
  drivers/gpu/drm/xe/xe_uc_fw.c | 1 +
  3 files changed, 12 insertions(+), 1 deletion(-)





[PATCH 0/3] LNL GSC FW support

2024-04-15 Thread Daniele Ceraolo Spurio
The flow is the same as MTL, so the only things we need to add are the
GSCCS and FW definitions. 
Due to the FW not being in its final state yet, we can't push it to
linux-firmware yet so it needs to be in the xe-for-ci branch. Also, due
to lack of mei support, a second patch for xe-for-ci has been added to
avoid attempting to use the GSC proxy until the mei patch is there.

I haven't yet added the gitlab links for the xe-for-ci patches because
the mei patch is expected to be published soon and therefore the patch
to skip the GSC proxy init might end up unneeded. I'll add the links in
if we decide to go with the series as-is.

Cc: Lucas De Marchi 

Daniele Ceraolo Spurio (3):
  drm/xe/gsc: define GSCCS for LNL
  drm/xe/gsc: Skip GSC proxy init
  drm/xe/gsc: define GSC FW for LNL

 drivers/gpu/drm/xe/xe_gsc_proxy.c | 9 +
 drivers/gpu/drm/xe/xe_pci.c   | 3 ++-
 drivers/gpu/drm/xe/xe_uc_fw.c | 1 +
 3 files changed, 12 insertions(+), 1 deletion(-)

-- 
2.43.0



[xe-for-ci 2/3] drm/xe/gsc: Skip GSC proxy init

2024-04-15 Thread Daniele Ceraolo Spurio
The mei support for LNL hasn't landed yet, so we can't use the GSC proxy
component. Note that the lack of the GSC proxy means that the content
protection features (PXP, HDCP) won't work.

Signed-off-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/xe/xe_gsc_proxy.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.c 
b/drivers/gpu/drm/xe/xe_gsc_proxy.c
index 35e397b68dfc..3a7ba63b5bf2 100644
--- a/drivers/gpu/drm/xe/xe_gsc_proxy.c
+++ b/drivers/gpu/drm/xe/xe_gsc_proxy.c
@@ -446,6 +446,15 @@ int xe_gsc_proxy_init(struct xe_gsc *gsc)
 
mutex_init(>proxy.mutex);
 
+   /*
+* FIXME: mei support for LNL hasn't been merged yet so we can't use the
+* GSC proxy component yet.
+*/
+   if (xe->info.platform == XE_LUNARLAKE) {
+   xe_gt_info(gt, "skipping GSC proxy init due to missing LNL mei 
support\n");
+   return -ENODEV;
+   }
+
if (!IS_ENABLED(CONFIG_INTEL_MEI_GSC_PROXY)) {
xe_gt_info(gt, "can't init GSC proxy due to missing mei 
component\n");
return -ENODEV;
-- 
2.43.0



[xe-for-ci 3/3] drm/xe/gsc: define GSC FW for LNL

2024-04-15 Thread Daniele Ceraolo Spurio
Interface and compatibility versions are the same as MTL.

Note that the FW is still in development and the current release is
for CI only. Theefore, we'll need to keep this patch in the xe-for-ci
branch until we get the finalized FW release.

Signed-off-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/xe/xe_uc_fw.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/xe/xe_uc_fw.c b/drivers/gpu/drm/xe/xe_uc_fw.c
index f27e96c47baa..ae38172b6e0e 100644
--- a/drivers/gpu/drm/xe/xe_uc_fw.c
+++ b/drivers/gpu/drm/xe/xe_uc_fw.c
@@ -126,6 +126,7 @@ struct fw_blobs_by_type {
 
 /* for the GSC FW we match the compatibility version and not the release one */
 #define XE_GSC_FIRMWARE_DEFS(fw_def, major_ver)\
+   fw_def(LUNARLAKE,   major_ver(intel-ci/xe, gsc, lnl, 1, 0, 0))  
\
fw_def(METEORLAKE,  major_ver(i915, gsc,mtl,1, 0, 0))
 
 #define MAKE_FW_PATH(dir__, uc__, shortname__, version__)  
\
-- 
2.43.0



[PATCH 1/3] drm/xe/gsc: define GSCCS for LNL

2024-04-15 Thread Daniele Ceraolo Spurio
LNL has 1 GSCCS, same as MTL. Note that the GSCCS will be disabled until
we have a GSC FW defined, but having it in the list of engine is a
requirement to add such definition.

Signed-off-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/xe/xe_pci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
index c47ab4b67467..45ed1be584c5 100644
--- a/drivers/gpu/drm/xe/xe_pci.c
+++ b/drivers/gpu/drm/xe/xe_pci.c
@@ -209,7 +209,8 @@ static const struct xe_media_desc media_xelpmp = {
 static const struct xe_media_desc media_xe2 = {
.name = "Xe2_LPM",
.hw_engine_mask =
-   BIT(XE_HW_ENGINE_VCS0) | BIT(XE_HW_ENGINE_VECS0), /* TODO: GSC0 
*/
+   BIT(XE_HW_ENGINE_VCS0) | BIT(XE_HW_ENGINE_VECS0) |
+   BIT(XE_HW_ENGINE_GSCCS0)
 };
 
 static const struct xe_device_desc tgl_desc = {
-- 
2.43.0



[PATCH] drm/i915/dg2: wait for HuC load completion before running selftests

2024-04-10 Thread Daniele Ceraolo Spurio
On DG2, submissions to VCS engines tied to a gem context are blocked
until the HuC is loaded. Since some selftests do use a gem context,
wait for the HuC load to complete before running the tests to avoid
contamination.

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/10564
Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
---
 .../gpu/drm/i915/selftests/i915_selftest.c| 36 ---
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_selftest.c 
b/drivers/gpu/drm/i915/selftests/i915_selftest.c
index ee79e0809a6d..fee76c1d2f45 100644
--- a/drivers/gpu/drm/i915/selftests/i915_selftest.c
+++ b/drivers/gpu/drm/i915/selftests/i915_selftest.c
@@ -154,6 +154,30 @@ __wait_gsc_proxy_completed(struct drm_i915_private *i915)
pr_warn(DRIVER_NAME "Timed out waiting for 
gsc_proxy_completion!\n");
 }
 
+static void
+__wait_gsc_huc_load_completed(struct drm_i915_private *i915)
+{
+   /* this only applies to DG2, so we only care about GT0 */
+   struct intel_huc *huc = _gt(i915)->uc.huc;
+   bool need_to_wait = (IS_ENABLED(CONFIG_INTEL_MEI_PXP) &&
+intel_huc_wait_required(huc));
+   /*
+* The GSC and PXP mei bringup depends on the kernel boot ordering, so
+* to account for the worst case scenario the HuC code waits for up to
+* 10s for the GSC driver to load and then another 5s for the PXP
+* component to bind before giving up, even though those steps normally
+* complete in less than a second from the i915 load. We match that
+* timeout here, but we expect to bail early due to the fence being
+* signalled even in a failure case, as it is extremely unlikely that
+* both components will use their full timeout.
+*/
+   unsigned long timeout_ms = 15000;
+
+   if (need_to_wait &&
+   wait_for(i915_sw_fence_done(>delayed_load.fence), timeout_ms))
+   pr_warn(DRIVER_NAME "Timed out waiting for huc load via 
GSC!\n");
+}
+
 static int __run_selftests(const char *name,
   struct selftest *st,
   unsigned int count,
@@ -228,14 +252,16 @@ int i915_mock_selftests(void)
 
 int i915_live_selftests(struct pci_dev *pdev)
 {
+   struct drm_i915_private *i915 = pdev_to_i915(pdev);
int err;
 
if (!i915_selftest.live)
return 0;
 
-   __wait_gsc_proxy_completed(pdev_to_i915(pdev));
+   __wait_gsc_proxy_completed(i915);
+   __wait_gsc_huc_load_completed(i915);
 
-   err = run_selftests(live, pdev_to_i915(pdev));
+   err = run_selftests(live, i915);
if (err) {
i915_selftest.live = err;
return err;
@@ -251,14 +277,16 @@ int i915_live_selftests(struct pci_dev *pdev)
 
 int i915_perf_selftests(struct pci_dev *pdev)
 {
+   struct drm_i915_private *i915 = pdev_to_i915(pdev);
int err;
 
if (!i915_selftest.perf)
return 0;
 
-   __wait_gsc_proxy_completed(pdev_to_i915(pdev));
+   __wait_gsc_proxy_completed(i915);
+   __wait_gsc_huc_load_completed(i915);
 
-   err = run_selftests(perf, pdev_to_i915(pdev));
+   err = run_selftests(perf, i915);
if (err) {
i915_selftest.perf = err;
return err;
-- 
2.43.0



[PR] i915: Add DG2 HuC to 7.10.15

2024-04-01 Thread Daniele Ceraolo Spurio
The following changes since commit 93f329774542b9b7d57abb18ea8b6542f2d8feac:

  Merge branch 'robot/pr-0-1709214990' into 'main' (2024-02-29 14:10:53 +)

are available in the Git repository at:

  g...@gitlab.freedesktop.org:drm/firmware.git tags/intel-2024-04-01

for you to fetch changes up to ab144168469a77f54ad539ac98dede7ce4c6a75d:

  i915: Add DG2 HuC 7.10.15 (2024-03-28 13:45:41 -0700)


Daniele Ceraolo Spurio (1):
  i915: Add DG2 HuC 7.10.15

 WHENCE   |   2 +-
 i915/dg2_huc_gsc.bin | Bin 622592 -> 630784 bytes
 2 files changed, 1 insertion(+), 1 deletion(-)
 mode change 100755 => 100644 i915/dg2_huc_gsc.bin


[CI] drm/i915/huc: pick the DG2 HuC up from the CI folder

2024-03-22 Thread Daniele Ceraolo Spurio
This is to test the new HuC release before overwriting the existing one.
This patch is for testing only and it should not be merged.

Signed-off-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index d80278eb45d7..19895872f7e8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -112,7 +112,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 
 #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_raw, huc_mmp, huc_gsc) \
fw_def(METEORLAKE,   0, huc_gsc(mtl)) \
-   fw_def(DG2,  0, huc_gsc(dg2)) \
+   fw_def(DG2,  0, huc_gsc(../intel-ci/i915/dg2)) \
fw_def(ALDERLAKE_P,  0, huc_raw(tgl)) \
fw_def(ALDERLAKE_P,  0, huc_mmp(tgl,  7, 9, 3)) \
fw_def(ALDERLAKE_S,  0, huc_raw(tgl)) \
-- 
2.43.0



Re: [PATCH 4/5] drm/xe/hdcp: Enable HDCP for XE

2024-02-14 Thread Daniele Ceraolo Spurio




On 2/13/2024 9:33 PM, Kandpal, Suraj wrote:

interaction of HDCP as a client with the GSC CS interface.

--v2
-add kfree at appropriate place [Daniele] -remove useless define
[Daniele] -move host session logic to xe_gsc_submit.c [Daniele] -call
xe_gsc_check_and_update_pending directly in an if condition [Daniele]
-use xe_device instead of drm_i915_private [Daniele]

--v3
-use xe prefix for newly exposed function [Daniele] -remove client
specific defines from intel_gsc_mtl_header [Daniele] -add missing
kfree() [Daniele] -have NULL check for hdcp_message in finish function
[Daniele] -dont have too many variable declarations in the same line
[Daniele]

Signed-off-by: Suraj Kandpal 
---
   drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 180

++-

   drivers/gpu/drm/xe/xe_gsc_submit.c   |  15 ++
   drivers/gpu/drm/xe/xe_gsc_submit.h   |   1 +
   3 files changed, 193 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index 425db3532ce5..aa8c13916bb6 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -4,12 +4,27 @@
*/

   #include 
+#include 

+#include "abi/gsc_command_header_abi.h"
   #include "intel_hdcp_gsc.h"
   #include "xe_device_types.h"
   #include "xe_gt.h"
   #include "xe_gsc_proxy.h"
   #include "xe_pm.h"
+#include "xe_bo.h"
+#include "xe_map.h"
+#include "xe_gsc_submit.h"
+
+#define HECI_MEADDRESS_HDCP 18
+
+struct intel_hdcp_gsc_message {
+   struct xe_bo *hdcp_bo;
+   u64 hdcp_cmd_in;
+   u64 hdcp_cmd_out;
+};
+
+#define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header)

   bool intel_hdcp_gsc_cs_required(struct xe_device *xe)
   {
@@ -40,19 +55,178 @@ bool intel_hdcp_gsc_check_status(struct xe_device

*xe)

return ret;
   }

+/*This function helps allocate memory for the command that we will
+send to gsc cs */ static int intel_hdcp_gsc_initialize_message(struct

xe_device *xe,

+struct intel_hdcp_gsc_message

*hdcp_message) {

+   struct xe_bo *bo = NULL;
+   u64 cmd_in, cmd_out;
+   int ret = 0;
+
+   /* allocate object of two page for HDCP command memory and store

it */

+   xe_device_mem_access_get(xe);
+   bo = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe), NULL,

PAGE_SIZE * 2,

+ ttm_bo_type_kernel,
+ XE_BO_CREATE_SYSTEM_BIT |
+ XE_BO_CREATE_GGTT_BIT);
+
+   if (IS_ERR(bo)) {
+   drm_err(>drm, "Failed to allocate bo for HDCP streaming

command!\n");

+   ret = PTR_ERR(bo);
+   goto out;
+   }
+
+   cmd_in = xe_bo_ggtt_addr(bo);
+   cmd_out = cmd_in + PAGE_SIZE;
+   xe_map_memset(xe, >vmap, 0, 0, bo->size);
+
+   hdcp_message->hdcp_bo = bo;
+   hdcp_message->hdcp_cmd_in = cmd_in;
+   hdcp_message->hdcp_cmd_out = cmd_out;
+out:
+   xe_device_mem_access_put(xe);
+   return ret;
+}
+
+static int intel_hdcp_gsc_hdcp2_init(struct xe_device *xe) {
+   struct intel_hdcp_gsc_message *hdcp_message;
+   int ret;
+
+   hdcp_message = kzalloc(sizeof(*hdcp_message), GFP_KERNEL);
+
+   if (!hdcp_message)
+   return -ENOMEM;
+
+   /*
+* NOTE: No need to lock the comp mutex here as it is already
+* going to be taken before this function called
+*/
+   ret = intel_hdcp_gsc_initialize_message(xe, hdcp_message);
+   xe->display.hdcp.hdcp_message = hdcp_message;
+
+   if (ret) {
+   drm_err(>drm, "Could not initialize hdcp_message\n");
+   kfree(hdcp_message);

Here you're leaving xe->display.hdcp.hdcp_message pointing to a memory
location that we no longer own. is that safe for the _fini function?


Would it be better to not have a kfree here if initialization fails it gets 
taken care of
In finish function anyways that would be safer I presume.


We normally try to clean up immediately when things go wrong, also 
because if this failure causes the driver load to abort the _fini 
function might not get called (but not sure if this is the case here).

In this case this can be easily fixed by simply changing it to:

ret = intel_hdcp_gsc_initialize_message(xe, hdcp_message);
if (ret) {
drm_err(>drm, "Could not initialize hdcp_message\n");
kfree(hdcp_message);
return ret;
}

xe->display.hdcp.hdcp_message = hdcp_message;
return 0;


Which guarantees that xe->display.hdcp.hdcp_message is only set when the 
allocation exists with minimal changes to the code.


Daniele




LGTM apart from this (assuming it is going to be squashed with the next
patch for merge).

Yes this will be squashed with the next patch when I send the new revision

Regards,
Suraj Kandpal

Daniele


+   }
+
+   return ret;
+}
+
   int intel_hdcp_gsc_init(struct xe_device *xe)
   {
-   

Re: [PATCH 4/5] drm/xe/hdcp: Enable HDCP for XE

2024-02-13 Thread Daniele Ceraolo Spurio




On 2/9/2024 2:14 AM, Suraj Kandpal wrote:

Enable HDCP for Xe by defining functions which take care of
interaction of HDCP as a client with the GSC CS interface.

--v2
-add kfree at appropriate place [Daniele]
-remove useless define [Daniele]
-move host session logic to xe_gsc_submit.c [Daniele]
-call xe_gsc_check_and_update_pending directly in an if condition
[Daniele]
-use xe_device instead of drm_i915_private [Daniele]

--v3
-use xe prefix for newly exposed function [Daniele]
-remove client specific defines from intel_gsc_mtl_header [Daniele]
-add missing kfree() [Daniele]
-have NULL check for hdcp_message in finish function [Daniele]
-dont have too many variable declarations in the same line [Daniele]

Signed-off-by: Suraj Kandpal 
---
  drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 180 ++-
  drivers/gpu/drm/xe/xe_gsc_submit.c   |  15 ++
  drivers/gpu/drm/xe/xe_gsc_submit.h   |   1 +
  3 files changed, 193 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c 
b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index 425db3532ce5..aa8c13916bb6 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -4,12 +4,27 @@
   */
  
  #include 

+#include 
  
+#include "abi/gsc_command_header_abi.h"

  #include "intel_hdcp_gsc.h"
  #include "xe_device_types.h"
  #include "xe_gt.h"
  #include "xe_gsc_proxy.h"
  #include "xe_pm.h"
+#include "xe_bo.h"
+#include "xe_map.h"
+#include "xe_gsc_submit.h"
+
+#define HECI_MEADDRESS_HDCP 18
+
+struct intel_hdcp_gsc_message {
+   struct xe_bo *hdcp_bo;
+   u64 hdcp_cmd_in;
+   u64 hdcp_cmd_out;
+};
+
+#define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header)
  
  bool intel_hdcp_gsc_cs_required(struct xe_device *xe)

  {
@@ -40,19 +55,178 @@ bool intel_hdcp_gsc_check_status(struct xe_device *xe)
return ret;
  }
  
+/*This function helps allocate memory for the command that we will send to gsc cs */

+static int intel_hdcp_gsc_initialize_message(struct xe_device *xe,
+struct intel_hdcp_gsc_message 
*hdcp_message)
+{
+   struct xe_bo *bo = NULL;
+   u64 cmd_in, cmd_out;
+   int ret = 0;
+
+   /* allocate object of two page for HDCP command memory and store it */
+   xe_device_mem_access_get(xe);
+   bo = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe), NULL, 
PAGE_SIZE * 2,
+ ttm_bo_type_kernel,
+ XE_BO_CREATE_SYSTEM_BIT |
+ XE_BO_CREATE_GGTT_BIT);
+
+   if (IS_ERR(bo)) {
+   drm_err(>drm, "Failed to allocate bo for HDCP streaming 
command!\n");
+   ret = PTR_ERR(bo);
+   goto out;
+   }
+
+   cmd_in = xe_bo_ggtt_addr(bo);
+   cmd_out = cmd_in + PAGE_SIZE;
+   xe_map_memset(xe, >vmap, 0, 0, bo->size);
+
+   hdcp_message->hdcp_bo = bo;
+   hdcp_message->hdcp_cmd_in = cmd_in;
+   hdcp_message->hdcp_cmd_out = cmd_out;
+out:
+   xe_device_mem_access_put(xe);
+   return ret;
+}
+
+static int intel_hdcp_gsc_hdcp2_init(struct xe_device *xe)
+{
+   struct intel_hdcp_gsc_message *hdcp_message;
+   int ret;
+
+   hdcp_message = kzalloc(sizeof(*hdcp_message), GFP_KERNEL);
+
+   if (!hdcp_message)
+   return -ENOMEM;
+
+   /*
+* NOTE: No need to lock the comp mutex here as it is already
+* going to be taken before this function called
+*/
+   ret = intel_hdcp_gsc_initialize_message(xe, hdcp_message);
+   xe->display.hdcp.hdcp_message = hdcp_message;
+
+   if (ret) {
+   drm_err(>drm, "Could not initialize hdcp_message\n");
+   kfree(hdcp_message);


Here you're leaving xe->display.hdcp.hdcp_message pointing to a memory 
location that we no longer own. is that safe for the _fini function?


LGTM apart from this (assuming it is going to be squashed with the next 
patch for merge).


Daniele


+   }
+
+   return ret;
+}
+
  int intel_hdcp_gsc_init(struct xe_device *xe)
  {
-   drm_dbg_kms(>drm, "HDCP support not yet implemented\n");
-   return -ENODEV;
+   struct i915_hdcp_arbiter *data;
+   int ret;
+
+   data = kzalloc(sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return -ENOMEM;
+
+   mutex_lock(>display.hdcp.hdcp_mutex);
+   xe->display.hdcp.arbiter = data;
+   xe->display.hdcp.arbiter->hdcp_dev = xe->drm.dev;
+   xe->display.hdcp.arbiter->ops = _hdcp_ops;
+   ret = intel_hdcp_gsc_hdcp2_init(xe);
+   if (ret)
+   kfree(data);
+
+   mutex_unlock(>display.hdcp.hdcp_mutex);
+
+   return ret;
  }
  
  void intel_hdcp_gsc_fini(struct xe_device *xe)

  {
+   struct intel_hdcp_gsc_message *hdcp_message =
+   xe->display.hdcp.hdcp_message;
+
+   if (!hdcp_message)
+   return;
+
+   

Re: [PATCH 3/5] drm/xe: Use gsc_proxy_init_done to check proxy status

2024-02-13 Thread Daniele Ceraolo Spurio




On 2/9/2024 2:14 AM, Suraj Kandpal wrote:

Expose gsc_proxy_init_done so that we can check if gsc proxy has
been initialized or not.

Signed-off-by: Suraj Kandpal 
---
  drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 25 +++-
  drivers/gpu/drm/xe/xe_gsc_proxy.c|  4 ++--
  drivers/gpu/drm/xe/xe_gsc_proxy.h|  1 +
  3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c 
b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index 5d1d0054b578..425db3532ce5 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -4,8 +4,12 @@
   */
  
  #include 

+
  #include "intel_hdcp_gsc.h"
  #include "xe_device_types.h"
+#include "xe_gt.h"
+#include "xe_gsc_proxy.h"
+#include "xe_pm.h"
  
  bool intel_hdcp_gsc_cs_required(struct xe_device *xe)

  {
@@ -14,7 +18,26 @@ bool intel_hdcp_gsc_cs_required(struct xe_device *xe)
  
  bool intel_hdcp_gsc_check_status(struct xe_device *xe)

  {
-   return false;
+   struct xe_tile *tile = xe_device_get_root_tile(xe);
+   struct xe_gt *gt = tile->media_gt;
+   bool ret = true;
+


Sorry for missing this in the previous rev, but I just remembered that 
if the GSC FW is not enabled then the forcewake domain is not 
initialized, which would lead to the forcewake_get throwing an error, so 
we need a check here first:


        if (!xe_uc_fw_is_enabled(>uc.gsc.fw))
                return false;

With this change:
Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+   xe_pm_runtime_get(xe);
+   ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GSC);
+   if (ret) {
+   drm_dbg_kms(>drm,
+   "failed to get forcewake to check proxy status\n");
+   ret = false;
+   goto out;
+   }
+
+   if (!xe_gsc_proxy_init_done(>uc.gsc))
+   ret = false;
+
+   xe_force_wake_put(gt_to_fw(gt), XE_FW_GSC);
+out:
+   xe_pm_runtime_put(xe);
+   return ret;
  }
  
  int intel_hdcp_gsc_init(struct xe_device *xe)

diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.c 
b/drivers/gpu/drm/xe/xe_gsc_proxy.c
index 309ef80e3b95..1ced6b4d4946 100644
--- a/drivers/gpu/drm/xe/xe_gsc_proxy.c
+++ b/drivers/gpu/drm/xe/xe_gsc_proxy.c
@@ -66,7 +66,7 @@ static inline struct xe_device *kdev_to_xe(struct device 
*kdev)
return dev_get_drvdata(kdev);
  }
  
-static bool gsc_proxy_init_done(struct xe_gsc *gsc)

+bool xe_gsc_proxy_init_done(struct xe_gsc *gsc)
  {
struct xe_gt *gt = gsc_to_gt(gsc);
u32 fwsts1 = xe_mmio_read32(gt, HECI_FWSTS1(MTL_GSC_HECI1_BASE));
@@ -528,7 +528,7 @@ int xe_gsc_proxy_start(struct xe_gsc *gsc)
if (err)
return err;
  
-	if (!gsc_proxy_init_done(gsc)) {

+   if (!xe_gsc_proxy_init_done(gsc)) {
xe_gt_err(gsc_to_gt(gsc), "GSC FW reports proxy init not 
completed\n");
return -EIO;
}
diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.h 
b/drivers/gpu/drm/xe/xe_gsc_proxy.h
index 908f9441f093..c511ade6b863 100644
--- a/drivers/gpu/drm/xe/xe_gsc_proxy.h
+++ b/drivers/gpu/drm/xe/xe_gsc_proxy.h
@@ -11,6 +11,7 @@
  struct xe_gsc;
  
  int xe_gsc_proxy_init(struct xe_gsc *gsc);

+bool xe_gsc_proxy_init_done(struct xe_gsc *gsc);
  void xe_gsc_proxy_remove(struct xe_gsc *gsc);
  int xe_gsc_proxy_start(struct xe_gsc *gsc);
  




Re: [PATCH 2/5] drm/xe/hdcp: Use xe_device struct

2024-02-13 Thread Daniele Ceraolo Spurio




On 2/9/2024 2:14 AM, Suraj Kandpal wrote:

Use xe_device struct instead of drm_i915_private so as to not
cause confusion and comply with Xe standards even though xe_device
gets translated to drm_i915_private.


AFAIU xe_device does not get translated to drm_i915_private, it's really 
an xe_device struct under the hood.
The change itself looks ok to me, but I'll leave the final r-b to 
someone on the display side to confirm this is the correct approach.


Daniele



Signed-off-by: Suraj Kandpal 
---
  drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 15 ---
  1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c 
b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index 0f11a39333e2..5d1d0054b578 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -3,30 +3,31 @@
   * Copyright 2023, Intel Corporation.
   */
  
-#include "i915_drv.h"

+#include 
  #include "intel_hdcp_gsc.h"
+#include "xe_device_types.h"
  
-bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915)

+bool intel_hdcp_gsc_cs_required(struct xe_device *xe)
  {
return true;
  }
  
-bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915)

+bool intel_hdcp_gsc_check_status(struct xe_device *xe)
  {
return false;
  }
  
-int intel_hdcp_gsc_init(struct drm_i915_private *i915)

+int intel_hdcp_gsc_init(struct xe_device *xe)
  {
-   drm_info(>drm, "HDCP support not yet implemented\n");
+   drm_dbg_kms(>drm, "HDCP support not yet implemented\n");
return -ENODEV;
  }
  
-void intel_hdcp_gsc_fini(struct drm_i915_private *i915)

+void intel_hdcp_gsc_fini(struct xe_device *xe)
  {
  }
  
-ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,

+ssize_t intel_hdcp_gsc_msg_send(struct xe_device *xe, u8 *msg_in,
size_t msg_in_len, u8 *msg_out,
size_t msg_out_len)
  {




Re: [PATCH 3/4] drm/xe/hdcp: Enable HDCP for XE

2024-02-08 Thread Daniele Ceraolo Spurio




On 2/7/2024 3:35 AM, Suraj Kandpal wrote:

Enable HDCP for Xe by defining functions which take care of
interaction of HDCP as a client with the GSC CS interface.

--v2
-add kfree at appropriate place [Daniele]
-forward declare drm_i915_private [Daniele]


I don't see the forward declaration, just the switch to xe_device (which 
is better).



-remove useless define [Daniele]
-move host session logic to xe_gsc_submit.c [Daniele]
-call xe_gsc_check_and_update_pending directly in an if condition
[Daniele]
-use xe_device instead of drm_i915_private [Daniele]

Signed-off-by: Suraj Kandpal 
---
  drivers/gpu/drm/i915/display/intel_hdcp_gsc.c |   4 +-
  .../gpu/drm/xe/abi/gsc_command_header_abi.h   |   2 +
  drivers/gpu/drm/xe/display/xe_hdcp_gsc.c  | 184 +-
  drivers/gpu/drm/xe/xe_gsc_submit.c|  19 ++
  drivers/gpu/drm/xe/xe_gsc_submit.h|   1 +
  5 files changed, 202 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c 
b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
index e44f60f00e8b..9e895f714f90 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c
@@ -123,8 +123,10 @@ static int intel_hdcp_gsc_hdcp2_init(struct 
drm_i915_private *i915)
i915->display.hdcp.hdcp_message = hdcp_message;
ret = intel_hdcp_gsc_initialize_message(i915, hdcp_message);
  
-	if (ret)

+   if (ret) {
drm_err(>drm, "Could not initialize hdcp_message\n");
+   kfree(hdcp_message);
+   }


AFAIU intel_hdcp_gsc.c is not used in Xe, so IMO you should send this 
change as an i915 patch.


  
  	return ret;

  }
diff --git a/drivers/gpu/drm/xe/abi/gsc_command_header_abi.h 
b/drivers/gpu/drm/xe/abi/gsc_command_header_abi.h
index a4c2646803b5..d2fbf71439be 100644
--- a/drivers/gpu/drm/xe/abi/gsc_command_header_abi.h
+++ b/drivers/gpu/drm/xe/abi/gsc_command_header_abi.h
@@ -21,6 +21,8 @@ struct intel_gsc_mtl_header {
  
  	/* FW allows host to decide host_session handle as it sees fit. */

u64 host_session_handle;
+#define HECI_MEADDRESS_PXP 17
+#define HECI_MEADDRESS_HDCP 18


This was purposely not defined here, and the PXP definition already 
exists in the separate header for the PXP stuff. The idea is that each 
client should have its own header with its own definitions.


  
  	/* handle generated by FW for messages that need to be re-submitted */

u64 gsc_message_handle;
diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c 
b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index ca17dfbc3fe9..d95c1b3b2d9c 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -3,11 +3,26 @@
   * Copyright 2023, Intel Corporation.
   */
  
-#include "i915_drv.h"

+#include 
+
+#include "abi/gsc_command_header_abi.h"
  #include "intel_hdcp_gsc.h"
  #include "xe_gt.h"
  #include "xe_gsc_proxy.h"
  #include "xe_pm.h"
+#include "xe_bo.h"
+#include "xe_map.h"
+#include "xe_gsc_submit.h"
+
+#define HECI_MEADDRESS_HDCP 18
+
+struct intel_hdcp_gsc_message {
+   struct xe_bo *hdcp_bo;
+   u64 hdcp_cmd_in;
+   u64 hdcp_cmd_out;
+};
+
+#define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header)
  
  bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915)

  {
@@ -37,19 +52,174 @@ bool intel_hdcp_gsc_check_status(struct xe_device *xe)
return ret;
  }
  
-int intel_hdcp_gsc_init(struct drm_i915_private *i915)

+/*This function helps allocate memory for the command that we will send to gsc 
cs */
+static int intel_hdcp_gsc_initialize_message(struct xe_device *xe,
+struct intel_hdcp_gsc_message 
*hdcp_message)
+{
+   struct xe_bo *bo = NULL;
+   u64 cmd_in, cmd_out;
+   int err, ret = 0;
+
+   /* allocate object of two page for HDCP command memory and store it */
+   xe_device_mem_access_get(xe);
+   bo = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe), NULL, 
PAGE_SIZE * 2,
+ ttm_bo_type_kernel,
+ XE_BO_CREATE_SYSTEM_BIT |
+ XE_BO_CREATE_GGTT_BIT);
+
+   if (IS_ERR(bo)) {
+   drm_err(>drm, "Failed to allocate bo for HDCP streaming 
command!\n");
+   ret = err;


err is unset here.


+   goto out;
+   }
+
+   cmd_in = xe_bo_ggtt_addr(bo);
+   cmd_out = cmd_in + PAGE_SIZE;
+   xe_map_memset(xe, >vmap, 0, 0, bo->size);
+
+   hdcp_message->hdcp_bo = bo;
+   hdcp_message->hdcp_cmd_in = cmd_in;
+   hdcp_message->hdcp_cmd_out = cmd_out;
+out:
+   xe_device_mem_access_put(xe);
+   return ret;
+}
+
+static int intel_hdcp_gsc_hdcp2_init(struct xe_device *xe)
+{
+   struct intel_hdcp_gsc_message *hdcp_message;
+   int ret;
+
+   hdcp_message = kzalloc(sizeof(*hdcp_message), GFP_KERNEL);
+
+   if (!hdcp_message)
+   return -ENOMEM;
+
+ 

Re: [PATCH 2/4] drm/xe: Use gsc_proxy_init_done to check proxy status

2024-02-08 Thread Daniele Ceraolo Spurio




On 2/7/2024 3:35 AM, Suraj Kandpal wrote:

Expose gsc_proxy_init_done so that we can check if gsc proxy has
been initialized or not.

Signed-off-by: Suraj Kandpal 
---
  drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 25 ++--
  drivers/gpu/drm/xe/xe_gsc_proxy.c|  2 +-
  drivers/gpu/drm/xe/xe_gsc_proxy.h|  1 +
  3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c 
b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index 0f11a39333e2..ca17dfbc3fe9 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -5,15 +5,36 @@
  
  #include "i915_drv.h"

  #include "intel_hdcp_gsc.h"
+#include "xe_gt.h"
+#include "xe_gsc_proxy.h"
+#include "xe_pm.h"
  
  bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915)

  {
return true;
  }
  
-bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915)

+bool intel_hdcp_gsc_check_status(struct xe_device *xe)


I think it'd be nice to have a prep patch to convert all the 
drm_i915_private in this file to xe_device and drop i915_drv.h, so we 
don't have the changes sprinkled through the patches.



  {
-   return false;
+   struct xe_tile *tile = xe_device_get_root_tile(xe);
+   struct xe_gt *gt = tile->media_gt;
+   int ret = true;


why are you initializing this integer to true?


+
+   xe_pm_runtime_get(xe);
+   ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GSC);
+   if (ret) {
+   drm_dbg_kms(>drm, "failed to get forcewake to disable GSC 
interrupts\n");


incorrect message, this has nothing to do with interrupts.


+   return false;
+   }
+
+   if (!gsc_proxy_init_done(>uc.gsc))
+   ret = false;
+
+   if (!ret)
+   xe_force_wake_put(gt_to_fw(gt), XE_FW_GSC);


Why is this conditional on !ret? you can't reach here if the _get fails 
and also you overwrite ret in the if above, so you can't use it as a 
condition here. This looks like it should just be an unconditional put.



+   xe_pm_runtime_get(xe);


this should be a put


+
+   return ret;
  }
  
  int intel_hdcp_gsc_init(struct drm_i915_private *i915)

diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.c 
b/drivers/gpu/drm/xe/xe_gsc_proxy.c
index 309ef80e3b95..f37f18a36209 100644
--- a/drivers/gpu/drm/xe/xe_gsc_proxy.c
+++ b/drivers/gpu/drm/xe/xe_gsc_proxy.c
@@ -66,7 +66,7 @@ static inline struct xe_device *kdev_to_xe(struct device 
*kdev)
return dev_get_drvdata(kdev);
  }
  
-static bool gsc_proxy_init_done(struct xe_gsc *gsc)

+bool gsc_proxy_init_done(struct xe_gsc *gsc)


this needs an xe_ prefix now that it is exposed.

Daniele


  {
struct xe_gt *gt = gsc_to_gt(gsc);
u32 fwsts1 = xe_mmio_read32(gt, HECI_FWSTS1(MTL_GSC_HECI1_BASE));
diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.h 
b/drivers/gpu/drm/xe/xe_gsc_proxy.h
index 908f9441f093..10de5359fbb8 100644
--- a/drivers/gpu/drm/xe/xe_gsc_proxy.h
+++ b/drivers/gpu/drm/xe/xe_gsc_proxy.h
@@ -11,6 +11,7 @@
  struct xe_gsc;
  
  int xe_gsc_proxy_init(struct xe_gsc *gsc);

+bool gsc_proxy_init_done(struct xe_gsc *gsc);
  void xe_gsc_proxy_remove(struct xe_gsc *gsc);
  int xe_gsc_proxy_start(struct xe_gsc *gsc);
  




Re: [PATCH 2/3] drm/xe/hdcp: Enable HDCP for XE

2024-02-06 Thread Daniele Ceraolo Spurio




On 2/6/2024 8:24 AM, Kandpal, Suraj wrote:

Subject: Re: [PATCH 2/3] drm/xe/hdcp: Enable HDCP for XE



On 2/2/2024 12:37 AM, Suraj Kandpal wrote:

Enable HDCP for Xe by defining functions which take care of
interaction of HDCP as a client with the GSC CS interface.

Signed-off-by: Suraj Kandpal 
---
   drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 188

++-

   1 file changed, 184 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index 0f11a39333e2..eca941d7b281 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -3,8 +3,24 @@
* Copyright 2023, Intel Corporation.
*/

+#include "abi/gsc_command_header_abi.h"

My original idea was for the users to not include this header and rely on the
size provided by the emit functions. I see you use the check the input size,
which I didn't do on the proxy side because the buffer is sized to be big
enough for all possible commands. Overall not a blocker, just consider the
option.


   #include "i915_drv.h"

Do you actually need i915_drv.h? You shouldn't be using any structure from
i915 here. If you just need it for the pointers to struct drm_i915_private, just
add a forward declaration for the structure.


Right


   #include "intel_hdcp_gsc.h"
+#include "xe_bo.h"
+#include "xe_map.h"
+#include "xe_gsc_submit.h"
+
+#define HECI_MEADDRESS_HDCP 18
+
+struct intel_hdcp_gsc_message {
+   struct xe_bo *hdcp_bo;
+   u64 hdcp_cmd_in;
+   u64 hdcp_cmd_out;
+};
+
+#define HOST_SESSION_CLIENT_MASK GENMASK_ULL(63, 56) #define
+HDCP_GSC_MESSAGE_SIZE sizeof(struct intel_hdcp_gsc_message)

this define is unused. Also, intel_hdcp_gsc_message is not the actual
message, but just contains a pointer to the object that holds the message.


True will get rid of it


+#define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header)

   bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915)
   {
@@ -13,22 +29,186 @@ bool intel_hdcp_gsc_cs_required(struct
drm_i915_private *i915)

   bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915)
   {
-   return false;
+   return true;

Shouldn't you actually do a check in here?

Not sure which function would check if gsc and gsc proxy is loaded or not
Any idea?


gsc_proxy_init_done() in xe_gsc_proxy.c . It's not exposed right now 
because there was no user outside of the file.


Note that, differently from i915, Xe is very explicit with pm and 
forcewake management, so you'll have to take both a pm and a forcewake 
ref before calling that function.






+}
+
+/*This function helps allocate memory for the command that we will
+send to gsc cs */ static int intel_hdcp_gsc_initialize_message(struct
+drm_i915_private *i915,

Having a drm_i915_private here that is actually an xe_device is really weird. I
understand that the aim is to re-use most of the display code from i915, but if
you need to different back-ends maybe just have the function accept a void
pointer and then internally cast it to drm_i915_private or xe_device based on
the driver, or use struct intel_display and cast it back to i915 or Xe with a
container_of. I'll leave the final comment on this to someone that has more
understanding than me of what's going on on the display side of things.


I understand it looks weird but display code seems to be following this 
convention for now
till a decision is made on how display code redundancy is removed maybe Ankit 
can further
back this design or comment on it.


+struct intel_hdcp_gsc_message

*hdcp_message) {

+   struct xe_bo *bo = NULL;
+   u64 cmd_in, cmd_out;
+   int err, ret = 0;
+
+   /* allocate object of two page for HDCP command memory and store

it

+*/
+
+   xe_device_mem_access_get(i915);
+   bo = xe_bo_create_pin_map(i915, xe_device_get_root_tile(i915),

NULL, PAGE_SIZE * 2,

+ ttm_bo_type_kernel,
+ XE_BO_CREATE_SYSTEM_BIT |
+ XE_BO_CREATE_GGTT_BIT);
+
+   if (IS_ERR(bo)) {
+   drm_err(>drm, "Failed to allocate bo for HDCP

streaming command!\n");

+   ret = err;
+   goto out;
+   }
+
+   cmd_in = xe_bo_ggtt_addr(bo);
+
+   if (iosys_map_is_null(>vmap)) {

this can't happen, if the bo fails to map then xe_bo_create_pin_map will
return an error.


  Ok got it


+   drm_err(>drm, "Failed to map gsc message page!\n");
+   ret = PTR_ERR(>vmap);
+   goto out;
+   }
+
+   cmd_out = cmd_in + PAGE_SIZE;
+
+   xe_map_memset(i915, >vmap, 0, 0, bo->size);
+
+   hdcp_message->hdcp_bo = bo;
+   hdcp_message->hdcp_cmd_in = cmd_in;
+   hdcp_message->hdcp_cmd_out = cmd_out;
+out:
+   xe_device_mem_access_put(i915);
+   return ret;
+}
+
+static int 

Re: [PATCH 2/3] drm/xe/hdcp: Enable HDCP for XE

2024-02-05 Thread Daniele Ceraolo Spurio




On 2/2/2024 12:37 AM, Suraj Kandpal wrote:

Enable HDCP for Xe by defining functions which take care of
interaction of HDCP as a client with the GSC CS interface.

Signed-off-by: Suraj Kandpal 
---
  drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 188 ++-
  1 file changed, 184 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c 
b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index 0f11a39333e2..eca941d7b281 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -3,8 +3,24 @@
   * Copyright 2023, Intel Corporation.
   */
  
+#include "abi/gsc_command_header_abi.h"


My original idea was for the users to not include this header and rely 
on the size provided by the emit functions. I see you use the check the 
input size, which I didn't do on the proxy side because the buffer is 
sized to be big enough for all possible commands. Overall not a blocker, 
just consider the option.



  #include "i915_drv.h"


Do you actually need i915_drv.h? You shouldn't be using any structure 
from i915 here. If you just need it for the pointers to struct 
drm_i915_private, just add a forward declaration for the structure.



  #include "intel_hdcp_gsc.h"
+#include "xe_bo.h"
+#include "xe_map.h"
+#include "xe_gsc_submit.h"
+
+#define HECI_MEADDRESS_HDCP 18
+
+struct intel_hdcp_gsc_message {
+   struct xe_bo *hdcp_bo;
+   u64 hdcp_cmd_in;
+   u64 hdcp_cmd_out;
+};
+
+#define HOST_SESSION_CLIENT_MASK GENMASK_ULL(63, 56)
+#define HDCP_GSC_MESSAGE_SIZE sizeof(struct intel_hdcp_gsc_message)


this define is unused. Also, intel_hdcp_gsc_message is not the actual 
message, but just contains a pointer to the object that holds the message.



+#define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header)
  
  bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915)

  {
@@ -13,22 +29,186 @@ bool intel_hdcp_gsc_cs_required(struct drm_i915_private 
*i915)
  
  bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915)

  {
-   return false;
+   return true;


Shouldn't you actually do a check in here?


+}
+
+/*This function helps allocate memory for the command that we will send to gsc 
cs */
+static int intel_hdcp_gsc_initialize_message(struct drm_i915_private *i915,


Having a drm_i915_private here that is actually an xe_device is really 
weird. I understand that the aim is to re-use most of the display code 
from i915, but if you need to different back-ends maybe just have the 
function accept a void pointer and then internally cast it to 
drm_i915_private or xe_device based on the driver, or use struct 
intel_display and cast it back to i915 or Xe with a container_of. I'll 
leave the final comment on this to someone that has more understanding 
than me of what's going on on the display side of things.



+struct intel_hdcp_gsc_message 
*hdcp_message)
+{
+   struct xe_bo *bo = NULL;
+   u64 cmd_in, cmd_out;
+   int err, ret = 0;
+
+   /* allocate object of two page for HDCP command memory and store it */
+
+   xe_device_mem_access_get(i915);
+   bo = xe_bo_create_pin_map(i915, xe_device_get_root_tile(i915), NULL, 
PAGE_SIZE * 2,
+ ttm_bo_type_kernel,
+ XE_BO_CREATE_SYSTEM_BIT |
+ XE_BO_CREATE_GGTT_BIT);
+
+   if (IS_ERR(bo)) {
+   drm_err(>drm, "Failed to allocate bo for HDCP streaming 
command!\n");
+   ret = err;
+   goto out;
+   }
+
+   cmd_in = xe_bo_ggtt_addr(bo);
+
+   if (iosys_map_is_null(>vmap)) {


this can't happen, if the bo fails to map then xe_bo_create_pin_map will 
return an error.



+   drm_err(>drm, "Failed to map gsc message page!\n");
+   ret = PTR_ERR(>vmap);
+   goto out;
+   }
+
+   cmd_out = cmd_in + PAGE_SIZE;
+
+   xe_map_memset(i915, >vmap, 0, 0, bo->size);
+
+   hdcp_message->hdcp_bo = bo;
+   hdcp_message->hdcp_cmd_in = cmd_in;
+   hdcp_message->hdcp_cmd_out = cmd_out;
+out:
+   xe_device_mem_access_put(i915);
+   return ret;
+}
+
+static int intel_hdcp_gsc_hdcp2_init(struct drm_i915_private *i915)
+{
+   struct intel_hdcp_gsc_message *hdcp_message;
+   int ret;
+
+   hdcp_message = kzalloc(sizeof(*hdcp_message), GFP_KERNEL);
+
+   if (!hdcp_message)
+   return -ENOMEM;
+
+   /*
+* NOTE: No need to lock the comp mutex here as it is already
+* going to be taken before this function called
+*/
+   i915->display.hdcp.hdcp_message = hdcp_message;
+   ret = intel_hdcp_gsc_initialize_message(i915, hdcp_message);
+
+   if (ret)
+   drm_err(>drm, "Could not initialize hdcp_message\n");


Don't you need a kfree in this error path? alternatively you can use 
drmm_kzalloc so that it is always automatically freed.



+
+   

Re: [PATCH] drm/i915/huc: Allow for very slow HuC loading

2024-01-04 Thread Daniele Ceraolo Spurio
 a problem. Note that the only reason
+ * an end user should hit the timeout is in case of extreme thermal throttling.
+ * And a system that is that hot during boot is probably dead anyway!
+ */
+#if defined(CONFIG_DRM_I915_DEBUG_GEM)
+#define HUC_LOAD_RETRY_LIMIT   20
+#else
+#define HUC_LOAD_RETRY_LIMIT   3
+#endif
+
  int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
 enum intel_huc_authentication_type type)
  {
struct intel_gt *gt = huc_to_gt(huc);
-   int ret;
+   struct intel_uncore *uncore = gt->uncore;
+   ktime_t before, after, delta;
+   int ret, count;
+   u64 delta_ms;
+   u32 before_freq;
  
-	ret = __intel_wait_for_register(gt->uncore,

-   huc->status[type].reg,
-   huc->status[type].mask,
-   huc->status[type].value,
-   2, 50, NULL);
+   /*
+* The KMD requests maximum frequency during driver load, however 
thermal
+* throttling can force the frequency down to minimum (although the 
board
+* really should never get that hot in real life!). IFWI  issues have 
been
+* seen to cause sporadic failures to grant the higher frequency. And at
+    * minimum frequency, the load time can be in the seconds range. Note 
that


this is not load time but auth time. With this fixed (when applying is 
fine):


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+* there is a limit on how long an individual wait_for() can wait. So 
wrap
+* it in a loop.
+*/
+   before_freq = intel_rps_read_actual_frequency(>rps);
+   before = ktime_get();
+   for (count = 0; count < HUC_LOAD_RETRY_LIMIT; count++) {
+   ret = __intel_wait_for_register(gt->uncore,
+   huc->status[type].reg,
+   huc->status[type].mask,
+   huc->status[type].value,
+   2, 1000, NULL);
+   if (!ret)
+   break;
+
+   huc_dbg(huc, "auth still in progress, count = %d, freq = %dMHz, 
status = 0x%08X\n",
+   count, intel_rps_read_actual_frequency(>rps),
+   huc->status[type].reg.reg);
+   }
+   after = ktime_get();
+   delta = ktime_sub(after, before);
+   delta_ms = ktime_to_ms(delta);
+
+   if (delta_ms > 50) {
+   huc_warn(huc, "excessive auth time: %lldms! [status = 0x%08X, count 
= %d, ret = %d]\n",
+delta_ms, huc->status[type].reg.reg, count, ret);
+   huc_warn(huc, "excessive auth time: [freq = %dMHz, before = %dMHz, 
perf_limit_reasons = 0x%08X]\n",
+intel_rps_read_actual_frequency(>rps), before_freq,
+intel_uncore_read(uncore, 
intel_gt_perf_limit_reasons_reg(gt)));
+   } else {
+   huc_dbg(huc, "auth took %lldms, freq = %dMHz, before = %dMHz, status 
= 0x%08X, count = %d, ret = %d\n",
+   delta_ms, intel_rps_read_actual_frequency(>rps),
+   before_freq, huc->status[type].reg.reg, count, ret);
+   }
  
  	/* mark the load process as complete even if the wait failed */

delayed_huc_load_complete(huc);




Re: [Intel-gfx] [PATCH v7 2/2] drm/i915/guc: Close deregister-context race against CT-loss

2023-12-06 Thread Daniele Ceraolo Spurio




On 11/30/2023 4:10 PM, Teres Alexis, Alan Previn wrote:

As far as i can tell, its only if we started resetting / wedging right after 
this
queued worker got started.

alan: hope Daniele can proof read my tracing and confirm if got it right.


Yup, we don't flush the worker in reset prepare, so there is a chance 
that it might run parallel to the reset/wedge code, which we handle by 
checking the submission status. The list manipulation is protected by 
spinlock so we're safe on that side. The rest of the approach also LGTM:


Acked-by: Daniele Ceraolo Spurio 

Daniele


Re: [Intel-gfx] [PATCH 2/2] drm/i915: Use internal class when counting engine resets

2023-12-05 Thread Daniele Ceraolo Spurio




On 12/1/2023 4:21 AM, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

Commit 503579448db9 ("drm/i915/gsc: Mark internal GSC engine with reserved uabi 
class")
made the GSC0 engine not have a valid uabi class and so broke the engine
reset counting, which in turn was made class based in cb823ed9915b ("drm/i915/gt: 
Use intel_gt as the primary object for handling resets").

Despite the title and commit text of the latter is not mentioning it (and
has left the storage array incorrectly sized), tracking by class, despite
it adding aliasing in hypthotetical multi-tile systems, is handy for
virtual engines which for instance do not have a valid engine->id.

Therefore we keep that but just change it to use the internal class which
is always valid. We also add a helper to increment the count, which
aligns with the existing getter.

What was broken without this fix were out of bounds reads every time a
reset would happen on the GSC0 engine, or during selftests when storing
and cross-checking the counts in igt_live_test_begin and
igt_live_test_end.

Signed-off-by: Tvrtko Ursulin 
Fixes: 503579448db9 ("drm/i915/gsc: Mark internal GSC engine with reserved uabi 
class")
Reported-by: Alan Previn Teres Alexis 
Cc: Daniele Ceraolo Spurio 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/intel_reset.c |  2 +-
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c |  5 +++--
  drivers/gpu/drm/i915/i915_gpu_error.h | 12 ++--
  3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c 
b/drivers/gpu/drm/i915/gt/intel_reset.c
index d5ed904f355d..6801f8b95c53 100644
--- a/drivers/gpu/drm/i915/gt/intel_reset.c
+++ b/drivers/gpu/drm/i915/gt/intel_reset.c
@@ -1293,7 +1293,7 @@ int __intel_engine_reset_bh(struct intel_engine_cs 
*engine, const char *msg)
if (msg)
drm_notice(>i915->drm,
   "Resetting %s for %s\n", engine->name, msg);
-   
atomic_inc(>i915->gpu_error.reset_engine_count[engine->uabi_class]);
+   i915_increase_reset_engine_count(>i915->gpu_error, engine);
  
  	ret = intel_gt_reset_engine(engine);

if (ret) {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 04f8377fd7a3..58ea285c51d4 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -5003,7 +5003,8 @@ static void capture_error_state(struct intel_guc *guc,
if (match) {
intel_engine_set_hung_context(e, ce);
engine_mask |= e->mask;
-   
atomic_inc(>gpu_error.reset_engine_count[e->uabi_class]);
+   
i915_increase_reset_engine_count(>gpu_error,
+e);
}
}
  
@@ -5015,7 +5016,7 @@ static void capture_error_state(struct intel_guc *guc,

} else {
intel_engine_set_hung_context(ce->engine, ce);
engine_mask = ce->engine->mask;
-   
atomic_inc(>gpu_error.reset_engine_count[ce->engine->uabi_class]);
+   i915_increase_reset_engine_count(>gpu_error, ce->engine);
}
  
  	with_intel_runtime_pm(>runtime_pm, wakeref)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h 
b/drivers/gpu/drm/i915/i915_gpu_error.h
index fa886620d3f8..7c255bb1c319 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.h
+++ b/drivers/gpu/drm/i915/i915_gpu_error.h
@@ -17,6 +17,7 @@
  #include "display/intel_display_device.h"
  #include "display/intel_display_params.h"
  #include "gt/intel_engine.h"
+#include "gt/intel_engine_types.h"
  #include "gt/intel_gt_types.h"
  #include "gt/uc/intel_uc_fw.h"
  
@@ -234,7 +235,7 @@ struct i915_gpu_error {

atomic_t reset_count;
  
  	/** Number of times an engine has been reset */

-   atomic_t reset_engine_count[I915_NUM_ENGINES];
+   atomic_t reset_engine_count[MAX_ENGINE_CLASS];
  };
  
  struct drm_i915_error_state_buf {

@@ -257,7 +258,14 @@ static inline u32 i915_reset_count(struct i915_gpu_error 
*error)
  static inline u32 i915_reset_engine_count(struct i915_gpu_error *error,
  const struct intel_engine_cs *engine)
  {
-   return atomic_read(>reset_engine_count[engine->uabi_class]);
+   return atomic_read(>reset_engine_count[engine->class]);
+}
+
+static inline void
+i915_increase_reset_engine_count(struct i915_gpu_error *error,
+const struct intel_engine_cs *engine)
+{
+   atomic_inc(>reset_engine_count[engine->class]);
  }
  
  #define CORE_DUMP_FLAG_NONE   0x0




Re: [Intel-gfx] [PATCH v2 2/2] drm/i915/guc: Add a selftest for FAST_REQUEST errors

2023-11-29 Thread Daniele Ceraolo Spurio




On 11/13/2023 5:00 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

There is a mechanism for reporting errors from fire and forget H2G
messages. This is the only way to find out about almost any error in
the GuC backend submission path. So it would be useful to know that it
is working.

v2: Fix some dumb over-complications and a couple of typos - review
feedback from Daniele.

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_guc.h|   4 +
  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   9 ++
  drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 115 ++
  3 files changed, 128 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 2b6dfe62c8f2a..e22c12ce245ad 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -297,6 +297,10 @@ struct intel_guc {
 * @number_guc_id_stolen: The number of guc_ids that have been stolen
 */
int number_guc_id_stolen;
+   /**
+* @fast_response_selftest: Backdoor to CT handler for fast response 
selftest
+*/
+   u32 fast_response_selftest;
  #endif
  };
  
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c

index 89e314b3756bb..ed6ce73ef3b07 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -1076,6 +1076,15 @@ static int ct_handle_response(struct intel_guc_ct *ct, 
struct ct_incoming_msg *r
found = true;
break;
}
+
+#ifdef CONFIG_DRM_I915_SELFTEST
+   if (!found && ct_to_guc(ct)->fast_response_selftest) {
+   CT_DEBUG(ct, "Assuming unsolicited response due to FAST_REQUEST 
selftest\n");
+   ct_to_guc(ct)->fast_response_selftest++;
+   found = true;
+   }
+#endif
+
if (!found) {
CT_ERROR(ct, "Unsolicited response message: len %u, data %#x (fence 
%u, last %u)\n",
 len, hxg[0], fence, ct->requests.last_fence);
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
index bfb72143566f6..c900aac85adba 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
@@ -286,11 +286,126 @@ static int intel_guc_steal_guc_ids(void *arg)
return ret;
  }
  
+/*

+ * Send a context schedule H2G message with an invalid context id.
+ * This should generate a GUC_RESULT_INVALID_CONTEXT response.
+ */
+static int bad_h2g(struct intel_guc *guc)
+{
+   u32 action[] = {
+  INTEL_GUC_ACTION_SCHED_CONTEXT,
+  0x12345678,
+   };
+
+   return intel_guc_send_nb(guc, action, ARRAY_SIZE(action), 0);
+}
+
+/*
+ * Set a spinner running to make sure the system is alive and active,
+ * then send a bad but asynchronous H2G command and wait to see if an
+ * error response is returned. If no response is received or if the
+ * spinner dies then the test will fail.
+ */
+#define FAST_RESPONSE_TIMEOUT_MS   1000
+static int intel_guc_fast_request(void *arg)
+{
+   struct intel_gt *gt = arg;
+   struct intel_context *ce;
+   struct igt_spinner spin;
+   struct i915_request *rq;
+   intel_wakeref_t wakeref;
+   struct intel_engine_cs *engine = intel_selftest_find_any_engine(gt);
+   bool spinning = false;
+   int ret = 0;
+
+   if (!engine)
+   return 0;
+
+   wakeref = intel_runtime_pm_get(gt->uncore->rpm);
+
+   ce = intel_context_create(engine);
+   if (IS_ERR(ce)) {
+   ret = PTR_ERR(ce);
+   gt_err(gt, "Failed to create spinner request: %pe\n", ce);
+   goto err_pm;
+   }
+
+   ret = igt_spinner_init(, engine->gt);
+   if (ret) {
+   gt_err(gt, "Failed to create spinner: %pe\n", ERR_PTR(ret));
+   goto err_pm;
+   }
+   spinning = true;
+
+   rq = igt_spinner_create_request(, ce, MI_ARB_CHECK);
+   intel_context_put(ce);
+   if (IS_ERR(rq)) {
+   ret = PTR_ERR(rq);
+   gt_err(gt, "Failed to create spinner request: %pe\n", rq);
+   goto err_spin;
+   }
+
+   ret = request_add_spin(rq, );
+   if (ret) {
+   gt_err(gt, "Failed to add Spinner request: %pe\n", 
ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   gt->uc.guc.fast_response_selftest = 1;
+
+   ret = bad_h2g(>uc.guc);
+   if (ret) {
+   gt_err(gt, "Failed to send H2G: %pe\n", ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   ret = wait_for(gt->uc.guc.fast_response_selftest != 1 || 
i915_request_completed(rq),
+  FAST_RESPONSE_TIMEOUT_MS);
+   if (r

Re: [Intel-gfx] [PATCH v2] drm/i915/gsc: Mark internal GSC engine with reserved uabi class

2023-11-17 Thread Daniele Ceraolo Spurio




On 11/16/2023 12:44 AM, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

The GSC CS is not exposed to the user, so we skipped assigning a uabi
class number for it. However, the trace logs use the uabi class and
instance to identify the engine, so leaving uabi class unset makes the
GSC CS show up as the RCS in those logs.

Given that the engine is not exposed to the user, we can't add a new
case in the uabi enum, so we insted internally define a kernel
internal class as -1.

At the same time remove special handling for the name and complete
the uabi_classes array so internal class is automatically correctly
assigned.

Engine will show as 65535:0 other0 in the logs/traces which should
be unique enough.

v2:
  * Fix uabi class u8 vs u16 type confusion.

Signed-off-by: Tvrtko Ursulin 
Fixes: 194babe26bdc ("drm/i915/mtl: don't expose GSC command streamer to the 
user")
Cc: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: Matt Roper 
Reviewed-by: Daniele Ceraolo Spurio  # v1


My r-b stands.

Thanks,
Daniele


---
  drivers/gpu/drm/i915/gt/intel_engine_user.c | 39 -
  1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c
index 118164ddbb2e..833987015b8b 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -41,12 +41,15 @@ void intel_engine_add_user(struct intel_engine_cs *engine)
llist_add(>uabi_llist, >i915->uabi_engines_llist);
  }
  
-static const u8 uabi_classes[] = {

+#define I915_NO_UABI_CLASS ((u16)(-1))
+
+static const u16 uabi_classes[] = {
[RENDER_CLASS] = I915_ENGINE_CLASS_RENDER,
[COPY_ENGINE_CLASS] = I915_ENGINE_CLASS_COPY,
[VIDEO_DECODE_CLASS] = I915_ENGINE_CLASS_VIDEO,
[VIDEO_ENHANCEMENT_CLASS] = I915_ENGINE_CLASS_VIDEO_ENHANCE,
[COMPUTE_CLASS] = I915_ENGINE_CLASS_COMPUTE,
+   [OTHER_CLASS] = I915_NO_UABI_CLASS, /* Not exposed to users, no uabi 
class. */
  };
  
  static int engine_cmp(void *priv, const struct list_head *A,

@@ -200,6 +203,7 @@ static void engine_rename(struct intel_engine_cs *engine, 
const char *name, u16
  
  void intel_engines_driver_register(struct drm_i915_private *i915)

  {
+   u16 name_instance, other_instance = 0;
struct legacy_ring ring = {};
struct list_head *it, *next;
struct rb_node **p, *prev;
@@ -216,27 +220,28 @@ void intel_engines_driver_register(struct 
drm_i915_private *i915)
if (intel_gt_has_unrecoverable_error(engine->gt))
continue; /* ignore incomplete engines */
  
-		/*

-* We don't want to expose the GSC engine to the users, but we
-* still rename it so it is easier to identify in the debug logs
-*/
-   if (engine->id == GSC0) {
-   engine_rename(engine, "gsc", 0);
-   continue;
-   }
-
GEM_BUG_ON(engine->class >= ARRAY_SIZE(uabi_classes));
engine->uabi_class = uabi_classes[engine->class];
+   if (engine->uabi_class == I915_NO_UABI_CLASS) {
+   name_instance = other_instance++;
+   } else {
+   GEM_BUG_ON(engine->uabi_class >=
+  ARRAY_SIZE(i915->engine_uabi_class_count));
+   name_instance =
+   
i915->engine_uabi_class_count[engine->uabi_class]++;
+   }
+   engine->uabi_instance = name_instance;
  
-		GEM_BUG_ON(engine->uabi_class >=

-  ARRAY_SIZE(i915->engine_uabi_class_count));
-   engine->uabi_instance =
-   i915->engine_uabi_class_count[engine->uabi_class]++;
-
-   /* Replace the internal name with the final user facing name */
+   /*
+* Replace the internal name with the final user and log facing
+* name.
+*/
engine_rename(engine,
  intel_engine_class_repr(engine->class),
- engine->uabi_instance);
+ name_instance);
+
+   if (engine->uabi_class == I915_NO_UABI_CLASS)
+   continue;
  
  		rb_link_node(>uabi_node, prev, p);

rb_insert_color(>uabi_node, >uabi_engines);




Re: [Intel-gfx] [PATCH 1/2] drm/i915/guc: Don't double enable a context

2023-11-15 Thread Daniele Ceraolo Spurio




On 11/9/2023 4:54 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

If a context is blocked, unblocked and subitted repeatedly in rapid
succession, the driver can end up trying to enable the context while
the previous enable request is still in flight. This can lead to much
confusion in the state tracking.

Prevent that by checking the pending enable flag before trying to
enable a context.

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index d37698bd6b91a..d399e4d238c10 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -720,7 +720,7 @@ static int __guc_add_request(struct intel_guc *guc, struct 
i915_request *rq)
if (unlikely(context_blocked(ce) && !intel_context_is_parent(ce)))
goto out;
  
-	enabled = context_enabled(ce) || context_blocked(ce);

+   enabled = context_enabled(ce) || context_blocked(ce) || 
context_pending_enable(ce);
  
  	if (!enabled) {

action[len++] = INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_SET;




Re: [Intel-gfx] [PATCH] drm/i915/gsc: Mark internal GSC engine with reserved uabi class

2023-11-15 Thread Daniele Ceraolo Spurio




On 11/15/2023 3:02 AM, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

The GSC CS is not exposed to the user, so we skipped assigning a uabi
class number for it. However, the trace logs use the uabi class and
instance to identify the engine, so leaving uabi class unset makes the
GSC CS show up as the RCS in those logs.

Given that the engine is not exposed to the user, we can't add a new
case in the uabi enum, so we insted internally define a kernel
internal class as -1.

At the same time remove special handling for the name and complete
the uabi_classes array so internal class is automatically correctly
assigned.

Engine will show as 65535:0 other0 in the logs/traces which should
be unique enough.

Signed-off-by: Tvrtko Ursulin 
Fixes: 194babe26bdc ("drm/i915/mtl: don't expose GSC command streamer to the 
user")
Cc: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: Matt Roper 
---
Daniele I borrowed most of your commit text as is, hope you don't mind but
I was lazy. See if you like this solution. It is also untested so lets see.


I'm ok with this approach. As you said the naming is unique so we can 
easily identify the engine. I've tested this locally with a small change 
(see below) and I see the expected values in the logs.



---
  drivers/gpu/drm/i915/gt/intel_engine_user.c | 37 -
  1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c
index 118164ddbb2e..7693ccfac1f9 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -41,12 +41,15 @@ void intel_engine_add_user(struct intel_engine_cs *engine)
llist_add(>uabi_llist, >i915->uabi_engines_llist);
  }
  
+#define I915_NO_UABI_CLASS (-1)


I see the lkp is complaining about using this for comparison against a 
u16. When I locally tried to reduce this to u16 my compiler also 
complained that we're assigning it to a u8 in the uabi_classes array, so 
I've just set I915_NO_UABI_CLASS directly to 255 and it all worked as 
expected. With that fix, or an alternative change to work with all the 
involved types:


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


+
  static const u8 uabi_classes[] = {
[RENDER_CLASS] = I915_ENGINE_CLASS_RENDER,
[COPY_ENGINE_CLASS] = I915_ENGINE_CLASS_COPY,
[VIDEO_DECODE_CLASS] = I915_ENGINE_CLASS_VIDEO,
[VIDEO_ENHANCEMENT_CLASS] = I915_ENGINE_CLASS_VIDEO_ENHANCE,
[COMPUTE_CLASS] = I915_ENGINE_CLASS_COMPUTE,
+   [OTHER_CLASS] = I915_NO_UABI_CLASS, /* Not exposed to users, no uabi 
class. */
  };
  
  static int engine_cmp(void *priv, const struct list_head *A,

@@ -200,6 +203,7 @@ static void engine_rename(struct intel_engine_cs *engine, 
const char *name, u16
  
  void intel_engines_driver_register(struct drm_i915_private *i915)

  {
+   u16 name_instance, other_instance = 0;
struct legacy_ring ring = {};
struct list_head *it, *next;
struct rb_node **p, *prev;
@@ -216,27 +220,28 @@ void intel_engines_driver_register(struct 
drm_i915_private *i915)
if (intel_gt_has_unrecoverable_error(engine->gt))
continue; /* ignore incomplete engines */
  
-		/*

-* We don't want to expose the GSC engine to the users, but we
-* still rename it so it is easier to identify in the debug logs
-*/
-   if (engine->id == GSC0) {
-   engine_rename(engine, "gsc", 0);
-   continue;
-   }
-
GEM_BUG_ON(engine->class >= ARRAY_SIZE(uabi_classes));
engine->uabi_class = uabi_classes[engine->class];
+   if (engine->uabi_class == I915_NO_UABI_CLASS) {
+   name_instance = other_instance++;
+   } else {
+   GEM_BUG_ON(engine->uabi_class >=
+  ARRAY_SIZE(i915->engine_uabi_class_count));
+   name_instance =
+   
i915->engine_uabi_class_count[engine->uabi_class]++;
+   }
+   engine->uabi_instance = name_instance;
  
-		GEM_BUG_ON(engine->uabi_class >=

-  ARRAY_SIZE(i915->engine_uabi_class_count));
-   engine->uabi_instance =
-   i915->engine_uabi_class_count[engine->uabi_class]++;
-
-   /* Replace the internal name with the final user facing name */
+   /*
+* Replace the internal name with the final user and log facing
+* name.
+*/
engine_rename(engine,
  intel_engine_class_repr(engine->class),
- engine->uabi_instance);
+ name_instance);
+
+ 

Re: [Intel-gfx] [PATCH] drm/i915/gsc: Assign a uabi class number to the GSC CS

2023-11-14 Thread Daniele Ceraolo Spurio




On 11/14/2023 9:20 AM, Tvrtko Ursulin wrote:


On 14/11/2023 17:03, Daniele Ceraolo Spurio wrote:

On 11/13/2023 8:46 AM, Tvrtko Ursulin wrote:

On 13/11/2023 15:51, Daniele Ceraolo Spurio wrote:

On 11/10/2023 4:00 AM, Tvrtko Ursulin wrote:


On 09/11/2023 23:53, Daniele Ceraolo Spurio wrote:
The GSC CS is not exposed to the user, so we skipped assigning a 
uabi

class number for it. However, the trace logs use the uabi class and
instance to identify the engine, so leaving uabi class unset 
makes the

GSC CS show up as the RCS in those logs.
Given that the engine is not exposed to the user, we can't add a new
case in the uabi enum, so we insted internally define a kernel
reserved class using the next free number.

Fixes: 194babe26bdc ("drm/i915/mtl: don't expose GSC command 
streamer to the user")
Signed-off-by: Daniele Ceraolo Spurio 


Cc: Tvrtko Ursulin 
Cc: Alan Previn 
Cc: Matt Roper 
---
  drivers/gpu/drm/i915/gt/intel_engine_user.c | 17 -
  drivers/gpu/drm/i915/gt/intel_engine_user.h |  4 
  drivers/gpu/drm/i915/i915_drm_client.h  |  2 +-
  drivers/gpu/drm/i915/i915_drv.h |  2 +-
  4 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c

index 118164ddbb2e..3fd32bedd6e7 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -47,6 +47,7 @@ static const u8 uabi_classes[] = {
  [VIDEO_DECODE_CLASS] = I915_ENGINE_CLASS_VIDEO,
  [VIDEO_ENHANCEMENT_CLASS] = I915_ENGINE_CLASS_VIDEO_ENHANCE,
  [COMPUTE_CLASS] = I915_ENGINE_CLASS_COMPUTE,
+    [OTHER_CLASS] = I915_KERNEL_RSVD_CLASS,


Could we set it to -1 (aka no uabi class) to avoid needing to 
maintain the new macros?


And then just teach intel_engines_driver_register to skip -1. 
Would also need teaching engine_rename to handle -1.


Might end up a smaller and more maintainable patch - worth a try 
do you think?


That was my initial idea as well, but the issue with this approach 
is the engine_uabi_class_count[] array, which is sized based on the 
number of uabi classes, so having class -1 would needlessly 
increase its size a lot even when using a u8. I thought about 
limiting the class entry to 3 


I was thinking the -1 entry wouldn't be in that array since -1 is 
not uabi class by its very definition. It is not reachable from the 
outside so no need to be there.


The issue there is that the array is used to assign uabi_instance, 
but I can hardcode that to 0 for now since we don't expect any new 
engines of that class. would that work for you?


My issue is that the starting position here is GSC engine has no uabi 
class, therefore it shouldn't have an uabi instance either, therefore 
the fact you cannot use the array called engine_*uabi*_class_count to 
assign it something which it shouldn't have, shouldn't be an argument. ;)


Agreed. The problem is that we use the uabi_class/instance for things 
that aren't strictly uabi (i.e. the traces) so we need to assign a value 
to those even if we don't need it for actual uabi purposes.





Otherwise I'll try the 3-bits thing and see how that looks.


3-bits.. I have to admit I don't know what you mean by that?


I was referring to limiting the uabi class index to 3 bits to limit the 
max array size to 8 and use -1 for the GSC uabi_class.




I can try to sketch out tomorrow what I have in mind. Lets go from 
there. I might fail and concede there is nothing to be gained by using 
a different approach.


sounds good.

Thanks,
Daniele



Regards,

Tvrtko



Daniele



bits so the array would max out at 8 entries, but that seemed to be 
getting a bit too convoluted. I can give it a go if you think it's 
be cleaner overall.


I had a feeling it would be, but without trying it out I won't claim 
100%.


Note that this patch does not introduce any new macros that would 
need to be maintained. I915_LAST_UABI_ENGINE_CLASS already existed 
(I just moved it from one file to another) and is the only one that 
changes when a new "real" uabi class is added; the other defines 
are based on this one. This also implies that if a new uabi class 
is added then I915_KERNEL_RSVD_CLASS would be bumped to the next 
free number, which would cause the GSC to show as a different uabi 
class in newer logs; considering that i915 is on its way out, a new 
class seems very unlikely so I thought it'd be an acceptable 
compromise to keep things simple.





  };
    static int engine_cmp(void *priv, const struct list_head *A,
@@ -138,7 +139,7 @@ const char *intel_engine_class_repr(u8 class)
  [COPY_ENGINE_CLASS] = "bcs",
  [VIDEO_DECODE_CLASS] = "vcs",
  [VIDEO_ENHANCEMENT_CLASS] = "vecs",
-    [OTHER_CLASS] = "other",
+    [OTHER_CLASS] = "gsc",


Maybe unrelated?


no. Before this patch, we hardcoded "gsc" b

Re: [Intel-gfx] [PATCH] drm/i915/gsc: Assign a uabi class number to the GSC CS

2023-11-14 Thread Daniele Ceraolo Spurio




On 11/13/2023 8:46 AM, Tvrtko Ursulin wrote:


On 13/11/2023 15:51, Daniele Ceraolo Spurio wrote:

On 11/10/2023 4:00 AM, Tvrtko Ursulin wrote:


On 09/11/2023 23:53, Daniele Ceraolo Spurio wrote:

The GSC CS is not exposed to the user, so we skipped assigning a uabi
class number for it. However, the trace logs use the uabi class and
instance to identify the engine, so leaving uabi class unset makes the
GSC CS show up as the RCS in those logs.
Given that the engine is not exposed to the user, we can't add a new
case in the uabi enum, so we insted internally define a kernel
reserved class using the next free number.

Fixes: 194babe26bdc ("drm/i915/mtl: don't expose GSC command 
streamer to the user")
Signed-off-by: Daniele Ceraolo Spurio 


Cc: Tvrtko Ursulin 
Cc: Alan Previn 
Cc: Matt Roper 
---
  drivers/gpu/drm/i915/gt/intel_engine_user.c | 17 -
  drivers/gpu/drm/i915/gt/intel_engine_user.h |  4 
  drivers/gpu/drm/i915/i915_drm_client.h  |  2 +-
  drivers/gpu/drm/i915/i915_drv.h |  2 +-
  4 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c

index 118164ddbb2e..3fd32bedd6e7 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -47,6 +47,7 @@ static const u8 uabi_classes[] = {
  [VIDEO_DECODE_CLASS] = I915_ENGINE_CLASS_VIDEO,
  [VIDEO_ENHANCEMENT_CLASS] = I915_ENGINE_CLASS_VIDEO_ENHANCE,
  [COMPUTE_CLASS] = I915_ENGINE_CLASS_COMPUTE,
+    [OTHER_CLASS] = I915_KERNEL_RSVD_CLASS,


Could we set it to -1 (aka no uabi class) to avoid needing to 
maintain the new macros?


And then just teach intel_engines_driver_register to skip -1. Would 
also need teaching engine_rename to handle -1.


Might end up a smaller and more maintainable patch - worth a try do 
you think?


That was my initial idea as well, but the issue with this approach is 
the engine_uabi_class_count[] array, which is sized based on the 
number of uabi classes, so having class -1 would needlessly increase 
its size a lot even when using a u8. I thought about limiting the 
class entry to 3 


I was thinking the -1 entry wouldn't be in that array since -1 is not 
uabi class by its very definition. It is not reachable from the 
outside so no need to be there.


The issue there is that the array is used to assign uabi_instance, but I 
can hardcode that to 0 for now since we don't expect any new engines of 
that class. would that work for you?

Otherwise I'll try the 3-bits thing and see how that looks.

Daniele



bits so the array would max out at 8 entries, but that seemed to be 
getting a bit too convoluted. I can give it a go if you think it's be 
cleaner overall.


I had a feeling it would be, but without trying it out I won't claim 
100%.


Note that this patch does not introduce any new macros that would 
need to be maintained. I915_LAST_UABI_ENGINE_CLASS already existed (I 
just moved it from one file to another) and is the only one that 
changes when a new "real" uabi class is added; the other defines are 
based on this one. This also implies that if a new uabi class is 
added then I915_KERNEL_RSVD_CLASS would be bumped to the next free 
number, which would cause the GSC to show as a different uabi class 
in newer logs; considering that i915 is on its way out, a new class 
seems very unlikely so I thought it'd be an acceptable compromise to 
keep things simple.





  };
    static int engine_cmp(void *priv, const struct list_head *A,
@@ -138,7 +139,7 @@ const char *intel_engine_class_repr(u8 class)
  [COPY_ENGINE_CLASS] = "bcs",
  [VIDEO_DECODE_CLASS] = "vcs",
  [VIDEO_ENHANCEMENT_CLASS] = "vecs",
-    [OTHER_CLASS] = "other",
+    [OTHER_CLASS] = "gsc",


Maybe unrelated?


no. Before this patch, we hardcoded "gsc" below when calling 
engine_rename() for it. With this patch, we use the name from this 
array, so it needs to be updated. The GEM_WARN_ON below was added to 
make sure we don't get different engines in OTHER_CLASS that might 
not match the "gsc" naming.


Ah okay, one special casing for another, a wash I guess.

Regards,

Tvrtko



Regards,

Tvrtko


  [COMPUTE_CLASS] = "ccs",
  };
  @@ -216,14 +217,8 @@ void intel_engines_driver_register(struct 
drm_i915_private *i915)

  if (intel_gt_has_unrecoverable_error(engine->gt))
  continue; /* ignore incomplete engines */
  -    /*
- * We don't want to expose the GSC engine to the users, 
but we
- * still rename it so it is easier to identify in the 
debug logs

- */
-    if (engine->id == GSC0) {
-    engine_rename(engine, "gsc", 0);
-    continue;
-    }
+    /* The only engine we expect in OTHER_CLASS is GSC0 */
+    GEM_WARN_ON(en

Re: [Intel-gfx] [PATCH] drm/i915/gsc: Assign a uabi class number to the GSC CS

2023-11-13 Thread Daniele Ceraolo Spurio




On 11/10/2023 4:00 AM, Tvrtko Ursulin wrote:


On 09/11/2023 23:53, Daniele Ceraolo Spurio wrote:

The GSC CS is not exposed to the user, so we skipped assigning a uabi
class number for it. However, the trace logs use the uabi class and
instance to identify the engine, so leaving uabi class unset makes the
GSC CS show up as the RCS in those logs.
Given that the engine is not exposed to the user, we can't add a new
case in the uabi enum, so we insted internally define a kernel
reserved class using the next free number.

Fixes: 194babe26bdc ("drm/i915/mtl: don't expose GSC command streamer 
to the user")

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Tvrtko Ursulin 
Cc: Alan Previn 
Cc: Matt Roper 
---
  drivers/gpu/drm/i915/gt/intel_engine_user.c | 17 -
  drivers/gpu/drm/i915/gt/intel_engine_user.h |  4 
  drivers/gpu/drm/i915/i915_drm_client.h  |  2 +-
  drivers/gpu/drm/i915/i915_drv.h |  2 +-
  4 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c

index 118164ddbb2e..3fd32bedd6e7 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -47,6 +47,7 @@ static const u8 uabi_classes[] = {
  [VIDEO_DECODE_CLASS] = I915_ENGINE_CLASS_VIDEO,
  [VIDEO_ENHANCEMENT_CLASS] = I915_ENGINE_CLASS_VIDEO_ENHANCE,
  [COMPUTE_CLASS] = I915_ENGINE_CLASS_COMPUTE,
+    [OTHER_CLASS] = I915_KERNEL_RSVD_CLASS,


Could we set it to -1 (aka no uabi class) to avoid needing to maintain 
the new macros?


And then just teach intel_engines_driver_register to skip -1. Would 
also need teaching engine_rename to handle -1.


Might end up a smaller and more maintainable patch - worth a try do 
you think?


That was my initial idea as well, but the issue with this approach is 
the engine_uabi_class_count[] array, which is sized based on the number 
of uabi classes, so having class -1 would needlessly increase its size a 
lot even when using a u8. I thought about limiting the class entry to 3 
bits so the array would max out at 8 entries, but that seemed to be 
getting a bit too convoluted. I can give it a go if you think it's be 
cleaner overall.


Note that this patch does not introduce any new macros that would need 
to be maintained. I915_LAST_UABI_ENGINE_CLASS already existed (I just 
moved it from one file to another) and is the only one that changes when 
a new "real" uabi class is added; the other defines are based on this 
one. This also implies that if a new uabi class is added then 
I915_KERNEL_RSVD_CLASS would be bumped to the next free number, which 
would cause the GSC to show as a different uabi class in newer logs; 
considering that i915 is on its way out, a new class seems very unlikely 
so I thought it'd be an acceptable compromise to keep things simple.





  };
    static int engine_cmp(void *priv, const struct list_head *A,
@@ -138,7 +139,7 @@ const char *intel_engine_class_repr(u8 class)
  [COPY_ENGINE_CLASS] = "bcs",
  [VIDEO_DECODE_CLASS] = "vcs",
  [VIDEO_ENHANCEMENT_CLASS] = "vecs",
-    [OTHER_CLASS] = "other",
+    [OTHER_CLASS] = "gsc",


Maybe unrelated?


no. Before this patch, we hardcoded "gsc" below when calling 
engine_rename() for it. With this patch, we use the name from this 
array, so it needs to be updated. The GEM_WARN_ON below was added to 
make sure we don't get different engines in OTHER_CLASS that might not 
match the "gsc" naming.


Daniele



Regards,

Tvrtko


  [COMPUTE_CLASS] = "ccs",
  };
  @@ -216,14 +217,8 @@ void intel_engines_driver_register(struct 
drm_i915_private *i915)

  if (intel_gt_has_unrecoverable_error(engine->gt))
  continue; /* ignore incomplete engines */
  -    /*
- * We don't want to expose the GSC engine to the users, but we
- * still rename it so it is easier to identify in the debug 
logs

- */
-    if (engine->id == GSC0) {
-    engine_rename(engine, "gsc", 0);
-    continue;
-    }
+    /* The only engine we expect in OTHER_CLASS is GSC0 */
+    GEM_WARN_ON(engine->class == OTHER_CLASS && engine->id != 
GSC0);

    GEM_BUG_ON(engine->class >= ARRAY_SIZE(uabi_classes));
  engine->uabi_class = uabi_classes[engine->class];
@@ -238,6 +233,10 @@ void intel_engines_driver_register(struct 
drm_i915_private *i915)

    intel_engine_class_repr(engine->class),
    engine->uabi_instance);
  +    /* We don't want to expose the GSC engine to the users */
+    if (engine->id == GSC0)
+    continue;
+
  rb_link_node(>uabi_node, prev, p);
  rb_insert_color(>uabi_node, >uabi_engines);
  diff --git a/drivers/gpu/drm/i915/

Re: [Intel-gfx] [PATCH] drm/i915/huc: Stop printing about unsupported HuC on MTL

2023-11-13 Thread Daniele Ceraolo Spurio




On 11/9/2023 6:06 PM, John Harrison wrote:

On 11/9/2023 15:54, Daniele Ceraolo Spurio wrote:

On MTL, the HuC is only supported on the media GT, so our validation
check on the module parameter detects an inconsistency on the root GT
(the modparams asks to enable HuC, but the support is not there) and
prints the following info message:

[drm] GT0: Incompatible option enable_guc=3 - HuC is not supported!

This can be confusing to the user and make them think that something is
wrong when it isn't, so we need to silence it.
Given that any platform that supports HuC also supports GuC, if a user
tries to enable HuC on a platform that really doesn't support it they'll
already see a message about GuC not being supported, so instead of just
silencing the HuC message on newer platforms we can just get rid of it
entirely.
Not following this argument. Someone might attempt to enable HuC only 
and do so on a older platform that supports neither HuC nor GuC. There 
would be no GuC warning because GuC was not requested. But now there 
would also be no HuC warning either.




Enabling HuC also enabled GuC loading, because the latter is needed to 
auth the former. The message about GuC not being supported is printed 
for all values of enable_guc that are not zero.


Daniele


John.



Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc.c | 5 -
  1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c

index 27f6561dd731..3872d309ed31 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -106,11 +106,6 @@ static void __confirm_options(struct intel_uc *uc)
  gt_info(gt,  "Incompatible option enable_guc=%d - %s\n",
  i915->params.enable_guc, "GuC is not supported!");
  -    if (i915->params.enable_guc & ENABLE_GUC_LOAD_HUC &&
-    !intel_uc_supports_huc(uc))
-    gt_info(gt, "Incompatible option enable_guc=%d - %s\n",
-    i915->params.enable_guc, "HuC is not supported!");
-
  if (i915->params.enable_guc & ENABLE_GUC_SUBMISSION &&
  !intel_uc_supports_guc_submission(uc))
  gt_info(gt, "Incompatible option enable_guc=%d - %s\n",






[Intel-gfx] [PATCH] drm/i915/huc: Stop printing about unsupported HuC on MTL

2023-11-09 Thread Daniele Ceraolo Spurio
On MTL, the HuC is only supported on the media GT, so our validation
check on the module parameter detects an inconsistency on the root GT
(the modparams asks to enable HuC, but the support is not there) and
prints the following info message:

[drm] GT0: Incompatible option enable_guc=3 - HuC is not supported!

This can be confusing to the user and make them think that something is
wrong when it isn't, so we need to silence it.
Given that any platform that supports HuC also supports GuC, if a user
tries to enable HuC on a platform that really doesn't support it they'll
already see a message about GuC not being supported, so instead of just
silencing the HuC message on newer platforms we can just get rid of it
entirely.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 27f6561dd731..3872d309ed31 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -106,11 +106,6 @@ static void __confirm_options(struct intel_uc *uc)
gt_info(gt,  "Incompatible option enable_guc=%d - %s\n",
i915->params.enable_guc, "GuC is not supported!");
 
-   if (i915->params.enable_guc & ENABLE_GUC_LOAD_HUC &&
-   !intel_uc_supports_huc(uc))
-   gt_info(gt, "Incompatible option enable_guc=%d - %s\n",
-   i915->params.enable_guc, "HuC is not supported!");
-
if (i915->params.enable_guc & ENABLE_GUC_SUBMISSION &&
!intel_uc_supports_guc_submission(uc))
gt_info(gt, "Incompatible option enable_guc=%d - %s\n",
-- 
2.41.0



[Intel-gfx] [PATCH] drm/i915/gsc: Assign a uabi class number to the GSC CS

2023-11-09 Thread Daniele Ceraolo Spurio
The GSC CS is not exposed to the user, so we skipped assigning a uabi
class number for it. However, the trace logs use the uabi class and
instance to identify the engine, so leaving uabi class unset makes the
GSC CS show up as the RCS in those logs.
Given that the engine is not exposed to the user, we can't add a new
case in the uabi enum, so we insted internally define a kernel
reserved class using the next free number.

Fixes: 194babe26bdc ("drm/i915/mtl: don't expose GSC command streamer to the 
user")
Signed-off-by: Daniele Ceraolo Spurio 
Cc: Tvrtko Ursulin 
Cc: Alan Previn 
Cc: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_engine_user.c | 17 -
 drivers/gpu/drm/i915/gt/intel_engine_user.h |  4 
 drivers/gpu/drm/i915/i915_drm_client.h  |  2 +-
 drivers/gpu/drm/i915/i915_drv.h |  2 +-
 4 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c
index 118164ddbb2e..3fd32bedd6e7 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -47,6 +47,7 @@ static const u8 uabi_classes[] = {
[VIDEO_DECODE_CLASS] = I915_ENGINE_CLASS_VIDEO,
[VIDEO_ENHANCEMENT_CLASS] = I915_ENGINE_CLASS_VIDEO_ENHANCE,
[COMPUTE_CLASS] = I915_ENGINE_CLASS_COMPUTE,
+   [OTHER_CLASS] = I915_KERNEL_RSVD_CLASS,
 };
 
 static int engine_cmp(void *priv, const struct list_head *A,
@@ -138,7 +139,7 @@ const char *intel_engine_class_repr(u8 class)
[COPY_ENGINE_CLASS] = "bcs",
[VIDEO_DECODE_CLASS] = "vcs",
[VIDEO_ENHANCEMENT_CLASS] = "vecs",
-   [OTHER_CLASS] = "other",
+   [OTHER_CLASS] = "gsc",
[COMPUTE_CLASS] = "ccs",
};
 
@@ -216,14 +217,8 @@ void intel_engines_driver_register(struct drm_i915_private 
*i915)
if (intel_gt_has_unrecoverable_error(engine->gt))
continue; /* ignore incomplete engines */
 
-   /*
-* We don't want to expose the GSC engine to the users, but we
-* still rename it so it is easier to identify in the debug logs
-*/
-   if (engine->id == GSC0) {
-   engine_rename(engine, "gsc", 0);
-   continue;
-   }
+   /* The only engine we expect in OTHER_CLASS is GSC0 */
+   GEM_WARN_ON(engine->class == OTHER_CLASS && engine->id != GSC0);
 
GEM_BUG_ON(engine->class >= ARRAY_SIZE(uabi_classes));
engine->uabi_class = uabi_classes[engine->class];
@@ -238,6 +233,10 @@ void intel_engines_driver_register(struct drm_i915_private 
*i915)
  intel_engine_class_repr(engine->class),
  engine->uabi_instance);
 
+   /* We don't want to expose the GSC engine to the users */
+   if (engine->id == GSC0)
+   continue;
+
rb_link_node(>uabi_node, prev, p);
rb_insert_color(>uabi_node, >uabi_engines);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.h 
b/drivers/gpu/drm/i915/gt/intel_engine_user.h
index 3dc7e8ab9fbc..dd31805b2a5a 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.h
@@ -11,6 +11,10 @@
 struct drm_i915_private;
 struct intel_engine_cs;
 
+#define I915_LAST_UABI_ENGINE_CLASS I915_ENGINE_CLASS_COMPUTE
+#define I915_KERNEL_RSVD_CLASS (I915_LAST_UABI_ENGINE_CLASS + 1)
+#define I915_MAX_UABI_CLASSES (I915_KERNEL_RSVD_CLASS + 1)
+
 struct intel_engine_cs *
 intel_engine_lookup_user(struct drm_i915_private *i915, u8 class, u8 instance);
 
diff --git a/drivers/gpu/drm/i915/i915_drm_client.h 
b/drivers/gpu/drm/i915/i915_drm_client.h
index 67816c912bca..c42cb2511348 100644
--- a/drivers/gpu/drm/i915/i915_drm_client.h
+++ b/drivers/gpu/drm/i915/i915_drm_client.h
@@ -12,7 +12,7 @@
 
 #include 
 
-#define I915_LAST_UABI_ENGINE_CLASS I915_ENGINE_CLASS_COMPUTE
+#include "gt/intel_engine_user.h"
 
 struct drm_file;
 struct drm_printer;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f3be9033a93f..a718b4cb5a2d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -238,7 +238,7 @@ struct drm_i915_private {
struct list_head uabi_engines_list;
struct rb_root uabi_engines;
};
-   unsigned int engine_uabi_class_count[I915_LAST_UABI_ENGINE_CLASS + 1];
+   unsigned int engine_uabi_class_count[I915_MAX_UABI_CLASSES];
 
/* protects the irq masks */
spinlock_t irq_lock;
-- 
2.41.0



Re: [Intel-gfx] [PATCH 1/2] drm/i915/guc: Fix for potential false positives in GuC hang selftest

2023-11-09 Thread Daniele Ceraolo Spurio




On 11/6/2023 3:59 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

Noticed that the hangcheck selftest is submitting a non-preemptoble
spinner. That means that even if the GuC does not die, the heartbeat
will still kick in and trigger a reset. Which is rather defeating the
purpose of the test - to verify that the heartbeat will kick in if the
GuC itself has died. The test is deliberately killing the GuC, so it
should never hit the case of a non-dead GuC. But it is not impossible
that the kill might fail at some future point due to other driver
re-work.

So, make the spinner pre-emptible. That way the heartbeat can get
through if the GuC is alive and context switching. Thus a reset only
happens if the GuC dies. Thus, if the kill should stop working the
test will now fail rather than claim to pass.

Signed-off-by: John Harrison 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
index 34b5d952e2bcb..26fdc392fce6c 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
@@ -74,7 +74,7 @@ static int intel_hang_guc(void *arg)
goto err;
}
  
-	rq = igt_spinner_create_request(, ce, MI_NOOP);

+   rq = igt_spinner_create_request(, ce, MI_ARB_CHECK);
intel_context_put(ce);
if (IS_ERR(rq)) {
ret = PTR_ERR(rq);




Re: [Intel-gfx] [PATCH 2/2] drm/i915/guc: Add a selftest for FAST_REQUEST errors

2023-11-09 Thread Daniele Ceraolo Spurio




On 11/6/2023 3:59 PM, john.c.harri...@intel.com wrote:

From: John Harrison 

There is a mechanism for reporting errors from fire and forget H2G
messages. This is the only way to find out about almost any error in
the GuC backend submission path. So it would be useful to know that it
is working.

Signed-off-by: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc.h|   4 +
  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   9 ++
  drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 122 ++
  3 files changed, 135 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 2b6dfe62c8f2a..e22c12ce245ad 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -297,6 +297,10 @@ struct intel_guc {
 * @number_guc_id_stolen: The number of guc_ids that have been stolen
 */
int number_guc_id_stolen;
+   /**
+* @fast_response_selftest: Backdoor to CT handler for fast response 
selftest
+*/
+   u32 fast_response_selftest;
  #endif
  };
  
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c

index 89e314b3756bb..9d958afb78b7f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -1076,6 +1076,15 @@ static int ct_handle_response(struct intel_guc_ct *ct, 
struct ct_incoming_msg *r
found = true;
break;
}
+
+#ifdef CONFIG_DRM_I915_SELFTEST
+   if (!found && ct_to_guc(ct)->fast_response_selftest) {
+   CT_DEBUG(ct, "Assuming unsolicited response due to FAST_REQUEST 
selftest\n");
+   ct_to_guc(ct)->fast_response_selftest++;
+   found = 1;


found = true ? it's the same thing, but it's cleaner to assign boolean 
values to bool variables



+   }
+#endif
+
if (!found) {
CT_ERROR(ct, "Unsolicited response message: len %u, data %#x (fence 
%u, last %u)\n",
 len, hxg[0], fence, ct->requests.last_fence);
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
index bfb72143566f6..97fbbb396336c 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
@@ -286,11 +286,133 @@ static int intel_guc_steal_guc_ids(void *arg)
return ret;
  }
  
+/*

+ * Send a context schedule H2G message with an invalid context id.
+ * This should generate a GUC_RESULT_INVALID_CONTEXT response.
+ */
+static int bad_h2g(struct intel_guc *guc)
+{
+   u32 action[3], len = 0;


AFAICS This is a 2 DW command, so you can use action[2].


+
+   action[len++] = INTEL_GUC_ACTION_SCHED_CONTEXT;
+   action[len++] = 0x12345678;
+
+   return intel_guc_send_nb(guc, action, len, 0);
+}
+
+/*
+ * Set a spinner running to make sure the system is alive and active,
+ * then send a bad but asynchronous H2G command and wait to see if an
+ * error response is returned. If no response is received or if the
+ * spinner dies then the test will fail.
+ */
+#define FAST_RESPONSE_TIMEOUT_MS   1000
+static int intel_guc_fast_request(void *arg)
+{
+   struct intel_gt *gt = arg;
+   struct intel_context *ce;
+   struct igt_spinner spin;
+   struct i915_request *rq;
+   intel_wakeref_t wakeref;
+   struct intel_engine_cs *engine = intel_selftest_find_any_engine(gt);
+   ktime_t before, now, delta;
+   bool spinning = false;
+   u64 delta_ms;
+   int ret = 0;
+
+   if (!engine)
+   return 0;
+
+   wakeref = intel_runtime_pm_get(gt->uncore->rpm);
+
+   ce = intel_context_create(engine);
+   if (IS_ERR(ce)) {
+   ret = PTR_ERR(ce);
+   gt_err(gt, "Failed to create spinner request: %pe\n", ce);
+   goto err_pm;
+   }
+
+   ret = igt_spinner_init(, engine->gt);
+   if (ret) {
+   gt_err(gt, "Failed to create spinner: %pe\n", ERR_PTR(ret));
+   goto err_pm;
+   }
+   spinning = true;
+
+   rq = igt_spinner_create_request(, ce, MI_ARB_CHECK);
+   intel_context_put(ce);
+   if (IS_ERR(rq)) {
+   ret = PTR_ERR(rq);
+   gt_err(gt, "Failed to create spinner request: %pe\n", rq);
+   goto err_spin;
+   }
+
+   ret = request_add_spin(rq, );
+   if (ret) {
+   gt_err(gt, "Failed to add Spinner request: %pe\n", 
ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   gt->uc.guc.fast_response_selftest = 1;
+
+   ret = bad_h2g(>uc.guc);
+   if (ret) {
+   gt_err(gt, "Failed to send H2G: %pe\n", ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   before = ktime_get();
+   while (gt->uc.guc.fast_response_selftest == 1) {
+   ret = i915_request_wait(rq, 0, 1);
+   if (ret != -ETIME) {
+   

[Intel-gfx] [CI] PR for PVC GuC 70.9.1

2023-10-04 Thread Daniele Ceraolo Spurio
The following changes since commit 5105ff4b9f43ba08d0a22260d670120e53c4b667:

  Merge branch 'mlimonci/upstream-packaging' into 'main' (2023-10-04 12:35:17 
+)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware xe_pvc_guc_70.9.1

for you to fetch changes up to ca4d55fbc3feca49f097afc86bbdfe88a8aa82d9:

  xe: add PVC GUC 70.9.1 (2023-10-04 09:31:44 -0700)


Daniele Ceraolo Spurio (1):
  xe: add PVC GUC 70.9.1

 WHENCE|   8 
 xe/pvc_guc_70.9.1.bin | Bin 0 -> 533312 bytes
 2 files changed, 8 insertions(+)
 create mode 100644 xe/pvc_guc_70.9.1.bin


Re: [Intel-gfx] [PATCH] i915/guc: Get runtime pm in busyness worker only if already active

2023-09-15 Thread Daniele Ceraolo Spurio




On 9/14/2023 6:28 PM, Umesh Nerlige Ramappa wrote:

Ideally the busyness worker should take a gt pm wakeref because the
worker only needs to be active while gt is awake. However, the gt_park
path cancels the worker synchronously and this complicates the flow if
the worker is also running at the same time. The cancel waits for the
worker and when the worker releases the wakeref, that would call gt_park
and would lead to a deadlock.

The resolution is to take the global pm wakeref if runtime pm is already
active. If not, we don't need to update the busyness stats as the stats
would already be updated when the gt was parked.

Note:
- We do not requeue the worker if we cannot take a reference to runtime
   pm since intel_guc_busyness_unpark would requeue the worker in the
   resume path.

- If the gt was parked longer than time taken for GT timestamp to roll
   over, we ignore those rollovers since we don't care about tracking the
   exact GT time. We only care about roll overs when the gt is active and
   running workloads.

- There is a window of time between gt_park and runtime suspend, where
   the worker may run. This is acceptable since the worker will not find
   any new data to update busyness.

v2: (Daniele)
- Edit commit message and code comment
- Use runtime pm in the worker
- Put runtime pm after enabling the worker
- Use Link tag and add Fixes tag

v3: (Daniele)
- Reword commit and comments and add details

Link: https://gitlab.freedesktop.org/drm/intel/-/issues/7077
Fixes: 77cdd054dd2c ("drm/i915/pmu: Connect engine busyness stats from GuC to 
pmu")
Signed-off-by: Umesh Nerlige Ramappa 


Reviewed-by: Daniele Ceraolo Spurio 

Daniele


---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 38 +--
  1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index cabdc645fcdd..ae3495a9c814 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1432,6 +1432,36 @@ static void guc_timestamp_ping(struct work_struct *wrk)
unsigned long index;
int srcu, ret;
  
+	/*

+* Ideally the busyness worker should take a gt pm wakeref because the
+* worker only needs to be active while gt is awake. However, the
+* gt_park path cancels the worker synchronously and this complicates
+* the flow if the worker is also running at the same time. The cancel
+* waits for the worker and when the worker releases the wakeref, that
+* would call gt_park and would lead to a deadlock.
+*
+* The resolution is to take the global pm wakeref if runtime pm is
+* already active. If not, we don't need to update the busyness stats as
+* the stats would already be updated when the gt was parked.
+*
+* Note:
+* - We do not requeue the worker if we cannot take a reference to 
runtime
+*   pm since intel_guc_busyness_unpark would requeue the worker in the
+*   resume path.
+*
+* - If the gt was parked longer than time taken for GT timestamp to 
roll
+*   over, we ignore those rollovers since we don't care about tracking
+*   the exact GT time. We only care about roll overs when the gt is
+*   active and running workloads.
+*
+* - There is a window of time between gt_park and runtime suspend,
+*   where the worker may run. This is acceptable since the worker will
+*   not find any new data to update busyness.
+*/
+   wakeref = intel_runtime_pm_get_if_active(>i915->runtime_pm);
+   if (!wakeref)
+   return;
+
/*
 * Synchronize with gt reset to make sure the worker does not
 * corrupt the engine/guc stats. NB: can't actually block waiting
@@ -1440,10 +1470,9 @@ static void guc_timestamp_ping(struct work_struct *wrk)
 */
ret = intel_gt_reset_trylock(gt, );
if (ret)
-   return;
+   goto err_trylock;
  
-	with_intel_runtime_pm(>i915->runtime_pm, wakeref)

-   __update_guc_busyness_stats(guc);
+   __update_guc_busyness_stats(guc);
  
  	/* adjust context stats for overflow */

xa_for_each(>context_lookup, index, ce)
@@ -1452,6 +1481,9 @@ static void guc_timestamp_ping(struct work_struct *wrk)
intel_gt_reset_unlock(gt, srcu);
  
  	guc_enable_busyness_worker(guc);

+
+err_trylock:
+   intel_runtime_pm_put(>i915->runtime_pm, wakeref);
  }
  
  static int guc_action_enable_usage_stats(struct intel_guc *guc)




Re: [Intel-gfx] [PATCH] i915/guc: Run busyness worker only if gt is awake

2023-09-14 Thread Daniele Ceraolo Spurio



On 9/11/2023 5:52 PM, Umesh Nerlige Ramappa wrote:

The worker is canceled in the __gt_park path, but we still see it
running sometimes during suspend.

Only update stats if gt is awake. If not, intel_guc_busyness_park would
have already updated the stats. Note that we do not requeue the worker
if gt is not awake since intel_guc_busyness_unpark would do that at some
point.

If the gt was parked longer than time taken for GT timestamp to roll
over, we ignore those rollovers since we don't care about tracking the
exact GT time. We only care about roll overs when the gt is active and
running workloads.

v2 (Daniele)
- Edit commit message and code comment
- Use runtime pm in the worker
- Put runtime pm after enabling the worker
- Use Link tag and add Fixes tag

Link: https://gitlab.freedesktop.org/drm/intel/-/issues/7077
Fixes: 77cdd054dd2c ("drm/i915/pmu: Connect engine busyness stats from GuC to 
pmu")
Signed-off-by: Umesh Nerlige Ramappa 
---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 26 ---
  1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index e250bedf90fb..d37b29a0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1461,6 +1461,24 @@ static void guc_timestamp_ping(struct work_struct *wrk)
unsigned long index;
int srcu, ret;
  
+	/*

+* The worker is canceled in the __gt_park path, but we still see it
+* running sometimes during suspend.


This sounds very vague and more like there is a bug in __gt_park. We 
actually do know that the issue on the park side is that the worker 
re-queues itself if it's running while we cancel it; that's not really a 
problem as long as we don't wake the device after it's gone to sleep 
(which is what your change below does), so this sentence should be 
reworded or dropped.



+*
+* Only update stats if gt is awake. If not, intel_guc_busyness_park
+* would have already updated the stats. Note that we do not requeue the
+* worker in this case since intel_guc_busyness_unpark would do that at
+* some point.
+*
+* If the gt was parked longer than time taken for GT timestamp to roll
+* over, we ignore those rollovers since we don't care about tracking
+* the exact GT time. We only care about roll overs when the gt is
+* active and running workloads.
+*/
+   wakeref = intel_runtime_pm_get_if_active(>i915->runtime_pm);


The patch title and the comment refer to GT being awake, but here you're 
taking a global rpm ref and not a gt_pm ref. I understand that taking a 
gt_pm ref in here can be complicated because of the canceling of the 
worker in the gt_park flow and that taking an rpm ref does work for what 
we need, but the title/comments need to reflect and explain that.


Daniele


+   if (!wakeref)
+   return;
+
/*
 * Synchronize with gt reset to make sure the worker does not
 * corrupt the engine/guc stats. NB: can't actually block waiting
@@ -1469,10 +1487,9 @@ static void guc_timestamp_ping(struct work_struct *wrk)
 */
ret = intel_gt_reset_trylock(gt, );
if (ret)
-   return;
+   goto err_trylock;
  
-	with_intel_runtime_pm(>i915->runtime_pm, wakeref)

-   __update_guc_busyness_stats(guc);
+   __update_guc_busyness_stats(guc);
  
  	/* adjust context stats for overflow */

xa_for_each(>context_lookup, index, ce)
@@ -1481,6 +1498,9 @@ static void guc_timestamp_ping(struct work_struct *wrk)
intel_gt_reset_unlock(gt, srcu);
  
  	guc_enable_busyness_worker(guc);

+
+err_trylock:
+   intel_runtime_pm_put(>i915->runtime_pm, wakeref);
  }
  
  static int guc_action_enable_usage_stats(struct intel_guc *guc)




[Intel-gfx] PR for HuC v8.5.4 for MTL

2023-09-14 Thread Daniele Ceraolo Spurio
The following changes since commit dfa11466cf000120d1551146fd5bf78c44941eda:

  Merge branch 'main' into 'main' (2023-09-07 11:36:57 +)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_huc_8.5.4

for you to fetch changes up to a5dbe400f776b0dc2d0a402ba76b4c16c231b38e:

  i915: update MTL HuC to version 8.5.4 (2023-09-14 08:34:08 -0700)


Daniele Ceraolo Spurio (1):
  i915: update MTL HuC to version 8.5.4

 WHENCE   |   2 +-
 i915/mtl_huc_gsc.bin | Bin 569344 -> 561152 bytes
 2 files changed, 1 insertion(+), 1 deletion(-)


Re: [Intel-gfx] [PATCH] i915/guc: Run busyness worker only if gt is awake

2023-09-11 Thread Daniele Ceraolo Spurio



On 9/8/2023 10:16 PM, Umesh Nerlige Ramappa wrote:

The worker is canceled in the __gt_park path, but we still see it
running sometimes during suspend. This is likely because some code is
getting a gt wakeref in the __gt_park path.
This possible root-cause doesn't seem plausible to me, because a gt 
wakeref would cause an unpark, so taking it within the park would 
probably cause a deadlock. Is it not more likely that the worker 
re-queued itself?



Only update stats if gt is awake. If not, intel_guc_busyness_park would
have already updated the stats. Note that we do not requeue the worker
if gt is not awake since intel_guc_busyness_unpark would do that at some
point.

If the gt was parked longer than time taken for GT timestamp to roll
over, we ignore those rollovers since we don't care about tracking the
exact GT time. We only care about roll overs when the gt is active and
running workloads.

Closes:https://gitlab.freedesktop.org/drm/intel/-/issues/7077
This needs a fixes tag. Also, I'm not 100% sure but I believe we prefer 
"Link" to "Closes".



Signed-off-by: Umesh Nerlige Ramappa
---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 27 ---
  1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index e250bedf90fb..df31d6047ce9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1457,10 +1457,27 @@ static void guc_timestamp_ping(struct work_struct *wrk)
struct intel_uc *uc = container_of(guc, typeof(*uc), guc);
struct intel_gt *gt = guc_to_gt(guc);
struct intel_context *ce;
-   intel_wakeref_t wakeref;
unsigned long index;
int srcu, ret;
  
+	/*

+* The worker is canceled in the __gt_park path, but we still see it
+* running sometimes during suspend. This is likely because some code
+* is getting a gt wakeref in the __gt_park path.


Same comment from before about this explanation. I would just remove 
this part from the comment.



+*
+* Only update stats if gt is awake. If not, intel_guc_busyness_park
+* would have already updated the stats. Note that we do not requeue the
+* worker in this case since intel_guc_busyness_unpark would do that at
+* some point.
+*
+* If the gt was parked longer than time taken for GT timestamp to roll
+* over, we ignore those rollovers since we don't care about tracking
+* the exact GT time. We only care about roll overs when the gt is
+* active and running workloads.
+*/
+   if (!intel_gt_pm_get_if_awake(gt))
+   return;
+


Do we need to drop the _sync from the busyness stats worker parking if 
we take the gt_pm wakeref in here, instead of an rpm one? because if the 
gt_pm_put below causes a park and the park waits on this worker to 
complete then we'll deadlock.



/*
 * Synchronize with gt reset to make sure the worker does not
 * corrupt the engine/guc stats. NB: can't actually block waiting
@@ -1468,17 +1485,19 @@ static void guc_timestamp_ping(struct work_struct *wrk)
 * this worker thread if started. So waiting would deadlock.
 */
ret = intel_gt_reset_trylock(gt, );
-   if (ret)
+   if (ret) {
+   intel_gt_pm_put(gt);
return;
+   }
  
-	with_intel_runtime_pm(>i915->runtime_pm, wakeref)

-   __update_guc_busyness_stats(guc);
+   __update_guc_busyness_stats(guc);
  
  	/* adjust context stats for overflow */

xa_for_each(>context_lookup, index, ce)
guc_context_update_stats(ce);
  
  	intel_gt_reset_unlock(gt, srcu);

+   intel_gt_pm_put(gt);


I think this needs to go after the queuing, because it could cause a 
park and if it does we don't want to re-queue the worker immediately 
after, while if we queue it before then the park will cancel it.
Non-blocking style comment: with gt_pm_put the last thing in function, 
you can also transform that early return in a "goto put;" and have a 
single place for the gt_put.


Daniele

  
  	guc_enable_busyness_worker(guc);

  }


[Intel-gfx] [CI] PR for MTL HuC v8.5.4

2023-09-06 Thread Daniele Ceraolo Spurio
The following changes since commit ad03b851816cc6868f27a29732489fc565739368:

  Merge branch 'rb12-fw-v2' into 'main' (2023-09-06 20:40:34 +)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_huc_8.5.4

for you to fetch changes up to 82ef648d026200e40a597ba7ea795b1c97dcebf2:

  i915: update MTL HuC to version 8.5.4 (2023-09-06 13:58:22 -0700)


Daniele Ceraolo Spurio (1):
  i915: update MTL HuC to version 8.5.4

 WHENCE   |   2 +-
 i915/mtl_huc_gsc.bin | Bin 569344 -> 561152 bytes
 2 files changed, 1 insertion(+), 1 deletion(-)


[Intel-gfx] [PATCH] drm/i915/gsc: define gsc fw

2023-08-25 Thread Daniele Ceraolo Spurio
Add FW definition and the matching override modparam.

The GSC FW has both a release version, based on platform and a rolling
counter, and a compatibility version, which is the one tracking
interface changes. Since what we care about is the interface, we use
the compatibility version in the binary names.

Same as with the GuC, a major version bump indicate a
backward-incompatible change, while a minor version bump indicates a
backward-compatible one, so we use only the former in the file name.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Cc: Tvrtko Ursulin 
Cc: Rodrigo Vivi 
Reviewed-by: Alan Previn 
---

This patch is already merged in topic/core-for-CI. It was merged there
because we didn't have a GSC FW ready to ship to linux-firmware, but we
still wanted to start testing what we had in CI. We finally have a FW
in flight towards linux-firmware [1], so we can transition this patch
to drm-intel-gt-next. The patch is unchanged since it was first sent
and reviewed [2], so I kept the r-b and I'm looking for an ack on the
move.
Note that since this patch is already applied, pre-merge CI won't
correctly run on it (which is not a problem given that the patch is
already included in all current runs).

References: https://gitlab.freedesktop.org/drm/intel/-/issues/8705
[1] https://lists.freedesktop.org/archives/intel-gfx/2023-August/22.html
[2] https://patchwork.freedesktop.org/patch/544638/

 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 32 ++--
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 9e833f499ac7..fc0d05d2df59 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -131,6 +131,17 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(BROXTON,  0, huc_mmp(bxt,  2, 0, 0)) \
fw_def(SKYLAKE,  0, huc_mmp(skl,  2, 0, 0))
 
+/*
+ * The GSC FW has multiple version (see intel_gsc_uc.h for details); since what
+ * we care about is the interface, we use the compatibility version in the
+ * binary names.
+ * Same as with the GuC, a major version bump indicate a
+ * backward-incompatible change, while a minor version bump indicates a
+ * backward-compatible one, so we use only the former in the file name.
+ */
+#define INTEL_GSC_FIRMWARE_DEFS(fw_def, gsc_def) \
+   fw_def(METEORLAKE,   0, gsc_def(mtl, 1, 0))
+
 /*
  * Set of macros for producing a list of filenames from the above table.
  */
@@ -166,6 +177,9 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 #define MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MMP(prefix_, "huc", major_, minor_, patch_)
 
+#define MAKE_GSC_FW_PATH(prefix_, major_, minor_) \
+   __MAKE_UC_FW_PATH_MAJOR(prefix_, "gsc", major_)
+
 /*
  * All blobs need to be declared via MODULE_FIRMWARE().
  * This first expansion of the table macros is solely to provide
@@ -176,6 +190,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 
 INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH_MAJOR, 
MAKE_GUC_FW_PATH_MMP)
 INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, 
MAKE_HUC_FW_PATH_MMP, MAKE_HUC_FW_PATH_GSC)
+INTEL_GSC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GSC_FW_PATH)
 
 /*
  * The next expansion of the table macros (in __uc_fw_auto_select below) 
provides
@@ -225,6 +240,10 @@ struct __packed uc_fw_blob {
 #define HUC_FW_BLOB_GSC(prefix_) \
UC_FW_BLOB_NEW(0, 0, 0, true, MAKE_HUC_FW_PATH_GSC(prefix_))
 
+#define GSC_FW_BLOB(prefix_, major_, minor_) \
+   UC_FW_BLOB_NEW(major_, minor_, 0, true, \
+  MAKE_GSC_FW_PATH(prefix_, major_, minor_))
+
 struct __packed uc_fw_platform_requirement {
enum intel_platform p;
u8 rev; /* first platform rev using this FW */
@@ -251,9 +270,14 @@ static const struct uc_fw_platform_requirement blobs_huc[] 
= {
INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, 
HUC_FW_BLOB_GSC)
 };
 
+static const struct uc_fw_platform_requirement blobs_gsc[] = {
+   INTEL_GSC_FIRMWARE_DEFS(MAKE_FW_LIST, GSC_FW_BLOB)
+};
+
 static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+   [INTEL_UC_FW_TYPE_GSC] = { blobs_gsc, ARRAY_SIZE(blobs_gsc) },
 };
 
 static void
@@ -266,14 +290,6 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
int i;
bool found;
 
-   /*
-* GSC FW support is still not fully in place, so we're not defining
-* the FW blob yet because we don't want the driver to attempt to load
-* it until we're ready for it.
-*/
-   if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)

[Intel-gfx] PR for GSC FW release 102.0.0.1655 for MTL

2023-08-23 Thread Daniele Ceraolo Spurio
The following changes since commit 0e048b061bde79ad735c7b7b5161ee1bd3400150:

  Merge branch 'for-upstream' of https://github.com/CirrusLogic/linux-firmware 
(2023-08-14 13:03:41 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_gsc_1655

for you to fetch changes up to 81caac98eda1696fa057191ee969c377154a:

  i915: add GSC 102.0.0.1655 for MTL (2023-08-21 14:13:11 -0700)


Daniele Ceraolo Spurio (1):
  i915: add GSC 102.0.0.1655 for MTL

 WHENCE |   3 +++
 i915/mtl_gsc_1.bin | Bin 0 -> 1142784 bytes
 2 files changed, 3 insertions(+)
 create mode 100755 i915/mtl_gsc_1.bin


[Intel-gfx] [CI] PR for GSC FW release 102.0.0.1655 for MTL

2023-08-21 Thread Daniele Ceraolo Spurio
The following changes since commit 0e048b061bde79ad735c7b7b5161ee1bd3400150:

  Merge branch 'for-upstream' of https://github.com/CirrusLogic/linux-firmware 
(2023-08-14 13:03:41 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_gsc_1655

for you to fetch changes up to 81caac98eda1696fa057191ee969c377154a:

  i915: add GSC 102.0.0.1655 for MTL (2023-08-21 14:13:11 -0700)


Daniele Ceraolo Spurio (1):
  i915: add GSC 102.0.0.1655 for MTL

 WHENCE |   3 +++
 i915/mtl_gsc_1.bin | Bin 0 -> 1142784 bytes
 2 files changed, 3 insertions(+)
 create mode 100755 i915/mtl_gsc_1.bin


[Intel-gfx] [PATCH v2] drm/i915/huc: silence injected failure in the load via GSC path

2023-08-16 Thread Daniele Ceraolo Spurio
If we can't load the HuC due to an injected failure, we don't want
to throw and error and trip CI. Using the gt_probe_error macro for
logging ensure that the error is only printed if it wasn't explicitly
injected.

v2: keep the line to less than 100 characters (checkpatch).

Link: https://gitlab.freedesktop.org/drm/intel/-/issues/7061
Signed-off-by: Daniele Ceraolo Spurio 
Reviewed-by: Andi Shyti  #v1
---
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index f89a1f80f50e..bb58fa9579b8 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 
 
 #include "gem/i915_gem_lmem.h"
+#include "gt/intel_gt_print.h"
 
 #include "i915_drv.h"
 #include "gt/intel_gt.h"
@@ -156,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 = >ctrl_gt->uc;
+   struct intel_gt *gt = pxp->ctrl_gt;
+   struct intel_uc *uc = >uc;
intel_wakeref_t wakeref;
int ret = 0;
 
@@ -176,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(>huc);
if (ret < 0)
-   drm_err(>drm, "failed to load huc via gsc 
%d\n", ret);
+   gt_probe_error(gt, "failed to load huc via gsc 
%d\n", ret);
}
}
 
-- 
2.41.0



[Intel-gfx] [CI] PR for PVC FWs for Xe

2023-08-04 Thread Daniele Ceraolo Spurio
Re-sending because the CI scripts had an issue with the xe folder the
first time around.

The following changes since commit 253cc179d849fc82489773b2b553a49858d8725f:

  amdgpu: Update DMCUB for DCN314 & Yellow Carp (2023-07-31 11:22:02 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware xe_pvc

for you to fetch changes up to 3b72a71413f8ef76c76e1dbff0273ac3b77f68da:

  xe: add PVC guc 70.6.4 and 70.8.0 (2023-07-31 14:16:51 -0700)

----
Daniele Ceraolo Spurio (1):
  xe: add PVC guc 70.6.4 and 70.8.0

 WHENCE|  11 +++
 xe/pvc_guc_70.6.4.bin | Bin 0 -> 525120 bytes
 xe/pvc_guc_70.bin | Bin 0 -> 533312 bytes
 3 files changed, 11 insertions(+)
 create mode 100644 xe/pvc_guc_70.6.4.bin
 create mode 100644 xe/pvc_guc_70.bin


[Intel-gfx] [CI] PR for PVC FWs for Xe

2023-08-02 Thread Daniele Ceraolo Spurio
The following changes since commit 253cc179d849fc82489773b2b553a49858d8725f:

  amdgpu: Update DMCUB for DCN314 & Yellow Carp (2023-07-31 11:22:02 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware xe_pvc

for you to fetch changes up to 3b72a71413f8ef76c76e1dbff0273ac3b77f68da:

  xe: add PVC guc 70.6.4 and 70.8.0 (2023-07-31 14:16:51 -0700)

----
Daniele Ceraolo Spurio (1):
  xe: add PVC guc 70.6.4 and 70.8.0

 WHENCE|  11 +++
 xe/pvc_guc_70.6.4.bin | Bin 0 -> 525120 bytes
 xe/pvc_guc_70.bin | Bin 0 -> 533312 bytes
 3 files changed, 11 insertions(+)
 create mode 100644 xe/pvc_guc_70.6.4.bin
 create mode 100644 xe/pvc_guc_70.bin


[Intel-gfx] [CI] PR for GSC FW 102.0.0.1636 for MTL

2023-07-21 Thread Daniele Ceraolo Spurio
The following changes since commit d3f66064cf43bd7338a79174bd0ff60c4ecbdf6d:

  Partially revert "amdgpu: DMCUB updates for DCN 3.1.4 and 3.1.5" (2023-07-07 
15:24:32 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_gsc_1636

for you to fetch changes up to 2a1f9984c8485eb56cb3825101a374750a8244f9:

  i915: add GSC 102.0.0.1636 for MTL (2023-07-21 10:02:39 -0700)

--------
Daniele Ceraolo Spurio (1):
  i915: add GSC 102.0.0.1636 for MTL

 WHENCE |   3 +++
 i915/mtl_gsc_1.bin | Bin 0 -> 1142784 bytes
 2 files changed, 3 insertions(+)
 create mode 100755 i915/mtl_gsc_1.bin


[Intel-gfx] [PATCH] drm/i915/huc: silence injected failure in the load via GSC path

2023-07-20 Thread Daniele Ceraolo Spurio
If we can't load the HuC due to an injected failure, we don't want
to throw and error and trip CI. Using the gt_probe_error macro for
logging ensure that the error is only printed if it wasn't explicitly
injected.

Link: https://gitlab.freedesktop.org/drm/intel/-/issues/7061
Signed-off-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 1ce07d7e8769..88215b5efe72 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 
 
 #include "gem/i915_gem_lmem.h"
+#include "gt/intel_gt_print.h"
 
 #include "i915_drv.h"
 
@@ -174,7 +175,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(>huc);
if (ret < 0)
-   drm_err(>drm, "failed to load huc via gsc 
%d\n", ret);
+   gt_probe_error(pxp->ctrl_gt, "failed to load 
huc via gsc %d\n", ret);
}
}
 
-- 
2.41.0



[Intel-gfx] [PR] GuC 70.8 for MTL and DG2 + HuC 8.5.1 for MTL

2023-07-20 Thread Daniele Ceraolo Spurio
The following changes since commit d3f66064cf43bd7338a79174bd0ff60c4ecbdf6d:

  Partially revert "amdgpu: DMCUB updates for DCN 3.1.4 and 3.1.5" (2023-07-07 
15:24:32 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware dg2_mtl_guc_70.8

for you to fetch changes up to 6f3a37f47d68d5e2108b98a900e4be910e8c7106:

  i915: update DG2 GuC to v70.8.0 (2023-07-20 10:14:57 -0700)

--------
Daniele Ceraolo Spurio (2):
  i915: update to GuC 70.8.0 and HuC 8.5.1 for MTL
  i915: update DG2 GuC to v70.8.0

 WHENCE   |   6 +++---
 i915/dg2_guc_70.bin  | Bin 369600 -> 385856 bytes
 i915/mtl_guc_70.bin  | Bin 303936 -> 308032 bytes
 i915/mtl_huc_gsc.bin | Bin 565248 -> 569344 bytes
 4 files changed, 3 insertions(+), 3 deletions(-)


[Intel-gfx] [CI] PR for MTL and DG2 FW updates

2023-07-19 Thread Daniele Ceraolo Spurio
This is a unified version of the 3 separate PRs that I've sent in the
last week. If there are no CI issues, this version will be sent to
linux-firmware instead of the other 3.

The following changes since commit d3f66064cf43bd7338a79174bd0ff60c4ecbdf6d:

  Partially revert "amdgpu: DMCUB updates for DCN 3.1.4 and 3.1.5" (2023-07-07 
15:24:32 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_fws_and_dg2_guc_70.8

for you to fetch changes up to 4e0915c88db08d0f601f3f797b0e63e7ddec0486:

  i915: update DG2 GuC to v70.8.0 (2023-07-19 11:05:35 -0700)

--------
Daniele Ceraolo Spurio (3):
  i915: update to GuC 70.8.0 and HuC 8.5.1 for MTL
  i915: add GSC 102.0.0.1625 for MTL
  i915: update DG2 GuC to v70.8.0

 WHENCE   |   9 ++---
 i915/dg2_guc_70.bin  | Bin 369600 -> 385856 bytes
 i915/mtl_gsc_1.bin   | Bin 0 -> 1142784 bytes
 i915/mtl_guc_70.bin  | Bin 303936 -> 308032 bytes
 i915/mtl_huc_gsc.bin | Bin 565248 -> 569344 bytes
 5 files changed, 6 insertions(+), 3 deletions(-)
 create mode 100755 i915/mtl_gsc_1.bin


[Intel-gfx] [PATCH v2] drm/i915/huc: check HuC and GuC version compatibility on MTL

2023-07-17 Thread Daniele Ceraolo Spurio
Due to a change in the auth flow on MTL, GuC 70.7.0 and newer will only
be able to authenticate HuC 8.5.1 and newer. The plan is to update the 2
binaries synchronously in linux-firmware so that the fw repo always has
a matching pair that works; still, it's better to check in the kernel so
we can print an error message and abort HuC loading if the binaries are
out of sync instead of failing the authentication.

v2: Add clarification comment, fix typo in commit msg, clean up variable
declaration (John)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
Reviewed-by: Andrzej Hajda  #v1
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 46 
 1 file changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 08e16017584b..7aadad5639c3 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -803,11 +803,57 @@ static int try_firmware_load(struct intel_uc_fw *uc_fw, 
const struct firmware **
return 0;
 }
 
+static int check_mtl_huc_guc_compatibility(struct intel_gt *gt,
+  struct intel_uc_fw_file 
*huc_selected)
+{
+   struct intel_uc_fw_file *guc_selected = >uc.guc.fw.file_selected;
+   struct intel_uc_fw_ver *huc_ver = _selected->ver;
+   struct intel_uc_fw_ver *guc_ver = _selected->ver;
+   bool new_huc, new_guc;
+
+   /* we can only do this check after having fetched both GuC and HuC */
+   GEM_BUG_ON(!huc_selected->path || !guc_selected->path);
+
+   /*
+* Due to changes in the authentication flow for MTL, HuC 8.5.1 or newer
+* requires GuC 70.7.0 or newer. Older HuC binaries will instead require
+* GuC < 70.7.0.
+*/
+   new_huc = huc_ver->major > 8 ||
+ (huc_ver->major == 8 && huc_ver->minor > 5) ||
+ (huc_ver->major == 8 && huc_ver->minor == 5 && huc_ver->patch 
>= 1);
+
+   new_guc = guc_ver->major > 70 ||
+ (guc_ver->major == 70 && guc_ver->minor >= 7);
+
+   if (new_huc != new_guc) {
+   UNEXPECTED(gt, "HuC %u.%u.%u is incompatible with GuC 
%u.%u.%u\n",
+  huc_ver->major, huc_ver->minor, huc_ver->patch,
+  guc_ver->major, guc_ver->minor, guc_ver->patch);
+   gt_info(gt, "MTL GuC 70.7.0+ and HuC 8.5.1+ don't work with 
older releases\n");
+   return -ENOEXEC;
+   }
+
+   return 0;
+}
+
 int intel_uc_check_file_version(struct intel_uc_fw *uc_fw, bool *old_ver)
 {
struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
struct intel_uc_fw_file *wanted = _fw->file_wanted;
struct intel_uc_fw_file *selected = _fw->file_selected;
+   int ret;
+
+   /*
+* MTL has some compatibility issues with early GuC/HuC binaries
+* not working with newer ones. This is specific to MTL and we
+* don't expect it to extend to other platforms.
+*/
+   if (IS_METEORLAKE(gt->i915) && uc_fw->type == INTEL_UC_FW_TYPE_HUC) {
+   ret = check_mtl_huc_guc_compatibility(gt, selected);
+   if (ret)
+   return ret;
+   }
 
if (!wanted->ver.major || !selected->ver.major)
return 0;
-- 
2.41.0



[Intel-gfx] [CI] PR for GSC 102.0.0.1625 for MTL

2023-07-17 Thread Daniele Ceraolo Spurio
The following changes since commit d3f66064cf43bd7338a79174bd0ff60c4ecbdf6d:

  Partially revert "amdgpu: DMCUB updates for DCN 3.1.4 and 3.1.5" (2023-07-07 
15:24:32 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_gsc_102.0.0.1625

for you to fetch changes up to e372271d839f921a147c03d10e8fd882a34c4890:

  i915: add GSC 102.0.0.1625 for MTL (2023-07-17 10:47:13 -0700)

--------
Daniele Ceraolo Spurio (1):
  i915: add GSC 102.0.0.1625 for MTL

 WHENCE |   3 +++
 i915/mtl_gsc_1.bin | Bin 0 -> 1142784 bytes
 2 files changed, 3 insertions(+)
 create mode 100755 i915/mtl_gsc_1.bin


[Intel-gfx] [CI] PR for GuC 70.8.0 for DG2

2023-07-14 Thread Daniele Ceraolo Spurio
The following changes since commit d3f66064cf43bd7338a79174bd0ff60c4ecbdf6d:

  Partially revert "amdgpu: DMCUB updates for DCN 3.1.4 and 3.1.5" (2023-07-07 
15:24:32 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware dg2_guc_7.8

for you to fetch changes up to 1e7fa2cfef80974642bfbaefc11e59e54244164a:

  i915: update DG2 GuC to v70.8.0 (2023-07-14 13:55:31 -0700)

--------
Daniele Ceraolo Spurio (1):
  i915: update DG2 GuC to v70.8.0

 WHENCE  |   2 +-
 i915/dg2_guc_70.bin | Bin 369600 -> 385856 bytes
 2 files changed, 1 insertion(+), 1 deletion(-)


[Intel-gfx] [PATCH] drm/i915/huc: check HuC and GuC version compatibility on MTL

2023-07-11 Thread Daniele Ceraolo Spurio
Due to a change in the auth flow on MTL, GuC 70.7.0 and newer will only
be able to authenticate HuC 8.5.1 and newer. The plan is to update the 2
binaries sinchronously in linux-firmware so that the fw repo always has
a matching pair that works; still, it's better to check in the kernel so
we can print an error message and abort HuC loading if the binaries are
out of sync instead of failing the authentication.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 42 
 1 file changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 08e16017584b..f0cc5bb47fa0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -803,11 +803,53 @@ static int try_firmware_load(struct intel_uc_fw *uc_fw, 
const struct firmware **
return 0;
 }
 
+static int check_mtl_huc_guc_compatibility(struct intel_gt *gt,
+  struct intel_uc_fw_file 
*huc_selected)
+{
+   struct intel_uc_fw_file *guc_selected = >uc.guc.fw.file_selected;
+   struct intel_uc_fw_ver *huc_ver = _selected->ver;
+   struct intel_uc_fw_ver *guc_ver = _selected->ver;
+   bool new_huc;
+   bool new_guc;
+
+   /* we can only do this check after having fetched both GuC and HuC */
+   GEM_BUG_ON(!huc_selected->path || !guc_selected->path);
+
+   /*
+* Due to changes in the authentication flow for MTL, HuC 8.5.1 or newer
+* requires GuC 70.7.0 or newer. Older HuC binaries will instead require
+* GuC < 70.7.0.
+*/
+   new_huc = huc_ver->major > 8 ||
+ (huc_ver->major == 8 && huc_ver->minor > 5) ||
+ (huc_ver->major == 8 && huc_ver->minor == 5 && huc_ver->patch 
>= 1);
+
+   new_guc = guc_ver->major > 70 ||
+ (guc_ver->major == 70 && guc_ver->minor >= 7);
+
+   if (new_huc != new_guc) {
+   UNEXPECTED(gt, "HuC %u.%u.%u is incompatible with GuC 
%u.%u.%u\n",
+  huc_ver->major, huc_ver->minor, huc_ver->patch,
+  guc_ver->major, guc_ver->minor, guc_ver->patch);
+   gt_info(gt, "MTL GuC 70.7.0+ and HuC 8.5.1+ don't work with 
older releases\n");
+   return -ENOEXEC;
+   }
+
+   return 0;
+}
+
 int intel_uc_check_file_version(struct intel_uc_fw *uc_fw, bool *old_ver)
 {
struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
struct intel_uc_fw_file *wanted = _fw->file_wanted;
struct intel_uc_fw_file *selected = _fw->file_selected;
+   int ret;
+
+   if (IS_METEORLAKE(gt->i915) && uc_fw->type == INTEL_UC_FW_TYPE_HUC) {
+   ret = check_mtl_huc_guc_compatibility(gt, selected);
+   if (ret)
+   return ret;
+   }
 
if (!wanted->ver.major || !selected->ver.major)
return 0;
-- 
2.41.0



[Intel-gfx] [CI] PR for GuC 70.8.0 and HuC 8.5.1 for MTL

2023-07-11 Thread Daniele Ceraolo Spurio
The following changes since commit d3f66064cf43bd7338a79174bd0ff60c4ecbdf6d:

  Partially revert "amdgpu: DMCUB updates for DCN 3.1.4 and 3.1.5" (2023-07-07 
15:24:32 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_guc_70.8_huc_v8.5.1

for you to fetch changes up to e05f81327fdf25f8c5508afdc1b0d3e2862a1663:

  i915: update to GuC 70.8.0 and HuC 8.5.1 for MTL (2023-07-11 12:01:10 -0700)

--------
Daniele Ceraolo Spurio (1):
  i915: update to GuC 70.8.0 and HuC 8.5.1 for MTL

 WHENCE   |   4 ++--
 i915/mtl_guc_70.bin  | Bin 303936 -> 308032 bytes
 i915/mtl_huc_gsc.bin | Bin 565248 -> 569344 bytes
 3 files changed, 2 insertions(+), 2 deletions(-)


[Intel-gfx] [topic/core-for-CI] drm/i915/gsc: define gsc fw

2023-06-28 Thread Daniele Ceraolo Spurio
Add FW definition and the matching override modparam.

The GSC FW has both a release version, based on platform and a rolling
counter, and a compatibility version, which is the one tracking
interface changes. Since what we care about is the interface, we use
the compatibility version in the binary names.

Same as with the GuC, a major version bump indicate a
backward-incompatible change, while a minor version bump indicates a
backward-compatible one, so we use only the former in the file name.

topic/core-for-CI note: the GSC team has asked us to hold off sending
the GSC FW to the linux-firmware repo, so we can't merge this to
drm-intel-gt-next yet. However, we do want to start running the GSC
code in CI, hence merging to topic/core-for-CI for now. See the gitlab
issue for expected FW availability.

References: https://gitlab.freedesktop.org/drm/intel/-/issues/8705
Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn 
Acked-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 32 ++--
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index d408856ae4c0..08e16017584b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -130,6 +130,17 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(BROXTON,  0, huc_mmp(bxt,  2, 0, 0)) \
fw_def(SKYLAKE,  0, huc_mmp(skl,  2, 0, 0))
 
+/*
+ * The GSC FW has multiple version (see intel_gsc_uc.h for details); since what
+ * we care about is the interface, we use the compatibility version in the
+ * binary names.
+ * Same as with the GuC, a major version bump indicate a
+ * backward-incompatible change, while a minor version bump indicates a
+ * backward-compatible one, so we use only the former in the file name.
+ */
+#define INTEL_GSC_FIRMWARE_DEFS(fw_def, gsc_def) \
+   fw_def(METEORLAKE,   0, gsc_def(mtl, 1, 0))
+
 /*
  * Set of macros for producing a list of filenames from the above table.
  */
@@ -165,6 +176,9 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 #define MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MMP(prefix_, "huc", major_, minor_, patch_)
 
+#define MAKE_GSC_FW_PATH(prefix_, major_, minor_) \
+   __MAKE_UC_FW_PATH_MAJOR(prefix_, "gsc", major_)
+
 /*
  * All blobs need to be declared via MODULE_FIRMWARE().
  * This first expansion of the table macros is solely to provide
@@ -175,6 +189,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 
 INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH_MAJOR, 
MAKE_GUC_FW_PATH_MMP)
 INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, 
MAKE_HUC_FW_PATH_MMP, MAKE_HUC_FW_PATH_GSC)
+INTEL_GSC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GSC_FW_PATH)
 
 /*
  * The next expansion of the table macros (in __uc_fw_auto_select below) 
provides
@@ -224,6 +239,10 @@ struct __packed uc_fw_blob {
 #define HUC_FW_BLOB_GSC(prefix_) \
UC_FW_BLOB_NEW(0, 0, 0, true, MAKE_HUC_FW_PATH_GSC(prefix_))
 
+#define GSC_FW_BLOB(prefix_, major_, minor_) \
+   UC_FW_BLOB_NEW(major_, minor_, 0, true, \
+  MAKE_GSC_FW_PATH(prefix_, major_, minor_))
+
 struct __packed uc_fw_platform_requirement {
enum intel_platform p;
u8 rev; /* first platform rev using this FW */
@@ -250,9 +269,14 @@ static const struct uc_fw_platform_requirement blobs_huc[] 
= {
INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, 
HUC_FW_BLOB_GSC)
 };
 
+static const struct uc_fw_platform_requirement blobs_gsc[] = {
+   INTEL_GSC_FIRMWARE_DEFS(MAKE_FW_LIST, GSC_FW_BLOB)
+};
+
 static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+   [INTEL_UC_FW_TYPE_GSC] = { blobs_gsc, ARRAY_SIZE(blobs_gsc) },
 };
 
 static void
@@ -265,14 +289,6 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
int i;
bool found;
 
-   /*
-* GSC FW support is still not fully in place, so we're not defining
-* the FW blob yet because we don't want the driver to attempt to load
-* it until we're ready for it.
-*/
-   if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
-   return;
-
/*
 * The only difference between the ADL GuC FWs is the HWConfig support.
 * ADL-N does not support HWConfig, so we should use the same binary as
-- 
2.41.0



[Intel-gfx] [CI] drm/i915/huc: Fix missing error code in intel_huc_init()

2023-06-14 Thread Daniele Ceraolo Spurio
From: Harshit Mogalapalli 

Smatch warns:
drivers/gpu/drm/i915/gt/uc/intel_huc.c:388
intel_huc_init() warn: missing error code 'err'

When the allocation of VMAs fail: The value of err is zero at this
point and it is passed to PTR_ERR and also finally returning zero which
is success instead of failure.

Fix this by adding the missing error code when VMA allocation fails.

Fixes: 08872cb13a71 ("drm/i915/mtl/huc: auth HuC via GSC")
Signed-off-by: Harshit Mogalapalli 
Reviewed-by: Daniele Ceraolo Spurio 
---

Re-sending for testing, because it looks like the original didn't make
it to intel-gfx and patchwork.

 drivers/gpu/drm/i915/gt/uc/intel_huc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index d3a7219e9ed1..bb95bdd1c3f9 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -384,6 +384,7 @@ int intel_huc_init(struct intel_huc *huc)
 
vma = intel_guc_allocate_vma(>uc.guc, 
PXP43_HUC_AUTH_INOUT_SIZE * 2);
if (IS_ERR(vma)) {
+   err = PTR_ERR(vma);
huc_info(huc, "Failed to allocate heci pkt\n");
goto out;
}
-- 
2.40.0



[Intel-gfx] [CI] drm/i915/gsc: define gsc fw

2023-06-13 Thread Daniele Ceraolo Spurio
Add FW definition and the matching override modparam.

The GSC FW has both a release version, based on platform and a rolling
counter, and a compatibility version, which is the one tracking
interface changes. Since what we care about is the interface, we use
the compatibility version in the binary names.

Same as with the GuC, a major version bump indicate a
backward-incompatible change, while a minor version bump indicates a
backward-compatible one, so we use only the former in the file name.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn 
---

The GSC team has asked us to hold off sending the GSC FW to the
linux-firmware repo, so we can't merge this to drm-intel-gt-next yet.
However, we do want to start running the GSC code in CI, so this needs
to be merged to topic/core-for-CI for now.

 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 32 ++--
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index d408856ae4c0..08e16017584b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -130,6 +130,17 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(BROXTON,  0, huc_mmp(bxt,  2, 0, 0)) \
fw_def(SKYLAKE,  0, huc_mmp(skl,  2, 0, 0))
 
+/*
+ * The GSC FW has multiple version (see intel_gsc_uc.h for details); since what
+ * we care about is the interface, we use the compatibility version in the
+ * binary names.
+ * Same as with the GuC, a major version bump indicate a
+ * backward-incompatible change, while a minor version bump indicates a
+ * backward-compatible one, so we use only the former in the file name.
+ */
+#define INTEL_GSC_FIRMWARE_DEFS(fw_def, gsc_def) \
+   fw_def(METEORLAKE,   0, gsc_def(mtl, 1, 0))
+
 /*
  * Set of macros for producing a list of filenames from the above table.
  */
@@ -165,6 +176,9 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 #define MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MMP(prefix_, "huc", major_, minor_, patch_)
 
+#define MAKE_GSC_FW_PATH(prefix_, major_, minor_) \
+   __MAKE_UC_FW_PATH_MAJOR(prefix_, "gsc", major_)
+
 /*
  * All blobs need to be declared via MODULE_FIRMWARE().
  * This first expansion of the table macros is solely to provide
@@ -175,6 +189,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 
 INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH_MAJOR, 
MAKE_GUC_FW_PATH_MMP)
 INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, 
MAKE_HUC_FW_PATH_MMP, MAKE_HUC_FW_PATH_GSC)
+INTEL_GSC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GSC_FW_PATH)
 
 /*
  * The next expansion of the table macros (in __uc_fw_auto_select below) 
provides
@@ -224,6 +239,10 @@ struct __packed uc_fw_blob {
 #define HUC_FW_BLOB_GSC(prefix_) \
UC_FW_BLOB_NEW(0, 0, 0, true, MAKE_HUC_FW_PATH_GSC(prefix_))
 
+#define GSC_FW_BLOB(prefix_, major_, minor_) \
+   UC_FW_BLOB_NEW(major_, minor_, 0, true, \
+  MAKE_GSC_FW_PATH(prefix_, major_, minor_))
+
 struct __packed uc_fw_platform_requirement {
enum intel_platform p;
u8 rev; /* first platform rev using this FW */
@@ -250,9 +269,14 @@ static const struct uc_fw_platform_requirement blobs_huc[] 
= {
INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, 
HUC_FW_BLOB_GSC)
 };
 
+static const struct uc_fw_platform_requirement blobs_gsc[] = {
+   INTEL_GSC_FIRMWARE_DEFS(MAKE_FW_LIST, GSC_FW_BLOB)
+};
+
 static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+   [INTEL_UC_FW_TYPE_GSC] = { blobs_gsc, ARRAY_SIZE(blobs_gsc) },
 };
 
 static void
@@ -265,14 +289,6 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
int i;
bool found;
 
-   /*
-* GSC FW support is still not fully in place, so we're not defining
-* the FW blob yet because we don't want the driver to attempt to load
-* it until we're ready for it.
-*/
-   if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
-   return;
-
/*
 * The only difference between the ADL GuC FWs is the HWConfig support.
 * ADL-N does not support HWConfig, so we should use the same binary as
-- 
2.40.0



[Intel-gfx] [CI 4/4] drm/i915/mtl/gsc: Add a gsc_info debugfs

2023-06-12 Thread Daniele Ceraolo Spurio
Add a new debugfs to dump information about the GSC. This includes:

- the FW path and SW tracking status;
- the release, security and compatibility versions;
- the HECI1 status registers.

Note that those are the same registers that the mei driver dumps in
their own status sysfs on DG2 (where mei owns the GSC).

To make it simpler to loop through the status register, the code has
been update to use a PICK macro and the existing code using the regs had
been adapted to match.

v2: fix includes and copyright dates (Alan)
v3: actually fix the includes

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn 
---
 drivers/gpu/drm/i915/Makefile |  3 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 28 +--
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 47 ++-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  2 +
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c | 39 +++
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h | 14 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  6 +--
 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c |  2 +
 drivers/gpu/drm/i915/i915_reg.h   | 26 +-
 9 files changed, 143 insertions(+), 24 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 789dce9e2608..2be9dd960540 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -192,7 +192,8 @@ i915-y += \
  gt/uc/intel_gsc_fw.o \
  gt/uc/intel_gsc_proxy.o \
  gt/uc/intel_gsc_uc.o \
- gt/uc/intel_gsc_uc_heci_cmd_submit.o\
+ gt/uc/intel_gsc_uc_debugfs.o \
+ gt/uc/intel_gsc_uc_heci_cmd_submit.o \
  gt/uc/intel_guc.o \
  gt/uc/intel_guc_ads.o \
  gt/uc/intel_guc_capture.o \
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 3b4ff3e31aed..856de9af1e3a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -12,19 +12,14 @@
 #include "intel_gsc_binary_headers.h"
 #include "intel_gsc_fw.h"
 #include "intel_gsc_uc_heci_cmd_submit.h"
-
-#define GSC_FW_STATUS_REG  _MMIO(0x116C40)
-#define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
-#define   GSC_FW_CURRENT_STATE_RESET   0
-#define   GSC_FW_PROXY_STATE_NORMAL5
-#define GSC_FW_INIT_COMPLETE_BIT   REG_BIT(9)
+#include "i915_reg.h"
 
 static bool gsc_is_in_reset(struct intel_uncore *uncore)
 {
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   u32 fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
-   return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
-  GSC_FW_CURRENT_STATE_RESET;
+   return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE, fw_status) ==
+   HECI1_FWSTS1_CURRENT_STATE_RESET;
 }
 
 static u32 gsc_uc_get_fw_status(struct intel_uncore *uncore)
@@ -33,21 +28,22 @@ static u32 gsc_uc_get_fw_status(struct intel_uncore *uncore)
u32 fw_status = 0;
 
with_intel_runtime_pm(uncore->rpm, wakeref)
-   fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
return fw_status;
 }
 
 bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
 {
-   return REG_FIELD_GET(GSC_FW_CURRENT_STATE,
+   return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE,
 gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore)) ==
-  GSC_FW_PROXY_STATE_NORMAL;
+  HECI1_FWSTS1_PROXY_STATE_NORMAL;
 }
 
 bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
 {
-   return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore) & 
GSC_FW_INIT_COMPLETE_BIT;
+   return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore) &
+  HECI1_FWSTS1_INIT_COMPLETE;
 }
 
 static inline u32 cpd_entry_offset(const struct intel_gsc_cpd_entry *entry)
@@ -298,9 +294,9 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
 static int gsc_fw_wait(struct intel_gt *gt)
 {
return intel_wait_for_register(gt->uncore,
-  GSC_FW_STATUS_REG,
-  GSC_FW_INIT_COMPLETE_BIT,
-  GSC_FW_INIT_COMPLETE_BIT,
+  HECI_FWSTS(MTL_GSC_HECI1_BASE, 1),
+  HECI1_FWSTS1_INIT_COMPLETE,
+  HECI1_FWSTS1_INIT_COMPLETE,
   500);
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel

[Intel-gfx] [CI 2/4] drm/i915/mtl/gsc: extract release and security versions from the gsc binary

2023-06-12 Thread Daniele Ceraolo Spurio
The release and security versions of the GSC binary are not used at
runtime to decide interface compatibility (there is a separate version
for that), but they're still useful for debug, so it is still worth
extracting them and printing them out in dmesg.

To get to these version, we need to navigate through various headers in
the binary. See in-code comment for details.

v2: fix and improve size checks when crawling the binary header, add
comment about the different version, wrap the partition base/offset
pairs in the GSC header in a struct (Alan)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Reviewed-by: Alan Previn 
---
 .../drm/i915/gt/uc/intel_gsc_binary_headers.h |  75 -
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 157 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  18 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c |  13 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  |  30 +++-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |   3 +
 7 files changed, 271 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
index 714f0c256118..6d009a905269 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
@@ -8,6 +8,74 @@
 
 #include 
 
+struct intel_gsc_version {
+   u16 major;
+   u16 minor;
+   u16 hotfix;
+   u16 build;
+} __packed;
+
+struct intel_gsc_partition {
+   u32 offset;
+   u32 size;
+} __packed;
+
+struct intel_gsc_layout_pointers {
+   u8 rom_bypass_vector[16];
+
+   /* size of pointers layout not including ROM bypass vector */
+   u16 size;
+
+   /*
+* bit0: Backup copy of layout pointers exist
+* bits1-15: reserved
+*/
+   u8 flags;
+
+   u8 reserved;
+
+   u32 crc32;
+
+   struct intel_gsc_partition datap;
+   struct intel_gsc_partition boot1;
+   struct intel_gsc_partition boot2;
+   struct intel_gsc_partition boot3;
+   struct intel_gsc_partition boot4;
+   struct intel_gsc_partition boot5;
+   struct intel_gsc_partition temp_pages;
+} __packed;
+
+/* Boot partition structures */
+struct intel_gsc_bpdt_header {
+   u32 signature;
+#define INTEL_GSC_BPDT_HEADER_SIGNATURE 0x55AA
+
+   u16 descriptor_count; /* num of entries after the header */
+
+   u8 version;
+   u8 configuration;
+
+   u32 crc32;
+
+   u32 build_version;
+   struct intel_gsc_version tool_version;
+} __packed;
+
+struct intel_gsc_bpdt_entry {
+   /*
+* Bits 0-15: BPDT entry type
+* Bits 16-17: reserved
+* Bit 18: code sub-partition
+* Bits 19-31: reserved
+*/
+   u32 type;
+#define INTEL_GSC_BPDT_ENTRY_TYPE_MASK GENMASK(15, 0)
+#define INTEL_GSC_BPDT_ENTRY_TYPE_GSC_RBE 0x1
+
+   u32 sub_partition_offset; /* from the base of the BPDT header */
+   u32 sub_partition_size;
+} __packed;
+
 /* Code partition directory (CPD) structures */
 struct intel_gsc_cpd_header_v2 {
u32 header_marker;
@@ -44,13 +112,6 @@ struct intel_gsc_cpd_entry {
u8 reserved[4];
 } __packed;
 
-struct intel_gsc_version {
-   u16 major;
-   u16 minor;
-   u16 hotfix;
-   u16 build;
-} __packed;
-
 struct intel_gsc_manifest_header {
u32 header_type; /* 0x4 for manifest type */
u32 header_length; /* in dwords */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index e6fa7745ff77..4c728ba6f4f7 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -9,6 +9,7 @@
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_print.h"
 #include "gt/intel_ring.h"
+#include "intel_gsc_binary_headers.h"
 #include "intel_gsc_fw.h"
 
 #define GSC_FW_STATUS_REG  _MMIO(0x116C40)
@@ -48,6 +49,156 @@ bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
return gsc_uc_get_fw_status(gsc_uc_to_gt(gsc)->uncore) & 
GSC_FW_INIT_COMPLETE_BIT;
 }
 
+static inline u32 cpd_entry_offset(const struct intel_gsc_cpd_entry *entry)
+{
+   return entry->offset & INTEL_GSC_CPD_ENTRY_OFFSET_MASK;
+}
+
+int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const void *data, 
size_t size)
+{
+   struct intel_gsc_uc *gsc = container_of(gsc_fw, struct intel_gsc_uc, 
fw);
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   const struct intel_gsc_layout_pointers *layout = data;
+   const struct intel_gsc_bpdt_header *bpdt_header = NULL;
+   const struct intel_gsc_bpdt_entry *bpdt_entry = NULL;
+   const struct intel_gsc_cpd_header_v2 *cpd_header = NULL;
+   const struct intel_gsc_cpd_entry *cpd_entry = NULL;
+   const struct intel_gsc_manifest_header *ma

[Intel-gfx] [CI 3/4] drm/i915/mtl/gsc: query the GSC FW for its compatibility version

2023-06-12 Thread Daniele Ceraolo Spurio
The compatibility version is queried via an MKHI command. Right now, the
only existing interface is 1.0
This is basically the interface version for the GSC FW, so the plan is
to use it as the main tracked version, including for the binary naming
in the fetch code.

v2: use define for the object size (Alan)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn 
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 95 ++-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 50 ++
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |  1 +
 4 files changed, 127 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 4c728ba6f4f7..3b4ff3e31aed 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -11,6 +11,7 @@
 #include "gt/intel_ring.h"
 #include "intel_gsc_binary_headers.h"
 #include "intel_gsc_fw.h"
+#include "intel_gsc_uc_heci_cmd_submit.h"
 
 #define GSC_FW_STATUS_REG  _MMIO(0x116C40)
 #define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
@@ -303,6 +304,88 @@ static int gsc_fw_wait(struct intel_gt *gt)
   500);
 }
 
+struct intel_gsc_mkhi_header {
+   u8  group_id;
+#define MKHI_GROUP_ID_GFX_SRV 0x30
+
+   u8  command;
+#define MKHI_GFX_SRV_GET_HOST_COMPATIBILITY_VERSION (0x42)
+
+   u8  reserved;
+   u8  result;
+} __packed;
+
+struct mtl_gsc_ver_msg_in {
+   struct intel_gsc_mtl_header header;
+   struct intel_gsc_mkhi_header mkhi;
+} __packed;
+
+struct mtl_gsc_ver_msg_out {
+   struct intel_gsc_mtl_header header;
+   struct intel_gsc_mkhi_header mkhi;
+   u16 proj_major;
+   u16 compat_major;
+   u16 compat_minor;
+   u16 reserved[5];
+} __packed;
+
+#define GSC_VER_PKT_SZ SZ_4K
+
+static int gsc_fw_query_compatibility_version(struct intel_gsc_uc *gsc)
+{
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   struct mtl_gsc_ver_msg_in *msg_in;
+   struct mtl_gsc_ver_msg_out *msg_out;
+   struct i915_vma *vma;
+   u64 offset;
+   void *vaddr;
+   int err;
+
+   err = intel_guc_allocate_and_map_vma(>uc.guc, GSC_VER_PKT_SZ * 2,
+, );
+   if (err) {
+   gt_err(gt, "failed to allocate vma for GSC version query\n");
+   return err;
+   }
+
+   offset = i915_ggtt_offset(vma);
+   msg_in = vaddr;
+   msg_out = vaddr + GSC_VER_PKT_SZ;
+
+   intel_gsc_uc_heci_cmd_emit_mtl_header(_in->header,
+ HECI_MEADDRESS_MKHI,
+ sizeof(*msg_in), 0);
+   msg_in->mkhi.group_id = MKHI_GROUP_ID_GFX_SRV;
+   msg_in->mkhi.command = MKHI_GFX_SRV_GET_HOST_COMPATIBILITY_VERSION;
+
+   err = intel_gsc_uc_heci_cmd_submit_packet(>uc.gsc,
+ offset,
+ sizeof(*msg_in),
+ offset + GSC_VER_PKT_SZ,
+ GSC_VER_PKT_SZ);
+   if (err) {
+   gt_err(gt,
+  "failed to submit GSC request for compatibility version: 
%d\n",
+  err);
+   goto out_vma;
+   }
+
+   if (msg_out->header.message_size != sizeof(*msg_out)) {
+   gt_err(gt, "invalid GSC reply length %u [expected %zu], s=0x%x, 
f=0x%x, r=0x%x\n",
+  msg_out->header.message_size, sizeof(*msg_out),
+  msg_out->header.status, msg_out->header.flags, 
msg_out->mkhi.result);
+   err = -EPROTO;
+   goto out_vma;
+   }
+
+   gsc->fw.file_selected.ver.major = msg_out->compat_major;
+   gsc->fw.file_selected.ver.minor = msg_out->compat_minor;
+
+out_vma:
+   i915_vma_unpin_and_release(, I915_VMA_RELEASE_MAP);
+   return err;
+}
+
 int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc)
 {
struct intel_gt *gt = gsc_uc_to_gt(gsc);
@@ -360,11 +443,21 @@ int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc)
if (err)
goto fail;
 
+   err = gsc_fw_query_compatibility_version(gsc);
+   if (err)
+   goto fail;
+
+   /* we only support compatibility version 1.0 at the moment */
+   err = intel_uc_check_file_version(gsc_fw, NULL);
+   if (err)
+   goto fail;
+
/* FW is not fully operational until we enable SW proxy */
intel_uc_fw_change_status(gsc_fw, INTEL_UC_FIRMWARE_TRANSFERRED);
 
-   gt_info(gt, "Loaded GSC firmware %s (r%u.%u.%u.%u, svn%u)\n",
+   gt_info(gt, &quo

[Intel-gfx] [CI 1/4] drm/i915/gsc: fixes and updates for GSC memory allocation

2023-06-12 Thread Daniele Ceraolo Spurio
A few fixes/updates are required around the GSC memory allocation and it
is easier to do them all at the same time. The changes are as follows:

1 - Switch the memory allocation to stolen memory. We need to avoid
accesses from GSC FW to normal memory after the suspend function has
completed and to do so we can either switch to using stolen or make sure
the GSC is gone to sleep before the end of the suspend function. Given
that the GSC waits for a bit before going idle even if there are no
pending operations, it is easier and quicker to just use stolen memory.

2 - Reduce the GSC allocation size to 4MBs, which is the POR requirement.
The 8MBs were needed only for early FW and I had misunderstood that as
being the expected POR size when I sent the original patch.

3 - Perma-map the GSC allocation. This isn't required immediately, but it
will be needed later to be able to quickly extract the GSC logs, which are
inside the allocation. Since the mapping code needs to be rewritten due to
switching to stolen, it makes sense to do the switch immediately to avoid
having to change it again later.

Note that the explicit setting of CACHE_NONE for Wa_22016122933 has been
dropped because that's the default setting for stolen memory on !LLC
platforms.

v2: only memset the memory we're not overwriting (Alan)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Cc: Vinay Belgaumkar 
Reviewed-by: Alan Previn 
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 29 ++---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 77 ---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  1 +
 3 files changed, 75 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 60e9c6c9e775..e6fa7745ff77 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -3,6 +3,7 @@
  * Copyright © 2022 Intel Corporation
  */
 
+#include "gem/i915_gem_lmem.h"
 #include "gt/intel_engine_pm.h"
 #include "gt/intel_gpu_commands.h"
 #include "gt/intel_gt.h"
@@ -115,38 +116,21 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
 {
struct intel_gt *gt = gsc_uc_to_gt(gsc);
struct drm_i915_private *i915 = gt->i915;
-   struct drm_i915_gem_object *obj;
-   void *src, *dst;
+   void *src;
 
if (!gsc->local)
return -ENODEV;
 
-   obj = gsc->local->obj;
-
-   if (obj->base.size < gsc->fw.size)
+   if (gsc->local->size < gsc->fw.size)
return -ENOSPC;
 
-   /*
-* Wa_22016122933: For MTL the shared memory needs to be mapped
-* as WC on CPU side and UC (PAT index 2) on GPU side
-*/
-   if (IS_METEORLAKE(i915))
-   i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
-
-   dst = i915_gem_object_pin_map_unlocked(obj,
-  i915_coherent_map_type(i915, 
obj, true));
-   if (IS_ERR(dst))
-   return PTR_ERR(dst);
-
src = i915_gem_object_pin_map_unlocked(gsc->fw.obj,
   i915_coherent_map_type(i915, 
gsc->fw.obj, true));
-   if (IS_ERR(src)) {
-   i915_gem_object_unpin_map(obj);
+   if (IS_ERR(src))
return PTR_ERR(src);
-   }
 
-   memset(dst, 0, obj->base.size);
-   memcpy(dst, src, gsc->fw.size);
+   memcpy_toio(gsc->local_vaddr, src, gsc->fw.size);
+   memset_io(gsc->local_vaddr + gsc->fw.size, 0, gsc->local->size - 
gsc->fw.size);
 
/*
 * Wa_22016122933: Making sure the data in dst is
@@ -155,7 +139,6 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
intel_guc_write_barrier(>uc.guc);
 
i915_gem_object_unpin_map(gsc->fw.obj);
-   i915_gem_object_unpin_map(obj);
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index c659cc01f32f..4fe639a80564 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -133,26 +133,85 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
}
 }
 
+static int gsc_allocate_and_map_vma(struct intel_gsc_uc *gsc, u32 size)
+{
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   struct drm_i915_gem_object *obj;
+   struct i915_vma *vma;
+   void __iomem *vaddr;
+   int ret = 0;
+
+   /*
+* The GSC FW doesn't immediately suspend after becoming idle, so there
+* is a chance that it could still be awake after we successfully
+* return from the  pci suspend function, even if there are no pending
+* operations.
+* The FW might therefore try to access memory for its suspend operation
+* after the kernel has completed the HW suspend flow; this c

[Intel-gfx] [CI 0/4] drm/i915: GSC FW support for MTL

2023-06-12 Thread Daniele Ceraolo Spurio
Last chunk of the required support for the GSC FW. This includes some
fixes to the GSC memory allocation, FW idefinition and version
management, plus a new debugfs for debug information.

The FW team has asked to not send the current FW blob to
linux-firmware yet, as they're planning some updates. Therefore, the
FW definition patch will be sent separately and merged to the
topic/core-for-CI branch.
The series has already been tested with the FW definition patch applied
(see CI results on previous rev), so this is a re-send for CI to make
sure everything works without that patch before merging.

Daniele Ceraolo Spurio (4):
  drm/i915/gsc: fixes and updates for GSC memory allocation
  drm/i915/mtl/gsc: extract release and security versions from the gsc
binary
  drm/i915/mtl/gsc: query the GSC FW for its compatibility version
  drm/i915/mtl/gsc: Add a gsc_info debugfs

 drivers/gpu/drm/i915/Makefile |   3 +-
 .../drm/i915/gt/uc/intel_gsc_binary_headers.h |  75 -
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 307 +++---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 124 ++-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  21 ++
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c |  39 +++
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h |  14 +
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|   6 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c |  13 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  |  80 +++--
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |   4 +
 drivers/gpu/drm/i915/i915_reg.h   |  26 +-
 15 files changed, 615 insertions(+), 102 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h

-- 
2.40.0



[Intel-gfx] PR for HuC v8.5.0 for MTL

2023-06-06 Thread Daniele Ceraolo Spurio
The following changes since commit fc90c59beebd551dde5fe5eb3e76d36651ba08fb:

  Merge branch 'db410c' of https://github.com/lumag/linux-firmware (2023-05-31 
07:35:15 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_huc_v8.5.0

for you to fetch changes up to 5de33fb45cee8d83abfe17e9e85bd74d51a2653f:

  i915: Add HuC v8.5.0 for MTL (2023-06-06 09:24:40 -0700)


Daniele Ceraolo Spurio (1):
  i915: Add HuC v8.5.0 for MTL

 WHENCE   |   3 +++
 i915/mtl_huc_gsc.bin | Bin 0 -> 565248 bytes
 2 files changed, 3 insertions(+)
 create mode 100755 i915/mtl_huc_gsc.bin


[Intel-gfx] [PATCH v3] drm/i915/mtl/gsc: Add a gsc_info debugfs

2023-06-05 Thread Daniele Ceraolo Spurio
Add a new debugfs to dump information about the GSC. This includes:

- the FW path and SW tracking status;
- the release, security and compatibility versions;
- the HECI1 status registers.

Note that those are the same registers that the mei driver dumps in
their own status sysfs on DG2 (where mei owns the GSC).

To make it simpler to loop through the status register, the code has
been update to use a PICK macro and the existing code using the regs had
been adapted to match.

v2: fix includes and copyright dates (Alan)
v3: actually fix the includes

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/Makefile |  3 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 29 +--
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 48 ++-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  2 +
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c | 39 +++
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h | 14 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  6 +--
 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c |  2 +
 drivers/gpu/drm/i915/i915_reg.h   | 26 +-
 9 files changed, 144 insertions(+), 25 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1c9ed4c52760..b6c54fb0b4cc 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -192,7 +192,8 @@ i915-y += \
  gt/uc/intel_gsc_fw.o \
  gt/uc/intel_gsc_proxy.o \
  gt/uc/intel_gsc_uc.o \
- gt/uc/intel_gsc_uc_heci_cmd_submit.o\
+ gt/uc/intel_gsc_uc_debugfs.o \
+ gt/uc/intel_gsc_uc_heci_cmd_submit.o \
  gt/uc/intel_guc.o \
  gt/uc/intel_guc_ads.o \
  gt/uc/intel_guc_capture.o \
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 7d48d59011c8..b069459e2596 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -12,36 +12,31 @@
 #include "intel_gsc_binary_headers.h"
 #include "intel_gsc_fw.h"
 #include "intel_gsc_uc_heci_cmd_submit.h"
-
-#define GSC_FW_STATUS_REG  _MMIO(0x116C40)
-#define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
-#define   GSC_FW_CURRENT_STATE_RESET   0
-#define   GSC_FW_PROXY_STATE_NORMAL5
-#define GSC_FW_INIT_COMPLETE_BIT   REG_BIT(9)
+#include "i915_reg.h"
 
 static bool gsc_is_in_reset(struct intel_uncore *uncore)
 {
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   u32 fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
-   return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
-  GSC_FW_CURRENT_STATE_RESET;
+   return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE, fw_status) ==
+   HECI1_FWSTS1_CURRENT_STATE_RESET;
 }
 
 bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
 {
struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   u32 fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
-   return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
-  GSC_FW_PROXY_STATE_NORMAL;
+   return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE, fw_status) ==
+  HECI1_FWSTS1_PROXY_STATE_NORMAL;
 }
 
 bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
 {
struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   u32 fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
-   return fw_status & GSC_FW_INIT_COMPLETE_BIT;
+   return fw_status & HECI1_FWSTS1_INIT_COMPLETE;
 }
 
 static inline u32 cpd_entry_offset(const struct intel_gsc_cpd_entry *entry)
@@ -293,9 +288,9 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
 static int gsc_fw_wait(struct intel_gt *gt)
 {
return intel_wait_for_register(gt->uncore,
-  GSC_FW_STATUS_REG,
-  GSC_FW_INIT_COMPLETE_BIT,
-  GSC_FW_INIT_COMPLETE_BIT,
+  HECI_FWSTS(MTL_GSC_HECI1_BASE, 1),
+  HECI1_FWSTS1_INIT_COMPLETE,
+  HECI1_FWSTS1_INIT_COMPLETE,
   500);
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index 4fe639a80564..6826aa5d6985 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@

[Intel-gfx] [PATCH v2 5/5] drm/i915/gsc: define gsc fw

2023-06-05 Thread Daniele Ceraolo Spurio
Add FW definition and the matching override modparam.

The GSC FW has both a release version, based on platform and a rolling
counter, and a compatibility version, which is the one tracking
interface changes. Since what we care about is the interface, we use
the compatibility version in the binary names.

Same as with the GuC, a major version bump indicate a
backward-incompatible change, while a minor version bump indicates a
backward-compatible one, so we use only the former in the file name.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 32 ++--
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index d408856ae4c0..08e16017584b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -130,6 +130,17 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(BROXTON,  0, huc_mmp(bxt,  2, 0, 0)) \
fw_def(SKYLAKE,  0, huc_mmp(skl,  2, 0, 0))
 
+/*
+ * The GSC FW has multiple version (see intel_gsc_uc.h for details); since what
+ * we care about is the interface, we use the compatibility version in the
+ * binary names.
+ * Same as with the GuC, a major version bump indicate a
+ * backward-incompatible change, while a minor version bump indicates a
+ * backward-compatible one, so we use only the former in the file name.
+ */
+#define INTEL_GSC_FIRMWARE_DEFS(fw_def, gsc_def) \
+   fw_def(METEORLAKE,   0, gsc_def(mtl, 1, 0))
+
 /*
  * Set of macros for producing a list of filenames from the above table.
  */
@@ -165,6 +176,9 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 #define MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MMP(prefix_, "huc", major_, minor_, patch_)
 
+#define MAKE_GSC_FW_PATH(prefix_, major_, minor_) \
+   __MAKE_UC_FW_PATH_MAJOR(prefix_, "gsc", major_)
+
 /*
  * All blobs need to be declared via MODULE_FIRMWARE().
  * This first expansion of the table macros is solely to provide
@@ -175,6 +189,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 
 INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH_MAJOR, 
MAKE_GUC_FW_PATH_MMP)
 INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, 
MAKE_HUC_FW_PATH_MMP, MAKE_HUC_FW_PATH_GSC)
+INTEL_GSC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GSC_FW_PATH)
 
 /*
  * The next expansion of the table macros (in __uc_fw_auto_select below) 
provides
@@ -224,6 +239,10 @@ struct __packed uc_fw_blob {
 #define HUC_FW_BLOB_GSC(prefix_) \
UC_FW_BLOB_NEW(0, 0, 0, true, MAKE_HUC_FW_PATH_GSC(prefix_))
 
+#define GSC_FW_BLOB(prefix_, major_, minor_) \
+   UC_FW_BLOB_NEW(major_, minor_, 0, true, \
+  MAKE_GSC_FW_PATH(prefix_, major_, minor_))
+
 struct __packed uc_fw_platform_requirement {
enum intel_platform p;
u8 rev; /* first platform rev using this FW */
@@ -250,9 +269,14 @@ static const struct uc_fw_platform_requirement blobs_huc[] 
= {
INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, 
HUC_FW_BLOB_GSC)
 };
 
+static const struct uc_fw_platform_requirement blobs_gsc[] = {
+   INTEL_GSC_FIRMWARE_DEFS(MAKE_FW_LIST, GSC_FW_BLOB)
+};
+
 static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+   [INTEL_UC_FW_TYPE_GSC] = { blobs_gsc, ARRAY_SIZE(blobs_gsc) },
 };
 
 static void
@@ -265,14 +289,6 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
int i;
bool found;
 
-   /*
-* GSC FW support is still not fully in place, so we're not defining
-* the FW blob yet because we don't want the driver to attempt to load
-* it until we're ready for it.
-*/
-   if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
-   return;
-
/*
 * The only difference between the ADL GuC FWs is the HWConfig support.
 * ADL-N does not support HWConfig, so we should use the same binary as
-- 
2.40.0



[Intel-gfx] [PATCH v2 3/5] drm/i915/mtl/gsc: query the GSC FW for its compatibility version

2023-06-05 Thread Daniele Ceraolo Spurio
The compatibility version is queried via an MKHI command. Right now, the
only existing interface is 1.0
This is basically the interface version for the GSC FW, so the plan is
to use it as the main tracked version, including for the binary naming
in the fetch code.

v2: use define for the object size (Alan)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn  #v1
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 95 ++-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 50 ++
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |  1 +
 4 files changed, 127 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 953c155b5170..7d48d59011c8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -11,6 +11,7 @@
 #include "gt/intel_ring.h"
 #include "intel_gsc_binary_headers.h"
 #include "intel_gsc_fw.h"
+#include "intel_gsc_uc_heci_cmd_submit.h"
 
 #define GSC_FW_STATUS_REG  _MMIO(0x116C40)
 #define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
@@ -298,6 +299,88 @@ static int gsc_fw_wait(struct intel_gt *gt)
   500);
 }
 
+struct intel_gsc_mkhi_header {
+   u8  group_id;
+#define MKHI_GROUP_ID_GFX_SRV 0x30
+
+   u8  command;
+#define MKHI_GFX_SRV_GET_HOST_COMPATIBILITY_VERSION (0x42)
+
+   u8  reserved;
+   u8  result;
+} __packed;
+
+struct mtl_gsc_ver_msg_in {
+   struct intel_gsc_mtl_header header;
+   struct intel_gsc_mkhi_header mkhi;
+} __packed;
+
+struct mtl_gsc_ver_msg_out {
+   struct intel_gsc_mtl_header header;
+   struct intel_gsc_mkhi_header mkhi;
+   u16 proj_major;
+   u16 compat_major;
+   u16 compat_minor;
+   u16 reserved[5];
+} __packed;
+
+#define GSC_VER_PKT_SZ SZ_4K
+
+static int gsc_fw_query_compatibility_version(struct intel_gsc_uc *gsc)
+{
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   struct mtl_gsc_ver_msg_in *msg_in;
+   struct mtl_gsc_ver_msg_out *msg_out;
+   struct i915_vma *vma;
+   u64 offset;
+   void *vaddr;
+   int err;
+
+   err = intel_guc_allocate_and_map_vma(>uc.guc, GSC_VER_PKT_SZ * 2,
+, );
+   if (err) {
+   gt_err(gt, "failed to allocate vma for GSC version query\n");
+   return err;
+   }
+
+   offset = i915_ggtt_offset(vma);
+   msg_in = vaddr;
+   msg_out = vaddr + GSC_VER_PKT_SZ;
+
+   intel_gsc_uc_heci_cmd_emit_mtl_header(_in->header,
+ HECI_MEADDRESS_MKHI,
+ sizeof(*msg_in), 0);
+   msg_in->mkhi.group_id = MKHI_GROUP_ID_GFX_SRV;
+   msg_in->mkhi.command = MKHI_GFX_SRV_GET_HOST_COMPATIBILITY_VERSION;
+
+   err = intel_gsc_uc_heci_cmd_submit_packet(>uc.gsc,
+ offset,
+ sizeof(*msg_in),
+ offset + GSC_VER_PKT_SZ,
+ GSC_VER_PKT_SZ);
+   if (err) {
+   gt_err(gt,
+  "failed to submit GSC request for compatibility version: 
%d\n",
+  err);
+   goto out_vma;
+   }
+
+   if (msg_out->header.message_size != sizeof(*msg_out)) {
+   gt_err(gt, "invalid GSC reply length %u [expected %zu], s=0x%x, 
f=0x%x, r=0x%x\n",
+   msg_out->header.message_size, sizeof(*msg_out),
+   msg_out->header.status, msg_out->header.flags, 
msg_out->mkhi.result);
+   err = -EPROTO;
+   goto out_vma;
+   }
+
+   gsc->fw.file_selected.ver.major = msg_out->compat_major;
+   gsc->fw.file_selected.ver.minor = msg_out->compat_minor;
+
+out_vma:
+   i915_vma_unpin_and_release(, I915_VMA_RELEASE_MAP);
+   return err;
+}
+
 int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc)
 {
struct intel_gt *gt = gsc_uc_to_gt(gsc);
@@ -355,11 +438,21 @@ int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc)
if (err)
goto fail;
 
+   err = gsc_fw_query_compatibility_version(gsc);
+   if (err)
+   goto fail;
+
+   /* we only support compatibility version 1.0 at the moment */
+   err = intel_uc_check_file_version(gsc_fw, NULL);
+   if (err)
+   goto fail;
+
/* FW is not fully operational until we enable SW proxy */
intel_uc_fw_change_status(gsc_fw, INTEL_UC_FIRMWARE_TRANSFERRED);
 
-   gt_info(gt, "Loaded GSC firmware %s (r%u.%u.%u.%u, svn%u)\n",

[Intel-gfx] [PATCH v2 4/5] drm/i915/mtl/gsc: Add a gsc_info debugfs

2023-06-05 Thread Daniele Ceraolo Spurio
Add a new debugfs to dump information about the GSC. This includes:

- the FW path and SW tracking status;
- the release, security and compatibility versions;
- the HECI1 status registers.

Note that those are the same registers that the mei driver dumps in
their own status sysfs on DG2 (where mei owns the GSC).

To make it simpler to loop through the status register, the code has
been update to use a PICK macro and the existing code using the regs had
been adapted to match.

v2: fix includes and copyright dates (Alan)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/Makefile |  3 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 29 +--
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 48 ++-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  2 +
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c | 38 +++
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h | 14 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  6 +--
 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c |  2 +
 drivers/gpu/drm/i915/i915_reg.h   | 26 +-
 9 files changed, 143 insertions(+), 25 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1c9ed4c52760..b6c54fb0b4cc 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -192,7 +192,8 @@ i915-y += \
  gt/uc/intel_gsc_fw.o \
  gt/uc/intel_gsc_proxy.o \
  gt/uc/intel_gsc_uc.o \
- gt/uc/intel_gsc_uc_heci_cmd_submit.o\
+ gt/uc/intel_gsc_uc_debugfs.o \
+ gt/uc/intel_gsc_uc_heci_cmd_submit.o \
  gt/uc/intel_guc.o \
  gt/uc/intel_guc_ads.o \
  gt/uc/intel_guc_capture.o \
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 7d48d59011c8..b069459e2596 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -12,36 +12,31 @@
 #include "intel_gsc_binary_headers.h"
 #include "intel_gsc_fw.h"
 #include "intel_gsc_uc_heci_cmd_submit.h"
-
-#define GSC_FW_STATUS_REG  _MMIO(0x116C40)
-#define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
-#define   GSC_FW_CURRENT_STATE_RESET   0
-#define   GSC_FW_PROXY_STATE_NORMAL5
-#define GSC_FW_INIT_COMPLETE_BIT   REG_BIT(9)
+#include "i915_reg.h"
 
 static bool gsc_is_in_reset(struct intel_uncore *uncore)
 {
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   u32 fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
-   return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
-  GSC_FW_CURRENT_STATE_RESET;
+   return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE, fw_status) ==
+   HECI1_FWSTS1_CURRENT_STATE_RESET;
 }
 
 bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
 {
struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   u32 fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
-   return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
-  GSC_FW_PROXY_STATE_NORMAL;
+   return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE, fw_status) ==
+  HECI1_FWSTS1_PROXY_STATE_NORMAL;
 }
 
 bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
 {
struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   u32 fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
-   return fw_status & GSC_FW_INIT_COMPLETE_BIT;
+   return fw_status & HECI1_FWSTS1_INIT_COMPLETE;
 }
 
 static inline u32 cpd_entry_offset(const struct intel_gsc_cpd_entry *entry)
@@ -293,9 +288,9 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
 static int gsc_fw_wait(struct intel_gt *gt)
 {
return intel_wait_for_register(gt->uncore,
-  GSC_FW_STATUS_REG,
-  GSC_FW_INIT_COMPLETE_BIT,
-  GSC_FW_INIT_COMPLETE_BIT,
+  HECI_FWSTS(MTL_GSC_HECI1_BASE, 1),
+  HECI1_FWSTS1_INIT_COMPLETE,
+  HECI1_FWSTS1_INIT_COMPLETE,
   500);
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index 4fe639a80564..6826aa5d6985 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -7,10 +7,11 @@
 
 #include 

[Intel-gfx] [PATCH v2 2/5] drm/i915/mtl/gsc: extract release and security versions from the gsc binary

2023-06-05 Thread Daniele Ceraolo Spurio
The release and security versions of the GSC binary are not used at
runtime to decide interface compatibility (there is a separate version
for that), but they're still useful for debug, so it is still worth
extracting them and printing them out in dmesg.

To get to these version, we need to navigate through various headers in
the binary. See in-code comment for details.

v2: fix and improve size checks when crawling the binary header, add
comment about the different version, wrap the partition base/offset
pairs in the GSC header in a struct (Alan)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
---
 .../drm/i915/gt/uc/intel_gsc_binary_headers.h |  76 -
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 158 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  18 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c |  13 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  |  30 +++-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |   3 +
 7 files changed, 273 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
index 714f0c256118..ad80afcafd23 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
@@ -8,6 +8,75 @@
 
 #include 
 
+struct intel_gsc_version {
+   u16 major;
+   u16 minor;
+   u16 hotfix;
+   u16 build;
+} __packed;
+
+struct intel_gsc_partition {
+   u32 offset;
+   u32 size;
+} __packed;
+
+struct intel_gsc_layout_pointers {
+   u8 rom_bypass_vector[16];
+
+   /* size of pointers layout not including ROM bypass vector */
+   u16 size;
+
+   /*
+* bit0: Backup copy of layout pointers exist
+* bits1-15: reserved
+*/
+   u8 flags;
+
+   u8 reserved;
+
+   u32 crc32;
+
+   struct intel_gsc_partition datap;
+   struct intel_gsc_partition boot1;
+   struct intel_gsc_partition boot2;
+   struct intel_gsc_partition boot3;
+   struct intel_gsc_partition boot4;
+   struct intel_gsc_partition boot5;
+   struct intel_gsc_partition temp_pages;
+} __packed;
+
+/* Boot partition structures */
+struct intel_gsc_bpdt_header {
+   u32 signature;
+#define INTEL_GSC_BPDT_HEADER_SIGNATURE 0x55AA
+
+   u16 descriptor_count; /* num of entries after the header */
+
+   u8 version;
+   u8 configuration;
+
+   u32 crc32;
+
+   u32 build_version;
+   struct intel_gsc_version tool_version;
+} __packed;
+
+
+struct intel_gsc_bpdt_entry {
+   /*
+* Bits 0-15: BPDT entry type
+* Bits 16-17: reserved
+* Bit 18: code sub-partition
+* Bits 19-31: reserved
+*/
+   u32 type;
+#define INTEL_GSC_BPDT_ENTRY_TYPE_MASK GENMASK(15,0)
+#define INTEL_GSC_BPDT_ENTRY_TYPE_GSC_RBE 0x1
+
+   u32 sub_partition_offset; /* from the base of the BPDT header */
+   u32 sub_partition_size;
+} __packed;
+
 /* Code partition directory (CPD) structures */
 struct intel_gsc_cpd_header_v2 {
u32 header_marker;
@@ -44,13 +113,6 @@ struct intel_gsc_cpd_entry {
u8 reserved[4];
 } __packed;
 
-struct intel_gsc_version {
-   u16 major;
-   u16 minor;
-   u16 hotfix;
-   u16 build;
-} __packed;
-
 struct intel_gsc_manifest_header {
u32 header_type; /* 0x4 for manifest type */
u32 header_length; /* in dwords */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 445995e55d87..953c155b5170 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -9,6 +9,7 @@
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_print.h"
 #include "gt/intel_ring.h"
+#include "intel_gsc_binary_headers.h"
 #include "intel_gsc_fw.h"
 
 #define GSC_FW_STATUS_REG  _MMIO(0x116C40)
@@ -42,6 +43,157 @@ bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
return fw_status & GSC_FW_INIT_COMPLETE_BIT;
 }
 
+static inline u32 cpd_entry_offset(const struct intel_gsc_cpd_entry *entry)
+{
+   return entry->offset & INTEL_GSC_CPD_ENTRY_OFFSET_MASK;
+}
+
+int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const void *data, 
size_t size)
+{
+   struct intel_gsc_uc *gsc = container_of(gsc_fw, struct intel_gsc_uc, 
fw);
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   const struct intel_gsc_layout_pointers *layout = data;
+   const struct intel_gsc_bpdt_header *bpdt_header = NULL;
+   const struct intel_gsc_bpdt_entry *bpdt_entry = NULL;
+   const struct intel_gsc_cpd_header_v2 *cpd_header = NULL;
+   const struct intel_gsc_cpd_entry *cpd_entry = NULL;
+   const struct intel_gsc_manifest_header *manifest;
+   size_t min_size = sizeof(*layout);
+   int i;
+
+   if (si

[Intel-gfx] [PATCH v2 0/5] drm/i915: GSC FW support for MTL

2023-06-05 Thread Daniele Ceraolo Spurio
Last chunk of the required support for the GSC FW. This includes some
fixes to the GSC memory allocation, FW idefinition and version
management, plus a new debugfs for debug information.

Adding the FW definition will enable all the features that are dependent
on the GSC being loaded (Media C6, HuC loading, SW proxy, PXP, HDCP).

NOTE: the FW team has asked to not send the current FW blob to
linux-firmware yet, as they're planning some updates. Therefore, the
FW definition patch will have to be merged to the topic/core-for-CI
branch for now and moved to gt-next once the FW is ready.

v2: fix header parsing, address other minor review comments.

Cc: Alan Previn 
Cc: John Harrison 
Cc: Suraj Kandpal 

Daniele Ceraolo Spurio (5):
  drm/i915/gsc: fixes and updates for GSC memory allocation
  drm/i915/mtl/gsc: extract release and security versions from the gsc
binary
  drm/i915/mtl/gsc: query the GSC FW for its compatibility version
  drm/i915/mtl/gsc: Add a gsc_info debugfs
  drm/i915/gsc: define gsc fw

 drivers/gpu/drm/i915/Makefile |   3 +-
 .../drm/i915/gt/uc/intel_gsc_binary_headers.h |  76 -
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 309 +++---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 125 ++-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  21 ++
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c |  38 +++
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h |  14 +
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|   6 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c |  13 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 112 +--
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |   4 +
 drivers/gpu/drm/i915/i915_reg.h   |  26 +-
 15 files changed, 641 insertions(+), 111 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h

-- 
2.40.0



[Intel-gfx] [PATCH v2 1/5] drm/i915/gsc: fixes and updates for GSC memory allocation

2023-06-05 Thread Daniele Ceraolo Spurio
A few fixes/updates are required around the GSC memory allocation and it
is easier to do them all at the same time. The changes are as follows:

1 - Switch the memory allocation to stolen memory. We need to avoid
accesses from GSC FW to normal memory after the suspend function has
completed and to do so we can either switch to using stolen or make sure
the GSC is gone to sleep before the end of the suspend function. Given
that the GSC waits for a bit before going idle even if there are no
pending operations, it is easier and quicker to just use stolen memory.

2 - Reduce the GSC allocation size to 4MBs, which is the POR requirement.
The 8MBs were needed only for early FW and I had misunderstood that as
being the expected POR size when I sent the original patch.

3 - Perma-map the GSC allocation. This isn't required immediately, but it
will be needed later to be able to quickly extract the GSC logs, which are
inside the allocation. Since the mapping code needs to be rewritten due to
switching to stolen, it makes sense to do the switch immediately to avoid
having to change it again later.

Note that the explicit setting of CACHE_NONE for Wa_22016122933 has been
dropped because that's the default setting for stolen memory on !LLC
platforms.

v2: only memset the memory we're not overwriting (Alan)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Cc: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 29 ++---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 77 ---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  1 +
 3 files changed, 75 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index f46eb17a7a98..445995e55d87 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -3,6 +3,7 @@
  * Copyright © 2022 Intel Corporation
  */
 
+#include "gem/i915_gem_lmem.h"
 #include "gt/intel_engine_pm.h"
 #include "gt/intel_gpu_commands.h"
 #include "gt/intel_gt.h"
@@ -109,38 +110,21 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
 {
struct intel_gt *gt = gsc_uc_to_gt(gsc);
struct drm_i915_private *i915 = gt->i915;
-   struct drm_i915_gem_object *obj;
-   void *src, *dst;
+   void *src;
 
if (!gsc->local)
return -ENODEV;
 
-   obj = gsc->local->obj;
-
-   if (obj->base.size < gsc->fw.size)
+   if (gsc->local->size < gsc->fw.size)
return -ENOSPC;
 
-   /*
-* Wa_22016122933: For MTL the shared memory needs to be mapped
-* as WC on CPU side and UC (PAT index 2) on GPU side
-*/
-   if (IS_METEORLAKE(i915))
-   i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
-
-   dst = i915_gem_object_pin_map_unlocked(obj,
-  i915_coherent_map_type(i915, 
obj, true));
-   if (IS_ERR(dst))
-   return PTR_ERR(dst);
-
src = i915_gem_object_pin_map_unlocked(gsc->fw.obj,
   i915_coherent_map_type(i915, 
gsc->fw.obj, true));
-   if (IS_ERR(src)) {
-   i915_gem_object_unpin_map(obj);
+   if (IS_ERR(src))
return PTR_ERR(src);
-   }
 
-   memset(dst, 0, obj->base.size);
-   memcpy(dst, src, gsc->fw.size);
+   memcpy_toio(gsc->local_vaddr, src, gsc->fw.size);
+   memset_io(gsc->local_vaddr + gsc->fw.size, 0, gsc->local->size - 
gsc->fw.size);
 
/*
 * Wa_22016122933: Making sure the data in dst is
@@ -149,7 +133,6 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
intel_guc_write_barrier(>uc.guc);
 
i915_gem_object_unpin_map(gsc->fw.obj);
-   i915_gem_object_unpin_map(obj);
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index c659cc01f32f..4fe639a80564 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -133,26 +133,85 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
}
 }
 
+static int gsc_allocate_and_map_vma(struct intel_gsc_uc *gsc, u32 size)
+{
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   struct drm_i915_gem_object *obj;
+   struct i915_vma *vma;
+   void __iomem *vaddr;
+   int ret = 0;
+
+   /*
+* The GSC FW doesn't immediately suspend after becoming idle, so there
+* is a chance that it could still be awake after we successfully
+* return from the  pci suspend function, even if there are no pending
+* operations.
+* The FW might therefore try to access memory for its suspend operation
+* after the kernel has completed the HW suspend flow; this can cause
+* is

[Intel-gfx] [PATCH v5 7/7] drm/i915/huc: define HuC FW version for MTL

2023-05-31 Thread Daniele Ceraolo Spurio
Follow the same logic as DG2, so just a meu binary with no version number.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index a1c8a982479f..944725e62414 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -108,6 +108,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(SKYLAKE,  0, guc_mmp(skl,  70, 1, 1))
 
 #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_raw, huc_mmp, huc_gsc) \
+   fw_def(METEORLAKE,   0, huc_gsc(mtl)) \
fw_def(DG2,  0, huc_gsc(dg2)) \
fw_def(ALDERLAKE_P,  0, huc_raw(tgl)) \
fw_def(ALDERLAKE_P,  0, huc_mmp(tgl,  7, 9, 3)) \
-- 
2.40.0



[Intel-gfx] [PATCH v5 4/7] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow

2023-05-31 Thread Daniele Ceraolo Spurio
Before we add the second step of the MTL HuC auth (via GSC), we need to
have the ability to differentiate between them. To do so, the huc
authentication check is duplicated for GuC and GSC auth, with
GSC-enabled binaries being considered fully authenticated only after
the GSC auth step.

To report the difference between the 2 auth steps, a new case is added
to the HuC getparam. This way, the clear media driver can start
submitting before full auth, as partial auth is enough for those
workloads.

v2: fix authentication status check for DG2

v3: add a better comment at the top of the HuC file to explain the
different approaches to load and auth (John)

v4: update call to intel_huc_is_authenticated in the pxp code to check
for GSC authentication

v5: drop references to meu and esclamation mark in huc_auth print (John)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn  #v2
---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c | 111 -
 drivers/gpu/drm/i915/gt/uc/intel_huc.h |  16 ++-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c  |   4 +-
 drivers/gpu/drm/i915/i915_reg.h|   3 +
 drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c |   2 +-
 include/uapi/drm/i915_drm.h|   3 +-
 6 files changed, 104 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 27c5e41fa84c..73efdb027082 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -10,6 +10,7 @@
 #include "intel_huc.h"
 #include "intel_huc_print.h"
 #include "i915_drv.h"
+#include "i915_reg.h"
 
 #include 
 #include 
@@ -22,15 +23,23 @@
  * capabilities by adding HuC specific commands to batch buffers.
  *
  * The kernel driver is only responsible for loading the HuC firmware and
- * triggering its security authentication, which is performed by the GuC on
- * older platforms and by the GSC on newer ones. For the GuC to correctly
- * perform the authentication, the HuC binary must be loaded before the GuC 
one.
+ * triggering its security authentication. This is done differently depending
+ * on the platform:
+ * - older platforms (from Gen9 to most Gen12s): the load is performed via DMA
+ *   and the authentication via GuC
+ * - DG2: load and authentication are both performed via GSC.
+ * - MTL and newer platforms: the load is performed via DMA (same as with
+ *   not-DG2 older platforms), while the authentication is done in 2-steps,
+ *   a first auth for clear-media workloads via GuC and a second one for all
+ *   workloads via GSC.
+ * On platforms where the GuC does the authentication, to correctly do so the
+ * HuC binary must be loaded before the GuC one.
  * Loading the HuC is optional; however, not using the HuC might negatively
  * impact power usage and/or performance of media workloads, depending on the
  * use-cases.
  * HuC must be reloaded on events that cause the WOPCM to lose its contents
- * (S3/S4, FLR); GuC-authenticated HuC must also be reloaded on GuC/GT reset,
- * while GSC-managed HuC will survive that.
+ * (S3/S4, FLR); on older platforms the HuC must also be reloaded on GuC/GT
+ * reset, while on newer ones it will survive that.
  *
  * See https://github.com/intel/media-driver for the latest details on HuC
  * functionality.
@@ -106,7 +115,7 @@ static enum hrtimer_restart 
huc_delayed_load_timer_callback(struct hrtimer *hrti
 {
struct intel_huc *huc = container_of(hrtimer, struct intel_huc, 
delayed_load.timer);
 
-   if (!intel_huc_is_authenticated(huc)) {
+   if (!intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC)) {
if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_GSC)
huc_notice(huc, "timed out waiting for MEI GSC\n");
else if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_PXP)
@@ -124,7 +133,7 @@ static void huc_delayed_load_start(struct intel_huc *huc)
 {
ktime_t delay;
 
-   GEM_BUG_ON(intel_huc_is_authenticated(huc));
+   GEM_BUG_ON(intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC));
 
/*
 * On resume we don't have to wait for MEI-GSC to be re-probed, but we
@@ -284,13 +293,23 @@ void intel_huc_init_early(struct intel_huc *huc)
}
 
if (GRAPHICS_VER(i915) >= 11) {
-   huc->status.reg = GEN11_HUC_KERNEL_LOAD_INFO;
-   huc->status.mask = HUC_LOAD_SUCCESSFUL;
-   huc->status.value = HUC_LOAD_SUCCESSFUL;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].reg = 
GEN11_HUC_KERNEL_LOAD_INFO;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].mask = HUC_LOAD_SUCCESSFUL;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].value = HUC_LOAD_SUCCESSFUL;
} else {
-   huc->status.reg = HUC_STATUS2;
-   huc->status.mask = HUC_FW_VERIFIE

[Intel-gfx] [PATCH v5 5/7] drm/i915/mtl/huc: auth HuC via GSC

2023-05-31 Thread Daniele Ceraolo Spurio
The full authentication via the GSC requires an heci packet submission
to the GSC FW via the GSC CS. The GSC has new PXP command for this
(literally called NEW_HUC_AUTH).
The intel_huc_auth function is also updated to handle both authentication
types.

v2: check that the GuC auth for clear media has completed before
proceding with the full auth

v3: use a define for the object size (Alan)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 27 +-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c |  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 53 ---
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  6 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 95 +++
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  2 +-
 .../drm/i915/pxp/intel_pxp_cmd_interface_43.h | 17 +++-
 drivers/gpu/drm/i915/pxp/intel_pxp_huc.c  |  2 +-
 9 files changed, 183 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index b26f493f86fa..c659cc01f32f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -29,13 +29,32 @@ static void gsc_work(struct work_struct *work)
 
if (actions & GSC_ACTION_FW_LOAD) {
ret = intel_gsc_uc_fw_upload(gsc);
-   if (ret == -EEXIST) /* skip proxy if not a new load */
-   actions &= ~GSC_ACTION_FW_LOAD;
-   else if (ret)
+   if (!ret)
+   /* setup proxy on a new load */
+   actions |= GSC_ACTION_SW_PROXY;
+   else if (ret != -EEXIST)
goto out_put;
+
+   /*
+* The HuC auth can be done both before or after the proxy init;
+* if done after, a proxy request will be issued and must be
+* serviced before the authentication can complete.
+* Since this worker also handles proxy requests, we can't
+* perform an action that requires the proxy from within it and
+* then stall waiting for it, because we'd be blocking the
+* service path. Therefore, it is easier for us to load HuC
+* first and do proxy later. The GSC will ack the HuC auth and
+* then send the HuC proxy request as part of the proxy init
+* flow.
+* Note that we can only do the GSC auth if the GuC auth was
+* successful.
+*/
+   if (intel_uc_uses_huc(>uc) &&
+   intel_huc_is_authenticated(>uc.huc, 
INTEL_HUC_AUTH_BY_GUC))
+   intel_huc_auth(>uc.huc, INTEL_HUC_AUTH_BY_GSC);
}
 
-   if (actions & (GSC_ACTION_FW_LOAD | GSC_ACTION_SW_PROXY)) {
+   if (actions & GSC_ACTION_SW_PROXY) {
if (!intel_gsc_uc_fw_init_done(gsc)) {
gt_err(gt, "Proxy request received with GSC not 
loaded!\n");
goto out_put;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
index 579c0f5a1438..0ad090304ca0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
@@ -99,7 +99,7 @@ void intel_gsc_uc_heci_cmd_emit_mtl_header(struct 
intel_gsc_mtl_header *header,
   u64 host_session_id)
 {
host_session_id &= ~HOST_SESSION_MASK;
-   if (heci_client_id == HECI_MEADDRESS_PXP)
+   if (host_session_id && heci_client_id == HECI_MEADDRESS_PXP)
host_session_id |= HOST_SESSION_PXP_SINGLE;
 
header->validity_marker = GSC_HECI_VALIDITY_MARKER;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 73efdb027082..df8f28ebfc94 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -11,6 +11,7 @@
 #include "intel_huc_print.h"
 #include "i915_drv.h"
 #include "i915_reg.h"
+#include "pxp/intel_pxp_cmd_interface_43.h"
 
 #include 
 #include 
@@ -371,20 +372,36 @@ static int check_huc_loading_mode(struct intel_huc *huc)
 
 int intel_huc_init(struct intel_huc *huc)
 {
+   struct intel_gt *gt = huc_to_gt(huc);
int err;
 
err = check_huc_loading_mode(huc);
if (err)
goto out;
 
+   if (HAS_ENGINE(gt, GSC0)) {
+   struct i915_vma *vma;
+
+   vma = intel_guc_allocate_vma(>uc.guc, 
PXP43_HUC_AUTH_INOUT_SIZE * 2);
+   if (IS_ERR(vma)) {
+   huc_info(huc, "Failed to allocate heci pkt\n");
+  

[Intel-gfx] [PATCH v5 6/7] drm/i915/mtl/huc: Use the media gt for the HuC getparam

2023-05-31 Thread Daniele Ceraolo Spurio
On MTL, for obvious reasons, HuC is only available on the media tile.
We already disable SW support for HuC on the root gt due to the
absence of VCS engines, but we also need to update the getparam to point
to the HuC struct in the media GT.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_getparam.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_getparam.c 
b/drivers/gpu/drm/i915/i915_getparam.c
index 6f11d7eaa91a..890f2b382bee 100644
--- a/drivers/gpu/drm/i915/i915_getparam.c
+++ b/drivers/gpu/drm/i915/i915_getparam.c
@@ -100,7 +100,11 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data,
value = sseu->min_eu_in_pool;
break;
case I915_PARAM_HUC_STATUS:
-   value = intel_huc_check_status(_gt(i915)->uc.huc);
+   /* On platform with a media GT, the HuC is on that GT */
+   if (i915->media_gt)
+   value = intel_huc_check_status(>media_gt->uc.huc);
+   else
+   value = intel_huc_check_status(_gt(i915)->uc.huc);
if (value < 0)
return value;
break;
-- 
2.40.0



[Intel-gfx] [PATCH v5 3/7] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so

2023-05-31 Thread Daniele Ceraolo Spurio
In the previous patch we extracted the offset of the legacy-style HuC
binary located within the GSC-enabled blob, so now we can use that to
load the HuC via DMA if the fuse is set that way.
Note that we now need to differentiate between "GSC-enabled binary" and
"loaded by GSC", so the former case has been renamed to "has GSC headers"
for clarity, while the latter is now based on the fuse instead of the
binary format. This way, all the legacy load paths are automatically
taken (including the auth by GuC) without having to implement further
code changes.

v2: s/is_meu_binary/has_gsc_headers/, clearer logs (John)

v3: split check for GSC access, better comments (John)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 49 +--
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  4 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c |  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 12 +++---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |  2 +-
 5 files changed, 47 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 6d795438b3e4..27c5e41fa84c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -298,31 +298,54 @@ void intel_huc_init_early(struct intel_huc *huc)
 static int check_huc_loading_mode(struct intel_huc *huc)
 {
struct intel_gt *gt = huc_to_gt(huc);
-   bool fw_needs_gsc = intel_huc_is_loaded_by_gsc(huc);
-   bool hw_uses_gsc = false;
+   bool gsc_enabled = huc->fw.has_gsc_headers;
 
/*
 * The fuse for HuC load via GSC is only valid on platforms that have
 * GuC deprivilege.
 */
if (HAS_GUC_DEPRIVILEGE(gt->i915))
-   hw_uses_gsc = intel_uncore_read(gt->uncore, GUC_SHIM_CONTROL2) &
- GSC_LOADS_HUC;
+   huc->loaded_via_gsc = intel_uncore_read(gt->uncore, 
GUC_SHIM_CONTROL2) &
+ GSC_LOADS_HUC;
 
-   if (fw_needs_gsc != hw_uses_gsc) {
-   huc_err(huc, "mismatch between FW (%s) and HW (%s) load 
modes\n",
-   HUC_LOAD_MODE_STRING(fw_needs_gsc), 
HUC_LOAD_MODE_STRING(hw_uses_gsc));
+   if (huc->loaded_via_gsc && !gsc_enabled) {
+   huc_err(huc, "HW requires a GSC-enabled blob, but we found a 
legacy one\n");
return -ENOEXEC;
}
 
-   /* make sure we can access the GSC via the mei driver if we need it */
-   if (!(IS_ENABLED(CONFIG_INTEL_MEI_PXP) && 
IS_ENABLED(CONFIG_INTEL_MEI_GSC)) &&
-   fw_needs_gsc) {
-   huc_info(huc, "can't load due to missing MEI modules\n");
-   return -EIO;
+   /*
+* On newer platforms we have GSC-enabled binaries but we load the HuC
+* via DMA. To do so we need to find the location of the legacy-style
+* binary inside the GSC-enabled one, which we do at fetch time. Make
+* sure that we were able to do so if the fuse says we need to load via
+* DMA and the binary is GSC-enabled.
+*/
+   if (!huc->loaded_via_gsc && gsc_enabled && !huc->fw.dma_start_offset) {
+   huc_err(huc, "HW in DMA mode, but we have an incompatible 
GSC-enabled blob\n");
+   return -ENOEXEC;
+   }
+
+   /*
+* If the HuC is loaded via GSC, we need to be able to access the GSC.
+* On DG2 this is done via the mei components, while on newer platforms
+* it is done via the GSCCS,
+*/
+   if (huc->loaded_via_gsc) {
+   if (IS_DG2(gt->i915)) {
+   if (!IS_ENABLED(CONFIG_INTEL_MEI_PXP) ||
+   !IS_ENABLED(CONFIG_INTEL_MEI_GSC)) {
+   huc_info(huc, "can't load due to missing mei 
modules\n");
+   return -EIO;
+   }
+   } else {
+   if (!HAS_ENGINE(gt, GSC0)){
+   huc_info(huc, "can't load due to missing 
GSCCS\n");
+   return -EIO;
+   }
+   }
}
 
-   huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(fw_needs_gsc));
+   huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(huc->loaded_via_gsc));
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
index 0789184d81a2..112f0dce4702 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
@@ -39,6 +39,8 @@ struct intel_huc {
struct notifier_block nb;
enum intel_huc_delayed_load_status status;
} delayed

[Intel-gfx] [PATCH v5 1/7] drm/i915/uc: perma-pin firmwares

2023-05-31 Thread Daniele Ceraolo Spurio
Now that each FW has its own reserved area, we can keep them always
pinned and skip the pin/unpin dance on reset. This will make things
easier for the 2-step HuC authentication, which requires the FW to be
pinned in GGTT after the xfer is completed.
Since the vma is now valid for a long time and not just for the quick
pin-load-unpin dance, the name "dummy" is no longer appropriare and has
been replaced with vma_res. All the functions have also been updated to
operate on vma_res for consistency.
Given that we pin the vma behind the allocator's back (which is ok
because we do the pinning in an area that was previously reserved for
thus purpose), we do need to explicitly re-pin on resume because the
automated helper won't cover us.

v2: better comments and commit message, s/dummy/vma_res/

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_ggtt.c  |  3 ++
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c |  7 +++-
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  8 
 drivers/gpu/drm/i915/gt/uc/intel_uc.h |  2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 50 ---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  | 22 ++
 8 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 2a7942fac798..f4e8aa8246e8 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1326,6 +1326,9 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
ggtt->vm.scratch_range(>vm, ggtt->error_capture.start,
   ggtt->error_capture.size);
 
+   list_for_each_entry(gt, >gt_list, ggtt_link)
+   intel_uc_resume_mappings(>uc);
+
ggtt->invalidate(ggtt);
 
if (flush)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index fb0984f875f9..b26f493f86fa 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -90,7 +90,12 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
 {
struct intel_gt *gt = gsc_uc_to_gt(gsc);
 
-   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_GSC);
+   /*
+* GSC FW needs to be copied to a dedicated memory allocations for
+* loading (see gsc->local), so we don't need to GGTT map the FW image
+* itself into GGTT.
+*/
+   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_GSC, false);
INIT_WORK(>work, gsc_work);
 
/* we can arrive here from i915_driver_early_probe for primary
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index c9f20385f6a0..2eb891b270ae 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -164,7 +164,7 @@ void intel_guc_init_early(struct intel_guc *guc)
struct intel_gt *gt = guc_to_gt(guc);
struct drm_i915_private *i915 = gt->i915;
 
-   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_GUC);
+   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_GUC, true);
intel_guc_ct_init_early(>ct);
intel_guc_log_init_early(>log);
intel_guc_submission_init_early(guc);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 04724ff56ded..268e036f8f28 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -276,7 +276,7 @@ void intel_huc_init_early(struct intel_huc *huc)
struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
struct intel_gt *gt = huc_to_gt(huc);
 
-   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_HUC);
+   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_HUC, true);
 
/*
 * we always init the fence as already completed, even if HuC is not
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index c8b9cbb7ba3a..1e7f5cc9d550 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -700,6 +700,12 @@ void intel_uc_suspend(struct intel_uc *uc)
}
 }
 
+static void __uc_resume_mappings(struct intel_uc *uc)
+{
+   intel_uc_fw_resume_mapping(>guc.fw);
+   intel_uc_fw_resume_mapping(>huc.fw);
+}
+
 static int __uc_resume(struct intel_uc *uc, bool enable_communication)
 {
struct intel_guc *guc = >guc;
@@ -767,4 +773,6 @@ static const struct intel_uc_ops uc_ops_on = {
 
.init_hw = __uc_init_hw,
.fini_hw = __uc_fini_hw,
+
+   .resume_mappings = __uc_resume_mappings,
 };
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
index d585524d94de..014bb7d83689 1006

[Intel-gfx] [PATCH v5 2/7] drm/i915/huc: Parse the GSC-enabled HuC binary

2023-05-31 Thread Daniele Ceraolo Spurio
The new binaries that support the 2-step authentication contain the
legacy-style binary, which we can use for loading the HuC via DMA. To
find out where this is located in the image, we need to parse the
manifest of the GSC-enabled HuC binary. The manifest consist of a
partition header followed by entries, one of which contains the offset
we're looking for.
Note that the DG2 GSC binary contains entries with the same names, but
it doesn't contain a full legacy binary, so we need to skip assigning
the dma offset in that case (which we can do by checking the ccs).
Also, since we're now parsing the entries, we can extract the HuC
version that way instead of using hardcoded offsets.

Note that the GSC binary uses the same structures in its binary header,
so they've been added in their own header file.

v2: fix structure names to match meu defines (s/CPT/CPD/), update commit
message, check ccs validity, drop old version location defines.

v3: drop references to the MEU tool to reduce confusion, fix log (John)

v4: fix log for real (John)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn  #v2
---
 .../drm/i915/gt/uc/intel_gsc_binary_headers.h |  74 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  11 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 136 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h |   5 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h  |  21 +++
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  |  72 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h  |   6 -
 8 files changed, 274 insertions(+), 53 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
new file mode 100644
index ..714f0c256118
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _INTEL_GSC_BINARY_HEADERS_H_
+#define _INTEL_GSC_BINARY_HEADERS_H_
+
+#include 
+
+/* Code partition directory (CPD) structures */
+struct intel_gsc_cpd_header_v2 {
+   u32 header_marker;
+#define INTEL_GSC_CPD_HEADER_MARKER 0x44504324
+
+   u32 num_of_entries;
+   u8 header_version;
+   u8 entry_version;
+   u8 header_length; /* in bytes */
+   u8 flags;
+   u32 partition_name;
+   u32 crc32;
+} __packed;
+
+struct intel_gsc_cpd_entry {
+   u8 name[12];
+
+   /*
+* Bits 0-24: offset from the beginning of the code partition
+* Bit 25: huffman compressed
+* Bits 26-31: reserved
+*/
+   u32 offset;
+#define INTEL_GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0)
+#define INTEL_GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25)
+
+   /*
+* Module/Item length, in bytes. For Huffman-compressed modules, this
+* refers to the uncompressed size. For software-compressed modules,
+* this refers to the compressed size.
+*/
+   u32 length;
+
+   u8 reserved[4];
+} __packed;
+
+struct intel_gsc_version {
+   u16 major;
+   u16 minor;
+   u16 hotfix;
+   u16 build;
+} __packed;
+
+struct intel_gsc_manifest_header {
+   u32 header_type; /* 0x4 for manifest type */
+   u32 header_length; /* in dwords */
+   u32 header_version;
+   u32 flags;
+   u32 vendor;
+   u32 date;
+   u32 size; /* In dwords, size of entire manifest (header + extensions) */
+   u32 header_id;
+   u32 internal_data;
+   struct intel_gsc_version fw_version;
+   u32 security_version;
+   struct intel_gsc_version meu_kit_version;
+   u32 meu_manifest_version;
+   u8 general_data[4];
+   u8 reserved3[56];
+   u32 modulus_size; /* in dwords */
+   u32 exponent_size; /* in dwords */
+} __packed;
+
+#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 268e036f8f28..6d795438b3e4 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -6,23 +6,14 @@
 #include 
 
 #include "gt/intel_gt.h"
-#include "gt/intel_gt_print.h"
 #include "intel_guc_reg.h"
 #include "intel_huc.h"
+#include "intel_huc_print.h"
 #include "i915_drv.h"
 
 #include 
 #include 
 
-#define huc_printk(_huc, _level, _fmt, ...) \
-   gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__)
-#define huc_err(_huc, _fmt, ...)   huc_printk((_huc), err, _fmt, 
##__VA_ARGS__)
-#define huc_warn(_huc, _fmt, ...)  huc_printk((_huc), warn, _fmt, 
##__VA_ARGS__)
-#define huc_notice(_huc, _fmt, ...)huc_printk((_huc), notice, _fmt, 
##__VA_ARGS__)
-#define huc_info(_huc, _fmt, ...)  huc_

[Intel-gfx] [PATCH v5 0/7] drm/i915: HuC loading and authentication for MTL

2023-05-31 Thread Daniele Ceraolo Spurio
The HuC loading and authentication flow is once again changing and a new
"clear-media only" authentication step is introduced. The flow is as
follows:

1) The HuC is loaded via DMA - same as all non-GSC HuC binaries.

2) The HuC is authenticated by the GuC - this is the same step as
performed for all non-GSC HuC binaries and re-uses the same code, but
it is now resulting in a partial authentication that only allows
clear-media workloads.

3) The HuC is fully authenticated for all workloads by the GSC - this
is done via a new PXP command, submitted via the GSCCS.

The advantage of this new flow is that we can start processing
clear-media workloads without having to wait for the GSC to be ready,
which can take several seconds.

As part of this change, the HuC status getparam has been updated with a
new value to indicate a partial authentication. Note tha the media
driver is checking for value > 0 for clear media workloads, so no
changes are required in userspace for that to work.

v2: fix HuC auth status check for DG2.

v3: addrss review feedback, stop using the "meu" tag for the naming of
the headers, better comments

v4: fix rebase on new PXP code

v5: better comments/logs/defines, fix checkpatch issues

Cc: Alan Previn 
Cc: John Harrison 
Acked-by: Tony Ye 

Daniele Ceraolo Spurio (7):
  drm/i915/uc: perma-pin firmwares
  drm/i915/huc: Parse the GSC-enabled HuC binary
  drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
  drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
  drm/i915/mtl/huc: auth HuC via GSC
  drm/i915/mtl/huc: Use the media gt for the HuC getparam
  drm/i915/huc: define HuC FW version for MTL

 drivers/gpu/drm/i915/gt/intel_ggtt.c  |   3 +
 .../drm/i915/gt/uc/intel_gsc_binary_headers.h |  74 ++
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c |  34 ++-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c |   2 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|   2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 224 -
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  26 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 235 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h |   6 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h  |  21 ++
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  10 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc.h |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 133 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |  26 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h  |   6 -
 drivers/gpu/drm/i915/i915_getparam.c  |   6 +-
 drivers/gpu/drm/i915/i915_reg.h   |   3 +
 .../drm/i915/pxp/intel_pxp_cmd_interface_43.h |  17 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c|   2 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_huc.c  |   2 +-
 include/uapi/drm/i915_drm.h   |   3 +-
 21 files changed, 682 insertions(+), 155 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h

-- 
2.40.0



[Intel-gfx] [PATCH v4] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow

2023-05-30 Thread Daniele Ceraolo Spurio
Before we add the second step of the MTL HuC auth (via GSC), we need to
have the ability to differentiate between them. To do so, the huc
authentication check is duplicated for GuC and GSC auth, with meu
binaries being considered fully authenticated only after the GSC auth
step.

To report the difference between the 2 auth steps, a new case is added
to the HuC getparam. This way, the clear media driver can start
submitting before full auth, as partial auth is enough for those
workloads.

v2: fix authentication status check for DG2

v3: add a better comment at the top of the HuC file to explain the
different approaches to load and auth (John)

v4: update call to intel_huc_is_authenticated in the pxp code to check
for GSC authentication

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn  #v2
---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c | 111 -
 drivers/gpu/drm/i915/gt/uc/intel_huc.h |  16 ++-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c  |   4 +-
 drivers/gpu/drm/i915/i915_reg.h|   3 +
 drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c |   2 +-
 include/uapi/drm/i915_drm.h|   3 +-
 6 files changed, 104 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 37c6a8ca5c71..ab5246ae3979 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -10,6 +10,7 @@
 #include "intel_huc.h"
 #include "intel_huc_print.h"
 #include "i915_drv.h"
+#include "i915_reg.h"
 
 #include 
 #include 
@@ -22,15 +23,23 @@
  * capabilities by adding HuC specific commands to batch buffers.
  *
  * The kernel driver is only responsible for loading the HuC firmware and
- * triggering its security authentication, which is performed by the GuC on
- * older platforms and by the GSC on newer ones. For the GuC to correctly
- * perform the authentication, the HuC binary must be loaded before the GuC 
one.
+ * triggering its security authentication. This is done differently depending
+ * on the platform:
+ * - older platforms (from Gen9 to most Gen12s): the load is performed via DMA
+ *   and the authentication via GuC
+ * - DG2: load and authentication are both performed via GSC.
+ * - MTL and newer platforms: the load is performed via DMA (same as with
+ *   not-DG2 older platforms), while the authentication is done in 2-steps,
+ *   a first auth for clear-media workloads via GuC and a second one for all
+ *   workloads via GSC.
+ * On platforms where the GuC does the authentication, to correctly do so the
+ * HuC binary must be loaded before the GuC one.
  * Loading the HuC is optional; however, not using the HuC might negatively
  * impact power usage and/or performance of media workloads, depending on the
  * use-cases.
  * HuC must be reloaded on events that cause the WOPCM to lose its contents
- * (S3/S4, FLR); GuC-authenticated HuC must also be reloaded on GuC/GT reset,
- * while GSC-managed HuC will survive that.
+ * (S3/S4, FLR); on older platforms the HuC must also be reloaded on GuC/GT
+ * reset, while on newer ones it will survive that.
  *
  * See https://github.com/intel/media-driver for the latest details on HuC
  * functionality.
@@ -106,7 +115,7 @@ static enum hrtimer_restart 
huc_delayed_load_timer_callback(struct hrtimer *hrti
 {
struct intel_huc *huc = container_of(hrtimer, struct intel_huc, 
delayed_load.timer);
 
-   if (!intel_huc_is_authenticated(huc)) {
+   if (!intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC)) {
if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_GSC)
huc_notice(huc, "timed out waiting for MEI GSC\n");
else if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_PXP)
@@ -124,7 +133,7 @@ static void huc_delayed_load_start(struct intel_huc *huc)
 {
ktime_t delay;
 
-   GEM_BUG_ON(intel_huc_is_authenticated(huc));
+   GEM_BUG_ON(intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC));
 
/*
 * On resume we don't have to wait for MEI-GSC to be re-probed, but we
@@ -284,13 +293,23 @@ void intel_huc_init_early(struct intel_huc *huc)
}
 
if (GRAPHICS_VER(i915) >= 11) {
-   huc->status.reg = GEN11_HUC_KERNEL_LOAD_INFO;
-   huc->status.mask = HUC_LOAD_SUCCESSFUL;
-   huc->status.value = HUC_LOAD_SUCCESSFUL;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].reg = 
GEN11_HUC_KERNEL_LOAD_INFO;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].mask = HUC_LOAD_SUCCESSFUL;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].value = HUC_LOAD_SUCCESSFUL;
} else {
-   huc->status.reg = HUC_STATUS2;
-   huc->status.mask = HUC_FW_VERIFIED;
-   huc->status.value = HUC_FW_VERIFIED;
+   huc->status[INTEL_HU

[Intel-gfx] [PATCH v3 7/7] drm/i915/huc: define HuC FW version for MTL

2023-05-26 Thread Daniele Ceraolo Spurio
Follow the same logic as DG2, so just a meu binary with no version number.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index b752a7f1ed99..db7fbce51f8b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -108,6 +108,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(SKYLAKE,  0, guc_mmp(skl,  70, 1, 1))
 
 #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_raw, huc_mmp, huc_gsc) \
+   fw_def(METEORLAKE,   0, huc_gsc(mtl)) \
fw_def(DG2,  0, huc_gsc(dg2)) \
fw_def(ALDERLAKE_P,  0, huc_raw(tgl)) \
fw_def(ALDERLAKE_P,  0, huc_mmp(tgl,  7, 9, 3)) \
-- 
2.40.0



[Intel-gfx] [PATCH v3 2/7] drm/i915/huc: Parse the GSC-enabled HuC binary

2023-05-26 Thread Daniele Ceraolo Spurio
The new binaries that support the 2-step authentication contain the
legacy-style binary, which we can use for loading the HuC via DMA. To
find out where this is located in the image, we need to parse the
manifest of the GSC-enabled HuC binary. The manifest consist of a
partition header followed by entries, one of which contains the offset
we're looking for.
Note that the DG2 GSC binary contains entries with the same names, but
it doesn't contain a full legacy binary, so we need to skip assigning
the dma offset in that case (which we can do by checking the ccs).
Also, since we're now parsing the entries, we can extract the HuC
version that way instead of using hardcoded offsets.

Note that the GSC binary uses the same structures in its binary header,
so they've been added in their own header file.

v2: fix structure names to match meu defines (s/CPT/CPD/), update commit
message, check ccs validity, drop old version location defines.

v3: drop references to the MEU tool to reduce confusion, fix log (John)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn  #v2
---
 .../drm/i915/gt/uc/intel_gsc_binary_headers.h |  74 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  11 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 135 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h |   5 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h  |  21 +++
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  |  71 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h  |   6 -
 8 files changed, 272 insertions(+), 53 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
new file mode 100644
index ..714f0c256118
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _INTEL_GSC_BINARY_HEADERS_H_
+#define _INTEL_GSC_BINARY_HEADERS_H_
+
+#include 
+
+/* Code partition directory (CPD) structures */
+struct intel_gsc_cpd_header_v2 {
+   u32 header_marker;
+#define INTEL_GSC_CPD_HEADER_MARKER 0x44504324
+
+   u32 num_of_entries;
+   u8 header_version;
+   u8 entry_version;
+   u8 header_length; /* in bytes */
+   u8 flags;
+   u32 partition_name;
+   u32 crc32;
+} __packed;
+
+struct intel_gsc_cpd_entry {
+   u8 name[12];
+
+   /*
+* Bits 0-24: offset from the beginning of the code partition
+* Bit 25: huffman compressed
+* Bits 26-31: reserved
+*/
+   u32 offset;
+#define INTEL_GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0)
+#define INTEL_GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25)
+
+   /*
+* Module/Item length, in bytes. For Huffman-compressed modules, this
+* refers to the uncompressed size. For software-compressed modules,
+* this refers to the compressed size.
+*/
+   u32 length;
+
+   u8 reserved[4];
+} __packed;
+
+struct intel_gsc_version {
+   u16 major;
+   u16 minor;
+   u16 hotfix;
+   u16 build;
+} __packed;
+
+struct intel_gsc_manifest_header {
+   u32 header_type; /* 0x4 for manifest type */
+   u32 header_length; /* in dwords */
+   u32 header_version;
+   u32 flags;
+   u32 vendor;
+   u32 date;
+   u32 size; /* In dwords, size of entire manifest (header + extensions) */
+   u32 header_id;
+   u32 internal_data;
+   struct intel_gsc_version fw_version;
+   u32 security_version;
+   struct intel_gsc_version meu_kit_version;
+   u32 meu_manifest_version;
+   u8 general_data[4];
+   u8 reserved3[56];
+   u32 modulus_size; /* in dwords */
+   u32 exponent_size; /* in dwords */
+} __packed;
+
+#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 268e036f8f28..6d795438b3e4 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -6,23 +6,14 @@
 #include 
 
 #include "gt/intel_gt.h"
-#include "gt/intel_gt_print.h"
 #include "intel_guc_reg.h"
 #include "intel_huc.h"
+#include "intel_huc_print.h"
 #include "i915_drv.h"
 
 #include 
 #include 
 
-#define huc_printk(_huc, _level, _fmt, ...) \
-   gt_##_level(huc_to_gt(_huc), "HuC: " _fmt, ##__VA_ARGS__)
-#define huc_err(_huc, _fmt, ...)   huc_printk((_huc), err, _fmt, 
##__VA_ARGS__)
-#define huc_warn(_huc, _fmt, ...)  huc_printk((_huc), warn, _fmt, 
##__VA_ARGS__)
-#define huc_notice(_huc, _fmt, ...)huc_printk((_huc), notice, _fmt, 
##__VA_ARGS__)
-#define huc_info(_huc, _fmt, ...)  huc_printk((_huc), info, _fmt, 
#

[Intel-gfx] [PATCH v3 5/7] drm/i915/mtl/huc: auth HuC via GSC

2023-05-26 Thread Daniele Ceraolo Spurio
The full authentication via the GSC requires an heci packet submission
to the GSC FW via the GSC CS. The GSC has new PXP command for this
(literally called NEW_HUC_AUTH).
The intel_huc_auth fuction is also updated to handle both authentication
types.

v2: check that the GuC auth for clear media has completed before
proceding with the full auth

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 27 +-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c |  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 50 +++---
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  6 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 94 +++
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  2 +-
 .../drm/i915/pxp/intel_pxp_cmd_interface_43.h | 14 ++-
 drivers/gpu/drm/i915/pxp/intel_pxp_huc.c  |  2 +-
 9 files changed, 176 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index b26f493f86fa..c659cc01f32f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -29,13 +29,32 @@ static void gsc_work(struct work_struct *work)
 
if (actions & GSC_ACTION_FW_LOAD) {
ret = intel_gsc_uc_fw_upload(gsc);
-   if (ret == -EEXIST) /* skip proxy if not a new load */
-   actions &= ~GSC_ACTION_FW_LOAD;
-   else if (ret)
+   if (!ret)
+   /* setup proxy on a new load */
+   actions |= GSC_ACTION_SW_PROXY;
+   else if (ret != -EEXIST)
goto out_put;
+
+   /*
+* The HuC auth can be done both before or after the proxy init;
+* if done after, a proxy request will be issued and must be
+* serviced before the authentication can complete.
+* Since this worker also handles proxy requests, we can't
+* perform an action that requires the proxy from within it and
+* then stall waiting for it, because we'd be blocking the
+* service path. Therefore, it is easier for us to load HuC
+* first and do proxy later. The GSC will ack the HuC auth and
+* then send the HuC proxy request as part of the proxy init
+* flow.
+* Note that we can only do the GSC auth if the GuC auth was
+* successful.
+*/
+   if (intel_uc_uses_huc(>uc) &&
+   intel_huc_is_authenticated(>uc.huc, 
INTEL_HUC_AUTH_BY_GUC))
+   intel_huc_auth(>uc.huc, INTEL_HUC_AUTH_BY_GSC);
}
 
-   if (actions & (GSC_ACTION_FW_LOAD | GSC_ACTION_SW_PROXY)) {
+   if (actions & GSC_ACTION_SW_PROXY) {
if (!intel_gsc_uc_fw_init_done(gsc)) {
gt_err(gt, "Proxy request received with GSC not 
loaded!\n");
goto out_put;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
index 579c0f5a1438..0ad090304ca0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c
@@ -99,7 +99,7 @@ void intel_gsc_uc_heci_cmd_emit_mtl_header(struct 
intel_gsc_mtl_header *header,
   u64 host_session_id)
 {
host_session_id &= ~HOST_SESSION_MASK;
-   if (heci_client_id == HECI_MEADDRESS_PXP)
+   if (host_session_id && heci_client_id == HECI_MEADDRESS_PXP)
host_session_id |= HOST_SESSION_PXP_SINGLE;
 
header->validity_marker = GSC_HECI_VALIDITY_MARKER;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index ab5246ae3979..5a4058d39550 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -355,20 +355,34 @@ static int check_huc_loading_mode(struct intel_huc *huc)
 
 int intel_huc_init(struct intel_huc *huc)
 {
+   struct intel_gt *gt = huc_to_gt(huc);
int err;
 
err = check_huc_loading_mode(huc);
if (err)
goto out;
 
+   if (HAS_ENGINE(gt, GSC0)) {
+   struct i915_vma *vma = intel_guc_allocate_vma(>uc.guc, 
SZ_8K);
+   if (IS_ERR(vma)) {
+   huc_info(huc, "Failed to allocate heci pkt\n");
+   goto out;
+   }
+
+   huc->heci_pkt = vma;
+   }
+
err = intel_uc_fw_init(>fw);
if (err)
-   goto out;
+   goto out_pkt;
 
intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_LOADABLE);
 
return 0;
 

[Intel-gfx] [PATCH v3 3/7] drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so

2023-05-26 Thread Daniele Ceraolo Spurio
In the previous patch we extracted the offset of the legacy-style HuC
binary located within the GSC-enabled blob, so now we can use that to
load the HuC via DMA if the fuse is set that way.
Note that we now need to differentiate between "GSC-enabled binary" and
"loaded by GSC", so the former case has been renamed to "has GSC headers"
for clarity, while the latter is now based on the fuse instead of the
binary format. This way, all the legacy load paths are automatically
taken (including the auth by GuC) without having to implement further
code changes.

v2: s/is_meu_binary/has_gsc_headers/, clearer logs (John)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 29 ++-
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  4 +++-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c |  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 12 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |  2 +-
 5 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 6d795438b3e4..37c6a8ca5c71 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -298,31 +298,38 @@ void intel_huc_init_early(struct intel_huc *huc)
 static int check_huc_loading_mode(struct intel_huc *huc)
 {
struct intel_gt *gt = huc_to_gt(huc);
-   bool fw_needs_gsc = intel_huc_is_loaded_by_gsc(huc);
-   bool hw_uses_gsc = false;
+   bool gsc_enabled = huc->fw.has_gsc_headers;
 
/*
 * The fuse for HuC load via GSC is only valid on platforms that have
 * GuC deprivilege.
 */
if (HAS_GUC_DEPRIVILEGE(gt->i915))
-   hw_uses_gsc = intel_uncore_read(gt->uncore, GUC_SHIM_CONTROL2) &
- GSC_LOADS_HUC;
+   huc->loaded_via_gsc = intel_uncore_read(gt->uncore, 
GUC_SHIM_CONTROL2) &
+ GSC_LOADS_HUC;
 
-   if (fw_needs_gsc != hw_uses_gsc) {
-   huc_err(huc, "mismatch between FW (%s) and HW (%s) load 
modes\n",
-   HUC_LOAD_MODE_STRING(fw_needs_gsc), 
HUC_LOAD_MODE_STRING(hw_uses_gsc));
+   if (huc->loaded_via_gsc && !gsc_enabled) {
+   huc_err(huc, "HW requires a GSC-enabled blob, but we found a 
legacy one\n");
return -ENOEXEC;
}
 
-   /* make sure we can access the GSC via the mei driver if we need it */
+   /*
+* Newer GSC_enabled blobs contain the old FW structure inside. If we
+* found that, we can use it to load the legacy way.
+*/
+   if (!huc->loaded_via_gsc && gsc_enabled && !huc->fw.dma_start_offset) {
+   huc_err(huc,"HW in DMA mode, but we have an incompatible 
GSC-enabled blob\n");
+   return -ENOEXEC;
+   }
+
+   /* make sure we can access the GSC if we need it */
if (!(IS_ENABLED(CONFIG_INTEL_MEI_PXP) && 
IS_ENABLED(CONFIG_INTEL_MEI_GSC)) &&
-   fw_needs_gsc) {
-   huc_info(huc, "can't load due to missing MEI modules\n");
+   !HAS_ENGINE(gt, GSC0) && huc->loaded_via_gsc) {
+   huc_info(huc, "can't load due to missing mei modules or 
GSCCS\n");
return -EIO;
}
 
-   huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(fw_needs_gsc));
+   huc_dbg(huc, "loaded by GSC = %s\n", str_yes_no(huc->loaded_via_gsc));
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
index 0789184d81a2..112f0dce4702 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
@@ -39,6 +39,8 @@ struct intel_huc {
struct notifier_block nb;
enum intel_huc_delayed_load_status status;
} delayed_load;
+
+   bool loaded_via_gsc;
 };
 
 int intel_huc_sanitize(struct intel_huc *huc);
@@ -73,7 +75,7 @@ static inline bool intel_huc_is_used(struct intel_huc *huc)
 
 static inline bool intel_huc_is_loaded_by_gsc(const struct intel_huc *huc)
 {
-   return huc->fw.loaded_via_gsc;
+   return huc->loaded_via_gsc;
 }
 
 static inline bool intel_huc_wait_required(struct intel_huc *huc)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
index 037d2ad4879d..3355dc1e2bc6 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c
@@ -50,7 +50,7 @@ int intel_huc_fw_get_binary_info(struct intel_uc_fw *huc_fw, 
const void *data, s
size_t min_size = sizeof(*header);
int i;
 
-   if (!huc_fw->loaded_via_gsc) {
+   if (!huc_fw->has_gsc_headers) {
huc_err(huc, &q

[Intel-gfx] [PATCH v3 4/7] drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow

2023-05-26 Thread Daniele Ceraolo Spurio
Before we add the second step of the MTL HuC auth (via GSC), we need to
have the ability to differentiate between them. To do so, the huc
authentication check is duplicated for GuC and GSC auth, with meu
binaries being considered fully authenticated only after the GSC auth
step.

To report the difference between the 2 auth steps, a new case is added
to the HuC getparam. This way, the clear media driver can start
submitting before full auth, as partial auth is enough for those
workloads.

v2: fix authentication status check for DG2

v3: add a better comment at the top of the HuC file to explain the
different approaches to load and auth (John)

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Reviewed-by: Alan Previn  #v2
---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 111 --
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  16 +++-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c |   4 +-
 drivers/gpu/drm/i915/i915_reg.h   |   3 +
 include/uapi/drm/i915_drm.h   |   3 +-
 5 files changed, 103 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 37c6a8ca5c71..ab5246ae3979 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -10,6 +10,7 @@
 #include "intel_huc.h"
 #include "intel_huc_print.h"
 #include "i915_drv.h"
+#include "i915_reg.h"
 
 #include 
 #include 
@@ -22,15 +23,23 @@
  * capabilities by adding HuC specific commands to batch buffers.
  *
  * The kernel driver is only responsible for loading the HuC firmware and
- * triggering its security authentication, which is performed by the GuC on
- * older platforms and by the GSC on newer ones. For the GuC to correctly
- * perform the authentication, the HuC binary must be loaded before the GuC 
one.
+ * triggering its security authentication. This is done differently depending
+ * on the platform:
+ * - older platforms (from Gen9 to most Gen12s): the load is performed via DMA
+ *   and the authentication via GuC
+ * - DG2: load and authentication are both performed via GSC.
+ * - MTL and newer platforms: the load is performed via DMA (same as with
+ *   not-DG2 older platforms), while the authentication is done in 2-steps,
+ *   a first auth for clear-media workloads via GuC and a second one for all
+ *   workloads via GSC.
+ * On platforms where the GuC does the authentication, to correctly do so the
+ * HuC binary must be loaded before the GuC one.
  * Loading the HuC is optional; however, not using the HuC might negatively
  * impact power usage and/or performance of media workloads, depending on the
  * use-cases.
  * HuC must be reloaded on events that cause the WOPCM to lose its contents
- * (S3/S4, FLR); GuC-authenticated HuC must also be reloaded on GuC/GT reset,
- * while GSC-managed HuC will survive that.
+ * (S3/S4, FLR); on older platforms the HuC must also be reloaded on GuC/GT
+ * reset, while on newer ones it will survive that.
  *
  * See https://github.com/intel/media-driver for the latest details on HuC
  * functionality.
@@ -106,7 +115,7 @@ static enum hrtimer_restart 
huc_delayed_load_timer_callback(struct hrtimer *hrti
 {
struct intel_huc *huc = container_of(hrtimer, struct intel_huc, 
delayed_load.timer);
 
-   if (!intel_huc_is_authenticated(huc)) {
+   if (!intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC)) {
if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_GSC)
huc_notice(huc, "timed out waiting for MEI GSC\n");
else if (huc->delayed_load.status == INTEL_HUC_WAITING_ON_PXP)
@@ -124,7 +133,7 @@ static void huc_delayed_load_start(struct intel_huc *huc)
 {
ktime_t delay;
 
-   GEM_BUG_ON(intel_huc_is_authenticated(huc));
+   GEM_BUG_ON(intel_huc_is_authenticated(huc, INTEL_HUC_AUTH_BY_GSC));
 
/*
 * On resume we don't have to wait for MEI-GSC to be re-probed, but we
@@ -284,13 +293,23 @@ void intel_huc_init_early(struct intel_huc *huc)
}
 
if (GRAPHICS_VER(i915) >= 11) {
-   huc->status.reg = GEN11_HUC_KERNEL_LOAD_INFO;
-   huc->status.mask = HUC_LOAD_SUCCESSFUL;
-   huc->status.value = HUC_LOAD_SUCCESSFUL;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].reg = 
GEN11_HUC_KERNEL_LOAD_INFO;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].mask = HUC_LOAD_SUCCESSFUL;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].value = HUC_LOAD_SUCCESSFUL;
} else {
-   huc->status.reg = HUC_STATUS2;
-   huc->status.mask = HUC_FW_VERIFIED;
-   huc->status.value = HUC_FW_VERIFIED;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].reg = HUC_STATUS2;
+   huc->status[INTEL_HUC_AUTH_BY_GUC].mask = HUC_FW_VERIFIED;
+   huc

[Intel-gfx] [PATCH v3 6/7] drm/i915/mtl/huc: Use the media gt for the HuC getparam

2023-05-26 Thread Daniele Ceraolo Spurio
On MTL, for obvious reasons, HuC is only available on the media tile.
We already disable SW support for HuC on the root gt due to the
absence of VCS engines, but we also need to update the getparam to point
to the HuC struct in the media GT.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
Reviewed-by: John Harrison 
---
 drivers/gpu/drm/i915/i915_getparam.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_getparam.c 
b/drivers/gpu/drm/i915/i915_getparam.c
index 6f11d7eaa91a..890f2b382bee 100644
--- a/drivers/gpu/drm/i915/i915_getparam.c
+++ b/drivers/gpu/drm/i915/i915_getparam.c
@@ -100,7 +100,11 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data,
value = sseu->min_eu_in_pool;
break;
case I915_PARAM_HUC_STATUS:
-   value = intel_huc_check_status(_gt(i915)->uc.huc);
+   /* On platform with a media GT, the HuC is on that GT */
+   if (i915->media_gt)
+   value = intel_huc_check_status(>media_gt->uc.huc);
+   else
+   value = intel_huc_check_status(_gt(i915)->uc.huc);
if (value < 0)
return value;
break;
-- 
2.40.0



[Intel-gfx] [PATCH v3 1/7] drm/i915/uc: perma-pin firmwares

2023-05-26 Thread Daniele Ceraolo Spurio
Now that each FW has its own reserved area, we can keep them always
pinned and skip the pin/unpin dance on reset. This will make things
easier for the 2-step HuC authentication, which requires the FW to be
pinned in GGTT after the xfer is completed.
Since the vma is now valid for a long time and not just for the quick
pin-load-unpin dance, the name "dummy" is no longer appropriare and has
been replaced with vma_res. All the functions have also been updated to
operate on vma_res for consistency.
Given that we pin the vma behind the allocator's back (which is ok
because we do the pinning in an area that was previously reserved for
thus purpose), we do need to explicitly re-pin on resume because the
automated helper won't cover us.

v2: better comments and commit message, s/dummy/vma_res/

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_ggtt.c  |  3 ++
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c |  7 +++-
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  2 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  8 
 drivers/gpu/drm/i915/gt/uc/intel_uc.h |  2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 50 ---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  | 22 ++
 8 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 2a7942fac798..f4e8aa8246e8 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1326,6 +1326,9 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
ggtt->vm.scratch_range(>vm, ggtt->error_capture.start,
   ggtt->error_capture.size);
 
+   list_for_each_entry(gt, >gt_list, ggtt_link)
+   intel_uc_resume_mappings(>uc);
+
ggtt->invalidate(ggtt);
 
if (flush)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index fb0984f875f9..b26f493f86fa 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -90,7 +90,12 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
 {
struct intel_gt *gt = gsc_uc_to_gt(gsc);
 
-   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_GSC);
+   /*
+* GSC FW needs to be copied to a dedicated memory allocations for
+* loading (see gsc->local), so we don't need to GGTT map the FW image
+* itself into GGTT.
+*/
+   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_GSC, false);
INIT_WORK(>work, gsc_work);
 
/* we can arrive here from i915_driver_early_probe for primary
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index c9f20385f6a0..2eb891b270ae 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -164,7 +164,7 @@ void intel_guc_init_early(struct intel_guc *guc)
struct intel_gt *gt = guc_to_gt(guc);
struct drm_i915_private *i915 = gt->i915;
 
-   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_GUC);
+   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_GUC, true);
intel_guc_ct_init_early(>ct);
intel_guc_log_init_early(>log);
intel_guc_submission_init_early(guc);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 04724ff56ded..268e036f8f28 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -276,7 +276,7 @@ void intel_huc_init_early(struct intel_huc *huc)
struct drm_i915_private *i915 = huc_to_gt(huc)->i915;
struct intel_gt *gt = huc_to_gt(huc);
 
-   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_HUC);
+   intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_HUC, true);
 
/*
 * we always init the fence as already completed, even if HuC is not
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index c8b9cbb7ba3a..1e7f5cc9d550 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -700,6 +700,12 @@ void intel_uc_suspend(struct intel_uc *uc)
}
 }
 
+static void __uc_resume_mappings(struct intel_uc *uc)
+{
+   intel_uc_fw_resume_mapping(>guc.fw);
+   intel_uc_fw_resume_mapping(>huc.fw);
+}
+
 static int __uc_resume(struct intel_uc *uc, bool enable_communication)
 {
struct intel_guc *guc = >guc;
@@ -767,4 +773,6 @@ static const struct intel_uc_ops uc_ops_on = {
 
.init_hw = __uc_init_hw,
.fini_hw = __uc_fini_hw,
+
+   .resume_mappings = __uc_resume_mappings,
 };
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
index d585524d94de..014bb7d83689 100644
--- a/drivers/gpu/drm/i915

[Intel-gfx] [PATCH v3 0/7] drm/i915: HuC loading and authentication for MTL

2023-05-26 Thread Daniele Ceraolo Spurio
The HuC loading and authentication flow is once again changing and a new
"clear-media only" authentication step is introduced. The flow is as
follows:

1) The HuC is loaded via DMA - same as all non-GSC HuC binaries.

2) The HuC is authenticated by the GuC - this is the same step as
performed for all non-GSC HuC binaries and re-uses the same code, but
it is now resulting in a partial authentication that only allows
clear-media workloads.

3) The HuC is fully authenticated for all workloads by the GSC - this
is done via a new PXP command, submitted via the GSCCS.

The advantage of this new flow is that we can start processing
clear-media workloads without having to wait for the GSC to be ready,
which can take several seconds.

As part of this change, the HuC status getparam has been updated with a
new value to indicate a partial authentication. Note tha the media
driver is checking for value > 0 for clear media workloads, so no
changes are required in userspace for that to work.

v2: fix HuC auth status check for DG2.

v3: addrss review feedback, stop using the "meu" tag for the naming of
the headers, better comments

Cc: Alan Previn 
Cc: John Harrison 
Acked-by: Tony Ye 

Daniele Ceraolo Spurio (7):
  drm/i915/uc: perma-pin firmwares
  drm/i915/huc: Parse the GSC-enabled HuC binary
  drm/i915/huc: Load GSC-enabled HuC via DMA xfer if the fuse says so
  drm/i915/huc: differentiate the 2 steps of the MTL HuC auth flow
  drm/i915/mtl/huc: auth HuC via GSC
  drm/i915/mtl/huc: Use the media gt for the HuC getparam
  drm/i915/huc: define HuC FW version for MTL

 drivers/gpu/drm/i915/gt/intel_ggtt.c  |   3 +
 .../drm/i915/gt/uc/intel_gsc_binary_headers.h |  74 ++
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c |  34 ++-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c |   2 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|   2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 201 ++-
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  26 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 233 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h |   6 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h  |  21 ++
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  10 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc.h |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 132 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |  26 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h  |   6 -
 drivers/gpu/drm/i915/i915_getparam.c  |   6 +-
 drivers/gpu/drm/i915/i915_reg.h   |   3 +
 .../drm/i915/pxp/intel_pxp_cmd_interface_43.h |  14 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_huc.c  |   2 +-
 include/uapi/drm/i915_drm.h   |   3 +-
 20 files changed, 654 insertions(+), 152 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_binary_headers.h
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h

-- 
2.40.0



[Intel-gfx] [CI] PR for MTL HuC v8.5.0

2023-05-26 Thread Daniele Ceraolo Spurio
The following changes since commit d11ae98478d52548172918511f949aa92193f2c6:

  brcm: Add symlinks from Pine64 devices to AW-CM256SM.txt (2023-05-25 08:26:29 
-0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_huc_8.5.0

for you to fetch changes up to eb86681057e248375ec91f6c340c671cfbf75501:

  i915: Add HuC v8.5.0 for MTL (2023-05-26 16:44:50 -0700)


Daniele Ceraolo Spurio (1):
  i915: Add HuC v8.5.0 for MTL

 WHENCE   |   3 +++
 i915/mtl_huc_gsc.bin | Bin 0 -> 565248 bytes
 2 files changed, 3 insertions(+)
 create mode 100755 i915/mtl_huc_gsc.bin


[Intel-gfx] [PATCH 5/6] drm/i915/uc/gsc: define gsc fw

2023-05-05 Thread Daniele Ceraolo Spurio
Add FW definition and the matching override modparam.

The GSC FW has both a release version, based on platform and a rolling
counter, and a compatibility version, which is the one tracking
interface changes. Since what we care about is the interface, we use
the compatibility version in the buinary names.

Same as with the GuC, a major version bump indicate a
backward-incompatible change, while a minor version bump indicates a
backward-compatible one, so we use only the former in the file name.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 32 ++--
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 36ee96c02d74..531cd172151d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -124,6 +124,18 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
fw_def(BROXTON,  0, huc_mmp(bxt,  2, 0, 0)) \
fw_def(SKYLAKE,  0, huc_mmp(skl,  2, 0, 0))
 
+/*
+ * The GSC FW has both a release version, based on platform and a rolling
+ * counter, and a compatibility version, which is the one tracking
+ * interface changes. Since what we care about is the interface, we use
+ * the compatibility version in the buinary names.
+ * Same as with the GuC, a major version bump indicate a
+ * backward-incompatible change, while a minor version bump indicates a
+ * backward-compatible one, so we use only the former in the file name.
+ */
+#define INTEL_GSC_FIRMWARE_DEFS(fw_def, gsc_def) \
+   fw_def(METEORLAKE,   0, gsc_def(mtl, 1, 0))
+
 /*
  * Set of macros for producing a list of filenames from the above table.
  */
@@ -159,6 +171,9 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 #define MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MMP(prefix_, "huc", major_, minor_, patch_)
 
+#define MAKE_GSC_FW_PATH(prefix_, major_, minor_) \
+   __MAKE_UC_FW_PATH_MAJOR(prefix_, "gsc", major_)
+
 /*
  * All blobs need to be declared via MODULE_FIRMWARE().
  * This first expansion of the table macros is solely to provide
@@ -169,6 +184,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 
 INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH_MAJOR, 
MAKE_GUC_FW_PATH_MMP)
 INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, 
MAKE_HUC_FW_PATH_MMP, MAKE_HUC_FW_PATH_GSC)
+INTEL_GSC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GSC_FW_PATH)
 
 /*
  * The next expansion of the table macros (in __uc_fw_auto_select below) 
provides
@@ -218,6 +234,10 @@ struct __packed uc_fw_blob {
 #define HUC_FW_BLOB_GSC(prefix_) \
UC_FW_BLOB_NEW(0, 0, 0, true, MAKE_HUC_FW_PATH_GSC(prefix_))
 
+#define GSC_FW_BLOB(prefix_, major_, minor_) \
+   UC_FW_BLOB_NEW(major_, minor_, 0, true, \
+  MAKE_GSC_FW_PATH(prefix_, major_, minor_))
+
 struct __packed uc_fw_platform_requirement {
enum intel_platform p;
u8 rev; /* first platform rev using this FW */
@@ -245,9 +265,13 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
static const struct uc_fw_platform_requirement blobs_huc[] = {
INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, 
HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)
};
+   static const struct uc_fw_platform_requirement blobs_gsc[] = {
+   INTEL_GSC_FIRMWARE_DEFS(MAKE_FW_LIST, GSC_FW_BLOB)
+   };
static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = 
{
[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+   [INTEL_UC_FW_TYPE_GSC] = { blobs_gsc, ARRAY_SIZE(blobs_gsc) },
};
static bool verified[INTEL_UC_FW_NUM_TYPES];
const struct uc_fw_platform_requirement *fw_blobs;
@@ -257,14 +281,6 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
int i;
bool found;
 
-   /*
-* GSC FW support is still not fully in place, so we're not defining
-* the FW blob yet because we don't want the driver to attempt to load
-* it until we're ready for it.
-*/
-   if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
-   return;
-
/*
 * The only difference between the ADL GuC FWs is the HWConfig support.
 * ADL-N does not support HWConfig, so we should use the same binary as
-- 
2.40.0



[Intel-gfx] [PATCH 2/6] drm/i915/uc/gsc: fixes and updates for GSC memory allocation

2023-05-05 Thread Daniele Ceraolo Spurio
A few fixes/updates are required around the GSC memory allocation and it
is easier to do them all at the same time. The changes are as follows:

1 - Switch the memory allocation to stolen memory. We need to avoid
accesses from GSC FW to normal memory after the suspend function has
completed and to do so we can either switch to using stolen or make sure
the GSC is gone to sleep before the end of the suspend function. Given
that the GSC waits for a bit before going idle even if there are no
pending operations, it is easier and quicker to just use stolen memory.

2 - Reduce the GSC allocation size to 4MBs, which is the POR requirement.
The 8MBs were needed only for early FW and I had misunderstood that as
being the expected POR size when I sent the original patch.

3 - Perma-map the GSC allocation. This isn't required immediately, but it
will be needed later to be able to quickly extract the GSC logs, which are
inside the allocation. Since the mapping code needs to be rewritten due to
switching to stolen, it makes sense to do the switch immediately to avoid
having to change it again later.

Note that the explicit setting of CACHE_NONE for Wa_22016122933 has been
dropped because that's the default setting for stolen memory on !LLC
platforms.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
Cc: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 29 ++---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 77 ---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  1 +
 3 files changed, 75 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index f46eb17a7a98..4814901fac9e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -3,6 +3,7 @@
  * Copyright © 2022 Intel Corporation
  */
 
+#include "gem/i915_gem_lmem.h"
 #include "gt/intel_engine_pm.h"
 #include "gt/intel_gpu_commands.h"
 #include "gt/intel_gt.h"
@@ -109,38 +110,21 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
 {
struct intel_gt *gt = gsc_uc_to_gt(gsc);
struct drm_i915_private *i915 = gt->i915;
-   struct drm_i915_gem_object *obj;
-   void *src, *dst;
+   void *src;
 
if (!gsc->local)
return -ENODEV;
 
-   obj = gsc->local->obj;
-
-   if (obj->base.size < gsc->fw.size)
+   if (gsc->local->size < gsc->fw.size)
return -ENOSPC;
 
-   /*
-* Wa_22016122933: For MTL the shared memory needs to be mapped
-* as WC on CPU side and UC (PAT index 2) on GPU side
-*/
-   if (IS_METEORLAKE(i915))
-   i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE);
-
-   dst = i915_gem_object_pin_map_unlocked(obj,
-  i915_coherent_map_type(i915, 
obj, true));
-   if (IS_ERR(dst))
-   return PTR_ERR(dst);
-
src = i915_gem_object_pin_map_unlocked(gsc->fw.obj,
   i915_coherent_map_type(i915, 
gsc->fw.obj, true));
-   if (IS_ERR(src)) {
-   i915_gem_object_unpin_map(obj);
+   if (IS_ERR(src))
return PTR_ERR(src);
-   }
 
-   memset(dst, 0, obj->base.size);
-   memcpy(dst, src, gsc->fw.size);
+   memset_io(gsc->local_vaddr, 0, gsc->local->size);
+   memcpy_toio(gsc->local_vaddr, src, gsc->fw.size);
 
/*
 * Wa_22016122933: Making sure the data in dst is
@@ -149,7 +133,6 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
intel_guc_write_barrier(>uc.guc);
 
i915_gem_object_unpin_map(gsc->fw.obj);
-   i915_gem_object_unpin_map(obj);
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index bbf21b93fc8d..2ae693b01b49 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -130,26 +130,85 @@ void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
}
 }
 
+static int gsc_allocate_and_map_vma(struct intel_gsc_uc *gsc, u32 size)
+{
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   struct drm_i915_gem_object *obj;
+   struct i915_vma *vma;
+   void __iomem *vaddr;
+   int ret = 0;
+
+   /*
+* The GSC FW doesn't immediately suspend after becoming idle, so there
+* is a chance that it could still be awake after we successfully
+* return from the  pci suspend function, even if there are no pending
+* operations.
+* The FW might therefore try to access memory for its suspend operation
+* after the kernel has completed the HW suspend flow; this can cause
+* issues if the FW is mapped in normal RAM memory, as some of the
+* involved HW units 

[Intel-gfx] [PATCH 6/6] drm/i915/uc/gsc: Add a gsc_info debugfs

2023-05-05 Thread Daniele Ceraolo Spurio
Add a new debugfs to dump information about the GSC. This includes:

- the FW path and SW tracking status;
- the release, security and compatibility versions;
- the HECI1 status registers.

Note that those are the same registers that the mei driver dumps in
their own status sysfs on DG2 (where mei owns the GSC).

To make it simpler to loop through the status register, the code has
been update to use a PICK macro and the existing code using the regs had
been adapted to match.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/Makefile |  3 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 29 +---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 46 ++-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  2 +
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c | 38 +++
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h | 14 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc.c|  6 +--
 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c |  2 +
 drivers/gpu/drm/i915/i915_reg.h   | 26 ++-
 9 files changed, 142 insertions(+), 24 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index d97d45ae1a0d..fd6a1ae542bd 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -196,7 +196,8 @@ i915-y += \
  gt/uc/intel_gsc_fw.o \
  gt/uc/intel_gsc_proxy.o \
  gt/uc/intel_gsc_uc.o \
- gt/uc/intel_gsc_uc_heci_cmd_submit.o\
+ gt/uc/intel_gsc_uc_debugfs.o \
+ gt/uc/intel_gsc_uc_heci_cmd_submit.o \
  gt/uc/intel_guc.o \
  gt/uc/intel_guc_ads.o \
  gt/uc/intel_guc_capture.o \
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 0b6dcd982b14..3014e982aab2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -12,36 +12,31 @@
 #include "intel_gsc_fw.h"
 #include "intel_gsc_meu_headers.h"
 #include "intel_gsc_uc_heci_cmd_submit.h"
-
-#define GSC_FW_STATUS_REG  _MMIO(0x116C40)
-#define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
-#define   GSC_FW_CURRENT_STATE_RESET   0
-#define   GSC_FW_PROXY_STATE_NORMAL5
-#define GSC_FW_INIT_COMPLETE_BIT   REG_BIT(9)
+#include "i915_reg.h"
 
 static bool gsc_is_in_reset(struct intel_uncore *uncore)
 {
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   u32 fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
-   return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
-  GSC_FW_CURRENT_STATE_RESET;
+   return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE, fw_status) ==
+   HECI1_FWSTS1_CURRENT_STATE_RESET;
 }
 
 bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
 {
struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   u32 fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
-   return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
-  GSC_FW_PROXY_STATE_NORMAL;
+   return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE, fw_status) ==
+  HECI1_FWSTS1_PROXY_STATE_NORMAL;
 }
 
 bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
 {
struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
-   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+   u32 fw_status = intel_uncore_read(uncore, 
HECI_FWSTS(MTL_GSC_HECI1_BASE, 1));
 
-   return fw_status & GSC_FW_INIT_COMPLETE_BIT;
+   return fw_status & HECI1_FWSTS1_INIT_COMPLETE;
 }
 
 static inline u32 cpd_entry_offset(const struct intel_gsc_cpd_entry *entry)
@@ -265,9 +260,9 @@ static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc)
 static int gsc_fw_wait(struct intel_gt *gt)
 {
return intel_wait_for_register(gt->uncore,
-  GSC_FW_STATUS_REG,
-  GSC_FW_INIT_COMPLETE_BIT,
-  GSC_FW_INIT_COMPLETE_BIT,
+  HECI_FWSTS(MTL_GSC_HECI1_BASE, 1),
+  HECI1_FWSTS1_INIT_COMPLETE,
+  HECI1_FWSTS1_INIT_COMPLETE,
   500);
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index 2ae693b01b49..5475e95d61c6 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -9,8 +9,9 @@
 #include "gt/intel_gt_print.h"
 #include "int

[Intel-gfx] [PATCH 3/6] drm/i915/uc/gsc: extract release and security versions from the gsc binary

2023-05-05 Thread Daniele Ceraolo Spurio
The release and security versions of the GSC binary are not used at
runtime to decide interface compatibility (there is a separate version
for that), but they're still useful for debug, so it is still worth
extracting them and printing them out in dmesg.

To get to these version, we need to navigate through various headers in
the binary. See in-code comment for details.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 130 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |   2 +
 .../drm/i915/gt/uc/intel_gsc_meu_headers.h|  83 ++-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |   3 +
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c |  13 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  |  30 ++--
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |   3 +
 7 files changed, 237 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 4814901fac9e..df53c13e99a3 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -10,6 +10,7 @@
 #include "gt/intel_gt_print.h"
 #include "gt/intel_ring.h"
 #include "intel_gsc_fw.h"
+#include "intel_gsc_meu_headers.h"
 
 #define GSC_FW_STATUS_REG  _MMIO(0x116C40)
 #define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
@@ -42,6 +43,129 @@ bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
return fw_status & GSC_FW_INIT_COMPLETE_BIT;
 }
 
+static inline u32 cpd_entry_offset(const struct intel_gsc_cpd_entry *entry)
+{
+   return entry->offset & INTEL_GSC_CPD_ENTRY_OFFSET_MASK;
+}
+
+int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const void *data, 
size_t size)
+{
+   struct intel_gsc_uc *gsc = container_of(gsc_fw, struct intel_gsc_uc, 
fw);
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   const struct intel_gsc_layout_pointers *layout = data;
+   const struct intel_gsc_bpdt_header *bpdt_header = NULL;
+   const struct intel_gsc_bpdt_entry *bpdt_entry = NULL;
+   const struct intel_gsc_cpd_header_v2 *cpd_header = NULL;
+   const struct intel_gsc_cpd_entry *cpd_entry = NULL;
+   const struct intel_gsc_manifest_header *manifest;
+   size_t min_size = sizeof(*layout);
+   int i;
+
+   if (size < min_size) {
+   gt_err(gt, "GSC FW too small! %zu < %zu\n", size, min_size);
+   return -ENODATA;
+   }
+
+   /*
+* The GSC binary starts with the pointer layout, which contains the
+* locations of the various partitions of the binary. The one we're
+* interested in to get the version is the boot1 partition, where we can
+* find a BPDT header followed by entries, one of which points to the
+* RBE sub-section of the partition. From here, we can parse the CPD
+* header and the following entries to find the manifest location
+* (entry identified by the "RBEP.man" name), from which we can finally
+* extract the version.
+*
+* --
+* [  intel_gsc_layout_pointers ]
+* [  ...   ]
+* [  boot1_offset  >---]--o
+* [  ...   ]  |
+* --  |
+* |
+* --  |
+* [  intel_gsc_bpdt_header ]<-o
+* --
+* [  intel_gsc_bpdt_entry[]]
+* [  entry1]
+* [  ...   ]
+* [  entryX]
+* [  type == GSC_RBE   ]
+* [  offset  >-]--o
+* [  ...   ]  |
+* --  |
+* |
+* --  |
+* [  intel_gsc_cpd_header_v2   ]<-o
+* --
+* [  intel_gsc_cpd_entry[] ]
+* [  entry1]
+* [  ...   ]
+* [  entryX]
+* [  "RBEP.man"]
+* [   ... 

[Intel-gfx] [PATCH 4/6] drm/i915/uc/gsc: query the GSC FW for its compatibility version

2023-05-05 Thread Daniele Ceraolo Spurio
The compatibility version is queried via an MKHI command. Right now, the
only existing interface is 1.0
This is basically the interface version for the GSC FW, so the plan is
to use it as the main tracked version, including for the binary naming
in the fetch code.

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 91 ++-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 44 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |  1 +
 4 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index df53c13e99a3..0b6dcd982b14 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -11,6 +11,7 @@
 #include "gt/intel_ring.h"
 #include "intel_gsc_fw.h"
 #include "intel_gsc_meu_headers.h"
+#include "intel_gsc_uc_heci_cmd_submit.h"
 
 #define GSC_FW_STATUS_REG  _MMIO(0x116C40)
 #define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
@@ -270,6 +271,84 @@ static int gsc_fw_wait(struct intel_gt *gt)
   500);
 }
 
+struct intel_gsc_mkhi_header {
+   u8  group_id;
+#define MKHI_GROUP_ID_GFX_SRV 0x30
+
+   u8  command;
+#define MKHI_GFX_SRV_GET_HOST_COMPATIBILITY_VERSION (0x42)
+
+   u8  reserved;
+   u8  result;
+} __packed;
+
+struct mtl_gsc_ver_msg_in {
+   struct intel_gsc_mtl_header header;
+   struct intel_gsc_mkhi_header mkhi;
+} __packed;
+
+struct mtl_gsc_ver_msg_out {
+   struct intel_gsc_mtl_header header;
+   struct intel_gsc_mkhi_header mkhi;
+   u16 proj_major;
+   u16 compat_major;
+   u16 compat_minor;
+   u16 reserved[5];
+} __packed;
+
+static int gsc_fw_query_compatibility_version(struct intel_gsc_uc *gsc)
+{
+   struct intel_gt *gt = gsc_uc_to_gt(gsc);
+   struct mtl_gsc_ver_msg_in *msg_in;
+   struct mtl_gsc_ver_msg_out *msg_out;
+   struct i915_vma *vma;
+   u64 offset;
+   void *vaddr;
+   int err;
+
+   err = intel_guc_allocate_and_map_vma(>uc.guc, PAGE_SIZE * 2,
+, );
+   if (err) {
+   gt_err(gt, "failed to allocate vma for GSC version query\n");
+   return err;
+   }
+
+   offset = i915_ggtt_offset(vma);
+   msg_in = vaddr;
+   msg_out = vaddr + SZ_4K;
+
+   intel_gsc_uc_heci_cmd_emit_mtl_header(_in->header,
+ HECI_MEADDRESS_MKHI,
+ sizeof(*msg_in), 0);
+   msg_in->mkhi.group_id = MKHI_GROUP_ID_GFX_SRV;
+   msg_in->mkhi.command = MKHI_GFX_SRV_GET_HOST_COMPATIBILITY_VERSION;
+
+   err = intel_gsc_uc_heci_cmd_submit_packet(>uc.gsc,
+ offset, sizeof(*msg_in),
+ offset + SZ_4K, SZ_4K);
+   if (err) {
+   gt_err(gt,
+  "failed to submit GSC request for compatibility version: 
%d\n",
+  err);
+   goto out_vma;
+   }
+
+   if (msg_out->header.message_size != sizeof(*msg_out)) {
+   gt_err(gt, "invalid GSC reply length %u [expected %zu], s=0x%x, 
f=0x%x, r=0x%x\n",
+   msg_out->header.message_size, sizeof(*msg_out),
+   msg_out->header.status, msg_out->header.flags, 
msg_out->mkhi.result);
+   err = -EPROTO;
+   goto out_vma;
+   }
+
+   gsc->fw.file_selected.ver.major = msg_out->compat_major;
+   gsc->fw.file_selected.ver.minor = msg_out->compat_minor;
+
+out_vma:
+   i915_vma_unpin_and_release(, I915_VMA_RELEASE_MAP);
+   return err;
+}
+
 int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc)
 {
struct intel_gt *gt = gsc_uc_to_gt(gsc);
@@ -327,11 +406,21 @@ int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc)
if (err)
goto fail;
 
+   err = gsc_fw_query_compatibility_version(gsc);
+   if (err)
+   goto fail;
+
+   /* we only support compatibility version 1.0 at the moment */
+   err = intel_uc_check_file_version(gsc_fw, NULL);
+   if (err)
+   goto fail;
+
/* FW is not fully operational until we enable SW proxy */
intel_uc_fw_change_status(gsc_fw, INTEL_UC_FIRMWARE_TRANSFERRED);
 
-   gt_info(gt, "Loaded GSC firmware %s (r%u.%u.%u.%u, svn%u)\n",
+   gt_info(gt, "Loaded GSC firmware %s (cv%u.%u, r%u.%u.%u.%u, svn %u)\n",
gsc_fw->file_selected.path,
+   gsc_fw->file_selected.ver.major, 
gsc_fw->file_selected.ver.minor,
gsc->release.maj

[Intel-gfx] [PATCH 1/6] DO NOT REVIEW: drm/i915: HuC loading and authentication for MTL

2023-05-05 Thread Daniele Ceraolo Spurio
This is a of the HuC support for MTL series [1]. It's been included
because one of the new patches in this series depend on it, but it
should be reviewd separately in its own thread.

[1] https://patchwork.freedesktop.org/series/117080/
Signed-off-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/intel_ggtt.c  |   3 +
 .../drm/i915/gt/uc/intel_gsc_meu_headers.h|  74 ++
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c |  31 ++-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c |   2 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|   2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 182 ++
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  26 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 233 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h |   6 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h  |  21 ++
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  10 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc.h |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 120 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |   9 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h  |   6 -
 drivers/gpu/drm/i915/i915_getparam.c  |   6 +-
 drivers/gpu/drm/i915/i915_reg.h   |   3 +
 .../drm/i915/pxp/intel_pxp_cmd_interface_43.h |  14 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_huc.c  |   2 +-
 include/uapi/drm/i915_drm.h   |   3 +-
 20 files changed, 621 insertions(+), 134 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h

diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 20915edc8bd9..ab71ed11de79 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1322,6 +1322,9 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
ggtt->vm.scratch_range(>vm, ggtt->error_capture.start,
   ggtt->error_capture.size);
 
+   list_for_each_entry(gt, >gt_list, ggtt_link)
+   intel_uc_resume_mappings(>uc);
+
ggtt->invalidate(ggtt);
 
if (flush)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
new file mode 100644
index ..d55a66202576
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef _INTEL_GSC_MEU_H_
+#define _INTEL_GSC_MEU_H_
+
+#include 
+
+/* Code partition directory (CPD) structures */
+struct intel_gsc_cpd_header_v2 {
+   u32 header_marker;
+#define INTEL_GSC_CPD_HEADER_MARKER 0x44504324
+
+   u32 num_of_entries;
+   u8 header_version;
+   u8 entry_version;
+   u8 header_length; /* in bytes */
+   u8 flags;
+   u32 partition_name;
+   u32 crc32;
+} __packed;
+
+struct intel_gsc_cpd_entry {
+   u8 name[12];
+
+   /*
+* Bits 0-24: offset from the beginning of the code partition
+* Bit 25: huffman compressed
+* Bits 26-31: reserved
+*/
+   u32 offset;
+#define INTEL_GSC_CPD_ENTRY_OFFSET_MASK GENMASK(24, 0)
+#define INTEL_GSC_CPD_ENTRY_HUFFMAN_COMP BIT(25)
+
+   /*
+* Module/Item length, in bytes. For Huffman-compressed modules, this
+* refers to the uncompressed size. For software-compressed modules,
+* this refers to the compressed size.
+*/
+   u32 length;
+
+   u8 reserved[4];
+} __packed;
+
+struct intel_gsc_meu_version {
+   u16 major;
+   u16 minor;
+   u16 hotfix;
+   u16 build;
+} __packed;
+
+struct intel_gsc_manifest_header {
+   u32 header_type; /* 0x4 for manifest type */
+   u32 header_length; /* in dwords */
+   u32 header_version;
+   u32 flags;
+   u32 vendor;
+   u32 date;
+   u32 size; /* In dwords, size of entire manifest (header + extensions) */
+   u32 header_id;
+   u32 internal_data;
+   struct intel_gsc_meu_version fw_version;
+   u32 security_version;
+   struct intel_gsc_meu_version meu_kit_version;
+   u32 meu_manifest_version;
+   u8 general_data[4];
+   u8 reserved3[56];
+   u32 modulus_size; /* in dwords */
+   u32 exponent_size; /* in dwords */
+} __packed;
+
+#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index fb0984f875f9..bbf21b93fc8d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -29,13 +29,29 @@ static void gsc_work(struct work_struct *work)
 
if (actions & GSC_ACTION_FW_LOAD) {
ret = intel_gsc_uc_fw_upload(gsc);
-   if (ret == -EEXIST) /* skip proxy if not a new load */
-   actions &= ~GSC_ACTION_FW_LOAD;
-   else if (

[Intel-gfx] [PATCH 0/6] drm/i915: GSC FW support for MTL

2023-05-05 Thread Daniele Ceraolo Spurio
Last chunk of the required support for the GSC FW. This includes some
fixes to the GSC memory allocation, FW idefinition and version
management, plus a new debugfs for debug information.

Adding the FW definition will enable all the features that are dependent
on the GSC being loaded (Media C6, HuC loading, SW proxy, PXP, HDCP).

The HuC series [1] has been included, squashed in a single patch,
as one of the patches in this series depends on it, but it should be
reviewd in its own thread.

[1] https://patchwork.freedesktop.org/series/117080/
Cc: Alan Previn 
Cc: John Harrison 
Cc: Suraj Kandpal 

Daniele Ceraolo Spurio (6):
  DO NOT REVIEW: drm/i915: HuC loading and authentication for MTL
  drm/i915/uc/gsc: fixes and updates for GSC memory allocation
  drm/i915/uc/gsc: extract release and security versions from the gsc
binary
  drm/i915/uc/gsc: query the GSC FW for its compatibility version
  drm/i915/uc/gsc: define gsc fw
  drm/i915/uc/gsc: Add a gsc_info debugfs

 drivers/gpu/drm/i915/Makefile |   3 +-
 drivers/gpu/drm/i915/gt/intel_ggtt.c  |   3 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c | 277 +++---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |   2 +
 .../drm/i915/gt/uc/intel_gsc_meu_headers.h| 143 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 154 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |   6 +
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c |  38 +++
 .../gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h |  14 +
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.c |   2 +-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|   2 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 182 
 drivers/gpu/drm/i915/gt/uc/intel_huc.h|  26 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 224 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h |   6 +-
 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h  |  21 ++
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  10 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc.h |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_debugfs.c |   2 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 218 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h  |  13 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw_abi.h  |   6 -
 drivers/gpu/drm/i915/i915_getparam.c  |   6 +-
 drivers/gpu/drm/i915/i915_reg.h   |  25 ++
 .../drm/i915/pxp/intel_pxp_cmd_interface_43.h |  14 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_huc.c  |   2 +-
 include/uapi/drm/i915_drm.h   |   3 +-
 28 files changed, 1191 insertions(+), 214 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_meu_headers.h
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.c
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc_debugfs.h
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_huc_print.h

-- 
2.40.0



[Intel-gfx] [CI] PR for GSC 102.0.0.1556 for MTL

2023-05-05 Thread Daniele Ceraolo Spurio
The following changes since commit 2bc50f50b092087636cc216f1605c557dc12a1ee:

  Merge branch 'mtl_guc_70.6.6' of 
git://anongit.freedesktop.org/drm/drm-firmware (2023-05-04 07:20:20 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_gsc_102.0.0.1556

for you to fetch changes up to d8944e5bb05b30bb8c0ed6813c8365de1e59306f:

  i915: add GSC 102.0.0.1556 for MTL (2023-05-05 07:25:26 -0700)


Daniele Ceraolo Spurio (1):
  i915: add GSC 102.0.0.1556 for MTL

 WHENCE |   3 +++
 i915/mtl_gsc_1.bin | Bin 0 -> 1142784 bytes
 2 files changed, 3 insertions(+)
 create mode 100644 i915/mtl_gsc_1.bin


[Intel-gfx] [PATCH v3 4/4] drm/i915/gsc: add support for GSC proxy interrupt

2023-05-02 Thread Daniele Ceraolo Spurio
The GSC notifies us of a proxy request via the HECI2 interrupt. The
interrupt must be enabled both in the HECI layer and in our usual gt irq
programming; for the latter, the interrupt is enabled via the same enable
register as the GSC CS, but it does have its own mask register. When the
interrupt is received, we also need to de-assert it in both layers.

The handling of the proxy request is deferred to the same worker that we
use for GSC load. New flags have been added to distinguish between the
init case and the proxy interrupt.

v2: Make sure not to set the reset bit when enabling/disabling the GSC
interrupts, fix defines (Alan)

v3: rebase on proxy status register check

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
---
 drivers/gpu/drm/i915/gt/intel_gt_irq.c   | 22 ++-
 drivers/gpu/drm/i915/gt/intel_gt_regs.h  |  3 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c | 44 +-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c| 61 ++--
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h|  3 +
 6 files changed, 112 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c 
b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index c0f3ff4746ad..95e59ed6651d 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -16,6 +16,7 @@
 #include "intel_uncore.h"
 #include "intel_rps.h"
 #include "pxp/intel_pxp_irq.h"
+#include "uc/intel_gsc_proxy.h"
 
 static void guc_irq_handler(struct intel_guc *guc, u16 iir)
 {
@@ -82,6 +83,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 
instance,
if (instance == OTHER_GSC_INSTANCE)
return intel_gsc_irq_handler(gt, iir);
 
+   if (instance == OTHER_GSC_HECI_2_INSTANCE)
+   return intel_gsc_proxy_irq_handler(>uc.gsc, iir);
+
WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
  instance, iir);
 }
@@ -101,6 +105,8 @@ static struct intel_gt *pick_gt(struct intel_gt *gt, u8 
class, u8 instance)
case VIDEO_ENHANCEMENT_CLASS:
return media_gt;
case OTHER_CLASS:
+   if (instance == OTHER_GSC_HECI_2_INSTANCE)
+   return media_gt;
if (instance == OTHER_GSC_INSTANCE && HAS_ENGINE(media_gt, 
GSC0))
return media_gt;
fallthrough;
@@ -257,6 +263,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
u32 irqs = GT_RENDER_USER_INTERRUPT;
u32 guc_mask = intel_uc_wants_guc(>uc) ? GUC_INTR_GUC2HOST : 0;
u32 gsc_mask = 0;
+   u32 heci_mask = 0;
u32 dmask;
u32 smask;
 
@@ -268,10 +275,16 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
dmask = irqs << 16 | irqs;
smask = irqs << 16;
 
-   if (HAS_ENGINE(gt, GSC0))
+   if (HAS_ENGINE(gt, GSC0)) {
+   /*
+* the heci2 interrupt is enabled via the same register as the
+* GSC interrupt, but it has its own mask register.
+*/
gsc_mask = irqs;
-   else if (HAS_HECI_GSC(gt->i915))
+   heci_mask = GSC_IRQ_INTF(1); /* HECI2 IRQ for SW Proxy*/
+   } else if (HAS_HECI_GSC(gt->i915)) {
gsc_mask = GSC_IRQ_INTF(0) | GSC_IRQ_INTF(1);
+   }
 
BUILD_BUG_ON(irqs & 0x);
 
@@ -281,7 +294,7 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
if (CCS_MASK(gt))
intel_uncore_write(uncore, GEN12_CCS_RSVD_INTR_ENABLE, smask);
if (gsc_mask)
-   intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE, 
gsc_mask);
+   intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_ENABLE, 
gsc_mask | heci_mask);
 
/* Unmask irqs on RCS, BCS, VCS and VECS engines. */
intel_uncore_write(uncore, GEN11_RCS0_RSVD_INTR_MASK, ~smask);
@@ -309,6 +322,9 @@ void gen11_gt_irq_postinstall(struct intel_gt *gt)
intel_uncore_write(uncore, GEN12_CCS2_CCS3_INTR_MASK, ~dmask);
if (gsc_mask)
intel_uncore_write(uncore, GEN11_GUNIT_CSME_INTR_MASK, 
~gsc_mask);
+   if (heci_mask)
+   intel_uncore_write(uncore, GEN12_HECI2_RSVD_INTR_MASK,
+  ~REG_FIELD_PREP(ENGINE1_MASK, heci_mask));
 
if (guc_mask) {
/* the enable bit is common for both GTs but the masks are 
separate */
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index af80d2fe739b..b8a39c219b60 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1596,6 +1596,7 @@
 
 #define GEN11_GT_INTR_DW(x)_MMIO(0x190018 + ((x) * 4))
 #define   GEN11_CSME   (31)
+#define   GEN12_HECI_2 

[Intel-gfx] [PATCH v3 1/4] drm/i915/mtl: Define GSC Proxy component interface

2023-05-02 Thread Daniele Ceraolo Spurio
From: Alexander Usyskin 

GSC Proxy component is used for communication between the
Intel graphics driver and MEI driver.

Cc: Alan Previn 
Signed-off-by: Alexander Usyskin 
Signed-off-by: Tomas Winkler 
Signed-off-by: Daniele Ceraolo Spurio 
Acked-by: Greg Kroah-Hartman 
---

v2: Improve documentation, remove unneeded includes

 include/drm/i915_component.h   |  3 +-
 include/drm/i915_gsc_proxy_mei_interface.h | 53 ++
 2 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 include/drm/i915_gsc_proxy_mei_interface.h

diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
index c1e2a43d2d1e..56a84ee1c64c 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/i915_component.h
@@ -29,7 +29,8 @@
 enum i915_component_type {
I915_COMPONENT_AUDIO = 1,
I915_COMPONENT_HDCP,
-   I915_COMPONENT_PXP
+   I915_COMPONENT_PXP,
+   I915_COMPONENT_GSC_PROXY,
 };
 
 /* MAX_PORT is the number of port
diff --git a/include/drm/i915_gsc_proxy_mei_interface.h 
b/include/drm/i915_gsc_proxy_mei_interface.h
new file mode 100644
index ..9462341d3ae1
--- /dev/null
+++ b/include/drm/i915_gsc_proxy_mei_interface.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2022-2023 Intel Corporation
+ */
+
+#ifndef _I915_GSC_PROXY_MEI_INTERFACE_H_
+#define _I915_GSC_PROXY_MEI_INTERFACE_H_
+
+#include 
+
+struct device;
+struct module;
+
+/**
+ * struct i915_gsc_proxy_component_ops - ops for GSC Proxy services.
+ * @owner: Module providing the ops
+ * @send: sends a proxy message from GSC FW to ME FW
+ * @recv: receives a proxy message for GSC FW from ME FW
+ */
+struct i915_gsc_proxy_component_ops {
+   struct module *owner;
+
+   /**
+* send - Sends a proxy message to ME FW.
+* @dev: device struct corresponding to the mei device
+* @buf: message buffer to send
+* @size: size of the message
+* Return: bytes sent on success, negative errno value on failure
+*/
+   int (*send)(struct device *dev, const void *buf, size_t size);
+
+   /**
+* recv - Receives a proxy message from ME FW.
+* @dev: device struct corresponding to the mei device
+* @buf: message buffer to contain the received message
+* @size: size of the buffer
+* Return: bytes received on success, negative errno value on failure
+*/
+   int (*recv)(struct device *dev, void *buf, size_t size);
+};
+
+/**
+ * struct i915_gsc_proxy_component - Used for communication between i915 and
+ * MEI drivers for GSC proxy services
+ * @mei_dev: device that provide the GSC proxy service.
+ * @ops: Ops implemented by GSC proxy driver, used by i915 driver.
+ */
+struct i915_gsc_proxy_component {
+   struct device *mei_dev;
+   const struct i915_gsc_proxy_component_ops *ops;
+};
+
+#endif /* _I915_GSC_PROXY_MEI_INTERFACE_H_ */
-- 
2.40.0



[Intel-gfx] [PATCH v3 3/4] drm/i915/gsc: add initial support for GSC proxy

2023-05-02 Thread Daniele Ceraolo Spurio
The GSC uC needs to communicate with the CSME to perform certain
operations. Since the GSC can't perform this communication directly
on platforms where it is integrated in GT, i915 needs to transfer the
messages from GSC to CSME and back.
The proxy flow is as follow:
1 - i915 submits a request to GSC asking for the message to CSME
2 - GSC replies with the proxy header + payload for CSME
3 - i915 sends the reply from GSC as-is to CSME via the mei proxy
component
4 - CSME replies with the proxy header + payload for GSC
5 - i915 submits a request to GSC with the reply from CSME
6 - GSC replies either with a new header + payload (same as step 2,
so we restart from there) or with an end message.

After GSC load, i915 is expected to start the first proxy message chain,
while all subsequent ones will be triggered by the GSC via interrupt.

To communicate with the CSME, we use a dedicated mei component, which
means that we need to wait for it to bind before we can initialize the
proxies. This usually happens quite fast, but given that there is a
chance that we'll have to wait a few seconds the GSC work has been moved
to a dedicated WQ to not stall other processes.

v2: fix code style, includes and variable naming (Alan)
v3: add extra check for proxy status, fix includes and comments

Signed-off-by: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Reviewed-by: Alan Previn  #v2
---
 drivers/gpu/drm/i915/Makefile |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c |  10 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c  | 385 ++
 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h  |  17 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c |  49 ++-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  14 +-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h |   1 +
 8 files changed, 473 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 9af76e376ca9..f2ac803e35b4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -194,6 +194,7 @@ i915-y += \
 # general-purpose microcontroller (GuC) support
 i915-y += \
  gt/uc/intel_gsc_fw.o \
+ gt/uc/intel_gsc_proxy.o \
  gt/uc/intel_gsc_uc.o \
  gt/uc/intel_gsc_uc_heci_cmd_submit.o\
  gt/uc/intel_guc.o \
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
index 236673c02f9a..f46eb17a7a98 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c
@@ -13,6 +13,7 @@
 #define GSC_FW_STATUS_REG  _MMIO(0x116C40)
 #define GSC_FW_CURRENT_STATE   REG_GENMASK(3, 0)
 #define   GSC_FW_CURRENT_STATE_RESET   0
+#define   GSC_FW_PROXY_STATE_NORMAL5
 #define GSC_FW_INIT_COMPLETE_BIT   REG_BIT(9)
 
 static bool gsc_is_in_reset(struct intel_uncore *uncore)
@@ -23,6 +24,15 @@ static bool gsc_is_in_reset(struct intel_uncore *uncore)
   GSC_FW_CURRENT_STATE_RESET;
 }
 
+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc)
+{
+   struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
+   u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG);
+
+   return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) ==
+  GSC_FW_PROXY_STATE_NORMAL;
+}
+
 bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc)
 {
struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
index f4c1106bb2a9..fff8928218df 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h
@@ -13,5 +13,6 @@ struct intel_uncore;
 
 int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc);
 bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc);
+bool intel_gsc_uc_fw_proxy_init_done(struct intel_gsc_uc *gsc);
 
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
new file mode 100644
index ..0513ac8d03ec
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#include 
+
+#include "drm/i915_component.h"
+#include "drm/i915_gsc_proxy_mei_interface.h"
+
+#include "gt/intel_gt.h"
+#include "gt/intel_gt_print.h"
+#include "intel_gsc_proxy.h"
+#include "intel_gsc_uc.h"
+#include "intel_gsc_uc_heci_cmd_submit.h"
+#include "i915_drv.h"
+
+/*
+ * GSC proxy:
+ * The GSC uC needs to communicate with the CSME to perform certain operations.
+ * Since the GSC can't perform this communication directly on platforms w

[Intel-gfx] [PATCH v3 2/4] mei: gsc_proxy: add gsc proxy driver

2023-05-02 Thread Daniele Ceraolo Spurio
From: Alexander Usyskin 

Add GSC proxy driver. It to allows messaging between GSC component
on Intel graphics card and CSE device.

Cc: Alan Previn 
Signed-off-by: Alexander Usyskin 
Signed-off-by: Tomas Winkler 
Signed-off-by: Daniele Ceraolo Spurio 
Acked-by: Greg Kroah-Hartman 
---

v2: re-order includes, drop reference to "on board" card in commit
message and comments.

 drivers/misc/mei/Kconfig   |   2 +-
 drivers/misc/mei/Makefile  |   1 +
 drivers/misc/mei/gsc_proxy/Kconfig |  14 ++
 drivers/misc/mei/gsc_proxy/Makefile|   7 +
 drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c | 208 +
 5 files changed, 231 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/mei/gsc_proxy/Kconfig
 create mode 100644 drivers/misc/mei/gsc_proxy/Makefile
 create mode 100644 drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c

diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index d21486d69df2..37db142de413 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -62,4 +62,4 @@ config INTEL_MEI_GSC
 
 source "drivers/misc/mei/hdcp/Kconfig"
 source "drivers/misc/mei/pxp/Kconfig"
-
+source "drivers/misc/mei/gsc_proxy/Kconfig"
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index fb740d754900..14aee253ae48 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -30,3 +30,4 @@ CFLAGS_mei-trace.o = -I$(src)
 
 obj-$(CONFIG_INTEL_MEI_HDCP) += hdcp/
 obj-$(CONFIG_INTEL_MEI_PXP) += pxp/
+obj-$(CONFIG_INTEL_MEI_GSC_PROXY) += gsc_proxy/
diff --git a/drivers/misc/mei/gsc_proxy/Kconfig 
b/drivers/misc/mei/gsc_proxy/Kconfig
new file mode 100644
index ..5f68d9f3d691
--- /dev/null
+++ b/drivers/misc/mei/gsc_proxy/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+#
+config INTEL_MEI_GSC_PROXY
+   tristate "Intel GSC Proxy services of ME Interface"
+   select INTEL_MEI_ME
+   depends on DRM_I915
+   help
+ MEI Support for GSC Proxy Services on Intel platforms.
+
+ MEI GSC proxy enables messaging between GSC service on
+ Intel graphics card and services on CSE (MEI) firmware
+ residing SoC or PCH.
+
diff --git a/drivers/misc/mei/gsc_proxy/Makefile 
b/drivers/misc/mei/gsc_proxy/Makefile
new file mode 100644
index ..358847e9aaa9
--- /dev/null
+++ b/drivers/misc/mei/gsc_proxy/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
+#
+# Makefile - GSC Proxy client driver for Intel MEI Bus Driver.
+
+obj-$(CONFIG_INTEL_MEI_GSC_PROXY) += mei_gsc_proxy.o
diff --git a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c 
b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
new file mode 100644
index ..be52b113aea9
--- /dev/null
+++ b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022-2023 Intel Corporation
+ */
+
+/**
+ * DOC: MEI_GSC_PROXY Client Driver
+ *
+ * The mei_gsc_proxy driver acts as a translation layer between
+ * proxy user (I915) and ME FW by proxying messages to ME FW
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * mei_gsc_proxy_send - Sends a proxy message to ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @buf: a message buffer to send
+ * @size: size of the message
+ * Return: bytes sent on Success, <0 on Failure
+ */
+static int mei_gsc_proxy_send(struct device *dev, const void *buf, size_t size)
+{
+   ssize_t ret;
+
+   if (!dev || !buf)
+   return -EINVAL;
+
+   ret = mei_cldev_send(to_mei_cl_device(dev), buf, size);
+   if (ret < 0)
+   dev_dbg(dev, "mei_cldev_send failed. %zd\n", ret);
+
+   return ret;
+}
+
+/**
+ * mei_gsc_proxy_recv - Receives a proxy message from ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @buf: a message buffer to contain the received message
+ * @size: size of the buffer
+ * Return: bytes received on Success, <0 on Failure
+ */
+static int mei_gsc_proxy_recv(struct device *dev, void *buf, size_t size)
+{
+   ssize_t ret;
+
+   if (!dev || !buf)
+   return -EINVAL;
+
+   ret = mei_cldev_recv(to_mei_cl_device(dev), buf, size);
+   if (ret < 0)
+   dev_dbg(dev, "mei_cldev_recv failed. %zd\n", ret);
+
+   return ret;
+}
+
+static const struct i915_gsc_proxy_component_ops mei_gsc_proxy_ops = {
+   .owner = THIS_MODULE,
+   .send = mei_gsc_proxy_send,
+   .recv = mei_gsc_proxy_recv,
+};
+
+static int mei_component_master_bind(struct device *dev)
+{
+   struct mei_cl_device *cldev = to_mei_cl_device(dev);
+   struct i915_gsc_proxy_component *comp_master = 
mei_cldev_get_drvdata(cldev);
+
+   com

[Intel-gfx] [PATCH v3 0/4] drm/i915: Add support for MTL GSC SW Proxy

2023-05-02 Thread Daniele Ceraolo Spurio
On platforms where the GSC is part of GT, it needs to communicate with
CSME for some of its operations. However, there is no direct HW
communication channel, so the i915 and mei drivers must carry the
messages back and forth between the 2 units. The protocol is fully
described in the i915 patch that adds the initial support, but it
basically amounts to SW blindly moving messages back and forth until the
GSC tells us to stop.

Implementing this features requires a new mei component to handle
the mei side of things. The patches for this have already been
reviewed on the char-misc ML and we already have an ack from Greg to
merge them via the drm tree [1].

v2: small fixes, better docs, code cleanup

v3: add extra check on proxy status after the init flow is done, address
checkpatch issues

[1] 
https://lore.kernel.org/lkml/20230208142358.1401618-1-tomas.wink...@intel.com/t/
Cc: Alan Previn 
Cc: Suraj Kandpal 
Cc: Alexander Usyskin 
Cc: Greg Kroah-Hartman 

Alexander Usyskin (2):
  drm/i915/mtl: Define GSC Proxy component interface
  mei: gsc_proxy: add gsc proxy driver

Daniele Ceraolo Spurio (2):
  drm/i915/gsc: add initial support for GSC proxy
  drm/i915/gsc: add support for GSC proxy interrupt

 drivers/gpu/drm/i915/Makefile |   1 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c|  22 +-
 drivers/gpu/drm/i915/gt/intel_gt_regs.h   |   3 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c |  10 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.h |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c  | 425 ++
 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h  |  18 +
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c |  76 +++-
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h |  17 +-
 .../i915/gt/uc/intel_gsc_uc_heci_cmd_submit.h |   1 +
 drivers/misc/mei/Kconfig  |   2 +-
 drivers/misc/mei/Makefile |   1 +
 drivers/misc/mei/gsc_proxy/Kconfig|  14 +
 drivers/misc/mei/gsc_proxy/Makefile   |   7 +
 drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c| 208 +
 include/drm/i915_component.h  |   3 +-
 include/drm/i915_gsc_proxy_mei_interface.h|  53 +++
 17 files changed, 852 insertions(+), 10 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c
 create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.h
 create mode 100644 drivers/misc/mei/gsc_proxy/Kconfig
 create mode 100644 drivers/misc/mei/gsc_proxy/Makefile
 create mode 100644 drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c
 create mode 100644 include/drm/i915_gsc_proxy_mei_interface.h

-- 
2.40.0



  1   2   3   4   5   6   7   8   9   10   >