summaryrefslogtreecommitdiff
path: root/driver/xf86-video-intel/src/i830_display.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2008-05-21 20:19:53 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2008-05-21 20:19:53 +0000
commit441d3c52cab6805717c92f85d08ace52c97c5881 (patch)
tree7a49a4b910dc3eaee3457a63d901b48684f9bc7d /driver/xf86-video-intel/src/i830_display.c
parent913928db385e6d08f0141674758a36e9f4978c33 (diff)
Update to xf86-video-intel 2.3.1. Tested by many.
Diffstat (limited to 'driver/xf86-video-intel/src/i830_display.c')
-rw-r--r--driver/xf86-video-intel/src/i830_display.c162
1 files changed, 123 insertions, 39 deletions
diff --git a/driver/xf86-video-intel/src/i830_display.c b/driver/xf86-video-intel/src/i830_display.c
index 8f7c0689f..4910d9671 100644
--- a/driver/xf86-video-intel/src/i830_display.c
+++ b/driver/xf86-video-intel/src/i830_display.c
@@ -541,9 +541,11 @@ i830_display_tiled(xf86CrtcPtr crtc)
* - SR display watermarks must be equal between 16bpp and 32bpp?
*
* FIXME: verify above conditions are true
+ *
+ * Enable 8xx style FB compression
*/
static void
-i830_enable_fb_compression(xf86CrtcPtr crtc)
+i830_enable_fb_compression_8xx(xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
@@ -554,13 +556,8 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
unsigned long interval = 1000;
- if (INREG(FBC_CONTROL) & FBC_CTL_EN) {
- char cur_plane = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on "
- "plane %c, not enabling on plane %c\n", cur_plane,
- plane ? 'b' : 'a');
+ if (INREG(FBC_CONTROL) & FBC_CTL_EN)
return;
- }
compressed_stride = pI830->compressed_front_buffer->size /
FBC_LL_SIZE;
@@ -578,7 +575,7 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
i830WaitForVblank(pScrn);
OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + 6);
- OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_FULL |
+ OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM |
FBC_CTL_CPU_FENCE | plane);
OUTREG(FBC_FENCE_OFF, crtc->y);
@@ -595,18 +592,17 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
fbc_ctl |= FBC_CTL_UNCOMPRESSIBLE;
fbc_ctl |= pI830->front_buffer->fence_nr;
OUTREG(FBC_CONTROL, fbc_ctl);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on plane %c\n", plane ?
- 'b' : 'a');
}
+/*
+ * Disable 8xx style FB compression
+ */
static void
-i830_disable_fb_compression(xf86CrtcPtr crtc)
+i830_disable_fb_compression_8xx(xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
uint32_t fbc_ctl;
- char plane = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
/* Disable compression */
fbc_ctl = INREG(FBC_CONTROL);
@@ -616,7 +612,75 @@ i830_disable_fb_compression(xf86CrtcPtr crtc)
/* Wait for compressing bit to clear */
while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
; /* nothing */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on plane %c\n", plane);
+}
+
+static void
+i830_disable_fb_compression2(xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ uint32_t dpfc_ctl;
+
+ /* Disable compression */
+ dpfc_ctl = INREG(DPFC_CONTROL);
+ dpfc_ctl &= ~DPFC_CTL_EN;
+ OUTREG(DPFC_CONTROL, dpfc_ctl);
+ i830WaitForVblank(pScrn);
+}
+
+static void
+i830_enable_fb_compression2(xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB);
+ unsigned long stall_watermark = 200, frames = 50;
+
+ if (INREG(DPFC_CONTROL) & DPFC_CTL_EN)
+ return;
+
+ /* Set it up... */
+ i830_disable_fb_compression2(crtc);
+ OUTREG(DPFC_CB_BASE, pI830->compressed_front_buffer->offset);
+ /* Update i830_memory.c too if compression ratio changes */
+ OUTREG(DPFC_CONTROL, plane | DPFC_CTL_FENCE_EN | DPFC_CTL_LIMIT_4X |
+ pI830->front_buffer->fence_nr);
+ OUTREG(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN |
+ (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) |
+ (frames << DPFC_RECOMP_TIMER_COUNT_SHIFT));
+ OUTREG(DPFC_FENCE_YOFF, crtc->y);
+
+ /* Zero buffers */
+ memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0,
+ pI830->compressed_front_buffer->size);
+
+ /* enable it... */
+ OUTREG(DPFC_CONTROL, INREG(DPFC_CONTROL) | DPFC_CTL_EN);
+}
+
+static void
+i830_enable_fb_compression(xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (IS_IGD_GM(pI830))
+ return i830_enable_fb_compression2(crtc);
+
+ i830_enable_fb_compression_8xx(crtc);
+}
+
+static void
+i830_disable_fb_compression(xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+
+ if (IS_IGD_GM(pI830))
+ return i830_disable_fb_compression2(crtc);
+
+ i830_disable_fb_compression_8xx(crtc);
}
static Bool
@@ -682,7 +746,7 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
int dspbase_reg = (plane == 0) ? DSPABASE : DSPBBASE;
- CARD32 temp;
+ uint32_t temp;
/* XXX: When our outputs are all unaware of DPMS modes other than off and
* on, we should map those modes to DPMSModeOff in the CRTC.
@@ -837,9 +901,12 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
static void
i830_crtc_prepare (xf86CrtcPtr crtc)
{
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
/* Temporarily turn off FB compression during modeset */
if (i830_use_fb_compression(crtc))
i830_disable_fb_compression(crtc);
+ if (intel_crtc->enabled)
+ crtc->funcs->hide_cursor (crtc);
crtc->funcs->dpms (crtc, DPMSModeOff);
}
@@ -927,7 +994,7 @@ i830_get_core_clock_speed(ScrnInfoPtr pScrn)
pci_device_cfg_read_u16 (bridge, &hpllcc, I855_HPLLCC);
#else
PCITAG bridge = pciTag(0, 0, 0); /* This is always the host bridge */
- CARD16 hpllcc = pciReadWord(bridge, I855_HPLLCC);
+ uint16_t hpllcc = pciReadWord(bridge, I855_HPLLCC);
#endif
/* Assume that the hardware is in the high speed state. This
@@ -955,7 +1022,7 @@ i830_get_core_clock_speed(ScrnInfoPtr pScrn)
static int
i830_panel_fitter_pipe(I830Ptr pI830)
{
- CARD32 pfit_control;
+ uint32_t pfit_control;
/* i830 doesn't have a panel fitter */
if (IS_I830(pI830))
@@ -992,6 +1059,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ I830OutputPrivatePtr intel_output;
int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
int fp_reg = (pipe == 0) ? FPA0 : FPB0;
@@ -1012,7 +1080,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
int i;
int refclk;
intel_clock_t clock;
- CARD32 dpll = 0, fp = 0, dspcntr, pipeconf;
+ uint32_t dpll = 0, fp = 0, dspcntr, pipeconf, lvds_bits = 0;
Bool ok, is_sdvo = FALSE, is_dvo = FALSE;
Bool is_crt = FALSE, is_lvds = FALSE, is_tv = FALSE;
@@ -1021,7 +1089,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
*/
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
- I830OutputPrivatePtr intel_output = output->driver_private;
+ intel_output = output->driver_private;
if (output->crtc != crtc)
continue;
@@ -1029,6 +1097,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
switch (intel_output->type) {
case I830_OUTPUT_LVDS:
is_lvds = TRUE;
+ lvds_bits = intel_output->lvds_bits;
break;
case I830_OUTPUT_SDVO:
is_sdvo = TRUE;
@@ -1191,26 +1260,26 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
if (!xf86ModesEqual(mode, adjusted_mode)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
- xf86PrintModeline(pScrn->scrnIndex, mode);
+ xf86PrintModeline(pScrn->scrnIndex, adjusted_mode);
}
i830PrintPll("chosen", &clock);
}
+ if (dpll & DPLL_VCO_ENABLE)
+ {
+ OUTREG(fp_reg, fp);
+ OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
+ POSTING_READ(dpll_reg);
+ usleep(150);
+ }
+
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
* This is an exception to the general rule that mode_set doesn't turn
* things on.
*/
if (is_lvds)
{
- CARD32 lvds = INREG(LVDS);
-
- if (dpll & DPLL_VCO_ENABLE)
- {
- OUTREG(fp_reg, fp);
- OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
- POSTING_READ(dpll_reg);
- usleep(150);
- }
+ uint32_t lvds = INREG(LVDS);
lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
/* Set the B0-B3 data pairs corresponding to whether we're going to
@@ -1221,10 +1290,21 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
else
lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
- /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
- * appropriately here, but we need to look more thoroughly into how
- * panels behave in the two modes.
- */
+ if (pI830->lvds_24_bit_mode) {
+ /* Option set which requests 24-bit mode
+ * (LVDS_A3_POWER_UP, as opposed to 18-bit mode) here; we
+ * still need to look more thoroughly into how panels
+ * behave in the two modes. This option enables that
+ * experimentation.
+ */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Selecting less common 24 bit TMDS pixel format.\n");
+ lvds |= LVDS_A3_POWER_UP;
+ lvds |= LVDS_DATA_FORMAT_DOT_ONE;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Selecting standard 18 bit TMDS pixel format.\n");
+ }
/* Enable dithering if we're in 18-bit mode. */
if (IS_I965G(pI830))
@@ -1235,6 +1315,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
lvds |= LVDS_DITHER_ENABLE;
}
+ lvds |= lvds_bits;
+
OUTREG(LVDS, lvds);
POSTING_READ(LVDS);
}
@@ -1423,9 +1505,9 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
I830CrtcPrivatePtr intel_crtc = crtc ? crtc->driver_private : NULL;
- CARD32 dspcntr = intel_crtc->plane == 0 ? INREG(DSPACNTR) :
+ uint32_t dspcntr = intel_crtc->plane == 0 ? INREG(DSPACNTR) :
INREG(DSPBCNTR);
- CARD32 pipeconf = i == 0 ? INREG(PIPEACONF) :
+ uint32_t pipeconf = i == 0 ? INREG(PIPEACONF) :
INREG(PIPEBCONF);
Bool hw_plane_enable = (dspcntr & DISPLAY_PLANE_ENABLE) != 0;
Bool hw_pipe_enable = (pipeconf & PIPEACONF_ENABLE) != 0;
@@ -1601,8 +1683,8 @@ i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
int pipe = intel_crtc->pipe;
- CARD32 dpll = INREG((pipe == 0) ? DPLL_A : DPLL_B);
- CARD32 fp;
+ uint32_t dpll = INREG((pipe == 0) ? DPLL_A : DPLL_B);
+ uint32_t fp;
intel_clock_t clock;
if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
@@ -1631,8 +1713,10 @@ i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
return 0;
}
- /* XXX: Handle the 100Mhz refclk */
- i9xx_clock(96000, &clock);
+ if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN)
+ i9xx_clock(100000, &clock);
+ else
+ i9xx_clock(96000, &clock);
} else {
Bool is_lvds = (pipe == 1) && (INREG(LVDS) & LVDS_PORT_EN);