Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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_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	4
 15#define DP_LINK_RATE_HBR2	540000 /* kbytes */
 16
 17struct msm_dp_panel_private {
 18	struct device *dev;
 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;
 24	bool panel_on;
 25};
 26
 27static void msm_dp_panel_read_psr_cap(struct msm_dp_panel_private *panel)
 28{
 29	ssize_t rlen;
 30	struct msm_dp_panel *msm_dp_panel;
 31
 32	msm_dp_panel = &panel->msm_dp_panel;
 33
 34	/* edp sink */
 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);
 43		} else
 44			DRM_ERROR("failed to read psr info, rlen=%zd\n", rlen);
 45	}
 46}
 47
 48static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
 49{
 50	int rc;
 51	struct msm_dp_panel_private *panel;
 52	struct msm_dp_link_info *link_info;
 53	u8 *dpcd, major, minor;
 54
 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);
 58	if (rc)
 59		return rc;
 60
 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;
 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 > msm_dp_panel->max_dp_lanes)
 72		link_info->num_lanes = msm_dp_panel->max_dp_lanes;
 73
 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;
 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	msm_dp_panel_read_psr_cap(panel);
 86
 87	return rc;
 88}
 89
 90static u32 msm_dp_panel_get_supported_bpp(struct msm_dp_panel *msm_dp_panel,
 91		u32 mode_edid_bpp, u32 mode_pclk_khz)
 92{
 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;
 96
 97	bpp = min(mode_edid_bpp, max_supported_bpp);
 98
 99	link_info = &msm_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 msm_dp_panel_read_sink_caps(struct msm_dp_panel *msm_dp_panel,
112	struct drm_connector *connector)
113{
114	int rc, bw_code;
115	int count;
116	struct msm_dp_panel_private *panel;
117
118	if (!msm_dp_panel || !connector) {
119		DRM_ERROR("invalid input\n");
120		return -EINVAL;
121	}
122
123	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
124
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);
127
128	rc = msm_dp_panel_read_dpcd(msm_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(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);
140		return -EINVAL;
141	}
142
143	if (drm_dp_is_branch(msm_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, msm_dp_panel->dpcd,
152					 msm_dp_panel->downstream_ports);
153	if (rc)
154		return rc;
155
156	drm_edid_free(msm_dp_panel->drm_edid);
157
158	msm_dp_panel->drm_edid = drm_edid_read_ddc(connector, &panel->aux->ddc);
159
160	drm_edid_connector_update(connector, msm_dp_panel->drm_edid);
161
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)) {
166			rc = -ETIMEDOUT;
167			goto end;
168		}
169	}
170
171end:
172	return rc;
173}
174
175u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,
176		u32 mode_edid_bpp, u32 mode_pclk_khz)
177{
178	struct msm_dp_panel_private *panel;
179	u32 bpp;
180
181	if (!msm_dp_panel || !mode_edid_bpp || !mode_pclk_khz) {
182		DRM_ERROR("invalid input\n");
183		return 0;
184	}
185
186	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
187
188	if (msm_dp_panel->video_test)
189		bpp = msm_dp_link_bit_depth_to_bpp(
190				panel->link->test_video.test_bit_depth);
191	else
192		bpp = msm_dp_panel_get_supported_bpp(msm_dp_panel, mode_edid_bpp,
193				mode_pclk_khz);
194
195	return bpp;
196}
197
198int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
199	struct drm_connector *connector)
200{
201	if (!msm_dp_panel) {
202		DRM_ERROR("invalid input\n");
203		return -EINVAL;
204	}
205
206	if (msm_dp_panel->drm_edid)
207		return drm_edid_connector_add_modes(connector);
208
209	return 0;
210}
211
212static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid)
213{
214	edid += edid->extensions;
215
216	return edid->checksum;
217}
218
219void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel)
220{
221	struct msm_dp_panel_private *panel;
222
223	if (!msm_dp_panel) {
224		DRM_ERROR("invalid input\n");
225		return;
226	}
227
228	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_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(msm_dp_panel->drm_edid);
233		u8 checksum;
234
235		if (edid)
236			checksum = msm_dp_panel_get_edid_checksum(edid);
237		else
238			checksum = msm_dp_panel->connector->real_edid_checksum;
239
240		msm_dp_link_send_edid_checksum(panel->link, checksum);
241		msm_dp_link_send_test_response(panel->link);
242	}
243}
244
245void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable)
246{
247	struct msm_dp_catalog *catalog;
248	struct msm_dp_panel_private *panel;
249
250	if (!msm_dp_panel) {
251		DRM_ERROR("invalid input\n");
252		return;
253	}
254
255	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_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		msm_dp_catalog_panel_tpg_disable(catalog);
266		return;
267	}
268
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);
271}
272
273static int msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel *msm_dp_panel)
274{
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;
280	ssize_t len;
281
282	if (!msm_dp_panel) {
283		DRM_ERROR("invalid input\n");
284		return -EINVAL;
285	}
286
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;
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 = msm_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	msm_dp_catalog_panel_enable_vsc_sdp(catalog, &vsc_sdp);
316
317	return 0;
318}
319
320void msm_dp_panel_dump_regs(struct msm_dp_panel *msm_dp_panel)
321{
322	struct msm_dp_catalog *catalog;
323	struct msm_dp_panel_private *panel;
324
325	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
326	catalog = panel->catalog;
327
328	msm_dp_catalog_dump_regs(catalog);
329}
330
331int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel)
332{
333	u32 data, total_ver, total_hor;
334	struct msm_dp_catalog *catalog;
335	struct msm_dp_panel_private *panel;
336	struct drm_display_mode *drm_mode;
337	u32 width_blanking;
338	u32 sync_start;
339	u32 msm_dp_active;
340	u32 total;
341
342	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
343	catalog = panel->catalog;
344	drm_mode = &panel->msm_dp_panel.msm_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->msm_dp_panel.msm_dp_mode.v_active_low << 31);
375	data |= drm_mode->hsync_end - drm_mode->hsync_start;
376	data |= (panel->msm_dp_panel.msm_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	msm_dp_active = data;
385
386	msm_dp_catalog_panel_timing_cfg(catalog, total, sync_start, width_blanking, msm_dp_active);
387
388	if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
389		msm_dp_panel_setup_vsc_sdp_yuv_420(msm_dp_panel);
390
391	panel->panel_on = true;
392
393	return 0;
394}
395
396int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel)
397{
398	struct drm_display_mode *drm_mode;
399	struct msm_dp_panel_private *panel;
400
401	drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode;
402
403	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
404
405	/*
406	 * print resolution info as this is a result
407	 * of user initiated action of cable connection
408	 */
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", msm_dp_panel->msm_dp_mode.bpp);
425
426	msm_dp_panel->msm_dp_mode.bpp = msm_dp_panel_get_mode_bpp(msm_dp_panel, msm_dp_panel->msm_dp_mode.bpp,
427						      msm_dp_panel->msm_dp_mode.drm_mode.clock);
428
429	drm_dbg_dp(panel->drm_dev, "updated bpp = %d\n",
430				msm_dp_panel->msm_dp_mode.bpp);
431
432	return 0;
433}
434
435static u32 msm_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 msm_dp_panel_parse_dt(struct msm_dp_panel *msm_dp_panel)
460{
461	struct msm_dp_panel_private *panel;
462	struct device_node *of_node;
463	int cnt;
464
465	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
466	of_node = panel->dev->of_node;
467
468	/*
469	 * data-lanes is the property of msm_dp_out endpoint
470	 */
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		msm_dp_panel->max_dp_lanes = cnt;
479	else
480		msm_dp_panel->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
481
482	msm_dp_panel->max_dp_link_rate = msm_dp_panel_link_frequencies(of_node);
483	if (!msm_dp_panel->max_dp_link_rate)
484		msm_dp_panel->max_dp_link_rate = DP_LINK_RATE_HBR2;
485
486	return 0;
487}
488
489struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in)
490{
491	struct msm_dp_panel_private *panel;
492	struct msm_dp_panel *msm_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	msm_dp_panel = &panel->msm_dp_panel;
510	msm_dp_panel->max_bw_code = DP_LINK_BW_8_1;
511
512	ret = msm_dp_panel_parse_dt(msm_dp_panel);
513	if (ret)
514		return ERR_PTR(ret);
515
516	return msm_dp_panel;
517}
518
519void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel)
520{
521	if (!msm_dp_panel)
522		return;
523
524	drm_edid_free(msm_dp_panel->drm_edid);
525}