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