On Fri, 09 Feb 2018 00:03:51 +0100, Jackie Li <yaodong.li@xxxxxxxxx> wrote:
Hardware may have specific restrictions on GuC WOPCM offset and size. On
Gen9, the value of the GuC WOPCM size register needs to be larger than
the
value of GuC WOPCM offset register + a Gen9 specific offset (144KB) for
reserved GuC WOPCM. Fail to enforce such a restriction on GuC WOPCM size
will lead to GuC firmware execution failures. So we need add code to
verify
the GuC WOPCM offset and size to avoid any GuC failures. On the other
hand,
with current static GuC WOPCM offset and size values (512KB for both
offset
and size), the GuC WOPCM size verification will fail on Gen9 even if it
can
be fixed by lowering the GuC WOPCM offset by calculating its value based
on
HuC firmware size (which is likely less than 200KB on Gen9), so that we
can
have a GuC WOPCM size value which is large enough to pass the GuC WOPCM
size check.
This patch updates the reserved GuC WOPCM size for RC6 context on Gen9 to
24KB to strictly align with the Gen9 GuC WOPCM layout and add support to
return CNL specific hardware reserved GuC WOPCM size. It also adds
support
to verify the GuC WOPCM size aganist the Gen9 hardware restrictions.
Meanwhile, it provides a common way to calculate GuC WOPCM offset and
size
based on GuC and HuC firmware sizes for all GuC/HuC enabled platforms.
Currently, GuC WOPCM offset is calculated based on HuC firmware size +
reserved WOPCM size while GuC WOPCM size is set to total WOPCM size - GuC
WOPCM offset - hardware reserved GuC WOPCM size. In this case, GuC WOPCM
offset will be updated based on the size of HuC firmware while GuC WOPCM
size will be set to use all the remaining WOPCM space.
v2:
- Removed intel_wopcm_init (Ville/Sagar/Joonas)
- Renamed and Moved the intel_wopcm_partition into intel_guc (Sagar)
- Removed unnecessary function calls (Joonas)
- Init GuC WOPCM partition as soon as firmware fetching is completed
v3:
- Fixed indentation issues (Chris)
- Removed layering violation code (Chris/Michal)
- Created separat files for GuC wopcm code (Michal)
- Used inline function to avoid code duplication (Michal)
v4:
- Preset the GuC WOPCM top during early GuC init (Chris)
- Fail intel_uc_init_hw() as soon as GuC WOPCM partitioning failed
v5:
- Moved GuC DMA WOPCM register updating code into intel_guc_wopcm.c
- Took care of the locking status before writing to GuC DMA
Write-Once registers. (Joonas)
v6:
- Made sure the GuC WOPCM size to be multiple of 4K (4K aligned)
v8:
- Updated comments and fixed naming issues (Sagar/Joonas)
- Updated commit message to include more description about the hardware
restriction on GuC WOPCM size (Sagar)
v9:
- Minor changes variable names and code comments (Sagar)
- Added detailed GuC WOPCM layout drawing (Sagar/Michal)
- Refined macro definitions to be reader friendly (Michal)
- Removed redundent check to valid flag (Michal)
- Unified first parameter for exported GuC WOPCM functions (Michal)
- Refined the name and parameter list of hardware restriction checking
functions (Michal)
Cc: Michal Wajdeczko <michal.wajdeczko@xxxxxxxxx>
Cc: Sagar Arun Kamble <sagar.a.kamble@xxxxxxxxx>
Cc: Sujaritha Sundaresan <sujaritha.sundaresan@xxxxxxxxx>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@xxxxxxxxx>
Cc: John Spotswood <john.a.spotswood@xxxxxxxxx>
Cc: Oscar Mateo <oscar.mateo@xxxxxxxxx>
Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx>
Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@xxxxxxxxx> (v8)
Signed-off-by: Jackie Li <yaodong.li@xxxxxxxxx>
---
drivers/gpu/drm/i915/i915_gem_context.c | 5 +-
drivers/gpu/drm/i915/intel_guc.c | 5 +-
drivers/gpu/drm/i915/intel_guc.h | 12 ++--
drivers/gpu/drm/i915/intel_guc_wopcm.c | 115
+++++++++++++++++++++++++++++---
drivers/gpu/drm/i915/intel_guc_wopcm.h | 85 +++++++++++++++++++++--
drivers/gpu/drm/i915/intel_huc.c | 2 +-
drivers/gpu/drm/i915/intel_uc.c | 11 ++-
drivers/gpu/drm/i915/intel_uc_fw.c | 11 ++-
drivers/gpu/drm/i915/intel_uc_fw.h | 16 +++++
9 files changed, 229 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c
b/drivers/gpu/drm/i915/i915_gem_context.c
index 3d75f48..414eab2 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -312,12 +312,13 @@ __create_hw_context(struct drm_i915_private
*dev_priv,
ctx->desc_template =
default_desc_template(dev_priv, dev_priv->mm.aliasing_ppgtt);
- /* GuC requires the ring to be placed above GUC_WOPCM_TOP. If GuC is
not
+ /*
+ * GuC requires the ring to be placed above GuC WOPCM top. If GuC is
not
* present or not in use we still need a small bias as ring wraparound
* at offset 0 sometimes hangs. No idea why.
*/
if (USES_GUC(dev_priv))
- ctx->ggtt_offset_bias = GUC_WOPCM_TOP;
+ ctx->ggtt_offset_bias = dev_priv->guc.wopcm.top;
else
ctx->ggtt_offset_bias = I915_GTT_PAGE_SIZE;
diff --git a/drivers/gpu/drm/i915/intel_guc.c
b/drivers/gpu/drm/i915/intel_guc.c
index d9bc2a9..ecd5da2 100644
--- a/drivers/gpu/drm/i915/intel_guc.c
+++ b/drivers/gpu/drm/i915/intel_guc.c
@@ -65,6 +65,7 @@ void intel_guc_init_early(struct intel_guc *guc)
intel_guc_fw_init_early(guc);
intel_guc_ct_init_early(&guc->ct);
intel_guc_log_init_early(guc);
+ intel_guc_wopcm_init_early(&guc->wopcm);
mutex_init(&guc->send_mutex);
guc->send = intel_guc_send_nop;
@@ -478,7 +479,7 @@ int intel_guc_resume(struct drm_i915_private
*dev_priv)
* This is a wrapper to create an object for use with the GuC. In order
to
* use it inside the GuC, an object needs to be pinned lifetime, so we
allocate
* both some backing storage and a range inside the Global GTT. We must
pin
- * it in the GGTT somewhere other than than [0, GUC_WOPCM_TOP) because
that
+ * it in the GGTT somewhere other than than [0, GuC WOPCM top) because
that
* range is reserved inside GuC.
*
* Return: A i915_vma if successful, otherwise an ERR_PTR.
@@ -499,7 +500,7 @@ struct i915_vma *intel_guc_allocate_vma(struct
intel_guc *guc, u32 size)
goto err;
ret = i915_vma_pin(vma, 0, PAGE_SIZE,
- PIN_GLOBAL | PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
+ PIN_GLOBAL | PIN_OFFSET_BIAS | guc->wopcm.top);
if (ret) {
vma = ERR_PTR(ret);
goto err;
diff --git a/drivers/gpu/drm/i915/intel_guc.h
b/drivers/gpu/drm/i915/intel_guc.h
index 50be6de..06f315e 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -49,6 +49,7 @@ struct intel_guc {
struct intel_uc_fw fw;
struct intel_guc_log log;
struct intel_guc_ct ct;
+ struct intel_guc_wopcm wopcm;
/* Log snapshot if GuC errors during load */
struct drm_i915_gem_object *load_err_log;
@@ -109,10 +110,10 @@ static inline void intel_guc_notify(struct
intel_guc *guc)
* @guc: intel guc.
* @vma: i915 graphics virtual memory area.
*
- * GuC does not allow any gfx GGTT address that falls into range [0,
WOPCM_TOP),
- * which is reserved for Boot ROM, SRAM and WOPCM. Currently this top
address is
- * 512K. In order to exclude 0-512K address space from GGTT, all gfx
objects
- * used by GuC is pinned with PIN_OFFSET_BIAS along with size of WOPCM.
+ * GuC does not allow any gfx GGTT address that falls into range
+ * [0, GuC WOPCM top), which is reserved for Boot ROM, SRAM and WOPCM.
+ * All gfx objects used by GuC is pinned with PIN_OFFSET_BIAS along with
+ * top of WOPCM.
*
* Return: GGTT offset that meets the GuC gfx address requirement.
*/
@@ -121,7 +122,8 @@ static inline u32 intel_guc_ggtt_offset(struct
intel_guc *guc,
{
u32 offset = i915_ggtt_offset(vma);
- GEM_BUG_ON(offset < GUC_WOPCM_TOP);
+ GEM_BUG_ON(!guc->wopcm.valid);
+ GEM_BUG_ON(offset < guc->wopcm.top);
GEM_BUG_ON(range_overflows_t(u64, offset, vma->size, GUC_GGTT_TOP));
return offset;
diff --git a/drivers/gpu/drm/i915/intel_guc_wopcm.c
b/drivers/gpu/drm/i915/intel_guc_wopcm.c
index c3d54f8..8b2ce49 100644
--- a/drivers/gpu/drm/i915/intel_guc_wopcm.c
+++ b/drivers/gpu/drm/i915/intel_guc_wopcm.c
@@ -27,22 +27,115 @@
#include "intel_guc_wopcm.h"
#include "i915_drv.h"
+static inline u32 guc_wopcm_context_reserved_size(struct intel_guc *guc)
+{
+ struct drm_i915_private *i915 = guc_to_i915(guc);
+
+ if (IS_GEN9_LP(i915))
+ return BXT_GUC_WOPCM_RC6_CTX_RESERVED;
+
+ return 0;
+}
+
+static inline int gen9_guc_wopcm_size_check(struct intel_guc_wopcm
*guc_wopcm)
+{
+ u32 guc_wopcm_start;
+ u32 delta;
+
+ /*
+ * GuC WOPCM size is at least a dword larger than the offset from WOPCM
+ * base (GuC WOPCM offset from WOPCM base + GEN9_GUC_WOPCM_OFFSET) due
+ * to hardware limitation on Gen9.
+ */
+ guc_wopcm_start = guc_wopcm->offset + GEN9_GUC_WOPCM_OFFSET;
+ if (unlikely(guc_wopcm_start > guc_wopcm->size))
+ return -E2BIG;
+
+ delta = guc_wopcm->size - guc_wopcm_start;
+ if (unlikely(delta < sizeof(u32)))
+ return -E2BIG;
+
+ return 0;
+}
+
+static inline int guc_wopcm_size_check(struct intel_guc *guc)
+{
+ struct drm_i915_private *i915 = guc_to_i915(guc);
+ struct intel_guc_wopcm *guc_wopcm = &guc->wopcm;
+
+ if (IS_GEN9(i915))
+ return gen9_guc_wopcm_size_check(guc_wopcm);
+
+ return 0;
+}
+
/**
- * intel_guc_wopcm_size() - Get the size of GuC WOPCM.
- * @guc: intel guc.
+ * intel_guc_wopcm_init() - Initialize the GuC WOPCM.
+ * @guc_wopcm: intel_guc_wopcm..
Please use better description, maybe "[pointer to] GuC WOPCM"
And remove redundant trailing dot.
+ * @guc_fw_size: size of GuC firmware.
+ * @huc_fw_size: size of HuC firmware.
*
- * Get the platform specific GuC WOPCM size.
+ * Calculate the GuC WOPCM offset and size based on GuC and HuC
firmware sizes.
+ * This function will set the GuC WOPCM size to the size of maximum
WOPCM
+ * available for GuC. This function will also enforce platform dependent
+ * hardware restrictions on GuC WOPCM offset and size. It will fail the
GuC
+ * WOPCM init if any of these checks were failed, so that the following
GuC
+ * firmware uploading would be aborted.
*
- * Return: size of the GuC WOPCM.
+ * Return: 0 on success, non-zero error code on failure.
*/
-u32 intel_guc_wopcm_size(struct intel_guc *guc)
+int intel_guc_wopcm_init(struct intel_guc_wopcm *guc_wopcm, u32
guc_fw_size,
+ u32 huc_fw_size)
{
- struct drm_i915_private *i915 = guc_to_i915(guc);
- u32 size = GUC_WOPCM_TOP;
+ struct intel_guc *guc =
+ container_of(guc_wopcm, struct intel_guc, wopcm);
If you define this as "wopcm_to_guc" inline helper, then maybe
all your functions could take "wopcm" as first parameter?
+ u32 reserved = guc_wopcm_context_reserved_size(guc);
+ u32 offset, size, top;
+ int err;
- /* On BXT, the top of WOPCM is reserved for RC6 context */
- if (IS_GEN9_LP(i915))
- size -= BXT_GUC_WOPCM_RC6_RESERVED;
+ if (!guc_fw_size)
+ return -EINVAL;
As there are many reasons to fail, maybe it would be good idea to
add at least DRM_DEBUG_DRIVER to each failing condition?
+
+ if (reserved >= WOPCM_DEFAULT_SIZE)
+ return -E2BIG;
Do we really need to check this every time in runtime?
I think we can enforce this as GEM_BUG_ON here or in
guc_wopcm_context_reserved_size() function.
+
+ offset = huc_fw_size + WOPCM_RESERVED_SIZE;
+ if (offset >= WOPCM_DEFAULT_SIZE)
+ return -E2BIG;
+
+ /* Hardware requires GuC WOPCM offset to be 16K aligned. */
+ offset = ALIGN(offset, GUC_WOPCM_OFFSET_ALIGNMENT);
+ if ((offset + reserved) >= WOPCM_DEFAULT_SIZE)
+ return -E2BIG;
+
+ top = WOPCM_DEFAULT_SIZE - offset;
+ size = top - reserved;
+
+ /* GuC WOPCM size must be multiple of 4K pages */
+ size &= PAGE_MASK;
Hmm, this will work only in CONFIG_IA64_PAGE_SIZE_4KB, is it ok?
+
+ /*
+ * GuC firmware size needs to be less than or equal to the size of the
+ * available GuC WOPCM (total available GuC WOPCM size - reserved
size).
+ * Need extra 8K stack for GuC firmware.
+ */
+ reserved = GUC_WOPCM_RESERVED + GUC_WOPCM_STACK_RESERVED;
+ if ((guc_fw_size + reserved) > size)
+ return -E2BIG;
+
+ guc->wopcm.offset = offset;
+ guc->wopcm.size = size;
+ guc->wopcm.top = top;
+
+ /* Check platform specific restrictions */
+ err = guc_wopcm_size_check(guc);
maybe "guc_wopcm_check_size(guc_wopcm)"
+ if (err)
+ return err;
+
+ guc->wopcm.valid = 1;
+
+ DRM_DEBUG_DRIVER("GuC WOPCM offset %dKB, size %dKB, top %dKB\n",
+ offset >> 10, size >> 10, top >> 10);
- return size;
+ return 0;
}
diff --git a/drivers/gpu/drm/i915/intel_guc_wopcm.h
b/drivers/gpu/drm/i915/intel_guc_wopcm.h
index 7323604..3af7ca9 100644
--- a/drivers/gpu/drm/i915/intel_guc_wopcm.h
+++ b/drivers/gpu/drm/i915/intel_guc_wopcm.h
@@ -31,15 +31,86 @@
struct intel_guc;
-/* 512KB static offset from WOPCM base. */
-#define GUC_WOPCM_OFFSET_VALUE (512 << 10)
/*
- * 512KB static GuC WOPCM size from GUC_WOPCM_OFFSET_VALUE to the end
of GuC
- * WOPCM. GuC addresses below GUC_WOPCM_TOP don't map through the GTT.
+ * The layout of the WOPCM will be determined by GuC WOPCM size and
offset
+ * registers settings. Currently, GuC WOPCM code calculates the GuC
WOPCM offset
+ * and size values based on a layout as shown below:
+ *
+ * +=====+==>+====================+<== GuC WOPCM top
+ * ^ ^ | HW contexts RSVD |
+ * | | +--------------------+<== GuC WOPCM size
+ * | | | |
+ * | GuC | |
+ * | WOPCM +--------------------+<== (Platform specific size)
+ * | | | GuC FW RSVD |
+ * WOPCM | +------------------- +<== (16KB)
+ * | v | RSVD GUC WOPCM |
Please be consistent in naming: Guc vs. GUC
+ * | +==>+====================+<== GuC WOPCM offset
+ * | | RSVD WOPCM |
+ * | +------------------- +
+ * v | HuC FW |
+ * +========>+====================+<== WOPCM Base
+ *
+ * GuC accessible WOPCM starts at GuC WOPCM offset and ends at GuC
WOPCM size.
+ * The top part of the GuC WOPCM is reserved for hardware contexts
(e.g. RC6
+ * context). We need to keep tracking the GuC WOPCM top since hardware
requires
+ * the GGTT offset of a GuC accessible GEM buffer to be larger than the
value of
+ * GuC WOPCM top. The values of GuC WOPCM size and top should be set to
the
+ * length from GuC WOPCM offset in bytes.
+ */
+
+/* Default WOPCM size 1MB. */
+#define WOPCM_DEFAULT_SIZE (0x1 << 20)
(1 << 20) or (1024 * 1024)
+/* The initial 16KB WOPCM (RSVD WOPCM) is reserved. */
+#define WOPCM_RESERVED_SIZE (16 << 10)
+
+/* GUC WOPCM offset needs to be 16KB aligned. */
+#define GUC_WOPCM_OFFSET_ALIGNMENT (16 << 10)
+/* 16KB reserved at the beginning of GuC WOPCM. */
+#define GUC_WOPCM_RESERVED (16 << 10)
+/* 8KB from GUC_WOPCM_RESERVED is reserved for GuC stack. */
+#define GUC_WOPCM_STACK_RESERVED (8 << 10)
+/* 24KB at the end of GuC WOPCM is reserved for RC6 CTX on BXT. */
+#define BXT_GUC_WOPCM_RC6_CTX_RESERVED (24 << 10)
+
+/*
+ * GuC WOPCM starts at 144KB (GUC_WOPCM_RESERVED + 128KB reserved for
GuC
+ * firmware loading) from GuC WOPCM offset on BXT.
+ */
+#define GEN9_GUC_WOPCM_OFFSET (144 << 10)
Other BXT specific macro (BXT_GUC_WOPCM_RC6_CTX_RESERVED) was
defined with BXT_ prefix ... can we use common prefix?
+
+/**
+ * intel_guc_wopcm - GuC WOPCM related settings.
+ * @offset: GuC WOPCM offset from the WOPCM base.
+ * @size: size of GuC WOPCM for GuC firmware.
+ * @top: start of the non-GuC WOPCM memory.
+ * @valid: whether this structure contains valid (1-valid, 0-invalid)
info.
+ *
+ * We simply use this structure to track the GuC use of WOPCM. The
layout of
+ * WOPCM would be defined by writing to GuC WOPCM offset and size
registers.
+ */
+struct intel_guc_wopcm {
+ u32 offset;
+ u32 size;
+ u32 top;
+ u32 valid;
+};
+
+/**
+ * intel_guc_wopcm_init_early() - Early initialization of the GuC WOPCM.
+ * @guc_wopcm: intel_guc_wopcm.
+ *
+ * Setup the GuC WOPCM top to the top of the overall WOPCM. This will
guarantee
+ * that the allocation of the GuC accessible objects won't fall into
WOPCM when
+ * GuC partition isn't present.
+ *
*/
-#define GUC_WOPCM_TOP (512 << 10)
-#define BXT_GUC_WOPCM_RC6_RESERVED (64 << 10)
+static inline void intel_guc_wopcm_init_early(struct intel_guc_wopcm
*guc_wopcm)
+{
+ guc_wopcm->top = WOPCM_DEFAULT_SIZE;
+}
-u32 intel_guc_wopcm_size(struct intel_guc *guc);
+int intel_guc_wopcm_init(struct intel_guc_wopcm *guc_wopcm, u32
guc_size,
+ u32 huc_size);
#endif
diff --git a/drivers/gpu/drm/i915/intel_huc.c
b/drivers/gpu/drm/i915/intel_huc.c
index aed9c1c..dc6a6c6 100644
--- a/drivers/gpu/drm/i915/intel_huc.c
+++ b/drivers/gpu/drm/i915/intel_huc.c
@@ -206,7 +206,7 @@ int intel_huc_auth(struct intel_huc *huc)
return -ENOEXEC;
vma = i915_gem_object_ggtt_pin(huc->fw.obj, NULL, 0, 0,
- PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
+ PIN_OFFSET_BIAS | guc->wopcm.top);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
DRM_ERROR("HuC: Failed to pin huc fw object %d\n", ret);
diff --git a/drivers/gpu/drm/i915/intel_uc.c
b/drivers/gpu/drm/i915/intel_uc.c
index 1b2831b..c842f36 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -283,6 +283,9 @@ void intel_uc_fini_misc(struct drm_i915_private
*dev_priv)
int intel_uc_init(struct drm_i915_private *dev_priv)
{
struct intel_guc *guc = &dev_priv->guc;
+ struct intel_huc *huc = &dev_priv->huc;
+ u32 guc_fw_size = intel_uc_fw_get_size(&guc->fw);
+ u32 huc_fw_size = intel_uc_fw_get_size(&huc->fw);
int ret;
if (!USES_GUC(dev_priv))
@@ -291,6 +294,10 @@ int intel_uc_init(struct drm_i915_private *dev_priv)
if (!HAS_GUC(dev_priv))
return -ENODEV;
+ ret = intel_guc_wopcm_init(&guc->wopcm, guc_fw_size, huc_fw_size);
+ if (ret)
+ return ret;
+
ret = intel_guc_init(guc);
if (ret)
return ret;
@@ -340,9 +347,9 @@ int intel_uc_init_hw(struct drm_i915_private
*dev_priv)
gen9_reset_guc_interrupts(dev_priv);
/* init WOPCM */
- I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(guc));
+ I915_WRITE(GUC_WOPCM_SIZE, guc->wopcm.size);
I915_WRITE(DMA_GUC_WOPCM_OFFSET,
- GUC_WOPCM_OFFSET_VALUE | HUC_LOADING_AGENT_GUC);
+ guc->wopcm.offset | HUC_LOADING_AGENT_GUC);
/* WaEnableuKernelHeaderValidFix:skl */
/* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c
b/drivers/gpu/drm/i915/intel_uc_fw.c
index 24945cf..791263a 100644
--- a/drivers/gpu/drm/i915/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/intel_uc_fw.c
@@ -95,9 +95,13 @@ void intel_uc_fw_fetch(struct drm_i915_private
*dev_priv,
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);
- /* Header and uCode will be loaded to WOPCM */
+ /*
+ * Header and uCode will be loaded to WOPCM
+ * Only check the size against the overall available WOPCM here. Will
+ * continue to check the size during WOPCM partition calculation.
+ */
size = uc_fw->header_size + uc_fw->ucode_size;
- if (size > intel_guc_wopcm_size(&dev_priv->guc)) {
+ if (size > WOPCM_DEFAULT_SIZE) {
DRM_WARN("%s: Firmware is too large to fit in WOPCM\n",
intel_uc_fw_type_repr(uc_fw->type));
err = -E2BIG;
@@ -207,6 +211,7 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
int (*xfer)(struct intel_uc_fw *uc_fw,
struct i915_vma *vma))
{
+ struct drm_i915_private *i915 = to_i915(uc_fw->obj->base.dev);
struct i915_vma *vma;
int err;
@@ -230,7 +235,7 @@ int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
}
vma = i915_gem_object_ggtt_pin(uc_fw->obj, NULL, 0, 0,
- PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
+ PIN_OFFSET_BIAS | i915->guc.wopcm.top);
if (IS_ERR(vma)) {
err = PTR_ERR(vma);
DRM_DEBUG_DRIVER("%s fw ggtt-pin err=%d\n",
diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h
b/drivers/gpu/drm/i915/intel_uc_fw.h
index d5fd460..298d475 100644
--- a/drivers/gpu/drm/i915/intel_uc_fw.h
+++ b/drivers/gpu/drm/i915/intel_uc_fw.h
@@ -115,6 +115,22 @@ static inline bool intel_uc_fw_is_selected(struct
intel_uc_fw *uc_fw)
return uc_fw->path != NULL;
}
+/**
+ * intel_uc_fw_get_size() - Get the size of the firmware.
+ * @uc_fw: intel_uc_fw structure.
+ *
+ * Get the size of the firmware that will be placed in WOPCM.
+ *
+ * Return: Zero on invalid firmware status. actual size on success.
Return: Size of the firmware, or zero on firmware fetch failure.
+ */
+static inline u32 intel_uc_fw_get_size(struct intel_uc_fw *uc_fw)
+{
+ if (uc_fw->fetch_status != INTEL_UC_FIRMWARE_SUCCESS)
+ return 0;
+
+ return uc_fw->header_size + uc_fw->ucode_size;
+}
+
void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
struct intel_uc_fw *uc_fw);
int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx