Re: [Intel-gfx] [PATCH 21/31] drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR

2017-09-28 Thread Sagar Arun Kamble



On 9/21/2017 7:36 PM, Michal Wajdeczko wrote:
On Tue, 19 Sep 2017 19:41:57 +0200, Sagar Arun Kamble 
 wrote:



Send host2guc SLPC reset event to GuC post GuC load.
Post this, i915 can ascertain if SLPC has started running successfully
through shared data. This check is done during intel_init_gt_powersave.
This allows to get initial configuration setup by SLPC and if needed
move to Host RPS if SLPC runs into issues.
On TDR/Engine reset i915 should send extra flag
SLPC_RESET_FLAG_TDR_OCCURREDto clear SLPC state as appropriate.

v1: Extract host2guc_slpc to handle slpc status code
    coding style changes (Paulo)
    Removed WARN_ON for checking msb of gtt address of
    shared gem obj. (ChrisW)
    host2guc_action to i915_guc_action change.(Sagar)
    Updating SLPC enabled status. (Sagar)

v2: Commit message update. (David)

v3: Rebase.

v4: Added DRM_INFO message when SLPC is enabled.

v5: Updated patch as host2guc_slpc is moved to earlier patch.
    SLPC activation status message put after checking the
    state from shared data during intel_init_gt_powersave.

v6: Added definition of host2guc_slpc and clflush the shared data only
    for required size. Setting state to NOT_RUNNING before sending RESET
    event. Output data for SLPC actions is to be retrieved during
    intel_guc_send with lock protection so created wrapper
    __intel_guc_send that outputs GuC output data if needed. Clearing
    pm_rps_events on confirming SLPC RUNNING status so that even if
    host touches any of the PM registers by mistake it should not have
    any effect. (Sagar)

v7: Added save/restore_default_rps as Uncore sanitize will clear the
    RP_CONTROL setup by BIOS. s/i915_ggtt_offset/guc_ggtt_offset.

v8: Added support for handling TDR based SLPC reset. Added functions
    host2guc_slpc_tdr_reset, intel_slpc_reset_prepare and
    intel_slpc_tdr_reset to handle TDR based SLPC reset.

Cc: Michal Wajdeczko 
Signed-off-by: Tom O'Rourke 
Signed-off-by: Sagar Arun Kamble 
---
 drivers/gpu/drm/i915/i915_drv.c   |   2 +
 drivers/gpu/drm/i915/i915_irq.c   |   7 +-
 drivers/gpu/drm/i915/intel_pm.c   |  10 +++
 drivers/gpu/drm/i915/intel_slpc.c | 170 
++

 drivers/gpu/drm/i915/intel_slpc.h |   9 ++
 drivers/gpu/drm/i915/intel_uc.c   |   1 +
 6 files changed, 198 insertions(+), 1 deletion(-)

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

index f13a3de..932f9ef 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1074,6 +1074,8 @@ static int i915_driver_init_hw(struct 
drm_i915_private *dev_priv)

intel_sanitize_options(dev_priv);
+    intel_slpc_save_default_rps(&dev_priv->guc.slpc);
+
 ret = i915_ggtt_probe_hw(dev_priv);
 if (ret)
 return ret;
diff --git a/drivers/gpu/drm/i915/i915_irq.c 
b/drivers/gpu/drm/i915/i915_irq.c

index 4a1554c..2d5ad13 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2838,8 +2838,13 @@ void i915_handle_error(struct drm_i915_private 
*dev_priv,

 }
 }
