This patch allows to optionally attach the lvds-channel to a panel supported by a drm_panel driver instead of supplying the modes via device tree.
Before:
ldb { ...
lvds-channel@0 { ...
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: ldb { ...
lvds-channel@0 { fsl,panel = <&panel>; ... }; };
panel: panel { compatible = "edt,etm0700g0dh6", "simple-panel"; };
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- drivers/staging/imx-drm/imx-ldb.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 4576830..38a0795 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -24,6 +24,7 @@ #include <drm/drmP.h> #include <drm/drm_fb_helper.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_panel.h> #include <linux/mfd/syscon.h> #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> #include <linux/of_address.h> @@ -60,6 +61,7 @@ struct imx_ldb_channel { struct imx_ldb *ldb; struct drm_connector connector; struct drm_encoder encoder; + struct drm_panel *panel; struct device_node *child; int chno; void *edid; @@ -96,6 +98,13 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); int num_modes = 0;
+ if (imx_ldb_ch->panel && imx_ldb_ch->panel->funcs && + imx_ldb_ch->panel->funcs->get_modes) { + num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel); + if (num_modes > 0) + return num_modes; + } + if (imx_ldb_ch->edid) { drm_mode_connector_update_edid_property(connector, imx_ldb_ch->edid); @@ -240,6 +249,8 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder) }
regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); + + drm_panel_enable(imx_ldb_ch->panel); }
static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, @@ -291,6 +302,8 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder) (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0) return;
+ drm_panel_disable(imx_ldb_ch->panel); + if (imx_ldb_ch == &ldb->channel[0]) ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; else if (imx_ldb_ch == &ldb->channel[1]) @@ -376,6 +389,9 @@ static int imx_ldb_register(struct drm_device *drm, drm_connector_init(drm, &imx_ldb_ch->connector, &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
+ if (imx_ldb_ch->panel) + drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector); + drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, &imx_ldb_ch->encoder);
@@ -490,6 +506,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
for_each_child_of_node(np, child) { struct imx_ldb_channel *channel; + struct device_node *panel_node;
ret = of_property_read_u32(child, "reg", &i); if (ret || i < 0 || i > 1) @@ -549,6 +566,10 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) return -EINVAL; }
+ panel_node = of_parse_phandle(child, "fsl,panel", 0); + if (panel_node) + channel->panel = of_drm_find_panel(panel_node); + ret = imx_ldb_register(drm, channel); if (ret) return ret;
This patch depends on the OF graph parsing helper and imx-drm-dt series. It allows to connect the panel to the output port (port@1 on i.MX53, port@4 on i.MX6) via the OF graph bindings.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- drivers/staging/imx-drm/imx-ldb.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 38a0795..4d1446a 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -27,8 +27,8 @@ #include <drm/drm_panel.h> #include <linux/mfd/syscon.h> #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> -#include <linux/of_address.h> #include <linux/of_device.h> +#include <linux/of_graph.h> #include <video/of_videomode.h> #include <linux/regmap.h> #include <linux/videodev2.h> @@ -506,7 +506,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
for_each_child_of_node(np, child) { struct imx_ldb_channel *channel; - struct device_node *panel_node; + struct device_node *port;
ret = of_property_read_u32(child, "reg", &i); if (ret || i < 0 || i > 1) @@ -566,9 +566,18 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) return -EINVAL; }
- panel_node = of_parse_phandle(child, "fsl,panel", 0); - if (panel_node) - channel->panel = of_drm_find_panel(panel_node); + /* The output port is port@4 with mux or port@1 without mux */ + port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 1); + if (port) { + struct device_node *endpoint, *remote; + + endpoint = of_get_child_by_name(port, "endpoint"); + if (endpoint) { + remote = of_graph_get_remote_port_parent(endpoint); + if (remote) + channel->panel = of_drm_find_panel(remote); + } + }
ret = imx_ldb_register(drm, channel); if (ret)
Am Donnerstag, den 06.03.2014, 14:54 +0100 schrieb Philipp Zabel:
This patch depends on the OF graph parsing helper and imx-drm-dt series. It allows to connect the panel to the output port (port@1 on i.MX53, port@4 on i.MX6) via the OF graph bindings.
If we postpone this until the imx-drm-dt binding series gets accepted, I can just squash the two patches together.
regards Philipp
On Thu, Mar 06, 2014 at 02:54:40PM +0100, Philipp Zabel wrote:
@@ -566,9 +566,18 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) return -EINVAL; }
panel_node = of_parse_phandle(child, "fsl,panel", 0);
if (panel_node)
channel->panel = of_drm_find_panel(panel_node);
/* The output port is port@4 with mux or port@1 without mux */
port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 1);
I guess we're holding off on these two patches while the last bits of the of-graph get sorted - the above function doesn't currently exist so causes a build failure.
Thanks.
On Thu, Mar 06, 2014 at 02:54:39PM +0100, Philipp Zabel wrote:
This patch allows to optionally attach the lvds-channel to a panel supported by a drm_panel driver instead of supplying the modes via device tree.
Hmm, I think something may be missing in this patch... you're introducing calls into the drm panel code, but there's nothign which ensures that code gets built alongside imx-ldb.c. With imx-ldb built as a module, I get:
ERROR: "drm_panel_attach" [drivers/staging/imx-drm/imx-ldb.ko] undefined! ERROR: "of_drm_find_panel" [drivers/staging/imx-drm/imx-ldb.ko] undefined!
Hi Russell,
Am Freitag, den 07.03.2014, 17:22 +0000 schrieb Russell King - ARM Linux:
On Thu, Mar 06, 2014 at 02:54:39PM +0100, Philipp Zabel wrote:
This patch allows to optionally attach the lvds-channel to a panel supported by a drm_panel driver instead of supplying the modes via device tree.
Hmm, I think something may be missing in this patch... you're introducing calls into the drm panel code, but there's nothign which ensures that code gets built alongside imx-ldb.c. With imx-ldb built as a module, I get:
ERROR: "drm_panel_attach" [drivers/staging/imx-drm/imx-ldb.ko] undefined! ERROR: "of_drm_find_panel" [drivers/staging/imx-drm/imx-ldb.ko] undefined!
Thanks for testing. Yes, this Kconfig change is missing from patch 1:
diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig index 82fb758..8e5b7e9 100644 --- a/drivers/staging/imx-drm/Kconfig +++ b/drivers/staging/imx-drm/Kconfig @@ -35,6 +35,7 @@ config DRM_IMX_TVE config DRM_IMX_LDB tristate "Support for LVDS displays" depends on DRM_IMX && MFD_SYSCON + select DRM_PANEL help Choose this to enable the internal LVDS Display Bridge (LDB) found on i.MX53 and i.MX6 processors.
I haven't noticed because I've enabled the parallel display driver, which does correctly select DRM_PANEL.
regards Philipp
dri-devel@lists.freedesktop.org