| Message ID | 20211213121613.3377432-1-jagan@amarulasolutions.com |
|---|---|
| State | New |
| Headers |
Return-Path: <linux-amarula+bncBD7MFH7A7EEBBSPT3SGQMGQEQSZULWI@amarulasolutions.com> X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id 5CCAA3F39B for <linux-amarula@patchwork.amarulasolutions.com>; Mon, 13 Dec 2021 13:17:19 +0100 (CET) Received: by mail-pj1-f69.google.com with SMTP id bf17-20020a17090b0b1100b001a634dbd737sf13328201pjb.9 for <linux-amarula@patchwork.amarulasolutions.com>; Mon, 13 Dec 2021 04:17:19 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1639397835; cv=pass; d=google.com; s=arc-20160816; b=gwOOr0gbsPnJnViQc4g3JIn24cZN84nXKe0jTPCcQRgAW0gpywOogHaESA0uaBNNo2 1bfOGMrnGLviul3IIc0+tUIf4RwXMMd3f1+8/wVi+RgReDd8SAl0TYUz2/zmlb5vdQa3 yJoDSALriYFRSXWPzgvK3j24vf9ogzU3sSqpNkXxMH9KAEjlRgQF1cmmV0dNk42MpFCE nVScHcRHthqNDfzzcUV36h3f8RWUNuo1B5R69+6hv7mWP+LLImzq+ep72j/K2N1vx8LD /3ziVgkFSmFIXeTa0HCZole105H4meOrk/C8oilcdb272werEXvVWe1ZDlu6C4TZ1wb0 Aw7Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=a1Dr+6OpD4LG482I/PHtKZT1tf2wc7rgHWzBzJsv3w4=; b=kq7bjRMO0V3B7fFBe6P5rl2G0f6ex6AykJLjfNSJA3mw04WP69eWqT6V4mOy+ZOfxu stTYG6AFq9xHEibuatOmwTAxR1+PGEC+ZgNt/gSMCeXqHC1mptB81f/f0t6c3VneTGgw JmLHCEuZr+0qdFnCzHhGaHf9ol89E59WguvfprIZT+6lNsnLdX4YEaQ4vh6qdpNOxEQd UjIxTRyH0/lZEvWdkU2Le9zskvbnt/p/Fj8HVrUquE/Cu1n1KFQ2OfMzc62yXuXBuRBX y1uWIN9n79z88yjBVw+Mbktj/JdDoexl5TwpC7J9wTZ4Zj+YTycQOcSfVcS2K53GjXFF 97eg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=ao0yG9mT; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=a1Dr+6OpD4LG482I/PHtKZT1tf2wc7rgHWzBzJsv3w4=; b=J3RZVbrh8O0q1MtIOm2zglyfonz1NkDR9AV9V5sx94Yf7Hofih4y30DotjEL8NH+OD pr7k7C8z/+JrBPpigIg57pPKAq5Tp/Ti+nS+sPxHHVx8JKMHwHgyTOiz95vFEUpXYE6V +XrKjgVXkbO5P5nriWOYKzjXQ3JcmNs+KxzSA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-spam-checked-in-group:list-post:list-help:list-archive :list-unsubscribe; bh=a1Dr+6OpD4LG482I/PHtKZT1tf2wc7rgHWzBzJsv3w4=; b=I1oRw75x2tc6fiJomaWqpb6XnWgi/YcOYlVCDlK6D83mmtRd2HocukGmlmC6+lV8oo QqUofN/Kf+bxe+RNv8EpaXQslOfx/WEwPkrummXy4LlDg3HBlsjtM4vYkcxrqhf1eRJW TcjYlB29HoOIWnyMgQgcjngtn291RSswl0FHi607azIc9Eh2j+5RGcPGrsrXjqj+BADb jmbMEsU9GBbr+BCWC7pi2LRYmt+kNRWcT+eOB6T2ErHDDVI0DZDxFWWHBjZsbAL/iiOo MS5a2VjIhQ5EUQOUf2GgjDkAajTi8BWfZC9EdtwPuifEERnW59yDXt8A/Y++CtNCRhvR 5/Cg== X-Gm-Message-State: AOAM5310tiMpeTqMm9CA4mUSANy/7n7v9ZgZYkrWIlgiWMye85ZT7a0v QDC0redlUY3mnubi9gTYQ/qKar6O X-Google-Smtp-Source: ABdhPJzbNXP9SNP8dpC/gotPLJO6eC3gcAucUzWmcONJ8TmduarO5d+aUXoGw/J+a83CLv4ikhWyjw== X-Received: by 2002:a63:560a:: with SMTP id k10mr45966216pgb.32.1639397833866; Mon, 13 Dec 2021 04:17:13 -0800 (PST) X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a05:6a00:2309:: with SMTP id h9ls5713292pfh.11.gmail; Mon, 13 Dec 2021 04:17:13 -0800 (PST) X-Received: by 2002:a63:8149:: with SMTP id t70mr9006835pgd.465.1639397833026; Mon, 13 Dec 2021 04:17:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1639397833; cv=none; d=google.com; s=arc-20160816; b=F4KHpvXIMdxJyE5qKWN1mIsB8+lVO2I74uL03E4aDQJg9HcRoCTe8FsHsh9fBKQHRA WvTS2Abnr+ObCRYv4kV1lr+IO4hTvyV2KW2aN/gTildmELGr93YSqT6IXf4cNg+fmnZz XJtP6+6uDte/kcFh9a+6sfHUGmm2B+tseYk7PEdO8q4bKUHHKGo4KKeZb8z0iQFuIIcz HmN/4dkSBBVSRwsHfDaWAraGqlbHXB4uwD2kLRSXBdsFlRseBqnZF9ezw9i8gHCO/eor pEceLWuYm/rX2X+iHDbUCzkC7BCY4MdildJqn+32gGx/e1HlCpvGZ5REPJC4rgqzAU53 tEBg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:dkim-signature; bh=33+gK+FBAawqy1Xlgw+tWZEjy9/Dc+BeSr4WfUFv8Pc=; b=0/wcC41iYGiHysDXXerkLC8wLulz5JMbDGnu+Wrx4eUo6OAhCibL2hYHh5gEckJuSz Rcosu9fPOqlLtQOiDDuIHJUmebizdO9SLis6y3F3NFmEanlhlpMBjoHYW9M8gYq440jV 6czAnVbSS8oPPb48o9Zhh/KUqHnCSNhr4ukQsY3ql6XRIxuUCZ3++p3IleR27c5aCen8 AG5/3lV1mXoWv3fkhNxnrAD0u2o8B82jURR+hBux666jOkyhCDYaDgVLczSKqL3UkMRs NX/fHdRLcMkrwPN5pcMSF/VFZ8EgJqM9GXoO6eMGqt/GkQDn2Mv/NZsJXhSl/RA3AE0X oF0w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=ao0yG9mT; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id m19sor4937741pgv.67.2021.12.13.04.17.12 for <linux-amarula@amarulasolutions.com> (Google Transport Security); Mon, 13 Dec 2021 04:17:13 -0800 (PST) Received-SPF: pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41; X-Received: by 2002:a63:7e42:: with SMTP id o2mr53571602pgn.296.1639397831310; Mon, 13 Dec 2021 04:17:11 -0800 (PST) Received: from localhost.localdomain ([2405:201:c00a:a0a9:a39d:db10:5743:a46e]) by smtp.gmail.com with ESMTPSA id b18sm12642149pfl.121.2021.12.13.04.17.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Dec 2021 04:17:10 -0800 (PST) From: Jagan Teki <jagan@amarulasolutions.com> To: Rob Herring <robh+dt@kernel.org>, Frank Rowand <frowand.list@gmail.com>, Maarten Lankhorst <maarten.lankhorst@linux.intel.com>, Maxime Ripard <mripard@kernel.org>, Thomas Zimmermann <tzimmermann@suse.de>, Laurent Pinchart <Laurent.pinchart@ideasonboard.com>, Linus Walleij <linus.walleij@linaro.org>, Andrzej Hajda <andrzej.hajda@intel.com>, Marek Szyprowski <m.szyprowski@samsung.com> Cc: devicetree@vger.kernel.org, linux-amarula@amarulasolutions.com, Jagan Teki <jagan@amarulasolutions.com> Subject: [PATCH v2] drm: of: Lookup if child node has panel or bridge Date: Mon, 13 Dec 2021 17:46:13 +0530 Message-Id: <20211213121613.3377432-1-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Original-Sender: jagan@amarulasolutions.com X-Original-Authentication-Results: mx.google.com; dkim=pass header.i=@amarulasolutions.com header.s=google header.b=ao0yG9mT; spf=pass (google.com: domain of jagan@amarulasolutions.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=jagan@amarulasolutions.com Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: <linux-amarula.amarulasolutions.com> X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: <https://groups.google.com/a/amarulasolutions.com/group/linux-amarula/post>, <mailto:linux-amarula@amarulasolutions.com> List-Help: <https://support.google.com/a/amarulasolutions.com/bin/topic.py?topic=25838>, <mailto:linux-amarula+help@amarulasolutions.com> List-Archive: <https://groups.google.com/a/amarulasolutions.com/group/linux-amarula/> List-Unsubscribe: <mailto:googlegroups-manage+476853432473+unsubscribe@googlegroups.com>, <https://groups.google.com/a/amarulasolutions.com/group/linux-amarula/subscribe> |
| Series |
[v2] drm: of: Lookup if child node has panel or bridge
|
|
Commit Message
Jagan Teki
Dec. 13, 2021, 12:16 p.m. UTC
Some OF graphs don't require 'ports' to represent the
downstream panel or bridge; instead it simply adds a child
node on a given parent node.
drm_of_find_panel_or_bridge can lookup panel or bridge for
a given node based on the OF graph port and endpoint and it
fails to use if the given node has a child panel or bridge.
This patch add support to lookup that given node has child
panel or bridge however that child node cannot be a 'port'
alone or it cannot be a 'port' node too.
Example OF graph representation of DSI host, which doesn't
have 'ports' and has child panel.
dsi {
compatible = "allwinner,sun6i-a31-mipi-dsi";
#address-cells = <1>;
#size-cells = <0>;
port {
dsi_in_tcon0: endpoint {
remote-endpoint = <tcon0_out_dsi>;
};
panel@0 {
reg = <0>;
};
};
Example OF graph representation of DSI host, which doesn't
have 'ports' and has child bridge.
dsi {
compatible = "allwinner,sun6i-a31-mipi-dsi";
#address-cells = <1>;
#size-cells = <0>;
port {
dsi_in_tcon0: endpoint {
remote-endpoint = <tcon0_out_dsi>;
};
bridge@0 {
reg = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
bridge_out: port@1 {
reg = <1>;
bridge_out_panel: endpoint {
remote-endpoint = <&panel_out_bridge>;
};
};
};
};
};
Example OF graph representation of DSI host, which doesn't
have 'ports' or 'port' and has child panel.
dsi0 {
compatible = "ste,mcde-dsi";
#address-cells = <1>;
#size-cells = <0>;
panel@0 {
reg = <0>;
};
};
Example OF graph representation of LTDC host, which doesn't
have 'ports' or child panel/bridge and has 'port'.
ltdc {
compatible = "st,stm32-ltdc";
#address-cells = <1>;
#size-cells = <0>;
port {
};
};
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Changes for v2:
- drop of helper
https://patchwork.kernel.org/project/dri-devel/cover/20211207054747.461029-1-jagan@amarulasolutions.com/
- support 'port' alone OF graph
- updated comments
- added simple code
drivers/gpu/drm/drm_of.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
Comments
Hi Jagan, Thank you for the patch. On Mon, Dec 13, 2021 at 05:46:13PM +0530, Jagan Teki wrote: > Some OF graphs don't require 'ports' to represent the > downstream panel or bridge; instead it simply adds a child > node on a given parent node. > > drm_of_find_panel_or_bridge can lookup panel or bridge for > a given node based on the OF graph port and endpoint and it > fails to use if the given node has a child panel or bridge. > > This patch add support to lookup that given node has child > panel or bridge however that child node cannot be a 'port' > alone or it cannot be a 'port' node too. > > Example OF graph representation of DSI host, which doesn't > have 'ports' and has child panel. > > dsi { > compatible = "allwinner,sun6i-a31-mipi-dsi"; > #address-cells = <1>; > #size-cells = <0>; > > port { > dsi_in_tcon0: endpoint { > remote-endpoint = <tcon0_out_dsi>; > }; > > panel@0 { > reg = <0>; > }; > }; > > Example OF graph representation of DSI host, which doesn't > have 'ports' and has child bridge. > > dsi { > compatible = "allwinner,sun6i-a31-mipi-dsi"; > #address-cells = <1>; > #size-cells = <0>; > > port { > dsi_in_tcon0: endpoint { > remote-endpoint = <tcon0_out_dsi>; > }; > > bridge@0 { > reg = <0>; > > ports { > #address-cells = <1>; > #size-cells = <0>; > > bridge_out: port@1 { > reg = <1>; > > bridge_out_panel: endpoint { > remote-endpoint = <&panel_out_bridge>; > }; > }; > }; > }; > }; > > Example OF graph representation of DSI host, which doesn't > have 'ports' or 'port' and has child panel. > > dsi0 { > compatible = "ste,mcde-dsi"; > #address-cells = <1>; > #size-cells = <0>; > > panel@0 { > reg = <0>; > }; > }; > > Example OF graph representation of LTDC host, which doesn't > have 'ports' or child panel/bridge and has 'port'. > > ltdc { > compatible = "st,stm32-ltdc"; > #address-cells = <1>; > #size-cells = <0>; > > port { > }; > }; > > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> > --- > Changes for v2: > - drop of helper > https://patchwork.kernel.org/project/dri-devel/cover/20211207054747.461029-1-jagan@amarulasolutions.com/ > - support 'port' alone OF graph > - updated comments > - added simple code > > drivers/gpu/drm/drm_of.c | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c > index 59d368ea006b..7d018ff8bc83 100644 > --- a/drivers/gpu/drm/drm_of.c > +++ b/drivers/gpu/drm/drm_of.c > @@ -249,6 +249,27 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, > if (panel) > *panel = NULL; > > + /** > + * Some OF graphs don't require 'ports' to represent the downstream > + * panel or bridge; instead it simply adds a child node on a given > + * parent node. > + * > + * Lookup that child node for a given parent however that child > + * cannot be a 'port' alone or it cannot be a 'port' node too. > + */ > + if (!of_get_child_by_name(np, "ports")) { > + if (of_get_child_by_name(np, "port") && (of_get_child_count(np) == 1)) This messes up reference counting of device_node. > + goto of_graph_get_remote; > + > + for_each_available_child_of_node(np, remote) { > + if (of_node_name_eq(remote, "port")) > + continue; > + > + goto of_find_panel_or_bridge; > + } > + } This really looks like a hack to me, I'm worried it may cause issues. It would be better, I think, to split the drm_of_find_panel_or_bridge() function in two, with the of_graph_get_remote_node() call moved to a wrapper function, calling an inner function that takes the remote device_node pointer. For the DSI use case, you could either look up the panel DT node in the display driver and call the inner function directly, or implement a DSI-specific wrapper. > + > +of_graph_get_remote: > /* > * of_graph_get_remote_node() produces a noisy error message if port > * node isn't found and the absence of the port is a legit case here, > @@ -259,6 +280,8 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, > return -ENODEV; > > remote = of_graph_get_remote_node(np, port, endpoint); > + > +of_find_panel_or_bridge: > if (!remote) > return -ENODEV; >
On Mon, Dec 13, 2021 at 02:28:39PM +0200, Laurent Pinchart wrote: > Hi Jagan, > > Thank you for the patch. > > On Mon, Dec 13, 2021 at 05:46:13PM +0530, Jagan Teki wrote: > > Some OF graphs don't require 'ports' to represent the > > downstream panel or bridge; instead it simply adds a child > > node on a given parent node. > > > > drm_of_find_panel_or_bridge can lookup panel or bridge for > > a given node based on the OF graph port and endpoint and it > > fails to use if the given node has a child panel or bridge. > > > > This patch add support to lookup that given node has child > > panel or bridge however that child node cannot be a 'port' > > alone or it cannot be a 'port' node too. > > > > Example OF graph representation of DSI host, which doesn't > > have 'ports' and has child panel. > > > > dsi { > > compatible = "allwinner,sun6i-a31-mipi-dsi"; > > #address-cells = <1>; > > #size-cells = <0>; > > > > port { > > dsi_in_tcon0: endpoint { > > remote-endpoint = <tcon0_out_dsi>; > > }; > > > > panel@0 { > > reg = <0>; > > }; > > }; > > > > Example OF graph representation of DSI host, which doesn't > > have 'ports' and has child bridge. > > > > dsi { > > compatible = "allwinner,sun6i-a31-mipi-dsi"; > > #address-cells = <1>; > > #size-cells = <0>; > > > > port { > > dsi_in_tcon0: endpoint { > > remote-endpoint = <tcon0_out_dsi>; > > }; > > > > bridge@0 { > > reg = <0>; > > > > ports { > > #address-cells = <1>; > > #size-cells = <0>; > > > > bridge_out: port@1 { > > reg = <1>; > > > > bridge_out_panel: endpoint { > > remote-endpoint = <&panel_out_bridge>; > > }; > > }; > > }; > > }; > > }; > > > > Example OF graph representation of DSI host, which doesn't > > have 'ports' or 'port' and has child panel. > > > > dsi0 { > > compatible = "ste,mcde-dsi"; > > #address-cells = <1>; > > #size-cells = <0>; > > > > panel@0 { > > reg = <0>; > > }; > > }; > > > > Example OF graph representation of LTDC host, which doesn't > > have 'ports' or child panel/bridge and has 'port'. > > > > ltdc { > > compatible = "st,stm32-ltdc"; > > #address-cells = <1>; > > #size-cells = <0>; > > > > port { > > }; > > }; > > > > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> > > --- > > Changes for v2: > > - drop of helper > > https://patchwork.kernel.org/project/dri-devel/cover/20211207054747.461029-1-jagan@amarulasolutions.com/ > > - support 'port' alone OF graph > > - updated comments > > - added simple code > > > > drivers/gpu/drm/drm_of.c | 23 +++++++++++++++++++++++ > > 1 file changed, 23 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c > > index 59d368ea006b..7d018ff8bc83 100644 > > --- a/drivers/gpu/drm/drm_of.c > > +++ b/drivers/gpu/drm/drm_of.c > > @@ -249,6 +249,27 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, > > if (panel) > > *panel = NULL; > > > > + /** > > + * Some OF graphs don't require 'ports' to represent the downstream > > + * panel or bridge; instead it simply adds a child node on a given > > + * parent node. > > + * > > + * Lookup that child node for a given parent however that child > > + * cannot be a 'port' alone or it cannot be a 'port' node too. > > + */ > > + if (!of_get_child_by_name(np, "ports")) { > > + if (of_get_child_by_name(np, "port") && (of_get_child_count(np) == 1)) > > This messes up reference counting of device_node. > > > + goto of_graph_get_remote; > > + > > + for_each_available_child_of_node(np, remote) { > > + if (of_node_name_eq(remote, "port")) > > + continue; > > + > > + goto of_find_panel_or_bridge; > > + } > > + } > > This really looks like a hack to me, I'm worried it may cause issues. It > would be better, I think, to split the drm_of_find_panel_or_bridge() > function in two, with the of_graph_get_remote_node() call moved to a > wrapper function, calling an inner function that takes the remote > device_node pointer. For the DSI use case, you could either look up the > panel DT node in the display driver and call the inner function > directly, or implement a DSI-specific wrapper. I disagree. The whole point of drm_of_find_panel_or_bridge was that it was a helper for the encoder / upstream bridge to retrieve whatever is there next. It's useful and removes boilerplate. We definitely want to have something just as convenient for DSI. Maxime
Hi Maxime, On Mon, Dec 13, 2021 at 02:09:36PM +0100, Maxime Ripard wrote: > On Mon, Dec 13, 2021 at 02:28:39PM +0200, Laurent Pinchart wrote: > > On Mon, Dec 13, 2021 at 05:46:13PM +0530, Jagan Teki wrote: > > > Some OF graphs don't require 'ports' to represent the > > > downstream panel or bridge; instead it simply adds a child > > > node on a given parent node. > > > > > > drm_of_find_panel_or_bridge can lookup panel or bridge for > > > a given node based on the OF graph port and endpoint and it > > > fails to use if the given node has a child panel or bridge. > > > > > > This patch add support to lookup that given node has child > > > panel or bridge however that child node cannot be a 'port' > > > alone or it cannot be a 'port' node too. > > > > > > Example OF graph representation of DSI host, which doesn't > > > have 'ports' and has child panel. > > > > > > dsi { > > > compatible = "allwinner,sun6i-a31-mipi-dsi"; > > > #address-cells = <1>; > > > #size-cells = <0>; > > > > > > port { > > > dsi_in_tcon0: endpoint { > > > remote-endpoint = <tcon0_out_dsi>; > > > }; > > > > > > panel@0 { > > > reg = <0>; > > > }; > > > }; > > > > > > Example OF graph representation of DSI host, which doesn't > > > have 'ports' and has child bridge. > > > > > > dsi { > > > compatible = "allwinner,sun6i-a31-mipi-dsi"; > > > #address-cells = <1>; > > > #size-cells = <0>; > > > > > > port { > > > dsi_in_tcon0: endpoint { > > > remote-endpoint = <tcon0_out_dsi>; > > > }; > > > > > > bridge@0 { > > > reg = <0>; > > > > > > ports { > > > #address-cells = <1>; > > > #size-cells = <0>; > > > > > > bridge_out: port@1 { > > > reg = <1>; > > > > > > bridge_out_panel: endpoint { > > > remote-endpoint = <&panel_out_bridge>; > > > }; > > > }; > > > }; > > > }; > > > }; > > > > > > Example OF graph representation of DSI host, which doesn't > > > have 'ports' or 'port' and has child panel. > > > > > > dsi0 { > > > compatible = "ste,mcde-dsi"; > > > #address-cells = <1>; > > > #size-cells = <0>; > > > > > > panel@0 { > > > reg = <0>; > > > }; > > > }; > > > > > > Example OF graph representation of LTDC host, which doesn't > > > have 'ports' or child panel/bridge and has 'port'. > > > > > > ltdc { > > > compatible = "st,stm32-ltdc"; > > > #address-cells = <1>; > > > #size-cells = <0>; > > > > > > port { > > > }; > > > }; > > > > > > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> > > > --- > > > Changes for v2: > > > - drop of helper > > > https://patchwork.kernel.org/project/dri-devel/cover/20211207054747.461029-1-jagan@amarulasolutions.com/ > > > - support 'port' alone OF graph > > > - updated comments > > > - added simple code > > > > > > drivers/gpu/drm/drm_of.c | 23 +++++++++++++++++++++++ > > > 1 file changed, 23 insertions(+) > > > > > > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c > > > index 59d368ea006b..7d018ff8bc83 100644 > > > --- a/drivers/gpu/drm/drm_of.c > > > +++ b/drivers/gpu/drm/drm_of.c > > > @@ -249,6 +249,27 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, > > > if (panel) > > > *panel = NULL; > > > > > > + /** > > > + * Some OF graphs don't require 'ports' to represent the downstream > > > + * panel or bridge; instead it simply adds a child node on a given > > > + * parent node. > > > + * > > > + * Lookup that child node for a given parent however that child > > > + * cannot be a 'port' alone or it cannot be a 'port' node too. > > > + */ > > > + if (!of_get_child_by_name(np, "ports")) { > > > + if (of_get_child_by_name(np, "port") && (of_get_child_count(np) == 1)) > > > > This messes up reference counting of device_node. > > > > > + goto of_graph_get_remote; > > > + > > > + for_each_available_child_of_node(np, remote) { > > > + if (of_node_name_eq(remote, "port")) > > > + continue; > > > + > > > + goto of_find_panel_or_bridge; > > > + } > > > + } > > > > This really looks like a hack to me, I'm worried it may cause issues. It > > would be better, I think, to split the drm_of_find_panel_or_bridge() > > function in two, with the of_graph_get_remote_node() call moved to a > > wrapper function, calling an inner function that takes the remote > > device_node pointer. For the DSI use case, you could either look up the > > panel DT node in the display driver and call the inner function > > directly, or implement a DSI-specific wrapper. > > I disagree. The whole point of drm_of_find_panel_or_bridge was that it > was a helper for the encoder / upstream bridge to retrieve whatever is > there next. It's useful and removes boilerplate. > > We definitely want to have something just as convenient for DSI. That could ba a drm_of_find_dsi_panel_or_bridge() :-) My point is that I'd like to avoid making assumptions on node names in the lower layers. I also have a different use case for a drm_of_find_panel_or_bridge() function ta would take a device_node pointer, so moving the of_graph_get_remote_node() lookup out would be useful there. We could have (names to be bikeshedded) - __drm_of_find_panel_or_bridge() without of_graph_get_remote_node() - drm_of_find_panel_or_bridge() calling of_graph_get_remote_node() and __drm_of_find_panel_or_bridge() - drm_of_find_dsi_panel_or_bridge() getting the device_node pointer in a way specific to DSI devices and calling __drm_of_find_panel_or_bridge() Ideally, though, the case where we have no port node should die out slowly, even when DSI devices are children of the DSI controller, there should be ports modelling the data connection.
On Mon, Dec 13, 2021 at 03:35:16PM +0200, Laurent Pinchart wrote: > Hi Maxime, > > On Mon, Dec 13, 2021 at 02:09:36PM +0100, Maxime Ripard wrote: > > On Mon, Dec 13, 2021 at 02:28:39PM +0200, Laurent Pinchart wrote: > > > On Mon, Dec 13, 2021 at 05:46:13PM +0530, Jagan Teki wrote: > > > > Some OF graphs don't require 'ports' to represent the > > > > downstream panel or bridge; instead it simply adds a child > > > > node on a given parent node. > > > > > > > > drm_of_find_panel_or_bridge can lookup panel or bridge for > > > > a given node based on the OF graph port and endpoint and it > > > > fails to use if the given node has a child panel or bridge. > > > > > > > > This patch add support to lookup that given node has child > > > > panel or bridge however that child node cannot be a 'port' > > > > alone or it cannot be a 'port' node too. > > > > > > > > Example OF graph representation of DSI host, which doesn't > > > > have 'ports' and has child panel. > > > > > > > > dsi { > > > > compatible = "allwinner,sun6i-a31-mipi-dsi"; > > > > #address-cells = <1>; > > > > #size-cells = <0>; > > > > > > > > port { > > > > dsi_in_tcon0: endpoint { > > > > remote-endpoint = <tcon0_out_dsi>; > > > > }; > > > > > > > > panel@0 { > > > > reg = <0>; > > > > }; > > > > }; > > > > > > > > Example OF graph representation of DSI host, which doesn't > > > > have 'ports' and has child bridge. > > > > > > > > dsi { > > > > compatible = "allwinner,sun6i-a31-mipi-dsi"; > > > > #address-cells = <1>; > > > > #size-cells = <0>; > > > > > > > > port { > > > > dsi_in_tcon0: endpoint { > > > > remote-endpoint = <tcon0_out_dsi>; > > > > }; > > > > > > > > bridge@0 { > > > > reg = <0>; > > > > > > > > ports { > > > > #address-cells = <1>; > > > > #size-cells = <0>; > > > > > > > > bridge_out: port@1 { > > > > reg = <1>; > > > > > > > > bridge_out_panel: endpoint { > > > > remote-endpoint = <&panel_out_bridge>; > > > > }; > > > > }; > > > > }; > > > > }; > > > > }; > > > > > > > > Example OF graph representation of DSI host, which doesn't > > > > have 'ports' or 'port' and has child panel. > > > > > > > > dsi0 { > > > > compatible = "ste,mcde-dsi"; > > > > #address-cells = <1>; > > > > #size-cells = <0>; > > > > > > > > panel@0 { > > > > reg = <0>; > > > > }; > > > > }; > > > > > > > > Example OF graph representation of LTDC host, which doesn't > > > > have 'ports' or child panel/bridge and has 'port'. > > > > > > > > ltdc { > > > > compatible = "st,stm32-ltdc"; > > > > #address-cells = <1>; > > > > #size-cells = <0>; > > > > > > > > port { > > > > }; > > > > }; > > > > > > > > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> > > > > --- > > > > Changes for v2: > > > > - drop of helper > > > > https://patchwork.kernel.org/project/dri-devel/cover/20211207054747.461029-1-jagan@amarulasolutions.com/ > > > > - support 'port' alone OF graph > > > > - updated comments > > > > - added simple code > > > > > > > > drivers/gpu/drm/drm_of.c | 23 +++++++++++++++++++++++ > > > > 1 file changed, 23 insertions(+) > > > > > > > > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c > > > > index 59d368ea006b..7d018ff8bc83 100644 > > > > --- a/drivers/gpu/drm/drm_of.c > > > > +++ b/drivers/gpu/drm/drm_of.c > > > > @@ -249,6 +249,27 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, > > > > if (panel) > > > > *panel = NULL; > > > > > > > > + /** > > > > + * Some OF graphs don't require 'ports' to represent the downstream > > > > + * panel or bridge; instead it simply adds a child node on a given > > > > + * parent node. > > > > + * > > > > + * Lookup that child node for a given parent however that child > > > > + * cannot be a 'port' alone or it cannot be a 'port' node too. > > > > + */ > > > > + if (!of_get_child_by_name(np, "ports")) { > > > > + if (of_get_child_by_name(np, "port") && (of_get_child_count(np) == 1)) > > > > > > This messes up reference counting of device_node. > > > > > > > + goto of_graph_get_remote; > > > > + > > > > + for_each_available_child_of_node(np, remote) { > > > > + if (of_node_name_eq(remote, "port")) > > > > + continue; > > > > + > > > > + goto of_find_panel_or_bridge; > > > > + } > > > > + } > > > > > > This really looks like a hack to me, I'm worried it may cause issues. It > > > would be better, I think, to split the drm_of_find_panel_or_bridge() > > > function in two, with the of_graph_get_remote_node() call moved to a > > > wrapper function, calling an inner function that takes the remote > > > device_node pointer. For the DSI use case, you could either look up the > > > panel DT node in the display driver and call the inner function > > > directly, or implement a DSI-specific wrapper. > > > > I disagree. The whole point of drm_of_find_panel_or_bridge was that it > > was a helper for the encoder / upstream bridge to retrieve whatever is > > there next. It's useful and removes boilerplate. > > > > We definitely want to have something just as convenient for DSI. > > That could ba a drm_of_find_dsi_panel_or_bridge() :-) My point is that > I'd like to avoid making assumptions on node names in the lower layers. > > I also have a different use case for a drm_of_find_panel_or_bridge() > function ta would take a device_node pointer, so moving the > of_graph_get_remote_node() lookup out would be useful there. We could > have (names to be bikeshedded) > > - __drm_of_find_panel_or_bridge() without of_graph_get_remote_node() > - drm_of_find_panel_or_bridge() calling of_graph_get_remote_node() and > __drm_of_find_panel_or_bridge() > - drm_of_find_dsi_panel_or_bridge() getting the device_node pointer in a > way specific to DSI devices and calling > __drm_of_find_panel_or_bridge() I don't really like the idea of a DSI helper either. Those node names are reserved so I'm not sure we'll ever find a conflict, but can we base our decision on remote-endpoint (for ports/endpoints) or reg (for DSI devices)? > Ideally, though, the case where we have no port node should die out > slowly, even when DSI devices are children of the DSI controller, there > should be ports modelling the data connection. I'm not really in favor of that either, it looks like making the DT more complex than it needs to be for no particular reason, but I guess it's a very subjective matter :) Maxime
Hi Laurent, On Mon, Dec 13, 2021 at 5:59 PM Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote: > > Hi Jagan, > > Thank you for the patch. > > On Mon, Dec 13, 2021 at 05:46:13PM +0530, Jagan Teki wrote: > > Some OF graphs don't require 'ports' to represent the > > downstream panel or bridge; instead it simply adds a child > > node on a given parent node. > > > > drm_of_find_panel_or_bridge can lookup panel or bridge for > > a given node based on the OF graph port and endpoint and it > > fails to use if the given node has a child panel or bridge. > > > > This patch add support to lookup that given node has child > > panel or bridge however that child node cannot be a 'port' > > alone or it cannot be a 'port' node too. > > > > Example OF graph representation of DSI host, which doesn't > > have 'ports' and has child panel. > > > > dsi { > > compatible = "allwinner,sun6i-a31-mipi-dsi"; > > #address-cells = <1>; > > #size-cells = <0>; > > > > port { > > dsi_in_tcon0: endpoint { > > remote-endpoint = <tcon0_out_dsi>; > > }; > > > > panel@0 { > > reg = <0>; > > }; > > }; > > > > Example OF graph representation of DSI host, which doesn't > > have 'ports' and has child bridge. > > > > dsi { > > compatible = "allwinner,sun6i-a31-mipi-dsi"; > > #address-cells = <1>; > > #size-cells = <0>; > > > > port { > > dsi_in_tcon0: endpoint { > > remote-endpoint = <tcon0_out_dsi>; > > }; > > > > bridge@0 { > > reg = <0>; > > > > ports { > > #address-cells = <1>; > > #size-cells = <0>; > > > > bridge_out: port@1 { > > reg = <1>; > > > > bridge_out_panel: endpoint { > > remote-endpoint = <&panel_out_bridge>; > > }; > > }; > > }; > > }; > > }; > > > > Example OF graph representation of DSI host, which doesn't > > have 'ports' or 'port' and has child panel. > > > > dsi0 { > > compatible = "ste,mcde-dsi"; > > #address-cells = <1>; > > #size-cells = <0>; > > > > panel@0 { > > reg = <0>; > > }; > > }; > > > > Example OF graph representation of LTDC host, which doesn't > > have 'ports' or child panel/bridge and has 'port'. > > > > ltdc { > > compatible = "st,stm32-ltdc"; > > #address-cells = <1>; > > #size-cells = <0>; > > > > port { > > }; > > }; > > > > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> > > --- > > Changes for v2: > > - drop of helper > > https://patchwork.kernel.org/project/dri-devel/cover/20211207054747.461029-1-jagan@amarulasolutions.com/ > > - support 'port' alone OF graph > > - updated comments > > - added simple code > > > > drivers/gpu/drm/drm_of.c | 23 +++++++++++++++++++++++ > > 1 file changed, 23 insertions(+) > > > > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c > > index 59d368ea006b..7d018ff8bc83 100644 > > --- a/drivers/gpu/drm/drm_of.c > > +++ b/drivers/gpu/drm/drm_of.c > > @@ -249,6 +249,27 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, > > if (panel) > > *panel = NULL; > > > > + /** > > + * Some OF graphs don't require 'ports' to represent the downstream > > + * panel or bridge; instead it simply adds a child node on a given > > + * parent node. > > + * > > + * Lookup that child node for a given parent however that child > > + * cannot be a 'port' alone or it cannot be a 'port' node too. > > + */ > > + if (!of_get_child_by_name(np, "ports")) { > > + if (of_get_child_by_name(np, "port") && (of_get_child_count(np) == 1)) > > This messes up reference counting of device_node. > > > + goto of_graph_get_remote; > > + > > + for_each_available_child_of_node(np, remote) { > > + if (of_node_name_eq(remote, "port")) > > + continue; > > + > > + goto of_find_panel_or_bridge; > > + } > > + } > > This really looks like a hack to me, I'm worried it may cause issues. It > would be better, I think, to split the drm_of_find_panel_or_bridge() > function in two, with the of_graph_get_remote_node() call moved to a > wrapper function, calling an inner function that takes the remote > device_node pointer. For the DSI use case, you could either look up the > panel DT node in the display driver and call the inner function > directly, or implement a DSI-specific wrapper. I sent the V3 for this, and considered whole video pipeline use cases. Please have a look and comment. Thanks, Jagan.
Hi Maxime, On Mon, Dec 13, 2021 at 02:42:55PM +0100, Maxime Ripard wrote: > On Mon, Dec 13, 2021 at 03:35:16PM +0200, Laurent Pinchart wrote: > > On Mon, Dec 13, 2021 at 02:09:36PM +0100, Maxime Ripard wrote: > > > On Mon, Dec 13, 2021 at 02:28:39PM +0200, Laurent Pinchart wrote: > > > > On Mon, Dec 13, 2021 at 05:46:13PM +0530, Jagan Teki wrote: > > > > > Some OF graphs don't require 'ports' to represent the > > > > > downstream panel or bridge; instead it simply adds a child > > > > > node on a given parent node. > > > > > > > > > > drm_of_find_panel_or_bridge can lookup panel or bridge for > > > > > a given node based on the OF graph port and endpoint and it > > > > > fails to use if the given node has a child panel or bridge. > > > > > > > > > > This patch add support to lookup that given node has child > > > > > panel or bridge however that child node cannot be a 'port' > > > > > alone or it cannot be a 'port' node too. > > > > > > > > > > Example OF graph representation of DSI host, which doesn't > > > > > have 'ports' and has child panel. > > > > > > > > > > dsi { > > > > > compatible = "allwinner,sun6i-a31-mipi-dsi"; > > > > > #address-cells = <1>; > > > > > #size-cells = <0>; > > > > > > > > > > port { > > > > > dsi_in_tcon0: endpoint { > > > > > remote-endpoint = <tcon0_out_dsi>; > > > > > }; > > > > > > > > > > panel@0 { > > > > > reg = <0>; > > > > > }; > > > > > }; > > > > > > > > > > Example OF graph representation of DSI host, which doesn't > > > > > have 'ports' and has child bridge. > > > > > > > > > > dsi { > > > > > compatible = "allwinner,sun6i-a31-mipi-dsi"; > > > > > #address-cells = <1>; > > > > > #size-cells = <0>; > > > > > > > > > > port { > > > > > dsi_in_tcon0: endpoint { > > > > > remote-endpoint = <tcon0_out_dsi>; > > > > > }; > > > > > > > > > > bridge@0 { > > > > > reg = <0>; > > > > > > > > > > ports { > > > > > #address-cells = <1>; > > > > > #size-cells = <0>; > > > > > > > > > > bridge_out: port@1 { > > > > > reg = <1>; > > > > > > > > > > bridge_out_panel: endpoint { > > > > > remote-endpoint = <&panel_out_bridge>; > > > > > }; > > > > > }; > > > > > }; > > > > > }; > > > > > }; > > > > > > > > > > Example OF graph representation of DSI host, which doesn't > > > > > have 'ports' or 'port' and has child panel. > > > > > > > > > > dsi0 { > > > > > compatible = "ste,mcde-dsi"; > > > > > #address-cells = <1>; > > > > > #size-cells = <0>; > > > > > > > > > > panel@0 { > > > > > reg = <0>; > > > > > }; > > > > > }; > > > > > > > > > > Example OF graph representation of LTDC host, which doesn't > > > > > have 'ports' or child panel/bridge and has 'port'. > > > > > > > > > > ltdc { > > > > > compatible = "st,stm32-ltdc"; > > > > > #address-cells = <1>; > > > > > #size-cells = <0>; > > > > > > > > > > port { > > > > > }; > > > > > }; > > > > > > > > > > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> > > > > > --- > > > > > Changes for v2: > > > > > - drop of helper > > > > > https://patchwork.kernel.org/project/dri-devel/cover/20211207054747.461029-1-jagan@amarulasolutions.com/ > > > > > - support 'port' alone OF graph > > > > > - updated comments > > > > > - added simple code > > > > > > > > > > drivers/gpu/drm/drm_of.c | 23 +++++++++++++++++++++++ > > > > > 1 file changed, 23 insertions(+) > > > > > > > > > > diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c > > > > > index 59d368ea006b..7d018ff8bc83 100644 > > > > > --- a/drivers/gpu/drm/drm_of.c > > > > > +++ b/drivers/gpu/drm/drm_of.c > > > > > @@ -249,6 +249,27 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, > > > > > if (panel) > > > > > *panel = NULL; > > > > > > > > > > + /** > > > > > + * Some OF graphs don't require 'ports' to represent the downstream > > > > > + * panel or bridge; instead it simply adds a child node on a given > > > > > + * parent node. > > > > > + * > > > > > + * Lookup that child node for a given parent however that child > > > > > + * cannot be a 'port' alone or it cannot be a 'port' node too. > > > > > + */ > > > > > + if (!of_get_child_by_name(np, "ports")) { > > > > > + if (of_get_child_by_name(np, "port") && (of_get_child_count(np) == 1)) > > > > > > > > This messes up reference counting of device_node. > > > > > > > > > + goto of_graph_get_remote; > > > > > + > > > > > + for_each_available_child_of_node(np, remote) { > > > > > + if (of_node_name_eq(remote, "port")) > > > > > + continue; > > > > > + > > > > > + goto of_find_panel_or_bridge; > > > > > + } > > > > > + } > > > > > > > > This really looks like a hack to me, I'm worried it may cause issues. It > > > > would be better, I think, to split the drm_of_find_panel_or_bridge() > > > > function in two, with the of_graph_get_remote_node() call moved to a > > > > wrapper function, calling an inner function that takes the remote > > > > device_node pointer. For the DSI use case, you could either look up the > > > > panel DT node in the display driver and call the inner function > > > > directly, or implement a DSI-specific wrapper. > > > > > > I disagree. The whole point of drm_of_find_panel_or_bridge was that it > > > was a helper for the encoder / upstream bridge to retrieve whatever is > > > there next. It's useful and removes boilerplate. > > > > > > We definitely want to have something just as convenient for DSI. > > > > That could ba a drm_of_find_dsi_panel_or_bridge() :-) My point is that > > I'd like to avoid making assumptions on node names in the lower layers. > > > > I also have a different use case for a drm_of_find_panel_or_bridge() > > function ta would take a device_node pointer, so moving the > > of_graph_get_remote_node() lookup out would be useful there. We could > > have (names to be bikeshedded) > > > > - __drm_of_find_panel_or_bridge() without of_graph_get_remote_node() > > - drm_of_find_panel_or_bridge() calling of_graph_get_remote_node() and > > __drm_of_find_panel_or_bridge() > > - drm_of_find_dsi_panel_or_bridge() getting the device_node pointer in a > > way specific to DSI devices and calling > > __drm_of_find_panel_or_bridge() > > I don't really like the idea of a DSI helper either. Those node names > are reserved so I'm not sure we'll ever find a conflict, but can we base > our decision on remote-endpoint (for ports/endpoints) or reg (for DSI > devices)? > > > Ideally, though, the case where we have no port node should die out > > slowly, even when DSI devices are children of the DSI controller, there > > should be ports modelling the data connection. > > I'm not really in favor of that either, it looks like making the DT more > complex than it needs to be for no particular reason, but I guess it's a > very subjective matter :) The reason is to simplify software support, which I think is worth it :-)
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 59d368ea006b..7d018ff8bc83 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -249,6 +249,27 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, if (panel) *panel = NULL; + /** + * Some OF graphs don't require 'ports' to represent the downstream + * panel or bridge; instead it simply adds a child node on a given + * parent node. + * + * Lookup that child node for a given parent however that child + * cannot be a 'port' alone or it cannot be a 'port' node too. + */ + if (!of_get_child_by_name(np, "ports")) { + if (of_get_child_by_name(np, "port") && (of_get_child_count(np) == 1)) + goto of_graph_get_remote; + + for_each_available_child_of_node(np, remote) { + if (of_node_name_eq(remote, "port")) + continue; + + goto of_find_panel_or_bridge; + } + } + +of_graph_get_remote: /* * of_graph_get_remote_node() produces a noisy error message if port * node isn't found and the absence of the port is a legit case here, @@ -259,6 +280,8 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, return -ENODEV; remote = of_graph_get_remote_node(np, port, endpoint); + +of_find_panel_or_bridge: if (!remote) return -ENODEV;