diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2014-02-25 10:55:04 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-27 20:43:36 (GMT) |
commit | 628f435be4359e6ae8ecfdda9b492053be76a057 (patch) | |
tree | 286896b3fb1449fc6e34b115cc9b4745e7296071 | |
parent | 1f15b69b597087937f370179661cc468f46ce545 (diff) | |
download | linux-628f435be4359e6ae8ecfdda9b492053be76a057.tar.xz |
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: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/imx-drm/Kconfig | 1 | ||||
-rw-r--r-- | drivers/staging/imx-drm/parallel-display.c | 23 |
2 files changed, 24 insertions, 0 deletions
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); |