526 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.4 */5 6#include "dp_panel.h"7#include "dp_utils.h"8 9#include <drm/drm_connector.h>10#include <drm/drm_edid.h>11#include <drm/drm_of.h>12#include <drm/drm_print.h>13 14#define DP_MAX_NUM_DP_LANES 415#define DP_LINK_RATE_HBR2 540000 /* kbytes */16 17struct dp_panel_private {18 struct device *dev;19 struct drm_device *drm_dev;20 struct dp_panel dp_panel;21 struct drm_dp_aux *aux;22 struct dp_link *link;23 struct dp_catalog *catalog;24 bool panel_on;25};26 27static void dp_panel_read_psr_cap(struct dp_panel_private *panel)28{29 ssize_t rlen;30 struct dp_panel *dp_panel;31 32 dp_panel = &panel->dp_panel;33 34 /* edp sink */35 if (dp_panel->dpcd[DP_EDP_CONFIGURATION_CAP]) {36 rlen = drm_dp_dpcd_read(panel->aux, DP_PSR_SUPPORT,37 &dp_panel->psr_cap, sizeof(dp_panel->psr_cap));38 if (rlen == sizeof(dp_panel->psr_cap)) {39 drm_dbg_dp(panel->drm_dev,40 "psr version: 0x%x, psr_cap: 0x%x\n",41 dp_panel->psr_cap.version,42 dp_panel->psr_cap.capabilities);43 } else44 DRM_ERROR("failed to read psr info, rlen=%zd\n", rlen);45 }46}47 48static int dp_panel_read_dpcd(struct dp_panel *dp_panel)49{50 int rc;51 struct dp_panel_private *panel;52 struct dp_link_info *link_info;53 u8 *dpcd, major, minor;54 55 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);56 dpcd = dp_panel->dpcd;57 rc = drm_dp_read_dpcd_caps(panel->aux, dpcd);58 if (rc)59 return rc;60 61 dp_panel->vsc_sdp_supported = drm_dp_vsc_sdp_supported(panel->aux, dpcd);62 link_info = &dp_panel->link_info;63 link_info->revision = dpcd[DP_DPCD_REV];64 major = (link_info->revision >> 4) & 0x0f;65 minor = link_info->revision & 0x0f;66 67 link_info->rate = drm_dp_max_link_rate(dpcd);68 link_info->num_lanes = drm_dp_max_lane_count(dpcd);69 70 /* Limit data lanes from data-lanes of endpoint property of dtsi */71 if (link_info->num_lanes > dp_panel->max_dp_lanes)72 link_info->num_lanes = dp_panel->max_dp_lanes;73 74 /* Limit link rate from link-frequencies of endpoint property of dtsi */75 if (link_info->rate > dp_panel->max_dp_link_rate)76 link_info->rate = dp_panel->max_dp_link_rate;77 78 drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);79 drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);80 drm_dbg_dp(panel->drm_dev, "lane_count=%d\n", link_info->num_lanes);81 82 if (drm_dp_enhanced_frame_cap(dpcd))83 link_info->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;84 85 dp_panel_read_psr_cap(panel);86 87 return rc;88}89 90static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel,91 u32 mode_edid_bpp, u32 mode_pclk_khz)92{93 const struct dp_link_info *link_info;94 const u32 max_supported_bpp = 30, min_supported_bpp = 18;95 u32 bpp, data_rate_khz;96 97 bpp = min(mode_edid_bpp, max_supported_bpp);98 99 link_info = &dp_panel->link_info;100 data_rate_khz = link_info->num_lanes * link_info->rate * 8;101 102 do {103 if (mode_pclk_khz * bpp <= data_rate_khz)104 return bpp;105 bpp -= 6;106 } while (bpp > min_supported_bpp);107 108 return min_supported_bpp;109}110 111int dp_panel_read_sink_caps(struct dp_panel *dp_panel,112 struct drm_connector *connector)113{114 int rc, bw_code;115 int count;116 struct dp_panel_private *panel;117 118 if (!dp_panel || !connector) {119 DRM_ERROR("invalid input\n");120 return -EINVAL;121 }122 123 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);124 125 drm_dbg_dp(panel->drm_dev, "max_lanes=%d max_link_rate=%d\n",126 dp_panel->max_dp_lanes, dp_panel->max_dp_link_rate);127 128 rc = dp_panel_read_dpcd(dp_panel);129 if (rc) {130 DRM_ERROR("read dpcd failed %d\n", rc);131 return rc;132 }133 134 bw_code = drm_dp_link_rate_to_bw_code(dp_panel->link_info.rate);135 if (!is_link_rate_valid(bw_code) ||136 !is_lane_count_valid(dp_panel->link_info.num_lanes) ||137 (bw_code > dp_panel->max_bw_code)) {138 DRM_ERROR("Illegal link rate=%d lane=%d\n", dp_panel->link_info.rate,139 dp_panel->link_info.num_lanes);140 return -EINVAL;141 }142 143 if (drm_dp_is_branch(dp_panel->dpcd)) {144 count = drm_dp_read_sink_count(panel->aux);145 if (!count) {146 panel->link->sink_count = 0;147 return -ENOTCONN;148 }149 }150 151 rc = drm_dp_read_downstream_info(panel->aux, dp_panel->dpcd,152 dp_panel->downstream_ports);153 if (rc)154 return rc;155 156 drm_edid_free(dp_panel->drm_edid);157 158 dp_panel->drm_edid = drm_edid_read_ddc(connector, &panel->aux->ddc);159 160 drm_edid_connector_update(connector, dp_panel->drm_edid);161 162 if (!dp_panel->drm_edid) {163 DRM_ERROR("panel edid read failed\n");164 /* check edid read fail is due to unplug */165 if (!dp_catalog_link_is_connected(panel->catalog)) {166 rc = -ETIMEDOUT;167 goto end;168 }169 }170 171end:172 return rc;173}174 175u32 dp_panel_get_mode_bpp(struct dp_panel *dp_panel,176 u32 mode_edid_bpp, u32 mode_pclk_khz)177{178 struct dp_panel_private *panel;179 u32 bpp;180 181 if (!dp_panel || !mode_edid_bpp || !mode_pclk_khz) {182 DRM_ERROR("invalid input\n");183 return 0;184 }185 186 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);187 188 if (dp_panel->video_test)189 bpp = dp_link_bit_depth_to_bpp(190 panel->link->test_video.test_bit_depth);191 else192 bpp = dp_panel_get_supported_bpp(dp_panel, mode_edid_bpp,193 mode_pclk_khz);194 195 return bpp;196}197 198int dp_panel_get_modes(struct dp_panel *dp_panel,199 struct drm_connector *connector)200{201 if (!dp_panel) {202 DRM_ERROR("invalid input\n");203 return -EINVAL;204 }205 206 if (dp_panel->drm_edid)207 return drm_edid_connector_add_modes(connector);208 209 return 0;210}211 212static u8 dp_panel_get_edid_checksum(const struct edid *edid)213{214 edid += edid->extensions;215 216 return edid->checksum;217}218 219void dp_panel_handle_sink_request(struct dp_panel *dp_panel)220{221 struct dp_panel_private *panel;222 223 if (!dp_panel) {224 DRM_ERROR("invalid input\n");225 return;226 }227 228 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);229 230 if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) {231 /* FIXME: get rid of drm_edid_raw() */232 const struct edid *edid = drm_edid_raw(dp_panel->drm_edid);233 u8 checksum;234 235 if (edid)236 checksum = dp_panel_get_edid_checksum(edid);237 else238 checksum = dp_panel->connector->real_edid_checksum;239 240 dp_link_send_edid_checksum(panel->link, checksum);241 dp_link_send_test_response(panel->link);242 }243}244 245void dp_panel_tpg_config(struct dp_panel *dp_panel, bool enable)246{247 struct dp_catalog *catalog;248 struct dp_panel_private *panel;249 250 if (!dp_panel) {251 DRM_ERROR("invalid input\n");252 return;253 }254 255 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);256 catalog = panel->catalog;257 258 if (!panel->panel_on) {259 drm_dbg_dp(panel->drm_dev,260 "DP panel not enabled, handle TPG on next on\n");261 return;262 }263 264 if (!enable) {265 dp_catalog_panel_tpg_disable(catalog);266 return;267 }268 269 drm_dbg_dp(panel->drm_dev, "calling catalog tpg_enable\n");270 dp_catalog_panel_tpg_enable(catalog, &panel->dp_panel.dp_mode.drm_mode);271}272 273static int dp_panel_setup_vsc_sdp_yuv_420(struct dp_panel *dp_panel)274{275 struct dp_catalog *catalog;276 struct dp_panel_private *panel;277 struct dp_display_mode *dp_mode;278 struct drm_dp_vsc_sdp vsc_sdp_data;279 struct dp_sdp vsc_sdp;280 ssize_t len;281 282 if (!dp_panel) {283 DRM_ERROR("invalid input\n");284 return -EINVAL;285 }286 287 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);288 catalog = panel->catalog;289 dp_mode = &dp_panel->dp_mode;290 291 memset(&vsc_sdp_data, 0, sizeof(vsc_sdp_data));292 293 /* VSC SDP header as per table 2-118 of DP 1.4 specification */294 vsc_sdp_data.sdp_type = DP_SDP_VSC;295 vsc_sdp_data.revision = 0x05;296 vsc_sdp_data.length = 0x13;297 298 /* VSC SDP Payload for DB16 */299 vsc_sdp_data.pixelformat = DP_PIXELFORMAT_YUV420;300 vsc_sdp_data.colorimetry = DP_COLORIMETRY_DEFAULT;301 302 /* VSC SDP Payload for DB17 */303 vsc_sdp_data.bpc = dp_mode->bpp / 3;304 vsc_sdp_data.dynamic_range = DP_DYNAMIC_RANGE_CTA;305 306 /* VSC SDP Payload for DB18 */307 vsc_sdp_data.content_type = DP_CONTENT_TYPE_GRAPHICS;308 309 len = drm_dp_vsc_sdp_pack(&vsc_sdp_data, &vsc_sdp);310 if (len < 0) {311 DRM_ERROR("unable to pack vsc sdp\n");312 return len;313 }314 315 dp_catalog_panel_enable_vsc_sdp(catalog, &vsc_sdp);316 317 return 0;318}319 320void dp_panel_dump_regs(struct dp_panel *dp_panel)321{322 struct dp_catalog *catalog;323 struct dp_panel_private *panel;324 325 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);326 catalog = panel->catalog;327 328 dp_catalog_dump_regs(catalog);329}330 331int dp_panel_timing_cfg(struct dp_panel *dp_panel)332{333 u32 data, total_ver, total_hor;334 struct dp_catalog *catalog;335 struct dp_panel_private *panel;336 struct drm_display_mode *drm_mode;337 u32 width_blanking;338 u32 sync_start;339 u32 dp_active;340 u32 total;341 342 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);343 catalog = panel->catalog;344 drm_mode = &panel->dp_panel.dp_mode.drm_mode;345 346 drm_dbg_dp(panel->drm_dev, "width=%d hporch= %d %d %d\n",347 drm_mode->hdisplay, drm_mode->htotal - drm_mode->hsync_end,348 drm_mode->hsync_start - drm_mode->hdisplay,349 drm_mode->hsync_end - drm_mode->hsync_start);350 351 drm_dbg_dp(panel->drm_dev, "height=%d vporch= %d %d %d\n",352 drm_mode->vdisplay, drm_mode->vtotal - drm_mode->vsync_end,353 drm_mode->vsync_start - drm_mode->vdisplay,354 drm_mode->vsync_end - drm_mode->vsync_start);355 356 total_hor = drm_mode->htotal;357 358 total_ver = drm_mode->vtotal;359 360 data = total_ver;361 data <<= 16;362 data |= total_hor;363 364 total = data;365 366 data = (drm_mode->vtotal - drm_mode->vsync_start);367 data <<= 16;368 data |= (drm_mode->htotal - drm_mode->hsync_start);369 370 sync_start = data;371 372 data = drm_mode->vsync_end - drm_mode->vsync_start;373 data <<= 16;374 data |= (panel->dp_panel.dp_mode.v_active_low << 31);375 data |= drm_mode->hsync_end - drm_mode->hsync_start;376 data |= (panel->dp_panel.dp_mode.h_active_low << 15);377 378 width_blanking = data;379 380 data = drm_mode->vdisplay;381 data <<= 16;382 data |= drm_mode->hdisplay;383 384 dp_active = data;385 386 dp_catalog_panel_timing_cfg(catalog, total, sync_start, width_blanking, dp_active);387 388 if (dp_panel->dp_mode.out_fmt_is_yuv_420)389 dp_panel_setup_vsc_sdp_yuv_420(dp_panel);390 391 panel->panel_on = true;392 393 return 0;394}395 396int dp_panel_init_panel_info(struct dp_panel *dp_panel)397{398 struct drm_display_mode *drm_mode;399 struct dp_panel_private *panel;400 401 drm_mode = &dp_panel->dp_mode.drm_mode;402 403 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);404 405 /*406 * print resolution info as this is a result407 * of user initiated action of cable connection408 */409 drm_dbg_dp(panel->drm_dev, "SET NEW RESOLUTION:\n");410 drm_dbg_dp(panel->drm_dev, "%dx%d@%dfps\n",411 drm_mode->hdisplay, drm_mode->vdisplay, drm_mode_vrefresh(drm_mode));412 drm_dbg_dp(panel->drm_dev,413 "h_porches(back|front|width) = (%d|%d|%d)\n",414 drm_mode->htotal - drm_mode->hsync_end,415 drm_mode->hsync_start - drm_mode->hdisplay,416 drm_mode->hsync_end - drm_mode->hsync_start);417 drm_dbg_dp(panel->drm_dev,418 "v_porches(back|front|width) = (%d|%d|%d)\n",419 drm_mode->vtotal - drm_mode->vsync_end,420 drm_mode->vsync_start - drm_mode->vdisplay,421 drm_mode->vsync_end - drm_mode->vsync_start);422 drm_dbg_dp(panel->drm_dev, "pixel clock (KHz)=(%d)\n",423 drm_mode->clock);424 drm_dbg_dp(panel->drm_dev, "bpp = %d\n", dp_panel->dp_mode.bpp);425 426 dp_panel->dp_mode.bpp = dp_panel_get_mode_bpp(dp_panel, dp_panel->dp_mode.bpp,427 dp_panel->dp_mode.drm_mode.clock);428 429 drm_dbg_dp(panel->drm_dev, "updated bpp = %d\n",430 dp_panel->dp_mode.bpp);431 432 return 0;433}434 435static u32 dp_panel_link_frequencies(struct device_node *of_node)436{437 struct device_node *endpoint;438 u64 frequency = 0;439 int cnt;440 441 endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port@1 */442 if (!endpoint)443 return 0;444 445 cnt = of_property_count_u64_elems(endpoint, "link-frequencies");446 447 if (cnt > 0)448 of_property_read_u64_index(endpoint, "link-frequencies",449 cnt - 1, &frequency);450 of_node_put(endpoint);451 452 do_div(frequency,453 10 * /* from symbol rate to link rate */454 1000); /* kbytes */455 456 return frequency;457}458 459static int dp_panel_parse_dt(struct dp_panel *dp_panel)460{461 struct dp_panel_private *panel;462 struct device_node *of_node;463 int cnt;464 465 panel = container_of(dp_panel, struct dp_panel_private, dp_panel);466 of_node = panel->dev->of_node;467 468 /*469 * data-lanes is the property of dp_out endpoint470 */471 cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);472 if (cnt < 0) {473 /* legacy code, data-lanes is the property of mdss_dp node */474 cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);475 }476 477 if (cnt > 0)478 dp_panel->max_dp_lanes = cnt;479 else480 dp_panel->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */481 482 dp_panel->max_dp_link_rate = dp_panel_link_frequencies(of_node);483 if (!dp_panel->max_dp_link_rate)484 dp_panel->max_dp_link_rate = DP_LINK_RATE_HBR2;485 486 return 0;487}488 489struct dp_panel *dp_panel_get(struct dp_panel_in *in)490{491 struct dp_panel_private *panel;492 struct dp_panel *dp_panel;493 int ret;494 495 if (!in->dev || !in->catalog || !in->aux || !in->link) {496 DRM_ERROR("invalid input\n");497 return ERR_PTR(-EINVAL);498 }499 500 panel = devm_kzalloc(in->dev, sizeof(*panel), GFP_KERNEL);501 if (!panel)502 return ERR_PTR(-ENOMEM);503 504 panel->dev = in->dev;505 panel->aux = in->aux;506 panel->catalog = in->catalog;507 panel->link = in->link;508 509 dp_panel = &panel->dp_panel;510 dp_panel->max_bw_code = DP_LINK_BW_8_1;511 512 ret = dp_panel_parse_dt(dp_panel);513 if (ret)514 return ERR_PTR(ret);515 516 return dp_panel;517}518 519void dp_panel_put(struct dp_panel *dp_panel)520{521 if (!dp_panel)522 return;523 524 drm_edid_free(dp_panel->drm_edid);525}526