It is useful to get the register snapshot. Add a debugfs I/F named "i915_reg" to dump the I915 register snapshot. And this is created under the dri/0/ of debugfs. The output format is similar to what we have done in UMS mode.
Signed-off-by: Zhao Yakui <yakui.z...@intel.com> --- drivers/gpu/drm/i915/Makefile | 1 drivers/gpu/drm/i915/i915_dma.c | 6 drivers/gpu/drm/i915/i915_drv.h | 3 drivers/gpu/drm/i915/i915_reg.h | 87 ++ drivers/gpu/drm/i915/i915_reg_debugfs.c | 1114 ++++++++++++++++++++++++++++++++ 5 files changed, 1208 insertions(+), 3 deletions(-) Index: linux-2.6/drivers/gpu/drm/i915/Makefile =================================================================== --- linux-2.6.orig/drivers/gpu/drm/i915/Makefile 2009-06-05 11:42:12.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/i915/Makefile 2009-06-05 11:42:43.000000000 +0800 @@ -8,6 +8,7 @@ i915_gem.o \ i915_gem_debug.o \ i915_gem_debugfs.o \ + i915_reg_debugfs.o \ i915_gem_tiling.o \ intel_display.o \ intel_crt.o \ Index: linux-2.6/drivers/gpu/drm/i915/i915_drv.h =================================================================== --- linux-2.6.orig/drivers/gpu/drm/i915/i915_drv.h 2009-06-05 11:42:12.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/i915/i915_drv.h 2009-06-05 11:42:43.000000000 +0800 @@ -689,7 +689,8 @@ /* modesetting */ extern void intel_modeset_init(struct drm_device *dev); extern void intel_modeset_cleanup(struct drm_device *dev); - +extern void i915_reg_debugfs_init(struct drm_device *dev); +extern void i915_reg_debugfs_cleanup(struct drm_device *dev); /** * Lock test for when it's just for synchronization of ring access. * Index: linux-2.6/drivers/gpu/drm/i915/i915_reg.h =================================================================== --- linux-2.6.orig/drivers/gpu/drm/i915/i915_reg.h 2009-06-05 11:42:12.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/i915/i915_reg.h 2009-06-05 11:42:43.000000000 +0800 @@ -202,7 +202,9 @@ #define I965_FENCE_TILING_Y_SHIFT 1 #define I965_FENCE_REG_VALID (1<<0) #define I965_FENCE_MAX_PITCH_VAL 0x0400 +#define I965_FENCE_Y_MAJOR 0x00000002 +#define PGETBL_CTL 0x2020 /* * Instruction and interrupt control regs */ @@ -263,7 +265,9 @@ #define FW_BLC 0x020d8 #define FW_BLC_SELF 0x020e0 /* 915+ only */ #define MI_ARB_STATE 0x020e4 /* 915+ only */ +#define MI_RDRET_STATE 0x020fc #define CACHE_MODE_0 0x02120 /* 915+ only */ +#define MI_MODE 0x0209c #define CM0_MASK_SHIFT 16 #define CM0_IZ_OPT_DISABLE (1<<6) #define CM0_ZR_OPT_DISABLE (1<<5) @@ -272,8 +276,7 @@ #define CM0_DEPTH_WRITE_DISABLE (1<<1) #define CM0_RC_OP_FLUSH_DISABLE (1<<0) #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ - - +#define ECOSKPD 0x021d0 /* * Framebuffer compression (915+ only) */ @@ -304,6 +307,7 @@ #define FBC_CTL_PLANEA (0<<0) #define FBC_CTL_PLANEB (1<<0) #define FBC_FENCE_OFF 0x0321b +#define FBC_MOD_NUM 0x03220 #define FBC_LL_SIZE (1536) @@ -529,6 +533,41 @@ #define CG_2D_DIS 0x6200 #define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) #define CG_3D_DIS 0x6204 +#define RENCLK_GATE_D2 0x6208 + +#define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */ +#define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */ +#define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */ +#define VRDUNIT_CLOCK_GATE_DISABLE (1 << 27) /* 965 */ +#define AUDUNIT_CLOCK_GATE_DISABLE (1 << 26) /* 965 */ +#define DPUNIT_A_CLOCK_GATE_DISABLE (1 << 25) /* 965 */ +#define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) /* 965 */ +#define TVRUNIT_CLOCK_GATE_DISABLE (1 << 23) /* 915-945 */ +#define TVCUNIT_CLOCK_GATE_DISABLE (1 << 22) /* 915-945 */ +#define TVFUNIT_CLOCK_GATE_DISABLE (1 << 21) /* 915-945 */ +#define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */ +#define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */ +#define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */ +#define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */ +#define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */ +#define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */ +#define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */ +#define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */ +#define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */ +#define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11) +#define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10) +#define DCUNIT_CLOCK_GATE_DISABLE (1 << 9) +#define DPUNIT_CLOCK_GATE_DISABLE (1 << 8) +#define VRUNIT_CLOCK_GATE_DISABLE (1 << 7) /* 915+: reserved */ +#define OVHUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 830-865 */ +#define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */ +#define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5) +#define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4) +#define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3) +#define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2) +#define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1) +#define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */ +#define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */ /* * Palette regs @@ -558,9 +597,21 @@ #define DCC_CHANNEL_XOR_DISABLE (1 << 10) #define DCC_CHANNEL_XOR_BIT_17 (1 << 9) +#define CHDECMISC 0x10111 +#define C0DRB0 0x10200 +#define C0DRB1 0x10202 +#define C0DRB2 0x10204 + /** 965 MCH register controlling DRAM channel configuration */ #define C0DRB3 0x10206 +#define C0DRA01 0x10208 +#define C0DRA23 0x1020a +#define C1DRB0 0x10600 +#define C1DRB1 0x10602 +#define C1DRB2 0x10604 #define C1DRB3 0x10606 +#define C1DRA01 0x10608 +#define C1DRA23 0x1060a /** GM965 GM45 render standby register */ #define MCHBAR_RENDER_STANDBY 0x111B8 @@ -594,6 +645,7 @@ #define VSYNC_A 0x60014 #define PIPEASRC 0x6001c #define BCLRPAT_A 0x60020 +#define VSYNCSHIFT_A 0x60028 /* Pipe B timing regs */ #define HTOTAL_B 0x61000 @@ -604,6 +656,7 @@ #define VSYNC_B 0x61014 #define PIPEBSRC 0x6101c #define BCLRPAT_B 0x61020 +#define VSYNCSHIFT_B 0x61028 /* VGA port control */ #define ADPA 0x61100 @@ -679,6 +732,7 @@ /* SDVO port control */ #define SDVOB 0x61140 #define SDVOC 0x61160 +#define SDVOUDI 0x61150 #define SDVO_ENABLE (1 << 31) #define SDVO_PIPE_B_SELECT (1 << 30) #define SDVO_STALL_SELECT (1 << 29) @@ -1382,6 +1436,10 @@ #define DSPARB_CSTART_SHIFT 7 #define DSPARB_BSTART_MASK (0x7f) #define DSPARB_BSTART_SHIFT 0 + +#define DSPFW1 0x70034 +#define DSPFW2 0x70038 +#define DSPFW3 0x7003c /* * The two pipe frame counter registers are not synchronized, so * reading a stable value is somewhat tricky. The following code @@ -1517,4 +1575,29 @@ # define VGA_2X_MODE (1 << 30) # define VGA_PIPE_B_SELECT (1 << 29) +#define DP_B 0x64100 +#define DPB_AUX_CH_CTL 0x64110 +#define DPB_AUX_CH_DATA1 0x64114 +#define DPB_AUX_CH_DATA2 0x64118 +#define DPB_AUX_CH_DATA3 0x6411c +#define DPB_AUX_CH_DATA4 0x64120 +#define DPB_AUX_CH_DATA5 0x64124 + +#define DP_C 0x64200 +#define DPC_AUX_CH_CTL 0x64210 +#define DPC_AUX_CH_DATA1 0x64214 +#define DPC_AUX_CH_DATA2 0x64218 +#define DPC_AUX_CH_DATA3 0x6421c +#define DPC_AUX_CH_DATA4 0x64220 +#define DPC_AUX_CH_DATA5 0x64224 + +#define DP_D 0x64300 +#define DPD_AUX_CH_CTL 0x64310 +#define DPD_AUX_CH_DATA1 0x64314 +#define DPD_AUX_CH_DATA2 0x64318 +#define DPD_AUX_CH_DATA3 0x6431c +#define DPD_AUX_CH_DATA4 0x64320 +#define DPD_AUX_CH_DATA5 0x64324 + + #endif /* _I915_REG_H_ */ Index: linux-2.6/drivers/gpu/drm/i915/i915_dma.c =================================================================== --- linux-2.6.orig/drivers/gpu/drm/i915/i915_dma.c 2009-06-05 11:42:41.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/i915/i915_dma.c 2009-06-05 11:42:43.000000000 +0800 @@ -1216,6 +1216,9 @@ /* Must be done after probing outputs */ intel_opregion_init(dev, 0); +#ifdef CONFIG_DEBUG_FS + i915_reg_debugfs_init(dev); +#endif return 0; @@ -1250,6 +1253,9 @@ iounmap(dev_priv->regs); intel_opregion_free(dev, 0); +#ifdef CONFIG_DEBUG_FS + i915_reg_debugfs_cleanup(dev); +#endif if (drm_core_check_feature(dev, DRIVER_MODESET)) { intel_modeset_cleanup(dev); Index: linux-2.6/drivers/gpu/drm/i915/i915_reg_debugfs.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6/drivers/gpu/drm/i915/i915_reg_debugfs.c 2009-06-05 11:44:24.000000000 +0800 @@ -0,0 +1,1114 @@ +/** + * \file i915_debug.c + * Proc debug support for I915 + * + * \author Zhao Yakui <yakui.z...@intel.com> + */ + +/* + * Created: Zhao Yakui <yakui.z...@intel.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <linux/debugfs.h> +#include <linux/seq_file.h> +#include "drmP.h" +#include "i915_reg.h" +#include "i915_drv.h" + +#define I915_REG_DUMP "i915_reg" +#define NR_BLOCK 8 +#define BUF_LEN 1024 +#ifdef CONFIG_DEBUG_FS +static struct dentry *i915_reg; +static char *p_buffer; +struct i915regsnapshotrec { + int reg; + char *name; + int (*debug_output)(struct seq_file *m, char *buf, + int reg, unsigned int val); + int bit_width; +}; +#define DEFINEREG2(reg, func) \ + { reg, #reg, func, 32 } +#define DEFINEREG(reg) \ + { reg , #reg, NULL, 32 } +#define DEFINEREG_16BIT(reg) \ + { reg, #reg, NULL, 16} + +static int i830_debug_dcc(struct seq_file *m, char *buf, int reg, u32 val) +{ + struct drm_device *drm_dev = m->private; + char *addressing = NULL; + int len; + + if (!IS_MOBILE(drm_dev)) + return 0; + + if (IS_I965G(drm_dev)) { + if (val & (1 << 1)) + addressing = "dual channel interlaved"; + else + addressing = "single or dual channel asymmetric"; + } else { + switch (val & 3) { + case 0: + addressing = "single channel"; + break; + case 1: + addressing = "dual channel asymmetric"; + break; + case 2: + addressing = "dual channel interleaved"; + break; + case 3: + addressing = "unknown channel layout"; + break; + } + } + len = snprintf(buf, BUF_LEN, + "%s, XOR randomization: %sabled, XOR bit: %d", + addressing, + (val & (1 << 10)) ? "dis" : "en", + (val & (1 << 9)) ? 17 : 11); + return len; +} +static int i830_debug_chdecmisc(struct seq_file *m, char *buf, int reg, u32 val) +{ + char *enhmodesel = NULL; + int len; + + switch ((val >> 5) & 3) { + case 1: + enhmodesel = "XOR bank/rank"; + break; + case 2: + enhmodesel = "swap bank"; + break; + case 3: + enhmodesel = "XOR bank"; + break; + case 0: + enhmodesel = "none"; + break; + } + + len = snprintf(buf, BUF_LEN, + "%s, ch2 enh %sabled, ch1 enh %sabled, ch0 enh " + " %sabled, flex %sabled, ep %spresent", + enhmodesel, + (val & (1 << 4)) ? "en" : "dis", + (val & (1 << 3)) ? "en" : "dis", + (val & (1 << 2)) ? "en" : "dis", + (val & (1 << 1)) ? "en" : "dis", + (val & (1 << 0)) ? "" : "not "); + return len; +} +static int i830_debug_fp(struct seq_file *m, char *buf, int reg, u32 val) +{ + struct drm_device *drm_dev = m->private; + int len; + + if (IS_IGD(drm_dev)) { + len = snprintf(buf, BUF_LEN, "n = %d, m1 = %d, m2 = %d", + ffs((val & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1, + ((val & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT), + ((val & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT)); + } else { + len = snprintf(buf, BUF_LEN, "n = %d, m1 = %d, m2 = %d", + ((val & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT), + ((val & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT), + ((val & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT)); + } + + return len; +} + +static int i830_debug_vga_pd(struct seq_file *m, char *buf, int reg, u32 val) +{ + int vga0_p1, vga0_p2, vga1_p1, vga1_p2; + int len; + + if (val & VGA0_PD_P1_DIV_2) + vga0_p1 = 2; + else + vga0_p1 = ((val & VGA0_PD_P1_MASK) >> VGA0_PD_P1_SHIFT) + 2; + vga0_p2 = (val & VGA0_PD_P2_DIV_4) ? 4 : 2; + + if (val & VGA1_PD_P1_DIV_2) + vga1_p1 = 2; + else + vga1_p1 = ((val & VGA1_PD_P1_MASK) >> VGA1_PD_P1_SHIFT) + 2; + vga1_p2 = (val & VGA1_PD_P2_DIV_4) ? 4 : 2; + + len = snprintf(buf, BUF_LEN, + "vga0 p1 = %d, p2 = %d, vga1 p1 = %d, p2 = %d", + vga0_p1, vga0_p2, vga1_p1, vga1_p2); + + return len; +} +static int i830_debug_dpll_test(struct seq_file *m, char *buf, + int reg, u32 val) +{ + char *dpllandiv, *dpllamdiv, *dpllainput; + char *dpllbndiv, *dpllbmdiv, *dpllbinput; + int len; + + dpllandiv = val & DPLLA_TEST_N_BYPASS ? ", DPLLA N bypassed" : ""; + dpllamdiv = val & DPLLA_TEST_M_BYPASS ? ", DPLLA M bypassed" : ""; + dpllainput = val & DPLLA_INPUT_BUFFER_ENABLE ? + "" : ", DPLLA input buffer disabled"; + dpllbndiv = val & DPLLB_TEST_N_BYPASS ? ", DPLLB N bypassed" : ""; + dpllbmdiv = val & DPLLB_TEST_M_BYPASS ? ", DPLLB M bypassed" : ""; + dpllbinput = val & DPLLB_INPUT_BUFFER_ENABLE ? + "" : ", DPLLB input buffer disabled"; + + len = snprintf(buf, BUF_LEN, + "%s%s%s%s%s%s", + dpllandiv, dpllamdiv, dpllainput, + dpllbndiv, dpllbmdiv, dpllbinput); + + return len; +} + +static int i830_debug_dspclk_gate_d(struct seq_file *m, char *buf, + int reg, u32 val) +{ + char *dpunit_b, *vsunit, *vrhunit, *vrdunit, *audunit; + char *dpunit_a, *dpcunit, *tvrunit, *tvcunit, *tvfunit; + char *tveunit, *dvsunit, *dssunit, *ddbunit, *dprunit; + char *dpfunit, *dpbmunit, *dplsunit, *dplunit, *dpounit; + char *dpbunit, *dcunit, *dpunit, *vrunit, *ovhunit; + char *dpiunit, *ovfunit, *ovbunit, *ovrunit, *ovcunit; + char *ovuunit, *ovlunit; + int len; + + dpunit_b = val & DPUNIT_B_CLOCK_GATE_DISABLE ? " DPUNIT_B" : ""; + vsunit = val & VSUNIT_CLOCK_GATE_DISABLE ? " VSUNIT" : ""; + vrhunit = val & VRHUNIT_CLOCK_GATE_DISABLE ? " VRHUNIT" : ""; + vrdunit = val & VRDUNIT_CLOCK_GATE_DISABLE ? " VRDUNIT" : ""; + audunit = val & AUDUNIT_CLOCK_GATE_DISABLE ? " AUDUNIT" : ""; + + dpunit_a = val & DPUNIT_A_CLOCK_GATE_DISABLE ? " DPUNIT_A" : ""; + dpcunit = val & DPCUNIT_CLOCK_GATE_DISABLE ? " DPCUNIT" : ""; + tvrunit = val & TVRUNIT_CLOCK_GATE_DISABLE ? " TVRUNIT" : ""; + tvcunit = val & TVCUNIT_CLOCK_GATE_DISABLE ? " TVCUNIT" : ""; + tvfunit = val & TVFUNIT_CLOCK_GATE_DISABLE ? " TVFUNIT" : ""; + + tveunit = val & TVEUNIT_CLOCK_GATE_DISABLE ? " TVEUNIT" : ""; + dvsunit = val & DVSUNIT_CLOCK_GATE_DISABLE ? " DVSUNIT" : ""; + dssunit = val & DSSUNIT_CLOCK_GATE_DISABLE ? " DSSUNIT" : ""; + ddbunit = val & DDBUNIT_CLOCK_GATE_DISABLE ? " DDBUNIT" : ""; + dprunit = val & DPRUNIT_CLOCK_GATE_DISABLE ? " DPRUNIT" : ""; + + dpfunit = val & DPFUNIT_CLOCK_GATE_DISABLE ? " DPFUNIT" : ""; + dpbmunit = val & DPBMUNIT_CLOCK_GATE_DISABLE ? " DPBMUNIT" : ""; + dplsunit = val & DPLSUNIT_CLOCK_GATE_DISABLE ? " DPLSUNIT" : ""; + dplunit = val & DPLUNIT_CLOCK_GATE_DISABLE ? " DPLUNIT" : ""; + dpounit = val & DPOUNIT_CLOCK_GATE_DISABLE ? " DPOUNIT" : ""; + + dpbunit = val & DPBUNIT_CLOCK_GATE_DISABLE ? " DPBUNIT" : ""; + dcunit = val & DCUNIT_CLOCK_GATE_DISABLE ? " DCUNIT" : ""; + dpunit = val & DPUNIT_CLOCK_GATE_DISABLE ? " DPUNIT" : ""; + vrunit = val & VRUNIT_CLOCK_GATE_DISABLE ? " VRUNIT" : ""; + ovhunit = val & OVHUNIT_CLOCK_GATE_DISABLE ? " OVHUNIT" : ""; + + dpiunit = val & DPIOUNIT_CLOCK_GATE_DISABLE ? " DPIOUNIT" : ""; + ovfunit = val & OVFUNIT_CLOCK_GATE_DISABLE ? " OVFUNIT" : ""; + ovbunit = val & OVBUNIT_CLOCK_GATE_DISABLE ? " OVBUNIT" : ""; + ovrunit = val & OVRUNIT_CLOCK_GATE_DISABLE ? " OVRUNIT" : ""; + ovcunit = val & OVCUNIT_CLOCK_GATE_DISABLE ? " OVCUNIT" : ""; + + ovuunit = val & OVUUNIT_CLOCK_GATE_DISABLE ? " OVUUNIT" : ""; + ovlunit = val & OVLUNIT_CLOCK_GATE_DISABLE ? " OVLUNIT" : ""; + + len = snprintf(buf, BUF_LEN, "clock gates disabled:" + "%s%s%s%s%s" + "%s%s%s%s%s" + "%s%s%s%s%s" + "%s%s%s%s%s" + "%s%s%s%s%s" + "%s%s%s%s%s" + "%s%s", + dpunit_b, vsunit, vrhunit, vrdunit, audunit, + dpunit_a, dpcunit, tvrunit, tvcunit, tvfunit, + tveunit, dvsunit, dssunit, ddbunit, dprunit, + dpfunit, dpbmunit, dplsunit, dplunit, dpounit, + dpbunit, dcunit, dpunit, vrunit, ovhunit, + dpiunit, ovfunit, ovbunit, ovrunit, ovcunit, + ovuunit, ovlunit); + + return len; +} +static int i830_debug_sdvo(struct seq_file *m, char *buf, int reg, u32 val) +{ + struct drm_device *drm_dev = m->private; + char *enable, *stall, *detected, *gang; + char pipe, sdvoextra[20]; + int len; + + enable = val & SDVO_ENABLE ? "enabled" : "disabled"; + pipe = val & SDVO_PIPE_B_SELECT ? 'B' : 'A'; + stall = val & SDVO_STALL_SELECT ? "enabled" : "disabled"; + detected = val & SDVO_DETECTED ? "" : "not "; + gang = val & SDVOC_GANG_MODE ? ", gang mode" : ""; + + if (IS_I915G(drm_dev) || IS_I915GM(drm_dev)) { + len = sprintf(sdvoextra, ", SDVO mult %d", + (int)((val & SDVO_PORT_MULTIPLY_MASK) >> + SDVO_PORT_MULTIPLY_SHIFT) + 1); + sdvoextra[len] = '\0'; + } else { + sdvoextra[0] = '\0'; + } + + len = snprintf(buf, BUF_LEN, "%s, pipe %c, stall %s, %sdetected%s%s", + enable, pipe, stall, detected, sdvoextra, gang); + return len ; +} +static int i830_debug_lvds(struct seq_file *m, char *buf, int reg, u32 val) +{ + char pipe; + char *enable, *channels; + int depth; + int len; + + pipe = val & LVDS_PIPEB_SELECT ? 'B' : 'A'; + enable = val & LVDS_PORT_EN ? "enabled" : "disabled"; + + if ((val & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) + depth = 24; + else + depth = 18; + + if ((val & LVDS_B0B3_POWER_MASK) == LVDS_B0B3_POWER_UP) + channels = "2 channels"; + else + channels = "1 channel"; + + len = snprintf(buf, BUF_LEN, "%s, pipe %c, %d bit, %s", + enable, pipe, depth, channels); + + return len; +} +static int i830_debug_adpa(struct seq_file *m, char *buf, int reg, u32 val) +{ + char pipe, hsync, vsync; + char *enable; + int len; + + pipe = (val & ADPA_PIPE_B_SELECT) ? 'B' : 'A'; + enable = (val & ADPA_DAC_ENABLE) ? "enabled" : "disabled"; + hsync = (val & ADPA_HSYNC_ACTIVE_HIGH) ? '+' : '-'; + vsync = (val & ADPA_VSYNC_ACTIVE_HIGH) ? '+' : '-'; + + len = snprintf(buf, BUF_LEN, "%s, pipe %c, %chsync, %cvsync", + enable, pipe, hsync, vsync); + return len; +} +static int i830_debug_dvo(struct seq_file *m, char *buf, int reg, u32 val) +{ + char pipe, hsync, vsync; + char *enable, *stall; + int len; + + enable = val & DVO_ENABLE ? "enabled" : "disabled"; + pipe = val & DVO_PIPE_B_SELECT ? 'B' : 'A'; + hsync = val & DVO_HSYNC_ACTIVE_HIGH ? '+' : '-'; + vsync = val & DVO_VSYNC_ACTIVE_HIGH ? '+' : '-'; + + switch (val & DVO_PIPE_STALL_MASK) { + case DVO_PIPE_STALL_UNUSED: + stall = "no stall"; + break; + case DVO_PIPE_STALL: + stall = "stall"; + break; + case DVO_PIPE_STALL_TV: + stall = "TV stall"; + break; + default: + stall = "unknown stall"; + break; + } + + len = snprintf(buf, BUF_LEN, "%s, pipe %c, %s, %chsync, %cvsync", + enable, pipe, stall, hsync, vsync); + + return len; +} +static int i830_debug_pp_control(struct seq_file *m, char *buf, + int reg, u32 val) +{ + int len; + + len = snprintf(buf, BUF_LEN, "power target: %s", + val & POWER_TARGET_ON ? "on" : "off"); + + return len; +} +static int i830_debug_pp_status(struct seq_file *m, char *buf, + int reg, u32 val) +{ + char *status, *ready, *seq; + int len; + + status = val & PP_ON ? "on" : "off"; + ready = val & PP_READY ? "ready" : "not ready"; + seq = "unknownn"; + + switch (val & PP_SEQUENCE_MASK) { + case PP_SEQUENCE_NONE: + seq = "idle"; + break; + case PP_SEQUENCE_ON: + seq = "on"; + break; + case PP_SEQUENCE_OFF: + seq = "off"; + break; + } + + len = snprintf(buf, BUF_LEN, "%s, %s, sequencing %s", + status, ready, seq); + + return len; +} +static int i830_debug_dspcntr(struct seq_file *m, char *buf, int reg, u32 val) +{ + char *enabled, plane; + int len; + + enabled = val & DISPLAY_PLANE_ENABLE ? "enabled" : "disabled"; + plane = val & DISPPLANE_SEL_PIPE_B ? 'B' : 'A'; + + len = snprintf(buf, BUF_LEN, "%s, pipe %c", enabled, plane); + + return len; +} +static int i830_debug_dspstride(struct seq_file *m, char *buf, + int reg, u32 val) +{ + int len; + + len = snprintf(buf, BUF_LEN, "%d bytes", val); + + return len; +} +static int i830_debug_xy(struct seq_file *m, char *buf, int reg, u32 val) +{ + int len; + + len = snprintf(buf, BUF_LEN, "%d, %d", + val & 0xffff, + (val & 0xffff0000) >> 16); + return len; +} +static int i830_debug_xyminus1(struct seq_file *m, char *buf, + int reg, u32 val) +{ + int len; + + len = snprintf(buf, BUF_LEN, "%d, %d", + (val & 0xffff) + 1, + ((val & 0xffff0000) >> 16) + 1); + return len; +} +static int i830_debug_yxminus1(struct seq_file *m, char *buf, int reg, u32 val) +{ + int len; + + len = snprintf(buf, BUF_LEN, "%d, %d", + ((val & 0xffff0000) >> 16) + 1, + (val & 0xffff) + 1); + return len; +} +static int i830_debug_pipeconf(struct seq_file *m, char *buf, int reg, u32 val) +{ + struct drm_device *drm_dev = m->private; + char *enabled, *bit30; + int len; + + enabled = val & PIPEACONF_ENABLE ? "enabled" : "disabled"; + if (IS_I965G(drm_dev)) + bit30 = val & I965_PIPECONF_ACTIVE ? "active" : "inactive"; + else + bit30 = val & PIPEACONF_DOUBLE_WIDE ? + "double-wide" : "single-wide"; + + len = snprintf(buf, BUF_LEN, "%s, %s", enabled, bit30); + + return len; +} +static int i830_debug_pipestat(struct seq_file *m, char *buf, int reg, u32 val) +{ + char *fifo_underun, *crc_error_enable, *crc_done_enable; + char *gmbus_event_enable, *vsync_int_enable, *dline_comp_enable; + char *dpst_event_enable, *lblc_event_enable, *ofield_int_enable; + char *efield_int_enable, *svblank_int_enable, *vblank_int_enable; + char *oreg_update_enable, *crc_error_int_sta, *crc_done_int_sta; + char *gmbus_int_sta, *vsync_int_sta, *dline_comp_sta; + char *dpst_event_sta, *lblc_event_sta, *ofield_int_sta; + char *efield_int_sta, *svblank_int_sta, *vblank_int_sta; + char *oreg_update_sta; + int len; + + fifo_underun = val & PIPE_FIFO_UNDERRUN_STATUS ? + " FIFO_UNDERRUN" : ""; + crc_error_enable = val & PIPE_CRC_ERROR_ENABLE ? + " CRC_ERROR_ENABLE" : ""; + crc_done_enable = val & PIPE_CRC_DONE_ENABLE ? + " CRC_DONE_ENABLE" : ""; + + gmbus_event_enable = val & PIPE_GMBUS_EVENT_ENABLE ? + " GMBUS_EVENT_ENABLE" : ""; + vsync_int_enable = val & PIPE_VSYNC_INTERRUPT_ENABLE ? + " VSYNC_INT_ENABLE" : ""; + dline_comp_enable = val & PIPE_DISPLAY_LINE_COMPARE_ENABLE ? + " Dispaly_LINE_COMPARE_ENABLE" : ""; + + dpst_event_enable = val & PIPE_DPST_EVENT_ENABLE ? + " DPST_EVENT_ENABLE" : ""; + lblc_event_enable = val & PIPE_LEGACY_BLC_EVENT_ENABLE ? + " Legacy_BLC_EVENT_ENABLE" : ""; + ofield_int_enable = val & PIPE_ODD_FIELD_INTERRUPT_ENABLE ? + " ODD_FIELD_INT_ENABLE" : ""; + + efield_int_enable = val & PIPE_EVEN_FIELD_INTERRUPT_ENABLE ? + " EVEN_FIELD_INT_ENABLE" : ""; + svblank_int_enable = val & PIPE_START_VBLANK_INTERRUPT_ENABLE ? + " SVBLANK_INT_ENABLE" : ""; + vblank_int_enable = val & PIPE_VBLANK_INTERRUPT_ENABLE ? + " VBLANK_INT_ENABLE" : ""; + + oreg_update_enable = val & PIPE_OVERLAY_UPDATED_ENABLE ? + " OverlayREG_UPDATE_ENABLE" : ""; + crc_error_int_sta = val & PIPE_CRC_ERROR_INTERRUPT_STATUS ? + " CRC_ERROR_INT_STATUS" : ""; + crc_done_int_sta = val & PIPE_CRC_DONE_INTERRUPT_STATUS ? + " CRC_DONE_INT_STATUS" : ""; + + gmbus_int_sta = val & PIPE_GMBUS_INTERRUPT_STATUS ? + " GMBUS_INT_STATUS" : ""; + vsync_int_sta = val & PIPE_VSYNC_INTERRUPT_STATUS ? + " VSYNC_INT_STATUS" : ""; + dline_comp_sta = val & PIPE_DISPLAY_LINE_COMPARE_STATUS ? + " Display_LINE_COMPARE_STATUS" : ""; + + dpst_event_sta = val & PIPE_DPST_EVENT_STATUS ? + " DPST_EVENT_STATUS" : ""; + lblc_event_sta = val & PIPE_LEGACY_BLC_EVENT_STATUS ? + " Legacy_BLC_EVENT_STATUS" : ""; + ofield_int_sta = val & PIPE_ODD_FIELD_INTERRUPT_STATUS ? + " ODD_FIELD_INT_STATUS" : ""; + + efield_int_sta = val & PIPE_EVEN_FIELD_INTERRUPT_STATUS ? + " EVEN_FIELD_INT_STATUS" : ""; + svblank_int_sta = val & PIPE_START_VBLANK_INTERRUPT_STATUS ? + " Start_VBLANK_INT_STATUS" : ""; + vblank_int_sta = val & PIPE_VBLANK_INTERRUPT_STATUS ? + " VBLANK_INT_STATUS" : ""; + oreg_update_sta = val & PIPE_OVERLAY_UPDATED_STATUS ? + " Overlay_REG_UPDATE_STATUS" : ""; + + len = snprintf(buf, BUF_LEN, "status:%s%s%s" + "%s%s%s" + "%s%s%s" + "%s%s%s" + "%s%s%s" + "%s%s%s" + "%s%s%s" + "%s%s%s%s", + fifo_underun, crc_error_enable, crc_done_enable, + gmbus_event_enable, vsync_int_enable, + dline_comp_enable, dpst_event_enable, + lblc_event_enable, ofield_int_enable, + efield_int_enable, svblank_int_enable, + vblank_int_enable, oreg_update_enable, + crc_error_int_sta, crc_done_int_sta, + gmbus_int_sta, vsync_int_sta, dline_comp_sta, + dpst_event_sta, lblc_event_sta, ofield_int_sta, + efield_int_sta, svblank_int_sta, vblank_int_sta, + oreg_update_sta); + + return len; +} +static int i830_debug_dpll(struct seq_file *m, char *buf, int reg, u32 val) +{ + struct drm_device *drm_dev = m->private; + struct drm_i915_private *dev_priv = drm_dev->dev_private; + char *enabled, *dvomode, *vgamode, *clock, *fpextra; + char *mode; + char sdvoextra[20]; + int p1, p2; + u32 lvds_value; + int is_lvds; + int len; + + enabled = val & DPLL_VCO_ENABLE ? "enabled" : "disabled"; + dvomode = val & DPLL_DVO_HIGH_SPEED ? "dvo" : "non-dvo"; + vgamode = val & DPLL_VGA_MODE_DIS ? "" : ", VGA"; + mode = "unknown"; + clock = "unknown"; + fpextra = val & DISPLAY_RATE_SELECT_FPA1 ? ", using FPx1!" : ""; + + p1 = p2 = 0; + + if (IS_I9XX(drm_dev)) { + if (IS_IGD(drm_dev)) { + p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >> + DPLL_FPA01_P1_POST_DIV_SHIFT_IGD); + } else { + p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + } + switch (val & DPLL_MODE_MASK) { + case DPLLB_MODE_DAC_SERIAL: + mode = "DAC/serial"; + p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; + break; + case DPLLB_MODE_LVDS: + mode = "LVDS"; + p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; + break; + } + } else { + lvds_value = I915_READ(LVDS); + is_lvds = 0; + if ((lvds_value & LVDS_PORT_EN) && (reg == DPLL_B)) + is_lvds = 1; + if (is_lvds) { + mode = "LVDS"; + p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) + >> DPLL_FPA01_P1_POST_DIV_SHIFT); + if ((lvds_value & LVDS_CLKB_POWER_MASK) == + LVDS_CLKB_POWER_UP) + p2 = 7; + else + p2 = 14; + } else { + mode = "DAC/serial"; + if (val & PLL_P1_DIVIDE_BY_TWO) { + p1 = 2; + } else { + /* Map the number in the field to (3, 33) */ + p1 = ((val & DPLL_FPA01_P1_POST_DIV_MASK_I830) + >> DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; + } + } + if (val & PLL_P2_DIVIDE_BY_4) + p2 = 4; + else + p2 = 2; + } + + switch (val & PLL_REF_INPUT_MASK) { + case PLL_REF_INPUT_DREFCLK: + clock = "default"; + break; + case PLL_REF_INPUT_TVCLKINA: + clock = "TV A"; + break; + case PLL_REF_INPUT_TVCLKINBC: + clock = "TV B/C"; + break; + case PLLB_REF_INPUT_SPREADSPECTRUMIN: + if (reg == DPLL_B) + clock = "spread spectrum"; + break; + default: + break; + } + + if (IS_I945G(drm_dev) || IS_I945GM(drm_dev) || IS_G33(drm_dev)) { + int len = 0; + len = sprintf(sdvoextra, ", SDVO mult %d", + (int)((val & SDVO_MULTIPLIER_MASK) >> + SDVO_MULTIPLIER_SHIFT_HIRES) + 1); + sdvoextra[len] = '\0'; + } else { + sdvoextra[0] = '\0'; + } + + len = snprintf(buf, BUF_LEN, "%s, %s%s, %s clock, %s mode, p1 = %d, " + "p2 = %d%s%s", + enabled, dvomode, vgamode, clock, mode, p1, p2, + fpextra, sdvoextra); + return len; +} +static int i830_debug_vgacntrl(struct seq_file *m, char *buf, int reg, u32 val) +{ + int len; + + len = snprintf(buf, BUF_LEN, "%s", + val & VGA_DISP_DISABLE ? "disabled" : "enabled"); + return len; +} +static int i830_debug_hvtotal(struct seq_file *m, char *buf, int reg, u32 val) +{ + int len; + + len = snprintf(buf, BUF_LEN, "%d active, %d total", + (val & 0xffff) + 1, + ((val & 0xffff0000) >> 16) + 1); + return len; +} +static int i830_debug_hvsyncblank(struct seq_file *m, char *buf, + int reg, u32 val) +{ + int len; + + len = snprintf(buf, BUF_LEN, "%d start, %d end", + (val & 0xffff) + 1, + ((val & 0xffff0000) >> 16) + 1); + + return len; +} + +static int drm_debug_i915_fence(struct seq_file *m, char *buf, int reg, u32 val) +{ + struct drm_device *drm_dev = m->private; + char *enable; + char format; + int pitch, size; + unsigned int offset; + int len; + + if (IS_I965G(drm_dev) || ((IS_I915G(drm_dev) || + IS_I915GM(drm_dev)) && reg >= FENCE_REG_945_8)) + return 0; + + enable = (val & 1) ? " enabled" : "disabled"; + format = (val & 1 << 12) ? 'Y' : 'X'; + pitch = 1 << (((val & 0x70) >> 4) - 1); + offset = val & 0x0ff00000; + size = (1024 * 1024) << (((val & 0x700) >> 8) - 1); + + if (format == 'X') + pitch *= 4; + + len = snprintf(buf, BUF_LEN, + "%s, %c tiled, %4d pitch, 0x%08x - 0x%08x (%dkb)", + enable, format, pitch, offset, offset + size, + size / 1024); + + return len; +} +static int drm_debug_965_fence_start(struct seq_file *m, char *buf, + int reg, u32 val) +{ + struct drm_device *drm_dev = m->private; + char *enable; + char format; + int pitch; + unsigned int offset; + int len; + + if (!IS_I965G(drm_dev)) + return 0; + + enable = (val & I965_FENCE_REG_VALID) ? " enabled" : "disabled"; + format = (val & I965_FENCE_Y_MAJOR) ? 'Y' : 'X'; + pitch = ((val & 0xffc) >> 2) * 128; + offset = val & 0xfffff000; + + len = snprintf(buf, BUF_LEN, "%s, %c tile walk, " + "%4d pitch, 0x%08x start", + enable, format, pitch, offset); + return len; +} + +static int drm_debug_965_fence_end(struct seq_file *m, char *buf, + int reg, u32 val) +{ + struct drm_device *drm_dev = m->private; + unsigned int end = val & 0xfffff000; + int len; + + if (!IS_I965G(drm_dev)) + return 0; + + len = snprintf(buf, BUF_LEN, + " 0x%08x end", end); + return len; +} + +static struct i915regsnapshotrec i915_reg_snapshot[] = { + DEFINEREG2(DCC, i830_debug_dcc), + DEFINEREG2(CHDECMISC, i830_debug_chdecmisc), + DEFINEREG_16BIT(C0DRB0), + DEFINEREG_16BIT(C0DRB1), + DEFINEREG_16BIT(C0DRB2), + DEFINEREG_16BIT(C0DRB3), + DEFINEREG_16BIT(C1DRB0), + DEFINEREG_16BIT(C1DRB1), + DEFINEREG_16BIT(C1DRB2), + DEFINEREG_16BIT(C1DRB3), + DEFINEREG_16BIT(C0DRA01), + DEFINEREG_16BIT(C0DRA23), + DEFINEREG_16BIT(C1DRA01), + DEFINEREG_16BIT(C1DRA23), + + DEFINEREG(PGETBL_CTL), + + DEFINEREG2(VGA0, i830_debug_fp), + DEFINEREG2(VGA1, i830_debug_fp), + DEFINEREG2(VGA_PD, i830_debug_vga_pd), + DEFINEREG2(DPLL_TEST, i830_debug_dpll_test), + DEFINEREG(CACHE_MODE_0), + DEFINEREG(D_STATE), + DEFINEREG2(CG_2D_DIS, i830_debug_dspclk_gate_d), + DEFINEREG(CG_3D_DIS), + DEFINEREG(RENCLK_GATE_D2), + /* DEFINEREG(RAMCLK_GATE_D), CRL only */ + DEFINEREG2(SDVOB, i830_debug_sdvo), + DEFINEREG2(SDVOC, i830_debug_sdvo), + /*DEFINEREG(UDIB_SVB_SHB_CODES), CRL only */ + /*DEFINEREG(UDIB_SHA_BLANK_CODES), CRL only */ + DEFINEREG(SDVOUDI), + DEFINEREG(DSPARB), + DEFINEREG(DSPFW1), + DEFINEREG(DSPFW2), + DEFINEREG(DSPFW3), + + DEFINEREG2(ADPA, i830_debug_adpa), + DEFINEREG2(LVDS, i830_debug_lvds), + DEFINEREG2(DVOA, i830_debug_dvo), + DEFINEREG2(DVOB, i830_debug_dvo), + DEFINEREG2(DVOC, i830_debug_dvo), + DEFINEREG(DVOA_SRCDIM), + DEFINEREG(DVOB_SRCDIM), + DEFINEREG(DVOC_SRCDIM), + + DEFINEREG2(PP_CONTROL, i830_debug_pp_control), + DEFINEREG2(PP_STATUS, i830_debug_pp_status), + DEFINEREG(PP_ON_DELAYS), + DEFINEREG(PP_OFF_DELAYS), + DEFINEREG(PP_DIVISOR), + DEFINEREG(PFIT_CONTROL), + DEFINEREG(PFIT_PGM_RATIOS), + DEFINEREG(PORT_HOTPLUG_EN), + DEFINEREG(PORT_HOTPLUG_STAT), + + DEFINEREG2(DSPACNTR, i830_debug_dspcntr), + DEFINEREG2(DSPASTRIDE, i830_debug_dspstride), + DEFINEREG2(DSPAPOS, i830_debug_xy), + DEFINEREG2(DSPASIZE, i830_debug_xyminus1), + DEFINEREG(DSPAADDR), + DEFINEREG(DSPASURF), + DEFINEREG(DSPATILEOFF), + DEFINEREG2(PIPEACONF, i830_debug_pipeconf), + DEFINEREG2(PIPEASRC, i830_debug_yxminus1), + DEFINEREG2(PIPEASTAT, i830_debug_pipestat), + + DEFINEREG2(FPA0, i830_debug_fp), + DEFINEREG2(FPA1, i830_debug_fp), + DEFINEREG2(DPLL_A, i830_debug_dpll), + DEFINEREG(DPLL_A_MD), + DEFINEREG2(HTOTAL_A, i830_debug_hvtotal), + DEFINEREG2(HBLANK_A, i830_debug_hvsyncblank), + DEFINEREG2(HSYNC_A, i830_debug_hvsyncblank), + DEFINEREG2(VTOTAL_A, i830_debug_hvtotal), + DEFINEREG2(VBLANK_A, i830_debug_hvsyncblank), + DEFINEREG2(VSYNC_A, i830_debug_hvsyncblank), + DEFINEREG(BCLRPAT_A), + DEFINEREG(VSYNCSHIFT_A), + + DEFINEREG2(DSPBCNTR, i830_debug_dspcntr), + DEFINEREG2(DSPBSTRIDE, i830_debug_dspstride), + DEFINEREG2(DSPBPOS, i830_debug_xy), + DEFINEREG2(DSPBSIZE, i830_debug_xyminus1), + DEFINEREG(DSPBADDR), + DEFINEREG(DSPBSURF), + DEFINEREG(DSPBTILEOFF), + DEFINEREG2(PIPEBCONF, i830_debug_pipeconf), + DEFINEREG2(PIPEBSRC, i830_debug_yxminus1), + DEFINEREG2(PIPEBSTAT, i830_debug_pipestat), + + DEFINEREG2(FPB0, i830_debug_fp), + DEFINEREG2(FPB1, i830_debug_fp), + DEFINEREG2(DPLL_B, i830_debug_dpll), + DEFINEREG(DPLL_B_MD), + DEFINEREG2(HTOTAL_B, i830_debug_hvtotal), + DEFINEREG2(HBLANK_B, i830_debug_hvsyncblank), + DEFINEREG2(HSYNC_B, i830_debug_hvsyncblank), + DEFINEREG2(VTOTAL_B, i830_debug_hvtotal), + DEFINEREG2(VBLANK_B, i830_debug_hvsyncblank), + DEFINEREG2(VSYNC_B, i830_debug_hvsyncblank), + DEFINEREG(BCLRPAT_B), + DEFINEREG(VSYNCSHIFT_B), + + DEFINEREG(VGA0), + DEFINEREG(VGA1), + DEFINEREG(VGA_PD), + DEFINEREG2(VGACNTRL, i830_debug_vgacntrl), + + DEFINEREG(TV_CTL), + DEFINEREG(TV_DAC), + DEFINEREG(TV_CSC_Y), + DEFINEREG(TV_CSC_Y2), + DEFINEREG(TV_CSC_U), + DEFINEREG(TV_CSC_U2), + DEFINEREG(TV_CSC_V), + DEFINEREG(TV_CSC_V2), + DEFINEREG(TV_CLR_KNOBS), + DEFINEREG(TV_CLR_LEVEL), + DEFINEREG(TV_H_CTL_1), + DEFINEREG(TV_H_CTL_2), + DEFINEREG(TV_H_CTL_3), + DEFINEREG(TV_V_CTL_1), + DEFINEREG(TV_V_CTL_2), + DEFINEREG(TV_V_CTL_3), + DEFINEREG(TV_V_CTL_4), + DEFINEREG(TV_V_CTL_5), + DEFINEREG(TV_V_CTL_6), + DEFINEREG(TV_V_CTL_7), + DEFINEREG(TV_SC_CTL_1), + DEFINEREG(TV_SC_CTL_2), + DEFINEREG(TV_SC_CTL_3), + DEFINEREG(TV_WIN_POS), + DEFINEREG(TV_WIN_SIZE), + DEFINEREG(TV_FILTER_CTL_1), + DEFINEREG(TV_FILTER_CTL_2), + DEFINEREG(TV_FILTER_CTL_3), + DEFINEREG(TV_CC_CONTROL), + DEFINEREG(TV_CC_DATA), + DEFINEREG(TV_H_LUMA_0), + DEFINEREG(TV_H_LUMA_59), + DEFINEREG(TV_H_CHROMA_0), + DEFINEREG(TV_H_CHROMA_59), + + DEFINEREG(FBC_CFB_BASE), + DEFINEREG(FBC_LL_BASE), + DEFINEREG(FBC_CONTROL), + DEFINEREG(FBC_COMMAND), + DEFINEREG(FBC_STATUS), + DEFINEREG(FBC_CONTROL2), + DEFINEREG(FBC_FENCE_OFF), + DEFINEREG(FBC_MOD_NUM), + + DEFINEREG(MI_MODE), + /* DEFINEREG(MI_DISPLAY_POWER_DOWN), CRL only */ + DEFINEREG(MI_ARB_STATE), + DEFINEREG(MI_RDRET_STATE), + DEFINEREG(ECOSKPD), + + DEFINEREG(DP_B), + DEFINEREG(DPB_AUX_CH_CTL), + DEFINEREG(DPB_AUX_CH_DATA1), + DEFINEREG(DPB_AUX_CH_DATA2), + DEFINEREG(DPB_AUX_CH_DATA3), + DEFINEREG(DPB_AUX_CH_DATA4), + DEFINEREG(DPB_AUX_CH_DATA5), + + DEFINEREG(DP_C), + DEFINEREG(DPC_AUX_CH_CTL), + DEFINEREG(DPC_AUX_CH_DATA1), + DEFINEREG(DPC_AUX_CH_DATA2), + DEFINEREG(DPC_AUX_CH_DATA3), + DEFINEREG(DPC_AUX_CH_DATA4), + DEFINEREG(DPC_AUX_CH_DATA5), + + DEFINEREG(DP_D), + DEFINEREG(DPD_AUX_CH_CTL), + DEFINEREG(DPD_AUX_CH_DATA1), + DEFINEREG(DPD_AUX_CH_DATA2), + DEFINEREG(DPD_AUX_CH_DATA3), + DEFINEREG(DPD_AUX_CH_DATA4), + DEFINEREG(DPD_AUX_CH_DATA5), +#define DEFINEFENCE_915(i) \ + { FENCE_REG_830_0 + i * 4, "FENCE " #i, drm_debug_i915_fence, 32 } +#define DEFINEFENCE_945(i) \ + { FENCE_REG_945_8 + (i - 8) * 4, "FENCE " #i, \ + drm_debug_i915_fence, 32 } + DEFINEFENCE_915(0), + DEFINEFENCE_915(1), + DEFINEFENCE_915(2), + DEFINEFENCE_915(3), + DEFINEFENCE_915(4), + DEFINEFENCE_915(5), + DEFINEFENCE_915(6), + DEFINEFENCE_915(7), + DEFINEFENCE_945(8), + DEFINEFENCE_945(9), + DEFINEFENCE_945(10), + DEFINEFENCE_945(11), + DEFINEFENCE_945(12), + DEFINEFENCE_945(13), + DEFINEFENCE_945(14), + DEFINEFENCE_945(15), + +#define DEFINEFENCE_965_START(i) \ + { FENCE_REG_965_0 + i * 8, "FENCE START " #i, \ + drm_debug_965_fence_start, 32 } +#define DEFINEFENCE_965_END(i) \ + { FENCE_REG_965_0 + i * 8 + 4, "FENCE END " #i, \ + drm_debug_965_fence_end, 32 } + DEFINEFENCE_965_START(0), + DEFINEFENCE_965_END(0), + DEFINEFENCE_965_START(1), + DEFINEFENCE_965_END(1), + DEFINEFENCE_965_START(2), + DEFINEFENCE_965_END(2), + DEFINEFENCE_965_START(3), + DEFINEFENCE_965_END(3), + DEFINEFENCE_965_START(4), + DEFINEFENCE_965_END(4), + DEFINEFENCE_965_START(5), + DEFINEFENCE_965_END(5), + DEFINEFENCE_965_START(6), + DEFINEFENCE_965_END(6), + DEFINEFENCE_965_START(7), + DEFINEFENCE_965_END(7), + DEFINEFENCE_965_START(8), + DEFINEFENCE_965_END(8), + DEFINEFENCE_965_START(9), + DEFINEFENCE_965_END(9), + DEFINEFENCE_965_START(10), + DEFINEFENCE_965_END(10), + DEFINEFENCE_965_START(11), + DEFINEFENCE_965_END(11), + DEFINEFENCE_965_START(12), + DEFINEFENCE_965_END(12), + DEFINEFENCE_965_START(13), + DEFINEFENCE_965_END(13), + DEFINEFENCE_965_START(14), + DEFINEFENCE_965_END(14), + DEFINEFENCE_965_START(15), + DEFINEFENCE_965_END(15), +}; +#define NR_REG_SIZE ARRAY_SIZE(i915_reg_snapshot) + +static int i915_reg_dump_show(struct seq_file *m, void *v) +{ + struct drm_device *drm_dev = m->private; + struct drm_i915_private *dev_priv = drm_dev->dev_private; + int i, pos, pos_end, len; + struct i915regsnapshotrec *p_reg; + u32 val; + + pos = *((int *)v); + pos *= NR_BLOCK; + pos_end = min_t(int, (pos + NR_BLOCK), NR_REG_SIZE); + if (pos == 0) + seq_printf(m, "Dump Registers \n"); + + for (i = pos; i < pos_end; i++) { + p_reg = &i915_reg_snapshot[i]; + if (p_reg->bit_width == 16) + val = I915_READ16(p_reg->reg); + else + val = I915_READ(p_reg->reg); + if (p_reg->debug_output) { + len = p_reg->debug_output(m, p_buffer, + p_reg->reg, val); + if (!len) + continue; + seq_printf(m, "%20.20s: 0x%08x (%s)\n", + p_reg->name, val, p_buffer); + memset(p_buffer, 0, len); + } else { + seq_printf(m, "%20.20s: 0x%08x\n", + p_reg->name, val); + } + } + + return 0; +} + +static void *i915_reg_start(struct seq_file *m, loff_t *pos) +{ + loff_t temp_pos; + + temp_pos = *pos; + temp_pos *= NR_BLOCK; + if (temp_pos >= NR_REG_SIZE) + return NULL; + return pos; +} + +static void *i915_reg_next(struct seq_file *m, void *v, loff_t *pos) +{ + (*pos) += 1; + return i915_reg_start(m, pos); +} + +static void i915_reg_stop(struct seq_file *m, void *v) +{ +} + +const struct seq_operations i915_reg_op = { + .start = i915_reg_start, + .next = i915_reg_next, + .stop = i915_reg_stop, + .show = i915_reg_dump_show, +}; + +static int i915_reg_open(struct inode *inode, struct file *file) +{ + int ret; + struct drm_device *drm_device = inode->i_private; + + ret = seq_open(file, &i915_reg_op); + if (!ret) { + struct seq_file *p = file->private_data; + p->private = drm_device; + } + return ret; +} + +static const struct file_operations i915_reg_fops = { + .owner = THIS_MODULE, + .open = i915_reg_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + + +void i915_reg_debugfs_init(struct drm_device *drm_device) +{ + struct drm_minor *primary = drm_device->primary; + + i915_reg = debugfs_create_file(I915_REG_DUMP, S_IFREG | S_IRUGO, + primary->debugfs_root, drm_device, + &i915_reg_fops); + if (i915_reg == NULL) + printk(KERN_DEBUG "Can't create the i915_reg entery " + "under dri/0/ debugfs\n"); + p_buffer = NULL; + p_buffer = kzalloc(BUF_LEN, GFP_KERNEL); + if (!p_buffer) + printk(KERN_DEBUG "can't allocate memory space \n"); + + return; +} +void i915_reg_debugfs_cleanup(struct drm_device *drm_device) +{ + if (i915_reg) { + debugfs_remove(i915_reg); + i915_reg = NULL; + } + kfree(p_buffer); + p_buffer = NULL; + return; +} +#endif ------------------------------------------------------------------------------ OpenSolaris 2009.06 is a cutting edge operating system for enterprises looking to deploy the next generation of Solaris that includes the latest innovations from Sun and the OpenSource community. Download a copy and enjoy capabilities such as Networking, Storage and Virtualization. Go to: http://p.sf.net/sfu/opensolaris-get -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel