From 14233359b6de2164f52667b235c60116a1442486 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 29 Oct 2006 01:04:15 -0800 Subject: reorder modesetting to try and follow the rules --- src/ch7xxx/ch7xxx.c | 6 +-- src/i810_reg.h | 66 ++++++++++++++++++++++++++ src/i830_crt.c | 1 + src/i830_debug.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/i830_display.c | 78 +++++++++++++++++++++++-------- src/i830_sdvo.c | 46 ++++++++++--------- 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); -- cgit v1.2.3