Re: [Intel-gfx] [PATCH v8 3/6] drm/i915/guc: Implement dynamic GuC WOPCM offset and size

2018-02-07 Thread Yaodong Li

On 02/07/2018 09:24 AM, Michal Wajdeczko wrote:
 int guc_wopcm_check_huc_fw_size(struct guc_wopcm *wopcm, u32 huc_size)


patch 1/6 & 2/6 are only for some code movings. but have to make it 
clean.

but I do not need this func anymore:o)


so maybe part of these code movement was unnecessary, and affected
code can be replaced directly in this patch ?

That's how I did it before!:-) but I learned my lesson that I've to keep 
every change/patch
clear enough or readers will get confused;-) Actually, I was struggling 
on this a bit, but it's clearer to have to valid bit in this
struct instead of only checking offset/size/top. And now that we have 
valid bit


But if check_hw_restrictions() fails we will return error and we should
never use this struct, so this 'valid' bit now seems more redundant.

In current code, we do verify the ggtt offset against wopcm top in our 
current code which means
current code won't trust the fact that ggtt offset would never be used 
after uc/guc init failed.
This is the reason for this valid bit - I won't assume the ggtt_offset 
would never be called even
if the uc/guc_init returned failure either, since it would be weird if 
we don't check the valid bit

in guc_ggtt_offset() but still verify the offset against the wopcm top.

Regards,
-Jackie

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


Re: [Intel-gfx] [PATCH v8 3/6] drm/i915/guc: Implement dynamic GuC WOPCM offset and size

2018-02-07 Thread Michal Wajdeczko
On Wed, 07 Feb 2018 05:51:56 +0100, Yaodong Li   
wrote:





On 02/06/2018 02:25 PM, Michal Wajdeczko wrote:



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;


I know that Joonas was against using extra inline function to read
value of "guc.wopcm.top" but maybe we should discuss it again as
now we maybe using invalid/unset value since now we are not verifying
"guc->wopcm.valid" flag.

It should be fine in this case since we have early inited the value to  
the worst
case (using the size of all WOPCM). we could not use valid here since  
uc_init

has been called at this point.


+static inline int gen9_guc_wopcm_size_check(struct drm_i915_private  
*i915)


maybe it would be better to pass "wopcm" instead of "i915" ?

hmm, I think it's better to have an unified parameter list for all the  
check functions.

and it the same since we will have to get wopcm from i915 anyways.


but you can still access i915 from wopcm using container_of trick.


+{
+struct intel_guc_wopcm *wopcm = >guc.wopcm;

use variable name as guc_wopcm?

+u32 guc_wopcm_start;
+u32 delta;
+
+/*
+ * GuC WOPCM size is at least 4 bytes larger than the offset  
from WOPCM


Either use 4B directly below (as you give explanation here) or move that
comment near the definition of GEN9_GUC_WOPCM_DELTA.

+ * base (GuC WOPCM offset from WOPCM base +  
GEN9_GUC_WOPCM_OFFSET) due

+ * to hardware limitation on Gen9.
+ */
+guc_wopcm_start = wopcm->offset + GEN9_GUC_WOPCM_OFFSET;
+if (unlikely(guc_wopcm_start > wopcm->size))
+return -E2BIG;
+
+delta = wopcm->size - guc_wopcm_start;
+if (unlikely(delta < GEN9_GUC_WOPCM_DELTA))
+return -E2BIG;
+
+return 0;
+}
+
+static inline int guc_wopcm_check_hw_restrictions(struct intel_guc  
*guc)

