summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@mandolin.jf.intel.com>2006-10-29 01:04:15 -0800
committerKeith Packard <keithp@mandolin.jf.intel.com>2006-10-29 01:04:15 -0800
commit14233359b6de2164f52667b235c60116a1442486 (patch)
tree4aa3878236ea40b1a6ce4a1297bdd4456ea83b78
parent2631014e9d5b2e64908ea413729eb5fd819b17fc (diff)
reorder modesetting to try and follow the rulesmodesetting-keithp-fu
-rw-r--r--src/ch7xxx/ch7xxx.c6
-rw-r--r--src/i810_reg.h66
-rw-r--r--src/i830_crt.c1
-rw-r--r--src/i830_debug.c130
-rw-r--r--src/i830_display.c78
-rw-r--r--src/i830_sdvo.c46
6 files changed, 282 insertions, 45 deletions
diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c
index fdc96d0a..d11c3550 100644
--- a/src/ch7xxx/ch7xxx.c
+++ b/src/ch7xxx/ch7xxx.c
@@ -38,7 +38,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "ch7xxx.h"
#include "ch7xxx_reg.h"
-static void ch7xxxSaveRegs(void *d);
+static void ch7xxxSaveRegs(I2CDevPtr d);
static CARD8 ch7xxxFreqRegs[][7] =
{ { 0, 0x23, 0x08, 0x16, 0x30, 0x60, 0x00 },
@@ -243,9 +243,9 @@ static void ch7xxxPrintRegs(I2CDevPtr d)
}
}
-static void ch7xxxSaveRegs(void *d)
+static void ch7xxxSaveRegs(I2CDevPtr d)
{
- CH7xxxPtr ch7xxx = CH7PTR(((I2CDevPtr)d));
+ CH7xxxPtr ch7xxx = CH7PTR(d);
int ret;
int i;
diff --git a/src/i810_reg.h b/src/i810_reg.h
index a80b66ee..e73b281c 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -739,6 +739,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define VSYNC_A 0x60014
#define PIPEASRC 0x6001c
#define BCLRPAT_A 0x60020
+#define VSYNCSHIFT_A 0x60028
#define HTOTAL_B 0x61000
#define HBLANK_B 0x61004
@@ -748,6 +749,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define VSYNC_B 0x61014
#define PIPEBSRC 0x6101c
#define BCLRPAT_B 0x61020
+#define VSYNCSHIFT_B 0x61028
#define PP_STATUS 0x61200
# define PP_ON (1 << 31)
@@ -803,6 +805,28 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# define SDVO_MULTIPLIER_SHIFT_HIRES 4
# define SDVO_MULTIPLIER_SHIFT_VGA 0
+/* SDVO/UDI Multiplier/Divisor register */
+#define DPLLAMD 0x601c
+#define DPLLBMD 0x6020
+
+/* Hi res source UDI divider (-1), non-zeor for UDI fixed freq mode */
+# define DPLLMD_UDI_DIVIDER_HIRES_MASK (0x3f << 24)
+# define DPLLMD_UDI_DIVIDER_HIRES_SHIFT 24
+# define DPLLMD_UDI_DIVIDER_VGA_MASK (0x3f << 16)
+# define DPLLMD_UDI_DIVIDER_VGA_SHIFT 16
+# define DPLLMD_SDVOUDI_MULTIPLIER_HIRES_MASK (0x3f << 8)
+# define DPLLMD_SDVOUDI_MULTIPLIER_HIRES_SHIFT 8
+# define DPLLMD_SDVOUDI_MULTIPLIER_VGA_MASK (0x3f << 0)
+# define DPLLMD_SDVOUDI_MULTIPLIER_VGA_SHIFT 0
+
+#define DPLL_TEST 0x606c
+
+#define D_STATE 0x6104
+#define DSPCLK_GATE_D 0x6200
+#define RENCLK_GATE_D1 0x6204
+#define RENCLK_GATE_D2 0x6208
+#define RAMCLK_GATE_D 0x6210 /* CRL only */
+
#define BLC_PWM_CTL 0x61254
#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
@@ -810,6 +834,21 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
+#define BLM_CTL 0x61260
+#define BLM_THRESHOLD_0 0x61270
+#define BLM_THRESHOLD_1 0x61274
+#define BLM_THRESHOLD_2 0x61278
+#define BLM_THRESHOLD_3 0x6127c
+#define BLM_THRESHOLD_4 0x61280
+#define BLM_THRESHOLD_5 0x61284
+
+#define BLM_ACCUMULATOR_0 0x61290
+#define BLM_ACCUMULATOR_1 0x61294
+#define BLM_ACCUMULATOR_2 0x61298
+#define BLM_ACCUMULATOR_3 0x6129c
+#define BLM_ACCUMULATOR_4 0x612a0
+#define BLM_ACCUMULATOR_5 0x612a4
+
#define FPA0 0x06040
#define FPA1 0x06044
#define FPB0 0x06048
@@ -855,6 +894,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Bits to be preserved when writing */
#define SDVOC_PRESERVE_MASK (1 << 17)
+#define UDIB_SVB_SHB_CODES 0x61144
+#define UDIB_SHA_BLANK_CODES 0x61148
+#define UDIB_START_END_FILL_CODES 0x6114c
+
+
+#define SDVOUDI 0x61150
+
#define I830_HTOTAL_MASK 0xfff0000
#define I830_HACTIVE_MASK 0x7ff
@@ -1502,6 +1548,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PIPEACONF_GAMMA (1<<24)
#define PIPECONF_FORCE_BORDER (1<<25)
+#define PIPEAGCMAXRED 0x70010
+#define PIPEAGCMAXGREEN 0x70014
+#define PIPEAGCMAXBLUE 0x70018
+#define PIPEASTAT 0x70024
+
+#define DSPARB 0x70030
+#define DSPFW1 0x70034
+#define DSPFW2 0x70038
+#define DSPFW3 0x7003c
+#define PIPEAFRAMEHIGH 0x70040
+#define PIPEAFRAMEPIXEL 0x70044
+
+
#define PIPEBCONF 0x71008
#define PIPEBCONF_ENABLE (1<<31)
#define PIPEBCONF_DISABLE 0
@@ -1510,6 +1569,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PIPEBCONF_GAMMA (1<<24)
#define PIPEBCONF_PALETTE 0
+#define PIPEBGCMAXRED 0x71010
+#define PIPEBGCMAXGREEN 0x71014
+#define PIPEBGCMAXBLUE 0x71018
+#define PIPEBSTAT 0x71024
+#define PIPEBFRAMEHIGH 0x71040
+#define PIPEBFRAMEPIXEL 0x71044
+
#define DSPACNTR 0x70180
#define DSPBCNTR 0x71180
#define DISPLAY_PLANE_ENABLE (1<<31)
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 7721a0c2..edbbda53 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -87,6 +87,7 @@ static void
i830_crt_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
DisplayModePtr pMode)
{
+
}
static void
diff --git a/src/i830_debug.c b/src/i830_debug.c
index a48e9f2f..19d3e63e 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -41,6 +41,26 @@ static struct i830SnapshotRec {
char *name;
CARD32 regval;
} i830_snapshot[] = {
+ DEFINEREG(VCLK_DIVISOR_VGA0),
+ DEFINEREG(VCLK_DIVISOR_VGA1),
+ DEFINEREG(VCLK_POST_DIV),
+ DEFINEREG(DPLL_TEST),
+ DEFINEREG(D_STATE),
+ DEFINEREG(DSPCLK_GATE_D),
+ DEFINEREG(RENCLK_GATE_D1),
+ DEFINEREG(RENCLK_GATE_D2),
+/* DEFINEREG(RAMCLK_GATE_D), CRL only */
+ DEFINEREG(SDVOB),
+ DEFINEREG(SDVOC),
+/* DEFINEREG(UDIB_SVB_SHB_CODES), CRL only */
+/* DEFINEREG(UDIB_SHA_BLANK_CODES), CRL only */
+ DEFINEREG(SDVOUDI),
+ DEFINEREG(DSPARB),
+ DEFINEREG(DSPFW1),
+ DEFINEREG(DSPFW2),
+ DEFINEREG(DSPFW3),
+
+
DEFINEREG(ADPA),
DEFINEREG(LVDS),
DEFINEREG(DVOA),
@@ -62,36 +82,46 @@ static struct i830SnapshotRec {
DEFINEREG(DSPAPOS),
DEFINEREG(DSPASIZE),
DEFINEREG(DSPABASE),
+ DEFINEREG(DSPASURF),
+ DEFINEREG(DSPATILEOFF),
DEFINEREG(PIPEACONF),
DEFINEREG(PIPEASRC),
DEFINEREG(FPA0),
DEFINEREG(FPA1),
DEFINEREG(DPLL_A),
+ DEFINEREG(DPLLAMD),
DEFINEREG(HTOTAL_A),
DEFINEREG(HBLANK_A),
DEFINEREG(HSYNC_A),
DEFINEREG(VTOTAL_A),
DEFINEREG(VBLANK_A),
DEFINEREG(VSYNC_A),
+ DEFINEREG(BCLRPAT_A),
+ DEFINEREG(VSYNCSHIFT_A),
DEFINEREG(DSPBCNTR),
DEFINEREG(DSPBSTRIDE),
DEFINEREG(DSPBPOS),
DEFINEREG(DSPBSIZE),
DEFINEREG(DSPBBASE),
+ DEFINEREG(DSPBSURF),
+ DEFINEREG(DSPBTILEOFF),
DEFINEREG(PIPEBCONF),
DEFINEREG(PIPEBSRC),
DEFINEREG(FPB0),
DEFINEREG(FPB1),
DEFINEREG(DPLL_B),
+ DEFINEREG(DPLLBMD),
DEFINEREG(HTOTAL_B),
DEFINEREG(HBLANK_B),
DEFINEREG(HSYNC_B),
DEFINEREG(VTOTAL_B),
DEFINEREG(VBLANK_B),
DEFINEREG(VSYNC_B),
+ DEFINEREG(BCLRPAT_B),
+ DEFINEREG(VSYNCSHIFT_B),
DEFINEREG(VCLK_DIVISOR_VGA0),
DEFINEREG(VCLK_DIVISOR_VGA1),
@@ -129,13 +159,111 @@ void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn)
}
}
+static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int min, int max)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ int i;
+
+ for (i = min; i <= max; i++) {
+ OUTREG8 (id, i);
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "%18.18s%02x: 0x%02x\n",
+ name, i, INREG8(val));
+ }
+}
+
void i830DumpRegs (ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
int i;
+ int fp, dpll;
+ int n, m1, m2, m, p1, p2;
+ int ref;
+ int dot;
+ int phase;
+ int msr;
+ int crt;
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "DumpRegsBegin\n");
for (i = 0; i < NUM_I830_SNAPSHOTREGS; i++) {
- xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "%10.10s: 0x%08x\n",
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "%20.20s: 0x%08x\n",
i830_snapshot[i].name, (unsigned int) INREG(i830_snapshot[i].reg));
}
+ i830DumpIndexed (pScrn, "SR", 0x3c4, 0x3c5, 0, 7);
+ msr = INREG8(0x3cc);
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "%20.20s: 0x%02x\n",
+ "MSR", (unsigned int) msr);
+
+ if (msr & 1)
+ crt = 0x3d0;
+ else
+ crt = 0x3b0;
+ i830DumpIndexed (pScrn, "CR", crt + 4, crt + 5, 0, 0x24);
+ fp = INREG(FPA0);
+ dpll = INREG(DPLL_A);
+ switch ((dpll >> 24) & 0x3) {
+ case 0:
+ p2 = 10;
+ break;
+ case 1:
+ p2 = 5;
+ break;
+ default:
+ p2 = 1;
+ xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "p2 out of range\n");
+ break;
+ }
+ switch ((dpll >> 16) & 0xff) {
+ 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;
+ default:
+ p1 = 1;
+ xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "p1 out of range\n");
+ break;
+ }
+ switch ((dpll >> 13) & 0x3) {
+ case 0:
+ ref = 96000;
+ break;
+ default:
+ ref = 0;
+ xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "ref out of range\n");
+ break;
+ }
+ phase = (dpll >> 9) & 0xf;
+ switch (phase) {
+ case 6:
+ break;
+ default:
+ xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "phase %d out of range\n", phase);
+ break;
+ }
+ switch ((dpll >> 8) & 1) {
+ case 0:
+ break;
+ default:
+ xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "fp select out of range\n");
+ break;
+ }
+ n = ((fp >> 16) & 0x3f);
+ m1 = ((fp >> 8) & 0x3f);
+ m2 = ((fp >> 0) & 0x3f);
+ m = 5 * (m1 + 2) + (m2 + 2);
+ dot = (ref * (5 * (m1 + 2) + (m2 + 2)) / (n + 2)) / (p1 * p2);
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "dot %d n %d m1 %d m2 %d p1 %d p2 %d\n",
+ dot, n, m1, m2, p1, p2);
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "DumpRegsEnd\n");
}
diff --git a/src/i830_display.c b/src/i830_display.c
index a94e21da..fea9911a 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -46,7 +46,7 @@
/** Returns the pixel clock for the given refclk and divisors. */
static int i830_clock(int refclk, int m1, int m2, int n, int p1, int p2)
{
- return refclk * (5 * m1 + m2) / n / (p1 * p2);
+ return (refclk * (5 * (m1 + 2) + (m2 + 2)) / (n + 2)) / (p1 * p2);
}
static void
@@ -65,7 +65,7 @@ i830PrintPll(char *prefix, int refclk, int m1, int m2, int n, int p1, int p2)
* the given outputs.
*
* The equation for these divisors would be:
- * clk = refclk * (5 * m1 + m2) / n / (p1 * p2)
+ * clk = refclk * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / (p1 * p2)
*/
static Bool
i830PllIsValid(ScrnInfoPtr pScrn, int outputs, int refclk, int m1, int m2,
@@ -78,11 +78,11 @@ i830PllIsValid(ScrnInfoPtr pScrn, int outputs, int refclk, int m1, int m2,
if (IS_I9XX(pI830)) {
min_m1 = 10;
- max_m1 = 20;
+ max_m1 = 31;
min_m2 = 5;
max_m2 = 9;
min_m = 70;
- max_m = 120;
+ max_m = 180;
min_n = 3;
max_n = 8;
min_p1 = 1;
@@ -95,9 +95,9 @@ i830PllIsValid(ScrnInfoPtr pScrn, int outputs, int refclk, int m1, int m2,
max_p = 80;
}
min_vco = 1400000;
- max_vco = 2800000;
+ max_vco = 3800000;
min_dot = 20000;
- max_dot = 400000;
+ max_dot = 1600000;
} else {
min_m1 = 18;
max_m1 = 26;
@@ -118,8 +118,8 @@ i830PllIsValid(ScrnInfoPtr pScrn, int outputs, int refclk, int m1, int m2,
}
p = p1 * p2;
- m = 5 * m1 + m2;
- vco = refclk * m / n;
+ m = 5 * (m1 + 2) + (m2 + 2);
+ vco = refclk * m / (n + 2);
dotclock = i830_clock(refclk, m1, m2, n, p1, p2);
if (p1 < min_p1 || p1 > max_p1)
@@ -150,7 +150,7 @@ i830PllIsValid(ScrnInfoPtr pScrn, int outputs, int refclk, int m1, int m2,
/**
* Returns a set of divisors for the desired target clock with the given refclk,
* or FALSE. Divisor values are the actual divisors for
- * clk = refclk * (5 * m1 + m2) / n / (p1 * p2)
+ * clk = refclk * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / (p1 * p2)
*/
static Bool
i830FindBestPLL(ScrnInfoPtr pScrn, int outputs, int target, int refclk,
@@ -163,7 +163,7 @@ i830FindBestPLL(ScrnInfoPtr pScrn, int outputs, int target, int refclk,
if (IS_I9XX(pI830)) {
min_m1 = 10;
- max_m1 = 20;
+ max_m1 = 31;
min_m2 = 5;
max_m2 = 9;
min_n = 3;
@@ -205,10 +205,16 @@ i830FindBestPLL(ScrnInfoPtr pScrn, int outputs, int target, int refclk,
if (!i830PllIsValid(pScrn, outputs, refclk, m1, m2, n,
p1, p2)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "mode %d %d %d %d %d = invalid\n",
+ m1, m2, n, p1, p2);
continue;
}
clock = i830_clock(refclk, m1, m2, n, p1, p2);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "mode %d %d %d %d %d = %d\n",
+ m1, m2, n, p1, p2, clock);
this_err = abs(clock - target);
if (this_err < err) {
*outm1 = m1;
@@ -435,6 +441,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
pipesrc = ((pMode->HDisplay - 1) << 16) | (pMode->VDisplay - 1);
dspsize = ((pMode->VDisplay - 1) << 16) | (pMode->HDisplay - 1);
pixel_clock = pMode->Clock;
+ xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "mode clock %d\n", pixel_clock);
if (is_lvds && pI830->panel_fixed_hactive != 0) {
/* To enable panel fitting, we need to set the pipe timings to that of
@@ -479,7 +486,13 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
* bytes.
*/
if (is_sdvo) {
- pixel_clock *= i830_sdvo_get_pixel_multiplier(pMode);
+ int pixel_multiply = i830_sdvo_get_pixel_multiplier(pMode);
+ pixel_clock *= pixel_multiply;
+ if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830))
+ {
+ xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "pixel multiply is %d\n", pixel_multiply);
+ dpll |= (pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
+ }
}
if (IS_I9XX(pI830)) {
@@ -528,10 +541,14 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
else if (is_lvds)
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
#endif
+ else if (is_sdvo)
+ dpll |= DPLL_DVO_HIGH_SPEED;
else
dpll |= PLL_REF_INPUT_DREFCLK;
- fp = ((n - 2) << 16) | ((m1 - 2) << 8) | (m2 - 2);
+ /* set phase */
+ dpll |= (6 << 9);
+ fp = (n << 16) | (m1 << 8) | m2;
#if 1
ErrorF("hact: %d htot: %d hbstart: %d hbend: %d hsyncstart: %d hsyncend: %d\n",
@@ -580,6 +597,11 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
OUTREG(VGACNTRL, VGA_DISP_DISABLE);
/* Finally, set the mode. */
+ /* Disable ports */
+ /* XXX */
+ temp = INREG(ADPA);
+ OUTREG(ADPA, temp & ~ADPA_DAC_ENABLE);
+
/* First, disable display planes */
temp = INREG(dspcntr_reg);
OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
@@ -591,13 +613,22 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
temp = INREG(pipeconf_reg);
OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
+ temp = INREG(VGACNTRL);
+ OUTREG(VGACNTRL, temp | VGA_DISP_DISABLE);
+
+ /* finally, disable the PLL */
+ temp = INREG(dpll_reg);
+ OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE);
+
+ i830WaitForVblank(pScrn);
+
+ /* enable the PLL */
+
OUTREG(fp_reg, fp);
+ /* writing DPLL triggers PLL frequency shift */
+ i830WaitForVblank(pScrn);
OUTREG(dpll_reg, dpll);
-
- for (i = 0; i < pI830->num_outputs; i++) {
- if (pI830->output[i].pipe == pipe)
- pI830->output[i].post_set_mode(pScrn, &pI830->output[i], pMode);
- }
+ i830WaitForVblank(pScrn);
OUTREG(htot_reg, htot);
OUTREG(hblank_reg, hblank);
@@ -608,16 +639,25 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
OUTREG(dspsize_reg, dspsize);
OUTREG(dsppos_reg, 0);
+
i830PipeSetBase(pScrn, pipe, pI830->pipeX[pipe], pI830->pipeX[pipe]);
OUTREG(pipesrc_reg, pipesrc);
- /* Then, turn the pipe on first */
+ i830WaitForVblank(pScrn);
+
+ /* enable the pipe */
temp = INREG(pipeconf_reg);
OUTREG(pipeconf_reg, temp | PIPEACONF_ENABLE);
- /* And then turn the plane on */
+ /* enable the plane */
OUTREG(dspcntr_reg, dspcntr);
+ /* enable the ports */
+ for (i = 0; i < pI830->num_outputs; i++) {
+ if (pI830->output[i].pipe == pipe && !pI830->output[i].disabled)
+ pI830->output[i].post_set_mode(pScrn, &pI830->output[i], pMode);
+ }
+
pI830->pipeCurMode[pipe] = *pMode;
return TRUE;
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index ac5ae48e..c10c4e60 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -277,7 +277,7 @@ i830_sdvo_get_trained_inputs(I830OutputPtr output, Bool *input_1, Bool *input_2)
i830_sdvo_write_cmd(output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
- i830_sdvo_read_response(output, response, 2);
+ status = i830_sdvo_read_response(output, response, 2);
if (status != SDVO_CMD_STATUS_SUCCESS)
return FALSE;
@@ -508,6 +508,21 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
DisplayModePtr mode)
{
I830Ptr pI830 = I830PTR(pScrn);
+
+ OUTREG(SDVOC, INREG(SDVOC) & ~SDVO_ENABLE);
+ OUTREG(SDVOB, INREG(SDVOB) & ~SDVO_ENABLE);
+}
+
+static void
+i830_sdvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
+ DisplayModePtr mode)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ Bool out1, out2, input1, input2;
+ CARD32 /*dpll, */ sdvob, sdvoc;
+/* int dpll_reg = (output->pipe == 0) ? DPLL_A : DPLL_B; */
+ int sdvo_pixel_multiply;
+ CARD8 status;
CARD16 width = mode->CrtcHDisplay;
CARD16 height = mode->CrtcVDisplay;
CARD16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
@@ -588,26 +603,11 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
break;
}
- OUTREG(SDVOC, INREG(SDVOC) & ~SDVO_ENABLE);
- OUTREG(SDVOB, INREG(SDVOB) & ~SDVO_ENABLE);
-}
-
-static void
-i830_sdvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
- DisplayModePtr mode)
-{
- I830Ptr pI830 = I830PTR(pScrn);
- Bool out1, out2, input1, input2;
- CARD32 dpll, sdvob, sdvoc;
- int dpll_reg = (output->pipe == 0) ? DPLL_A : DPLL_B;
- int sdvo_pixel_multiply;
- CARD8 status;
-
/* the BIOS writes out 6 commands post mode set */
/* two 03s, 04 05, 10, 1d */
/* these contain the height and mode clock / 10 by the looks of it */
- i830_sdvo_get_trained_inputs(output, &input1, &input2);
+ status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
/* Warn if the device reported failure to sync. */
if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
@@ -627,15 +627,17 @@ i830_sdvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
if (output->pipe == 1)
sdvob |= SDVO_PIPE_B_SELECT;
- dpll = INREG(dpll_reg);
+/* dpll = INREG(dpll_reg); */
sdvo_pixel_multiply = i830_sdvo_get_pixel_multiplier(mode);
- if (IS_I945G(pI830) || IS_I945GM(pI830))
- dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
- else
+ if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830)) {
+ /* already done */
+ /* dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; */
+ ;
+ } else
sdvob |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
- OUTREG(dpll_reg, dpll | DPLL_DVO_HIGH_SPEED);
+/* OUTREG(dpll_reg, dpll | DPLL_DVO_HIGH_SPEED); */
OUTREG(SDVOB, sdvob);
OUTREG(SDVOC, sdvoc);