Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd132858 authored by Anusha Srivatsa's avatar Anusha Srivatsa Committed by Jani Nikula
Browse files

drm/i915/huc: Add HuC fw loading support

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. 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.
v6: 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>
v7: Change dev to dev_priv in macro definition.
Corrected comments.
v8: rebased on top of drm-tip. 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.
v9: 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.
v10: rebased. Correct comments. Make intel_huc_fini() accept dev_priv
instead of dev like intel_huc_init() and intel_huc_load().Move definition
to i915_guc_reg.h from intel_uc.h. Clean DMA_CTRL bits after HuC DMA
transfer in huc_ucode_xfer() instead of guc_ucode_xfer(). Add suitable
WARNs to give extra info.
v11: rebased. Add proper bias for HuC and make sure there are
asserts on failure by using guc_ggtt_offset_vma(). Introduce
intel_huc.c and remove intel_huc_loader.c since it has functions that
do more than just loading.Correct year in copyright.
v12: remove invalidates that are not required anymore.

Cc: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Cc: Michal Wajdeczko <michal.wajdeczko@intel.com>
Tested-by: default avatarXiang Haihao <haihao.xiang@intel.com>
Signed-off-by: default avatarAnusha Srivatsa <anusha.srivatsa@intel.com>
Signed-off-by: default avatarAlex Dai <yu.dai@intel.com>
Signed-off-by: default avatarPeter Antoine <peter.antoine@intel.com>
Reviewed-by: default avatarMichal Wajdeczko <michal.wajdeczko@intel.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1484755558-1234-1-git-send-email-anusha.srivatsa@intel.com
parent 5b8cd075
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ i915-y += i915_cmd_parser.o \
i915-y += intel_uc.o \
	  intel_guc_log.o \
	  intel_guc_loader.o \
	  intel_huc.o \
	  i915_guc_submission.o

# autogenerated null render state
+3 −0
Original line number Diff line number Diff line
@@ -599,6 +599,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)
	i915_gem_fini(dev_priv);
cleanup_irq:
	intel_guc_fini(dev_priv);
	intel_huc_fini(dev_priv);
	drm_irq_uninstall(dev);
	intel_teardown_gmbus(dev_priv);
cleanup_csr:
@@ -1314,6 +1316,7 @@ void i915_driver_unload(struct drm_device *dev)
	drain_workqueue(dev_priv->wq);

	intel_guc_fini(dev_priv);
	intel_huc_fini(dev_priv);
	i915_gem_fini(dev_priv);
	intel_fbc_cleanup_cfb(dev_priv);

+2 −0
Original line number Diff line number Diff line
@@ -2073,6 +2073,7 @@ struct drm_i915_private {

	struct intel_gvt *gvt;

	struct intel_huc huc;
	struct intel_guc guc;

	struct intel_csr csr;
@@ -2847,6 +2848,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)

+6 −0
Original line number Diff line number Diff line
@@ -61,12 +61,18 @@
#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)

#define HUC_STATUS2             _MMIO(0xD3B0)
#define   HUC_FW_VERIFIED       (1<<7)

/* Defines WOPCM space available to GuC firmware */
#define GUC_WOPCM_SIZE			_MMIO(0xc050)
/* GuC addresses below GUC_WOPCM_TOP don't map through the GTT */
+4 −3
Original line number Diff line number Diff line
@@ -328,7 +328,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;

@@ -364,7 +364,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. */
@@ -506,6 +506,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;
@@ -654,7 +655,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;
		}
Loading