Commit 628f435b authored by Philipp Zabel's avatar Philipp Zabel Committed by Greg Kroah-Hartman

imx-drm: parallel-display: Add drm_panel support

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: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1f15b69b
...@@ -20,6 +20,7 @@ config DRM_IMX_FB_HELPER ...@@ -20,6 +20,7 @@ config DRM_IMX_FB_HELPER
config DRM_IMX_PARALLEL_DISPLAY config DRM_IMX_PARALLEL_DISPLAY
tristate "Support for parallel displays" tristate "Support for parallel displays"
select DRM_PANEL
depends on DRM_IMX depends on DRM_IMX
select VIDEOMODE_HELPERS select VIDEOMODE_HELPERS
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include <drm/drm_panel.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <video/of_display_timing.h> #include <video/of_display_timing.h>
...@@ -40,6 +41,7 @@ struct imx_parallel_display { ...@@ -40,6 +41,7 @@ struct imx_parallel_display {
u32 interface_pix_fmt; u32 interface_pix_fmt;
int mode_valid; int mode_valid;
struct drm_display_mode mode; struct drm_display_mode mode;
struct drm_panel *panel;
}; };
static enum drm_connector_status imx_pd_connector_detect( static enum drm_connector_status imx_pd_connector_detect(
...@@ -54,6 +56,13 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) ...@@ -54,6 +56,13 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
struct device_node *np = imxpd->dev->of_node; struct device_node *np = imxpd->dev->of_node;
int num_modes = 0; 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) { if (imxpd->edid) {
drm_mode_connector_update_edid_property(connector, imxpd->edid); drm_mode_connector_update_edid_property(connector, imxpd->edid);
num_modes = drm_add_edid_modes(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( ...@@ -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) 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, static bool imx_pd_encoder_mode_fixup(struct drm_encoder *encoder,
...@@ -164,6 +179,9 @@ static int imx_pd_register(struct drm_device *drm, ...@@ -164,6 +179,9 @@ static int imx_pd_register(struct drm_device *drm,
drm_connector_init(drm, &imxpd->connector, &imx_pd_connector_funcs, drm_connector_init(drm, &imxpd->connector, &imx_pd_connector_funcs,
DRM_MODE_CONNECTOR_VGA); DRM_MODE_CONNECTOR_VGA);
if (imxpd->panel)
drm_panel_attach(imxpd->panel, &imxpd->connector);
drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder); drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder);
imxpd->connector.encoder = &imxpd->encoder; imxpd->connector.encoder = &imxpd->encoder;
...@@ -175,6 +193,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) ...@@ -175,6 +193,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
{ {
struct drm_device *drm = data; struct drm_device *drm = data;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct device_node *panel_node;
const u8 *edidp; const u8 *edidp;
struct imx_parallel_display *imxpd; struct imx_parallel_display *imxpd;
int ret; int ret;
...@@ -198,6 +217,10 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) ...@@ -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; 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; imxpd->dev = dev;
ret = imx_pd_register(drm, imxpd); ret = imx_pd_register(drm, imxpd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment