mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
drm/bridge: analogix_dp: support for switching the eDP/DP mode
Since the Analogix IP can support both eDP v1.3 and DP v1.2, it is sensible to first check whether the last bridge is connected to a panel in order to determine and pass on the eDP/DP submodes to the PHY, which can help separate the eDP/DP configurations in the PHY driver. Change-Id: I86e1c52e15f9348ff9524caaa159f92e5c6fc5de Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#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>
|
||||
@@ -1685,6 +1686,8 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
|
||||
struct analogix_dp_device *dp = bridge->driver_private;
|
||||
struct drm_encoder *encoder = dp->encoder;
|
||||
struct drm_connector *connector = NULL;
|
||||
struct drm_bridge *last_bridge;
|
||||
struct drm_panel *panel = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!bridge->encoder) {
|
||||
@@ -1692,6 +1695,9 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!dp->plat_data->panel)
|
||||
dp->dp_mode = true;
|
||||
|
||||
if (dp->plat_data->bridge) {
|
||||
ret = drm_bridge_attach(bridge->encoder, dp->plat_data->bridge, bridge,
|
||||
dp->plat_data->skip_connector ?
|
||||
@@ -1700,6 +1706,12 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge,
|
||||
DRM_ERROR("Failed to attach external bridge: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
last_bridge = list_last_entry(&bridge->encoder->bridge_chain,
|
||||
struct drm_bridge, chain_node);
|
||||
ret = drm_of_find_panel_or_bridge(last_bridge->of_node, 1, -1, &panel, NULL);
|
||||
if (!ret && panel)
|
||||
dp->dp_mode = false;
|
||||
}
|
||||
|
||||
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
|
||||
|
||||
@@ -209,6 +209,8 @@ struct analogix_dp_device {
|
||||
u32 split_area;
|
||||
|
||||
const struct analogix_dp_output_format *output_fmt;
|
||||
|
||||
bool dp_mode;
|
||||
};
|
||||
|
||||
/* analogix_dp_reg.c */
|
||||
|
||||
@@ -1103,9 +1103,13 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
|
||||
|
||||
int analogix_dp_phy_power_on(struct analogix_dp_device *dp)
|
||||
{
|
||||
int submode = PHY_SUBMODE_EDP;
|
||||
int ret;
|
||||
|
||||
ret = phy_set_mode(dp->phy, PHY_MODE_DP);
|
||||
if (dp->plat_data->support_dp_mode && dp->dp_mode)
|
||||
submode = PHY_SUBMODE_DP;
|
||||
|
||||
ret = phy_set_mode_ext(dp->phy, PHY_MODE_DP, submode);
|
||||
if (ret) {
|
||||
dev_err(dp->dev, "phy_set_mode failed: %d\n", ret);
|
||||
return ret;
|
||||
|
||||
@@ -748,6 +748,7 @@ static int rockchip_dp_probe(struct platform_device *pdev)
|
||||
dp->adp = ERR_PTR(-ENODEV);
|
||||
dp->data = &dp_data[id];
|
||||
dp->plat_data.ssc = dp->data->ssc;
|
||||
dp->plat_data.support_dp_mode = dp->data->support_dp_mode;
|
||||
dp->plat_data.max_bpc = dp->data->max_bpc ? dp->data->max_bpc : 8;
|
||||
dp->plat_data.panel = panel;
|
||||
dp->plat_data.dev_type = dp->data->chip_type;
|
||||
|
||||
@@ -43,6 +43,7 @@ struct analogix_dp_plat_data {
|
||||
struct drm_connector *connector;
|
||||
bool skip_connector;
|
||||
bool ssc;
|
||||
bool support_dp_mode;
|
||||
|
||||
bool split_mode;
|
||||
bool dual_channel_mode;
|
||||
|
||||
Reference in New Issue
Block a user