1 /*
2  * Copyright 2015 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #include <linux/string.h>
27 #include <linux/acpi.h>
28 #include <linux/version.h>
29 #include <linux/i2c.h>
30 
31 #include <drm/drm_probe_helper.h>
32 #include <drm/amdgpu_drm.h>
33 #include <drm/drm_edid.h>
34 
35 #include "dm_services.h"
36 #include "amdgpu.h"
37 #include "dc.h"
38 #include "amdgpu_dm.h"
39 #include "amdgpu_dm_irq.h"
40 
41 #include "dm_helpers.h"
42 
43 /* dm_helpers_parse_edid_caps
44  *
45  * Parse edid caps
46  *
47  * @edid:	[in] pointer to edid
48  *  edid_caps:	[in] pointer to edid caps
49  * @return
50  *	void
51  * */
52 enum dc_edid_status dm_helpers_parse_edid_caps(
53 		struct dc_context *ctx,
54 		const struct dc_edid *edid,
55 		struct dc_edid_caps *edid_caps)
56 {
57 	struct edid *edid_buf = (struct edid *) edid->raw_edid;
58 	struct cea_sad *sads;
59 	int sad_count = -1;
60 	int sadb_count = -1;
61 	int i = 0;
62 	int j = 0;
63 	uint8_t *sadb = NULL;
64 
65 	enum dc_edid_status result = EDID_OK;
66 
67 	if (!edid_caps || !edid)
68 		return EDID_BAD_INPUT;
69 
70 	if (!drm_edid_is_valid(edid_buf))
71 		result = EDID_BAD_CHECKSUM;
72 
73 	edid_caps->manufacturer_id = (uint16_t) edid_buf->mfg_id[0] |
74 					((uint16_t) edid_buf->mfg_id[1])<<8;
75 	edid_caps->product_id = (uint16_t) edid_buf->prod_code[0] |
76 					((uint16_t) edid_buf->prod_code[1])<<8;
77 	edid_caps->serial_number = edid_buf->serial;
78 	edid_caps->manufacture_week = edid_buf->mfg_week;
79 	edid_caps->manufacture_year = edid_buf->mfg_year;
80 
81 	/* One of the four detailed_timings stores the monitor name. It's
82 	 * stored in an array of length 13. */
83 	for (i = 0; i < 4; i++) {
84 		if (edid_buf->detailed_timings[i].data.other_data.type == 0xfc) {
85 			while (j < 13 && edid_buf->detailed_timings[i].data.other_data.data.str.str[j]) {
86 				if (edid_buf->detailed_timings[i].data.other_data.data.str.str[j] == '\n')
87 					break;
88 
89 				edid_caps->display_name[j] =
90 					edid_buf->detailed_timings[i].data.other_data.data.str.str[j];
91 				j++;
92 			}
93 		}
94 	}
95 
96 	edid_caps->edid_hdmi = drm_detect_hdmi_monitor(
97 			(struct edid *) edid->raw_edid);
98 
99 	sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
100 	if (sad_count < 0)
101 		DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
102 	if (sad_count <= 0)
103 		return result;
104 
105 	edid_caps->audio_mode_count = sad_count < DC_MAX_AUDIO_DESC_COUNT ? sad_count : DC_MAX_AUDIO_DESC_COUNT;
106 	for (i = 0; i < edid_caps->audio_mode_count; ++i) {
107 		struct cea_sad *sad = &sads[i];
108 
109 		edid_caps->audio_modes[i].format_code = sad->format;
110 		edid_caps->audio_modes[i].channel_count = sad->channels + 1;
111 		edid_caps->audio_modes[i].sample_rate = sad->freq;
112 		edid_caps->audio_modes[i].sample_size = sad->byte2;
113 	}
114 
115 	sadb_count = drm_edid_to_speaker_allocation((struct edid *) edid->raw_edid, &sadb);
116 
117 	if (sadb_count < 0) {
118 		DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sadb_count);
119 		sadb_count = 0;
120 	}
121 
122 	if (sadb_count)
123 		edid_caps->speaker_flags = sadb[0];
124 	else
125 		edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION;
126 
127 	kfree(sads);
128 	kfree(sadb);
129 
130 	return result;
131 }
132 
133 static void get_payload_table(
134 		struct amdgpu_dm_connector *aconnector,
135 		struct dp_mst_stream_allocation_table *proposed_table)
136 {
137 	int i;
138 	struct drm_dp_mst_topology_mgr *mst_mgr =
139 			&aconnector->mst_port->mst_mgr;
140 
141 	mutex_lock(&mst_mgr->payload_lock);
142 
143 	proposed_table->stream_count = 0;
144 
145 	/* number of active streams */
146 	for (i = 0; i < mst_mgr->max_payloads; i++) {
147 		if (mst_mgr->payloads[i].num_slots == 0)
148 			break; /* end of vcp_id table */
149 
150 		ASSERT(mst_mgr->payloads[i].payload_state !=
151 				DP_PAYLOAD_DELETE_LOCAL);
152 
153 		if (mst_mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL ||
154 			mst_mgr->payloads[i].payload_state ==
155 					DP_PAYLOAD_REMOTE) {
156 
157 			struct dp_mst_stream_allocation *sa =
158 					&proposed_table->stream_allocations[
159 						proposed_table->stream_count];
160 
161 			sa->slot_count = mst_mgr->payloads[i].num_slots;
162 			sa->vcp_id = mst_mgr->proposed_vcpis[i]->vcpi;
163 			proposed_table->stream_count++;
164 		}
165 	}
166 
167 	mutex_unlock(&mst_mgr->payload_lock);
168 }
169 
170 void dm_helpers_dp_update_branch_info(
171 	struct dc_context *ctx,
172 	const struct dc_link *link)
173 {}
174 
175 /*
176  * Writes payload allocation table in immediate downstream device.
177  */
178 bool dm_helpers_dp_mst_write_payload_allocation_table(
179 		struct dc_context *ctx,
180 		const struct dc_stream_state *stream,
181 		struct dp_mst_stream_allocation_table *proposed_table,
182 		bool enable)
183 {
184 	struct amdgpu_dm_connector *aconnector;
185 	struct drm_dp_mst_topology_mgr *mst_mgr;
186 	struct drm_dp_mst_port *mst_port;
187 	int slots = 0;
188 	bool ret;
189 	int clock;
190 	int bpp = 0;
191 	int pbn = 0;
192 
193 	aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
194 
195 	if (!aconnector || !aconnector->mst_port)
196 		return false;
197 
198 	mst_mgr = &aconnector->mst_port->mst_mgr;
199 
200 	if (!mst_mgr->mst_state)
201 		return false;
202 
203 	mst_port = aconnector->port;
204 
205 	if (enable) {
206 		clock = stream->timing.pix_clk_100hz / 10;
207 
208 		switch (stream->timing.display_color_depth) {
209 
210 		case COLOR_DEPTH_666:
211 			bpp = 6;
212 			break;
213 		case COLOR_DEPTH_888:
214 			bpp = 8;
215 			break;
216 		case COLOR_DEPTH_101010:
217 			bpp = 10;
218 			break;
219 		case COLOR_DEPTH_121212:
220 			bpp = 12;
221 			break;
222 		case COLOR_DEPTH_141414:
223 			bpp = 14;
224 			break;
225 		case COLOR_DEPTH_161616:
226 			bpp = 16;
227 			break;
228 		default:
229 			ASSERT(bpp != 0);
230 			break;
231 		}
232 
233 		bpp = bpp * 3;
234 
235 		/* TODO need to know link rate */
236 
237 		pbn = drm_dp_calc_pbn_mode(clock, bpp);
238 
239 		slots = drm_dp_find_vcpi_slots(mst_mgr, pbn);
240 		ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port, pbn, slots);
241 
242 		if (!ret)
243 			return false;
244 
245 	} else {
246 		drm_dp_mst_reset_vcpi_slots(mst_mgr, mst_port);
247 	}
248 
249 	ret = drm_dp_update_payload_part1(mst_mgr);
250 
251 	/* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
252 	 * AUX message. The sequence is slot 1-63 allocated sequence for each
253 	 * stream. AMD ASIC stream slot allocation should follow the same
254 	 * sequence. copy DRM MST allocation to dc */
255 
256 	get_payload_table(aconnector, proposed_table);
257 
258 	if (ret)
259 		return false;
260 
261 	return true;
262 }
263 
264 /*
265  * poll pending down reply
266  */
267 void dm_helpers_dp_mst_poll_pending_down_reply(
268 	struct dc_context *ctx,
269 	const struct dc_link *link)
270 {}
271 
272 /*
273  * Clear payload allocation table before enable MST DP link.
274  */
275 void dm_helpers_dp_mst_clear_payload_allocation_table(
276 	struct dc_context *ctx,
277 	const struct dc_link *link)
278 {}
279 
280 /*
281  * Polls for ACT (allocation change trigger) handled and sends
282  * ALLOCATE_PAYLOAD message.
283  */
284 enum act_return_status dm_helpers_dp_mst_poll_for_allocation_change_trigger(
285 		struct dc_context *ctx,
286 		const struct dc_stream_state *stream)
287 {
288 	struct amdgpu_dm_connector *aconnector;
289 	struct drm_dp_mst_topology_mgr *mst_mgr;
290 	int ret;
291 
292 	aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
293 
294 	if (!aconnector || !aconnector->mst_port)
295 		return ACT_FAILED;
296 
297 	mst_mgr = &aconnector->mst_port->mst_mgr;
298 
299 	if (!mst_mgr->mst_state)
300 		return ACT_FAILED;
301 
302 	ret = drm_dp_check_act_status(mst_mgr);
303 
304 	if (ret)
305 		return ACT_FAILED;
306 
307 	return ACT_SUCCESS;
308 }
309 
310 bool dm_helpers_dp_mst_send_payload_allocation(
311 		struct dc_context *ctx,
312 		const struct dc_stream_state *stream,
313 		bool enable)
314 {
315 	struct amdgpu_dm_connector *aconnector;
316 	struct drm_dp_mst_topology_mgr *mst_mgr;
317 	struct drm_dp_mst_port *mst_port;
318 	int ret;
319 
320 	aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
321 
322 	if (!aconnector || !aconnector->mst_port)
323 		return false;
324 
325 	mst_port = aconnector->port;
326 
327 	mst_mgr = &aconnector->mst_port->mst_mgr;
328 
329 	if (!mst_mgr->mst_state)
330 		return false;
331 
332 	ret = drm_dp_update_payload_part2(mst_mgr);
333 
334 	if (ret)
335 		return false;
336 
337 	if (!enable)
338 		drm_dp_mst_deallocate_vcpi(mst_mgr, mst_port);
339 
340 	return true;
341 }
342 
343 void dm_dtn_log_begin(struct dc_context *ctx,
344 	struct dc_log_buffer_ctx *log_ctx)
345 {
346 	static const char msg[] = "[dtn begin]\n";
347 
348 	if (!log_ctx) {
349 		pr_info("%s", msg);
350 		return;
351 	}
352 
353 	dm_dtn_log_append_v(ctx, log_ctx, "%s", msg);
354 }
355 
356 void dm_dtn_log_append_v(struct dc_context *ctx,
357 	struct dc_log_buffer_ctx *log_ctx,
358 	const char *msg, ...)
359 {
360 	va_list args;
361 	size_t total;
362 	int n;
363 
364 	if (!log_ctx) {
365 		/* No context, redirect to dmesg. */
366 		struct va_format vaf;
367 
368 		vaf.fmt = msg;
369 		vaf.va = &args;
370 
371 		va_start(args, msg);
372 		pr_info("%pV", &vaf);
373 		va_end(args);
374 
375 		return;
376 	}
377 
378 	/* Measure the output. */
379 	va_start(args, msg);
380 	n = vsnprintf(NULL, 0, msg, args);
381 	va_end(args);
382 
383 	if (n <= 0)
384 		return;
385 
386 	/* Reallocate the string buffer as needed. */
387 	total = log_ctx->pos + n + 1;
388 
389 	if (total > log_ctx->size) {
390 		char *buf = (char *)kvcalloc(total, sizeof(char), GFP_KERNEL);
391 
392 		if (buf) {
393 			memcpy(buf, log_ctx->buf, log_ctx->pos);
394 			kfree(log_ctx->buf);
395 
396 			log_ctx->buf = buf;
397 			log_ctx->size = total;
398 		}
399 	}
400 
401 	if (!log_ctx->buf)
402 		return;
403 
404 	/* Write the formatted string to the log buffer. */
405 	va_start(args, msg);
406 	n = vscnprintf(
407 		log_ctx->buf + log_ctx->pos,
408 		log_ctx->size - log_ctx->pos,
409 		msg,
410 		args);
411 	va_end(args);
412 
413 	if (n > 0)
414 		log_ctx->pos += n;
415 }
416 
417 void dm_dtn_log_end(struct dc_context *ctx,
418 	struct dc_log_buffer_ctx *log_ctx)
419 {
420 	static const char msg[] = "[dtn end]\n";
421 
422 	if (!log_ctx) {
423 		pr_info("%s", msg);
424 		return;
425 	}
426 
427 	dm_dtn_log_append_v(ctx, log_ctx, "%s", msg);
428 }
429 
430 bool dm_helpers_dp_mst_start_top_mgr(
431 		struct dc_context *ctx,
432 		const struct dc_link *link,
433 		bool boot)
434 {
435 	struct amdgpu_dm_connector *aconnector = link->priv;
436 
437 	if (!aconnector) {
438 			DRM_ERROR("Failed to found connector for link!");
439 			return false;
440 	}
441 
442 	if (boot) {
443 		DRM_INFO("DM_MST: Differing MST start on aconnector: %p [id: %d]\n",
444 					aconnector, aconnector->base.base.id);
445 		return true;
446 	}
447 
448 	DRM_INFO("DM_MST: starting TM on aconnector: %p [id: %d]\n",
449 			aconnector, aconnector->base.base.id);
450 
451 	return (drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true) == 0);
452 }
453 
454 void dm_helpers_dp_mst_stop_top_mgr(
455 		struct dc_context *ctx,
456 		const struct dc_link *link)
457 {
458 	struct amdgpu_dm_connector *aconnector = link->priv;
459 
460 	if (!aconnector) {
461 			DRM_ERROR("Failed to found connector for link!");
462 			return;
463 	}
464 
465 	DRM_INFO("DM_MST: stopping TM on aconnector: %p [id: %d]\n",
466 			aconnector, aconnector->base.base.id);
467 
468 	if (aconnector->mst_mgr.mst_state == true)
469 		drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, false);
470 }
471 
472 bool dm_helpers_dp_read_dpcd(
473 		struct dc_context *ctx,
474 		const struct dc_link *link,
475 		uint32_t address,
476 		uint8_t *data,
477 		uint32_t size)
478 {
479 
480 	struct amdgpu_dm_connector *aconnector = link->priv;
481 
482 	if (!aconnector) {
483 		DRM_ERROR("Failed to found connector for link!");
484 		return false;
485 	}
486 
487 	return drm_dp_dpcd_read(&aconnector->dm_dp_aux.aux, address,
488 			data, size) > 0;
489 }
490 
491 bool dm_helpers_dp_write_dpcd(
492 		struct dc_context *ctx,
493 		const struct dc_link *link,
494 		uint32_t address,
495 		const uint8_t *data,
496 		uint32_t size)
497 {
498 	struct amdgpu_dm_connector *aconnector = link->priv;
499 
500 	if (!aconnector) {
501 		DRM_ERROR("Failed to found connector for link!");
502 		return false;
503 	}
504 
505 	return drm_dp_dpcd_write(&aconnector->dm_dp_aux.aux,
506 			address, (uint8_t *)data, size) > 0;
507 }
508 
509 bool dm_helpers_submit_i2c(
510 		struct dc_context *ctx,
511 		const struct dc_link *link,
512 		struct i2c_command *cmd)
513 {
514 	struct amdgpu_dm_connector *aconnector = link->priv;
515 	struct i2c_msg *msgs;
516 	int i = 0;
517 	int num = cmd->number_of_payloads;
518 	bool result;
519 
520 	if (!aconnector) {
521 		DRM_ERROR("Failed to found connector for link!");
522 		return false;
523 	}
524 
525 	msgs = kcalloc(num, sizeof(struct i2c_msg), GFP_KERNEL);
526 
527 	if (!msgs)
528 		return false;
529 
530 	for (i = 0; i < num; i++) {
531 		msgs[i].flags = cmd->payloads[i].write ? 0 : I2C_M_RD;
532 		msgs[i].addr = cmd->payloads[i].address;
533 		msgs[i].len = cmd->payloads[i].length;
534 		msgs[i].buf = cmd->payloads[i].data;
535 	}
536 
537 	result = i2c_transfer(&aconnector->i2c->base, msgs, num) == num;
538 
539 	kfree(msgs);
540 
541 	return result;
542 }
543 #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
544 bool dm_helpers_dp_write_dsc_enable(
545 		struct dc_context *ctx,
546 		const struct dc_stream_state *stream,
547 		bool enable
548 )
549 {
550 	uint8_t enable_dsc = enable ? 1 : 0;
551 
552 	return dm_helpers_dp_write_dpcd(ctx, stream->sink->link, DP_DSC_ENABLE, &enable_dsc, 1);
553 }
554 #endif
555 
556 bool dm_helpers_is_dp_sink_present(struct dc_link *link)
557 {
558 	bool dp_sink_present;
559 	struct amdgpu_dm_connector *aconnector = link->priv;
560 
561 	if (!aconnector) {
562 		BUG_ON("Failed to found connector for link!");
563 		return true;
564 	}
565 
566 	mutex_lock(&aconnector->dm_dp_aux.aux.hw_mutex);
567 	dp_sink_present = dc_link_is_dp_sink_present(link);
568 	mutex_unlock(&aconnector->dm_dp_aux.aux.hw_mutex);
569 	return dp_sink_present;
570 }
571 
572 enum dc_edid_status dm_helpers_read_local_edid(
573 		struct dc_context *ctx,
574 		struct dc_link *link,
575 		struct dc_sink *sink)
576 {
577 	struct amdgpu_dm_connector *aconnector = link->priv;
578 	struct i2c_adapter *ddc;
579 	int retry = 3;
580 	enum dc_edid_status edid_status;
581 	struct edid *edid;
582 
583 	if (link->aux_mode)
584 		ddc = &aconnector->dm_dp_aux.aux.ddc;
585 	else
586 		ddc = &aconnector->i2c->base;
587 
588 	/* some dongles read edid incorrectly the first time,
589 	 * do check sum and retry to make sure read correct edid.
590 	 */
591 	do {
592 
593 		edid = drm_get_edid(&aconnector->base, ddc);
594 
595 		if (!edid)
596 			return EDID_NO_RESPONSE;
597 
598 		sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1);
599 		memmove(sink->dc_edid.raw_edid, (uint8_t *)edid, sink->dc_edid.length);
600 
601 		/* We don't need the original edid anymore */
602 		kfree(edid);
603 
604 		edid_status = dm_helpers_parse_edid_caps(
605 						ctx,
606 						&sink->dc_edid,
607 						&sink->edid_caps);
608 
609 	} while (edid_status == EDID_BAD_CHECKSUM && --retry > 0);
610 
611 	if (edid_status != EDID_OK)
612 		DRM_ERROR("EDID err: %d, on connector: %s",
613 				edid_status,
614 				aconnector->base.name);
615 	if (link->aux_mode) {
616 		union test_request test_request = { {0} };
617 		union test_response test_response = { {0} };
618 
619 		dm_helpers_dp_read_dpcd(ctx,
620 					link,
621 					DP_TEST_REQUEST,
622 					&test_request.raw,
623 					sizeof(union test_request));
624 
625 		if (!test_request.bits.EDID_READ)
626 			return edid_status;
627 
628 		test_response.bits.EDID_CHECKSUM_WRITE = 1;
629 
630 		dm_helpers_dp_write_dpcd(ctx,
631 					link,
632 					DP_TEST_EDID_CHECKSUM,
633 					&sink->dc_edid.raw_edid[sink->dc_edid.length-1],
634 					1);
635 
636 		dm_helpers_dp_write_dpcd(ctx,
637 					link,
638 					DP_TEST_RESPONSE,
639 					&test_response.raw,
640 					sizeof(test_response));
641 
642 	}
643 
644 	return edid_status;
645 }
646 
647 void dm_set_dcn_clocks(struct dc_context *ctx, struct dc_clocks *clks)
648 {
649 	/* TODO: something */
650 }
651