From 85e32ad2dadcce1134fcadb14ece8ff30f3925f2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 2 Nov 2006 11:56:12 -0800 Subject: [PATCH 01/10] ch7xxxSaveRegs receives real type instead of void * --- src/ch7xxx/ch7xxx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 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; From 786ec54c4c1540f4aced63ef21d567c3b9f3282e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 2 Nov 2006 11:56:50 -0800 Subject: [PATCH 02/10] Add a few more registers from the 965 spec --- src/i810_reg.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/i810_reg.h b/src/i810_reg.h index 34e6e536..31f88859 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) @@ -849,6 +851,28 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 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) @@ -856,6 +880,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 +946,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 +1600,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 +1621,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) From 2636d68663a02f6d9eaf36971706b67036ebf56c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 2 Nov 2006 11:57:11 -0800 Subject: [PATCH 03/10] Dump more registers for debug purposes --- src/i830_debug.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/src/i830_debug.c b/src/i830_debug.c index a48e9f2f..802330e9 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,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"); } From 87b15cfbf762468d4b8728b3e7a39c76654017de Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 2 Nov 2006 11:30:21 -0800 Subject: [PATCH 04/10] Remove dead specifiedMonitor field. --- src/i830.h | 1 - src/i830_driver.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/i830.h b/src/i830.h index a07ba8ea..bb17f3fd 100644 --- a/src/i830.h +++ b/src/i830.h @@ -397,7 +397,6 @@ typedef struct _I830Rec { int MonType1; int MonType2; - Bool specifiedMonitor; DGAModePtr DGAModes; int numDGAModes; diff --git a/src/i830_driver.c b/src/i830_driver.c index 3612af76..779037b0 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1279,7 +1279,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->MonType1 = PIPE_NONE; pI830->MonType2 = PIPE_NONE; - pI830->specifiedMonitor = FALSE; if ((s = xf86GetOptValString(pI830->Options, OPTION_MONITOR_LAYOUT)) && I830IsPrimary(pScrn)) { @@ -1366,7 +1365,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. * From 7887c76062b7c79e14fb8e4f13486aa592dcbce8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 2 Nov 2006 12:27:21 -0800 Subject: [PATCH 05/10] Add airlied's I2C code, ifdeffed out. I've gone back to compare our behavior to it several times, so I'll just keep the code in tree for now. --- src/i810_reg.h | 2 + src/i830_i2c.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+) diff --git a/src/i810_reg.h b/src/i810_reg.h index 31f88859..11c06596 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -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) diff --git a/src/i830_i2c.c b/src/i830_i2c.c index cee7bb51..8b93c8e6 100644 --- a/src/i830_i2c.c +++ b/src/i830_i2c.c @@ -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)) From a9eac38bcdb49df2ce1122b49bd8b1eb19e8cae5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 2 Nov 2006 13:24:54 -0800 Subject: [PATCH 06/10] Remove duplicated register defs that were just added. --- src/i810_reg.h | 14 -------------- src/i830_debug.c | 5 ++--- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/i810_reg.h b/src/i810_reg.h index 11c06596..d6f7147b 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -853,20 +853,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 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 diff --git a/src/i830_debug.c b/src/i830_debug.c index 802330e9..7922af0a 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -59,7 +59,6 @@ static struct i830SnapshotRec { DEFINEREG(DSPFW1), DEFINEREG(DSPFW2), DEFINEREG(DSPFW3), - DEFINEREG(ADPA), DEFINEREG(LVDS), @@ -90,7 +89,7 @@ static struct i830SnapshotRec { DEFINEREG(FPA0), DEFINEREG(FPA1), DEFINEREG(DPLL_A), - DEFINEREG(DPLLAMD), + DEFINEREG(DPLL_A_MD), DEFINEREG(HTOTAL_A), DEFINEREG(HBLANK_A), DEFINEREG(HSYNC_A), @@ -113,7 +112,7 @@ static struct i830SnapshotRec { DEFINEREG(FPB0), DEFINEREG(FPB1), DEFINEREG(DPLL_B), - DEFINEREG(DPLLBMD), + DEFINEREG(DPLL_B_MD), DEFINEREG(HTOTAL_B), DEFINEREG(HBLANK_B), DEFINEREG(HSYNC_B), From f22d9bcc25aea19ba38d35282367b591fd1b7ca0 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 2 Nov 2006 13:34:45 -0800 Subject: [PATCH 07/10] Add another couple of new registers --- src/i810_reg.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/i810_reg.h b/src/i810_reg.h index d6f7147b..e126904f 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -1652,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 From 56f6d4f1bb67f447500af3f4f7fa557c3e887baa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 2 Nov 2006 13:42:17 -0800 Subject: [PATCH 08/10] Disable the panel fitter when not using it. Cleans up SDVO DVI output. The panel fitter appears to exist on the 965 hardware (at least) and causes troubles with DVI output over SDVO when enabled. This patch checks to see if the panel fitter is pointing at the pipe being configured and disables it unconditionally in that case. The LVDS driver will configure it correctly if necessary afterwards. --- src/i830_display.c | 10 ++++++++++ src/i830_driver.c | 4 ++++ src/i830_lvds.c | 2 -- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/i830_display.c b/src/i830_display.c index b3019f80..4716e865 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -607,6 +607,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); diff --git a/src/i830_driver.c b/src/i830_driver.c index 779037b0..4fb8ac26 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2308,6 +2308,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]); @@ -2426,6 +2428,8 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(SWF31, pI830->saveSWF[15]); OUTREG(SWF32, pI830->saveSWF[16]); + OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL); + i830CompareRegsToSnapshot(pScrn); return TRUE; diff --git a/src/i830_lvds.c b/src/i830_lvds.c index 7b9fe634..ea45420f 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -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) From 2c9ab6e0594769274f2dbcdf7c00fe297fc385d5 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 2 Nov 2006 13:44:55 -0800 Subject: [PATCH 09/10] set the v_sync_off_high to zero. XXX should check docs --- src/i830_sdvo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index eda28579..da611590 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -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; From 9681602177124e84a817a1e1d428f1779f2a45c9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 3 Nov 2006 12:55:25 -0800 Subject: [PATCH 10/10] Create I830PipeRec to hold pipe-specific data. Remove unused I830 members. I830 contained six parallel arrays for pipe-specific data; these have been moved to a I830PipeRec structure instead. I830 also contained several unused members: unsigned int bios_version; Bool newPipeSwitch; Bool fakeSwitch; int fixedPipe; These have been removed, along with the code that set them. --- src/i830.h | 28 +++++------ src/i830_cursor.c | 35 +++++++------ src/i830_display.c | 119 +++++++++++++++++---------------------------- src/i830_dri.c | 2 +- src/i830_driver.c | 35 ++++--------- src/i830_modes.c | 21 -------- src/i830_randr.c | 31 ++++++------ 7 files changed, 101 insertions(+), 170 deletions(-) diff --git a/src/i830.h b/src/i830.h index bb17f3fd..b4b17ded 100644 --- a/src/i830.h +++ b/src/i830.h @@ -287,31 +287,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; @@ -478,8 +476,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; diff --git a/src/i830_cursor.c b/src/i830_cursor.c index 92239f1b..0b7e772b 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -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); diff --git a/src/i830_display.c b/src/i830_display.c index 4716e865..1175cf10 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -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; } /** @@ -363,6 +364,7 @@ Bool i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) { 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; @@ -391,7 +393,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", @@ -576,7 +578,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) FatalError("unknown display bpp\n"); } - if (pI830->gammaEnabled[pipe]) { + if (pI830Pipe->gammaEnabled) { dspcntr |= DISPPLANE_GAMMA_ENABLE; } @@ -626,7 +628,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 */ @@ -636,7 +638,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) /* And then turn the plane on */ OUTREG(dspcntr_reg, dspcntr); - pI830->pipeCurMode[pipe] = *pMode; + pI830Pipe->curMode = *pMode; return TRUE; } @@ -658,63 +660,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) @@ -732,31 +720,17 @@ 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); - if (!ok) - goto done; - } - if (pI830->planeEnabled[1]) { - ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, 1, pMode), - 1); + for (i = 0; i < MAX_DISPLAY_PIPES; i++) + { + if (pI830->pipes[i].planeEnabled) + ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i, pMode), + i); if (!ok) goto done; } @@ -776,13 +750,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) @@ -821,7 +792,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'); } diff --git a/src/i830_dri.c b/src/i830_dri.c index c9b52c48..41ea21ca 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -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; diff --git a/src/i830_driver.c b/src/i830_driver.c index 4fb8ac26..3b219748 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -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,16 +1266,6 @@ 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; @@ -1681,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])) { @@ -3400,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"); @@ -3431,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; @@ -3584,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; @@ -3633,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; diff --git a/src/i830_modes.c b/src/i830_modes.c index 0bb17a54..b6867c3c 100644 --- a/src/i830_modes.c +++ b/src/i830_modes.c @@ -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. diff --git a/src/i830_randr.c b/src/i830_randr.c index 59ebcc08..67641d6a 100644 --- a/src/i830_randr.c +++ b/src/i830_randr.c @@ -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)) @@ -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,