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 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 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 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 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 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 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 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 235 int msm_dp_panel_read_sink_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 if (rc) 275 return rc; 276 277 drm_edid_free(msm_dp_panel->drm_edid); 278 279 msm_dp_panel->drm_edid = drm_edid_read_ddc(connector, &panel->aux->ddc); 280 281 drm_edid_connector_update(connector, msm_dp_panel->drm_edid); 282 283 if (!msm_dp_panel->drm_edid) { 284 DRM_ERROR("panel edid read failed\n"); 285 /* check edid read fail is due to unplug */ 286 if (!msm_dp_aux_is_link_connected(panel->aux)) { 287 rc = -ETIMEDOUT; 288 goto end; 289 } 290 } 291 292 end: 293 return rc; 294 } 295 296 u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, 297 u32 mode_edid_bpp, u32 mode_pclk_khz) 298 { 299 struct msm_dp_panel_private *panel; 300 u32 bpp; 301 302 if (!msm_dp_panel || !mode_edid_bpp || !mode_pclk_khz) { 303 DRM_ERROR("invalid input\n"); 304 return 0; 305 } 306 307 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel); 308 309 if (msm_dp_panel->video_test) 310 bpp = msm_dp_link_bit_depth_to_bpp( 311 panel->link->test_video.test_bit_depth); 312 else 313 bpp = msm_dp_panel_get_supported_bpp(msm_dp_panel, mode_edid_bpp, 314 mode_pclk_khz); 315 316 return bpp; 317 } 318 319 int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel, 320 struct drm_connector *connector) 321 { 322 if (!msm_dp_panel) { 323 DRM_ERROR("invalid input\n"); 324 return -EINVAL; 325 } 326 327 if (msm_dp_panel->drm_edid) 328 return drm_edid_connector_add_modes(connector); 329 330 return 0; 331 } 332 333 static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid) 334 { 335 edid += edid->extensions; 336 337 return edid->checksum; 338 } 339 340 void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel) 341 { 342 struct msm_dp_panel_private *panel; 343 344 if (!msm_dp_panel) { 345 DRM_ERROR("invalid input\n"); 346 return; 347 } 348 349 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel); 350 351 if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) { 352 /* FIXME: get rid of drm_edid_raw() */ 353 const struct edid *edid = drm_edid_raw(msm_dp_panel->drm_edid); 354 u8 checksum; 355 356 if (edid) 357 checksum = msm_dp_panel_get_edid_checksum(edid); 358 else 359 checksum = msm_dp_panel->connector->real_edid_checksum; 360 361 msm_dp_link_send_edid_checksum(panel->link, checksum); 362 msm_dp_link_send_test_response(panel->link); 363 } 364 } 365 366 static void msm_dp_panel_tpg_enable(struct msm_dp_panel *msm_dp_panel, 367 struct drm_display_mode *drm_mode) 368 { 369 struct msm_dp_panel_private *panel = 370 container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel); 371 u32 hsync_period, vsync_period; 372 u32 display_v_start, display_v_end; 373 u32 hsync_start_x, hsync_end_x; 374 u32 v_sync_width; 375 u32 hsync_ctl; 376 u32 display_hctl; 377 378 /* TPG config parameters*/ 379 hsync_period = drm_mode->htotal; 380 vsync_period = drm_mode->vtotal; 381 382 display_v_start = ((drm_mode->vtotal - drm_mode->vsync_start) * 383 hsync_period); 384 display_v_end = ((vsync_period - (drm_mode->vsync_start - 385 drm_mode->vdisplay)) 386 * hsync_period) - 1; 387 388 display_v_start += drm_mode->htotal - drm_mode->hsync_start; 389 display_v_end -= (drm_mode->hsync_start - drm_mode->hdisplay); 390 391 hsync_start_x = drm_mode->htotal - drm_mode->hsync_start; 392 hsync_end_x = hsync_period - (drm_mode->hsync_start - 393 drm_mode->hdisplay) - 1; 394 395 v_sync_width = drm_mode->vsync_end - drm_mode->vsync_start; 396 397 hsync_ctl = (hsync_period << 16) | 398 (drm_mode->hsync_end - drm_mode->hsync_start); 399 display_hctl = (hsync_end_x << 16) | hsync_start_x; 400 401 402 msm_dp_write_p0(panel, MMSS_DP_INTF_HSYNC_CTL, hsync_ctl); 403 msm_dp_write_p0(panel, MMSS_DP_INTF_VSYNC_PERIOD_F0, vsync_period * 404 hsync_period); 405 msm_dp_write_p0(panel, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0, v_sync_width * 406 hsync_period); 407 msm_dp_write_p0(panel, MMSS_DP_INTF_VSYNC_PERIOD_F1, 0); 408 msm_dp_write_p0(panel, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1, 0); 409 msm_dp_write_p0(panel, MMSS_DP_INTF_DISPLAY_HCTL, display_hctl); 410 msm_dp_write_p0(panel, MMSS_DP_INTF_ACTIVE_HCTL, 0); 411 msm_dp_write_p0(panel, MMSS_INTF_DISPLAY_V_START_F0, display_v_start); 412 msm_dp_write_p0(panel, MMSS_DP_INTF_DISPLAY_V_END_F0, display_v_end); 413 msm_dp_write_p0(panel, MMSS_INTF_DISPLAY_V_START_F1, 0); 414 msm_dp_write_p0(panel, MMSS_DP_INTF_DISPLAY_V_END_F1, 0); 415 msm_dp_write_p0(panel, MMSS_DP_INTF_ACTIVE_V_START_F0, 0); 416 msm_dp_write_p0(panel, MMSS_DP_INTF_ACTIVE_V_END_F0, 0); 417 msm_dp_write_p0(panel, MMSS_DP_INTF_ACTIVE_V_START_F1, 0); 418 msm_dp_write_p0(panel, MMSS_DP_INTF_ACTIVE_V_END_F1, 0); 419 msm_dp_write_p0(panel, MMSS_DP_INTF_POLARITY_CTL, 0); 420 421 msm_dp_write_p0(panel, MMSS_DP_TPG_MAIN_CONTROL, 422 DP_TPG_CHECKERED_RECT_PATTERN); 423 msm_dp_write_p0(panel, MMSS_DP_TPG_VIDEO_CONFIG, 424 DP_TPG_VIDEO_CONFIG_BPP_8BIT | 425 DP_TPG_VIDEO_CONFIG_RGB); 426 msm_dp_write_p0(panel, MMSS_DP_BIST_ENABLE, 427 DP_BIST_ENABLE_DPBIST_EN); 428 msm_dp_write_p0(panel, MMSS_DP_TIMING_ENGINE_EN, 429 DP_TIMING_ENGINE_EN_EN); 430 drm_dbg_dp(panel->drm_dev, "%s: enabled tpg\n", __func__); 431 } 432 433 static void msm_dp_panel_tpg_disable(struct msm_dp_panel *msm_dp_panel) 434 { 435 struct msm_dp_panel_private *panel = 436 container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel); 437 438 msm_dp_write_p0(panel, MMSS_DP_TPG_MAIN_CONTROL, 0x0); 439 msm_dp_write_p0(panel, MMSS_DP_BIST_ENABLE, 0x0); 440 msm_dp_write_p0(panel, MMSS_DP_TIMING_ENGINE_EN, 0x0); 441 } 442 443 void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable) 444 { 445 struct msm_dp_panel_private *panel; 446 447 if (!msm_dp_panel) { 448 DRM_ERROR("invalid input\n"); 449 return; 450 } 451 452 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel); 453 454 if (!panel->panel_on) { 455 drm_dbg_dp(panel->drm_dev, 456 "DP panel not enabled, handle TPG on next on\n"); 457 return; 458 } 459 460 if (!enable) { 461 msm_dp_panel_tpg_disable(msm_dp_panel); 462 return; 463 } 464 465 drm_dbg_dp(panel->drm_dev, "calling panel's tpg_enable\n"); 466 msm_dp_panel_tpg_enable(msm_dp_panel, &panel->msm_dp_panel.msm_dp_mode.drm_mode); 467 } 468 469 void msm_dp_panel_clear_dsc_dto(struct msm_dp_panel *msm_dp_panel) 470 { 471 struct msm_dp_panel_private *panel = 472 container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel); 473 474 msm_dp_write_p0(panel, MMSS_DP_DSC_DTO, 0x0); 475 } 476 477 static void msm_dp_panel_send_vsc_sdp(struct msm_dp_panel_private *panel, struct dp_sdp *vsc_sdp) 478 { 479 u32 header[2]; 480 u32 val; 481 int i; 482 483 msm_dp_utils_pack_sdp_header(&vsc_sdp->sdp_header, header); 484 485 msm_dp_write_link(panel, MMSS_DP_GENERIC0_0, header[0]); 486 msm_dp_write_link(panel, MMSS_DP_GENERIC0_1, header[1]); 487 488 for (i = 0; i < sizeof(vsc_sdp->db); i += 4) { 489 val = ((vsc_sdp->db[i]) | (vsc_sdp->db[i + 1] << 8) | (vsc_sdp->db[i + 2] << 16) | 490 (vsc_sdp->db[i + 3] << 24)); 491 msm_dp_write_link(panel, MMSS_DP_GENERIC0_2 + i, val); 492 } 493 } 494 495 static void msm_dp_panel_update_sdp(struct msm_dp_panel_private *panel) 496 { 497 u32 hw_revision = panel->msm_dp_panel.hw_revision; 498 499 if (hw_revision >= DP_HW_VERSION_1_0 && 500 hw_revision < DP_HW_VERSION_1_2) { 501 msm_dp_write_link(panel, MMSS_DP_SDP_CFG3, UPDATE_SDP); 502 msm_dp_write_link(panel, MMSS_DP_SDP_CFG3, 0x0); 503 } 504 } 505 506 void msm_dp_panel_enable_vsc_sdp(struct msm_dp_panel *msm_dp_panel, struct dp_sdp *vsc_sdp) 507 { 508 struct msm_dp_panel_private *panel = 509 container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel); 510 u32 cfg, cfg2, misc; 511 512 cfg = msm_dp_read_link(panel, MMSS_DP_SDP_CFG); 513 cfg2 = msm_dp_read_link(panel, MMSS_DP_SDP_CFG2); 514 misc = msm_dp_read_link(panel, REG_DP_MISC1_MISC0); 515 516 cfg |= GEN0_SDP_EN; 517 msm_dp_write_link(panel, MMSS_DP_SDP_CFG, cfg); 518 519 cfg2 |= GENERIC0_SDPSIZE_VALID; 520 msm_dp_write_link(panel, MMSS_DP_SDP_CFG2, cfg2); 521 522 msm_dp_panel_send_vsc_sdp(panel, vsc_sdp); 523 524 /* indicates presence of VSC (BIT(6) of MISC1) */ 525 misc |= DP_MISC1_VSC_SDP; 526 527 drm_dbg_dp(panel->drm_dev, "vsc sdp enable=1\n"); 528 529 pr_debug("misc settings = 0x%x\n", misc); 530 msm_dp_write_link(panel, REG_DP_MISC1_MISC0, misc); 531 532 msm_dp_panel_update_sdp(panel); 533 } 534 535 void msm_dp_panel_disable_vsc_sdp(struct msm_dp_panel *msm_dp_panel) 536 { 537 struct msm_dp_panel_private *panel = 538 container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel); 539 u32 cfg, cfg2, misc; 540 541 cfg = msm_dp_read_link(panel, MMSS_DP_SDP_CFG); 542 cfg2 = msm_dp_read_link(panel, MMSS_DP_SDP_CFG2); 543 misc = msm_dp_read_link(panel, REG_DP_MISC1_MISC0); 544 545 cfg &= ~GEN0_SDP_EN; 546 msm_dp_write_link(panel, MMSS_DP_SDP_CFG, cfg); 547 548 cfg2 &= ~GENERIC0_SDPSIZE_VALID; 549 msm_dp_write_link(panel, MMSS_DP_SDP_CFG2, cfg2); 550 551 /* switch back to MSA */ 552 misc &= ~DP_MISC1_VSC_SDP; 553 554 drm_dbg_dp(panel->drm_dev, "vsc sdp enable=0\n"); 555 556 pr_debug("misc settings = 0x%x\n", misc); 557 msm_dp_write_link(panel, REG_DP_MISC1_MISC0, misc); 558 559 msm_dp_panel_update_sdp(panel); 560 } 561 562 static int msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel *msm_dp_panel) 563 { 564 struct msm_dp_display_mode *msm_dp_mode; 565 struct drm_dp_vsc_sdp vsc_sdp_data; 566 struct dp_sdp vsc_sdp; 567 ssize_t len; 568 569 if (!msm_dp_panel) { 570 DRM_ERROR("invalid input\n"); 571 return -EINVAL; 572 } 573 574 msm_dp_mode = &msm_dp_panel->msm_dp_mode; 575 576 memset(&vsc_sdp_data, 0, sizeof(vsc_sdp_data)); 577 578 /* VSC SDP header as per table 2-118 of DP 1.4 specification */ 579 vsc_sdp_data.sdp_type = DP_SDP_VSC; 580 vsc_sdp_data.revision = 0x05; 581 vsc_sdp_data.length = 0x13; 582 583 /* VSC SDP Payload for DB16 */ 584 vsc_sdp_data.pixelformat = DP_PIXELFORMAT_YUV420; 585 vsc_sdp_data.colorimetry = DP_COLORIMETRY_DEFAULT; 586 587 /* VSC SDP Payload for DB17 */ 588 vsc_sdp_data.bpc = msm_dp_mode->bpp / 3; 589 vsc_sdp_data.dynamic_range = DP_DYNAMIC_RANGE_CTA; 590 591 /* VSC SDP Payload for DB18 */ 592 vsc_sdp_data.content_type = DP_CONTENT_TYPE_GRAPHICS; 593 594 len = drm_dp_vsc_sdp_pack(&vsc_sdp_data, &vsc_sdp); 595 if (len < 0) { 596 DRM_ERROR("unable to pack vsc sdp\n"); 597 return len; 598 } 599 600 msm_dp_panel_enable_vsc_sdp(msm_dp_panel, &vsc_sdp); 601 602 return 0; 603 } 604 605 int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel, bool wide_bus_en) 606 { 607 u32 data, total_ver, total_hor; 608 struct msm_dp_panel_private *panel; 609 struct drm_display_mode *drm_mode; 610 u32 width_blanking; 611 u32 sync_start; 612 u32 msm_dp_active; 613 u32 total; 614 u32 reg; 615 616 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel); 617 drm_mode = &panel->msm_dp_panel.msm_dp_mode.drm_mode; 618 619 drm_dbg_dp(panel->drm_dev, "width=%d hporch= %d %d %d\n", 620 drm_mode->hdisplay, drm_mode->htotal - drm_mode->hsync_end, 621 drm_mode->hsync_start - drm_mode->hdisplay, 622 drm_mode->hsync_end - drm_mode->hsync_start); 623 624 drm_dbg_dp(panel->drm_dev, "height=%d vporch= %d %d %d\n", 625 drm_mode->vdisplay, drm_mode->vtotal - drm_mode->vsync_end, 626 drm_mode->vsync_start - drm_mode->vdisplay, 627 drm_mode->vsync_end - drm_mode->vsync_start); 628 629 total_hor = drm_mode->htotal; 630 631 total_ver = drm_mode->vtotal; 632 633 data = total_ver; 634 data <<= 16; 635 data |= total_hor; 636 637 total = data; 638 639 data = (drm_mode->vtotal - drm_mode->vsync_start); 640 data <<= 16; 641 data |= (drm_mode->htotal - drm_mode->hsync_start); 642 643 sync_start = data; 644 645 data = drm_mode->vsync_end - drm_mode->vsync_start; 646 data <<= 16; 647 data |= (panel->msm_dp_panel.msm_dp_mode.v_active_low << 31); 648 data |= drm_mode->hsync_end - drm_mode->hsync_start; 649 data |= (panel->msm_dp_panel.msm_dp_mode.h_active_low << 15); 650 651 width_blanking = data; 652 653 data = drm_mode->vdisplay; 654 data <<= 16; 655 data |= drm_mode->hdisplay; 656 657 msm_dp_active = data; 658 659 msm_dp_write_link(panel, REG_DP_TOTAL_HOR_VER, total); 660 msm_dp_write_link(panel, REG_DP_START_HOR_VER_FROM_SYNC, sync_start); 661 msm_dp_write_link(panel, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, width_blanking); 662 msm_dp_write_link(panel, REG_DP_ACTIVE_HOR_VER, msm_dp_active); 663 664 reg = msm_dp_read_p0(panel, MMSS_DP_INTF_CONFIG); 665 if (wide_bus_en) 666 reg |= DP_INTF_CONFIG_DATABUS_WIDEN; 667 else 668 reg &= ~DP_INTF_CONFIG_DATABUS_WIDEN; 669 670 drm_dbg_dp(panel->drm_dev, "wide_bus_en=%d reg=%#x\n", wide_bus_en, reg); 671 672 msm_dp_write_p0(panel, MMSS_DP_INTF_CONFIG, reg); 673 674 if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420) 675 msm_dp_panel_setup_vsc_sdp_yuv_420(msm_dp_panel); 676 677 panel->panel_on = true; 678 679 return 0; 680 } 681 682 int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel) 683 { 684 struct drm_display_mode *drm_mode; 685 struct msm_dp_panel_private *panel; 686 687 drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode; 688 689 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel); 690 691 /* 692 * print resolution info as this is a result 693 * of user initiated action of cable connection 694 */ 695 drm_dbg_dp(panel->drm_dev, "SET NEW RESOLUTION:\n"); 696 drm_dbg_dp(panel->drm_dev, "%dx%d@%dfps\n", 697 drm_mode->hdisplay, drm_mode->vdisplay, drm_mode_vrefresh(drm_mode)); 698 drm_dbg_dp(panel->drm_dev, 699 "h_porches(back|front|width) = (%d|%d|%d)\n", 700 drm_mode->htotal - drm_mode->hsync_end, 701 drm_mode->hsync_start - drm_mode->hdisplay, 702 drm_mode->hsync_end - drm_mode->hsync_start); 703 drm_dbg_dp(panel->drm_dev, 704 "v_porches(back|front|width) = (%d|%d|%d)\n", 705 drm_mode->vtotal - drm_mode->vsync_end, 706 drm_mode->vsync_start - drm_mode->vdisplay, 707 drm_mode->vsync_end - drm_mode->vsync_start); 708 drm_dbg_dp(panel->drm_dev, "pixel clock (KHz)=(%d)\n", 709 drm_mode->clock); 710 drm_dbg_dp(panel->drm_dev, "bpp = %d\n", msm_dp_panel->msm_dp_mode.bpp); 711 712 msm_dp_panel->msm_dp_mode.bpp = msm_dp_panel_get_mode_bpp(msm_dp_panel, msm_dp_panel->msm_dp_mode.bpp, 713 msm_dp_panel->msm_dp_mode.drm_mode.clock); 714 715 drm_dbg_dp(panel->drm_dev, "updated bpp = %d\n", 716 msm_dp_panel->msm_dp_mode.bpp); 717 718 return 0; 719 } 720 721 struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux, 722 struct msm_dp_link *link, 723 void __iomem *link_base, 724 void __iomem *p0_base) 725 { 726 struct msm_dp_panel_private *panel; 727 struct msm_dp_panel *msm_dp_panel; 728 729 if (!dev || !aux || !link) { 730 DRM_ERROR("invalid input\n"); 731 return ERR_PTR(-EINVAL); 732 } 733 734 panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL); 735 if (!panel) 736 return ERR_PTR(-ENOMEM); 737 738 panel->dev = dev; 739 panel->aux = aux; 740 panel->link = link; 741 panel->link_base = link_base; 742 panel->p0_base = p0_base; 743 744 msm_dp_panel = &panel->msm_dp_panel; 745 msm_dp_panel->max_bw_code = DP_LINK_BW_8_1; 746 747 return msm_dp_panel; 748 } 749 750 void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel) 751 { 752 if (!msm_dp_panel) 753 return; 754 755 drm_edid_free(msm_dp_panel->drm_edid); 756 } 757