[PATCH V4 4/7] Add new mode function in drm backend

Quanxian Wang quanxian.wang at intel.com
Thu Apr 24 00:50:08 PDT 2014


provide drm_output_new_mode interface to create new mode
from outsite instead of only from edid or configure.

Signed-off-by: Quanxian Wang <quanxian.wang at intel.com>
---
 src/compositor-drm.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 154e15e..f988692 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -1390,6 +1390,96 @@ drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info)
 }
 
 static int
+drm_output_compare_timing(struct weston_mode *mode,
+			  uint32_t clock,
+			  int hdisplay,
+			  int hsync_start,
+			  int hsync_end,
+			  int htotal,
+			  int vdisplay,
+			  int vsync_start,
+			  int vsync_end,
+			  int vtotal,
+			  int vscan,
+			  uint32_t flags)
+{
+	struct drm_mode *drmmode = (struct drm_mode *)mode;
+	drmModeModeInfo *modeinfo = &drmmode->mode_info;
+
+	return (modeinfo->clock == clock &&
+		modeinfo->hdisplay == hdisplay &&
+		modeinfo->hsync_start == hsync_start &&
+		modeinfo->hsync_end == hsync_end &&
+		modeinfo->htotal == htotal &&
+		modeinfo->vdisplay == vdisplay &&
+		modeinfo->vsync_start == vsync_start &&
+		modeinfo->vsync_end == vsync_end &&
+		modeinfo->vtotal == vtotal &&
+		modeinfo->vscan == vscan &&
+		modeinfo->flags == flags);
+}
+
+static struct weston_mode *
+drm_output_new_timing(struct weston_output *output,
+		      uint32_t clock,
+		      int hdisplay,
+		      int hsync_start,
+		      int hsync_end,
+		      int htotal,
+		      int vdisplay,
+		      int vsync_start,
+		      int vsync_end,
+		      int vtotal,
+		      int vscan,
+		      uint32_t flags)
+{
+	drmModeModeInfo *modeinfo;
+	struct drm_mode *mode = NULL;
+	uint64_t refresh;
+
+	modeinfo = zalloc(sizeof(*modeinfo));
+	if (modeinfo == NULL)
+		return NULL;
+
+	modeinfo->type = DRM_MODE_TYPE_USERDEF;
+	modeinfo->hskew = 0;
+	modeinfo->hdisplay = hdisplay;
+	modeinfo->hsync_start = hsync_start;
+	modeinfo->hsync_end = hsync_end;
+	modeinfo->htotal = htotal;
+	modeinfo->vdisplay = vdisplay;
+	modeinfo->vsync_start = vsync_start;
+	modeinfo->vsync_end = vsync_end;
+	modeinfo->vtotal = vtotal;
+	modeinfo->vscan = vscan;
+	modeinfo->flags = flags;
+	modeinfo->clock = clock;
+
+	/* Calculate higher precision (mHz) refresh rate */
+	refresh = (clock * 1000000LL / htotal +
+		   vtotal / 2) / vtotal;
+
+	if (flags & DRM_MODE_FLAG_INTERLACE)
+		refresh *= 2;
+	if (flags & DRM_MODE_FLAG_DBLSCAN)
+		refresh /= 2;
+	if (vscan > 1)
+		refresh /= vscan;
+
+	/* For new timing, there is no set for vrefresh.
+	 * But in choose_mode, it will check with refresh value.
+	 * So set vrefresh value to be refresh.
+	 */
+	modeinfo->vrefresh = refresh;
+
+	mode = drm_output_add_mode((struct drm_output *)output, modeinfo);
+	if (mode)
+		return &mode->base;
+	else
+		return NULL;
+}
+
+static int
 drm_subpixel_to_wayland(int drm_value)
 {
 	switch (drm_value) {
@@ -2046,6 +2136,8 @@ create_output_for_connector(struct drm_compositor *ec,
 	output->base.assign_planes = drm_assign_planes;
 	output->base.set_dpms = drm_set_dpms;
 	output->base.switch_mode = drm_output_switch_mode;
+	output->base.new_timing = drm_output_new_timing;
+	output->base.compare_timing = drm_output_compare_timing;
 
 	output->base.gamma_size = output->original_crtc->gamma_size;
 	output->base.set_gamma = drm_output_set_gamma;
-- 
1.8.1.2



More information about the wayland-devel mailing list