-    if (!engine_mask)
+    if (!engine_mask) {
+    if (intel_slpc_active(&dev_priv->guc.slpc)) {
+ intel_slpc_reset_prepare(&dev_priv->guc.slpc);
+    intel_slpc_tdr_reset(&dev_priv->guc.slpc);
+    }


Can you just jump to single slpc function that will hide slpc internals ?
we need to have these two calls as currently SLPC gets enabled during 
intel_uc_init_hw and we can reset from two places.

1. engine reset 2. full gpu reset
In 1st case we want to disable SLPC and reset it
In 2nd case we just want to disable SLPC and let it get enabled through 
intel_slpc_enable based on flag tdr_reset.
I will remove intel_slpc_active check here and probably create two 
functions now to handle these different types of resets.

 goto out;
+    }
/* Full reset needs the mutex, stop any other user trying to do 
so. */
 if (test_and_set_bit(I915_RESET_BACKOFF, 
&dev_priv->gpu_error.flags)) {
diff --git a/drivers/gpu/drm/i915/intel_pm.c 
b/drivers/gpu/drm/i915/intel_pm.c

index 6b2b7f8..c2065f2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7918,6 +7918,16 @@ void intel_init_gt_powersave(struct 
drm_i915_private *dev_priv)

 intel_runtime_pm_get(dev_priv);
 }
+    if (intel_slpc_enabled()) {
+    dev_priv->guc.slpc.active =
+    intel_slpc_get_status(&dev_priv->guc.slpc);
+    if (!intel_slpc_active(&dev_priv->guc.slpc)) {
+    i915.enable_slpc = 0;
+    intel_sanitize_gt_powersave(dev_priv);
+    } else
+    dev_priv->pm_rps_events = 0;
+    }
+


Hmm, on one hand you're trying to use friendly wrappers like
enabled() active() but at the same time you're modifying data
which these helpers were trying to hide ...

This actually is point from where on intel_slpc_active() is determined.
SLPC enabling is asynchronous and we would need to poll on the shared 
memory status to k

Re: [Intel-gfx] [PATCH 21/31] drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR

2017-09-21 Thread Michal Wajdeczko
On Tue, 19 Sep 2017 19:41:57 +0200, Sagar Arun Kamble  
 wrote:



Send host2guc SLPC reset event to GuC post GuC load.
Post this, i915 can ascertain if SLPC has started running successfully
through shared data. This check is done during intel_init_gt_powersave.
This allows to get initial configuration setup by SLPC and if needed
move to Host RPS if SLPC runs into issues.
On TDR/Engine reset i915 should send extra flag
SLPC_RESET_FLAG_TDR_OCCURREDto clear SLPC state as appropriate.

v1: Extract host2guc_slpc to handle slpc status code
coding style changes (Paulo)
Removed WARN_ON for checking msb of gtt address of
shared gem obj. (ChrisW)
host2guc_action to i915_guc_action change.(Sagar)
Updating SLPC enabled status. (Sagar)

v2: Commit message update. (David)

v3: Rebase.

v4: Added DRM_INFO message when SLPC is enabled.

v5: Updated patch as host2guc_slpc is moved to earlier patch.
SLPC activation status message put after checking the
state from shared data during intel_init_gt_powersave.

v6: Added definition of host2guc_slpc and clflush the shared data only
for required size. Setting state to NOT_RUNNING before sending RESET
event. Output data for SLPC actions is to be retrieved during
intel_guc_send with lock protection so created wrapper
__intel_guc_send that outputs GuC output data if needed. Clearing
pm_rps_events on confirming SLPC RUNNING status so that even if
host touches any of the PM registers by mistake it should not have
any effect. (Sagar)

v7: Added save/restore_default_rps as Uncore sanitize will clear the
RP_CONTROL setup by BIOS. s/i915_ggtt_offset/guc_ggtt_offset.

v8: Added support for handling TDR based SLPC reset. Added functions
host2guc_slpc_tdr_reset, intel_slpc_reset_prepare and
intel_slpc_tdr_reset to handle TDR based SLPC reset.

Cc: Michal Wajdeczko 
Signed-off-by: Tom O'Rourke 
Signed-off-by: Sagar Arun Kamble 
---
 drivers/gpu/drm/i915/i915_drv.c   |   2 +
 drivers/gpu/drm/i915/i915_irq.c   |   7 +-
 drivers/gpu/drm/i915/intel_pm.c   |  10 +++
 drivers/gpu/drm/i915/intel_slpc.c | 170  