+{
+struct drm_i915_private *i915 = guc_to_i915(guc);
+
+if (IS_GEN9(i915))
+return gen9_guc_wopcm_size_check(i915);


please use function name that matches dispatcher function

guc_wopcm_check_hw_restrictions()
gen9_guc_wopcm_check_hw_restrictions()

or

guc_wopcm_size_check()
gen9_guc_wopcm_size_check()


+
+return 0;
+}
+
+/**
+ * intel_guc_wopcm_init() - Initialize the GuC WOPCM..

remove extra "."

   * @guc: intel guc.
+ * @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 to set the GuC WOPCM size to the size of  
maximum WOPCM

remove "to"
+ * 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)


Hmm, it looks that all your changes for this function from patch 2/6
are now lost ...

patch 1/6 & 2/6 are only for some code movings. but have to make it  
clean.

but I do not need this func anymore:o)


so maybe part of these code movement was unnecessary, and affected
code can be replaced directly in this patch ?


+int intel_guc_wopcm_init(struct intel_guc *guc, u32 guc_fw_size,
+ u32 huc_fw_size)
  {
-struct drm_i915_private *i915 = guc_to_i915(guc);
-u32 size = GUC_WOPCM_TOP;
+u32 reserved = guc_reserved_wopcm_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->wopcm.valid)
+return 0;


Is there a scenario when this function will be called more than one?

You're right. we need not need such a check anymore.



+
+if (!guc_fw_size)
+return -EINVAL;


GEM_BUG_ON ?


+
+if (reserved >= WOPCM_DEFAULT_SIZE)
+return -E2BIG;


GEM_BUG_ON ?

Will give the control back to uc_init.?


Why?
Note that we control what guc_reserved_wopcm_size() will return
so this check is just for us, we should never fail here.




+
+offset = huc_fw_size + WOPCM_RESERVED_SIZE;


What's the difference between guc_reserved_wopcm_size and  
WOPCM_RESERVED_SIZE



WOPCM_RESERVED_SIZE is the reserved size in Non-GuC WOPCM.

+guc->wopcm.offset = offset;
+guc->wopcm.size = size;
+guc->wopcm.top = top;
+
+/* Check 

Re: [Intel-gfx] [PATCH v8 3/6] drm/i915/guc: Implement dynamic GuC WOPCM offset and size

2018-02-06 Thread Yaodong Li



On 02/06/2018 02:25 PM, Michal Wajdeczko wrote:



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;


I know that Joonas was against using extra inline function to read
value of "guc.wopcm.top" but maybe we should discuss it again as
now we maybe using invalid/unset value since now we are not verifying
"guc->wopcm.valid" flag.

It should be fine in this case since we have early inited the value to 
the worst
case (using the size of all WOPCM). we could not use valid here since 
uc_init

has been called at this point.


+static inline int gen9_guc_wopcm_size_check(struct drm_i915_private 
*i915)


maybe it would be better to pass "wopcm" instead of "i915" ?

hmm, I think it's better to have an unified parameter list for all the 
check functions.

and it the same since we will have to get wopcm from i915 anyways.

+{
+    struct intel_guc_wopcm *wopcm = >guc.wopcm;

use variable name as guc_wopcm?

+    u32 guc_wopcm_start;
+    u32 delta;
+
+    /*
+ * GuC WOPCM size is at least 4 bytes larger than the offset 
from WOPCM


Either use 4B directly below (as you give explanation here) or move that
comment near the definition of GEN9_GUC_WOPCM_DELTA.

+ * base (GuC WOPCM offset from WOPCM base + 
GEN9_GUC_WOPCM_OFFSET) due

+ * to hardware limitation on Gen9.
+ */
+    guc_wopcm_start = wopcm->offset + GEN9_GUC_WOPCM_OFFSET;
+    if (unlikely(guc_wopcm_start > wopcm->size))
+    return -E2BIG;
+
+    delta = wopcm->size - guc_wopcm_start;
+    if (unlikely(delta < GEN9_GUC_WOPCM_DELTA))
+    return -E2BIG;
+
+    return 0;
+}
+
+static inline int guc_wopcm_check_hw_restrictions(struct intel_guc 
*guc)

+{
+    struct drm_i915_private *i915 = guc_to_i915(guc);
+
+    if (IS_GEN9(i915))
+    return gen9_guc_wopcm_size_check(i915);


please use function name that matches dispatcher function

guc_wopcm_check_hw_restrictions()
gen9_guc_wopcm_check_hw_restrictions()

or

guc_wopcm_size_check()
gen9_guc_wopcm_size_check()


+
+    return 0;
+}
+
+/**
+ * intel_guc_wopcm_init() - Initialize the GuC WOPCM..

remove extra "."

   * @guc: intel guc.
+ * @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 to set the GuC WOPCM size to the size of 
maximum WOPCM

remove "to"
+ * 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)


Hmm, it looks that all your changes for this function from patch 2/6
are now lost ...


patch 1/6 & 2/6 are only for some code movings. but have to make it clean.
but I do not need this func anymore:o)

+int intel_guc_wopcm_init(struct intel_guc *guc, u32 guc_fw_size,
+ u32 huc_fw_size)
  {
-    struct drm_i915_private *i915 = guc_to_i915(guc);
-    u32 size = GUC_WOPCM_TOP;
+    u32 reserved = guc_reserved_wopcm_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->wopcm.valid)
+    return 0;


Is there a scenario when this function will be called more than one?

You're right. we need not need such a check anymore.



+
+    if (!guc_fw_size)
+    return -EINVAL;


GEM_BUG_ON ?


+
+    if (reserved >= WOPCM_DEFAULT_SIZE)
+    return -E2BIG;


GEM_BUG_ON ?

Will give the control back to uc_init.?



+
+    offset = huc_fw_size + WOPCM_RESERVED_SIZE;


What's the difference between guc_reserved_wopcm_size and 
WOPCM_RESERVED_SIZE



WOPCM_RESERVED_SIZE is the reserved size in Non-GuC WOPCM.

+    guc->wopcm.offset = offset;
+    guc->wopcm.size = size;
+    guc->wopcm.top = top;
+
+    /* Check platform specific restrictions */
+    err = guc_wopcm_check_hw_restrictions(guc);


