diff options
author | Eric Anholt <anholt@FreeBSD.org> | 2006-03-23 11:31:24 -0800 |
---|---|---|
committer | Eric Anholt <anholt@leguin.anholt.net> | 2006-04-06 15:58:59 -0700 |
commit | 8411c126ae66239f8b3a2261e338a723c36aa44f (patch) | |
tree | 48a44b9e36e7b84fc8852b6f457bda7b203ccdd4 | |
parent | 6414ad89b9d368a032adf2358a65404f5443ef35 (diff) |
Update to newer airlied DDC code, and do some cleanups as well. Now tries DDC
on LVDS, though my current LVDS gives no results.
-rw-r--r-- | src/i830.h | 43 | ||||
-rw-r--r-- | src/i830_driver.c | 176 |
2 files changed, 143 insertions, 76 deletions
@@ -157,41 +157,55 @@ typedef struct { /* store information about an Ixxx DVO */ /* The i830->i865 use multiple DVOs with multiple i2cs */ /* the i915, i945 have a single sDVO i2c bus - which is different */ -#define MAX_DVOS 4 +#define MAX_OUTPUTS 6 #define I830_I2C_BUS_DVO 1 #define I830_I2C_BUS_SDVO 2 +/* these are outputs from the chip - integrated only + external chips are via DVO or SDVO output */ +#define I830_OUTPUT_UNUSED 0 +#define I830_OUTPUT_ANALOG 1 +#define I830_OUTPUT_DVO 2 +#define I830_OUTPUT_SDVO 3 +#define I830_OUTPUT_LVDS 4 +#define I830_OUTPUT_TVOUT 5 + #define I830_DVO_CHIP_NONE 0 #define I830_DVO_CHIP_LVDS 1 #define I830_DVO_CHIP_TMDS 2 #define I830_DVO_CHIP_TVOUT 4 -struct _I830RegI2CDriver { +struct _I830DVODriver { int type; char *modulename; char *fntablename; int address; const char **symbols; +#if 0 + I830I2CVidOutputRec *vid_rec; +#endif void *devpriv; pointer modhandle; }; - -struct _I830DVORec { - int bus_type; - int flags; - I2CBusPtr pI2CBus; - I2CBusPtr pDDCBus; - xf86MonPtr MonInfo; - struct _I830RegI2CDriver *i2c_drv; -}; -typedef struct _I830SDVORec { +typedef struct _I830SDVODriver { int found; I2CDevRec d; unsigned char sdvo_regs[20]; } I830SDVORec, *I830SDVOPtr; +struct _I830OutputRec { + int type; + int pipe; + int flags; + xf86MonPtr MonInfo; + I2CBusPtr pI2CBus; + I2CBusPtr pDDCBus; + struct _I830DVODriver *i2c_drv; + struct _I830SDVODriver *sdvo_drv; +}; + typedef struct _I830Rec { unsigned char *MMIOBase; unsigned char *FbBase; @@ -412,9 +426,8 @@ typedef struct _I830Rec { OsTimerPtr devicesTimer; int ddc2; - int num_dvos; - - struct _I830DVORec dvos[MAX_DVOS]; + int num_outputs; + struct _I830OutputRec output[MAX_OUTPUTS]; I830SDVOPtr sdvo; CARD32 saveDSPACNTR; diff --git a/src/i830_driver.c b/src/i830_driver.c index f05e273f..ee5c635b 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -269,6 +269,15 @@ static OptionInfoRec I830BIOSOptions[] = { }; /* *INDENT-ON* */ +static const char *output_type_names[] = { + "Unused", + "Analog", + "DVO", + "SDVO", + "LVDS", + "TVOUT", +}; + static void I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); static void i830AdjustFrame(int scrnIndex, int x, int y, int flags); @@ -1916,6 +1925,58 @@ I830UseDDC(ScrnInfoPtr pScrn) return mon_range->max_clock; } +static void +I830SetupOutputBusses(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + /* everyone has at least a single analog output */ + pI830->num_outputs = 1; + pI830->output[0].type = I830_OUTPUT_ANALOG; + + /* setup the DDC bus for the analog output */ + I830I2CInit(pScrn, &pI830->output[0].pDDCBus, GPIOA, "CRTDDC_A"); + + /* need to add the output busses for each device + * - this function is very incomplete + * - i915GM has LVDS and TVOUT for example + */ + switch(pI830->PciInfo->chipType) { + case PCI_CHIP_I830_M: + case PCI_CHIP_845_G: + case PCI_CHIP_I855_GM: + case PCI_CHIP_I865_G: + pI830->num_outputs = 2; + pI830->output[1].type = I830_OUTPUT_DVO; + I830I2CInit(pScrn, &pI830->output[1].pDDCBus, GPIOD, "DVODDC_D"); + I830I2CInit(pScrn, &pI830->output[1].pI2CBus, GPIOE, "DVOI2C_E"); + break; + case PCI_CHIP_E7221_G: + /* ??? */ + break; + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + pI830->num_outputs = 2; + pI830->output[1].type = I830_OUTPUT_LVDS; + I830I2CInit(pScrn, &pI830->output[1].pDDCBus, GPIOC, "LVDSDDC_C"); + break; +#if 0 + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + /* SDVO ports have a single control bus */ + pI830->num_outputs = 2; + pI830->output[1].type = I830_OUTPUT_SDVO; + I830I2CInit(pScrn, &pI830->output[1].pI2CBus, GPIOE, "SDVOCTRL_E"); + + pI830->output[1].sdvo_drv = I830SDVOInit(pI830->output[1].pI2CBus); + ret = I830I2CDetectSDVOController(pScrn, 1); + if (ret == TRUE) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found sDVO\n"); + break; +#endif + } +} + void I830PreInitDDC(ScrnInfoPtr pScrn) { @@ -1932,41 +1993,9 @@ I830PreInitDDC(ScrnInfoPtr pScrn) /* Load I2C if we have the code to use it */ if (pI830->ddc2) { if (xf86LoadSubModule(pScrn, "i2c")) { - xf86LoaderReqSymLists(I810i2cSymbols,NULL); - - pI830->num_dvos = 1; - pI830->dvos[0].bus_type = I830_I2C_BUS_DVO; - /* setup the common CRT DVO */ - pI830->ddc2 = I830I2CInit(pScrn, &pI830->dvos[0].pDDCBus, GPIOA, "DDCGPIOA"); - if (pI830->ddc2 == FALSE) - return; - pI830->ddc2 = I830I2CInit(pScrn, &pI830->dvos[0].pI2CBus, GPIOB, "I2CGPIOB"); - if (pI830->ddc2 == FALSE) - return; - - if (!(IS_I9XX(pI830))) { - pI830->dvos[1].bus_type = I830_I2C_BUS_DVO; - pI830->num_dvos = 2; - - pI830->ddc2 = I830I2CInit(pScrn, &pI830->dvos[1].pDDCBus, GPIOD, "DDCGPIOD"); - if (pI830->ddc2 == FALSE) - return; - pI830->ddc2 = I830I2CInit(pScrn, &pI830->dvos[1].pI2CBus, GPIOE, "I2CGPIOE"); - if (pI830->ddc2 == FALSE) - return; - } -#if 0 - else { - pointer ret_p; - pI830->num_dvos = 2; - pI830->dvos[1].bus_type = I830_I2C_BUS_SDVO; - /* i915 has sDVO */ - pI830->ddc2 = I830I2CInit(pScrn, &pI830->dvos[1].pI2CBus, GPIOE, "SDVOCTRL"); - if (pI830->ddc2 = FALSE) - return; - pI830->sdvo=I830SDVOInit(pI830->dvos[1].pI2CBus); - } -#endif + xf86LoaderReqSymLists(I810i2cSymbols, NULL); + + I830SetupOutputBusses(pScrn); pI830->ddc2 = TRUE; } else { @@ -1978,42 +2007,67 @@ I830PreInitDDC(ScrnInfoPtr pScrn) void I830DetectMonitors(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - int i; + int i, ret; if (!pI830->ddc2) return; - for (i=0; i<pI830->num_dvos; i++) { - /* we can't do EDID on sDVO yet */ - if (pI830->dvos[i].bus_type == I830_I2C_BUS_DVO) { - pI830->dvos[i].MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, - pI830->dvos[i].pDDCBus); - - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "checking DVO %d, %08X\n", i, - pI830->dvos[i].pDDCBus->DriverPrivate.uval); - xf86PrintEDID(pI830->dvos[i].MonInfo); - -#if 0 + for (i=0; i<pI830->num_outputs; i++) { + switch (pI830->output[i].type) { + case I830_OUTPUT_ANALOG: + case I830_OUTPUT_LVDS: + /* for an analog/LVDS output, just do DDC */ + pI830->output[i].MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, + pI830->output[i].pDDCBus); + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DDC %s %d, %08X\n", + output_type_names[pI830->output[i].type], i, + pI830->output[i].pDDCBus->DriverPrivate.uval); + xf86PrintEDID(pI830->output[i].MonInfo); + break; + case I830_OUTPUT_DVO: + /* check for DDC */ + pI830->output[i].MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, + pI830->output[i].pDDCBus); + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DDC DVO %d, %08lX\n", i, + pI830->output[i].pDDCBus->DriverPrivate.uval); + xf86PrintEDID(pI830->output[i].MonInfo); + /* if we are on an i2C bus > 0 and we see a monitor - try to * find a controller chip */ - if (i > 0 && pI830->dvos[i].MonInfo) { - ret = I830I2CDetectControllers(pScrn, pI830->dvos[i].pI2CBus, - &pI830->dvos[i].i2c_drv); + if (pI830->output[i].MonInfo) { + ret = I830I2CDetectDVOControllers(pScrn, pI830->output[i].pI2CBus, + &pI830->output[i].i2c_drv); if (ret==TRUE) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found i2c %s on %08X\n", pI830->dvos[i].i2c_drv->modulename, pI830->dvos[i].pI2CBus->DriverPrivate.uval); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found i2c %s on %08X\n", + pI830->output[i].i2c_drv->modulename, + pI830->output[i].pI2CBus->DriverPrivate.uval); } } -#endif - } + break; #if 0 - else { - ret = I830I2CDetectSDVOController(pScrn, pI830->dvos[i].pI2CBus); - if (ret==TRUE) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found sDVO\n"); + case I830_OUTPUT_SDVO: + if (pI830->output[i].sdvo_drv->found) { + I830SDVOSetupDDC(pI830->output[i].sdvo_drv); + + pI830->output[i].MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, + pI830->output[i].pI2CBus); + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DDC SDVO %d, %08X\n", i, + pI830->output[i].pI2CBus->DriverPrivate.uval); + xf86PrintEDID(pI830->output[i].MonInfo); } - } + break; #endif + case I830_OUTPUT_UNUSED: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unknown or unhandled output device at %d\n", i); + break; + } } } @@ -2502,9 +2556,9 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) I830DetectMonitors(pScrn); - for (i=0; i<MAX_DVOS; i++) { - if (pI830->dvos[i].MonInfo) { - pScrn->monitor->DDC = pI830->dvos[i].MonInfo; + for (i = 0; i < MAX_OUTPUTS; i++) { + if (pI830->output[i].MonInfo) { + pScrn->monitor->DDC = pI830->output[i].MonInfo; break; } } |