xf86-video-intel: Branch 'modesetting' - 4 commits - src/i830_display.c src/i830_driver.c src/i830_sdvo.c src/i830_xf86Crtc.c
Keith Packard
keithp at kemper.freedesktop.org
Sun Dec 17 07:12:54 EET 2006
src/i830_display.c | 26 +++++------------
src/i830_driver.c | 78 ++++++++++++++++++++++++++++------------------------
src/i830_sdvo.c | 55 ++++++++++++++++++++++++------------
src/i830_xf86Crtc.c | 2 -
4 files changed, 88 insertions(+), 73 deletions(-)
New commits:
diff-tree 6823ca87f3b1ef3b28ed167254dcfce2a80467df (from 86558cc622b516b568cc26efdf9b64d4b660f50f)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date: Sat Dec 16 21:12:47 2006 -0800
Follow mode setting order in RestoreHWState.
Add delays after output and CRTC disable. Restore panel fit register before
PLLs are restarted. Move all VGA restore code last. Shuffle various register
writes around and add delays to match PipeSetMode code.
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 998b36f..7da4bf5 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2210,18 +2210,22 @@ RestoreHWState(ScrnInfoPtr pScrn)
#ifdef XF86DRI
I830DRISetVBlankInterrupt (pScrn, FALSE);
#endif
-
/* Disable outputs */
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
output->funcs->dpms(output, DPMSModeOff);
}
-
+ i830WaitForVblank(pScrn);
+
/* Disable pipes */
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
crtc->funcs->dpms(crtc, DPMSModeOff);
}
+ i830WaitForVblank(pScrn);
+
+ if (!IS_I830(pI830) && !IS_845G(pI830))
+ OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
if (pI830->saveDPLL_A & DPLL_VCO_ENABLE)
{
@@ -2248,32 +2252,31 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE);
OUTREG(DSPASIZE, pI830->saveDSPASIZE);
OUTREG(DSPAPOS, pI830->saveDSPAPOS);
- OUTREG(DSPACNTR, pI830->saveDSPACNTR);
+ OUTREG(PIPEASRC, pI830->savePIPEASRC);
OUTREG(DSPABASE, pI830->saveDSPABASE);
- if (IS_I965G(pI830)) {
+ if (IS_I965G(pI830))
OUTREG(DSPASURF, pI830->saveDSPASURF);
- }
-
- OUTREG(PIPEASRC, pI830->savePIPEASRC);
OUTREG(PIPEACONF, pI830->savePIPEACONF);
+ i830WaitForVblank(pScrn);
+ OUTREG(DSPACNTR, pI830->saveDSPACNTR);
+ OUTREG(DSPABASE, INREG(DSPABASE));
+ i830WaitForVblank(pScrn);
- for(i = 0; i < 256; i++) {
- OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]);
- }
-
- if(xf86_config->num_crtc == 2) {
- OUTREG(FPB0, pI830->saveFPB0);
- OUTREG(FPB1, pI830->saveFPB1);
- if (IS_I965G(pI830))
- OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD);
+ if(xf86_config->num_crtc == 2)
+ {
if (pI830->saveDPLL_B & DPLL_VCO_ENABLE)
{
OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE);
usleep(150);
}
+ OUTREG(FPB0, pI830->saveFPB0);
+ OUTREG(FPB1, pI830->saveFPB1);
OUTREG(DPLL_B, pI830->saveDPLL_B);
usleep(150);
- OUTREG(DPLL_B, pI830->saveDPLL_B);
+ if (IS_I965G(pI830))
+ OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD);
+ else
+ OUTREG(DPLL_B, pI830->saveDPLL_B);
usleep(150);
OUTREG(HTOTAL_B, pI830->saveHTOTAL_B);
@@ -2286,43 +2289,48 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(DSPBSIZE, pI830->saveDSPBSIZE);
OUTREG(DSPBPOS, pI830->saveDSPBPOS);
OUTREG(PIPEBSRC, pI830->savePIPEBSRC);
- OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
- OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
OUTREG(DSPBBASE, pI830->saveDSPBBASE);
- if (IS_I965G(pI830)) {
+ if (IS_I965G(pI830))
OUTREG(DSPBSURF, pI830->saveDSPBSURF);
- }
- for(i= 0; i < 256; i++) {
- OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]);
- }
+ OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
+ i830WaitForVblank(pScrn);
+ OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
+ OUTREG(DSPBBASE, INREG(DSPBBASE));
+ i830WaitForVblank(pScrn);
}
- if (!IS_I830(pI830) && !IS_845G(pI830))
- OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
-
+ /* Restore outputs */
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ if (output->funcs->restore)
+ output->funcs->restore(output);
+ }
+
OUTREG(VGACNTRL, pI830->saveVGACNTRL);
OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0);
OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1);
OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV);
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- (*output->funcs->restore) (output);
+ for(i = 0; i < 256; i++) {
+ OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]);
+ }
+
+ if(xf86_config->num_crtc == 2) {
+ for(i= 0; i < 256; i++) {
+ OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]);
+ }
}
for(i = 0; i < 7; i++) {
- OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]);
- OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]);
+ OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]);
+ OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]);
}
OUTREG(SWF30, pI830->saveSWF[14]);
OUTREG(SWF31, pI830->saveSWF[15]);
OUTREG(SWF32, pI830->saveSWF[16]);
- for (i = 0; i < 2; i++)
- i830WaitForVblank(pScrn);
-
vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
vgaHWLock(hwp);
diff-tree 86558cc622b516b568cc26efdf9b64d4b660f50f (from 8e6ab99b3195325f9fe5432725fe328591c0c7e2)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date: Sat Dec 16 21:09:31 2006 -0800
Prefer earliest CRTC when mapping to outputs.
For some reason, the code was preferring the last possible output when
mapping outputs to crtcs. Use the earlier CRTC instead to make the i830
driver consistent with BIOS usage.
diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
index 76d6d03..51e6f1c 100644
--- a/src/i830_xf86Crtc.c
+++ b/src/i830_xf86Crtc.c
@@ -359,7 +359,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn,
crtcs[n] = crtc;
memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1, width, height);
- if (score >= best_score)
+ if (score > best_score)
{
best_crtc = crtc;
best_score = score;
diff-tree 8e6ab99b3195325f9fe5432725fe328591c0c7e2 (from bffd611b0a1cb05868e0f93e6ff9357a3116eaa6)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date: Sat Dec 16 21:06:36 2006 -0800
Not restoring active outputs. Wait for input sync before enabling outputs.
Oops--looks like a typo to me; the code was callint set_target_output
instead of set_active_outputs.
BIOS loops waiting for the SDVO input to sync before enabling outputs, this
makes sense to me.
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index d19b8b0..cb68802 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -693,18 +693,16 @@ i830_sdvo_dpms(xf86OutputPtr output, int
temp = INREG(dev_priv->output_device);
if ((temp & SDVO_ENABLE) == 0)
+ {
OUTREG(dev_priv->output_device, temp | SDVO_ENABLE);
-
- i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
-
#if 0
- /* Do it again! If we remove this below register write, or the exact
- * same one 2 lines up, the mac mini SDVO output doesn't turn on.
- */
- OUTREG(dev_priv->output_device,
- INREG(dev_priv->output_device) | SDVO_ENABLE);
+ /* Do it again! If we remove this below register write, or the exact
+ * same one 2 lines up, the mac mini SDVO output doesn't turn on.
+ */
+ OUTREG(dev_priv->output_device,
+ INREG(dev_priv->output_device) | SDVO_ENABLE);
#endif
-
+ }
for (i = 0; i < 2; i++)
i830WaitForVblank(pScrn);
@@ -716,6 +714,8 @@ i830_sdvo_dpms(xf86OutputPtr output, int
"First %s output reported failure to sync\n",
SDVO_NAME(dev_priv));
}
+
+ i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
}
}
@@ -764,16 +764,11 @@ i830_sdvo_restore(xf86OutputPtr output)
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
I830Ptr pI830 = I830PTR(pScrn);
int o;
+ int i;
+ Bool input1, input2;
+ CARD8 status;
- if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
- i830_sdvo_set_target_input(output, TRUE, FALSE);
- i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1);
- }
-
- if (dev_priv->caps.sdvo_inputs_mask & 0x2) {
- i830_sdvo_set_target_input(output, FALSE, TRUE);
- i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_2);
- }
+ i830_sdvo_set_active_outputs(output, 0);
for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
{
@@ -784,11 +779,33 @@ i830_sdvo_restore(xf86OutputPtr output)
i830_sdvo_set_output_timing(output, &dev_priv->save_output_dtd[o]);
}
}
- i830_sdvo_set_target_output(output, dev_priv->save_active_outputs);
+
+ if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
+ i830_sdvo_set_target_input(output, TRUE, FALSE);
+ i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1);
+ }
+
+ if (dev_priv->caps.sdvo_inputs_mask & 0x2) {
+ i830_sdvo_set_target_input(output, FALSE, TRUE);
+ i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_2);
+ }
i830_sdvo_set_clock_rate_mult(output, dev_priv->save_sdvo_mult);
OUTREG(dev_priv->output_device, dev_priv->save_SDVOX);
+
+ if (dev_priv->save_SDVOX & SDVO_ENABLE)
+ {
+ for (i = 0; i < 2; i++)
+ i830WaitForVblank(pScrn);
+ status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
+ if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "First %s output reported failure to sync\n",
+ SDVO_NAME(dev_priv));
+ }
+
+ i830_sdvo_set_active_outputs(output, dev_priv->save_active_outputs);
}
static int
diff-tree bffd611b0a1cb05868e0f93e6ff9357a3116eaa6 (from 9b1a1b170befae2e705c23ce295837d0d13b60c0)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date: Sat Dec 16 21:03:15 2006 -0800
Follow BIOS order in writing DPLL/DPLL_MD registers.
965 BIOS writes DPLL and then DPLL_MD.
945 BIOS writes DPLL twice.
diff --git a/src/i830_display.c b/src/i830_display.c
index 6971e28..f87aadc 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -787,12 +787,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
i830PrintPll("chosen", &clock);
ErrorF("clock regs: 0x%08x, 0x%08x\n", (int)dpll, (int)fp);
- if (IS_I965G(pI830)) {
- 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));
- }
-
if (dpll & DPLL_VCO_ENABLE)
{
OUTREG(fp_reg, fp);
@@ -804,21 +798,17 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
/* Wait for the clocks to stabilize. */
usleep(150);
- /* write it again -- the BIOS does, after all */
- OUTREG(dpll_reg, dpll);
+ if (IS_I965G(pI830)) {
+ 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));
+ } else {
+ /* write it again -- the BIOS does, after all */
+ OUTREG(dpll_reg, dpll);
+ }
/* Wait for the clocks to stabilize. */
usleep(150);
-#if 0
- /* Magic re-write of the register for the Mac Mini. Without this, the
- * first X invocation after a cold boot will stick in 4x pixel multiply
- * mode. Alternatives that don't work include sleeping and doing an
- * INREG for presumable pci write posting magic before and after the dpll
- * write above.
- */
- OUTREG(dpll_reg, dpll);
-#endif
-
OUTREG(htot_reg, (adjusted_mode->CrtcHDisplay - 1) |
((adjusted_mode->CrtcHTotal - 1) << 16));
OUTREG(hblank_reg, (adjusted_mode->CrtcHBlankStart - 1) |
More information about the xorg-commit
mailing list