drm/tegra: output: hdmi: Support bridge/connector
authorMaxim Schwalm <maxim.schwalm@gmail.com>
Sun, 18 Jun 2023 08:50:45 +0000 (11:50 +0300)
committerThierry Reding <treding@nvidia.com>
Thu, 27 Jul 2023 16:41:59 +0000 (18:41 +0200)
Some Tegra device-trees may specify a video output graph, which involves
MHL bridge/simple bridge and/or connector framework. This patch adds
support for the bridge/connector attached to the HDMI output, allowing
us to model the hardware properly.

Inspired by: 29efdc2 ("drm/tegra: output: rgb: Support LVDS encoder bridge")

Tested-by: Andreas Westman Dorcsak <hedmoo@yahoo.com> # ASUS TF T30
Tested-by: Maxim Schwalm <maxim.schwalm@gmail.com> # ASUS P1801-T T30
Tested-by: Robert Eckelmann <longnoserob@gmail.com> # ASUS TF101 T20
Tested-by: Svyatoslav Ryhel <clamor95@gmail.com> # ASUS TF201 T30
Signed-off-by: Maxim Schwalm <maxim.schwalm@gmail.com>
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230618085046.10081-2-clamor95@gmail.com
drivers/gpu/drm/tegra/hdmi.c

index 00be307..549a156 100644 (file)
@@ -20,6 +20,7 @@
 #include <soc/tegra/common.h>
 #include <sound/hdmi-codec.h>
 
+#include <drm/drm_bridge_connector.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_debugfs.h>
@@ -1545,26 +1546,47 @@ static int tegra_hdmi_init(struct host1x_client *client)
 {
        struct tegra_hdmi *hdmi = host1x_client_to_hdmi(client);
        struct drm_device *drm = dev_get_drvdata(client->host);
+       struct drm_connector *connector;
        int err;
 
        hdmi->output.dev = client->dev;
 
-       drm_connector_init_with_ddc(drm, &hdmi->output.connector,
-                                   &tegra_hdmi_connector_funcs,
-                                   DRM_MODE_CONNECTOR_HDMIA,
-                                   hdmi->output.ddc);
-       drm_connector_helper_add(&hdmi->output.connector,
-                                &tegra_hdmi_connector_helper_funcs);
-       hdmi->output.connector.dpms = DRM_MODE_DPMS_OFF;
-
        drm_simple_encoder_init(drm, &hdmi->output.encoder,
                                DRM_MODE_ENCODER_TMDS);
        drm_encoder_helper_add(&hdmi->output.encoder,
                               &tegra_hdmi_encoder_helper_funcs);
 
-       drm_connector_attach_encoder(&hdmi->output.connector,
-                                         &hdmi->output.encoder);
-       drm_connector_register(&hdmi->output.connector);
+       if (hdmi->output.bridge) {
+               err = drm_bridge_attach(&hdmi->output.encoder, hdmi->output.bridge,
+                                       NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+               if (err) {
+                       dev_err(client->dev, "failed to attach bridge: %d\n",
+                               err);
+                       return err;
+               }
+
+               connector = drm_bridge_connector_init(drm, &hdmi->output.encoder);
+               if (IS_ERR(connector)) {
+                       dev_err(client->dev,
+                               "failed to initialize bridge connector: %pe\n",
+                               connector);
+                       return PTR_ERR(connector);
+               }
+
+               drm_connector_attach_encoder(connector, &hdmi->output.encoder);
+       } else {
+               drm_connector_init_with_ddc(drm, &hdmi->output.connector,
+                                           &tegra_hdmi_connector_funcs,
+                                           DRM_MODE_CONNECTOR_HDMIA,
+                                           hdmi->output.ddc);
+               drm_connector_helper_add(&hdmi->output.connector,
+                                        &tegra_hdmi_connector_helper_funcs);
+               hdmi->output.connector.dpms = DRM_MODE_DPMS_OFF;
+
+               drm_connector_attach_encoder(&hdmi->output.connector,
+                                            &hdmi->output.encoder);
+               drm_connector_register(&hdmi->output.connector);
+       }
 
        err = tegra_output_init(drm, &hdmi->output);
        if (err < 0) {