mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
drm/exynos: exynos_dp: Apply of-display-mode-bridge to parse the display-timings node
If there is neither a panel nor a bridge, the display timing can be parsed from the display-timings node under the dp node. In order to get rid of &analogix_dp_plat_data.get_modes() and make the codes more consistent, apply DRM of-display-mode-bridge to parse display timings. Signed-off-by: Damon Ding <damon.ding@rock-chips.com> Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Heiko Stuebner <heiko@sntech.de> # rk3588 Link: https://patch.msgid.link/20260409065301.446670-6-damon.ding@rock-chips.com Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
This commit is contained in:
parent
af917a1b95
commit
1b7cee81d8
|
|
@ -72,6 +72,7 @@ config DRM_EXYNOS_DP
|
|||
select DRM_ANALOGIX_DP
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
default DRM_EXYNOS
|
||||
select DRM_OF_DISPLAY_MODE_BRIDGE
|
||||
select DRM_PANEL
|
||||
help
|
||||
This enables support for DP device.
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <video/videomode.h>
|
||||
|
||||
#include <drm/bridge/analogix_dp.h>
|
||||
#include <drm/bridge/of-display-mode-bridge.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_bridge.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
|
|
@ -38,9 +39,10 @@ struct exynos_dp_device {
|
|||
struct drm_device *drm_dev;
|
||||
struct device *dev;
|
||||
|
||||
struct videomode vm;
|
||||
struct analogix_dp_device *adp;
|
||||
struct analogix_dp_plat_data plat_data;
|
||||
|
||||
bool has_of_bridge;
|
||||
};
|
||||
|
||||
static int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
|
||||
|
|
@ -67,44 +69,20 @@ static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data)
|
|||
return exynos_dp_crtc_clock_enable(plat_data, false);
|
||||
}
|
||||
|
||||
static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct exynos_dp_device *dp = to_dp(plat_data);
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
if (dp->plat_data.panel)
|
||||
return 0;
|
||||
|
||||
mode = drm_mode_create(connector->dev);
|
||||
if (!mode) {
|
||||
DRM_DEV_ERROR(dp->dev,
|
||||
"failed to create a new display mode.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
drm_display_mode_from_videomode(&dp->vm, mode);
|
||||
connector->display_info.width_mm = mode->width_mm;
|
||||
connector->display_info.height_mm = mode->height_mm;
|
||||
|
||||
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
|
||||
drm_mode_set_name(mode);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
|
||||
struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct exynos_dp_device *dp = to_dp(plat_data);
|
||||
enum drm_bridge_attach_flags flags = 0;
|
||||
int ret;
|
||||
|
||||
/* Pre-empt DP connector creation if there's a bridge */
|
||||
if (plat_data->next_bridge) {
|
||||
ret = drm_bridge_attach(&dp->encoder, plat_data->next_bridge, bridge,
|
||||
0);
|
||||
if (dp->has_of_bridge)
|
||||
flags = DRM_BRIDGE_ATTACH_NO_CONNECTOR;
|
||||
|
||||
ret = drm_bridge_attach(&dp->encoder, plat_data->next_bridge, bridge, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -129,19 +107,6 @@ static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
|
|||
.disable = exynos_dp_nop,
|
||||
};
|
||||
|
||||
static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = of_get_videomode(dp->dev->of_node, &dp->vm, OF_USE_NATIVE_MODE);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(dp->dev,
|
||||
"failed: of_get_videomode() : %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
|
||||
{
|
||||
struct exynos_dp_device *dp = dev_get_drvdata(dev);
|
||||
|
|
@ -151,12 +116,6 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
|
|||
|
||||
dp->drm_dev = drm_dev;
|
||||
|
||||
if (!dp->plat_data.panel && !dp->plat_data.next_bridge) {
|
||||
ret = exynos_dp_dt_parse_panel(dp);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
|
||||
|
||||
drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs);
|
||||
|
|
@ -223,6 +182,14 @@ static int exynos_dp_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &panel, &bridge);
|
||||
if (ret == -ENODEV) {
|
||||
dp->plat_data.next_bridge = devm_drm_of_display_mode_bridge(dp->dev,
|
||||
dp->dev->of_node,
|
||||
DRM_MODE_CONNECTOR_eDP);
|
||||
ret = IS_ERR(dp->plat_data.next_bridge) ? PTR_ERR(dp->plat_data.next_bridge) : 0;
|
||||
if (!ret)
|
||||
dp->has_of_bridge = true;
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -233,7 +200,6 @@ static int exynos_dp_probe(struct platform_device *pdev)
|
|||
dp->plat_data.power_on = exynos_dp_poweron;
|
||||
dp->plat_data.power_off = exynos_dp_poweroff;
|
||||
dp->plat_data.attach = exynos_dp_bridge_attach;
|
||||
dp->plat_data.get_modes = exynos_dp_get_modes;
|
||||
dp->plat_data.skip_connector = !!bridge;
|
||||
|
||||
out:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user