Merge branch 'modesetting-origin' into modesetting

Conflicts:

	src/i830_display.c
This commit is contained in:
Eric Anholt 2006-11-03 15:59:59 -08:00
commit ecbe73b940
13 changed files with 531 additions and 180 deletions

View File

@ -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;

View File

@ -276,11 +276,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define GPIOG 0x5028
#define GPIOH 0x502c
# define GPIO_CLOCK_DIR_MASK (1 << 0)
# define GPIO_CLOCK_DIR_IN (0 << 1)
# define GPIO_CLOCK_DIR_OUT (1 << 1)
# define GPIO_CLOCK_VAL_MASK (1 << 2)
# define GPIO_CLOCK_VAL_OUT (1 << 3)
# define GPIO_CLOCK_VAL_IN (1 << 4)
# define GPIO_DATA_DIR_MASK (1 << 8)
# define GPIO_DATA_DIR_IN (0 << 9)
# define GPIO_DATA_DIR_OUT (1 << 9)
# define GPIO_DATA_VAL_MASK (1 << 10)
# define GPIO_DATA_VAL_OUT (1 << 11)
@ -739,6 +741,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 +751,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)
@ -849,6 +853,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# define DPLL_MD_VGA_UDI_MULTIPLIER_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)
@ -856,6 +868,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
@ -907,6 +934,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
#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
@ -1554,6 +1588,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
@ -1562,6 +1609,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)
@ -1598,6 +1652,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DSPBADDR DSPBBASE
#define DSPBSTRIDE 0x71188
#define DSPAKEYVAL 0x70194
#define DSPAKEYMASK 0x70198
#define DSPAPOS 0x7018C /* reserved */
#define DSPASIZE 0x70190
#define DSPBPOS 0x7118C

View File

