diff mbox

imx-drm: parallel-display: Add drm_panel support

Message ID 1393325704-21165-1-git-send-email-p.zabel@pengutronix.de (mailing list archive)
State New, archived
Headers show

Commit Message

Philipp Zabel Feb. 25, 2014, 10:55 a.m. UTC
This patch allows to optionally attach the parallel-display to a panel
supported by a drm_panel driver instead of supplying the modes via
device tree.

Before:
	parallel-display {
		compatible = "fsl,imx-parallel-display";
		...

		display-timings {
			native-timing = <&timing1>;
			timing1: etm0700g0dh6 {
				hactive = <800>;
				vactive = <480>;
				clock-frequency = <33260000>;
				hsync-len = <128>;
				hback-porch = <88>;
				hfront-porch = <40>;
				vsync-len = <2>;
				vback-porch = <33>;
				vfront-porch = <10>;
				hsync-active = <0>;
				vsync-active = <0>;
				...
			};
		};
		...
	};

After:
	parallel-display {
		compatible = "fsl,imx-parallel-display";
		fsl,panel = <&panel>;
		...
	};

	panel: panel {
		compatible = "edt,etm0700g0dh6", "simple-panel";
	};

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/staging/imx-drm/Kconfig            |  1 +
 drivers/staging/imx-drm/parallel-display.c | 23 +++++++++++++++++++++++
 2 files changed, 24 insertions(+)
diff mbox

Patch

diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig
index 78319ad..c6e8ba7 100644
--- a/drivers/staging/imx-drm/Kconfig
+++ b/drivers/staging/imx-drm/Kconfig
@@ -20,6 +20,7 @@  config DRM_IMX_FB_HELPER
 
 config DRM_IMX_PARALLEL_DISPLAY
 	tristate "Support for parallel displays"
+	select DRM_PANEL
 	depends on DRM_IMX
 	select VIDEOMODE_HELPERS
 
diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c
index d610f07..6bce140 100644
--- a/drivers/staging/imx-drm/parallel-display.c
+++ b/drivers/staging/imx-drm/parallel-display.c
@@ -23,6 +23,7 @@ 
 #include <drm/drmP.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
 #include <linux/videodev2.h>
 #include <video/of_display_timing.h>
 
@@ -40,6 +41,7 @@  struct imx_parallel_display {
 	u32 interface_pix_fmt;
 	int mode_valid;
 	struct drm_display_mode mode;
+	struct drm_panel *panel;
 };
 
 static enum drm_connector_status imx_pd_connector_detect(
@@ -54,6 +56,13 @@  static int imx_pd_connector_get_modes(struct drm_connector *connector)
 	struct device_node *np = imxpd->dev->of_node;
 	int num_modes = 0;
 
+	if (imxpd->panel && imxpd->panel->funcs &&
+	    imxpd->panel->funcs->get_modes) {
+		num_modes = imxpd->panel->funcs->get_modes(imxpd->panel);
+		if (num_modes > 0)
+			return num_modes;
+	}
+
 	if (imxpd->edid) {
 		drm_mode_connector_update_edid_property(connector, imxpd->edid);
 		num_modes = drm_add_edid_modes(connector, imxpd->edid);
@@ -89,6 +98,12 @@  static struct drm_encoder *imx_pd_connector_best_encoder(
 
 static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode)
 {
+	struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
+
+	if (mode != DRM_MODE_DPMS_ON)
+		drm_panel_disable(imxpd->panel);
+	else
+		drm_panel_enable(imxpd->panel);
 }
 
 static bool imx_pd_encoder_mode_fixup(struct drm_encoder *encoder,
@@ -164,6 +179,9 @@  static int imx_pd_register(struct drm_device *drm,
 	drm_connector_init(drm, &imxpd->connector, &imx_pd_connector_funcs,
 			   DRM_MODE_CONNECTOR_VGA);
 
+	if (imxpd->panel)
+		drm_panel_attach(imxpd->panel, &imxpd->connector);
+
 	drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder);
 
 	imxpd->connector.encoder = &imxpd->encoder;
@@ -175,6 +193,7 @@  static int imx_pd_bind(struct device *dev, struct device *master, void *data)
 {
 	struct drm_device *drm = data;
 	struct device_node *np = dev->of_node;
+	struct device_node *panel_node;
 	const u8 *edidp;
 	struct imx_parallel_display *imxpd;
 	int ret;
@@ -198,6 +217,10 @@  static int imx_pd_bind(struct device *dev, struct device *master, void *data)
 			imxpd->interface_pix_fmt = V4L2_PIX_FMT_BGR666;
 	}
 
+	panel_node = of_parse_phandle(np, "fsl,panel", 0);
+	if (panel_node)
+		imxpd->panel = of_drm_find_panel(panel_node);
+
 	imxpd->dev = dev;
 
 	ret = imx_pd_register(drm, imxpd);