drm/bridge: analogix_dp: Add new API analogix_dp_finish_probe()

Since the panel/bridge should logically be positioned behind the
Analogix bridge in the display pipeline, it makes sense to handle
the panel/bridge parsing on the Analogix side. Therefore, we add
a new API analogix_dp_finish_probe(), which combines the panel/bridge
parsing with component addition, to do it.

In order to process component binding right after the probe completes,
the &analogix_dp_plat_data.ops is newly added to pass &component_ops,
for which the &dp_aux_ep_device_with_data.done_probing() of DP AUX bus
only supports passing &drm_dp_aux.

Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Heiko Stuebner <heiko@sntech.de> # rk3588
Link: https://patch.msgid.link/20260413132551.1049307-4-damon.ding@rock-chips.com
[Luca: propagate 'depends on OF' to DRM_ANALOGIX_DP and reverse dependencies]
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
This commit is contained in:
Damon Ding 2026-04-13 21:25:46 +08:00 committed by Luca Ceresoli
parent 99a49ff5ef
commit e9c897c898
4 changed files with 52 additions and 0 deletions

View File

@ -15,6 +15,7 @@ config DRM_ANALOGIX_ANX6345
config DRM_ANALOGIX_ANX78XX
tristate "Analogix ANX78XX bridge"
depends on OF
select DRM_ANALOGIX_DP
select DRM_DISPLAY_DP_HELPER
select DRM_DISPLAY_HELPER
@ -29,6 +30,8 @@ config DRM_ANALOGIX_ANX78XX
config DRM_ANALOGIX_DP
tristate
depends on DRM
depends on OF
select DRM_DISPLAY_DP_AUX_BUS
config DRM_ANALOGIX_ANX7625
tristate "Analogix Anx7625 MIPI to DP interface support"

View File

@ -21,12 +21,14 @@
#include <linux/platform_device.h>
#include <drm/bridge/analogix_dp.h>
#include <drm/display/drm_dp_aux_bus.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@ -1582,6 +1584,50 @@ struct drm_dp_aux *analogix_dp_get_aux(struct analogix_dp_device *dp)
}
EXPORT_SYMBOL_GPL(analogix_dp_get_aux);
static int analogix_dp_aux_done_probing(struct drm_dp_aux *aux)
{
struct analogix_dp_device *dp = to_dp(aux);
struct analogix_dp_plat_data *plat_data = dp->plat_data;
int port = plat_data->dev_type == EXYNOS_DP ? 0 : 1;
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, port, 0,
&plat_data->panel, &plat_data->next_bridge);
if (ret && ret != -ENODEV)
return ret;
return component_add(dp->dev, plat_data->ops);
}
int analogix_dp_finish_probe(struct analogix_dp_device *dp)
{
int ret;
ret = devm_of_dp_aux_populate_bus(&dp->aux, analogix_dp_aux_done_probing);
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 callback function
* analogix_dp_aux_done_probing() 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 analogix_dp_aux_done_probing(&dp->aux);
}
return 0;
}
EXPORT_SYMBOL_GPL(analogix_dp_finish_probe);
MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
MODULE_DESCRIPTION("Analogix DP Core Driver");
MODULE_LICENSE("GPL v2");

View File

@ -69,6 +69,7 @@ config DRM_EXYNOS_DSI
config DRM_EXYNOS_DP
bool "Exynos specific extensions for Analogix DP driver"
depends on DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON
depends on OF
select DRM_ANALOGIX_DP
select DRM_BRIDGE_CONNECTOR
select DRM_DISPLAY_DP_HELPER

View File

@ -30,6 +30,7 @@ struct analogix_dp_plat_data {
struct drm_bridge *next_bridge;
struct drm_encoder *encoder;
struct drm_connector *connector;
const struct component_ops *ops;
int (*power_on)(struct analogix_dp_plat_data *);
int (*power_off)(struct analogix_dp_plat_data *);
@ -49,5 +50,6 @@ int analogix_dp_stop_crc(struct drm_connector *connector);
struct analogix_dp_plat_data *analogix_dp_aux_to_plat_data(struct drm_dp_aux *aux);
struct drm_dp_aux *analogix_dp_get_aux(struct analogix_dp_device *dp);
int analogix_dp_finish_probe(struct analogix_dp_device *dp);
#endif /* _ANALOGIX_DP_H_ */