++

 drivers/gpu/drm/i915/intel_slpc.h |   9 ++
 drivers/gpu/drm/i915/intel_uc.c   |   1 +
 6 files changed, 198 insertions(+), 1 deletion(-)

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

index f13a3de..932f9ef 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1074,6 +1074,8 @@ static int i915_driver_init_hw(struct  
drm_i915_private *dev_priv)

intel_sanitize_options(dev_priv);
+   intel_slpc_save_default_rps(&dev_priv->guc.slpc);
+
ret = i915_ggtt_probe_hw(dev_priv);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/i915/i915_irq.c  
b/drivers/gpu/drm/i915/i915_irq.c

index 4a1554c..2d5ad13 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2838,8 +2838,13 @@ void i915_handle_error(struct drm_i915_private  
*dev_priv,

}
}
-   if (!engine_mask)
+   if (!engine_mask) {
+   if (intel_slpc_active(&dev_priv->guc.slpc)) {
+   intel_slpc_reset_prepare(&dev_priv->guc.slpc);
+   intel_slpc_tdr_reset(&dev_priv->guc.slpc);
+   }


Can you just jump to single slpc function that will hide slpc internals ?


goto out;
+   }
/* Full reset needs the mutex, stop any other user trying to do so. */
if (test_and_set_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags)) {
diff --git a/drivers/gpu/drm/i915/intel_pm.c  
b/drivers/gpu/drm/i915/intel_pm.c

index 6b2b7f8..c2065f2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7918,6 +7918,16 @@ void intel_init_gt_powersave(struct  
drm_i915_private *dev_priv)

intel_runtime_pm_get(dev_priv);
}
+   if (intel_slpc_enabled()) {
+   dev_priv->guc.slpc.active =
+   intel_slpc_get_status(&dev_priv->guc.slpc);
+   if (!intel_slpc_active(&dev_priv->guc.slpc)) {
+   i915.enable_slpc = 0;
+   intel_sanitize_gt_powersave(dev_priv);
+   } else
+   dev_priv->pm_rps_events = 0;
+   }
+


Hmm, on one hand you're trying to use friendly wrappers like
enabled() active() but at the same time you're modifying data
which these helpers were trying to hide ...


mutex_lock(&dev_priv->drm.struct_mutex);
mutex_lock(&dev_priv->pm.pcu_lock);
diff --git a/drivers/gpu/drm/i915/intel_slpc.c  
b/drivers/gpu/drm/i915/intel_slpc.c

index f47d81e..57e69d4 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -390,6 +390,140 @@ static void slpc_shared_data_init(struct  
intel_slpc *slpc)

kunmap_atomic(data);
 }
