diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | lib/intel_gpu_tools.h | 2 | ||||
-rw-r--r-- | lib/intel_reg.h | 548 | ||||
-rw-r--r-- | man/Makefile.am | 1 | ||||
-rw-r--r-- | man/intel_reg_dumper.1 | 11 | ||||
-rw-r--r-- | tools/Makefile.am | 1 | ||||
-rw-r--r-- | tools/intel_gpu_dump.c | 2 | ||||
-rw-r--r-- | tools/intel_reg_dumper.c | 1658 |
8 files changed, 2222 insertions, 2 deletions
@@ -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 diff --git a/lib/intel_gpu_tools.h b/lib/intel_gpu_tools.h index d696d72a..dd687f4f 100644 --- a/lib/intel_gpu_tools.h +++ b/lib/intel_gpu_tools.h @@ -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) { diff --git a/lib/intel_reg.h b/lib/intel_reg.h index bce19e88..ec30c9a2 100644 --- a/lib/intel_reg.h +++ b/lib/intel_reg.h @@ -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 */ diff --git a/man/Makefile.am b/man/Makefile.am index 2922f7f4..70e5320e 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -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 index 00000000..cdaeee12 --- /dev/null +++ b/man/intel_reg_dumper.1 @@ -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. diff --git a/tools/Makefile.am b/tools/Makefile.am index 31520b7c..545ddc60 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,6 +2,7 @@ bin_PROGRAMS = \ intel_gpu_dump \ intel_gpu_top \ intel_stepping \ + intel_reg_dumper \ intel_reg_write intel_gpu_dump_SOURCES = \ diff --git a/tools/intel_gpu_dump.c b/tools/intel_gpu_dump.c index c80dfccf..21862f47 100644 --- a/tools/intel_gpu_dump.c +++ b/tools/intel_gpu_dump.c @@ -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 index 00000000..55a05316 --- /dev/null +++ b/tools/intel_reg_dumper.c @@ -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; +} |