summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <anholt@FreeBSD.org>2006-03-23 11:31:24 -0800
committerEric Anholt <anholt@leguin.anholt.net>2006-04-06 15:58:59 -0700
commit8411c126ae66239f8b3a2261e338a723c36aa44f (patch)
tree48a44b9e36e7b84fc8852b6f457bda7b203ccdd4
parent6414ad89b9d368a032adf2358a65404f5443ef35 (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.h43
-rw-r--r--src/i830_driver.c176
2 files changed, 143 insertions, 76 deletions
diff --git a/src/i830.h b/src/i830.h
index d3d1f5a3..f971638c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -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;
}
}