diff options
author | Keith Packard <keithp@neko.keithp.com> | 2007-07-13 10:58:06 -0700 |
---|---|---|
committer | Keith Packard <keithp@neko.keithp.com> | 2007-07-13 13:39:36 -0700 |
commit | 00f4587025a3879626623135b0a153fcdb906719 (patch) | |
tree | e7fd6319f676a077e3b95912a98968d4b62b3707 | |
parent | 6f18300aed1340348c6d395f326061b5315be643 (diff) |
Ensure pipe/output active before doing load detection.
If the pipe or output have been set to DPMSOff, then load detection will not
work correctly. Also, share the load detection configuration code between
crt and tv outputs.
-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) { |