Hi,
this latest version of the imx-drm DT binding patches applies on top of staging-next and also depends on the OF graph binding patchset that moves the v4l2_of helpers to drivers/of. Currently, the two patchsets are also available at: git://git.pengutronix.de/git/pza/linux.git topic/of-graph git://git.pengutronix.de/git/pza/linux.git topic/imx-drm-dt
I have added device tree bindings between IPU and the encoders as documented in Documentation/devicetree/bindings/graph.txt and used those to determine the possible_crtcs and mux_id, and to find all necessary components that hang off of the display interface ports. This allows to move the imx-drm node into the SoC level dtsi. The existing i.MX51 and i.MX53 device trees are updated and device tree binding documentation is included.
Changes since v4: - Changed DT compatible string to 'fsl,imx-display-subsystem' instead of Linux specific 'fsl,imx-drm' - Changed DT node name from 'imx-drm' to 'display-subsystem' - Fixed copy&paste documentation error and added optional 'ddc-i2c-bus' property in HDMI binding documentation - Fixed imx-tve and imx-hdmi to use the common 'ddc-i2c-bus' property as already used by the simple-panel binding instead of the custom but very generic 'ddc'.
regards Philipp
Philipp Zabel (11): staging: imx-drm-core: Use OF graph to find components and connections between encoder and crtcs staging: imx-drm-core: use of_graph_parse_endpoint staging: imx-drm: Document updated imx-drm device tree bindings staging: imx-drm: Document imx-hdmi device tree bindings imx-drm: imx-hdmi: Fix DDC I2C bus property imx-drm: imx-tve: Fix DDC I2C bus property ARM: dts: imx53-mba53: Fix TVE DDC I2C bus property ARM: dts: imx51: Add IPU ports and endpoints, move imx-drm node to dtsi ARM: dts: imx53: Add IPU DI ports and endpoints, move imx-drm node to dtsi ARM: dts: imx6qdl: Add IPU DI ports and endpoints, move imx-drm node to dtsi staging: imx-drm: Update TODO
.../bindings/staging/imx-drm/fsl-imx-drm.txt | 48 ++++- .../devicetree/bindings/staging/imx-drm/hdmi.txt | 58 ++++++ .../devicetree/bindings/staging/imx-drm/ldb.txt | 20 +- arch/arm/boot/dts/imx51-apf51dev.dts | 11 +- arch/arm/boot/dts/imx51-babbage.dts | 28 ++- arch/arm/boot/dts/imx51.dtsi | 22 ++- arch/arm/boot/dts/imx53-m53evk.dts | 17 +- arch/arm/boot/dts/imx53-mba53.dts | 17 +- arch/arm/boot/dts/imx53-qsb.dts | 17 +- arch/arm/boot/dts/imx53.dtsi | 64 +++++- arch/arm/boot/dts/imx6dl.dtsi | 22 +-- arch/arm/boot/dts/imx6q-sabresd.dts | 4 - arch/arm/boot/dts/imx6q.dtsi | 124 +++++++++++- arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 6 - arch/arm/boot/dts/imx6qdl.dtsi | 128 +++++++++++- drivers/staging/imx-drm/TODO | 5 - drivers/staging/imx-drm/imx-drm-core.c | 217 +++++++++++++++------ drivers/staging/imx-drm/imx-drm.h | 5 +- drivers/staging/imx-drm/imx-hdmi.c | 4 +- drivers/staging/imx-drm/imx-ldb.c | 4 +- drivers/staging/imx-drm/imx-tve.c | 2 +- drivers/staging/imx-drm/ipuv3-crtc.c | 47 ++++- 22 files changed, 712 insertions(+), 158 deletions(-) create mode 100644 Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt
From: Philipp Zabel philipp.zabel@gmail.com
This patch adds support to find the involved components connected to the IPU display interface ports using the OF graph bindings documented in Documentation/devicetree/bindings/media/video-interfaces.txt. It makes use of the of_graph (formerly v4l2_of) parsing helpers and thus depends on the patch that moves those out to drivers/of.
Each display interface needs to have an associated port node in the device tree. We can associate this node with the crtc platform device and use it to find the crtc corresponding to a given port node instead of using a combination of parent device node and id number, as before.
Explicitly converting the void* cookie to the port device tree node allows to get rid of the ipu_id and di_id fields. The multiplexer setting on i.MX6 now can be obtained from the port id (reg property) in the device tree.
The imx-drm node now needs a ports property that contains phandles to each of the IPU display interface port nodes. From there, all attached encoders are scanned and enabled encoders are added to a waiting list. The bind order makes sure that once all components are probed, crtcs are bound before encoders, so that imx_drm_encoder_parse_of can be called from the encoder bind callbacks.
For parsing the OF graph, temporary copies of the V4L2 OF graph helpers are used, that can be removed again once those are available at a generic place.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- Changes since v4: - changed DT compatible string to 'fsl,imx-display-subsystem' instead of Linux specific 'fsl,imx-drm' --- drivers/staging/imx-drm/imx-drm-core.c | 217 +++++++++++++++++++++++---------- drivers/staging/imx-drm/imx-drm.h | 5 +- drivers/staging/imx-drm/imx-hdmi.c | 2 +- drivers/staging/imx-drm/imx-ldb.c | 4 +- drivers/staging/imx-drm/ipuv3-crtc.c | 47 +++++-- 5 files changed, 199 insertions(+), 76 deletions(-)
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 6b91c8e..ecfc88b 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -17,6 +17,7 @@ #include <linux/device.h> #include <linux/fb.h> #include <linux/module.h> +#include <linux/of_graph.h> #include <linux/platform_device.h> #include <drm/drmP.h> #include <drm/drm_fb_helper.h> @@ -30,6 +31,11 @@
struct imx_drm_crtc;
+struct imx_drm_component { + struct device_node *of_node; + struct list_head list; +}; + struct imx_drm_device { struct drm_device *drm; struct imx_drm_crtc *crtc[MAX_CRTC]; @@ -41,9 +47,7 @@ struct imx_drm_crtc { struct drm_crtc *crtc; int pipe; struct imx_drm_crtc_helper_funcs imx_drm_helper_funcs; - void *cookie; - int id; - int mux_id; + struct device_node *port; };
static int legacyfb_depth = 16; @@ -341,14 +345,11 @@ err_kms:
/* * imx_drm_add_crtc - add a new crtc - * - * The return value if !NULL is a cookie for the caller to pass to - * imx_drm_remove_crtc later. */ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, struct imx_drm_crtc **new_crtc, const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs, - void *cookie, int id) + struct device_node *port) { struct imx_drm_device *imxdrm = drm->dev_private; struct imx_drm_crtc *imx_drm_crtc; @@ -370,9 +371,7 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs; imx_drm_crtc->pipe = imxdrm->pipes++; - imx_drm_crtc->cookie = cookie; - imx_drm_crtc->id = id; - imx_drm_crtc->mux_id = imx_drm_crtc->pipe; + imx_drm_crtc->port = port; imx_drm_crtc->crtc = crtc;
imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc; @@ -416,49 +415,56 @@ int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc) EXPORT_SYMBOL_GPL(imx_drm_remove_crtc);
/* - * Find the DRM CRTC possible mask for the device node cookie/id. + * Find the DRM CRTC possible mask for the connected endpoint. * * The encoder possible masks are defined by their position in the * mode_config crtc_list. This means that CRTCs must not be added * or removed once the DRM device has been fully initialised. */ static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm, - void *cookie, int id) + struct device_node *endpoint) { + struct device_node *port; unsigned i;
+ port = of_graph_get_remote_port(endpoint); + if (!port) + return 0; + of_node_put(port); + for (i = 0; i < MAX_CRTC; i++) { struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i]; - if (imx_drm_crtc && imx_drm_crtc->id == id && - imx_drm_crtc->cookie == cookie) + if (imx_drm_crtc && imx_drm_crtc->port == port) return drm_crtc_mask(imx_drm_crtc->crtc); }
return 0; }
+static struct device_node *imx_drm_of_get_next_endpoint( + const struct device_node *parent, struct device_node *prev) +{ + struct device_node *node = of_graph_get_next_endpoint(parent, prev); + of_node_put(prev); + return node; +} + int imx_drm_encoder_parse_of(struct drm_device *drm, struct drm_encoder *encoder, struct device_node *np) { struct imx_drm_device *imxdrm = drm->dev_private; + struct device_node *ep = NULL; uint32_t crtc_mask = 0; - int i, ret = 0; + int i;
- for (i = 0; !ret; i++) { - struct of_phandle_args args; - uint32_t mask; - int id; + for (i = 0; ; i++) { + u32 mask;
- ret = of_parse_phandle_with_args(np, "crtcs", "#crtc-cells", i, - &args); - if (ret == -ENOENT) + ep = imx_drm_of_get_next_endpoint(np, ep); + if (!ep) break; - if (ret < 0) - return ret;
- id = args.args_count > 0 ? args.args[0] : 0; - mask = imx_drm_find_crtc_mask(imxdrm, args.np, id); - of_node_put(args.np); + mask = imx_drm_find_crtc_mask(imxdrm, ep);
/* * If we failed to find the CRTC(s) which this encoder is @@ -472,6 +478,11 @@ int imx_drm_encoder_parse_of(struct drm_device *drm, crtc_mask |= mask; }
+ if (ep) + of_node_put(ep); + if (i == 0) + return -ENOENT; + encoder->possible_crtcs = crtc_mask;
/* FIXME: this is the mask of outputs which can clone this output. */ @@ -481,11 +492,36 @@ int imx_drm_encoder_parse_of(struct drm_device *drm, } EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of);
-int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder) +/* + * @node: device tree node containing encoder input ports + * @encoder: drm_encoder + */ +int imx_drm_encoder_get_mux_id(struct device_node *node, + struct drm_encoder *encoder) { struct imx_drm_crtc *imx_crtc = imx_drm_find_crtc(encoder->crtc); + struct device_node *ep = NULL; + struct device_node *port; + int id, ret; + + if (!node || !imx_crtc) + return -EINVAL; + + do { + ep = imx_drm_of_get_next_endpoint(node, ep); + if (!ep) + break; + + port = of_graph_get_remote_port(ep); + of_node_put(port); + if (port == imx_crtc->port) { + ret = of_property_read_u32(ep->parent, "reg", &id); + of_node_put(ep); + return ret ? ret : id; + } + } while (ep);
- return imx_crtc ? imx_crtc->mux_id : -EINVAL; + return -EINVAL; } EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id);
@@ -528,48 +564,29 @@ static struct drm_driver imx_drm_driver = { .patchlevel = 0, };
-static int compare_parent_of(struct device *dev, void *data) -{ - struct of_phandle_args *args = data; - return dev->parent && dev->parent->of_node == args->np; -} - static int compare_of(struct device *dev, void *data) { - return dev->of_node == data; -} - -static int imx_drm_add_components(struct device *master, struct master *m) -{ - struct device_node *np = master->of_node; - unsigned i; - int ret; + struct device_node *np = data;
- for (i = 0; ; i++) { - struct of_phandle_args args; - - ret = of_parse_phandle_with_fixed_args(np, "crtcs", 1, - i, &args); - if (ret) - break; - - ret = component_master_add_child(m, compare_parent_of, &args); - of_node_put(args.np); - - if (ret) - return ret; + /* Special case for LDB, one device for two channels */ + if (of_node_cmp(np->name, "lvds-channel") == 0) { + np = of_get_parent(np); + of_node_put(np); }
- for (i = 0; ; i++) { - struct device_node *node; + return dev->of_node == np; +}
- node = of_parse_phandle(np, "connectors", i); - if (!node) - break; +static LIST_HEAD(imx_drm_components);
- ret = component_master_add_child(m, compare_of, node); - of_node_put(node); +static int imx_drm_add_components(struct device *master, struct master *m) +{ + struct imx_drm_component *component; + int ret;
+ list_for_each_entry(component, &imx_drm_components, list) { + ret = component_master_add_child(m, compare_of, + component->of_node); if (ret) return ret; } @@ -592,9 +609,81 @@ static const struct component_master_ops imx_drm_ops = { .unbind = imx_drm_unbind, };
+static struct imx_drm_component *imx_drm_find_component(struct device *dev, + struct device_node *node) +{ + struct imx_drm_component *component; + + list_for_each_entry(component, &imx_drm_components, list) + if (component->of_node == node) + return component; + + return NULL; +} + +static int imx_drm_add_component(struct device *dev, struct device_node *node) +{ + struct imx_drm_component *component; + + if (imx_drm_find_component(dev, node)) + return 0; + + component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL); + if (!component) + return -ENOMEM; + + component->of_node = node; + list_add_tail(&component->list, &imx_drm_components); + + return 0; +} + static int imx_drm_platform_probe(struct platform_device *pdev) { + struct device_node *ep, *port, *remote; int ret; + int i; + + /* + * Bind the IPU display interface ports first, so that + * imx_drm_encoder_parse_of called from encoder .bind callbacks + * works as expected. + */ + for (i = 0; ; i++) { + port = of_parse_phandle(pdev->dev.of_node, "ports", i); + if (!port) + break; + + ret = imx_drm_add_component(&pdev->dev, port); + if (ret < 0) + return ret; + } + + if (i == 0) { + dev_err(&pdev->dev, "missing 'ports' property\n"); + return -ENODEV; + } + + /* Then bind all encoders */ + for (i = 0; ; i++) { + port = of_parse_phandle(pdev->dev.of_node, "ports", i); + if (!port) + break; + + for_each_child_of_node(port, ep) { + remote = of_graph_get_remote_port_parent(ep); + if (!remote || !of_device_is_available(remote)) { + of_node_put(remote); + continue; + } + + ret = imx_drm_add_component(&pdev->dev, remote); + of_node_put(remote); + if (ret < 0) + return ret; + } + of_node_put(port); + }
ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) @@ -610,7 +699,7 @@ static int imx_drm_platform_remove(struct platform_device *pdev) }
static const struct of_device_id imx_drm_dt_ids[] = { - { .compatible = "fsl,imx-drm", }, + { .compatible = "fsl,imx-display-subsystem", }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, imx_drm_dt_ids); diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index 035ab62..a322bac 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -26,7 +26,7 @@ struct imx_drm_crtc_helper_funcs { int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, struct imx_drm_crtc **new_crtc, const struct imx_drm_crtc_helper_funcs *imx_helper_funcs, - void *cookie, int id); + struct device_node *port); int imx_drm_remove_crtc(struct imx_drm_crtc *); int imx_drm_init_drm(struct platform_device *pdev, int preferred_bpp); @@ -45,7 +45,8 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder, int imx_drm_panel_format(struct drm_encoder *encoder, u32 interface_pix_fmt);
-int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder); +int imx_drm_encoder_get_mux_id(struct device_node *node, + struct drm_encoder *encoder); int imx_drm_encoder_parse_of(struct drm_device *drm, struct drm_encoder *encoder, struct device_node *np);
diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 8384cea..909bee4 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1459,7 +1459,7 @@ static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder) static void imx_hdmi_encoder_commit(struct drm_encoder *encoder) { struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); - int mux = imx_drm_encoder_get_mux_id(encoder); + int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
imx_hdmi_set_ipu_di_mux(hdmi, mux);
diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index daa54df..33d2b883 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -170,7 +170,7 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) u32 pixel_fmt; unsigned long serial_clk; unsigned long di_clk = mode->clock * 1000; - int mux = imx_drm_encoder_get_mux_id(encoder); + int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) { /* dual channel LVDS mode */ @@ -205,7 +205,7 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder) struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); struct imx_ldb *ldb = imx_ldb_ch->ldb; int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; - int mux = imx_drm_encoder_get_mux_id(encoder); + int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
if (dual) { clk_prepare_enable(ldb->clk[0]); diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c index e646017..a8d0178 100644 --- a/drivers/staging/imx-drm/ipuv3-crtc.c +++ b/drivers/staging/imx-drm/ipuv3-crtc.c @@ -350,10 +350,8 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, return ret; }
- ret = imx_drm_add_crtc(drm, &ipu_crtc->base, - &ipu_crtc->imx_crtc, - &ipu_crtc_helper_funcs, - ipu_crtc->dev->parent->of_node, pdata->di); + ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc, + &ipu_crtc_helper_funcs, ipu_crtc->dev->of_node); if (ret) { dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret); goto err_put_resources; @@ -401,6 +399,28 @@ err_put_resources: return ret; }
+static struct device_node *ipu_drm_get_port_by_id(struct device_node *parent, + int port_id) +{ + struct device_node *port; + int id, ret; + + port = of_get_child_by_name(parent, "port"); + while (port) { + ret = of_property_read_u32(port, "reg", &id); + if (!ret && id == port_id) + return port; + + do { + port = of_get_next_child(parent, port); + if (!port) + return NULL; + } while (of_node_cmp(port->name, "port")); + } + + return NULL; +} + static int ipu_drm_bind(struct device *dev, struct device *master, void *data) { struct ipu_client_platformdata *pdata = dev->platform_data; @@ -441,16 +461,29 @@ static const struct component_ops ipu_crtc_ops = {
static int ipu_drm_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; + struct ipu_client_platformdata *pdata = dev->platform_data; int ret;
- if (!pdev->dev.platform_data) + if (!dev->platform_data) return -EINVAL;
- ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (!dev->of_node) { + /* Associate crtc device with the corresponding DI port node */ + dev->of_node = ipu_drm_get_port_by_id(dev->parent->of_node, + pdata->di + 2); + if (!dev->of_node) { + dev_err(dev, "missing port@%d node in %s\n", + pdata->di + 2, dev->parent->of_node->full_name); + return -ENODEV; + } + } + + ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); if (ret) return ret;
- return component_add(&pdev->dev, &ipu_crtc_ops); + return component_add(dev, &ipu_crtc_ops); }
static int ipu_drm_remove(struct platform_device *pdev)
On Wed, Mar 05, 2014 at 10:20:52AM +0100, Philipp Zabel wrote:
+struct imx_drm_component {
- struct device_node *of_node;
- struct list_head list;
+};
The only thing this structure appears to be doing is ensuring that a single component doesn't get added twice - is that correct? If so, (and the troublesome problem with the IPU crtcs is now gone) we can modify the core component code such that it does this:
if (c->master && c->master != master) continue;
if (compare(c->dev, compare_data)) { if (!c->master) component_attach_master(master, c); ret = 0; break; }
which will mean that you don't need to build this list anymore to track what will be added - though I'd like to think a little more about that before making that change. Please confirm whether this will eliminate your list generation.
Thanks.
Am Mittwoch, den 05.03.2014, 10:05 +0000 schrieb Russell King - ARM Linux:
On Wed, Mar 05, 2014 at 10:20:52AM +0100, Philipp Zabel wrote:
+struct imx_drm_component {
- struct device_node *of_node;
- struct list_head list;
+};
The only thing this structure appears to be doing is ensuring that a single component doesn't get added twice - is that correct?
I also think of it as an optimization. Now we scan the whole device graph once in the probe function into a list of needed components that can be walked quickly every time master_ops' .add_components callback is run, instead of having to walk the device tree graph over and over.
Functionally, it only protects against duplicate addition.
If so, (and the troublesome problem with the IPU crtcs is now gone) we can modify the core component code such that it does this:
if (c->master && c->master != master) continue; if (compare(c->dev, compare_data)) { if (!c->master) component_attach_master(master, c); ret = 0; break; }
which will mean that you don't need to build this list anymore to track what will be added - though I'd like to think a little more about that before making that change. Please confirm whether this will eliminate your list generation.
Yes, I can confirm that with this change, I can remove the list, like this (tested on i.MX6S with a single LVDS panel):
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 014e546..f6135b9 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -32,11 +32,6 @@
struct imx_drm_crtc;
-struct imx_drm_component { - struct device_node *of_node; - struct list_head list; -}; - struct imx_drm_device { struct drm_device *drm; struct imx_drm_crtc *crtc[MAX_CRTC]; @@ -587,72 +582,10 @@ static int compare_of(struct device *dev, void *data) return dev->of_node == np; }
-static LIST_HEAD(imx_drm_components); - static int imx_drm_add_components(struct device *master, struct master *m) { - struct imx_drm_component *component; - int ret; - - list_for_each_entry(component, &imx_drm_components, list) { - ret = component_master_add_child(m, compare_of, - component->of_node); - if (ret) - return ret; - } - return 0; -} - -static int imx_drm_bind(struct device *dev) -{ - return drm_platform_init(&imx_drm_driver, to_platform_device(dev)); -} - -static void imx_drm_unbind(struct device *dev) -{ - drm_put_dev(dev_get_drvdata(dev)); -} - -static const struct component_master_ops imx_drm_ops = { - .add_components = imx_drm_add_components, - .bind = imx_drm_bind, - .unbind = imx_drm_unbind, -}; - -static struct imx_drm_component *imx_drm_find_component(struct device *dev, - struct device_node *node) -{ - struct imx_drm_component *component; - - list_for_each_entry(component, &imx_drm_components, list) - if (component->of_node == node) - return component; - - return NULL; -} - -static int imx_drm_add_component(struct device *dev, struct device_node *node) -{ - struct imx_drm_component *component; - - if (imx_drm_find_component(dev, node)) - return 0; - - component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL); - if (!component) - return -ENOMEM; - - component->of_node = node; - list_add_tail(&component->list, &imx_drm_components); - - return 0; -} - -static int imx_drm_platform_probe(struct platform_device *pdev) -{ struct device_node *ep, *port, *remote; - int ret; - int i; + int i, ret;
/* * Bind the IPU display interface ports first, so that @@ -660,23 +593,18 @@ static int imx_drm_platform_probe(struct platform_device *pdev) * works as expected. */ for (i = 0; ; i++) { - port = of_parse_phandle(pdev->dev.of_node, "ports", i); + port = of_parse_phandle(master->of_node, "ports", i); if (!port) break;
- ret = imx_drm_add_component(&pdev->dev, port); - if (ret < 0) + ret = component_master_add_child(m, compare_of, port); + if (ret) return ret; }
- if (i == 0) { - dev_err(&pdev->dev, "missing 'ports' property\n"); - return -ENODEV; - } - /* Then bind all encoders */ for (i = 0; ; i++) { - port = of_parse_phandle(pdev->dev.of_node, "ports", i); + port = of_parse_phandle(master->of_node, "ports", i); if (!port) break;
@@ -687,14 +615,44 @@ static int imx_drm_platform_probe(struct platform_device *pdev) continue; }
- ret = imx_drm_add_component(&pdev->dev, remote); + ret = component_master_add_child(m, compare_of, remote); of_node_put(remote); - if (ret < 0) + if (ret) return ret; } of_node_put(port); }
+ return 0; +} + +static int imx_drm_bind(struct device *dev) +{ + return drm_platform_init(&imx_drm_driver, to_platform_device(dev)); +} + +static void imx_drm_unbind(struct device *dev) +{ + drm_put_dev(dev_get_drvdata(dev)); +} + +static const struct component_master_ops imx_drm_ops = { + .add_components = imx_drm_add_components, + .bind = imx_drm_bind, + .unbind = imx_drm_unbind, +}; + +static int imx_drm_platform_probe(struct platform_device *pdev) +{ + struct device_node *port; + int ret; + + port = of_parse_phandle(pdev->dev.of_node, "ports", 0); + if (!port) { + dev_err(&pdev->dev, "missing 'ports' property\n"); + return -ENODEV; + } + ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) return ret;
Using of_graph_parse_endpoint recovers the port id from an endpoint device tree node. This just replaces an open coded read of the "reg" property.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- drivers/staging/imx-drm/imx-drm-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index ecfc88b..4144a75 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -501,8 +501,9 @@ int imx_drm_encoder_get_mux_id(struct device_node *node, { struct imx_drm_crtc *imx_crtc = imx_drm_find_crtc(encoder->crtc); struct device_node *ep = NULL; + struct of_endpoint endpoint; struct device_node *port; - int id, ret; + int ret;
if (!node || !imx_crtc) return -EINVAL; @@ -515,9 +516,8 @@ int imx_drm_encoder_get_mux_id(struct device_node *node, port = of_graph_get_remote_port(ep); of_node_put(port); if (port == imx_crtc->port) { - ret = of_property_read_u32(ep->parent, "reg", &id); - of_node_put(ep); - return ret ? ret : id; + ret = of_graph_parse_endpoint(ep, &endpoint); + return ret ? ret : endpoint.id; } } while (ep);
This patch updates the device tree binding documentation for i.MX IPU/display nodes using the OF graph bindings documented in Documentation/devicetree/bindings/media/video-interfaces.txt.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- Changes since v4: - changed DT compatible string to 'fsl,imx-display-subsystem' instead of Linux specific 'fsl,imx-drm' - Changed DT node name from 'imx-drm' to 'display-subsystem' --- .../bindings/staging/imx-drm/fsl-imx-drm.txt | 48 +++++++++++++++++++--- .../devicetree/bindings/staging/imx-drm/ldb.txt | 20 +++++++-- 2 files changed, 59 insertions(+), 9 deletions(-)
diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt index b876d49..3be5ce7 100644 --- a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt +++ b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt @@ -1,3 +1,22 @@ +Freescale i.MX DRM master device +================================ + +The freescale i.MX DRM master device is a virtual device needed to list all +IPU or other display interface nodes that comprise the graphics subsystem. + +Required properties: +- compatible: Should be "fsl,imx-display-subsystem" +- ports: Should contain a list of phandles pointing to display interface ports + of IPU devices + +example: + +display-subsystem { + compatible = "fsl,display-subsystem"; + ports = <&ipu_di0>; +}; + + Freescale i.MX IPUv3 ====================
@@ -7,18 +26,31 @@ Required properties: datasheet - interrupts: Should contain sync interrupt and error interrupt, in this order. -- #crtc-cells: 1, See below - resets: phandle pointing to the system reset controller and reset line index, see reset/fsl,imx-src.txt for details +Optional properties: +- port@[0-3]: Port nodes with endpoint definitions as defined in + Documentation/devicetree/bindings/media/video-interfaces.txt. + Ports 0 and 1 should correspond to CSI0 and CSI1, + ports 2 and 3 should correspond to DI0 and DI1, respectively.
example:
ipu: ipu@18000000 { - #crtc-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; compatible = "fsl,imx53-ipu"; reg = <0x18000000 0x080000000>; interrupts = <11 10>; resets = <&src 2>; + + ipu_di0: port@2 { + reg = <2>; + + ipu_di0_disp0: endpoint { + remote-endpoint = <&display_in>; + }; + }; };
Parallel display support @@ -26,19 +58,25 @@ Parallel display support
Required properties: - compatible: Should be "fsl,imx-parallel-display" -- crtc: the crtc this display is connected to, see below Optional properties: - interface_pix_fmt: How this display is connected to the - crtc. Currently supported types: "rgb24", "rgb565", "bgr666" + display interface. Currently supported types: "rgb24", "rgb565", "bgr666" - edid: verbatim EDID data block describing attached display. - ddc: phandle describing the i2c bus handling the display data channel +- port: A port node with endpoint definitions as defined in + Documentation/devicetree/bindings/media/video-interfaces.txt.
example:
display@di0 { compatible = "fsl,imx-parallel-display"; edid = [edid-data]; - crtc = <&ipu 0>; interface-pix-fmt = "rgb24"; + + port { + display_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; }; diff --git a/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt b/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt index ed93778..578a1fc 100644 --- a/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt +++ b/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt @@ -50,12 +50,14 @@ have a look at Documentation/devicetree/bindings/video/display-timing.txt.
Required properties: - reg : should be <0> or <1> - - crtcs : a list of phandles with index pointing to the IPU display interfaces - that can be used as video source for this channel. - fsl,data-mapping : should be "spwg" or "jeida" This describes how the color bits are laid out in the serialized LVDS signal. - fsl,data-width : should be <18> or <24> + - port: A port node with endpoint definitions as defined in + Documentation/devicetree/bindings/media/video-interfaces.txt. + On i.MX6, there should be four ports (port@[0-3]) that correspond + to the four LVDS multiplexer inputs.
example:
@@ -77,23 +79,33 @@ ldb: ldb@53fa8008 {
lvds-channel@0 { reg = <0>; - crtcs = <&ipu 0>; fsl,data-mapping = "spwg"; fsl,data-width = <24>;
display-timings { /* ... */ }; + + port { + lvds0_in: endpoint { + remote-endpoint = <&ipu_di0_lvds0>; + }; + }; };
lvds-channel@1 { reg = <1>; - crtcs = <&ipu 1>; fsl,data-mapping = "spwg"; fsl,data-width = <24>;
display-timings { /* ... */ }; + + port { + lvds1_in: endpoint { + remote-endpoint = <&ipu_di1_lvds1>; + }; + }; }; };
This patch adds device tree binding documentation for the HDMI transmitter on i.MX6.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- Changes since v4: - Fixed copy&paste documentation error - Added optional 'ddc-i2c-bus' property --- .../devicetree/bindings/staging/imx-drm/hdmi.txt | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt
diff --git a/Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt b/Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt new file mode 100644 index 0000000..1b756cf --- /dev/null +++ b/Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt @@ -0,0 +1,58 @@ +Device-Tree bindings for HDMI Transmitter + +HDMI Transmitter +================ + +The HDMI Transmitter is a Synopsys DesignWare HDMI 1.4 TX controller IP +with accompanying PHY IP. + +Required properties: + - #address-cells : should be <1> + - #size-cells : should be <0> + - compatible : should be "fsl,imx6q-hdmi" or "fsl,imx6dl-hdmi". + - gpr : should be <&gpr>. + The phandle points to the iomuxc-gpr region containing the HDMI + multiplexer control register. + - clocks, clock-names : phandles to the HDMI iahb and isrf clocks, as described + in Documentation/devicetree/bindings/clock/clock-bindings.txt and + Documentation/devicetree/bindings/clock/imx6q-clock.txt. + - port@[0-4]: Up to four port nodes with endpoint definitions as defined in + Documentation/devicetree/bindings/media/video-interfaces.txt, + corresponding to the four inputs to the HDMI multiplexer. + +Optional properties: + - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing + +example: + + gpr: iomuxc-gpr@020e0000 { + /* ... */ + }; + + hdmi: hdmi@0120000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx6q-hdmi"; + reg = <0x00120000 0x9000>; + interrupts = <0 115 0x04>; + gpr = <&gpr>; + clocks = <&clks 123>, <&clks 124>; + clock-names = "iahb", "isfr"; + ddc-i2c-bus = <&i2c2>; + + port@0 { + reg = <0>; + + hdmi_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_hdmi>; + }; + }; + + port@1 { + reg = <1>; + + hdmi_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_hdmi>; + }; + }; + };
This patch fixes the DDC I2C bus property to use the common 'ddc-i2c-bus' property name instead of 'ddc'. This is already documented in Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- drivers/staging/imx-drm/imx-hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 909bee4..4540a9aa 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1610,7 +1610,7 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) hdmi->dev_type = device_id->driver_data; }
- ddc_node = of_parse_phandle(np, "ddc", 0); + ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); if (ddc_node) { hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); if (!hdmi->ddc)
This patch fixes the TV Encoder DDC I2C bus property to use the common 'ddc-i2c-bus' property name instead of 'ddc'.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- drivers/staging/imx-drm/imx-tve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/staging/imx-drm/imx-tve.c index 50b25f1..575533f 100644 --- a/drivers/staging/imx-drm/imx-tve.c +++ b/drivers/staging/imx-drm/imx-tve.c @@ -582,7 +582,7 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) tve->dev = dev; spin_lock_init(&tve->lock);
- ddc_node = of_parse_phandle(np, "ddc", 0); + ddc_node = of_parse_phandle(np, "i2c-ddc-bus", 0); if (ddc_node) { tve->ddc = of_find_i2c_adapter_by_node(ddc_node); of_node_put(ddc_node);
On Wed, Mar 05, 2014 at 10:20:57AM +0100, Philipp Zabel wrote:
This patch fixes the TV Encoder DDC I2C bus property to use the common 'ddc-i2c-bus' property name instead of 'ddc'.
Looking at both hdmi and tve, the ddc part is very similar. The difference is how the probe is handled:
imx-hdmi: ddc_node = of_parse_phandle(np, "ddc", 0); if (ddc_node) { hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); if (!hdmi->ddc) dev_dbg(hdmi->dev, "failed to read ddc node\n");
of_node_put(ddc_node); } else { dev_dbg(hdmi->dev, "no ddc property found\n"); }
imx-tve: ddc_node = of_parse_phandle(np, "ddc", 0); if (ddc_node) { tve->ddc = of_find_i2c_adapter_by_node(ddc_node); of_node_put(ddc_node); }
It appears to differ only by debug prints - is there any reason we couldn't unify the DDC backend part? I've tinkered with this idea, and already have a patch, though it needs a little rework.
Any thoughts?
Hi Russell,
Am Donnerstag, den 06.03.2014, 13:03 +0000 schrieb Russell King - ARM Linux:
On Wed, Mar 05, 2014 at 10:20:57AM +0100, Philipp Zabel wrote:
This patch fixes the TV Encoder DDC I2C bus property to use the common 'ddc-i2c-bus' property name instead of 'ddc'.
Looking at both hdmi and tve, the ddc part is very similar. The difference is how the probe is handled:
imx-hdmi: ddc_node = of_parse_phandle(np, "ddc", 0); if (ddc_node) { hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); if (!hdmi->ddc) dev_dbg(hdmi->dev, "failed to read ddc node\n");
of_node_put(ddc_node); } else { dev_dbg(hdmi->dev, "no ddc property found\n"); }
imx-tve: ddc_node = of_parse_phandle(np, "ddc", 0); if (ddc_node) { tve->ddc = of_find_i2c_adapter_by_node(ddc_node); of_node_put(ddc_node); }
panel-simple.c ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0); if (ddc) { panel->ddc = of_find_i2c_adapter_by_node(ddc); of_node_put(ddc);
if (!panel->ddc) { err = -EPROBE_DEFER; goto free_backlight; } }
It appears to differ only by debug prints - is there any reason we couldn't unify the DDC backend part? I've tinkered with this idea, and already have a patch, though it needs a little rework.
Any thoughts?
there should be a generic helper for obtaining the DDC I2C adapter from the device tree. I'd prefer not to stall the imx-drm-dt series on this, though.
regards Philipp
This patch fixes the Television Encoder node's DDC I2C bus property to use the common property name of 'ddc-i2c-bus' instead of just 'ddc'.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- arch/arm/boot/dts/imx53-mba53.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx53-mba53.dts b/arch/arm/boot/dts/imx53-mba53.dts index 9b6e769..f2affb0 100644 --- a/arch/arm/boot/dts/imx53-mba53.dts +++ b/arch/arm/boot/dts/imx53-mba53.dts @@ -234,7 +234,7 @@ &tve { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_vga_sync_1>; - ddc = <&i2c3>; + i2c-ddc-bus = <&i2c3>; fsl,tve-mode = "vga"; fsl,hsync-pin = <4>; fsl,vsync-pin = <6>;
This patch connects IPU and and parallel display device tree nodes using the OF graph bindings described in Documentation/devicetree/bindings/media/video-interfaces.txt
The IPU ports correspond to the two display interfaces. The order of endpoints in the ports is arbitrary.
Since the imx-drm node now only needs to contain links to the display interfaces, it can be moved to the SoC dtsi level. At the board level, only connections between the display interface ports and panels have to be added.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- Changes since v4: - Changed DT compatible string to 'fsl,imx-display-subsystem' instead of Linux specific 'fsl,imx-drm', changed DT node name from 'imx-drm' to 'display-subsystem'. --- arch/arm/boot/dts/imx51-apf51dev.dts | 11 ++++++++++- arch/arm/boot/dts/imx51-babbage.dts | 28 ++++++++++++++++++++-------- arch/arm/boot/dts/imx51.dtsi | 22 +++++++++++++++++++++- 3 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/arch/arm/boot/dts/imx51-apf51dev.dts b/arch/arm/boot/dts/imx51-apf51dev.dts index 5a7f552..d3f9814 100644 --- a/arch/arm/boot/dts/imx51-apf51dev.dts +++ b/arch/arm/boot/dts/imx51-apf51dev.dts @@ -18,7 +18,6 @@
display@di1 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 0>; interface-pix-fmt = "bgr666"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp1_1>; @@ -41,6 +40,12 @@ pixelclk-active = <0>; }; }; + + port { + display_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; };
gpio-keys { @@ -122,3 +127,7 @@ }; }; }; + +&ipu_di0_disp0 { + remote-endpoint = <&display_in>; +}; diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index 6ff15a0..6719271 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -23,7 +23,6 @@
display0: display@di0 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 0>; interface-pix-fmt = "rgb24"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp1_1>; @@ -41,11 +40,16 @@ vsync-len = <10>; }; }; + + port { + display0_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; };
display1: display@di1 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 1>; interface-pix-fmt = "rgb565"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp2_1>; @@ -68,6 +72,12 @@ pixelclk-active = <0>; }; }; + + port { + display1_in: endpoint { + remote-endpoint = <&ipu_di1_disp1>; + }; + }; };
gpio-keys { @@ -81,12 +91,6 @@ }; };
- imx-drm { - compatible = "fsl,imx-drm"; - crtcs = <&ipu 0>, <&ipu 1>; - connectors = <&display0>, <&display1>; - }; - sound { compatible = "fsl,imx51-babbage-sgtl5000", "fsl,imx-audio-sgtl5000"; @@ -264,6 +268,14 @@ }; };
+&ipu_di0_disp0 { + remote-endpoint = <&display0_in>; +}; + +&ipu_di1_disp1 { + remote-endpoint = <&display1_in>; +}; + &ssi2 { fsl,mode = "i2s-slave"; status = "okay"; diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 4bcdd3a..28c96aa 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -79,6 +79,11 @@ }; };
+ display-subsystem { + compatible = "fsl,imx-display-subsystem"; + ports = <&ipu_di0>, <&ipu_di1>; + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -92,13 +97,28 @@ };
ipu: ipu@40000000 { - #crtc-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; compatible = "fsl,imx51-ipu"; reg = <0x40000000 0x20000000>; interrupts = <11 10>; clocks = <&clks 59>, <&clks 110>, <&clks 61>; clock-names = "bus", "di0", "di1"; resets = <&src 2>; + + ipu_di0: port@2 { + reg = <2>; + + ipu_di0_disp0: endpoint { + }; + }; + + ipu_di1: port@3 { + reg = <3>; + + ipu_di1_disp1: endpoint { + }; + }; };
aips@70000000 { /* AIPS1 */
This patch connects IPU and display encoder (VGA, LVDS) device tree nodes, as well as parallel displays on the DISP0 and DISP1 outputs, using the OF graph bindings described in Documentation/devicetree/bindings/media/video-interfaces.txt
The IPU ports correspond to the two display interfaces. The order of endpoints in the ports is arbitrary.
Since the imx-drm node now only needs to contain links to the display interfaces, it can be moved to the SoC dtsi level. At the board level, only connections between the display interface ports and encoders or panels have to be added.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- - Changed DT compatible string to 'fsl,imx-display-subsystem' instead of Linux specific 'fsl,imx-drm', changed DT node name from 'imx-drm' to 'display-subsystem'. --- arch/arm/boot/dts/imx53-m53evk.dts | 17 +++++----- arch/arm/boot/dts/imx53-mba53.dts | 15 +++++---- arch/arm/boot/dts/imx53-qsb.dts | 17 +++++----- arch/arm/boot/dts/imx53.dtsi | 64 +++++++++++++++++++++++++++++++++++--- 4 files changed, 89 insertions(+), 24 deletions(-)
diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts index ee6107b..0298adc 100644 --- a/arch/arm/boot/dts/imx53-m53evk.dts +++ b/arch/arm/boot/dts/imx53-m53evk.dts @@ -23,7 +23,6 @@ soc { display1: display@di1 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 1>; interface-pix-fmt = "bgr666"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp2_1>; @@ -44,6 +43,12 @@ }; }; }; + + port { + display1_in: endpoint { + remote-endpoint = <&ipu_di1_disp1>; + }; + }; };
backlight { @@ -53,12 +58,6 @@ default-brightness-level = <6>; };
- imx-drm { - compatible = "fsl,imx-drm"; - crtcs = <&ipu 1>; - connectors = <&display1>; - }; - leds { compatible = "gpio-leds"; pinctrl-names = "default"; @@ -227,6 +226,10 @@ }; };
+&ipu_di1_disp1 { + remote-endpoint = <&display1_in>; +}; + &nfc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_nand_1>; diff --git a/arch/arm/boot/dts/imx53-mba53.dts b/arch/arm/boot/dts/imx53-mba53.dts index f2affb0..a5b55c6 100644 --- a/arch/arm/boot/dts/imx53-mba53.dts +++ b/arch/arm/boot/dts/imx53-mba53.dts @@ -38,15 +38,14 @@ compatible = "fsl,imx-parallel-display"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_disp1_1>; - crtcs = <&ipu 1>; interface-pix-fmt = "rgb24"; status = "disabled"; - };
- imx-drm { - compatible = "fsl,imx-drm"; - crtcs = <&ipu 1>; - connectors = <&disp1>, <&tve>; + port { + display1_in: endpoint { + remote-endpoint = <&ipu_di1_disp1>; + }; + }; };
reg_3p2v: 3p2v { @@ -147,6 +146,10 @@ }; };
+&ipu_di1_disp1 { + remote-endpoint = <&display1_in>; +}; + &cspi { status = "okay"; }; diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts index 3cb4f77..8b25428 100644 --- a/arch/arm/boot/dts/imx53-qsb.dts +++ b/arch/arm/boot/dts/imx53-qsb.dts @@ -23,7 +23,6 @@
display0: display@di0 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 0>; interface-pix-fmt = "rgb565"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ipu_disp0_1>; @@ -46,6 +45,12 @@ pixelclk-active = <0>; }; }; + + port { + display0_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; };
gpio-keys { @@ -72,12 +77,6 @@ }; };
- imx-drm { - compatible = "fsl,imx-drm"; - crtcs = <&ipu 0>; - connectors = <&display0>; - }; - leds { compatible = "gpio-leds"; pinctrl-names = "default"; @@ -132,6 +131,10 @@ status = "okay"; };
+&ipu_di0_disp0 { + remote-endpoint = <&display0_in>; +}; + &ssi2 { fsl,mode = "i2s-slave"; status = "okay"; diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 4307e80..04d3127 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -45,6 +45,11 @@ }; };
+ display-subsystem { + compatible = "fsl,imx-display-subsystem"; + ports = <&ipu_di0>, <&ipu_di1>; + }; + tzic: tz-interrupt-controller@0fffc000 { compatible = "fsl,imx53-tzic", "fsl,tzic"; interrupt-controller; @@ -85,13 +90,49 @@ ranges;
ipu: ipu@18000000 { - #crtc-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; compatible = "fsl,imx53-ipu"; reg = <0x18000000 0x080000000>; interrupts = <11 10>; clocks = <&clks 59>, <&clks 110>, <&clks 61>; clock-names = "bus", "di0", "di1"; resets = <&src 2>; + + ipu_di0: port@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + ipu_di0_disp0: endpoint@0 { + reg = <0>; + }; + + ipu_di0_lvds0: endpoint@1 { + reg = <1>; + remote-endpoint = <&lvds0_in>; + }; + }; + + ipu_di1: port@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + ipu_di1_disp1: endpoint@0 { + reg = <0>; + }; + + ipu_di1_lvds1: endpoint@1 { + reg = <1>; + remote-endpoint = <&lvds1_in>; + }; + + ipu_di1_tve: endpoint@2 { + reg = <2>; + remote-endpoint = <&tve_in>; + }; + }; };
aips@50000000 { /* AIPS1 */ @@ -838,14 +879,24 @@
lvds-channel@0 { reg = <0>; - crtcs = <&ipu 0>; status = "disabled"; + + port { + lvds0_in: endpoint { + remote-endpoint = <&ipu_di0_lvds0>; + }; + }; };
lvds-channel@1 { reg = <1>; - crtcs = <&ipu 1>; status = "disabled"; + + port { + lvds1_in: endpoint { + remote-endpoint = <&ipu_di0_lvds0>; + }; + }; }; };
@@ -1103,8 +1154,13 @@ interrupts = <92>; clocks = <&clks 69>, <&clks 116>; clock-names = "tve", "di_sel"; - crtcs = <&ipu 1>; status = "disabled"; + + port { + tve_in: endpoint { + remote-endpoint = <&ipu_di1_tve>; + }; + }; };
vpu: vpu@63ff4000 {
This patch connects IPU and display encoder (HDMI, LVDS, MIPI) device tree nodes, as well as parallel displays on the DISP0 and DISP1 outputs, using the OF graph bindings described in Documentation/devicetree/bindings/media/video-interfaces.txt
The IPU ports correspond to the two display interfaces. The order of endpoints in the ports is arbitrary.
Each encoder with an associated input multiplexer has multiple input ports in the device tree. The order and reg property of the ports must correspond to the multiplexer input order.
Since the imx-drm node now only needs to contain links to the display interfaces, it can be moved to the SoC dtsi level. At the board level, only connections between the display interface ports and encoders or panels have to be added.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- - Changed DT compatible string to 'fsl,imx-display-subsystem' instead of Linux specific 'fsl,imx-drm', changed DT node name from 'imx-drm' to 'display-subsystem'. --- arch/arm/boot/dts/imx6dl.dtsi | 22 +++--- arch/arm/boot/dts/imx6q-sabresd.dts | 4 -- arch/arm/boot/dts/imx6q.dtsi | 124 ++++++++++++++++++++++++++++++-- arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 6 -- arch/arm/boot/dts/imx6qdl.dtsi | 128 ++++++++++++++++++++++++++++++++- 5 files changed, 253 insertions(+), 31 deletions(-)
diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi index 6dc3970..25bbdd6 100644 --- a/arch/arm/boot/dts/imx6dl.dtsi +++ b/arch/arm/boot/dts/imx6dl.dtsi @@ -70,6 +70,15 @@ }; }; }; + + display-subsystem { + compatible = "fsl,imx-display-subsystem"; + ports = <&ipu1_di0>, <&ipu1_di1>; + }; +}; + +&hdmi { + compatible = "fsl,imx6dl-hdmi"; };
&ldb { @@ -79,17 +88,4 @@ clock-names = "di0_pll", "di1_pll", "di0_sel", "di1_sel", "di0", "di1"; - - lvds-channel@0 { - crtcs = <&ipu1 0>, <&ipu1 1>; - }; - - lvds-channel@1 { - crtcs = <&ipu1 0>, <&ipu1 1>; - }; -}; - -&hdmi { - compatible = "fsl,imx6dl-hdmi"; - crtcs = <&ipu1 0>, <&ipu1 1>; }; diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts b/arch/arm/boot/dts/imx6q-sabresd.dts index 66f220a..9cbdfe7 100644 --- a/arch/arm/boot/dts/imx6q-sabresd.dts +++ b/arch/arm/boot/dts/imx6q-sabresd.dts @@ -20,10 +20,6 @@ compatible = "fsl,imx6q-sabresd", "fsl,imx6q"; };
-&imx_drm { - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; -}; - &sata { status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 187fe33..2a8d9de 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -132,13 +132,84 @@ };
ipu2: ipu@02800000 { - #crtc-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; compatible = "fsl,imx6q-ipu"; reg = <0x02800000 0x400000>; interrupts = <0 8 0x4 0 7 0x4>; clocks = <&clks 133>, <&clks 134>, <&clks 137>; clock-names = "bus", "di0", "di1"; resets = <&src 4>; + + ipu2_di0: port@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + ipu2_di0_disp0: endpoint@0 { + }; + + ipu2_di0_hdmi: endpoint@1 { + remote-endpoint = <&hdmi_mux_2>; + }; + + ipu2_di0_mipi: endpoint@2 { + }; + + ipu2_di0_lvds0: endpoint@3 { + remote-endpoint = <&lvds0_mux_2>; + }; + + ipu2_di0_lvds1: endpoint@4 { + remote-endpoint = <&lvds1_mux_2>; + }; + }; + + ipu2_di1: port@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + ipu2_di1_hdmi: endpoint@1 { + remote-endpoint = <&hdmi_mux_3>; + }; + + ipu2_di1_mipi: endpoint@2 { + }; + + ipu2_di1_lvds0: endpoint@3 { + remote-endpoint = <&lvds0_mux_3>; + }; + + ipu2_di1_lvds1: endpoint@4 { + remote-endpoint = <&lvds1_mux_3>; + }; + }; + }; + }; + + display-subsystem { + compatible = "fsl,imx-display-subsystem"; + ports = <&ipu1_di0>, <&ipu1_di1>, <&ipu2_di0>, <&ipu2_di1>; + }; +}; + +&hdmi { + compatible = "fsl,imx6q-hdmi"; + + port@2 { + reg = <2>; + + hdmi_mux_2: endpoint { + remote-endpoint = <&ipu2_di0_hdmi>; + }; + }; + + port@3 { + reg = <3>; + + hdmi_mux_3: endpoint { + remote-endpoint = <&ipu2_di1_hdmi>; }; }; }; @@ -152,15 +223,56 @@ "di0", "di1";
lvds-channel@0 { - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; + port@2 { + reg = <2>; + + lvds0_mux_2: endpoint { + remote-endpoint = <&ipu2_di0_lvds0>; + }; + }; + + port@3 { + reg = <3>; + + lvds0_mux_3: endpoint { + remote-endpoint = <&ipu2_di1_lvds0>; + }; + }; };
lvds-channel@1 { - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; + port@2 { + reg = <2>; + + lvds1_mux_2: endpoint { + remote-endpoint = <&ipu2_di0_lvds1>; + }; + }; + + port@3 { + reg = <3>; + + lvds1_mux_3: endpoint { + remote-endpoint = <&ipu2_di1_lvds1>; + }; + }; }; };
-&hdmi { - compatible = "fsl,imx6q-hdmi"; - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; +&mipi_dsi { + port@2 { + reg = <2>; + + mipi_mux_2: endpoint { + remote-endpoint = <&ipu2_di0_mipi>; + }; + }; + + port@3 { + reg = <3>; + + mipi_mux_3: endpoint { + remote-endpoint = <&ipu2_di1_mipi>; + }; + }; }; diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi index dfca3e0..e75e11b 100644 --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -62,12 +62,6 @@ }; };
- imx_drm: imx-drm { - compatible = "fsl,imx-drm"; - crtcs = <&ipu1 0>, <&ipu1 1>; - connectors = <&ldb>; - }; - sound { compatible = "fsl,imx6q-sabresd-wm8962", "fsl,imx-audio-wm8962"; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 930ebe0..64a8cbe 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -1358,23 +1358,77 @@ status = "disabled";
lvds-channel@0 { + #address-cells = <1>; + #size-cells = <0>; reg = <0>; status = "disabled"; + + port@0 { + reg = <0>; + + lvds0_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_lvds0>; + }; + }; + + port@1 { + reg = <1>; + + lvds0_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_lvds0>; + }; + }; };
lvds-channel@1 { + #address-cells = <1>; + #size-cells = <0>; reg = <1>; status = "disabled"; + + port@0 { + reg = <0>; + + lvds1_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_lvds1>; + }; + }; + + port@1 { + reg = <1>; + + lvds1_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_lvds1>; + }; + }; }; };
hdmi: hdmi@0120000 { + #address-cells = <1>; + #size-cells = <0>; reg = <0x00120000 0x9000>; interrupts = <0 115 0x04>; gpr = <&gpr>; clocks = <&clks 123>, <&clks 124>; clock-names = "iahb", "isfr"; status = "disabled"; + + port@0 { + reg = <0>; + + hdmi_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_hdmi>; + }; + }; + + port@1 { + reg = <1>; + + hdmi_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_hdmi>; + }; + }; };
dcic1: dcic@020e4000 { @@ -1588,8 +1642,27 @@ reg = <0x021dc000 0x4000>; };
- mipi@021e0000 { /* MIPI-DSI */ + mipi_dsi: mipi@021e0000 { + #address-cells = <1>; + #size-cells = <0>; reg = <0x021e0000 0x4000>; + status = "disabled"; + + port@0 { + reg = <0>; + + mipi_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_mipi>; + }; + }; + + port@1 { + reg = <1>; + + mipi_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_mipi>; + }; + }; };
vdoa@021e4000 { @@ -1643,13 +1716,64 @@ };
ipu1: ipu@02400000 { - #crtc-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; compatible = "fsl,imx6q-ipu"; reg = <0x02400000 0x400000>; interrupts = <0 6 0x4 0 5 0x4>; clocks = <&clks 130>, <&clks 131>, <&clks 132>; clock-names = "bus", "di0", "di1"; resets = <&src 2>; + + ipu1_di0: port@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + ipu1_di0_disp0: endpoint@0 { + }; + + ipu1_di0_hdmi: endpoint@1 { + remote-endpoint = <&hdmi_mux_0>; + }; + + ipu1_di0_mipi: endpoint@2 { + remote-endpoint = <&mipi_mux_0>; + }; + + ipu1_di0_lvds0: endpoint@3 { + remote-endpoint = <&lvds0_mux_0>; + }; + + ipu1_di0_lvds1: endpoint@4 { + remote-endpoint = <&lvds1_mux_0>; + }; + }; + + ipu1_di1: port@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + ipu1_di0_disp1: endpoint@0 { + }; + + ipu1_di1_hdmi: endpoint@1 { + remote-endpoint = <&hdmi_mux_1>; + }; + + ipu1_di1_mipi: endpoint@2 { + remote-endpoint = <&mipi_mux_1>; + }; + + ipu1_di1_lvds0: endpoint@3 { + remote-endpoint = <&lvds0_mux_1>; + }; + + ipu1_di1_lvds1: endpoint@4 { + remote-endpoint = <&lvds1_mux_1>; + }; + }; }; }; };
The device tree bindings are updated regardless of the common display framework and in the meantime the HDMI driver was included.
Signed-off-by: Philipp Zabel p.zabel@pengutronix.de --- drivers/staging/imx-drm/TODO | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/drivers/staging/imx-drm/TODO b/drivers/staging/imx-drm/TODO index 6a9da94..29636fb 100644 --- a/drivers/staging/imx-drm/TODO +++ b/drivers/staging/imx-drm/TODO @@ -1,15 +1,10 @@ TODO: - get DRM Maintainer review for this code -- Wait for common display framework to hit mainline and update the IPU - driver to use it. This will most probably make changes to the devicetree - bindings necessary. -- Factor out more code to common helper functions - decide where to put the base driver. It is not specific to a subsystem and would be used by DRM/KMS and media/V4L2
Missing features (not necessarily for moving out of staging):
-- Add i.MX6 HDMI support - Add support for IC (Image converter) - Add support for CSI (CMOS Sensor interface) - Add support for VDIC (Video Deinterlacer)
On Wed, Mar 05, 2014 at 10:20:51AM +0100, Philipp Zabel wrote:
Hi,
this latest version of the imx-drm DT binding patches applies on top of staging-next and also depends on the OF graph binding patchset that moves the v4l2_of helpers to drivers/of. Currently, the two patchsets are also available at: git://git.pengutronix.de/git/pza/linux.git topic/of-graph git://git.pengutronix.de/git/pza/linux.git topic/imx-drm-dt
Okay, having looked at the second tree, pulling that will result in pulling in all of the staging tree here, which I'd rather not do. Unless there's any objection, I'd like to take these as patches on top of the imx-drm stuff which I sent to Greg plus the of-graph stuff which they depend upon. In other words, exactly how I've been testing it today.
Any objections?
On Fri, Mar 07, 2014 at 05:56:12PM +0000, Russell King - ARM Linux wrote:
On Wed, Mar 05, 2014 at 10:20:51AM +0100, Philipp Zabel wrote:
Hi,
this latest version of the imx-drm DT binding patches applies on top of staging-next and also depends on the OF graph binding patchset that moves the v4l2_of helpers to drivers/of. Currently, the two patchsets are also available at: git://git.pengutronix.de/git/pza/linux.git topic/of-graph git://git.pengutronix.de/git/pza/linux.git topic/imx-drm-dt
Okay, having looked at the second tree, pulling that will result in pulling in all of the staging tree here, which I'd rather not do. Unless there's any objection, I'd like to take these as patches on top of the imx-drm stuff which I sent to Greg plus the of-graph stuff which they depend upon. In other words, exactly how I've been testing it today.
Any objections?
None from me! :)
[Added Shawn to Cc:]
On Fri, Mar 7, 2014 at 7:28 PM, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Fri, Mar 07, 2014 at 05:56:12PM +0000, Russell King - ARM Linux wrote:
On Wed, Mar 05, 2014 at 10:20:51AM +0100, Philipp Zabel wrote:
Hi,
this latest version of the imx-drm DT binding patches applies on top of staging-next and also depends on the OF graph binding patchset that moves the v4l2_of helpers to drivers/of. Currently, the two patchsets are also available at: git://git.pengutronix.de/git/pza/linux.git topic/of-graph git://git.pengutronix.de/git/pza/linux.git topic/imx-drm-dt
Okay, having looked at the second tree, pulling that will result in pulling in all of the staging tree here, which I'd rather not do. Unless there's any objection, I'd like to take these as patches on top of the imx-drm stuff which I sent to Greg plus the of-graph stuff which they depend upon. In other words, exactly how I've been testing it today.
Any objections?
None from me! :)
Nor from me. But I'd like to point out that there already is one merge issue with Shawn's for-next branch in arch/arm/boot/dts/imx53-qsb.dts between d5eb195 "ARM: dts: i.MX53: move common QSB nodes to new file" and these two patches: 17b5001 "imx-drm: convert to componentised device support". "ARM: dts: imx53: Add IPU DI ports and endpoints, move imx-drm node to dtsi" The first one already is in staging-next.
regards Philipp
On Fri, Mar 07, 2014 at 07:57:51PM +0100, Philipp Zabel wrote:
[Added Shawn to Cc:]
On Fri, Mar 7, 2014 at 7:28 PM, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Fri, Mar 07, 2014 at 05:56:12PM +0000, Russell King - ARM Linux wrote:
On Wed, Mar 05, 2014 at 10:20:51AM +0100, Philipp Zabel wrote:
Hi,
this latest version of the imx-drm DT binding patches applies on top of staging-next and also depends on the OF graph binding patchset that moves the v4l2_of helpers to drivers/of. Currently, the two patchsets are also available at: git://git.pengutronix.de/git/pza/linux.git topic/of-graph git://git.pengutronix.de/git/pza/linux.git topic/imx-drm-dt
Okay, having looked at the second tree, pulling that will result in pulling in all of the staging tree here, which I'd rather not do. Unless there's any objection, I'd like to take these as patches on top of the imx-drm stuff which I sent to Greg plus the of-graph stuff which they depend upon. In other words, exactly how I've been testing it today.
Any objections?
None from me! :)
Nor from me. But I'd like to point out that there already is one merge issue with Shawn's for-next branch in arch/arm/boot/dts/imx53-qsb.dts between d5eb195 "ARM: dts: i.MX53: move common QSB nodes to new file" and these two patches: 17b5001 "imx-drm: convert to componentised device support". "ARM: dts: imx53: Add IPU DI ports and endpoints, move imx-drm node to dtsi" The first one already is in staging-next.
Yes, I'm aware of that (since I've been encountering it when creating the build tree for my autobuilder.)
Thanks.
On Wed, Mar 05, 2014 at 10:20:51AM +0100, Philipp Zabel wrote:
Hi,
this latest version of the imx-drm DT binding patches applies on top of staging-next and also depends on the OF graph binding patchset that moves the v4l2_of helpers to drivers/of. Currently, the two patchsets are also available at: git://git.pengutronix.de/git/pza/linux.git topic/of-graph git://git.pengutronix.de/git/pza/linux.git topic/imx-drm-dt
Hi Philipp,
I just came across a couple problems when testing the series on my imx6dl-sabresd board in dual display case - HDMI + LVDS. I tested it using Russell's branch below, which I believe has all the pieces put together.
git://ftp.arm.linux.org.uk/~rmk/linux-arm.git imx-drm-staging
- When I enable HDMI and LVDS support in both kernel build and device tree, HDMI seems working fine but LVDS color is corrupted quite badly.
- When I enable HDMI and LVDS support in kernel build but only LVDS in device tree (keep HDMI disabled in device tree by not changing 'status' of HDMI node to 'okay'), LVDS does not even work. In this case, it seems that the binding of display-subsystem does not succeed.
Please confirm if they are real problems or I'm missing something here.
Shawn
Hi Shawn,
Am Dienstag, den 11.03.2014, 11:46 +0800 schrieb Shawn Guo:
On Wed, Mar 05, 2014 at 10:20:51AM +0100, Philipp Zabel wrote:
Hi,
this latest version of the imx-drm DT binding patches applies on top of staging-next and also depends on the OF graph binding patchset that moves the v4l2_of helpers to drivers/of. Currently, the two patchsets are also available at: git://git.pengutronix.de/git/pza/linux.git topic/of-graph git://git.pengutronix.de/git/pza/linux.git topic/imx-drm-dt
Hi Philipp,
I just came across a couple problems when testing the series on my imx6dl-sabresd board in dual display case - HDMI + LVDS. I tested it using Russell's branch below, which I believe has all the pieces put together.
git://ftp.arm.linux.org.uk/~rmk/linux-arm.git imx-drm-staging
When I enable HDMI and LVDS support in both kernel build and device tree, HDMI seems working fine but LVDS color is corrupted quite badly.
When I enable HDMI and LVDS support in kernel build but only LVDS in device tree (keep HDMI disabled in device tree by not changing 'status' of HDMI node to 'okay'), LVDS does not even work. In this case, it seems that the binding of display-subsystem does not succeed.
Can you check if you get the bound messages from drivers/base/component.c:
imx-drm display-subsystem.11: bound imx-ipuv3-crtc.0 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.1 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound ldb.10 (ops imx_ldb_ops)
I have tried this branch with a Phytec phyFLEX i.MX6S on PBAB01 baseboard with EDT 800x480 LVDS panel, and it seems to work. The check in drivers/staging/imx-drm/imx-drm-core.c:675 should make sure that unavailable (status="disabled") devices are just skipped.
Please confirm if they are real problems or I'm missing something here.
If the devices are bound, can you check in debugfs whether the panel (ldb_di) clock is set correctly? I wonder if Russell's DI code makes a decision that the panel clock can't be supported from the IPU internal clock. Then you'd need something like this to allow setting the video PLL:
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index f6c5af5..f9b90e7 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -258,14 +258,14 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); - clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu2_di1_pre_sel] = imx_clk_mux("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu1_di0_sel] = imx_clk_mux("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels)); - clk[ipu1_di1_sel] = imx_clk_mux("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels)); - clk[ipu2_di0_sel] = imx_clk_mux("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels)); - clk[ipu2_di1_sel] = imx_clk_mux("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels)); + clk[ipu1_di0_pre_sel] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu1_di1_pre_sel] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di0_pre_sel] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di1_pre_sel] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu1_di0_sel] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT); + clk[ipu1_di1_sel] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di0_sel] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di1_sel] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT); clk[hsi_tx_sel] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels)); clk[pcie_axi_sel] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); clk[ssi1_sel] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup);
regards Philipp
On Tue, Mar 11, 2014 at 12:42:08PM +0100, Philipp Zabel wrote:
Hi Shawn,
Am Dienstag, den 11.03.2014, 11:46 +0800 schrieb Shawn Guo:
On Wed, Mar 05, 2014 at 10:20:51AM +0100, Philipp Zabel wrote:
Hi,
this latest version of the imx-drm DT binding patches applies on top of staging-next and also depends on the OF graph binding patchset that moves the v4l2_of helpers to drivers/of. Currently, the two patchsets are also available at: git://git.pengutronix.de/git/pza/linux.git topic/of-graph git://git.pengutronix.de/git/pza/linux.git topic/imx-drm-dt
Hi Philipp,
I just came across a couple problems when testing the series on my imx6dl-sabresd board in dual display case - HDMI + LVDS. I tested it using Russell's branch below, which I believe has all the pieces put together.
git://ftp.arm.linux.org.uk/~rmk/linux-arm.git imx-drm-staging
When I enable HDMI and LVDS support in both kernel build and device tree, HDMI seems working fine but LVDS color is corrupted quite badly.
When I enable HDMI and LVDS support in kernel build but only LVDS in device tree (keep HDMI disabled in device tree by not changing 'status' of HDMI node to 'okay'), LVDS does not even work. In this case, it seems that the binding of display-subsystem does not succeed.
Can you check if you get the bound messages from drivers/base/component.c:
imx-drm display-subsystem.11: bound imx-ipuv3-crtc.0 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.1 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound ldb.10 (ops imx_ldb_ops)
I have tried this branch with a Phytec phyFLEX i.MX6S on PBAB01 baseboard with EDT 800x480 LVDS panel, and it seems to work. The check in drivers/staging/imx-drm/imx-drm-core.c:675 should make sure that unavailable (status="disabled") devices are just skipped.
Sorry, Philipp. The setup in my report is incorrect. The correct setup to see this issue consists of:
1) build a kernel without HDMI support, i.e. !CONFIG_DRM_IMX_HDMI
2) enable HDMI device in DT, i.e. adding the lines below in board dts.
&hdmi { status = "okay"; };
Sorry for the confusion.
Shawn
Am Dienstag, den 11.03.2014, 21:27 +0800 schrieb Shawn Guo:
On Tue, Mar 11, 2014 at 12:42:08PM +0100, Philipp Zabel wrote:
Hi Shawn,
Am Dienstag, den 11.03.2014, 11:46 +0800 schrieb Shawn Guo:
On Wed, Mar 05, 2014 at 10:20:51AM +0100, Philipp Zabel wrote:
Hi,
this latest version of the imx-drm DT binding patches applies on top of staging-next and also depends on the OF graph binding patchset that moves the v4l2_of helpers to drivers/of. Currently, the two patchsets are also available at: git://git.pengutronix.de/git/pza/linux.git topic/of-graph git://git.pengutronix.de/git/pza/linux.git topic/imx-drm-dt
Hi Philipp,
I just came across a couple problems when testing the series on my imx6dl-sabresd board in dual display case - HDMI + LVDS. I tested it using Russell's branch below, which I believe has all the pieces put together.
git://ftp.arm.linux.org.uk/~rmk/linux-arm.git imx-drm-staging
When I enable HDMI and LVDS support in both kernel build and device tree, HDMI seems working fine but LVDS color is corrupted quite badly.
When I enable HDMI and LVDS support in kernel build but only LVDS in device tree (keep HDMI disabled in device tree by not changing 'status' of HDMI node to 'okay'), LVDS does not even work. In this case, it seems that the binding of display-subsystem does not succeed.
Can you check if you get the bound messages from drivers/base/component.c:
imx-drm display-subsystem.11: bound imx-ipuv3-crtc.0 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound imx-ipuv3-crtc.1 (ops ipu_crtc_ops) imx-drm display-subsystem.11: bound ldb.10 (ops imx_ldb_ops)
I have tried this branch with a Phytec phyFLEX i.MX6S on PBAB01 baseboard with EDT 800x480 LVDS panel, and it seems to work. The check in drivers/staging/imx-drm/imx-drm-core.c:675 should make sure that unavailable (status="disabled") devices are just skipped.
Sorry, Philipp. The setup in my report is incorrect. The correct setup to see this issue consists of:
build a kernel without HDMI support, i.e. !CONFIG_DRM_IMX_HDMI
enable HDMI device in DT, i.e. adding the lines below in board dts.
&hdmi { status = "okay"; };
Sorry for the confusion.
This isn't a supported use-case, the componentized device stuff is there exactly to ensure that the DRM device is only brought up after all active components have an driver attached to them.
Regards, Lucas
On Tue, Mar 11, 2014 at 02:34:38PM +0100, Lucas Stach wrote:
Sorry, Philipp. The setup in my report is incorrect. The correct setup to see this issue consists of:
build a kernel without HDMI support, i.e. !CONFIG_DRM_IMX_HDMI
enable HDMI device in DT, i.e. adding the lines below in board dts.
&hdmi { status = "okay"; };
Sorry for the confusion.
This isn't a supported use-case, the componentized device stuff is there exactly to ensure that the DRM device is only brought up after all active components have an driver attached to them.
Ah, yes. I was in the impression that LVDS should still work in this setup, but that was the case before Philipp's series. In Russell's original imx-drm setup, LVDS still works even if I enable the HDMI device in DT, as long as I do not reference it from 'connectors'.
imx_drm: imx-drm { compatible = "fsl,imx-drm"; crtcs = <&ipu1 0>, <&ipu1 1>; connectors = <&ldb>; };
Thanks for the clarification.
Shawn
On Tue, Mar 11, 2014 at 11:46:11AM +0800, Shawn Guo wrote:
I just came across a couple problems when testing the series on my imx6dl-sabresd board in dual display case - HDMI + LVDS. I tested it using Russell's branch below, which I believe has all the pieces put together.
git://ftp.arm.linux.org.uk/~rmk/linux-arm.git imx-drm-staging
- When I enable HDMI and LVDS support in both kernel build and device tree, HDMI seems working fine but LVDS color is corrupted quite badly.
Philipp,
Did you get any chance to reproduce this dual display issue? Now it shows on mainline kernel.
And I see another HDMI regression with my testing on mainline kernel. I can have my HDMI work at 1920x1080 with v3.14 kernel, but it can only probes 1024x768 with the mainline today. The Xorg.0.log are attached below. The hardware and user space are same, so I guess this is another issue introduced by the recently kernel driver changes?
Shawn
mainline kernel ===============
[ 20.606] (II) LoadModule: "modesetting" [ 20.607] (II) Loading /usr/lib/xorg/modules/drivers/modesetting_drv.so [ 20.609] (II) Module modesetting: vendor="X.Org Foundation" [ 20.609] compiled for 1.12.1.902, module version = 0.3.0 [ 20.610] Module class: X.Org Video Driver [ 20.610] ABI class: X.Org Video Driver, version 12.0 [ 20.610] (II) modesetting: Driver for Modesetting Kernel Drivers: kms [ 20.610] (++) using VT number 7
[ 20.624] (WW) Falling back to old probe method for modesetting [ 20.624] (II) modesetting(0): using default device [ 20.627] (II) modesetting(0): Creating default Display subsection in Screen section "Default Screen Section" for depth/fbbpp 24/32 [ 20.627] (==) modesetting(0): Depth 24, (==) framebuffer bpp 32 [ 20.628] (==) modesetting(0): RGB weight 888 [ 20.628] (==) modesetting(0): Default visual is TrueColor [ 20.628] (II) modesetting(0): ShadowFB: preferred NO, enabled NO [ 20.628] (II) modesetting(0): Output HDMI-0 has no monitor section [ 20.629] (II) modesetting(0): EDID for output HDMI-0 [ 20.629] (II) modesetting(0): Printing probed modes for output HDMI-0 [ 20.629] (II) modesetting(0): Modeline "1024x768"x60.0 65.00 1024 1048 1184 1344 768 771 777 806 -hsync -vsync (48.4 kHz e) [ 20.629] (II) modesetting(0): Modeline "800x600"x60.3 40.00 800 840 968 1056 600 601 605 628 +hsync +vsync (37.9 kHz e) [ 20.629] (II) modesetting(0): Modeline "800x600"x56.2 36.00 800 824 896 1024 600 601 603 625 +hsync +vsync (35.2 kHz e) [ 20.630] (II) modesetting(0): Modeline "848x480"x60.0 33.75 848 864 976 1088 480 486 494 517 +hsync +vsync (31.0 kHz e) [ 20.630] (II) modesetting(0): Modeline "640x480"x59.9 25.18 640 656 752 800 480 489 492 525 -hsync -vsync (31.5 kHz e) [ 20.630] (II) modesetting(0): Output HDMI-0 connected [ 20.630] (II) modesetting(0): Using exact sizes for initial modes [ 20.630] (II) modesetting(0): Output HDMI-0 using initial mode 1024x768 [ 20.630] (II) modesetting(0): Using default gamma of (1.0, 1.0, 1.0) unless otherwise stated. [ 20.630] (==) modesetting(0): DPI set to (96, 96)
v3.14 kernel ============
[ 20.214] (II) LoadModule: "modesetting" [ 20.215] (II) Loading /usr/lib/xorg/modules/drivers/modesetting_drv.so [ 20.217] (II) Module modesetting: vendor="X.Org Foundation" [ 20.217] compiled for 1.12.1.902, module version = 0.3.0 [ 20.217] Module class: X.Org Video Driver [ 20.217] ABI class: X.Org Video Driver, version 12.0 [ 20.217] (II) modesetting: Driver for Modesetting Kernel Drivers: kms [ 20.217] (++) using VT number 7
[ 20.240] (WW) Falling back to old probe method for modesetting [ 20.241] (II) modesetting(0): using default device [ 20.241] (WW) VGA arbiter: cannot open kernel arbiter, no multi-card support [ 20.244] (II) modesetting(0): Creating default Display subsection in Screen section "Default Screen Section" for depth/fbbpp 24/32 [ 20.244] (==) modesetting(0): Depth 24, (==) framebuffer bpp 32 [ 20.244] (==) modesetting(0): RGB weight 888 [ 20.244] (==) modesetting(0): Default visual is TrueColor [ 20.244] (II) modesetting(0): ShadowFB: preferred NO, enabled NO [ 20.282] (II) modesetting(0): Output HDMI-0 has no monitor section [ 20.329] (II) modesetting(0): EDID for output HDMI-0 [ 20.330] (II) modesetting(0): Manufacturer: RAW Model: 0 Serial#: 1 [ 20.330] (II) modesetting(0): Year: 2012 Week: 6 [ 20.330] (II) modesetting(0): EDID Version: 1.3 [ 20.331] (II) modesetting(0): Digital Display Input [ 20.331] (II) modesetting(0): Indeterminate output size [ 20.331] (II) modesetting(0): Gamma: 2.20 [ 20.331] (II) modesetting(0): No DPMS capabilities specified [ 20.331] (II) modesetting(0): Supported color encodings: RGB 4:4:4 YCrCb 4:4:4 [ 20.332] (II) modesetting(0): First detailed timing is preferred mode [ 20.332] (II) modesetting(0): redX: 0.636 redY: 0.349 greenX: 0.290 greenY: 0.589 [ 20.332] (II) modesetting(0): blueX: 0.143 blueY: 0.080 whiteX: 0.313 whiteY: 0.329 [ 20.332] (II) modesetting(0): Supported established timings: [ 20.333] (II) modesetting(0): 720x400@70Hz [ 20.333] (II) modesetting(0): 640x480@60Hz [ 20.333] (II) modesetting(0): 640x480@72Hz [ 20.333] (II) modesetting(0): 640x480@75Hz [ 20.333] (II) modesetting(0): 800x600@56Hz [ 20.334] (II) modesetting(0): 800x600@60Hz [ 20.334] (II) modesetting(0): 800x600@72Hz [ 20.334] (II) modesetting(0): 800x600@75Hz [ 20.334] (II) modesetting(0): 1024x768@60Hz [ 20.334] (II) modesetting(0): 1024x768@70Hz [ 20.334] (II) modesetting(0): 1024x768@75Hz [ 20.335] (II) modesetting(0): 1280x1024@75Hz [ 20.335] (II) modesetting(0): Manufacturer's mask: 1 [ 20.335] (II) modesetting(0): Supported standard timings: [ 20.335] (II) modesetting(0): #0: hsize: 1920 vsize 1080 refresh: 60 vid: 49361 [ 20.335] (II) modesetting(0): #1: hsize: 1680 vsize 1050 refresh: 60 vid: 179 [ 20.336] (II) modesetting(0): #2: hsize: 1280 vsize 800 refresh: 60 vid: 129 [ 20.336] (II) modesetting(0): #3: hsize: 1280 vsize 1024 refresh: 60 vid: 32897 [ 20.336] (II) modesetting(0): #4: hsize: 1280 vsize 960 refresh: 60 vid: 16513 [ 20.336] (II) modesetting(0): #5: hsize: 1280 vsize 720 refresh: 60 vid: 49281 [ 20.337] (II) modesetting(0): Supported detailed timing: [ 20.337] (II) modesetting(0): clock: 148.5 MHz Image Size: 575 x 323 mm [ 20.337] (II) modesetting(0): h_active: 1920 h_sync: 2008 h_sync_end 2052 h_blank_end 2200 h_border: 0 [ 20.337] (II) modesetting(0): v_active: 1080 v_sync: 1084 v_sync_end 1089 v_blanking: 1125 v_border: 0 [ 20.337] (II) modesetting(0): Supported detailed timing: [ 20.338] (II) modesetting(0): clock: 85.5 MHz Image Size: 575 x 323 mm [ 20.338] (II) modesetting(0): h_active: 1360 h_sync: 1424 h_sync_end 1536 h_blank_end 1792 h_border: 0 [ 20.338] (II) modesetting(0): v_active: 768 v_sync: 771 v_sync_end 777 v_blanking: 795 v_border: 0 [ 20.338] (II) modesetting(0): Ranges: V min: 50 V max: 76 Hz, H min: 30 H max: 80 kHz, PixClock max 165 MHz [ 20.339] (II) modesetting(0): Monitor name: TV [ 20.339] (II) modesetting(0): Supported detailed timing: [ 20.339] (II) modesetting(0): clock: 27.0 MHz Image Size: 509 x 286 mm [ 20.339] (II) modesetting(0): h_active: 720 h_sync: 736 h_sync_end 798 h_blank_end 858 h_border: 0 [ 20.339] (II) modesetting(0): v_active: 480 v_sync: 489 v_sync_end 495 v_blanking: 525 v_border: 0 [ 20.340] (II) modesetting(0): Supported detailed timing: [ 20.340] (II) modesetting(0): clock: 27.0 MHz Image Size: 509 x 286 mm [ 20.340] (II) modesetting(0): h_active: 720 h_sync: 732 h_sync_end 796 h_blank_end 864 h_border: 0 [ 20.340] (II) modesetting(0): v_active: 576 v_sync: 581 v_sync_end 586 v_blanking: 625 v_border: 0 [ 20.340] (II) modesetting(0): Supported detailed timing: [ 20.341] (II) modesetting(0): clock: 74.2 MHz Image Size: 509 x 286 mm [ 20.341] (II) modesetting(0): h_active: 1920 h_sync: 2008 h_sync_end 2052 h_blank_end 2200 h_border: 0 [ 20.341] (II) modesetting(0): v_active: 540 v_sync: 542 v_sync_end 547 v_blanking: 562 v_border: 0 [ 20.341] (II) modesetting(0): Supported detailed timing: [ 20.341] (II) modesetting(0): clock: 74.2 MHz Image Size: 509 x 286 mm [ 20.342] (II) modesetting(0): h_active: 1920 h_sync: 2448 h_sync_end 2492 h_blank_end 2640 h_border: 0 [ 20.342] (II) modesetting(0): v_active: 540 v_sync: 542 v_sync_end 547 v_blanking: 562 v_border: 0 [ 20.342] (II) modesetting(0): Number of EDID sections to follow: 1 [ 20.342] (II) modesetting(0): EDID (in hex): [ 20.342] (II) modesetting(0): 00ffffffffffff004837000001000000 [ 20.343] (II) modesetting(0): 06160103800000780ad7a5a2594a9624 [ 20.343] (II) modesetting(0): 145054afcf01d1c0b300810081808140 [ 20.343] (II) modesetting(0): 81c001010101023a801871382d40582c [ 20.343] (II) modesetting(0): 45003f432100001a662150b051001b30 [ 20.343] (II) modesetting(0): 407036003f432100001e000000fd0032 [ 20.344] (II) modesetting(0): 4c1e5010000a202020202020000000fc [ 20.344] (II) modesetting(0): 0054560a2020202020202020200a010e [ 20.344] (II) modesetting(0): 020329f123097f074f90010203060715 [ 20.344] (II) modesetting(0): 161112130405141f830100006c030c00 [ 20.344] (II) modesetting(0): 1000b82dc0010101018c0ad08a20e02d [ 20.344] (II) modesetting(0): 10103e9600fd1e110000188c0ad09020 [ 20.345] (II) modesetting(0): 4031200c405500fd1e11000018011d80 [ 20.345] (II) modesetting(0): 18711c1620582c2500fd1e1100009e01 [ 20.345] (II) modesetting(0): 1d80d0721c1620102c2580fd1e110000 [ 20.345] (II) modesetting(0): 9e00000000000000000000000000003e [ 20.345] (II) modesetting(0): EDID vendor "RAW", prod id 0 [ 20.346] (II) modesetting(0): Using EDID range info for horizontal sync [ 20.347] (II) modesetting(0): Using EDID range info for vertical refresh [ 20.347] (II) modesetting(0): Printing DDC gathered Modelines: [ 20.347] (II) modesetting(0): Modeline "1920x1080"x0.0 148.50 1920 2008 2052 2200 1080 1084 1089 1125 +hsync -vsync (67.5 kHz eP) [ 20.347] (II) modesetting(0): Modeline "1360x768"x0.0 85.50 1360 1424 1536 1792 768 771 777 795 +hsync +vsync (47.7 kHz e) [ 20.347] (II) modesetting(0): Modeline "720x480"x0.0 27.00 720 736 798 858 480 489 495 525 -hsync -vsync (31.5 kHz e) [ 20.348] (II) modesetting(0): Modeline "720x576"x0.0 27.00 720 732 796 864 576 581 586 625 -hsync -vsync (31.2 kHz e) [ 20.348] (II) modesetting(0): Modeline "1920x1080i"x0.0 74.25 1920 2008 2052 2200 1080 1084 1094 1125 interlace +hsync +vsync (33.8 kHz e) [ 20.348] (II) modesetting(0): Modeline "1920x1080i"x0.0 74.25 1920 2448 2492 2640 1080 1084 1094 1125 interlace +hsync +vsync (28.1 kHz e) [ 20.348] (II) modesetting(0): Modeline "800x600"x0.0 40.00 800 840 968 1056 600 601 605 628 +hsync +vsync (37.9 kHz e) [ 20.348] (II) modesetting(0): Modeline "800x600"x0.0 36.00 800 824 896 1024 600 601 603 625 +hsync +vsync (35.2 kHz e) [ 20.349] (II) modesetting(0): Modeline "640x480"x0.0 31.50 640 656 720 840 480 481 484 500 -hsync -vsync (37.5 kHz e) [ 20.349] (II) modesetting(0): Modeline "640x480"x0.0 31.50 640 664 704 832 480 489 492 520 -hsync -vsync (37.9 kHz e) [ 20.349] (II) modesetting(0): Modeline "640x480"x0.0 25.18 640 656 752 800 480 490 492 525 -hsync -vsync (31.5 kHz e) [ 20.349] (II) modesetting(0): Modeline "720x400"x0.0 28.32 720 738 846 900 400 412 414 449 -hsync +vsync (31.5 kHz e) [ 20.349] (II) modesetting(0): Modeline "1280x1024"x0.0 135.00 1280 1296 1440 1688 1024 1025 1028 1066 +hsync +vsync (80.0 kHz e) [ 20.350] (II) modesetting(0): Modeline "1024x768"x0.0 78.75 1024 1040 1136 1312 768 769 772 800 +hsync +vsync (60.0 kHz e) [ 20.350] (II) modesetting(0): Modeline "1024x768"x0.0 75.00 1024 1048 1184 1328 768 771 777 806 -hsync -vsync (56.5 kHz e) [ 20.350] (II) modesetting(0): Modeline "1024x768"x0.0 65.00 1024 1048 1184 1344 768 771 777 806 -hsync -vsync (48.4 kHz e) [ 20.350] (II) modesetting(0): Modeline "800x600"x0.0 49.50 800 816 896 1056 600 601 604 625 +hsync +vsync (46.9 kHz e) [ 20.351] (II) modesetting(0): Modeline "800x600"x0.0 50.00 800 856 976 1040 600 637 643 666 +hsync +vsync (48.1 kHz e) [ 20.351] (II) modesetting(0): Modeline "1920x1080"x60.0 172.80 1920 2040 2248 2576 1080 1081 1084 1118 -hsync +vsync (67.1 kHz e) [ 20.351] (II) modesetting(0): Modeline "1680x1050"x0.0 119.00 1680 1728 1760 1840 1050 1053 1059 1080 +hsync -vsync (64.7 kHz e) [ 20.351] (II) modesetting(0): Modeline "1280x800"x0.0 71.00 1280 1328 1360 1440 800 803 809 823 +hsync -vsync (49.3 kHz e) [ 20.351] (II) modesetting(0): Modeline "1280x1024"x0.0 108.00 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync (64.0 kHz e) [ 20.352] (II) modesetting(0): Modeline "1280x960"x0.0 108.00 1280 1376 1488 1800 960 961 964 1000 +hsync +vsync (60.0 kHz e) [ 20.352] (II) modesetting(0): Modeline "1280x720"x60.0 74.48 1280 1336 1472 1664 720 721 724 746 -hsync +vsync (44.8 kHz e) [ 20.352] (II) modesetting(0): Modeline "1280x720"x0.0 74.25 1280 1390 1430 1650 720 725 730 750 +hsync +vsync (45.0 kHz e) [ 20.352] (II) modesetting(0): Modeline "1440x480i"x0.0 27.00 1440 1478 1602 1716 480 488 494 525 interlace -hsync -vsync (15.7 kHz e) [ 20.352] (II) modesetting(0): Modeline "1440x240"x0.0 27.00 1440 1478 1602 1716 240 244 247 262 -hsync -vsync (15.7 kHz e) [ 20.353] (II) modesetting(0): Modeline "1440x576i"x0.0 27.00 1440 1464 1590 1728 576 580 586 625 interlace -hsync -vsync (15.6 kHz e) [ 20.353] (II) modesetting(0): Modeline "1440x288"x0.0 27.00 1440 1464 1590 1728 288 290 293 312 -hsync -vsync (15.6 kHz e) [ 20.353] (II) modesetting(0): Modeline "1280x720"x0.0 74.25 1280 1720 1760 1980 720 725 730 750 +hsync +vsync (37.5 kHz e) [ 20.353] (II) modesetting(0): Modeline "1920x1080"x0.0 74.25 1920 2558 2602 2750 1080 1084 1089 1125 +hsync +vsync (27.0 kHz e) [ 20.354] (II) modesetting(0): Printing probed modes for output HDMI-0 [ 20.354] (II) modesetting(0): Modeline "1920x1080"x60.0 148.50 1920 2008 2052 2200 1080 1084 1089 1125 +hsync -vsync (67.5 kHz eP) [ 20.354] (II) modesetting(0): Modeline "1920x1080"x60.0 148.50 1920 2008 2052 2200 1080 1084 1089 1125 +hsync +vsync (67.5 kHz e) [ 20.354] (II) modesetting(0): Modeline "1920x1080"x50.0 148.50 1920 2448 2492 2640 1080 1084 1089 1125 +hsync +vsync (56.2 kHz e) [ 20.354] (II) modesetting(0): Modeline "1920x1080"x59.9 148.35 1920 2008 2052 2200 1080 1084 1089 1125 +hsync +vsync (67.4 kHz e) [ 20.355] (II) modesetting(0): Modeline "1680x1050"x59.9 119.00 1680 1728 1760 1840 1050 1053 1059 1080 +hsync -vsync (64.7 kHz e) [ 20.355] (II) modesetting(0): Modeline "1280x1024"x75.0 135.00 1280 1296 1440 1688 1024 1025 1028 1066 +hsync +vsync (80.0 kHz e) [ 20.355] (II) modesetting(0): Modeline "1280x1024"x60.0 108.00 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync (64.0 kHz e) [ 20.355] (II) modesetting(0): Modeline "1280x960"x60.0 108.00 1280 1376 1488 1800 960 961 964 1000 +hsync +vsync (60.0 kHz e) [ 20.356] (II) modesetting(0): Modeline "1360x768"x60.0 85.50 1360 1424 1536 1792 768 771 777 795 +hsync +vsync (47.7 kHz e) [ 20.356] (II) modesetting(0): Modeline "1280x800"x59.9 71.00 1280 1328 1360 1440 800 803 809 823 +hsync -vsync (49.3 kHz e) [ 20.356] (II) modesetting(0): Modeline "1280x720"x60.0 74.44 1280 1336 1472 1664 720 721 724 746 -hsync +vsync (44.7 kHz) [ 20.356] (II) modesetting(0): Modeline "1280x720"x60.0 74.25 1280 1390 1430 1650 720 725 730 750 +hsync +vsync (45.0 kHz e) [ 20.356] (II) modesetting(0): Modeline "1280x720"x50.0 74.25 1280 1720 1760 1980 720 725 730 750 +hsync +vsync (37.5 kHz e) [ 20.357] (II) modesetting(0): Modeline "1280x720"x59.9 74.18 1280 1390 1430 1650 720 725 730 750 +hsync +vsync (45.0 kHz e) [ 20.357] (II) modesetting(0): Modeline "1024x768"x75.1 78.80 1024 1040 1136 1312 768 769 772 800 +hsync +vsync (60.1 kHz e) [ 20.357] (II) modesetting(0): Modeline "1024x768"x70.1 75.00 1024 1048 1184 1328 768 771 777 806 -hsync -vsync (56.5 kHz e) [ 20.357] (II) modesetting(0): Modeline "1024x768"x60.0 65.00 1024 1048 1184 1344 768 771 777 806 -hsync -vsync (48.4 kHz e) [ 20.357] (II) modesetting(0): Modeline "800x600"x72.2 50.00 800 856 976 1040 600 637 643 666 +hsync +vsync (48.1 kHz e) [ 20.358] (II) modesetting(0): Modeline "800x600"x75.0 49.50 800 816 896 1056 600 601 604 625 +hsync +vsync (46.9 kHz e) [ 20.358] (II) modesetting(0): Modeline "800x600"x60.3 40.00 800 840 968 1056 600 601 605 628 +hsync +vsync (37.9 kHz e) [ 20.358] (II) modesetting(0): Modeline "800x600"x56.2 36.00 800 824 896 1024 600 601 603 625 +hsync +vsync (35.2 kHz e) [ 20.358] (II) modesetting(0): Modeline "720x576"x50.0 27.00 720 732 796 864 576 581 586 625 -hsync -vsync (31.2 kHz e) [ 20.358] (II) modesetting(0): Modeline "848x480"x60.0 33.75 848 864 976 1088 480 486 494 517 +hsync +vsync (31.0 kHz e) [ 20.359] (II) modesetting(0): Modeline "720x480"x60.0 27.03 720 736 798 858 480 489 495 525 -hsync -vsync (31.5 kHz e) [ 20.359] (II) modesetting(0): Modeline "720x480"x59.9 27.00 720 736 798 858 480 489 495 525 -hsync -vsync (31.5 kHz e) [ 20.359] (II) modesetting(0): Modeline "640x480"x75.0 31.50 640 656 720 840 480 481 484 500 -hsync -vsync (37.5 kHz e) [ 20.359] (II) modesetting(0): Modeline "640x480"x72.8 31.50 640 664 704 832 480 489 491 520 -hsync -vsync (37.9 kHz e) [ 20.359] (II) modesetting(0): Modeline "640x480"x60.0 25.20 640 656 752 800 480 490 492 525 -hsync -vsync (31.5 kHz e) [ 20.360] (II) modesetting(0): Modeline "640x480"x59.9 25.18 640 656 752 800 480 490 492 525 -hsync -vsync (31.5 kHz e) [ 20.360] (II) modesetting(0): Modeline "640x480"x59.9 25.18 640 656 752 800 480 489 492 525 -hsync -vsync (31.5 kHz e) [ 20.360] (II) modesetting(0): Modeline "720x400"x70.1 28.32 720 738 846 900 400 412 414 449 -hsync +vsync (31.5 kHz e) [ 20.360] (II) modesetting(0): Output HDMI-0 connected [ 20.360] (II) modesetting(0): Using exact sizes for initial modes [ 20.361] (II) modesetting(0): Output HDMI-0 using initial mode 1920x1080 [ 20.361] (II) modesetting(0): Using default gamma of (1.0, 1.0, 1.0) unless otherwise stated. [ 20.361] (==) modesetting(0): DPI set to (96, 96)
On Mon, Apr 07, 2014 at 12:23:37PM +0800, Shawn Guo wrote:
And I see another HDMI regression with my testing on mainline kernel. I can have my HDMI work at 1920x1080 with v3.14 kernel, but it can only probes 1024x768 with the mainline today.
Works for me here.
[ 20.606] (II) LoadModule: "modesetting" [ 20.607] (II) Loading /usr/lib/xorg/modules/drivers/modesetting_drv.so [ 20.609] (II) Module modesetting: vendor="X.Org Foundation" [ 20.609] compiled for 1.12.1.902, module version = 0.3.0 [ 20.610] Module class: X.Org Video Driver [ 20.610] ABI class: X.Org Video Driver, version 12.0 [ 20.610] (II) modesetting: Driver for Modesetting Kernel Drivers: kms [ 20.610] (++) using VT number 7
[ 20.624] (WW) Falling back to old probe method for modesetting [ 20.624] (II) modesetting(0): using default device [ 20.627] (II) modesetting(0): Creating default Display subsection in Screen section "Default Screen Section" for depth/fbbpp 24/32 [ 20.627] (==) modesetting(0): Depth 24, (==) framebuffer bpp 32 [ 20.628] (==) modesetting(0): RGB weight 888 [ 20.628] (==) modesetting(0): Default visual is TrueColor [ 20.628] (II) modesetting(0): ShadowFB: preferred NO, enabled NO [ 20.628] (II) modesetting(0): Output HDMI-0 has no monitor section [ 20.629] (II) modesetting(0): EDID for output HDMI-0 [ 20.629] (II) modesetting(0): Printing probed modes for output HDMI-0
So no EDID. Did you update the "ddc" property to "ddc-i2c-bus" ?
Hi Shawn,
Am Montag, den 07.04.2014, 12:23 +0800 schrieb Shawn Guo:
On Tue, Mar 11, 2014 at 11:46:11AM +0800, Shawn Guo wrote:
I just came across a couple problems when testing the series on my imx6dl-sabresd board in dual display case - HDMI + LVDS. I tested it using Russell's branch below, which I believe has all the pieces put together.
git://ftp.arm.linux.org.uk/~rmk/linux-arm.git imx-drm-staging
- When I enable HDMI and LVDS support in both kernel build and device tree, HDMI seems working fine but LVDS color is corrupted quite badly.
Philipp,
Did you get any chance to reproduce this dual display issue? Now it shows on mainline kernel.
I have not yet reproduced, but I've sent a patch today ("imx-drm: imx-drm-core: Fix imx_drm_encoder_get_mux_id") that might fix this.
And I see another HDMI regression with my testing on mainline kernel. I can have my HDMI work at 1920x1080 with v3.14 kernel, but it can only probes 1024x768 with the mainline today. The Xorg.0.log are attached below. The hardware and user space are same, so I guess this is another issue introduced by the recently kernel driver changes?
Hmm, not sure. Have you updated to the i2c-ddc-bus phandle property as described in Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt?
regards Philipp
Am Montag, den 07.04.2014, 12:05 +0200 schrieb Philipp Zabel:
Hi Shawn,
Am Montag, den 07.04.2014, 12:23 +0800 schrieb Shawn Guo:
On Tue, Mar 11, 2014 at 11:46:11AM +0800, Shawn Guo wrote:
I just came across a couple problems when testing the series on my imx6dl-sabresd board in dual display case - HDMI + LVDS. I tested it using Russell's branch below, which I believe has all the pieces put together.
git://ftp.arm.linux.org.uk/~rmk/linux-arm.git imx-drm-staging
- When I enable HDMI and LVDS support in both kernel build and device tree, HDMI seems working fine but LVDS color is corrupted quite badly.
Philipp,
Did you get any chance to reproduce this dual display issue? Now it shows on mainline kernel.
I have not yet reproduced, but I've sent a patch today ("imx-drm: imx-drm-core: Fix imx_drm_encoder_get_mux_id") that might fix this.
Tested on imx6q-phytec-pbab01 with LVDS panel and DVI monitor.
And I see another HDMI regression with my testing on mainline kernel. I can have my HDMI work at 1920x1080 with v3.14 kernel, but it can only probes 1024x768 with the mainline today. The Xorg.0.log are attached below. The hardware and user space are same, so I guess this is another issue introduced by the recently kernel driver changes?
Hmm, not sure. Have you updated to the i2c-ddc-bus phandle property as described in Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt?
regards Philipp
On Mon, Apr 07, 2014 at 12:05:35PM +0200, Philipp Zabel wrote:
Did you get any chance to reproduce this dual display issue? Now it shows on mainline kernel.
I have not yet reproduced, but I've sent a patch today ("imx-drm: imx-drm-core: Fix imx_drm_encoder_get_mux_id") that might fix this.
Yes, it fixes my issue.
And I see another HDMI regression with my testing on mainline kernel. I can have my HDMI work at 1920x1080 with v3.14 kernel, but it can only probes 1024x768 with the mainline today. The Xorg.0.log are attached below. The hardware and user space are same, so I guess this is another issue introduced by the recently kernel driver changes?
Hmm, not sure. Have you updated to the i2c-ddc-bus phandle property as described in Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt?
That's indeed the cause of my problem. Thanks, Philipp.
Shawn
dri-devel@lists.freedesktop.org