drm: xlnx: zynqmp_dpsub: Use DRM connector bridge helper
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Fri, 6 Aug 2021 11:29:52 +0000 (14:29 +0300)
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Wed, 19 Oct 2022 13:51:02 +0000 (16:51 +0300)
Replace the manual connector implementation and registration in the DP
encoder with the DRM connector bridge helper. This removes boilerplate
code and simplifies the driver.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
drivers/gpu/drm/xlnx/zynqmp_dp.c
drivers/gpu/drm/xlnx/zynqmp_dpsub.c

index 0aa810e..a18cb97 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <drm/display/drm_dp_helper.h>
 #include <drm/drm_atomic_helper.h>
-#include <drm/drm_connector.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_device.h>
 #include <drm/drm_edid.h>
@@ -275,7 +274,6 @@ struct zynqmp_dp_config {
 
 /**
  * struct zynqmp_dp - Xilinx DisplayPort core
- * @connector: the drm connector structure
  * @dev: device structure
  * @dpsub: Display subsystem
  * @drm: DRM core
@@ -297,7 +295,6 @@ struct zynqmp_dp_config {
  * @train_set: set of training data
  */
 struct zynqmp_dp {
-       struct drm_connector connector;
        struct device *dev;
        struct zynqmp_dpsub *dpsub;
        struct drm_device *drm;
@@ -322,11 +319,6 @@ struct zynqmp_dp {
        u8 train_set[ZYNQMP_DP_MAX_LANES];
 };
 
-static inline struct zynqmp_dp *connector_to_dp(struct drm_connector *connector)
-{
-       return container_of(connector, struct zynqmp_dp, connector);
-}
-
 static inline struct zynqmp_dp *bridge_to_dp(struct drm_bridge *bridge)
 {
        return container_of(bridge, struct zynqmp_dp, bridge);
@@ -1285,33 +1277,15 @@ static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp,
  * DRM Bridge
  */
 
-static const struct drm_connector_funcs zynqmp_dp_connector_funcs;
-static const struct drm_connector_helper_funcs zynqmp_dp_connector_helper_funcs;
-
 static int zynqmp_dp_bridge_attach(struct drm_bridge *bridge,
                                   enum drm_bridge_attach_flags flags)
 {
        struct zynqmp_dp *dp = bridge_to_dp(bridge);
-       struct drm_connector *connector = &dp->connector;
        int ret;
 
-       /* Create the DRM connector. */
-       connector->polled = DRM_CONNECTOR_POLL_HPD;
-       ret = drm_connector_init(dp->drm, connector,
-                                &zynqmp_dp_connector_funcs,
-                                DRM_MODE_CONNECTOR_DisplayPort);
-       if (ret) {
-               dev_err(dp->dev, "failed to create the DRM connector\n");
-               return ret;
-       }
-
-       drm_connector_helper_add(connector, &zynqmp_dp_connector_helper_funcs);
-       drm_connector_register(connector);
-       drm_connector_attach_encoder(connector, bridge->encoder);
-
        if (dp->next_bridge) {
                ret = drm_bridge_attach(bridge->encoder, dp->next_bridge,
-                                       bridge, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+                                       bridge, flags);
                if (ret < 0)
                        return ret;
        }
@@ -1533,68 +1507,6 @@ static const struct drm_bridge_funcs zynqmp_dp_bridge_funcs = {
 };
 
 /* -----------------------------------------------------------------------------
- * DRM Connector
- */
-
-static enum drm_connector_status
-zynqmp_dp_connector_detect(struct drm_connector *connector, bool force)
-{
-       struct zynqmp_dp *dp = connector_to_dp(connector);
-
-       return zynqmp_dp_bridge_detect(&dp->bridge);
-}
-
-static int zynqmp_dp_connector_get_modes(struct drm_connector *connector)
-{
-       struct zynqmp_dp *dp = connector_to_dp(connector);
-       struct edid *edid;
-       int ret;
-
-       edid = zynqmp_dp_bridge_get_edid(&dp->bridge, connector);
-       if (!edid)
-               return 0;
-
-       drm_connector_update_edid_property(connector, edid);
-       ret = drm_add_edid_modes(connector, edid);
-       kfree(edid);
-
-       return ret;
-}
-
-static struct drm_encoder *
-zynqmp_dp_connector_best_encoder(struct drm_connector *connector)
-{
-       struct zynqmp_dp *dp = connector_to_dp(connector);
-
-       return &dp->dpsub->encoder;
-}
-
-static int zynqmp_dp_connector_mode_valid(struct drm_connector *connector,
-                                         struct drm_display_mode *mode)
-{
-       struct zynqmp_dp *dp = connector_to_dp(connector);
-
-       return zynqmp_dp_bridge_mode_valid(&dp->bridge, &connector->display_info,
-                                          mode);
-}
-
-static const struct drm_connector_funcs zynqmp_dp_connector_funcs = {
-       .detect                 = zynqmp_dp_connector_detect,
-       .fill_modes             = drm_helper_probe_single_connector_modes,
-       .destroy                = drm_connector_cleanup,
-       .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-       .atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
-       .reset                  = drm_atomic_helper_connector_reset,
-};
-
-static const struct drm_connector_helper_funcs
-zynqmp_dp_connector_helper_funcs = {
-       .get_modes      = zynqmp_dp_connector_get_modes,
-       .best_encoder   = zynqmp_dp_connector_best_encoder,
-       .mode_valid     = zynqmp_dp_connector_mode_valid,
-};
-
-/* -----------------------------------------------------------------------------
  * Interrupt Handling
  */
 
index bb7c74a..6f6e7c6 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_connector.h>
 #include <drm/drm_device.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_fb_helper.h>
@@ -97,6 +99,7 @@ static const struct drm_driver zynqmp_dpsub_drm_driver = {
 static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub)
 {
        struct drm_encoder *encoder = &dpsub->encoder;
+       struct drm_connector *connector;
        struct drm_device *drm = &dpsub->drm;
        int ret;
 
@@ -133,12 +136,27 @@ static int zynqmp_dpsub_drm_init(struct zynqmp_dpsub *dpsub)
        encoder->possible_crtcs |= zynqmp_disp_get_crtc_mask(dpsub->disp);
        drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
 
-       ret = drm_bridge_attach(encoder, dpsub->bridge, NULL, 0);
+       ret = drm_bridge_attach(encoder, dpsub->bridge, NULL,
+                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
        if (ret) {
                dev_err(dpsub->dev, "failed to attach bridge to encoder\n");
                goto err_poll_fini;
        }
 
+       /* Create the connector for the chain of bridges. */
+       connector = drm_bridge_connector_init(drm, encoder);
+       if (IS_ERR(connector)) {
+               dev_err(dpsub->dev, "failed to created connector\n");
+               ret = PTR_ERR(connector);
+               goto err_poll_fini;
+       }
+
+       ret = drm_connector_attach_encoder(connector, encoder);
+       if (ret < 0) {
+               dev_err(dpsub->dev, "failed to attach connector to encoder\n");
+               goto err_poll_fini;
+       }
+
        /* Reset all components and register the DRM device. */
        drm_mode_config_reset(drm);