summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2006-10-16 16:51:04 -0700
committerEric Anholt <eric@anholt.net>2006-10-16 16:51:04 -0700
commit8149681f2eac0af3b70a9457c5204e17da56142b (patch)
treea7634dbbf81c73d87324e01d0169dbbf8f940667 /src
parent1838671476875e9f5b3dde235eacf9fb43afb66c (diff)
Add a per-output mode-valid method.
This is currently disconnected, but will be used in more overhaul work. This should be where any output limitations, such as clocks, resolution, scaling limits, or other options, are validated. Other limitations, such as chipset resolution limits, CRTC clock limits, etc. should be elsewhere.
Diffstat (limited to 'src')
-rw-r--r--src/i830.h14
-rw-r--r--src/i830_crt.c8
-rw-r--r--src/i830_dvo.c18
-rw-r--r--src/i830_lvds.c8
-rw-r--r--src/i830_sdvo.c22
5 files changed, 62 insertions, 8 deletions
diff --git a/src/i830.h b/src/i830.h
index c41cb569..90fdcb85 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -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",