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>
This commit is contained in:
parent
1f15b69b59
commit
628f435be4
2 changed files with 24 additions and 0 deletions
|
@ -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 @@
|
||||||
#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 {
|
||||||
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)
|
||||||
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(
|
||||||
|
|
||||||
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,
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue