1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
9 #include <drm/drm_connector.h>
10 #include <drm/drm_edid.h>
11 #include <drm/drm_of.h>
12 #include <drm/drm_print.h>
14 #define DP_MAX_NUM_DP_LANES 4
15 #define DP_LINK_RATE_HBR2 540000 /* kbytes */
17 struct msm_dp_panel_private {
19 struct drm_device *drm_dev;
20 struct msm_dp_panel msm_dp_panel;
21 struct drm_dp_aux *aux;
22 struct msm_dp_link *link;
23 struct msm_dp_catalog *catalog;
27 static void msm_dp_panel_read_psr_cap(struct msm_dp_panel_private *panel)
30 struct msm_dp_panel *msm_dp_panel;
32 msm_dp_panel = &panel->msm_dp_panel;
35 if (msm_dp_panel->dpcd[DP_EDP_CONFIGURATION_CAP]) {
36 rlen = drm_dp_dpcd_read(panel->aux, DP_PSR_SUPPORT,
37 &msm_dp_panel->psr_cap, sizeof(msm_dp_panel->psr_cap));
38 if (rlen == sizeof(msm_dp_panel->psr_cap)) {
39 drm_dbg_dp(panel->drm_dev,
40 "psr version: 0x%x, psr_cap: 0x%x\n",
41 msm_dp_panel->psr_cap.version,
42 msm_dp_panel->psr_cap.capabilities);
44 DRM_ERROR("failed to read psr info, rlen=%zd\n", rlen);
48 static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
51 struct msm_dp_panel_private *panel;
52 struct msm_dp_link_info *link_info;
53 u8 *dpcd, major, minor;
55 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
56 dpcd = msm_dp_panel->dpcd;
57 rc = drm_dp_read_dpcd_caps(panel->aux, dpcd);
61 msm_dp_panel->vsc_sdp_supported = drm_dp_vsc_sdp_supported(panel->aux, dpcd);
62 link_info = &msm_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;
67 link_info->rate = drm_dp_max_link_rate(dpcd);
68 link_info->num_lanes = drm_dp_max_lane_count(dpcd);
70 /* Limit data lanes from data-lanes of endpoint property of dtsi */
71 if (link_info->num_lanes > msm_dp_panel->max_dp_lanes)
72 link_info->num_lanes = msm_dp_panel->max_dp_lanes;
74 /* Limit link rate from link-frequencies of endpoint property of dtsi */
75 if (link_info->rate > msm_dp_panel->max_dp_link_rate)
76 link_info->rate = msm_dp_panel->max_dp_link_rate;
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);
82 if (drm_dp_enhanced_frame_cap(dpcd))
83 link_info->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
85 msm_dp_panel_read_psr_cap(panel);
90 static u32 msm_dp_panel_get_supported_bpp(struct msm_dp_panel *msm_dp_panel,
91 u32 mode_edid_bpp, u32 mode_pclk_khz)
93 const struct msm_dp_link_info *link_info;
94 const u32 max_supported_bpp = 30, min_supported_bpp = 18;
95 u32 bpp, data_rate_khz;
97 bpp = min(mode_edid_bpp, max_supported_bpp);
99 link_info = &msm_dp_panel->link_info;
100 data_rate_khz = link_info->num_lanes * link_info->rate * 8;
103 if (mode_pclk_khz * bpp <= data_rate_khz)
106 } while (bpp > min_supported_bpp);
108 return min_supported_bpp;
111 int msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
112 struct drm_connector *connector)
116 struct msm_dp_panel_private *panel;
118 if (!msm_dp_panel || !connector) {
119 DRM_ERROR("invalid input\n");
123 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
125 drm_dbg_dp(panel->drm_dev, "max_lanes=%d max_link_rate=%d\n",
126 msm_dp_panel->max_dp_lanes, msm_dp_panel->max_dp_link_rate);
128 rc = msm_dp_panel_read_dpcd(msm_dp_panel);
130 DRM_ERROR("read dpcd failed %d\n", rc);
134 bw_code = drm_dp_link_rate_to_bw_code(msm_dp_panel->link_info.rate);
135 if (!is_link_rate_valid(bw_code) ||
136 !is_lane_count_valid(msm_dp_panel->link_info.num_lanes) ||
137 (bw_code > msm_dp_panel->max_bw_code)) {
138 DRM_ERROR("Illegal link rate=%d lane=%d\n", msm_dp_panel->link_info.rate,
139 msm_dp_panel->link_info.num_lanes);
143 if (drm_dp_is_branch(msm_dp_panel->dpcd)) {
144 count = drm_dp_read_sink_count(panel->aux);
146 panel->link->sink_count = 0;
151 rc = drm_dp_read_downstream_info(panel->aux, msm_dp_panel->dpcd,
152 msm_dp_panel->downstream_ports);
156 drm_edid_free(msm_dp_panel->drm_edid);
158 msm_dp_panel->drm_edid = drm_edid_read_ddc(connector, &panel->aux->ddc);
160 drm_edid_connector_update(connector, msm_dp_panel->drm_edid);
162 if (!msm_dp_panel->drm_edid) {
163 DRM_ERROR("panel edid read failed\n");
164 /* check edid read fail is due to unplug */
165 if (!msm_dp_catalog_link_is_connected(panel->catalog)) {
175 u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,
176 u32 mode_edid_bpp, u32 mode_pclk_khz)
178 struct msm_dp_panel_private *panel;
181 if (!msm_dp_panel || !mode_edid_bpp || !mode_pclk_khz) {
182 DRM_ERROR("invalid input\n");
186 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
188 if (msm_dp_panel->video_test)
189 bpp = msm_dp_link_bit_depth_to_bpp(
190 panel->link->test_video.test_bit_depth);
192 bpp = msm_dp_panel_get_supported_bpp(msm_dp_panel, mode_edid_bpp,
198 int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
199 struct drm_connector *connector)
202 DRM_ERROR("invalid input\n");
206 if (msm_dp_panel->drm_edid)
207 return drm_edid_connector_add_modes(connector);
212 static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid)
214 edid += edid->extensions;
216 return edid->checksum;
219 void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel)
221 struct msm_dp_panel_private *panel;
224 DRM_ERROR("invalid input\n");
228 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
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(msm_dp_panel->drm_edid);
236 checksum = msm_dp_panel_get_edid_checksum(edid);
238 checksum = msm_dp_panel->connector->real_edid_checksum;
240 msm_dp_link_send_edid_checksum(panel->link, checksum);
241 msm_dp_link_send_test_response(panel->link);
245 void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable)
247 struct msm_dp_catalog *catalog;
248 struct msm_dp_panel_private *panel;
251 DRM_ERROR("invalid input\n");
255 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
256 catalog = panel->catalog;
258 if (!panel->panel_on) {
259 drm_dbg_dp(panel->drm_dev,
260 "DP panel not enabled, handle TPG on next on\n");
265 msm_dp_catalog_panel_tpg_disable(catalog);
269 drm_dbg_dp(panel->drm_dev, "calling catalog tpg_enable\n");
270 msm_dp_catalog_panel_tpg_enable(catalog, &panel->msm_dp_panel.msm_dp_mode.drm_mode);
273 static int msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel *msm_dp_panel)
275 struct msm_dp_catalog *catalog;
276 struct msm_dp_panel_private *panel;
277 struct msm_dp_display_mode *msm_dp_mode;
278 struct drm_dp_vsc_sdp vsc_sdp_data;
279 struct dp_sdp vsc_sdp;
283 DRM_ERROR("invalid input\n");
287 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
288 catalog = panel->catalog;
289 msm_dp_mode = &msm_dp_panel->msm_dp_mode;
291 memset(&vsc_sdp_data, 0, sizeof(vsc_sdp_data));
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;
298 /* VSC SDP Payload for DB16 */
299 vsc_sdp_data.pixelformat = DP_PIXELFORMAT_YUV420;
300 vsc_sdp_data.colorimetry = DP_COLORIMETRY_DEFAULT;
302 /* VSC SDP Payload for DB17 */
303 vsc_sdp_data.bpc = msm_dp_mode->bpp / 3;
304 vsc_sdp_data.dynamic_range = DP_DYNAMIC_RANGE_CTA;
306 /* VSC SDP Payload for DB18 */
307 vsc_sdp_data.content_type = DP_CONTENT_TYPE_GRAPHICS;
309 len = drm_dp_vsc_sdp_pack(&vsc_sdp_data, &vsc_sdp);
311 DRM_ERROR("unable to pack vsc sdp\n");
315 msm_dp_catalog_panel_enable_vsc_sdp(catalog, &vsc_sdp);
320 int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel)
322 u32 data, total_ver, total_hor;
323 struct msm_dp_catalog *catalog;
324 struct msm_dp_panel_private *panel;
325 struct drm_display_mode *drm_mode;
331 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
332 catalog = panel->catalog;
333 drm_mode = &panel->msm_dp_panel.msm_dp_mode.drm_mode;
335 drm_dbg_dp(panel->drm_dev, "width=%d hporch= %d %d %d\n",
336 drm_mode->hdisplay, drm_mode->htotal - drm_mode->hsync_end,
337 drm_mode->hsync_start - drm_mode->hdisplay,
338 drm_mode->hsync_end - drm_mode->hsync_start);
340 drm_dbg_dp(panel->drm_dev, "height=%d vporch= %d %d %d\n",
341 drm_mode->vdisplay, drm_mode->vtotal - drm_mode->vsync_end,
342 drm_mode->vsync_start - drm_mode->vdisplay,
343 drm_mode->vsync_end - drm_mode->vsync_start);
345 total_hor = drm_mode->htotal;
347 total_ver = drm_mode->vtotal;
355 data = (drm_mode->vtotal - drm_mode->vsync_start);
357 data |= (drm_mode->htotal - drm_mode->hsync_start);
361 data = drm_mode->vsync_end - drm_mode->vsync_start;
363 data |= (panel->msm_dp_panel.msm_dp_mode.v_active_low << 31);
364 data |= drm_mode->hsync_end - drm_mode->hsync_start;
365 data |= (panel->msm_dp_panel.msm_dp_mode.h_active_low << 15);
367 width_blanking = data;
369 data = drm_mode->vdisplay;
371 data |= drm_mode->hdisplay;
373 msm_dp_active = data;
375 msm_dp_catalog_panel_timing_cfg(catalog, total, sync_start, width_blanking, msm_dp_active);
377 if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
378 msm_dp_panel_setup_vsc_sdp_yuv_420(msm_dp_panel);
380 panel->panel_on = true;
385 int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel)
387 struct drm_display_mode *drm_mode;
388 struct msm_dp_panel_private *panel;
390 drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode;
392 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
395 * print resolution info as this is a result
396 * of user initiated action of cable connection
398 drm_dbg_dp(panel->drm_dev, "SET NEW RESOLUTION:\n");
399 drm_dbg_dp(panel->drm_dev, "%dx%d@%dfps\n",
400 drm_mode->hdisplay, drm_mode->vdisplay, drm_mode_vrefresh(drm_mode));
401 drm_dbg_dp(panel->drm_dev,
402 "h_porches(back|front|width) = (%d|%d|%d)\n",
403 drm_mode->htotal - drm_mode->hsync_end,
404 drm_mode->hsync_start - drm_mode->hdisplay,
405 drm_mode->hsync_end - drm_mode->hsync_start);
406 drm_dbg_dp(panel->drm_dev,
407 "v_porches(back|front|width) = (%d|%d|%d)\n",
408 drm_mode->vtotal - drm_mode->vsync_end,
409 drm_mode->vsync_start - drm_mode->vdisplay,
410 drm_mode->vsync_end - drm_mode->vsync_start);
411 drm_dbg_dp(panel->drm_dev, "pixel clock (KHz)=(%d)\n",
413 drm_dbg_dp(panel->drm_dev, "bpp = %d\n", msm_dp_panel->msm_dp_mode.bpp);
415 msm_dp_panel->msm_dp_mode.bpp = msm_dp_panel_get_mode_bpp(msm_dp_panel, msm_dp_panel->msm_dp_mode.bpp,
416 msm_dp_panel->msm_dp_mode.drm_mode.clock);
418 drm_dbg_dp(panel->drm_dev, "updated bpp = %d\n",
419 msm_dp_panel->msm_dp_mode.bpp);
424 static u32 msm_dp_panel_link_frequencies(struct device_node *of_node)
426 struct device_node *endpoint;
430 endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port@1 */
434 cnt = of_property_count_u64_elems(endpoint, "link-frequencies");
437 of_property_read_u64_index(endpoint, "link-frequencies",
438 cnt - 1, &frequency);
439 of_node_put(endpoint);
442 10 * /* from symbol rate to link rate */
448 static int msm_dp_panel_parse_dt(struct msm_dp_panel *msm_dp_panel)
450 struct msm_dp_panel_private *panel;
451 struct device_node *of_node;
454 panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
455 of_node = panel->dev->of_node;
458 * data-lanes is the property of msm_dp_out endpoint
460 cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
462 /* legacy code, data-lanes is the property of mdss_dp node */
463 cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
467 msm_dp_panel->max_dp_lanes = cnt;
469 msm_dp_panel->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
471 msm_dp_panel->max_dp_link_rate = msm_dp_panel_link_frequencies(of_node);
472 if (!msm_dp_panel->max_dp_link_rate)
473 msm_dp_panel->max_dp_link_rate = DP_LINK_RATE_HBR2;
478 struct msm_dp_panel *msm_dp_panel_get(struct device *dev, struct drm_dp_aux *aux,
479 struct msm_dp_link *link, struct msm_dp_catalog *catalog)
481 struct msm_dp_panel_private *panel;
482 struct msm_dp_panel *msm_dp_panel;
485 if (!dev || !catalog || !aux || !link) {
486 DRM_ERROR("invalid input\n");
487 return ERR_PTR(-EINVAL);
490 panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
492 return ERR_PTR(-ENOMEM);
496 panel->catalog = catalog;
499 msm_dp_panel = &panel->msm_dp_panel;
500 msm_dp_panel->max_bw_code = DP_LINK_BW_8_1;
502 ret = msm_dp_panel_parse_dt(msm_dp_panel);
509 void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel)
514 drm_edid_free(msm_dp_panel->drm_edid);