diff options
author | Keith Packard <keithp@dulcimer.keithp.com> | 2007-05-27 12:35:55 -0700 |
---|---|---|
committer | Keith Packard <keithp@dulcimer.keithp.com> | 2007-05-27 12:35:55 -0700 |
commit | 2a365eab0178c28782fba97bdd22365f30ce8963 (patch) | |
tree | 3f194e499b075e351e9a8558763f4eb6e230165d | |
parent | ff8c8cb869a3c780dbd826f7c94f06e4f3fda6af (diff) |
On i830, Pipe B cannot be lit the first time unless Pipe A is running.
I don't understand it, but just like the video overlay, if Pipe A is not
running, Pipe B will not turn the first time it is activated. This
patch restructures the code used for the video overlay to share it
with the crtc commit function.
-rw-r--r-- | src/i830.h | 11 | ||||
-rw-r--r-- | src/i830_display.c | 80 | ||||
-rw-r--r-- | src/i830_video.c | 31 |
3 files changed, 98 insertions, 24 deletions
@@ -216,6 +216,8 @@ extern const char *i830_output_type_names[]; typedef struct _I830CrtcPrivateRec { int pipe; + Bool enabled; + /* Lookup table values to be set when the CRTC is enabled */ CARD8 lut_r[256], lut_g[256], lut_b[256]; @@ -579,6 +581,15 @@ extern void I830InitVideo(ScreenPtr pScreen); extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on); #endif +int +i830_crtc_pipe (xf86CrtcPtr crtc); + +Bool +i830_pipe_a_require_activate (ScrnInfoPtr scrn); + +void +i830_pipe_a_require_deactivate (ScrnInfoPtr scrn); + #ifdef XF86DRI extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags); extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn); diff --git a/src/i830_display.c b/src/i830_display.c index 023a1aab..adc7479e 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -429,6 +429,76 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) #endif } +/* + * Both crtc activation and video overlay enablement on pipe B + * will fail on i830 if pipe A is not running. This function + * makes sure pipe A is active for these cases + */ + +int +i830_crtc_pipe (xf86CrtcPtr crtc) +{ + if (crtc == NULL) + return 0; + return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe; +} + +static xf86CrtcPtr +i830_crtc_for_pipe (ScrnInfoPtr scrn, int pipe) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + for (c = 0; c < xf86_config->num_crtc; c++) + { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + if (i830_crtc_pipe (crtc) == pipe) + return crtc; + } + return NULL; +} + +Bool +i830_pipe_a_require_activate (ScrnInfoPtr scrn) +{ + xf86CrtcPtr crtc = i830_crtc_for_pipe (scrn, 0); + /* 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 + }; + + if (!crtc) + return FALSE; + if (crtc->enabled) + return FALSE; + xf86SetModeCrtc (&mode, INTERLACE_HALVE_V); + crtc->funcs->mode_set (crtc, &mode, &mode, 0, 0); + crtc->funcs->dpms (crtc, DPMSModeOn); + return TRUE; +} + +void +i830_pipe_a_require_deactivate (ScrnInfoPtr scrn) +{ + xf86CrtcPtr crtc = i830_crtc_for_pipe (scrn, 0); + + if (!crtc) + return; + if (crtc->enabled) + return; + crtc->funcs->dpms (crtc, DPMSModeOff); + return; +} + + /** * Sets the power management mode of the pipe and plane. * @@ -593,9 +663,19 @@ i830_crtc_prepare (xf86CrtcPtr crtc) static void i830_crtc_commit (xf86CrtcPtr crtc) { + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + Bool deactivate = FALSE; + + if (!intel_crtc->enabled && intel_crtc->pipe != 0) + deactivate = i830_pipe_a_require_activate (crtc->scrn); + + intel_crtc->enabled = TRUE; + crtc->funcs->dpms (crtc, DPMSModeOn); if (crtc->scrn->pScreen != NULL) xf86_reload_cursors (crtc->scrn->pScreen); + if (deactivate) + i830_pipe_a_require_deactivate (crtc->scrn); } void diff --git a/src/i830_video.c b/src/i830_video.c index d57519b9..4517975c 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -382,6 +382,7 @@ i830_overlay_on(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); I830OverlayRegPtr overlay = I830OVERLAYREG(pI830); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; + Bool deactivate = FALSE; xf86CrtcPtr crtc0 = NULL; if (*pI830->overlayOn) @@ -393,30 +394,12 @@ i830_overlay_on(ScrnInfoPtr pScrn) * screen. Light up pipe A in this case to provide a clock * for the overlay hardware */ - if (!pPriv->started_video) + if (pPriv->current_crtc && + i830_crtc_pipe (pPriv->current_crtc) != 0 && + !pPriv->started_video) { pPriv->started_video = TRUE; - crtc0 = I830CrtcForPipe (pScrn, 0); - if (!crtc0->enabled) - { - /* 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 - }; - xf86SetModeCrtc (&mode, INTERLACE_HALVE_V); - crtc0->funcs->mode_set (crtc0, &mode, &mode, 0, 0); - crtc0->funcs->dpms (crtc0, DPMSModeOn); - } - else - crtc0 = NULL; + deactivate = i830_pipe_a_require_activate (pScrn); } overlay->OCMD &= ~OVERLAY_ENABLE; @@ -435,8 +418,8 @@ i830_overlay_on(ScrnInfoPtr pScrn) * If we turned pipe A on up above, turn it * back off */ - if (crtc0) - crtc0->funcs->dpms (crtc0, DPMSModeOff); + if (deactivate) + i830_pipe_a_require_deactivate (pScrn); OVERLAY_DEBUG("overlay_on\n"); *pI830->overlayOn = TRUE; |