From f97108d1d0facc7902134ebc453b226bbd4d1cdb Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 29 Jan 2010 11:27:07 -0800 Subject: drm/i915: add dynamic performance control support for Ironlake Ironlake (and 965GM, which this patch doesn't support) supports a hardware performance and power management feature that allows it to adjust to changes in GPU load over time with software help. The goal if this is to maximize performance/power for a given workload. This patch enables that feature, which is also a requirement for supporting Intelligent Power Sharing, a feature which allows for dynamic budgeting of power between the CPU and GPU in Arrandale platforms. Tested-by: ykzhao [anholt: Resolved against the irq handler loop removal] Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt --- drivers/gpu/drm/i915/i915_debugfs.c | 96 +++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) (limited to 'drivers/gpu/drm/i915/i915_debugfs.c') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a894ade03093..55340de618ea 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -386,6 +386,97 @@ out: return 0; } +static int i915_rstdby_delays(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + u16 crstanddelay = I915_READ16(CRSTANDVID); + + seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f)); + + return 0; +} + +static int i915_cur_delayinfo(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + u16 rgvswctl = I915_READ16(MEMSWCTL); + + seq_printf(m, "Last command: 0x%01x\n", (rgvswctl >> 13) & 0x3); + seq_printf(m, "Command status: %d\n", (rgvswctl >> 12) & 1); + seq_printf(m, "P%d DELAY 0x%02x\n", (rgvswctl >> 8) & 0xf, + rgvswctl & 0x3f); + + return 0; +} + +static int i915_delayfreq_table(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + u32 delayfreq; + int i; + + for (i = 0; i < 16; i++) { + delayfreq = I915_READ(PXVFREQ_BASE + i * 4); + seq_printf(m, "P%02dVIDFREQ: 0x%08x\n", i, delayfreq); + } + + return 0; +} + +static inline int MAP_TO_MV(int map) +{ + return 1250 - (map * 25); +} + +static int i915_inttoext_table(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + u32 inttoext; + int i; + + for (i = 1; i <= 32; i++) { + inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4); + seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext); + } + + 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; + drm_i915_private_t *dev_priv = dev->dev_private; + u32 rgvmodectl = I915_READ(MEMMODECTL); + + seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? + "yes" : "no"); + seq_printf(m, "Boost freq: %d\n", + (rgvmodectl & MEMMODE_BOOST_FREQ_MASK) >> + MEMMODE_BOOST_FREQ_SHIFT); + seq_printf(m, "HW control enabled: %s\n", + rgvmodectl & MEMMODE_HWIDLE_EN ? "yes" : "no"); + seq_printf(m, "SW control enabled: %s\n", + rgvmodectl & MEMMODE_SWMODE_EN ? "yes" : "no"); + seq_printf(m, "Gated voltage change: %s\n", + rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no"); + seq_printf(m, "Starting frequency: P%d\n", + (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT); + seq_printf(m, "Max frequency: P%d\n", + (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT); + seq_printf(m, "Min frequency: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK)); + + return 0; +} + static int i915_wedged_open(struct inode *inode, struct file *filp) @@ -503,6 +594,11 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, {"i915_batchbuffers", i915_batchbuffer_info, 0}, {"i915_error_state", i915_error_state, 0}, + {"i915_rstdby_delays", i915_rstdby_delays, 0}, + {"i915_cur_delayinfo", i915_cur_delayinfo, 0}, + {"i915_delayfreq_table", i915_delayfreq_table, 0}, + {"i915_inttoext_table", i915_inttoext_table, 0}, + {"i915_drpc_info", i915_drpc_info, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) -- cgit v1.2.2