diff options
-rw-r--r-- | src/i830.h | 2 | ||||
-rw-r--r-- | src/i830_crt.c | 46 | ||||
-rw-r--r-- | src/i830_display.c | 93 | ||||
-rw-r--r-- | src/i830_display.h | 4 | ||||
-rw-r--r-- | src/i830_tv.c | 19 |
5 files changed, 94 insertions, 70 deletions
@@ -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) { |