aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c73
1 files changed, 28 insertions, 45 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 0f42a2782afc..b7b0a38acd67 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -994,68 +994,51 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv,
994 ei->media_c0 = I915_READ(VLV_MEDIA_C0_COUNT); 994 ei->media_c0 = I915_READ(VLV_MEDIA_C0_COUNT);
995} 995}
996 996
997static bool vlv_c0_above(struct drm_i915_private *dev_priv,
998 const struct intel_rps_ei *old,
999 const struct intel_rps_ei *now,
1000 int threshold)
1001{
1002 u64 time, c0;
1003 unsigned int mul = 100;
1004
1005 if (old->cz_clock == 0)
1006 return false;
1007
1008 if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
1009 mul <<= 8;
1010
1011 time = now->cz_clock - old->cz_clock;
1012 time *= threshold * dev_priv->czclk_freq;
1013
1014 /* Workload can be split between render + media, e.g. SwapBuffers
1015 * being blitted in X after being rendered in mesa. To account for
1016 * this we need to combine both engines into our activity counter.
1017 */
1018 c0 = now->render_c0 - old->render_c0;
1019 c0 += now->media_c0 - old->media_c0;
1020 c0 *= mul * VLV_CZ_CLOCK_TO_MILLI_SEC;
1021
1022 return c0 >= time;
1023}
1024
1025void gen6_rps_reset_ei(struct drm_i915_private *dev_priv) 997void gen6_rps_reset_ei(struct drm_i915_private *dev_priv)
1026{ 998{
1027 vlv_c0_read(dev_priv, &dev_priv->rps.down_ei); 999 memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei));
1028 dev_priv->rps.up_ei = dev_priv->rps.down_ei;
1029} 1000}
1030 1001
1031static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) 1002static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
1032{ 1003{
1004 const struct intel_rps_ei *prev = &dev_priv->rps.ei;
1033 struct intel_rps_ei now; 1005 struct intel_rps_ei now;
1034 u32 events = 0; 1006 u32 events = 0;
1035 1007
1036 if ((pm_iir & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) == 0) 1008 if ((pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) == 0)
1037 return 0; 1009 return 0;
1038 1010
1039 vlv_c0_read(dev_priv, &now); 1011 vlv_c0_read(dev_priv, &now);
1040 if (now.cz_clock == 0) 1012 if (now.cz_clock == 0)
1041 return 0; 1013 return 0;
1042 1014
1043 if (pm_iir & GEN6_PM_RP_DOWN_EI_EXPIRED) { 1015 if (prev->cz_clock) {
1044 if (!vlv_c0_above(dev_priv, 1016 u64 time, c0;
1045 &dev_priv->rps.down_ei, &now, 1017 unsigned int mul;
1046 dev_priv->rps.down_threshold))
1047 events |= GEN6_PM_RP_DOWN_THRESHOLD;
1048 dev_priv->rps.down_ei = now;
1049 }
1050 1018
1051 if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) { 1019 mul = VLV_CZ_CLOCK_TO_MILLI_SEC * 100; /* scale to threshold% */
1052 if (vlv_c0_above(dev_priv, 1020 if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH)
1053 &dev_priv->rps.up_ei, &now, 1021 mul <<= 8;
1054 dev_priv->rps.up_threshold)) 1022
1055 events |= GEN6_PM_RP_UP_THRESHOLD; 1023 time = now.cz_clock - prev->cz_clock;
1056 dev_priv->rps.up_ei = now; 1024 time *= dev_priv->czclk_freq;
1025
1026 /* Workload can be split between render + media,
1027 * e.g. SwapBuffers being blitted in X after being rendered in
1028 * mesa. To account for this we need to combine both engines
1029 * into our activity counter.
1030 */
1031 c0 = now.render_c0 - prev->render_c0;
1032 c0 += now.media_c0 - prev->media_c0;
1033 c0 *= mul;
1034
1035 if (c0 > time * dev_priv->rps.up_threshold)
1036 events = GEN6_PM_RP_UP_THRESHOLD;
1037 else if (c0 < time * dev_priv->rps.down_threshold)
1038 events = GEN6_PM_RP_DOWN_THRESHOLD;
1057 } 1039 }
1058 1040
1041 dev_priv->rps.ei = now;
1059 return events; 1042 return events;
1060} 1043}
1061 1044
@@ -4390,7 +4373,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
4390 /* Let's track the enabled rps events */ 4373 /* Let's track the enabled rps events */
4391 if (IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) 4374 if (IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv))
4392 /* WaGsvRC0ResidencyMethod:vlv */ 4375 /* WaGsvRC0ResidencyMethod:vlv */
4393 dev_priv->pm_rps_events = GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED; 4376 dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED;
4394 else 4377 else
4395 dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; 4378 dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
4396 4379