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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.