diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dp/dp_display.c')
-rw-r--r-- | drivers/gpu/drm/msm/dp/dp_display.c | 84 |
1 files changed, 44 insertions, 40 deletions
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 3898850739ab..386c4669c831 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -11,7 +11,9 @@ #include <linux/of_irq.h> #include <linux/phy/phy.h> #include <linux/delay.h> +#include <linux/string_choices.h> #include <drm/display/drm_dp_aux_bus.h> +#include <drm/display/drm_hdmi_audio_helper.h> #include <drm/drm_edid.h> #include "msm_drv.h" @@ -287,13 +289,6 @@ static int msm_dp_display_bind(struct device *dev, struct device *master, goto end; } - - rc = msm_dp_register_audio_driver(dev, dp->audio); - if (rc) { - DRM_ERROR("Audio registration Dp failed\n"); - goto end; - } - rc = msm_dp_hpd_event_thread_start(dp); if (rc) { DRM_ERROR("Event thread create failed\n"); @@ -315,7 +310,6 @@ static void msm_dp_display_unbind(struct device *dev, struct device *master, of_dp_aux_depopulate_bus(dp->aux); - msm_dp_unregister_audio_driver(dev, dp->audio); msm_dp_aux_unregister(dp->aux); dp->drm_dev = NULL; dp->aux->drm_dev = NULL; @@ -343,8 +337,7 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d { if ((hpd && dp->msm_dp_display.link_ready) || (!hpd && !dp->msm_dp_display.link_ready)) { - drm_dbg_dp(dp->drm_dev, "HPD already %s\n", - (hpd ? "on" : "off")); + drm_dbg_dp(dp->drm_dev, "HPD already %s\n", str_on_off(hpd)); return 0; } @@ -367,11 +360,35 @@ static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *d return 0; } +static int msm_dp_display_lttpr_init(struct msm_dp_display_private *dp, u8 *dpcd) +{ + int rc, lttpr_count; + + if (drm_dp_read_lttpr_common_caps(dp->aux, dpcd, dp->link->lttpr_common_caps)) + return 0; + + lttpr_count = drm_dp_lttpr_count(dp->link->lttpr_common_caps); + rc = drm_dp_lttpr_init(dp->aux, lttpr_count); + if (rc) { + DRM_ERROR("failed to set LTTPRs transparency mode, rc=%d\n", rc); + return 0; + } + + return lttpr_count; +} + static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp) { struct drm_connector *connector = dp->msm_dp_display.connector; const struct drm_display_info *info = &connector->display_info; int rc = 0; + u8 dpcd[DP_RECEIVER_CAP_SIZE]; + + rc = drm_dp_read_dpcd_caps(dp->aux, dpcd); + if (rc) + goto end; + + dp->link->lttpr_count = msm_dp_display_lttpr_init(dp, dpcd); rc = msm_dp_panel_read_sink_caps(dp->panel, connector); if (rc) @@ -611,9 +628,9 @@ static void msm_dp_display_handle_plugged_change(struct msm_dp *msm_dp_display, struct msm_dp_display_private, msm_dp_display); /* notify audio subsystem only if sink supports audio */ - if (msm_dp_display->plugged_cb && msm_dp_display->codec_dev && - dp->audio_supported) - msm_dp_display->plugged_cb(msm_dp_display->codec_dev, plugged); + if (dp->audio_supported) + drm_connector_hdmi_audio_plugged_notify(msm_dp_display->connector, + plugged); } static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp, u32 data) @@ -892,19 +909,6 @@ static int msm_dp_display_disable(struct msm_dp_display_private *dp) return 0; } -int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display, - hdmi_codec_plugged_cb fn, struct device *codec_dev) -{ - bool plugged; - - msm_dp_display->plugged_cb = fn; - msm_dp_display->codec_dev = codec_dev; - plugged = msm_dp_display->link_ready; - msm_dp_display_handle_plugged_change(msm_dp_display, plugged); - - return 0; -} - /** * msm_dp_bridge_mode_valid - callback to determine if specified mode is valid * @bridge: Pointer to drm bridge structure @@ -1492,13 +1496,13 @@ int msm_dp_modeset_init(struct msm_dp *msm_dp_display, struct drm_device *dev, } void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge, - struct drm_bridge_state *old_bridge_state) + struct drm_atomic_state *state) { struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge); struct msm_dp *dp = msm_dp_bridge->msm_dp_display; int rc = 0; struct msm_dp_display_private *msm_dp_display; - u32 state; + u32 hpd_state; bool force_link_train = false; msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display); @@ -1517,8 +1521,8 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge, return; } - state = msm_dp_display->hpd_state; - if (state != ST_DISPLAY_OFF && state != ST_MAINLINK_READY) { + hpd_state = msm_dp_display->hpd_state; + if (hpd_state != ST_DISPLAY_OFF && hpd_state != ST_MAINLINK_READY) { mutex_unlock(&msm_dp_display->event_mutex); return; } @@ -1530,9 +1534,9 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge, return; } - state = msm_dp_display->hpd_state; + hpd_state = msm_dp_display->hpd_state; - if (state == ST_DISPLAY_OFF) { + if (hpd_state == ST_DISPLAY_OFF) { msm_dp_display_host_phy_init(msm_dp_display); force_link_train = true; } @@ -1553,7 +1557,7 @@ void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge, } void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge, - struct drm_bridge_state *old_bridge_state) + struct drm_atomic_state *state) { struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge); struct msm_dp *dp = msm_dp_bridge->msm_dp_display; @@ -1565,11 +1569,11 @@ void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge, } void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, - struct drm_bridge_state *old_bridge_state) + struct drm_atomic_state *state) { struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge); struct msm_dp *dp = msm_dp_bridge->msm_dp_display; - u32 state; + u32 hpd_state; struct msm_dp_display_private *msm_dp_display; msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display); @@ -1579,15 +1583,15 @@ void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, mutex_lock(&msm_dp_display->event_mutex); - state = msm_dp_display->hpd_state; - if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED) + hpd_state = msm_dp_display->hpd_state; + if (hpd_state != ST_DISCONNECT_PENDING && hpd_state != ST_CONNECTED) drm_dbg_dp(dp->drm_dev, "type=%d wrong hpd_state=%d\n", - dp->connector_type, state); + dp->connector_type, hpd_state); msm_dp_display_disable(msm_dp_display); - state = msm_dp_display->hpd_state; - if (state == ST_DISCONNECT_PENDING) { + hpd_state = msm_dp_display->hpd_state; + if (hpd_state == ST_DISCONNECT_PENDING) { /* completed disconnection */ msm_dp_display->hpd_state = ST_DISCONNECTED; } else { |