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.
This commit is contained in:
Keith Packard 2007-05-17 15:00:12 -07:00
parent a441954630
commit e89d5f2754
8 changed files with 60 additions and 59 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
xf86OutputPtr output = NULL;
if (drv->type & I830_DVO_CHIP_LVDS) {
output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
"LVDS");
} else {
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");
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,
"TV");
break;
}
if (output == NULL) {
xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);

View File

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

View File

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

View File

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