ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 805-display-0023-drm-mhdp-reset-video-mode-after-hdmi-dp-cable-plugin.patch
1 From 9ff3c9d6063c6464e243b85bbbbd03e2096a57c0 Mon Sep 17 00:00:00 2001
2 From: Sandor Yu <Sandor.yu@nxp.com>
3 Date: Mon, 28 Oct 2019 17:07:06 +0800
4 Subject: [PATCH] drm: mhdp: reset video mode after hdmi/dp cable plugin
5
6 DP need setup link training, and HDMI need reset hdmi sink SCDC
7 status after cable reconnected.
8 Add video mode_set function when cable plugin.
9 Add 20ms/50ms delay for hdmi/dp to waite FW stable.
10
11 Signed-off-by: Sandor Yu <Sandor.yu@nxp.com>
12 ---
13  drivers/gpu/drm/bridge/cadence/cdns-dp-core.c   | 20 ++++----
14  drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 63 ++++++++++++-------------
15  2 files changed, 43 insertions(+), 40 deletions(-)
16
17 --- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
18 +++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
19 @@ -108,19 +108,19 @@ static void dp_pixel_clk_reset(struct cd
20         cdns_mhdp_reg_write(mhdp, SOURCE_HDTX_CAR, val);
21  }
22  
23 -static void cdns_dp_mode_set(struct cdns_mhdp_device *mhdp,
24 -                       const struct drm_display_mode *mode)
25 +static void cdns_dp_mode_set(struct cdns_mhdp_device *mhdp)
26  {
27         u32 lane_mapping = mhdp->lane_mapping;
28         struct drm_dp_link *link = &mhdp->dp.link;
29         char linkid[6];
30         int ret;
31  
32 -       memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
33 +       cdns_mhdp_plat_call(mhdp, pclk_rate);
34  
35 -       dp_pixel_clk_reset(mhdp);
36 +       /* delay for DP FW stable after pixel clock relock */
37 +       msleep(50);
38  
39 -       cdns_mhdp_plat_call(mhdp, pclk_rate);
40 +       dp_pixel_clk_reset(mhdp);
41  
42         ret = drm_dp_downstream_id(&mhdp->dp.aux, linkid);
43         if (ret < 0) {
44 @@ -330,11 +330,10 @@ static void cdns_dp_bridge_mode_set(stru
45         video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
46  
47         DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode->clock); 
48 +       memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
49  
50         mutex_lock(&mhdp->lock);
51 -
52 -       cdns_dp_mode_set(mhdp, mode);
53 -
54 +       cdns_dp_mode_set(mhdp);
55         mutex_unlock(&mhdp->lock);
56  }
57  
58 @@ -367,6 +366,11 @@ static void hotplug_work_func(struct wor
59         drm_helper_hpd_irq_event(connector->dev);
60  
61         if (connector->status == connector_status_connected) {
62 +               /* reset video mode after cable plugin */
63 +               mutex_lock(&mhdp->lock);
64 +               cdns_dp_mode_set(mhdp);
65 +               mutex_unlock(&mhdp->lock);
66 +
67                 DRM_INFO("HDMI/DP Cable Plug In\n");
68                 enable_irq(mhdp->irq[IRQ_OUT]);
69         } else if (connector->status == connector_status_disconnected) {
70 --- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
71 +++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
72 @@ -11,11 +11,11 @@
73   */
74  #include <drm/bridge/cdns-mhdp-common.h>
75  #include <drm/drm_atomic_helper.h>
76 -#include <drm/drm_crtc_helper.h>
77  #include <drm/drm_edid.h>
78  #include <drm/drm_encoder_slave.h>
79  #include <drm/drm_of.h>
80  #include <drm/drm_probe_helper.h>
81 +#include <drm/drm_scdc_helper.h>
82  #include <drm/drmP.h>
83  #include <linux/delay.h>
84  #include <linux/err.h>
85 @@ -26,25 +26,30 @@
86  #include <linux/mutex.h>
87  #include <linux/of_device.h>
88  
89 -static int hdmi_sink_config(struct cdns_mhdp_device *mhdp)
90 +static void hdmi_sink_config(struct cdns_mhdp_device *mhdp)
91  {
92         struct drm_scdc *scdc = &mhdp->connector.base.display_info.hdmi.scdc;
93         u8 buff;
94 -       int ret;
95 +
96 +       /* check sink support SCDC or not */
97 +       if (scdc->supported != true) {
98 +               DRM_INFO("Sink Not Support SCDC\n");
99 +               return;
100 +       }
101  
102         if (mhdp->hdmi.char_rate > 340000) {
103                 /*
104                  * TMDS Character Rate above 340MHz should working in HDMI2.0
105                  * Enable scrambling and TMDS_Bit_Clock_Ratio
106                  */
107 -               buff = 3;
108 +               buff = SCDC_TMDS_BIT_CLOCK_RATIO_BY_40 | SCDC_SCRAMBLING_ENABLE;
109                 mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
110         } else  if (scdc->scrambling.low_rates) {
111                 /*
112                  * Enable scrambling and HDMI2.0 when scrambling capability of sink
113                  * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit
114                  */
115 -               buff = 1;
116 +               buff = SCDC_SCRAMBLING_ENABLE;
117                 mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
118         } else {
119                 /* Default work in HDMI1.4 */
120 @@ -53,8 +58,7 @@ static int hdmi_sink_config(struct cdns_
121          }
122  
123         /* TMDS config */
124 -       ret = cdns_hdmi_scdc_write(mhdp, 0x20, buff);
125 -       return ret;
126 +       cdns_hdmi_scdc_write(mhdp, 0x20, buff);
127  }
128  
129  static void hdmi_lanes_config(struct cdns_mhdp_device *mhdp)
130 @@ -142,7 +146,7 @@ static int hdmi_avi_info_set(struct cdns
131         return 0;
132  }
133  
134 -static int hdmi_vendor_info_set(struct cdns_mhdp_device *mhdp,
135 +static void hdmi_vendor_info_set(struct cdns_mhdp_device *mhdp,
136                                 struct drm_display_mode *mode)
137  {
138         struct hdmi_vendor_infoframe frame;
139 @@ -152,19 +156,18 @@ static int hdmi_vendor_info_set(struct c
140         /* Initialise vendor frame from DRM mode */
141         ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, &mhdp->connector.base, mode);
142         if (ret < 0) {
143 -               DRM_WARN("Unable to init vendor infoframe: %d\n", ret);
144 -               return -1;
145 +               DRM_INFO("No vendor infoframe\n");
146 +               return;
147         }
148  
149         ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
150         if (ret < 0) {
151                 DRM_WARN("Unable to pack vendor infoframe: %d\n", ret);
152 -               return -1;
153 +               return;
154         }
155  
156         buf[0] = 0;
157         cdns_mhdp_infoframe_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_VENDOR);
158 -       return 0;
159  }
160  
161  void cdns_hdmi_mode_set(struct cdns_mhdp_device *mhdp)
162 @@ -172,9 +175,16 @@ void cdns_hdmi_mode_set(struct cdns_mhdp
163         struct drm_display_mode *mode = &mhdp->mode;
164         int ret;
165  
166 -       ret = hdmi_sink_config(mhdp);
167 -       if (ret < 0)
168 -               DRM_DEBUG("%s failed\n", __func__);
169 +       hdmi_lanes_config(mhdp);
170 +
171 +       cdns_mhdp_plat_call(mhdp, pclk_rate);
172 +
173 +       /* delay for HDMI FW stable after pixel clock relock */
174 +       msleep(20);
175 +
176 +       cdns_mhdp_plat_call(mhdp, phy_set);
177 +
178 +       hdmi_sink_config(mhdp);
179  
180         ret = cdns_hdmi_ctrl_init(mhdp, mhdp->hdmi.hdmi_type, mhdp->hdmi.char_rate);
181         if (ret < 0) {
182 @@ -195,18 +205,13 @@ void cdns_hdmi_mode_set(struct cdns_mhdp
183         }
184  
185         /* vendor info frame is enable only  when HDMI1.4 4K mode */
186 -       ret = hdmi_vendor_info_set(mhdp, mode);
187 -       if (ret < 0)
188 -               DRM_WARN("Unable to configure Vendor infoframe\n");
189 +       hdmi_vendor_info_set(mhdp, mode);
190  
191         ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info);
192         if (ret < 0) {
193                 DRM_ERROR("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
194                 return;
195         }
196 -
197 -       /* wait HDMI PHY pixel clock stable */
198 -       msleep(50);
199  }
200  
201  static enum drm_connector_status
202 @@ -335,20 +340,11 @@ static void cdns_hdmi_bridge_mode_set(st
203         video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
204         video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
205  
206 -       mutex_lock(&mhdp->lock);
207 -
208         DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode->clock); 
209 -
210         memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
211  
212 -       hdmi_lanes_config(mhdp);
213 -
214 -       cdns_mhdp_plat_call(mhdp, pclk_rate);
215 -
216 -       cdns_mhdp_plat_call(mhdp, phy_set);
217 -
218 +       mutex_lock(&mhdp->lock);
219         cdns_hdmi_mode_set(mhdp);
220 -
221         mutex_unlock(&mhdp->lock);
222  }
223  
224 @@ -367,8 +363,11 @@ static void hotplug_work_func(struct wor
225         drm_helper_hpd_irq_event(connector->dev);
226  
227         if (connector->status == connector_status_connected) {
228 -               /* Cable Connected */
229                 DRM_INFO("HDMI Cable Plug In\n");
230 +               /* reset video mode after cable plugin */
231 +               mutex_lock(&mhdp->lock);
232 +               cdns_hdmi_mode_set(mhdp);
233 +               mutex_unlock(&mhdp->lock);
234                 enable_irq(mhdp->irq[IRQ_OUT]);
235         } else if (connector->status == connector_status_disconnected) {
236                 /* Cable Disconnedted  */