summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i830.h2
-rw-r--r--src/i830_crt.c46
-rw-r--r--src/i830_display.c93
-rw-r--r--src/i830_display.h4
-rw-r--r--src/i830_tv.c19
5 files changed, 94 insertions, 70 deletions
diff --git a/src/i830.h b/src/i830.h
index 409057cc..b85ee269 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -220,6 +220,8 @@ typedef struct _I830CrtcPrivateRec {
Bool enabled;
+ int dpms_mode;
+
/* Lookup table values to be set when the CRTC is enabled */
CARD8 lut_r[256], lut_g[256], lut_b[256];
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 1900dfb7..9e6180e3 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -349,8 +349,9 @@ i830_crt_detect(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
- xf86CrtcPtr crtc;
-
+ xf86CrtcPtr crtc;
+ int dpms_mode;
+
if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830) ||
IS_G33CLASS(pI830)) {
if (i830_crt_detect_hotplug(output))
@@ -359,49 +360,18 @@ i830_crt_detect(xf86OutputPtr output)
return XF86OutputStatusDisconnected;
}
- if (i830_crt_detect_ddc(output))
- return XF86OutputStatusConnected;
+// if (i830_crt_detect_ddc(output))
+// return XF86OutputStatusConnected;
/* Use the load-detect method if we have no other way of telling. */
- crtc = i830GetLoadDetectPipe (output);
+ crtc = i830GetLoadDetectPipe (output, NULL, &dpms_mode);
if (crtc)
{
- /* VESA 640x480x72Hz mode to set on the pipe */
- static DisplayModeRec mode = {
- NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
- 31500,
- 640, 664, 704, 832, 0,
- 480, 489, 491, 520, 0,
- V_NHSYNC | V_NVSYNC,
- 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
- };
Bool connected;
- I830OutputPrivatePtr intel_output = output->driver_private;
-
- if (!crtc->enabled)
- {
- xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
- /*
- * Give us some border at the bottom for load detection on i8xx
- */
- mode.CrtcVBlankStart = mode.CrtcVSyncStart;
- if (mode.CrtcVBlankEnd - mode.CrtcVBlankStart < 3)
- mode.CrtcVBlankStart = mode.CrtcVBlankEnd - 3;
- xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
- }
- else if (intel_output->load_detect_temp)
- {
- /* Add this output to the crtc */
- output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
- output->funcs->commit (output);
- }
- connected = i830_crt_detect_load (crtc, output);
- i830ReleaseLoadDetectPipe (output);
+ connected = i830_crt_detect_load (crtc, output);
+ i830ReleaseLoadDetectPipe (output, dpms_mode);
if (connected)
return XF86OutputStatusConnected;
else
diff --git a/src/i830_display.c b/src/i830_display.c
index ff25b297..16af4966 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -605,6 +605,8 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
break;
}
+ intel_crtc->dpms_mode = mode;
+
#ifdef XF86DRI
if (pI830->directRenderingEnabled) {
drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen);
@@ -1424,58 +1426,116 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
* \return crtc, or NULL if no pipes are available.
*/
+/* VESA 640x480x72Hz mode to set on the pipe */
+static DisplayModeRec load_detect_mode = {
+ NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT,
+ 31500,
+ 640, 664, 704, 832, 0,
+ 480, 489, 491, 520, 0,
+ V_NHSYNC | V_NVSYNC,
+ 0, 0,
+
+ 640, 640, 664, 704, 832, 832, 0,
+ 480, 489, 489, 491, 520, 520,
+ FALSE, FALSE, 0, NULL, 0, 0.0, 0.0
+};
+
xf86CrtcPtr
-i830GetLoadDetectPipe(xf86OutputPtr output)
+i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, int *dpms_mode)
{
ScrnInfoPtr pScrn = output->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830OutputPrivatePtr intel_output = output->driver_private;
+ I830CrtcPrivatePtr intel_crtc;
xf86CrtcPtr supported_crtc =NULL;
- xf86CrtcPtr detect_crtc = NULL;
+ xf86CrtcPtr crtc = NULL;
int i;
if (output->crtc)
- return output->crtc;
+ {
+ crtc = output->crtc;
+ /*
+ * Make sure the crtc and output are running
+ */
+ intel_crtc = crtc->driver_private;
+ *dpms_mode = intel_crtc->dpms_mode;
+ if (intel_crtc->dpms_mode != DPMSModeOn)
+ {
+ crtc->funcs->dpms (crtc, DPMSModeOn);
+ output->funcs->dpms (output, DPMSModeOn);
+ }
+ return crtc;
+ }
for (i = 0; i < xf86_config->num_crtc; i++)
{
- xf86CrtcPtr crtc;
+ xf86CrtcPtr possible_crtc;
if (!(output->possible_crtcs & (1 << i)))
continue;
- crtc = xf86_config->crtc[i];
- if (!crtc->enabled)
+ possible_crtc = xf86_config->crtc[i];
+ if (!possible_crtc->enabled)
{
- detect_crtc = crtc;
+ crtc = possible_crtc;
break;
}
if (!supported_crtc)
- supported_crtc = crtc;
+ supported_crtc = possible_crtc;
+ }
+ if (!crtc)
+ {
+ crtc = supported_crtc;
+ if (!crtc)
+ return NULL;
}
- if (!detect_crtc)
- detect_crtc = supported_crtc;
- if (!detect_crtc)
- return NULL;
- output->crtc = detect_crtc;
+ output->crtc = crtc;
intel_output->load_detect_temp = TRUE;
+
+ intel_crtc = crtc->driver_private;
+ *dpms_mode = intel_crtc->dpms_mode;
- return detect_crtc;
+ if (!crtc->enabled)
+ {
+ if (!mode)
+ mode = &load_detect_mode;
+ xf86CrtcSetMode (crtc, mode, RR_Rotate_0, 0, 0);
+ }
+ else
+ {
+ if (intel_crtc->dpms_mode != DPMSModeOn)
+ crtc->funcs->dpms (crtc, DPMSModeOn);
+
+ /* Add this output to the crtc */
+ output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
+ output->funcs->commit (output);
+ }
+
+ return crtc;
}
void
-i830ReleaseLoadDetectPipe(xf86OutputPtr output)
+i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode)
{
ScrnInfoPtr pScrn = output->scrn;
I830OutputPrivatePtr intel_output = output->driver_private;
+ xf86CrtcPtr crtc = output->crtc;
if (intel_output->load_detect_temp)
{
- xf86CrtcPtr crtc = output->crtc;
output->crtc = NULL;
intel_output->load_detect_temp = FALSE;
crtc->enabled = xf86CrtcInUse (crtc);
xf86DisableUnusedFunctions(pScrn);
}
+ /*
+ * Switch crtc and output back off if necessary
+ */
+ if (crtc->enabled && dpms_mode != DPMSModeOn)
+ {
+ if (output->crtc == crtc)
+ output->funcs->dpms (output, dpms_mode);
+ crtc->funcs->dpms (crtc, dpms_mode);
+ }
}
/* Returns the clock of the currently programmed mode of the given pipe. */
@@ -1623,6 +1683,7 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pipe)
intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1);
intel_crtc->pipe = pipe;
+ intel_crtc->dpms_mode = DPMSModeOff;
/* Initialize the LUTs for when we turn on the CRTC. */
for (i = 0; i < 256; i++) {
diff --git a/src/i830_display.h b/src/i830_display.h
index 07dfe93a..1eeb7f15 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -32,8 +32,8 @@ void i830PipeSetBase(xf86CrtcPtr crtc, int x, int y);
void i830WaitForVblank(ScrnInfoPtr pScrn);
void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn);
-xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output);
-void i830ReleaseLoadDetectPipe(xf86OutputPtr output);
+xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, int *dpms_mode);
+void i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode);
void i830_crtc_init(ScrnInfoPtr pScrn, int pipe);
void i830_crtc_load_lut(xf86CrtcPtr crtc);
DisplayModePtr i830_crtc_mode_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc);
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 1c818bae..8337d864 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1353,24 +1353,15 @@ i830_tv_detect(xf86OutputPtr output)
DisplayModeRec mode;
I830OutputPrivatePtr intel_output = output->driver_private;
struct i830_tv_priv *dev_priv = intel_output->dev_priv;
+ int dpms_mode;
- crtc = i830GetLoadDetectPipe (output);
+ mode = reported_modes[0];
+ xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
+ crtc = i830GetLoadDetectPipe (output, &mode, &dpms_mode);
if (crtc)
{
- if (!crtc->enabled)
- {
- /* we only need the pixel clock set correctly here */
- mode = reported_modes[0];
- xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
- crtc->funcs->mode_set(crtc, &mode, &mode, 0, 0);
- }
- else if (intel_output->load_detect_temp)
- {
- output->funcs->mode_set (output, &crtc->mode, &crtc->mode);
- output->funcs->commit (output);
- }
i830_tv_detect_type (crtc, output);
- i830ReleaseLoadDetectPipe (output);
+ i830ReleaseLoadDetectPipe (output, dpms_mode);
}
switch (dev_priv->type) {