All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] HuC Loading Patches
@ 2016-12-22 23:12 Anusha Srivatsa
  2016-12-22 23:12 ` [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general Anusha Srivatsa
                   ` (8 more replies)
  0 siblings, 9 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2016-12-22 23:12 UTC (permalink / raw)
  To: intel-gfx

These patches add HuC loading support. The driver builds a frame level
workload which is stored in the graphics memory. This workload is presented
to HuC for processing. The driver, therefore should first determine if the
HuC is enabled and also read the huC athentication status bit to determine
if HuC was successfully loaded. The GuC is required to authenticate the HuC.
The userspace patches that check for a fully loaded HuC firmware and use it
can be found at:

https://lists.freedesktop.org/archives/libva/2016-September/004554.html
https://lists.freedesktop.org/archives/libva/2016-September/004555.html
 
More information regarding the HuC, batch commands that configure the 
HuC etc can be found at-
https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-skl-vol02a-commandreference-instructions-huc.pdf
https://www.x.org/docs/intel/CHV/intel-gfx-prm-osrc-chv-bsw-vol10-hevc.pdf

v2: rebased.
v3: rebased. Changed the code following the review comments.
v4: Added action_lock initialization fix provided by Arek
(Hiler Arkadiusz) to the first patch in the series- Make the
GuC fw loading helper functions general. 
v5: rebased on top of drm-tip. The patch series is now in sync with GuC 
code reorganization efforts by Arek-
https://patchwork.freedesktop.org/series/15896/
v6:rebased. Organize code. Move contents of intel_huc.h to intel_uc.h.
Update function intel_huc_load(),intel_huc_init() and intel_uc_fw_fetch()
to accept dev_priv instead of dev.
v7: rebased. Remove intel_is_huc_valid() since it is called onoly once.
Refactor the code to reduce redundency. Remove fiels like uc_dev which
are no longer used.
v8: rebased. Beautify the code- remove comments that no longer hold
good, add newlines etc. 

Anusha Srivatsa (3):
  drm/i915/huc: Add HuC fw loading support
  drm/i915/huc: Add BXT HuC Loading Support
  drm/i915/HuC: Add KBL huC loading Support

Peter Antoine (5):
  drm/i915/guc: Make the GuC fw loading helper functions general
  drm/i915/huc: Unified css_header struct for GuC and HuC
  drm/i915/huc: Add debugfs for HuC loading status check
  drm/i915/huc: Support HuC authentication
  drm/i915/get_params: Add HuC status to getparams

 drivers/gpu/drm/i915/Makefile              |   1 +
 drivers/gpu/drm/i915/i915_debugfs.c        |  43 ++++-
 drivers/gpu/drm/i915/i915_drv.c            |  11 +-
 drivers/gpu/drm/i915/i915_drv.h            |   3 +-
 drivers/gpu/drm/i915/i915_guc_reg.h        |   3 +
 drivers/gpu/drm/i915/i915_guc_submission.c |   4 +-
 drivers/gpu/drm/i915/intel_guc_fwif.h      |  24 ++-
 drivers/gpu/drm/i915/intel_guc_loader.c    | 200 +++++++++++---------
 drivers/gpu/drm/i915/intel_huc_loader.c    | 286 +++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_uc.c            |  62 +++++++
 drivers/gpu/drm/i915/intel_uc.h            |  63 +++++--
 include/uapi/drm/i915_drm.h                |   1 +
 12 files changed, 577 insertions(+), 124 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c

-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general
  2016-12-22 23:12 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
@ 2016-12-22 23:12 ` Anusha Srivatsa
  2016-12-23 14:15   ` Arkadiusz Hiler
  2016-12-27 17:28   ` Michal Wajdeczko
  2016-12-22 23:12 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
                   ` (7 subsequent siblings)
  8 siblings, 2 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2016-12-22 23:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

Rename some of the GuC fw loading code to make them more general. We
will utilise them for HuC loading as well.
     s/intel_guc_fw/intel_uc_fw/g
     s/GUC_FIRMWARE/UC_FIRMWARE/g

Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts members,
such as 'guc' or 'guc_fw' either is renamed to 'uc' or removed for
same purpose.

v2: rebased on top of nightly.
    reapplied the search/replace as upstream code as changed.
v3: rebased again on drm-nightly.
v4: removed G from messages in shared fw fetch function.
v5: rebased.
v7: rebased.
v8: rebased.
v9: rebased.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip
v13: rebased.Updated dev to dev_priv in intel_guc_setup(), guc_fw_getch()
and intel_guc_init().
v14: rebased. Remove uint32_t fw_type to patch 2. Add INTEL_ prefix for
fields in enum intel_uc_fw_status. Remove uc_dev field since its never
used.Rename uc_fw to just fw and guc_fw to fw to avoid redundency.
v15: rebased. Remove sections of code that were commented and no longer
required.

Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c        |  12 +--
 drivers/gpu/drm/i915/i915_guc_submission.c |   4 +-
 drivers/gpu/drm/i915/intel_guc_loader.c    | 156 ++++++++++++++---------------
 drivers/gpu/drm/i915/intel_uc.h            |  36 +++----
 4 files changed, 104 insertions(+), 104 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index a5552a1..0a3c575 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2328,7 +2328,7 @@ static int i915_llc(struct seq_file *m, void *data)
 static int i915_guc_load_status_info(struct seq_file *m, void *data)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
-	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
 	u32 tmp, i;
 
 	if (!HAS_GUC_UCODE(dev_priv))
@@ -2336,15 +2336,15 @@ static int i915_guc_load_status_info(struct seq_file *m, void *data)
 
 	seq_printf(m, "GuC firmware status:\n");
 	seq_printf(m, "\tpath: %s\n",
-		guc_fw->guc_fw_path);
+		guc_fw->uc_fw_path);
 	seq_printf(m, "\tfetch: %s\n",
-		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
+		intel_uc_fw_status_repr(guc_fw->fetch_status));
 	seq_printf(m, "\tload: %s\n",
-		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+		intel_uc_fw_status_repr(guc_fw->load_status));
 	seq_printf(m, "\tversion wanted: %d.%d\n",
-		guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
+		guc_fw->major_ver_wanted, guc_fw->minor_ver_wanted);
 	seq_printf(m, "\tversion found: %d.%d\n",
-		guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found);
+		guc_fw->major_ver_found, guc_fw->minor_ver_found);
 	seq_printf(m, "\theader: offset is %d; size = %d\n",
 		guc_fw->header_offset, guc_fw->header_size);
 	seq_printf(m, "\tuCode: offset is %d; size = %d\n",
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 3e20fe2..6e2d403 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -1484,7 +1484,7 @@ int intel_guc_suspend(struct drm_i915_private *dev_priv)
 	struct i915_gem_context *ctx;
 	u32 data[3];
 
-	if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
+	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
 		return 0;
 
 	gen9_disable_guc_interrupts(dev_priv);
@@ -1511,7 +1511,7 @@ int intel_guc_resume(struct drm_i915_private *dev_priv)
 	struct i915_gem_context *ctx;
 	u32 data[3];
 
-	if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
+	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
 		return 0;
 
 	if (i915.guc_log_level >= 0)
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 21db697..ffe53dd7 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -81,16 +81,16 @@ MODULE_FIRMWARE(I915_BXT_GUC_UCODE);
 MODULE_FIRMWARE(I915_KBL_GUC_UCODE);
 
 /* User-friendly representation of an enum */
-const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status)
+const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
 {
 	switch (status) {
-	case GUC_FIRMWARE_FAIL:
+	case INTEL_UC_FIRMWARE_FAIL:
 		return "FAIL";
-	case GUC_FIRMWARE_NONE:
+	case INTEL_UC_FIRMWARE_NONE:
 		return "NONE";
-	case GUC_FIRMWARE_PENDING:
+	case INTEL_UC_FIRMWARE_PENDING:
 		return "PENDING";
-	case GUC_FIRMWARE_SUCCESS:
+	case INTEL_UC_FIRMWARE_SUCCESS:
 		return "SUCCESS";
 	default:
 		return "UNKNOWN!";
@@ -278,7 +278,7 @@ static inline bool guc_ucode_response(struct drm_i915_private *dev_priv,
 static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
 			      struct i915_vma *vma)
 {
-	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
 	unsigned long offset;
 	struct sg_table *sg = vma->pages;
 	u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT];
@@ -350,17 +350,17 @@ static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
  */
 static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
 {
-	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
 	struct i915_vma *vma;
 	int ret;
 
-	ret = i915_gem_object_set_to_gtt_domain(guc_fw->guc_fw_obj, false);
+	ret = i915_gem_object_set_to_gtt_domain(guc_fw->uc_fw_obj, false);
 	if (ret) {
 		DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
 		return ret;
 	}
 
-	vma = i915_gem_object_ggtt_pin(guc_fw->guc_fw_obj, NULL, 0, 0, 0);
+	vma = i915_gem_object_ggtt_pin(guc_fw->uc_fw_obj, NULL, 0, 0, 0);
 	if (IS_ERR(vma)) {
 		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
 		return PTR_ERR(vma);
@@ -450,14 +450,14 @@ static int guc_hw_reset(struct drm_i915_private *dev_priv)
  */
 int intel_guc_setup(struct drm_i915_private *dev_priv)
 {
-	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
-	const char *fw_path = guc_fw->guc_fw_path;
+	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
+	const char *fw_path = guc_fw->uc_fw_path;
 	int retries, ret, err;
 
 	DRM_DEBUG_DRIVER("GuC fw status: path %s, fetch %s, load %s\n",
 		fw_path,
-		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
-		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+		intel_uc_fw_status_repr(guc_fw->fetch_status),
+		intel_uc_fw_status_repr(guc_fw->load_status));
 
 	/* Loading forbidden, or no firmware to load? */
 	if (!i915.enable_guc_loading) {
@@ -475,10 +475,10 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
 	}
 
 	/* Fetch failed, or already fetched but failed to load? */
-	if (guc_fw->guc_fw_fetch_status != GUC_FIRMWARE_SUCCESS) {
+	if (guc_fw->fetch_status != INTEL_UC_FIRMWARE_SUCCESS) {
 		err = -EIO;
 		goto fail;
-	} else if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_FAIL) {
+	} else if (guc_fw->load_status == INTEL_UC_FIRMWARE_FAIL) {
 		err = -ENOEXEC;
 		goto fail;
 	}
@@ -486,11 +486,11 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
 	guc_interrupts_release(dev_priv);
 	gen9_reset_guc_interrupts(dev_priv);
 
-	guc_fw->guc_fw_load_status = GUC_FIRMWARE_PENDING;
+	guc_fw->load_status = INTEL_UC_FIRMWARE_PENDING;
 
 	DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
-		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
-		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+		intel_uc_fw_status_repr(guc_fw->fetch_status),
+		intel_uc_fw_status_repr(guc_fw->load_status));
 
 	err = i915_guc_submission_init(dev_priv);
 	if (err)
@@ -522,11 +522,11 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
 			 "retry %d more time(s)\n", err, retries);
 	}
 
-	guc_fw->guc_fw_load_status = GUC_FIRMWARE_SUCCESS;
+	guc_fw->load_status = INTEL_UC_FIRMWARE_SUCCESS;
 
 	DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
-		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
-		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
+		intel_uc_fw_status_repr(guc_fw->fetch_status),
+		intel_uc_fw_status_repr(guc_fw->load_status));
 
 	if (i915.enable_guc_submission) {
 		if (i915.guc_log_level >= 0)
@@ -541,8 +541,8 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
 	return 0;
 
 fail:
-	if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_PENDING)
-		guc_fw->guc_fw_load_status = GUC_FIRMWARE_FAIL;
+	if (guc_fw->load_status == INTEL_UC_FIRMWARE_PENDING)
+		guc_fw->load_status = INTEL_UC_FIRMWARE_FAIL;
 
 	guc_interrupts_release(dev_priv);
 	i915_guc_submission_disable(dev_priv);
@@ -587,8 +587,8 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
 	return ret;
 }
 
-static void guc_fw_fetch(struct drm_i915_private *dev_priv,
-			 struct intel_guc_fw *guc_fw)
+void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
+			 struct intel_uc_fw *uc_fw)
 {
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 	struct drm_i915_gem_object *obj;
@@ -597,17 +597,17 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
 	size_t size;
 	int err;
 
-	DRM_DEBUG_DRIVER("before requesting firmware: GuC fw fetch status %s\n",
-		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
+	DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status %s\n",
+		intel_uc_fw_status_repr(uc_fw->fetch_status));
 
-	err = request_firmware(&fw, guc_fw->guc_fw_path, &pdev->dev);
+	err = request_firmware(&fw, uc_fw->uc_fw_path, &pdev->dev);
 	if (err)
 		goto fail;
 	if (!fw)
 		goto fail;
 
-	DRM_DEBUG_DRIVER("fetch GuC fw from %s succeeded, fw %p\n",
-		guc_fw->guc_fw_path, fw);
+	DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n",
+		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
 	if (fw->size < sizeof(struct guc_css_header)) {
@@ -618,36 +618,36 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
 	css = (struct guc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
-	guc_fw->header_offset = 0;
-	guc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
+	uc_fw->header_offset = 0;
+	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (guc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
 
 	/* then, uCode */
-	guc_fw->ucode_offset = guc_fw->header_offset + guc_fw->header_size;
-	guc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
+	uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
+	uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
 
 	/* now RSA */
 	if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
 		DRM_NOTE("RSA key size is bad\n");
 		goto fail;
 	}
-	guc_fw->rsa_offset = guc_fw->ucode_offset + guc_fw->ucode_size;
-	guc_fw->rsa_size = css->key_size_dw * sizeof(u32);
+	uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
+	uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
 
 	/* At least, it should have header, uCode and RSA. Size of all three. */
-	size = guc_fw->header_size + guc_fw->ucode_size + guc_fw->rsa_size;
+	size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size;
 	if (fw->size < size) {
 		DRM_NOTE("Missing firmware components\n");
 		goto fail;
 	}
 
 	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = guc_fw->header_size + guc_fw->ucode_size;
+	size = uc_fw->header_size + uc_fw->ucode_size;
 	if (size > guc_wopcm_size(dev_priv)) {
 		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
 		goto fail;
@@ -659,21 +659,21 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	guc_fw->guc_fw_major_found = css->guc_sw_version >> 16;
-	guc_fw->guc_fw_minor_found = css->guc_sw_version & 0xFFFF;
-
-	if (guc_fw->guc_fw_major_found != guc_fw->guc_fw_major_wanted ||
-	    guc_fw->guc_fw_minor_found < guc_fw->guc_fw_minor_wanted) {
-		DRM_NOTE("GuC firmware version %d.%d, required %d.%d\n",
-			guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found,
-			guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
+	uc_fw->major_ver_found = css->guc_sw_version >> 16;
+	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+
+	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
+	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
+		DRM_NOTE("uC firmware version %d.%d, required %d.%d\n",
+			uc_fw->major_ver_found, uc_fw->minor_ver_found,
+			uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
 		err = -ENOEXEC;
 		goto fail;
 	}
 
 	DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n",
-			guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found,
-			guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
+			uc_fw->major_ver_found, uc_fw->minor_ver_found,
+			uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
 
 	mutex_lock(&dev_priv->drm.struct_mutex);
 	obj = i915_gem_object_create_from_data(dev_priv, fw->data, fw->size);
@@ -683,31 +683,31 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
 		goto fail;
 	}
 
-	guc_fw->guc_fw_obj = obj;
-	guc_fw->guc_fw_size = fw->size;
+	uc_fw->uc_fw_obj = obj;
+	uc_fw->size = fw->size;
 
-	DRM_DEBUG_DRIVER("GuC fw fetch status SUCCESS, obj %p\n",
-			guc_fw->guc_fw_obj);
+	DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n",
+			uc_fw->uc_fw_obj);
 
 	release_firmware(fw);
-	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_SUCCESS;
+	uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS;
 	return;
 
 fail:
-	DRM_WARN("Failed to fetch valid GuC firmware from %s (error %d)\n",
-		 guc_fw->guc_fw_path, err);
-	DRM_DEBUG_DRIVER("GuC fw fetch status FAIL; err %d, fw %p, obj %p\n",
-		err, fw, guc_fw->guc_fw_obj);
+	DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n",
+		 uc_fw->uc_fw_path, err);
+	DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj %p\n",
+		err, fw, uc_fw->uc_fw_obj);
 
 	mutex_lock(&dev_priv->drm.struct_mutex);
-	obj = guc_fw->guc_fw_obj;
+	obj = uc_fw->uc_fw_obj;
 	if (obj)
 		i915_gem_object_put(obj);
-	guc_fw->guc_fw_obj = NULL;
+	uc_fw->uc_fw_obj = NULL;
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
 	release_firmware(fw);		/* OK even if fw is NULL */
-	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_FAIL;
+	uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL;
 }
 
 /**
@@ -721,7 +721,7 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
  */
 void intel_guc_init(struct drm_i915_private *dev_priv)
 {
-	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
 	const char *fw_path;
 
 	if (!HAS_GUC(dev_priv)) {
@@ -739,23 +739,23 @@ void intel_guc_init(struct drm_i915_private *dev_priv)
 		fw_path = NULL;
 	} else if (IS_SKYLAKE(dev_priv)) {
 		fw_path = I915_SKL_GUC_UCODE;
-		guc_fw->guc_fw_major_wanted = SKL_FW_MAJOR;
-		guc_fw->guc_fw_minor_wanted = SKL_FW_MINOR;
+		guc_fw->major_ver_wanted = SKL_FW_MAJOR;
+		guc_fw->minor_ver_wanted = SKL_FW_MINOR;
 	} else if (IS_BROXTON(dev_priv)) {
 		fw_path = I915_BXT_GUC_UCODE;
-		guc_fw->guc_fw_major_wanted = BXT_FW_MAJOR;
-		guc_fw->guc_fw_minor_wanted = BXT_FW_MINOR;
+		guc_fw->major_ver_wanted = BXT_FW_MAJOR;
+		guc_fw->minor_ver_wanted = BXT_FW_MINOR;
 	} else if (IS_KABYLAKE(dev_priv)) {
 		fw_path = I915_KBL_GUC_UCODE;
-		guc_fw->guc_fw_major_wanted = KBL_FW_MAJOR;
-		guc_fw->guc_fw_minor_wanted = KBL_FW_MINOR;
+		guc_fw->major_ver_wanted = KBL_FW_MAJOR;
+		guc_fw->minor_ver_wanted = KBL_FW_MINOR;
 	} else {
 		fw_path = "";	/* unknown device */
 	}
 
-	guc_fw->guc_fw_path = fw_path;
-	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_NONE;
-	guc_fw->guc_fw_load_status = GUC_FIRMWARE_NONE;
+	guc_fw->uc_fw_path = fw_path;
+	guc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
+	guc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
 
 	/* Early (and silent) return if GuC loading is disabled */
 	if (!i915.enable_guc_loading)
@@ -765,9 +765,9 @@ void intel_guc_init(struct drm_i915_private *dev_priv)
 	if (*fw_path == '\0')
 		return;
 
-	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_PENDING;
+	guc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
 	DRM_DEBUG_DRIVER("GuC firmware pending, path %s\n", fw_path);
-	guc_fw_fetch(dev_priv, guc_fw);
+	intel_uc_fw_fetch(dev_priv, guc_fw);
 	/* status must now be FAIL or SUCCESS */
 }
 
@@ -777,17 +777,17 @@ void intel_guc_init(struct drm_i915_private *dev_priv)
  */
 void intel_guc_fini(struct drm_i915_private *dev_priv)
 {
-	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
+	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
 
 	mutex_lock(&dev_priv->drm.struct_mutex);
 	guc_interrupts_release(dev_priv);
 	i915_guc_submission_disable(dev_priv);
 	i915_guc_submission_fini(dev_priv);
 
-	if (guc_fw->guc_fw_obj)
-		i915_gem_object_put(guc_fw->guc_fw_obj);
-	guc_fw->guc_fw_obj = NULL;
+	if (guc_fw->uc_fw_obj)
+		i915_gem_object_put(guc_fw->uc_fw_obj);
+	guc_fw->uc_fw_obj = NULL;
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
-	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_NONE;
+	guc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
 }
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 11f5608..893bcec 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -91,28 +91,28 @@ struct i915_guc_client {
 	uint64_t submissions[I915_NUM_ENGINES];
 };
 
-enum intel_guc_fw_status {
-	GUC_FIRMWARE_FAIL = -1,
-	GUC_FIRMWARE_NONE = 0,
-	GUC_FIRMWARE_PENDING,
-	GUC_FIRMWARE_SUCCESS
+enum intel_uc_fw_status {
+	INTEL_UC_FIRMWARE_FAIL = -1,
+	INTEL_UC_FIRMWARE_NONE = 0,
+	INTEL_UC_FIRMWARE_PENDING,
+	INTEL_UC_FIRMWARE_SUCCESS
 };
 
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
  */
-struct intel_guc_fw {
-	const char *			guc_fw_path;
-	size_t				guc_fw_size;
-	struct drm_i915_gem_object *	guc_fw_obj;
-	enum intel_guc_fw_status	guc_fw_fetch_status;
-	enum intel_guc_fw_status	guc_fw_load_status;
-
-	uint16_t			guc_fw_major_wanted;
-	uint16_t			guc_fw_minor_wanted;
-	uint16_t			guc_fw_major_found;
-	uint16_t			guc_fw_minor_found;
+struct intel_uc_fw {
+	const char *uc_fw_path;
+	size_t size;
+	struct drm_i915_gem_object *uc_fw_obj;
+	enum intel_uc_fw_status fetch_status;
+	enum intel_uc_fw_status load_status;
+
+	uint16_t major_ver_wanted;
+	uint16_t minor_ver_wanted;
+	uint16_t major_ver_found;
+	uint16_t minor_ver_found;
 
 	uint32_t header_size;
 	uint32_t header_offset;
@@ -139,7 +139,7 @@ struct intel_guc_log {
 };
 
 struct intel_guc {
-	struct intel_guc_fw guc_fw;
+	struct intel_uc_fw fw;
 	struct intel_guc_log log;
 
 	/* intel_guc_recv interrupt related state */
@@ -181,7 +181,7 @@ int intel_guc_log_control(struct intel_guc *guc, u32 control_val);
 extern void intel_guc_init(struct drm_i915_private *dev_priv);
 extern int intel_guc_setup(struct drm_i915_private *dev_priv);
 extern void intel_guc_fini(struct drm_i915_private *dev_priv);
-extern const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status);
+extern const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status);
 extern int intel_guc_suspend(struct drm_i915_private *dev_priv);
 extern int intel_guc_resume(struct drm_i915_private *dev_priv);
 
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-12-22 23:12 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
  2016-12-22 23:12 ` [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general Anusha Srivatsa
@ 2016-12-22 23:12 ` Anusha Srivatsa
  2016-12-23 14:21   ` Arkadiusz Hiler
  2016-12-22 23:12 ` [PATCH 3/8] drm/i915/huc: Add HuC fw loading support Anusha Srivatsa
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 50+ messages in thread
From: Anusha Srivatsa @ 2016-12-22 23:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.
v9: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip.
v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
v14: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
from patch 1.Combine two different unions for huc and guc version,
reserved etc into one union with two structs.
v15: rebased.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_uc.h         |  6 +++++
 3 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 3202b32..ed1ab40 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -145,7 +145,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -172,9 +172,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -205,8 +212,16 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		struct {
+			uint32_t branch_client_version;
+			uint32_t sw_version;
+	} guc;
+		struct {
+			uint32_t sw_version;
+			uint32_t reserved;
+	} huc;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index ffe53dd7..06e3e5c 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw = NULL;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(dev_priv)) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw_type) {
+	case INTEL_UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(dev_priv)) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
+		break;
+
+	case INTEL_UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 893bcec..ad140e2 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -98,6 +98,11 @@ enum intel_uc_fw_status {
 	INTEL_UC_FIRMWARE_SUCCESS
 };
 
+enum {
+	INTEL_UC_FW_TYPE_GUC,
+	INTEL_UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -114,6 +119,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	uint32_t fw_type;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
  2016-12-22 23:12 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
  2016-12-22 23:12 ` [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general Anusha Srivatsa
  2016-12-22 23:12 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
@ 2016-12-22 23:12 ` Anusha Srivatsa
  2016-12-27 12:37   ` Arkadiusz Hiler
  2016-12-27 17:50   ` Michal Wajdeczko
  2016-12-22 23:12 ` [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support Anusha Srivatsa
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2016-12-22 23:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

The HuC loading process is similar to GuC. The intel_uc_fw_fetch()
is used for both cases.

HuC loading needs to be before GuC loading. The WOPCM setting must
be done early before loading any of them.

v2: rebased on-top of drm-intel-nightly.
    removed if(HAS_GUC()) before the guc call. (D.Gordon)
    update huc_version number of format.
v3: rebased to drm-intel-nightly, changed the file name format to
    match the one in the huc package.
    Changed dev->dev_private to to_i915()
v4: moved function back to where it was.
    change wait_for_atomic to wait_for.
v5: rebased + comment changes.
v7: rebased.
v8: rebased.
v9: rebased. Changed the year in the copyright message to reflect
the right year.Correct the comments,remove the unwanted WARN message,
replace drm_gem_object_unreference() with i915_gem_object_put().Make the
prototypes in intel_huc.h non-extern.
v10: rebased. Update the file construction done by HuC. It is similar to
GuC.Adopted the approach used in-
https://patchwork.freedesktop.org/patch/104355/ <Tvrtko Ursulin>
v11: Fix warnings remove old declaration
v12: Change dev to dev_priv in macro definition.
Corrected comments.
v13: rebased.
v14: rebased on top of drm-tip
v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
of intel_huc.h to intel_uc.h
v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to guc_wopcm_size().
Remove unwanted checks in intel_uc.h. Rename huc_fw in struct intel_huc to
simply fw to avoid redundency.
v17: rebased.

Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
---
 drivers/gpu/drm/i915/Makefile           |   1 +
 drivers/gpu/drm/i915/i915_drv.c         |   4 +-
 drivers/gpu/drm/i915/i915_drv.h         |   3 +-
 drivers/gpu/drm/i915/i915_guc_reg.h     |   3 +
 drivers/gpu/drm/i915/intel_guc_loader.c |  11 +-
 drivers/gpu/drm/i915/intel_huc_loader.c | 263 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_uc.h         |  18 +++
 7 files changed, 296 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 5196509..45ae124 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -57,6 +57,7 @@ i915-y += i915_cmd_parser.o \
 # general-purpose microcontroller (GuC) support
 i915-y += intel_uc.o \
 	  intel_guc_loader.o \
+	  intel_huc_loader.o \
 	  i915_guc_submission.o
 
 # autogenerated null render state
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6428588..85a47c2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -600,6 +600,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
 	if (ret)
 		goto cleanup_irq;
 
+	intel_huc_init(dev_priv);
 	intel_guc_init(dev_priv);
 
 	ret = i915_gem_init(dev_priv);
@@ -627,6 +628,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
 		DRM_ERROR("failed to idle hardware; continuing to unload!\n");
 	i915_gem_fini(dev_priv);
 cleanup_irq:
+	intel_huc_fini(dev);
 	intel_guc_fini(dev_priv);
 	drm_irq_uninstall(dev);
 	intel_teardown_gmbus(dev_priv);
@@ -1313,7 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)
 
 	/* Flush any outstanding unpin_work. */
 	drain_workqueue(dev_priv->wq);
-
+	intel_huc_fini(dev);
 	intel_guc_fini(dev_priv);
 	i915_gem_fini(dev_priv);
 	intel_fbc_cleanup_cfb(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1a91409..7ac7730 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2147,6 +2147,7 @@ struct drm_i915_private {
 
 	struct intel_gvt *gvt;
 
+	struct intel_huc huc;
 	struct intel_guc guc;
 
 	struct intel_csr csr;
@@ -2921,7 +2922,7 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define HAS_GUC(dev_priv)	((dev_priv)->info.has_guc)
 #define HAS_GUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
 #define HAS_GUC_SCHED(dev_priv)	(HAS_GUC(dev_priv))
-
+#define HAS_HUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
 #define HAS_RESOURCE_STREAMER(dev_priv) ((dev_priv)->info.has_resource_streamer)
 
 #define HAS_POOLED_EU(dev_priv)	((dev_priv)->info.has_pooled_eu)
diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h b/drivers/gpu/drm/i915/i915_guc_reg.h
index 5e638fc..f9829f6 100644
--- a/drivers/gpu/drm/i915/i915_guc_reg.h
+++ b/drivers/gpu/drm/i915/i915_guc_reg.h
@@ -61,9 +61,12 @@
 #define   DMA_ADDRESS_SPACE_GTT		  (8 << 16)
 #define DMA_COPY_SIZE			_MMIO(0xc310)
 #define DMA_CTRL			_MMIO(0xc314)
+#define   HUC_UKERNEL			  (1<<9)
 #define   UOS_MOVE			  (1<<4)
 #define   START_DMA			  (1<<0)
 #define DMA_GUC_WOPCM_OFFSET		_MMIO(0xc340)
+#define   HUC_LOADING_AGENT_VCR		  (0<<1)
+#define   HUC_LOADING_AGENT_GUC		  (1<<1)
 #define   GUC_WOPCM_OFFSET_VALUE	  0x80000	/* 512KB */
 #define GUC_MAX_IDLE_COUNT		_MMIO(0xC3E4)
 
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 06e3e5c..8c77e94 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -309,8 +309,8 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
 	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
 
 	/* Finally start the DMA */
-	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA));
-
+	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA) |
+		_MASKED_BIT_DISABLE(HUC_UKERNEL));
 	/*
 	 * Wait for the DMA to complete & the GuC to start up.
 	 * NB: Docs recommend not using the interrupt for completion.
@@ -334,7 +334,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
 	return ret;
 }
 
-static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
+u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv)
 {
 	u32 wopcm_size = GUC_WOPCM_TOP;
 
@@ -372,7 +372,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
 	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 	/* init WOPCM */
-	I915_WRITE(GUC_WOPCM_SIZE, guc_wopcm_size(dev_priv));
+	I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
 	I915_WRITE(DMA_GUC_WOPCM_OFFSET, GUC_WOPCM_OFFSET_VALUE);
 
 	/* Enable MIA caching. GuC clock gating is disabled. */
@@ -511,6 +511,7 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
 		if (err)
 			goto fail;
 
+		intel_huc_load(dev_priv);
 		err = guc_ucode_xfer(dev_priv);
 		if (!err)
 			break;
@@ -658,7 +659,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		size = uc_fw->header_size + uc_fw->ucode_size;
 
 		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
-		if (size > guc_wopcm_size(dev_priv)) {
+		if (size > intel_guc_wopcm_size(dev_priv)) {
 			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
 			goto fail;
 		}
diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c b/drivers/gpu/drm/i915/intel_huc_loader.c
new file mode 100644
index 0000000..98d631c
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_huc_loader.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+#include <linux/firmware.h>
+#include "i915_drv.h"
+#include "intel_uc.h"
+
+/**
+ * DOC: HuC Firmware
+ *
+ * Motivation:
+ * GEN9 introduces a new dedicated firmware for usage in media HEVC (High
+ * Efficiency Video Coding) operations. Userspace can use the firmware
+ * capabilities by adding HuC specific commands to batch buffers.
+ *
+ * Implementation:
+ * The same firmware loader is used as the GuC. However, the actual
+ * loading to HW is deferred until GEM initialization is done.
+ *
+ * Note that HuC firmware loading must be done before GuC loading.
+ */
+
+#define SKL_HUC_FW_MAJOR 01
+#define SKL_HUC_FW_MINOR 07
+#define SKL_BLD_NUM 1398
+
+#define HUC_FW_PATH(platform, major, minor, bld_num) \
+	"i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \
+	__stringify(minor) "_" __stringify(bld_num) ".bin"
+
+#define I915_SKL_HUC_UCODE HUC_FW_PATH(skl, SKL_HUC_FW_MAJOR, \
+	SKL_HUC_FW_MINOR, SKL_BLD_NUM)
+MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
+
+/**
+ * huc_ucode_xfer() - DMA's the firmware
+ * @dev_priv: the drm device
+ *
+ * This function takes the gem object containing the firmware, sets up the DMA
+ * engine MMIO, triggers the DMA operation and waits for it to finish.
+ *
+ * Transfer the firmware image to RAM for execution by the microcontroller.
+ *
+ * Return: 0 on success, non-zero on failure
+ */
+static int huc_ucode_xfer(struct drm_i915_private *dev_priv)
+{
+	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
+	struct i915_vma *vma;
+	unsigned long offset = 0;
+	u32 size;
+	int ret;
+
+	ret = i915_gem_object_set_to_gtt_domain(huc_fw->uc_fw_obj, false);
+	if (ret) {
+		DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
+		return ret;
+	}
+
+	vma = i915_gem_object_ggtt_pin(huc_fw->uc_fw_obj, NULL, 0, 0, 0);
+	if (IS_ERR(vma)) {
+		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
+		return PTR_ERR(vma);
+	}
+
+	/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
+	I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+
+	/* init WOPCM */
+	I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
+	I915_WRITE(DMA_GUC_WOPCM_OFFSET, GUC_WOPCM_OFFSET_VALUE |
+			HUC_LOADING_AGENT_GUC);
+
+	/* Set the source address for the uCode */
+	offset = i915_ggtt_offset(vma) + huc_fw->header_offset;
+	I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
+	I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
+
+	/* Hardware doesn't look at destination address for HuC. Set it to 0,
+	 * but still program the correct address space.
+	 */
+	I915_WRITE(DMA_ADDR_1_LOW, 0);
+	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
+
+	size = huc_fw->header_size + huc_fw->ucode_size;
+	I915_WRITE(DMA_COPY_SIZE, size);
+
+	/* Start the DMA */
+	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(HUC_UKERNEL | START_DMA));
+
+	/* Wait for DMA to finish */
+	ret = wait_for((I915_READ(DMA_CTRL) & START_DMA) == 0, 100);
+
+	DRM_DEBUG_DRIVER("HuC DMA transfer wait over with ret %d\n", ret);
+
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+
+	/*
+	 * We keep the object pages for reuse during resume. But we can unpin it
+	 * now that DMA has completed, so it doesn't continue to take up space.
+	 */
+	i915_vma_unpin(vma);
+
+	return ret;
+}
+
+/**
+ * intel_huc_init() - initiate HuC firmware loading request
+ * @dev_priv: the drm_i915_private device
+ *
+ * Called early during driver load, but after GEM is initialised. The loading
+ * will continue only when driver explicitly specify firmware name and version.
+ * All other cases are considered as INTEL_UC_FIRMWARE_NONE either because HW
+ * is not capable or driver yet support it. And there will be no error message
+ * for INTEL_UC_FIRMWARE_NONE cases.
+ *
+ * The DMA-copying to HW is done later when intel_huc_load() is called.
+ */
+void intel_huc_init(struct drm_i915_private *dev_priv)
+{
+	struct intel_huc *huc = &dev_priv->huc;
+	struct intel_uc_fw *huc_fw = &huc->fw;
+	const char *fw_path = NULL;
+
+	huc_fw->uc_fw_path = NULL;
+	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
+	huc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
+	huc_fw->fw_type = INTEL_UC_FW_TYPE_HUC;
+
+	if (!HAS_HUC_UCODE(dev_priv))
+		return;
+
+	if (IS_SKYLAKE(dev_priv)) {
+		fw_path = I915_SKL_HUC_UCODE;
+		huc_fw->major_ver_wanted = SKL_HUC_FW_MAJOR;
+		huc_fw->minor_ver_wanted = SKL_HUC_FW_MINOR;
+	}
+
+	huc_fw->uc_fw_path = fw_path;
+	huc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
+
+	DRM_DEBUG_DRIVER("HuC firmware pending, path %s\n", fw_path);
+
+	intel_uc_fw_fetch(dev_priv, huc_fw);
+}
+
+/**
+ * intel_huc_load() - load HuC uCode to device
+ * @dev_priv: the drm_i915_private device
+ *
+ * Called from gem_init_hw() during driver loading and also after a GPU reset.
+ * Be note that HuC loading must be done before GuC loading.
+ *
+ * The firmware image should have already been fetched into memory by the
+ * earlier call to intel_huc_init(), so here we need only check that
+ * is succeeded, and then transfer the image to the h/w.
+ *
+ * Return:	non-zero code on error
+ */
+int intel_huc_load(struct drm_i915_private *dev_priv)
+{
+	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
+	int err;
+
+	if (huc_fw->fetch_status == INTEL_UC_FIRMWARE_NONE)
+		return 0;
+
+	DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
+		huc_fw->uc_fw_path,
+		intel_uc_fw_status_repr(huc_fw->fetch_status),
+		intel_uc_fw_status_repr(huc_fw->load_status));
+
+	if (huc_fw->fetch_status == INTEL_UC_FIRMWARE_SUCCESS &&
+	    huc_fw->load_status == INTEL_UC_FIRMWARE_FAIL)
+		return -ENOEXEC;
+
+	huc_fw->load_status = INTEL_UC_FIRMWARE_PENDING;
+
+	switch (huc_fw->fetch_status) {
+	case INTEL_UC_FIRMWARE_FAIL:
+		/* something went wrong :( */
+		err = -EIO;
+		goto fail;
+
+	case INTEL_UC_FIRMWARE_NONE:
+	case INTEL_UC_FIRMWARE_PENDING:
+	default:
+		/* "can't happen" */
+		WARN_ONCE(1, "HuC fw %s invalid fetch_status %s [%d]\n",
+			huc_fw->uc_fw_path,
+			intel_uc_fw_status_repr(huc_fw->fetch_status),
+			huc_fw->fetch_status);
+		err = -ENXIO;
+		goto fail;
+
+	case INTEL_UC_FIRMWARE_SUCCESS:
+		break;
+	}
+
+	err = huc_ucode_xfer(dev_priv);
+	if (err)
+		goto fail;
+
+	huc_fw->load_status = INTEL_UC_FIRMWARE_SUCCESS;
+
+	DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
+		huc_fw->uc_fw_path,
+		intel_uc_fw_status_repr(huc_fw->fetch_status),
+		intel_uc_fw_status_repr(huc_fw->load_status));
+
+	return 0;
+
+fail:
+	if (huc_fw->load_status == INTEL_UC_FIRMWARE_PENDING)
+		huc_fw->load_status = INTEL_UC_FIRMWARE_FAIL;
+
+	DRM_ERROR("Failed to complete HuC uCode load with ret %d\n", err);
+
+	return err;
+}
+
+/**
+ * intel_huc_fini() - clean up resources allocated for HuC
+ * @dev: the drm device
+ *
+ * Cleans up by releasing the huc firmware GEM obj.
+ */
+void intel_huc_fini(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
+
+	mutex_lock(&dev->struct_mutex);
+	if (huc_fw->uc_fw_obj)
+		i915_gem_object_put(huc_fw->uc_fw_obj);
+	huc_fw->uc_fw_obj = NULL;
+	mutex_unlock(&dev->struct_mutex);
+
+	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
+}
+
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index ad140e2..57aef56 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -24,6 +24,9 @@
 #ifndef _INTEL_UC_H_
 #define _INTEL_UC_H_
 
+#define HUC_STATUS2             _MMIO(0xD3B0)
+#define   HUC_FW_VERIFIED       (1<<7)
+
 #include "intel_guc_fwif.h"
 #include "i915_guc_reg.h"
 #include "intel_ringbuffer.h"
@@ -174,6 +177,13 @@ struct intel_guc {
 	struct mutex send_mutex;
 };
 
+struct intel_huc {
+	/* Generic uC firmware management */
+	struct intel_uc_fw fw;
+
+	/* HuC-specific additions */
+};
+
 /* intel_uc.c */
 void intel_uc_init_early(struct drm_i915_private *dev_priv);
 bool intel_guc_recv(struct drm_i915_private *dev_priv, u32 *status);
@@ -190,6 +200,9 @@ extern void intel_guc_fini(struct drm_i915_private *dev_priv);
 extern const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status);
 extern int intel_guc_suspend(struct drm_i915_private *dev_priv);
 extern int intel_guc_resume(struct drm_i915_private *dev_priv);
+void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
+	struct intel_uc_fw *uc_fw);
+u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv);
 
 /* i915_guc_submission.c */
 int i915_guc_submission_init(struct drm_i915_private *dev_priv);
@@ -204,4 +217,9 @@ void i915_guc_register(struct drm_i915_private *dev_priv);
 void i915_guc_unregister(struct drm_i915_private *dev_priv);
 int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val);
 
+/* intel_huc_loader.c */
+void intel_huc_init(struct drm_i915_private *dev_priv);
+void intel_huc_fini(struct drm_device *dev);
+int intel_huc_load(struct drm_i915_private *dev_priv);
+
 #endif
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support
  2016-12-22 23:12 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
                   ` (2 preceding siblings ...)
  2016-12-22 23:12 ` [PATCH 3/8] drm/i915/huc: Add HuC fw loading support Anusha Srivatsa
@ 2016-12-22 23:12 ` Anusha Srivatsa
  2016-12-23 14:43   ` Arkadiusz Hiler
  2016-12-22 23:12 ` [PATCH 5/8] drm/i915/HuC: Add KBL huC loading Support Anusha Srivatsa
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 50+ messages in thread
From: Anusha Srivatsa @ 2016-12-22 23:12 UTC (permalink / raw)
  To: intel-gfx

This patch adds the HuC Loading for the BXT by using
the updated file construction.

Version 1.7 of the HuC firmware.

v2: rebased.
v3: rebased on top of drm-tip
v4: rebased.
v5: rebased. Rename BXT_FW_MAJOR to BXT_HUC_FW_
v6: rebased.

Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
---
 drivers/gpu/drm/i915/intel_huc_loader.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c b/drivers/gpu/drm/i915/intel_huc_loader.c
index 98d631c..c525f41 100644
--- a/drivers/gpu/drm/i915/intel_huc_loader.c
+++ b/drivers/gpu/drm/i915/intel_huc_loader.c
@@ -40,6 +40,10 @@
  * Note that HuC firmware loading must be done before GuC loading.
  */
 
+#define BXT_HUC_FW_MAJOR 01
+#define BXT_HUC_FW_MINOR 07
+#define BXT_BLD_NUM 1398
+
 #define SKL_HUC_FW_MAJOR 01
 #define SKL_HUC_FW_MINOR 07
 #define SKL_BLD_NUM 1398
@@ -52,6 +56,9 @@
 	SKL_HUC_FW_MINOR, SKL_BLD_NUM)
 MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
 
+#define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_HUC_FW_MAJOR, \
+	BXT_HUC_FW_MINOR, BXT_BLD_NUM)
+MODULE_FIRMWARE(I915_BXT_HUC_UCODE);
 /**
  * huc_ucode_xfer() - DMA's the firmware
  * @dev_priv: the drm device
@@ -156,6 +163,10 @@ void intel_huc_init(struct drm_i915_private *dev_priv)
 		fw_path = I915_SKL_HUC_UCODE;
 		huc_fw->major_ver_wanted = SKL_HUC_FW_MAJOR;
 		huc_fw->minor_ver_wanted = SKL_HUC_FW_MINOR;
+	} else if (IS_BROXTON(dev_priv)) {
+		fw_path = I915_BXT_HUC_UCODE;
+		huc_fw->major_ver_wanted = BXT_HUC_FW_MAJOR;
+		huc_fw->minor_ver_wanted = BXT_HUC_FW_MINOR;
 	}
 
 	huc_fw->uc_fw_path = fw_path;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 5/8] drm/i915/HuC: Add KBL huC loading Support
  2016-12-22 23:12 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
                   ` (3 preceding siblings ...)
  2016-12-22 23:12 ` [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support Anusha Srivatsa
@ 2016-12-22 23:12 ` Anusha Srivatsa
  2016-12-23 14:43   ` Arkadiusz Hiler
  2016-12-22 23:12 ` [PATCH 6/8] drm/i915/huc: Add debugfs for HuC loading status check Anusha Srivatsa
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 50+ messages in thread
From: Anusha Srivatsa @ 2016-12-22 23:12 UTC (permalink / raw)
  To: intel-gfx

This patch adds the support to load HuC on KBL
Version 2.0

v2: rebased.
v3: rebased on top of drm-tip
v4: rebased.
v5: rebased. Rename KBL_FW_ to KBL_HUC_FW_
v6: rebased. Remove old checks.

Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
---
 drivers/gpu/drm/i915/intel_huc_loader.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c b/drivers/gpu/drm/i915/intel_huc_loader.c
index c525f41..75f3dc5 100644
--- a/drivers/gpu/drm/i915/intel_huc_loader.c
+++ b/drivers/gpu/drm/i915/intel_huc_loader.c
@@ -48,6 +48,10 @@
 #define SKL_HUC_FW_MINOR 07
 #define SKL_BLD_NUM 1398
 
+#define KBL_HUC_FW_MAJOR 02
+#define KBL_HUC_FW_MINOR 00
+#define KBL_BLD_NUM 1810
+
 #define HUC_FW_PATH(platform, major, minor, bld_num) \
 	"i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \
 	__stringify(minor) "_" __stringify(bld_num) ".bin"
@@ -59,6 +63,11 @@ MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
 #define I915_BXT_HUC_UCODE HUC_FW_PATH(bxt, BXT_HUC_FW_MAJOR, \
 	BXT_HUC_FW_MINOR, BXT_BLD_NUM)
 MODULE_FIRMWARE(I915_BXT_HUC_UCODE);
+
+#define I915_KBL_HUC_UCODE HUC_FW_PATH(kbl, KBL_HUC_FW_MAJOR, \
+	KBL_HUC_FW_MINOR, KBL_BLD_NUM)
+MODULE_FIRMWARE(I915_KBL_HUC_UCODE);
+
 /**
  * huc_ucode_xfer() - DMA's the firmware
  * @dev_priv: the drm device
@@ -167,6 +176,10 @@ void intel_huc_init(struct drm_i915_private *dev_priv)
 		fw_path = I915_BXT_HUC_UCODE;
 		huc_fw->major_ver_wanted = BXT_HUC_FW_MAJOR;
 		huc_fw->minor_ver_wanted = BXT_HUC_FW_MINOR;
+	} else if (IS_KABYLAKE(dev_priv)) {
+		fw_path = I915_KBL_HUC_UCODE;
+		huc_fw->major_ver_wanted = KBL_HUC_FW_MAJOR;
+		huc_fw->minor_ver_wanted = KBL_HUC_FW_MINOR;
 	}
 
 	huc_fw->uc_fw_path = fw_path;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 6/8] drm/i915/huc: Add debugfs for HuC loading status check
  2016-12-22 23:12 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
                   ` (4 preceding siblings ...)
  2016-12-22 23:12 ` [PATCH 5/8] drm/i915/HuC: Add KBL huC loading Support Anusha Srivatsa
@ 2016-12-22 23:12 ` Anusha Srivatsa
  2016-12-22 23:12 ` [PATCH 7/8] drm/i915/huc: Support HuC authentication Anusha Srivatsa
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2016-12-22 23:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

Add debugfs entry for HuC loading status check.

v2: rebase on-top of drm-intel-nightly.
v3: rebased again.
v7: rebased.
v8: rebased.
v9: rebased.
v10: rebased.
v11: rebased on top of drm-tip
v12: rebased.
v13: rebased.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Jeff McGee <jeff.mcgee@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 0a3c575..f43b41e 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2325,6 +2325,36 @@ static int i915_llc(struct seq_file *m, void *data)
 	return 0;
 }
 
+static int i915_huc_load_status_info(struct seq_file *m, void *data)
+{
+	struct drm_i915_private *dev_priv = node_to_i915(m->private);
+	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
+
+	if (!HAS_HUC_UCODE(dev_priv))
+		return 0;
+
+	seq_puts(m, "HuC firmware status:\n");
+	seq_printf(m, "\tpath: %s\n", huc_fw->uc_fw_path);
+	seq_printf(m, "\tfetch: %s\n",
+		intel_uc_fw_status_repr(huc_fw->fetch_status));
+	seq_printf(m, "\tload: %s\n",
+		intel_uc_fw_status_repr(huc_fw->load_status));
+	seq_printf(m, "\tversion wanted: %d.%d\n",
+		huc_fw->major_ver_wanted, huc_fw->minor_ver_wanted);
+	seq_printf(m, "\tversion found: %d.%d\n",
+		huc_fw->major_ver_found, huc_fw->minor_ver_found);
+	seq_printf(m, "\theader: offset is %d; size = %d\n",
+		huc_fw->header_offset, huc_fw->header_size);
+	seq_printf(m, "\tuCode: offset is %d; size = %d\n",
+		huc_fw->ucode_offset, huc_fw->ucode_size);
+	seq_printf(m, "\tRSA: offset is %d; size = %d\n",
+		huc_fw->rsa_offset, huc_fw->rsa_size);
+
+	seq_printf(m, "\nHuC status 0x%08x:\n", I915_READ(HUC_STATUS2));
+
+	return 0;
+}
+
 static int i915_guc_load_status_info(struct seq_file *m, void *data)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -4553,6 +4583,7 @@ static const struct drm_info_list i915_debugfs_list[] = {
 	{"i915_guc_info", i915_guc_info, 0},
 	{"i915_guc_load_status", i915_guc_load_status_info, 0},
 	{"i915_guc_log_dump", i915_guc_log_dump, 0},
+	{"i915_huc_load_status", i915_huc_load_status_info, 0},
 	{"i915_frequency_info", i915_frequency_info, 0},
 	{"i915_hangcheck_info", i915_hangcheck_info, 0},
 	{"i915_drpc_info", i915_drpc_info, 0},
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 7/8] drm/i915/huc: Support HuC authentication
  2016-12-22 23:12 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
                   ` (5 preceding siblings ...)
  2016-12-22 23:12 ` [PATCH 6/8] drm/i915/huc: Add debugfs for HuC loading status check Anusha Srivatsa
@ 2016-12-22 23:12 ` Anusha Srivatsa
  2016-12-22 23:30   ` Chris Wilson
  2016-12-22 23:12 ` [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams Anusha Srivatsa
  2016-12-22 23:53 ` ✓ Fi.CI.BAT: success for HuC Loading Patches Patchwork
  8 siblings, 1 reply; 50+ messages in thread
From: Anusha Srivatsa @ 2016-12-22 23:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

The HuC authentication is done by host2guc call. The HuC RSA keys
are sent to GuC for authentication.

v2: rebased on top of drm-intel-nightly.
    changed name format and upped version 1.7.
v3: rebased on top of drm-intel-nightly.
v4: changed wait_for_automic to wait_for
v5: rebased.
v7: rebased.
v8: rebased.
v9: rebased. Rename intel_huc_auh() to intel_guc_auth_huc()
and place the prototype in intel_guc.h,correct the comments.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip
v13: rebased. Moved intel_guc_auth_huc from i915_guc_submission.c
to intel_uc.c.Update dev to dev_priv in intel_guc_auth_huc().
Renamed HOST2GUC_ACTION_AUTHENTICATE_HUC TO INTEL_GUC_ACTION_
AUTHENTICATE_HUC
v14: rebased.
v15: rebased. Add newline on DRM_ERRORs that already dont have one.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   |  1 +
 drivers/gpu/drm/i915/intel_guc_loader.c |  2 ++
 drivers/gpu/drm/i915/intel_uc.c         | 62 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_uc.h         |  1 +
 4 files changed, 66 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index ed1ab40..ce4e05e 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -506,6 +506,7 @@ enum intel_guc_action {
 	INTEL_GUC_ACTION_EXIT_S_STATE = 0x502,
 	INTEL_GUC_ACTION_SLPC_REQUEST = 0x3003,
 	INTEL_GUC_ACTION_UK_LOG_ENABLE_LOGGING = 0x0E000,
+	INTEL_GUC_ACTION_AUTHENTICATE_HUC = 0x4000,
 	INTEL_GUC_ACTION_LIMIT
 };
 
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 8c77e94..85c0a2a 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -529,6 +529,8 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
 		intel_uc_fw_status_repr(guc_fw->fetch_status),
 		intel_uc_fw_status_repr(guc_fw->load_status));
 
+	intel_guc_auth_huc(dev_priv);
+
 	if (i915.enable_guc_submission) {
 		if (i915.guc_log_level >= 0)
 			gen9_enable_guc_interrupts(dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index 8ae6795..b858d36 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -138,3 +138,65 @@ int intel_guc_log_control(struct intel_guc *guc, u32 control_val)
 
 	return intel_guc_send(guc, action, ARRAY_SIZE(action));
 }
+
+/**
+ * intel_guc_auth_huc() - authenticate ucode
+ * @dev_priv: the drm_i915_device
+ *
+ * Triggers a HuC fw authentication request to the GuC via intel_guc_action_
+ * authenticate_huc interface.
+ * interface.
+ */
+void intel_guc_auth_huc(struct drm_i915_private *dev_priv)
+{
+	struct intel_guc *guc = &dev_priv->guc;
+	struct intel_huc *huc = &dev_priv->huc;
+	struct i915_vma *vma;
+	int ret;
+	u32 data[2];
+
+	/* Bypass the case where there is no HuC firmware */
+	if (huc->fw.fetch_status == INTEL_UC_FIRMWARE_NONE ||
+		huc->fw.load_status == INTEL_UC_FIRMWARE_NONE)
+		return;
+
+	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) {
+		DRM_ERROR("HuC: GuC fw wasn't loaded. Can't authenticate\n");
+		return;
+	}
+
+	if (huc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) {
+		DRM_ERROR("HuC: fw wasn't loaded. Nothing to authenticate\n");
+		return;
+	}
+
+	vma = i915_gem_object_ggtt_pin(huc->fw.uc_fw_obj, NULL, 0, 0, 0);
+	if (IS_ERR(vma)) {
+		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
+		return;
+	}
+
+
+	/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
+	I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+
+	/* Specify auth action and where public signature is. */
+	data[0] = INTEL_GUC_ACTION_AUTHENTICATE_HUC;
+	data[1] = i915_ggtt_offset(vma) + huc->fw.rsa_offset;
+
+	ret = intel_guc_send(guc, data, ARRAY_SIZE(data));
+	if (ret) {
+		DRM_ERROR("HuC: GuC did not ack Auth request\n");
+		goto out;
+	}
+
+	/* Check authentication status, it should be done by now */
+	ret = wait_for((I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) > 0, 50);
+	if (ret) {
+		DRM_ERROR("HuC: Authentication failed\n");
+		goto out;
+	}
+
+out:
+	i915_vma_unpin(vma);
+}
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 57aef56..e69d47c 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -192,6 +192,7 @@ int intel_guc_sample_forcewake(struct intel_guc *guc);
 int intel_guc_log_flush_complete(struct intel_guc *guc);
 int intel_guc_log_flush(struct intel_guc *guc);
 int intel_guc_log_control(struct intel_guc *guc, u32 control_val);
+void intel_guc_auth_huc(struct drm_i915_private *dev_priv);
 
 /* intel_guc_loader.c */
 extern void intel_guc_init(struct drm_i915_private *dev_priv);
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams
  2016-12-22 23:12 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
                   ` (6 preceding siblings ...)
  2016-12-22 23:12 ` [PATCH 7/8] drm/i915/huc: Support HuC authentication Anusha Srivatsa
@ 2016-12-22 23:12 ` Anusha Srivatsa
  2016-12-23 14:33   ` Arkadiusz Hiler
  2016-12-22 23:53 ` ✓ Fi.CI.BAT: success for HuC Loading Patches Patchwork
  8 siblings, 1 reply; 50+ messages in thread
From: Anusha Srivatsa @ 2016-12-22 23:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

This patch will allow for getparams to return the status of the HuC.
As the HuC has to be validated by the GuC this patch uses the validated
status to show when the HuC is loaded and ready for use. You cannot use
the loaded status as with the GuC as the HuC is verified after it is
loaded and is not usable until it is verified.

v2: removed the forewakes as the registers are already force-woken.
     (T.Ursulin)
v4: rebased.
v5: rebased on top of drm-tip.
v6: rebased. Removed any reference to intel_huc.h
v7: rebased. Rename I915_PARAM_HAS_HUC to I915_PARAM_HUC_STATUS.
Remove intel_is_huc_valid() since it is used only in one place.
Put the case of I915_PARAM_HAS_HUC() in the right place.
v8: rebased. Add a comment to specify that I915_READ(reg)
does not read garbage value. The register HUC_STATUS2 is force
woken and no rpm is needed.

Signed-off-by: Peter Antoine <peter.antoine@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c         | 7 +++++++
 drivers/gpu/drm/i915/intel_huc_loader.c | 1 -
 include/uapi/drm/i915_drm.h             | 1 +
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 85a47c2..c4f0620 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -49,6 +49,7 @@
 #include "i915_trace.h"
 #include "i915_vgpu.h"
 #include "intel_drv.h"
+#include "intel_uc.h"
 
 static struct drm_driver driver;
 
@@ -315,6 +316,12 @@ static int i915_getparam(struct drm_device *dev, void *data,
 	case I915_PARAM_MIN_EU_IN_POOL:
 		value = INTEL_INFO(dev_priv)->sseu.min_eu_in_pool;
 		break;
+	case I915_PARAM_HUC_STATUS:
+		/* The register is already force-woken. We dont need
+		 * any rpm here
+		 */
+		value = I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED;
+		break;
 	case I915_PARAM_MMAP_GTT_VERSION:
 		/* Though we've started our numbering from 1, and so class all
 		 * earlier versions as 0, in effect their value is undefined as
diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c b/drivers/gpu/drm/i915/intel_huc_loader.c
index 75f3dc5..dd42676 100644
--- a/drivers/gpu/drm/i915/intel_huc_loader.c
+++ b/drivers/gpu/drm/i915/intel_huc_loader.c
@@ -284,4 +284,3 @@ void intel_huc_fini(struct drm_device *dev)
 
 	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
 }
-
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index da32c2f..57093b4 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -395,6 +395,7 @@ typedef struct drm_i915_irq_wait {
  * priorities and the driver will attempt to execute batches in priority order.
  */
 #define I915_PARAM_HAS_SCHEDULER	 41
+#define I915_PARAM_HUC_STATUS		 42
 
 typedef struct drm_i915_getparam {
 	__s32 param;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH 7/8] drm/i915/huc: Support HuC authentication
  2016-12-22 23:12 ` [PATCH 7/8] drm/i915/huc: Support HuC authentication Anusha Srivatsa
@ 2016-12-22 23:30   ` Chris Wilson
  2017-01-03 19:55     ` Srivatsa, Anusha
  0 siblings, 1 reply; 50+ messages in thread
From: Chris Wilson @ 2016-12-22 23:30 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx, Alex Dai, Peter Antoine

On Thu, Dec 22, 2016 at 03:12:23PM -0800, Anusha Srivatsa wrote:
> +void intel_guc_auth_huc(struct drm_i915_private *dev_priv)
> +{
> +	struct intel_guc *guc = &dev_priv->guc;
> +	struct intel_huc *huc = &dev_priv->huc;
> +	struct i915_vma *vma;
> +	int ret;
> +	u32 data[2];
> +
> +	/* Bypass the case where there is no HuC firmware */
> +	if (huc->fw.fetch_status == INTEL_UC_FIRMWARE_NONE ||
> +		huc->fw.load_status == INTEL_UC_FIRMWARE_NONE)
> +		return;
> +
> +	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) {
> +		DRM_ERROR("HuC: GuC fw wasn't loaded. Can't authenticate\n");
> +		return;
> +	}
> +
> +	if (huc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) {
> +		DRM_ERROR("HuC: fw wasn't loaded. Nothing to authenticate\n");
> +		return;
> +	}
> +
> +	vma = i915_gem_object_ggtt_pin(huc->fw.uc_fw_obj, NULL, 0, 0, 0);
> +	if (IS_ERR(vma)) {
> +		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
> +		return;
> +	}
> +
> +
> +	/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
> +	I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);

Still working on stopping this from frequently popping up in code
outside of the GTT routines.

> +	/* Specify auth action and where public signature is. */
> +	data[0] = INTEL_GUC_ACTION_AUTHENTICATE_HUC;
> +	data[1] = i915_ggtt_offset(vma) + huc->fw.rsa_offset;
> +
> +	ret = intel_guc_send(guc, data, ARRAY_SIZE(data));
> +	if (ret) {
> +		DRM_ERROR("HuC: GuC did not ack Auth request\n");
> +		goto out;
> +	}
> +
> +	/* Check authentication status, it should be done by now */
> +	ret = wait_for((I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) > 0, 50);

ret = intel_wait_for_register(dev_priv,
			      HUC_STATUS2,
			      HUC_FW_VERIFIED,
			      HUC_FW_VERIFIED,
			      50);

wait_for() is a rather large macro, and intel_wait_for_register()
employs the spin then sleep optimisation for quick responses.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* ✓ Fi.CI.BAT: success for HuC Loading Patches
  2016-12-22 23:12 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
                   ` (7 preceding siblings ...)
  2016-12-22 23:12 ` [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams Anusha Srivatsa
@ 2016-12-22 23:53 ` Patchwork
  8 siblings, 0 replies; 50+ messages in thread
From: Patchwork @ 2016-12-22 23:53 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx

== Series Details ==

Series: HuC Loading Patches
URL   : https://patchwork.freedesktop.org/series/17150/
State : success

== Summary ==

Series 17150v1 HuC Loading Patches
https://patchwork.freedesktop.org/api/1.0/series/17150/revisions/1/mbox/


fi-bdw-5557u     total:246  pass:232  dwarn:0   dfail:0   fail:0   skip:14 
fi-bsw-n3050     total:246  pass:207  dwarn:0   dfail:0   fail:0   skip:39 
fi-bxt-j4205     total:246  pass:224  dwarn:0   dfail:0   fail:0   skip:22 
fi-bxt-t5700     total:82   pass:69   dwarn:0   dfail:0   fail:0   skip:12 
fi-byt-j1900     total:246  pass:219  dwarn:0   dfail:0   fail:0   skip:27 
fi-byt-n2820     total:246  pass:215  dwarn:0   dfail:0   fail:0   skip:31 
fi-hsw-4770      total:246  pass:227  dwarn:0   dfail:0   fail:0   skip:19 
fi-hsw-4770r     total:246  pass:227  dwarn:0   dfail:0   fail:0   skip:19 
fi-ivb-3520m     total:246  pass:225  dwarn:0   dfail:0   fail:0   skip:21 
fi-ivb-3770      total:246  pass:225  dwarn:0   dfail:0   fail:0   skip:21 
fi-kbl-7500u     total:246  pass:225  dwarn:0   dfail:0   fail:0   skip:21 
fi-skl-6260u     total:246  pass:233  dwarn:0   dfail:0   fail:0   skip:13 
fi-skl-6700hq    total:246  pass:226  dwarn:0   dfail:0   fail:0   skip:20 
fi-skl-6700k     total:246  pass:222  dwarn:3   dfail:0   fail:0   skip:21 
fi-skl-6770hq    total:246  pass:233  dwarn:0   dfail:0   fail:0   skip:13 
fi-snb-2600      total:246  pass:214  dwarn:0   dfail:0   fail:0   skip:32 

7165fdc7f0b0b536557fcd0a222d083a901be57c drm-tip: 2016y-12m-22d-19h-42m-25s UTC integration manifest
e8b433c drm/i915/get_params: Add HuC status to getparams
6ffbe20 drm/i915/huc: Support HuC authentication
8cb202b drm/i915/huc: Add debugfs for HuC loading status check
b1bbca7 drm/i915/HuC: Add KBL huC loading Support
6a3c405 drm/i915/huc: Add BXT HuC Loading Support
97fad48 drm/i915/huc: Add HuC fw loading support
b2a545d drm/i915/huc: Unified css_header struct for GuC and HuC
170ce27 drm/i915/guc: Make the GuC fw loading helper functions general

== Logs ==

For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3381/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general
  2016-12-22 23:12 ` [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general Anusha Srivatsa
@ 2016-12-23 14:15   ` Arkadiusz Hiler
  2016-12-27 17:28   ` Michal Wajdeczko
  1 sibling, 0 replies; 50+ messages in thread
From: Arkadiusz Hiler @ 2016-12-23 14:15 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx, Alex Dai, Peter Antoine

On Thu, Dec 22, 2016 at 03:12:17PM -0800, Anusha Srivatsa wrote:
> From: Peter Antoine <peter.antoine@intel.com>
> 
> Rename some of the GuC fw loading code to make them more general. We
> will utilise them for HuC loading as well.
>      s/intel_guc_fw/intel_uc_fw/g
>      s/GUC_FIRMWARE/UC_FIRMWARE/g
> 
> Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts members,
> such as 'guc' or 'guc_fw' either is renamed to 'uc' or removed for
> same purpose.
> 
> v2: rebased on top of nightly.
>     reapplied the search/replace as upstream code as changed.
> v3: rebased again on drm-nightly.
> v4: removed G from messages in shared fw fetch function.
> v5: rebased.
> v7: rebased.
> v8: rebased.
> v9: rebased.
> v10: rebased.
> v11: rebased.
> v12: rebased on top of drm-tip
> v13: rebased.Updated dev to dev_priv in intel_guc_setup(), guc_fw_getch()
> and intel_guc_init().
> v14: rebased. Remove uint32_t fw_type to patch 2. Add INTEL_ prefix for
> fields in enum intel_uc_fw_status. Remove uc_dev field since its never
> used.Rename uc_fw to just fw and guc_fw to fw to avoid redundency.
> v15: rebased. Remove sections of code that were commented and no longer
> required.
> 
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-12-22 23:12 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
@ 2016-12-23 14:21   ` Arkadiusz Hiler
  2016-12-23 17:32     ` Srivatsa, Anusha
  0 siblings, 1 reply; 50+ messages in thread
From: Arkadiusz Hiler @ 2016-12-23 14:21 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx, Alex Dai, Peter Antoine

On Thu, Dec 22, 2016 at 03:12:18PM -0800, Anusha Srivatsa wrote:
> From: Peter Antoine <peter.antoine@intel.com>
> 
> HuC firmware css header has almost exactly same definition as GuC
> firmware except for the sw_version. Also, add a new member fw_type
> into intel_uc_fw to indicate what kind of fw it is. So, the loader
> will pull right sw_version from header.
> 
> v2: rebased on-top of drm-intel-nightly
> v3: rebased on-top of drm-intel-nightly (again).
> v4: rebased + spaces.
> v7: rebased.
> v8: rebased.
> v9: rebased. Rename device_id to guc_branch_client_version,
> make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
> and UC_FW_TYPE_HUC into an enum.
> v10: rebased.
> v11: rebased.
> v12: rebased on top of drm-tip.
> v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
> v14: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
> from patch 1.Combine two different unions for huc and guc version,
> reserved etc into one union with two structs.
> v15: rebased.
> 
> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++++++++++++++----
>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
>  drivers/gpu/drm/i915/intel_uc.h         |  6 +++++
>  3 files changed, 53 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
> index 3202b32..ed1ab40 100644
> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
> @@ -145,7 +145,7 @@
>   * The GuC firmware layout looks like this:
>   *
>   *     +-------------------------------+
> - *     |        guc_css_header         |
> + *     |         uc_css_header         |
>   *     |                               |
>   *     | contains major/minor version  |
>   *     +-------------------------------+
> @@ -172,9 +172,16 @@
>   * 3. Length info of each component can be found in header, in dwords.
>   * 4. Modulus and exponent key are not required by driver. They may not appear
>   *    in fw. So driver will load a truncated firmware in this case.
> + *
> + * HuC firmware layout is same as GuC firmware.
> + *
> + * HuC firmware css header is different. However, the only difference is where
> + * the version information is saved. The uc_css_header is unified to support
> + * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
> + * uc_css_header.guc_sw_version for GuC.
>   */
>  
> -struct guc_css_header {
> +struct uc_css_header {
>  	uint32_t module_type;
>  	/* header_size includes all non-uCode bits, including css_header, rsa
>  	 * key, modulus key and exponent data. */
> @@ -205,8 +212,16 @@ struct guc_css_header {
>  
>  	char username[8];
>  	char buildnumber[12];
> -	uint32_t device_id;
> -	uint32_t guc_sw_version;
> +	union {
> +		struct {
> +			uint32_t branch_client_version;
> +			uint32_t sw_version;
> +	} guc;
> +		struct {
> +			uint32_t sw_version;
> +			uint32_t reserved;
> +	} huc;
> +	};
>  	uint32_t prod_preprod_fw;
>  	uint32_t reserved[12];
>  	uint32_t header_info;
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> index ffe53dd7..06e3e5c 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>  	struct pci_dev *pdev = dev_priv->drm.pdev;
>  	struct drm_i915_gem_object *obj;
>  	const struct firmware *fw = NULL;
> -	struct guc_css_header *css;
> +	struct uc_css_header *css;
>  	size_t size;
>  	int err;
>  
> @@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>  		uc_fw->uc_fw_path, fw);
>  
>  	/* Check the size of the blob before examining buffer contents */
> -	if (fw->size < sizeof(struct guc_css_header)) {
> +	if (fw->size < sizeof(struct uc_css_header)) {
>  		DRM_NOTE("Firmware header is missing\n");
>  		goto fail;
>  	}
>  
> -	css = (struct guc_css_header *)fw->data;
> +	css = (struct uc_css_header *)fw->data;
>  
>  	/* Firmware bits always start from header */
>  	uc_fw->header_offset = 0;
>  	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
>  
> -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
> +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>  		DRM_NOTE("CSS header definition mismatch\n");
>  		goto fail;
>  	}
> @@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>  		goto fail;
>  	}
>  
> -	/* Header and uCode will be loaded to WOPCM. Size of the two. */
> -	size = uc_fw->header_size + uc_fw->ucode_size;
> -	if (size > guc_wopcm_size(dev_priv)) {
> -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
> -		goto fail;
> -	}
> -
>  	/*
>  	 * The GuC firmware image has the version number embedded at a well-known
>  	 * offset within the firmware blob; note that major / minor version are
>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
>  	 * in terms of bytes (u8).
>  	 */
> -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
> -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> +	switch (uc_fw->fw_type) {
> +	case INTEL_UC_FW_TYPE_GUC:
> +		/* Header and uCode will be loaded to WOPCM. Size of the two. */
> +		size = uc_fw->header_size + uc_fw->ucode_size;
> +
> +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
> +		if (size > guc_wopcm_size(dev_priv)) {
> +			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
> +			goto fail;
> +		}
> +		uc_fw->major_ver_found = css->guc.sw_version >> 16;
> +		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
> +		break;
> +
> +	case INTEL_UC_FW_TYPE_HUC:
> +		uc_fw->major_ver_found = css->huc.sw_version >> 16;
> +		uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
> +		break;
> +
> +	default:
> +		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
> +		err = -ENOEXEC;
> +		goto fail;
> +	}
>  
>  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
> diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
> index 893bcec..ad140e2 100644
> --- a/drivers/gpu/drm/i915/intel_uc.h
> +++ b/drivers/gpu/drm/i915/intel_uc.h
> @@ -98,6 +98,11 @@ enum intel_uc_fw_status {
>  	INTEL_UC_FIRMWARE_SUCCESS
>  };
>  
> +enum {
> +	INTEL_UC_FW_TYPE_GUC,
> +	INTEL_UC_FW_TYPE_HUC
> +};
> +
>  /*
>   * This structure encapsulates all the data needed during the process
>   * of fetching, caching, and loading the firmware image into the GuC.
> @@ -114,6 +119,7 @@ struct intel_uc_fw {
>  	uint16_t major_ver_found;
>  	uint16_t minor_ver_found;
>  
> +	uint32_t fw_type;

Any reason why we use uint32_t instead of a named enum type here?

>  	uint32_t header_size;
>  	uint32_t header_offset;
>  	uint32_t rsa_size;
> -- 
> 2.7.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams
  2016-12-22 23:12 ` [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams Anusha Srivatsa
@ 2016-12-23 14:33   ` Arkadiusz Hiler
  0 siblings, 0 replies; 50+ messages in thread
From: Arkadiusz Hiler @ 2016-12-23 14:33 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx, Peter Antoine

On Thu, Dec 22, 2016 at 03:12:24PM -0800, Anusha Srivatsa wrote:
> From: Peter Antoine <peter.antoine@intel.com>
> 
> This patch will allow for getparams to return the status of the HuC.
> As the HuC has to be validated by the GuC this patch uses the validated
> status to show when the HuC is loaded and ready for use. You cannot use
> the loaded status as with the GuC as the HuC is verified after it is
> loaded and is not usable until it is verified.
> 
> v2: removed the forewakes as the registers are already force-woken.
>      (T.Ursulin)
> v4: rebased.
> v5: rebased on top of drm-tip.
> v6: rebased. Removed any reference to intel_huc.h
> v7: rebased. Rename I915_PARAM_HAS_HUC to I915_PARAM_HUC_STATUS.
> Remove intel_is_huc_valid() since it is used only in one place.
> Put the case of I915_PARAM_HAS_HUC() in the right place.
> v8: rebased. Add a comment to specify that I915_READ(reg)
> does not read garbage value. The register HUC_STATUS2 is force
> woken and no rpm is needed.
> 
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>

Where is your s-o-b?

other than that:
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support
  2016-12-22 23:12 ` [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support Anusha Srivatsa
@ 2016-12-23 14:43   ` Arkadiusz Hiler
  0 siblings, 0 replies; 50+ messages in thread
From: Arkadiusz Hiler @ 2016-12-23 14:43 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx

On Thu, Dec 22, 2016 at 03:12:20PM -0800, Anusha Srivatsa wrote:
> This patch adds the HuC Loading for the BXT by using
> the updated file construction.
> 
> Version 1.7 of the HuC firmware.
> 
> v2: rebased.
> v3: rebased on top of drm-tip
> v4: rebased.
> v5: rebased. Rename BXT_FW_MAJOR to BXT_HUC_FW_
> v6: rebased.
> 
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 5/8] drm/i915/HuC: Add KBL huC loading Support
  2016-12-22 23:12 ` [PATCH 5/8] drm/i915/HuC: Add KBL huC loading Support Anusha Srivatsa
@ 2016-12-23 14:43   ` Arkadiusz Hiler
  0 siblings, 0 replies; 50+ messages in thread
From: Arkadiusz Hiler @ 2016-12-23 14:43 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx

On Thu, Dec 22, 2016 at 03:12:21PM -0800, Anusha Srivatsa wrote:
> This patch adds the support to load HuC on KBL
> Version 2.0
> 
> v2: rebased.
> v3: rebased on top of drm-tip
> v4: rebased.
> v5: rebased. Rename KBL_FW_ to KBL_HUC_FW_
> v6: rebased. Remove old checks.
> 
> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-12-23 14:21   ` Arkadiusz Hiler
@ 2016-12-23 17:32     ` Srivatsa, Anusha
  0 siblings, 0 replies; 50+ messages in thread
From: Srivatsa, Anusha @ 2016-12-23 17:32 UTC (permalink / raw)
  To: Hiler, Arkadiusz; +Cc: intel-gfx, Alex Dai, Peter Antoine



>-----Original Message-----
>From: Hiler, Arkadiusz
>Sent: Friday, December 23, 2016 6:22 AM
>To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
>Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter Antoine
><peter.antoine@intel.com>
>Subject: Re: [Intel-gfx] [PATCH 2/8] drm/i915/huc: Unified css_header struct for
>GuC and HuC
>
>On Thu, Dec 22, 2016 at 03:12:18PM -0800, Anusha Srivatsa wrote:
>> From: Peter Antoine <peter.antoine@intel.com>
>>
>> HuC firmware css header has almost exactly same definition as GuC
>> firmware except for the sw_version. Also, add a new member fw_type
>> into intel_uc_fw to indicate what kind of fw it is. So, the loader
>> will pull right sw_version from header.
>>
>> v2: rebased on-top of drm-intel-nightly
>> v3: rebased on-top of drm-intel-nightly (again).
>> v4: rebased + spaces.
>> v7: rebased.
>> v8: rebased.
>> v9: rebased. Rename device_id to guc_branch_client_version, make
>> guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC and
>> UC_FW_TYPE_HUC into an enum.
>> v10: rebased.
>> v11: rebased.
>> v12: rebased on top of drm-tip.
>> v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
>> v14: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
>> from patch 1.Combine two different unions for huc and guc version,
>> reserved etc into one union with two structs.
>> v15: rebased.
>>
>> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
>> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
>> Signed-off-by: Alex Dai <yu.dai@intel.com>
>> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++++++++++++++----
>>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-------
>----
>>  drivers/gpu/drm/i915/intel_uc.h         |  6 +++++
>>  3 files changed, 53 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h
>> b/drivers/gpu/drm/i915/intel_guc_fwif.h
>> index 3202b32..ed1ab40 100644
>> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
>> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
>> @@ -145,7 +145,7 @@
>>   * The GuC firmware layout looks like this:
>>   *
>>   *     +-------------------------------+
>> - *     |        guc_css_header         |
>> + *     |         uc_css_header         |
>>   *     |                               |
>>   *     | contains major/minor version  |
>>   *     +-------------------------------+
>> @@ -172,9 +172,16 @@
>>   * 3. Length info of each component can be found in header, in dwords.
>>   * 4. Modulus and exponent key are not required by driver. They may not
>appear
>>   *    in fw. So driver will load a truncated firmware in this case.
>> + *
>> + * HuC firmware layout is same as GuC firmware.
>> + *
>> + * HuC firmware css header is different. However, the only difference
>> + is where
>> + * the version information is saved. The uc_css_header is unified to
>> + support
>> + * both. Driver should get HuC version from
>> + uc_css_header.huc_sw_version, while
>> + * uc_css_header.guc_sw_version for GuC.
>>   */
>>
>> -struct guc_css_header {
>> +struct uc_css_header {
>>  	uint32_t module_type;
>>  	/* header_size includes all non-uCode bits, including css_header, rsa
>>  	 * key, modulus key and exponent data. */ @@ -205,8 +212,16 @@
>> struct guc_css_header {
>>
>>  	char username[8];
>>  	char buildnumber[12];
>> -	uint32_t device_id;
>> -	uint32_t guc_sw_version;
>> +	union {
>> +		struct {
>> +			uint32_t branch_client_version;
>> +			uint32_t sw_version;
>> +	} guc;
>> +		struct {
>> +			uint32_t sw_version;
>> +			uint32_t reserved;
>> +	} huc;
>> +	};
>>  	uint32_t prod_preprod_fw;
>>  	uint32_t reserved[12];
>>  	uint32_t header_info;
>> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c
>> b/drivers/gpu/drm/i915/intel_guc_loader.c
>> index ffe53dd7..06e3e5c 100644
>> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
>> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
>> @@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private
>*dev_priv,
>>  	struct pci_dev *pdev = dev_priv->drm.pdev;
>>  	struct drm_i915_gem_object *obj;
>>  	const struct firmware *fw = NULL;
>> -	struct guc_css_header *css;
>> +	struct uc_css_header *css;
>>  	size_t size;
>>  	int err;
>>
>> @@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private
>*dev_priv,
>>  		uc_fw->uc_fw_path, fw);
>>
>>  	/* Check the size of the blob before examining buffer contents */
>> -	if (fw->size < sizeof(struct guc_css_header)) {
>> +	if (fw->size < sizeof(struct uc_css_header)) {
>>  		DRM_NOTE("Firmware header is missing\n");
>>  		goto fail;
>>  	}
>>
>> -	css = (struct guc_css_header *)fw->data;
>> +	css = (struct uc_css_header *)fw->data;
>>
>>  	/* Firmware bits always start from header */
>>  	uc_fw->header_offset = 0;
>>  	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
>>
>> -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
>> +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>>  		DRM_NOTE("CSS header definition mismatch\n");
>>  		goto fail;
>>  	}
>> @@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private
>*dev_priv,
>>  		goto fail;
>>  	}
>>
>> -	/* Header and uCode will be loaded to WOPCM. Size of the two. */
>> -	size = uc_fw->header_size + uc_fw->ucode_size;
>> -	if (size > guc_wopcm_size(dev_priv)) {
>> -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
>> -		goto fail;
>> -	}
>> -
>>  	/*
>>  	 * The GuC firmware image has the version number embedded at a well-
>known
>>  	 * offset within the firmware blob; note that major / minor version are
>>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
>>  	 * in terms of bytes (u8).
>>  	 */
>> -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
>> -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
>> +	switch (uc_fw->fw_type) {
>> +	case INTEL_UC_FW_TYPE_GUC:
>> +		/* Header and uCode will be loaded to WOPCM. Size of the two.
>*/
>> +		size = uc_fw->header_size + uc_fw->ucode_size;
>> +
>> +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context).
>*/
>> +		if (size > guc_wopcm_size(dev_priv)) {
>> +			DRM_ERROR("Firmware is too large to fit in
>WOPCM\n");
>> +			goto fail;
>> +		}
>> +		uc_fw->major_ver_found = css->guc.sw_version >> 16;
>> +		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
>> +		break;
>> +
>> +	case INTEL_UC_FW_TYPE_HUC:
>> +		uc_fw->major_ver_found = css->huc.sw_version >> 16;
>> +		uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
>> +		break;
>> +
>> +	default:
>> +		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
>> +		err = -ENOEXEC;
>> +		goto fail;
>> +	}
>>
>>  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>>  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) { diff --git
>> a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
>> index 893bcec..ad140e2 100644
>> --- a/drivers/gpu/drm/i915/intel_uc.h
>> +++ b/drivers/gpu/drm/i915/intel_uc.h
>> @@ -98,6 +98,11 @@ enum intel_uc_fw_status {
>>  	INTEL_UC_FIRMWARE_SUCCESS
>>  };
>>
>> +enum {
>> +	INTEL_UC_FW_TYPE_GUC,
>> +	INTEL_UC_FW_TYPE_HUC
>> +};
>> +
>>  /*
>>   * This structure encapsulates all the data needed during the process
>>   * of fetching, caching, and loading the firmware image into the GuC.
>> @@ -114,6 +119,7 @@ struct intel_uc_fw {
>>  	uint16_t major_ver_found;
>>  	uint16_t minor_ver_found;
>>
>> +	uint32_t fw_type;
>
>Any reason why we use uint32_t instead of a named enum type here?

Maintains the uniformity of the struct intel_uc_fw...... every field is either uint32_t or uint16_t.

Anusha
>>  	uint32_t header_size;
>>  	uint32_t header_offset;
>>  	uint32_t rsa_size;
>> --
>> 2.7.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>--
>Cheers,
>Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
  2016-12-22 23:12 ` [PATCH 3/8] drm/i915/huc: Add HuC fw loading support Anusha Srivatsa
@ 2016-12-27 12:37   ` Arkadiusz Hiler
  2016-12-27 17:50   ` Michal Wajdeczko
  1 sibling, 0 replies; 50+ messages in thread
From: Arkadiusz Hiler @ 2016-12-27 12:37 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx

On Thu, Dec 22, 2016 at 03:12:19PM -0800, Anusha Srivatsa wrote:
> The HuC loading process is similar to GuC. The intel_uc_fw_fetch()
> is used for both cases.
> 
> HuC loading needs to be before GuC loading. The WOPCM setting must
> be done early before loading any of them.
> 
> v2: rebased on-top of drm-intel-nightly.
>     removed if(HAS_GUC()) before the guc call. (D.Gordon)
>     update huc_version number of format.
> v3: rebased to drm-intel-nightly, changed the file name format to
>     match the one in the huc package.
>     Changed dev->dev_private to to_i915()
> v4: moved function back to where it was.
>     change wait_for_atomic to wait_for.
> v5: rebased + comment changes.
> v7: rebased.
> v8: rebased.
> v9: rebased. Changed the year in the copyright message to reflect
> the right year.Correct the comments,remove the unwanted WARN message,
> replace drm_gem_object_unreference() with i915_gem_object_put().Make the
> prototypes in intel_huc.h non-extern.
> v10: rebased. Update the file construction done by HuC. It is similar to
> GuC.Adopted the approach used in-
> https://patchwork.freedesktop.org/patch/104355/ <Tvrtko Ursulin>
> v11: Fix warnings remove old declaration
> v12: Change dev to dev_priv in macro definition.
> Corrected comments.
> v13: rebased.
> v14: rebased on top of drm-tip
> v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
> intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
> of intel_huc.h to intel_uc.h
> v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to guc_wopcm_size().
> Remove unwanted checks in intel_uc.h. Rename huc_fw in struct intel_huc to
> simply fw to avoid redundency.
> v17: rebased.
> 
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general
  2016-12-22 23:12 ` [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general Anusha Srivatsa
  2016-12-23 14:15   ` Arkadiusz Hiler
@ 2016-12-27 17:28   ` Michal Wajdeczko
  2017-01-03  0:07     ` Srivatsa, Anusha
  1 sibling, 1 reply; 50+ messages in thread
From: Michal Wajdeczko @ 2016-12-27 17:28 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx, Alex Dai, Peter Antoine

On Thu, Dec 22, 2016 at 03:12:17PM -0800, Anusha Srivatsa wrote:
> From: Peter Antoine <peter.antoine@intel.com>
> 
> Rename some of the GuC fw loading code to make them more general. We
> will utilise them for HuC loading as well.
>      s/intel_guc_fw/intel_uc_fw/g
>      s/GUC_FIRMWARE/UC_FIRMWARE/g
> 
> Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts members,
> such as 'guc' or 'guc_fw' either is renamed to 'uc' or removed for
> same purpose.
> 
> v2: rebased on top of nightly.
>     reapplied the search/replace as upstream code as changed.
> v3: rebased again on drm-nightly.
> v4: removed G from messages in shared fw fetch function.
> v5: rebased.
> v7: rebased.
> v8: rebased.
> v9: rebased.
> v10: rebased.
> v11: rebased.
> v12: rebased on top of drm-tip
> v13: rebased.Updated dev to dev_priv in intel_guc_setup(), guc_fw_getch()
> and intel_guc_init().
> v14: rebased. Remove uint32_t fw_type to patch 2. Add INTEL_ prefix for
> fields in enum intel_uc_fw_status. Remove uc_dev field since its never
> used.Rename uc_fw to just fw and guc_fw to fw to avoid redundency.
> v15: rebased. Remove sections of code that were commented and no longer
> required.
> 
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c        |  12 +--
>  drivers/gpu/drm/i915/i915_guc_submission.c |   4 +-
>  drivers/gpu/drm/i915/intel_guc_loader.c    | 156 ++++++++++++++---------------
>  drivers/gpu/drm/i915/intel_uc.h            |  36 +++----
>  4 files changed, 104 insertions(+), 104 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index a5552a1..0a3c575 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2328,7 +2328,7 @@ static int i915_llc(struct seq_file *m, void *data)
>  static int i915_guc_load_status_info(struct seq_file *m, void *data)
>  {
>  	struct drm_i915_private *dev_priv = node_to_i915(m->private);
> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>  	u32 tmp, i;
>  
>  	if (!HAS_GUC_UCODE(dev_priv))
> @@ -2336,15 +2336,15 @@ static int i915_guc_load_status_info(struct seq_file *m, void *data)
>  
>  	seq_printf(m, "GuC firmware status:\n");
>  	seq_printf(m, "\tpath: %s\n",
> -		guc_fw->guc_fw_path);
> +		guc_fw->uc_fw_path);
>  	seq_printf(m, "\tfetch: %s\n",
> -		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
> +		intel_uc_fw_status_repr(guc_fw->fetch_status));
>  	seq_printf(m, "\tload: %s\n",
> -		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
> +		intel_uc_fw_status_repr(guc_fw->load_status));
>  	seq_printf(m, "\tversion wanted: %d.%d\n",
> -		guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
> +		guc_fw->major_ver_wanted, guc_fw->minor_ver_wanted);
>  	seq_printf(m, "\tversion found: %d.%d\n",
> -		guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found);
> +		guc_fw->major_ver_found, guc_fw->minor_ver_found);
>  	seq_printf(m, "\theader: offset is %d; size = %d\n",
>  		guc_fw->header_offset, guc_fw->header_size);
>  	seq_printf(m, "\tuCode: offset is %d; size = %d\n",
> diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
> index 3e20fe2..6e2d403 100644
> --- a/drivers/gpu/drm/i915/i915_guc_submission.c
> +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
> @@ -1484,7 +1484,7 @@ int intel_guc_suspend(struct drm_i915_private *dev_priv)
>  	struct i915_gem_context *ctx;
>  	u32 data[3];
>  
> -	if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
> +	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
>  		return 0;
>  
>  	gen9_disable_guc_interrupts(dev_priv);
> @@ -1511,7 +1511,7 @@ int intel_guc_resume(struct drm_i915_private *dev_priv)
>  	struct i915_gem_context *ctx;
>  	u32 data[3];
>  
> -	if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
> +	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
>  		return 0;
>  
>  	if (i915.guc_log_level >= 0)
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> index 21db697..ffe53dd7 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -81,16 +81,16 @@ MODULE_FIRMWARE(I915_BXT_GUC_UCODE);
>  MODULE_FIRMWARE(I915_KBL_GUC_UCODE);
>  
>  /* User-friendly representation of an enum */
> -const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status)
> +const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
>  {
>  	switch (status) {
> -	case GUC_FIRMWARE_FAIL:
> +	case INTEL_UC_FIRMWARE_FAIL:
>  		return "FAIL";
> -	case GUC_FIRMWARE_NONE:
> +	case INTEL_UC_FIRMWARE_NONE:
>  		return "NONE";
> -	case GUC_FIRMWARE_PENDING:
> +	case INTEL_UC_FIRMWARE_PENDING:
>  		return "PENDING";
> -	case GUC_FIRMWARE_SUCCESS:
> +	case INTEL_UC_FIRMWARE_SUCCESS:
>  		return "SUCCESS";
>  	default:
>  		return "UNKNOWN!";
> @@ -278,7 +278,7 @@ static inline bool guc_ucode_response(struct drm_i915_private *dev_priv,
>  static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
>  			      struct i915_vma *vma)
>  {
> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>  	unsigned long offset;
>  	struct sg_table *sg = vma->pages;
>  	u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT];
> @@ -350,17 +350,17 @@ static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
>   */
>  static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
>  {
> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>  	struct i915_vma *vma;
>  	int ret;
>  
> -	ret = i915_gem_object_set_to_gtt_domain(guc_fw->guc_fw_obj, false);
> +	ret = i915_gem_object_set_to_gtt_domain(guc_fw->uc_fw_obj, false);
>  	if (ret) {
>  		DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
>  		return ret;
>  	}
>  
> -	vma = i915_gem_object_ggtt_pin(guc_fw->guc_fw_obj, NULL, 0, 0, 0);
> +	vma = i915_gem_object_ggtt_pin(guc_fw->uc_fw_obj, NULL, 0, 0, 0);
>  	if (IS_ERR(vma)) {
>  		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
>  		return PTR_ERR(vma);
> @@ -450,14 +450,14 @@ static int guc_hw_reset(struct drm_i915_private *dev_priv)
>   */
>  int intel_guc_setup(struct drm_i915_private *dev_priv)
>  {
> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
> -	const char *fw_path = guc_fw->guc_fw_path;
> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
> +	const char *fw_path = guc_fw->uc_fw_path;
>  	int retries, ret, err;
>  
>  	DRM_DEBUG_DRIVER("GuC fw status: path %s, fetch %s, load %s\n",
>  		fw_path,
> -		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
> -		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
> +		intel_uc_fw_status_repr(guc_fw->fetch_status),
> +		intel_uc_fw_status_repr(guc_fw->load_status));
>  
>  	/* Loading forbidden, or no firmware to load? */
>  	if (!i915.enable_guc_loading) {
> @@ -475,10 +475,10 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>  	}
>  
>  	/* Fetch failed, or already fetched but failed to load? */
> -	if (guc_fw->guc_fw_fetch_status != GUC_FIRMWARE_SUCCESS) {
> +	if (guc_fw->fetch_status != INTEL_UC_FIRMWARE_SUCCESS) {
>  		err = -EIO;
>  		goto fail;
> -	} else if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_FAIL) {
> +	} else if (guc_fw->load_status == INTEL_UC_FIRMWARE_FAIL) {
>  		err = -ENOEXEC;
>  		goto fail;
>  	}
> @@ -486,11 +486,11 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>  	guc_interrupts_release(dev_priv);
>  	gen9_reset_guc_interrupts(dev_priv);
>  
> -	guc_fw->guc_fw_load_status = GUC_FIRMWARE_PENDING;
> +	guc_fw->load_status = INTEL_UC_FIRMWARE_PENDING;
>  
>  	DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
> -		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
> -		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
> +		intel_uc_fw_status_repr(guc_fw->fetch_status),
> +		intel_uc_fw_status_repr(guc_fw->load_status));
>  
>  	err = i915_guc_submission_init(dev_priv);
>  	if (err)
> @@ -522,11 +522,11 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>  			 "retry %d more time(s)\n", err, retries);
>  	}
>  
> -	guc_fw->guc_fw_load_status = GUC_FIRMWARE_SUCCESS;
> +	guc_fw->load_status = INTEL_UC_FIRMWARE_SUCCESS;
>  
>  	DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
> -		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
> -		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
> +		intel_uc_fw_status_repr(guc_fw->fetch_status),
> +		intel_uc_fw_status_repr(guc_fw->load_status));
>  
>  	if (i915.enable_guc_submission) {
>  		if (i915.guc_log_level >= 0)
> @@ -541,8 +541,8 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>  	return 0;
>  
>  fail:
> -	if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_PENDING)
> -		guc_fw->guc_fw_load_status = GUC_FIRMWARE_FAIL;
> +	if (guc_fw->load_status == INTEL_UC_FIRMWARE_PENDING)
> +		guc_fw->load_status = INTEL_UC_FIRMWARE_FAIL;
>  
>  	guc_interrupts_release(dev_priv);
>  	i915_guc_submission_disable(dev_priv);
> @@ -587,8 +587,8 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>  	return ret;
>  }
>  
> -static void guc_fw_fetch(struct drm_i915_private *dev_priv,
> -			 struct intel_guc_fw *guc_fw)
> +void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
> +			 struct intel_uc_fw *uc_fw)
>  {
>  	struct pci_dev *pdev = dev_priv->drm.pdev;
>  	struct drm_i915_gem_object *obj;
> @@ -597,17 +597,17 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
>  	size_t size;
>  	int err;
>  
> -	DRM_DEBUG_DRIVER("before requesting firmware: GuC fw fetch status %s\n",
> -		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
> +	DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status %s\n",
> +		intel_uc_fw_status_repr(uc_fw->fetch_status));
>  
> -	err = request_firmware(&fw, guc_fw->guc_fw_path, &pdev->dev);
> +	err = request_firmware(&fw, uc_fw->uc_fw_path, &pdev->dev);
>  	if (err)
>  		goto fail;
>  	if (!fw)
>  		goto fail;
>  
> -	DRM_DEBUG_DRIVER("fetch GuC fw from %s succeeded, fw %p\n",
> -		guc_fw->guc_fw_path, fw);
> +	DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n",
> +		uc_fw->uc_fw_path, fw);
>  
>  	/* Check the size of the blob before examining buffer contents */
>  	if (fw->size < sizeof(struct guc_css_header)) {
> @@ -618,36 +618,36 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
>  	css = (struct guc_css_header *)fw->data;
>  
>  	/* Firmware bits always start from header */
> -	guc_fw->header_offset = 0;
> -	guc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
> +	uc_fw->header_offset = 0;
> +	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
>  
> -	if (guc_fw->header_size != sizeof(struct guc_css_header)) {
> +	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
>  		DRM_NOTE("CSS header definition mismatch\n");
>  		goto fail;
>  	}
>  
>  	/* then, uCode */
> -	guc_fw->ucode_offset = guc_fw->header_offset + guc_fw->header_size;
> -	guc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
> +	uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
> +	uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
>  
>  	/* now RSA */
>  	if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
>  		DRM_NOTE("RSA key size is bad\n");
>  		goto fail;
>  	}
> -	guc_fw->rsa_offset = guc_fw->ucode_offset + guc_fw->ucode_size;
> -	guc_fw->rsa_size = css->key_size_dw * sizeof(u32);
> +	uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
> +	uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
>  
>  	/* At least, it should have header, uCode and RSA. Size of all three. */
> -	size = guc_fw->header_size + guc_fw->ucode_size + guc_fw->rsa_size;
> +	size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size;
>  	if (fw->size < size) {
>  		DRM_NOTE("Missing firmware components\n");
>  		goto fail;
>  	}
>  
>  	/* Header and uCode will be loaded to WOPCM. Size of the two. */
> -	size = guc_fw->header_size + guc_fw->ucode_size;
> +	size = uc_fw->header_size + uc_fw->ucode_size;
>  	if (size > guc_wopcm_size(dev_priv)) {
>  		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
>  		goto fail;
> @@ -659,21 +659,21 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
>  	 * in terms of bytes (u8).
>  	 */
> -	guc_fw->guc_fw_major_found = css->guc_sw_version >> 16;
> -	guc_fw->guc_fw_minor_found = css->guc_sw_version & 0xFFFF;
> -
> -	if (guc_fw->guc_fw_major_found != guc_fw->guc_fw_major_wanted ||
> -	    guc_fw->guc_fw_minor_found < guc_fw->guc_fw_minor_wanted) {
> -		DRM_NOTE("GuC firmware version %d.%d, required %d.%d\n",
> -			guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found,
> -			guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
> +	uc_fw->major_ver_found = css->guc_sw_version >> 16;
> +	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> +
> +	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
> +	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
> +		DRM_NOTE("uC firmware version %d.%d, required %d.%d\n",
> +			uc_fw->major_ver_found, uc_fw->minor_ver_found,
> +			uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
>  		err = -ENOEXEC;
>  		goto fail;
>  	}
>  
>  	DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n",
> -			guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found,
> -			guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
> +			uc_fw->major_ver_found, uc_fw->minor_ver_found,
> +			uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
>  
>  	mutex_lock(&dev_priv->drm.struct_mutex);
>  	obj = i915_gem_object_create_from_data(dev_priv, fw->data, fw->size);
> @@ -683,31 +683,31 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
>  		goto fail;
>  	}
>  
> -	guc_fw->guc_fw_obj = obj;
> -	guc_fw->guc_fw_size = fw->size;
> +	uc_fw->uc_fw_obj = obj;
> +	uc_fw->size = fw->size;
>  
> -	DRM_DEBUG_DRIVER("GuC fw fetch status SUCCESS, obj %p\n",
> -			guc_fw->guc_fw_obj);
> +	DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n",
> +			uc_fw->uc_fw_obj);
>  
>  	release_firmware(fw);
> -	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_SUCCESS;
> +	uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS;
>  	return;
>  
>  fail:
> -	DRM_WARN("Failed to fetch valid GuC firmware from %s (error %d)\n",
> -		 guc_fw->guc_fw_path, err);
> -	DRM_DEBUG_DRIVER("GuC fw fetch status FAIL; err %d, fw %p, obj %p\n",
> -		err, fw, guc_fw->guc_fw_obj);
> +	DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n",
> +		 uc_fw->uc_fw_path, err);
> +	DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj %p\n",
> +		err, fw, uc_fw->uc_fw_obj);
>  
>  	mutex_lock(&dev_priv->drm.struct_mutex);
> -	obj = guc_fw->guc_fw_obj;
> +	obj = uc_fw->uc_fw_obj;
>  	if (obj)
>  		i915_gem_object_put(obj);
> -	guc_fw->guc_fw_obj = NULL;
> +	uc_fw->uc_fw_obj = NULL;
>  	mutex_unlock(&dev_priv->drm.struct_mutex);
>  
>  	release_firmware(fw);		/* OK even if fw is NULL */
> -	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_FAIL;
> +	uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL;
>  }
>  
>  /**
> @@ -721,7 +721,7 @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
>   */
>  void intel_guc_init(struct drm_i915_private *dev_priv)
>  {
> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>  	const char *fw_path;
>  
>  	if (!HAS_GUC(dev_priv)) {
> @@ -739,23 +739,23 @@ void intel_guc_init(struct drm_i915_private *dev_priv)
>  		fw_path = NULL;
>  	} else if (IS_SKYLAKE(dev_priv)) {
>  		fw_path = I915_SKL_GUC_UCODE;
> -		guc_fw->guc_fw_major_wanted = SKL_FW_MAJOR;
> -		guc_fw->guc_fw_minor_wanted = SKL_FW_MINOR;
> +		guc_fw->major_ver_wanted = SKL_FW_MAJOR;
> +		guc_fw->minor_ver_wanted = SKL_FW_MINOR;
>  	} else if (IS_BROXTON(dev_priv)) {
>  		fw_path = I915_BXT_GUC_UCODE;
> -		guc_fw->guc_fw_major_wanted = BXT_FW_MAJOR;
> -		guc_fw->guc_fw_minor_wanted = BXT_FW_MINOR;
> +		guc_fw->major_ver_wanted = BXT_FW_MAJOR;
> +		guc_fw->minor_ver_wanted = BXT_FW_MINOR;
>  	} else if (IS_KABYLAKE(dev_priv)) {
>  		fw_path = I915_KBL_GUC_UCODE;
> -		guc_fw->guc_fw_major_wanted = KBL_FW_MAJOR;
> -		guc_fw->guc_fw_minor_wanted = KBL_FW_MINOR;
> +		guc_fw->major_ver_wanted = KBL_FW_MAJOR;
> +		guc_fw->minor_ver_wanted = KBL_FW_MINOR;
>  	} else {
>  		fw_path = "";	/* unknown device */
>  	}
>  
> -	guc_fw->guc_fw_path = fw_path;
> -	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_NONE;
> -	guc_fw->guc_fw_load_status = GUC_FIRMWARE_NONE;
> +	guc_fw->uc_fw_path = fw_path;
> +	guc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
> +	guc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
>  
>  	/* Early (and silent) return if GuC loading is disabled */
>  	if (!i915.enable_guc_loading)
> @@ -765,9 +765,9 @@ void intel_guc_init(struct drm_i915_private *dev_priv)
>  	if (*fw_path == '\0')
>  		return;
>  
> -	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_PENDING;
> +	guc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
>  	DRM_DEBUG_DRIVER("GuC firmware pending, path %s\n", fw_path);
> -	guc_fw_fetch(dev_priv, guc_fw);
> +	intel_uc_fw_fetch(dev_priv, guc_fw);
>  	/* status must now be FAIL or SUCCESS */
>  }
>  
> @@ -777,17 +777,17 @@ void intel_guc_init(struct drm_i915_private *dev_priv)
>   */
>  void intel_guc_fini(struct drm_i915_private *dev_priv)
>  {
> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>  
>  	mutex_lock(&dev_priv->drm.struct_mutex);
>  	guc_interrupts_release(dev_priv);
>  	i915_guc_submission_disable(dev_priv);
>  	i915_guc_submission_fini(dev_priv);
>  
> -	if (guc_fw->guc_fw_obj)
> -		i915_gem_object_put(guc_fw->guc_fw_obj);
> -	guc_fw->guc_fw_obj = NULL;
> +	if (guc_fw->uc_fw_obj)
> +		i915_gem_object_put(guc_fw->uc_fw_obj);
> +	guc_fw->uc_fw_obj = NULL;
>  	mutex_unlock(&dev_priv->drm.struct_mutex);
>  
> -	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_NONE;
> +	guc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
>  }
> diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
> index 11f5608..893bcec 100644
> --- a/drivers/gpu/drm/i915/intel_uc.h
> +++ b/drivers/gpu/drm/i915/intel_uc.h
> @@ -91,28 +91,28 @@ struct i915_guc_client {
>  	uint64_t submissions[I915_NUM_ENGINES];
>  };
>  
> -enum intel_guc_fw_status {
> -	GUC_FIRMWARE_FAIL = -1,
> -	GUC_FIRMWARE_NONE = 0,
> -	GUC_FIRMWARE_PENDING,
> -	GUC_FIRMWARE_SUCCESS
> +enum intel_uc_fw_status {
> +	INTEL_UC_FIRMWARE_FAIL = -1,
> +	INTEL_UC_FIRMWARE_NONE = 0,
> +	INTEL_UC_FIRMWARE_PENDING,
> +	INTEL_UC_FIRMWARE_SUCCESS
>  };
>  
>  /*
>   * This structure encapsulates all the data needed during the process
>   * of fetching, caching, and loading the firmware image into the GuC.
>   */
> -struct intel_guc_fw {
> -	const char *			guc_fw_path;
> -	size_t				guc_fw_size;
> -	struct drm_i915_gem_object *	guc_fw_obj;
> -	enum intel_guc_fw_status	guc_fw_fetch_status;
> -	enum intel_guc_fw_status	guc_fw_load_status;
> -
> -	uint16_t			guc_fw_major_wanted;
> -	uint16_t			guc_fw_minor_wanted;
> -	uint16_t			guc_fw_major_found;
> -	uint16_t			guc_fw_minor_found;
> +struct intel_uc_fw {
> +	const char *uc_fw_path;

Can we drop "uc_fw_" prefix also from path and obj members?

Michal

> +	size_t size;
> +	struct drm_i915_gem_object *uc_fw_obj;
> +	enum intel_uc_fw_status fetch_status;
> +	enum intel_uc_fw_status load_status;
> +
> +	uint16_t major_ver_wanted;
> +	uint16_t minor_ver_wanted;
> +	uint16_t major_ver_found;
> +	uint16_t minor_ver_found;
>  
>  	uint32_t header_size;
>  	uint32_t header_offset;
> @@ -139,7 +139,7 @@ struct intel_guc_log {
>  };
>  
>  struct intel_guc {
> -	struct intel_guc_fw guc_fw;
> +	struct intel_uc_fw fw;
>  	struct intel_guc_log log;
>  
>  	/* intel_guc_recv interrupt related state */
> @@ -181,7 +181,7 @@ int intel_guc_log_control(struct intel_guc *guc, u32 control_val);
>  extern void intel_guc_init(struct drm_i915_private *dev_priv);
>  extern int intel_guc_setup(struct drm_i915_private *dev_priv);
>  extern void intel_guc_fini(struct drm_i915_private *dev_priv);
> -extern const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status);
> +extern const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status);
>  extern int intel_guc_suspend(struct drm_i915_private *dev_priv);
>  extern int intel_guc_resume(struct drm_i915_private *dev_priv);
>  
> -- 
> 2.7.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
  2016-12-22 23:12 ` [PATCH 3/8] drm/i915/huc: Add HuC fw loading support Anusha Srivatsa
  2016-12-27 12:37   ` Arkadiusz Hiler
@ 2016-12-27 17:50   ` Michal Wajdeczko
  2017-01-03  0:08     ` Srivatsa, Anusha
  1 sibling, 1 reply; 50+ messages in thread
From: Michal Wajdeczko @ 2016-12-27 17:50 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx, Alex Dai, Peter Antoine

On Thu, Dec 22, 2016 at 03:12:19PM -0800, Anusha Srivatsa wrote:
> The HuC loading process is similar to GuC. The intel_uc_fw_fetch()
> is used for both cases.
> 
> HuC loading needs to be before GuC loading. The WOPCM setting must
> be done early before loading any of them.
> 
> v2: rebased on-top of drm-intel-nightly.
>     removed if(HAS_GUC()) before the guc call. (D.Gordon)
>     update huc_version number of format.
> v3: rebased to drm-intel-nightly, changed the file name format to
>     match the one in the huc package.
>     Changed dev->dev_private to to_i915()
> v4: moved function back to where it was.
>     change wait_for_atomic to wait_for.
> v5: rebased + comment changes.
> v7: rebased.
> v8: rebased.
> v9: rebased. Changed the year in the copyright message to reflect
> the right year.Correct the comments,remove the unwanted WARN message,
> replace drm_gem_object_unreference() with i915_gem_object_put().Make the
> prototypes in intel_huc.h non-extern.
> v10: rebased. Update the file construction done by HuC. It is similar to
> GuC.Adopted the approach used in-
> https://patchwork.freedesktop.org/patch/104355/ <Tvrtko Ursulin>
> v11: Fix warnings remove old declaration
> v12: Change dev to dev_priv in macro definition.
> Corrected comments.
> v13: rebased.
> v14: rebased on top of drm-tip
> v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
> intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
> of intel_huc.h to intel_uc.h
> v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to guc_wopcm_size().
> Remove unwanted checks in intel_uc.h. Rename huc_fw in struct intel_huc to
> simply fw to avoid redundency.
> v17: rebased.
> 
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> ---
>  drivers/gpu/drm/i915/Makefile           |   1 +
>  drivers/gpu/drm/i915/i915_drv.c         |   4 +-
>  drivers/gpu/drm/i915/i915_drv.h         |   3 +-
>  drivers/gpu/drm/i915/i915_guc_reg.h     |   3 +
>  drivers/gpu/drm/i915/intel_guc_loader.c |  11 +-
>  drivers/gpu/drm/i915/intel_huc_loader.c | 263 ++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_uc.h         |  18 +++
>  7 files changed, 296 insertions(+), 7 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 5196509..45ae124 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -57,6 +57,7 @@ i915-y += i915_cmd_parser.o \
>  # general-purpose microcontroller (GuC) support
>  i915-y += intel_uc.o \
>  	  intel_guc_loader.o \
> +	  intel_huc_loader.o \
>  	  i915_guc_submission.o
>  
>  # autogenerated null render state
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 6428588..85a47c2 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -600,6 +600,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
>  	if (ret)
>  		goto cleanup_irq;
>  
> +	intel_huc_init(dev_priv);
>  	intel_guc_init(dev_priv);
>  
>  	ret = i915_gem_init(dev_priv);
> @@ -627,6 +628,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
>  		DRM_ERROR("failed to idle hardware; continuing to unload!\n");
>  	i915_gem_fini(dev_priv);
>  cleanup_irq:
> +	intel_huc_fini(dev);
>  	intel_guc_fini(dev_priv);
>  	drm_irq_uninstall(dev);
>  	intel_teardown_gmbus(dev_priv);
> @@ -1313,7 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)
>  
>  	/* Flush any outstanding unpin_work. */
>  	drain_workqueue(dev_priv->wq);
> -
> +	intel_huc_fini(dev);
>  	intel_guc_fini(dev_priv);
>  	i915_gem_fini(dev_priv);
>  	intel_fbc_cleanup_cfb(dev_priv);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 1a91409..7ac7730 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2147,6 +2147,7 @@ struct drm_i915_private {
>  
>  	struct intel_gvt *gvt;
>  
> +	struct intel_huc huc;
>  	struct intel_guc guc;
>  
>  	struct intel_csr csr;
> @@ -2921,7 +2922,7 @@ intel_info(const struct drm_i915_private *dev_priv)
>  #define HAS_GUC(dev_priv)	((dev_priv)->info.has_guc)
>  #define HAS_GUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
>  #define HAS_GUC_SCHED(dev_priv)	(HAS_GUC(dev_priv))
> -
> +#define HAS_HUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
>  #define HAS_RESOURCE_STREAMER(dev_priv) ((dev_priv)->info.has_resource_streamer)
>  
>  #define HAS_POOLED_EU(dev_priv)	((dev_priv)->info.has_pooled_eu)
> diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h b/drivers/gpu/drm/i915/i915_guc_reg.h
> index 5e638fc..f9829f6 100644
> --- a/drivers/gpu/drm/i915/i915_guc_reg.h
> +++ b/drivers/gpu/drm/i915/i915_guc_reg.h
> @@ -61,9 +61,12 @@
>  #define   DMA_ADDRESS_SPACE_GTT		  (8 << 16)
>  #define DMA_COPY_SIZE			_MMIO(0xc310)
>  #define DMA_CTRL			_MMIO(0xc314)
> +#define   HUC_UKERNEL			  (1<<9)
>  #define   UOS_MOVE			  (1<<4)
>  #define   START_DMA			  (1<<0)
>  #define DMA_GUC_WOPCM_OFFSET		_MMIO(0xc340)
> +#define   HUC_LOADING_AGENT_VCR		  (0<<1)
> +#define   HUC_LOADING_AGENT_GUC		  (1<<1)
>  #define   GUC_WOPCM_OFFSET_VALUE	  0x80000	/* 512KB */
>  #define GUC_MAX_IDLE_COUNT		_MMIO(0xC3E4)
>  
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> index 06e3e5c..8c77e94 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -309,8 +309,8 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
>  	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
>  
>  	/* Finally start the DMA */
> -	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA));
> -
> +	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA) |
> +		_MASKED_BIT_DISABLE(HUC_UKERNEL));
>  	/*
>  	 * Wait for the DMA to complete & the GuC to start up.
>  	 * NB: Docs recommend not using the interrupt for completion.
> @@ -334,7 +334,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
>  	return ret;
>  }
>  
> -static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
> +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv)
>  {
>  	u32 wopcm_size = GUC_WOPCM_TOP;
>  
> @@ -372,7 +372,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
>  	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>  
>  	/* init WOPCM */
> -	I915_WRITE(GUC_WOPCM_SIZE, guc_wopcm_size(dev_priv));
> +	I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
>  	I915_WRITE(DMA_GUC_WOPCM_OFFSET, GUC_WOPCM_OFFSET_VALUE);
>  
>  	/* Enable MIA caching. GuC clock gating is disabled. */
> @@ -511,6 +511,7 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>  		if (err)
>  			goto fail;
>  
> +		intel_huc_load(dev_priv);
>  		err = guc_ucode_xfer(dev_priv);
>  		if (!err)
>  			break;
> @@ -658,7 +659,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>  		size = uc_fw->header_size + uc_fw->ucode_size;
>  
>  		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
> -		if (size > guc_wopcm_size(dev_priv)) {
> +		if (size > intel_guc_wopcm_size(dev_priv)) {
>  			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
>  			goto fail;
>  		}
> diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c b/drivers/gpu/drm/i915/intel_huc_loader.c
> new file mode 100644
> index 0000000..98d631c
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_huc_loader.c
> @@ -0,0 +1,263 @@
> +/*
> + * Copyright © 2016 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + */
> +#include <linux/firmware.h>
> +#include "i915_drv.h"
> +#include "intel_uc.h"
> +
> +/**
> + * DOC: HuC Firmware
> + *
> + * Motivation:
> + * GEN9 introduces a new dedicated firmware for usage in media HEVC (High
> + * Efficiency Video Coding) operations. Userspace can use the firmware
> + * capabilities by adding HuC specific commands to batch buffers.
> + *
> + * Implementation:
> + * The same firmware loader is used as the GuC. However, the actual
> + * loading to HW is deferred until GEM initialization is done.
> + *
> + * Note that HuC firmware loading must be done before GuC loading.
> + */
> +
> +#define SKL_HUC_FW_MAJOR 01
> +#define SKL_HUC_FW_MINOR 07
> +#define SKL_BLD_NUM 1398
> +
> +#define HUC_FW_PATH(platform, major, minor, bld_num) \
> +	"i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \
> +	__stringify(minor) "_" __stringify(bld_num) ".bin"
> +
> +#define I915_SKL_HUC_UCODE HUC_FW_PATH(skl, SKL_HUC_FW_MAJOR, \
> +	SKL_HUC_FW_MINOR, SKL_BLD_NUM)
> +MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
> +
> +/**
> + * huc_ucode_xfer() - DMA's the firmware
> + * @dev_priv: the drm device
> + *
> + * This function takes the gem object containing the firmware, sets up the DMA

Hmm, this function takes just dev_priv...


> + * engine MMIO, triggers the DMA operation and waits for it to finish.
> + *
> + * Transfer the firmware image to RAM for execution by the microcontroller.
> + *
> + * Return: 0 on success, non-zero on failure
> + */
> +static int huc_ucode_xfer(struct drm_i915_private *dev_priv)
> +{
> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
> +	struct i915_vma *vma;
> +	unsigned long offset = 0;
> +	u32 size;
> +	int ret;
> +
> +	ret = i915_gem_object_set_to_gtt_domain(huc_fw->uc_fw_obj, false);
> +	if (ret) {
> +		DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
> +		return ret;
> +	}
> +
> +	vma = i915_gem_object_ggtt_pin(huc_fw->uc_fw_obj, NULL, 0, 0, 0);
> +	if (IS_ERR(vma)) {
> +		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
> +		return PTR_ERR(vma);
> +	}
> +
> +	/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
> +	I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
> +
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
> +
> +	/* init WOPCM */
> +	I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
> +	I915_WRITE(DMA_GUC_WOPCM_OFFSET, GUC_WOPCM_OFFSET_VALUE |
> +			HUC_LOADING_AGENT_GUC);
> +
> +	/* Set the source address for the uCode */
> +	offset = i915_ggtt_offset(vma) + huc_fw->header_offset;
> +	I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
> +	I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
> +
> +	/* Hardware doesn't look at destination address for HuC. Set it to 0,
> +	 * but still program the correct address space.
> +	 */
> +	I915_WRITE(DMA_ADDR_1_LOW, 0);
> +	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
> +
> +	size = huc_fw->header_size + huc_fw->ucode_size;
> +	I915_WRITE(DMA_COPY_SIZE, size);
> +
> +	/* Start the DMA */
> +	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(HUC_UKERNEL | START_DMA));
> +
> +	/* Wait for DMA to finish */
> +	ret = wait_for((I915_READ(DMA_CTRL) & START_DMA) == 0, 100);
> +
> +	DRM_DEBUG_DRIVER("HuC DMA transfer wait over with ret %d\n", ret);
> +
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
> +
> +	/*
> +	 * We keep the object pages for reuse during resume. But we can unpin it
> +	 * now that DMA has completed, so it doesn't continue to take up space.
> +	 */
> +	i915_vma_unpin(vma);
> +
> +	return ret;
> +}
> +
> +/**
> + * intel_huc_init() - initiate HuC firmware loading request
> + * @dev_priv: the drm_i915_private device
> + *
> + * Called early during driver load, but after GEM is initialised. The loading
> + * will continue only when driver explicitly specify firmware name and version.
> + * All other cases are considered as INTEL_UC_FIRMWARE_NONE either because HW
> + * is not capable or driver yet support it. And there will be no error message
> + * for INTEL_UC_FIRMWARE_NONE cases.
> + *
> + * The DMA-copying to HW is done later when intel_huc_load() is called.
> + */
> +void intel_huc_init(struct drm_i915_private *dev_priv)
> +{
> +	struct intel_huc *huc = &dev_priv->huc;
> +	struct intel_uc_fw *huc_fw = &huc->fw;
> +	const char *fw_path = NULL;
> +
> +	huc_fw->uc_fw_path = NULL;
> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
> +	huc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
> +	huc_fw->fw_type = INTEL_UC_FW_TYPE_HUC;
> +
> +	if (!HAS_HUC_UCODE(dev_priv))
> +		return;
> +
> +	if (IS_SKYLAKE(dev_priv)) {
> +		fw_path = I915_SKL_HUC_UCODE;
> +		huc_fw->major_ver_wanted = SKL_HUC_FW_MAJOR;
> +		huc_fw->minor_ver_wanted = SKL_HUC_FW_MINOR;
> +	}
> +
> +	huc_fw->uc_fw_path = fw_path;
> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
> +
> +	DRM_DEBUG_DRIVER("HuC firmware pending, path %s\n", fw_path);
> +
> +	intel_uc_fw_fetch(dev_priv, huc_fw);
> +}
> +
> +/**
> + * intel_huc_load() - load HuC uCode to device
> + * @dev_priv: the drm_i915_private device
> + *
> + * Called from gem_init_hw() during driver loading and also after a GPU reset.
> + * Be note that HuC loading must be done before GuC loading.
> + *
> + * The firmware image should have already been fetched into memory by the
> + * earlier call to intel_huc_init(), so here we need only check that
> + * is succeeded, and then transfer the image to the h/w.
> + *
> + * Return:	non-zero code on error
> + */
> +int intel_huc_load(struct drm_i915_private *dev_priv)
> +{
> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
> +	int err;
> +
> +	if (huc_fw->fetch_status == INTEL_UC_FIRMWARE_NONE)
> +		return 0;
> +
> +	DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
> +		huc_fw->uc_fw_path,
> +		intel_uc_fw_status_repr(huc_fw->fetch_status),
> +		intel_uc_fw_status_repr(huc_fw->load_status));
> +
> +	if (huc_fw->fetch_status == INTEL_UC_FIRMWARE_SUCCESS &&
> +	    huc_fw->load_status == INTEL_UC_FIRMWARE_FAIL)
> +		return -ENOEXEC;
> +
> +	huc_fw->load_status = INTEL_UC_FIRMWARE_PENDING;
> +
> +	switch (huc_fw->fetch_status) {
> +	case INTEL_UC_FIRMWARE_FAIL:
> +		/* something went wrong :( */
> +		err = -EIO;
> +		goto fail;
> +
> +	case INTEL_UC_FIRMWARE_NONE:
> +	case INTEL_UC_FIRMWARE_PENDING:
> +	default:
> +		/* "can't happen" */
> +		WARN_ONCE(1, "HuC fw %s invalid fetch_status %s [%d]\n",
> +			huc_fw->uc_fw_path,
> +			intel_uc_fw_status_repr(huc_fw->fetch_status),
> +			huc_fw->fetch_status);
> +		err = -ENXIO;
> +		goto fail;
> +
> +	case INTEL_UC_FIRMWARE_SUCCESS:
> +		break;
> +	}
> +
> +	err = huc_ucode_xfer(dev_priv);
> +	if (err)
> +		goto fail;
> +
> +	huc_fw->load_status = INTEL_UC_FIRMWARE_SUCCESS;
> +
> +	DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
> +		huc_fw->uc_fw_path,
> +		intel_uc_fw_status_repr(huc_fw->fetch_status),
> +		intel_uc_fw_status_repr(huc_fw->load_status));

Hmm, this message will always display "fetch SUCCESS load SUCCESS"
as all other cases all handled as fail below... is it expected ? 

> +
> +	return 0;
> +
> +fail:
> +	if (huc_fw->load_status == INTEL_UC_FIRMWARE_PENDING)
> +		huc_fw->load_status = INTEL_UC_FIRMWARE_FAIL;
> +
> +	DRM_ERROR("Failed to complete HuC uCode load with ret %d\n", err);
> +
> +	return err;
> +}
> +
> +/**
> + * intel_huc_fini() - clean up resources allocated for HuC
> + * @dev: the drm device
> + *
> + * Cleans up by releasing the huc firmware GEM obj.
> + */
> +void intel_huc_fini(struct drm_device *dev)

Why this function takes dev? All other functions take dev_priv.

Michal

> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
> +
> +	mutex_lock(&dev->struct_mutex);
> +	if (huc_fw->uc_fw_obj)
> +		i915_gem_object_put(huc_fw->uc_fw_obj);
> +	huc_fw->uc_fw_obj = NULL;
> +	mutex_unlock(&dev->struct_mutex);
> +
> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
> +}
> +
> diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
> index ad140e2..57aef56 100644
> --- a/drivers/gpu/drm/i915/intel_uc.h
> +++ b/drivers/gpu/drm/i915/intel_uc.h
> @@ -24,6 +24,9 @@
>  #ifndef _INTEL_UC_H_
>  #define _INTEL_UC_H_
>  
> +#define HUC_STATUS2             _MMIO(0xD3B0)
> +#define   HUC_FW_VERIFIED       (1<<7)
> +
>  #include "intel_guc_fwif.h"
>  #include "i915_guc_reg.h"
>  #include "intel_ringbuffer.h"
> @@ -174,6 +177,13 @@ struct intel_guc {
>  	struct mutex send_mutex;
>  };
>  
> +struct intel_huc {
> +	/* Generic uC firmware management */
> +	struct intel_uc_fw fw;
> +
> +	/* HuC-specific additions */
> +};
> +
>  /* intel_uc.c */
>  void intel_uc_init_early(struct drm_i915_private *dev_priv);
>  bool intel_guc_recv(struct drm_i915_private *dev_priv, u32 *status);
> @@ -190,6 +200,9 @@ extern void intel_guc_fini(struct drm_i915_private *dev_priv);
>  extern const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status);
>  extern int intel_guc_suspend(struct drm_i915_private *dev_priv);
>  extern int intel_guc_resume(struct drm_i915_private *dev_priv);
> +void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
> +	struct intel_uc_fw *uc_fw);
> +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv);
>  
>  /* i915_guc_submission.c */
>  int i915_guc_submission_init(struct drm_i915_private *dev_priv);
> @@ -204,4 +217,9 @@ void i915_guc_register(struct drm_i915_private *dev_priv);
>  void i915_guc_unregister(struct drm_i915_private *dev_priv);
>  int i915_guc_log_control(struct drm_i915_private *dev_priv, u64 control_val);
>  
> +/* intel_huc_loader.c */
> +void intel_huc_init(struct drm_i915_private *dev_priv);
> +void intel_huc_fini(struct drm_device *dev);
> +int intel_huc_load(struct drm_i915_private *dev_priv);
> +
>  #endif
> -- 
> 2.7.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general
  2016-12-27 17:28   ` Michal Wajdeczko
@ 2017-01-03  0:07     ` Srivatsa, Anusha
  2017-01-03 14:15       ` Michal Wajdeczko
  0 siblings, 1 reply; 50+ messages in thread
From: Srivatsa, Anusha @ 2017-01-03  0:07 UTC (permalink / raw)
  To: Wajdeczko, Michal; +Cc: intel-gfx, Alex Dai, Peter Antoine



>-----Original Message-----
>From: Wajdeczko, Michal
>Sent: Tuesday, December 27, 2016 9:28 AM
>To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
>Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter Antoine
><peter.antoine@intel.com>
>Subject: Re: [Intel-gfx] [PATCH 1/8] drm/i915/guc: Make the GuC fw loading
>helper functions general
>
>On Thu, Dec 22, 2016 at 03:12:17PM -0800, Anusha Srivatsa wrote:
>> From: Peter Antoine <peter.antoine@intel.com>
>>
>> Rename some of the GuC fw loading code to make them more general. We
>> will utilise them for HuC loading as well.
>>      s/intel_guc_fw/intel_uc_fw/g
>>      s/GUC_FIRMWARE/UC_FIRMWARE/g
>>
>> Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts members,
>> such as 'guc' or 'guc_fw' either is renamed to 'uc' or removed for
>> same purpose.
>>
>> v2: rebased on top of nightly.
>>     reapplied the search/replace as upstream code as changed.
>> v3: rebased again on drm-nightly.
>> v4: removed G from messages in shared fw fetch function.
>> v5: rebased.
>> v7: rebased.
>> v8: rebased.
>> v9: rebased.
>> v10: rebased.
>> v11: rebased.
>> v12: rebased on top of drm-tip
>> v13: rebased.Updated dev to dev_priv in intel_guc_setup(),
>> guc_fw_getch() and intel_guc_init().
>> v14: rebased. Remove uint32_t fw_type to patch 2. Add INTEL_ prefix
>> for fields in enum intel_uc_fw_status. Remove uc_dev field since its
>> never used.Rename uc_fw to just fw and guc_fw to fw to avoid redundency.
>> v15: rebased. Remove sections of code that were commented and no
>> longer required.
>>
>> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
>> Signed-off-by: Alex Dai <yu.dai@intel.com>
>> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_debugfs.c        |  12 +--
>>  drivers/gpu/drm/i915/i915_guc_submission.c |   4 +-
>>  drivers/gpu/drm/i915/intel_guc_loader.c    | 156 ++++++++++++++---------------
>>  drivers/gpu/drm/i915/intel_uc.h            |  36 +++----
>>  4 files changed, 104 insertions(+), 104 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
>> b/drivers/gpu/drm/i915/i915_debugfs.c
>> index a5552a1..0a3c575 100644
>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>> @@ -2328,7 +2328,7 @@ static int i915_llc(struct seq_file *m, void
>> *data)  static int i915_guc_load_status_info(struct seq_file *m, void
>> *data)  {
>>  	struct drm_i915_private *dev_priv = node_to_i915(m->private);
>> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
>> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>>  	u32 tmp, i;
>>
>>  	if (!HAS_GUC_UCODE(dev_priv))
>> @@ -2336,15 +2336,15 @@ static int i915_guc_load_status_info(struct
>> seq_file *m, void *data)
>>
>>  	seq_printf(m, "GuC firmware status:\n");
>>  	seq_printf(m, "\tpath: %s\n",
>> -		guc_fw->guc_fw_path);
>> +		guc_fw->uc_fw_path);
>>  	seq_printf(m, "\tfetch: %s\n",
>> -		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
>> +		intel_uc_fw_status_repr(guc_fw->fetch_status));
>>  	seq_printf(m, "\tload: %s\n",
>> -		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
>> +		intel_uc_fw_status_repr(guc_fw->load_status));
>>  	seq_printf(m, "\tversion wanted: %d.%d\n",
>> -		guc_fw->guc_fw_major_wanted, guc_fw-
>>guc_fw_minor_wanted);
>> +		guc_fw->major_ver_wanted, guc_fw->minor_ver_wanted);
>>  	seq_printf(m, "\tversion found: %d.%d\n",
>> -		guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found);
>> +		guc_fw->major_ver_found, guc_fw->minor_ver_found);
>>  	seq_printf(m, "\theader: offset is %d; size = %d\n",
>>  		guc_fw->header_offset, guc_fw->header_size);
>>  	seq_printf(m, "\tuCode: offset is %d; size = %d\n", diff --git
>> a/drivers/gpu/drm/i915/i915_guc_submission.c
>> b/drivers/gpu/drm/i915/i915_guc_submission.c
>> index 3e20fe2..6e2d403 100644
>> --- a/drivers/gpu/drm/i915/i915_guc_submission.c
>> +++ b/drivers/gpu/drm/i915/i915_guc_submission.c
>> @@ -1484,7 +1484,7 @@ int intel_guc_suspend(struct drm_i915_private
>*dev_priv)
>>  	struct i915_gem_context *ctx;
>>  	u32 data[3];
>>
>> -	if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
>> +	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
>>  		return 0;
>>
>>  	gen9_disable_guc_interrupts(dev_priv);
>> @@ -1511,7 +1511,7 @@ int intel_guc_resume(struct drm_i915_private
>*dev_priv)
>>  	struct i915_gem_context *ctx;
>>  	u32 data[3];
>>
>> -	if (guc->guc_fw.guc_fw_load_status != GUC_FIRMWARE_SUCCESS)
>> +	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
>>  		return 0;
>>
>>  	if (i915.guc_log_level >= 0)
>> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c
>> b/drivers/gpu/drm/i915/intel_guc_loader.c
>> index 21db697..ffe53dd7 100644
>> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
>> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
>> @@ -81,16 +81,16 @@ MODULE_FIRMWARE(I915_BXT_GUC_UCODE);
>>  MODULE_FIRMWARE(I915_KBL_GUC_UCODE);
>>
>>  /* User-friendly representation of an enum */ -const char
>> *intel_guc_fw_status_repr(enum intel_guc_fw_status status)
>> +const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
>>  {
>>  	switch (status) {
>> -	case GUC_FIRMWARE_FAIL:
>> +	case INTEL_UC_FIRMWARE_FAIL:
>>  		return "FAIL";
>> -	case GUC_FIRMWARE_NONE:
>> +	case INTEL_UC_FIRMWARE_NONE:
>>  		return "NONE";
>> -	case GUC_FIRMWARE_PENDING:
>> +	case INTEL_UC_FIRMWARE_PENDING:
>>  		return "PENDING";
>> -	case GUC_FIRMWARE_SUCCESS:
>> +	case INTEL_UC_FIRMWARE_SUCCESS:
>>  		return "SUCCESS";
>>  	default:
>>  		return "UNKNOWN!";
>> @@ -278,7 +278,7 @@ static inline bool guc_ucode_response(struct
>> drm_i915_private *dev_priv,  static int guc_ucode_xfer_dma(struct
>drm_i915_private *dev_priv,
>>  			      struct i915_vma *vma)
>>  {
>> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
>> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>>  	unsigned long offset;
>>  	struct sg_table *sg = vma->pages;
>>  	u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT]; @@ -350,17 +350,17
>@@
>> static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
>>   */
>>  static int guc_ucode_xfer(struct drm_i915_private *dev_priv)  {
>> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
>> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>>  	struct i915_vma *vma;
>>  	int ret;
>>
>> -	ret = i915_gem_object_set_to_gtt_domain(guc_fw->guc_fw_obj, false);
>> +	ret = i915_gem_object_set_to_gtt_domain(guc_fw->uc_fw_obj, false);
>>  	if (ret) {
>>  		DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
>>  		return ret;
>>  	}
>>
>> -	vma = i915_gem_object_ggtt_pin(guc_fw->guc_fw_obj, NULL, 0, 0, 0);
>> +	vma = i915_gem_object_ggtt_pin(guc_fw->uc_fw_obj, NULL, 0, 0, 0);
>>  	if (IS_ERR(vma)) {
>>  		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
>>  		return PTR_ERR(vma);
>> @@ -450,14 +450,14 @@ static int guc_hw_reset(struct drm_i915_private
>*dev_priv)
>>   */
>>  int intel_guc_setup(struct drm_i915_private *dev_priv)  {
>> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
>> -	const char *fw_path = guc_fw->guc_fw_path;
>> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>> +	const char *fw_path = guc_fw->uc_fw_path;
>>  	int retries, ret, err;
>>
>>  	DRM_DEBUG_DRIVER("GuC fw status: path %s, fetch %s, load %s\n",
>>  		fw_path,
>> -		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
>> -		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
>> +		intel_uc_fw_status_repr(guc_fw->fetch_status),
>> +		intel_uc_fw_status_repr(guc_fw->load_status));
>>
>>  	/* Loading forbidden, or no firmware to load? */
>>  	if (!i915.enable_guc_loading) {
>> @@ -475,10 +475,10 @@ int intel_guc_setup(struct drm_i915_private
>*dev_priv)
>>  	}
>>
>>  	/* Fetch failed, or already fetched but failed to load? */
>> -	if (guc_fw->guc_fw_fetch_status != GUC_FIRMWARE_SUCCESS) {
>> +	if (guc_fw->fetch_status != INTEL_UC_FIRMWARE_SUCCESS) {
>>  		err = -EIO;
>>  		goto fail;
>> -	} else if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_FAIL) {
>> +	} else if (guc_fw->load_status == INTEL_UC_FIRMWARE_FAIL) {
>>  		err = -ENOEXEC;
>>  		goto fail;
>>  	}
>> @@ -486,11 +486,11 @@ int intel_guc_setup(struct drm_i915_private
>*dev_priv)
>>  	guc_interrupts_release(dev_priv);
>>  	gen9_reset_guc_interrupts(dev_priv);
>>
>> -	guc_fw->guc_fw_load_status = GUC_FIRMWARE_PENDING;
>> +	guc_fw->load_status = INTEL_UC_FIRMWARE_PENDING;
>>
>>  	DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
>> -		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
>> -		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
>> +		intel_uc_fw_status_repr(guc_fw->fetch_status),
>> +		intel_uc_fw_status_repr(guc_fw->load_status));
>>
>>  	err = i915_guc_submission_init(dev_priv);
>>  	if (err)
>> @@ -522,11 +522,11 @@ int intel_guc_setup(struct drm_i915_private
>*dev_priv)
>>  			 "retry %d more time(s)\n", err, retries);
>>  	}
>>
>> -	guc_fw->guc_fw_load_status = GUC_FIRMWARE_SUCCESS;
>> +	guc_fw->load_status = INTEL_UC_FIRMWARE_SUCCESS;
>>
>>  	DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
>> -		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status),
>> -		intel_guc_fw_status_repr(guc_fw->guc_fw_load_status));
>> +		intel_uc_fw_status_repr(guc_fw->fetch_status),
>> +		intel_uc_fw_status_repr(guc_fw->load_status));
>>
>>  	if (i915.enable_guc_submission) {
>>  		if (i915.guc_log_level >= 0)
>> @@ -541,8 +541,8 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>>  	return 0;
>>
>>  fail:
>> -	if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_PENDING)
>> -		guc_fw->guc_fw_load_status = GUC_FIRMWARE_FAIL;
>> +	if (guc_fw->load_status == INTEL_UC_FIRMWARE_PENDING)
>> +		guc_fw->load_status = INTEL_UC_FIRMWARE_FAIL;
>>
>>  	guc_interrupts_release(dev_priv);
>>  	i915_guc_submission_disable(dev_priv);
>> @@ -587,8 +587,8 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>>  	return ret;
>>  }
>>
>> -static void guc_fw_fetch(struct drm_i915_private *dev_priv,
>> -			 struct intel_guc_fw *guc_fw)
>> +void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>> +			 struct intel_uc_fw *uc_fw)
>>  {
>>  	struct pci_dev *pdev = dev_priv->drm.pdev;
>>  	struct drm_i915_gem_object *obj;
>> @@ -597,17 +597,17 @@ static void guc_fw_fetch(struct drm_i915_private
>*dev_priv,
>>  	size_t size;
>>  	int err;
>>
>> -	DRM_DEBUG_DRIVER("before requesting firmware: GuC fw fetch status
>%s\n",
>> -		intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
>> +	DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status
>%s\n",
>> +		intel_uc_fw_status_repr(uc_fw->fetch_status));
>>
>> -	err = request_firmware(&fw, guc_fw->guc_fw_path, &pdev->dev);
>> +	err = request_firmware(&fw, uc_fw->uc_fw_path, &pdev->dev);
>>  	if (err)
>>  		goto fail;
>>  	if (!fw)
>>  		goto fail;
>>
>> -	DRM_DEBUG_DRIVER("fetch GuC fw from %s succeeded, fw %p\n",
>> -		guc_fw->guc_fw_path, fw);
>> +	DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n",
>> +		uc_fw->uc_fw_path, fw);
>>
>>  	/* Check the size of the blob before examining buffer contents */
>>  	if (fw->size < sizeof(struct guc_css_header)) { @@ -618,36 +618,36
>> @@ static void guc_fw_fetch(struct drm_i915_private *dev_priv,
>>  	css = (struct guc_css_header *)fw->data;
>>
>>  	/* Firmware bits always start from header */
>> -	guc_fw->header_offset = 0;
>> -	guc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>> +	uc_fw->header_offset = 0;
>> +	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
>>
>> -	if (guc_fw->header_size != sizeof(struct guc_css_header)) {
>> +	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
>>  		DRM_NOTE("CSS header definition mismatch\n");
>>  		goto fail;
>>  	}
>>
>>  	/* then, uCode */
>> -	guc_fw->ucode_offset = guc_fw->header_offset + guc_fw->header_size;
>> -	guc_fw->ucode_size = (css->size_dw - css->header_size_dw) *
>sizeof(u32);
>> +	uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
>> +	uc_fw->ucode_size = (css->size_dw - css->header_size_dw) *
>> +sizeof(u32);
>>
>>  	/* now RSA */
>>  	if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
>>  		DRM_NOTE("RSA key size is bad\n");
>>  		goto fail;
>>  	}
>> -	guc_fw->rsa_offset = guc_fw->ucode_offset + guc_fw->ucode_size;
>> -	guc_fw->rsa_size = css->key_size_dw * sizeof(u32);
>> +	uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
>> +	uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
>>
>>  	/* At least, it should have header, uCode and RSA. Size of all three. */
>> -	size = guc_fw->header_size + guc_fw->ucode_size + guc_fw->rsa_size;
>> +	size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size;
>>  	if (fw->size < size) {
>>  		DRM_NOTE("Missing firmware components\n");
>>  		goto fail;
>>  	}
>>
>>  	/* Header and uCode will be loaded to WOPCM. Size of the two. */
>> -	size = guc_fw->header_size + guc_fw->ucode_size;
>> +	size = uc_fw->header_size + uc_fw->ucode_size;
>>  	if (size > guc_wopcm_size(dev_priv)) {
>>  		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
>>  		goto fail;
>> @@ -659,21 +659,21 @@ static void guc_fw_fetch(struct drm_i915_private
>*dev_priv,
>>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
>>  	 * in terms of bytes (u8).
>>  	 */
>> -	guc_fw->guc_fw_major_found = css->guc_sw_version >> 16;
>> -	guc_fw->guc_fw_minor_found = css->guc_sw_version & 0xFFFF;
>> -
>> -	if (guc_fw->guc_fw_major_found != guc_fw->guc_fw_major_wanted ||
>> -	    guc_fw->guc_fw_minor_found < guc_fw->guc_fw_minor_wanted) {
>> -		DRM_NOTE("GuC firmware version %d.%d, required %d.%d\n",
>> -			guc_fw->guc_fw_major_found, guc_fw-
>>guc_fw_minor_found,
>> -			guc_fw->guc_fw_major_wanted, guc_fw-
>>guc_fw_minor_wanted);
>> +	uc_fw->major_ver_found = css->guc_sw_version >> 16;
>> +	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
>> +
>> +	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>> +	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
>> +		DRM_NOTE("uC firmware version %d.%d, required %d.%d\n",
>> +			uc_fw->major_ver_found, uc_fw->minor_ver_found,
>> +			uc_fw->major_ver_wanted, uc_fw-
>>minor_ver_wanted);
>>  		err = -ENOEXEC;
>>  		goto fail;
>>  	}
>>
>>  	DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum
>%d.%d)\n",
>> -			guc_fw->guc_fw_major_found, guc_fw-
>>guc_fw_minor_found,
>> -			guc_fw->guc_fw_major_wanted, guc_fw-
>>guc_fw_minor_wanted);
>> +			uc_fw->major_ver_found, uc_fw->minor_ver_found,
>> +			uc_fw->major_ver_wanted, uc_fw-
>>minor_ver_wanted);
>>
>>  	mutex_lock(&dev_priv->drm.struct_mutex);
>>  	obj = i915_gem_object_create_from_data(dev_priv, fw->data,
>> fw->size); @@ -683,31 +683,31 @@ static void guc_fw_fetch(struct
>drm_i915_private *dev_priv,
>>  		goto fail;
>>  	}
>>
>> -	guc_fw->guc_fw_obj = obj;
>> -	guc_fw->guc_fw_size = fw->size;
>> +	uc_fw->uc_fw_obj = obj;
>> +	uc_fw->size = fw->size;
>>
>> -	DRM_DEBUG_DRIVER("GuC fw fetch status SUCCESS, obj %p\n",
>> -			guc_fw->guc_fw_obj);
>> +	DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n",
>> +			uc_fw->uc_fw_obj);
>>
>>  	release_firmware(fw);
>> -	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_SUCCESS;
>> +	uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS;
>>  	return;
>>
>>  fail:
>> -	DRM_WARN("Failed to fetch valid GuC firmware from %s (error %d)\n",
>> -		 guc_fw->guc_fw_path, err);
>> -	DRM_DEBUG_DRIVER("GuC fw fetch status FAIL; err %d, fw %p, obj
>%p\n",
>> -		err, fw, guc_fw->guc_fw_obj);
>> +	DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n",
>> +		 uc_fw->uc_fw_path, err);
>> +	DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj
>%p\n",
>> +		err, fw, uc_fw->uc_fw_obj);
>>
>>  	mutex_lock(&dev_priv->drm.struct_mutex);
>> -	obj = guc_fw->guc_fw_obj;
>> +	obj = uc_fw->uc_fw_obj;
>>  	if (obj)
>>  		i915_gem_object_put(obj);
>> -	guc_fw->guc_fw_obj = NULL;
>> +	uc_fw->uc_fw_obj = NULL;
>>  	mutex_unlock(&dev_priv->drm.struct_mutex);
>>
>>  	release_firmware(fw);		/* OK even if fw is NULL */
>> -	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_FAIL;
>> +	uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL;
>>  }
>>
>>  /**
>> @@ -721,7 +721,7 @@ static void guc_fw_fetch(struct drm_i915_private
>*dev_priv,
>>   */
>>  void intel_guc_init(struct drm_i915_private *dev_priv)  {
>> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
>> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>>  	const char *fw_path;
>>
>>  	if (!HAS_GUC(dev_priv)) {
>> @@ -739,23 +739,23 @@ void intel_guc_init(struct drm_i915_private
>*dev_priv)
>>  		fw_path = NULL;
>>  	} else if (IS_SKYLAKE(dev_priv)) {
>>  		fw_path = I915_SKL_GUC_UCODE;
>> -		guc_fw->guc_fw_major_wanted = SKL_FW_MAJOR;
>> -		guc_fw->guc_fw_minor_wanted = SKL_FW_MINOR;
>> +		guc_fw->major_ver_wanted = SKL_FW_MAJOR;
>> +		guc_fw->minor_ver_wanted = SKL_FW_MINOR;
>>  	} else if (IS_BROXTON(dev_priv)) {
>>  		fw_path = I915_BXT_GUC_UCODE;
>> -		guc_fw->guc_fw_major_wanted = BXT_FW_MAJOR;
>> -		guc_fw->guc_fw_minor_wanted = BXT_FW_MINOR;
>> +		guc_fw->major_ver_wanted = BXT_FW_MAJOR;
>> +		guc_fw->minor_ver_wanted = BXT_FW_MINOR;
>>  	} else if (IS_KABYLAKE(dev_priv)) {
>>  		fw_path = I915_KBL_GUC_UCODE;
>> -		guc_fw->guc_fw_major_wanted = KBL_FW_MAJOR;
>> -		guc_fw->guc_fw_minor_wanted = KBL_FW_MINOR;
>> +		guc_fw->major_ver_wanted = KBL_FW_MAJOR;
>> +		guc_fw->minor_ver_wanted = KBL_FW_MINOR;
>>  	} else {
>>  		fw_path = "";	/* unknown device */
>>  	}
>>
>> -	guc_fw->guc_fw_path = fw_path;
>> -	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_NONE;
>> -	guc_fw->guc_fw_load_status = GUC_FIRMWARE_NONE;
>> +	guc_fw->uc_fw_path = fw_path;
>> +	guc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
>> +	guc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
>>
>>  	/* Early (and silent) return if GuC loading is disabled */
>>  	if (!i915.enable_guc_loading)
>> @@ -765,9 +765,9 @@ void intel_guc_init(struct drm_i915_private *dev_priv)
>>  	if (*fw_path == '\0')
>>  		return;
>>
>> -	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_PENDING;
>> +	guc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
>>  	DRM_DEBUG_DRIVER("GuC firmware pending, path %s\n", fw_path);
>> -	guc_fw_fetch(dev_priv, guc_fw);
>> +	intel_uc_fw_fetch(dev_priv, guc_fw);
>>  	/* status must now be FAIL or SUCCESS */  }
>>
>> @@ -777,17 +777,17 @@ void intel_guc_init(struct drm_i915_private
>*dev_priv)
>>   */
>>  void intel_guc_fini(struct drm_i915_private *dev_priv)  {
>> -	struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
>> +	struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
>>
>>  	mutex_lock(&dev_priv->drm.struct_mutex);
>>  	guc_interrupts_release(dev_priv);
>>  	i915_guc_submission_disable(dev_priv);
>>  	i915_guc_submission_fini(dev_priv);
>>
>> -	if (guc_fw->guc_fw_obj)
>> -		i915_gem_object_put(guc_fw->guc_fw_obj);
>> -	guc_fw->guc_fw_obj = NULL;
>> +	if (guc_fw->uc_fw_obj)
>> +		i915_gem_object_put(guc_fw->uc_fw_obj);
>> +	guc_fw->uc_fw_obj = NULL;
>>  	mutex_unlock(&dev_priv->drm.struct_mutex);
>>
>> -	guc_fw->guc_fw_fetch_status = GUC_FIRMWARE_NONE;
>> +	guc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
>>  }
>> diff --git a/drivers/gpu/drm/i915/intel_uc.h
>> b/drivers/gpu/drm/i915/intel_uc.h index 11f5608..893bcec 100644
>> --- a/drivers/gpu/drm/i915/intel_uc.h
>> +++ b/drivers/gpu/drm/i915/intel_uc.h
>> @@ -91,28 +91,28 @@ struct i915_guc_client {
>>  	uint64_t submissions[I915_NUM_ENGINES];  };
>>
>> -enum intel_guc_fw_status {
>> -	GUC_FIRMWARE_FAIL = -1,
>> -	GUC_FIRMWARE_NONE = 0,
>> -	GUC_FIRMWARE_PENDING,
>> -	GUC_FIRMWARE_SUCCESS
>> +enum intel_uc_fw_status {
>> +	INTEL_UC_FIRMWARE_FAIL = -1,
>> +	INTEL_UC_FIRMWARE_NONE = 0,
>> +	INTEL_UC_FIRMWARE_PENDING,
>> +	INTEL_UC_FIRMWARE_SUCCESS
>>  };
>>
>>  /*
>>   * This structure encapsulates all the data needed during the process
>>   * of fetching, caching, and loading the firmware image into the GuC.
>>   */
>> -struct intel_guc_fw {
>> -	const char *			guc_fw_path;
>> -	size_t				guc_fw_size;
>> -	struct drm_i915_gem_object *	guc_fw_obj;
>> -	enum intel_guc_fw_status	guc_fw_fetch_status;
>> -	enum intel_guc_fw_status	guc_fw_load_status;
>> -
>> -	uint16_t			guc_fw_major_wanted;
>> -	uint16_t			guc_fw_minor_wanted;
>> -	uint16_t			guc_fw_major_found;
>> -	uint16_t			guc_fw_minor_found;
>> +struct intel_uc_fw {
>> +	const char *uc_fw_path;
>
>Can we drop "uc_fw_" prefix also from path and obj members?

Michal, you think we can do this change as a part of the guc refactor effort which will happen post this series gets merged? Or do you feel its makes more sense to that we have this change in this series....

Anusha
>Michal
>
>> +	size_t size;
>> +	struct drm_i915_gem_object *uc_fw_obj;
>> +	enum intel_uc_fw_status fetch_status;
>> +	enum intel_uc_fw_status load_status;
>> +
>> +	uint16_t major_ver_wanted;
>> +	uint16_t minor_ver_wanted;
>> +	uint16_t major_ver_found;
>> +	uint16_t minor_ver_found;
>>
>>  	uint32_t header_size;
>>  	uint32_t header_offset;
>> @@ -139,7 +139,7 @@ struct intel_guc_log {  };
>>
>>  struct intel_guc {
>> -	struct intel_guc_fw guc_fw;
>> +	struct intel_uc_fw fw;
>>  	struct intel_guc_log log;
>>
>>  	/* intel_guc_recv interrupt related state */ @@ -181,7 +181,7 @@ int
>> intel_guc_log_control(struct intel_guc *guc, u32 control_val);  extern
>> void intel_guc_init(struct drm_i915_private *dev_priv);  extern int
>> intel_guc_setup(struct drm_i915_private *dev_priv);  extern void
>> intel_guc_fini(struct drm_i915_private *dev_priv); -extern const char
>> *intel_guc_fw_status_repr(enum intel_guc_fw_status status);
>> +extern const char *intel_uc_fw_status_repr(enum intel_uc_fw_status
>> +status);
>>  extern int intel_guc_suspend(struct drm_i915_private *dev_priv);
>> extern int intel_guc_resume(struct drm_i915_private *dev_priv);
>>
>> --
>> 2.7.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
  2016-12-27 17:50   ` Michal Wajdeczko
@ 2017-01-03  0:08     ` Srivatsa, Anusha
  2017-01-03 18:59       ` Srivatsa, Anusha
  0 siblings, 1 reply; 50+ messages in thread
From: Srivatsa, Anusha @ 2017-01-03  0:08 UTC (permalink / raw)
  To: Wajdeczko, Michal; +Cc: intel-gfx, Alex Dai, Peter Antoine



>-----Original Message-----
>From: Wajdeczko, Michal
>Sent: Tuesday, December 27, 2016 9:51 AM
>To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
>Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter Antoine
><peter.antoine@intel.com>
>Subject: Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
>
>On Thu, Dec 22, 2016 at 03:12:19PM -0800, Anusha Srivatsa wrote:
>> The HuC loading process is similar to GuC. The intel_uc_fw_fetch() is
>> used for both cases.
>>
>> HuC loading needs to be before GuC loading. The WOPCM setting must be
>> done early before loading any of them.
>>
>> v2: rebased on-top of drm-intel-nightly.
>>     removed if(HAS_GUC()) before the guc call. (D.Gordon)
>>     update huc_version number of format.
>> v3: rebased to drm-intel-nightly, changed the file name format to
>>     match the one in the huc package.
>>     Changed dev->dev_private to to_i915()
>> v4: moved function back to where it was.
>>     change wait_for_atomic to wait_for.
>> v5: rebased + comment changes.
>> v7: rebased.
>> v8: rebased.
>> v9: rebased. Changed the year in the copyright message to reflect the
>> right year.Correct the comments,remove the unwanted WARN message,
>> replace drm_gem_object_unreference() with i915_gem_object_put().Make
>> the prototypes in intel_huc.h non-extern.
>> v10: rebased. Update the file construction done by HuC. It is similar
>> to GuC.Adopted the approach used in-
>> https://patchwork.freedesktop.org/patch/104355/ <Tvrtko Ursulin>
>> v11: Fix warnings remove old declaration
>> v12: Change dev to dev_priv in macro definition.
>> Corrected comments.
>> v13: rebased.
>> v14: rebased on top of drm-tip
>> v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
>> intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
>> of intel_huc.h to intel_uc.h
>> v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to
>guc_wopcm_size().
>> Remove unwanted checks in intel_uc.h. Rename huc_fw in struct
>> intel_huc to simply fw to avoid redundency.
>> v17: rebased.
>>
>> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
>> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
>> Signed-off-by: Alex Dai <yu.dai@intel.com>
>> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
>> ---
>>  drivers/gpu/drm/i915/Makefile           |   1 +
>>  drivers/gpu/drm/i915/i915_drv.c         |   4 +-
>>  drivers/gpu/drm/i915/i915_drv.h         |   3 +-
>>  drivers/gpu/drm/i915/i915_guc_reg.h     |   3 +
>>  drivers/gpu/drm/i915/intel_guc_loader.c |  11 +-
>> drivers/gpu/drm/i915/intel_huc_loader.c | 263
>++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_uc.h         |  18 +++
>>  7 files changed, 296 insertions(+), 7 deletions(-)  create mode
>> 100644 drivers/gpu/drm/i915/intel_huc_loader.c
>>
>> diff --git a/drivers/gpu/drm/i915/Makefile
>> b/drivers/gpu/drm/i915/Makefile index 5196509..45ae124 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -57,6 +57,7 @@ i915-y += i915_cmd_parser.o \  # general-purpose
>> microcontroller (GuC) support  i915-y += intel_uc.o \
>>  	  intel_guc_loader.o \
>> +	  intel_huc_loader.o \
>>  	  i915_guc_submission.o
>>
>>  # autogenerated null render state
>> diff --git a/drivers/gpu/drm/i915/i915_drv.c
>> b/drivers/gpu/drm/i915/i915_drv.c index 6428588..85a47c2 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.c
>> +++ b/drivers/gpu/drm/i915/i915_drv.c
>> @@ -600,6 +600,7 @@ static int i915_load_modeset_init(struct drm_device
>*dev)
>>  	if (ret)
>>  		goto cleanup_irq;
>>
>> +	intel_huc_init(dev_priv);
>>  	intel_guc_init(dev_priv);
>>
>>  	ret = i915_gem_init(dev_priv);
>> @@ -627,6 +628,7 @@ static int i915_load_modeset_init(struct drm_device
>*dev)
>>  		DRM_ERROR("failed to idle hardware; continuing to unload!\n");
>>  	i915_gem_fini(dev_priv);
>>  cleanup_irq:
>> +	intel_huc_fini(dev);
>>  	intel_guc_fini(dev_priv);
>>  	drm_irq_uninstall(dev);
>>  	intel_teardown_gmbus(dev_priv);
>> @@ -1313,7 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)
>>
>>  	/* Flush any outstanding unpin_work. */
>>  	drain_workqueue(dev_priv->wq);
>> -
>> +	intel_huc_fini(dev);
>>  	intel_guc_fini(dev_priv);
>>  	i915_gem_fini(dev_priv);
>>  	intel_fbc_cleanup_cfb(dev_priv);
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
>> b/drivers/gpu/drm/i915/i915_drv.h index 1a91409..7ac7730 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -2147,6 +2147,7 @@ struct drm_i915_private {
>>
>>  	struct intel_gvt *gvt;
>>
>> +	struct intel_huc huc;
>>  	struct intel_guc guc;
>>
>>  	struct intel_csr csr;
>> @@ -2921,7 +2922,7 @@ intel_info(const struct drm_i915_private *dev_priv)
>>  #define HAS_GUC(dev_priv)	((dev_priv)->info.has_guc)
>>  #define HAS_GUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
>>  #define HAS_GUC_SCHED(dev_priv)	(HAS_GUC(dev_priv))
>> -
>> +#define HAS_HUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
>>  #define HAS_RESOURCE_STREAMER(dev_priv)
>> ((dev_priv)->info.has_resource_streamer)
>>
>>  #define HAS_POOLED_EU(dev_priv)	((dev_priv)->info.has_pooled_eu)
>> diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h
>> b/drivers/gpu/drm/i915/i915_guc_reg.h
>> index 5e638fc..f9829f6 100644
>> --- a/drivers/gpu/drm/i915/i915_guc_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_guc_reg.h
>> @@ -61,9 +61,12 @@
>>  #define   DMA_ADDRESS_SPACE_GTT		  (8 << 16)
>>  #define DMA_COPY_SIZE			_MMIO(0xc310)
>>  #define DMA_CTRL			_MMIO(0xc314)
>> +#define   HUC_UKERNEL			  (1<<9)
>>  #define   UOS_MOVE			  (1<<4)
>>  #define   START_DMA			  (1<<0)
>>  #define DMA_GUC_WOPCM_OFFSET		_MMIO(0xc340)
>> +#define   HUC_LOADING_AGENT_VCR		  (0<<1)
>> +#define   HUC_LOADING_AGENT_GUC		  (1<<1)
>>  #define   GUC_WOPCM_OFFSET_VALUE	  0x80000	/* 512KB */
>>  #define GUC_MAX_IDLE_COUNT		_MMIO(0xC3E4)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c
>> b/drivers/gpu/drm/i915/intel_guc_loader.c
>> index 06e3e5c..8c77e94 100644
>> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
>> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
>> @@ -309,8 +309,8 @@ static int guc_ucode_xfer_dma(struct drm_i915_private
>*dev_priv,
>>  	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
>>
>>  	/* Finally start the DMA */
>> -	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE |
>START_DMA));
>> -
>> +	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE |
>START_DMA) |
>> +		_MASKED_BIT_DISABLE(HUC_UKERNEL));
>>  	/*
>>  	 * Wait for the DMA to complete & the GuC to start up.
>>  	 * NB: Docs recommend not using the interrupt for completion.
>> @@ -334,7 +334,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private
>*dev_priv,
>>  	return ret;
>>  }
>>
>> -static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
>> +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv)
>>  {
>>  	u32 wopcm_size = GUC_WOPCM_TOP;
>>
>> @@ -372,7 +372,7 @@ static int guc_ucode_xfer(struct drm_i915_private
>*dev_priv)
>>  	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>>
>>  	/* init WOPCM */
>> -	I915_WRITE(GUC_WOPCM_SIZE, guc_wopcm_size(dev_priv));
>> +	I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
>>  	I915_WRITE(DMA_GUC_WOPCM_OFFSET,
>GUC_WOPCM_OFFSET_VALUE);
>>
>>  	/* Enable MIA caching. GuC clock gating is disabled. */ @@ -511,6
>> +511,7 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>>  		if (err)
>>  			goto fail;
>>
>> +		intel_huc_load(dev_priv);
>>  		err = guc_ucode_xfer(dev_priv);
>>  		if (!err)
>>  			break;
>> @@ -658,7 +659,7 @@ void intel_uc_fw_fetch(struct drm_i915_private
>*dev_priv,
>>  		size = uc_fw->header_size + uc_fw->ucode_size;
>>
>>  		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context).
>*/
>> -		if (size > guc_wopcm_size(dev_priv)) {
>> +		if (size > intel_guc_wopcm_size(dev_priv)) {
>>  			DRM_ERROR("Firmware is too large to fit in
>WOPCM\n");
>>  			goto fail;
>>  		}
>> diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c
>> b/drivers/gpu/drm/i915/intel_huc_loader.c
>> new file mode 100644
>> index 0000000..98d631c
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/intel_huc_loader.c
>> @@ -0,0 +1,263 @@
>> +/*
>> + * Copyright (c) 2016 Intel Corporation
>> + *
>> + * Permission is hereby granted, free of charge, to any person
>> +obtaining a
>> + * copy of this software and associated documentation files (the
>> +"Software"),
>> + * to deal in the Software without restriction, including without
>> +limitation
>> + * the rights to use, copy, modify, merge, publish, distribute,
>> +sublicense,
>> + * and/or sell copies of the Software, and to permit persons to whom
>> +the
>> + * Software is furnished to do so, subject to the following conditions:
>> + *
>> + * The above copyright notice and this permission notice (including
>> +the next
>> + * paragraph) shall be included in all copies or substantial portions
>> +of the
>> + * Software.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> +EXPRESS OR
>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>> +MERCHANTABILITY,
>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO
>EVENT
>> +SHALL
>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
>DAMAGES
>> +OR OTHER
>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
>> +ARISING
>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>> +OTHER DEALINGS
>> + * IN THE SOFTWARE.
>> + *
>> + */
>> +#include <linux/firmware.h>
>> +#include "i915_drv.h"
>> +#include "intel_uc.h"
>> +
>> +/**
>> + * DOC: HuC Firmware
>> + *
>> + * Motivation:
>> + * GEN9 introduces a new dedicated firmware for usage in media HEVC
>> +(High
>> + * Efficiency Video Coding) operations. Userspace can use the
>> +firmware
>> + * capabilities by adding HuC specific commands to batch buffers.
>> + *
>> + * Implementation:
>> + * The same firmware loader is used as the GuC. However, the actual
>> + * loading to HW is deferred until GEM initialization is done.
>> + *
>> + * Note that HuC firmware loading must be done before GuC loading.
>> + */
>> +
>> +#define SKL_HUC_FW_MAJOR 01
>> +#define SKL_HUC_FW_MINOR 07
>> +#define SKL_BLD_NUM 1398
>> +
>> +#define HUC_FW_PATH(platform, major, minor, bld_num) \
>> +	"i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \
>> +	__stringify(minor) "_" __stringify(bld_num) ".bin"
>> +
>> +#define I915_SKL_HUC_UCODE HUC_FW_PATH(skl, SKL_HUC_FW_MAJOR, \
>> +	SKL_HUC_FW_MINOR, SKL_BLD_NUM)
>> +MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
>> +
>> +/**
>> + * huc_ucode_xfer() - DMA's the firmware
>> + * @dev_priv: the drm device
>> + *
>> + * This function takes the gem object containing the firmware, sets
>> +up the DMA
>
>Hmm, this function takes just dev_priv...

Oops.... will change the comment.

Anusha
>
>> + * engine MMIO, triggers the DMA operation and waits for it to finish.
>> + *
>> + * Transfer the firmware image to RAM for execution by the microcontroller.
>> + *
>> + * Return: 0 on success, non-zero on failure  */ static int
>> +huc_ucode_xfer(struct drm_i915_private *dev_priv) {
>> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
>> +	struct i915_vma *vma;
>> +	unsigned long offset = 0;
>> +	u32 size;
>> +	int ret;
>> +
>> +	ret = i915_gem_object_set_to_gtt_domain(huc_fw->uc_fw_obj, false);
>> +	if (ret) {
>> +		DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	vma = i915_gem_object_ggtt_pin(huc_fw->uc_fw_obj, NULL, 0, 0, 0);
>> +	if (IS_ERR(vma)) {
>> +		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
>> +		return PTR_ERR(vma);
>> +	}
>> +
>> +	/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
>> +	I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
>> +
>> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>> +
>> +	/* init WOPCM */
>> +	I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
>> +	I915_WRITE(DMA_GUC_WOPCM_OFFSET,
>GUC_WOPCM_OFFSET_VALUE |
>> +			HUC_LOADING_AGENT_GUC);
>> +
>> +	/* Set the source address for the uCode */
>> +	offset = i915_ggtt_offset(vma) + huc_fw->header_offset;
>> +	I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
>> +	I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
>> +
>> +	/* Hardware doesn't look at destination address for HuC. Set it to 0,
>> +	 * but still program the correct address space.
>> +	 */
>> +	I915_WRITE(DMA_ADDR_1_LOW, 0);
>> +	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
>> +
>> +	size = huc_fw->header_size + huc_fw->ucode_size;
>> +	I915_WRITE(DMA_COPY_SIZE, size);
>> +
>> +	/* Start the DMA */
>> +	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(HUC_UKERNEL |
>START_DMA));
>> +
>> +	/* Wait for DMA to finish */
>> +	ret = wait_for((I915_READ(DMA_CTRL) & START_DMA) == 0, 100);
>> +
>> +	DRM_DEBUG_DRIVER("HuC DMA transfer wait over with ret %d\n", ret);
>> +
>> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>> +
>> +	/*
>> +	 * We keep the object pages for reuse during resume. But we can unpin it
>> +	 * now that DMA has completed, so it doesn't continue to take up space.
>> +	 */
>> +	i915_vma_unpin(vma);
>> +
>> +	return ret;
>> +}
>> +
>> +/**
>> + * intel_huc_init() - initiate HuC firmware loading request
>> + * @dev_priv: the drm_i915_private device
>> + *
>> + * Called early during driver load, but after GEM is initialised. The
>> +loading
>> + * will continue only when driver explicitly specify firmware name and version.
>> + * All other cases are considered as INTEL_UC_FIRMWARE_NONE either
>> +because HW
>> + * is not capable or driver yet support it. And there will be no
>> +error message
>> + * for INTEL_UC_FIRMWARE_NONE cases.
>> + *
>> + * The DMA-copying to HW is done later when intel_huc_load() is called.
>> + */
>> +void intel_huc_init(struct drm_i915_private *dev_priv) {
>> +	struct intel_huc *huc = &dev_priv->huc;
>> +	struct intel_uc_fw *huc_fw = &huc->fw;
>> +	const char *fw_path = NULL;
>> +
>> +	huc_fw->uc_fw_path = NULL;
>> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
>> +	huc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
>> +	huc_fw->fw_type = INTEL_UC_FW_TYPE_HUC;
>> +
>> +	if (!HAS_HUC_UCODE(dev_priv))
>> +		return;
>> +
>> +	if (IS_SKYLAKE(dev_priv)) {
>> +		fw_path = I915_SKL_HUC_UCODE;
>> +		huc_fw->major_ver_wanted = SKL_HUC_FW_MAJOR;
>> +		huc_fw->minor_ver_wanted = SKL_HUC_FW_MINOR;
>> +	}
>> +
>> +	huc_fw->uc_fw_path = fw_path;
>> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
>> +
>> +	DRM_DEBUG_DRIVER("HuC firmware pending, path %s\n", fw_path);
>> +
>> +	intel_uc_fw_fetch(dev_priv, huc_fw); }
>> +
>> +/**
>> + * intel_huc_load() - load HuC uCode to device
>> + * @dev_priv: the drm_i915_private device
>> + *
>> + * Called from gem_init_hw() during driver loading and also after a GPU reset.
>> + * Be note that HuC loading must be done before GuC loading.
>> + *
>> + * The firmware image should have already been fetched into memory by
>> +the
>> + * earlier call to intel_huc_init(), so here we need only check that
>> + * is succeeded, and then transfer the image to the h/w.
>> + *
>> + * Return:	non-zero code on error
>> + */
>> +int intel_huc_load(struct drm_i915_private *dev_priv) {
>> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
>> +	int err;
>> +
>> +	if (huc_fw->fetch_status == INTEL_UC_FIRMWARE_NONE)
>> +		return 0;
>> +
>> +	DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
>> +		huc_fw->uc_fw_path,
>> +		intel_uc_fw_status_repr(huc_fw->fetch_status),
>> +		intel_uc_fw_status_repr(huc_fw->load_status));
>> +
>> +	if (huc_fw->fetch_status == INTEL_UC_FIRMWARE_SUCCESS &&
>> +	    huc_fw->load_status == INTEL_UC_FIRMWARE_FAIL)
>> +		return -ENOEXEC;
>> +
>> +	huc_fw->load_status = INTEL_UC_FIRMWARE_PENDING;
>> +
>> +	switch (huc_fw->fetch_status) {
>> +	case INTEL_UC_FIRMWARE_FAIL:
>> +		/* something went wrong :( */
>> +		err = -EIO;
>> +		goto fail;
>> +
>> +	case INTEL_UC_FIRMWARE_NONE:
>> +	case INTEL_UC_FIRMWARE_PENDING:
>> +	default:
>> +		/* "can't happen" */
>> +		WARN_ONCE(1, "HuC fw %s invalid fetch_status %s [%d]\n",
>> +			huc_fw->uc_fw_path,
>> +			intel_uc_fw_status_repr(huc_fw->fetch_status),
>> +			huc_fw->fetch_status);
>> +		err = -ENXIO;
>> +		goto fail;
>> +
>> +	case INTEL_UC_FIRMWARE_SUCCESS:
>> +		break;
>> +	}
>> +
>> +	err = huc_ucode_xfer(dev_priv);
>> +	if (err)
>> +		goto fail;
>> +
>> +	huc_fw->load_status = INTEL_UC_FIRMWARE_SUCCESS;
>> +
>> +	DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
>> +		huc_fw->uc_fw_path,
>> +		intel_uc_fw_status_repr(huc_fw->fetch_status),
>> +		intel_uc_fw_status_repr(huc_fw->load_status));
>
>Hmm, this message will always display "fetch SUCCESS load SUCCESS"
>as all other cases all handled as fail below... is it expected ?
>
>> +
>> +	return 0;
>> +
>> +fail:
>> +	if (huc_fw->load_status == INTEL_UC_FIRMWARE_PENDING)
>> +		huc_fw->load_status = INTEL_UC_FIRMWARE_FAIL;
>> +
>> +	DRM_ERROR("Failed to complete HuC uCode load with ret %d\n", err);
>> +
>> +	return err;
>> +}
>> +
>> +/**
>> + * intel_huc_fini() - clean up resources allocated for HuC
>> + * @dev: the drm device
>> + *
>> + * Cleans up by releasing the huc firmware GEM obj.
>> + */
>> +void intel_huc_fini(struct drm_device *dev)
>
>Why this function takes dev? All other functions take dev_priv.
>
>Michal
>
>> +{
>> +	struct drm_i915_private *dev_priv = to_i915(dev);
>> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
>> +
>> +	mutex_lock(&dev->struct_mutex);
>> +	if (huc_fw->uc_fw_obj)
>> +		i915_gem_object_put(huc_fw->uc_fw_obj);
>> +	huc_fw->uc_fw_obj = NULL;
>> +	mutex_unlock(&dev->struct_mutex);
>> +
>> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE; }
>> +
>> diff --git a/drivers/gpu/drm/i915/intel_uc.h
>> b/drivers/gpu/drm/i915/intel_uc.h index ad140e2..57aef56 100644
>> --- a/drivers/gpu/drm/i915/intel_uc.h
>> +++ b/drivers/gpu/drm/i915/intel_uc.h
>> @@ -24,6 +24,9 @@
>>  #ifndef _INTEL_UC_H_
>>  #define _INTEL_UC_H_
>>
>> +#define HUC_STATUS2             _MMIO(0xD3B0)
>> +#define   HUC_FW_VERIFIED       (1<<7)
>> +
>>  #include "intel_guc_fwif.h"
>>  #include "i915_guc_reg.h"
>>  #include "intel_ringbuffer.h"
>> @@ -174,6 +177,13 @@ struct intel_guc {
>>  	struct mutex send_mutex;
>>  };
>>
>> +struct intel_huc {
>> +	/* Generic uC firmware management */
>> +	struct intel_uc_fw fw;
>> +
>> +	/* HuC-specific additions */
>> +};
>> +
>>  /* intel_uc.c */
>>  void intel_uc_init_early(struct drm_i915_private *dev_priv);  bool
>> intel_guc_recv(struct drm_i915_private *dev_priv, u32 *status); @@
>> -190,6 +200,9 @@ extern void intel_guc_fini(struct drm_i915_private
>> *dev_priv);  extern const char *intel_uc_fw_status_repr(enum
>> intel_uc_fw_status status);  extern int intel_guc_suspend(struct
>> drm_i915_private *dev_priv);  extern int intel_guc_resume(struct
>> drm_i915_private *dev_priv);
>> +void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>> +	struct intel_uc_fw *uc_fw);
>> +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv);
>>
>>  /* i915_guc_submission.c */
>>  int i915_guc_submission_init(struct drm_i915_private *dev_priv); @@
>> -204,4 +217,9 @@ void i915_guc_register(struct drm_i915_private
>> *dev_priv);  void i915_guc_unregister(struct drm_i915_private
>> *dev_priv);  int i915_guc_log_control(struct drm_i915_private
>> *dev_priv, u64 control_val);
>>
>> +/* intel_huc_loader.c */
>> +void intel_huc_init(struct drm_i915_private *dev_priv); void
>> +intel_huc_fini(struct drm_device *dev); int intel_huc_load(struct
>> +drm_i915_private *dev_priv);
>> +
>>  #endif
>> --
>> 2.7.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general
  2017-01-03  0:07     ` Srivatsa, Anusha
@ 2017-01-03 14:15       ` Michal Wajdeczko
  2017-01-03 17:43         ` Srivatsa, Anusha
  0 siblings, 1 reply; 50+ messages in thread
From: Michal Wajdeczko @ 2017-01-03 14:15 UTC (permalink / raw)
  To: Srivatsa, Anusha; +Cc: intel-gfx

On Tue, Jan 03, 2017 at 01:07:14AM +0100, Srivatsa, Anusha wrote:
> 
> 
> >-----Original Message-----
> >From: Wajdeczko, Michal
> >Sent: Tuesday, December 27, 2016 9:28 AM
> >To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
> >Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter Antoine
> ><peter.antoine@intel.com>
> >Subject: Re: [Intel-gfx] [PATCH 1/8] drm/i915/guc: Make the GuC fw loading
> >helper functions general
> >
> >On Thu, Dec 22, 2016 at 03:12:17PM -0800, Anusha Srivatsa wrote:
> >> From: Peter Antoine <peter.antoine@intel.com>
> >>
> >> Rename some of the GuC fw loading code to make them more general. We
> >> will utilise them for HuC loading as well.
> >>      s/intel_guc_fw/intel_uc_fw/g
> >>      s/GUC_FIRMWARE/UC_FIRMWARE/g
> >>
> >> Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts members,
> >> such as 'guc' or 'guc_fw' either is renamed to 'uc' or removed for
> >> same purpose.
> >>
> >> v2: rebased on top of nightly.
> >>     reapplied the search/replace as upstream code as changed.
> >> v3: rebased again on drm-nightly.
> >> v4: removed G from messages in shared fw fetch function.
> >> v5: rebased.
> >> v7: rebased.
> >> v8: rebased.
> >> v9: rebased.
> >> v10: rebased.
> >> v11: rebased.
> >> v12: rebased on top of drm-tip
> >> v13: rebased.Updated dev to dev_priv in intel_guc_setup(),
> >> guc_fw_getch() and intel_guc_init().
> >> v14: rebased. Remove uint32_t fw_type to patch 2. Add INTEL_ prefix
> >> for fields in enum intel_uc_fw_status. Remove uc_dev field since its
> >> never used.Rename uc_fw to just fw and guc_fw to fw to avoid redundency.
> >> v15: rebased. Remove sections of code that were commented and no
> >> longer required.
> >>
> >> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> >> Signed-off-by: Alex Dai <yu.dai@intel.com>
> >> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/i915_debugfs.c        |  12 +--
> >>  drivers/gpu/drm/i915/i915_guc_submission.c |   4 +-
> >>  drivers/gpu/drm/i915/intel_guc_loader.c    | 156 ++++++++++++++---------------
> >>  drivers/gpu/drm/i915/intel_uc.h            |  36 +++----
> >>  4 files changed, 104 insertions(+), 104 deletions(-)
> >>

... CUT ...

> >> diff --git a/drivers/gpu/drm/i915/intel_uc.h
> >> b/drivers/gpu/drm/i915/intel_uc.h index 11f5608..893bcec 100644
> >> --- a/drivers/gpu/drm/i915/intel_uc.h
> >> +++ b/drivers/gpu/drm/i915/intel_uc.h
> >> @@ -91,28 +91,28 @@ struct i915_guc_client {
> >>  	uint64_t submissions[I915_NUM_ENGINES];  };
> >>
> >> -enum intel_guc_fw_status {
> >> -	GUC_FIRMWARE_FAIL = -1,
> >> -	GUC_FIRMWARE_NONE = 0,
> >> -	GUC_FIRMWARE_PENDING,
> >> -	GUC_FIRMWARE_SUCCESS
> >> +enum intel_uc_fw_status {
> >> +	INTEL_UC_FIRMWARE_FAIL = -1,
> >> +	INTEL_UC_FIRMWARE_NONE = 0,
> >> +	INTEL_UC_FIRMWARE_PENDING,
> >> +	INTEL_UC_FIRMWARE_SUCCESS
> >>  };
> >>
> >>  /*
> >>   * This structure encapsulates all the data needed during the process
> >>   * of fetching, caching, and loading the firmware image into the GuC.
> >>   */
> >> -struct intel_guc_fw {
> >> -	const char *			guc_fw_path;
> >> -	size_t				guc_fw_size;
> >> -	struct drm_i915_gem_object *	guc_fw_obj;
> >> -	enum intel_guc_fw_status	guc_fw_fetch_status;
> >> -	enum intel_guc_fw_status	guc_fw_load_status;
> >> -
> >> -	uint16_t			guc_fw_major_wanted;
> >> -	uint16_t			guc_fw_minor_wanted;
> >> -	uint16_t			guc_fw_major_found;
> >> -	uint16_t			guc_fw_minor_found;
> >> +struct intel_uc_fw {
> >> +	const char *uc_fw_path;
> >
> >Can we drop "uc_fw_" prefix also from path and obj members?
> 
> Michal, you think we can do this change as a part of the guc refactor effort which will happen post this series gets merged? Or do you feel its makes more sense to that we have this change in this series....
> 

IMHO we should avoid introducing changes that we already know they are bad and easy to fix.
Number of changes in names shall be minimized to avoid confusion and merge conflicts.
Also relaying on the future refactor effort (that has no known ETA) is not good option, as one can forget to fix it ;)

Thanks,
Michal
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general
  2017-01-03 14:15       ` Michal Wajdeczko
@ 2017-01-03 17:43         ` Srivatsa, Anusha
  0 siblings, 0 replies; 50+ messages in thread
From: Srivatsa, Anusha @ 2017-01-03 17:43 UTC (permalink / raw)
  To: Wajdeczko, Michal; +Cc: intel-gfx



>-----Original Message-----
>From: Wajdeczko, Michal
>Sent: Tuesday, January 3, 2017 6:15 AM
>To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
>Cc: intel-gfx@lists.freedesktop.org
>Subject: Re: [Intel-gfx] [PATCH 1/8] drm/i915/guc: Make the GuC fw loading
>helper functions general
>
>On Tue, Jan 03, 2017 at 01:07:14AM +0100, Srivatsa, Anusha wrote:
>>
>>
>> >-----Original Message-----
>> >From: Wajdeczko, Michal
>> >Sent: Tuesday, December 27, 2016 9:28 AM
>> >To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
>> >Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>;
>> >Peter Antoine <peter.antoine@intel.com>
>> >Subject: Re: [Intel-gfx] [PATCH 1/8] drm/i915/guc: Make the GuC fw
>> >loading helper functions general
>> >
>> >On Thu, Dec 22, 2016 at 03:12:17PM -0800, Anusha Srivatsa wrote:
>> >> From: Peter Antoine <peter.antoine@intel.com>
>> >>
>> >> Rename some of the GuC fw loading code to make them more general.
>> >> We will utilise them for HuC loading as well.
>> >>      s/intel_guc_fw/intel_uc_fw/g
>> >>      s/GUC_FIRMWARE/UC_FIRMWARE/g
>> >>
>> >> Struct intel_guc_fw is renamed to intel_uc_fw. Prefix of tts
>> >> members, such as 'guc' or 'guc_fw' either is renamed to 'uc' or
>> >> removed for same purpose.
>> >>
>> >> v2: rebased on top of nightly.
>> >>     reapplied the search/replace as upstream code as changed.
>> >> v3: rebased again on drm-nightly.
>> >> v4: removed G from messages in shared fw fetch function.
>> >> v5: rebased.
>> >> v7: rebased.
>> >> v8: rebased.
>> >> v9: rebased.
>> >> v10: rebased.
>> >> v11: rebased.
>> >> v12: rebased on top of drm-tip
>> >> v13: rebased.Updated dev to dev_priv in intel_guc_setup(),
>> >> guc_fw_getch() and intel_guc_init().
>> >> v14: rebased. Remove uint32_t fw_type to patch 2. Add INTEL_ prefix
>> >> for fields in enum intel_uc_fw_status. Remove uc_dev field since
>> >> its never used.Rename uc_fw to just fw and guc_fw to fw to avoid
>redundency.
>> >> v15: rebased. Remove sections of code that were commented and no
>> >> longer required.
>> >>
>> >> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
>> >> Signed-off-by: Alex Dai <yu.dai@intel.com>
>> >> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
>> >> ---
>> >>  drivers/gpu/drm/i915/i915_debugfs.c        |  12 +--
>> >>  drivers/gpu/drm/i915/i915_guc_submission.c |   4 +-
>> >>  drivers/gpu/drm/i915/intel_guc_loader.c    | 156 ++++++++++++++------------
>---
>> >>  drivers/gpu/drm/i915/intel_uc.h            |  36 +++----
>> >>  4 files changed, 104 insertions(+), 104 deletions(-)
>> >>
>
>... CUT ...
>
>> >> diff --git a/drivers/gpu/drm/i915/intel_uc.h
>> >> b/drivers/gpu/drm/i915/intel_uc.h index 11f5608..893bcec 100644
>> >> --- a/drivers/gpu/drm/i915/intel_uc.h
>> >> +++ b/drivers/gpu/drm/i915/intel_uc.h
>> >> @@ -91,28 +91,28 @@ struct i915_guc_client {
>> >>  	uint64_t submissions[I915_NUM_ENGINES];  };
>> >>
>> >> -enum intel_guc_fw_status {
>> >> -	GUC_FIRMWARE_FAIL = -1,
>> >> -	GUC_FIRMWARE_NONE = 0,
>> >> -	GUC_FIRMWARE_PENDING,
>> >> -	GUC_FIRMWARE_SUCCESS
>> >> +enum intel_uc_fw_status {
>> >> +	INTEL_UC_FIRMWARE_FAIL = -1,
>> >> +	INTEL_UC_FIRMWARE_NONE = 0,
>> >> +	INTEL_UC_FIRMWARE_PENDING,
>> >> +	INTEL_UC_FIRMWARE_SUCCESS
>> >>  };
>> >>
>> >>  /*
>> >>   * This structure encapsulates all the data needed during the process
>> >>   * of fetching, caching, and loading the firmware image into the GuC.
>> >>   */
>> >> -struct intel_guc_fw {
>> >> -	const char *			guc_fw_path;
>> >> -	size_t				guc_fw_size;
>> >> -	struct drm_i915_gem_object *	guc_fw_obj;
>> >> -	enum intel_guc_fw_status	guc_fw_fetch_status;
>> >> -	enum intel_guc_fw_status	guc_fw_load_status;
>> >> -
>> >> -	uint16_t			guc_fw_major_wanted;
>> >> -	uint16_t			guc_fw_minor_wanted;
>> >> -	uint16_t			guc_fw_major_found;
>> >> -	uint16_t			guc_fw_minor_found;
>> >> +struct intel_uc_fw {
>> >> +	const char *uc_fw_path;
>> >
>> >Can we drop "uc_fw_" prefix also from path and obj members?
>>
>> Michal, you think we can do this change as a part of the guc refactor effort
>which will happen post this series gets merged? Or do you feel its makes more
>sense to that we have this change in this series....
>>
>
>IMHO we should avoid introducing changes that we already know they are bad
>and easy to fix.
>Number of changes in names shall be minimized to avoid confusion and merge
>conflicts.
>Also relaying on the future refactor effort (that has no known ETA) is not good
>option, as one can forget to fix it ;)

Sure. :)

Anusha
>Thanks,
>Michal
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
  2017-01-03  0:08     ` Srivatsa, Anusha
@ 2017-01-03 18:59       ` Srivatsa, Anusha
  2017-01-04 15:15         ` Arkadiusz Hiler
  0 siblings, 1 reply; 50+ messages in thread
From: Srivatsa, Anusha @ 2017-01-03 18:59 UTC (permalink / raw)
  To: Srivatsa, Anusha, Wajdeczko, Michal; +Cc: intel-gfx, Alex Dai, Peter Antoine



>-----Original Message-----
>From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of
>Srivatsa, Anusha
>Sent: Monday, January 2, 2017 4:09 PM
>To: Wajdeczko, Michal <Michal.Wajdeczko@intel.com>
>Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter Antoine
><peter.antoine@intel.com>
>Subject: Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
>
>
>
>>-----Original Message-----
>>From: Wajdeczko, Michal
>>Sent: Tuesday, December 27, 2016 9:51 AM
>>To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
>>Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter
>>Antoine <peter.antoine@intel.com>
>>Subject: Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading
>>support
>>
>>On Thu, Dec 22, 2016 at 03:12:19PM -0800, Anusha Srivatsa wrote:
>>> The HuC loading process is similar to GuC. The intel_uc_fw_fetch() is
>>> used for both cases.
>>>
>>> HuC loading needs to be before GuC loading. The WOPCM setting must be
>>> done early before loading any of them.
>>>
>>> v2: rebased on-top of drm-intel-nightly.
>>>     removed if(HAS_GUC()) before the guc call. (D.Gordon)
>>>     update huc_version number of format.
>>> v3: rebased to drm-intel-nightly, changed the file name format to
>>>     match the one in the huc package.
>>>     Changed dev->dev_private to to_i915()
>>> v4: moved function back to where it was.
>>>     change wait_for_atomic to wait_for.
>>> v5: rebased + comment changes.
>>> v7: rebased.
>>> v8: rebased.
>>> v9: rebased. Changed the year in the copyright message to reflect the
>>> right year.Correct the comments,remove the unwanted WARN message,
>>> replace drm_gem_object_unreference() with i915_gem_object_put().Make
>>> the prototypes in intel_huc.h non-extern.
>>> v10: rebased. Update the file construction done by HuC. It is similar
>>> to GuC.Adopted the approach used in-
>>> https://patchwork.freedesktop.org/patch/104355/ <Tvrtko Ursulin>
>>> v11: Fix warnings remove old declaration
>>> v12: Change dev to dev_priv in macro definition.
>>> Corrected comments.
>>> v13: rebased.
>>> v14: rebased on top of drm-tip
>>> v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
>>> intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
>>> of intel_huc.h to intel_uc.h
>>> v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to
>>guc_wopcm_size().
>>> Remove unwanted checks in intel_uc.h. Rename huc_fw in struct
>>> intel_huc to simply fw to avoid redundency.
>>> v17: rebased.
>>>
>>> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
>>> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
>>> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
>>> Signed-off-by: Alex Dai <yu.dai@intel.com>
>>> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
>>> ---
>>>  drivers/gpu/drm/i915/Makefile           |   1 +
>>>  drivers/gpu/drm/i915/i915_drv.c         |   4 +-
>>>  drivers/gpu/drm/i915/i915_drv.h         |   3 +-
>>>  drivers/gpu/drm/i915/i915_guc_reg.h     |   3 +
>>>  drivers/gpu/drm/i915/intel_guc_loader.c |  11 +-
>>> drivers/gpu/drm/i915/intel_huc_loader.c | 263
>>++++++++++++++++++++++++++++++++
>>>  drivers/gpu/drm/i915/intel_uc.h         |  18 +++
>>>  7 files changed, 296 insertions(+), 7 deletions(-)  create mode
>>> 100644 drivers/gpu/drm/i915/intel_huc_loader.c
>>>
>>> diff --git a/drivers/gpu/drm/i915/Makefile
>>> b/drivers/gpu/drm/i915/Makefile index 5196509..45ae124 100644
>>> --- a/drivers/gpu/drm/i915/Makefile
>>> +++ b/drivers/gpu/drm/i915/Makefile
>>> @@ -57,6 +57,7 @@ i915-y += i915_cmd_parser.o \  # general-purpose
>>> microcontroller (GuC) support  i915-y += intel_uc.o \
>>>  	  intel_guc_loader.o \
>>> +	  intel_huc_loader.o \
>>>  	  i915_guc_submission.o
>>>
>>>  # autogenerated null render state
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.c
>>> b/drivers/gpu/drm/i915/i915_drv.c index 6428588..85a47c2 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.c
>>> +++ b/drivers/gpu/drm/i915/i915_drv.c
>>> @@ -600,6 +600,7 @@ static int i915_load_modeset_init(struct
>>> drm_device
>>*dev)
>>>  	if (ret)
>>>  		goto cleanup_irq;
>>>
>>> +	intel_huc_init(dev_priv);
>>>  	intel_guc_init(dev_priv);
>>>
>>>  	ret = i915_gem_init(dev_priv);
>>> @@ -627,6 +628,7 @@ static int i915_load_modeset_init(struct
>>> drm_device
>>*dev)
>>>  		DRM_ERROR("failed to idle hardware; continuing to unload!\n");
>>>  	i915_gem_fini(dev_priv);
>>>  cleanup_irq:
>>> +	intel_huc_fini(dev);
>>>  	intel_guc_fini(dev_priv);
>>>  	drm_irq_uninstall(dev);
>>>  	intel_teardown_gmbus(dev_priv);
>>> @@ -1313,7 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)
>>>
>>>  	/* Flush any outstanding unpin_work. */
>>>  	drain_workqueue(dev_priv->wq);
>>> -
>>> +	intel_huc_fini(dev);
>>>  	intel_guc_fini(dev_priv);
>>>  	i915_gem_fini(dev_priv);
>>>  	intel_fbc_cleanup_cfb(dev_priv);
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
>>> b/drivers/gpu/drm/i915/i915_drv.h index 1a91409..7ac7730 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -2147,6 +2147,7 @@ struct drm_i915_private {
>>>
>>>  	struct intel_gvt *gvt;
>>>
>>> +	struct intel_huc huc;
>>>  	struct intel_guc guc;
>>>
>>>  	struct intel_csr csr;
>>> @@ -2921,7 +2922,7 @@ intel_info(const struct drm_i915_private *dev_priv)
>>>  #define HAS_GUC(dev_priv)	((dev_priv)->info.has_guc)
>>>  #define HAS_GUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
>>>  #define HAS_GUC_SCHED(dev_priv)	(HAS_GUC(dev_priv))
>>> -
>>> +#define HAS_HUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
>>>  #define HAS_RESOURCE_STREAMER(dev_priv)
>>> ((dev_priv)->info.has_resource_streamer)
>>>
>>>  #define HAS_POOLED_EU(dev_priv)	((dev_priv)->info.has_pooled_eu)
>>> diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h
>>> b/drivers/gpu/drm/i915/i915_guc_reg.h
>>> index 5e638fc..f9829f6 100644
>>> --- a/drivers/gpu/drm/i915/i915_guc_reg.h
>>> +++ b/drivers/gpu/drm/i915/i915_guc_reg.h
>>> @@ -61,9 +61,12 @@
>>>  #define   DMA_ADDRESS_SPACE_GTT		  (8 << 16)
>>>  #define DMA_COPY_SIZE			_MMIO(0xc310)
>>>  #define DMA_CTRL			_MMIO(0xc314)
>>> +#define   HUC_UKERNEL			  (1<<9)
>>>  #define   UOS_MOVE			  (1<<4)
>>>  #define   START_DMA			  (1<<0)
>>>  #define DMA_GUC_WOPCM_OFFSET		_MMIO(0xc340)
>>> +#define   HUC_LOADING_AGENT_VCR		  (0<<1)
>>> +#define   HUC_LOADING_AGENT_GUC		  (1<<1)
>>>  #define   GUC_WOPCM_OFFSET_VALUE	  0x80000	/* 512KB */
>>>  #define GUC_MAX_IDLE_COUNT		_MMIO(0xC3E4)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c
>>> b/drivers/gpu/drm/i915/intel_guc_loader.c
>>> index 06e3e5c..8c77e94 100644
>>> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
>>> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
>>> @@ -309,8 +309,8 @@ static int guc_ucode_xfer_dma(struct
>>> drm_i915_private
>>*dev_priv,
>>>  	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
>>>
>>>  	/* Finally start the DMA */
>>> -	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE |
>>START_DMA));
>>> -
>>> +	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE |
>>START_DMA) |
>>> +		_MASKED_BIT_DISABLE(HUC_UKERNEL));
>>>  	/*
>>>  	 * Wait for the DMA to complete & the GuC to start up.
>>>  	 * NB: Docs recommend not using the interrupt for completion.
>>> @@ -334,7 +334,7 @@ static int guc_ucode_xfer_dma(struct
>>> drm_i915_private
>>*dev_priv,
>>>  	return ret;
>>>  }
>>>
>>> -static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
>>> +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv)
>>>  {
>>>  	u32 wopcm_size = GUC_WOPCM_TOP;
>>>
>>> @@ -372,7 +372,7 @@ static int guc_ucode_xfer(struct drm_i915_private
>>*dev_priv)
>>>  	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>>>
>>>  	/* init WOPCM */
>>> -	I915_WRITE(GUC_WOPCM_SIZE, guc_wopcm_size(dev_priv));
>>> +	I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
>>>  	I915_WRITE(DMA_GUC_WOPCM_OFFSET,
>>GUC_WOPCM_OFFSET_VALUE);
>>>
>>>  	/* Enable MIA caching. GuC clock gating is disabled. */ @@ -511,6
>>> +511,7 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>>>  		if (err)
>>>  			goto fail;
>>>
>>> +		intel_huc_load(dev_priv);
>>>  		err = guc_ucode_xfer(dev_priv);
>>>  		if (!err)
>>>  			break;
>>> @@ -658,7 +659,7 @@ void intel_uc_fw_fetch(struct drm_i915_private
>>*dev_priv,
>>>  		size = uc_fw->header_size + uc_fw->ucode_size;
>>>
>>>  		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context).
>>*/
>>> -		if (size > guc_wopcm_size(dev_priv)) {
>>> +		if (size > intel_guc_wopcm_size(dev_priv)) {
>>>  			DRM_ERROR("Firmware is too large to fit in
>>WOPCM\n");
>>>  			goto fail;
>>>  		}
>>> diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c
>>> b/drivers/gpu/drm/i915/intel_huc_loader.c
>>> new file mode 100644
>>> index 0000000..98d631c
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/i915/intel_huc_loader.c
>>> @@ -0,0 +1,263 @@
>>> +/*
>>> + * Copyright (c) 2016 Intel Corporation
>>> + *
>>> + * Permission is hereby granted, free of charge, to any person
>>> +obtaining a
>>> + * copy of this software and associated documentation files (the
>>> +"Software"),
>>> + * to deal in the Software without restriction, including without
>>> +limitation
>>> + * the rights to use, copy, modify, merge, publish, distribute,
>>> +sublicense,
>>> + * and/or sell copies of the Software, and to permit persons to whom
>>> +the
>>> + * Software is furnished to do so, subject to the following conditions:
>>> + *
>>> + * The above copyright notice and this permission notice (including
>>> +the next
>>> + * paragraph) shall be included in all copies or substantial
>>> +portions of the
>>> + * Software.
>>> + *
>>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>>> +EXPRESS OR
>>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>>> +MERCHANTABILITY,
>>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO
>>EVENT
>>> +SHALL
>>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
>>DAMAGES
>>> +OR OTHER
>>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
>>> +ARISING
>>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>>> +OTHER DEALINGS
>>> + * IN THE SOFTWARE.
>>> + *
>>> + */
>>> +#include <linux/firmware.h>
>>> +#include "i915_drv.h"
>>> +#include "intel_uc.h"
>>> +
>>> +/**
>>> + * DOC: HuC Firmware
>>> + *
>>> + * Motivation:
>>> + * GEN9 introduces a new dedicated firmware for usage in media HEVC
>>> +(High
>>> + * Efficiency Video Coding) operations. Userspace can use the
>>> +firmware
>>> + * capabilities by adding HuC specific commands to batch buffers.
>>> + *
>>> + * Implementation:
>>> + * The same firmware loader is used as the GuC. However, the actual
>>> + * loading to HW is deferred until GEM initialization is done.
>>> + *
>>> + * Note that HuC firmware loading must be done before GuC loading.
>>> + */
>>> +
>>> +#define SKL_HUC_FW_MAJOR 01
>>> +#define SKL_HUC_FW_MINOR 07
>>> +#define SKL_BLD_NUM 1398
>>> +
>>> +#define HUC_FW_PATH(platform, major, minor, bld_num) \
>>> +	"i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \
>>> +	__stringify(minor) "_" __stringify(bld_num) ".bin"
>>> +
>>> +#define I915_SKL_HUC_UCODE HUC_FW_PATH(skl, SKL_HUC_FW_MAJOR, \
>>> +	SKL_HUC_FW_MINOR, SKL_BLD_NUM)
>>> +MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
>>> +
>>> +/**
>>> + * huc_ucode_xfer() - DMA's the firmware
>>> + * @dev_priv: the drm device
>>> + *
>>> + * This function takes the gem object containing the firmware, sets
>>> +up the DMA
>>
>>Hmm, this function takes just dev_priv...
>
>Oops.... will change the comment.
>
>Anusha
>>
>>> + * engine MMIO, triggers the DMA operation and waits for it to finish.
>>> + *
>>> + * Transfer the firmware image to RAM for execution by the microcontroller.
>>> + *
>>> + * Return: 0 on success, non-zero on failure  */ static int
>>> +huc_ucode_xfer(struct drm_i915_private *dev_priv) {
>>> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
>>> +	struct i915_vma *vma;
>>> +	unsigned long offset = 0;
>>> +	u32 size;
>>> +	int ret;
>>> +
>>> +	ret = i915_gem_object_set_to_gtt_domain(huc_fw->uc_fw_obj, false);
>>> +	if (ret) {
>>> +		DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
>>> +		return ret;
>>> +	}
>>> +
>>> +	vma = i915_gem_object_ggtt_pin(huc_fw->uc_fw_obj, NULL, 0, 0, 0);
>>> +	if (IS_ERR(vma)) {
>>> +		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
>>> +		return PTR_ERR(vma);
>>> +	}
>>> +
>>> +	/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
>>> +	I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
>>> +
>>> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>>> +
>>> +	/* init WOPCM */
>>> +	I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
>>> +	I915_WRITE(DMA_GUC_WOPCM_OFFSET,
>>GUC_WOPCM_OFFSET_VALUE |
>>> +			HUC_LOADING_AGENT_GUC);
>>> +
>>> +	/* Set the source address for the uCode */
>>> +	offset = i915_ggtt_offset(vma) + huc_fw->header_offset;
>>> +	I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
>>> +	I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
>>> +
>>> +	/* Hardware doesn't look at destination address for HuC. Set it to 0,
>>> +	 * but still program the correct address space.
>>> +	 */
>>> +	I915_WRITE(DMA_ADDR_1_LOW, 0);
>>> +	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
>>> +
>>> +	size = huc_fw->header_size + huc_fw->ucode_size;
>>> +	I915_WRITE(DMA_COPY_SIZE, size);
>>> +
>>> +	/* Start the DMA */
>>> +	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(HUC_UKERNEL |
>>START_DMA));
>>> +
>>> +	/* Wait for DMA to finish */
>>> +	ret = wait_for((I915_READ(DMA_CTRL) & START_DMA) == 0, 100);
>>> +
>>> +	DRM_DEBUG_DRIVER("HuC DMA transfer wait over with ret %d\n", ret);
>>> +
>>> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>>> +
>>> +	/*
>>> +	 * We keep the object pages for reuse during resume. But we can unpin it
>>> +	 * now that DMA has completed, so it doesn't continue to take up space.
>>> +	 */
>>> +	i915_vma_unpin(vma);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +/**
>>> + * intel_huc_init() - initiate HuC firmware loading request
>>> + * @dev_priv: the drm_i915_private device
>>> + *
>>> + * Called early during driver load, but after GEM is initialised.
>>> +The loading
>>> + * will continue only when driver explicitly specify firmware name and
>version.
>>> + * All other cases are considered as INTEL_UC_FIRMWARE_NONE either
>>> +because HW
>>> + * is not capable or driver yet support it. And there will be no
>>> +error message
>>> + * for INTEL_UC_FIRMWARE_NONE cases.
>>> + *
>>> + * The DMA-copying to HW is done later when intel_huc_load() is called.
>>> + */
>>> +void intel_huc_init(struct drm_i915_private *dev_priv) {
>>> +	struct intel_huc *huc = &dev_priv->huc;
>>> +	struct intel_uc_fw *huc_fw = &huc->fw;
>>> +	const char *fw_path = NULL;
>>> +
>>> +	huc_fw->uc_fw_path = NULL;
>>> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
>>> +	huc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
>>> +	huc_fw->fw_type = INTEL_UC_FW_TYPE_HUC;
>>> +
>>> +	if (!HAS_HUC_UCODE(dev_priv))
>>> +		return;
>>> +
>>> +	if (IS_SKYLAKE(dev_priv)) {
>>> +		fw_path = I915_SKL_HUC_UCODE;
>>> +		huc_fw->major_ver_wanted = SKL_HUC_FW_MAJOR;
>>> +		huc_fw->minor_ver_wanted = SKL_HUC_FW_MINOR;
>>> +	}
>>> +
>>> +	huc_fw->uc_fw_path = fw_path;
>>> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
>>> +
>>> +	DRM_DEBUG_DRIVER("HuC firmware pending, path %s\n", fw_path);
>>> +
>>> +	intel_uc_fw_fetch(dev_priv, huc_fw); }
>>> +
>>> +/**
>>> + * intel_huc_load() - load HuC uCode to device
>>> + * @dev_priv: the drm_i915_private device
>>> + *
>>> + * Called from gem_init_hw() during driver loading and also after a GPU reset.
>>> + * Be note that HuC loading must be done before GuC loading.
>>> + *
>>> + * The firmware image should have already been fetched into memory
>>> +by the
>>> + * earlier call to intel_huc_init(), so here we need only check that
>>> + * is succeeded, and then transfer the image to the h/w.
>>> + *
>>> + * Return:	non-zero code on error
>>> + */
>>> +int intel_huc_load(struct drm_i915_private *dev_priv) {
>>> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
>>> +	int err;
>>> +
>>> +	if (huc_fw->fetch_status == INTEL_UC_FIRMWARE_NONE)
>>> +		return 0;
>>> +
>>> +	DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
>>> +		huc_fw->uc_fw_path,
>>> +		intel_uc_fw_status_repr(huc_fw->fetch_status),
>>> +		intel_uc_fw_status_repr(huc_fw->load_status));
>>> +
>>> +	if (huc_fw->fetch_status == INTEL_UC_FIRMWARE_SUCCESS &&
>>> +	    huc_fw->load_status == INTEL_UC_FIRMWARE_FAIL)
>>> +		return -ENOEXEC;
>>> +
>>> +	huc_fw->load_status = INTEL_UC_FIRMWARE_PENDING;
>>> +
>>> +	switch (huc_fw->fetch_status) {
>>> +	case INTEL_UC_FIRMWARE_FAIL:
>>> +		/* something went wrong :( */
>>> +		err = -EIO;
>>> +		goto fail;
>>> +
>>> +	case INTEL_UC_FIRMWARE_NONE:
>>> +	case INTEL_UC_FIRMWARE_PENDING:
>>> +	default:
>>> +		/* "can't happen" */
>>> +		WARN_ONCE(1, "HuC fw %s invalid fetch_status %s [%d]\n",
>>> +			huc_fw->uc_fw_path,
>>> +			intel_uc_fw_status_repr(huc_fw->fetch_status),
>>> +			huc_fw->fetch_status);
>>> +		err = -ENXIO;
>>> +		goto fail;
>>> +
>>> +	case INTEL_UC_FIRMWARE_SUCCESS:
>>> +		break;
>>> +	}
>>> +
>>> +	err = huc_ucode_xfer(dev_priv);
>>> +	if (err)
>>> +		goto fail;
>>> +
>>> +	huc_fw->load_status = INTEL_UC_FIRMWARE_SUCCESS;
>>> +
>>> +	DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
>>> +		huc_fw->uc_fw_path,
>>> +		intel_uc_fw_status_repr(huc_fw->fetch_status),
>>> +		intel_uc_fw_status_repr(huc_fw->load_status));
>>
>>Hmm, this message will always display "fetch SUCCESS load SUCCESS"
>>as all other cases all handled as fail below... is it expected ?

Yes. I think we need a message for the case when there is no failure.

>>> +
>>> +	return 0;
>>> +
>>> +fail:
>>> +	if (huc_fw->load_status == INTEL_UC_FIRMWARE_PENDING)
>>> +		huc_fw->load_status = INTEL_UC_FIRMWARE_FAIL;
>>> +
>>> +	DRM_ERROR("Failed to complete HuC uCode load with ret %d\n", err);
>>> +
>>> +	return err;
>>> +}
>>> +
>>> +/**
>>> + * intel_huc_fini() - clean up resources allocated for HuC
>>> + * @dev: the drm device
>>> + *
>>> + * Cleans up by releasing the huc firmware GEM obj.
>>> + */
>>> +void intel_huc_fini(struct drm_device *dev)
>>
>>Why this function takes dev? All other functions take dev_priv.

Last I heard this was the only function that took dev and there some WIP before we make it take dev_priv.
Arek, can we change this now?

>>Michal
>>
>>> +{
>>> +	struct drm_i915_private *dev_priv = to_i915(dev);
>>> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
>>> +
>>> +	mutex_lock(&dev->struct_mutex);
>>> +	if (huc_fw->uc_fw_obj)
>>> +		i915_gem_object_put(huc_fw->uc_fw_obj);
>>> +	huc_fw->uc_fw_obj = NULL;
>>> +	mutex_unlock(&dev->struct_mutex);
>>> +
>>> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE; }
>>> +
>>> diff --git a/drivers/gpu/drm/i915/intel_uc.h
>>> b/drivers/gpu/drm/i915/intel_uc.h index ad140e2..57aef56 100644
>>> --- a/drivers/gpu/drm/i915/intel_uc.h
>>> +++ b/drivers/gpu/drm/i915/intel_uc.h
>>> @@ -24,6 +24,9 @@
>>>  #ifndef _INTEL_UC_H_
>>>  #define _INTEL_UC_H_
>>>
>>> +#define HUC_STATUS2             _MMIO(0xD3B0)
>>> +#define   HUC_FW_VERIFIED       (1<<7)
>>> +
>>>  #include "intel_guc_fwif.h"
>>>  #include "i915_guc_reg.h"
>>>  #include "intel_ringbuffer.h"
>>> @@ -174,6 +177,13 @@ struct intel_guc {
>>>  	struct mutex send_mutex;
>>>  };
>>>
>>> +struct intel_huc {
>>> +	/* Generic uC firmware management */
>>> +	struct intel_uc_fw fw;
>>> +
>>> +	/* HuC-specific additions */
>>> +};
>>> +
>>>  /* intel_uc.c */
>>>  void intel_uc_init_early(struct drm_i915_private *dev_priv);  bool
>>> intel_guc_recv(struct drm_i915_private *dev_priv, u32 *status); @@
>>> -190,6 +200,9 @@ extern void intel_guc_fini(struct drm_i915_private
>>> *dev_priv);  extern const char *intel_uc_fw_status_repr(enum
>>> intel_uc_fw_status status);  extern int intel_guc_suspend(struct
>>> drm_i915_private *dev_priv);  extern int intel_guc_resume(struct
>>> drm_i915_private *dev_priv);
>>> +void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>>> +	struct intel_uc_fw *uc_fw);
>>> +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv);
>>>
>>>  /* i915_guc_submission.c */
>>>  int i915_guc_submission_init(struct drm_i915_private *dev_priv); @@
>>> -204,4 +217,9 @@ void i915_guc_register(struct drm_i915_private
>>> *dev_priv);  void i915_guc_unregister(struct drm_i915_private
>>> *dev_priv);  int i915_guc_log_control(struct drm_i915_private
>>> *dev_priv, u64 control_val);
>>>
>>> +/* intel_huc_loader.c */
>>> +void intel_huc_init(struct drm_i915_private *dev_priv); void
>>> +intel_huc_fini(struct drm_device *dev); int intel_huc_load(struct
>>> +drm_i915_private *dev_priv);
>>> +
>>>  #endif
>>> --
>>> 2.7.4
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>_______________________________________________
>Intel-gfx mailing list
>Intel-gfx@lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 7/8] drm/i915/huc: Support HuC authentication
  2016-12-22 23:30   ` Chris Wilson
@ 2017-01-03 19:55     ` Srivatsa, Anusha
  0 siblings, 0 replies; 50+ messages in thread
From: Srivatsa, Anusha @ 2017-01-03 19:55 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx, Alex Dai, Peter Antoine



>-----Original Message-----
>From: Chris Wilson [mailto:chris@chris-wilson.co.uk]
>Sent: Thursday, December 22, 2016 3:30 PM
>To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
>Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter Antoine
><peter.antoine@intel.com>
>Subject: Re: [Intel-gfx] [PATCH 7/8] drm/i915/huc: Support HuC authentication
>
>On Thu, Dec 22, 2016 at 03:12:23PM -0800, Anusha Srivatsa wrote:
>> +void intel_guc_auth_huc(struct drm_i915_private *dev_priv) {
>> +	struct intel_guc *guc = &dev_priv->guc;
>> +	struct intel_huc *huc = &dev_priv->huc;
>> +	struct i915_vma *vma;
>> +	int ret;
>> +	u32 data[2];
>> +
>> +	/* Bypass the case where there is no HuC firmware */
>> +	if (huc->fw.fetch_status == INTEL_UC_FIRMWARE_NONE ||
>> +		huc->fw.load_status == INTEL_UC_FIRMWARE_NONE)
>> +		return;
>> +
>> +	if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) {
>> +		DRM_ERROR("HuC: GuC fw wasn't loaded. Can't
>authenticate\n");
>> +		return;
>> +	}
>> +
>> +	if (huc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS) {
>> +		DRM_ERROR("HuC: fw wasn't loaded. Nothing to
>authenticate\n");
>> +		return;
>> +	}
>> +
>> +	vma = i915_gem_object_ggtt_pin(huc->fw.uc_fw_obj, NULL, 0, 0, 0);
>> +	if (IS_ERR(vma)) {
>> +		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
>> +		return;
>> +	}
>> +
>> +
>> +	/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
>> +	I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
>
>Still working on stopping this from frequently popping up in code outside of the
>GTT routines.
So, basically beautify the code such that the GTT routines do not pop out in non GTT parts of code. Correct? 
>
>> +	/* Specify auth action and where public signature is. */
>> +	data[0] = INTEL_GUC_ACTION_AUTHENTICATE_HUC;
>> +	data[1] = i915_ggtt_offset(vma) + huc->fw.rsa_offset;
>> +
>> +	ret = intel_guc_send(guc, data, ARRAY_SIZE(data));
>> +	if (ret) {
>> +		DRM_ERROR("HuC: GuC did not ack Auth request\n");
>> +		goto out;
>> +	}
>> +
>> +	/* Check authentication status, it should be done by now */
>> +	ret = wait_for((I915_READ(HUC_STATUS2) & HUC_FW_VERIFIED) > 0,
>50);
>
>ret = intel_wait_for_register(dev_priv,
>			      HUC_STATUS2,
>			      HUC_FW_VERIFIED,
>			      HUC_FW_VERIFIED,
>			      50);
>
>wait_for() is a rather large macro, and intel_wait_for_register() employs the spin
>then sleep optimisation for quick responses.

Thankyou for bringing this to my notice. 

Anusha

>-Chris
>
>--
>Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
  2017-01-03 18:59       ` Srivatsa, Anusha
@ 2017-01-04 15:15         ` Arkadiusz Hiler
  0 siblings, 0 replies; 50+ messages in thread
From: Arkadiusz Hiler @ 2017-01-04 15:15 UTC (permalink / raw)
  To: Srivatsa, Anusha; +Cc: intel-gfx, Alex Dai, Peter Antoine

On Tue, Jan 03, 2017 at 06:59:11PM +0000, Srivatsa, Anusha wrote:
> 
> 
> >-----Original Message-----
> >From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of
> >Srivatsa, Anusha
> >Sent: Monday, January 2, 2017 4:09 PM
> >To: Wajdeczko, Michal <Michal.Wajdeczko@intel.com>
> >Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter Antoine
> ><peter.antoine@intel.com>
> >Subject: Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
> >
> >
> >
> >>-----Original Message-----
> >>From: Wajdeczko, Michal
> >>Sent: Tuesday, December 27, 2016 9:51 AM
> >>To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
> >>Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter
> >>Antoine <peter.antoine@intel.com>
> >>Subject: Re: [Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading
> >>support
> >>
> >>On Thu, Dec 22, 2016 at 03:12:19PM -0800, Anusha Srivatsa wrote:
> >>> The HuC loading process is similar to GuC. The intel_uc_fw_fetch() is
> >>> used for both cases.
> >>>
> >>> HuC loading needs to be before GuC loading. The WOPCM setting must be
> >>> done early before loading any of them.
> >>>
> >>> v2: rebased on-top of drm-intel-nightly.
> >>>     removed if(HAS_GUC()) before the guc call. (D.Gordon)
> >>>     update huc_version number of format.
> >>> v3: rebased to drm-intel-nightly, changed the file name format to
> >>>     match the one in the huc package.
> >>>     Changed dev->dev_private to to_i915()
> >>> v4: moved function back to where it was.
> >>>     change wait_for_atomic to wait_for.
> >>> v5: rebased + comment changes.
> >>> v7: rebased.
> >>> v8: rebased.
> >>> v9: rebased. Changed the year in the copyright message to reflect the
> >>> right year.Correct the comments,remove the unwanted WARN message,
> >>> replace drm_gem_object_unreference() with i915_gem_object_put().Make
> >>> the prototypes in intel_huc.h non-extern.
> >>> v10: rebased. Update the file construction done by HuC. It is similar
> >>> to GuC.Adopted the approach used in-
> >>> https://patchwork.freedesktop.org/patch/104355/ <Tvrtko Ursulin>
> >>> v11: Fix warnings remove old declaration
> >>> v12: Change dev to dev_priv in macro definition.
> >>> Corrected comments.
> >>> v13: rebased.
> >>> v14: rebased on top of drm-tip
> >>> v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
> >>> intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
> >>> of intel_huc.h to intel_uc.h
> >>> v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to
> >>guc_wopcm_size().
> >>> Remove unwanted checks in intel_uc.h. Rename huc_fw in struct
> >>> intel_huc to simply fw to avoid redundency.
> >>> v17: rebased.
> >>>
> >>> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> >>> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> >>> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> >>> Signed-off-by: Alex Dai <yu.dai@intel.com>
> >>> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> >>> ---
> >>>  drivers/gpu/drm/i915/Makefile           |   1 +
> >>>  drivers/gpu/drm/i915/i915_drv.c         |   4 +-
> >>>  drivers/gpu/drm/i915/i915_drv.h         |   3 +-
> >>>  drivers/gpu/drm/i915/i915_guc_reg.h     |   3 +
> >>>  drivers/gpu/drm/i915/intel_guc_loader.c |  11 +-
> >>> drivers/gpu/drm/i915/intel_huc_loader.c | 263
> >>++++++++++++++++++++++++++++++++
> >>>  drivers/gpu/drm/i915/intel_uc.h         |  18 +++
> >>>  7 files changed, 296 insertions(+), 7 deletions(-)  create mode
> >>> 100644 drivers/gpu/drm/i915/intel_huc_loader.c
> >>>
> >>> diff --git a/drivers/gpu/drm/i915/Makefile
> >>> b/drivers/gpu/drm/i915/Makefile index 5196509..45ae124 100644
> >>> --- a/drivers/gpu/drm/i915/Makefile
> >>> +++ b/drivers/gpu/drm/i915/Makefile
> >>> @@ -57,6 +57,7 @@ i915-y += i915_cmd_parser.o \  # general-purpose
> >>> microcontroller (GuC) support  i915-y += intel_uc.o \
> >>>  	  intel_guc_loader.o \
> >>> +	  intel_huc_loader.o \
> >>>  	  i915_guc_submission.o
> >>>
> >>>  # autogenerated null render state
> >>> diff --git a/drivers/gpu/drm/i915/i915_drv.c
> >>> b/drivers/gpu/drm/i915/i915_drv.c index 6428588..85a47c2 100644
> >>> --- a/drivers/gpu/drm/i915/i915_drv.c
> >>> +++ b/drivers/gpu/drm/i915/i915_drv.c
> >>> @@ -600,6 +600,7 @@ static int i915_load_modeset_init(struct
> >>> drm_device
> >>*dev)
> >>>  	if (ret)
> >>>  		goto cleanup_irq;
> >>>
> >>> +	intel_huc_init(dev_priv);
> >>>  	intel_guc_init(dev_priv);
> >>>
> >>>  	ret = i915_gem_init(dev_priv);
> >>> @@ -627,6 +628,7 @@ static int i915_load_modeset_init(struct
> >>> drm_device
> >>*dev)
> >>>  		DRM_ERROR("failed to idle hardware; continuing to unload!\n");
> >>>  	i915_gem_fini(dev_priv);
> >>>  cleanup_irq:
> >>> +	intel_huc_fini(dev);
> >>>  	intel_guc_fini(dev_priv);
> >>>  	drm_irq_uninstall(dev);
> >>>  	intel_teardown_gmbus(dev_priv);
> >>> @@ -1313,7 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)
> >>>
> >>>  	/* Flush any outstanding unpin_work. */
> >>>  	drain_workqueue(dev_priv->wq);
> >>> -
> >>> +	intel_huc_fini(dev);
> >>>  	intel_guc_fini(dev_priv);
> >>>  	i915_gem_fini(dev_priv);
> >>>  	intel_fbc_cleanup_cfb(dev_priv);
> >>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> >>> b/drivers/gpu/drm/i915/i915_drv.h index 1a91409..7ac7730 100644
> >>> --- a/drivers/gpu/drm/i915/i915_drv.h
> >>> +++ b/drivers/gpu/drm/i915/i915_drv.h
> >>> @@ -2147,6 +2147,7 @@ struct drm_i915_private {
> >>>
> >>>  	struct intel_gvt *gvt;
> >>>
> >>> +	struct intel_huc huc;
> >>>  	struct intel_guc guc;
> >>>
> >>>  	struct intel_csr csr;
> >>> @@ -2921,7 +2922,7 @@ intel_info(const struct drm_i915_private *dev_priv)
> >>>  #define HAS_GUC(dev_priv)	((dev_priv)->info.has_guc)
> >>>  #define HAS_GUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
> >>>  #define HAS_GUC_SCHED(dev_priv)	(HAS_GUC(dev_priv))
> >>> -
> >>> +#define HAS_HUC_UCODE(dev_priv)	(HAS_GUC(dev_priv))
> >>>  #define HAS_RESOURCE_STREAMER(dev_priv)
> >>> ((dev_priv)->info.has_resource_streamer)
> >>>
> >>>  #define HAS_POOLED_EU(dev_priv)	((dev_priv)->info.has_pooled_eu)
> >>> diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h
> >>> b/drivers/gpu/drm/i915/i915_guc_reg.h
> >>> index 5e638fc..f9829f6 100644
> >>> --- a/drivers/gpu/drm/i915/i915_guc_reg.h
> >>> +++ b/drivers/gpu/drm/i915/i915_guc_reg.h
> >>> @@ -61,9 +61,12 @@
> >>>  #define   DMA_ADDRESS_SPACE_GTT		  (8 << 16)
> >>>  #define DMA_COPY_SIZE			_MMIO(0xc310)
> >>>  #define DMA_CTRL			_MMIO(0xc314)
> >>> +#define   HUC_UKERNEL			  (1<<9)
> >>>  #define   UOS_MOVE			  (1<<4)
> >>>  #define   START_DMA			  (1<<0)
> >>>  #define DMA_GUC_WOPCM_OFFSET		_MMIO(0xc340)
> >>> +#define   HUC_LOADING_AGENT_VCR		  (0<<1)
> >>> +#define   HUC_LOADING_AGENT_GUC		  (1<<1)
> >>>  #define   GUC_WOPCM_OFFSET_VALUE	  0x80000	/* 512KB */
> >>>  #define GUC_MAX_IDLE_COUNT		_MMIO(0xC3E4)
> >>>
> >>> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c
> >>> b/drivers/gpu/drm/i915/intel_guc_loader.c
> >>> index 06e3e5c..8c77e94 100644
> >>> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> >>> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> >>> @@ -309,8 +309,8 @@ static int guc_ucode_xfer_dma(struct
> >>> drm_i915_private
> >>*dev_priv,
> >>>  	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
> >>>
> >>>  	/* Finally start the DMA */
> >>> -	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE |
> >>START_DMA));
> >>> -
> >>> +	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE |
> >>START_DMA) |
> >>> +		_MASKED_BIT_DISABLE(HUC_UKERNEL));
> >>>  	/*
> >>>  	 * Wait for the DMA to complete & the GuC to start up.
> >>>  	 * NB: Docs recommend not using the interrupt for completion.
> >>> @@ -334,7 +334,7 @@ static int guc_ucode_xfer_dma(struct
> >>> drm_i915_private
> >>*dev_priv,
> >>>  	return ret;
> >>>  }
> >>>
> >>> -static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
> >>> +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv)
> >>>  {
> >>>  	u32 wopcm_size = GUC_WOPCM_TOP;
> >>>
> >>> @@ -372,7 +372,7 @@ static int guc_ucode_xfer(struct drm_i915_private
> >>*dev_priv)
> >>>  	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
> >>>
> >>>  	/* init WOPCM */
> >>> -	I915_WRITE(GUC_WOPCM_SIZE, guc_wopcm_size(dev_priv));
> >>> +	I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
> >>>  	I915_WRITE(DMA_GUC_WOPCM_OFFSET,
> >>GUC_WOPCM_OFFSET_VALUE);
> >>>
> >>>  	/* Enable MIA caching. GuC clock gating is disabled. */ @@ -511,6
> >>> +511,7 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
> >>>  		if (err)
> >>>  			goto fail;
> >>>
> >>> +		intel_huc_load(dev_priv);
> >>>  		err = guc_ucode_xfer(dev_priv);
> >>>  		if (!err)
> >>>  			break;
> >>> @@ -658,7 +659,7 @@ void intel_uc_fw_fetch(struct drm_i915_private
> >>*dev_priv,
> >>>  		size = uc_fw->header_size + uc_fw->ucode_size;
> >>>
> >>>  		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context).
> >>*/
> >>> -		if (size > guc_wopcm_size(dev_priv)) {
> >>> +		if (size > intel_guc_wopcm_size(dev_priv)) {
> >>>  			DRM_ERROR("Firmware is too large to fit in
> >>WOPCM\n");
> >>>  			goto fail;
> >>>  		}
> >>> diff --git a/drivers/gpu/drm/i915/intel_huc_loader.c
> >>> b/drivers/gpu/drm/i915/intel_huc_loader.c
> >>> new file mode 100644
> >>> index 0000000..98d631c
> >>> --- /dev/null
> >>> +++ b/drivers/gpu/drm/i915/intel_huc_loader.c
> >>> @@ -0,0 +1,263 @@
> >>> +/*
> >>> + * Copyright (c) 2016 Intel Corporation
> >>> + *
> >>> + * Permission is hereby granted, free of charge, to any person
> >>> +obtaining a
> >>> + * copy of this software and associated documentation files (the
> >>> +"Software"),
> >>> + * to deal in the Software without restriction, including without
> >>> +limitation
> >>> + * the rights to use, copy, modify, merge, publish, distribute,
> >>> +sublicense,
> >>> + * and/or sell copies of the Software, and to permit persons to whom
> >>> +the
> >>> + * Software is furnished to do so, subject to the following conditions:
> >>> + *
> >>> + * The above copyright notice and this permission notice (including
> >>> +the next
> >>> + * paragraph) shall be included in all copies or substantial
> >>> +portions of the
> >>> + * Software.
> >>> + *
> >>> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> >>> +EXPRESS OR
> >>> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> >>> +MERCHANTABILITY,
> >>> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO
> >>EVENT
> >>> +SHALL
> >>> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
> >>DAMAGES
> >>> +OR OTHER
> >>> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> >>> +ARISING
> >>> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> >>> +OTHER DEALINGS
> >>> + * IN THE SOFTWARE.
> >>> + *
> >>> + */
> >>> +#include <linux/firmware.h>
> >>> +#include "i915_drv.h"
> >>> +#include "intel_uc.h"
> >>> +
> >>> +/**
> >>> + * DOC: HuC Firmware
> >>> + *
> >>> + * Motivation:
> >>> + * GEN9 introduces a new dedicated firmware for usage in media HEVC
> >>> +(High
> >>> + * Efficiency Video Coding) operations. Userspace can use the
> >>> +firmware
> >>> + * capabilities by adding HuC specific commands to batch buffers.
> >>> + *
> >>> + * Implementation:
> >>> + * The same firmware loader is used as the GuC. However, the actual
> >>> + * loading to HW is deferred until GEM initialization is done.
> >>> + *
> >>> + * Note that HuC firmware loading must be done before GuC loading.
> >>> + */
> >>> +
> >>> +#define SKL_HUC_FW_MAJOR 01
> >>> +#define SKL_HUC_FW_MINOR 07
> >>> +#define SKL_BLD_NUM 1398
> >>> +
> >>> +#define HUC_FW_PATH(platform, major, minor, bld_num) \
> >>> +	"i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \
> >>> +	__stringify(minor) "_" __stringify(bld_num) ".bin"
> >>> +
> >>> +#define I915_SKL_HUC_UCODE HUC_FW_PATH(skl, SKL_HUC_FW_MAJOR, \
> >>> +	SKL_HUC_FW_MINOR, SKL_BLD_NUM)
> >>> +MODULE_FIRMWARE(I915_SKL_HUC_UCODE);
> >>> +
> >>> +/**
> >>> + * huc_ucode_xfer() - DMA's the firmware
> >>> + * @dev_priv: the drm device
> >>> + *
> >>> + * This function takes the gem object containing the firmware, sets
> >>> +up the DMA
> >>
> >>Hmm, this function takes just dev_priv...
> >
> >Oops.... will change the comment.
> >
> >Anusha
> >>
> >>> + * engine MMIO, triggers the DMA operation and waits for it to finish.
> >>> + *
> >>> + * Transfer the firmware image to RAM for execution by the microcontroller.
> >>> + *
> >>> + * Return: 0 on success, non-zero on failure  */ static int
> >>> +huc_ucode_xfer(struct drm_i915_private *dev_priv) {
> >>> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
> >>> +	struct i915_vma *vma;
> >>> +	unsigned long offset = 0;
> >>> +	u32 size;
> >>> +	int ret;
> >>> +
> >>> +	ret = i915_gem_object_set_to_gtt_domain(huc_fw->uc_fw_obj, false);
> >>> +	if (ret) {
> >>> +		DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
> >>> +		return ret;
> >>> +	}
> >>> +
> >>> +	vma = i915_gem_object_ggtt_pin(huc_fw->uc_fw_obj, NULL, 0, 0, 0);
> >>> +	if (IS_ERR(vma)) {
> >>> +		DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
> >>> +		return PTR_ERR(vma);
> >>> +	}
> >>> +
> >>> +	/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
> >>> +	I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
> >>> +
> >>> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
> >>> +
> >>> +	/* init WOPCM */
> >>> +	I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
> >>> +	I915_WRITE(DMA_GUC_WOPCM_OFFSET,
> >>GUC_WOPCM_OFFSET_VALUE |
> >>> +			HUC_LOADING_AGENT_GUC);
> >>> +
> >>> +	/* Set the source address for the uCode */
> >>> +	offset = i915_ggtt_offset(vma) + huc_fw->header_offset;
> >>> +	I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
> >>> +	I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
> >>> +
> >>> +	/* Hardware doesn't look at destination address for HuC. Set it to 0,
> >>> +	 * but still program the correct address space.
> >>> +	 */
> >>> +	I915_WRITE(DMA_ADDR_1_LOW, 0);
> >>> +	I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
> >>> +
> >>> +	size = huc_fw->header_size + huc_fw->ucode_size;
> >>> +	I915_WRITE(DMA_COPY_SIZE, size);
> >>> +
> >>> +	/* Start the DMA */
> >>> +	I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(HUC_UKERNEL |
> >>START_DMA));
> >>> +
> >>> +	/* Wait for DMA to finish */
> >>> +	ret = wait_for((I915_READ(DMA_CTRL) & START_DMA) == 0, 100);
> >>> +
> >>> +	DRM_DEBUG_DRIVER("HuC DMA transfer wait over with ret %d\n", ret);
> >>> +
> >>> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
> >>> +
> >>> +	/*
> >>> +	 * We keep the object pages for reuse during resume. But we can unpin it
> >>> +	 * now that DMA has completed, so it doesn't continue to take up space.
> >>> +	 */
> >>> +	i915_vma_unpin(vma);
> >>> +
> >>> +	return ret;
> >>> +}
> >>> +
> >>> +/**
> >>> + * intel_huc_init() - initiate HuC firmware loading request
> >>> + * @dev_priv: the drm_i915_private device
> >>> + *
> >>> + * Called early during driver load, but after GEM is initialised.
> >>> +The loading
> >>> + * will continue only when driver explicitly specify firmware name and
> >version.
> >>> + * All other cases are considered as INTEL_UC_FIRMWARE_NONE either
> >>> +because HW
> >>> + * is not capable or driver yet support it. And there will be no
> >>> +error message
> >>> + * for INTEL_UC_FIRMWARE_NONE cases.
> >>> + *
> >>> + * The DMA-copying to HW is done later when intel_huc_load() is called.
> >>> + */
> >>> +void intel_huc_init(struct drm_i915_private *dev_priv) {
> >>> +	struct intel_huc *huc = &dev_priv->huc;
> >>> +	struct intel_uc_fw *huc_fw = &huc->fw;
> >>> +	const char *fw_path = NULL;
> >>> +
> >>> +	huc_fw->uc_fw_path = NULL;
> >>> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
> >>> +	huc_fw->load_status = INTEL_UC_FIRMWARE_NONE;
> >>> +	huc_fw->fw_type = INTEL_UC_FW_TYPE_HUC;
> >>> +
> >>> +	if (!HAS_HUC_UCODE(dev_priv))
> >>> +		return;
> >>> +
> >>> +	if (IS_SKYLAKE(dev_priv)) {
> >>> +		fw_path = I915_SKL_HUC_UCODE;
> >>> +		huc_fw->major_ver_wanted = SKL_HUC_FW_MAJOR;
> >>> +		huc_fw->minor_ver_wanted = SKL_HUC_FW_MINOR;
> >>> +	}
> >>> +
> >>> +	huc_fw->uc_fw_path = fw_path;
> >>> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
> >>> +
> >>> +	DRM_DEBUG_DRIVER("HuC firmware pending, path %s\n", fw_path);
> >>> +
> >>> +	intel_uc_fw_fetch(dev_priv, huc_fw); }
> >>> +
> >>> +/**
> >>> + * intel_huc_load() - load HuC uCode to device
> >>> + * @dev_priv: the drm_i915_private device
> >>> + *
> >>> + * Called from gem_init_hw() during driver loading and also after a GPU reset.
> >>> + * Be note that HuC loading must be done before GuC loading.
> >>> + *
> >>> + * The firmware image should have already been fetched into memory
> >>> +by the
> >>> + * earlier call to intel_huc_init(), so here we need only check that
> >>> + * is succeeded, and then transfer the image to the h/w.
> >>> + *
> >>> + * Return:	non-zero code on error
> >>> + */
> >>> +int intel_huc_load(struct drm_i915_private *dev_priv) {
> >>> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
> >>> +	int err;
> >>> +
> >>> +	if (huc_fw->fetch_status == INTEL_UC_FIRMWARE_NONE)
> >>> +		return 0;
> >>> +
> >>> +	DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
> >>> +		huc_fw->uc_fw_path,
> >>> +		intel_uc_fw_status_repr(huc_fw->fetch_status),
> >>> +		intel_uc_fw_status_repr(huc_fw->load_status));
> >>> +
> >>> +	if (huc_fw->fetch_status == INTEL_UC_FIRMWARE_SUCCESS &&
> >>> +	    huc_fw->load_status == INTEL_UC_FIRMWARE_FAIL)
> >>> +		return -ENOEXEC;
> >>> +
> >>> +	huc_fw->load_status = INTEL_UC_FIRMWARE_PENDING;
> >>> +
> >>> +	switch (huc_fw->fetch_status) {
> >>> +	case INTEL_UC_FIRMWARE_FAIL:
> >>> +		/* something went wrong :( */
> >>> +		err = -EIO;
> >>> +		goto fail;
> >>> +
> >>> +	case INTEL_UC_FIRMWARE_NONE:
> >>> +	case INTEL_UC_FIRMWARE_PENDING:
> >>> +	default:
> >>> +		/* "can't happen" */
> >>> +		WARN_ONCE(1, "HuC fw %s invalid fetch_status %s [%d]\n",
> >>> +			huc_fw->uc_fw_path,
> >>> +			intel_uc_fw_status_repr(huc_fw->fetch_status),
> >>> +			huc_fw->fetch_status);
> >>> +		err = -ENXIO;
> >>> +		goto fail;
> >>> +
> >>> +	case INTEL_UC_FIRMWARE_SUCCESS:
> >>> +		break;
> >>> +	}
> >>> +
> >>> +	err = huc_ucode_xfer(dev_priv);
> >>> +	if (err)
> >>> +		goto fail;
> >>> +
> >>> +	huc_fw->load_status = INTEL_UC_FIRMWARE_SUCCESS;
> >>> +
> >>> +	DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
> >>> +		huc_fw->uc_fw_path,
> >>> +		intel_uc_fw_status_repr(huc_fw->fetch_status),
> >>> +		intel_uc_fw_status_repr(huc_fw->load_status));
> >>
> >>Hmm, this message will always display "fetch SUCCESS load SUCCESS"
> >>as all other cases all handled as fail below... is it expected ?
> 
> Yes. I think we need a message for the case when there is no failure.
> 
> >>> +
> >>> +	return 0;
> >>> +
> >>> +fail:
> >>> +	if (huc_fw->load_status == INTEL_UC_FIRMWARE_PENDING)
> >>> +		huc_fw->load_status = INTEL_UC_FIRMWARE_FAIL;
> >>> +
> >>> +	DRM_ERROR("Failed to complete HuC uCode load with ret %d\n", err);
> >>> +
> >>> +	return err;
> >>> +}
> >>> +
> >>> +/**
> >>> + * intel_huc_fini() - clean up resources allocated for HuC
> >>> + * @dev: the drm device
> >>> + *
> >>> + * Cleans up by releasing the huc firmware GEM obj.
> >>> + */
> >>> +void intel_huc_fini(struct drm_device *dev)
> >>
> >>Why this function takes dev? All other functions take dev_priv.
> 
> Last I heard this was the only function that took dev and there some WIP before we make it take dev_priv.
> Arek, can we change this now?

IIRC the refactoring that happened changed dev to dev_priv everywhere
where the latter was used exclusively. This patchset was changed
accordingly and this function was left with dev, as it uses it for lock
access.

But I see your point with being consistent.

> >>Michal
> >>
> >>> +{
> >>> +	struct drm_i915_private *dev_priv = to_i915(dev);
> >>> +	struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
> >>> +
> >>> +	mutex_lock(&dev->struct_mutex);
> >>> +	if (huc_fw->uc_fw_obj)
> >>> +		i915_gem_object_put(huc_fw->uc_fw_obj);
> >>> +	huc_fw->uc_fw_obj = NULL;
> >>> +	mutex_unlock(&dev->struct_mutex);
> >>> +
> >>> +	huc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE; }
> >>> +
> >>> diff --git a/drivers/gpu/drm/i915/intel_uc.h
> >>> b/drivers/gpu/drm/i915/intel_uc.h index ad140e2..57aef56 100644
> >>> --- a/drivers/gpu/drm/i915/intel_uc.h
> >>> +++ b/drivers/gpu/drm/i915/intel_uc.h
> >>> @@ -24,6 +24,9 @@
> >>>  #ifndef _INTEL_UC_H_
> >>>  #define _INTEL_UC_H_
> >>>
> >>> +#define HUC_STATUS2             _MMIO(0xD3B0)
> >>> +#define   HUC_FW_VERIFIED       (1<<7)
> >>> +
> >>>  #include "intel_guc_fwif.h"
> >>>  #include "i915_guc_reg.h"
> >>>  #include "intel_ringbuffer.h"
> >>> @@ -174,6 +177,13 @@ struct intel_guc {
> >>>  	struct mutex send_mutex;
> >>>  };
> >>>
> >>> +struct intel_huc {
> >>> +	/* Generic uC firmware management */
> >>> +	struct intel_uc_fw fw;
> >>> +
> >>> +	/* HuC-specific additions */
> >>> +};
> >>> +
> >>>  /* intel_uc.c */
> >>>  void intel_uc_init_early(struct drm_i915_private *dev_priv);  bool
> >>> intel_guc_recv(struct drm_i915_private *dev_priv, u32 *status); @@
> >>> -190,6 +200,9 @@ extern void intel_guc_fini(struct drm_i915_private
> >>> *dev_priv);  extern const char *intel_uc_fw_status_repr(enum
> >>> intel_uc_fw_status status);  extern int intel_guc_suspend(struct
> >>> drm_i915_private *dev_priv);  extern int intel_guc_resume(struct
> >>> drm_i915_private *dev_priv);
> >>> +void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
> >>> +	struct intel_uc_fw *uc_fw);
> >>> +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv);
> >>>
> >>>  /* i915_guc_submission.c */
> >>>  int i915_guc_submission_init(struct drm_i915_private *dev_priv); @@
> >>> -204,4 +217,9 @@ void i915_guc_register(struct drm_i915_private
> >>> *dev_priv);  void i915_guc_unregister(struct drm_i915_private
> >>> *dev_priv);  int i915_guc_log_control(struct drm_i915_private
> >>> *dev_priv, u64 control_val);
> >>>
> >>> +/* intel_huc_loader.c */
> >>> +void intel_huc_init(struct drm_i915_private *dev_priv); void
> >>> +intel_huc_fini(struct drm_device *dev); int intel_huc_load(struct
> >>> +drm_i915_private *dev_priv);
> >>> +
> >>>  #endif
> >>> --
> >>> 2.7.4
> >>>
> >>> _______________________________________________
> >>> Intel-gfx mailing list
> >>> Intel-gfx@lists.freedesktop.org
> >>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >_______________________________________________
> >Intel-gfx mailing list
> >Intel-gfx@lists.freedesktop.org
> >https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2017-01-14  1:17 [PATCH 0/8] " Anusha Srivatsa
@ 2017-01-14  1:17 ` Anusha Srivatsa
  0 siblings, 0 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2017-01-14  1:17 UTC (permalink / raw)
  To: intel-gfx

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v4: rebased on top of drm-tip.Update dev to dev_priv in
intel_uc_fw_fetch.
v5: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
from patch 1.Combine two different unions for huc and guc version,
reserved etc into one union with two structs.
v6: rebased. Change fw_type to enum.
v7: rebased. Rename the enum fw_type to intel_uc_fw_type.

Cc: Michal Wajdeczko <michal.wajdeczko.@intel.com>
Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_uc.h         |  6 +++++
 3 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 3202b32..ed1ab40 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -145,7 +145,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -172,9 +172,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -205,8 +212,16 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		struct {
+			uint32_t branch_client_version;
+			uint32_t sw_version;
+	} guc;
+		struct {
+			uint32_t sw_version;
+			uint32_t reserved;
+	} huc;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 5a2c86f..30801ee 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -595,7 +595,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw = NULL;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -612,19 +612,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		uc_fw->path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -648,21 +648,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(dev_priv)) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw) {
+	case INTEL_UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(dev_priv)) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
+		break;
+
+	case INTEL_UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 9bb8a1e..c2c3919 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -100,6 +100,11 @@ enum intel_uc_fw_status {
 	INTEL_UC_FIRMWARE_SUCCESS
 };
 
+enum intel_uc_fw_type {
+	INTEL_UC_FW_TYPE_GUC,
+	INTEL_UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -116,6 +121,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	enum intel_uc_fw_type fw;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2017-01-13 18:08 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
@ 2017-01-13 18:08 ` Anusha Srivatsa
  0 siblings, 0 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2017-01-13 18:08 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v4: rebased on top of drm-tip.Update dev to dev_priv in
intel_uc_fw_fetch.
v5: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
from patch 1.Combine two different unions for huc and guc version,
reserved etc into one union with two structs.
v6: rebased. Change fw_type to enum.
v7: rebased. Rename the enum fw_type to intel_uc_fw_type.

Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_uc.h         |  6 +++++
 3 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 3202b32..ed1ab40 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -145,7 +145,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -172,9 +172,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -205,8 +212,16 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		struct {
+			uint32_t branch_client_version;
+			uint32_t sw_version;
+	} guc;
+		struct {
+			uint32_t sw_version;
+			uint32_t reserved;
+	} huc;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 5a2c86f..30801ee 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -595,7 +595,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw = NULL;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -612,19 +612,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		uc_fw->path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -648,21 +648,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(dev_priv)) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw) {
+	case INTEL_UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(dev_priv)) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
+		break;
+
+	case INTEL_UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 9bb8a1e..c2c3919 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -100,6 +100,11 @@ enum intel_uc_fw_status {
 	INTEL_UC_FIRMWARE_SUCCESS
 };
 
+enum intel_uc_fw_type {
+	INTEL_UC_FW_TYPE_GUC,
+	INTEL_UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -116,6 +121,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	enum intel_uc_fw_type fw;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
@ 2017-01-13 17:06 Anusha Srivatsa
  0 siblings, 0 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2017-01-13 17:06 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v4: rebased on top of drm-tip.Update dev to dev_priv in
intel_uc_fw_fetch.
v5: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
from patch 1.Combine two different unions for huc and guc version,
reserved etc into one union with two structs.
v6: rebased. Change fw_type to enum.
v7: rebased. Rename the enum fw_type to intel_uc_fw_type.

Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_uc.h         |  6 +++++
 3 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 3202b32..ed1ab40 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -145,7 +145,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -172,9 +172,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -205,8 +212,16 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		struct {
+			uint32_t branch_client_version;
+			uint32_t sw_version;
+	} guc;
+		struct {
+			uint32_t sw_version;
+			uint32_t reserved;
+	} huc;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 9071575..8ca2f62 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -594,7 +594,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw = NULL;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -611,19 +611,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		uc_fw->path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -647,21 +647,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(dev_priv)) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw) {
+	case INTEL_UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(dev_priv)) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
+		break;
+
+	case INTEL_UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 9bb8a1e..c2c3919 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -100,6 +100,11 @@ enum intel_uc_fw_status {
 	INTEL_UC_FIRMWARE_SUCCESS
 };
 
+enum intel_uc_fw_type {
+	INTEL_UC_FW_TYPE_GUC,
+	INTEL_UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -116,6 +121,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	enum intel_uc_fw_type fw;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2017-01-04 14:55 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
@ 2017-01-04 15:10   ` Arkadiusz Hiler
  0 siblings, 0 replies; 50+ messages in thread
From: Arkadiusz Hiler @ 2017-01-04 15:10 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx, Alex Dai, Peter Antoine

On Wed, Jan 04, 2017 at 06:55:49AM -0800, Anusha Srivatsa wrote:
> From: Peter Antoine <peter.antoine@intel.com>
> 
> HuC firmware css header has almost exactly same definition as GuC
> firmware except for the sw_version. Also, add a new member fw_type
> into intel_uc_fw to indicate what kind of fw it is. So, the loader
> will pull right sw_version from header.
> 
> v2: rebased on-top of drm-intel-nightly
> v3: rebased on-top of drm-intel-nightly (again).
> v4: rebased + spaces.
> v7: rebased.
> v8: rebased.
> v9: rebased. Rename device_id to guc_branch_client_version,
> make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
> and UC_FW_TYPE_HUC into an enum.
> v10: rebased.
> v11: rebased.
> v12: rebased on top of drm-tip.
> v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
> v14: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
> from patch 1.Combine two different unions for huc and guc version,
> reserved etc into one union with two structs.
> v15: rebased.
> v16: rebased. Change fw_type to enum.
> 
> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++++++++++++++----
>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
>  drivers/gpu/drm/i915/intel_uc.h         |  6 +++++
>  3 files changed, 53 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
> index 3202b32..ed1ab40 100644
> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
> @@ -145,7 +145,7 @@
>   * The GuC firmware layout looks like this:
>   *
>   *     +-------------------------------+
> - *     |        guc_css_header         |
> + *     |         uc_css_header         |
>   *     |                               |
>   *     | contains major/minor version  |
>   *     +-------------------------------+
> @@ -172,9 +172,16 @@
>   * 3. Length info of each component can be found in header, in dwords.
>   * 4. Modulus and exponent key are not required by driver. They may not appear
>   *    in fw. So driver will load a truncated firmware in this case.
> + *
> + * HuC firmware layout is same as GuC firmware.
> + *
> + * HuC firmware css header is different. However, the only difference is where
> + * the version information is saved. The uc_css_header is unified to support
> + * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
> + * uc_css_header.guc_sw_version for GuC.
>   */
>  
> -struct guc_css_header {
> +struct uc_css_header {
>  	uint32_t module_type;
>  	/* header_size includes all non-uCode bits, including css_header, rsa
>  	 * key, modulus key and exponent data. */
> @@ -205,8 +212,16 @@ struct guc_css_header {
>  
>  	char username[8];
>  	char buildnumber[12];
> -	uint32_t device_id;
> -	uint32_t guc_sw_version;
> +	union {
> +		struct {
> +			uint32_t branch_client_version;
> +			uint32_t sw_version;
> +	} guc;
> +		struct {
> +			uint32_t sw_version;
> +			uint32_t reserved;
> +	} huc;
> +	};
>  	uint32_t prod_preprod_fw;
>  	uint32_t reserved[12];
>  	uint32_t header_info;
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> index a55cfa7..68af7ae 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>  	struct pci_dev *pdev = dev_priv->drm.pdev;
>  	struct drm_i915_gem_object *obj;
>  	const struct firmware *fw = NULL;
> -	struct guc_css_header *css;
> +	struct uc_css_header *css;
>  	size_t size;
>  	int err;
>  
> @@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>  		uc_fw->path, fw);
>  
>  	/* Check the size of the blob before examining buffer contents */
> -	if (fw->size < sizeof(struct guc_css_header)) {
> +	if (fw->size < sizeof(struct uc_css_header)) {
>  		DRM_NOTE("Firmware header is missing\n");
>  		goto fail;
>  	}
>  
> -	css = (struct guc_css_header *)fw->data;
> +	css = (struct uc_css_header *)fw->data;
>  
>  	/* Firmware bits always start from header */
>  	uc_fw->header_offset = 0;
>  	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
>  
> -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
> +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>  		DRM_NOTE("CSS header definition mismatch\n");
>  		goto fail;
>  	}
> @@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>  		goto fail;
>  	}
>  
> -	/* Header and uCode will be loaded to WOPCM. Size of the two. */
> -	size = uc_fw->header_size + uc_fw->ucode_size;
> -	if (size > guc_wopcm_size(dev_priv)) {
> -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
> -		goto fail;
> -	}
> -
>  	/*
>  	 * The GuC firmware image has the version number embedded at a well-known
>  	 * offset within the firmware blob; note that major / minor version are
>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
>  	 * in terms of bytes (u8).
>  	 */
> -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
> -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> +	switch (uc_fw->fw) {
> +	case INTEL_UC_FW_TYPE_GUC:
> +		/* Header and uCode will be loaded to WOPCM. Size of the two. */
> +		size = uc_fw->header_size + uc_fw->ucode_size;
> +
> +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
> +		if (size > guc_wopcm_size(dev_priv)) {
> +			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
> +			goto fail;
> +		}
> +		uc_fw->major_ver_found = css->guc.sw_version >> 16;
> +		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
> +		break;
> +
> +	case INTEL_UC_FW_TYPE_HUC:
> +		uc_fw->major_ver_found = css->huc.sw_version >> 16;
> +		uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
> +		break;
> +
> +	default:
> +		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw);
> +		err = -ENOEXEC;
> +		goto fail;
> +	}
>  
>  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
> diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
> index 2634b57..f8ee571 100644
> --- a/drivers/gpu/drm/i915/intel_uc.h
> +++ b/drivers/gpu/drm/i915/intel_uc.h
> @@ -100,6 +100,11 @@ enum intel_uc_fw_status {
>  	INTEL_UC_FIRMWARE_SUCCESS
>  };
>  
> +enum fw_type{

WARNING: missing space after enum definition
#180: FILE: drivers/gpu/drm/i915/intel_uc.h:103:

with the space fixed
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>


> +	INTEL_UC_FW_TYPE_GUC,
> +	INTEL_UC_FW_TYPE_HUC
> +};
> +
>  /*
>   * This structure encapsulates all the data needed during the process
>   * of fetching, caching, and loading the firmware image into the GuC.
> @@ -116,6 +121,7 @@ struct intel_uc_fw {
>  	uint16_t major_ver_found;
>  	uint16_t minor_ver_found;
>  
> +	enum fw_type fw;
>  	uint32_t header_size;
>  	uint32_t header_offset;
>  	uint32_t rsa_size;
> -- 
> 2.7.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2017-01-04 14:55 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
@ 2017-01-04 14:55 ` Anusha Srivatsa
  2017-01-04 15:10   ` Arkadiusz Hiler
  0 siblings, 1 reply; 50+ messages in thread
From: Anusha Srivatsa @ 2017-01-04 14:55 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.
v9: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip.
v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
v14: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
from patch 1.Combine two different unions for huc and guc version,
reserved etc into one union with two structs.
v15: rebased.
v16: rebased. Change fw_type to enum.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_uc.h         |  6 +++++
 3 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 3202b32..ed1ab40 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -145,7 +145,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -172,9 +172,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -205,8 +212,16 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		struct {
+			uint32_t branch_client_version;
+			uint32_t sw_version;
+	} guc;
+		struct {
+			uint32_t sw_version;
+			uint32_t reserved;
+	} huc;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index a55cfa7..68af7ae 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw = NULL;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		uc_fw->path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(dev_priv)) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw) {
+	case INTEL_UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(dev_priv)) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
+		break;
+
+	case INTEL_UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 2634b57..f8ee571 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -100,6 +100,11 @@ enum intel_uc_fw_status {
 	INTEL_UC_FIRMWARE_SUCCESS
 };
 
+enum fw_type{
+	INTEL_UC_FW_TYPE_GUC,
+	INTEL_UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -116,6 +121,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	enum fw_type fw;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2017-01-04 13:27 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
@ 2017-01-04 13:27 ` Anusha Srivatsa
  0 siblings, 0 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2017-01-04 13:27 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.
v9: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip.
v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
v14: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
from patch 1.Combine two different unions for huc and guc version,
reserved etc into one union with two structs.
v15: rebased.
v16: rebased. Change fw_type to enum.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_uc.h         |  6 +++++
 3 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 3202b32..ed1ab40 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -145,7 +145,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -172,9 +172,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -205,8 +212,16 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		struct {
+			uint32_t branch_client_version;
+			uint32_t sw_version;
+	} guc;
+		struct {
+			uint32_t sw_version;
+			uint32_t reserved;
+	} huc;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 15215b7..a4196e2 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw = NULL;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(dev_priv)) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw) {
+	case INTEL_UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(dev_priv)) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
+		break;
+
+	case INTEL_UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 7986f22..efc125d 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -100,6 +100,11 @@ enum intel_uc_fw_status {
 	INTEL_UC_FIRMWARE_SUCCESS
 };
 
+enum fw_type{
+	INTEL_UC_FW_TYPE_GUC,
+	INTEL_UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -116,6 +121,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	enum fw_type fw;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-12-15 22:29 [PATCH 0/8] HuC Loading Patches anushasr
@ 2016-12-15 22:29 ` anushasr
  0 siblings, 0 replies; 50+ messages in thread
From: anushasr @ 2016-12-15 22:29 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.
v9: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip.
v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
v14: rebased. Add INTEL_ prefix to an enum. Add fw_type declaration
from patch 1.Combine two different unions for huc and guc version,
reserved etc into one union with two structs.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 23 ++++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_uc.h         |  6 +++++
 3 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 3202b32..ed1ab40 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -145,7 +145,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -172,9 +172,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -205,8 +212,16 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		struct {
+			uint32_t branch_client_version;
+			uint32_t sw_version;
+	} guc;
+		struct {
+			uint32_t sw_version;
+			uint32_t reserved;
+	} huc;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 9b3dbea..09e463b 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw = NULL;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(dev_priv)) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw_type) {
+	case INTEL_UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(dev_priv)) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
+		break;
+
+	case INTEL_UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc.sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index 893bcec..ad140e2 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -98,6 +98,11 @@ enum intel_uc_fw_status {
 	INTEL_UC_FIRMWARE_SUCCESS
 };
 
+enum {
+	INTEL_UC_FW_TYPE_GUC,
+	INTEL_UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -114,6 +119,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	uint32_t fw_type;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-12-09 21:42     ` Srivatsa, Anusha
@ 2016-12-12 11:56       ` Arkadiusz Hiler
  0 siblings, 0 replies; 50+ messages in thread
From: Arkadiusz Hiler @ 2016-12-12 11:56 UTC (permalink / raw)
  To: Srivatsa, Anusha; +Cc: intel-gfx, Michal Wajdeczko

On Fri, Dec 09, 2016 at 09:42:06PM +0000, Srivatsa, Anusha wrote:
> 
> 
> >-----Original Message-----
> >From: Michal Wajdeczko [mailto:michal.wajdeczko@linux.intel.com]
> >Sent: Friday, December 9, 2016 3:56 AM
> >To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
> >Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter Antoine
> ><peter.antoine@intel.com>
> >Subject: Re: [Intel-gfx] [PATCH 2/8] drm/i915/huc: Unified css_header struct for
> >GuC and HuC
> >
> >On Thu, Dec 08, 2016 at 03:02:13PM -0800, anushasr wrote:
> >> From: Peter Antoine <peter.antoine@intel.com>
> >>
> >> HuC firmware css header has almost exactly same definition as GuC
> >> firmware except for the sw_version. Also, add a new member fw_type
> >> into intel_uc_fw to indicate what kind of fw it is. So, the loader
> >> will pull right sw_version from header.
> >>
> >> v2: rebased on-top of drm-intel-nightly
> >> v3: rebased on-top of drm-intel-nightly (again).
> >> v4: rebased + spaces.
> >> v7: rebased.
> >> v8: rebased.
> >> v9: rebased. Rename device_id to guc_branch_client_version, make
> >> guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC and
> >> UC_FW_TYPE_HUC into an enum.
> >> v10: rebased.
> >> v11: rebased.
> >> v12: rebased on top of drm-tip.
> >> v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
> >>
> >> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> >> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> >> Signed-off-by: Alex Dai <yu.dai@intel.com>
> >> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
> >>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-------
> >----
> >>  drivers/gpu/drm/i915/intel_uc.h         |  5 ++++
> >>  3 files changed, 50 insertions(+), 17 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h
> >> b/drivers/gpu/drm/i915/intel_guc_fwif.h
> >> index 3202b32..c1e7faf 100644
> >> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
> >> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
> >> @@ -145,7 +145,7 @@
> >>   * The GuC firmware layout looks like this:
> >>   *
> >>   *     +-------------------------------+
> >> - *     |        guc_css_header         |
> >> + *     |         uc_css_header         |
> >>   *     |                               |
> >>   *     | contains major/minor version  |
> >>   *     +-------------------------------+
> >> @@ -172,9 +172,16 @@
> >>   * 3. Length info of each component can be found in header, in dwords.
> >>   * 4. Modulus and exponent key are not required by driver. They may not
> >appear
> >>   *    in fw. So driver will load a truncated firmware in this case.
> >> + *
> >> + * HuC firmware layout is same as GuC firmware.
> >> + *
> >> + * HuC firmware css header is different. However, the only difference
> >> + is where
> >> + * the version information is saved. The uc_css_header is unified to
> >> + support
> >> + * both. Driver should get HuC version from
> >> + uc_css_header.huc_sw_version, while
> >> + * uc_css_header.guc_sw_version for GuC.
> >>   */
> >>
> >> -struct guc_css_header {
> >> +struct uc_css_header {
> >
> >Hmm, I'm wondering why we don't use "intel_uc_" prefix for structs defined here.
> >It seems that only enums are defined with intel_ prefix.
> If we rename it to intel_uc_css_header, wont it be confused with intel_css_header in intel_csr.c? Unles we want to combine them....
> 
> >Also, it looks that this struct definition is very similar to the intel_css_header
> >defined in intel_csr.c. Are there any plans to unify them all ?
> >
> No idea about any plans regarding unifying the struct in intel_csr.c and this struct. Arek, any idea?

Currently not, but that seems like idea worth exploring. I'll look into
it this week and if it turns sensible to do, I'll add it to my GuC
cleanup series.

> >>  	uint32_t module_type;
> >
> >What values are used here? Are they the same as used in fw_type?

module_type is just a part of HuC/GuC's firmware header (css). You can
read it from the blobs:

module_type for guc == 0006 0000 00a1 0000 (v6, v4)
module_type for huc == 0006 0000 00a1 0000 (v1)

It's kind of magic value to determine it's a firmware (I am not aware of
other values than the one above, but that might change in the future).
We do not check for that exact field though. We do not use it at all,
but that, as well,  might change in the future.

fw_type provides means to distingush between HuC/GuC FW.

> >
> >>  	/* header_size includes all non-uCode bits, including css_header, rsa
> >>  	 * key, modulus key and exponent data. */ @@ -205,8 +212,14 @@
> >> struct guc_css_header {
> >>
> >>  	char username[8];
> >>  	char buildnumber[12];
> >> -	uint32_t device_id;
> >> -	uint32_t guc_sw_version;
> >> +	union {
> >> +		uint32_t guc_branch_client_version;
> >> +		uint32_t huc_sw_version;
> >> +	};
> >> +	union {
> >> +		uint32_t guc_sw_version;
> >> +		uint32_t huc_reserved;
> >> +	};
> >
> >Maybe to make this a little easier to read we can use:
> >
> >union {
> >  struct {
> >    uint32_t branch_client_version;
> >    uint32_t sw_version;
> >  } guc;
> >  struct {
> >    uint32_t sw_version;
> >    unit32_t reserved;
> >  } huc;
> >};
> Yes. Will do.
> >
> >>  	uint32_t prod_preprod_fw;
> >>  	uint32_t reserved[12];
> >>  	uint32_t header_info;
> >> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c
> >> b/drivers/gpu/drm/i915/intel_guc_loader.c
> >> index 8f04f6e..26a184f 100644
> >> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> >> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> >> @@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private
> >*dev_priv,
> >>  	struct pci_dev *pdev = dev_priv->drm.pdev;
> >>  	struct drm_i915_gem_object *obj;
> >>  	const struct firmware *fw = NULL;
> >> -	struct guc_css_header *css;
> >> +	struct uc_css_header *css;
> >>  	size_t size;
> >>  	int err;
> >>
> >> @@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private
> >*dev_priv,
> >>  		uc_fw->uc_fw_path, fw);
> >>
> >>  	/* Check the size of the blob before examining buffer contents */
> >> -	if (fw->size < sizeof(struct guc_css_header)) {
> >> +	if (fw->size < sizeof(struct uc_css_header)) {
> >>  		DRM_NOTE("Firmware header is missing\n");
> >>  		goto fail;
> >>  	}
> >>
> >> -	css = (struct guc_css_header *)fw->data;
> >> +	css = (struct uc_css_header *)fw->data;
> >>
> >>  	/* Firmware bits always start from header */
> >>  	uc_fw->header_offset = 0;
> >>  	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
> >>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
> >>
> >> -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
> >> +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
> >>  		DRM_NOTE("CSS header definition mismatch\n");
> >>  		goto fail;
> >>  	}
> >> @@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private
> >*dev_priv,
> >>  		goto fail;
> >>  	}
> >>
> >> -	/* Header and uCode will be loaded to WOPCM. Size of the two. */
> >> -	size = uc_fw->header_size + uc_fw->ucode_size;
> >> -	if (size > guc_wopcm_size(dev_priv)) {
> >> -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
> >> -		goto fail;
> >> -	}
> >> -
> >>  	/*
> >>  	 * The GuC firmware image has the version number embedded at a well-
> >known
> >>  	 * offset within the firmware blob; note that major / minor version are
> >>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
> >>  	 * in terms of bytes (u8).
> >>  	 */
> >> -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
> >> -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> >> +	switch (uc_fw->fw_type) {
> >> +	case UC_FW_TYPE_GUC:
> >> +		/* Header and uCode will be loaded to WOPCM. Size of the two.
> >*/
> >> +		size = uc_fw->header_size + uc_fw->ucode_size;
> >> +
> >> +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context).
> >*/
> >> +		if (size > guc_wopcm_size(dev_priv)) {
> >> +			DRM_ERROR("Firmware is too large to fit in
> >WOPCM\n");
> >> +			goto fail;
> >> +		}
> >> +		uc_fw->major_ver_found = css->guc_sw_version >> 16;
> >> +		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> >> +		break;
> >> +
> >> +	case UC_FW_TYPE_HUC:
> >> +		uc_fw->major_ver_found = css->huc_sw_version >> 16;
> >> +		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
> >> +		break;
> >> +
> >> +	default:
> >> +		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
> >> +		err = -ENOEXEC;
> >> +		goto fail;
> >> +	}
> >>
> >>  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
> >>  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) { diff --git
> >> a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
> >> index f9f598d..be89f0b 100644
> >> --- a/drivers/gpu/drm/i915/intel_uc.h
> >> +++ b/drivers/gpu/drm/i915/intel_uc.h
> >> @@ -98,6 +98,11 @@ enum intel_uc_fw_status {
> >>  	UC_FIRMWARE_SUCCESS
> >>  };
> >>
> >> +enum {
> >> +	UC_FW_TYPE_GUC,
> >> +	UC_FW_TYPE_HUC
> >
> >Can we have INTEL_ prefix here?
> >
> >> +};
> >> Yes. Thanks Michal.
> 
> 
> Anusha
> >>  /*
> >>   * This structure encapsulates all the data needed during the process
> >>   * of fetching, caching, and loading the firmware image into the GuC.
> >> --
> >> 2.7.4
> >>
> >> _______________________________________________
> >> Intel-gfx mailing list
> >> Intel-gfx@lists.freedesktop.org
> >> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-12-09 11:55   ` Michal Wajdeczko
@ 2016-12-09 21:42     ` Srivatsa, Anusha
  2016-12-12 11:56       ` Arkadiusz Hiler
  0 siblings, 1 reply; 50+ messages in thread
From: Srivatsa, Anusha @ 2016-12-09 21:42 UTC (permalink / raw)
  To: Michal Wajdeczko; +Cc: intel-gfx



>-----Original Message-----
>From: Michal Wajdeczko [mailto:michal.wajdeczko@linux.intel.com]
>Sent: Friday, December 9, 2016 3:56 AM
>To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
>Cc: intel-gfx@lists.freedesktop.org; Alex Dai <yu.dai@intel.com>; Peter Antoine
><peter.antoine@intel.com>
>Subject: Re: [Intel-gfx] [PATCH 2/8] drm/i915/huc: Unified css_header struct for
>GuC and HuC
>
>On Thu, Dec 08, 2016 at 03:02:13PM -0800, anushasr wrote:
>> From: Peter Antoine <peter.antoine@intel.com>
>>
>> HuC firmware css header has almost exactly same definition as GuC
>> firmware except for the sw_version. Also, add a new member fw_type
>> into intel_uc_fw to indicate what kind of fw it is. So, the loader
>> will pull right sw_version from header.
>>
>> v2: rebased on-top of drm-intel-nightly
>> v3: rebased on-top of drm-intel-nightly (again).
>> v4: rebased + spaces.
>> v7: rebased.
>> v8: rebased.
>> v9: rebased. Rename device_id to guc_branch_client_version, make
>> guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC and
>> UC_FW_TYPE_HUC into an enum.
>> v10: rebased.
>> v11: rebased.
>> v12: rebased on top of drm-tip.
>> v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
>>
>> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
>> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
>> Signed-off-by: Alex Dai <yu.dai@intel.com>
>> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
>>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-------
>----
>>  drivers/gpu/drm/i915/intel_uc.h         |  5 ++++
>>  3 files changed, 50 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h
>> b/drivers/gpu/drm/i915/intel_guc_fwif.h
>> index 3202b32..c1e7faf 100644
>> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
>> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
>> @@ -145,7 +145,7 @@
>>   * The GuC firmware layout looks like this:
>>   *
>>   *     +-------------------------------+
>> - *     |        guc_css_header         |
>> + *     |         uc_css_header         |
>>   *     |                               |
>>   *     | contains major/minor version  |
>>   *     +-------------------------------+
>> @@ -172,9 +172,16 @@
>>   * 3. Length info of each component can be found in header, in dwords.
>>   * 4. Modulus and exponent key are not required by driver. They may not
>appear
>>   *    in fw. So driver will load a truncated firmware in this case.
>> + *
>> + * HuC firmware layout is same as GuC firmware.
>> + *
>> + * HuC firmware css header is different. However, the only difference
>> + is where
>> + * the version information is saved. The uc_css_header is unified to
>> + support
>> + * both. Driver should get HuC version from
>> + uc_css_header.huc_sw_version, while
>> + * uc_css_header.guc_sw_version for GuC.
>>   */
>>
>> -struct guc_css_header {
>> +struct uc_css_header {
>
>Hmm, I'm wondering why we don't use "intel_uc_" prefix for structs defined here.
>It seems that only enums are defined with intel_ prefix.
If we rename it to intel_uc_css_header, wont it be confused with intel_css_header in intel_csr.c? Unles we want to combine them....

>Also, it looks that this struct definition is very similar to the intel_css_header
>defined in intel_csr.c. Are there any plans to unify them all ?
>
No idea about any plans regarding unifying the struct in intel_csr.c and this struct. Arek, any idea?
>>  	uint32_t module_type;
>
>What values are used here? Are they the same as used in fw_type?
>
>
>>  	/* header_size includes all non-uCode bits, including css_header, rsa
>>  	 * key, modulus key and exponent data. */ @@ -205,8 +212,14 @@
>> struct guc_css_header {
>>
>>  	char username[8];
>>  	char buildnumber[12];
>> -	uint32_t device_id;
>> -	uint32_t guc_sw_version;
>> +	union {
>> +		uint32_t guc_branch_client_version;
>> +		uint32_t huc_sw_version;
>> +	};
>> +	union {
>> +		uint32_t guc_sw_version;
>> +		uint32_t huc_reserved;
>> +	};
>
>Maybe to make this a little easier to read we can use:
>
>union {
>  struct {
>    uint32_t branch_client_version;
>    uint32_t sw_version;
>  } guc;
>  struct {
>    uint32_t sw_version;
>    unit32_t reserved;
>  } huc;
>};
Yes. Will do.
>
>>  	uint32_t prod_preprod_fw;
>>  	uint32_t reserved[12];
>>  	uint32_t header_info;
>> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c
>> b/drivers/gpu/drm/i915/intel_guc_loader.c
>> index 8f04f6e..26a184f 100644
>> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
>> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
>> @@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private
>*dev_priv,
>>  	struct pci_dev *pdev = dev_priv->drm.pdev;
>>  	struct drm_i915_gem_object *obj;
>>  	const struct firmware *fw = NULL;
>> -	struct guc_css_header *css;
>> +	struct uc_css_header *css;
>>  	size_t size;
>>  	int err;
>>
>> @@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private
>*dev_priv,
>>  		uc_fw->uc_fw_path, fw);
>>
>>  	/* Check the size of the blob before examining buffer contents */
>> -	if (fw->size < sizeof(struct guc_css_header)) {
>> +	if (fw->size < sizeof(struct uc_css_header)) {
>>  		DRM_NOTE("Firmware header is missing\n");
>>  		goto fail;
>>  	}
>>
>> -	css = (struct guc_css_header *)fw->data;
>> +	css = (struct uc_css_header *)fw->data;
>>
>>  	/* Firmware bits always start from header */
>>  	uc_fw->header_offset = 0;
>>  	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
>>
>> -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
>> +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>>  		DRM_NOTE("CSS header definition mismatch\n");
>>  		goto fail;
>>  	}
>> @@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private
>*dev_priv,
>>  		goto fail;
>>  	}
>>
>> -	/* Header and uCode will be loaded to WOPCM. Size of the two. */
>> -	size = uc_fw->header_size + uc_fw->ucode_size;
>> -	if (size > guc_wopcm_size(dev_priv)) {
>> -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
>> -		goto fail;
>> -	}
>> -
>>  	/*
>>  	 * The GuC firmware image has the version number embedded at a well-
>known
>>  	 * offset within the firmware blob; note that major / minor version are
>>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
>>  	 * in terms of bytes (u8).
>>  	 */
>> -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
>> -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
>> +	switch (uc_fw->fw_type) {
>> +	case UC_FW_TYPE_GUC:
>> +		/* Header and uCode will be loaded to WOPCM. Size of the two.
>*/
>> +		size = uc_fw->header_size + uc_fw->ucode_size;
>> +
>> +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context).
>*/
>> +		if (size > guc_wopcm_size(dev_priv)) {
>> +			DRM_ERROR("Firmware is too large to fit in
>WOPCM\n");
>> +			goto fail;
>> +		}
>> +		uc_fw->major_ver_found = css->guc_sw_version >> 16;
>> +		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
>> +		break;
>> +
>> +	case UC_FW_TYPE_HUC:
>> +		uc_fw->major_ver_found = css->huc_sw_version >> 16;
>> +		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
>> +		break;
>> +
>> +	default:
>> +		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
>> +		err = -ENOEXEC;
>> +		goto fail;
>> +	}
>>
>>  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>>  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) { diff --git
>> a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
>> index f9f598d..be89f0b 100644
>> --- a/drivers/gpu/drm/i915/intel_uc.h
>> +++ b/drivers/gpu/drm/i915/intel_uc.h
>> @@ -98,6 +98,11 @@ enum intel_uc_fw_status {
>>  	UC_FIRMWARE_SUCCESS
>>  };
>>
>> +enum {
>> +	UC_FW_TYPE_GUC,
>> +	UC_FW_TYPE_HUC
>
>Can we have INTEL_ prefix here?
>
>> +};
>> Yes. Thanks Michal.


Anusha
>>  /*
>>   * This structure encapsulates all the data needed during the process
>>   * of fetching, caching, and loading the firmware image into the GuC.
>> --
>> 2.7.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-12-08 23:02 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC anushasr
  2016-12-09  9:20   ` Arkadiusz Hiler
@ 2016-12-09 11:55   ` Michal Wajdeczko
  2016-12-09 21:42     ` Srivatsa, Anusha
  1 sibling, 1 reply; 50+ messages in thread
From: Michal Wajdeczko @ 2016-12-09 11:55 UTC (permalink / raw)
  To: anushasr; +Cc: intel-gfx, Alex Dai, Peter Antoine

On Thu, Dec 08, 2016 at 03:02:13PM -0800, anushasr wrote:
> From: Peter Antoine <peter.antoine@intel.com>
> 
> HuC firmware css header has almost exactly same definition as GuC
> firmware except for the sw_version. Also, add a new member fw_type
> into intel_uc_fw to indicate what kind of fw it is. So, the loader
> will pull right sw_version from header.
> 
> v2: rebased on-top of drm-intel-nightly
> v3: rebased on-top of drm-intel-nightly (again).
> v4: rebased + spaces.
> v7: rebased.
> v8: rebased.
> v9: rebased. Rename device_id to guc_branch_client_version,
> make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
> and UC_FW_TYPE_HUC into an enum.
> v10: rebased.
> v11: rebased.
> v12: rebased on top of drm-tip.
> v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
> 
> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
>  drivers/gpu/drm/i915/intel_uc.h         |  5 ++++
>  3 files changed, 50 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
> index 3202b32..c1e7faf 100644
> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
> @@ -145,7 +145,7 @@
>   * The GuC firmware layout looks like this:
>   *
>   *     +-------------------------------+
> - *     |        guc_css_header         |
> + *     |         uc_css_header         |
>   *     |                               |
>   *     | contains major/minor version  |
>   *     +-------------------------------+
> @@ -172,9 +172,16 @@
>   * 3. Length info of each component can be found in header, in dwords.
>   * 4. Modulus and exponent key are not required by driver. They may not appear
>   *    in fw. So driver will load a truncated firmware in this case.
> + *
> + * HuC firmware layout is same as GuC firmware.
> + *
> + * HuC firmware css header is different. However, the only difference is where
> + * the version information is saved. The uc_css_header is unified to support
> + * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
> + * uc_css_header.guc_sw_version for GuC.
>   */
>  
> -struct guc_css_header {
> +struct uc_css_header {

Hmm, I'm wondering why we don't use "intel_uc_" prefix for structs defined here.
It seems that only enums are defined with intel_ prefix.

Also, it looks that this struct definition is very similar to the intel_css_header
defined in intel_csr.c. Are there any plans to unify them all ?


>  	uint32_t module_type;

What values are used here? Are they the same as used in fw_type?


>  	/* header_size includes all non-uCode bits, including css_header, rsa
>  	 * key, modulus key and exponent data. */
> @@ -205,8 +212,14 @@ struct guc_css_header {
>  
>  	char username[8];
>  	char buildnumber[12];
> -	uint32_t device_id;
> -	uint32_t guc_sw_version;
> +	union {
> +		uint32_t guc_branch_client_version;
> +		uint32_t huc_sw_version;
> +	};
> +	union {
> +		uint32_t guc_sw_version;
> +		uint32_t huc_reserved;
> +	};

Maybe to make this a little easier to read we can use:

union {
  struct {
    uint32_t branch_client_version;
    uint32_t sw_version;
  } guc;
  struct {
    uint32_t sw_version;
    unit32_t reserved;
  } huc;
};


>  	uint32_t prod_preprod_fw;
>  	uint32_t reserved[12];
>  	uint32_t header_info;
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> index 8f04f6e..26a184f 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>  	struct pci_dev *pdev = dev_priv->drm.pdev;
>  	struct drm_i915_gem_object *obj;
>  	const struct firmware *fw = NULL;
> -	struct guc_css_header *css;
> +	struct uc_css_header *css;
>  	size_t size;
>  	int err;
>  
> @@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>  		uc_fw->uc_fw_path, fw);
>  
>  	/* Check the size of the blob before examining buffer contents */
> -	if (fw->size < sizeof(struct guc_css_header)) {
> +	if (fw->size < sizeof(struct uc_css_header)) {
>  		DRM_NOTE("Firmware header is missing\n");
>  		goto fail;
>  	}
>  
> -	css = (struct guc_css_header *)fw->data;
> +	css = (struct uc_css_header *)fw->data;
>  
>  	/* Firmware bits always start from header */
>  	uc_fw->header_offset = 0;
>  	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
>  
> -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
> +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>  		DRM_NOTE("CSS header definition mismatch\n");
>  		goto fail;
>  	}
> @@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
>  		goto fail;
>  	}
>  
> -	/* Header and uCode will be loaded to WOPCM. Size of the two. */
> -	size = uc_fw->header_size + uc_fw->ucode_size;
> -	if (size > guc_wopcm_size(dev_priv)) {
> -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
> -		goto fail;
> -	}
> -
>  	/*
>  	 * The GuC firmware image has the version number embedded at a well-known
>  	 * offset within the firmware blob; note that major / minor version are
>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
>  	 * in terms of bytes (u8).
>  	 */
> -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
> -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> +	switch (uc_fw->fw_type) {
> +	case UC_FW_TYPE_GUC:
> +		/* Header and uCode will be loaded to WOPCM. Size of the two. */
> +		size = uc_fw->header_size + uc_fw->ucode_size;
> +
> +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
> +		if (size > guc_wopcm_size(dev_priv)) {
> +			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
> +			goto fail;
> +		}
> +		uc_fw->major_ver_found = css->guc_sw_version >> 16;
> +		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> +		break;
> +
> +	case UC_FW_TYPE_HUC:
> +		uc_fw->major_ver_found = css->huc_sw_version >> 16;
> +		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
> +		break;
> +
> +	default:
> +		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
> +		err = -ENOEXEC;
> +		goto fail;
> +	}
>  
>  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
> diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
> index f9f598d..be89f0b 100644
> --- a/drivers/gpu/drm/i915/intel_uc.h
> +++ b/drivers/gpu/drm/i915/intel_uc.h
> @@ -98,6 +98,11 @@ enum intel_uc_fw_status {
>  	UC_FIRMWARE_SUCCESS
>  };
>  
> +enum {
> +	UC_FW_TYPE_GUC,
> +	UC_FW_TYPE_HUC

Can we have INTEL_ prefix here?

> +};
> +
>  /*
>   * This structure encapsulates all the data needed during the process
>   * of fetching, caching, and loading the firmware image into the GuC.
> -- 
> 2.7.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-12-08 23:02 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC anushasr
@ 2016-12-09  9:20   ` Arkadiusz Hiler
  2016-12-09 11:55   ` Michal Wajdeczko
  1 sibling, 0 replies; 50+ messages in thread
From: Arkadiusz Hiler @ 2016-12-09  9:20 UTC (permalink / raw)
  To: anushasr; +Cc: intel-gfx

On Thu, Dec 08, 2016 at 03:02:13PM -0800, anushasr wrote:
> From: Peter Antoine <peter.antoine@intel.com>
> 
> HuC firmware css header has almost exactly same definition as GuC
> firmware except for the sw_version. Also, add a new member fw_type
> into intel_uc_fw to indicate what kind of fw it is. So, the loader
> will pull right sw_version from header.
> 
> v2: rebased on-top of drm-intel-nightly
> v3: rebased on-top of drm-intel-nightly (again).
> v4: rebased + spaces.
> v7: rebased.
> v8: rebased.
> v9: rebased. Rename device_id to guc_branch_client_version,
> make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
> and UC_FW_TYPE_HUC into an enum.
> v10: rebased.
> v11: rebased.
> v12: rebased on top of drm-tip.
> v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch
> 
> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
>  drivers/gpu/drm/i915/intel_uc.h         |  5 ++++
>  3 files changed, 50 insertions(+), 17 deletions(-)

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-12-08 23:02 [PATCH 0/8]HuC Loading Patches anushasr
@ 2016-12-08 23:02 ` anushasr
  2016-12-09  9:20   ` Arkadiusz Hiler
  2016-12-09 11:55   ` Michal Wajdeczko
  0 siblings, 2 replies; 50+ messages in thread
From: anushasr @ 2016-12-08 23:02 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.
v9: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip.
v13: rebased.Update dev to dev_priv in intel_uc_fw_fetch

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_uc.h         |  5 ++++
 3 files changed, 50 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 3202b32..c1e7faf 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -145,7 +145,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -172,9 +172,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -205,8 +212,14 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		uint32_t guc_branch_client_version;
+		uint32_t huc_sw_version;
+	};
+	union {
+		uint32_t guc_sw_version;
+		uint32_t huc_reserved;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 8f04f6e..26a184f 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw = NULL;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(dev_priv)) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw_type) {
+	case UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(dev_priv)) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+		break;
+
+	case UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index f9f598d..be89f0b 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -98,6 +98,11 @@ enum intel_uc_fw_status {
 	UC_FIRMWARE_SUCCESS
 };
 
+enum {
+	UC_FW_TYPE_GUC,
+	UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-12-01 12:22   ` Arkadiusz Hiler
@ 2016-12-01 18:22     ` Srivatsa, Anusha
  0 siblings, 0 replies; 50+ messages in thread
From: Srivatsa, Anusha @ 2016-12-01 18:22 UTC (permalink / raw)
  To: Hiler, Arkadiusz; +Cc: intel-gfx



>-----Original Message-----
>From: Hiler, Arkadiusz
>Sent: Thursday, December 1, 2016 4:23 AM
>To: Srivatsa, Anusha <anusha.srivatsa@intel.com>
>Cc: intel-gfx@lists.freedesktop.org; Mcgee, Jeff <jeff.mcgee@intel.com>;
>Kamble, Sagar A <sagar.a.kamble@intel.com>
>Subject: Re: [Intel-gfx] [PATCH 2/8] drm/i915/huc: Unified css_header struct for
>GuC and HuC
>
>On Wed, Nov 30, 2016 at 03:31:28PM -0800, Anusha Srivatsa wrote:
>> From: Peter Antoine <peter.antoine@intel.com>
>>
>> HuC firmware css header has almost exactly same definition as GuC
>> firmware except for the sw_version. Also, add a new member fw_type
>> into intel_uc_fw to indicate what kind of fw it is. So, the loader
>> will pull right sw_version from header.
>>
>> v2: rebased on-top of drm-intel-nightly
>> v3: rebased on-top of drm-intel-nightly (again).
>> v4: rebased + spaces.
>> v7: rebased.
>> v8: rebased.
>> v9: rebased. Rename device_id to guc_branch_client_version, make
>> guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC and
>> UC_FW_TYPE_HUC into an enum.
>> v10: rebased.
>> v11: rebased.
>> v12: rebased on top of drm-tip.
>>
>> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
>> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
>> Signed-off-by: Alex Dai <yu.dai@intel.com>
>> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
>> Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
>> Reviewed-by: Jeff McGee <jeff.mcgee@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
>>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-------
>----
>>  drivers/gpu/drm/i915/intel_uc.h         |  5 ++++
>>  3 files changed, 50 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h
>> b/drivers/gpu/drm/i915/intel_guc_fwif.h
>> index 00ca0df..c07d9da 100644
>> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
>> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
>> @@ -154,7 +154,7 @@
>>   * The GuC firmware layout looks like this:
>>   *
>>   *     +-------------------------------+
>> - *     |        guc_css_header         |
>> + *     |         uc_css_header         |
>>   *     |                               |
>>   *     | contains major/minor version  |
>>   *     +-------------------------------+
>> @@ -181,9 +181,16 @@
>>   * 3. Length info of each component can be found in header, in dwords.
>>   * 4. Modulus and exponent key are not required by driver. They may not
>appear
>>   *    in fw. So driver will load a truncated firmware in this case.
>> + *
>> + * HuC firmware layout is same as GuC firmware.
>> + *
>> + * HuC firmware css header is different. However, the only difference
>> + is where
>> + * the version information is saved. The uc_css_header is unified to
>> + support
>> + * both. Driver should get HuC version from
>> + uc_css_header.huc_sw_version, while
>> + * uc_css_header.guc_sw_version for GuC.
>>   */
>>
>> -struct guc_css_header {
>> +struct uc_css_header {
>
>I think we should either move most of this stuff to intel_uc.{c,h} or rename the
>file to intel_uc_fwif.h.
>
>Anyway, this file contains information on top that this is automatically generated
>and your changes might be lost...
>
>The file was introduced and then *manually edited* *multiple times* by *many
>people*, without any signs of changes lost or file being regenerated.
>
>I think we can, at least, drop the warning. I am in favor of drooping the file
>completely though.
So, basically move all these struct and union declarations to intel_uc.h?
>If something would change, we can assume it would be done by hand anyway.
>
>Jeff, Sagar: any thought on that?
>
>>  	uint32_t module_type;
>>  	/* header_size includes all non-uCode bits, including css_header, rsa
>>  	 * key, modulus key and exponent data. */ @@ -214,8 +221,14 @@
>> struct guc_css_header {
>>
>>  	char username[8];
>>  	char buildnumber[12];
>> -	uint32_t device_id;
>> -	uint32_t guc_sw_version;
>> +	union {
>> +		uint32_t guc_branch_client_version;
>> +		uint32_t huc_sw_version;
>> +	};
>> +	union {
>> +		uint32_t guc_sw_version;
>> +		uint32_t huc_reserved;
>> +	};
>>  	uint32_t prod_preprod_fw;
>>  	uint32_t reserved[12];
>>  	uint32_t header_info;
>> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c
>> b/drivers/gpu/drm/i915/intel_guc_loader.c
>> index e55ec2c..557d4b4 100644
>> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
>> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
>> @@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct
>intel_uc_fw *uc_fw)
>>  	struct pci_dev *pdev = dev->pdev;
>>  	struct drm_i915_gem_object *obj;
>>  	const struct firmware *fw = NULL;
>> -	struct guc_css_header *css;
>> +	struct uc_css_header *css;
>>  	size_t size;
>>  	int err;
>>
>> @@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_device *dev,
>struct intel_uc_fw *uc_fw)
>>  		uc_fw->uc_fw_path, fw);
>>
>>  	/* Check the size of the blob before examining buffer contents */
>> -	if (fw->size < sizeof(struct guc_css_header)) {
>> +	if (fw->size < sizeof(struct uc_css_header)) {
>>  		DRM_NOTE("Firmware header is missing\n");
>>  		goto fail;
>>  	}
>>
>> -	css = (struct guc_css_header *)fw->data;
>> +	css = (struct uc_css_header *)fw->data;
>>
>>  	/* Firmware bits always start from header */
>>  	uc_fw->header_offset = 0;
>>  	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
>>
>> -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
>> +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>>  		DRM_NOTE("CSS header definition mismatch\n");
>>  		goto fail;
>>  	}
>> @@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_device *dev,
>struct intel_uc_fw *uc_fw)
>>  		goto fail;
>>  	}
>>
>> -	/* Header and uCode will be loaded to WOPCM. Size of the two. */
>> -	size = uc_fw->header_size + uc_fw->ucode_size;
>> -	if (size > guc_wopcm_size(to_i915(dev))) {
>> -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
>> -		goto fail;
>> -	}
>> -
>>  	/*
>>  	 * The GuC firmware image has the version number embedded at a well-
>known
>>  	 * offset within the firmware blob; note that major / minor version are
>>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
>>  	 * in terms of bytes (u8).
>>  	 */
>> -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
>> -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
>> +	switch (uc_fw->fw_type) {
>> +	case UC_FW_TYPE_GUC:
>> +		/* Header and uCode will be loaded to WOPCM. Size of the two.
>*/
>> +		size = uc_fw->header_size + uc_fw->ucode_size;
>> +
>> +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context).
>*/
>> +		if (size > guc_wopcm_size(to_i915(dev))) {
>> +			DRM_ERROR("Firmware is too large to fit in
>WOPCM\n");
>> +			goto fail;
>> +		}
>> +		uc_fw->major_ver_found = css->guc_sw_version >> 16;
>> +		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
>> +		break;
>> +
>> +	case UC_FW_TYPE_HUC:
>> +		uc_fw->major_ver_found = css->huc_sw_version >> 16;
>> +		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
>> +		break;
>> +
>> +	default:
>> +		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
>> +		err = -ENOEXEC;
>> +		goto fail;
>> +	}
>>
>>  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>>  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) { diff --git
>> a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
>> index a1c771f..1616cac 100644
>> --- a/drivers/gpu/drm/i915/intel_uc.h
>> +++ b/drivers/gpu/drm/i915/intel_uc.h
>> @@ -98,6 +98,11 @@ enum intel_uc_fw_status {
>>  	UC_FIRMWARE_SUCCESS
>>  };
>>
>> +enum {
>> +	UC_FW_TYPE_GUC,
>> +	UC_FW_TYPE_HUC
>> +};
>> +
>>  /*
>>   * This structure encapsulates all the data needed during the process
>>   * of fetching, caching, and loading the firmware image into the GuC.
>> --
>> 2.7.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>--
>Cheers,
>Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-11-30 23:31 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
@ 2016-12-01 12:22   ` Arkadiusz Hiler
  2016-12-01 18:22     ` Srivatsa, Anusha
  0 siblings, 1 reply; 50+ messages in thread
From: Arkadiusz Hiler @ 2016-12-01 12:22 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx

On Wed, Nov 30, 2016 at 03:31:28PM -0800, Anusha Srivatsa wrote:
> From: Peter Antoine <peter.antoine@intel.com>
> 
> HuC firmware css header has almost exactly same definition as GuC
> firmware except for the sw_version. Also, add a new member fw_type
> into intel_uc_fw to indicate what kind of fw it is. So, the loader
> will pull right sw_version from header.
> 
> v2: rebased on-top of drm-intel-nightly
> v3: rebased on-top of drm-intel-nightly (again).
> v4: rebased + spaces.
> v7: rebased.
> v8: rebased.
> v9: rebased. Rename device_id to guc_branch_client_version,
> make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
> and UC_FW_TYPE_HUC into an enum.
> v10: rebased.
> v11: rebased.
> v12: rebased on top of drm-tip.
> 
> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
> Reviewed-by: Jeff McGee <jeff.mcgee@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
>  drivers/gpu/drm/i915/intel_uc.h         |  5 ++++
>  3 files changed, 50 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
> index 00ca0df..c07d9da 100644
> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
> @@ -154,7 +154,7 @@
>   * The GuC firmware layout looks like this:
>   *
>   *     +-------------------------------+
> - *     |        guc_css_header         |
> + *     |         uc_css_header         |
>   *     |                               |
>   *     | contains major/minor version  |
>   *     +-------------------------------+
> @@ -181,9 +181,16 @@
>   * 3. Length info of each component can be found in header, in dwords.
>   * 4. Modulus and exponent key are not required by driver. They may not appear
>   *    in fw. So driver will load a truncated firmware in this case.
> + *
> + * HuC firmware layout is same as GuC firmware.
> + *
> + * HuC firmware css header is different. However, the only difference is where
> + * the version information is saved. The uc_css_header is unified to support
> + * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
> + * uc_css_header.guc_sw_version for GuC.
>   */
>  
> -struct guc_css_header {
> +struct uc_css_header {

I think we should either move most of this stuff to intel_uc.{c,h} or
rename the file to intel_uc_fwif.h.

Anyway, this file contains information on top that this is automatically
generated and your changes might be lost...

The file was introduced and then *manually edited* *multiple times* by
*many people*, without any signs of changes lost or file being
regenerated.

I think we can, at least, drop the warning. I am in favor of drooping
the file completely though.

If something would change, we can assume it would be done by hand anyway.

Jeff, Sagar: any thought on that?

>  	uint32_t module_type;
>  	/* header_size includes all non-uCode bits, including css_header, rsa
>  	 * key, modulus key and exponent data. */
> @@ -214,8 +221,14 @@ struct guc_css_header {
>  
>  	char username[8];
>  	char buildnumber[12];
> -	uint32_t device_id;
> -	uint32_t guc_sw_version;
> +	union {
> +		uint32_t guc_branch_client_version;
> +		uint32_t huc_sw_version;
> +	};
> +	union {
> +		uint32_t guc_sw_version;
> +		uint32_t huc_reserved;
> +	};
>  	uint32_t prod_preprod_fw;
>  	uint32_t reserved[12];
>  	uint32_t header_info;
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> index e55ec2c..557d4b4 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
>  	struct pci_dev *pdev = dev->pdev;
>  	struct drm_i915_gem_object *obj;
>  	const struct firmware *fw = NULL;
> -	struct guc_css_header *css;
> +	struct uc_css_header *css;
>  	size_t size;
>  	int err;
>  
> @@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
>  		uc_fw->uc_fw_path, fw);
>  
>  	/* Check the size of the blob before examining buffer contents */
> -	if (fw->size < sizeof(struct guc_css_header)) {
> +	if (fw->size < sizeof(struct uc_css_header)) {
>  		DRM_NOTE("Firmware header is missing\n");
>  		goto fail;
>  	}
>  
> -	css = (struct guc_css_header *)fw->data;
> +	css = (struct uc_css_header *)fw->data;
>  
>  	/* Firmware bits always start from header */
>  	uc_fw->header_offset = 0;
>  	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
>  
> -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
> +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>  		DRM_NOTE("CSS header definition mismatch\n");
>  		goto fail;
>  	}
> @@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
>  		goto fail;
>  	}
>  
> -	/* Header and uCode will be loaded to WOPCM. Size of the two. */
> -	size = uc_fw->header_size + uc_fw->ucode_size;
> -	if (size > guc_wopcm_size(to_i915(dev))) {
> -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
> -		goto fail;
> -	}
> -
>  	/*
>  	 * The GuC firmware image has the version number embedded at a well-known
>  	 * offset within the firmware blob; note that major / minor version are
>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
>  	 * in terms of bytes (u8).
>  	 */
> -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
> -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> +	switch (uc_fw->fw_type) {
> +	case UC_FW_TYPE_GUC:
> +		/* Header and uCode will be loaded to WOPCM. Size of the two. */
> +		size = uc_fw->header_size + uc_fw->ucode_size;
> +
> +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
> +		if (size > guc_wopcm_size(to_i915(dev))) {
> +			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
> +			goto fail;
> +		}
> +		uc_fw->major_ver_found = css->guc_sw_version >> 16;
> +		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> +		break;
> +
> +	case UC_FW_TYPE_HUC:
> +		uc_fw->major_ver_found = css->huc_sw_version >> 16;
> +		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
> +		break;
> +
> +	default:
> +		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
> +		err = -ENOEXEC;
> +		goto fail;
> +	}
>  
>  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
> diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
> index a1c771f..1616cac 100644
> --- a/drivers/gpu/drm/i915/intel_uc.h
> +++ b/drivers/gpu/drm/i915/intel_uc.h
> @@ -98,6 +98,11 @@ enum intel_uc_fw_status {
>  	UC_FIRMWARE_SUCCESS
>  };
>  
> +enum {
> +	UC_FW_TYPE_GUC,
> +	UC_FW_TYPE_HUC
> +};
> +
>  /*
>   * This structure encapsulates all the data needed during the process
>   * of fetching, caching, and loading the firmware image into the GuC.
> -- 
> 2.7.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Cheers,
Arek
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-11-30 23:31 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
@ 2016-11-30 23:31 ` Anusha Srivatsa
  2016-12-01 12:22   ` Arkadiusz Hiler
  0 siblings, 1 reply; 50+ messages in thread
From: Anusha Srivatsa @ 2016-11-30 23:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.
v9: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v10: rebased.
v11: rebased.
v12: rebased on top of drm-tip.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
Reviewed-by: Jeff McGee <jeff.mcgee@intel.com>
---
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_uc.h         |  5 ++++
 3 files changed, 50 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 00ca0df..c07d9da 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -154,7 +154,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -181,9 +181,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -214,8 +221,14 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		uint32_t guc_branch_client_version;
+		uint32_t huc_sw_version;
+	};
+	union {
+		uint32_t guc_sw_version;
+		uint32_t huc_reserved;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index e55ec2c..557d4b4 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 	struct pci_dev *pdev = dev->pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw = NULL;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(to_i915(dev))) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw_type) {
+	case UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(to_i915(dev))) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+		break;
+
+	case UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h
index a1c771f..1616cac 100644
--- a/drivers/gpu/drm/i915/intel_uc.h
+++ b/drivers/gpu/drm/i915/intel_uc.h
@@ -98,6 +98,11 @@ enum intel_uc_fw_status {
 	UC_FIRMWARE_SUCCESS
 };
 
+enum {
+	UC_FW_TYPE_GUC,
+	UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-11-23 22:27 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
@ 2016-11-23 22:27 ` Anusha Srivatsa
  0 siblings, 0 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2016-11-23 22:27 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.
v9: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v10: rebased.
v11: rebased.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
Reviewed-by: Jeff McGee <jeff.mcgee@intel.com>
---
 drivers/gpu/drm/i915/intel_guc.h        |  6 +++++
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 3 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 6dc328f..45dfa40 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -98,6 +98,11 @@ enum intel_uc_fw_status {
 	UC_FIRMWARE_SUCCESS
 };
 
+enum {
+	UC_FW_TYPE_GUC,
+	UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -115,6 +120,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	uint32_t fw_type;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 324ea90..c2a7fdd 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -154,7 +154,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -181,9 +181,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -214,8 +221,14 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		uint32_t guc_branch_client_version;
+		uint32_t huc_sw_version;
+	};
+	union {
+		uint32_t guc_sw_version;
+		uint32_t huc_reserved;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index c1b53a6..70b372b 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 	struct pci_dev *pdev = dev->pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(to_i915(dev))) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw_type) {
+	case UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(to_i915(dev))) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+		break;
+
+	case UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-11-11  0:15 [PATCH v4 0/8] HuC Loading Patches Anusha Srivatsa
@ 2016-11-11  0:15 ` Anusha Srivatsa
  0 siblings, 0 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2016-11-11  0:15 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.
v9: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v10: rebased.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
Reviewed-by: Jeff McGee <jeff.mcgee@intel.com>
---
 drivers/gpu/drm/i915/intel_guc.h        |  6 +++++
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 3 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 6dc328f..45dfa40 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -98,6 +98,11 @@ enum intel_uc_fw_status {
 	UC_FIRMWARE_SUCCESS
 };
 
+enum {
+	UC_FW_TYPE_GUC,
+	UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -115,6 +120,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	uint32_t fw_type;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 324ea90..c2a7fdd 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -154,7 +154,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -181,9 +181,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -214,8 +221,14 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		uint32_t guc_branch_client_version;
+		uint32_t huc_sw_version;
+	};
+	union {
+		uint32_t guc_sw_version;
+		uint32_t huc_reserved;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 6683a88..ff26d2c 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 	struct pci_dev *pdev = dev->pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(to_i915(dev))) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw_type) {
+	case UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(to_i915(dev))) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+		break;
+
+	case UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-11-09 18:51 [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general Anusha Srivatsa
@ 2016-11-09 18:51 ` Anusha Srivatsa
  0 siblings, 0 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2016-11-09 18:51 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alex Dai, Peter Antoine

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.
v9: rebased. Rename device_id to guc_branch_client_version,
make guc_sw_version a union. <Jeff Mcgee>. Put UC_FW_TYPE_GUC
and UC_FW_TYPE_HUC into an enum.
v10: rebased.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
Reviewed-by: Jeff McGee <jeff.mcgee@intel.com>
---
 drivers/gpu/drm/i915/intel_guc.h        |  6 +++++
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 21 +++++++++++++----
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 3 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 6dc328f..45dfa40 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -98,6 +98,11 @@ enum intel_uc_fw_status {
 	UC_FIRMWARE_SUCCESS
 };
 
+enum {
+	UC_FW_TYPE_GUC,
+	UC_FW_TYPE_HUC
+};
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -115,6 +120,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	uint32_t fw_type;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index 324ea90..c2a7fdd 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -154,7 +154,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -181,9 +181,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -214,8 +221,14 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
-	uint32_t guc_sw_version;
+	union {
+		uint32_t guc_branch_client_version;
+		uint32_t huc_sw_version;
+	};
+	union {
+		uint32_t guc_sw_version;
+		uint32_t huc_reserved;
+	};
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
 	uint32_t header_info;
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 6683a88..ff26d2c 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -593,7 +593,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 	struct pci_dev *pdev = dev->pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -610,19 +610,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -646,21 +646,36 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(to_i915(dev))) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw_type) {
+	case UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(to_i915(dev))) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+		break;
+
+	case UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-10-03 18:42 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
  2016-10-13 15:45   ` Jeff McGee
@ 2016-10-24 21:42   ` Carlos Santa
  1 sibling, 0 replies; 50+ messages in thread
From: Carlos Santa @ 2016-10-24 21:42 UTC (permalink / raw)
  To: Anusha Srivatsa, intel-gfx

On Mon, 2016-10-03 at 11:42 -0700, Anusha Srivatsa wrote:
> From: Peter Antoine <peter.antoine@intel.com>
> 
> HuC firmware css header has almost exactly same definition as GuC
> firmware except for the sw_version. Also, add a new member fw_type
> into intel_uc_fw to indicate what kind of fw it is. So, the loader
> will pull right sw_version from header.
> 
> v2: rebased on-top of drm-intel-nightly
> v3: rebased on-top of drm-intel-nightly (again).
> v4: rebased + spaces.
> v7: rebased.
> v8: rebased.
> 
> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_guc.h        |  4 ++++
>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 16 ++++++++++---
>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-
> ----------
>  3 files changed, 45 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_guc.h
> b/drivers/gpu/drm/i915/intel_guc.h
> index b134a41..812e4ca 100644
> --- a/drivers/gpu/drm/i915/intel_guc.h
> +++ b/drivers/gpu/drm/i915/intel_guc.h
> @@ -98,6 +98,9 @@ enum intel_uc_fw_status {
>  	UC_FIRMWARE_SUCCESS
>  };
>  
> +#define UC_FW_TYPE_GUC		0
> +#define UC_FW_TYPE_HUC		1
> +

This can be changed to an enum as suggested earlier by Rodrigo.

>  /*
>   * This structure encapsulates all the data needed during the
> process
>   * of fetching, caching, and loading the firmware image into the
> GuC.
> @@ -115,6 +118,7 @@ struct intel_uc_fw {
>  	uint16_t major_ver_found;
>  	uint16_t minor_ver_found;
> 
> +	uint32_t fw_type;

Maybe a comment can be added to this variable to explicitly describe
what it is ("GuC/HuC FW")?

Carlos

>  	uint32_t header_size;
>  	uint32_t header_offset;
>  	uint32_t rsa_size;
> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h
> b/drivers/gpu/drm/i915/intel_guc_fwif.h
> index e40db2d..b38b6b4 100644
> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
> @@ -154,7 +154,7 @@
>   * The GuC firmware layout looks like this:
>   *
>   *     +-------------------------------+
> - *     |        guc_css_header         |
> + *     |         uc_css_header         |
>   *     |                               |
>   *     | contains major/minor version  |
>   *     +-------------------------------+
> @@ -181,9 +181,16 @@
>   * 3. Length info of each component can be found in header, in
> dwords.
>   * 4. Modulus and exponent key are not required by driver. They may
> not appear
>   *    in fw. So driver will load a truncated firmware in this case.
> + *
> + * HuC firmware layout is same as GuC firmware.
> + *
> + * HuC firmware css header is different. However, the only
> difference is where
> + * the version information is saved. The uc_css_header is unified to
> support
> + * both. Driver should get HuC version from
> uc_css_header.huc_sw_version, while
> + * uc_css_header.guc_sw_version for GuC.
>   */
>  
> -struct guc_css_header {
> +struct uc_css_header {
>  	uint32_t module_type;
>  	/* header_size includes all non-uCode bits, including
> css_header, rsa
>  	 * key, modulus key and exponent data. */
> @@ -214,7 +221,10 @@ struct guc_css_header {
>  
>  	char username[8];
>  	char buildnumber[12];
> -	uint32_t device_id;
> +	union {
> +		uint32_t device_id;
> +		uint32_t huc_sw_version;
> +	};
>  	uint32_t guc_sw_version;
>  	uint32_t prod_preprod_fw;
>  	uint32_t reserved[12];
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c
> b/drivers/gpu/drm/i915/intel_guc_loader.c
> index 493295d..0b863a1 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -586,7 +586,7 @@ void intel_uc_fw_fetch(struct drm_device *dev,
> struct intel_uc_fw *uc_fw)
>  	struct pci_dev *pdev = dev->pdev;
>  	struct drm_i915_gem_object *obj;
>  	const struct firmware *fw;
> -	struct guc_css_header *css;
> +	struct uc_css_header *css;
>  	size_t size;
>  	int err;
>  
> @@ -603,19 +603,19 @@ void intel_uc_fw_fetch(struct drm_device *dev,
> struct intel_uc_fw *uc_fw)
>  		uc_fw->uc_fw_path, fw);
>  
>  	/* Check the size of the blob before examining buffer
> contents */
> -	if (fw->size < sizeof(struct guc_css_header)) {
> +	if (fw->size < sizeof(struct uc_css_header)) {
>  		DRM_NOTE("Firmware header is missing\n");
>  		goto fail;
>  	}
>  
> -	css = (struct guc_css_header *)fw->data;
> +	css = (struct uc_css_header *)fw->data;
>  
>  	/* Firmware bits always start from header */
>  	uc_fw->header_offset = 0;
>  	uc_fw->header_size = (css->header_size_dw - css-
> >modulus_size_dw -
>  		css->key_size_dw - css->exponent_size_dw) *
> sizeof(u32);
>  
> -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
> +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>  		DRM_NOTE("CSS header definition mismatch\n");
>  		goto fail;
>  	}
> @@ -639,21 +639,36 @@ void intel_uc_fw_fetch(struct drm_device *dev,
> struct intel_uc_fw *uc_fw)
>  		goto fail;
>  	}
>  
> -	/* Header and uCode will be loaded to WOPCM. Size of the
> two. */
> -	size = uc_fw->header_size + uc_fw->ucode_size;
> -	if (size > guc_wopcm_size(to_i915(dev))) {
> -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
> -		goto fail;
> -	}
> -
>  	/*
>  	 * The GuC firmware image has the version number embedded at
> a well-known
>  	 * offset within the firmware blob; note that major / minor
> version are
>  	 * TWO bytes each (i.e. u16), although all pointers and
> offsets are defined
>  	 * in terms of bytes (u8).
>  	 */
> -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
> -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> +	switch (uc_fw->fw_type) {
> +	case UC_FW_TYPE_GUC:
> +		/* Header and uCode will be loaded to WOPCM. Size of
> the two. */
> +		size = uc_fw->header_size + uc_fw->ucode_size;
> +
> +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6
> context). */
> +		if (size > guc_wopcm_size(to_i915(dev))) {
> +			DRM_ERROR("Firmware is too large to fit in
> WOPCM\n");
> +			goto fail;
> +		}
> +		uc_fw->major_ver_found = css->guc_sw_version >> 16;
> +		uc_fw->minor_ver_found = css->guc_sw_version &
> 0xFFFF;
> +		break;
> +
> +	case UC_FW_TYPE_HUC:
> +		uc_fw->major_ver_found = css->huc_sw_version >> 16;
> +		uc_fw->minor_ver_found = css->huc_sw_version &
> 0xFFFF;
> +		break;
> +
> +	default:
> +		DRM_ERROR("Unknown firmware type %d\n", uc_fw-
> >fw_type);
> +		err = -ENOEXEC;
> +		goto fail;
> +	}
>  
>  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-10-13 15:45   ` Jeff McGee
@ 2016-10-14  4:24     ` Jeff McGee
  0 siblings, 0 replies; 50+ messages in thread
From: Jeff McGee @ 2016-10-14  4:24 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx

On Thu, Oct 13, 2016 at 08:45:45AM -0700, Jeff McGee wrote:
> On Mon, Oct 03, 2016 at 11:42:56AM -0700, Anusha Srivatsa wrote:
> > From: Peter Antoine <peter.antoine@intel.com>
> > 
> > HuC firmware css header has almost exactly same definition as GuC
> > firmware except for the sw_version. Also, add a new member fw_type
> > into intel_uc_fw to indicate what kind of fw it is. So, the loader
> > will pull right sw_version from header.
> > 
> > v2: rebased on-top of drm-intel-nightly
> > v3: rebased on-top of drm-intel-nightly (again).
> > v4: rebased + spaces.
> > v7: rebased.
> > v8: rebased.
> > 
> > Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> > Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> > Signed-off-by: Alex Dai <yu.dai@intel.com>
> > Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> > Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_guc.h        |  4 ++++
> >  drivers/gpu/drm/i915/intel_guc_fwif.h   | 16 ++++++++++---
> >  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
> >  3 files changed, 45 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
> > index b134a41..812e4ca 100644
> > --- a/drivers/gpu/drm/i915/intel_guc.h
> > +++ b/drivers/gpu/drm/i915/intel_guc.h
> > @@ -98,6 +98,9 @@ enum intel_uc_fw_status {
> >  	UC_FIRMWARE_SUCCESS
> >  };
> >  
> > +#define UC_FW_TYPE_GUC		0
> > +#define UC_FW_TYPE_HUC		1
> > +
> >  /*
> >   * This structure encapsulates all the data needed during the process
> >   * of fetching, caching, and loading the firmware image into the GuC.
> > @@ -115,6 +118,7 @@ struct intel_uc_fw {
> >  	uint16_t major_ver_found;
> >  	uint16_t minor_ver_found;
> >  
> > +	uint32_t fw_type;
> >  	uint32_t header_size;
> >  	uint32_t header_offset;
> >  	uint32_t rsa_size;
> > diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
> > index e40db2d..b38b6b4 100644
> > --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
> > +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
> > @@ -154,7 +154,7 @@
> >   * The GuC firmware layout looks like this:
> >   *
> >   *     +-------------------------------+
> > - *     |        guc_css_header         |
> > + *     |         uc_css_header         |
> >   *     |                               |
> >   *     | contains major/minor version  |
> >   *     +-------------------------------+
> > @@ -181,9 +181,16 @@
> >   * 3. Length info of each component can be found in header, in dwords.
> >   * 4. Modulus and exponent key are not required by driver. They may not appear
> >   *    in fw. So driver will load a truncated firmware in this case.
> > + *
> > + * HuC firmware layout is same as GuC firmware.
> > + *
> > + * HuC firmware css header is different. However, the only difference is where
> > + * the version information is saved. The uc_css_header is unified to support
> > + * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
> > + * uc_css_header.guc_sw_version for GuC.
> >   */
> >  
> > -struct guc_css_header {
> > +struct uc_css_header {
> >  	uint32_t module_type;
> >  	/* header_size includes all non-uCode bits, including css_header, rsa
> >  	 * key, modulus key and exponent data. */
> > @@ -214,7 +221,10 @@ struct guc_css_header {
> >  
> >  	char username[8];
> >  	char buildnumber[12];
> > -	uint32_t device_id;
> > +	union {
> > +		uint32_t device_id;
> > +		uint32_t huc_sw_version;
> > +	};
> >  	uint32_t guc_sw_version;
> >  	uint32_t prod_preprod_fw;
> >  	uint32_t reserved[12];
> 
> I propose renaming the device_id field in this union to
> 'guc_client_branch_version'. GuC uses this position to store a client
> version and branch version. I'm not sure where the 'device_id' term came
> from. We don't reference this currently but may need to in the future
> so might as well name it properly. At the very least we should probably
> make it guc_device_id, to help indicate that it applies to guc fw only.
> 
> In that same vein, can we make guc_sw_version into a union as below to
> reinforce the difference to huc?
> 
> 	union {
> 		uint32_t guc_sw_version;
> 		uint32_t huc_reserved;
> 	};
> 
> Jeff
> 

One correction. The branch version is considered the "major" and the
client version the "minor", so the better name for this field is
'guc_branch_client_version'.

> > diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> > index 493295d..0b863a1 100644
> > --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> > +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> > @@ -586,7 +586,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
> >  	struct pci_dev *pdev = dev->pdev;
> >  	struct drm_i915_gem_object *obj;
> >  	const struct firmware *fw;
> > -	struct guc_css_header *css;
> > +	struct uc_css_header *css;
> >  	size_t size;
> >  	int err;
> >  
> > @@ -603,19 +603,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
> >  		uc_fw->uc_fw_path, fw);
> >  
> >  	/* Check the size of the blob before examining buffer contents */
> > -	if (fw->size < sizeof(struct guc_css_header)) {
> > +	if (fw->size < sizeof(struct uc_css_header)) {
> >  		DRM_NOTE("Firmware header is missing\n");
> >  		goto fail;
> >  	}
> >  
> > -	css = (struct guc_css_header *)fw->data;
> > +	css = (struct uc_css_header *)fw->data;
> >  
> >  	/* Firmware bits always start from header */
> >  	uc_fw->header_offset = 0;
> >  	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
> >  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
> >  
> > -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
> > +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
> >  		DRM_NOTE("CSS header definition mismatch\n");
> >  		goto fail;
> >  	}
> > @@ -639,21 +639,36 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
> >  		goto fail;
> >  	}
> >  
> > -	/* Header and uCode will be loaded to WOPCM. Size of the two. */
> > -	size = uc_fw->header_size + uc_fw->ucode_size;
> > -	if (size > guc_wopcm_size(to_i915(dev))) {
> > -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
> > -		goto fail;
> > -	}
> > -
> >  	/*
> >  	 * The GuC firmware image has the version number embedded at a well-known
> >  	 * offset within the firmware blob; note that major / minor version are
> >  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
> >  	 * in terms of bytes (u8).
> >  	 */
> > -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
> > -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> > +	switch (uc_fw->fw_type) {
> > +	case UC_FW_TYPE_GUC:
> > +		/* Header and uCode will be loaded to WOPCM. Size of the two. */
> > +		size = uc_fw->header_size + uc_fw->ucode_size;
> > +
> > +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
> > +		if (size > guc_wopcm_size(to_i915(dev))) {
> > +			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
> > +			goto fail;
> > +		}
> > +		uc_fw->major_ver_found = css->guc_sw_version >> 16;
> > +		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> > +		break;
> > +
> > +	case UC_FW_TYPE_HUC:
> > +		uc_fw->major_ver_found = css->huc_sw_version >> 16;
> > +		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
> > +		break;
> > +
> > +	default:
> > +		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
> > +		err = -ENOEXEC;
> > +		goto fail;
> > +	}
> >  
> >  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
> >  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
> > -- 
> > 2.7.4
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-10-03 18:42 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
@ 2016-10-13 15:45   ` Jeff McGee
  2016-10-14  4:24     ` Jeff McGee
  2016-10-24 21:42   ` Carlos Santa
  1 sibling, 1 reply; 50+ messages in thread
From: Jeff McGee @ 2016-10-13 15:45 UTC (permalink / raw)
  To: Anusha Srivatsa; +Cc: intel-gfx

On Mon, Oct 03, 2016 at 11:42:56AM -0700, Anusha Srivatsa wrote:
> From: Peter Antoine <peter.antoine@intel.com>
> 
> HuC firmware css header has almost exactly same definition as GuC
> firmware except for the sw_version. Also, add a new member fw_type
> into intel_uc_fw to indicate what kind of fw it is. So, the loader
> will pull right sw_version from header.
> 
> v2: rebased on-top of drm-intel-nightly
> v3: rebased on-top of drm-intel-nightly (again).
> v4: rebased + spaces.
> v7: rebased.
> v8: rebased.
> 
> Tested-by: Xiang Haihao <haihao.xiang@intel.com>
> Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_guc.h        |  4 ++++
>  drivers/gpu/drm/i915/intel_guc_fwif.h   | 16 ++++++++++---
>  drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
>  3 files changed, 45 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
> index b134a41..812e4ca 100644
> --- a/drivers/gpu/drm/i915/intel_guc.h
> +++ b/drivers/gpu/drm/i915/intel_guc.h
> @@ -98,6 +98,9 @@ enum intel_uc_fw_status {
>  	UC_FIRMWARE_SUCCESS
>  };
>  
> +#define UC_FW_TYPE_GUC		0
> +#define UC_FW_TYPE_HUC		1
> +
>  /*
>   * This structure encapsulates all the data needed during the process
>   * of fetching, caching, and loading the firmware image into the GuC.
> @@ -115,6 +118,7 @@ struct intel_uc_fw {
>  	uint16_t major_ver_found;
>  	uint16_t minor_ver_found;
>  
> +	uint32_t fw_type;
>  	uint32_t header_size;
>  	uint32_t header_offset;
>  	uint32_t rsa_size;
> diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
> index e40db2d..b38b6b4 100644
> --- a/drivers/gpu/drm/i915/intel_guc_fwif.h
> +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
> @@ -154,7 +154,7 @@
>   * The GuC firmware layout looks like this:
>   *
>   *     +-------------------------------+
> - *     |        guc_css_header         |
> + *     |         uc_css_header         |
>   *     |                               |
>   *     | contains major/minor version  |
>   *     +-------------------------------+
> @@ -181,9 +181,16 @@
>   * 3. Length info of each component can be found in header, in dwords.
>   * 4. Modulus and exponent key are not required by driver. They may not appear
>   *    in fw. So driver will load a truncated firmware in this case.
> + *
> + * HuC firmware layout is same as GuC firmware.
> + *
> + * HuC firmware css header is different. However, the only difference is where
> + * the version information is saved. The uc_css_header is unified to support
> + * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
> + * uc_css_header.guc_sw_version for GuC.
>   */
>  
> -struct guc_css_header {
> +struct uc_css_header {
>  	uint32_t module_type;
>  	/* header_size includes all non-uCode bits, including css_header, rsa
>  	 * key, modulus key and exponent data. */
> @@ -214,7 +221,10 @@ struct guc_css_header {
>  
>  	char username[8];
>  	char buildnumber[12];
> -	uint32_t device_id;
> +	union {
> +		uint32_t device_id;
> +		uint32_t huc_sw_version;
> +	};
>  	uint32_t guc_sw_version;
>  	uint32_t prod_preprod_fw;
>  	uint32_t reserved[12];

I propose renaming the device_id field in this union to
'guc_client_branch_version'. GuC uses this position to store a client
version and branch version. I'm not sure where the 'device_id' term came
from. We don't reference this currently but may need to in the future
so might as well name it properly. At the very least we should probably
make it guc_device_id, to help indicate that it applies to guc fw only.

In that same vein, can we make guc_sw_version into a union as below to
reinforce the difference to huc?

	union {
		uint32_t guc_sw_version;
		uint32_t huc_reserved;
	};

Jeff

> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> index 493295d..0b863a1 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -586,7 +586,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
>  	struct pci_dev *pdev = dev->pdev;
>  	struct drm_i915_gem_object *obj;
>  	const struct firmware *fw;
> -	struct guc_css_header *css;
> +	struct uc_css_header *css;
>  	size_t size;
>  	int err;
>  
> @@ -603,19 +603,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
>  		uc_fw->uc_fw_path, fw);
>  
>  	/* Check the size of the blob before examining buffer contents */
> -	if (fw->size < sizeof(struct guc_css_header)) {
> +	if (fw->size < sizeof(struct uc_css_header)) {
>  		DRM_NOTE("Firmware header is missing\n");
>  		goto fail;
>  	}
>  
> -	css = (struct guc_css_header *)fw->data;
> +	css = (struct uc_css_header *)fw->data;
>  
>  	/* Firmware bits always start from header */
>  	uc_fw->header_offset = 0;
>  	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
>  		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
>  
> -	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
> +	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
>  		DRM_NOTE("CSS header definition mismatch\n");
>  		goto fail;
>  	}
> @@ -639,21 +639,36 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
>  		goto fail;
>  	}
>  
> -	/* Header and uCode will be loaded to WOPCM. Size of the two. */
> -	size = uc_fw->header_size + uc_fw->ucode_size;
> -	if (size > guc_wopcm_size(to_i915(dev))) {
> -		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
> -		goto fail;
> -	}
> -
>  	/*
>  	 * The GuC firmware image has the version number embedded at a well-known
>  	 * offset within the firmware blob; note that major / minor version are
>  	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
>  	 * in terms of bytes (u8).
>  	 */
> -	uc_fw->major_ver_found = css->guc_sw_version >> 16;
> -	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> +	switch (uc_fw->fw_type) {
> +	case UC_FW_TYPE_GUC:
> +		/* Header and uCode will be loaded to WOPCM. Size of the two. */
> +		size = uc_fw->header_size + uc_fw->ucode_size;
> +
> +		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
> +		if (size > guc_wopcm_size(to_i915(dev))) {
> +			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
> +			goto fail;
> +		}
> +		uc_fw->major_ver_found = css->guc_sw_version >> 16;
> +		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
> +		break;
> +
> +	case UC_FW_TYPE_HUC:
> +		uc_fw->major_ver_found = css->huc_sw_version >> 16;
> +		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
> +		break;
> +
> +	default:
> +		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
> +		err = -ENOEXEC;
> +		goto fail;
> +	}
>  
>  	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
>  	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
> -- 
> 2.7.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-10-03 18:42 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
@ 2016-10-03 18:42 ` Anusha Srivatsa
  2016-10-13 15:45   ` Jeff McGee
  2016-10-24 21:42   ` Carlos Santa
  0 siblings, 2 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2016-10-03 18:42 UTC (permalink / raw)
  To: intel-gfx

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
---
 drivers/gpu/drm/i915/intel_guc.h        |  4 ++++
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 16 ++++++++++---
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 3 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index b134a41..812e4ca 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -98,6 +98,9 @@ enum intel_uc_fw_status {
 	UC_FIRMWARE_SUCCESS
 };
 
+#define UC_FW_TYPE_GUC		0
+#define UC_FW_TYPE_HUC		1
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -115,6 +118,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	uint32_t fw_type;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index e40db2d..b38b6b4 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -154,7 +154,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -181,9 +181,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -214,7 +221,10 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
+	union {
+		uint32_t device_id;
+		uint32_t huc_sw_version;
+	};
 	uint32_t guc_sw_version;
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 493295d..0b863a1 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -586,7 +586,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 	struct pci_dev *pdev = dev->pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -603,19 +603,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -639,21 +639,36 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(to_i915(dev))) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw_type) {
+	case UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(to_i915(dev))) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+		break;
+
+	case UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC
  2016-09-29 18:03 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
@ 2016-09-29 18:03 ` Anusha Srivatsa
  0 siblings, 0 replies; 50+ messages in thread
From: Anusha Srivatsa @ 2016-09-29 18:03 UTC (permalink / raw)
  To: intel-gfx

From: Peter Antoine <peter.antoine@intel.com>

HuC firmware css header has almost exactly same definition as GuC
firmware except for the sw_version. Also, add a new member fw_type
into intel_uc_fw to indicate what kind of fw it is. So, the loader
will pull right sw_version from header.

v2: rebased on-top of drm-intel-nightly
v3: rebased on-top of drm-intel-nightly (again).
v4: rebased + spaces.
v7: rebased.
v8: rebased.

Tested-by: Xiang Haihao <haihao.xiang@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: Alex Dai <yu.dai@intel.com>
Signed-off-by: Peter Antoine <peter.antoine@intel.com>
Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
---
 drivers/gpu/drm/i915/intel_guc.h        |  4 ++++
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 16 ++++++++++---
 drivers/gpu/drm/i915/intel_guc_loader.c | 41 ++++++++++++++++++++++-----------
 3 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index b134a41..812e4ca 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -98,6 +98,9 @@ enum intel_uc_fw_status {
 	UC_FIRMWARE_SUCCESS
 };
 
+#define UC_FW_TYPE_GUC		0
+#define UC_FW_TYPE_HUC		1
+
 /*
  * This structure encapsulates all the data needed during the process
  * of fetching, caching, and loading the firmware image into the GuC.
@@ -115,6 +118,7 @@ struct intel_uc_fw {
 	uint16_t major_ver_found;
 	uint16_t minor_ver_found;
 
+	uint32_t fw_type;
 	uint32_t header_size;
 	uint32_t header_offset;
 	uint32_t rsa_size;
diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h
index e40db2d..b38b6b4 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -154,7 +154,7 @@
  * The GuC firmware layout looks like this:
  *
  *     +-------------------------------+
- *     |        guc_css_header         |
+ *     |         uc_css_header         |
  *     |                               |
  *     | contains major/minor version  |
  *     +-------------------------------+
@@ -181,9 +181,16 @@
  * 3. Length info of each component can be found in header, in dwords.
  * 4. Modulus and exponent key are not required by driver. They may not appear
  *    in fw. So driver will load a truncated firmware in this case.
+ *
+ * HuC firmware layout is same as GuC firmware.
+ *
+ * HuC firmware css header is different. However, the only difference is where
+ * the version information is saved. The uc_css_header is unified to support
+ * both. Driver should get HuC version from uc_css_header.huc_sw_version, while
+ * uc_css_header.guc_sw_version for GuC.
  */
 
-struct guc_css_header {
+struct uc_css_header {
 	uint32_t module_type;
 	/* header_size includes all non-uCode bits, including css_header, rsa
 	 * key, modulus key and exponent data. */
@@ -214,7 +221,10 @@ struct guc_css_header {
 
 	char username[8];
 	char buildnumber[12];
-	uint32_t device_id;
+	union {
+		uint32_t device_id;
+		uint32_t huc_sw_version;
+	};
 	uint32_t guc_sw_version;
 	uint32_t prod_preprod_fw;
 	uint32_t reserved[12];
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 493295d..0b863a1 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -586,7 +586,7 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 	struct pci_dev *pdev = dev->pdev;
 	struct drm_i915_gem_object *obj;
 	const struct firmware *fw;
-	struct guc_css_header *css;
+	struct uc_css_header *css;
 	size_t size;
 	int err;
 
@@ -603,19 +603,19 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		uc_fw->uc_fw_path, fw);
 
 	/* Check the size of the blob before examining buffer contents */
-	if (fw->size < sizeof(struct guc_css_header)) {
+	if (fw->size < sizeof(struct uc_css_header)) {
 		DRM_NOTE("Firmware header is missing\n");
 		goto fail;
 	}
 
-	css = (struct guc_css_header *)fw->data;
+	css = (struct uc_css_header *)fw->data;
 
 	/* Firmware bits always start from header */
 	uc_fw->header_offset = 0;
 	uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
 		css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
-	if (uc_fw->header_size != sizeof(struct guc_css_header)) {
+	if (uc_fw->header_size != sizeof(struct uc_css_header)) {
 		DRM_NOTE("CSS header definition mismatch\n");
 		goto fail;
 	}
@@ -639,21 +639,36 @@ void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw)
 		goto fail;
 	}
 
-	/* Header and uCode will be loaded to WOPCM. Size of the two. */
-	size = uc_fw->header_size + uc_fw->ucode_size;
-	if (size > guc_wopcm_size(to_i915(dev))) {
-		DRM_NOTE("Firmware is too large to fit in WOPCM\n");
-		goto fail;
-	}
-
 	/*
 	 * The GuC firmware image has the version number embedded at a well-known
 	 * offset within the firmware blob; note that major / minor version are
 	 * TWO bytes each (i.e. u16), although all pointers and offsets are defined
 	 * in terms of bytes (u8).
 	 */
-	uc_fw->major_ver_found = css->guc_sw_version >> 16;
-	uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+	switch (uc_fw->fw_type) {
+	case UC_FW_TYPE_GUC:
+		/* Header and uCode will be loaded to WOPCM. Size of the two. */
+		size = uc_fw->header_size + uc_fw->ucode_size;
+
+		/* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+		if (size > guc_wopcm_size(to_i915(dev))) {
+			DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+			goto fail;
+		}
+		uc_fw->major_ver_found = css->guc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->guc_sw_version & 0xFFFF;
+		break;
+
+	case UC_FW_TYPE_HUC:
+		uc_fw->major_ver_found = css->huc_sw_version >> 16;
+		uc_fw->minor_ver_found = css->huc_sw_version & 0xFFFF;
+		break;
+
+	default:
+		DRM_ERROR("Unknown firmware type %d\n", uc_fw->fw_type);
+		err = -ENOEXEC;
+		goto fail;
+	}
 
 	if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
 	    uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 50+ messages in thread

end of thread, other threads:[~2017-01-14  1:20 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-22 23:12 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
2016-12-22 23:12 ` [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general Anusha Srivatsa
2016-12-23 14:15   ` Arkadiusz Hiler
2016-12-27 17:28   ` Michal Wajdeczko
2017-01-03  0:07     ` Srivatsa, Anusha
2017-01-03 14:15       ` Michal Wajdeczko
2017-01-03 17:43         ` Srivatsa, Anusha
2016-12-22 23:12 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
2016-12-23 14:21   ` Arkadiusz Hiler
2016-12-23 17:32     ` Srivatsa, Anusha
2016-12-22 23:12 ` [PATCH 3/8] drm/i915/huc: Add HuC fw loading support Anusha Srivatsa
2016-12-27 12:37   ` Arkadiusz Hiler
2016-12-27 17:50   ` Michal Wajdeczko
2017-01-03  0:08     ` Srivatsa, Anusha
2017-01-03 18:59       ` Srivatsa, Anusha
2017-01-04 15:15         ` Arkadiusz Hiler
2016-12-22 23:12 ` [PATCH 4/8] drm/i915/huc: Add BXT HuC Loading Support Anusha Srivatsa
2016-12-23 14:43   ` Arkadiusz Hiler
2016-12-22 23:12 ` [PATCH 5/8] drm/i915/HuC: Add KBL huC loading Support Anusha Srivatsa
2016-12-23 14:43   ` Arkadiusz Hiler
2016-12-22 23:12 ` [PATCH 6/8] drm/i915/huc: Add debugfs for HuC loading status check Anusha Srivatsa
2016-12-22 23:12 ` [PATCH 7/8] drm/i915/huc: Support HuC authentication Anusha Srivatsa
2016-12-22 23:30   ` Chris Wilson
2017-01-03 19:55     ` Srivatsa, Anusha
2016-12-22 23:12 ` [PATCH 8/8] drm/i915/get_params: Add HuC status to getparams Anusha Srivatsa
2016-12-23 14:33   ` Arkadiusz Hiler
2016-12-22 23:53 ` ✓ Fi.CI.BAT: success for HuC Loading Patches Patchwork
  -- strict thread matches above, loose matches on Subject: below --
2017-01-14  1:17 [PATCH 0/8] " Anusha Srivatsa
2017-01-14  1:17 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
2017-01-13 18:08 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
2017-01-13 18:08 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
2017-01-13 17:06 Anusha Srivatsa
2017-01-04 14:55 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
2017-01-04 14:55 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
2017-01-04 15:10   ` Arkadiusz Hiler
2017-01-04 13:27 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
2017-01-04 13:27 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
2016-12-15 22:29 [PATCH 0/8] HuC Loading Patches anushasr
2016-12-15 22:29 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC anushasr
2016-12-08 23:02 [PATCH 0/8]HuC Loading Patches anushasr
2016-12-08 23:02 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC anushasr
2016-12-09  9:20   ` Arkadiusz Hiler
2016-12-09 11:55   ` Michal Wajdeczko
2016-12-09 21:42     ` Srivatsa, Anusha
2016-12-12 11:56       ` Arkadiusz Hiler
2016-11-30 23:31 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
2016-11-30 23:31 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
2016-12-01 12:22   ` Arkadiusz Hiler
2016-12-01 18:22     ` Srivatsa, Anusha
2016-11-23 22:27 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
2016-11-23 22:27 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
2016-11-11  0:15 [PATCH v4 0/8] HuC Loading Patches Anusha Srivatsa
2016-11-11  0:15 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
2016-11-09 18:51 [PATCH 1/8] drm/i915/guc: Make the GuC fw loading helper functions general Anusha Srivatsa
2016-11-09 18:51 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
2016-10-03 18:42 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
2016-10-03 18:42 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa
2016-10-13 15:45   ` Jeff McGee
2016-10-14  4:24     ` Jeff McGee
2016-10-24 21:42   ` Carlos Santa
2016-09-29 18:03 [PATCH 0/8] HuC Loading Patches Anusha Srivatsa
2016-09-29 18:03 ` [PATCH 2/8] drm/i915/huc: Unified css_header struct for GuC and HuC Anusha Srivatsa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.