From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Jyri Sarha <jsarha@ti.com>
Cc: devicetree@vger.kernel.org, bcousson@baylibre.com,
khilman@baylibre.com, dri-devel@lists.freedesktop.org,
bgolaszewski@baylibre.com, tomi.valkeinen@ti.com
Subject: Re: [PATCH 3/3] drm/tilcdc: Add drm bridge support for attaching drm bridge drivers
Date: Thu, 03 Nov 2016 19:50:08 +0200 [thread overview]
Message-ID: <4030126.Q3156qUFoV@avalon> (raw)
In-Reply-To: <463d18493ac508708ed764e71d11c2b89662544c.1478103726.git.jsarha@ti.com>
Hi Jyri,
Thank you for the patch.
On Wednesday 02 Nov 2016 18:32:17 Jyri Sarha wrote:
> Adds drm bride support for attaching drm bridge drivers to tilcdc. The
> decision whether a video port leads to an external encoder or bridge
> is made simply based on remote device's compatible string. The code
> has been tested with BeagleBone-Black with and without BeagleBone
> DVI-D Cape Rev A3 using ti-tfp410 driver.
>
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> ---
> .../devicetree/bindings/display/tilcdc/tilcdc.txt | 7 +-
> drivers/gpu/drm/tilcdc/tilcdc_drv.c | 7 +-
> drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 +
> drivers/gpu/drm/tilcdc/tilcdc_external.c | 140 ++++++++++++++---
> drivers/gpu/drm/tilcdc/tilcdc_external.h | 1 +
> 5 files changed, 135 insertions(+), 22 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
> b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt index
> 6fddb4f..ae7a942 100644
> --- a/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
> +++ b/Documentation/devicetree/bindings/display/tilcdc/tilcdc.txt
> @@ -34,9 +34,10 @@ Optional properties:
>
> Optional nodes:
>
> - - port/ports: to describe a connection to an external encoder. The
> - binding follows Documentation/devicetree/bindings/graph.txt and
> - suppors a single port with a single endpoint.
> + - port/ports: to describe a connection to an external encoder or
> + bridge. The binding follows
What's the difference between encoder and bridge here ? drm_bridge and
drm_encoder are irrelevant to DT bindings, we should only care about the
hardware view of the system here.
> + Documentation/devicetree/bindings/graph.txt and suppors a single
> + port with a single endpoint.
>
> - See also Documentation/devicetree/bindings/display/tilcdc/panel.txt and
> Documentation/devicetree/bindings/display/tilcdc/tfp410.txt for
> connecting diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> b/drivers/gpu/drm/tilcdc/tilcdc_drv.c index dcc9621..ec22576 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
> @@ -384,9 +384,14 @@ static int tilcdc_init(struct drm_driver *ddrv, struct
> device *dev) ret = tilcdc_add_external_encoders(ddev);
> if (ret < 0)
> goto init_failed;
> + } else {
> + ret = tilcdc_attach_remote_device(ddev);
> + if (ret)
> + goto init_failed;
> }
>
> - if ((priv->num_encoders == 0) || (priv->num_connectors == 0)) {
> + if (!priv->remote_encoder &&
> + ((priv->num_encoders == 0) || (priv->num_connectors == 0))) {
> dev_err(dev, "no encoders/connectors found\n");
> ret = -ENXIO;
> goto init_failed;
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
> b/drivers/gpu/drm/tilcdc/tilcdc_drv.h index d31fe5d..283ff28 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
> @@ -90,6 +90,8 @@ struct tilcdc_drm_private {
> struct drm_connector *connectors[8];
> const struct drm_connector_helper_funcs *connector_funcs[8];
>
> + struct drm_encoder *remote_encoder;
> +
> bool is_registered;
> bool is_componentized;
> };
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.c
> b/drivers/gpu/drm/tilcdc/tilcdc_external.c index 06a4c58..bcb1324 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_external.c
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c
> @@ -28,6 +28,18 @@
> .raster_order = 0,
> };
>
> +static const struct tilcdc_panel_info panel_info_default = {
> + .ac_bias = 255,
> + .ac_bias_intrpt = 0,
> + .dma_burst_sz = 16,
> + .bpp = 16,
> + .fdd = 0x80,
> + .tft_alt_mode = 0,
> + .sync_edge = 0,
> + .sync_ctrl = 1,
> + .raster_order = 0,
> +};
> +
> static int tilcdc_external_mode_valid(struct drm_connector *connector,
> struct drm_display_mode *mode)
> {
> @@ -130,6 +142,101 @@ void tilcdc_remove_external_encoders(struct drm_device
> *dev) priv->connector_funcs[i]);
> }
>
> +static struct drm_encoder_funcs tilcdc_remote_encoder_funcs = {
> + .destroy = drm_encoder_cleanup,
> +};
> +
> +static
> +int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge
> *bridge) +{
> + struct tilcdc_drm_private *priv = ddev->dev_private;
> + int ret;
> +
> + priv->remote_encoder->possible_crtcs = BIT(0);
> + priv->remote_encoder->bridge = bridge;
> + bridge->encoder = priv->remote_encoder;
> +
> + ret = drm_bridge_attach(ddev, bridge);
> + if (ret) {
> + dev_err(ddev->dev, "drm_bridge_attach() failed %d\n", ret);
> + return ret;
> + }
> +
> + tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_default);
> +
> + return 0;
> +}
> +
> +static int tilcdc_node_has_port(struct device_node *dev_node)
> +{
> + struct device_node *node;
> +
> + node = of_get_child_by_name(dev_node, "ports");
> + if (!node)
> + node = of_get_child_by_name(dev_node, "port");
> + if (!node)
> + return 0;
> + of_node_put(node);
> +
> + return 1;
> +}
> +
> +static
> +struct device_node *tilcdc_get_remote_node(struct device_node *node)
> +{
> + struct device_node *ep;
> + struct device_node *parent;
> +
> + if (!tilcdc_node_has_port(node))
> + return NULL;
> +
> + ep = of_graph_get_next_endpoint(node, NULL);
> + if (!ep)
> + return NULL;
> +
> + parent = of_graph_get_remote_port_parent(ep);
> + of_node_put(ep);
> +
> + return parent;
> +}
> +
> +int tilcdc_attach_remote_device(struct drm_device *ddev)
> +{
> + struct tilcdc_drm_private *priv = ddev->dev_private;
> + struct device_node *remote_node;
> + struct drm_bridge *bridge;
> + int ret;
> +
> + remote_node = tilcdc_get_remote_node(ddev->dev->of_node);
> + if (!remote_node)
> + return 0;
> +
> + bridge = of_drm_find_bridge(remote_node);
> + of_node_put(remote_node);
> + if (!bridge)
> + return -EPROBE_DEFER;
> +
> + priv->remote_encoder = devm_kzalloc(ddev->dev,
> + sizeof(*priv->remote_encoder),
> + GFP_KERNEL);
> + if (!priv->remote_encoder)
> + return -ENOMEM;
> +
> + ret = drm_encoder_init(ddev, priv->remote_encoder,
> + &tilcdc_remote_encoder_funcs,
> + DRM_MODE_ENCODER_NONE, NULL);
> + if (ret) {
> + dev_err(ddev->dev, "drm_encoder_init() failed %d\n", ret);
> + return ret;
> + }
> +
> + ret = tilcdc_attach_bridge(ddev, bridge);
> + if (ret)
> + drm_encoder_cleanup(priv->remote_encoder);
> +
> + return ret;
> +}
> +
> static int dev_match_of(struct device *dev, void *data)
> {
> return dev->of_node == data;
> @@ -141,16 +248,10 @@ int tilcdc_get_external_components(struct device *dev,
> struct device_node *node;
> struct device_node *ep = NULL;
> int count = 0;
> + int ret = 0;
>
> - /* Avoid error print by of_graph_get_next_endpoint() if there
> - * is no ports present.
> - */
> - node = of_get_child_by_name(dev->of_node, "ports");
> - if (!node)
> - node = of_get_child_by_name(dev->of_node, "port");
> - if (!node)
> + if (!tilcdc_node_has_port(dev->of_node))
> return 0;
> - of_node_put(node);
>
> while ((ep = of_graph_get_next_endpoint(dev->of_node, ep))) {
> node = of_graph_get_remote_port_parent(ep);
> @@ -160,17 +261,20 @@ int tilcdc_get_external_components(struct device *dev,
> }
>
> dev_dbg(dev, "Subdevice node '%s' found\n", node->name);
> - if (match)
> - drm_of_component_match_add(dev, match, dev_match_of,
> - node);
> - of_node_put(node);
> - count++;
> - }
>
> - if (count > 1) {
> - dev_err(dev, "Only one external encoder is supported\n");
> - return -EINVAL;
> + if (of_device_is_compatible(node, "nxp,tda998x")) {
> + if (match)
> + drm_of_component_match_add(dev, match,
> + dev_match_of,
node);
> + ret = 1;
> + }
> +
> + of_node_put(node);
> + if (count++ > 1) {
> + dev_err(dev, "Only one port is supported\n");
> + return -EINVAL;
> + }
> }
>
> - return count;
> + return ret;
> }
> diff --git a/drivers/gpu/drm/tilcdc/tilcdc_external.h
> b/drivers/gpu/drm/tilcdc/tilcdc_external.h index c700e0c..a27c365 100644
> --- a/drivers/gpu/drm/tilcdc/tilcdc_external.h
> +++ b/drivers/gpu/drm/tilcdc/tilcdc_external.h
> @@ -22,4 +22,5 @@
> void tilcdc_remove_external_encoders(struct drm_device *dev);
> int tilcdc_get_external_components(struct device *dev,
> struct component_match **match);
> +int tilcdc_attach_remote_device(struct drm_device *ddev);
> #endif /* __TILCDC_SLAVE_H__ */
--
Regards,
Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2016-11-03 17:50 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-02 16:32 [PATCH 0/3] drm/tilcdc: Add bridge support and sync-lost flood recovery Jyri Sarha
2016-11-02 16:32 ` [PATCH 1/3] drm/tilcdc: Recover from sync lost error flood by resetting the LCDC Jyri Sarha
2016-11-02 16:32 ` [PATCH 2/3] drm/bridge: Add ti-ftp410 HDMI transmitter driver Jyri Sarha
2016-11-03 10:24 ` Tomi Valkeinen
2016-11-03 17:46 ` Laurent Pinchart
2016-11-10 9:16 ` Jyri Sarha
2016-11-10 12:15 ` Laurent Pinchart
2016-11-10 12:16 ` Tomi Valkeinen
2016-11-14 8:49 ` Jyri Sarha
2016-11-14 11:10 ` Laurent Pinchart
2016-11-14 11:16 ` Tomi Valkeinen
[not found] ` <ac8e0f72-fac2-45e5-0004-d6028ddeb221-l0cyMroinI0@public.gmane.org>
2016-11-14 11:22 ` Laurent Pinchart
2016-11-02 16:32 ` [PATCH 3/3] drm/tilcdc: Add drm bridge support for attaching drm bridge drivers Jyri Sarha
2016-11-03 17:50 ` Laurent Pinchart [this message]
[not found] ` <463d18493ac508708ed764e71d11c2b89662544c.1478103726.git.jsarha-l0cyMroinI0@public.gmane.org>
2016-11-10 0:50 ` Rob Herring
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4030126.Q3156qUFoV@avalon \
--to=laurent.pinchart@ideasonboard.com \
--cc=bcousson@baylibre.com \
--cc=bgolaszewski@baylibre.com \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=jsarha@ti.com \
--cc=khilman@baylibre.com \
--cc=tomi.valkeinen@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox