diff options
-rw-r--r-- | src/i830.h | 14 | ||||
-rw-r--r-- | src/i830_crt.c | 8 | ||||
-rw-r--r-- | src/i830_dvo.c | 18 | ||||
-rw-r--r-- | src/i830_lvds.c | 8 | ||||
-rw-r--r-- | src/i830_sdvo.c | 22 |
5 files changed, 62 insertions, 8 deletions
@@ -211,6 +211,9 @@ typedef struct _I830SDVODriver { CARD32 output_device; /* SDVOB or SDVOC */ i830_sdvo_caps caps; + + CARD16 pixel_clock_min, pixel_clock_max; + int save_sdvo_mult; Bool save_sdvo_active_1, save_sdvo_active_2; i830_sdvo_dtd save_input_dtd_1, save_input_dtd_2; @@ -245,6 +248,17 @@ struct _I830OutputRec { void (*restore)(ScrnInfoPtr pScrn, I830OutputPtr output); /** + * Callback for testing a video mode for a given output. + * + * This function should only check for cases where a mode can't be supported + * on the pipe specifically, and not represent generic CRTC limitations. + * + * \return MODE_OK if the mode is valid, or another MODE_* otherwise. + */ + int (*mode_valid)(ScrnInfoPtr pScrn, I830OutputPtr output, + DisplayModePtr pMode); + + /** * Callback for setting up a video mode before any pipe/dpll changes. * * \param pMode the mode that will be set, or NULL if the mode to be set is diff --git a/src/i830_crt.c b/src/i830_crt.c index 1cf1687e..7721a0c2 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -76,6 +76,13 @@ i830_crt_restore(ScrnInfoPtr pScrn, I830OutputPtr output) OUTREG(ADPA, pI830->saveADPA); } +static int +i830_crt_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output, + DisplayModePtr pMode) +{ + return MODE_OK; +} + static void i830_crt_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output, DisplayModePtr pMode) @@ -114,6 +121,7 @@ i830_crt_init(ScrnInfoPtr pScrn) pI830->output[pI830->num_outputs].dpms = i830_crt_dpms; pI830->output[pI830->num_outputs].save = i830_crt_save; pI830->output[pI830->num_outputs].restore = i830_crt_restore; + pI830->output[pI830->num_outputs].mode_valid = i830_crt_mode_valid; pI830->output[pI830->num_outputs].pre_set_mode = i830_crt_pre_set_mode; pI830->output[pI830->num_outputs].post_set_mode = i830_crt_post_set_mode; diff --git a/src/i830_dvo.c b/src/i830_dvo.c index ea74337a..01858f2c 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -92,15 +92,22 @@ i830_dvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output) output->i2c_drv->vid_rec->RestoreRegs(output->i2c_drv->dev_priv); } +static int +i830_dvo_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output, + DisplayModePtr pMode) +{ + if (output->i2c_drv->vid_rec->ModeValid(output->i2c_drv->dev_priv, pMode)) + return MODE_OK; + else + return MODE_BAD; +} + static void i830_dvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output, DisplayModePtr pMode) { I830Ptr pI830 = I830PTR(pScrn); - if (output->i2c_drv == NULL) - return; - output->i2c_drv->vid_rec->Mode(output->i2c_drv->dev_priv, pMode); OUTREG(DVOC, INREG(DVOC) & ~DVO_ENABLE); @@ -179,8 +186,9 @@ i830_dvo_init(ScrnInfoPtr pScrn) pI830->output[i].dpms = i830_dvo_dpms; pI830->output[i].save = i830_dvo_save; pI830->output[i].restore = i830_dvo_restore; - pI830->output[i].pre_set_mode = i830_dvo_pre_set_mode ; - pI830->output[i].post_set_mode = i830_dvo_post_set_mode ; + pI830->output[i].mode_valid = i830_dvo_mode_valid; + pI830->output[i].pre_set_mode = i830_dvo_pre_set_mode; + pI830->output[i].post_set_mode = i830_dvo_post_set_mode; /* Set up the I2C and DDC buses */ ret = I830I2CInit(pScrn, &pI830->output[i].pI2CBus, GPIOE, "DVOI2C_E"); diff --git a/src/i830_lvds.c b/src/i830_lvds.c index 186d33b5..399324f0 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -123,6 +123,13 @@ i830_lvds_restore(ScrnInfoPtr pScrn, I830OutputPtr output) i830SetLVDSPanelPower(pScrn, FALSE); } +static int +i830_lvds_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output, + DisplayModePtr pMode) +{ + return MODE_OK; +} + static void i830_lvds_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output, DisplayModePtr pMode) @@ -178,6 +185,7 @@ i830_lvds_init(ScrnInfoPtr pScrn) pI830->output[pI830->num_outputs].dpms = i830_lvds_dpms; pI830->output[pI830->num_outputs].save = i830_lvds_save; pI830->output[pI830->num_outputs].restore = i830_lvds_restore; + pI830->output[pI830->num_outputs].mode_valid = i830_lvds_mode_valid; pI830->output[pI830->num_outputs].pre_set_mode = i830_lvds_pre_set_mode; pI830->output[pI830->num_outputs].post_set_mode = i830_lvds_post_set_mode; diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index 9a1e1550..76080dfa 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -545,7 +545,6 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output, CARD8 c16a[8]; CARD8 c17a[8]; CARD16 out_timings[6]; - CARD16 clock_min, clock_max; Bool out1, out2; I830SDVOPtr s = output->sdvo_drv; @@ -588,8 +587,6 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output, out_timings[5] = c17a[3] | ((short)c17a[2] << 8); I830SDVOSetTargetInput(s, FALSE, FALSE); - I830SDVOGetInputPixelClockRange(s, &clock_min, &clock_max); - ErrorF("clock min/max: %d %d\n", clock_min, clock_max); I830SDVOGetActiveOutputs(s, &out1, &out2); @@ -775,6 +772,21 @@ i830_sdvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output) sdvo->save_sdvo_active_2); } +static int +i830_sdvo_mode_valid(ScrnInfoPtr pScrn, I830OutputPtr output, + DisplayModePtr pMode) +{ + I830SDVOPtr sdvo = output->sdvo_drv; + + if (sdvo->pixel_clock_min > pMode->Clock) + return MODE_CLOCK_HIGH; + + if (sdvo->pixel_clock_max < pMode->Clock) + return MODE_CLOCK_LOW; + + return MODE_OK; +} + static void I830SDVOGetCapabilities(I830SDVOPtr s, i830_sdvo_caps *caps) { @@ -954,6 +966,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) pI830->output[pI830->num_outputs].dpms = i830_sdvo_dpms; pI830->output[pI830->num_outputs].save = i830_sdvo_save; pI830->output[pI830->num_outputs].restore = i830_sdvo_restore; + pI830->output[pI830->num_outputs].mode_valid = i830_sdvo_mode_valid; pI830->output[pI830->num_outputs].pre_set_mode = i830_sdvo_pre_set_mode; pI830->output[pI830->num_outputs].post_set_mode = i830_sdvo_post_set_mode; @@ -1042,6 +1055,9 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) I830SDVOGetCapabilities(sdvo, &sdvo->caps); + I830SDVOGetInputPixelClockRange(sdvo, &sdvo->pixel_clock_min, + &sdvo->pixel_clock_max); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SDVO device VID/DID: %02X:%02X.%02X, %02X," "output 1: %c, output 2: %c\n", |