summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@dulcimer.keithp.com>2007-05-17 15:00:12 -0700
committerKeith Packard <keithp@dulcimer.keithp.com>2007-05-17 15:00:12 -0700
commite89d5f275442915cc7777e75d3fcf7e7ed0f2084 (patch)
tree26ea06fdb3af64ce40003c234e9ba9b3e5dfecb0
parenta441954630c6cdabbf463bfc3404160f97a04b4f (diff)
Make each output control clones/crtcs. Split DVO into LVDS, TMDS, TV.
Move clone/crtc config into each output where it's easier to understand (no need for a switch statement in I830PrepareOutputs. Also, split DVO into three sub-types (TMDS, LVDS, TVOUT) as those have different cloning abilities.
-rw-r--r--src/i830.h17
-rw-r--r--src/i830_crt.c3
-rw-r--r--src/i830_display.c4
-rw-r--r--src/i830_driver.c46
-rw-r--r--src/i830_dvo.c42
-rw-r--r--src/i830_lvds.c3
-rw-r--r--src/i830_sdvo.c2
-rw-r--r--src/i830_tv.c2
8 files changed, 60 insertions, 59 deletions
diff --git a/src/i830.h b/src/i830.h
index 0fe5d414..ab52da0c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -191,15 +191,12 @@ typedef struct {
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
+#define I830_OUTPUT_DVO_TMDS 2
+#define I830_OUTPUT_DVO_LVDS 3
+#define I830_OUTPUT_DVO_TVOUT 4
+#define I830_OUTPUT_SDVO 5
+#define I830_OUTPUT_LVDS 6
+#define I830_OUTPUT_TVOUT 7
struct _I830DVODriver {
int type;
@@ -246,6 +243,8 @@ typedef struct _I830OutputPrivateRec {
I2CBusPtr pDDCBus;
struct _I830DVODriver *i2c_drv;
Bool load_detect_temp;
+ int pipe_mask;
+ int clone_mask;
/** Output-private structure. Should replace i2c_drv */
void *dev_priv;
} I830OutputPrivateRec, *I830OutputPrivatePtr;
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 879ae9f3..bbb4a830 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -394,6 +394,9 @@ i830_crt_init(ScrnInfoPtr pScrn)
return;
}
i830_output->type = I830_OUTPUT_ANALOG;
+ i830_output->pipe_mask = ((1 << 0) | (1 << 1));
+ i830_output->clone_mask = ((1 << I830_OUTPUT_ANALOG) |
+ (1 << I830_OUTPUT_DVO_TMDS));
output->driver_private = i830_output;
output->interlaceAllowed = FALSE;
diff --git a/src/i830_display.c b/src/i830_display.c
index 4b205ba3..9caab856 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -752,7 +752,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
case I830_OUTPUT_SDVO:
is_sdvo = TRUE;
break;
- case I830_OUTPUT_DVO:
+ case I830_OUTPUT_DVO_TMDS:
+ case I830_OUTPUT_DVO_LVDS:
+ case I830_OUTPUT_DVO_TVOUT:
is_dvo = TRUE;
break;
case I830_OUTPUT_TVOUT:
diff --git a/src/i830_driver.c b/src/i830_driver.c
index b4d9d086..2cbddb02 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -728,44 +728,20 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
{
xf86OutputPtr output = config->output[o];
I830OutputPrivatePtr intel_output = output->driver_private;
- int crtc_mask = 0, clone_mask = 0;
+ int crtc_mask;
+ int c;
- /*
- * Valid crtcs
- */
- switch (intel_output->type) {
- case I830_OUTPUT_DVO:
- case I830_OUTPUT_SDVO:
- crtc_mask = ((1 << 0)|
- (1 << 1));
- clone_mask = ((1 << I830_OUTPUT_ANALOG) |
- (1 << I830_OUTPUT_DVO) |
- (1 << I830_OUTPUT_SDVO));
- break;
- case I830_OUTPUT_ANALOG:
- crtc_mask = ((1 << 0));
- /*
- * 915 cannot do double-wide on pipe B
- * 830 cannot put CRT on pipe B
- */
- if (!IS_I915G(pI830) && !IS_I915GM (pI830) && !IS_I830(pI830))
- crtc_mask |= ((1 << 1));
- clone_mask = ((1 << I830_OUTPUT_ANALOG) |
- (1 << I830_OUTPUT_DVO) |
- (1 << I830_OUTPUT_SDVO));
- break;
- case I830_OUTPUT_LVDS:
- crtc_mask = (1 << 1);
- clone_mask = (1 << I830_OUTPUT_LVDS);
- break;
- case I830_OUTPUT_TVOUT:
- crtc_mask = ((1 << 0) |
- (1 << 1));
- clone_mask = (1 << I830_OUTPUT_TVOUT);
- break;
+ crtc_mask = 0;
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = config->crtc[c];
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+
+ if (intel_output->pipe_mask & (1 << intel_crtc->pipe))
+ crtc_mask |= (1 << c);
}
output->possible_crtcs = crtc_mask;
- output->possible_clones = i830_output_clones (pScrn, clone_mask);
+ output->possible_clones = i830_output_clones (pScrn, intel_output->clone_mask);
}
}
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index b69105e9..d81e5dd7 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -60,22 +60,22 @@ static const char *ch7017_symbols[] = {
/* driver list */
struct _I830DVODriver i830_dvo_drivers[] =
{
- {I830_DVO_CHIP_TMDS, "sil164", "SIL164VidOutput", DVOC,
+ {I830_OUTPUT_DVO_TMDS, "sil164", "SIL164VidOutput", DVOC,
(SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL},
- {I830_DVO_CHIP_TMDS | I830_DVO_CHIP_TVOUT, "ch7xxx", "CH7xxxVidOutput", DVOC,
+ {I830_OUTPUT_DVO_TMDS | I830_OUTPUT_DVO_TVOUT, "ch7xxx", "CH7xxxVidOutput", DVOC,
(CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL},
- {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods", DVOA,
+ {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods", DVOA,
0x04, ivch_symbols, NULL, NULL, NULL},
/*
- {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+ {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
0x44, ivch_symbols, NULL, NULL, NULL},
- {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+ {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
0x84, ivch_symbols, NULL, NULL, NULL},
- {I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
+ {I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
0xc4, ivch_symbols, NULL, NULL, NULL},
*/
/*
- { I830_DVO_CHIP_LVDS, "ch7017", "ch7017_methods",
+ { I830_OUTPUT_DVO_LVDS, "ch7017", "ch7017_methods",
0xea, ch7017_symbols, NULL, NULL, NULL }
*/
};
@@ -351,7 +351,6 @@ i830_dvo_init(ScrnInfoPtr pScrn)
intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
if (!intel_output)
return;
- intel_output->type = I830_OUTPUT_DVO;
/* Set up the DDC bus */
ret = I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "DVODDC_D");
@@ -374,7 +373,7 @@ i830_dvo_init(ScrnInfoPtr pScrn)
ret_ptr = NULL;
drv->vid_rec = LoaderSymbol(drv->fntablename);
- if (drv->type & I830_DVO_CHIP_LVDS)
+ if (drv->type == I830_OUTPUT_DVO_LVDS)
gpio = GPIOB;
else
gpio = GPIOE;
@@ -396,14 +395,29 @@ i830_dvo_init(ScrnInfoPtr pScrn)
ret_ptr = drv->vid_rec->init(pI2CBus, drv->address);
if (ret_ptr != NULL) {
- xf86OutputPtr output;
-
- if (drv->type & I830_DVO_CHIP_LVDS) {
+ xf86OutputPtr output = NULL;
+
+ intel_output->type = drv->type;
+ switch (drv->type) {
+ case I830_OUTPUT_DVO_TMDS:
+ intel_output->pipe_mask = ((1 << 0) | (1 << 1));
+ intel_output->clone_mask = ((1 << I830_OUTPUT_ANALOG) |
+ (1 << I830_OUTPUT_DVO_TMDS));
+ output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
+ "TMDS");
+ break;
+ case I830_OUTPUT_DVO_LVDS:
+ intel_output->pipe_mask = (1 << 1);
+ intel_output->clone_mask = (1 << I830_OUTPUT_DVO_LVDS);
output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
"LVDS");
- } else {
+ break;
+ case I830_OUTPUT_DVO_TVOUT:
+ intel_output->pipe_mask = (1 << 1);
+ intel_output->clone_mask = (1 << I830_OUTPUT_DVO_TVOUT);
output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
- "TMDS");
+ "TV");
+ break;
}
if (output == NULL) {
xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index e9098129..566c8689 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -445,6 +445,9 @@ i830_lvds_init(ScrnInfoPtr pScrn)
return;
}
intel_output->type = I830_OUTPUT_LVDS;
+ intel_output->pipe_mask = (1 << 1);
+ intel_output->clone_mask = (1 << I830_OUTPUT_LVDS);
+
output->driver_private = intel_output;
output->subpixel_order = SubPixelHorizontalRGB;
output->interlaceAllowed = FALSE;
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 43b55a09..24c9c99b 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -1179,6 +1179,8 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
dev_priv = (struct i830_sdvo_priv *) (intel_output + 1);
intel_output->type = I830_OUTPUT_SDVO;
+ intel_output->pipe_mask = ((1 << 0) | (1 << 1));
+ intel_output->clone_mask = (1 << I830_OUTPUT_SDVO);
/* While it's the same bus, we just initialize a new copy to avoid trouble
* with tracking refcounting ourselves, since the XFree86 DDX bits don't.
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 336214f1..b95986f0 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1669,6 +1669,8 @@ i830_tv_init(ScrnInfoPtr pScrn)
}
dev_priv = (struct i830_tv_priv *) (intel_output + 1);
intel_output->type = I830_OUTPUT_TVOUT;
+ intel_output->pipe_mask = ((1 << 0) | (1 << 1));
+ intel_output->clone_mask = (1 << I830_OUTPUT_TVOUT);
intel_output->dev_priv = dev_priv;
dev_priv->type = TV_TYPE_UNKNOWN;