Add intel_gpu_dump from the 2D driver.
authorEric Anholt <eric@anholt.net>
Wed, 7 Oct 2009 00:25:10 +0000 (17:25 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 7 Oct 2009 00:49:05 +0000 (17:49 -0700)
.gitignore
lib/intel_gpu_tools.h
lib/intel_reg.h
man/Makefile.am
man/intel_reg_dumper.1 [new file with mode: 0644]
tools/Makefile.am
tools/intel_gpu_dump.c
tools/intel_reg_dumper.c [new file with mode: 0644]

index 86d054d..9100a61 100644 (file)
@@ -53,5 +53,6 @@ tests/gem_bad_blit
 tests/gem_hang
 tools/intel_gpu_dump
 tools/intel_gpu_top
+tools/intel_reg_dumper
 tools/intel_reg_write
 tools/intel_stepping
index d696d72..dd687f4 100644 (file)
@@ -36,6 +36,8 @@ extern struct pci_device *pci_dev;
 extern uint32_t devid;
 extern void *mmio;
 
+#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
+
 static inline uint32_t
 INREG(uint32_t reg)
 {
index bce19e8..ec30c9a 100644 (file)
@@ -1053,9 +1053,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 # define PLL_P1_DIVIDE_BY_TWO                  (1 << 21) /* i830 */
 # define PLL_REF_INPUT_DREFCLK                 (0 << 13)
 # define PLL_REF_INPUT_TVCLKINA                        (1 << 13) /* i830 */
+# define PLL_REF_INPUT_SUPER_SSC               (1 << 13) /* Ironlake: 120M SSC */
 # define PLL_REF_INPUT_TVCLKINBC               (2 << 13) /* SDVO TVCLKIN */
 # define PLLB_REF_INPUT_SPREADSPECTRUMIN       (3 << 13)
 # define PLL_REF_INPUT_MASK                    (3 << 13)
+# define PLL_REF_INPUT_DMICLK                  (5 << 13) /* Ironlake: DMI refclk */
 # define PLL_LOAD_PULSE_PHASE_SHIFT            9
 /*
  * Parallel to Serial Load Pulse phase selection.
@@ -1065,6 +1067,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 # define PLL_LOAD_PULSE_PHASE_MASK             (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
 # define DISPLAY_RATE_SELECT_FPA1              (1 << 8)
+/* Ironlake */
+# define PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT    9
+# define PLL_REF_SDVO_HDMI_MULTIPLIER_MASK     (7 << 9)
+# define PLL_REF_SDVO_HDMI_MULTIPLIER(x)       (((x)-1)<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT)
+# define DPLL_FPA1_P1_POST_DIV_SHIFT           0
+# define DPLL_FPA1_P1_POST_DIV_MASK            0xff
 
 /**
  * SDVO multiplier for 945G/GM. Not used on 965.
@@ -2215,6 +2223,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define PIPECONF_PROGRESSIVE   (0 << 21)
 #define PIPECONF_INTERLACE_W_FIELD_INDICATION  (6 << 21)
 #define PIPECONF_INTERLACE_FIELD_0_ONLY                (7 << 21)
+/* ironlake: gamma */
+#define PIPECONF_PALETTE_8BIT  (0<<24)
+#define PIPECONF_PALETTE_10BIT (1<<24)
+#define PIPECONF_PALETTE_12BIT (2<<24)
+#define PIPECONF_FORCE_BORDER  (1<<25)
+#define PIPECONF_PROGRESSIVE   (0 << 21)
+#define PIPECONF_INTERLACE_W_FIELD_INDICATION  (6 << 21)
+#define PIPECONF_INTERLACE_FIELD_0_ONLY                (7 << 21)
+/* ironlake */
+#define PIPECONF_MSA_TIMING_DELAY      (0<<18) /* for eDP */
+#define PIPECONF_NO_DYNAMIC_RATE_CHANGE        (0 << 16)
+#define PIPECONF_NO_ROTATION           (0<<14)
+#define PIPECONF_FULL_COLOR_RANGE      (0<<13)
+#define PIPECONF_CE_COLOR_RANGE                (1<<13)
+#define PIPECONF_COLOR_SPACE_RGB       (0<<11)
+#define PIPECONF_COLOR_SPACE_YUV601    (1<<11)
+#define PIPECONF_COLOR_SPACE_YUV709    (2<<11)
+#define PIPECONF_CONNECT_DEFAULT       (0<<9)
+#define PIPECONF_8BPP                  (0<<5)
+#define PIPECONF_10BPP                 (1<<5)
+#define PIPECONF_6BPP                  (2<<5)
+#define PIPECONF_12BPP                 (3<<5)
+#define PIPECONF_ENABLE_DITHER         (1<<4)
+#define PIPECONF_DITHER_SPATIAL                (0<<2)
+#define PIPECONF_DITHER_ST1            (1<<2)
+#define PIPECONF_DITHER_ST2            (2<<2)
+#define PIPECONF_DITHER_TEMPORAL       (3<<2)
 
 #define PIPEAGCMAXRED          0x70010
 #define PIPEAGCMAXGREEN                0x70014
@@ -2280,6 +2315,43 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define PIPE_PIXEL_MASK                0x00ffffff
 #define PIPE_PIXEL_SHIFT       0
 
+/*
+ * Computing GMCH M and N values.
+ *
+ * GMCH M/N = dot clock * bytes per pixel / ls_clk * # of lanes
+ *
+ * ls_clk (we assume) is the DP link clock (1.62 or 2.7 GHz)
+ *
+ * The GMCH value is used internally
+ */
+#define PIPEA_GMCH_DATA_M      0x70050
+
+/* Transfer unit size for display port - 1, default is 0x3f (for TU size 64) */
+#define PIPE_GMCH_DATA_M_TU_SIZE_MASK  (0x3f << 25)
+#define PIPE_GMCH_DATA_M_TU_SIZE_SHIFT 25
+
+#define PIPE_GMCH_DATA_M_MASK          (0xffffff)
+
+#define PIPEA_GMCH_DATA_N      0x70054
+#define PIPE_GMCH_DATA_N_MASK          (0xffffff)
+
+/*
+ * Computing Link M and N values.
+ *
+ * Link M / N = pixel_clock / ls_clk
+ *
+ * (the DP spec calls pixel_clock the 'strm_clk')
+ *
+ * The Link value is transmitted in the Main Stream
+ * Attributes and VB-ID.
+ */
+
+#define PIPEA_DP_LINK_M                0x70060
+#define PIPEA_DP_LINK_M_MASK   (0xffffff)
+
+#define PIPEA_DP_LINK_N                0x70064
+#define PIPEA_DP_LINK_N_MASK   (0xffffff)
+
 #define PIPEB_DSL              0x71000
 
 #define PIPEBCONF 0x71008
@@ -2297,6 +2369,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define PIPEBFRAMEHIGH         0x71040
 #define PIPEBFRAMEPIXEL                0x71044
 
+#define PIPEB_GMCH_DATA_M      0x71050
+#define PIPEB_GMCH_DATA_N      0x71054
+#define PIPEB_DP_LINK_M                0x71060
+#define PIPEB_DP_LINK_N                0x71064
+
 #define DSPACNTR               0x70180
 #define DSPBCNTR               0x71180
 #define DISPLAY_PLANE_ENABLE                   (1<<31)
@@ -2942,4 +3019,475 @@ typedef enum {
 #define MCHBAR_RENDER_STANDBY  0x111B8
 #define RENDER_STANDBY_ENABLE  (1 << 30)
 
+
+/* Ironlake */
+
+/* warmup time in us */
+#define WARMUP_PCH_REF_CLK_SSC_MOD     1
+#define WARMUP_PCH_FDI_RECEIVER_PLL    25
+#define WARMUP_PCH_DPLL                        50
+#define WARMUP_CPU_DP_PLL              20
+#define WARMUP_CPU_FDI_TRANSMITTER_PLL 10
+#define WARMUP_DMI_LATENCY             20
+#define FDI_TRAIN_PATTERN_1_TIME       0.5
+#define FDI_TRAIN_PATTERN_2_TIME       1.5
+#define FDI_ONE_IDLE_PATTERN_TIME      31
+
+#define CPU_VGACNTRL           0x41000
+
+#define DIGITAL_PORT_HOTPLUG_CNTRL     0x44030
+#define  DIGITAL_PORTA_HOTPLUG_ENABLE          (1 << 4)
+#define  DIGITAL_PORTA_SHORT_PULSE_2MS         (0 << 2)
+#define  DIGITAL_PORTA_SHORT_PULSE_4_5MS       (1 << 2)
+#define  DIGITAL_PORTA_SHORT_PULSE_6MS         (2 << 2)
+#define  DIGITAL_PORTA_SHORT_PULSE_100MS       (3 << 2)
+#define  DIGITAL_PORTA_NO_DETECT               (0 << 0)
+#define  DIGITAL_PORTA_LONG_PULSE_DETECT_MASK  (1 << 1)
+#define  DIGITAL_PORTA_SHORT_PULSE_DETECT_MASK (1 << 0)
+
+/* refresh rate hardware control */
+#define RR_HW_CTL      0x45300
+#define  RR_HW_LOW_POWER_FRAMES_MASK   0xff
+#define  RR_HW_HIGH_POWER_FRAMES_MASK  0xff00
+
+#define FDI_PLL_BIOS_0                 0x46000
+#define FDI_PLL_BIOS_1                 0x46004
+#define FDI_PLL_BIOS_2                 0x46008
+#define DISPLAY_PORT_PLL_BIOS_0                0x4600c
+#define DISPLAY_PORT_PLL_BIOS_1                0x46010
+#define DISPLAY_PORT_PLL_BIOS_2                0x46014
+
+#define FDI_PLL_FREQ_CTL       0x46030
+#define  FDI_PLL_FREQ_CHANGE_REQUEST   (1<<24)
+#define  FDI_PLL_FREQ_LOCK_LIMIT_MASK  0xfff00
+#define  FDI_PLL_FREQ_DISABLE_COUNT_LIMIT_MASK 0xff
+
+#define PIPEA_DATA_M1          0x60030
+#define  TU_SIZE(x)            (((x)-1) << 25) /* default size 64 */
+#define  TU_SIZE_MASK          0x7e000000
+#define  PIPEA_DATA_M1_OFFSET  0
+#define PIPEA_DATA_N1          0x60034
+#define  PIPEA_DATA_N1_OFFSET  0
+
+#define PIPEA_DATA_M2          0x60038
+#define  PIPEA_DATA_M2_OFFSET  0
+#define PIPEA_DATA_N2          0x6003c
+#define  PIPEA_DATA_N2_OFFSET  0
+
+#define PIPEA_LINK_M1          0x60040
+#define  PIPEA_LINK_M1_OFFSET  0
+#define PIPEA_LINK_N1          0x60044
+#define  PIPEA_LINK_N1_OFFSET  0
+
+#define PIPEA_LINK_M2          0x60048
+#define  PIPEA_LINK_M2_OFFSET  0
+#define PIPEA_LINK_N2          0x6004c
+#define  PIPEA_LINK_N2_OFFSET  0
+
+/* PIPEB timing regs are same start from 0x61000 */
+
+#define PIPEB_DATA_M1          0x61030
+#define  PIPEB_DATA_M1_OFFSET  0
+#define PIPEB_DATA_N1          0x61034
+#define  PIPEB_DATA_N1_OFFSET  0
+
+#define PIPEB_DATA_M2          0x61038
+#define  PIPEB_DATA_M2_OFFSET  0
+#define PIPEB_DATA_N2          0x6103c
+#define  PIPEB_DATA_N2_OFFSET  0
+
+#define PIPEB_LINK_M1          0x61040
+#define  PIPEB_LINK_M1_OFFSET  0
+#define PIPEB_LINK_N1          0x61044
+#define  PIPEB_LINK_N1_OFFSET  0
+
+#define PIPEB_LINK_M2          0x61048
+#define  PIPEB_LINK_M2_OFFSET  0
+#define PIPEB_LINK_N2          0x6104c
+#define  PIPEB_LINK_N2_OFFSET  0
+
+/* PIPECONF for pipe A/B addr is same */
+
+/* cusor A is only connected to pipe A,
+   cursor B is connected to pipe B. Otherwise no change. */
+
+/* Plane A/B, DSPACNTR/DSPBCNTR addr not changed */
+
+/* CPU panel fitter */
+#define PFA_CTL_1              0x68080
+#define PFB_CTL_1              0x68880
+#define  PF_ENABLE             (1<<31)
+
+#define PFA_WIN_POS            0x68070
+#define PFB_WIN_POS            0x68870
+#define PFA_WIN_SIZE           0x68074
+#define PFB_WIN_SIZE           0x68874
+
+/* legacy palette */
+#define LGC_PALETTE_A          0x4a000
+#define LGC_PALETTE_B          0x4a800
+
+/* interrupts */
+#define DE_MASTER_IRQ_CONTROL  (1 << 31)
+#define DE_SPRITEB_FLIP_DONE   (1 << 29)
+#define DE_SPRITEA_FLIP_DONE   (1 << 28)
+#define DE_PLANEB_FLIP_DONE    (1 << 27)
+#define DE_PLANEA_FLIP_DONE    (1 << 26)
+#define DE_PCU_EVENT           (1 << 25)
+#define DE_GTT_FAULT           (1 << 24)
+#define DE_POISON              (1 << 23)
+#define DE_PERFORM_COUNTER     (1 << 22)
+#define DE_PCH_EVENT           (1 << 21)
+#define DE_AUX_CHANNEL_A       (1 << 20)
+#define DE_DP_A_HOTPLUG                (1 << 19)
+#define DE_GSE                 (1 << 18)
+#define DE_PIPEB_VBLANK                (1 << 15)
+#define DE_PIPEB_EVEN_FIELD    (1 << 14)
+#define DE_PIPEB_ODD_FIELD     (1 << 13)
+#define DE_PIPEB_LINE_COMPARE  (1 << 12)
+#define DE_PIPEB_VSYNC         (1 << 11)
+#define DE_PIPEB_FIFO_UNDERRUN (1 << 8)
+#define DE_PIPEA_VBLANK                (1 << 7)
+#define DE_PIPEA_EVEN_FIELD    (1 << 6)
+#define DE_PIPEA_ODD_FIELD     (1 << 5)
+#define DE_PIPEA_LINE_COMPARE  (1 << 4)
+#define DE_PIPEA_VSYNC         (1 << 3)
+#define DE_PIPEA_FIFO_UNDERRUN (1 << 0)
+
+#define DEISR  0x44000
+#define DEIMR  0x44004
+#define DEIIR  0x44008
+#define DEIER  0x4400c
+
+/* GT interrupt */
+#define GT_SYNC_STATUS         (1 << 2)
+#define GT_USER_INTERRUPT      (1 << 0)
+
+#define GTISR  0x44010
+#define GTIMR  0x44014
+#define GTIIR  0x44018
+#define GTIER  0x4401c
+
+/* PCH */
+
+/* south display engine interrupt */
+#define SDE_CRT_HOTPLUG                (1 << 11)
+#define SDE_PORTD_HOTPLUG      (1 << 10)
+#define SDE_PORTC_HOTPLUG      (1 << 9)
+#define SDE_PORTB_HOTPLUG      (1 << 8)
+#define SDE_SDVOB_HOTPLUG      (1 << 6)
+
+#define SDEISR 0xc4000
+#define SDEIMR 0xc4004
+#define SDEIIR 0xc4008
+#define SDEIER 0xc400c
+
+/* digital port hotplug */
+#define PCH_PORT_HOTPLUG       0xc4030
+#define PORTD_HOTPLUG_ENABLE           (1 << 20)
+#define PORTD_PULSE_DURATION_2ms       (0)
+#define PORTD_PULSE_DURATION_4_5ms     (1 << 18)
+#define PORTD_PULSE_DURATION_6ms       (2 << 18)
+#define PORTD_PULSE_DURATION_100ms     (3 << 18)
+#define PORTD_HOTPLUG_NO_DETECT                (0)
+#define PORTD_HOTPLUG_SHORT_DETECT     (1 << 16)
+#define PORTD_HOTPLUG_LONG_DETECT      (1 << 17)
+#define PORTC_HOTPLUG_ENABLE           (1 << 12)
+#define PORTC_PULSE_DURATION_2ms       (0)
+#define PORTC_PULSE_DURATION_4_5ms     (1 << 10)
+#define PORTC_PULSE_DURATION_6ms       (2 << 10)
+#define PORTC_PULSE_DURATION_100ms     (3 << 10)
+#define PORTC_HOTPLUG_NO_DETECT                (0)
+#define PORTC_HOTPLUG_SHORT_DETECT     (1 << 8)
+#define PORTC_HOTPLUG_LONG_DETECT      (1 << 9)
+#define PORTB_HOTPLUG_ENABLE           (1 << 4)
+#define PORTB_PULSE_DURATION_2ms       (0)
+#define PORTB_PULSE_DURATION_4_5ms     (1 << 2)
+#define PORTB_PULSE_DURATION_6ms       (2 << 2)
+#define PORTB_PULSE_DURATION_100ms     (3 << 2)
+#define PORTB_HOTPLUG_NO_DETECT                (0)
+#define PORTB_HOTPLUG_SHORT_DETECT     (1 << 0)
+#define PORTB_HOTPLUG_LONG_DETECT      (1 << 1)
+
+#define PCH_GPIOA              0xc5010
+#define PCH_GPIOB              0xc5014
+#define PCH_GPIOC              0xc5018
+#define PCH_GPIOD              0xc501c
+#define PCH_GPIOE              0xc5020
+#define PCH_GPIOF              0xc5024
+#define PCH_GMBUS0             0xc5100
+#define PCH_GMBUS1             0xc5104
+#define PCH_GMBUS2             0xc5108
+#define PCH_GMBUS3             0xc510c
+#define PCH_GMBUS4             0xc5110
+#define PCH_GMBUS5             0xc5120
+
+#define PCH_DPLL_A             0xc6014
+#define PCH_DPLL_B             0xc6018
+
+#define PCH_FPA0               0xc6040
+#define PCH_FPA1               0xc6044
+#define PCH_FPB0               0xc6048
+#define PCH_FPB1               0xc604c
+
+#define PCH_DPLL_TEST          0xc606c
+
+#define PCH_DREF_CONTROL       0xC6200
+#define  DREF_CONTROL_MASK     0x7fc3
+#define  DREF_CPU_SOURCE_OUTPUT_DISABLE                (0<<13)
+#define  DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD     (2<<13)
+#define  DREF_CPU_SOURCE_OUTPUT_NONSPREAD      (3<<13)
+#define  DREF_SSC_SOURCE_DISABLE               (0<<11)
+#define  DREF_SSC_SOURCE_ENABLE                        (2<<11)
+#define  DREF_NONSPREAD_SOURCE_DISABLE         (0<<9)
+#define  DREF_NONSPREAD_SOURCE_ENABLE          (2<<9)
+#define  DREF_SUPERSPREAD_SOURCE_DISABLE       (0<<7)
+#define  DREF_SUPERSPREAD_SOURCE_ENABLE                (2<<7)
+#define  DREF_SSC4_DOWNSPREAD                  (0<<6)
+#define  DREF_SSC4_CENTERSPREAD                        (1<<6)
+#define  DREF_SSC1_DISABLE                     (0<<1)
+#define  DREF_SSC1_ENABLE                      (1<<1)
+#define  DREF_SSC4_DISABLE                     (0)
+#define  DREF_SSC4_ENABLE                      (1)
+
+#define PCH_RAWCLK_FREQ                0xc6204
+#define  FDL_TP1_TIMER_SHIFT   12
+#define  FDL_TP1_TIMER_MASK    (3<<12)
+#define  FDL_TP2_TIMER_SHIFT   10
+#define  FDL_TP2_TIMER_MASK    (3<<10)
+#define  RAWCLK_FREQ_MASK      0x3ff
+
+#define PCH_DPLL_TMR_CFG       0xc6208
+
+#define PCH_SSC4_PARMS         0xc6210
+#define PCH_SSC4_AUX_PARMS     0xc6214
+
+/* transcoder */
+
+#define TRANS_HTOTAL_A         0xe0000
+#define  TRANS_HTOTAL_SHIFT    16
+#define  TRANS_HACTIVE_SHIFT   0
+#define TRANS_HBLANK_A         0xe0004
+#define  TRANS_HBLANK_END_SHIFT        16
+#define  TRANS_HBLANK_START_SHIFT 0
+#define TRANS_HSYNC_A          0xe0008
+#define  TRANS_HSYNC_END_SHIFT 16
+#define  TRANS_HSYNC_START_SHIFT 0
+#define TRANS_VTOTAL_A         0xe000c
+#define  TRANS_VTOTAL_SHIFT    16
+#define  TRANS_VACTIVE_SHIFT   0
+#define TRANS_VBLANK_A         0xe0010
+#define  TRANS_VBLANK_END_SHIFT        16
+#define  TRANS_VBLANK_START_SHIFT 0
+#define TRANS_VSYNC_A          0xe0014
+#define  TRANS_VSYNC_END_SHIFT 16
+#define  TRANS_VSYNC_START_SHIFT 0
+
+#define TRANSA_DATA_M1         0xe0030
+#define TRANSA_DATA_N1         0xe0034
+#define TRANSA_DATA_M2         0xe0038
+#define TRANSA_DATA_N2         0xe003c
+#define TRANSA_DP_LINK_M1      0xe0040
+#define TRANSA_DP_LINK_N1      0xe0044
+#define TRANSA_DP_LINK_M2      0xe0048
+#define TRANSA_DP_LINK_N2      0xe004c
+
+#define TRANS_HTOTAL_B         0xe1000
+#define TRANS_HBLANK_B         0xe1004
+#define TRANS_HSYNC_B          0xe1008
+#define TRANS_VTOTAL_B         0xe100c
+#define TRANS_VBLANK_B         0xe1010
+#define TRANS_VSYNC_B          0xe1014
+
+#define TRANSB_DATA_M1         0xe1030
+#define TRANSB_DATA_N1         0xe1034
+#define TRANSB_DATA_M2         0xe1038
+#define TRANSB_DATA_N2         0xe103c
+#define TRANSB_DP_LINK_M1      0xe1040
+#define TRANSB_DP_LINK_N1      0xe1044
+#define TRANSB_DP_LINK_M2      0xe1048
+#define TRANSB_DP_LINK_N2      0xe104c
+
+#define TRANSACONF             0xf0008
+#define TRANSBCONF             0xf1008
+#define  TRANS_DISABLE         (0<<31)
+#define  TRANS_ENABLE          (1<<31)
+#define  TRANS_STATE_MASK      (1<<30)
+#define  TRANS_STATE_DISABLE   (0<<30)
+#define  TRANS_STATE_ENABLE    (1<<30)
+#define  TRANS_FSYNC_DELAY_HB1 (0<<27)
+#define  TRANS_FSYNC_DELAY_HB2 (1<<27)
+#define  TRANS_FSYNC_DELAY_HB3 (2<<27)
+#define  TRANS_FSYNC_DELAY_HB4 (3<<27)
+#define  TRANS_DP_AUDIO_ONLY   (1<<26)
+#define  TRANS_DP_VIDEO_AUDIO  (0<<26)
+#define  TRANS_PROGRESSIVE     (0<<21)
+#define  TRANS_8BPC            (0<<5)
+#define  TRANS_10BPC           (1<<5)
+#define  TRANS_6BPC            (2<<5)
+#define  TRANS_12BPC           (3<<5)
+
+#define FDI_RXA_CHICKEN                0xc200c
+#define FDI_RXB_CHICKEN                0xc2010
+#define  FDI_RX_PHASE_SYNC_POINTER_ENABLE      (1)
+
+/* CPU: FDI_TX */
+#define FDI_TXA_CTL            0x60100
+#define FDI_TXB_CTL            0x61100
+#define  FDI_TX_DISABLE                (0<<31)
+#define  FDI_TX_ENABLE         (1<<31)
+#define  FDI_LINK_TRAIN_PATTERN_1      (0<<28)
+#define  FDI_LINK_TRAIN_PATTERN_2      (1<<28)
+#define  FDI_LINK_TRAIN_PATTERN_IDLE   (2<<28)
+#define  FDI_LINK_TRAIN_NONE           (3<<28)
+#define  FDI_LINK_TRAIN_VOLTAGE_0_4V   (0<<25)
+#define  FDI_LINK_TRAIN_VOLTAGE_0_6V   (1<<25)
+#define  FDI_LINK_TRAIN_VOLTAGE_0_8V   (2<<25)
+#define  FDI_LINK_TRAIN_VOLTAGE_1_2V   (3<<25)
+#define  FDI_LINK_TRAIN_PRE_EMPHASIS_NONE (0<<22)
+#define  FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1<<22)
+#define  FDI_LINK_TRAIN_PRE_EMPHASIS_2X          (2<<22)
+#define  FDI_LINK_TRAIN_PRE_EMPHASIS_3X          (3<<22)
+#define  FDI_DP_PORT_WIDTH_X1          (0<<19)
+#define  FDI_DP_PORT_WIDTH_X2          (1<<19)
+#define  FDI_DP_PORT_WIDTH_X3          (2<<19)
+#define  FDI_DP_PORT_WIDTH_X4          (3<<19)
+#define  FDI_TX_ENHANCE_FRAME_ENABLE   (1<<18)
+/* Ironlake: hardwired to 1 */
+#define  FDI_TX_PLL_ENABLE             (1<<14)
+/* both Tx and Rx */
+#define  FDI_SCRAMBLING_ENABLE         (0<<7)
+#define  FDI_SCRAMBLING_DISABLE                (1<<7)
+
+/* FDI_RX, FDI_X is hard-wired to Transcoder_X */
+#define FDI_RXA_CTL            0xf000c
+#define FDI_RXB_CTL            0xf100c
+#define  FDI_RX_ENABLE         (1<<31)
+#define  FDI_RX_DISABLE                (0<<31)
+/* train, dp width same as FDI_TX */
+#define  FDI_DP_PORT_WIDTH_X8          (7<<19)
+#define  FDI_8BPC                      (0<<16)
+#define  FDI_10BPC                     (1<<16)
+#define  FDI_6BPC                      (2<<16)
+#define  FDI_12BPC                     (3<<16)
+#define  FDI_LINK_REVERSE_OVERWRITE    (1<<15)
+#define  FDI_DMI_LINK_REVERSE_MASK     (1<<14)
+#define  FDI_RX_PLL_ENABLE             (1<<13)
+#define  FDI_FS_ERR_CORRECT_ENABLE     (1<<11)
+#define  FDI_FE_ERR_CORRECT_ENABLE     (1<<10)
+#define  FDI_FS_ERR_REPORT_ENABLE      (1<<9)
+#define  FDI_FE_ERR_REPORT_ENABLE      (1<<8)
+#define  FDI_RX_ENHANCE_FRAME_ENABLE   (1<<6)
+#define  FDI_SEL_RAWCLK                        (0<<4)
+#define  FDI_SEL_PCDCLK                        (1<<4)
+
+#define FDI_RXA_MISC           0xf0010
+#define FDI_RXB_MISC           0xf1010
+#define FDI_RXA_TUSIZE1                0xf0030
+#define FDI_RXA_TUSIZE2                0xf0038
+#define FDI_RXB_TUSIZE1                0xf1030
+#define FDI_RXB_TUSIZE2                0xf1038
+
+/* FDI_RX interrupt register format */
+#define FDI_RX_INTER_LANE_ALIGN                (1<<10)
+#define FDI_RX_SYMBOL_LOCK             (1<<9) /* train 2 */
+#define FDI_RX_BIT_LOCK                        (1<<8) /* train 1 */
+#define FDI_RX_TRAIN_PATTERN_2_FAIL    (1<<7)
+#define FDI_RX_FS_CODE_ERR             (1<<6)
+#define FDI_RX_FE_CODE_ERR             (1<<5)
+#define FDI_RX_SYMBOL_ERR_RATE_ABOVE   (1<<4)
+#define FDI_RX_HDCP_LINK_FAIL          (1<<3)
+#define FDI_RX_PIXEL_FIFO_OVERFLOW     (1<<2)
+#define FDI_RX_CROSS_CLOCK_OVERFLOW    (1<<1)
+#define FDI_RX_SYMBOL_QUEUE_OVERFLOW   (1<<0)
+
+#define FDI_RXA_IIR            0xf0014
+#define FDI_RXA_IMR            0xf0018
+#define FDI_RXB_IIR            0xf1014
+#define FDI_RXB_IMR            0xf1018
+
+#define FDI_PLL_CTL_1          0xfe000
+#define FDI_PLL_CTL_2          0xfe004
+
+/* CRT */
+#define PCH_ADPA               0xe1100
+#define  ADPA_TRANS_SELECT_MASK        (1<<30)
+#define  ADPA_TRANS_A_SELECT   0
+#define  ADPA_TRANS_B_SELECT   (1<<30)
+/* HPD is here */
+#define  ADPA_CRT_HOTPLUG_MASK 0x03ff0000 /* bit 25-16 */
+#define         ADPA_CRT_HOTPLUG_MONITOR_NONE  (0<<24)
+#define  ADPA_CRT_HOTPLUG_MONITOR_MASK (3<<24)
+#define  ADPA_CRT_HOTPLUG_MONITOR_COLOR        (3<<24)
+#define  ADPA_CRT_HOTPLUG_MONITOR_MONO (2<<24)
+#define  ADPA_CRT_HOTPLUG_ENABLE       (1<<23)
+#define  ADPA_CRT_HOTPLUG_PERIOD_64    (0<<22)
+#define  ADPA_CRT_HOTPLUG_PERIOD_128   (1<<22)
+#define  ADPA_CRT_HOTPLUG_WARMUP_5MS   (0<<21)
+#define  ADPA_CRT_HOTPLUG_WARMUP_10MS  (1<<21)
+#define  ADPA_CRT_HOTPLUG_SAMPLE_2S    (0<<20)
+#define  ADPA_CRT_HOTPLUG_SAMPLE_4S    (1<<20)
+#define  ADPA_CRT_HOTPLUG_VOLTAGE_40   (0<<18)
+#define  ADPA_CRT_HOTPLUG_VOLTAGE_50   (1<<18)
+#define  ADPA_CRT_HOTPLUG_VOLTAGE_60   (2<<18)
+#define  ADPA_CRT_HOTPLUG_VOLTAGE_70   (3<<18)
+#define  ADPA_CRT_HOTPLUG_VOLREF_325MV (0<<17)
+#define  ADPA_CRT_HOTPLUG_VOLREF_475MV (1<<17)
+#define  ADPA_CRT_HOTPLUG_FORCE_TRIGGER        (1<<16)
+/* polarity control not changed */
+
+/* or SDVOB */
+#define HDMIB  0xe1140
+#define  PORT_ENABLE   (1 << 31)
+#define  TRANSCODER_A  (0)
+#define  TRANSCODER_B  (1 << 30)
+#define  COLOR_FORMAT_8bpc     (0)
+#define  COLOR_FORMAT_12bpc    (3 << 26)
+#define  SDVOB_HOTPLUG_ENABLE  (1 << 23)
+#define  SDVO_ENCODING         (0)
+#define  TMDS_ENCODING         (2 << 10)
+#define  NULL_PACKET_VSYNC_ENABLE      (1 << 9)
+#define  SDVOB_BORDER_ENABLE   (1 << 7)
+#define  AUDIO_ENABLE          (1 << 6)
+#define  VSYNC_ACTIVE_HIGH     (1 << 4)
+#define  HSYNC_ACTIVE_HIGH     (1 << 3)
+#define  PORT_DETECTED         (1 << 2)
+
+#define HDMIC  0xe1150
+#define HDMID  0xe1160
+#define PCH_LVDS               0xe1180
+
+#define AUD_CONFIG              0x62000
+#define AUD_DEBUG               0x62010
+#define AUD_VID_DID             0x62020
+#define AUD_RID                 0x62024
+#define AUD_SUBN_CNT            0x62028
+#define AUD_FUNC_GRP            0x62040
+#define AUD_SUBN_CNT2           0x62044
+#define AUD_GRP_CAP             0x62048
+#define AUD_PWRST               0x6204c
+#define AUD_SUPPWR              0x62050
+#define AUD_SID                 0x62054
+#define AUD_OUT_CWCAP           0x62070
+#define AUD_OUT_PCMSIZE         0x62074
+#define AUD_OUT_STR             0x62078
+#define AUD_OUT_DIG_CNVT        0x6207c
+#define AUD_OUT_CH_STR          0x62080
+#define AUD_OUT_STR_DESC        0x62084
+#define AUD_PINW_CAP            0x620a0
+#define AUD_PIN_CAP             0x620a4
+#define AUD_PINW_CONNLNG        0x620a8
+#define AUD_PINW_CONNLST        0x620ac
+#define AUD_PINW_CNTR           0x620b0
+#define AUD_PINW_UNSOLRESP      0x620b8
+#define AUD_CNTL_ST             0x620b4
+#define AUD_PINW_CONFIG         0x620bc
+#define AUD_HDMIW_STATUS        0x620d4
+#define AUD_HDMIW_HDMIEDID      0x6210c
+#define AUD_HDMIW_INFOFR        0x62118
+#define AUD_CONV_CHCNT          0x62120
+#define AUD_CTS_ENABLE          0x62128
+
+#define VIDEO_DIP_CTL           0x61170
+
 #endif /* _I810_REG_H */
index 2922f7f..70e5320 100644 (file)
@@ -1,6 +1,7 @@
 dist_man1_MANS = \
        intel_gpu_dump.1 \
        intel_gpu_top.1 \
+       intel_reg_dumper.1 \
        intel_reg_write.1 \
        intel_stepping.1 \
        intel_upload_blit_large.1 \
diff --git a/man/intel_reg_dumper.1 b/man/intel_reg_dumper.1
new file mode 100644 (file)
index 0000000..cdaeee1
--- /dev/null
@@ -0,0 +1,11 @@
+emacs .\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH intel_reg_dumper 1 "intel_reg_dumper 1.0"
+.SH NAME
+intel_reg_dumper \- Decode a bunch of Intel GPU registers for debugging
+.SH SYNOPSIS
+.B intel_reg_dumper
+.SH DESCRIPTION
+.B intel_reg_write
+is a tool to read and decode the values of many Intel GPU registers.  It is
+commonly used in debugging video mode setting issues.
index 31520b7..545ddc6 100644 (file)
@@ -2,6 +2,7 @@ bin_PROGRAMS = \
        intel_gpu_dump \
        intel_gpu_top \
        intel_stepping \
+       intel_reg_dumper \
        intel_reg_write
 
 intel_gpu_dump_SOURCES = \
index c80dfcc..21862f4 100644 (file)
@@ -59,8 +59,6 @@
     return count;                                              \
 } while (0)
 
-#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
-
 static FILE *out;
 static uint32_t saved_s2 = 0, saved_s4 = 0;
 static char saved_s2_set = 0, saved_s4_set = 0;
diff --git a/tools/intel_reg_dumper.c b/tools/intel_reg_dumper.c
new file mode 100644 (file)
index 0000000..55a0531
--- /dev/null
@@ -0,0 +1,1658 @@
+/*
+ * Copyright Â© 2006,2009 Intel Corporation
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <err.h>
+#include "intel_gpu_tools.h"
+
+#define DEBUGSTRING(func) static void func(char **result, int reg, uint32_t val)
+
+DEBUGSTRING(i830_16bit_func)
+{
+       asprintf(result, "0x%04x", (uint16_t) val);
+}
+
+DEBUGSTRING(i830_debug_dcc)
+{
+       char *addressing = NULL;
+
+       if (!IS_MOBILE(devid))
+               return;
+
+       if (IS_965(devid)) {
+               if (val & (1 << 1))
+                       addressing = "dual channel interleaved";
+               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;
+               }
+       }
+
+       asprintf(result, "%s, XOR randomization: %sabled, XOR bit: %d",
+                addressing,
+                (val & (1 << 10)) ? "dis" : "en",
+                (val & (1 << 9)) ? 17 : 11);
+}
+
+DEBUGSTRING(i830_debug_chdecmisc)
+{
+       char *enhmodesel = NULL;
+
+       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;
+       }
+
+       asprintf(result,
+                "%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 ");
+}
+
+DEBUGSTRING(i830_debug_xyminus1)
+{
+       asprintf(result, "%d, %d", (val & 0xffff) + 1,
+                ((val & 0xffff0000) >> 16) + 1);
+}
+
+DEBUGSTRING(i830_debug_yxminus1)
+{
+       asprintf(result, "%d, %d", ((val & 0xffff0000) >> 16) + 1,
+                (val & 0xffff) + 1);
+}
+
+DEBUGSTRING(i830_debug_xy)
+{
+       asprintf(result, "%d, %d", (val & 0xffff), ((val & 0xffff0000) >> 16));
+}
+
+DEBUGSTRING(i830_debug_dspstride)
+{
+       asprintf(result, "%d bytes", val);
+}
+
+DEBUGSTRING(i830_debug_dspcntr)
+{
+       char *enabled = val & DISPLAY_PLANE_ENABLE ? "enabled" : "disabled";
+       char plane = val & DISPPLANE_SEL_PIPE_B ? 'B' : 'A';
+       if (IS_IRONLAKE(devid))
+               asprintf(result, "%s", enabled);
+       else
+               asprintf(result, "%s, pipe %c", enabled, plane);
+}
+
+DEBUGSTRING(i830_debug_pipeconf)
+{
+       char *enabled = val & PIPEACONF_ENABLE ? "enabled" : "disabled";
+       char *bit30;
+       char *bpc = NULL;
+
+       if (IS_965(devid))
+               bit30 = val & I965_PIPECONF_ACTIVE ? "active" : "inactive";
+       else
+               bit30 =
+                   val & PIPEACONF_DOUBLE_WIDE ? "double-wide" : "single-wide";
+
+       if (IS_IRONLAKE(devid)) {
+               switch (val & (7 << 5)) {
+               case PIPECONF_8BPP:
+                       bpc = "8bpc";
+                       break;
+               case PIPECONF_10BPP:
+                       bpc = "10bpc";
+                       break;
+               case PIPECONF_6BPP:
+                       bpc = "6bpc";
+                       break;
+               case PIPECONF_12BPP:
+                       bpc = "12bpc";
+                       break;
+               }
+       }
+       if (IS_IRONLAKE(devid))
+               asprintf(result, "%s, %s, %s", enabled, bit30, bpc);
+       else
+               asprintf(result, "%s, %s", enabled, bit30);
+}
+
+DEBUGSTRING(i830_debug_pipestat)
+{
+       char *_FIFO_UNDERRUN = val & FIFO_UNDERRUN ? " FIFO_UNDERRUN" : "";
+       char *_CRC_ERROR_ENABLE =
+           val & CRC_ERROR_ENABLE ? " CRC_ERROR_ENABLE" : "";
+       char *_CRC_DONE_ENABLE =
+           val & CRC_DONE_ENABLE ? " CRC_DONE_ENABLE" : "";
+       char *_GMBUS_EVENT_ENABLE =
+           val & GMBUS_EVENT_ENABLE ? " GMBUS_EVENT_ENABLE" : "";
+       char *_VSYNC_INT_ENABLE =
+           val & VSYNC_INT_ENABLE ? " VSYNC_INT_ENABLE" : "";
+       char *_DLINE_COMPARE_ENABLE =
+           val & DLINE_COMPARE_ENABLE ? " DLINE_COMPARE_ENABLE" : "";
+       char *_DPST_EVENT_ENABLE =
+           val & DPST_EVENT_ENABLE ? " DPST_EVENT_ENABLE" : "";
+       char *_LBLC_EVENT_ENABLE =
+           val & LBLC_EVENT_ENABLE ? " LBLC_EVENT_ENABLE" : "";
+       char *_OFIELD_INT_ENABLE =
+           val & OFIELD_INT_ENABLE ? " OFIELD_INT_ENABLE" : "";
+       char *_EFIELD_INT_ENABLE =
+           val & EFIELD_INT_ENABLE ? " EFIELD_INT_ENABLE" : "";
+       char *_SVBLANK_INT_ENABLE =
+           val & SVBLANK_INT_ENABLE ? " SVBLANK_INT_ENABLE" : "";
+       char *_VBLANK_INT_ENABLE =
+           val & VBLANK_INT_ENABLE ? " VBLANK_INT_ENABLE" : "";
+       char *_OREG_UPDATE_ENABLE =
+           val & OREG_UPDATE_ENABLE ? " OREG_UPDATE_ENABLE" : "";
+       char *_CRC_ERROR_INT_STATUS =
+           val & CRC_ERROR_INT_STATUS ? " CRC_ERROR_INT_STATUS" : "";
+       char *_CRC_DONE_INT_STATUS =
+           val & CRC_DONE_INT_STATUS ? " CRC_DONE_INT_STATUS" : "";
+       char *_GMBUS_INT_STATUS =
+           val & GMBUS_INT_STATUS ? " GMBUS_INT_STATUS" : "";
+       char *_VSYNC_INT_STATUS =
+           val & VSYNC_INT_STATUS ? " VSYNC_INT_STATUS" : "";
+       char *_DLINE_COMPARE_STATUS =
+           val & DLINE_COMPARE_STATUS ? " DLINE_COMPARE_STATUS" : "";
+       char *_DPST_EVENT_STATUS =
+           val & DPST_EVENT_STATUS ? " DPST_EVENT_STATUS" : "";
+       char *_LBLC_EVENT_STATUS =
+           val & LBLC_EVENT_STATUS ? " LBLC_EVENT_STATUS" : "";
+       char *_OFIELD_INT_STATUS =
+           val & OFIELD_INT_STATUS ? " OFIELD_INT_STATUS" : "";
+       char *_EFIELD_INT_STATUS =
+           val & EFIELD_INT_STATUS ? " EFIELD_INT_STATUS" : "";
+       char *_SVBLANK_INT_STATUS =
+           val & SVBLANK_INT_STATUS ? " SVBLANK_INT_STATUS" : "";
+       char *_VBLANK_INT_STATUS =
+           val & VBLANK_INT_STATUS ? " VBLANK_INT_STATUS" : "";
+       char *_OREG_UPDATE_STATUS =
+           val & OREG_UPDATE_STATUS ? " OREG_UPDATE_STATUS" : "";
+       asprintf(result,
+                "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_UNDERRUN,
+                _CRC_ERROR_ENABLE,
+                _CRC_DONE_ENABLE,
+                _GMBUS_EVENT_ENABLE,
+                _VSYNC_INT_ENABLE,
+                _DLINE_COMPARE_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_STATUS,
+                _CRC_DONE_INT_STATUS,
+                _GMBUS_INT_STATUS,
+                _VSYNC_INT_STATUS,
+                _DLINE_COMPARE_STATUS,
+                _DPST_EVENT_STATUS,
+                _LBLC_EVENT_STATUS,
+                _OFIELD_INT_STATUS,
+                _EFIELD_INT_STATUS,
+                _SVBLANK_INT_STATUS,
+                _VBLANK_INT_STATUS,
+                _OREG_UPDATE_STATUS);
+}
+
+DEBUGSTRING(i830_debug_hvtotal)
+{
+       asprintf(result, "%d active, %d total",
+                (val & 0xffff) + 1,
+                ((val & 0xffff0000) >> 16) + 1);
+}
+
+DEBUGSTRING(i830_debug_hvsyncblank)
+{
+       asprintf(result, "%d start, %d end",
+                (val & 0xffff) + 1,
+                ((val & 0xffff0000) >> 16) + 1);
+}
+
+DEBUGSTRING(i830_debug_vgacntrl)
+{
+       asprintf(result, "%s",
+                val & VGA_DISP_DISABLE ? "disabled" : "enabled");
+}
+
+DEBUGSTRING(i830_debug_fp)
+{
+       if (IS_IGD(devid)) {
+               asprintf(result, "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));
+       }
+       asprintf(result, "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));
+}
+
+DEBUGSTRING(i830_debug_vga_pd)
+{
+       int vga0_p1, vga0_p2, vga1_p1, vga1_p2;
+
+       /* XXX: i9xx version */
+
+       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;
+
+       asprintf(result, "vga0 p1 = %d, p2 = %d, vga1 p1 = %d, p2 = %d",
+                        vga0_p1, vga0_p2, vga1_p1, vga1_p2);
+}
+
+DEBUGSTRING(i830_debug_pp_status)
+{
+       char *status = val & PP_ON ? "on" : "off";
+       char *ready = val & PP_READY ? "ready" : "not ready";
+       char *seq = "unknown";
+
+       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;
+       }
+
+       asprintf(result, "%s, %s, sequencing %s", status, ready, seq);
+}
+
+DEBUGSTRING(i830_debug_pp_control)
+{
+       asprintf(result, "power target: %s",
+                        val & POWER_TARGET_ON ? "on" : "off");
+}
+
+DEBUGSTRING(i830_debug_dpll)
+{
+       char *enabled = val & DPLL_VCO_ENABLE ? "enabled" : "disabled";
+       char *dvomode = val & DPLL_DVO_HIGH_SPEED ? "dvo" : "non-dvo";
+       char *vgamode = val & DPLL_VGA_MODE_DIS ? "" : ", VGA";
+       char *mode = "unknown";
+       char *clock = "unknown";
+       char *fpextra = val & DISPLAY_RATE_SELECT_FPA1 ? ", using FPx1!" : "";
+       char sdvoextra[20];
+       int p1, p2 = 0;
+
+       if (IS_9XX(devid)) {
+               if (IS_IGD(devid)) {
+                       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 {
+               char is_lvds = (INREG(LVDS) & LVDS_PORT_EN) && (reg == DPLL_B);
+
+               if (is_lvds) {
+                       mode = "LVDS";
+                       p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS)
+                                >> DPLL_FPA01_P1_POST_DIV_SHIFT);
+                       if ((INREG(LVDS) & 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;
+       }
+
+       if (IS_945(devid)) {
+               sprintf(sdvoextra, ", SDVO mult %d",
+                       (int)((val & SDVO_MULTIPLIER_MASK) >>
+                             SDVO_MULTIPLIER_SHIFT_HIRES) + 1);
+       } else {
+               sdvoextra[0] = '\0';
+       }
+
+       asprintf(result, "%s, %s%s, %s clock, %s mode, p1 = %d, "
+                        "p2 = %d%s%s",
+                        enabled, dvomode, vgamode, clock, mode, p1, p2,
+                        fpextra, sdvoextra);
+}
+
+DEBUGSTRING(i830_debug_dpll_test)
+{
+       char *dpllandiv = val & DPLLA_TEST_N_BYPASS ? ", DPLLA N bypassed" : "";
+       char *dpllamdiv = val & DPLLA_TEST_M_BYPASS ? ", DPLLA M bypassed" : "";
+       char *dpllainput = val & DPLLA_INPUT_BUFFER_ENABLE ?
+           "" : ", DPLLA input buffer disabled";
+       char *dpllbndiv = val & DPLLB_TEST_N_BYPASS ? ", DPLLB N bypassed" : "";
+       char *dpllbmdiv = val & DPLLB_TEST_M_BYPASS ? ", DPLLB M bypassed" : "";
+       char *dpllbinput = val & DPLLB_INPUT_BUFFER_ENABLE ?
+           "" : ", DPLLB input buffer disabled";
+
+       asprintf(result, "%s%s%s%s%s%s",
+                        dpllandiv, dpllamdiv, dpllainput,
+                        dpllbndiv, dpllbmdiv, dpllbinput);
+}
+
+DEBUGSTRING(i830_debug_adpa)
+{
+       char pipe = (val & ADPA_PIPE_B_SELECT) ? 'B' : 'A';
+       char *enable = (val & ADPA_DAC_ENABLE) ? "enabled" : "disabled";
+       char hsync = (val & ADPA_HSYNC_ACTIVE_HIGH) ? '+' : '-';
+       char vsync = (val & ADPA_VSYNC_ACTIVE_HIGH) ? '+' : '-';
+
+       if (IS_IRONLAKE(devid))
+               asprintf(result, "%s, transcoder %c, %chsync, %cvsync",
+                                enable, pipe, hsync, vsync);
+       else
+               asprintf(result, "%s, pipe %c, %chsync, %cvsync",
+                                enable, pipe, hsync, vsync);
+}
+
+DEBUGSTRING(i830_debug_lvds)
+{
+       char pipe = val & LVDS_PIPEB_SELECT ? 'B' : 'A';
+       char *enable = val & LVDS_PORT_EN ? "enabled" : "disabled";
+       int depth;
+       char *channels;
+
+       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";
+
+       asprintf(result, "%s, pipe %c, %d bit, %s",
+                        enable, pipe, depth, channels);
+}
+
+DEBUGSTRING(i830_debug_dvo)
+{
+       char *enable = val & DVO_ENABLE ? "enabled" : "disabled";
+       char pipe = val & DVO_PIPE_B_SELECT ? 'B' : 'A';
+       char *stall;
+       char hsync = val & DVO_HSYNC_ACTIVE_HIGH ? '+' : '-';
+       char 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;
+       }
+
+       asprintf(result, "%s, pipe %c, %s, %chsync, %cvsync",
+                        enable, pipe, stall, hsync, vsync);
+}
+
+DEBUGSTRING(i830_debug_sdvo)
+{
+       char *enable = val & SDVO_ENABLE ? "enabled" : "disabled";
+       char pipe = val & SDVO_PIPE_B_SELECT ? 'B' : 'A';
+       char *stall = val & SDVO_STALL_SELECT ? "enabled" : "disabled";
+       char *detected = val & SDVO_DETECTED ? "" : "not ";
+       char *gang = val & SDVOC_GANG_MODE ? ", gang mode" : "";
+       char sdvoextra[20];
+
+       if (IS_915(devid)) {
+               sprintf(sdvoextra, ", SDVO mult %d",
+                       (int)((val & SDVO_PORT_MULTIPLY_MASK) >>
+                             SDVO_PORT_MULTIPLY_SHIFT) + 1);
+       } else {
+               sdvoextra[0] = '\0';
+       }
+
+       asprintf(result, "%s, pipe %c, stall %s, %sdetected%s%s",
+                        enable, pipe, stall, detected, sdvoextra, gang);
+}
+
+DEBUGSTRING(i830_debug_dspclk_gate_d)
+{
+       char *DPUNIT_B = val & DPUNIT_B_CLOCK_GATE_DISABLE ? " DPUNIT_B" : "";
+       char *VSUNIT = val & VSUNIT_CLOCK_GATE_DISABLE ? " VSUNIT" : "";
+       char *VRHUNIT = val & VRHUNIT_CLOCK_GATE_DISABLE ? " VRHUNIT" : "";
+       char *VRDUNIT = val & VRDUNIT_CLOCK_GATE_DISABLE ? " VRDUNIT" : "";
+       char *AUDUNIT = val & AUDUNIT_CLOCK_GATE_DISABLE ? " AUDUNIT" : "";
+       char *DPUNIT_A = val & DPUNIT_A_CLOCK_GATE_DISABLE ? " DPUNIT_A" : "";
+       char *DPCUNIT = val & DPCUNIT_CLOCK_GATE_DISABLE ? " DPCUNIT" : "";
+       char *TVRUNIT = val & TVRUNIT_CLOCK_GATE_DISABLE ? " TVRUNIT" : "";
+       char *TVCUNIT = val & TVCUNIT_CLOCK_GATE_DISABLE ? " TVCUNIT" : "";
+       char *TVFUNIT = val & TVFUNIT_CLOCK_GATE_DISABLE ? " TVFUNIT" : "";
+       char *TVEUNIT = val & TVEUNIT_CLOCK_GATE_DISABLE ? " TVEUNIT" : "";
+       char *DVSUNIT = val & DVSUNIT_CLOCK_GATE_DISABLE ? " DVSUNIT" : "";
+       char *DSSUNIT = val & DSSUNIT_CLOCK_GATE_DISABLE ? " DSSUNIT" : "";
+       char *DDBUNIT = val & DDBUNIT_CLOCK_GATE_DISABLE ? " DDBUNIT" : "";
+       char *DPRUNIT = val & DPRUNIT_CLOCK_GATE_DISABLE ? " DPRUNIT" : "";
+       char *DPFUNIT = val & DPFUNIT_CLOCK_GATE_DISABLE ? " DPFUNIT" : "";
+       char *DPBMUNIT = val & DPBMUNIT_CLOCK_GATE_DISABLE ? " DPBMUNIT" : "";
+       char *DPLSUNIT = val & DPLSUNIT_CLOCK_GATE_DISABLE ? " DPLSUNIT" : "";
+       char *DPLUNIT = val & DPLUNIT_CLOCK_GATE_DISABLE ? " DPLUNIT" : "";
+       char *DPOUNIT = val & DPOUNIT_CLOCK_GATE_DISABLE ? " DPOUNIT" : "";
+       char *DPBUNIT = val & DPBUNIT_CLOCK_GATE_DISABLE ? " DPBUNIT" : "";
+       char *DCUNIT = val & DCUNIT_CLOCK_GATE_DISABLE ? " DCUNIT" : "";
+       char *DPUNIT = val & DPUNIT_CLOCK_GATE_DISABLE ? " DPUNIT" : "";
+       char *VRUNIT = val & VRUNIT_CLOCK_GATE_DISABLE ? " VRUNIT" : "";
+       char *OVHUNIT = val & OVHUNIT_CLOCK_GATE_DISABLE ? " OVHUNIT" : "";
+       char *DPIOUNIT = val & DPIOUNIT_CLOCK_GATE_DISABLE ? " DPIOUNIT" : "";
+       char *OVFUNIT = val & OVFUNIT_CLOCK_GATE_DISABLE ? " OVFUNIT" : "";
+       char *OVBUNIT = val & OVBUNIT_CLOCK_GATE_DISABLE ? " OVBUNIT" : "";
+       char *OVRUNIT = val & OVRUNIT_CLOCK_GATE_DISABLE ? " OVRUNIT" : "";
+       char *OVCUNIT = val & OVCUNIT_CLOCK_GATE_DISABLE ? " OVCUNIT" : "";
+       char *OVUUNIT = val & OVUUNIT_CLOCK_GATE_DISABLE ? " OVUUNIT" : "";
+       char *OVLUNIT = val & OVLUNIT_CLOCK_GATE_DISABLE ? " OVLUNIT" : "";
+
+       asprintf(result,
+                "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, DPIOUNIT, OVFUNIT, OVBUNIT,
+                OVRUNIT, OVCUNIT, OVUUNIT, OVLUNIT);
+}
+
+DEBUGSTRING(i810_debug_915_fence)
+{
+       char *enable = (val & 1) ? " enabled" : "disabled";
+       char format = (val & 1 << 12) ? 'Y' : 'X';
+       int pitch = 1 << (((val & 0x70) >> 4) - 1);
+       unsigned int offset = val & 0x0ff00000;
+       int size = (1024 * 1024) << (((val & 0x700) >> 8) - 1);
+
+       if (IS_965(devid) || (IS_915(devid) && reg >= FENCE_NEW))
+               return;
+
+       if (format == 'X')
+               pitch *= 4;
+
+       asprintf(result, "%s, %c tiled, %4d pitch, 0x%08x - 0x%08x (%dkb)",
+                enable, format, pitch, offset, offset + size,
+                size / 1024);
+}
+
+DEBUGSTRING(i810_debug_965_fence_start)
+{
+       char *enable = (val & FENCE_VALID) ? " enabled" : "disabled";
+       char format = (val & I965_FENCE_Y_MAJOR) ? 'Y' : 'X';
+       int pitch = ((val & 0xffc) >> 2) * 128;
+       unsigned int offset = val & 0xfffff000;
+
+       if (!IS_965(devid))
+               return;
+
+       asprintf(result, "%s, %c tile walk, %4d pitch, 0x%08x start",
+                enable, format, pitch, offset);
+}
+
+DEBUGSTRING(i810_debug_965_fence_end)
+{
+       unsigned int end = val & 0xfffff000;
+
+       if (!IS_965(devid))
+               return;
+
+       asprintf(result, "                                   0x%08x end", end);
+}
+
+#define DEFINEREG(reg) \
+       { reg, #reg, NULL, 0 }
+#define DEFINEREG_16BIT(reg) \
+       { reg, #reg, i830_16bit_func, 0 }
+#define DEFINEREG2(reg, func) \
+       { reg, #reg, func, 0 }
+
+struct reg_debug {
+       int reg;
+       char *name;
+       void (*debug_output) (char **result, int reg, uint32_t val);
+       uint32_t val;
+};
+
+static struct reg_debug intel_debug_regs[] = {
+       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(VCLK_DIVISOR_VGA0, i830_debug_fp),
+       DEFINEREG2(VCLK_DIVISOR_VGA1, i830_debug_fp),
+       DEFINEREG2(VCLK_POST_DIV, i830_debug_vga_pd),
+       DEFINEREG2(DPLL_TEST, i830_debug_dpll_test),
+       DEFINEREG(CACHE_MODE_0),
+       DEFINEREG(D_STATE),
+       DEFINEREG2(DSPCLK_GATE_D, i830_debug_dspclk_gate_d),
+       DEFINEREG(RENCLK_GATE_D1),
+       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(DSPABASE),
+       DEFINEREG(DSPASURF),
+       DEFINEREG(DSPATILEOFF),
+       DEFINEREG2(PIPEACONF, i830_debug_pipeconf),
+       DEFINEREG2(PIPEASRC, i830_debug_yxminus1),
+       DEFINEREG2(PIPEASTAT, i830_debug_pipestat),
+       DEFINEREG(PIPEA_GMCH_DATA_M),
+       DEFINEREG(PIPEA_GMCH_DATA_N),
+       DEFINEREG(PIPEA_DP_LINK_M),
+       DEFINEREG(PIPEA_DP_LINK_N),
+       DEFINEREG(CURSOR_A_BASE),
+       DEFINEREG(CURSOR_A_CONTROL),
+       DEFINEREG(CURSOR_A_POSITION),
+
+       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(DSPBBASE),
+       DEFINEREG(DSPBSURF),
+       DEFINEREG(DSPBTILEOFF),
+       DEFINEREG2(PIPEBCONF, i830_debug_pipeconf),
+       DEFINEREG2(PIPEBSRC, i830_debug_yxminus1),
+       DEFINEREG2(PIPEBSTAT, i830_debug_pipestat),
+       DEFINEREG(PIPEB_GMCH_DATA_M),
+       DEFINEREG(PIPEB_GMCH_DATA_N),
+       DEFINEREG(PIPEB_DP_LINK_M),
+       DEFINEREG(PIPEB_DP_LINK_N),
+       DEFINEREG(CURSOR_B_BASE),
+       DEFINEREG(CURSOR_B_CONTROL),
+       DEFINEREG(CURSOR_B_POSITION),
+
+       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(VCLK_DIVISOR_VGA0),
+       DEFINEREG(VCLK_DIVISOR_VGA1),
+       DEFINEREG(VCLK_POST_DIV),
+       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),
+
+       DEFINEREG(AUD_CONFIG),
+       DEFINEREG(AUD_HDMIW_STATUS),
+       DEFINEREG(AUD_CONV_CHCNT),
+       DEFINEREG(VIDEO_DIP_CTL),
+       DEFINEREG(AUD_PINW_CNTR),
+       DEFINEREG(AUD_CNTL_ST),
+       DEFINEREG(AUD_PIN_CAP),
+       DEFINEREG(AUD_PINW_CAP),
+       DEFINEREG(AUD_PINW_UNSOLRESP),
+       DEFINEREG(AUD_OUT_DIG_CNVT),
+       DEFINEREG(AUD_OUT_CWCAP),
+       DEFINEREG(AUD_GRP_CAP),
+
+#define DEFINEFENCE_915(i) \
+       { FENCE+i*4, "FENCE  " #i, i810_debug_915_fence, 0 }
+#define DEFINEFENCE_945(i)                                             \
+       { FENCE_NEW+(i - 8) * 4, "FENCE  " #i, i810_debug_915_fence, 0 }
+
+       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(i) \
+       { FENCE_NEW+i*8, "FENCE START " #i, i810_debug_965_fence_start, 0 }, \
+       { FENCE_NEW+i*8+4, "FENCE END " #i, i810_debug_965_fence_end, 0 }
+
+       DEFINEFENCE_965(0),
+       DEFINEFENCE_965(1),
+       DEFINEFENCE_965(2),
+       DEFINEFENCE_965(3),
+       DEFINEFENCE_965(4),
+       DEFINEFENCE_965(5),
+       DEFINEFENCE_965(6),
+       DEFINEFENCE_965(7),
+       DEFINEFENCE_965(8),
+       DEFINEFENCE_965(9),
+       DEFINEFENCE_965(10),
+       DEFINEFENCE_965(11),
+       DEFINEFENCE_965(12),
+       DEFINEFENCE_965(13),
+       DEFINEFENCE_965(14),
+       DEFINEFENCE_965(15),
+};
+
+DEBUGSTRING(ironlake_debug_rr_hw_ctl)
+{
+       asprintf(result, "low %d, high %d", val & RR_HW_LOW_POWER_FRAMES_MASK,
+                (val & RR_HW_HIGH_POWER_FRAMES_MASK) >> 8);
+}
+
+DEBUGSTRING(ironlake_debug_m_tu)
+{
+       asprintf(result, "TU %d, val 0x%x %d", (val >> 25) + 1, val & 0xffffff,
+                val & 0xffffff);
+}
+
+DEBUGSTRING(ironlake_debug_n)
+{
+       asprintf(result, "val 0x%x %d", val & 0xffffff, val & 0xffffff);
+}
+
+DEBUGSTRING(ironlake_debug_fdi_tx_ctl)
+{
+       char *train = NULL, *voltage = NULL, *pre_emphasis = NULL, *portw =
+           NULL;
+
+       switch (val & FDI_LINK_TRAIN_NONE) {
+       case FDI_LINK_TRAIN_PATTERN_1:
+               train = "pattern_1";
+               break;
+       case FDI_LINK_TRAIN_PATTERN_2:
+               train = "pattern_2";
+               break;
+       case FDI_LINK_TRAIN_PATTERN_IDLE:
+               train = "pattern_idle";
+               break;
+       case FDI_LINK_TRAIN_NONE:
+               train = "not train";
+               break;
+       }
+
+       switch (val & (7 << 25)) {
+       case FDI_LINK_TRAIN_VOLTAGE_0_4V:
+               voltage = "0.4V";
+               break;
+       case FDI_LINK_TRAIN_VOLTAGE_0_6V:
+               voltage = "0.6V";
+               break;
+       case FDI_LINK_TRAIN_VOLTAGE_0_8V:
+               voltage = "0.8V";
+               break;
+       case FDI_LINK_TRAIN_VOLTAGE_1_2V:
+               voltage = "1.2V";
+               break;
+       default:
+               voltage = "reserved";
+       }
+
+       switch (val & (7 << 22)) {
+       case FDI_LINK_TRAIN_PRE_EMPHASIS_NONE:
+               pre_emphasis = "none";
+               break;
+       case FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X:
+               pre_emphasis = "1.5x";
+               break;
+       case FDI_LINK_TRAIN_PRE_EMPHASIS_2X:
+               pre_emphasis = "2x";
+               break;
+       case FDI_LINK_TRAIN_PRE_EMPHASIS_3X:
+               pre_emphasis = "3x";
+               break;
+       default:
+               pre_emphasis = "reserved";
+       }
+
+       switch (val & (7 << 19)) {
+       case FDI_DP_PORT_WIDTH_X1:
+               portw = "X1";
+               break;
+       case FDI_DP_PORT_WIDTH_X2:
+               portw = "X2";
+               break;
+       case FDI_DP_PORT_WIDTH_X3:
+               portw = "X3";
+               break;
+       case FDI_DP_PORT_WIDTH_X4:
+               portw = "X4";
+               break;
+       }
+
+       asprintf(result, "%s, train pattern %s, voltage swing %s,"
+                "pre-emphasis %s, port width %s, enhanced framing %s, FDI PLL %s, scrambing %s, master mode %s",
+                val & FDI_TX_ENABLE ? "enable" : "disable",
+                train, voltage, pre_emphasis, portw,
+                val & FDI_TX_ENHANCE_FRAME_ENABLE ? "enable" :
+                "disable",
+                val & FDI_TX_PLL_ENABLE ? "enable" : "disable",
+                val & (1 << 7) ? "disable" : "enable",
+                val & (1 << 0) ? "enable" : "disable");
+}
+
+DEBUGSTRING(ironlake_debug_fdi_rx_ctl)
+{
+       char *train = NULL, *portw = NULL, *bpc = NULL;
+
+       switch (val & FDI_LINK_TRAIN_NONE) {
+       case FDI_LINK_TRAIN_PATTERN_1:
+               train = "pattern_1";
+               break;
+       case FDI_LINK_TRAIN_PATTERN_2:
+               train = "pattern_2";
+               break;
+       case FDI_LINK_TRAIN_PATTERN_IDLE:
+               train = "pattern_idle";
+               break;
+       case FDI_LINK_TRAIN_NONE:
+               train = "not train";
+               break;
+       }
+
+       switch (val & (7 << 19)) {
+       case FDI_DP_PORT_WIDTH_X1:
+               portw = "X1";
+               break;
+       case FDI_DP_PORT_WIDTH_X2:
+               portw = "X2";
+               break;
+       case FDI_DP_PORT_WIDTH_X3:
+               portw = "X3";
+               break;
+       case FDI_DP_PORT_WIDTH_X4:
+               portw = "X4";
+               break;
+       }
+
+       switch (val & (7 << 16)) {
+       case FDI_8BPC:
+               bpc = "8bpc";
+               break;
+       case FDI_10BPC:
+               bpc = "10bpc";
+               break;
+       case FDI_6BPC:
+               bpc = "6bpc";
+               break;
+       case FDI_12BPC:
+               bpc = "12bpc";
+               break;
+       }
+
+       asprintf(result, "%s, train pattern %s, port width %s, %s,"
+                "link_reverse_strap_overwrite %s, dmi_link_reverse %s, FDI PLL %s,"
+                "FS ecc %s, FE ecc %s, FS err report %s, FE err report %s,"
+                "scrambing %s, enhanced framing %s, %s",
+                val & FDI_RX_ENABLE ? "enable" : "disable",
+                train, portw, bpc,
+                val & FDI_LINK_REVERSE_OVERWRITE ? "yes" : "no",
+                val & FDI_DMI_LINK_REVERSE_MASK ? "yes" : "no",
+                val & FDI_RX_PLL_ENABLE ? "enable" : "disable",
+                val & FDI_FS_ERR_CORRECT_ENABLE ? "enable" : "disable",
+                val & FDI_FE_ERR_CORRECT_ENABLE ? "enable" : "disable",
+                val & FDI_FS_ERR_REPORT_ENABLE ? "enable" : "disable",
+                val & FDI_FE_ERR_REPORT_ENABLE ? "enable" : "disable",
+                val & (1 << 7) ? "disable" : "enable",
+                val & FDI_RX_ENHANCE_FRAME_ENABLE ? "enable" :
+                "disable", val & FDI_SEL_PCDCLK ? "PCDClk" : "RawClk");
+}
+
+DEBUGSTRING(ironlake_debug_dspstride)
+{
+       asprintf(result, "%d", val >> 6);
+}
+
+DEBUGSTRING(ironlake_debug_pch_dpll)
+{
+       char *enable = val & DPLL_VCO_ENABLE ? "enable" : "disable";
+       char *highspeed = val & DPLL_DVO_HIGH_SPEED ? "yes" : "no";
+       char *mode = NULL;
+       char *p2 = NULL;
+       int fpa0_p1, fpa1_p1;
+       char *refclk = NULL;
+       int sdvo_mul;
+
+       if ((val & DPLLB_MODE_LVDS) == DPLLB_MODE_LVDS) {
+               mode = "LVDS";
+               if (val & DPLLB_LVDS_P2_CLOCK_DIV_7)
+                       p2 = "Div 7";
+               else
+                       p2 = "Div 14";
+       } else if ((val & DPLLB_MODE_LVDS) == DPLLB_MODE_DAC_SERIAL) {
+               mode = "Non-LVDS";
+               if (val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5)
+                       p2 = "Div 5";
+               else
+                       p2 = "Div 10";
+       }
+       fpa0_p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >> 16);
+       fpa1_p1 = ffs((val & DPLL_FPA1_P1_POST_DIV_MASK));
+
+       switch (val & PLL_REF_INPUT_MASK) {
+       case PLL_REF_INPUT_DREFCLK:
+               refclk = "default 120Mhz";
+               break;
+       case PLL_REF_INPUT_SUPER_SSC:
+               refclk = "SuperSSC 120Mhz";
+               break;
+       case PLL_REF_INPUT_TVCLKINBC:
+               refclk = "SDVO TVClkIn";
+               break;
+       case PLLB_REF_INPUT_SPREADSPECTRUMIN:
+               refclk = "SSC";
+               break;
+       case PLL_REF_INPUT_DMICLK:
+               refclk = "DMI RefCLK";
+               break;
+       }
+
+       sdvo_mul = ((val & PLL_REF_SDVO_HDMI_MULTIPLIER_MASK) >> 9) + 1;
+
+       asprintf(result, "%s, sdvo high speed %s, mode %s, p2 %s, "
+                "FPA0 P1 %d, FPA1 P1 %d, refclk %s, sdvo/hdmi mul %d",
+                enable, highspeed, mode, p2, fpa0_p1, fpa1_p1, refclk,
+                sdvo_mul);
+}
+
+DEBUGSTRING(ironlake_debug_dref_ctl)
+{
+       char *cpu_source;
+       char *ssc_source = val & DREF_SSC_SOURCE_ENABLE ? "enable" : "disable";
+       char *nonspread_source =
+           val & DREF_NONSPREAD_SOURCE_ENABLE ? "enable" : "disable";
+       char *superspread_source =
+           val & DREF_SUPERSPREAD_SOURCE_ENABLE ? "enable" : "disable";
+       char *ssc4_mode =
+           val & DREF_SSC4_CENTERSPREAD ? "centerspread" : "downspread";
+       char *ssc1 = val & DREF_SSC1_ENABLE ? "enable" : "disable";
+       char *ssc4 = val & DREF_SSC4_ENABLE ? "enable" : "disable";
+
+       switch (val & DREF_CPU_SOURCE_OUTPUT_NONSPREAD) {
+       case DREF_CPU_SOURCE_OUTPUT_DISABLE:
+               cpu_source = "disable";
+               break;
+       case DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD:
+               cpu_source = "downspread";
+               break;
+       case DREF_CPU_SOURCE_OUTPUT_NONSPREAD:
+               cpu_source = "nonspread";
+               break;
+       default:
+               cpu_source = "reserved";
+       }
+       asprintf(result, "cpu source %s, ssc_source %s, nonspread_source %s, "
+                "superspread_source %s, ssc4_mode %s, ssc1 %s, ssc4 %s",
+                cpu_source, ssc_source, nonspread_source,
+                superspread_source, ssc4_mode, ssc1, ssc4);
+}
+
+DEBUGSTRING(ironlake_debug_rawclk_freq)
+{
+       char *tp1 = NULL, *tp2 = NULL;
+
+       switch (val & FDL_TP1_TIMER_MASK) {
+       case 0:
+               tp1 = "0.5us";
+               break;
+       case (1 << 12):
+               tp1 = "1.0us";
+               break;
+       case (2 << 12):
+               tp1 = "2.0us";
+               break;
+       case (3 << 12):
+               tp1 = "4.0us";
+               break;
+       }
+       switch (val & FDL_TP2_TIMER_MASK) {
+       case 0:
+               tp2 = "1.5us";
+               break;
+       case (1 << 10):
+               tp2 = "3.0us";
+               break;
+       case (2 << 10):
+               tp2 = "6.0us";
+               break;
+       case (3 << 10):
+               tp2 = "12.0us";
+               break;
+       }
+       asprintf(result, "FDL_TP1 timer %s, FDL_TP2 timer %s, freq %d",
+                tp1, tp2, val & RAWCLK_FREQ_MASK);
+
+}
+
+DEBUGSTRING(ironlake_debug_fdi_rx_misc)
+{
+       asprintf(result, "FDI Delay %d", val & ((1 << 13) - 1));
+}
+
+DEBUGSTRING(ironlake_debug_transconf)
+{
+       asprintf(result, "%s, %s",
+                val & TRANS_ENABLE ? "enable" : "disable",
+                val & TRANS_STATE_ENABLE ? "active" : "inactive");
+}
+
+DEBUGSTRING(ironlake_debug_panel_fitting)
+{
+       char *vadapt = NULL, *filter_sel = NULL;
+
+       switch (val & (3 << 25)) {
+       case 0:
+               vadapt = "least";
+               break;
+       case (1 << 25):
+               vadapt = "moderate";
+               break;
+       case (2 << 25):
+               vadapt = "reserved";
+               break;
+       case (3 << 25):
+               vadapt = "most";
+               break;
+       }
+
+       switch (val & (3 << 23)) {
+       case 0:
+               filter_sel = "programmed";
+               break;
+       case (1 << 25):
+               filter_sel = "hardcoded";
+               break;
+       case (2 << 25):
+               filter_sel = "edge_enhance";
+               break;
+       case (3 << 25):
+               filter_sel = "edge_soften";
+               break;
+       }
+
+       asprintf(result,
+                "%s, auto_scale %s, auto_scale_cal %s, v_filter %s, vadapt %s, mode %s, filter_sel %s,"
+                "chroma pre-filter %s, vert3tap %s, v_inter_invert %s",
+                val & PF_ENABLE ? "enable" : "disable",
+                val & (1 << 30) ? "no" : "yes", val & (1 << 29) ? "yes" : "no",
+                val & (1 << 28) ? "bypass" : "enable",
+                val & (1 << 27) ? "enable" : "disable", vadapt, filter_sel,
+                val & (1 << 22) ? "enable" : "disable",
+                val & (1 << 21) ? "force" : "auto",
+                val & (1 << 20) ? "field 0" : "field 1");
+}
+
+DEBUGSTRING(ironlake_debug_pf_win)
+{
+       int a, b;
+
+       a = (val >> 16) & 0x1fff;
+       b = val & 0xfff;
+
+       asprintf(result, "%d, %d", a, b);
+}
+
+static struct reg_debug ironlake_debug_regs[] = {
+       DEFINEREG2(CPU_VGACNTRL, i830_debug_vgacntrl),
+       DEFINEREG(DIGITAL_PORT_HOTPLUG_CNTRL),
+
+       DEFINEREG2(RR_HW_CTL, ironlake_debug_rr_hw_ctl),
+
+       DEFINEREG(FDI_PLL_BIOS_0),
+       DEFINEREG(FDI_PLL_BIOS_1),
+       DEFINEREG(FDI_PLL_BIOS_2),
+
+       DEFINEREG(DISPLAY_PORT_PLL_BIOS_0),
+       DEFINEREG(DISPLAY_PORT_PLL_BIOS_1),
+       DEFINEREG(DISPLAY_PORT_PLL_BIOS_2),
+
+       DEFINEREG(FDI_PLL_FREQ_CTL),
+
+       DEFINEREG2(PIPEACONF, i830_debug_pipeconf),
+
+       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(VSYNCSHIFT_A),
+       DEFINEREG2(PIPEASRC, i830_debug_yxminus1),
+
+       DEFINEREG2(PIPEA_DATA_M1, ironlake_debug_m_tu),
+       DEFINEREG2(PIPEA_DATA_N1, ironlake_debug_n),
+       DEFINEREG2(PIPEA_DATA_M2, ironlake_debug_m_tu),
+       DEFINEREG2(PIPEA_DATA_N2, ironlake_debug_n),
+
+       DEFINEREG2(PIPEA_LINK_M1, ironlake_debug_n),
+       DEFINEREG2(PIPEA_LINK_N1, ironlake_debug_n),
+       DEFINEREG2(PIPEA_LINK_M2, ironlake_debug_n),
+       DEFINEREG2(PIPEA_LINK_N2, ironlake_debug_n),
+
+       DEFINEREG2(DSPACNTR, i830_debug_dspcntr),
+       DEFINEREG(DSPABASE),
+       DEFINEREG2(DSPASTRIDE, ironlake_debug_dspstride),
+       DEFINEREG(DSPASURF),
+       DEFINEREG2(DSPATILEOFF, i830_debug_xy),
+
+       DEFINEREG2(PIPEBCONF, i830_debug_pipeconf),
+
+       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(VSYNCSHIFT_B),
+
+       DEFINEREG2(DSPBCNTR, i830_debug_dspcntr),
+       DEFINEREG(DSPBBASE),
+       DEFINEREG2(DSPBSTRIDE, ironlake_debug_dspstride),
+       DEFINEREG(DSPBSURF),
+       DEFINEREG2(DSPBTILEOFF, i830_debug_xy),
+
+       DEFINEREG2(PIPEBSRC, i830_debug_yxminus1),
+
+       DEFINEREG2(PIPEB_DATA_M1, ironlake_debug_m_tu),
+       DEFINEREG2(PIPEB_DATA_N1, ironlake_debug_n),
+       DEFINEREG2(PIPEB_DATA_M2, ironlake_debug_m_tu),
+       DEFINEREG2(PIPEB_DATA_N2, ironlake_debug_n),
+
+       DEFINEREG2(PIPEB_LINK_M1, ironlake_debug_n),
+       DEFINEREG2(PIPEB_LINK_N1, ironlake_debug_n),
+       DEFINEREG2(PIPEB_LINK_M2, ironlake_debug_n),
+       DEFINEREG2(PIPEB_LINK_N2, ironlake_debug_n),
+
+       DEFINEREG2(PFA_CTL_1, ironlake_debug_panel_fitting),
+       DEFINEREG2(PFB_CTL_1, ironlake_debug_panel_fitting),
+       DEFINEREG2(PFA_WIN_POS, ironlake_debug_pf_win),
+       DEFINEREG2(PFB_WIN_POS, ironlake_debug_pf_win),
+       DEFINEREG2(PFA_WIN_SIZE, ironlake_debug_pf_win),
+       DEFINEREG2(PFB_WIN_SIZE, ironlake_debug_pf_win),
+
+       /* PCH */
+
+       DEFINEREG2(PCH_DREF_CONTROL, ironlake_debug_dref_ctl),
+       DEFINEREG2(PCH_RAWCLK_FREQ, ironlake_debug_rawclk_freq),
+       DEFINEREG(PCH_DPLL_TMR_CFG),
+       DEFINEREG(PCH_SSC4_PARMS),
+       DEFINEREG(PCH_SSC4_AUX_PARMS),
+
+       DEFINEREG2(PCH_DPLL_A, ironlake_debug_pch_dpll),
+       DEFINEREG2(PCH_DPLL_B, ironlake_debug_pch_dpll),
+       DEFINEREG2(PCH_FPA0, i830_debug_fp),
+       DEFINEREG2(PCH_FPA1, i830_debug_fp),
+       DEFINEREG2(PCH_FPB0, i830_debug_fp),
+       DEFINEREG2(PCH_FPB1, i830_debug_fp),
+
+       DEFINEREG2(TRANS_HTOTAL_A, i830_debug_hvtotal),
+       DEFINEREG2(TRANS_HBLANK_A, i830_debug_hvsyncblank),
+       DEFINEREG2(TRANS_HSYNC_A, i830_debug_hvsyncblank),
+       DEFINEREG2(TRANS_VTOTAL_A, i830_debug_hvtotal),
+       DEFINEREG2(TRANS_VBLANK_A, i830_debug_hvsyncblank),
+       DEFINEREG2(TRANS_VSYNC_A, i830_debug_hvsyncblank),
+
+       DEFINEREG2(TRANSA_DATA_M1, ironlake_debug_m_tu),
+       DEFINEREG2(TRANSA_DATA_N1, ironlake_debug_n),
+       DEFINEREG2(TRANSA_DATA_M2, ironlake_debug_m_tu),
+       DEFINEREG2(TRANSA_DATA_N2, ironlake_debug_n),
+       DEFINEREG2(TRANSA_DP_LINK_M1, ironlake_debug_n),
+       DEFINEREG2(TRANSA_DP_LINK_N1, ironlake_debug_n),
+       DEFINEREG2(TRANSA_DP_LINK_M2, ironlake_debug_n),
+       DEFINEREG2(TRANSA_DP_LINK_N2, ironlake_debug_n),
+
+       DEFINEREG2(TRANS_HTOTAL_B, i830_debug_hvtotal),
+       DEFINEREG2(TRANS_HBLANK_B, i830_debug_hvsyncblank),
+       DEFINEREG2(TRANS_HSYNC_B, i830_debug_hvsyncblank),
+       DEFINEREG2(TRANS_VTOTAL_B, i830_debug_hvtotal),
+       DEFINEREG2(TRANS_VBLANK_B, i830_debug_hvsyncblank),
+       DEFINEREG2(TRANS_VSYNC_B, i830_debug_hvsyncblank),
+
+       DEFINEREG2(TRANSB_DATA_M1, ironlake_debug_m_tu),
+       DEFINEREG2(TRANSB_DATA_N1, ironlake_debug_n),
+       DEFINEREG2(TRANSB_DATA_M2, ironlake_debug_m_tu),
+       DEFINEREG2(TRANSB_DATA_N2, ironlake_debug_n),
+       DEFINEREG2(TRANSB_DP_LINK_M1, ironlake_debug_n),
+       DEFINEREG2(TRANSB_DP_LINK_N1, ironlake_debug_n),
+       DEFINEREG2(TRANSB_DP_LINK_M2, ironlake_debug_n),
+       DEFINEREG2(TRANSB_DP_LINK_N2, ironlake_debug_n),
+
+       DEFINEREG2(TRANSACONF, ironlake_debug_transconf),
+       DEFINEREG2(TRANSBCONF, ironlake_debug_transconf),
+
+       DEFINEREG2(FDI_TXA_CTL, ironlake_debug_fdi_tx_ctl),
+       DEFINEREG2(FDI_TXB_CTL, ironlake_debug_fdi_tx_ctl),
+       DEFINEREG2(FDI_RXA_CTL, ironlake_debug_fdi_rx_ctl),
+       DEFINEREG2(FDI_RXB_CTL, ironlake_debug_fdi_rx_ctl),
+
+       DEFINEREG2(FDI_RXA_MISC, ironlake_debug_fdi_rx_misc),
+       DEFINEREG2(FDI_RXB_MISC, ironlake_debug_fdi_rx_misc),
+       DEFINEREG(FDI_RXA_TUSIZE1),
+       DEFINEREG(FDI_RXA_TUSIZE2),
+       DEFINEREG(FDI_RXB_TUSIZE1),
+       DEFINEREG(FDI_RXB_TUSIZE2),
+
+       DEFINEREG(FDI_PLL_CTL_1),
+       DEFINEREG(FDI_PLL_CTL_2),
+
+       DEFINEREG(FDI_RXA_IIR),
+       DEFINEREG(FDI_RXA_IMR),
+       DEFINEREG(FDI_RXB_IIR),
+       DEFINEREG(FDI_RXB_IMR),
+
+       DEFINEREG2(PCH_ADPA, i830_debug_adpa),
+       DEFINEREG(HDMIB),
+       DEFINEREG(HDMIC),
+       DEFINEREG(HDMID),
+       DEFINEREG2(PCH_LVDS, i830_debug_lvds),
+};
+
+static void
+ironlake_dump_regs(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ironlake_debug_regs); i++) {
+               uint32_t val = INREG(ironlake_debug_regs[i].reg);
+
+               if (ironlake_debug_regs[i].debug_output != NULL) {
+                       char *debug = NULL;
+                       ironlake_debug_regs[i].debug_output(&debug,
+                                                         ironlake_debug_regs
+                                                         [i].reg,
+                                                         val);
+                       if (debug != NULL) {
+                               printf("%20.20s: 0x%08x (%s)\n",
+                                      ironlake_debug_regs[i].name,
+                                      (unsigned int)val, debug);
+                               free(debug);
+                       }
+               } else {
+                       printf("%20.20s: 0x%08x\n", ironlake_debug_regs[i].name,
+                              (unsigned int)val);
+               }
+       }
+}
+
+static void
+intel_dump_regs(void)
+{
+       int i;
+       int fp, dpll;
+       int pipe;
+       int n, m1, m2, m, p1, p2;
+       int ref;
+       int dot;
+       int phase;
+#if 0
+       int msr;
+       int crt;
+#endif
+
+       for (i = 0; i < ARRAY_SIZE(intel_debug_regs); i++) {
+               uint32_t val = INREG(intel_debug_regs[i].reg);
+
+               if (intel_debug_regs[i].debug_output != NULL) {
+                       char *debug = NULL;
+                       
+                       intel_debug_regs[i].debug_output(&debug,
+                                                        intel_debug_regs[i].reg,
+                                                        val);
+                       if (debug != NULL) {
+                               printf("%20.20s: 0x%08x (%s)\n",
+                                      intel_debug_regs[i].name,
+                                      (unsigned int)val, debug);
+                               free(debug);
+                       }
+               } else {
+                       printf("%20.20s: 0x%08x\n",
+                              intel_debug_regs[i].name,
+                              (unsigned int)val);
+               }
+       }
+#if 0
+       i830DumpIndexed(pScrn, "SR", 0x3c4, 0x3c5, 0, 7);
+       msr = INREG8(0x3cc);
+       printf("%20.20s: 0x%02x\n",
+                  "MSR", (unsigned int)msr);
+
+       i830DumpAR(pScrn);
+       if (msr & 1)
+               crt = 0x3d0;
+       else
+               crt = 0x3b0;
+       i830DumpIndexed(pScrn, "CR", crt + 4, crt + 5, 0, 0x24);
+#endif
+       for (pipe = 0; pipe <= 1; pipe++) {
+               fp = INREG(pipe == 0 ? FPA0 : FPB0);
+               dpll = INREG(pipe == 0 ? DPLL_A : DPLL_B);
+               if (IS_9XX(devid)) {
+                       uint32_t lvds = INREG(LVDS);
+                       if ((lvds & LVDS_PORT_EN) &&
+                           (lvds & LVDS_PIPEB_SELECT) == (pipe << 30)) {
+                               if ((lvds & LVDS_CLKB_POWER_MASK) ==
+                                   LVDS_CLKB_POWER_UP)
+                                       p2 = 7;
+                               else
+                                       p2 = 14;
+                       } else {
+                               switch ((dpll >> 24) & 0x3) {
+                               case 0:
+                                       p2 = 10;
+                                       break;
+                               case 1:
+                                       p2 = 5;
+                                       break;
+                               default:
+                                       p2 = 1;
+                                       printf("p2 out of range\n");
+                                       break;
+                               }
+                       }
+                       if (IS_IGD(devid))
+                               i = (dpll >> DPLL_FPA01_P1_POST_DIV_SHIFT_IGD) &
+                                   0x1ff;
+                       else
+                               i = (dpll >> DPLL_FPA01_P1_POST_DIV_SHIFT) &
+                                   0xff;
+                       switch (i) {
+                       case 1:
+                               p1 = 1;
+                               break;
+                       case 2:
+                               p1 = 2;
+                               break;
+                       case 4:
+                               p1 = 3;
+                               break;
+                       case 8:
+                               p1 = 4;
+                               break;
+                       case 16:
+                               p1 = 5;
+                               break;
+                       case 32:
+                               p1 = 6;
+                               break;
+                       case 64:
+                               p1 = 7;
+                               break;
+                       case 128:
+                               p1 = 8;
+                               break;
+                       case 256:
+                               if (IS_IGD(devid)) {
+                                       p1 = 9;
+                                       break;
+                               }       /* fallback */
+                       default:
+                               p1 = 1;
+                               printf("p1 out of range\n");
+                               break;
+                       }
+
+                       switch ((dpll >> 13) & 0x3) {
+                       case 0:
+                               ref = 96000;
+                               break;
+                       case 3:
+                               ref = 100000;
+                               break;
+                       default:
+                               ref = 0;
+                               printf("ref out of range\n");
+                               break;
+                       }
+               } else {
+                       uint32_t lvds = INREG(LVDS);
+                       if (devid == PCI_CHIP_I855_GM &&
+                           (lvds & LVDS_PORT_EN) &&
+                           (lvds & LVDS_PIPEB_SELECT) == (pipe << 30)) {
+                               if ((lvds & LVDS_CLKB_POWER_MASK) ==
+                                   LVDS_CLKB_POWER_UP)
+                                       p2 = 7;
+                               else
+                                       p2 = 14;
+                               switch ((dpll >> 16) & 0x3f) {
+                               case 0x01:
+                                       p1 = 1;
+                                       break;
+                               case 0x02:
+                                       p1 = 2;
+                                       break;
+                               case 0x04:
+                                       p1 = 3;
+                                       break;
+                               case 0x08:
+                                       p1 = 4;
+                                       break;
+                               case 0x10:
+                                       p1 = 5;
+                                       break;
+                               case 0x20:
+                                       p1 = 6;
+                                       break;
+                               default:
+                                       p1 = 1;
+                                       printf("LVDS P1 0x%x invalid encoding\n",
+                                              (dpll >> 16) & 0x3f);
+                                       break;
+                               }
+                       } else {
+                               if (dpll & (1 << 23))
+                                       p2 = 4;
+                               else
+                                       p2 = 2;
+                               if (dpll & PLL_P1_DIVIDE_BY_TWO)
+                                       p1 = 2;
+                               else
+                                       p1 = ((dpll >> 16) & 0x3f) + 2;
+                       }
+
+                       switch ((dpll >> 13) & 0x3) {
+                       case 0:
+                               ref = 48000;
+                               break;
+                       case 3:
+                               ref = 66000;
+                               break;
+                       default:
+                               ref = 0;
+                               printf("ref out of range\n");
+                               break;
+                       }
+               }
+               if (IS_965(devid)) {
+                       phase = (dpll >> 9) & 0xf;
+                       switch (phase) {
+                       case 6:
+                               break;
+                       default:
+                               printf("SDVO phase shift %d out of range -- probobly not "
+                                      "an issue.\n", phase);
+                               break;
+                       }
+               }
+               switch ((dpll >> 8) & 1) {
+               case 0:
+                       break;
+               default:
+                       printf("fp select out of range\n");
+                       break;
+               }
+               m1 = ((fp >> 8) & 0x3f);
+               if (IS_IGD(devid)) {
+                       n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
+                       m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT;
+                       m = m2 + 2;
+                       dot = (ref * m) / n / (p1 * p2);
+               } else {
+                       n = ((fp >> 16) & 0x3f);
+                       m2 = ((fp >> 0) & 0x3f);
+                       m = 5 * (m1 + 2) + (m2 + 2);
+                       dot =
+                           (ref * (5 * (m1 + 2) + (m2 + 2)) / (n + 2)) / (p1 *
+                                                                          p2);
+               }
+
+               printf("pipe %s dot %d n %d m1 %d m2 %d p1 %d p2 %d\n",
+                      pipe == 0 ? "A" : "B", dot, n, m1, m2, p1, p2);
+       }
+}
+
+int main(int argc, char** argv)
+{
+       intel_get_mmio();
+
+       if (IS_IRONLAKE(devid))
+               ironlake_dump_regs();
+       else
+               intel_dump_regs();
+
+       return 0;
+}