Re: [Intel-gfx] [PATCH 3/3] drm/i915: Disable PSMI idle messaging when stopping ring

2019-02-28 Thread Mika Kuoppala
Chris Wilson  writes:

> Quoting Mika Kuoppala (2019-02-28 16:01:33)
>> Hardware cannot be in a middle of idle flow messaging
>> when we pull the plug from ringbuffer. Disable idle
>> messaging before we do so to avoid potential deadlock
>> on engine initialization and reset.
>> 
>> v2: INVALID_MMIO_REG, unconditional enable (Chris)
>> v3: comment (Chris), bspec reference
>> 
>> References: bspec/11751
>> Cc: Chris Wilson 
>> Acked-by: Chris Wilson 
>> Signed-off-by: Mika Kuoppala 
>> ---
>>  drivers/gpu/drm/i915/intel_engine_cs.c | 64 +-
>>  1 file changed, 63 insertions(+), 1 deletion(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
>> b/drivers/gpu/drm/i915/intel_engine_cs.c
>> index 2a94b92cfcd3..10cb6b22fe92 100644
>> --- a/drivers/gpu/drm/i915/intel_engine_cs.c
>> +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
>> @@ -764,7 +764,7 @@ int intel_engine_init_common(struct intel_engine_cs 
>> *engine)
>>  
>>  /**
>>   * intel_engines_cleanup_common - cleans up the engine state created by
>> - *the common initiailizers.
>> + *the common initializers.
>>   * @engine: Engine to cleanup.
>>   *
>>   * This cleans up everything created by the common helpers.
>> @@ -865,6 +865,63 @@ void intel_engine_cancel_stop_cs(struct intel_engine_cs 
>> *engine)
>>   _MASKED_BIT_DISABLE(STOP_RING));
>>  }
>>  
>> +static i915_reg_t get_idle_poll_reg(const struct intel_engine_cs *engine)
>> +{
>> +   if (engine->id != RCS)
>> +   return INVALID_MMIO_REG;
>> +
>> +   if (IS_GEN(engine->i915, 9))
>> +   return GEN9_RCS_FE_FSM2;
>> +
>> +   if (IS_GEN(engine->i915, 8))
>> +   return GEN6_RCS_PWR_FSM;
>> +
>> +   return INVALID_MMIO_REG;
>> +}
>> +
>> +static void disable_idle_messaging(struct intel_engine_cs *engine)
>> +{
>> +   struct drm_i915_private *dev_priv = engine->i915;
>> +   i915_reg_t poll_reg;
>> +
>> +   poll_reg = get_idle_poll_reg(engine);
>> +   if (!i915_mmio_reg_valid(poll_reg))
>> +   return;
>> +
>> +   GEM_DEBUG_WARN_ON(I915_READ_FW(GEN6_RC_SLEEP_PSMI_CONTROL) &
>> + GEN6_PSMI_SLEEP_MSG_DISABLE);
>> +   /*
>> +* Hardware must not be in middle of idle flow signalling
>> +* when the RING_CTL is zeroed. In order to prevent this
>> +* we disable the messaging temporarily.
>> +*/
>> +   I915_WRITE_FW(GEN6_RC_SLEEP_PSMI_CONTROL,
>> + _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
>> +
>> +   /*
>> +* Poll the magic bits to ensure that engine state machine
>> +* is in valid state for stopping the ring.
>> +*/
>> +   if (__intel_wait_for_register_fw(dev_priv, poll_reg,
>> +0x7f, 0x30,
>> +5000, 0,
>> +NULL))
>> +   DRM_DEBUG_DRIVER("psmi idle msg poll timeout\n");
>> +}
>> +
>> +static void enable_idle_messaging(struct intel_engine_cs *engine)
>> +{
>> +   struct drm_i915_private *dev_priv = engine->i915;
>> +   i915_reg_t poll_reg;
>> +
>> +   poll_reg = get_idle_poll_reg(engine);
>> +   if (!i915_mmio_reg_valid(poll_reg))
>> +   return;
>> +
>> +   I915_WRITE_FW(GEN6_RC_SLEEP_PSMI_CONTROL,
>> + _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
>> +}
>> +
>>  int intel_engine_stop_ring(struct intel_engine_cs *engine)
>>  {
>> struct drm_i915_private *dev_priv = engine->i915;
>> @@ -880,9 +937,14 @@ int intel_engine_stop_ring(struct intel_engine_cs 
>> *engine)
>> I915_WRITE_FW(RING_TAIL(base), 0);
>> POSTING_READ_FW(RING_TAIL(base));
>>  
>> +   /* Idle messaging needs to be off during ring disable */
>
> Ok, that's ott :)

Rest assured, Captain Obvious will scrap this before merging.

>
> The previous pair are a nice why, peeling back some of the layers of the
> HW to see what's going on. This one is just repeating
> disable_idle_messing().

There is this dream I had where hardware engineers
did review patches.

But it should be close enough of 'what's going on'

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

Re: [Intel-gfx] [PATCH 3/3] drm/i915: Disable PSMI idle messaging when stopping ring

2019-02-28 Thread Chris Wilson
Quoting Mika Kuoppala (2019-02-28 16:01:33)
> Hardware cannot be in a middle of idle flow messaging
> when we pull the plug from ringbuffer. Disable idle
> messaging before we do so to avoid potential deadlock
> on engine initialization and reset.
> 
> v2: INVALID_MMIO_REG, unconditional enable (Chris)
> v3: comment (Chris), bspec reference
> 
> References: bspec/11751
> Cc: Chris Wilson 
> Acked-by: Chris Wilson 
> Signed-off-by: Mika Kuoppala 
> ---
>  drivers/gpu/drm/i915/intel_engine_cs.c | 64 +-
>  1 file changed, 63 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
> b/drivers/gpu/drm/i915/intel_engine_cs.c
> index 2a94b92cfcd3..10cb6b22fe92 100644
> --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> @@ -764,7 +764,7 @@ int intel_engine_init_common(struct intel_engine_cs 
> *engine)
>  
>  /**
>   * intel_engines_cleanup_common - cleans up the engine state created by
> - *the common initiailizers.
> + *the common initializers.
>   * @engine: Engine to cleanup.
>   *
>   * This cleans up everything created by the common helpers.
> @@ -865,6 +865,63 @@ void intel_engine_cancel_stop_cs(struct intel_engine_cs 
> *engine)
>   _MASKED_BIT_DISABLE(STOP_RING));
>  }
>  
> +static i915_reg_t get_idle_poll_reg(const struct intel_engine_cs *engine)
> +{
> +   if (engine->id != RCS)
> +   return INVALID_MMIO_REG;
> +
> +   if (IS_GEN(engine->i915, 9))
> +   return GEN9_RCS_FE_FSM2;
> +
> +   if (IS_GEN(engine->i915, 8))
> +   return GEN6_RCS_PWR_FSM;
> +
> +   return INVALID_MMIO_REG;
> +}
> +
> +static void disable_idle_messaging(struct intel_engine_cs *engine)
> +{
> +   struct drm_i915_private *dev_priv = engine->i915;
> +   i915_reg_t poll_reg;
> +
> +   poll_reg = get_idle_poll_reg(engine);
> +   if (!i915_mmio_reg_valid(poll_reg))
> +   return;
> +
> +   GEM_DEBUG_WARN_ON(I915_READ_FW(GEN6_RC_SLEEP_PSMI_CONTROL) &
> + GEN6_PSMI_SLEEP_MSG_DISABLE);
> +   /*
> +* Hardware must not be in middle of idle flow signalling
> +* when the RING_CTL is zeroed. In order to prevent this
> +* we disable the messaging temporarily.
> +*/
> +   I915_WRITE_FW(GEN6_RC_SLEEP_PSMI_CONTROL,
> + _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
> +
> +   /*
> +* Poll the magic bits to ensure that engine state machine
> +* is in valid state for stopping the ring.
> +*/
> +   if (__intel_wait_for_register_fw(dev_priv, poll_reg,
> +0x7f, 0x30,
> +5000, 0,
> +NULL))
> +   DRM_DEBUG_DRIVER("psmi idle msg poll timeout\n");
> +}
> +
> +static void enable_idle_messaging(struct intel_engine_cs *engine)
> +{
> +   struct drm_i915_private *dev_priv = engine->i915;
> +   i915_reg_t poll_reg;
> +
> +   poll_reg = get_idle_poll_reg(engine);
> +   if (!i915_mmio_reg_valid(poll_reg))
> +   return;
> +
> +   I915_WRITE_FW(GEN6_RC_SLEEP_PSMI_CONTROL,
> + _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
> +}
> +
>  int intel_engine_stop_ring(struct intel_engine_cs *engine)
>  {
> struct drm_i915_private *dev_priv = engine->i915;
> @@ -880,9 +937,14 @@ int intel_engine_stop_ring(struct intel_engine_cs 
> *engine)
> I915_WRITE_FW(RING_TAIL(base), 0);
> POSTING_READ_FW(RING_TAIL(base));
>  
> +   /* Idle messaging needs to be off during ring disable */

Ok, that's ott :)

The previous pair are a nice why, peeling back some of the layers of the
HW to see what's going on. This one is just repeating
disable_idle_messing().
-Chris
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Intel-gfx] [PATCH 3/3] drm/i915: Disable PSMI idle messaging when stopping ring

2019-02-28 Thread Mika Kuoppala
Hardware cannot be in a middle of idle flow messaging
when we pull the plug from ringbuffer. Disable idle
messaging before we do so to avoid potential deadlock
on engine initialization and reset.

v2: INVALID_MMIO_REG, unconditional enable (Chris)
v3: comment (Chris), bspec reference

References: bspec/11751
Cc: Chris Wilson 
Acked-by: Chris Wilson 
Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/intel_engine_cs.c | 64 +-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index 2a94b92cfcd3..10cb6b22fe92 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -764,7 +764,7 @@ int intel_engine_init_common(struct intel_engine_cs *engine)
 
 /**
  * intel_engines_cleanup_common - cleans up the engine state created by
- *the common initiailizers.
+ *the common initializers.
  * @engine: Engine to cleanup.
  *
  * This cleans up everything created by the common helpers.
@@ -865,6 +865,63 @@ void intel_engine_cancel_stop_cs(struct intel_engine_cs 
*engine)
  _MASKED_BIT_DISABLE(STOP_RING));
 }
 
+static i915_reg_t get_idle_poll_reg(const struct intel_engine_cs *engine)
+{
+   if (engine->id != RCS)
+   return INVALID_MMIO_REG;
+
+   if (IS_GEN(engine->i915, 9))
+   return GEN9_RCS_FE_FSM2;
+
+   if (IS_GEN(engine->i915, 8))
+   return GEN6_RCS_PWR_FSM;
+
+   return INVALID_MMIO_REG;
+}
+
+static void disable_idle_messaging(struct intel_engine_cs *engine)
+{
+   struct drm_i915_private *dev_priv = engine->i915;
+   i915_reg_t poll_reg;
+
+   poll_reg = get_idle_poll_reg(engine);
+   if (!i915_mmio_reg_valid(poll_reg))
+   return;
+
+   GEM_DEBUG_WARN_ON(I915_READ_FW(GEN6_RC_SLEEP_PSMI_CONTROL) &
+ GEN6_PSMI_SLEEP_MSG_DISABLE);
+   /*
+* Hardware must not be in middle of idle flow signalling
+* when the RING_CTL is zeroed. In order to prevent this
+* we disable the messaging temporarily.
+*/
+   I915_WRITE_FW(GEN6_RC_SLEEP_PSMI_CONTROL,
+ _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
+
+   /*
+* Poll the magic bits to ensure that engine state machine
+* is in valid state for stopping the ring.
+*/
+   if (__intel_wait_for_register_fw(dev_priv, poll_reg,
+0x7f, 0x30,
+5000, 0,
+NULL))
+   DRM_DEBUG_DRIVER("psmi idle msg poll timeout\n");
+}
+
+static void enable_idle_messaging(struct intel_engine_cs *engine)
+{
+   struct drm_i915_private *dev_priv = engine->i915;
+   i915_reg_t poll_reg;
+
+   poll_reg = get_idle_poll_reg(engine);
+   if (!i915_mmio_reg_valid(poll_reg))
+   return;
+
+   I915_WRITE_FW(GEN6_RC_SLEEP_PSMI_CONTROL,
+ _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
+}
+
 int intel_engine_stop_ring(struct intel_engine_cs *engine)
 {
struct drm_i915_private *dev_priv = engine->i915;
@@ -880,9 +937,14 @@ int intel_engine_stop_ring(struct intel_engine_cs *engine)
I915_WRITE_FW(RING_TAIL(base), 0);
POSTING_READ_FW(RING_TAIL(base));
 
+   /* Idle messaging needs to be off during ring disable */
+   disable_idle_messaging(engine);
+
/* The ring must be empty before it is disabled */
I915_WRITE_FW(RING_CTL(base), 0);
 
+   enable_idle_messaging(engine);
+
/* Check acts as a post */
if (I915_READ_FW(RING_HEAD(base))) {
GEM_TRACE("%s: ring head [%x] not parked\n",
-- 
2.17.1

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

Re: [Intel-gfx] [PATCH 3/3] drm/i915: Disable PSMI idle messaging when stopping ring

2019-02-27 Thread Chris Wilson
Quoting Mika Kuoppala (2019-02-27 16:58:50)
> Hardware cannot be in a middle of idle flow messaging
> when we pull the plug from ringbuffer. Disable idle
> messaging before we do so to avoid potential deadlock
> on engine initialization and reset.
> 
> v2: INVALID_MMIO_REG, unconditional enable (Chris)
> 
> Cc: Chris Wilson 
> Signed-off-by: Mika Kuoppala 
> ---
>  drivers/gpu/drm/i915/intel_engine_cs.c | 56 +-
>  1 file changed, 55 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
> b/drivers/gpu/drm/i915/intel_engine_cs.c
> index a8e47cfa6e35..fe7fca392b63 100644
> --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> @@ -725,7 +725,7 @@ int intel_engine_init_common(struct intel_engine_cs 
> *engine)
>  
>  /**
>   * intel_engines_cleanup_common - cleans up the engine state created by
> - *the common initiailizers.
> + *the common initializers.
>   * @engine: Engine to cleanup.
>   *
>   * This cleans up everything created by the common helpers.
> @@ -826,6 +826,55 @@ void intel_engine_cancel_stop_cs(struct intel_engine_cs 
> *engine)
>   _MASKED_BIT_DISABLE(STOP_RING));
>  }
>  
> +static i915_reg_t get_idle_poll_reg(const struct intel_engine_cs *engine)
> +{
> +   if (engine->id != RCS)
> +   return INVALID_MMIO_REG;
> +
> +   if (IS_GEN(engine->i915, 9))
> +   return GEN9_RCS_FE_FSM2;
> +
> +   if (IS_GEN(engine->i915, 8))
> +   return GEN6_RCS_PWR_FSM;
> +
> +   return INVALID_MMIO_REG;
> +}
> +
> +static void disable_idle_messaging(struct intel_engine_cs *engine)
> +{
> +   struct drm_i915_private *dev_priv = engine->i915;
> +   i915_reg_t poll_reg;
> +
> +   poll_reg = get_idle_poll_reg(engine);
> +   if (!i915_mmio_reg_valid(poll_reg))
> +   return;
> +
> +   GEM_DEBUG_WARN_ON(I915_READ_FW(GEN6_RC_SLEEP_PSMI_CONTROL) &
> + GEN6_PSMI_SLEEP_MSG_DISABLE);
> +
> +   I915_WRITE_FW(GEN6_RC_SLEEP_PSMI_CONTROL,
> + _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
> +

Needs some reference at least. Or a synposis of what exactly we are
waiting for in a comment.

> +   if (__intel_wait_for_register_fw(dev_priv, poll_reg,
> +0x7f, 0x30,
> +5000, 0,
> +NULL))
> +   DRM_DEBUG_DRIVER("psmi idle msg poll timeout\n");
> +}
> +
> +static void enable_idle_messaging(struct intel_engine_cs *engine)
> +{
> +   struct drm_i915_private *dev_priv = engine->i915;
> +   i915_reg_t poll_reg;
> +
> +   poll_reg = get_idle_poll_reg(engine);
> +   if (!i915_mmio_reg_valid(poll_reg))
> +   return;
> +
> +   I915_WRITE_FW(GEN6_RC_SLEEP_PSMI_CONTROL,
> + _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
> +}
> +
>  int intel_engine_stop_ringbuffer(struct intel_engine_cs *engine)
>  {
> struct drm_i915_private *dev_priv = engine->i915;
> @@ -841,9 +890,14 @@ int intel_engine_stop_ringbuffer(struct intel_engine_cs 
> *engine)
> I915_WRITE_FW(RING_TAIL(base), 0);
> POSTING_READ_FW(RING_TAIL(base));
>  
> +   /* Idle messaging needs to be off during ring disable */
> +   disable_idle_messaging(engine);
> +
> /* The ring must be empty before it is disabled */
> I915_WRITE_FW(RING_CTL(base), 0);
>  
> +   enable_idle_messaging(engine);
> +
> /* Check acts as a post */
> if (I915_READ_FW(RING_HEAD(base))) {
> GEM_TRACE("%s: ring head [%x] not parked\n",

Given the history SLEEP_MSG_DISABLE around RING_CTL is not surprising.

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

[Intel-gfx] [PATCH 3/3] drm/i915: Disable PSMI idle messaging when stopping ring

2019-02-27 Thread Mika Kuoppala
Hardware cannot be in a middle of idle flow messaging
when we pull the plug from ringbuffer. Disable idle
messaging before we do so to avoid potential deadlock
on engine initialization and reset.

v2: INVALID_MMIO_REG, unconditional enable (Chris)

Cc: Chris Wilson 
Signed-off-by: Mika Kuoppala 
---
 drivers/gpu/drm/i915/intel_engine_cs.c | 56 +-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index a8e47cfa6e35..fe7fca392b63 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -725,7 +725,7 @@ int intel_engine_init_common(struct intel_engine_cs *engine)
 
 /**
  * intel_engines_cleanup_common - cleans up the engine state created by
- *the common initiailizers.
+ *the common initializers.
  * @engine: Engine to cleanup.
  *
  * This cleans up everything created by the common helpers.
@@ -826,6 +826,55 @@ void intel_engine_cancel_stop_cs(struct intel_engine_cs 
*engine)
  _MASKED_BIT_DISABLE(STOP_RING));
 }
 
+static i915_reg_t get_idle_poll_reg(const struct intel_engine_cs *engine)
+{
+   if (engine->id != RCS)
+   return INVALID_MMIO_REG;
+
+   if (IS_GEN(engine->i915, 9))
+   return GEN9_RCS_FE_FSM2;
+
+   if (IS_GEN(engine->i915, 8))
+   return GEN6_RCS_PWR_FSM;
+
+   return INVALID_MMIO_REG;
+}
+
+static void disable_idle_messaging(struct intel_engine_cs *engine)
+{
+   struct drm_i915_private *dev_priv = engine->i915;
+   i915_reg_t poll_reg;
+
+   poll_reg = get_idle_poll_reg(engine);
+   if (!i915_mmio_reg_valid(poll_reg))
+   return;
+
+   GEM_DEBUG_WARN_ON(I915_READ_FW(GEN6_RC_SLEEP_PSMI_CONTROL) &
+ GEN6_PSMI_SLEEP_MSG_DISABLE);
+
+   I915_WRITE_FW(GEN6_RC_SLEEP_PSMI_CONTROL,
+ _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
+
+   if (__intel_wait_for_register_fw(dev_priv, poll_reg,
+0x7f, 0x30,
+5000, 0,
+NULL))
+   DRM_DEBUG_DRIVER("psmi idle msg poll timeout\n");
+}
+
+static void enable_idle_messaging(struct intel_engine_cs *engine)
+{
+   struct drm_i915_private *dev_priv = engine->i915;
+   i915_reg_t poll_reg;
+
+   poll_reg = get_idle_poll_reg(engine);
+   if (!i915_mmio_reg_valid(poll_reg))
+   return;
+
+   I915_WRITE_FW(GEN6_RC_SLEEP_PSMI_CONTROL,
+ _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE));
+}
+
 int intel_engine_stop_ringbuffer(struct intel_engine_cs *engine)
 {
struct drm_i915_private *dev_priv = engine->i915;
@@ -841,9 +890,14 @@ int intel_engine_stop_ringbuffer(struct intel_engine_cs 
*engine)
I915_WRITE_FW(RING_TAIL(base), 0);
POSTING_READ_FW(RING_TAIL(base));
 
+   /* Idle messaging needs to be off during ring disable */
+   disable_idle_messaging(engine);
+
/* The ring must be empty before it is disabled */
I915_WRITE_FW(RING_CTL(base), 0);
 
+   enable_idle_messaging(engine);
+
/* Check acts as a post */
if (I915_READ_FW(RING_HEAD(base))) {
GEM_TRACE("%s: ring head [%x] not parked\n",
-- 
2.17.1

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