[Nouveau] [PATCH 3/3] kms: Add TV-out support
Francisco Jerez
currojerez at riseup.net
Tue Aug 11 17:18:28 PDT 2009
---
src/drmmode_display.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 9b61da8..daa3f53 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -571,8 +571,16 @@ drmmode_output_detect(xf86OutputPtr output)
}
static Bool
-drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
+drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
{
+ drmmode_output_private_ptr drmmode_output = output->driver_private;
+ drmModeConnectorPtr koutput = drmmode_output->mode_output;
+
+ if (koutput->connector_type == DRM_MODE_CONNECTOR_TV
+ && mode->type & M_T_DEFAULT)
+ /* Default modes are harmful here. */
+ return MODE_BAD;
+
return MODE_OK;
}
@@ -778,8 +786,10 @@ static Bool
drmmode_output_set_property(xf86OutputPtr output, Atom property,
RRPropertyValuePtr value)
{
+ ScrnInfoPtr pScrn = output->scrn;
drmmode_output_private_ptr drmmode_output = output->driver_private;
drmmode_ptr drmmode = drmmode_output->drmmode;
+ const char* property_name = NameForAtom(property);
int i, ret;
for (i = 0; i < drmmode_output->num_props; i++) {
@@ -802,7 +812,7 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property,
if (ret)
return FALSE;
- return TRUE;
+ goto out;
} else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
Atom atom;
@@ -825,7 +835,7 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property,
if (ret)
return FALSE;
- return TRUE;
+ goto out;
}
}
@@ -833,6 +843,62 @@ drmmode_output_set_property(xf86OutputPtr output, Atom property,
}
}
+out:
+ /* The following properties are evil because they often
+ * render the current CRTC mode invalid.
+ */
+
+ if (!strcmp(property_name, "mode")
+ || !strcmp(property_name, "scale")) {
+ xf86CrtcPtr crtc = output->crtc;
+ drmmode_crtc_private_ptr drmmode_crtc;
+ DisplayModePtr mode,
+ mode_same = NULL,
+ mode_preferred = NULL;
+
+ drmModeFreeConnector(drmmode_output->mode_output);
+ drmmode_output->mode_output = drmModeGetConnector(drmmode->fd,
+ drmmode_output->output_id);
+
+ if (!drmmode_output->mode_output || !pScrn->vtSema
+ || !crtc || !crtc->enabled)
+ return TRUE;
+
+ drmmode_crtc = crtc->driver_private;
+
+ xf86ProbeOutputModes(pScrn, 0, 0);
+ xf86SetScrnInfoModes(pScrn);
+
+ /* Look for a mode with the same dimensions, otherwise
+ * use the preferred one. */
+
+ for (mode = output->probed_modes; mode;
+ mode = mode->next) {
+ if (crtc->mode.HDisplay == mode->HDisplay
+ && crtc->mode.VDisplay == mode->VDisplay)
+ mode_same = mode;
+
+ if (mode->type & M_T_PREFERRED)
+ mode_preferred = mode;
+ }
+
+ if (mode_same)
+ mode = mode_same;
+ else if (mode_preferred)
+ mode = mode_preferred;
+
+ /* Disable the CRTC first to ensure a full modeset is performed. */
+ drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+ 0, 0, 0, NULL, 0, NULL);
+
+ if(mode)
+ drmmode_set_mode_major(crtc, mode, crtc->rotation, crtc->x, crtc->y);
+
+ if (output->randr_output->modes)
+ xf86RandR12TellChanged(pScrn->pScreen);
+
+ }
+
return TRUE;
}
@@ -922,13 +988,14 @@ const char *output_names[] = { "None",
"DVI-D",
"DVI-A",
"Composite",
- "TV",
+ "SVIDEO",
"LVDS",
"CTV",
"DIN",
"DP",
"HDMI",
"HDMI",
+ "TV",
};
--
1.6.3.3
More information about the Nouveau
mailing list