@ -292,31 +292,29 @@ struct _I830OutputRec {
void *dev_priv;
};
typedef struct _I830PipeRec {
Bool gammaEnabled;
int x;
int y;
Bool cursorInRange;
Bool cursorShown;
Bool planeEnabled;
DisplayModeRec curMode;
} I830PipeRec, *I830PipePtr;
typedef struct _I830Rec {
unsigned char *MMIOBase;
unsigned char *FbBase;
int cpp;
unsigned int bios_version;
Bool newPipeSwitch;
Bool fakeSwitch;
int fixedPipe;
DisplayModePtr currentMode;
/* Mode saved during randr reprobe, which will need to be freed at the point
* of the next SwitchMode, when we lose this last reference to it.
*/
DisplayModePtr savedCurrentMode;
Bool gammaEnabled[MAX_DISPLAY_PIPES];
int pipeX[MAX_DISPLAY_PIPES];
int pipeY[MAX_DISPLAY_PIPES];
Bool cursorInRange[MAX_DISPLAY_PIPES];
Bool cursorShown[MAX_DISPLAY_PIPES];
I830PipeRec pipes[MAX_DISPLAY_PIPES];
Bool Clone;
int CloneRefresh;
int CloneHDisplay;
@ -402,7 +400,6 @@ typedef struct _I830Rec {
int MonType1;
int MonType2;
Bool specifiedMonitor;
DGAModePtr DGAModes;
int numDGAModes;
@ -484,8 +481,6 @@ typedef struct _I830Rec {
/* [0] is Pipe A, [1] is Pipe B. */
int availablePipes;
/* [0] is display plane A, [1] is display plane B. */
int planeEnabled[MAX_DISPLAY_PIPES];
DisplayModeRec pipeCurMode[MAX_DISPLAY_PIPES];
/* Driver phase/state information */
Bool preinit;

View File

@ -105,14 +105,15 @@ void
I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
{
I830Ptr pI830 = I830PTR(pScrn);
I830PipePtr pI830Pipe = &pI830->pipes[pipe];
CARD32 temp;
Bool show;
if (!pI830->planeEnabled[pipe])
if (!pI830Pipe->planeEnabled)
return;
show = pI830->cursorOn && pI830->cursorInRange[pipe];
if (show && (force || !pI830->cursorShown[pipe]))
show = pI830->cursorOn && pI830Pipe->cursorInRange;
if (show && (force || !pI830Pipe->cursorShown))
{
if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
int cursor_control;
@ -124,7 +125,7 @@ I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
if (pI830->CursorIsARGB) {
temp |= CURSOR_MODE_64_ARGB_AX;
if (pI830->gammaEnabled[pipe])
if (pI830Pipe->gammaEnabled)
temp |= MCURSOR_GAMMA_ENABLE;
} else
temp |= CURSOR_MODE_64_4C_AX;
@ -138,15 +139,15 @@ I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
temp |= CURSOR_ENABLE;
if (pI830->CursorIsARGB) {
temp |= CURSOR_FORMAT_ARGB;
if (pI830->gammaEnabled[pipe])
if (pI830Pipe->gammaEnabled)
temp |= CURSOR_GAMMA_ENABLE;
} else
temp |= CURSOR_FORMAT_3C;
OUTREG(CURSOR_CONTROL, temp);
}
pI830->cursorShown[pipe] = TRUE;
pI830Pipe->cursorShown = TRUE;
}
else if (!show && (force || pI830->cursorShown[pipe]))
else if (!show && (force || pI830Pipe->cursorShown))
{
if (IS_MOBILE(pI830) || IS_I9XX(pI830))
{
@ -164,7 +165,7 @@ I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe, Bool force)
temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE);
OUTREG(CURSOR_CONTROL, temp);
}
pI830->cursorShown[pipe] = FALSE;
pI830Pipe->cursorShown = FALSE;
}
/* Flush cursor changes. */
@ -179,7 +180,8 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
int i;
DPRINTF(PFX, "I830InitHWCursor\n");
for (i = 0; i < MAX_DISPLAY_PIPES; i++) pI830->cursorShown[i] = FALSE;
for (i = 0; i < MAX_DISPLAY_PIPES; i++)
pI830->pipes[i].cursorShown = FALSE;
/* Initialise the HW cursor registers, leaving the cursor hidden. */
if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
for (i = 0; i < MAX_DISPLAY_PIPES; i++)
@ -484,11 +486,12 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
{
DisplayModePtr mode = &pI830->pipeCurMode[pipe];
int thisx = x - pI830->pipeX[pipe];
int thisy = y - pI830->pipeY[pipe];
I830PipePtr pI830Pipe = &pI830->pipes[pipe];
DisplayModePtr mode = &pI830Pipe->curMode;
int thisx = x - pI830Pipe->x;
int thisy = y - pI830Pipe->y;
if (!pI830->planeEnabled[pipe])
if (!pI830Pipe->planeEnabled)
continue;
/*
@ -524,7 +527,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
if (pipe == 1)
OUTREG(CURSOR_B_POSITION, temp);
pI830->cursorInRange[pipe] = inrange;
pI830Pipe->cursorInRange = inrange;
I830SetPipeCursor (pScrn, pipe, FALSE);
}
@ -577,14 +580,14 @@ I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
DPRINTF(PFX, "I830SetCursorColors\n");
if (pI830->planeEnabled[0])
if (pI830->pipes[0].planeEnabled)
{
OUTREG(CURSOR_A_PALETTE0, bg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE1, fg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE2, fg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE3, bg & 0x00ffffff);
}
if (pI830->planeEnabled[1])
if (pI830->pipes[1].planeEnabled)
{
OUTREG(CURSOR_B_PALETTE0, bg & 0x00ffffff);
OUTREG(CURSOR_B_PALETTE1, fg & 0x00ffffff);

View File

@ -41,6 +41,25 @@ 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 +81,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(DPLL_A_MD),
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(DPLL_B_MD),
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 +158,115 @@ 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 pipe;
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);
for (pipe = 0; pipe <= 1; pipe++)
{
fp = INREG(pipe == 0 ? FPA0 : FPB0);
dpll = INREG(pipe == 0 ? DPLL_A : DPLL_B);
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, "pipe %s dot %d n %d m1 %d m2 %d p1 %d p2 %d\n",
pipe == 0 ? "A" : "B", dot, n, m1, m2, p1, p2);
}
xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "DumpRegsEnd\n");
}

View File

@ -237,6 +237,7 @@ void
i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y)
{
I830Ptr pI830 = I830PTR(pScrn);
I830PipePtr pI830Pipe = &pI830->pipes[pipe];
unsigned long Start;
int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
@ -255,8 +256,8 @@ i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y)
OUTREG(dspbase, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
}
pI830->pipeX[pipe] = x;
pI830->pipeY[pipe] = y;
pI830Pipe->x = x;
pI830Pipe->y = y;
}
/**
@ -368,6 +369,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
Bool plane_enable)
{
I830Ptr pI830 = I830PTR(pScrn);
I830PipePtr pI830Pipe = &pI830->pipes[pipe];
int m1 = 0, m2 = 0, n = 0, p1 = 0, p2 = 0;
CARD32 dpll = 0, fp = 0, temp;
CARD32 htot, hblank, hsync, vtot, vblank, vsync, dspcntr;
@ -396,7 +398,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
else
outputs = (pI830->operatingDevices >> 8) & 0xff;
if (I830ModesEqual(&pI830->pipeCurMode[pipe], pMode))
if (I830ModesEqual(&pI830Pipe->curMode, pMode))
return TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested pix clock: %d\n",
@ -581,7 +583,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
FatalError("unknown display bpp\n");
}
if (pI830->gammaEnabled[pipe]) {
if (pI830Pipe->gammaEnabled) {
dspcntr |= DISPPLANE_GAMMA_ENABLE;
}
@ -612,6 +614,16 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
pI830->output[i].post_set_mode(pScrn, &pI830->output[i], pMode);
}
/*
* If the panel fitter is stuck on our pipe, turn it off
* the LVDS output will whack it correctly if it needs it
*/
if (((INREG(PFIT_CONTROL) >> 29) & 0x3) == pipe)
OUTREG(PFIT_CONTROL, 0);
OUTREG(PFIT_PGM_RATIOS, 0x10001000);
OUTREG(DSPARB, (47 << 0) | (95 << 7));
OUTREG(htot_reg, htot);
OUTREG(hblank_reg, hblank);
OUTREG(hsync_reg, hsync);
@ -621,7 +633,7 @@ 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]);
i830PipeSetBase(pScrn, pipe, pI830Pipe->x, pI830Pipe->y);
OUTREG(pipesrc_reg, pipesrc);
/* Then, turn the pipe on first */
@ -633,7 +645,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe,
OUTREG(dspcntr_reg, dspcntr);
}
pI830->pipeCurMode[pipe] = *pMode;
pI830Pipe->curMode = *pMode;
return TRUE;
}
@ -655,63 +667,49 @@ i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
* internal TV) should have no outputs trying to pull data out of it, so
* we're ready to turn those off.
*/
if (!pI830->planeEnabled[0]) {
CARD32 dspcntr, pipeconf, dpll;
for (i = 0; i < MAX_DISPLAY_PIPES; i++) {
I830PipePtr pI830Pipe = &pI830->pipes[i];
int dspcntr_reg = pipe == 0 ? DSPACNTR : DSPBCNTR;
int pipeconf_reg = pipe == 0 ? PIPEACONF : PIPEBCONF;
int dpll_reg = pipe == 0 ? DPLL_A : DPLL_B;
CARD32 dspcntr, pipeconf, dpll;
char *pipe_name = pipe == 0 ? "A" : "B";
dspcntr = INREG(DSPACNTR);
if (pI830Pipe->planeEnabled)
continue;
dspcntr = INREG(dspcntr_reg);
if (dspcntr & DISPLAY_PLANE_ENABLE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling plane A\n");
OUTREG(DSPACNTR, dspcntr & ~DISPLAY_PLANE_ENABLE);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling plane %s\n",
pipe_name);
OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
/* Wait for vblank for the disable to take effect */
i830WaitForVblank(pScrn);
}
pipeconf = INREG(PIPEACONF);
pipeconf = INREG(pipeconf_reg);
if (pipeconf & PIPEACONF_ENABLE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling pipe A\n");
OUTREG(PIPEACONF, pipeconf & ~PIPEACONF_ENABLE);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling pipe %s\n",
pipe_name);
OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
}
dpll = INREG(DPLL_A);
dpll = INREG(dpll_reg);
if (dpll & DPLL_VCO_ENABLE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DPLL A\n");
OUTREG(DPLL_A, dpll & ~DPLL_VCO_ENABLE);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DPLL %s\n",
pipe_name);
OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
}
memset(&pI830->pipeCurMode[0], 0, sizeof(pI830->pipeCurMode[0]));
}
if (!pI830->planeEnabled[1]) {
CARD32 dspcntr, pipeconf, dpll;
dspcntr = INREG(DSPBCNTR);
if (dspcntr & DISPLAY_PLANE_ENABLE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling plane B\n");
OUTREG(DSPBCNTR, dspcntr & ~DISPLAY_PLANE_ENABLE);
/* Wait for vblank for the disable to take effect */
i830WaitForVblank(pScrn);
}
pipeconf = INREG(PIPEBCONF);
if (pipeconf & PIPEBCONF_ENABLE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling pipe B\n");
OUTREG(PIPEBCONF, pipeconf & ~PIPEBCONF_ENABLE);
}
dpll = INREG(DPLL_B);
if (dpll & DPLL_VCO_ENABLE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DPLL B\n");
OUTREG(DPLL_B, dpll & ~DPLL_VCO_ENABLE);
}
memset(&pI830->pipeCurMode[1], 0, sizeof(pI830->pipeCurMode[1]));
memset(&pI830Pipe->curMode, 0, sizeof(pI830Pipe->curMode));
}
}
/**
* This function sets the given mode on the active pipes.
* This function configures the screens in clone mode on
* all active outputs using a mode similar to the specified mode.
*/
Bool
i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
@ -729,31 +727,18 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
didLock = I830DRILock(pScrn);
#endif
if (pI830->operatingDevices & 0xff) {
pI830->planeEnabled[0] = 1;
} else {
pI830->planeEnabled[0] = 0;
}
pI830->pipes[0].planeEnabled = (pI830->operatingDevices & 0xff) != 0;
pI830->pipes[1].planeEnabled = (pI830->operatingDevices & 0xff00) != 0;
if (pI830->operatingDevices & 0xff00) {
pI830->planeEnabled[1] = 1;
} else {
pI830->planeEnabled[1] = 0;
}
for (i = 0; i < pI830->num_outputs; i++) {
for (i = 0; i < pI830->num_outputs; i++)
pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
}
if (pI830->planeEnabled[0]) {
ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, 0, pMode),
0, TRUE);
if (!ok)
goto done;
}
if (pI830->planeEnabled[1]) {
ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, 1, pMode),
1, TRUE);
for (i = 0; i < MAX_DISPLAY_PIPES; i++)
{
if (pI830->pipes[i].planeEnabled)
ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i,
pMode),
i, TRUE);
if (!ok)
goto done;
}
@ -773,13 +758,10 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
/* If we might have enabled/disabled some pipes, we need to reset
* cloning mode support.
*/
if ((pI830->operatingDevices & 0x00ff) &&
(pI830->operatingDevices & 0xff00))
{
if (pI830->pipes[0].planeEnabled && pI830->pipes[1].planeEnabled)
pI830->Clone = TRUE;
} else {
else
pI830->Clone = FALSE;
}
/* If HW cursor currently showing, reset cursor state */
if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn)
@ -818,7 +800,7 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
" Display plane %c is now %s and connected to pipe %c.\n",
'A' + i,
pI830->planeEnabled[i] ? "enabled" : "disabled",
pI830->pipes[i].planeEnabled ? "enabled" : "disabled",
dspcntr & DISPPLANE_SEL_PIPE_MASK ? 'B' : 'A');
}

