From 026a675e691c0f4e36f40843fdb2ac3ffd2bdf71 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Wed, 21 Dec 2011 21:25:03 +0000 Subject: Add support for Sandy Bridge. Not perfect yet. Most notably 3D acceleration is completely absent, and playing video doesn't work yet. But support for "normal" 2D stuff is pretty solid and it is really nice to be able to use my laptop at the panel's native resolution and be able to suspend and resume the machine. tested by some --- driver/xf86-video-intel/src/i830_bios.c | 2 +- driver/xf86-video-intel/src/i830_crt.c | 44 +++-- driver/xf86-video-intel/src/i830_display.c | 267 +++++++++++++++++++++++------ driver/xf86-video-intel/src/i830_hdmi.c | 6 +- driver/xf86-video-intel/src/i830_lvds.c | 46 ++--- driver/xf86-video-intel/src/i830_reg.h | 69 ++++++++ driver/xf86-video-intel/src/intel.h | 7 +- driver/xf86-video-intel/src/intel_driver.c | 139 ++++++++++----- driver/xf86-video-intel/src/intel_driver.h | 59 +++++-- driver/xf86-video-intel/src/intel_module.c | 4 +- 10 files changed, 474 insertions(+), 169 deletions(-) (limited to 'driver/xf86-video-intel/src') diff --git a/driver/xf86-video-intel/src/i830_bios.c b/driver/xf86-video-intel/src/i830_bios.c index c366ecb0c..3c63f76c4 100644 --- a/driver/xf86-video-intel/src/i830_bios.c +++ b/driver/xf86-video-intel/src/i830_bios.c @@ -210,7 +210,7 @@ static void parse_general_features(intel_screen_private *intel, struct bdb_heade if (intel->lvds_use_ssc) { if (IS_I85X(intel)) intel->lvds_ssc_freq = general->ssc_freq ? 66 : 48; - else if (IS_IGDNG(intel)) + else if (IS_GEN5(intel) || IS_GEN6(intel)) intel->lvds_ssc_freq = general->ssc_freq ? 100 : 120; else intel->lvds_ssc_freq = general->ssc_freq ? 100 : 96; diff --git a/driver/xf86-video-intel/src/i830_crt.c b/driver/xf86-video-intel/src/i830_crt.c index 8cc061a21..1889c8c61 100644 --- a/driver/xf86-video-intel/src/i830_crt.c +++ b/driver/xf86-video-intel/src/i830_crt.c @@ -44,7 +44,7 @@ i830_crt_dpms(xf86OutputPtr output, int mode) intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t temp, reg; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) reg = PCH_ADPA; else reg = ADPA; @@ -76,7 +76,7 @@ i830_crt_save (xf86OutputPtr output) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); - uint32_t reg = IS_IGDNG(intel) ? PCH_ADPA : ADPA; + uint32_t reg = HAS_PCH_SPLIT(intel) ? PCH_ADPA : ADPA; intel->saveADPA = INREG(reg); } @@ -86,7 +86,7 @@ i830_crt_restore (xf86OutputPtr output) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); - uint32_t reg = IS_IGDNG(intel) ? PCH_ADPA : ADPA; + uint32_t reg = HAS_PCH_SPLIT(intel) ? PCH_ADPA : ADPA; OUTREG(reg, intel->saveADPA); } @@ -139,7 +139,7 @@ i830_crt_mode_set(xf86OutputPtr output, DisplayModePtr mode, else dpll_md_reg = DPLL_B_MD; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) adpa_reg = PCH_ADPA; else adpa_reg = ADPA; @@ -148,7 +148,7 @@ i830_crt_mode_set(xf86OutputPtr output, DisplayModePtr mode, * Disable separate mode multiplier used when cloning SDVO to CRT * XXX this needs to be adjusted when we really are cloning */ - if (IS_I965G(intel) && !IS_IGDNG(intel)) + if (IS_I965G(intel) && !HAS_PCH_SPLIT(intel)) { dpll_md = INREG(dpll_md_reg); OUTREG(dpll_md_reg, dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); @@ -163,50 +163,58 @@ i830_crt_mode_set(xf86OutputPtr output, DisplayModePtr mode, if (i830_crtc->pipe == 0) { adpa |= ADPA_PIPE_A_SELECT; - if (!IS_IGDNG(intel)) + if (!HAS_PCH_SPLIT(intel)) OUTREG(BCLRPAT_A, 0); } else { adpa |= ADPA_PIPE_B_SELECT; - if (!IS_IGDNG(intel)) + if (!HAS_PCH_SPLIT(intel)) OUTREG(BCLRPAT_B, 0); } OUTREG(adpa_reg, adpa); } -static Bool intel_igdng_crt_detect_hotplug(xf86OutputPtr output) +static Bool intel_ironlake_crt_detect_hotplug(xf86OutputPtr output) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); - uint32_t adpa; + Bool turn_off_dac = HAS_PCH_SPLIT(intel); + uint32_t adpa, save_adpa; Bool ret; adpa = INREG(PCH_ADPA); - adpa &= ~ADPA_CRT_HOTPLUG_MASK; - adpa |= (ADPA_CRT_HOTPLUG_PERIOD_64 | ADPA_CRT_HOTPLUG_WARMUP_5MS | ADPA_CRT_HOTPLUG_SAMPLE_2S | ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */ ADPA_CRT_HOTPLUG_VOLREF_325MV); OUTREG(PCH_ADPA, adpa); + INREG(PCH_ADPA); usleep(6000); /* warmup */ + save_adpa = adpa = INREG(PCH_ADPA); + adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; + if (turn_off_dac) + adpa &= ~ADPA_DAC_ENABLE; OUTREG(PCH_ADPA, adpa); while (INREG(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) - ; + usleep(1000); + + if (turn_off_dac) { + OUTREG(PCH_ADPA, save_adpa); + INREG(PCH_ADPA); + } /* Check the status to see if both blue and green are on now */ - adpa = INREG(PCH_ADPA) & ADPA_CRT_HOTPLUG_MONITOR_MASK; - if (adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR || - adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO) + adpa = INREG(PCH_ADPA); + if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) ret = TRUE; else ret = FALSE; @@ -233,8 +241,8 @@ i830_crt_detect_hotplug(xf86OutputPtr output) int tries = 1; int try; - if (IS_IGDNG(intel)) - return intel_igdng_crt_detect_hotplug(output); + if (HAS_PCH_SPLIT(intel)) + return intel_ironlake_crt_detect_hotplug(output); /* On 4 series desktop, CRT detect sequence need to be done twice * to get a reliable result. */ @@ -526,7 +534,7 @@ i830_get_edid(xf86OutputPtr output, int gpio_reg, char *gpio_str) uint32_t i2c_reg; /* Set up the DDC bus. */ - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) i2c_reg = PCH_GPIOA; else i2c_reg = GPIOA; diff --git a/driver/xf86-video-intel/src/i830_display.c b/driver/xf86-video-intel/src/i830_display.c index f83357758..fec4dc028 100644 --- a/driver/xf86-video-intel/src/i830_display.c +++ b/driver/xf86-video-intel/src/i830_display.c @@ -555,7 +555,7 @@ static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = { }; -static const intel_limit_t *intel_igdng_limit(xf86CrtcPtr crtc) +static const intel_limit_t *intel_ironlake_limit(xf86CrtcPtr crtc) { ScrnInfoPtr scrn = crtc->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); @@ -613,8 +613,8 @@ static const intel_limit_t *intel_limit (xf86CrtcPtr crtc) intel_screen_private *intel = intel_get_screen_private(scrn); const intel_limit_t *limit; - if (IS_IGDNG(intel)) { - limit = intel_igdng_limit(crtc); + if (HAS_PCH_SPLIT(intel)) { + limit = intel_ironlake_limit(crtc); } else if (IS_G4X(intel)) { limit = intel_limit_g4x(crtc); } else if (IS_I9XX(intel) && !IS_IGD(intel)) { @@ -1026,7 +1026,7 @@ i830_pipe_a_require_activate (ScrnInfoPtr scrn) FALSE, FALSE, 0, NULL, 0, 0.0, 0.0 }; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) return FALSE; if (!crtc) @@ -1115,7 +1115,7 @@ i830_disable_vga_plane (xf86CrtcPtr crtc) uint8_t sr01 = 0; uint32_t vga_reg, vgacntrl; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) vga_reg = CPU_VGACNTRL; else vga_reg = VGACNTRL; @@ -1367,6 +1367,124 @@ static void ironlake_fdi_link_train(xf86CrtcPtr crtc) ErrorF("FDI train done\n"); } +static const int snb_b_fdi_train_param [] = { + FDI_LINK_TRAIN_400MV_0DB_SNB_B, + FDI_LINK_TRAIN_400MV_6DB_SNB_B, + FDI_LINK_TRAIN_600MV_3_5DB_SNB_B, + FDI_LINK_TRAIN_800MV_0DB_SNB_B, +}; + +static void gen6_fdi_link_train(xf86CrtcPtr crtc) +{ + ScrnInfoPtr scrn = crtc->scrn; + intel_screen_private *intel = intel_get_screen_private(scrn); + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + int pipe = intel_crtc->pipe; + int fdi_tx_reg = (pipe == 0) ? FDI_TXA_CTL : FDI_TXB_CTL; + int fdi_rx_reg = (pipe == 0) ? FDI_RXA_CTL : FDI_RXB_CTL; + int fdi_rx_iir_reg = (pipe == 0) ? FDI_RXA_IIR : FDI_RXB_IIR; + int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR; + uint32_t temp, i = 0; + + /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit + for train result */ + temp = INREG(fdi_rx_imr_reg); + temp &= ~FDI_RX_SYMBOL_LOCK; + temp &= ~FDI_RX_BIT_LOCK; + OUTREG(fdi_rx_imr_reg, temp); + INREG(fdi_rx_imr_reg); + usleep(150); + + /* enable CPU FDI TX and PCH FDI RX */ + temp = INREG(fdi_tx_reg); + temp |= FDI_TX_ENABLE; + temp &= ~(7 << 19); + temp |= /*(intel_crtc->fdi_lanes - 1)*/3 << 19; + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_1; + temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; + /* SNB-B */ + temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; + OUTREG(fdi_tx_reg, temp); + INREG(fdi_tx_reg); + + temp = INREG(fdi_rx_reg); + if (HAS_PCH_CPT(intel)) { + temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; + temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; + } else { + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_1; + } + OUTREG(fdi_rx_reg, temp | FDI_RX_ENABLE); + INREG(fdi_rx_reg); + usleep(150); + + for (i = 0; i < 4; i++) { + temp = INREG(fdi_tx_reg); + temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; + temp |= snb_b_fdi_train_param[i]; + OUTREG(fdi_tx_reg, temp); + INREG(fdi_tx_reg); + + temp = INREG(fdi_rx_iir_reg); + ErrorF("FDI_RX_IIR 0x%x\n", temp); + + if ((temp & FDI_RX_BIT_LOCK)) { + ErrorF("FDI train 1 done.\n"); + OUTREG(fdi_rx_iir_reg, + temp | FDI_RX_BIT_LOCK); + break; + } + } + if (i == 4) + ErrorF("FDI train 1 fail!\n"); + + /* Train 2 */ + temp = INREG(fdi_tx_reg); + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_2; + if (IS_GEN6(intel)) { + temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; + /* SNB-B */ + temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; + } + OUTREG(fdi_tx_reg, temp); + + temp = INREG(fdi_rx_reg); + if (HAS_PCH_CPT(intel)) { + temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; + temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; + } else { + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_2; + } + OUTREG(fdi_rx_reg, temp); + usleep(150); + + for (i = 0; i < 4; i++) { + temp = INREG(fdi_tx_reg); + temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; + temp |= snb_b_fdi_train_param[i]; + OUTREG(fdi_tx_reg, temp); + INREG(fdi_tx_reg); + + temp = INREG(fdi_rx_iir_reg); + ErrorF("FDI_RX_IIR 0x%x\n", temp); + + if ((temp & FDI_RX_SYMBOL_LOCK)) { + ErrorF("FDI train 2 done.\n"); + OUTREG(fdi_rx_iir_reg, + temp | FDI_RX_SYMBOL_LOCK); + break; + } + } + if (i == 4) + ErrorF("FDI train 2 fail!\n"); + + ErrorF("FDI train done\n"); +} + static void ironlake_crtc_enable(xf86CrtcPtr crtc) { @@ -1422,6 +1540,7 @@ ironlake_crtc_enable(xf86CrtcPtr crtc) INREG(fdi_rx_reg); usleep(200); + /* Switch from Rawclk to PCDclk */ temp = INREG(fdi_rx_reg); OUTREG(fdi_rx_reg, temp | FDI_SEL_PCDCLK); temp = INREG(fdi_rx_reg); @@ -1435,8 +1554,10 @@ ironlake_crtc_enable(xf86CrtcPtr crtc) usleep(100); } + i830WaitForVblank(scrn); + /* Enable panel fitting for LVDS */ #define PF_FILTER_MASK (3<<23) #define PF_FILTER_MED_3x3 (1<<23) if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) { @@ -1471,7 +1592,10 @@ ironlake_crtc_enable(xf86CrtcPtr crtc) OUTREG(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); /* Train FDI. */ - ironlake_fdi_link_train(crtc); + if (IS_GEN6(intel)) + gen6_fdi_link_train(crtc); + else + ironlake_fdi_link_train(crtc); /* enable PCH DPLL */ temp = INREG(pch_dpll_reg); @@ -1481,6 +1605,16 @@ ironlake_crtc_enable(xf86CrtcPtr crtc) } usleep(200); + if (HAS_PCH_CPT(intel)) { + /* Be sure PCH DPLL SEL is set */ + temp = INREG(PCH_DPLL_SEL); + if (pipe == 0 && (temp & TRANSA_DPLL_ENABLE) == 0) + temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); + else if (pipe == 1 && (temp & TRANSB_DPLL_ENABLE) == 0) + temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); + OUTREG(PCH_DPLL_SEL, temp); + } + /* set transcoder timing */ OUTREG(trans_htot_reg, INREG(cpu_htot_reg)); OUTREG(trans_hblank_reg, INREG(cpu_hblank_reg)); @@ -1490,7 +1624,7 @@ ironlake_crtc_enable(xf86CrtcPtr crtc) OUTREG(trans_vblank_reg, INREG(cpu_vblank_reg)); OUTREG(trans_vsync_reg, INREG(cpu_vsync_reg)); - /* enable normal */ + /* enable normal train */ ErrorF("FDI TX link normal\n"); temp = INREG(fdi_tx_reg); @@ -1500,10 +1634,14 @@ ironlake_crtc_enable(xf86CrtcPtr crtc) INREG(fdi_tx_reg); temp = INREG(fdi_rx_reg); - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_NONE; - - OUTREG(fdi_rx_reg, temp | FDI_LINK_TRAIN_NONE); + if (HAS_PCH_CPT(intel)) { + temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; + temp |= FDI_LINK_TRAIN_NORMAL_CPT; + } else { + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_NONE; + } + OUTREG(fdi_rx_reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); INREG(fdi_rx_reg); usleep(100); @@ -1618,15 +1756,20 @@ ironlake_crtc_disable(xf86CrtcPtr crtc) ErrorF("FDI RX train 1 preload\n"); temp = INREG(fdi_rx_reg); - temp &= ~FDI_LINK_TRAIN_NONE; - temp |= FDI_LINK_TRAIN_PATTERN_1; + if (HAS_PCH_CPT(intel)) { + temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; + temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; + } else { + temp &= ~FDI_LINK_TRAIN_NONE; + temp |= FDI_LINK_TRAIN_PATTERN_1; + } OUTREG(fdi_rx_reg, temp); INREG(fdi_rx_reg); usleep(100); - ErrorF("LVDS port force off\n"); if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) { + ErrorF("LVDS port force off\n"); while ((temp = INREG(PCH_LVDS)) & PORT_ENABLE) { OUTREG(PCH_LVDS, temp & ~LVDS_PORT_EN); INREG(PCH_LVDS); @@ -1668,6 +1811,7 @@ ironlake_crtc_disable(xf86CrtcPtr crtc) INREG(pch_dpll_reg); ErrorF("FDI RX PLL PCD disable\n"); + /* Switch from PCDclk to Rawclk */ temp = INREG(fdi_rx_reg); temp &= ~FDI_SEL_PCDCLK; OUTREG(fdi_rx_reg, temp); @@ -1691,7 +1835,7 @@ ironlake_crtc_disable(xf86CrtcPtr crtc) usleep(150); } -static void igdng_crtc_dpms(xf86CrtcPtr crtc, int mode) +static void ironlake_crtc_dpms(xf86CrtcPtr crtc, int mode) { I830CrtcPrivatePtr intel_crtc = crtc->driver_private; @@ -1754,8 +1898,8 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) intel_screen_private *intel = intel_get_screen_private(scrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - if (IS_IGDNG(intel)) - igdng_crtc_dpms(crtc, mode); + if (HAS_PCH_SPLIT(intel)) + ironlake_crtc_dpms(crtc, mode); else i9xx_crtc_dpms(crtc, mode); @@ -1824,7 +1968,7 @@ i830_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, ScrnInfoPtr scrn = crtc->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { /* FDI link clock is fixed at 2.7G */ if (mode->Clock * 3 > 27000 * 4) return MODE_CLOCK_HIGH; @@ -2124,7 +2268,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, "using SSC reference clock of %d MHz\n", refclk / 1000); } else if (IS_I9XX(intel)) { refclk = 96000; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) refclk = 120000; /* 120Mhz refclk */ } else { refclk = 48000; @@ -2168,7 +2312,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, } } - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { int bpp = 24; if (is_lvds) { uint32_t lvds_reg = INREG(PCH_LVDS); @@ -2185,7 +2329,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, intel_crtc->bpc = bpp / 3; } - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { uint32_t temp; temp = INREG(PCH_DREF_CONTROL); @@ -2206,7 +2350,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, else fp = clock.n << 16 | clock.m1 << 8 | clock.m2; - if (!IS_IGDNG(intel)) + if (!HAS_PCH_SPLIT(intel)) dpll = DPLL_VGA_MODE_DIS; if (IS_I9XX(intel)) { if (is_lvds) @@ -2219,7 +2363,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock; if ((IS_I945G(intel) || IS_I945GM(intel) || IS_G33CLASS(intel))) dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; - else if (IS_IGDNG(intel)) + else if (HAS_PCH_SPLIT(intel)) dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; } @@ -2243,7 +2387,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; break; } - if (IS_I965G(intel) && !IS_GM45(intel) && !IS_IGDNG(intel)) + if (IS_I965G(intel) && !IS_GM45(intel) && !HAS_PCH_SPLIT(intel)) dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); } else { if (is_lvds) { @@ -2274,7 +2418,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, /* Set up the display plane register */ dspcntr = DISPPLANE_GAMMA_ENABLE; /* this is "must be enabled" in the docs, but not set by bios */ - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; switch (scrn->bitsPerPixel) { @@ -2294,9 +2438,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, FatalError("unknown display bpp\n"); } - /* IGDNG's plane is forced to pipe, bit 24 is to + /* Ironlake's plane is forced to pipe, bit 24 is to enable color space conversion */ - if (!IS_IGDNG(intel)) { + if (!HAS_PCH_SPLIT(intel)) { if (pipe == 0) dspcntr |= DISPPLANE_SEL_PIPE_A; else @@ -2321,7 +2465,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, pipeconf &= ~PIPEACONF_DOUBLE_WIDE; } - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { pipeconf &= ~(7 << 5); if (intel_crtc->bpc == 6) pipeconf |= (1 << 6); /* 0 is 8bpc */ @@ -2334,7 +2478,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, * will be run after the mode is set. On 9xx, it helps. * On 855, it can lock up the chip (and the entire machine) */ - if (!IS_I85X (intel) && !IS_IGDNG(intel)) + if (!IS_I85X (intel) && !HAS_PCH_SPLIT(intel)) { dspcntr |= DISPLAY_PLANE_ENABLE; pipeconf |= PIPEACONF_ENABLE; @@ -2342,7 +2486,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, } /* Disable the panel fitter if it was on our pipe */ - if (!IS_IGDNG(intel) && i830_panel_fitter_pipe (intel) == pipe) + if (!HAS_PCH_SPLIT(intel) && i830_panel_fitter_pipe (intel) == pipe) OUTREG(PFIT_CONTROL, 0); if (intel->debug_modes) { @@ -2357,8 +2501,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, i830PrintPll(scrn, "chosen", &clock); } - /* assign to IGDNG registers */ - if (IS_IGDNG(intel)) { + /* assign to PCH registers */ + if (HAS_PCH_SPLIT(intel)) { fp_reg = pch_fp_reg; dpll_reg = pch_dpll_reg; } @@ -2379,15 +2523,23 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, { uint32_t lvds; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) lvds_reg = PCH_LVDS; lvds = INREG(lvds_reg); lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; - if (IS_IGDNG(intel)) - lvds |= (pipe == 1) ? LVDS_PIPEB_SELECT : 0; - else - lvds |= LVDS_PIPEB_SELECT; + if (pipe == 1) { + if (HAS_PCH_CPT(intel)) + lvds |= PORT_TRANS_B_SEL_CPT; + else + lvds |= LVDS_PIPEB_SELECT; + } else { + if (HAS_PCH_CPT(intel)) + lvds &= ~PORT_TRANS_SEL_MASK; + else + lvds &= ~LVDS_PIPEB_SELECT; + } + /* Set the B0-B3 data pairs corresponding to whether we're going to * set the DPLLs for dual-channel mode or not. */ @@ -2427,6 +2579,21 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, POSTING_READ(lvds_reg); } + if (HAS_PCH_SPLIT(intel)) { + /* For non-DP output, clear any trans DP clock recovery setting.*/ + if (pipe == 0) { + OUTREG(TRANSA_DATA_M1, 0); + OUTREG(TRANSA_DATA_N1, 0); + OUTREG(TRANSA_DP_LINK_M1, 0); + OUTREG(TRANSA_DP_LINK_N1, 0); + } else { + OUTREG(TRANSB_DATA_M1, 0); + OUTREG(TRANSB_DATA_N1, 0); + OUTREG(TRANSB_DP_LINK_M1, 0); + OUTREG(TRANSB_DP_LINK_N1, 0); + } + } + OUTREG(fp_reg, fp); /* OUTREG(fp_reg + 4, fp); RHEL had this... wtf? */ OUTREG(dpll_reg, dpll); @@ -2434,7 +2601,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, /* Wait for the clocks to stabilize. */ usleep(150); - if (IS_I965G(intel) && !IS_IGDNG(intel)) { + if (IS_I965G(intel) && !HAS_PCH_SPLIT(intel)) { int sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock; OUTREG(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); @@ -2465,13 +2632,13 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, /* pipesrc and dspsize control the size that is scaled from, which should * always be the user's requested size. */ - if (!IS_IGDNG(intel)) { + if (!HAS_PCH_SPLIT(intel)) { OUTREG(dspsize_reg, ((mode->VDisplay - 1) << 16) | (mode->HDisplay - 1)); OUTREG(dsppos_reg, 0); } OUTREG(pipesrc_reg, ((mode->HDisplay - 1) << 16) | (mode->VDisplay - 1)); - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { OUTREG(data_m1_reg, TU_SIZE(m_n.tu) | m_n.gmch_m); OUTREG(data_n1_reg, TU_SIZE(m_n.tu) | m_n.gmch_n); OUTREG(link_m1_reg, m_n.link_m); @@ -2497,7 +2664,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, POSTING_READ(pipeconf_reg); i830WaitForVblank(scrn); - if (IS_IGDNG(intel)) { + if (IS_GEN5(intel)) { /* enable address swizzle for tiling buffer */ temp = INREG(DISP_ARB_CTL); OUTREG(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING); @@ -2525,10 +2692,9 @@ i830_crtc_load_lut(xf86CrtcPtr crtc) if (!crtc->enabled) return; - /* use legacy palette for IGDNG */ - if (IS_IGDNG(intel)) - palreg = (intel_crtc->pipe == 0) ? LGC_PALETTE_A : - LGC_PALETTE_B; + /* use legacy palette for Ironlake */ + if (HAS_PCH_SPLIT(intel)) + palreg = (intel_crtc->pipe == 0) ? LGC_PALETTE_A : LGC_PALETTE_B; for (i = 0; i < 256; i++) { OUTREG(palreg + 4 * i, @@ -2699,7 +2865,7 @@ i830DescribeOutputConfiguration(ScrnInfoPtr scrn) Bool hw_pipe_enable = (pipeconf & PIPEACONF_ENABLE) != 0; int pipe; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) pipe = intel_crtc->plane; else pipe = !!(dspcntr & DISPPLANE_SEL_PIPE_MASK); @@ -2914,22 +3080,19 @@ i830_crtc_clock_get(ScrnInfoPtr scrn, xf86CrtcPtr crtc) return 0; } - if (IS_IGDNG(intel)) - i9xx_clock(120000, &clock); - else if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) + if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) intel_clock(intel, 100000, &clock); else intel_clock(intel, 96000, &clock); } else { - CARD32 lvds = IS_IGDNG(intel) ? PCH_LVDS : LVDS; - Bool is_lvds = (pipe == 1) && (INREG(lvds) & LVDS_PORT_EN); + Bool is_lvds = (pipe == 1) && (INREG(LVDS) & LVDS_PORT_EN); if (is_lvds) { clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> DPLL_FPA01_P1_POST_DIV_SHIFT); /* if LVDS is dual-channel, p2 = 7 */ - if ((INREG(lvds) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) + if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) clock.p2 = 7; else clock.p2 = 14; diff --git a/driver/xf86-video-intel/src/i830_hdmi.c b/driver/xf86-video-intel/src/i830_hdmi.c index 980fea85c..3c856cbc7 100644 --- a/driver/xf86-video-intel/src/i830_hdmi.c +++ b/driver/xf86-video-intel/src/i830_hdmi.c @@ -138,7 +138,7 @@ i830_hdmi_restore(xf86OutputPtr output) } static xf86OutputStatus -igdng_hdmi_detect(xf86OutputPtr output) +ironlake_hdmi_detect(xf86OutputPtr output) { DisplayModePtr modes; xf86OutputStatus status; @@ -172,8 +172,8 @@ i830_hdmi_detect(xf86OutputPtr output) dev_priv->has_hdmi_sink = FALSE; - if (IS_IGDNG(intel)) - return igdng_hdmi_detect(output); + if (HAS_PCH_SPLIT(intel)) + return ironlake_hdmi_detect(output); /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written 0xd. * Failure to do so will result in spurious interrupts being diff --git a/driver/xf86-video-intel/src/i830_lvds.c b/driver/xf86-video-intel/src/i830_lvds.c index 03f8a321e..8cecdfe63 100644 --- a/driver/xf86-video-intel/src/i830_lvds.c +++ b/driver/xf86-video-intel/src/i830_lvds.c @@ -141,10 +141,6 @@ i830_set_lvds_backlight_method(xf86OutputPtr output) if (i830_kernel_backlight_available(output)) { method = BCM_KERNEL; -#if 0 - } else if (IS_IGDNG(intel)) { - method = BCM_IRONLAKE_NULL; -#endif } else if (IS_I965GM(intel) || IS_GM45(intel)) { blc_pwm_ctl2 = INREG(BLC_PWM_CTL2); if (blc_pwm_ctl2 & BLM_LEGACY_MODE2) @@ -168,7 +164,7 @@ i830_lvds_set_backlight_native(xf86OutputPtr output, int level) intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t blc_pwm_ctl, reg; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) reg = BLC_PWM_CPU_CTL; else reg = BLC_PWM_CTL; @@ -185,7 +181,7 @@ i830_lvds_get_backlight_native(xf86OutputPtr output) intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t blc_pwm_ctl, reg; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) reg = BLC_PWM_CPU_CTL; else reg = BLC_PWM_CTL; @@ -203,7 +199,7 @@ i830_lvds_get_backlight_max_native(xf86OutputPtr output) uint32_t pwm_ctl; int val, reg; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) reg = BLC_PWM_PCH_CTL2; else reg = BLC_PWM_CTL; @@ -518,7 +514,7 @@ i830SetLVDSPanelPower(xf86OutputPtr output, Bool on) intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t pp_status, ctl_reg, status_reg, lvds_reg; - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { ctl_reg = PCH_PP_CONTROL; status_reg = PCH_PP_STATUS; lvds_reg = PCH_LVDS; @@ -583,7 +579,7 @@ i830_lvds_save (xf86OutputPtr output) intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg, pwm_ctl_reg; - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { pp_on_reg = PCH_PP_ON_DELAYS; pp_off_reg = PCH_PP_OFF_DELAYS; pp_ctl_reg = PCH_PP_CONTROL; @@ -616,7 +612,7 @@ i830_lvds_restore(xf86OutputPtr output) uint32_t pp_on_reg, pp_off_reg, pp_ctl_reg, pp_div_reg; uint32_t pwm_ctl_reg; - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { pp_on_reg = PCH_PP_ON_DELAYS; pp_off_reg = PCH_PP_OFF_DELAYS; pp_ctl_reg = PCH_PP_CONTROL; @@ -693,7 +689,7 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, } } - if (!IS_IGDNG(intel) && intel_crtc->pipe == 0) { + if (INTEL_INFO(intel)->gen < 40 && intel_crtc->pipe == 0) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Can't support LVDS on pipe A\n"); return FALSE; @@ -732,7 +728,7 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, } /* only full screen scale for now */ - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) goto out; /* 965+ wants fuzzy fitting */ @@ -757,14 +753,13 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, /* * Enable automatic panel scaling for non-native modes so that they fill - * the screen. Should be enabled before the pipe is enabled, according to - * register description and PRM. + * the screen. Should be enabled before the pipe is enabled, according + * to register description and PRM. + * Change the value here to see the borders for debugging */ - /* Change the value here to see the borders for debugging */ - if (!IS_IGDNG(intel)) { - OUTREG(BCLRPAT_A, 0); - OUTREG(BCLRPAT_B, 0); - } + OUTREG(BCLRPAT_A, 0); + OUTREG(BCLRPAT_B, 0); + switch (dev_priv->fitting_mode) { case CENTER: /* @@ -975,7 +970,7 @@ i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode, * DPLL settings. */ - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) return; /* @@ -1220,11 +1215,6 @@ i830_lvds_set_backlight_control(xf86OutputPtr output) dev_priv->backlight_max = i830_lvds_get_backlight_max_kernel(output); break; - case BCM_IRONLAKE_NULL: - dev_priv->set_backlight = i830_lvds_set_backlight_null; - dev_priv->get_backlight = i830_lvds_get_backlight_null; - dev_priv->backlight_max = 1; - break; default: /* * Should be impossible to get here unless the caller set a bogus @@ -1549,7 +1539,7 @@ i830_lvds_init(ScrnInfoPtr scrn) if (intel->quirk_flag & QUIRK_IGNORE_LVDS) return; - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { if ((INREG(PCH_LVDS) & LVDS_DETECTED) == 0) return; gpio = PCH_GPIOC; @@ -1640,7 +1630,7 @@ i830_lvds_init(ScrnInfoPtr scrn) * turned on. If so, assume that whatever is currently programmed is the * correct mode. */ - if (!intel->lvds_fixed_mode && !IS_IGDNG(intel)) { + if (!intel->lvds_fixed_mode && !HAS_PCH_SPLIT(intel)) { uint32_t lvds = INREG(LVDS); int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); @@ -1718,7 +1708,7 @@ found_mode: */ dev_priv->fitting_mode = FULL_ASPECT; - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { CARD32 pwm; /* make sure PWM is enabled */ pwm = INREG(BLC_PWM_CPU_CTL2); diff --git a/driver/xf86-video-intel/src/i830_reg.h b/driver/xf86-video-intel/src/i830_reg.h index fa4d288c5..668fff2db 100644 --- a/driver/xf86-video-intel/src/i830_reg.h +++ b/driver/xf86-video-intel/src/i830_reg.h @@ -3210,6 +3210,24 @@ #define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4) #define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4) +#define SNB_GMCH_CTRL 0x50 +#define SNB_GMCH_GMS_STOLEN_MASK 0xF8 +#define SNB_GMCH_GMS_STOLEN_32M (1 << 3) +#define SNB_GMCH_GMS_STOLEN_64M (2 << 3) +#define SNB_GMCH_GMS_STOLEN_96M (3 << 3) +#define SNB_GMCH_GMS_STOLEN_128M (4 << 3) +#define SNB_GMCH_GMS_STOLEN_160M (5 << 3) +#define SNB_GMCH_GMS_STOLEN_192M (6 << 3) +#define SNB_GMCH_GMS_STOLEN_224M (7 << 3) +#define SNB_GMCH_GMS_STOLEN_256M (8 << 3) +#define SNB_GMCH_GMS_STOLEN_288M (9 << 3) +#define SNB_GMCH_GMS_STOLEN_320M (0xa << 3) +#define SNB_GMCH_GMS_STOLEN_352M (0xb << 3) +#define SNB_GMCH_GMS_STOLEN_384M (0xc << 3) +#define SNB_GMCH_GMS_STOLEN_416M (0xd << 3) +#define SNB_GMCH_GMS_STOLEN_448M (0xe << 3) +#define SNB_GMCH_GMS_STOLEN_480M (0xf << 3) +#define SNB_GMCH_GMS_STOLEN_512M (0x10 << 3) #define I85X_CAPID 0x44 #define I85X_VARIANT_MASK 0x7 @@ -3773,6 +3791,14 @@ typedef enum { #define DISPLAY_PORT_PLL_BIOS_1 0x46010 #define DISPLAY_PORT_PLL_BIOS_2 0x46014 +#define PCH_DSPCLK_GATE_D 0x42020 +#define DPFDUNIT_CLOCK_GATE_DISABLE (1 << 7) +#define DPARBUNIT_CLOCK_GATE_DISABLE (1 << 5) + +#define PCH_3DCGDIS0 0x46020 +#define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18) +#define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1) + #define FDI_PLL_FREQ_CTL 0x46030 #define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24) #define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 @@ -3900,6 +3926,11 @@ typedef enum { #define SDE_PORTC_HOTPLUG (1 << 9) #define SDE_PORTB_HOTPLUG (1 << 8) #define SDE_SDVOB_HOTPLUG (1 << 6) +/* CPT */ +#define SDE_CRT_HOTPLUG_CPT (1 << 19) +#define SDE_PORTD_HOTPLUG_CPT (1 << 23) +#define SDE_PORTC_HOTPLUG_CPT (1 << 22) +#define SDE_PORTB_HOTPLUG_CPT (1 << 21) #define SDEISR 0xc4000 #define SDEIMR 0xc4004 @@ -3989,6 +4020,17 @@ typedef enum { #define PCH_SSC4_PARMS 0xc6210 #define PCH_SSC4_AUX_PARMS 0xc6214 +#define PCH_DPLL_SEL 0xc7000 +#define TRANSA_DPLL_ENABLE (1<<3) +#define TRANSA_DPLLB_SEL (1<<0) +#define TRANSA_DPLLA_SEL 0 +#define TRANSB_DPLL_ENABLE (1<<7) +#define TRANSB_DPLLB_SEL (1<<4) +#define TRANSB_DPLLA_SEL (0) +#define TRANSC_DPLL_ENABLE (1<<11) +#define TRANSC_DPLLB_SEL (1<<8) +#define TRANSC_DPLLA_SEL (0) + /* transcoder */ #define TRANS_HTOTAL_A 0xe0000 @@ -4054,6 +4096,12 @@ typedef enum { #define TRANS_6BPC (2<<5) #define TRANS_12BPC (3<<5) +/* CPT */ +#define PORT_TRANS_A_SEL_CPT 0 +#define PORT_TRANS_B_SEL_CPT (1<<29) +#define PORT_TRANS_C_SEL_CPT (2<<29) +#define PORT_TRANS_SEL_MASK (3<<29) + #define FDI_RXA_CHICKEN 0xc200c #define FDI_RXB_CHICKEN 0xc2010 #define FDI_RX_PHASE_SYNC_POINTER_ENABLE (1) @@ -4075,6 +4123,20 @@ typedef enum { #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) +/* ILK always use 400mV 0dB for voltage swing and pre-emphasis level. + SNB has different settings. */ + +/* SNB A-stepping */ +#define FDI_LINK_TRAIN_400MV_0DB_SNB_A (0x38<<22) +#define FDI_LINK_TRAIN_400MV_6DB_SNB_A (0x02<<22) +#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01<<22) +#define FDI_LINK_TRAIN_800MV_0DB_SNB_A (0x0<<22) +/* SNB B-stepping */ +#define FDI_LINK_TRAIN_400MV_0DB_SNB_B (0x0<<22) +#define FDI_LINK_TRAIN_400MV_6DB_SNB_B (0x3a<<22) +#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_B (0x39<<22) +#define FDI_LINK_TRAIN_800MV_0DB_SNB_B (0x38<<22) +#define FDI_LINK_TRAIN_VOL_EMP_MASK (0x3f<<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) @@ -4109,6 +4171,13 @@ typedef enum { #define FDI_RX_ENHANCE_FRAME_ENABLE (1<<6) #define FDI_SEL_RAWCLK (0<<4) #define FDI_SEL_PCDCLK (1<<4) +/* CPT */ +#define FDI_AUTO_TRAINING (1<<10) +#define FDI_LINK_TRAIN_PATTERN_1_CPT (0<<8) +#define FDI_LINK_TRAIN_PATTERN_2_CPT (1<<8) +#define FDI_LINK_TRAIN_PATTERN_IDLE_CPT (2<<8) +#define FDI_LINK_TRAIN_NORMAL_CPT (3<<8) +#define FDI_LINK_TRAIN_PATTERN_MASK_CPT (3<<8) #define FDI_RXA_MISC 0xf0010 #define FDI_RXB_MISC 0xf1010 diff --git a/driver/xf86-video-intel/src/intel.h b/driver/xf86-video-intel/src/intel.h index 3cb1a5d4b..52dedd4fc 100644 --- a/driver/xf86-video-intel/src/intel.h +++ b/driver/xf86-video-intel/src/intel.h @@ -435,18 +435,13 @@ enum last_3d { * BCM_KERNEL: use kernel methods for controlling the backlight * This is only available on some platforms, but where present this can * provide the best user experience. - * - * And, if you're in EL5, a fifth! - * BCM_IRONLAKE_NULL: just don't do anything and be quiet about it. This is - * a workaround for an RHGB interaction; you won't hit this at runtime. */ enum backlight_control { BCM_NATIVE = 0, BCM_LEGACY, BCM_COMBO, - BCM_KERNEL, - BCM_IRONLAKE_NULL + BCM_KERNEL }; enum dri_type { diff --git a/driver/xf86-video-intel/src/intel_driver.c b/driver/xf86-video-intel/src/intel_driver.c index 5d9980ebf..03b15861a 100644 --- a/driver/xf86-video-intel/src/intel_driver.c +++ b/driver/xf86-video-intel/src/intel_driver.c @@ -204,7 +204,11 @@ I830DetectMemory(ScrnInfoPtr scrn) int memsize = 0, gtt_size; int range; struct pci_device *bridge = intel_host_bridge (); - pci_device_cfg_read_u16(bridge, & gmch_ctrl, I830_GMCH_CTRL); + + if (IS_GEN6(intel)) + pci_device_cfg_read_u16(bridge, &gmch_ctrl, SNB_GMCH_CTRL); + else + pci_device_cfg_read_u16(bridge, &gmch_ctrl, I830_GMCH_CTRL); if (IS_I965G(intel)) { /* The 965 may have a GTT that is actually larger than is necessary @@ -259,10 +263,61 @@ I830DetectMemory(ScrnInfoPtr scrn) range = gtt_size + 4; /* new 4 series hardware has seperate GTT stolen with GFX stolen */ - if (IS_G4X(intel) || IS_IGD(intel) || IS_IGDNG(intel)) + if (IS_G4X(intel) || IS_IGD(intel) || IS_GEN5(intel) || IS_GEN6(intel)) range = 4; - if (IS_I85X(intel) || IS_I865G(intel) || IS_I9XX(intel)) { + if (IS_GEN6(intel)) { + switch (gmch_ctrl & SNB_GMCH_GMS_STOLEN_MASK) { + case SNB_GMCH_GMS_STOLEN_32M: + memsize = MB(32) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_64M: + memsize = MB(64) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_96M: + memsize = MB(96) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_128M: + memsize = MB(128) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_160M: + memsize = MB(160) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_192M: + memsize = MB(192) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_224M: + memsize = MB(224) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_256M: + memsize = MB(256) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_288M: + memsize = MB(288) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_320M: + memsize = MB(320) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_352M: + memsize = MB(352) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_384M: + memsize = MB(384) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_416M: + memsize = MB(416) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_448M: + memsize = MB(448) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_480M: + memsize = MB(480) - KB(range); + break; + case SNB_GMCH_GMS_STOLEN_512M: + memsize = MB(512) - KB(range); + break; + } + } else if (IS_I85X(intel) || IS_I865G(intel) || IS_I9XX(intel)) { switch (gmch_ctrl & I855_GMCH_GMS_MASK) { case I855_GMCH_GMS_STOLEN_1M: memsize = MB(1) - KB(range); @@ -375,7 +430,7 @@ I830MapMMIO(ScrnInfoPtr scrn) if (IS_I965G(intel)) { - if (IS_G4X(intel) || IS_IGDNG(intel)) { + if (IS_G4X(intel) || IS_GEN5(intel) || IS_GEN6(intel)) { gttaddr = intel->MMIOAddr + MB(2); intel->GTTMapSize = MB(2); } else { @@ -580,9 +635,9 @@ static void I830SetupOutputs(ScrnInfoPtr scrn) /* Set up integrated LVDS */ if (IS_MOBILE(intel) && !IS_I830(intel)) - i830_lvds_init(scrn); + i830_lvds_init(scrn); - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { int found; if (INREG(HDMIB) & PORT_DETECTED) { @@ -623,7 +678,8 @@ static void I830SetupOutputs(ScrnInfoPtr scrn) } else { i830_dvo_init(scrn); } - if (IS_I9XX(intel) && IS_MOBILE(intel) && !IS_IGDNG(intel)) + + if (SUPPORTS_TV(intel)) i830_tv_init(scrn); for (o = 0; o < config->num_output; o++) { @@ -654,7 +710,10 @@ static void i830_init_clock_gating(ScrnInfoPtr scrn) /* Disable clock gating reported to work incorrectly according to the specs. */ - if (IS_G4X(intel)) { + if (IS_GEN6(intel)) { + uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; + OUTREG(PCH_DSPCLK_GATE_D, dspclk_gate); + } else if (IS_G4X(intel)) { uint32_t dspclk_gate; OUTREG(RENCLK_GATE_D1, 0); OUTREG(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | @@ -1493,7 +1552,7 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags) if (!intel->use_drm_mode) { /* console hack, stolen from G80 */ - if (IS_IGDNG(intel)) { + if (IS_GEN5(intel)) { if (xf86LoadSubModule(scrn, "int10")) { intel->int10 = xf86InitInt10(pEnt->index); if (intel->int10) { @@ -1540,7 +1599,7 @@ static Bool i830_pipe_enabled(intel_screen_private *intel, enum pipe pipe) { uint32_t dpll_reg; - if (IS_IGDNG(intel)) { + if (HAS_PCH_SPLIT(intel)) { dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A : PCH_DPLL_B; } else { dpll_reg = (pipe == PIPE_A) ? DPLL_A : DPLL_B; @@ -1558,7 +1617,7 @@ static void i830_save_palette(intel_screen_private *intel, enum pipe pipe) if (!i830_pipe_enabled(intel, pipe)) return; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; if (pipe == PIPE_A) @@ -1579,7 +1638,7 @@ static void i830_restore_palette(intel_screen_private *intel, enum pipe pipe) if (!i830_pipe_enabled(intel, pipe)) return; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; if (pipe == PIPE_A) @@ -1599,8 +1658,8 @@ static Bool SaveHWState(ScrnInfoPtr scrn) vgaRegPtr vgaReg = &hwp->SavedReg; int i; - if (IS_IGDNG(intel)) - return TRUE; + if (HAS_PCH_SPLIT(intel)) + return TRUE; /* Save video mode information for native mode-setting. */ if (!DSPARB_HWCONTROL(intel)) @@ -1628,28 +1687,28 @@ static Bool SaveHWState(ScrnInfoPtr scrn) i830_save_palette(intel, PIPE_A); - if(xf86_config->num_crtc == 2) { - intel->savePIPEBCONF = INREG(PIPEBCONF); - intel->savePIPEBSRC = INREG(PIPEBSRC); - intel->saveDSPBCNTR = INREG(DSPBCNTR); - intel->saveFPB0 = INREG(FPB0); - intel->saveFPB1 = INREG(FPB1); - intel->saveDPLL_B = INREG(DPLL_B); - if (IS_I965G(intel)) - intel->saveDPLL_B_MD = INREG(DPLL_B_MD); - intel->saveHTOTAL_B = INREG(HTOTAL_B); - intel->saveHBLANK_B = INREG(HBLANK_B); - intel->saveHSYNC_B = INREG(HSYNC_B); - intel->saveVTOTAL_B = INREG(VTOTAL_B); - intel->saveVBLANK_B = INREG(VBLANK_B); - intel->saveVSYNC_B = INREG(VSYNC_B); - intel->saveBCLRPAT_B = INREG(BCLRPAT_B); - intel->saveDSPBSTRIDE = INREG(DSPBSTRIDE); - intel->saveDSPBSIZE = INREG(DSPBSIZE); - intel->saveDSPBPOS = INREG(DSPBPOS); - intel->saveDSPBBASE = INREG(DSPBBASE); - - i830_save_palette(intel, PIPE_B); + if (xf86_config->num_crtc == 2) { + intel->savePIPEBCONF = INREG(PIPEBCONF); + intel->savePIPEBSRC = INREG(PIPEBSRC); + intel->saveDSPBCNTR = INREG(DSPBCNTR); + intel->saveFPB0 = INREG(FPB0); + intel->saveFPB1 = INREG(FPB1); + intel->saveDPLL_B = INREG(DPLL_B); + if (IS_I965G(intel)) + intel->saveDPLL_B_MD = INREG(DPLL_B_MD); + intel->saveHTOTAL_B = INREG(HTOTAL_B); + intel->saveHBLANK_B = INREG(HBLANK_B); + intel->saveHSYNC_B = INREG(HSYNC_B); + intel->saveVTOTAL_B = INREG(VTOTAL_B); + intel->saveVBLANK_B = INREG(VBLANK_B); + intel->saveVSYNC_B = INREG(VSYNC_B); + intel->saveBCLRPAT_B = INREG(BCLRPAT_B); + intel->saveDSPBSTRIDE = INREG(DSPBSTRIDE); + intel->saveDSPBSIZE = INREG(DSPBSIZE); + intel->saveDSPBPOS = INREG(DSPBPOS); + intel->saveDSPBBASE = INREG(DSPBBASE); + + i830_save_palette(intel, PIPE_B); } if (IS_I965G(intel)) { @@ -1720,8 +1779,8 @@ static Bool RestoreHWState(ScrnInfoPtr scrn) vgaRegPtr vgaReg = &hwp->SavedReg; int i; - if (IS_IGDNG(intel)) - return TRUE; + if (HAS_PCH_SPLIT(intel)) + return TRUE; DPRINTF(PFX, "RestoreHWState\n"); @@ -2541,7 +2600,7 @@ static void I830LeaveVT(int scrnIndex, int flags) RestoreHWState(scrn); /* console restore hack */ - if (IS_IGDNG(intel) && intel->int10 && intel->int10Mode) { + if (IS_GEN5(intel) && intel->int10 && intel->int10Mode) { xf86Int10InfoPtr int10 = intel->int10; /* Use int10 to restore the console mode */ @@ -2621,7 +2680,7 @@ static Bool I830EnterVT(int scrnIndex, int flags) /* Disable pipes */ for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; - if (IS_IGDNG(intel)) + if (HAS_PCH_SPLIT(intel)) ironlake_crtc_disable(crtc); else i830_crtc_disable(crtc, TRUE); diff --git a/driver/xf86-video-intel/src/intel_driver.h b/driver/xf86-video-intel/src/intel_driver.h index c1fb92b96..4aedc975e 100644 --- a/driver/xf86-video-intel/src/intel_driver.h +++ b/driver/xf86-video-intel/src/intel_driver.h @@ -221,13 +221,44 @@ /* Some chips have specific errata (or limits) that we need to workaround. */ #define IS_I830(intel) (DEVICE_ID((intel)->PciInfo) == PCI_CHIP_I830_M) #define IS_845G(intel) (DEVICE_ID((intel)->PciInfo) == PCI_CHIP_845_G) -#define IS_I85X(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I855_GM || \ - DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I854) -#define IS_I855(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I855_GM && (pI810->chipset.variant == I855_GM || pI810->chipset.variant == I855_GME)) #define IS_I865G(intel) (DEVICE_ID((intel)->PciInfo) == PCI_CHIP_I865_G) #define IS_I915G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I915_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_E7221_G) #define IS_I915GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I915_GM) + +#define IS_965_Q(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q) + +/* supports Y tiled surfaces (pre-965 Mesa isn't ready yet) */ +#define SUPPORTS_YTILING(pI810) (INTEL_INFO(intel)->gen >= 40) +#define HAS_BLT(pI810) (INTEL_INFO(intel)->gen >= 60) + +#define IS_CRESTLINE(intel) IS_I965GM(intel) +#define IS_PINEVIEW(intel) IS_IGD(intel) +#define IS_IRONLAKE_M(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IRONLAKE_M_G) +#define IS_SANDYBRIDGE_M(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_SANDYBRIDGE_M_GT1 || \ + DEVICE_ID(pI810->PciInfo) == PCI_CHIP_SANDYBRIDGE_M_GT2 || \ + DEVICE_ID(pI810->PciInfo) == PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS) + +#define IS_IVYBRIDGE_M(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IVYBRIDGE_M_GT1 || \ + DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IVYBRIDGE_M_GT2) + +#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ + IS_I945GM(dev) || IS_CRESTLINE(dev) || IS_GM45(dev) || \ + IS_PINEVIEW(dev) || IS_IRONLAKE_M(dev) || IS_SANDYBRIDGE_M(dev) || \ + IS_IVYBRIDGE_M(dev)) + +#define SUPPORTS_TV(dev) (IS_I915GM(dev) || IS_I945GM(dev) || \ + IS_CRESTLINE(dev) || IS_GM45(dev)) + +#define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev)) +#define HAS_PCH_CPT(dev) (IS_GEN6(dev)) /* XXX */ + + +/* Some chips have specific errata (or limits) that we need to workaround. */ +#define IS_I85X(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I855_GM || \ + DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I854) +#define IS_I855(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I855_GM && (pI810->chipset.variant == I855_GM || pI810->chipset.variant == I855_GME)) + #define IS_I945G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_G) #define IS_I945GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I945_GME) #define IS_IGDGM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_PINEVIEW_M) @@ -237,10 +268,6 @@ #define IS_G4X(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G45_E_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G45_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q45_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G41_G || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_B43_G || IS_GM45(pI810)) #define IS_I965GM(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME) -#define IS_965_Q(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q) -#define IS_IGDNG_D(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IRONLAKE_D_G) -#define IS_IGDNG_M(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_IRONLAKE_M_G) -#define IS_IGDNG(pI810) (IS_IGDNG_D(pI810) || IS_IGDNG_M(pI810)) #define IS_I965G(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_G || \ DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G35_G || \ DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q || \ @@ -248,7 +275,7 @@ DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GM || \ DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_GME || \ IS_G4X(pI810) || \ - IS_IGDNG(pI810) || \ + IS_GEN5(pI810) || \ IS_GEN6(pI810)) #define IS_G33CLASS(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_G33_G ||\ DEVICE_ID(pI810->PciInfo) == PCI_CHIP_Q35_G ||\ @@ -262,25 +289,19 @@ IS_I965G(pI810) || \ IS_G33CLASS(pI810)) -#define IS_I915(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_G33CLASS(pI810)) - -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810) || IS_I965GM(pI810) || IS_GM45(pI810) || IS_IGD(pI810) || IS_IGDNG_M(pI810)) /* mark chipsets for using gfx VM offset for overlay */ #define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810) || IS_I965G(pI810)) /* mark chipsets without overlay hw */ -#define OVERLAY_NOEXIST(pI810) (IS_G4X(pI810) || IS_IGDNG(pI810)) +#define OVERLAY_NOEXIST(pI810) (IS_G4X(pI810) || IS_GEN5(pI810) || IS_GEN6(pI810)) /* chipsets require graphics mem for hardware status page */ #define HWS_NEED_GFX(pI810) (!pI810->use_drm_mode && \ (IS_G33CLASS(pI810) ||\ - IS_G4X(pI810) || IS_IGDNG(pI810))) + IS_G4X(pI810) || IS_GEN5(pI810) || IS_GEN6(pI810))) /* chipsets require status page in non stolen memory */ -#define HWS_NEED_NONSTOLEN(pI810) (IS_G4X(pI810) || IS_IGDNG(pI810)) -#define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_G4X(pI810) || IS_IGDNG(pI810)) +#define HWS_NEED_NONSTOLEN(pI810) (IS_G4X(pI810) || IS_GEN5(pI810) || IS_GEN6(pI810)) +#define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_G4X(pI810) || IS_GEN5(pI810) || IS_GEN6(pI810)) /* dsparb controlled by hw only */ -#define DSPARB_HWCONTROL(pI810) (IS_G4X(pI810) || IS_IGDNG(pI810)) -/* supports Y tiled surfaces (pre-965 Mesa isn't ready yet) */ -#define SUPPORTS_YTILING(pI810) (INTEL_INFO(intel)->gen >= 40) -#define HAS_BLT(pI810) (INTEL_INFO(intel)->gen >= 60) +#define DSPARB_HWCONTROL(pI810) (IS_G4X(pI810) || IS_GEN5(pI810) || IS_GEN6(pI810)) extern SymTabRec *intel_chipsets; diff --git a/driver/xf86-video-intel/src/intel_module.c b/driver/xf86-video-intel/src/intel_module.c index 0a059de05..eb0fc68f6 100644 --- a/driver/xf86-video-intel/src/intel_module.c +++ b/driver/xf86-video-intel/src/intel_module.c @@ -112,7 +112,6 @@ static const SymTabRec _intel_chipsets[] = { {PCI_CHIP_B43_G1, "B43"}, {PCI_CHIP_IRONLAKE_D_G, "Clarkdale"}, {PCI_CHIP_IRONLAKE_M_G, "Arrandale"}, -#if 0 {PCI_CHIP_SANDYBRIDGE_GT1, "Sandybridge Desktop (GT1)" }, {PCI_CHIP_SANDYBRIDGE_GT2, "Sandybridge Desktop (GT2)" }, {PCI_CHIP_SANDYBRIDGE_GT2_PLUS, "Sandybridge Desktop (GT2+)" }, @@ -120,6 +119,7 @@ static const SymTabRec _intel_chipsets[] = { {PCI_CHIP_SANDYBRIDGE_M_GT2, "Sandybridge Mobile (GT2)" }, {PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS, "Sandybridge Mobile (GT2+)" }, {PCI_CHIP_SANDYBRIDGE_S_GT, "Sandybridge Server" }, +#if 0 {PCI_CHIP_IVYBRIDGE_M_GT1, "Ivybridge Mobile (GT1)" }, {PCI_CHIP_IVYBRIDGE_M_GT2, "Ivybridge Mobile (GT2)" }, {PCI_CHIP_IVYBRIDGE_D_GT1, "Ivybridge Desktop (GT1)" }, @@ -179,7 +179,6 @@ static const struct pci_id_match intel_device_match[] = { INTEL_DEVICE_MATCH (PCI_CHIP_IRONLAKE_D_G, &intel_ironlake_info ), INTEL_DEVICE_MATCH (PCI_CHIP_IRONLAKE_M_G, &intel_ironlake_info ), -#if 0 INTEL_DEVICE_MATCH (PCI_CHIP_SANDYBRIDGE_GT1, &intel_sandybridge_info ), INTEL_DEVICE_MATCH (PCI_CHIP_SANDYBRIDGE_GT2, &intel_sandybridge_info ), INTEL_DEVICE_MATCH (PCI_CHIP_SANDYBRIDGE_GT2_PLUS, &intel_sandybridge_info ), @@ -188,6 +187,7 @@ static const struct pci_id_match intel_device_match[] = { INTEL_DEVICE_MATCH (PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS, &intel_sandybridge_info ), INTEL_DEVICE_MATCH (PCI_CHIP_SANDYBRIDGE_S_GT, &intel_sandybridge_info ), +#if 0 INTEL_DEVICE_MATCH (PCI_CHIP_IVYBRIDGE_M_GT1, &intel_ivybridge_info ), INTEL_DEVICE_MATCH (PCI_CHIP_IVYBRIDGE_M_GT2, &intel_ivybridge_info ), INTEL_DEVICE_MATCH (PCI_CHIP_IVYBRIDGE_D_GT1, &intel_ivybridge_info ), -- cgit v1.2.3