diff --git a/src/i830_display.c b/src/i830_display.c index 306fed4..3a11933 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -1093,6 +1093,74 @@ i830_panel_fitter_pipe(I830Ptr pI830) } /** + * Sets up the DSPARB register to split the display fifo appropriately between + * the display planes. + * + * Adjusting this register requires that the planes be off. + */ +static void +i830_update_dsparb(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); + uint32_t dspacntr, dspbcntr; + int total_hdisplay = 0, planea_hdisplay = 0, planeb_hdisplay = 0; + int fifo_entries = 0, planea_entries = 0, planeb_entries = 0, i; + + dspacntr = INREG(DSPACNTR); + dspbcntr = INREG(DSPBCNTR); + + /* Disable planes since DSPARB can only be updated when they're + * off. + */ + OUTREG(DSPACNTR, dspacntr & ~DISPLAY_PLANE_ENABLE); + OUTREG(DSPBCNTR, dspbcntr & ~DISPLAY_PLANE_ENABLE); + i830WaitForVblank(pScrn); + + /* + * FIFO entries will be split based on programmed modes + */ + if (IS_I965GM(pI830) || IS_GM45(pI830)) + fifo_entries = 128; + else if (IS_I9XX(pI830)) + fifo_entries = 96; + else + fifo_entries = 256; + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + if (crtc->enabled) { + total_hdisplay += crtc->mode.HDisplay; + if (intel_crtc->plane == 0) + planea_hdisplay = crtc->mode.HDisplay; + else + planeb_hdisplay = crtc->mode.HDisplay; + } + } + + planea_entries = fifo_entries * planea_hdisplay / total_hdisplay; + planeb_entries = fifo_entries * planeb_hdisplay / total_hdisplay; + + ErrorF("planea entries: %d, planeb entries: %d\n", + planea_entries, planeb_entries); + + if (IS_I965GM(pI830) || IS_GM45(pI830)) + OUTREG(DSPARB, (planea_entries + planeb_entries << DSPARB_CSTART_SHIFT) | + (planea_entries << DSPARB_BSTART_SHIFT)); + else if (IS_I9XX(pI830)) + OUTREG(DSPARB, (planea_entries + planeb_entries << DSPARB_CSTART_SHIFT) | + (planea_entries << DSPARB_BSTART_SHIFT)); + else + OUTREG(DSPARB, (planea_entries + planeb_entries << DSPARB_BEND_SHIFT) | + (planea_entries << DSPARB_AEND_SHIFT)); + + OUTREG(DSPACNTR, dspacntr); + OUTREG(DSPBCNTR, dspbcntr); + i830WaitForVblank(pScrn); +} + +/** * Sets up registers for the given mode/adjusted_mode pair. * * The clocks, CRTCs and outputs attached to this CRTC must be off. @@ -1429,6 +1497,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, i830WaitForVblank(pScrn); + i830_update_dsparb(pScrn); + /* Clear any FIFO underrun status that may have occurred normally */ OUTREG(pipestat_reg, INREG(pipestat_reg) | FIFO_UNDERRUN); } diff --git a/src/i830_driver.c b/src/i830_driver.c index 0a49d3a..5d7178e 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1954,50 +1954,6 @@ i830_refresh_ring(ScrnInfoPtr pScrn) i830MarkSync(pScrn); } -/** - * Sets up the DSPARB register to split the display fifo appropriately between - * the display planes. - * - * Adjusting this register requires that the planes be off, thus as a side - * effect they are disabled by this function. - */ -static void -i830_set_dsparb(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - int i; - - /* Disable outputs & pipes since DSPARB can only be updated when they're - * off. - */ - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - output->funcs->dpms(output, DPMSModeOff); - } - i830WaitForVblank(pScrn); - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - crtc->funcs->dpms(crtc, DPMSModeOff); - } - i830WaitForVblank(pScrn); - - /* Fixup FIFO defaults: - * we don't use plane C at all so we can allocate all but one of the 96 - * FIFO RAM entries equally between planes A and B. - */ - if (IS_I9XX(pI830)) { - if (IS_I965GM(pI830) || IS_GM45(pI830)) - OUTREG(DSPARB, (127 << DSPARB_CSTART_SHIFT) | - (64 << DSPARB_BSTART_SHIFT)); - else - OUTREG(DSPARB, (95 << DSPARB_CSTART_SHIFT) | - (48 << DSPARB_BSTART_SHIFT)); - } else { - OUTREG(DSPARB, 254 << DSPARB_BEND_SHIFT | 128 << DSPARB_AEND_SHIFT); - } -} - enum pipe { PIPE_A = 0, PIPE_B, @@ -3407,11 +3363,6 @@ I830EnterVT(int scrnIndex, int flags) if (!pI830->SWCursor) I830InitHWCursor(pScrn); - /* Set the DSPARB register. This disables the outputs, which is about to - * happen (likely) in xf86SetDesiredModes anyway. - */ - i830_set_dsparb(pScrn); - /* Tell the BIOS that we're in control of mode setting now. */ i830_init_bios_control(pScrn);