hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
....@@ -28,8 +28,7 @@
2828 #include <linux/version.h>
2929 #include <linux/i2c.h>
3030
31
-#include <drm/drmP.h>
32
-#include <drm/drm_crtc_helper.h>
31
+#include <drm/drm_probe_helper.h>
3332 #include <drm/amdgpu_drm.h>
3433 #include <drm/drm_edid.h>
3534
....@@ -38,6 +37,7 @@
3837 #include "dc.h"
3938 #include "amdgpu_dm.h"
4039 #include "amdgpu_dm_irq.h"
40
+#include "amdgpu_dm_mst_types.h"
4141
4242 #include "dm_helpers.h"
4343
....@@ -98,11 +98,8 @@
9898 (struct edid *) edid->raw_edid);
9999
100100 sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads);
101
- if (sad_count <= 0) {
102
- DRM_INFO("SADs count is: %d, don't need to read it\n",
103
- sad_count);
101
+ if (sad_count <= 0)
104102 return result;
105
- }
106103
107104 edid_caps->audio_mode_count = sad_count < DC_MAX_AUDIO_DESC_COUNT ? sad_count : DC_MAX_AUDIO_DESC_COUNT;
108105 for (i = 0; i < edid_caps->audio_mode_count; ++i) {
....@@ -184,18 +181,21 @@
184181 bool enable)
185182 {
186183 struct amdgpu_dm_connector *aconnector;
184
+ struct dm_connector_state *dm_conn_state;
187185 struct drm_dp_mst_topology_mgr *mst_mgr;
188186 struct drm_dp_mst_port *mst_port;
189
- int slots = 0;
190187 bool ret;
191
- int clock;
192
- int bpp = 0;
193
- int pbn = 0;
194188
195
- aconnector = stream->sink->priv;
189
+ aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
190
+ /* Accessing the connector state is required for vcpi_slots allocation
191
+ * and directly relies on behaviour in commit check
192
+ * that blocks before commit guaranteeing that the state
193
+ * is not gonna be swapped while still in use in commit tail */
196194
197195 if (!aconnector || !aconnector->mst_port)
198196 return false;
197
+
198
+ dm_conn_state = to_dm_connector_state(aconnector->base.state);
199199
200200 mst_mgr = &aconnector->mst_port->mst_mgr;
201201
....@@ -205,42 +205,10 @@
205205 mst_port = aconnector->port;
206206
207207 if (enable) {
208
- clock = stream->timing.pix_clk_khz;
209208
210
- switch (stream->timing.display_color_depth) {
211
-
212
- case COLOR_DEPTH_666:
213
- bpp = 6;
214
- break;
215
- case COLOR_DEPTH_888:
216
- bpp = 8;
217
- break;
218
- case COLOR_DEPTH_101010:
219
- bpp = 10;
220
- break;
221
- case COLOR_DEPTH_121212:
222
- bpp = 12;
223
- break;
224
- case COLOR_DEPTH_141414:
225
- bpp = 14;
226
- break;
227
- case COLOR_DEPTH_161616:
228
- bpp = 16;
229
- break;
230
- default:
231
- ASSERT(bpp != 0);
232
- break;
233
- }
234
-
235
- bpp = bpp * 3;
236
-
237
- /* TODO need to know link rate */
238
-
239
- pbn = drm_dp_calc_pbn_mode(clock, bpp);
240
-
241
- slots = drm_dp_find_vcpi_slots(mst_mgr, pbn);
242
- ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port, pbn, slots);
243
-
209
+ ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port,
210
+ dm_conn_state->pbn,
211
+ dm_conn_state->vcpi_slots);
244212 if (!ret)
245213 return false;
246214
....@@ -261,6 +229,13 @@
261229 return true;
262230 }
263231
232
+/*
233
+ * poll pending down reply
234
+ */
235
+void dm_helpers_dp_mst_poll_pending_down_reply(
236
+ struct dc_context *ctx,
237
+ const struct dc_link *link)
238
+{}
264239
265240 /*
266241 * Clear payload allocation table before enable MST DP link.
....@@ -274,7 +249,7 @@
274249 * Polls for ACT (allocation change trigger) handled and sends
275250 * ALLOCATE_PAYLOAD message.
276251 */
277
-bool dm_helpers_dp_mst_poll_for_allocation_change_trigger(
252
+enum act_return_status dm_helpers_dp_mst_poll_for_allocation_change_trigger(
278253 struct dc_context *ctx,
279254 const struct dc_stream_state *stream)
280255 {
....@@ -282,22 +257,22 @@
282257 struct drm_dp_mst_topology_mgr *mst_mgr;
283258 int ret;
284259
285
- aconnector = stream->sink->priv;
260
+ aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
286261
287262 if (!aconnector || !aconnector->mst_port)
288
- return false;
263
+ return ACT_FAILED;
289264
290265 mst_mgr = &aconnector->mst_port->mst_mgr;
291266
292267 if (!mst_mgr->mst_state)
293
- return false;
268
+ return ACT_FAILED;
294269
295270 ret = drm_dp_check_act_status(mst_mgr);
296271
297272 if (ret)
298
- return false;
273
+ return ACT_FAILED;
299274
300
- return true;
275
+ return ACT_SUCCESS;
301276 }
302277
303278 bool dm_helpers_dp_mst_send_payload_allocation(
....@@ -309,7 +284,7 @@
309284 struct drm_dp_mst_topology_mgr *mst_mgr;
310285 struct drm_dp_mst_port *mst_port;
311286
312
- aconnector = stream->sink->priv;
287
+ aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
313288
314289 if (!aconnector || !aconnector->mst_port)
315290 return false;
....@@ -330,15 +305,92 @@
330305 return true;
331306 }
332307
333
-void dm_dtn_log_begin(struct dc_context *ctx)
334
-{}
308
+void dm_dtn_log_begin(struct dc_context *ctx,
309
+ struct dc_log_buffer_ctx *log_ctx)
310
+{
311
+ static const char msg[] = "[dtn begin]\n";
312
+
313
+ if (!log_ctx) {
314
+ pr_info("%s", msg);
315
+ return;
316
+ }
317
+
318
+ dm_dtn_log_append_v(ctx, log_ctx, "%s", msg);
319
+}
335320
336321 void dm_dtn_log_append_v(struct dc_context *ctx,
337
- const char *pMsg, ...)
338
-{}
322
+ struct dc_log_buffer_ctx *log_ctx,
323
+ const char *msg, ...)
324
+{
325
+ va_list args;
326
+ size_t total;
327
+ int n;
339328
340
-void dm_dtn_log_end(struct dc_context *ctx)
341
-{}
329
+ if (!log_ctx) {
330
+ /* No context, redirect to dmesg. */
331
+ struct va_format vaf;
332
+
333
+ vaf.fmt = msg;
334
+ vaf.va = &args;
335
+
336
+ va_start(args, msg);
337
+ pr_info("%pV", &vaf);
338
+ va_end(args);
339
+
340
+ return;
341
+ }
342
+
343
+ /* Measure the output. */
344
+ va_start(args, msg);
345
+ n = vsnprintf(NULL, 0, msg, args);
346
+ va_end(args);
347
+
348
+ if (n <= 0)
349
+ return;
350
+
351
+ /* Reallocate the string buffer as needed. */
352
+ total = log_ctx->pos + n + 1;
353
+
354
+ if (total > log_ctx->size) {
355
+ char *buf = (char *)kvcalloc(total, sizeof(char), GFP_KERNEL);
356
+
357
+ if (buf) {
358
+ memcpy(buf, log_ctx->buf, log_ctx->pos);
359
+ kfree(log_ctx->buf);
360
+
361
+ log_ctx->buf = buf;
362
+ log_ctx->size = total;
363
+ }
364
+ }
365
+
366
+ if (!log_ctx->buf)
367
+ return;
368
+
369
+ /* Write the formatted string to the log buffer. */
370
+ va_start(args, msg);
371
+ n = vscnprintf(
372
+ log_ctx->buf + log_ctx->pos,
373
+ log_ctx->size - log_ctx->pos,
374
+ msg,
375
+ args);
376
+ va_end(args);
377
+
378
+ if (n > 0)
379
+ log_ctx->pos += n;
380
+}
381
+
382
+void dm_dtn_log_end(struct dc_context *ctx,
383
+ struct dc_log_buffer_ctx *log_ctx)
384
+{
385
+ static const char msg[] = "[dtn end]\n";
386
+
387
+ if (!log_ctx) {
388
+ pr_info("%s", msg);
389
+ return;
390
+ }
391
+
392
+ dm_dtn_log_append_v(ctx, log_ctx, "%s", msg);
393
+}
342394
343395 bool dm_helpers_dp_mst_start_top_mgr(
344396 struct dc_context *ctx,
....@@ -348,8 +400,8 @@
348400 struct amdgpu_dm_connector *aconnector = link->priv;
349401
350402 if (!aconnector) {
351
- DRM_ERROR("Failed to found connector for link!");
352
- return false;
403
+ DRM_ERROR("Failed to find connector for link!");
404
+ return false;
353405 }
354406
355407 if (boot) {
....@@ -371,8 +423,8 @@
371423 struct amdgpu_dm_connector *aconnector = link->priv;
372424
373425 if (!aconnector) {
374
- DRM_ERROR("Failed to found connector for link!");
375
- return;
426
+ DRM_ERROR("Failed to find connector for link!");
427
+ return;
376428 }
377429
378430 DRM_INFO("DM_MST: stopping TM on aconnector: %p [id: %d]\n",
....@@ -393,7 +445,7 @@
393445 struct amdgpu_dm_connector *aconnector = link->priv;
394446
395447 if (!aconnector) {
396
- DRM_ERROR("Failed to found connector for link!");
448
+ DC_LOG_DC("Failed to find connector for link!\n");
397449 return false;
398450 }
399451
....@@ -411,7 +463,7 @@
411463 struct amdgpu_dm_connector *aconnector = link->priv;
412464
413465 if (!aconnector) {
414
- DRM_ERROR("Failed to found connector for link!");
466
+ DRM_ERROR("Failed to find connector for link!");
415467 return false;
416468 }
417469
....@@ -431,7 +483,7 @@
431483 bool result;
432484
433485 if (!aconnector) {
434
- DRM_ERROR("Failed to found connector for link!");
486
+ DRM_ERROR("Failed to find connector for link!");
435487 return false;
436488 }
437489
....@@ -453,6 +505,32 @@
453505
454506 return result;
455507 }
508
+bool dm_helpers_dp_write_dsc_enable(
509
+ struct dc_context *ctx,
510
+ const struct dc_stream_state *stream,
511
+ bool enable
512
+)
513
+{
514
+ uint8_t enable_dsc = enable ? 1 : 0;
515
+ struct amdgpu_dm_connector *aconnector;
516
+
517
+ if (!stream)
518
+ return false;
519
+
520
+ if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
521
+ aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
522
+
523
+ if (!aconnector->dsc_aux)
524
+ return false;
525
+
526
+ return (drm_dp_dpcd_write(aconnector->dsc_aux, DP_DSC_ENABLE, &enable_dsc, 1) >= 0);
527
+ }
528
+
529
+ if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT)
530
+ return dm_helpers_dp_write_dpcd(ctx, stream->link, DP_DSC_ENABLE, &enable_dsc, 1);
531
+
532
+ return false;
533
+}
456534
457535 bool dm_helpers_is_dp_sink_present(struct dc_link *link)
458536 {
....@@ -460,7 +538,7 @@
460538 struct amdgpu_dm_connector *aconnector = link->priv;
461539
462540 if (!aconnector) {
463
- BUG_ON("Failed to found connector for link!");
541
+ BUG_ON("Failed to find connector for link!");
464542 return true;
465543 }
466544
....@@ -476,6 +554,7 @@
476554 struct dc_sink *sink)
477555 {
478556 struct amdgpu_dm_connector *aconnector = link->priv;
557
+ struct drm_connector *connector = &aconnector->base;
479558 struct i2c_adapter *ddc;
480559 int retry = 3;
481560 enum dc_edid_status edid_status;
....@@ -493,6 +572,15 @@
493572
494573 edid = drm_get_edid(&aconnector->base, ddc);
495574
575
+ /* DP Compliance Test 4.2.2.6 */
576
+ if (link->aux_mode && connector->edid_corrupt)
577
+ drm_dp_send_real_edid_checksum(&aconnector->dm_dp_aux.aux, connector->real_edid_checksum);
578
+
579
+ if (!edid && connector->edid_corrupt) {
580
+ connector->edid_corrupt = false;
581
+ return EDID_BAD_CHECKSUM;
582
+ }
583
+
496584 if (!edid)
497585 return EDID_NO_RESPONSE;
498586
....@@ -501,6 +589,20 @@
501589
502590 /* We don't need the original edid anymore */
503591 kfree(edid);
592
+
593
+ /* connector->display_info will be parsed from EDID and saved
594
+ * into drm_connector->display_info from edid by call stack
595
+ * below:
596
+ * drm_parse_ycbcr420_deep_color_info
597
+ * drm_parse_hdmi_forum_vsdb
598
+ * drm_parse_cea_ext
599
+ * drm_add_display_info
600
+ * drm_connector_update_edid_property
601
+ *
602
+ * drm_connector->display_info will be used by amdgpu_dm funcs,
603
+ * like fill_stream_properties_from_drm_display_mode
604
+ */
605
+ amdgpu_dm_update_connector_after_detect(aconnector);
504606
505607 edid_status = dm_helpers_parse_edid_caps(
506608 ctx,
....@@ -513,34 +615,10 @@
513615 DRM_ERROR("EDID err: %d, on connector: %s",
514616 edid_status,
515617 aconnector->base.name);
516
- if (link->aux_mode) {
517
- union test_request test_request = { {0} };
518
- union test_response test_response = { {0} };
519618
520
- dm_helpers_dp_read_dpcd(ctx,
521
- link,
522
- DP_TEST_REQUEST,
523
- &test_request.raw,
524
- sizeof(union test_request));
525
-
526
- if (!test_request.bits.EDID_READ)
527
- return edid_status;
528
-
529
- test_response.bits.EDID_CHECKSUM_WRITE = 1;
530
-
531
- dm_helpers_dp_write_dpcd(ctx,
532
- link,
533
- DP_TEST_EDID_CHECKSUM,
534
- &sink->dc_edid.raw_edid[sink->dc_edid.length-1],
535
- 1);
536
-
537
- dm_helpers_dp_write_dpcd(ctx,
538
- link,
539
- DP_TEST_RESPONSE,
540
- &test_response.raw,
541
- sizeof(test_response));
542
-
543
- }
619
+ /* DP Compliance Test 4.2.2.3 */
620
+ if (link->aux_mode)
621
+ drm_dp_send_real_edid_checksum(&aconnector->dm_dp_aux.aux, sink->dc_edid.raw_edid[sink->dc_edid.length-1]);
544622
545623 return edid_status;
546624 }
....@@ -549,3 +627,23 @@
549627 {
550628 /* TODO: something */
551629 }
630
+#ifdef CONFIG_DRM_AMD_DC_DCN3_0
631
+
632
+void *dm_helpers_allocate_gpu_mem(
633
+ struct dc_context *ctx,
634
+ enum dc_gpu_mem_alloc_type type,
635
+ size_t size,
636
+ long long *addr)
637
+{
638
+ // TODO
639
+ return NULL;
640
+}
641
+
642
+void dm_helpers_free_gpu_mem(
643
+ struct dc_context *ctx,
644
+ enum dc_gpu_mem_alloc_type type,
645
+ void *pvMem)
646
+{
647
+ // TODO
648
+}
649
+#endif