+static void host2guc_slpc_reset(struct intel_slpc *slpc)
+{
+ 

[Intel-gfx] [PATCH 21/31] drm/i915/slpc: Send RESET event to enable SLPC during Load/TDR

2017-09-19 Thread Sagar Arun Kamble
Send host2guc SLPC reset event to GuC post GuC load.
Post this, i915 can ascertain if SLPC has started running successfully
through shared data. This check is done during intel_init_gt_powersave.
This allows to get initial configuration setup by SLPC and if needed
move to Host RPS if SLPC runs into issues.
On TDR/Engine reset i915 should send extra flag
SLPC_RESET_FLAG_TDR_OCCURREDto clear SLPC state as appropriate.

v1: Extract host2guc_slpc to handle slpc status code
coding style changes (Paulo)
Removed WARN_ON for checking msb of gtt address of
shared gem obj. (ChrisW)
host2guc_action to i915_guc_action change.(Sagar)
Updating SLPC enabled status. (Sagar)

v2: Commit message update. (David)

v3: Rebase.

v4: Added DRM_INFO message when SLPC is enabled.

v5: Updated patch as host2guc_slpc is moved to earlier patch.
SLPC activation status message put after checking the
state from shared data during intel_init_gt_powersave.

v6: Added definition of host2guc_slpc and clflush the shared data only
for required size. Setting state to NOT_RUNNING before sending RESET
event. Output data for SLPC actions is to be retrieved during
intel_guc_send with lock protection so created wrapper
__intel_guc_send that outputs GuC output data if needed. Clearing
pm_rps_events on confirming SLPC RUNNING status so that even if
host touches any of the PM registers by mistake it should not have
any effect. (Sagar)

v7: Added save/restore_default_rps as Uncore sanitize will clear the
RP_CONTROL setup by BIOS. s/i915_ggtt_offset/guc_ggtt_offset.

v8: Added support for handling TDR based SLPC reset. Added functions
host2guc_slpc_tdr_reset, intel_slpc_reset_prepare and
intel_slpc_tdr_reset to handle TDR based SLPC reset.

Cc: Michal Wajdeczko 
Signed-off-by: Tom O'Rourke 
Signed-off-by: Sagar Arun Kamble 
---
 drivers/gpu/drm/i915/i915_drv.c   |   2 +
 drivers/gpu/drm/i915/i915_irq.c   |   7 +-
 drivers/gpu/drm/i915/intel_pm.c   |  10 +++
 drivers/gpu/drm/i915/intel_slpc.c | 170 ++
 drivers/gpu/drm/i915/intel_slpc.h |   9 ++
 drivers/gpu/drm/i915/intel_uc.c   |   1 +
 6 files changed, 198 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index f13a3de..932f9ef 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1074,6 +1074,8 @@ static int i915_driver_init_hw(struct drm_i915_private 
*dev_priv)
 
intel_sanitize_options(dev_priv);
 
+   intel_slpc_save_default_rps(&dev_priv->guc.slpc);
+
ret = i915_ggtt_probe_hw(dev_priv);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4a1554c..2d5ad13 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2838,8 +2838,13 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
}
}
 
-   if (!engine_mask)
+   if (!engine_mask) {
+   if (intel_slpc_active(&dev_priv->guc.slpc)) {
+   intel_slpc_reset_prepare(&dev_priv->guc.slpc);
+   intel_slpc_tdr_reset(&dev_priv->guc.slpc);
+   }
goto out;
+   }
 
/* Full reset needs the mutex, stop any other user trying to do so. */
if (test_and_set_bit(I915_RESET_BACKOFF, &dev_priv->gpu_error.flags)) {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6b2b7f8..c2065f2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7918,6 +7918,16 @@ void intel_init_gt_powersave(struct drm_i915_private 
*dev_priv)
intel_runtime_pm_get(dev_priv);
}
 
+   if (intel_slpc_enabled()) {
+   dev_priv->guc.slpc.active =
+   intel_slpc_get_status(&dev_priv->guc.slpc);
+   if (!intel_slpc_active(&dev_priv->guc.slpc)) {
+   i915.enable_slpc = 0;
+   intel_sanitize_gt_powersave(dev_priv);
+   } else
+   dev_priv->pm_rps_events = 0;
+   }
+
mutex_lock(&dev_priv->drm.struct_mutex);
mutex_lock(&dev_priv->pm.pcu_lock);
 
diff --git a/drivers/gpu/drm/i915/intel_slpc.c 
b/drivers/gpu/drm/i915/intel_slpc.c
index f47d81e..57e69d4 100644
--- a/drivers/gpu/drm/i915/intel_slpc.c
+++ b/drivers/gpu/drm/i915/intel_slpc.c
@@ -390,6 +390,140 @@ static void slpc_shared_data_init(struct intel_slpc *slpc)
kunmap_atomic(data);
 }
 
+static void host2guc_slpc_reset(struct intel_slpc *slpc)
+{
+   struct slpc_event_input data = {0};
+   u32 shared_data_gtt_offset = guc_ggtt_offset(slpc->vma);
+
+   data.header.value = SLPC_EVENT(SLPC_EVENT_RESET, 2);
+   data.args[0] = shared_data_gtt_offset;
+   data.args[1] = 0;
+
+   host2guc_slpc(slpc, &data, 4);
+}
+
+static void host2guc_slpc_tdr_reset(