1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
4 */
5
6 #include "dp_panel.h"
7 #include "dp_reg.h"
8 #include "dp_utils.h"
9
10 #include <drm/drm_connector.h>
11 #include <drm/drm_edid.h>
12 #include <drm/drm_of.h>
13 #include <drm/drm_print.h>
14
15 #include <linux/io.h>
16
17 #define DP_INTF_CONFIG_DATABUS_WIDEN BIT(4)
18
19 #define DP_MAX_NUM_DP_LANES 4
20 #define DP_LINK_RATE_HBR2 540000 /* kbytes */
21
22 struct msm_dp_panel_private {
23 struct device *dev;
24 struct drm_device *drm_dev;
25 struct msm_dp_panel msm_dp_panel;
26 struct drm_dp_aux *aux;
27 struct msm_dp_link *link;
28 void __iomem *link_base;
29 void __iomem *p0_base;
30 bool panel_on;
31 };
32
msm_dp_read_link(struct msm_dp_panel_private * panel,u32 offset)33 static inline u32 msm_dp_read_link(struct msm_dp_panel_private *panel, u32 offset)
34 {
35 return readl_relaxed(panel->link_base + offset);
36 }
37
msm_dp_write_link(struct msm_dp_panel_private * panel,u32 offset,u32 data)38 static inline void msm_dp_write_link(struct msm_dp_panel_private *panel,
39 u32 offset, u32 data)
40 {
41 /*
42 * To make sure link reg writes happens before any other operation,
43 * this function uses writel() instread of writel_relaxed()
44 */
45 writel(data, panel->link_base + offset);
46 }
47
msm_dp_write_p0(struct msm_dp_panel_private * panel,u32 offset,u32 data)48 static inline void msm_dp_write_p0(struct msm_dp_panel_private *panel,
49 u32 offset, u32 data)
50 {
51 /*
52 * To make sure interface reg writes happens before any other operation,
53 * this function uses writel() instread of writel_relaxed()
54 */
55 writel(data, panel->p0_base + offset);
56 }
57
msm_dp_read_p0(struct msm_dp_panel_private * panel,u32 offset)58 static inline u32 msm_dp_read_p0(struct msm_dp_panel_private *panel,
59 u32 offset)
60 {
61 /*
62 * To make sure interface reg writes happens before any other operation,
63 * this function uses writel() instread of writel_relaxed()
64 */
65 return readl_relaxed(panel->p0_base + offset);
66 }
67
msm_dp_panel_read_psr_cap(struct msm_dp_panel_private * panel)68 static void msm_dp_panel_read_psr_cap(struct msm_dp_panel_private *panel)
69 {
70 ssize_t rlen;
71 struct msm_dp_panel *msm_dp_panel;
72
73 msm_dp_panel = &panel->msm_dp_panel;
74
75 /* edp sink */
76 if (msm_dp_panel->dpcd[DP_EDP_CONFIGURATION_CAP]) {
77 rlen = drm_dp_dpcd_read(panel->aux, DP_PSR_SUPPORT,
78 &msm_dp_panel->psr_cap, sizeof(msm_dp_panel->psr_cap));
79 if (rlen == sizeof(msm_dp_panel->psr_cap)) {
80 drm_dbg_dp(panel->drm_dev,
81 "psr version: 0x%x, psr_cap: 0x%x\n",
82 msm_dp_panel->psr_cap.version,
83 msm_dp_panel->psr_cap.capabilities);
84 } else
85 DRM_ERROR("failed to read psr info, rlen=%zd\n", rlen);
86 }
87 }
88
msm_dp_panel_read_dpcd(struct msm_dp_panel * msm_dp_panel)89 static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
90 {
91 int rc, max_lttpr_lanes, max_lttpr_rate;
92 struct msm_dp_panel_private *panel;
93 struct msm_dp_link_info *link_info;
94 u8 *dpcd, major, minor;
95
96 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
97 dpcd = msm_dp_panel->dpcd;
98 rc = drm_dp_read_dpcd_caps(panel->aux, dpcd);
99 if (rc)
100 return rc;
101
102 msm_dp_panel->vsc_sdp_supported = drm_dp_vsc_sdp_supported(panel->aux, dpcd);
103 link_info = &msm_dp_panel->link_info;
104 link_info->revision = dpcd[DP_DPCD_REV];
105 major = (link_info->revision >> 4) & 0x0f;
106 minor = link_info->revision & 0x0f;
107
108 link_info->rate = drm_dp_max_link_rate(dpcd);
109 link_info->num_lanes = drm_dp_max_lane_count(dpcd);
110
111 /* Limit data lanes from data-lanes of endpoint property of dtsi */
112 if (link_info->num_lanes > msm_dp_panel->max_dp_lanes)
113 link_info->num_lanes = msm_dp_panel->max_dp_lanes;
114
115 /* Limit link rate from link-frequencies of endpoint property of dtsi */
116 if (link_info->rate > msm_dp_panel->max_dp_link_rate)
117 link_info->rate = msm_dp_panel->max_dp_link_rate;
118
119 /* Limit data lanes from LTTPR capabilities, if any */
120 max_lttpr_lanes = drm_dp_lttpr_max_lane_count(panel->link->lttpr_common_caps);
121 if (max_lttpr_lanes && max_lttpr_lanes < link_info->num_lanes)
122 link_info->num_lanes = max_lttpr_lanes;
123
124 /* Limit link rate from LTTPR capabilities, if any */
125 max_lttpr_rate = drm_dp_lttpr_max_link_rate(panel->link->lttpr_common_caps);
126 if (max_lttpr_rate && max_lttpr_rate < link_info->rate)
127 link_info->rate = max_lttpr_rate;
128
129 drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);
130 drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);
131 drm_dbg_dp(panel->drm_dev, "lane_count=%d\n", link_info->num_lanes);
132
133 if (drm_dp_enhanced_frame_cap(dpcd))
134 link_info->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
135
136 msm_dp_panel_read_psr_cap(panel);
137
138 return rc;
139 }
140
msm_dp_panel_get_supported_bpp(struct msm_dp_panel * msm_dp_panel,u32 mode_edid_bpp,u32 mode_pclk_khz)141 static u32 msm_dp_panel_get_supported_bpp(struct msm_dp_panel *msm_dp_panel,
142 u32 mode_edid_bpp, u32 mode_pclk_khz)
143 {
144 const struct msm_dp_link_info *link_info;
145 const u32 max_supported_bpp = 30, min_supported_bpp = 18;
146 u32 bpp, data_rate_khz;
147
148 bpp = min(mode_edid_bpp, max_supported_bpp);
149
150 link_info = &msm_dp_panel->link_info;
151 data_rate_khz = link_info->num_lanes * link_info->rate * 8;
152
153 do {
154 if (mode_pclk_khz * bpp <= data_rate_khz)
155 return bpp;
156 bpp -= 6;
157 } while (bpp > min_supported_bpp);
158
159 return min_supported_bpp;
160 }
161
msm_dp_panel_read_sink_caps(struct msm_dp_panel * msm_dp_panel,struct drm_connector * connector)162 int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
163 struct drm_connector *connector)
164 {
165 int rc, bw_code;
166 int count;
167 struct msm_dp_panel_private *panel;
168
169 if (!msm_dp_panel || !connector) {
170 DRM_ERROR("invalid input\n");
171 return -EINVAL;
172 }
173
174 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
175
176 drm_dbg_dp(panel->drm_dev, "max_lanes=%d max_link_rate=%d\n",
177 msm_dp_panel->max_dp_lanes, msm_dp_panel->max_dp_link_rate);
178
179 rc = msm_dp_panel_read_dpcd(msm_dp_panel);
180 if (rc) {
181 DRM_ERROR("read dpcd failed %d\n", rc);
182 return rc;
183 }
184
185 bw_code = drm_dp_link_rate_to_bw_code(msm_dp_panel->link_info.rate);
186 if (!is_link_rate_valid(bw_code) ||
187 !is_lane_count_valid(msm_dp_panel->link_info.num_lanes) ||
188 (bw_code > msm_dp_panel->max_bw_code)) {
189 DRM_ERROR("Illegal link rate=%d lane=%d\n", msm_dp_panel->link_info.rate,
190 msm_dp_panel->link_info.num_lanes);
191 return -EINVAL;
192 }
193
194 if (drm_dp_is_branch(msm_dp_panel->dpcd)) {
195 count = drm_dp_read_sink_count(panel->aux);
196 if (!count) {
197 panel->link->sink_count = 0;
198 return -ENOTCONN;
199 }
200 }
201
202 rc = drm_dp_read_downstream_info(panel->aux, msm_dp_panel->dpcd,
203 msm_dp_panel->downstream_ports);
204 if (rc)
205 return rc;
206
207 drm_edid_free(msm_dp_panel->drm_edid);
208
209 msm_dp_panel->drm_edid = drm_edid_read_ddc(connector, &panel->aux->ddc);
210
211 drm_edid_connector_update(connector, msm_dp_panel->drm_edid);
212
213 if (!msm_dp_panel->drm_edid) {
214 DRM_ERROR("panel edid read failed\n");
215 /* check edid read fail is due to unplug */
216 if (!msm_dp_aux_is_link_connected(panel->aux)) {
217 rc = -ETIMEDOUT;
218 goto end;
219 }
220 }
221
222 end:
223 return rc;
224 }
225
msm_dp_panel_get_mode_bpp(struct msm_dp_panel * msm_dp_panel,u32 mode_edid_bpp,u32 mode_pclk_khz)226 u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,
227 u32 mode_edid_bpp, u32 mode_pclk_khz)
228 {
229 struct msm_dp_panel_private *panel;
230 u32 bpp;
231
232 if (!msm_dp_panel || !mode_edid_bpp || !mode_pclk_khz) {
233 DRM_ERROR("invalid input\n");
234 return 0;
235 }
236
237 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
238
239 if (msm_dp_panel->video_test)
240 bpp = msm_dp_link_bit_depth_to_bpp(
241 panel->link->test_video.test_bit_depth);
242 else
243 bpp = msm_dp_panel_get_supported_bpp(msm_dp_panel, mode_edid_bpp,
244 mode_pclk_khz);
245
246 return bpp;
247 }
248
msm_dp_panel_get_modes(struct msm_dp_panel * msm_dp_panel,struct drm_connector * connector)249 int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
250 struct drm_connector *connector)
251 {
252 if (!msm_dp_panel) {
253 DRM_ERROR("invalid input\n");
254 return -EINVAL;
255 }
256
257 if (msm_dp_panel->drm_edid)
258 return drm_edid_connector_add_modes(connector);
259
260 return 0;
261 }
262
msm_dp_panel_get_edid_checksum(const struct edid * edid)263 static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid)
264 {
265 edid += edid->extensions;
266
267 return edid->checksum;
268 }
269
msm_dp_panel_handle_sink_request(struct msm_dp_panel * msm_dp_panel)270 void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel)
271 {
272 struct msm_dp_panel_private *panel;
273
274 if (!msm_dp_panel) {
275 DRM_ERROR("invalid input\n");
276 return;
277 }
278
279 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
280
281 if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) {
282 /* FIXME: get rid of drm_edid_raw() */
283 const struct edid *edid = drm_edid_raw(msm_dp_panel->drm_edid);
284 u8 checksum;
285
286 if (edid)
287 checksum = msm_dp_panel_get_edid_checksum(edid);
288 else
289 checksum = msm_dp_panel->connector->real_edid_checksum;
290
291 msm_dp_link_send_edid_checksum(panel->link, checksum);
292 msm_dp_link_send_test_response(panel->link);
293 }
294 }
295
msm_dp_panel_tpg_enable(struct msm_dp_panel * msm_dp_panel,struct drm_display_mode * drm_mode)296 static void msm_dp_panel_tpg_enable(struct msm_dp_panel *msm_dp_panel,
297 struct drm_display_mode *drm_mode)
298 {
299 struct msm_dp_panel_private *panel =
300 container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
301 u32 hsync_period, vsync_period;
302 u32 display_v_start, display_v_end;
303 u32 hsync_start_x, hsync_end_x;
304 u32 v_sync_width;
305 u32 hsync_ctl;
306 u32 display_hctl;
307
308 /* TPG config parameters*/
309 hsync_period = drm_mode->htotal;
310 vsync_period = drm_mode->vtotal;
311
312 display_v_start = ((drm_mode->vtotal - drm_mode->vsync_start) *
313 hsync_period);
314 display_v_end = ((vsync_period - (drm_mode->vsync_start -
315 drm_mode->vdisplay))
316 * hsync_period) - 1;
317
318 display_v_start += drm_mode->htotal - drm_mode->hsync_start;
319 display_v_end -= (drm_mode->hsync_start - drm_mode->hdisplay);
320
321 hsync_start_x = drm_mode->htotal - drm_mode->hsync_start;
322 hsync_end_x = hsync_period - (drm_mode->hsync_start -
323 drm_mode->hdisplay) - 1;
324
325 v_sync_width = drm_mode->vsync_end - drm_mode->vsync_start;
326
327 hsync_ctl = (hsync_period << 16) |
328 (drm_mode->hsync_end - drm_mode->hsync_start);
329 display_hctl = (hsync_end_x << 16) | hsync_start_x;
330
331
332 msm_dp_write_p0(panel, MMSS_DP_INTF_HSYNC_CTL, hsync_ctl);
333 msm_dp_write_p0(panel, MMSS_DP_INTF_VSYNC_PERIOD_F0, vsync_period *
334 hsync_period);
335 msm_dp_write_p0(panel, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0, v_sync_width *
336 hsync_period);
337 msm_dp_write_p0(panel, MMSS_DP_INTF_VSYNC_PERIOD_F1, 0);
338 msm_dp_write_p0(panel, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1, 0);
339 msm_dp_write_p0(panel, MMSS_DP_INTF_DISPLAY_HCTL, display_hctl);
340 msm_dp_write_p0(panel, MMSS_DP_INTF_ACTIVE_HCTL, 0);
341 msm_dp_write_p0(panel, MMSS_INTF_DISPLAY_V_START_F0, display_v_start);
342 msm_dp_write_p0(panel, MMSS_DP_INTF_DISPLAY_V_END_F0, display_v_end);
343 msm_dp_write_p0(panel, MMSS_INTF_DISPLAY_V_START_F1, 0);
344 msm_dp_write_p0(panel, MMSS_DP_INTF_DISPLAY_V_END_F1, 0);
345 msm_dp_write_p0(panel, MMSS_DP_INTF_ACTIVE_V_START_F0, 0);
346 msm_dp_write_p0(panel, MMSS_DP_INTF_ACTIVE_V_END_F0, 0);
347 msm_dp_write_p0(panel, MMSS_DP_INTF_ACTIVE_V_START_F1, 0);
348 msm_dp_write_p0(panel, MMSS_DP_INTF_ACTIVE_V_END_F1, 0);
349 msm_dp_write_p0(panel, MMSS_DP_INTF_POLARITY_CTL, 0);
350
351 msm_dp_write_p0(panel, MMSS_DP_TPG_MAIN_CONTROL,
352 DP_TPG_CHECKERED_RECT_PATTERN);
353 msm_dp_write_p0(panel, MMSS_DP_TPG_VIDEO_CONFIG,
354 DP_TPG_VIDEO_CONFIG_BPP_8BIT |
355 DP_TPG_VIDEO_CONFIG_RGB);
356 msm_dp_write_p0(panel, MMSS_DP_BIST_ENABLE,
357 DP_BIST_ENABLE_DPBIST_EN);
358 msm_dp_write_p0(panel, MMSS_DP_TIMING_ENGINE_EN,
359 DP_TIMING_ENGINE_EN_EN);
360 drm_dbg_dp(panel->drm_dev, "%s: enabled tpg\n", __func__);
361 }
362
msm_dp_panel_tpg_disable(struct msm_dp_panel * msm_dp_panel)363 static void msm_dp_panel_tpg_disable(struct msm_dp_panel *msm_dp_panel)
364 {
365 struct msm_dp_panel_private *panel =
366 container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
367
368 msm_dp_write_p0(panel, MMSS_DP_TPG_MAIN_CONTROL, 0x0);
369 msm_dp_write_p0(panel, MMSS_DP_BIST_ENABLE, 0x0);
370 msm_dp_write_p0(panel, MMSS_DP_TIMING_ENGINE_EN, 0x0);
371 }
372
msm_dp_panel_tpg_config(struct msm_dp_panel * msm_dp_panel,bool enable)373 void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable)
374 {
375 struct msm_dp_panel_private *panel;
376
377 if (!msm_dp_panel) {
378 DRM_ERROR("invalid input\n");
379 return;
380 }
381
382 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
383
384 if (!panel->panel_on) {
385 drm_dbg_dp(panel->drm_dev,
386 "DP panel not enabled, handle TPG on next on\n");
387 return;
388 }
389
390 if (!enable) {
391 msm_dp_panel_tpg_disable(msm_dp_panel);
392 return;
393 }
394
395 drm_dbg_dp(panel->drm_dev, "calling panel's tpg_enable\n");
396 msm_dp_panel_tpg_enable(msm_dp_panel, &panel->msm_dp_panel.msm_dp_mode.drm_mode);
397 }
398
msm_dp_panel_clear_dsc_dto(struct msm_dp_panel * msm_dp_panel)399 void msm_dp_panel_clear_dsc_dto(struct msm_dp_panel *msm_dp_panel)
400 {
401 struct msm_dp_panel_private *panel =
402 container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
403
404 msm_dp_write_p0(panel, MMSS_DP_DSC_DTO, 0x0);
405 }
406
msm_dp_panel_send_vsc_sdp(struct msm_dp_panel_private * panel,struct dp_sdp * vsc_sdp)407 static void msm_dp_panel_send_vsc_sdp(struct msm_dp_panel_private *panel, struct dp_sdp *vsc_sdp)
408 {
409 u32 header[2];
410 u32 val;
411 int i;
412
413 msm_dp_utils_pack_sdp_header(&vsc_sdp->sdp_header, header);
414
415 msm_dp_write_link(panel, MMSS_DP_GENERIC0_0, header[0]);
416 msm_dp_write_link(panel, MMSS_DP_GENERIC0_1, header[1]);
417
418 for (i = 0; i < sizeof(vsc_sdp->db); i += 4) {
419 val = ((vsc_sdp->db[i]) | (vsc_sdp->db[i + 1] << 8) | (vsc_sdp->db[i + 2] << 16) |
420 (vsc_sdp->db[i + 3] << 24));
421 msm_dp_write_link(panel, MMSS_DP_GENERIC0_2 + i, val);
422 }
423 }
424
msm_dp_panel_update_sdp(struct msm_dp_panel_private * panel)425 static void msm_dp_panel_update_sdp(struct msm_dp_panel_private *panel)
426 {
427 u32 hw_revision = panel->msm_dp_panel.hw_revision;
428
429 if (hw_revision >= DP_HW_VERSION_1_0 &&
430 hw_revision < DP_HW_VERSION_1_2) {
431 msm_dp_write_link(panel, MMSS_DP_SDP_CFG3, UPDATE_SDP);
432 msm_dp_write_link(panel, MMSS_DP_SDP_CFG3, 0x0);
433 }
434 }
435
msm_dp_panel_enable_vsc_sdp(struct msm_dp_panel * msm_dp_panel,struct dp_sdp * vsc_sdp)436 void msm_dp_panel_enable_vsc_sdp(struct msm_dp_panel *msm_dp_panel, struct dp_sdp *vsc_sdp)
437 {
438 struct msm_dp_panel_private *panel =
439 container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
440 u32 cfg, cfg2, misc;
441
442 cfg = msm_dp_read_link(panel, MMSS_DP_SDP_CFG);
443 cfg2 = msm_dp_read_link(panel, MMSS_DP_SDP_CFG2);
444 misc = msm_dp_read_link(panel, REG_DP_MISC1_MISC0);
445
446 cfg |= GEN0_SDP_EN;
447 msm_dp_write_link(panel, MMSS_DP_SDP_CFG, cfg);
448
449 cfg2 |= GENERIC0_SDPSIZE_VALID;
450 msm_dp_write_link(panel, MMSS_DP_SDP_CFG2, cfg2);
451
452 msm_dp_panel_send_vsc_sdp(panel, vsc_sdp);
453
454 /* indicates presence of VSC (BIT(6) of MISC1) */
455 misc |= DP_MISC1_VSC_SDP;
456
457 drm_dbg_dp(panel->drm_dev, "vsc sdp enable=1\n");
458
459 pr_debug("misc settings = 0x%x\n", misc);
460 msm_dp_write_link(panel, REG_DP_MISC1_MISC0, misc);
461
462 msm_dp_panel_update_sdp(panel);
463 }
464
msm_dp_panel_disable_vsc_sdp(struct msm_dp_panel * msm_dp_panel)465 void msm_dp_panel_disable_vsc_sdp(struct msm_dp_panel *msm_dp_panel)
466 {
467 struct msm_dp_panel_private *panel =
468 container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
469 u32 cfg, cfg2, misc;
470
471 cfg = msm_dp_read_link(panel, MMSS_DP_SDP_CFG);
472 cfg2 = msm_dp_read_link(panel, MMSS_DP_SDP_CFG2);
473 misc = msm_dp_read_link(panel, REG_DP_MISC1_MISC0);
474
475 cfg &= ~GEN0_SDP_EN;
476 msm_dp_write_link(panel, MMSS_DP_SDP_CFG, cfg);
477
478 cfg2 &= ~GENERIC0_SDPSIZE_VALID;
479 msm_dp_write_link(panel, MMSS_DP_SDP_CFG2, cfg2);
480
481 /* switch back to MSA */
482 misc &= ~DP_MISC1_VSC_SDP;
483
484 drm_dbg_dp(panel->drm_dev, "vsc sdp enable=0\n");
485
486 pr_debug("misc settings = 0x%x\n", misc);
487 msm_dp_write_link(panel, REG_DP_MISC1_MISC0, misc);
488
489 msm_dp_panel_update_sdp(panel);
490 }
491
msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel * msm_dp_panel)492 static int msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel *msm_dp_panel)
493 {
494 struct msm_dp_display_mode *msm_dp_mode;
495 struct drm_dp_vsc_sdp vsc_sdp_data;
496 struct dp_sdp vsc_sdp;
497 ssize_t len;
498
499 if (!msm_dp_panel) {
500 DRM_ERROR("invalid input\n");
501 return -EINVAL;
502 }
503
504 msm_dp_mode = &msm_dp_panel->msm_dp_mode;
505
506 memset(&vsc_sdp_data, 0, sizeof(vsc_sdp_data));
507
508 /* VSC SDP header as per table 2-118 of DP 1.4 specification */
509 vsc_sdp_data.sdp_type = DP_SDP_VSC;
510 vsc_sdp_data.revision = 0x05;
511 vsc_sdp_data.length = 0x13;
512
513 /* VSC SDP Payload for DB16 */
514 vsc_sdp_data.pixelformat = DP_PIXELFORMAT_YUV420;
515 vsc_sdp_data.colorimetry = DP_COLORIMETRY_DEFAULT;
516
517 /* VSC SDP Payload for DB17 */
518 vsc_sdp_data.bpc = msm_dp_mode->bpp / 3;
519 vsc_sdp_data.dynamic_range = DP_DYNAMIC_RANGE_CTA;
520
521 /* VSC SDP Payload for DB18 */
522 vsc_sdp_data.content_type = DP_CONTENT_TYPE_GRAPHICS;
523
524 len = drm_dp_vsc_sdp_pack(&vsc_sdp_data, &vsc_sdp);
525 if (len < 0) {
526 DRM_ERROR("unable to pack vsc sdp\n");
527 return len;
528 }
529
530 msm_dp_panel_enable_vsc_sdp(msm_dp_panel, &vsc_sdp);
531
532 return 0;
533 }
534
msm_dp_panel_timing_cfg(struct msm_dp_panel * msm_dp_panel,bool wide_bus_en)535 int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel, bool wide_bus_en)
536 {
537 u32 data, total_ver, total_hor;
538 struct msm_dp_panel_private *panel;
539 struct drm_display_mode *drm_mode;
540 u32 width_blanking;
541 u32 sync_start;
542 u32 msm_dp_active;
543 u32 total;
544 u32 reg;
545
546 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
547 drm_mode = &panel->msm_dp_panel.msm_dp_mode.drm_mode;
548
549 drm_dbg_dp(panel->drm_dev, "width=%d hporch= %d %d %d\n",
550 drm_mode->hdisplay, drm_mode->htotal - drm_mode->hsync_end,
551 drm_mode->hsync_start - drm_mode->hdisplay,
552 drm_mode->hsync_end - drm_mode->hsync_start);
553
554 drm_dbg_dp(panel->drm_dev, "height=%d vporch= %d %d %d\n",
555 drm_mode->vdisplay, drm_mode->vtotal - drm_mode->vsync_end,
556 drm_mode->vsync_start - drm_mode->vdisplay,
557 drm_mode->vsync_end - drm_mode->vsync_start);
558
559 total_hor = drm_mode->htotal;
560
561 total_ver = drm_mode->vtotal;
562
563 data = total_ver;
564 data <<= 16;
565 data |= total_hor;
566
567 total = data;
568
569 data = (drm_mode->vtotal - drm_mode->vsync_start);
570 data <<= 16;
571 data |= (drm_mode->htotal - drm_mode->hsync_start);
572
573 sync_start = data;
574
575 data = drm_mode->vsync_end - drm_mode->vsync_start;
576 data <<= 16;
577 data |= (panel->msm_dp_panel.msm_dp_mode.v_active_low << 31);
578 data |= drm_mode->hsync_end - drm_mode->hsync_start;
579 data |= (panel->msm_dp_panel.msm_dp_mode.h_active_low << 15);
580
581 width_blanking = data;
582
583 data = drm_mode->vdisplay;
584 data <<= 16;
585 data |= drm_mode->hdisplay;
586
587 msm_dp_active = data;
588
589 msm_dp_write_link(panel, REG_DP_TOTAL_HOR_VER, total);
590 msm_dp_write_link(panel, REG_DP_START_HOR_VER_FROM_SYNC, sync_start);
591 msm_dp_write_link(panel, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, width_blanking);
592 msm_dp_write_link(panel, REG_DP_ACTIVE_HOR_VER, msm_dp_active);
593
594 reg = msm_dp_read_p0(panel, MMSS_DP_INTF_CONFIG);
595 if (wide_bus_en)
596 reg |= DP_INTF_CONFIG_DATABUS_WIDEN;
597 else
598 reg &= ~DP_INTF_CONFIG_DATABUS_WIDEN;
599
600 drm_dbg_dp(panel->drm_dev, "wide_bus_en=%d reg=%#x\n", wide_bus_en, reg);
601
602 msm_dp_write_p0(panel, MMSS_DP_INTF_CONFIG, reg);
603
604 if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
605 msm_dp_panel_setup_vsc_sdp_yuv_420(msm_dp_panel);
606
607 panel->panel_on = true;
608
609 return 0;
610 }
611
msm_dp_panel_init_panel_info(struct msm_dp_panel * msm_dp_panel)612 int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel)
613 {
614 struct drm_display_mode *drm_mode;
615 struct msm_dp_panel_private *panel;
616
617 drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode;
618
619 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
620
621 /*
622 * print resolution info as this is a result
623 * of user initiated action of cable connection
624 */
625 drm_dbg_dp(panel->drm_dev, "SET NEW RESOLUTION:\n");
626 drm_dbg_dp(panel->drm_dev, "%dx%d@%dfps\n",
627 drm_mode->hdisplay, drm_mode->vdisplay, drm_mode_vrefresh(drm_mode));
628 drm_dbg_dp(panel->drm_dev,
629 "h_porches(back|front|width) = (%d|%d|%d)\n",
630 drm_mode->htotal - drm_mode->hsync_end,
631 drm_mode->hsync_start - drm_mode->hdisplay,
632 drm_mode->hsync_end - drm_mode->hsync_start);
633 drm_dbg_dp(panel->drm_dev,
634 "v_porches(back|front|width) = (%d|%d|%d)\n",
635 drm_mode->vtotal - drm_mode->vsync_end,
636 drm_mode->vsync_start - drm_mode->vdisplay,
637 drm_mode->vsync_end - drm_mode->vsync_start);
638 drm_dbg_dp(panel->drm_dev, "pixel clock (KHz)=(%d)\n",
639 drm_mode->clock);
640 drm_dbg_dp(panel->drm_dev, "bpp = %d\n", msm_dp_panel->msm_dp_mode.bpp);
641
642 msm_dp_panel->msm_dp_mode.bpp = msm_dp_panel_get_mode_bpp(msm_dp_panel, msm_dp_panel->msm_dp_mode.bpp,
643 msm_dp_panel->msm_dp_mode.drm_mode.clock);
644
645 drm_dbg_dp(panel->drm_dev, "updated bpp = %d\n",
646 msm_dp_panel->msm_dp_mode.bpp);
647
648 return 0;
649 }
650
msm_dp_panel_link_frequencies(struct device_node * of_node)651 static u32 msm_dp_panel_link_frequencies(struct device_node *of_node)
652 {
653 struct device_node *endpoint;
654 u64 frequency = 0;
655 int cnt;
656
657 endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port@1 */
658 if (!endpoint)
659 return 0;
660
661 cnt = of_property_count_u64_elems(endpoint, "link-frequencies");
662
663 if (cnt > 0)
664 of_property_read_u64_index(endpoint, "link-frequencies",
665 cnt - 1, &frequency);
666 of_node_put(endpoint);
667
668 do_div(frequency,
669 10 * /* from symbol rate to link rate */
670 1000); /* kbytes */
671
672 return frequency;
673 }
674
msm_dp_panel_parse_dt(struct msm_dp_panel * msm_dp_panel)675 static int msm_dp_panel_parse_dt(struct msm_dp_panel *msm_dp_panel)
676 {
677 struct msm_dp_panel_private *panel;
678 struct device_node *of_node;
679 int cnt;
680
681 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
682 of_node = panel->dev->of_node;
683
684 /*
685 * data-lanes is the property of msm_dp_out endpoint
686 */
687 cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
688 if (cnt < 0) {
689 /* legacy code, data-lanes is the property of mdss_dp node */
690 cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
691 }
692
693 if (cnt > 0)
694 msm_dp_panel->max_dp_lanes = cnt;
695 else
696 msm_dp_panel->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
697
698 msm_dp_panel->max_dp_link_rate = msm_dp_panel_link_frequencies(of_node);
699 if (!msm_dp_panel->max_dp_link_rate)
700 msm_dp_panel->max_dp_link_rate = DP_LINK_RATE_HBR2;
701
702 return 0;
703 }
704
msm_dp_panel_get(struct device * dev,struct drm_dp_aux * aux,struct msm_dp_link * link,void __iomem * link_base,void __iomem * p0_base)705 struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux,
706 struct msm_dp_link *link,
707 void __iomem *link_base,
708 void __iomem *p0_base)
709 {
710 struct msm_dp_panel_private *panel;
711 struct msm_dp_panel *msm_dp_panel;
712 int ret;
713
714 if (!dev || !aux || !link) {
715 DRM_ERROR("invalid input\n");
716 return ERR_PTR(-EINVAL);
717 }
718
719 panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
720 if (!panel)
721 return ERR_PTR(-ENOMEM);
722
723 panel->dev = dev;
724 panel->aux = aux;
725 panel->link = link;
726 panel->link_base = link_base;
727 panel->p0_base = p0_base;
728
729 msm_dp_panel = &panel->msm_dp_panel;
730 msm_dp_panel->max_bw_code = DP_LINK_BW_8_1;
731
732 ret = msm_dp_panel_parse_dt(msm_dp_panel);
733 if (ret)
734 return ERR_PTR(ret);
735
736 return msm_dp_panel;
737 }
738
msm_dp_panel_put(struct msm_dp_panel * msm_dp_panel)739 void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel)
740 {
741 if (!msm_dp_panel)
742 return;
743
744 drm_edid_free(msm_dp_panel->drm_edid);
745 }
746