summaryrefslogtreecommitdiff
path: root/src/i830_display.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@dulcimer.keithp.com>2007-05-27 12:35:55 -0700
committerKeith Packard <keithp@dulcimer.keithp.com>2007-05-27 12:35:55 -0700
commit2a365eab0178c28782fba97bdd22365f30ce8963 (patch)
tree3f194e499b075e351e9a8558763f4eb6e230165d /src/i830_display.c
parentff8c8cb869a3c780dbd826f7c94f06e4f3fda6af (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.
Diffstat (limited to 'src/i830_display.c')
-rw-r--r--src/i830_display.c80
1 files changed, 80 insertions, 0 deletions
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