maybe you should check HW restrictions *before* initializing the 
structure?


err = check_hw_restrictions(i915, offset, size, top);
Actually, I was struggling on this a bit, but it's clearer to have to 
valid bit in this
struct instead of only checking offset/size/top. And now that we have 
valid bit
it would be better to init the 

Re: [Intel-gfx] [PATCH v8 3/6] drm/i915/guc: Implement dynamic GuC WOPCM offset and size

2018-02-06 Thread Michal Wajdeczko
On Tue, 06 Feb 2018 07:20:41 +0100, Sagar Arun Kamble  
 wrote:



change looks good to me. minor updates suggested with r-b.


On 2/6/2018 5:32 AM, Jackie Li 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.

Add below line here?

Second restriction is for Gen9 and Gen10 and it is w.r.t. HuC firmware  
size as per which "GuC WOPCM size - 16K" should

be greater than or equal to HuC firmware size.

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. 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 - reserved RC6CTX 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)

Cc: Michal Wajdeczko 
Cc: Sagar Arun Kamble 
Cc: Sujaritha Sundaresan 
Cc: Daniele Ceraolo Spurio 
Cc: John Spotswood 
Cc: Oscar Mateo 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
Signed-off-by: Jackie Li 


Reviewed-by: Sagar Arun Kamble 

---
  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  | 116  
+---

  drivers/gpu/drm/i915/intel_guc_wopcm.h  |  66 --
  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, 213 insertions(+), 31 deletions(-)

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

index 648e753..546404e 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;


I know that Joonas was against using extra inline function to read
value of 

Re: [Intel-gfx] [PATCH v8 3/6] drm/i915/guc: Implement dynamic GuC WOPCM offset and size

2018-02-05 Thread Sagar Arun Kamble

change looks good to me. minor updates suggested with r-b.


On 2/6/2018 5:32 AM, Jackie Li 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.

Add below line here?

Second restriction is for Gen9 and Gen10 and it is w.r.t. HuC firmware 
size as per which "GuC WOPCM size - 16K" should

be greater than or equal to HuC firmware size.

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. 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 - reserved RC6CTX 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)

Cc: Michal Wajdeczko 
Cc: Sagar Arun Kamble 
Cc: Sujaritha Sundaresan 
Cc: Daniele Ceraolo Spurio 
Cc: John Spotswood 
Cc: Oscar Mateo 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
Signed-off-by: Jackie Li 


Reviewed-by: Sagar Arun Kamble 

---
  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  | 116 +---
  drivers/gpu/drm/i915/intel_guc_wopcm.h  |  66 --
  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, 213 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 648e753..546404e 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
--- 

[Intel-gfx] [PATCH v8 3/6] drm/i915/guc: Implement dynamic GuC WOPCM offset and size

2018-02-05 Thread Jackie Li
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. 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 - reserved RC6CTX 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)

Cc: Michal Wajdeczko 
Cc: Sagar Arun Kamble 
Cc: Sujaritha Sundaresan 
Cc: Daniele Ceraolo Spurio 
Cc: John Spotswood 
Cc: Oscar Mateo 
Cc: Chris Wilson 
Cc: Joonas Lahtinen 
Signed-off-by: Jackie Li 
---
 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  | 116 +---
 drivers/gpu/drm/i915/intel_guc_wopcm.h  |  66 --
 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, 213 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_context.c 
b/drivers/gpu/drm/i915/i915_gem_context.c
index 648e753..546404e 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(>ct);
intel_guc_log_init_early(guc);
+   intel_guc_wopcm_init_early(>wopcm);
 
mutex_init(>send_mutex);
guc->send = intel_guc_send_nop;
@@ -478,7 +479,7 @@