[PATCH 65/72] imx-drm: imx-ldb: Add all defined of video modes

Steve Longerbeam slongerbeam at gmail.com
Fri Oct 31 15:54:48 PDT 2014


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_ldb_connector_get_modes().

Signed-off-by: Steve Longerbeam <steve_longerbeam at mentor.com>
---
 drivers/staging/imx-drm/imx-ldb.c |   46 ++++++++++++++++++++++---------------
 1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c
index 53d9d82..615e090 100644
--- a/drivers/staging/imx-drm/imx-ldb.c
+++ b/drivers/staging/imx-drm/imx-ldb.c
@@ -28,7 +28,9 @@
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
-#include <video/of_videomode.h>
+#include <video/display_timing.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
 #include <linux/regmap.h>
 #include <linux/videodev2.h>
 
@@ -65,8 +67,7 @@ struct imx_ldb_channel {
 	int chno;
 	void *edid;
 	int edid_len;
-	struct drm_display_mode mode;
-	int mode_valid;
+	struct display_timings *timings;
 };
 
 struct bus_mux {
@@ -100,6 +101,7 @@ static enum drm_connector_status imx_ldb_connector_detect(
 static int imx_ldb_connector_get_modes(struct drm_connector *connector)
 {
 	struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
+	struct display_timings *timings = imx_ldb_ch->timings;
 	int num_modes = 0;
 
 	imx_ldb_entry_dbg(imx_ldb_ch);
@@ -113,16 +115,26 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector)
 		num_modes = drm_add_edid_modes(connector, imx_ldb_ch->edid);
 	}
 
-	if (imx_ldb_ch->mode_valid) {
+	if (timings) {
 		struct drm_display_mode *mode;
+		struct videomode vm;
+		int i;
 
-		mode = drm_mode_create(connector->dev);
-		if (!mode)
-			return -EINVAL;
-		drm_mode_copy(mode, &imx_ldb_ch->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;
+
+			mode = drm_mode_create(connector->dev);
+			drm_display_mode_from_videomode(&vm, mode);
+
+			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;
@@ -568,16 +580,11 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
 				channel->edid = kmemdup(edidp,
 							channel->edid_len,
 							GFP_KERNEL);
-			} else {
-				/* fallback to display-timings node */
-				ret = of_get_drm_display_mode(child,
-							      &channel->mode,
-							      0);
-				if (!ret)
-					channel->mode_valid = 1;
 			}
 		}
 
+		channel->timings = of_get_display_timings(child);
+
 		ret = of_property_read_u32(child, "fsl,data-width", &datawidth);
 		if (ret)
 			datawidth = 0;
@@ -639,6 +646,9 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
 		channel->encoder.funcs->destroy(&channel->encoder);
 
 		i2c_put_adapter(channel->ddc);
+
+		if (channel->timings)
+			display_timings_release(channel->timings);
 	}
 }
 
-- 
1.7.9.5



More information about the dri-devel mailing list