Move the ivch's fixed panel mode support to i830_dvo.c for other LVDS drivers.
This also results in removal of the setup hook, which was being called unconditionally and breaking non-ivch dvo drivers.
This commit is contained in:
parent
ec236c76b9
commit
f8d7cbc6e1
|
|
@ -30,12 +30,6 @@ typedef struct _I830I2CVidOutputRec {
|
|||
* Returns NULL if the device does not exist.
|
||||
*/
|
||||
void *(*init)(I2CBusPtr b, I2CSlaveAddr addr);
|
||||
|
||||
/**
|
||||
* Setup the device for use, after the relevant output has been created
|
||||
*/
|
||||
Bool
|
||||
(*setup) (I2CDevPtr d, xf86OutputPtr output);
|
||||
|
||||
/**
|
||||
* Called to allow the output a chance to create properties after the
|
||||
|
|
|
|||
|
|
@ -209,6 +209,8 @@ struct _I830DVODriver {
|
|||
I830I2CVidOutputRec *vid_rec;
|
||||
void *dev_priv;
|
||||
pointer modhandle;
|
||||
DisplayModePtr panel_fixed_mode;
|
||||
Bool panel_wants_dither;
|
||||
};
|
||||
|
||||
extern const char *i830_output_type_names[];
|
||||
|
|
|
|||
|
|
@ -60,20 +60,30 @@ static const char *ch7017_symbols[] = {
|
|||
/* driver list */
|
||||
struct _I830DVODriver i830_dvo_drivers[] =
|
||||
{
|
||||
{I830_OUTPUT_DVO_TMDS, "sil164", "SIL164VidOutput", DVOC,
|
||||
(SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL},
|
||||
{I830_OUTPUT_DVO_TMDS | I830_OUTPUT_DVO_TVOUT, "ch7xxx", "CH7xxxVidOutput", DVOC,
|
||||
(CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL},
|
||||
{I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods", DVOA,
|
||||
0x04, ivch_symbols, NULL, NULL, NULL},
|
||||
/*
|
||||
{I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
|
||||
0x44, ivch_symbols, NULL, NULL, NULL},
|
||||
{I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
|
||||
0x84, ivch_symbols, NULL, NULL, NULL},
|
||||
{I830_OUTPUT_DVO_LVDS, "ivch", "ivch_methods",
|
||||
0xc4, ivch_symbols, NULL, NULL, NULL},
|
||||
*/
|
||||
{
|
||||
.type = I830_OUTPUT_DVO_TMDS,
|
||||
.modulename = "sil164",
|
||||
.fntablename = "SIL164VidOutput",
|
||||
.dvo_reg = DVOC,
|
||||
.address = (SIL164_ADDR_1<<1),
|
||||
.symbols = SIL164Symbols
|
||||
},
|
||||
{
|
||||
.type = I830_OUTPUT_DVO_TMDS,
|
||||
.modulename = "ch7xxx",
|
||||
.fntablename = "CH7xxxVidOutput",
|
||||
.dvo_reg = DVOC,
|
||||
.address = (CH7xxx_ADDR_1<<1),
|
||||
.symbols = CH7xxxSymbols
|
||||
},
|
||||
{
|
||||
.type = I830_OUTPUT_DVO_LVDS,
|
||||
.modulename = "ivch",
|
||||
.fntablename = "ivch_methods",
|
||||
.dvo_reg = DVOA,
|
||||
.address = 0x04, /* Might also be 0x44, 0x84, 0xc4 */
|
||||
.symbols = ivch_symbols
|
||||
},
|
||||
/*
|
||||
{ I830_OUTPUT_DVO_LVDS, "ch7017", "ch7017_methods",
|
||||
0xea, ch7017_symbols, NULL, NULL, NULL }
|
||||
|
|
@ -140,6 +150,7 @@ static int
|
|||
i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
|
||||
{
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct _I830DVODriver *drv = intel_output->i2c_drv;
|
||||
void *dev_priv = intel_output->i2c_drv->dev_priv;
|
||||
|
||||
if (pMode->Flags & V_DBLSCAN)
|
||||
|
|
@ -147,6 +158,13 @@ i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
|
|||
|
||||
/* XXX: Validate clock range */
|
||||
|
||||
if (drv->panel_fixed_mode) {
|
||||
if (pMode->HDisplay > drv->panel_fixed_mode->HDisplay)
|
||||
return MODE_PANEL;
|
||||
if (pMode->VDisplay > drv->panel_fixed_mode->VDisplay)
|
||||
return MODE_PANEL;
|
||||
}
|
||||
|
||||
return intel_output->i2c_drv->vid_rec->mode_valid(dev_priv, pMode);
|
||||
}
|
||||
|
||||
|
|
@ -155,6 +173,25 @@ i830_dvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
|
|||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct _I830DVODriver *drv = intel_output->i2c_drv;
|
||||
|
||||
/* If we have timings from the BIOS for the panel, put them in
|
||||
* to the adjusted mode. The CRTC will be set up for this mode,
|
||||
* with the panel scaling set up to source from the H/VDisplay
|
||||
* of the original mode.
|
||||
*/
|
||||
if (drv->panel_fixed_mode != NULL) {
|
||||
adjusted_mode->HDisplay = drv->panel_fixed_mode->HDisplay;
|
||||
adjusted_mode->HSyncStart = drv->panel_fixed_mode->HSyncStart;
|
||||
adjusted_mode->HSyncEnd = drv->panel_fixed_mode->HSyncEnd;
|
||||
adjusted_mode->HTotal = drv->panel_fixed_mode->HTotal;
|
||||
adjusted_mode->VDisplay = drv->panel_fixed_mode->VDisplay;
|
||||
adjusted_mode->VSyncStart = drv->panel_fixed_mode->VSyncStart;
|
||||
adjusted_mode->VSyncEnd = drv->panel_fixed_mode->VSyncEnd;
|
||||
adjusted_mode->VTotal = drv->panel_fixed_mode->VTotal;
|
||||
adjusted_mode->Clock = drv->panel_fixed_mode->Clock;
|
||||
xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
|
||||
}
|
||||
|
||||
if (intel_output->i2c_drv->vid_rec->mode_fixup)
|
||||
return intel_output->i2c_drv->vid_rec->mode_fixup (intel_output->i2c_drv->dev_priv,
|
||||
|
|
@ -235,6 +272,7 @@ static DisplayModePtr
|
|||
i830_dvo_get_modes(xf86OutputPtr output)
|
||||
{
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct _I830DVODriver *drv = intel_output->i2c_drv;
|
||||
DisplayModePtr modes;
|
||||
|
||||
/* We should probably have an i2c driver get_modes function for those
|
||||
|
|
@ -253,6 +291,9 @@ i830_dvo_get_modes(xf86OutputPtr output)
|
|||
return modes;
|
||||
}
|
||||
|
||||
if (drv->panel_fixed_mode != NULL)
|
||||
return xf86DuplicateMode(drv->panel_fixed_mode);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -436,7 +477,19 @@ i830_dvo_init(ScrnInfoPtr pScrn)
|
|||
drv->dev_priv = ret_ptr;
|
||||
intel_output->i2c_drv = drv;
|
||||
intel_output->pI2CBus = pI2CBus;
|
||||
drv->vid_rec->setup (drv->dev_priv, output);
|
||||
|
||||
if (intel_output->type == I830_OUTPUT_DVO_LVDS) {
|
||||
/* For our LVDS chipsets, we should hopefully be able to
|
||||
* dig the fixed panel mode out of the BIOS data. However,
|
||||
* it's in a different format from the BIOS data on chipsets
|
||||
* with integrated LVDS (stored in AIM headers, liekly),
|
||||
* so for now, just get the current mode being output through
|
||||
* DVO.
|
||||
*/
|
||||
drv->panel_fixed_mode = i830_dvo_get_current_mode(output);
|
||||
drv->panel_wants_dither = TRUE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
xf86UnloadSubModule(drv->modhandle);
|
||||
|
|
|
|||
|
|
@ -49,9 +49,6 @@ struct ivch_priv {
|
|||
|
||||
xf86OutputPtr output;
|
||||
|
||||
DisplayModePtr panel_fixed_mode;
|
||||
Bool panel_wants_dither;
|
||||
|
||||
CARD16 width;
|
||||
CARD16 height;
|
||||
|
||||
|
|
@ -189,6 +186,9 @@ ivch_init(I2CBusPtr b, I2CSlaveAddr addr)
|
|||
goto out;
|
||||
}
|
||||
|
||||
ivch_read(priv, VR20, &priv->width);
|
||||
ivch_read(priv, VR21, &priv->height);
|
||||
|
||||
return priv;
|
||||
|
||||
out:
|
||||
|
|
@ -196,60 +196,18 @@ out:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/** Gets the panel mode */
|
||||
static Bool
|
||||
ivch_setup (I2CDevPtr d, xf86OutputPtr output)
|
||||
{
|
||||
struct ivch_priv *priv = d->DriverPrivate.ptr;
|
||||
|
||||
priv->output = output;
|
||||
ivch_read (priv, VR20, &priv->width);
|
||||
ivch_read (priv, VR21, &priv->height);
|
||||
|
||||
priv->panel_fixed_mode = i830_bios_get_panel_mode (output->scrn, &priv->panel_wants_dither);
|
||||
if (!priv->panel_fixed_mode)
|
||||
{
|
||||
priv->panel_fixed_mode = i830_dvo_get_current_mode (output);
|
||||
priv->panel_wants_dither = TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static xf86OutputStatus
|
||||
ivch_detect(I2CDevPtr d)
|
||||
{
|
||||
return XF86OutputStatusConnected;
|
||||
}
|
||||
|
||||
static DisplayModePtr
|
||||
ivch_get_modes (I2CDevPtr d)
|
||||
{
|
||||
struct ivch_priv *priv = d->DriverPrivate.ptr;
|
||||
|
||||
if (priv->panel_fixed_mode)
|
||||
return xf86DuplicateMode (priv->panel_fixed_mode);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ModeStatus
|
||||
ivch_mode_valid(I2CDevPtr d, DisplayModePtr mode)
|
||||
{
|
||||
struct ivch_priv *priv = d->DriverPrivate.ptr;
|
||||
DisplayModePtr panel_fixed_mode = priv->panel_fixed_mode;
|
||||
|
||||
if (mode->Clock > 112000)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
if (panel_fixed_mode)
|
||||
{
|
||||
if (mode->HDisplay > panel_fixed_mode->HDisplay)
|
||||
return MODE_PANEL;
|
||||
if (mode->VDisplay > panel_fixed_mode->VDisplay)
|
||||
return MODE_PANEL;
|
||||
}
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
|
|
@ -291,33 +249,6 @@ ivch_dpms(I2CDevPtr d, int mode)
|
|||
usleep (16 * 1000);
|
||||
}
|
||||
|
||||
static Bool
|
||||
ivch_mode_fixup(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
|
||||
{
|
||||
struct ivch_priv *priv = d->DriverPrivate.ptr;
|
||||
DisplayModePtr panel_fixed_mode = priv->panel_fixed_mode;
|
||||
|
||||
/* If we have timings from the BIOS for the panel, put them in
|
||||
* to the adjusted mode. The CRTC will be set up for this mode,
|
||||
* with the panel scaling set up to source from the H/VDisplay
|
||||
* of the original mode.
|
||||
*/
|
||||
if (panel_fixed_mode != NULL) {
|
||||
adjusted_mode->HDisplay = panel_fixed_mode->HDisplay;
|
||||
adjusted_mode->HSyncStart = panel_fixed_mode->HSyncStart;
|
||||
adjusted_mode->HSyncEnd = panel_fixed_mode->HSyncEnd;
|
||||
adjusted_mode->HTotal = panel_fixed_mode->HTotal;
|
||||
adjusted_mode->VDisplay = panel_fixed_mode->VDisplay;
|
||||
adjusted_mode->VSyncStart = panel_fixed_mode->VSyncStart;
|
||||
adjusted_mode->VSyncEnd = panel_fixed_mode->VSyncEnd;
|
||||
adjusted_mode->VTotal = panel_fixed_mode->VTotal;
|
||||
adjusted_mode->Clock = panel_fixed_mode->Clock;
|
||||
xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ivch_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode)
|
||||
{
|
||||
|
|
@ -420,14 +351,11 @@ ivch_restore(I2CDevPtr d)
|
|||
|
||||
I830I2CVidOutputRec ivch_methods = {
|
||||
.init = ivch_init,
|
||||
.setup = ivch_setup,
|
||||
.dpms = ivch_dpms,
|
||||
.save = ivch_save,
|
||||
.restore = ivch_restore,
|
||||
.mode_valid = ivch_mode_valid,
|
||||
.mode_fixup = ivch_mode_fixup,
|
||||
.mode_set = ivch_mode_set,
|
||||
.detect = ivch_detect,
|
||||
.get_modes = ivch_get_modes,
|
||||
.dump_regs = ivch_dump_regs,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue