diff mbox

[66/72] imx-drm: parallel-display: Add all defined of video modes

Message ID 1414796095-10107-67-git-send-email-steve_longerbeam@mentor.com (mailing list archive)
State New, archived
Headers show

Commit Message

Steve Longerbeam Oct. 31, 2014, 10:54 p.m. UTC
Instead of assuming only a single defined display-timing node in the
device tree, assume there can be multiple modes and register all of
them in imx_pd_connector_get_modes().

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
---
 drivers/staging/imx-drm/parallel-display.c |   48 +++++++++++++++-------------
 1 file changed, 26 insertions(+), 22 deletions(-)
diff mbox

Patch

diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c
index e0b0b56..11ae35d 100644
--- a/drivers/staging/imx-drm/parallel-display.c
+++ b/drivers/staging/imx-drm/parallel-display.c
@@ -25,8 +25,9 @@ 
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_panel.h>
 #include <linux/videodev2.h>
+#include <video/display_timing.h>
 #include <video/of_display_timing.h>
-#include <video/imx-ipu-v3.h>
+#include <video/videomode.h>
 
 #include "imx-drm.h"
 
@@ -41,8 +42,7 @@  struct imx_parallel_display {
 	int edid_len;
 	u32 interface_pix_fmt;
 	struct ipu_dc_if_map *interface_map;
-	int mode_valid;
-	struct drm_display_mode mode;
+	struct display_timings *timings;
 	struct drm_panel *panel;
 };
 
@@ -55,7 +55,7 @@  static enum drm_connector_status imx_pd_connector_detect(
 static int imx_pd_connector_get_modes(struct drm_connector *connector)
 {
 	struct imx_parallel_display *imxpd = con_to_imxpd(connector);
-	struct device_node *np = imxpd->dev->of_node;
+	struct display_timings *timings = imxpd->timings;
 	int num_modes = 0;
 
 	if (imxpd->panel && imxpd->panel->funcs &&
@@ -70,27 +70,26 @@  static int imx_pd_connector_get_modes(struct drm_connector *connector)
 		num_modes = drm_add_edid_modes(connector, imxpd->edid);
 	}
 
-	if (imxpd->mode_valid) {
-		struct drm_display_mode *mode = drm_mode_create(connector->dev);
+	if (timings) {
+		struct drm_display_mode *mode;
+		struct videomode vm;
+		int i;
 
-		if (!mode)
-			return -EINVAL;
-		drm_mode_copy(mode, &imxpd->mode);
-		mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
-		drm_mode_probed_add(connector, mode);
-		num_modes++;
-	}
+		for (i = 0; i < timings->num_timings; i++) {
+			if (videomode_from_timings(timings, &vm, i))
+				break;
 
-	if (np) {
-		struct drm_display_mode *mode = drm_mode_create(connector->dev);
+			mode = drm_mode_create(connector->dev);
+			drm_display_mode_from_videomode(&vm, mode);
 
-		if (!mode)
-			return -EINVAL;
-		of_get_drm_display_mode(np, &imxpd->mode, OF_USE_NATIVE_MODE);
-		drm_mode_copy(mode, &imxpd->mode);
-		mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
-		drm_mode_probed_add(connector, mode);
-		num_modes++;
+			mode->type = DRM_MODE_TYPE_DRIVER;
+			if (i == timings->native_mode)
+				mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+			drm_mode_set_name(mode);
+			drm_mode_probed_add(connector, mode);
+			num_modes++;
+		}
 	}
 
 	return num_modes;
@@ -223,6 +222,8 @@  static int imx_pd_bind(struct device *dev, struct device *master, void *data)
 	if (edidp)
 		imxpd->edid = kmemdup(edidp, imxpd->edid_len, GFP_KERNEL);
 
+	imxpd->timings = of_get_display_timings(np);
+
 	ret = of_property_read_string(np, "interface-pix-fmt", &fmt);
 	if (!ret) {
 		if (!strcmp(fmt, "rgb24"))
@@ -282,6 +283,9 @@  static void imx_pd_unbind(struct device *dev, struct device *master,
 
 	imxpd->encoder.funcs->destroy(&imxpd->encoder);
 	imxpd->connector.funcs->destroy(&imxpd->connector);
+
+	if (imxpd->timings)
+		display_timings_release(imxpd->timings);
 }
 
 static const struct component_ops imx_pd_ops = {