View File

@ -1485,7 +1485,7 @@ I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on)
if (pI830->directRenderingEnabled && pI830->drmMinor >= 5) {
if (on) {
if (pI830->planeEnabled[1])
if (pI830->pipes[1].planeEnabled)
pipe.pipe = DRM_I830_VBLANK_PIPE_B;
else
pipe.pipe = DRM_I830_VBLANK_PIPE_A;

View File

@ -640,6 +640,7 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
pI830 = I830PTR(pScrn);
for(p=0; p < pI830->availablePipes; p++) {
I830PipePtr pI830Pipe = &pI830->pipes[p];
if (p == 0) {
palreg = PALETTE_A;
@ -653,10 +654,10 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
dspsurf = DSPBSURF;
}
if (pI830->planeEnabled[p] == 0)
if (pI830Pipe->planeEnabled == 0)
continue;
pI830->gammaEnabled[p] = 1;
pI830Pipe->gammaEnabled = 1;
/* To ensure gamma is enabled we need to turn off and on the plane */
temp = INREG(dspreg);
@ -1265,21 +1266,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->LinearAlloc = 0;
}
pI830->fixedPipe = -1;
if ((s = xf86GetOptValString(pI830->Options, OPTION_FIXEDPIPE)) &&
I830IsPrimary(pScrn)) {
if (strstr(s, "A") || strstr(s, "a") || strstr(s, "0"))
pI830->fixedPipe = 0;
else if (strstr(s, "B") || strstr(s, "b") || strstr(s, "1"))
pI830->fixedPipe = 1;
}
I830PreInitDDC(pScrn);
pI830->MonType1 = PIPE_NONE;
pI830->MonType2 = PIPE_NONE;
pI830->specifiedMonitor = FALSE;
if ((s = xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT)) &&
I830IsPrimary(pScrn)) {
@ -1366,7 +1356,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->pipe = 1;
pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1;
pI830->specifiedMonitor = TRUE;
} else if (I830IsPrimary(pScrn)) {
/* Choose a default set of outputs to use based on what we've detected.
*
@ -1683,16 +1672,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
}
if (IS_I9XX(pI830))
pI830->newPipeSwitch = TRUE;
else
if (pI830->availablePipes == 2 && pI830->bios_version >= 3062) {
/* BIOS build 3062 changed the pipe switching functionality */
pI830->newPipeSwitch = TRUE;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using new Pipe switch code\n");
} else
pI830->newPipeSwitch = FALSE;
PrintDisplayDeviceInfo(pScrn);
if (xf86IsEntityShared(pScrn->entityList[0])) {
@ -2310,6 +2289,8 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->saveSWF[15] = INREG(SWF31);
pI830->saveSWF[16] = INREG(SWF32);
pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL);
for (i = 0; i < pI830->num_outputs; i++) {
if (pI830->output[i].save != NULL)
pI830->output[i].save(pScrn, &pI830->output[i]);
@ -2428,6 +2409,8 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(SWF31, pI830->saveSWF[15]);
OUTREG(SWF32, pI830->saveSWF[16]);
OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
i830CompareRegsToSnapshot(pScrn);
return TRUE;
@ -3398,7 +3381,8 @@ static Bool
I830EnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
int i;
DPRINTF(PFX, "Enter VT\n");
@ -3429,7 +3413,8 @@ I830EnterVT(int scrnIndex, int flags)
SetHWOperatingState(pScrn);
/* Mark that we'll need to re-set the mode for sure */
memset(pI830->pipeCurMode, 0, sizeof(pI830->pipeCurMode));
for (i = 0; i < MAX_DISPLAY_PIPES; i++)
memset(&pI830->pipes[i].curMode, 0, sizeof(pI830->pipes[i].curMode));
if (!i830SetMode(pScrn, pScrn->currentMode))
return FALSE;
@ -3582,7 +3567,7 @@ I830SaveScreen(ScreenPtr pScreen, int mode)
base = DSPBADDR;
surf = DSPBSURF;
}
if (pI830->planeEnabled[i]) {
if (pI830->pipes[i].planeEnabled) {
temp = INREG(ctrl);
if (on)
temp |= DISPLAY_PLANE_ENABLE;
@ -3631,7 +3616,7 @@ I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
ctrl = DSPBCNTR;
base = DSPBADDR;
}
if (pI830->planeEnabled[i]) {
if (pI830->pipes[i].planeEnabled) {
temp = INREG(ctrl);
if (PowerManagementMode == DPMSModeOn)
temp |= DISPLAY_PLANE_ENABLE;

View File

@ -48,6 +48,219 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "shadow.h"
#include "i830.h"
#define AIRLIED_I2C 0
#if AIRLIED_I2C
#define I2C_TIMEOUT(x) /*(x)*/ /* Report timeouts */
#define I2C_TRACE(x) /*(x)*/ /* Report progress */
static void i830_setscl(I2CBusPtr b, int state)
{
ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
CARD32 val;
OUTREG(b->DriverPrivate.uval,
(state ? GPIO_CLOCK_VAL_OUT : 0) | GPIO_CLOCK_DIR_OUT |
GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_VAL_MASK);
val = INREG(b->DriverPrivate.uval);
}
static void i830_setsda(I2CBusPtr b, int state)
{
ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
CARD32 val;
OUTREG(b->DriverPrivate.uval,
(state ? GPIO_DATA_VAL_OUT : 0) | GPIO_DATA_DIR_OUT |
GPIO_DATA_DIR_MASK | GPIO_DATA_VAL_MASK);
val = INREG(b->DriverPrivate.uval);
}
static void i830_getscl(I2CBusPtr b, int *state)
{
ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
CARD32 val;
OUTREG(b->DriverPrivate.uval, GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK);
OUTREG(b->DriverPrivate.uval, 0);
val = INREG(b->DriverPrivate.uval);
*state = ((val & GPIO_DATA_VAL_IN) != 0);
}
static int i830_getsda(I2CBusPtr b)
{
ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
CARD32 val;
OUTREG(b->DriverPrivate.uval, GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK);
OUTREG(b->DriverPrivate.uval, 0);
val = INREG(b->DriverPrivate.uval);
return ((val & GPIO_DATA_VAL_IN) != 0);
}
static inline void sdalo(I2CBusPtr b)
{
i830_setsda(b, 0);
b->I2CUDelay(b, b->RiseFallTime);
}
static inline void sdahi(I2CBusPtr b)
{
i830_setsda(b, 1);
b->I2CUDelay(b, b->RiseFallTime);
}
static inline void scllo(I2CBusPtr b)
{
i830_setscl(b, 0);
b->I2CUDelay(b, b->RiseFallTime);
}
static inline int sclhi(I2CBusPtr b, int timeout)
{
int scl = 0;
int i;
i830_setscl(b, 1);
b->I2CUDelay(b, b->RiseFallTime);
for (i = timeout; i > 0; i -= b->RiseFallTime) {
i830_getscl(b, &scl);
if (scl) break;
b->I2CUDelay(b, b->RiseFallTime);
}
if (i <= 0) {
I2C_TIMEOUT(ErrorF("[I2CRaiseSCL(<%s>, %d) timeout]",
b->BusName, timeout));
return FALSE;
}
return TRUE;
}
static Bool
I830I2CGetByte(I2CDevPtr d, I2CByte *data, Bool last)
{
I2CBusPtr b = d->pI2CBus;
int i, sda;
unsigned char indata = 0;
sdahi(b);
for (i = 0; i < 8; i++) {
if (sclhi(b, d->BitTimeout) == FALSE) {
I2C_TRACE(ErrorF("timeout at bit #%d\n", 7-i));
return FALSE;
};
indata *= 2;
if (i830_getsda(b))
indata |= 0x01;
scllo(b);
}
if (last) {
sdahi(b);
} else {
sdalo(b);
}
if (sclhi(b, d->BitTimeout) == FALSE) {
sdahi(b);
return FALSE;
};
scllo(b);
sdahi(b);
*data = indata & 0xff;
I2C_TRACE(ErrorF("R%02x ", (int) *data));
return TRUE;
}
static Bool
I830I2CPutByte(I2CDevPtr d, I2CByte c)
{
Bool r;
int i, scl, sda;
int sb, ack;
I2CBusPtr b = d->pI2CBus;
for (i = 7; i >= 0; i--) {
sb = c & (1 << i);
i830_setsda(b, sb);
b->I2CUDelay(b, b->RiseFallTime);
if (sclhi(b, d->ByteTimeout) == FALSE) {
sdahi(b);
return FALSE;
}
i830_setscl(b, 0);
b->I2CUDelay(b, b->RiseFallTime);
}
sdahi(b);
if (sclhi(b, d->ByteTimeout) == FALSE) {
I2C_TIMEOUT(ErrorF("[I2CPutByte(<%s>, 0x%02x, %d, %d, %d) timeout]",
b->BusName, c, d->BitTimeout,
d->ByteTimeout, d->AcknTimeout));
return FALSE;
}
ack = i830_getsda(b);
I2C_TRACE(ErrorF("Put byte 0x%02x , getsda() = %d\n", c & 0xff, ack));
scllo(b);
return (0 == ack);
}
static Bool
I830I2CStart(I2CBusPtr b, int timeout)
{
if (sclhi(b, timeout) == FALSE)
return FALSE;
sdalo(b);
scllo(b);
return TRUE;
}
static void
I830I2CStop(I2CDevPtr d)
{
I2CBusPtr b = d->pI2CBus;
sdalo(b);
sclhi(b, d->ByteTimeout);
sdahi(b);
}
static Bool
I830I2CAddress(I2CDevPtr d, I2CSlaveAddr addr)
{
if (I830I2CStart(d->pI2CBus, d->StartTimeout)) {
if (I830I2CPutByte(d, addr & 0xFF)) {
if ((addr & 0xF8) != 0xF0 &&
(addr & 0xFE) != 0x00)
return TRUE;
if (I830I2CPutByte(d, (addr >> 8) & 0xFF))
return TRUE;
}
I830I2CStop(d);
}
return FALSE;
}
#else
static void
i830I2CGetBits(I2CBusPtr b, int *clock, int *data)
{
@ -76,6 +289,7 @@ i830I2CPutBits(I2CBusPtr b, int clock, int data)
GPIO_DATA_DIR_MASK |
GPIO_DATA_VAL_MASK);
}
#endif
/* the i830 has a number of I2C Buses */
Bool
@ -90,8 +304,16 @@ I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
pI2CBus->BusName = name;
pI2CBus->scrnIndex = pScrn->scrnIndex;
#if AIRLIED_I2C
pI2CBus->I2CGetByte = I830I2CGetByte;
pI2CBus->I2CPutByte = I830I2CPutByte;
pI2CBus->I2CStart = I830I2CStart;
pI2CBus->I2CStop = I830I2CStop;
pI2CBus->I2CAddress = I830I2CAddress;
#else
pI2CBus->I2CGetBits = i830I2CGetBits;
pI2CBus->I2CPutBits = i830I2CPutBits;
#endif
pI2CBus->DriverPrivate.uval = i2c_reg;
if (!xf86I2CBusInit(pI2CBus))

View File

@ -86,7 +86,6 @@ i830_lvds_save(ScrnInfoPtr pScrn, I830OutputPtr output)
{
I830Ptr pI830 = I830PTR(pScrn);
pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL);
pI830->savePP_ON = INREG(LVDSPP_ON);
pI830->savePP_OFF = INREG(LVDSPP_OFF);
pI830->saveLVDS = INREG(LVDS);
@ -115,7 +114,6 @@ i830_lvds_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
OUTREG(LVDSPP_ON, pI830->savePP_ON);
OUTREG(LVDSPP_OFF, pI830->savePP_OFF);
OUTREG(PP_CYCLE, pI830->savePP_CYCLE);
OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
OUTREG(LVDS, pI830->saveLVDS);
OUTREG(PP_CONTROL, pI830->savePP_CONTROL);
if (pI830->savePP_CONTROL & POWER_TARGET_ON)

View File

@ -384,27 +384,6 @@ i830GetModeListTail(DisplayModePtr pModeList)
return last;
}
/**
* Appends a list of modes to another mode list, without duplication.
*/
static void
i830AppendModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
DisplayModePtr addModes)
{
DisplayModePtr first = *modeList;
DisplayModePtr last = i830GetModeListTail(first);
if (addModes == NULL)
return;
if (first == NULL) {
*modeList = addModes;
} else {
last->next = addModes;
addModes->prev = last;
}
}
/**
* This function removes a mode from a list of modes. It should probably be
* moved to xf86Mode.c.

View File

@ -489,12 +489,13 @@ I830RandRCrtcNotify (RRCrtcPtr crtc)
struct _I830OutputRec *output;
RROutputPtr rrout;
int pipe = (int) crtc->devPrivate;
I830PipePtr pI830Pipe = &pI830->pipes[pipe];
int i, j;
DisplayModePtr pipeMode = &pI830->pipeCurMode[pipe];
DisplayModePtr pipeMode = &pI830Pipe->curMode;
int pipe_type;
x = pI830->pipeX[pipe];
y = pI830->pipeY[pipe];
x = pI830Pipe->x;
y = pI830Pipe->y;
rotation = RR_Rotate_0;
numOutputs = 0;
for (i = 0; i < pI830->num_outputs; i++)
@ -550,6 +551,7 @@ I830RandRCrtcSet (ScreenPtr pScreen,
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
int pipe = (int) (crtc->devPrivate);
I830PipePtr pI830Pipe = &pI830->pipes[pipe];
DisplayModePtr display_mode = mode ? mode->devPrivate : NULL;
/* Sync the engine before adjust mode */
@ -560,7 +562,7 @@ I830RandRCrtcSet (ScreenPtr pScreen,
if (display_mode != randrp->modes[pipe])
{
pI830->planeEnabled[pipe] = mode != NULL;
pI830Pipe->planeEnabled = mode != NULL;
if (display_mode)
{
if (!i830PipeSetMode (pScrn, display_mode, pipe, TRUE))
@ -833,18 +835,15 @@ I830RandRCreateScreenResources12 (ScreenPtr pScreen)
{
int mmWidth, mmHeight;
if (mode->HDisplay == pScreen->width &&
mode->VDisplay == pScreen->height)
{
mmWidth = pScrn->widthmm;
mmHeight = pScrn->heightmm;
}
else
{
#define MMPERINCH 25.4
mmWidth = (double) mode->HDisplay / pScrn->xDpi * MMPERINCH;
mmHeight = (double) mode->VDisplay / pScrn->yDpi * MMPERINCH;
}
mmWidth = pScreen->mmWidth;
mmHeight = pScreen->mmHeight;
if (mode->HDisplay != pScreen->width)
mmWidth = mmWidth * mode->HDisplay / pScreen->width;
if (mode->VDisplay == pScreen->height)
mmHeight = mmHeight * mode->VDisplay / pScreen->height;
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Setting screen physical size to %d x %d\n",
mmWidth, mmHeight);
I830RandRScreenSetSize (pScreen,
mode->HDisplay,
mode->VDisplay,

View File

@ -553,7 +553,7 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
output_dtd.part2.sync_off_width_high = 0;
output_dtd.part2.dtd_flags = 0x18;
output_dtd.part2.sdvo_flags = 0;
output_dtd.part2.v_sync_off_width = 0;
output_dtd.part2.v_sync_off_high = 0;
output_dtd.part2.reserved = 0;
if (mode->Flags & V_PHSYNC)
output_dtd.part2.dtd_flags |= 0x2;