drm/rockchip: analogix_dp: Add support to get panel from the DP AUX bus
authorDamon Ding <damon.ding@rock-chips.com>
Mon, 10 Mar 2025 10:41:09 +0000 (18:41 +0800)
committerDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Sun, 20 Apr 2025 22:27:10 +0000 (01:27 +0300)
Move drm_of_find_panel_or_bridge() a little later and combine it with
component_add() into a new function rockchip_dp_link_panel(). The function
will serve as done_probing() callback of devm_of_dp_aux_populate_bus(),
aiding to support for obtaining the eDP panel via the DP AUX bus.

If failed to get the panel from the DP AUX bus, it will then try the other
way to get panel information through the platform bus.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Link: https://lore.kernel.org/r/20250310104114.2608063-9-damon.ding@rock-chips.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
drivers/gpu/drm/rockchip/Kconfig
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c

index 26c4410b2407c0deebc530853b4c112d08d533da..f9d7776a859adbd536654bcb18f977914751ef55 100644 (file)
@@ -8,6 +8,7 @@ config DRM_ROCKCHIP
        select DRM_PANEL
        select VIDEOMODE_HELPERS
        select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP
+       select DRM_DISPLAY_DP_AUX_BUS if ROCKCHIP_ANALOGIX_DP
        select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
        select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP
        select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
index a8265a1bf9ffb48fb53837187766ee69cb2fccb4..5632b7e3e12273567e866fdffc1a2d7d64b86732 100644 (file)
@@ -21,6 +21,7 @@
 #include <video/of_videomode.h>
 #include <video/videomode.h>
 
+#include <drm/display/drm_dp_aux_bus.h>
 #include <drm/display/drm_dp_helper.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
@@ -392,11 +393,28 @@ static const struct component_ops rockchip_dp_component_ops = {
        .unbind = rockchip_dp_unbind,
 };
 
+static int rockchip_dp_link_panel(struct drm_dp_aux *aux)
+{
+       struct analogix_dp_plat_data *plat_data = analogix_dp_aux_to_plat_data(aux);
+       struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data);
+       int ret;
+
+       /*
+        * If drm_of_find_panel_or_bridge() returns -ENODEV, there may be no valid panel
+        * or bridge nodes. The driver should go on for the driver-free bridge or the DP
+        * mode applications.
+        */
+       ret = drm_of_find_panel_or_bridge(dp->dev->of_node, 1, 0, &plat_data->panel, NULL);
+       if (ret && ret != -ENODEV)
+               return ret;
+
+       return component_add(dp->dev, &rockchip_dp_component_ops);
+}
+
 static int rockchip_dp_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        const struct rockchip_dp_chip_data *dp_data;
-       struct drm_panel *panel = NULL;
        struct rockchip_dp_device *dp;
        struct resource *res;
        int i;
@@ -406,10 +424,6 @@ static int rockchip_dp_probe(struct platform_device *pdev)
        if (!dp_data)
                return -ENODEV;
 
-       ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
-       if (ret < 0 && ret != -ENODEV)
-               return ret;
-
        dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
        if (!dp)
                return -ENOMEM;
@@ -432,7 +446,6 @@ static int rockchip_dp_probe(struct platform_device *pdev)
 
        dp->dev = dev;
        dp->adp = ERR_PTR(-ENODEV);
-       dp->plat_data.panel = panel;
        dp->plat_data.dev_type = dp->data->chip_type;
        dp->plat_data.power_on = rockchip_dp_poweron;
        dp->plat_data.power_off = rockchip_dp_powerdown;
@@ -448,9 +461,20 @@ static int rockchip_dp_probe(struct platform_device *pdev)
        if (IS_ERR(dp->adp))
                return PTR_ERR(dp->adp);
 
-       ret = component_add(dev, &rockchip_dp_component_ops);
-       if (ret)
-               return ret;
+       ret = devm_of_dp_aux_populate_bus(analogix_dp_get_aux(dp->adp), rockchip_dp_link_panel);
+       if (ret) {
+               /*
+                * If devm_of_dp_aux_populate_bus() returns -ENODEV, the done_probing() will not
+                * be called because there are no EP devices. Then the rockchip_dp_link_panel()
+                * will be called directly in order to support the other valid DT configurations.
+                *
+                * NOTE: The devm_of_dp_aux_populate_bus() is allowed to return -EPROBE_DEFER.
+                */
+               if (ret != -ENODEV)
+                       return dev_err_probe(dp->dev, ret, "failed to populate aux bus\n");
+
+               return rockchip_dp_link_panel(analogix_dp_get_aux(dp->adp));
+       }
 
        return 0;
 }