| From d13b544c949e85e39f6c1c20485d8f37f5127e59 Mon Sep 17 00:00:00 2001 |
| From: Sandor Yu <Sandor.yu@nxp.com> |
| Date: Fri, 20 Dec 2019 17:31:52 +0800 |
| Subject: [PATCH] LF-568-2: drm: gpu: bridge: cdns: Add force mode set flag |
| |
| In DRM framework, when hdmi/dp cable plugout/plugin in the same HDMI |
| sink, because the video mode is same, DRM will not call mode_set. |
| But for HDMI 2.0 sink the SCDC configurate will lost, and DP sink |
| linktraning status will lost too after cable plugout then plugin. |
| |
| Currently, hdmi/dp driver will call mode_set function in HPD thread, |
| But the mode_set function is called out of DRM framework, and it have |
| chance to fail. |
| In the patch add force_mode_set flag, set the crtc_state->mode_changed |
| to force drm call mode_set when cable plugin. |
| |
| Signed-off-by: Sandor Yu <Sandor.yu@nxp.com> |
| --- |
| drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 5 +++++ |
| drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 12 ++++++++---- |
| drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c | 4 ++++ |
| include/drm/bridge/cdns-mhdp-common.h | 1 + |
| 4 files changed, 18 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c |
| +++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c |
| @@ -322,6 +322,9 @@ static void cdns_dp_bridge_mode_set(stru |
| mutex_lock(&mhdp->lock); |
| cdns_dp_mode_set(mhdp); |
| mutex_unlock(&mhdp->lock); |
| + |
| + /* reset force mode set flag */ |
| + mhdp->force_mode_set = false; |
| } |
| |
| static void cdn_dp_bridge_enable(struct drm_bridge *bridge) |
| @@ -375,6 +378,8 @@ static void hotplug_work_func(struct wor |
| } else if (connector->status == connector_status_disconnected) { |
| /* Cable Disconnedted */ |
| DRM_INFO("HDMI/DP Cable Plug Out\n"); |
| + /* force mode set for cable replugin to recovery DP video modes */ |
| + mhdp->force_mode_set = true; |
| enable_irq(mhdp->irq[IRQ_IN]); |
| } |
| } |
| --- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c |
| +++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c |
| @@ -178,6 +178,10 @@ void cdns_hdmi_mode_set(struct cdns_mhdp |
| struct drm_display_mode *mode = &mhdp->mode; |
| int ret; |
| |
| + /* video mode valid check */ |
| + if (mode->clock == 0 || mode->hdisplay == 0 || mode->vdisplay == 0) |
| + return; |
| + |
| hdmi_lanes_config(mhdp); |
| |
| cdns_mhdp_plat_call(mhdp, pclk_rate); |
| @@ -393,6 +397,8 @@ static void cdns_hdmi_bridge_mode_set(st |
| mutex_lock(&mhdp->lock); |
| cdns_hdmi_mode_set(mhdp); |
| mutex_unlock(&mhdp->lock); |
| + /* reset force mode set flag */ |
| + mhdp->force_mode_set = false; |
| } |
| |
| bool cdns_hdmi_bridge_mode_fixup(struct drm_bridge *bridge, |
| @@ -467,14 +473,12 @@ static void hotplug_work_func(struct wor |
| |
| if (connector->status == connector_status_connected) { |
| DRM_INFO("HDMI Cable Plug In\n"); |
| - /* reset video mode after cable plugin */ |
| - mutex_lock(&mhdp->lock); |
| - cdns_hdmi_mode_set(mhdp); |
| - mutex_unlock(&mhdp->lock); |
| enable_irq(mhdp->irq[IRQ_OUT]); |
| } else if (connector->status == connector_status_disconnected) { |
| /* Cable Disconnedted */ |
| DRM_INFO("HDMI Cable Plug Out\n"); |
| + /* force mode set for cable replugin to recovery HDMI2.0 video modes */ |
| + mhdp->force_mode_set = true; |
| enable_irq(mhdp->irq[IRQ_IN]); |
| } |
| } |
| --- a/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c |
| +++ b/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c |
| @@ -40,6 +40,10 @@ static int cdns_mhdp_imx_encoder_atomic_ |
| |
| if (mhdp->plat_data->video_format != 0) |
| imx_crtc_state->bus_format = mhdp->plat_data->video_format; |
| + |
| + if (mhdp->force_mode_set) |
| + crtc_state->mode_changed = true; |
| + |
| return 0; |
| } |
| |
| --- a/include/drm/bridge/cdns-mhdp-common.h |
| +++ b/include/drm/bridge/cdns-mhdp-common.h |
| @@ -684,6 +684,7 @@ struct cdns_mhdp_device { |
| bool link_up; |
| bool power_up; |
| bool plugged; |
| + bool force_mode_set; |
| bool is_hpd; |
| bool is_ls1028a; |
| struct mutex lock; |