1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/uaccess.h>
27
28#include <drm/drm_debugfs.h>
29
30#include "dc.h"
31#include "amdgpu.h"
32#include "amdgpu_dm.h"
33#include "amdgpu_dm_debugfs.h"
34#include "dm_helpers.h"
35#include "dmub/dmub_srv.h"
36#include "resource.h"
37#include "dsc.h"
38#include "dc_link_dp.h"
39
40struct dmub_debugfs_trace_header {
41 uint32_t entry_count;
42 uint32_t reserved[3];
43};
44
45struct dmub_debugfs_trace_entry {
46 uint32_t trace_code;
47 uint32_t tick_count;
48 uint32_t param0;
49 uint32_t param1;
50};
51
52
53
54
55
56
57
58
59
60
61static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,
62 long *param, const char __user *buf,
63 int max_param_num,
64 uint8_t *param_nums)
65{
66 char *wr_buf_ptr = NULL;
67 uint32_t wr_buf_count = 0;
68 int r;
69 char *sub_str = NULL;
70 const char delimiter[3] = {' ', '\n', '\0'};
71 uint8_t param_index = 0;
72
73 *param_nums = 0;
74
75 wr_buf_ptr = wr_buf;
76
77 r = copy_from_user(wr_buf_ptr, buf, wr_buf_size);
78
79
80 if (r >= wr_buf_size) {
81 DRM_DEBUG_DRIVER("user data not be read\n");
82 return -EINVAL;
83 }
84
85
86 while ((*wr_buf_ptr != 0xa) && (wr_buf_count < wr_buf_size)) {
87
88 while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) {
89 wr_buf_ptr++;
90 wr_buf_count++;
91 }
92
93 if (wr_buf_count == wr_buf_size)
94 break;
95
96
97 while ((!isspace(*wr_buf_ptr)) && (wr_buf_count < wr_buf_size)) {
98 wr_buf_ptr++;
99 wr_buf_count++;
100 }
101
102 (*param_nums)++;
103
104 if (wr_buf_count == wr_buf_size)
105 break;
106 }
107
108 if (*param_nums > max_param_num)
109 *param_nums = max_param_num;
110;
111
112 wr_buf_ptr = wr_buf;
113 wr_buf_count = 0;
114
115 while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) {
116 wr_buf_ptr++;
117 wr_buf_count++;
118 }
119
120 while (param_index < *param_nums) {
121
122 sub_str = strsep(&wr_buf_ptr, delimiter);
123
124 r = kstrtol(sub_str, 16, &(param[param_index]));
125
126 if (r)
127 DRM_DEBUG_DRIVER("string to int convert error code: %d\n", r);
128
129 param_index++;
130 }
131
132 return 0;
133}
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
177 size_t size, loff_t *pos)
178{
179 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
180 struct dc_link *link = connector->dc_link;
181 char *rd_buf = NULL;
182 char *rd_buf_ptr = NULL;
183 const uint32_t rd_buf_size = 100;
184 uint32_t result = 0;
185 uint8_t str_len = 0;
186 int r;
187
188 if (*pos & 3 || size & 3)
189 return -EINVAL;
190
191 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
192 if (!rd_buf)
193 return 0;
194
195 rd_buf_ptr = rd_buf;
196
197 str_len = strlen("Current: %d %d %d ");
198 snprintf(rd_buf_ptr, str_len, "Current: %d %d %d ",
199 link->cur_link_settings.lane_count,
200 link->cur_link_settings.link_rate,
201 link->cur_link_settings.link_spread);
202 rd_buf_ptr += str_len;
203
204 str_len = strlen("Verified: %d %d %d ");
205 snprintf(rd_buf_ptr, str_len, "Verified: %d %d %d ",
206 link->verified_link_cap.lane_count,
207 link->verified_link_cap.link_rate,
208 link->verified_link_cap.link_spread);
209 rd_buf_ptr += str_len;
210
211 str_len = strlen("Reported: %d %d %d ");
212 snprintf(rd_buf_ptr, str_len, "Reported: %d %d %d ",
213 link->reported_link_cap.lane_count,
214 link->reported_link_cap.link_rate,
215 link->reported_link_cap.link_spread);
216 rd_buf_ptr += str_len;
217
218 str_len = strlen("Preferred: %d %d %d ");
219 snprintf(rd_buf_ptr, str_len, "Preferred: %d %d %d\n",
220 link->preferred_link_setting.lane_count,
221 link->preferred_link_setting.link_rate,
222 link->preferred_link_setting.link_spread);
223
224 while (size) {
225 if (*pos >= rd_buf_size)
226 break;
227
228 r = put_user(*(rd_buf + result), buf);
229 if (r)
230 return r;
231
232 buf += 1;
233 size -= 1;
234 *pos += 1;
235 result += 1;
236 }
237
238 kfree(rd_buf);
239 return result;
240}
241
242static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
243 size_t size, loff_t *pos)
244{
245 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
246 struct dc_link *link = connector->dc_link;
247 struct dc *dc = (struct dc *)link->dc;
248 struct dc_link_settings prefer_link_settings;
249 char *wr_buf = NULL;
250 const uint32_t wr_buf_size = 40;
251
252 int max_param_num = 2;
253 uint8_t param_nums = 0;
254 long param[2];
255 bool valid_input = false;
256
257 if (size == 0)
258 return -EINVAL;
259
260 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
261 if (!wr_buf)
262 return -ENOSPC;
263
264 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
265 (long *)param, buf,
266 max_param_num,
267 ¶m_nums)) {
268 kfree(wr_buf);
269 return -EINVAL;
270 }
271
272 if (param_nums <= 0) {
273 kfree(wr_buf);
274 DRM_DEBUG_DRIVER("user data not be read\n");
275 return -EINVAL;
276 }
277
278 switch (param[0]) {
279 case LANE_COUNT_ONE:
280 case LANE_COUNT_TWO:
281 case LANE_COUNT_FOUR:
282 valid_input = true;
283 break;
284 default:
285 break;
286 }
287
288 switch (param[1]) {
289 case LINK_RATE_LOW:
290 case LINK_RATE_HIGH:
291 case LINK_RATE_RBR2:
292 case LINK_RATE_HIGH2:
293 case LINK_RATE_HIGH3:
294 valid_input = true;
295 break;
296 default:
297 break;
298 }
299
300 if (!valid_input) {
301 kfree(wr_buf);
302 DRM_DEBUG_DRIVER("Invalid Input value No HW will be programmed\n");
303 return size;
304 }
305
306
307
308
309 prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
310 prefer_link_settings.lane_count = param[0];
311 prefer_link_settings.link_rate = param[1];
312
313 dc_link_set_preferred_link_settings(dc, &prefer_link_settings, link);
314
315 kfree(wr_buf);
316 return size;
317}
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360static ssize_t dp_phy_settings_read(struct file *f, char __user *buf,
361 size_t size, loff_t *pos)
362{
363 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
364 struct dc_link *link = connector->dc_link;
365 char *rd_buf = NULL;
366 const uint32_t rd_buf_size = 20;
367 uint32_t result = 0;
368 int r;
369
370 if (*pos & 3 || size & 3)
371 return -EINVAL;
372
373 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
374 if (!rd_buf)
375 return -EINVAL;
376
377 snprintf(rd_buf, rd_buf_size, " %d %d %d ",
378 link->cur_lane_setting.VOLTAGE_SWING,
379 link->cur_lane_setting.PRE_EMPHASIS,
380 link->cur_lane_setting.POST_CURSOR2);
381
382 while (size) {
383 if (*pos >= rd_buf_size)
384 break;
385
386 r = put_user((*(rd_buf + result)), buf);
387 if (r)
388 return r;
389
390 buf += 1;
391 size -= 1;
392 *pos += 1;
393 result += 1;
394 }
395
396 kfree(rd_buf);
397 return result;
398}
399
400static ssize_t dp_phy_settings_write(struct file *f, const char __user *buf,
401 size_t size, loff_t *pos)
402{
403 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
404 struct dc_link *link = connector->dc_link;
405 struct dc *dc = (struct dc *)link->dc;
406 char *wr_buf = NULL;
407 uint32_t wr_buf_size = 40;
408 long param[3];
409 bool use_prefer_link_setting;
410 struct link_training_settings link_lane_settings;
411 int max_param_num = 3;
412 uint8_t param_nums = 0;
413 int r = 0;
414
415
416 if (size == 0)
417 return -EINVAL;
418
419 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
420 if (!wr_buf)
421 return -ENOSPC;
422
423 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
424 (long *)param, buf,
425 max_param_num,
426 ¶m_nums)) {
427 kfree(wr_buf);
428 return -EINVAL;
429 }
430
431 if (param_nums <= 0) {
432 kfree(wr_buf);
433 DRM_DEBUG_DRIVER("user data not be read\n");
434 return -EINVAL;
435 }
436
437 if ((param[0] > VOLTAGE_SWING_MAX_LEVEL) ||
438 (param[1] > PRE_EMPHASIS_MAX_LEVEL) ||
439 (param[2] > POST_CURSOR2_MAX_LEVEL)) {
440 kfree(wr_buf);
441 DRM_DEBUG_DRIVER("Invalid Input No HW will be programmed\n");
442 return size;
443 }
444
445
446 use_prefer_link_setting =
447 ((link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) &&
448 (link->test_pattern_enabled));
449
450 memset(&link_lane_settings, 0, sizeof(link_lane_settings));
451
452 if (use_prefer_link_setting) {
453 link_lane_settings.link_settings.lane_count =
454 link->preferred_link_setting.lane_count;
455 link_lane_settings.link_settings.link_rate =
456 link->preferred_link_setting.link_rate;
457 link_lane_settings.link_settings.link_spread =
458 link->preferred_link_setting.link_spread;
459 } else {
460 link_lane_settings.link_settings.lane_count =
461 link->cur_link_settings.lane_count;
462 link_lane_settings.link_settings.link_rate =
463 link->cur_link_settings.link_rate;
464 link_lane_settings.link_settings.link_spread =
465 link->cur_link_settings.link_spread;
466 }
467
468
469 for (r = 0; r < link_lane_settings.link_settings.lane_count; r++) {
470 link_lane_settings.lane_settings[r].VOLTAGE_SWING =
471 (enum dc_voltage_swing) (param[0]);
472 link_lane_settings.lane_settings[r].PRE_EMPHASIS =
473 (enum dc_pre_emphasis) (param[1]);
474 link_lane_settings.lane_settings[r].POST_CURSOR2 =
475 (enum dc_post_cursor2) (param[2]);
476 }
477
478
479 dc_link_set_drive_settings(dc, &link_lane_settings, link);
480
481 kfree(wr_buf);
482 return size;
483}
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __user *buf,
544 size_t size, loff_t *pos)
545{
546 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
547 struct dc_link *link = connector->dc_link;
548 char *wr_buf = NULL;
549 uint32_t wr_buf_size = 100;
550 long param[11] = {0x0};
551 int max_param_num = 11;
552 enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
553 bool disable_hpd = false;
554 bool valid_test_pattern = false;
555 uint8_t param_nums = 0;
556
557 uint8_t custom_pattern[10] = {
558 0x1f, 0x7c, 0xf0, 0xc1, 0x07,
559 0x1f, 0x7c, 0xf0, 0xc1, 0x07
560 };
561 struct dc_link_settings prefer_link_settings = {LANE_COUNT_UNKNOWN,
562 LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED};
563 struct dc_link_settings cur_link_settings = {LANE_COUNT_UNKNOWN,
564 LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED};
565 struct link_training_settings link_training_settings;
566 int i;
567
568 if (size == 0)
569 return -EINVAL;
570
571 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
572 if (!wr_buf)
573 return -ENOSPC;
574
575 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
576 (long *)param, buf,
577 max_param_num,
578 ¶m_nums)) {
579 kfree(wr_buf);
580 return -EINVAL;
581 }
582
583 if (param_nums <= 0) {
584 kfree(wr_buf);
585 DRM_DEBUG_DRIVER("user data not be read\n");
586 return -EINVAL;
587 }
588
589
590 test_pattern = param[0];
591
592 switch (test_pattern) {
593 case DP_TEST_PATTERN_VIDEO_MODE:
594 case DP_TEST_PATTERN_COLOR_SQUARES:
595 case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
596 case DP_TEST_PATTERN_VERTICAL_BARS:
597 case DP_TEST_PATTERN_HORIZONTAL_BARS:
598 case DP_TEST_PATTERN_COLOR_RAMP:
599 valid_test_pattern = true;
600 break;
601
602 case DP_TEST_PATTERN_D102:
603 case DP_TEST_PATTERN_SYMBOL_ERROR:
604 case DP_TEST_PATTERN_PRBS7:
605 case DP_TEST_PATTERN_80BIT_CUSTOM:
606 case DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE:
607 case DP_TEST_PATTERN_TRAINING_PATTERN4:
608 disable_hpd = true;
609 valid_test_pattern = true;
610 break;
611
612 default:
613 valid_test_pattern = false;
614 test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
615 break;
616 }
617
618 if (!valid_test_pattern) {
619 kfree(wr_buf);
620 DRM_DEBUG_DRIVER("Invalid Test Pattern Parameters\n");
621 return size;
622 }
623
624 if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) {
625 for (i = 0; i < 10; i++) {
626 if ((uint8_t) param[i + 1] != 0x0)
627 break;
628 }
629
630 if (i < 10) {
631
632 for (i = 0; i < 10; i++)
633 custom_pattern[i] = (uint8_t) param[i + 1];
634 }
635 }
636
637
638
639
640
641
642
643
644
645 if (!disable_hpd)
646 dc_link_enable_hpd(link);
647
648 prefer_link_settings.lane_count = link->verified_link_cap.lane_count;
649 prefer_link_settings.link_rate = link->verified_link_cap.link_rate;
650 prefer_link_settings.link_spread = link->verified_link_cap.link_spread;
651
652 cur_link_settings.lane_count = link->cur_link_settings.lane_count;
653 cur_link_settings.link_rate = link->cur_link_settings.link_rate;
654 cur_link_settings.link_spread = link->cur_link_settings.link_spread;
655
656 link_training_settings.link_settings = cur_link_settings;
657
658
659 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
660 if (prefer_link_settings.lane_count != LANE_COUNT_UNKNOWN &&
661 prefer_link_settings.link_rate != LINK_RATE_UNKNOWN &&
662 (prefer_link_settings.lane_count != cur_link_settings.lane_count ||
663 prefer_link_settings.link_rate != cur_link_settings.link_rate))
664 link_training_settings.link_settings = prefer_link_settings;
665 }
666
667 for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++)
668 link_training_settings.lane_settings[i] = link->cur_lane_setting;
669
670 dc_link_set_test_pattern(
671 link,
672 test_pattern,
673 DP_TEST_PATTERN_COLOR_SPACE_RGB,
674 &link_training_settings,
675 custom_pattern,
676 10);
677
678
679
680
681
682
683 if (valid_test_pattern && disable_hpd)
684 dc_link_disable_hpd(link);
685
686 kfree(wr_buf);
687
688 return size;
689}
690
691
692
693
694
695static int dmub_tracebuffer_show(struct seq_file *m, void *data)
696{
697 struct amdgpu_device *adev = m->private;
698 struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
699 struct dmub_debugfs_trace_entry *entries;
700 uint8_t *tbuf_base;
701 uint32_t tbuf_size, max_entries, num_entries, i;
702
703 if (!fb_info)
704 return 0;
705
706 tbuf_base = (uint8_t *)fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].cpu_addr;
707 if (!tbuf_base)
708 return 0;
709
710 tbuf_size = fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].size;
711 max_entries = (tbuf_size - sizeof(struct dmub_debugfs_trace_header)) /
712 sizeof(struct dmub_debugfs_trace_entry);
713
714 num_entries =
715 ((struct dmub_debugfs_trace_header *)tbuf_base)->entry_count;
716
717 num_entries = min(num_entries, max_entries);
718
719 entries = (struct dmub_debugfs_trace_entry
720 *)(tbuf_base +
721 sizeof(struct dmub_debugfs_trace_header));
722
723 for (i = 0; i < num_entries; ++i) {
724 struct dmub_debugfs_trace_entry *entry = &entries[i];
725
726 seq_printf(m,
727 "trace_code=%u tick_count=%u param0=%u param1=%u\n",
728 entry->trace_code, entry->tick_count, entry->param0,
729 entry->param1);
730 }
731
732 return 0;
733}
734
735
736
737
738
739static int dmub_fw_state_show(struct seq_file *m, void *data)
740{
741 struct amdgpu_device *adev = m->private;
742 struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
743 uint8_t *state_base;
744 uint32_t state_size;
745
746 if (!fb_info)
747 return 0;
748
749 state_base = (uint8_t *)fb_info->fb[DMUB_WINDOW_6_FW_STATE].cpu_addr;
750 if (!state_base)
751 return 0;
752
753 state_size = fb_info->fb[DMUB_WINDOW_6_FW_STATE].size;
754
755 return seq_write(m, state_base, state_size);
756}
757
758
759
760
761
762static int output_bpc_show(struct seq_file *m, void *data)
763{
764 struct drm_connector *connector = m->private;
765 struct drm_device *dev = connector->dev;
766 struct drm_crtc *crtc = NULL;
767 struct dm_crtc_state *dm_crtc_state = NULL;
768 int res = -ENODEV;
769 unsigned int bpc;
770
771 mutex_lock(&dev->mode_config.mutex);
772 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
773
774 if (connector->state == NULL)
775 goto unlock;
776
777 crtc = connector->state->crtc;
778 if (crtc == NULL)
779 goto unlock;
780
781 drm_modeset_lock(&crtc->mutex, NULL);
782 if (crtc->state == NULL)
783 goto unlock;
784
785 dm_crtc_state = to_dm_crtc_state(crtc->state);
786 if (dm_crtc_state->stream == NULL)
787 goto unlock;
788
789 switch (dm_crtc_state->stream->timing.display_color_depth) {
790 case COLOR_DEPTH_666:
791 bpc = 6;
792 break;
793 case COLOR_DEPTH_888:
794 bpc = 8;
795 break;
796 case COLOR_DEPTH_101010:
797 bpc = 10;
798 break;
799 case COLOR_DEPTH_121212:
800 bpc = 12;
801 break;
802 case COLOR_DEPTH_161616:
803 bpc = 16;
804 break;
805 default:
806 goto unlock;
807 }
808
809 seq_printf(m, "Current: %u\n", bpc);
810 seq_printf(m, "Maximum: %u\n", connector->display_info.bpc);
811 res = 0;
812
813unlock:
814 if (crtc)
815 drm_modeset_unlock(&crtc->mutex);
816
817 drm_modeset_unlock(&dev->mode_config.connection_mutex);
818 mutex_unlock(&dev->mode_config.mutex);
819
820 return res;
821}
822
823#ifdef CONFIG_DRM_AMD_DC_HDCP
824
825
826
827
828
829
830
831
832
833static int hdcp_sink_capability_show(struct seq_file *m, void *data)
834{
835 struct drm_connector *connector = m->private;
836 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
837 bool hdcp_cap, hdcp2_cap;
838
839 if (connector->status != connector_status_connected)
840 return -ENODEV;
841
842 seq_printf(m, "%s:%d HDCP version: ", connector->name, connector->base.id);
843
844 hdcp_cap = dc_link_is_hdcp14(aconnector->dc_link, aconnector->dc_sink->sink_signal);
845 hdcp2_cap = dc_link_is_hdcp22(aconnector->dc_link, aconnector->dc_sink->sink_signal);
846
847
848 if (hdcp_cap)
849 seq_printf(m, "%s ", "HDCP1.4");
850 if (hdcp2_cap)
851 seq_printf(m, "%s ", "HDCP2.2");
852
853 if (!hdcp_cap && !hdcp2_cap)
854 seq_printf(m, "%s ", "None");
855
856 seq_puts(m, "\n");
857
858 return 0;
859}
860#endif
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875static ssize_t dp_sdp_message_debugfs_write(struct file *f, const char __user *buf,
876 size_t size, loff_t *pos)
877{
878 int r;
879 uint8_t data[36];
880 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
881 struct dm_crtc_state *acrtc_state;
882 uint32_t write_size = 36;
883
884 if (connector->base.status != connector_status_connected)
885 return -ENODEV;
886
887 if (size == 0)
888 return 0;
889
890 acrtc_state = to_dm_crtc_state(connector->base.state->crtc->state);
891
892 r = copy_from_user(data, buf, write_size);
893
894 write_size -= r;
895
896 dc_stream_send_dp_sdp(acrtc_state->stream, data, write_size);
897
898 return write_size;
899}
900
901static ssize_t dp_dpcd_address_write(struct file *f, const char __user *buf,
902 size_t size, loff_t *pos)
903{
904 int r;
905 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
906
907 if (size < sizeof(connector->debugfs_dpcd_address))
908 return 0;
909
910 r = copy_from_user(&connector->debugfs_dpcd_address,
911 buf, sizeof(connector->debugfs_dpcd_address));
912
913 return size - r;
914}
915
916static ssize_t dp_dpcd_size_write(struct file *f, const char __user *buf,
917 size_t size, loff_t *pos)
918{
919 int r;
920 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
921
922 if (size < sizeof(connector->debugfs_dpcd_size))
923 return 0;
924
925 r = copy_from_user(&connector->debugfs_dpcd_size,
926 buf, sizeof(connector->debugfs_dpcd_size));
927
928 if (connector->debugfs_dpcd_size > 256)
929 connector->debugfs_dpcd_size = 0;
930
931 return size - r;
932}
933
934static ssize_t dp_dpcd_data_write(struct file *f, const char __user *buf,
935 size_t size, loff_t *pos)
936{
937 int r;
938 char *data;
939 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
940 struct dc_link *link = connector->dc_link;
941 uint32_t write_size = connector->debugfs_dpcd_size;
942
943 if (size < write_size)
944 return 0;
945
946 data = kzalloc(write_size, GFP_KERNEL);
947 if (!data)
948 return 0;
949
950 r = copy_from_user(data, buf, write_size);
951
952 dm_helpers_dp_write_dpcd(link->ctx, link,
953 connector->debugfs_dpcd_address, data, write_size - r);
954 kfree(data);
955 return write_size - r;
956}
957
958static ssize_t dp_dpcd_data_read(struct file *f, char __user *buf,
959 size_t size, loff_t *pos)
960{
961 int r;
962 char *data;
963 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
964 struct dc_link *link = connector->dc_link;
965 uint32_t read_size = connector->debugfs_dpcd_size;
966
967 if (size < read_size)
968 return 0;
969
970 data = kzalloc(read_size, GFP_KERNEL);
971 if (!data)
972 return 0;
973
974 dm_helpers_dp_read_dpcd(link->ctx, link,
975 connector->debugfs_dpcd_address, data, read_size);
976
977 r = copy_to_user(buf, data, read_size);
978
979 kfree(data);
980 return read_size - r;
981}
982
983static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
984 size_t size, loff_t *pos)
985{
986 char *rd_buf = NULL;
987 char *rd_buf_ptr = NULL;
988 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
989 struct display_stream_compressor *dsc;
990 struct dcn_dsc_state dsc_state = {0};
991 const uint32_t rd_buf_size = 10;
992 struct pipe_ctx *pipe_ctx;
993 ssize_t result = 0;
994 int i, r, str_len = 30;
995
996 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
997
998 if (!rd_buf)
999 return -ENOMEM;
1000
1001 rd_buf_ptr = rd_buf;
1002
1003 for (i = 0; i < MAX_PIPES; i++) {
1004 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1005 if (pipe_ctx && pipe_ctx->stream &&
1006 pipe_ctx->stream->link == aconnector->dc_link)
1007 break;
1008 }
1009
1010 if (!pipe_ctx)
1011 return -ENXIO;
1012
1013 dsc = pipe_ctx->stream_res.dsc;
1014 if (dsc)
1015 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1016
1017 snprintf(rd_buf_ptr, str_len,
1018 "%d\n",
1019 dsc_state.dsc_clock_en);
1020 rd_buf_ptr += str_len;
1021
1022 while (size) {
1023 if (*pos >= rd_buf_size)
1024 break;
1025
1026 r = put_user(*(rd_buf + result), buf);
1027 if (r)
1028 return r;
1029
1030 buf += 1;
1031 size -= 1;
1032 *pos += 1;
1033 result += 1;
1034 }
1035
1036 kfree(rd_buf);
1037 return result;
1038}
1039
1040static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
1041 size_t size, loff_t *pos)
1042{
1043 char *rd_buf = NULL;
1044 char *rd_buf_ptr = NULL;
1045 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1046 struct display_stream_compressor *dsc;
1047 struct dcn_dsc_state dsc_state = {0};
1048 const uint32_t rd_buf_size = 100;
1049 struct pipe_ctx *pipe_ctx;
1050 ssize_t result = 0;
1051 int i, r, str_len = 30;
1052
1053 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1054
1055 if (!rd_buf)
1056 return -ENOMEM;
1057
1058 rd_buf_ptr = rd_buf;
1059
1060 for (i = 0; i < MAX_PIPES; i++) {
1061 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1062 if (pipe_ctx && pipe_ctx->stream &&
1063 pipe_ctx->stream->link == aconnector->dc_link)
1064 break;
1065 }
1066
1067 if (!pipe_ctx)
1068 return -ENXIO;
1069
1070 dsc = pipe_ctx->stream_res.dsc;
1071 if (dsc)
1072 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1073
1074 snprintf(rd_buf_ptr, str_len,
1075 "%d\n",
1076 dsc_state.dsc_slice_width);
1077 rd_buf_ptr += str_len;
1078
1079 while (size) {
1080 if (*pos >= rd_buf_size)
1081 break;
1082
1083 r = put_user(*(rd_buf + result), buf);
1084 if (r)
1085 return r;
1086
1087 buf += 1;
1088 size -= 1;
1089 *pos += 1;
1090 result += 1;
1091 }
1092
1093 kfree(rd_buf);
1094 return result;
1095}
1096
1097static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
1098 size_t size, loff_t *pos)
1099{
1100 char *rd_buf = NULL;
1101 char *rd_buf_ptr = NULL;
1102 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1103 struct display_stream_compressor *dsc;
1104 struct dcn_dsc_state dsc_state = {0};
1105 const uint32_t rd_buf_size = 100;
1106 struct pipe_ctx *pipe_ctx;
1107 ssize_t result = 0;
1108 int i, r, str_len = 30;
1109
1110 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1111
1112 if (!rd_buf)
1113 return -ENOMEM;
1114
1115 rd_buf_ptr = rd_buf;
1116
1117 for (i = 0; i < MAX_PIPES; i++) {
1118 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1119 if (pipe_ctx && pipe_ctx->stream &&
1120 pipe_ctx->stream->link == aconnector->dc_link)
1121 break;
1122 }
1123
1124 if (!pipe_ctx)
1125 return -ENXIO;
1126
1127 dsc = pipe_ctx->stream_res.dsc;
1128 if (dsc)
1129 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1130
1131 snprintf(rd_buf_ptr, str_len,
1132 "%d\n",
1133 dsc_state.dsc_slice_height);
1134 rd_buf_ptr += str_len;
1135
1136 while (size) {
1137 if (*pos >= rd_buf_size)
1138 break;
1139
1140 r = put_user(*(rd_buf + result), buf);
1141 if (r)
1142 return r;
1143
1144 buf += 1;
1145 size -= 1;
1146 *pos += 1;
1147 result += 1;
1148 }
1149
1150 kfree(rd_buf);
1151 return result;
1152}
1153
1154static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
1155 size_t size, loff_t *pos)
1156{
1157 char *rd_buf = NULL;
1158 char *rd_buf_ptr = NULL;
1159 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1160 struct display_stream_compressor *dsc;
1161 struct dcn_dsc_state dsc_state = {0};
1162 const uint32_t rd_buf_size = 100;
1163 struct pipe_ctx *pipe_ctx;
1164 ssize_t result = 0;
1165 int i, r, str_len = 30;
1166
1167 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1168
1169 if (!rd_buf)
1170 return -ENOMEM;
1171
1172 rd_buf_ptr = rd_buf;
1173
1174 for (i = 0; i < MAX_PIPES; i++) {
1175 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1176 if (pipe_ctx && pipe_ctx->stream &&
1177 pipe_ctx->stream->link == aconnector->dc_link)
1178 break;
1179 }
1180
1181 if (!pipe_ctx)
1182 return -ENXIO;
1183
1184 dsc = pipe_ctx->stream_res.dsc;
1185 if (dsc)
1186 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1187
1188 snprintf(rd_buf_ptr, str_len,
1189 "%d\n",
1190 dsc_state.dsc_bits_per_pixel);
1191 rd_buf_ptr += str_len;
1192
1193 while (size) {
1194 if (*pos >= rd_buf_size)
1195 break;
1196
1197 r = put_user(*(rd_buf + result), buf);
1198 if (r)
1199 return r;
1200
1201 buf += 1;
1202 size -= 1;
1203 *pos += 1;
1204 result += 1;
1205 }
1206
1207 kfree(rd_buf);
1208 return result;
1209}
1210
1211static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
1212 size_t size, loff_t *pos)
1213{
1214 char *rd_buf = NULL;
1215 char *rd_buf_ptr = NULL;
1216 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1217 struct display_stream_compressor *dsc;
1218 struct dcn_dsc_state dsc_state = {0};
1219 const uint32_t rd_buf_size = 100;
1220 struct pipe_ctx *pipe_ctx;
1221 ssize_t result = 0;
1222 int i, r, str_len = 30;
1223
1224 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1225
1226 if (!rd_buf)
1227 return -ENOMEM;
1228
1229 rd_buf_ptr = rd_buf;
1230
1231 for (i = 0; i < MAX_PIPES; i++) {
1232 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1233 if (pipe_ctx && pipe_ctx->stream &&
1234 pipe_ctx->stream->link == aconnector->dc_link)
1235 break;
1236 }
1237
1238 if (!pipe_ctx)
1239 return -ENXIO;
1240
1241 dsc = pipe_ctx->stream_res.dsc;
1242 if (dsc)
1243 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1244
1245 snprintf(rd_buf_ptr, str_len,
1246 "%d\n",
1247 dsc_state.dsc_pic_width);
1248 rd_buf_ptr += str_len;
1249
1250 while (size) {
1251 if (*pos >= rd_buf_size)
1252 break;
1253
1254 r = put_user(*(rd_buf + result), buf);
1255 if (r)
1256 return r;
1257
1258 buf += 1;
1259 size -= 1;
1260 *pos += 1;
1261 result += 1;
1262 }
1263
1264 kfree(rd_buf);
1265 return result;
1266}
1267
1268static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
1269 size_t size, loff_t *pos)
1270{
1271 char *rd_buf = NULL;
1272 char *rd_buf_ptr = NULL;
1273 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1274 struct display_stream_compressor *dsc;
1275 struct dcn_dsc_state dsc_state = {0};
1276 const uint32_t rd_buf_size = 100;
1277 struct pipe_ctx *pipe_ctx;
1278 ssize_t result = 0;
1279 int i, r, str_len = 30;
1280
1281 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1282
1283 if (!rd_buf)
1284 return -ENOMEM;
1285
1286 rd_buf_ptr = rd_buf;
1287
1288 for (i = 0; i < MAX_PIPES; i++) {
1289 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1290 if (pipe_ctx && pipe_ctx->stream &&
1291 pipe_ctx->stream->link == aconnector->dc_link)
1292 break;
1293 }
1294
1295 if (!pipe_ctx)
1296 return -ENXIO;
1297
1298 dsc = pipe_ctx->stream_res.dsc;
1299 if (dsc)
1300 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1301
1302 snprintf(rd_buf_ptr, str_len,
1303 "%d\n",
1304 dsc_state.dsc_pic_height);
1305 rd_buf_ptr += str_len;
1306
1307 while (size) {
1308 if (*pos >= rd_buf_size)
1309 break;
1310
1311 r = put_user(*(rd_buf + result), buf);
1312 if (r)
1313 return r;
1314
1315 buf += 1;
1316 size -= 1;
1317 *pos += 1;
1318 result += 1;
1319 }
1320
1321 kfree(rd_buf);
1322 return result;
1323}
1324
1325static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
1326 size_t size, loff_t *pos)
1327{
1328 char *rd_buf = NULL;
1329 char *rd_buf_ptr = NULL;
1330 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1331 struct display_stream_compressor *dsc;
1332 struct dcn_dsc_state dsc_state = {0};
1333 const uint32_t rd_buf_size = 100;
1334 struct pipe_ctx *pipe_ctx;
1335 ssize_t result = 0;
1336 int i, r, str_len = 30;
1337
1338 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1339
1340 if (!rd_buf)
1341 return -ENOMEM;
1342
1343 rd_buf_ptr = rd_buf;
1344
1345 for (i = 0; i < MAX_PIPES; i++) {
1346 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1347 if (pipe_ctx && pipe_ctx->stream &&
1348 pipe_ctx->stream->link == aconnector->dc_link)
1349 break;
1350 }
1351
1352 if (!pipe_ctx)
1353 return -ENXIO;
1354
1355 dsc = pipe_ctx->stream_res.dsc;
1356 if (dsc)
1357 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1358
1359 snprintf(rd_buf_ptr, str_len,
1360 "%d\n",
1361 dsc_state.dsc_chunk_size);
1362 rd_buf_ptr += str_len;
1363
1364 while (size) {
1365 if (*pos >= rd_buf_size)
1366 break;
1367
1368 r = put_user(*(rd_buf + result), buf);
1369 if (r)
1370 return r;
1371
1372 buf += 1;
1373 size -= 1;
1374 *pos += 1;
1375 result += 1;
1376 }
1377
1378 kfree(rd_buf);
1379 return result;
1380}
1381
1382static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
1383 size_t size, loff_t *pos)
1384{
1385 char *rd_buf = NULL;
1386 char *rd_buf_ptr = NULL;
1387 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1388 struct display_stream_compressor *dsc;
1389 struct dcn_dsc_state dsc_state = {0};
1390 const uint32_t rd_buf_size = 100;
1391 struct pipe_ctx *pipe_ctx;
1392 ssize_t result = 0;
1393 int i, r, str_len = 30;
1394
1395 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1396
1397 if (!rd_buf)
1398 return -ENOMEM;
1399
1400 rd_buf_ptr = rd_buf;
1401
1402 for (i = 0; i < MAX_PIPES; i++) {
1403 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1404 if (pipe_ctx && pipe_ctx->stream &&
1405 pipe_ctx->stream->link == aconnector->dc_link)
1406 break;
1407 }
1408
1409 if (!pipe_ctx)
1410 return -ENXIO;
1411
1412 dsc = pipe_ctx->stream_res.dsc;
1413 if (dsc)
1414 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1415
1416 snprintf(rd_buf_ptr, str_len,
1417 "%d\n",
1418 dsc_state.dsc_slice_bpg_offset);
1419 rd_buf_ptr += str_len;
1420
1421 while (size) {
1422 if (*pos >= rd_buf_size)
1423 break;
1424
1425 r = put_user(*(rd_buf + result), buf);
1426 if (r)
1427 return r;
1428
1429 buf += 1;
1430 size -= 1;
1431 *pos += 1;
1432 result += 1;
1433 }
1434
1435 kfree(rd_buf);
1436 return result;
1437}
1438
1439DEFINE_SHOW_ATTRIBUTE(dmub_fw_state);
1440DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer);
1441DEFINE_SHOW_ATTRIBUTE(output_bpc);
1442#ifdef CONFIG_DRM_AMD_DC_HDCP
1443DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability);
1444#endif
1445
1446static const struct file_operations dp_dsc_clock_en_debugfs_fops = {
1447 .owner = THIS_MODULE,
1448 .read = dp_dsc_clock_en_read,
1449 .llseek = default_llseek
1450};
1451
1452static const struct file_operations dp_dsc_slice_width_debugfs_fops = {
1453 .owner = THIS_MODULE,
1454 .read = dp_dsc_slice_width_read,
1455 .llseek = default_llseek
1456};
1457
1458static const struct file_operations dp_dsc_slice_height_debugfs_fops = {
1459 .owner = THIS_MODULE,
1460 .read = dp_dsc_slice_height_read,
1461 .llseek = default_llseek
1462};
1463
1464static const struct file_operations dp_dsc_bits_per_pixel_debugfs_fops = {
1465 .owner = THIS_MODULE,
1466 .read = dp_dsc_bits_per_pixel_read,
1467 .llseek = default_llseek
1468};
1469
1470static const struct file_operations dp_dsc_pic_width_debugfs_fops = {
1471 .owner = THIS_MODULE,
1472 .read = dp_dsc_pic_width_read,
1473 .llseek = default_llseek
1474};
1475
1476static const struct file_operations dp_dsc_pic_height_debugfs_fops = {
1477 .owner = THIS_MODULE,
1478 .read = dp_dsc_pic_height_read,
1479 .llseek = default_llseek
1480};
1481
1482static const struct file_operations dp_dsc_chunk_size_debugfs_fops = {
1483 .owner = THIS_MODULE,
1484 .read = dp_dsc_chunk_size_read,
1485 .llseek = default_llseek
1486};
1487
1488static const struct file_operations dp_dsc_slice_bpg_offset_debugfs_fops = {
1489 .owner = THIS_MODULE,
1490 .read = dp_dsc_slice_bpg_offset_read,
1491 .llseek = default_llseek
1492};
1493
1494static const struct file_operations dp_link_settings_debugfs_fops = {
1495 .owner = THIS_MODULE,
1496 .read = dp_link_settings_read,
1497 .write = dp_link_settings_write,
1498 .llseek = default_llseek
1499};
1500
1501static const struct file_operations dp_phy_settings_debugfs_fop = {
1502 .owner = THIS_MODULE,
1503 .read = dp_phy_settings_read,
1504 .write = dp_phy_settings_write,
1505 .llseek = default_llseek
1506};
1507
1508static const struct file_operations dp_phy_test_pattern_fops = {
1509 .owner = THIS_MODULE,
1510 .write = dp_phy_test_pattern_debugfs_write,
1511 .llseek = default_llseek
1512};
1513
1514static const struct file_operations sdp_message_fops = {
1515 .owner = THIS_MODULE,
1516 .write = dp_sdp_message_debugfs_write,
1517 .llseek = default_llseek
1518};
1519
1520static const struct file_operations dp_dpcd_address_debugfs_fops = {
1521 .owner = THIS_MODULE,
1522 .write = dp_dpcd_address_write,
1523 .llseek = default_llseek
1524};
1525
1526static const struct file_operations dp_dpcd_size_debugfs_fops = {
1527 .owner = THIS_MODULE,
1528 .write = dp_dpcd_size_write,
1529 .llseek = default_llseek
1530};
1531
1532static const struct file_operations dp_dpcd_data_debugfs_fops = {
1533 .owner = THIS_MODULE,
1534 .read = dp_dpcd_data_read,
1535 .write = dp_dpcd_data_write,
1536 .llseek = default_llseek
1537};
1538
1539static const struct {
1540 char *name;
1541 const struct file_operations *fops;
1542} dp_debugfs_entries[] = {
1543 {"link_settings", &dp_link_settings_debugfs_fops},
1544 {"phy_settings", &dp_phy_settings_debugfs_fop},
1545 {"test_pattern", &dp_phy_test_pattern_fops},
1546#ifdef CONFIG_DRM_AMD_DC_HDCP
1547 {"hdcp_sink_capability", &hdcp_sink_capability_fops},
1548#endif
1549 {"sdp_message", &sdp_message_fops},
1550 {"aux_dpcd_address", &dp_dpcd_address_debugfs_fops},
1551 {"aux_dpcd_size", &dp_dpcd_size_debugfs_fops},
1552 {"aux_dpcd_data", &dp_dpcd_data_debugfs_fops},
1553 {"dsc_clock_en", &dp_dsc_clock_en_debugfs_fops},
1554 {"dsc_slice_width", &dp_dsc_slice_width_debugfs_fops},
1555 {"dsc_slice_height", &dp_dsc_slice_height_debugfs_fops},
1556 {"dsc_bits_per_pixel", &dp_dsc_bits_per_pixel_debugfs_fops},
1557 {"dsc_pic_width", &dp_dsc_pic_width_debugfs_fops},
1558 {"dsc_pic_height", &dp_dsc_pic_height_debugfs_fops},
1559 {"dsc_chunk_size", &dp_dsc_chunk_size_debugfs_fops},
1560 {"dsc_slice_bpg", &dp_dsc_slice_bpg_offset_debugfs_fops}
1561};
1562
1563#ifdef CONFIG_DRM_AMD_DC_HDCP
1564static const struct {
1565 char *name;
1566 const struct file_operations *fops;
1567} hdmi_debugfs_entries[] = {
1568 {"hdcp_sink_capability", &hdcp_sink_capability_fops}
1569};
1570#endif
1571
1572
1573
1574static int force_yuv420_output_set(void *data, u64 val)
1575{
1576 struct amdgpu_dm_connector *connector = data;
1577
1578 connector->force_yuv420_output = (bool)val;
1579
1580 return 0;
1581}
1582
1583
1584
1585
1586static int force_yuv420_output_get(void *data, u64 *val)
1587{
1588 struct amdgpu_dm_connector *connector = data;
1589
1590 *val = connector->force_yuv420_output;
1591
1592 return 0;
1593}
1594
1595DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
1596 force_yuv420_output_set, "%llu\n");
1597
1598
1599
1600
1601static int psr_get(void *data, u64 *val)
1602{
1603 struct amdgpu_dm_connector *connector = data;
1604 struct dc_link *link = connector->dc_link;
1605 uint32_t psr_state = 0;
1606
1607 dc_link_get_psr_state(link, &psr_state);
1608
1609 *val = psr_state;
1610
1611 return 0;
1612}
1613
1614
1615DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n");
1616
1617void connector_debugfs_init(struct amdgpu_dm_connector *connector)
1618{
1619 int i;
1620 struct dentry *dir = connector->base.debugfs_entry;
1621
1622 if (connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
1623 connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) {
1624 for (i = 0; i < ARRAY_SIZE(dp_debugfs_entries); i++) {
1625 debugfs_create_file(dp_debugfs_entries[i].name,
1626 0644, dir, connector,
1627 dp_debugfs_entries[i].fops);
1628 }
1629 }
1630 if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
1631 debugfs_create_file_unsafe("psr_state", 0444, dir, connector, &psr_fops);
1632
1633 debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector,
1634 &force_yuv420_output_fops);
1635
1636 debugfs_create_file("output_bpc", 0644, dir, connector,
1637 &output_bpc_fops);
1638
1639 connector->debugfs_dpcd_address = 0;
1640 connector->debugfs_dpcd_size = 0;
1641
1642#ifdef CONFIG_DRM_AMD_DC_HDCP
1643 if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) {
1644 for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_entries); i++) {
1645 debugfs_create_file(hdmi_debugfs_entries[i].name,
1646 0644, dir, connector,
1647 hdmi_debugfs_entries[i].fops);
1648 }
1649 }
1650#endif
1651}
1652
1653
1654
1655
1656
1657static ssize_t dtn_log_read(
1658 struct file *f,
1659 char __user *buf,
1660 size_t size,
1661 loff_t *pos)
1662{
1663 struct amdgpu_device *adev = file_inode(f)->i_private;
1664 struct dc *dc = adev->dm.dc;
1665 struct dc_log_buffer_ctx log_ctx = { 0 };
1666 ssize_t result = 0;
1667
1668 if (!buf || !size)
1669 return -EINVAL;
1670
1671 if (!dc->hwss.log_hw_state)
1672 return 0;
1673
1674 dc->hwss.log_hw_state(dc, &log_ctx);
1675
1676 if (*pos < log_ctx.pos) {
1677 size_t to_copy = log_ctx.pos - *pos;
1678
1679 to_copy = min(to_copy, size);
1680
1681 if (!copy_to_user(buf, log_ctx.buf + *pos, to_copy)) {
1682 *pos += to_copy;
1683 result = to_copy;
1684 }
1685 }
1686
1687 kfree(log_ctx.buf);
1688
1689 return result;
1690}
1691
1692
1693
1694
1695
1696static ssize_t dtn_log_write(
1697 struct file *f,
1698 const char __user *buf,
1699 size_t size,
1700 loff_t *pos)
1701{
1702 struct amdgpu_device *adev = file_inode(f)->i_private;
1703 struct dc *dc = adev->dm.dc;
1704
1705
1706 if (size == 0)
1707 return 0;
1708
1709 if (dc->hwss.log_hw_state)
1710 dc->hwss.log_hw_state(dc, NULL);
1711
1712 return size;
1713}
1714
1715
1716
1717
1718
1719
1720static int current_backlight_read(struct seq_file *m, void *data)
1721{
1722 struct drm_info_node *node = (struct drm_info_node *)m->private;
1723 struct drm_device *dev = node->minor->dev;
1724 struct amdgpu_device *adev = dev->dev_private;
1725 struct amdgpu_display_manager *dm = &adev->dm;
1726
1727 unsigned int backlight = dc_link_get_backlight_level(dm->backlight_link);
1728
1729 seq_printf(m, "0x%x\n", backlight);
1730 return 0;
1731}
1732
1733
1734
1735
1736
1737
1738static int target_backlight_read(struct seq_file *m, void *data)
1739{
1740 struct drm_info_node *node = (struct drm_info_node *)m->private;
1741 struct drm_device *dev = node->minor->dev;
1742 struct amdgpu_device *adev = dev->dev_private;
1743 struct amdgpu_display_manager *dm = &adev->dm;
1744
1745 unsigned int backlight = dc_link_get_target_backlight_pwm(dm->backlight_link);
1746
1747 seq_printf(m, "0x%x\n", backlight);
1748 return 0;
1749}
1750
1751static int mst_topo(struct seq_file *m, void *unused)
1752{
1753 struct drm_info_node *node = (struct drm_info_node *)m->private;
1754 struct drm_device *dev = node->minor->dev;
1755 struct drm_connector *connector;
1756 struct drm_connector_list_iter conn_iter;
1757 struct amdgpu_dm_connector *aconnector;
1758
1759 drm_connector_list_iter_begin(dev, &conn_iter);
1760 drm_for_each_connector_iter(connector, &conn_iter) {
1761 if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
1762 continue;
1763
1764 aconnector = to_amdgpu_dm_connector(connector);
1765
1766 seq_printf(m, "\nMST topology for connector %d\n", aconnector->connector_id);
1767 drm_dp_mst_dump_topology(m, &aconnector->mst_mgr);
1768 }
1769 drm_connector_list_iter_end(&conn_iter);
1770
1771 return 0;
1772}
1773
1774static const struct drm_info_list amdgpu_dm_debugfs_list[] = {
1775 {"amdgpu_current_backlight_pwm", ¤t_backlight_read},
1776 {"amdgpu_target_backlight_pwm", &target_backlight_read},
1777 {"amdgpu_mst_topology", &mst_topo},
1778};
1779
1780
1781
1782
1783
1784static int visual_confirm_set(void *data, u64 val)
1785{
1786 struct amdgpu_device *adev = data;
1787
1788 adev->dm.dc->debug.visual_confirm = (enum visual_confirm)val;
1789
1790 return 0;
1791}
1792
1793
1794
1795
1796
1797static int visual_confirm_get(void *data, u64 *val)
1798{
1799 struct amdgpu_device *adev = data;
1800
1801 *val = adev->dm.dc->debug.visual_confirm;
1802
1803 return 0;
1804}
1805
1806DEFINE_DEBUGFS_ATTRIBUTE(visual_confirm_fops, visual_confirm_get,
1807 visual_confirm_set, "%llu\n");
1808
1809int dtn_debugfs_init(struct amdgpu_device *adev)
1810{
1811 static const struct file_operations dtn_log_fops = {
1812 .owner = THIS_MODULE,
1813 .read = dtn_log_read,
1814 .write = dtn_log_write,
1815 .llseek = default_llseek
1816 };
1817
1818 struct drm_minor *minor = adev->ddev->primary;
1819 struct dentry *root = minor->debugfs_root;
1820 int ret;
1821
1822 ret = amdgpu_debugfs_add_files(adev, amdgpu_dm_debugfs_list,
1823 ARRAY_SIZE(amdgpu_dm_debugfs_list));
1824 if (ret)
1825 return ret;
1826
1827 debugfs_create_file("amdgpu_dm_dtn_log", 0644, root, adev,
1828 &dtn_log_fops);
1829
1830 debugfs_create_file_unsafe("amdgpu_dm_visual_confirm", 0644, root, adev,
1831 &visual_confirm_fops);
1832
1833 debugfs_create_file_unsafe("amdgpu_dm_dmub_tracebuffer", 0644, root,
1834 adev, &dmub_tracebuffer_fops);
1835
1836 debugfs_create_file_unsafe("amdgpu_dm_dmub_fw_state", 0644, root,
1837 adev, &dmub_fw_state_fops);
1838
1839 return 0;
1840}
1841