drm/i915: drpc debugfs update for gen6
authorBen Widawsky <ben@bwidawsk.net>
Tue, 13 Dec 2011 03:34:16 +0000 (19:34 -0800)
committerKeith Packard <keithp@keithp.com>
Tue, 3 Jan 2012 17:09:45 +0000 (09:09 -0800)
Many of the old fields from Ironlake have gone away. Strip all those
fields, and try to update to fields people care about. RC information
isn't exactly ideal anymore. All we can guarantee when we read the
register is that we're not using forcewake, ie. the software isn't
forcing the hardware to stay awake. The downside is that in doing this
we may wait a while and that causes an unnaturally idle state on the
GPU.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42578
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Keith Packard <keithp@keithp.com>
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_reg.h

index 004b048..1180798 100644 (file)
@@ -1001,7 +1001,7 @@ static int i915_inttoext_table(struct seq_file *m, void *unused)
        return 0;
 }
 
-static int i915_drpc_info(struct seq_file *m, void *unused)
+static int ironlake_drpc_info(struct seq_file *m)
 {
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_device *dev = node->minor->dev;
@@ -1068,6 +1068,90 @@ static int i915_drpc_info(struct seq_file *m, void *unused)
        return 0;
 }
 
+static int gen6_drpc_info(struct seq_file *m)
+{
+
+       struct drm_info_node *node = (struct drm_info_node *) m->private;
+       struct drm_device *dev = node->minor->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 rpmodectl1, gt_core_status, rcctl1;
+       int count=0, ret;
+
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
+       if (atomic_read(&dev_priv->forcewake_count)) {
+               seq_printf(m, "RC information inaccurate because userspace "
+                             "holds a reference \n");
+       } else {
+               /* NB: we cannot use forcewake, else we read the wrong values */
+               while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
+                       udelay(10);
+               seq_printf(m, "RC information accurate: %s\n", yesno(count < 51));
+       }
+
+       gt_core_status = readl(dev_priv->regs + GEN6_GT_CORE_STATUS);
+       trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4);
+
+       rpmodectl1 = I915_READ(GEN6_RP_CONTROL);
+       rcctl1 = I915_READ(GEN6_RC_CONTROL);
+       mutex_unlock(&dev->struct_mutex);
+
+       seq_printf(m, "Video Turbo Mode: %s\n",
+                  yesno(rpmodectl1 & GEN6_RP_MEDIA_TURBO));
+       seq_printf(m, "HW control enabled: %s\n",
+                  yesno(rpmodectl1 & GEN6_RP_ENABLE));
+       seq_printf(m, "SW control enabled: %s\n",
+                  yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) ==
+                         GEN6_RP_MEDIA_SW_MODE));
+       seq_printf(m, "RC6 Enabled: %s\n",
+                  yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
+       seq_printf(m, "RC6 Enabled: %s\n",
+                  yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE));
+       seq_printf(m, "Deep RC6 Enabled: %s\n",
+                  yesno(rcctl1 & GEN6_RC_CTL_RC6p_ENABLE));
+       seq_printf(m, "Deepest RC6 Enabled: %s\n",
+                  yesno(rcctl1 & GEN6_RC_CTL_RC6pp_ENABLE));
+       seq_printf(m, "Current RC state: ");
+       switch (gt_core_status & GEN6_RCn_MASK) {
+       case GEN6_RC0:
+               if (gt_core_status & GEN6_CORE_CPD_STATE_MASK)
+                       seq_printf(m, "Core Power Down\n");
+               else
+                       seq_printf(m, "on\n");
+               break;
+       case GEN6_RC3:
+               seq_printf(m, "RC3\n");
+               break;
+       case GEN6_RC6:
+               seq_printf(m, "RC6\n");
+               break;
+       case GEN6_RC7:
+               seq_printf(m, "RC7\n");
+               break;
+       default:
+               seq_printf(m, "Unknown\n");
+               break;
+       }
+
+       seq_printf(m, "Core Power Down: %s\n",
+                  yesno(gt_core_status & GEN6_CORE_CPD_STATE_MASK));
+       return 0;
+}
+
+static int i915_drpc_info(struct seq_file *m, void *unused)
+{
+       struct drm_info_node *node = (struct drm_info_node *) m->private;
+       struct drm_device *dev = node->minor->dev;
+
+       if (IS_GEN6(dev) || IS_GEN7(dev))
+               return gen6_drpc_info(m);
+       else
+               return ironlake_drpc_info(m);
+}
+
 static int i915_fbc_status(struct seq_file *m, void *unused)
 {
        struct drm_info_node *node = (struct drm_info_node *) m->private;
index 583e8c7..44eabb0 100644 (file)
 #define GEN6_PCODE_DATA                                0x138128
 #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT       8
 
+#define GEN6_GT_CORE_STATUS            0x138060
+#define   GEN6_CORE_CPD_STATE_MASK     (7<<4)
+#define   GEN6_RCn_MASK                        7
+#define   GEN6_RC0                     0
+#define   GEN6_RC3                     2
+#define   GEN6_RC6                     3
+#define   GEN6_RC7                     4
+
 #define G4X_AUD_VID_DID                        0x62020
 #define INTEL_AUDIO_DEVCL              0x808629FB
 #define INTEL_AUDIO_DEVBLC             0x80862801