Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * Copyright 2018 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_helpers.h>
27#include <linux/uaccess.h>
28
29#include "dc.h"
30#include "amdgpu.h"
31#include "amdgpu_dm.h"
32#include "amdgpu_dm_debugfs.h"
33#include "dm_helpers.h"
34#include "dmub/dmub_srv.h"
35#include "resource.h"
36#include "dsc.h"
37#include "dc_link_dp.h"
38#include "link_hwss.h"
39#include "dc/dc_dmub_srv.h"
40
41struct dmub_debugfs_trace_header {
42 uint32_t entry_count;
43 uint32_t reserved[3];
44};
45
46struct dmub_debugfs_trace_entry {
47 uint32_t trace_code;
48 uint32_t tick_count;
49 uint32_t param0;
50 uint32_t param1;
51};
52
53/* parse_write_buffer_into_params - Helper function to parse debugfs write buffer into an array
54 *
55 * Function takes in attributes passed to debugfs write entry
56 * and writes into param array.
57 * The user passes max_param_num to identify maximum number of
58 * parameters that could be parsed.
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 is bytes not be copied */
78 if (copy_from_user(wr_buf_ptr, buf, wr_buf_size)) {
79 DRM_DEBUG_DRIVER("user data could not be read successfully\n");
80 return -EFAULT;
81 }
82
83 /* check number of parameters. isspace could not differ space and \n */
84 while ((*wr_buf_ptr != 0xa) && (wr_buf_count < wr_buf_size)) {
85 /* skip space*/
86 while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) {
87 wr_buf_ptr++;
88 wr_buf_count++;
89 }
90
91 if (wr_buf_count == wr_buf_size)
92 break;
93
94 /* skip non-space*/
95 while ((!isspace(*wr_buf_ptr)) && (wr_buf_count < wr_buf_size)) {
96 wr_buf_ptr++;
97 wr_buf_count++;
98 }
99
100 (*param_nums)++;
101
102 if (wr_buf_count == wr_buf_size)
103 break;
104 }
105
106 if (*param_nums > max_param_num)
107 *param_nums = max_param_num;
108
109 wr_buf_ptr = wr_buf; /* reset buf pointer */
110 wr_buf_count = 0; /* number of char already checked */
111
112 while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) {
113 wr_buf_ptr++;
114 wr_buf_count++;
115 }
116
117 while (param_index < *param_nums) {
118 /* after strsep, wr_buf_ptr will be moved to after space */
119 sub_str = strsep(&wr_buf_ptr, delimiter);
120
121 r = kstrtol(sub_str, 16, &(param[param_index]));
122
123 if (r)
124 DRM_DEBUG_DRIVER("string to int convert error code: %d\n", r);
125
126 param_index++;
127 }
128
129 return 0;
130}
131
132/* function description
133 * get/ set DP configuration: lane_count, link_rate, spread_spectrum
134 *
135 * valid lane count value: 1, 2, 4
136 * valid link rate value:
137 * 06h = 1.62Gbps per lane
138 * 0Ah = 2.7Gbps per lane
139 * 0Ch = 3.24Gbps per lane
140 * 14h = 5.4Gbps per lane
141 * 1Eh = 8.1Gbps per lane
142 *
143 * debugfs is located at /sys/kernel/debug/dri/0/DP-x/link_settings
144 *
145 * --- to get dp configuration
146 *
147 * cat /sys/kernel/debug/dri/0/DP-x/link_settings
148 *
149 * It will list current, verified, reported, preferred dp configuration.
150 * current -- for current video mode
151 * verified --- maximum configuration which pass link training
152 * reported --- DP rx report caps (DPCD register offset 0, 1 2)
153 * preferred --- user force settings
154 *
155 * --- set (or force) dp configuration
156 *
157 * echo <lane_count> <link_rate> > link_settings
158 *
159 * for example, to force to 2 lane, 2.7GHz,
160 * echo 4 0xa > /sys/kernel/debug/dri/0/DP-x/link_settings
161 *
162 * spread_spectrum could not be changed dynamically.
163 *
164 * in case invalid lane count, link rate are force, no hw programming will be
165 * done. please check link settings after force operation to see if HW get
166 * programming.
167 *
168 * cat /sys/kernel/debug/dri/0/DP-x/link_settings
169 *
170 * check current and preferred settings.
171 *
172 */
173static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
174 size_t size, loff_t *pos)
175{
176 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
177 struct dc_link *link = connector->dc_link;
178 char *rd_buf = NULL;
179 char *rd_buf_ptr = NULL;
180 const uint32_t rd_buf_size = 100;
181 uint32_t result = 0;
182 uint8_t str_len = 0;
183 int r;
184
185 if (*pos & 3 || size & 3)
186 return -EINVAL;
187
188 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
189 if (!rd_buf)
190 return 0;
191
192 rd_buf_ptr = rd_buf;
193
194 str_len = strlen("Current: %d 0x%x %d ");
195 snprintf(rd_buf_ptr, str_len, "Current: %d 0x%x %d ",
196 link->cur_link_settings.lane_count,
197 link->cur_link_settings.link_rate,
198 link->cur_link_settings.link_spread);
199 rd_buf_ptr += str_len;
200
201 str_len = strlen("Verified: %d 0x%x %d ");
202 snprintf(rd_buf_ptr, str_len, "Verified: %d 0x%x %d ",
203 link->verified_link_cap.lane_count,
204 link->verified_link_cap.link_rate,
205 link->verified_link_cap.link_spread);
206 rd_buf_ptr += str_len;
207
208 str_len = strlen("Reported: %d 0x%x %d ");
209 snprintf(rd_buf_ptr, str_len, "Reported: %d 0x%x %d ",
210 link->reported_link_cap.lane_count,
211 link->reported_link_cap.link_rate,
212 link->reported_link_cap.link_spread);
213 rd_buf_ptr += str_len;
214
215 str_len = strlen("Preferred: %d 0x%x %d ");
216 snprintf(rd_buf_ptr, str_len, "Preferred: %d 0x%x %d\n",
217 link->preferred_link_setting.lane_count,
218 link->preferred_link_setting.link_rate,
219 link->preferred_link_setting.link_spread);
220
221 while (size) {
222 if (*pos >= rd_buf_size)
223 break;
224
225 r = put_user(*(rd_buf + result), buf);
226 if (r) {
227 kfree(rd_buf);
228 return r; /* r = -EFAULT */
229 }
230
231 buf += 1;
232 size -= 1;
233 *pos += 1;
234 result += 1;
235 }
236
237 kfree(rd_buf);
238 return result;
239}
240
241static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
242 size_t size, loff_t *pos)
243{
244 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
245 struct dc_link *link = connector->dc_link;
246 struct amdgpu_device *adev = drm_to_adev(connector->base.dev);
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 /* 0: lane_count; 1: link_rate */
252 int max_param_num = 2;
253 uint8_t param_nums = 0;
254 long param[2];
255 bool valid_input = true;
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 break;
283 default:
284 valid_input = false;
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 case LINK_RATE_UHBR10:
295 break;
296 default:
297 valid_input = false;
298 break;
299 }
300
301 if (!valid_input) {
302 kfree(wr_buf);
303 DRM_DEBUG_DRIVER("Invalid Input value No HW will be programmed\n");
304 mutex_lock(&adev->dm.dc_lock);
305 dc_link_set_preferred_training_settings(dc, NULL, NULL, link, false);
306 mutex_unlock(&adev->dm.dc_lock);
307 return size;
308 }
309
310 /* save user force lane_count, link_rate to preferred settings
311 * spread spectrum will not be changed
312 */
313 prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
314 prefer_link_settings.use_link_rate_set = false;
315 prefer_link_settings.lane_count = param[0];
316 prefer_link_settings.link_rate = param[1];
317
318 mutex_lock(&adev->dm.dc_lock);
319 dc_link_set_preferred_training_settings(dc, &prefer_link_settings, NULL, link, false);
320 mutex_unlock(&adev->dm.dc_lock);
321
322 kfree(wr_buf);
323 return size;
324}
325
326/* function: get current DP PHY settings: voltage swing, pre-emphasis,
327 * post-cursor2 (defined by VESA DP specification)
328 *
329 * valid values
330 * voltage swing: 0,1,2,3
331 * pre-emphasis : 0,1,2,3
332 * post cursor2 : 0,1,2,3
333 *
334 *
335 * how to use this debugfs
336 *
337 * debugfs is located at /sys/kernel/debug/dri/0/DP-x
338 *
339 * there will be directories, like DP-1, DP-2,DP-3, etc. for DP display
340 *
341 * To figure out which DP-x is the display for DP to be check,
342 * cd DP-x
343 * ls -ll
344 * There should be debugfs file, like link_settings, phy_settings.
345 * cat link_settings
346 * from lane_count, link_rate to figure which DP-x is for display to be worked
347 * on
348 *
349 * To get current DP PHY settings,
350 * cat phy_settings
351 *
352 * To change DP PHY settings,
353 * echo <voltage_swing> <pre-emphasis> <post_cursor2> > phy_settings
354 * for examle, to change voltage swing to 2, pre-emphasis to 3, post_cursor2 to
355 * 0,
356 * echo 2 3 0 > phy_settings
357 *
358 * To check if change be applied, get current phy settings by
359 * cat phy_settings
360 *
361 * In case invalid values are set by user, like
362 * echo 1 4 0 > phy_settings
363 *
364 * HW will NOT be programmed by these settings.
365 * cat phy_settings will show the previous valid settings.
366 */
367static ssize_t dp_phy_settings_read(struct file *f, char __user *buf,
368 size_t size, loff_t *pos)
369{
370 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
371 struct dc_link *link = connector->dc_link;
372 char *rd_buf = NULL;
373 const uint32_t rd_buf_size = 20;
374 uint32_t result = 0;
375 int r;
376
377 if (*pos & 3 || size & 3)
378 return -EINVAL;
379
380 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
381 if (!rd_buf)
382 return -EINVAL;
383
384 snprintf(rd_buf, rd_buf_size, " %d %d %d\n",
385 link->cur_lane_setting[0].VOLTAGE_SWING,
386 link->cur_lane_setting[0].PRE_EMPHASIS,
387 link->cur_lane_setting[0].POST_CURSOR2);
388
389 while (size) {
390 if (*pos >= rd_buf_size)
391 break;
392
393 r = put_user((*(rd_buf + result)), buf);
394 if (r) {
395 kfree(rd_buf);
396 return r; /* r = -EFAULT */
397 }
398
399 buf += 1;
400 size -= 1;
401 *pos += 1;
402 result += 1;
403 }
404
405 kfree(rd_buf);
406 return result;
407}
408
409static int dp_lttpr_status_show(struct seq_file *m, void *d)
410{
411 char *data;
412 struct amdgpu_dm_connector *connector = file_inode(m->file)->i_private;
413 struct dc_link *link = connector->dc_link;
414 uint32_t read_size = 1;
415 uint8_t repeater_count = 0;
416
417 data = kzalloc(read_size, GFP_KERNEL);
418 if (!data)
419 return 0;
420
421 dm_helpers_dp_read_dpcd(link->ctx, link, 0xF0002, data, read_size);
422
423 switch ((uint8_t)*data) {
424 case 0x80:
425 repeater_count = 1;
426 break;
427 case 0x40:
428 repeater_count = 2;
429 break;
430 case 0x20:
431 repeater_count = 3;
432 break;
433 case 0x10:
434 repeater_count = 4;
435 break;
436 case 0x8:
437 repeater_count = 5;
438 break;
439 case 0x4:
440 repeater_count = 6;
441 break;
442 case 0x2:
443 repeater_count = 7;
444 break;
445 case 0x1:
446 repeater_count = 8;
447 break;
448 case 0x0:
449 repeater_count = 0;
450 break;
451 default:
452 repeater_count = (uint8_t)*data;
453 break;
454 }
455
456 seq_printf(m, "phy repeater count: %d\n", repeater_count);
457
458 dm_helpers_dp_read_dpcd(link->ctx, link, 0xF0003, data, read_size);
459
460 if ((uint8_t)*data == 0x55)
461 seq_printf(m, "phy repeater mode: transparent\n");
462 else if ((uint8_t)*data == 0xAA)
463 seq_printf(m, "phy repeater mode: non-transparent\n");
464 else if ((uint8_t)*data == 0x00)
465 seq_printf(m, "phy repeater mode: non lttpr\n");
466 else
467 seq_printf(m, "phy repeater mode: read error\n");
468
469 kfree(data);
470 return 0;
471}
472
473static ssize_t dp_phy_settings_write(struct file *f, const char __user *buf,
474 size_t size, loff_t *pos)
475{
476 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
477 struct dc_link *link = connector->dc_link;
478 struct dc *dc = (struct dc *)link->dc;
479 char *wr_buf = NULL;
480 uint32_t wr_buf_size = 40;
481 long param[3];
482 bool use_prefer_link_setting;
483 struct link_training_settings link_lane_settings;
484 int max_param_num = 3;
485 uint8_t param_nums = 0;
486 int r = 0;
487
488
489 if (size == 0)
490 return -EINVAL;
491
492 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
493 if (!wr_buf)
494 return -ENOSPC;
495
496 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
497 (long *)param, buf,
498 max_param_num,
499 ¶m_nums)) {
500 kfree(wr_buf);
501 return -EINVAL;
502 }
503
504 if (param_nums <= 0) {
505 kfree(wr_buf);
506 DRM_DEBUG_DRIVER("user data not be read\n");
507 return -EINVAL;
508 }
509
510 if ((param[0] > VOLTAGE_SWING_MAX_LEVEL) ||
511 (param[1] > PRE_EMPHASIS_MAX_LEVEL) ||
512 (param[2] > POST_CURSOR2_MAX_LEVEL)) {
513 kfree(wr_buf);
514 DRM_DEBUG_DRIVER("Invalid Input No HW will be programmed\n");
515 return size;
516 }
517
518 /* get link settings: lane count, link rate */
519 use_prefer_link_setting =
520 ((link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) &&
521 (link->test_pattern_enabled));
522
523 memset(&link_lane_settings, 0, sizeof(link_lane_settings));
524
525 if (use_prefer_link_setting) {
526 link_lane_settings.link_settings.lane_count =
527 link->preferred_link_setting.lane_count;
528 link_lane_settings.link_settings.link_rate =
529 link->preferred_link_setting.link_rate;
530 link_lane_settings.link_settings.link_spread =
531 link->preferred_link_setting.link_spread;
532 } else {
533 link_lane_settings.link_settings.lane_count =
534 link->cur_link_settings.lane_count;
535 link_lane_settings.link_settings.link_rate =
536 link->cur_link_settings.link_rate;
537 link_lane_settings.link_settings.link_spread =
538 link->cur_link_settings.link_spread;
539 }
540
541 /* apply phy settings from user */
542 for (r = 0; r < link_lane_settings.link_settings.lane_count; r++) {
543 link_lane_settings.lane_settings[r].VOLTAGE_SWING =
544 (enum dc_voltage_swing) (param[0]);
545 link_lane_settings.lane_settings[r].PRE_EMPHASIS =
546 (enum dc_pre_emphasis) (param[1]);
547 link_lane_settings.lane_settings[r].POST_CURSOR2 =
548 (enum dc_post_cursor2) (param[2]);
549 }
550
551 /* program ASIC registers and DPCD registers */
552 dc_link_set_drive_settings(dc, &link_lane_settings, link);
553
554 kfree(wr_buf);
555 return size;
556}
557
558/* function description
559 *
560 * set PHY layer or Link layer test pattern
561 * PHY test pattern is used for PHY SI check.
562 * Link layer test will not affect PHY SI.
563 *
564 * Reset Test Pattern:
565 * 0 = DP_TEST_PATTERN_VIDEO_MODE
566 *
567 * PHY test pattern supported:
568 * 1 = DP_TEST_PATTERN_D102
569 * 2 = DP_TEST_PATTERN_SYMBOL_ERROR
570 * 3 = DP_TEST_PATTERN_PRBS7
571 * 4 = DP_TEST_PATTERN_80BIT_CUSTOM
572 * 5 = DP_TEST_PATTERN_CP2520_1
573 * 6 = DP_TEST_PATTERN_CP2520_2 = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE
574 * 7 = DP_TEST_PATTERN_CP2520_3
575 *
576 * DP PHY Link Training Patterns
577 * 8 = DP_TEST_PATTERN_TRAINING_PATTERN1
578 * 9 = DP_TEST_PATTERN_TRAINING_PATTERN2
579 * a = DP_TEST_PATTERN_TRAINING_PATTERN3
580 * b = DP_TEST_PATTERN_TRAINING_PATTERN4
581 *
582 * DP Link Layer Test pattern
583 * c = DP_TEST_PATTERN_COLOR_SQUARES
584 * d = DP_TEST_PATTERN_COLOR_SQUARES_CEA
585 * e = DP_TEST_PATTERN_VERTICAL_BARS
586 * f = DP_TEST_PATTERN_HORIZONTAL_BARS
587 * 10= DP_TEST_PATTERN_COLOR_RAMP
588 *
589 * debugfs phy_test_pattern is located at /syskernel/debug/dri/0/DP-x
590 *
591 * --- set test pattern
592 * echo <test pattern #> > test_pattern
593 *
594 * If test pattern # is not supported, NO HW programming will be done.
595 * for DP_TEST_PATTERN_80BIT_CUSTOM, it needs extra 10 bytes of data
596 * for the user pattern. input 10 bytes data are separated by space
597 *
598 * echo 0x4 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x99 0xaa > test_pattern
599 *
600 * --- reset test pattern
601 * echo 0 > test_pattern
602 *
603 * --- HPD detection is disabled when set PHY test pattern
604 *
605 * when PHY test pattern (pattern # within [1,7]) is set, HPD pin of HW ASIC
606 * is disable. User could unplug DP display from DP connected and plug scope to
607 * check test pattern PHY SI.
608 * If there is need unplug scope and plug DP display back, do steps below:
609 * echo 0 > phy_test_pattern
610 * unplug scope
611 * plug DP display.
612 *
613 * "echo 0 > phy_test_pattern" will re-enable HPD pin again so that video sw
614 * driver could detect "unplug scope" and "plug DP display"
615 */
616static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __user *buf,
617 size_t size, loff_t *pos)
618{
619 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
620 struct dc_link *link = connector->dc_link;
621 char *wr_buf = NULL;
622 uint32_t wr_buf_size = 100;
623 long param[11] = {0x0};
624 int max_param_num = 11;
625 enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
626 bool disable_hpd = false;
627 bool valid_test_pattern = false;
628 uint8_t param_nums = 0;
629 /* init with default 80bit custom pattern */
630 uint8_t custom_pattern[10] = {
631 0x1f, 0x7c, 0xf0, 0xc1, 0x07,
632 0x1f, 0x7c, 0xf0, 0xc1, 0x07
633 };
634 struct dc_link_settings prefer_link_settings = {LANE_COUNT_UNKNOWN,
635 LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED};
636 struct dc_link_settings cur_link_settings = {LANE_COUNT_UNKNOWN,
637 LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED};
638 struct link_training_settings link_training_settings;
639 int i;
640
641 if (size == 0)
642 return -EINVAL;
643
644 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
645 if (!wr_buf)
646 return -ENOSPC;
647
648 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
649 (long *)param, buf,
650 max_param_num,
651 ¶m_nums)) {
652 kfree(wr_buf);
653 return -EINVAL;
654 }
655
656 if (param_nums <= 0) {
657 kfree(wr_buf);
658 DRM_DEBUG_DRIVER("user data not be read\n");
659 return -EINVAL;
660 }
661
662
663 test_pattern = param[0];
664
665 switch (test_pattern) {
666 case DP_TEST_PATTERN_VIDEO_MODE:
667 case DP_TEST_PATTERN_COLOR_SQUARES:
668 case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
669 case DP_TEST_PATTERN_VERTICAL_BARS:
670 case DP_TEST_PATTERN_HORIZONTAL_BARS:
671 case DP_TEST_PATTERN_COLOR_RAMP:
672 valid_test_pattern = true;
673 break;
674
675 case DP_TEST_PATTERN_D102:
676 case DP_TEST_PATTERN_SYMBOL_ERROR:
677 case DP_TEST_PATTERN_PRBS7:
678 case DP_TEST_PATTERN_80BIT_CUSTOM:
679 case DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE:
680 case DP_TEST_PATTERN_TRAINING_PATTERN4:
681 disable_hpd = true;
682 valid_test_pattern = true;
683 break;
684
685 default:
686 valid_test_pattern = false;
687 test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
688 break;
689 }
690
691 if (!valid_test_pattern) {
692 kfree(wr_buf);
693 DRM_DEBUG_DRIVER("Invalid Test Pattern Parameters\n");
694 return size;
695 }
696
697 if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) {
698 for (i = 0; i < 10; i++) {
699 if ((uint8_t) param[i + 1] != 0x0)
700 break;
701 }
702
703 if (i < 10) {
704 /* not use default value */
705 for (i = 0; i < 10; i++)
706 custom_pattern[i] = (uint8_t) param[i + 1];
707 }
708 }
709
710 /* Usage: set DP physical test pattern using debugfs with normal DP
711 * panel. Then plug out DP panel and connect a scope to measure
712 * For normal video mode and test pattern generated from CRCT,
713 * they are visibile to user. So do not disable HPD.
714 * Video Mode is also set to clear the test pattern, so enable HPD
715 * because it might have been disabled after a test pattern was set.
716 * AUX depends on HPD * sequence dependent, do not move!
717 */
718 if (!disable_hpd)
719 dc_link_enable_hpd(link);
720
721 prefer_link_settings.lane_count = link->verified_link_cap.lane_count;
722 prefer_link_settings.link_rate = link->verified_link_cap.link_rate;
723 prefer_link_settings.link_spread = link->verified_link_cap.link_spread;
724
725 cur_link_settings.lane_count = link->cur_link_settings.lane_count;
726 cur_link_settings.link_rate = link->cur_link_settings.link_rate;
727 cur_link_settings.link_spread = link->cur_link_settings.link_spread;
728
729 link_training_settings.link_settings = cur_link_settings;
730
731
732 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
733 if (prefer_link_settings.lane_count != LANE_COUNT_UNKNOWN &&
734 prefer_link_settings.link_rate != LINK_RATE_UNKNOWN &&
735 (prefer_link_settings.lane_count != cur_link_settings.lane_count ||
736 prefer_link_settings.link_rate != cur_link_settings.link_rate))
737 link_training_settings.link_settings = prefer_link_settings;
738 }
739
740 for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++)
741 link_training_settings.lane_settings[i] = link->cur_lane_setting[i];
742
743 dc_link_set_test_pattern(
744 link,
745 test_pattern,
746 DP_TEST_PATTERN_COLOR_SPACE_RGB,
747 &link_training_settings,
748 custom_pattern,
749 10);
750
751 /* Usage: Set DP physical test pattern using AMDDP with normal DP panel
752 * Then plug out DP panel and connect a scope to measure DP PHY signal.
753 * Need disable interrupt to avoid SW driver disable DP output. This is
754 * done after the test pattern is set.
755 */
756 if (valid_test_pattern && disable_hpd)
757 dc_link_disable_hpd(link);
758
759 kfree(wr_buf);
760
761 return size;
762}
763
764/*
765 * Returns the DMCUB tracebuffer contents.
766 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dmub_tracebuffer
767 */
768static int dmub_tracebuffer_show(struct seq_file *m, void *data)
769{
770 struct amdgpu_device *adev = m->private;
771 struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
772 struct dmub_debugfs_trace_entry *entries;
773 uint8_t *tbuf_base;
774 uint32_t tbuf_size, max_entries, num_entries, i;
775
776 if (!fb_info)
777 return 0;
778
779 tbuf_base = (uint8_t *)fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].cpu_addr;
780 if (!tbuf_base)
781 return 0;
782
783 tbuf_size = fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].size;
784 max_entries = (tbuf_size - sizeof(struct dmub_debugfs_trace_header)) /
785 sizeof(struct dmub_debugfs_trace_entry);
786
787 num_entries =
788 ((struct dmub_debugfs_trace_header *)tbuf_base)->entry_count;
789
790 num_entries = min(num_entries, max_entries);
791
792 entries = (struct dmub_debugfs_trace_entry
793 *)(tbuf_base +
794 sizeof(struct dmub_debugfs_trace_header));
795
796 for (i = 0; i < num_entries; ++i) {
797 struct dmub_debugfs_trace_entry *entry = &entries[i];
798
799 seq_printf(m,
800 "trace_code=%u tick_count=%u param0=%u param1=%u\n",
801 entry->trace_code, entry->tick_count, entry->param0,
802 entry->param1);
803 }
804
805 return 0;
806}
807
808/*
809 * Returns the DMCUB firmware state contents.
810 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dmub_fw_state
811 */
812static int dmub_fw_state_show(struct seq_file *m, void *data)
813{
814 struct amdgpu_device *adev = m->private;
815 struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
816 uint8_t *state_base;
817 uint32_t state_size;
818
819 if (!fb_info)
820 return 0;
821
822 state_base = (uint8_t *)fb_info->fb[DMUB_WINDOW_6_FW_STATE].cpu_addr;
823 if (!state_base)
824 return 0;
825
826 state_size = fb_info->fb[DMUB_WINDOW_6_FW_STATE].size;
827
828 return seq_write(m, state_base, state_size);
829}
830
831/* psr_capability_show() - show eDP panel PSR capability
832 *
833 * The read function: sink_psr_capability_show
834 * Shows if sink has PSR capability or not.
835 * If yes - the PSR version is appended
836 *
837 * cat /sys/kernel/debug/dri/0/eDP-X/psr_capability
838 *
839 * Expected output:
840 * "Sink support: no\n" - if panel doesn't support PSR
841 * "Sink support: yes [0x01]\n" - if panel supports PSR1
842 * "Driver support: no\n" - if driver doesn't support PSR
843 * "Driver support: yes [0x01]\n" - if driver supports PSR1
844 */
845static int psr_capability_show(struct seq_file *m, void *data)
846{
847 struct drm_connector *connector = m->private;
848 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
849 struct dc_link *link = aconnector->dc_link;
850
851 if (!link)
852 return -ENODEV;
853
854 if (link->type == dc_connection_none)
855 return -ENODEV;
856
857 if (!(link->connector_signal & SIGNAL_TYPE_EDP))
858 return -ENODEV;
859
860 seq_printf(m, "Sink support: %s", str_yes_no(link->dpcd_caps.psr_info.psr_version != 0));
861 if (link->dpcd_caps.psr_info.psr_version)
862 seq_printf(m, " [0x%02x]", link->dpcd_caps.psr_info.psr_version);
863 seq_puts(m, "\n");
864
865 seq_printf(m, "Driver support: %s", str_yes_no(link->psr_settings.psr_feature_enabled));
866 if (link->psr_settings.psr_version)
867 seq_printf(m, " [0x%02x]", link->psr_settings.psr_version);
868 seq_puts(m, "\n");
869
870 return 0;
871}
872
873/*
874 * Returns the current and maximum output bpc for the connector.
875 * Example usage: cat /sys/kernel/debug/dri/0/DP-1/output_bpc
876 */
877static int output_bpc_show(struct seq_file *m, void *data)
878{
879 struct drm_connector *connector = m->private;
880 struct drm_device *dev = connector->dev;
881 struct drm_crtc *crtc = NULL;
882 struct dm_crtc_state *dm_crtc_state = NULL;
883 int res = -ENODEV;
884 unsigned int bpc;
885
886 mutex_lock(&dev->mode_config.mutex);
887 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
888
889 if (connector->state == NULL)
890 goto unlock;
891
892 crtc = connector->state->crtc;
893 if (crtc == NULL)
894 goto unlock;
895
896 drm_modeset_lock(&crtc->mutex, NULL);
897 if (crtc->state == NULL)
898 goto unlock;
899
900 dm_crtc_state = to_dm_crtc_state(crtc->state);
901 if (dm_crtc_state->stream == NULL)
902 goto unlock;
903
904 switch (dm_crtc_state->stream->timing.display_color_depth) {
905 case COLOR_DEPTH_666:
906 bpc = 6;
907 break;
908 case COLOR_DEPTH_888:
909 bpc = 8;
910 break;
911 case COLOR_DEPTH_101010:
912 bpc = 10;
913 break;
914 case COLOR_DEPTH_121212:
915 bpc = 12;
916 break;
917 case COLOR_DEPTH_161616:
918 bpc = 16;
919 break;
920 default:
921 goto unlock;
922 }
923
924 seq_printf(m, "Current: %u\n", bpc);
925 seq_printf(m, "Maximum: %u\n", connector->display_info.bpc);
926 res = 0;
927
928unlock:
929 if (crtc)
930 drm_modeset_unlock(&crtc->mutex);
931
932 drm_modeset_unlock(&dev->mode_config.connection_mutex);
933 mutex_unlock(&dev->mode_config.mutex);
934
935 return res;
936}
937
938/*
939 * Example usage:
940 * Disable dsc passthrough, i.e.,: have dsc decoding at converver, not external RX
941 * echo 1 /sys/kernel/debug/dri/0/DP-1/dsc_disable_passthrough
942 * Enable dsc passthrough, i.e.,: have dsc passthrough to external RX
943 * echo 0 /sys/kernel/debug/dri/0/DP-1/dsc_disable_passthrough
944 */
945static ssize_t dp_dsc_passthrough_set(struct file *f, const char __user *buf,
946 size_t size, loff_t *pos)
947{
948 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
949 char *wr_buf = NULL;
950 uint32_t wr_buf_size = 42;
951 int max_param_num = 1;
952 long param;
953 uint8_t param_nums = 0;
954
955 if (size == 0)
956 return -EINVAL;
957
958 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
959
960 if (!wr_buf) {
961 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
962 return -ENOSPC;
963 }
964
965 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
966 ¶m, buf,
967 max_param_num,
968 ¶m_nums)) {
969 kfree(wr_buf);
970 return -EINVAL;
971 }
972
973 aconnector->dsc_settings.dsc_force_disable_passthrough = param;
974
975 kfree(wr_buf);
976 return 0;
977}
978
979#ifdef CONFIG_DRM_AMD_DC_HDCP
980/*
981 * Returns the HDCP capability of the Display (1.4 for now).
982 *
983 * NOTE* Not all HDMI displays report their HDCP caps even when they are capable.
984 * Since its rare for a display to not be HDCP 1.4 capable, we set HDMI as always capable.
985 *
986 * Example usage: cat /sys/kernel/debug/dri/0/DP-1/hdcp_sink_capability
987 * or cat /sys/kernel/debug/dri/0/HDMI-A-1/hdcp_sink_capability
988 */
989static int hdcp_sink_capability_show(struct seq_file *m, void *data)
990{
991 struct drm_connector *connector = m->private;
992 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
993 bool hdcp_cap, hdcp2_cap;
994
995 if (connector->status != connector_status_connected)
996 return -ENODEV;
997
998 seq_printf(m, "%s:%d HDCP version: ", connector->name, connector->base.id);
999
1000 hdcp_cap = dc_link_is_hdcp14(aconnector->dc_link, aconnector->dc_sink->sink_signal);
1001 hdcp2_cap = dc_link_is_hdcp22(aconnector->dc_link, aconnector->dc_sink->sink_signal);
1002
1003
1004 if (hdcp_cap)
1005 seq_printf(m, "%s ", "HDCP1.4");
1006 if (hdcp2_cap)
1007 seq_printf(m, "%s ", "HDCP2.2");
1008
1009 if (!hdcp_cap && !hdcp2_cap)
1010 seq_printf(m, "%s ", "None");
1011
1012 seq_puts(m, "\n");
1013
1014 return 0;
1015}
1016#endif
1017
1018/*
1019 * Returns whether the connected display is internal and not hotpluggable.
1020 * Example usage: cat /sys/kernel/debug/dri/0/DP-1/internal_display
1021 */
1022static int internal_display_show(struct seq_file *m, void *data)
1023{
1024 struct drm_connector *connector = m->private;
1025 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
1026 struct dc_link *link = aconnector->dc_link;
1027
1028 seq_printf(m, "Internal: %u\n", link->is_internal_display);
1029
1030 return 0;
1031}
1032
1033/* function description
1034 *
1035 * generic SDP message access for testing
1036 *
1037 * debugfs sdp_message is located at /syskernel/debug/dri/0/DP-x
1038 *
1039 * SDP header
1040 * Hb0 : Secondary-Data Packet ID
1041 * Hb1 : Secondary-Data Packet type
1042 * Hb2 : Secondary-Data-packet-specific header, Byte 0
1043 * Hb3 : Secondary-Data-packet-specific header, Byte 1
1044 *
1045 * for using custom sdp message: input 4 bytes SDP header and 32 bytes raw data
1046 */
1047static ssize_t dp_sdp_message_debugfs_write(struct file *f, const char __user *buf,
1048 size_t size, loff_t *pos)
1049{
1050 int r;
1051 uint8_t data[36];
1052 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
1053 struct dm_crtc_state *acrtc_state;
1054 uint32_t write_size = 36;
1055
1056 if (connector->base.status != connector_status_connected)
1057 return -ENODEV;
1058
1059 if (size == 0)
1060 return 0;
1061
1062 acrtc_state = to_dm_crtc_state(connector->base.state->crtc->state);
1063
1064 r = copy_from_user(data, buf, write_size);
1065
1066 write_size -= r;
1067
1068 dc_stream_send_dp_sdp(acrtc_state->stream, data, write_size);
1069
1070 return write_size;
1071}
1072
1073static ssize_t dp_dpcd_address_write(struct file *f, const char __user *buf,
1074 size_t size, loff_t *pos)
1075{
1076 int r;
1077 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
1078
1079 if (size < sizeof(connector->debugfs_dpcd_address))
1080 return -EINVAL;
1081
1082 r = copy_from_user(&connector->debugfs_dpcd_address,
1083 buf, sizeof(connector->debugfs_dpcd_address));
1084
1085 return size - r;
1086}
1087
1088static ssize_t dp_dpcd_size_write(struct file *f, const char __user *buf,
1089 size_t size, loff_t *pos)
1090{
1091 int r;
1092 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
1093
1094 if (size < sizeof(connector->debugfs_dpcd_size))
1095 return -EINVAL;
1096
1097 r = copy_from_user(&connector->debugfs_dpcd_size,
1098 buf, sizeof(connector->debugfs_dpcd_size));
1099
1100 if (connector->debugfs_dpcd_size > 256)
1101 connector->debugfs_dpcd_size = 0;
1102
1103 return size - r;
1104}
1105
1106static ssize_t dp_dpcd_data_write(struct file *f, const char __user *buf,
1107 size_t size, loff_t *pos)
1108{
1109 int r;
1110 char *data;
1111 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
1112 struct dc_link *link = connector->dc_link;
1113 uint32_t write_size = connector->debugfs_dpcd_size;
1114
1115 if (!write_size || size < write_size)
1116 return -EINVAL;
1117
1118 data = kzalloc(write_size, GFP_KERNEL);
1119 if (!data)
1120 return 0;
1121
1122 r = copy_from_user(data, buf, write_size);
1123
1124 dm_helpers_dp_write_dpcd(link->ctx, link,
1125 connector->debugfs_dpcd_address, data, write_size - r);
1126 kfree(data);
1127 return write_size - r;
1128}
1129
1130static ssize_t dp_dpcd_data_read(struct file *f, char __user *buf,
1131 size_t size, loff_t *pos)
1132{
1133 int r;
1134 char *data;
1135 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
1136 struct dc_link *link = connector->dc_link;
1137 uint32_t read_size = connector->debugfs_dpcd_size;
1138
1139 if (!read_size || size < read_size)
1140 return 0;
1141
1142 data = kzalloc(read_size, GFP_KERNEL);
1143 if (!data)
1144 return 0;
1145
1146 dm_helpers_dp_read_dpcd(link->ctx, link,
1147 connector->debugfs_dpcd_address, data, read_size);
1148
1149 r = copy_to_user(buf, data, read_size);
1150
1151 kfree(data);
1152 return read_size - r;
1153}
1154
1155/* function: Read link's DSC & FEC capabilities
1156 *
1157 *
1158 * Access it with the following command (you need to specify
1159 * connector like DP-1):
1160 *
1161 * cat /sys/kernel/debug/dri/0/DP-X/dp_dsc_fec_support
1162 *
1163 */
1164static int dp_dsc_fec_support_show(struct seq_file *m, void *data)
1165{
1166 struct drm_connector *connector = m->private;
1167 struct drm_modeset_acquire_ctx ctx;
1168 struct drm_device *dev = connector->dev;
1169 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
1170 int ret = 0;
1171 bool try_again = false;
1172 bool is_fec_supported = false;
1173 bool is_dsc_supported = false;
1174 struct dpcd_caps dpcd_caps;
1175
1176 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
1177 do {
1178 try_again = false;
1179 ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx);
1180 if (ret) {
1181 if (ret == -EDEADLK) {
1182 ret = drm_modeset_backoff(&ctx);
1183 if (!ret) {
1184 try_again = true;
1185 continue;
1186 }
1187 }
1188 break;
1189 }
1190 if (connector->status != connector_status_connected) {
1191 ret = -ENODEV;
1192 break;
1193 }
1194 dpcd_caps = aconnector->dc_link->dpcd_caps;
1195 if (aconnector->port) {
1196 /* aconnector sets dsc_aux during get_modes call
1197 * if MST connector has it means it can either
1198 * enable DSC on the sink device or on MST branch
1199 * its connected to.
1200 */
1201 if (aconnector->dsc_aux) {
1202 is_fec_supported = true;
1203 is_dsc_supported = true;
1204 }
1205 } else {
1206 is_fec_supported = dpcd_caps.fec_cap.raw & 0x1;
1207 is_dsc_supported = dpcd_caps.dsc_caps.dsc_basic_caps.raw[0] & 0x1;
1208 }
1209 } while (try_again);
1210
1211 drm_modeset_drop_locks(&ctx);
1212 drm_modeset_acquire_fini(&ctx);
1213
1214 seq_printf(m, "FEC_Sink_Support: %s\n", str_yes_no(is_fec_supported));
1215 seq_printf(m, "DSC_Sink_Support: %s\n", str_yes_no(is_dsc_supported));
1216
1217 return ret;
1218}
1219
1220/* function: Trigger virtual HPD redetection on connector
1221 *
1222 * This function will perform link rediscovery, link disable
1223 * and enable, and dm connector state update.
1224 *
1225 * Retrigger HPD on an existing connector by echoing 1 into
1226 * its respectful "trigger_hotplug" debugfs entry:
1227 *
1228 * echo 1 > /sys/kernel/debug/dri/0/DP-X/trigger_hotplug
1229 *
1230 * This function can perform HPD unplug:
1231 *
1232 * echo 0 > /sys/kernel/debug/dri/0/DP-X/trigger_hotplug
1233 *
1234 */
1235static ssize_t trigger_hotplug(struct file *f, const char __user *buf,
1236 size_t size, loff_t *pos)
1237{
1238 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1239 struct drm_connector *connector = &aconnector->base;
1240 struct dc_link *link = NULL;
1241 struct drm_device *dev = connector->dev;
1242 enum dc_connection_type new_connection_type = dc_connection_none;
1243 char *wr_buf = NULL;
1244 uint32_t wr_buf_size = 42;
1245 int max_param_num = 1;
1246 long param[1] = {0};
1247 uint8_t param_nums = 0;
1248
1249 if (!aconnector || !aconnector->dc_link)
1250 return -EINVAL;
1251
1252 if (size == 0)
1253 return -EINVAL;
1254
1255 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1256
1257 if (!wr_buf) {
1258 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1259 return -ENOSPC;
1260 }
1261
1262 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
1263 (long *)param, buf,
1264 max_param_num,
1265 ¶m_nums)) {
1266 kfree(wr_buf);
1267 return -EINVAL;
1268 }
1269
1270 if (param_nums <= 0) {
1271 DRM_DEBUG_DRIVER("user data not be read\n");
1272 kfree(wr_buf);
1273 return -EINVAL;
1274 }
1275
1276 if (param[0] == 1) {
1277 mutex_lock(&aconnector->hpd_lock);
1278
1279 if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type) &&
1280 new_connection_type != dc_connection_none)
1281 goto unlock;
1282
1283 if (!dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD))
1284 goto unlock;
1285
1286 amdgpu_dm_update_connector_after_detect(aconnector);
1287
1288 drm_modeset_lock_all(dev);
1289 dm_restore_drm_connector_state(dev, connector);
1290 drm_modeset_unlock_all(dev);
1291
1292 drm_kms_helper_connector_hotplug_event(connector);
1293 } else if (param[0] == 0) {
1294 if (!aconnector->dc_link)
1295 goto unlock;
1296
1297 link = aconnector->dc_link;
1298
1299 if (link->local_sink) {
1300 dc_sink_release(link->local_sink);
1301 link->local_sink = NULL;
1302 }
1303
1304 link->dpcd_sink_count = 0;
1305 link->type = dc_connection_none;
1306 link->dongle_max_pix_clk = 0;
1307
1308 amdgpu_dm_update_connector_after_detect(aconnector);
1309
1310 drm_modeset_lock_all(dev);
1311 dm_restore_drm_connector_state(dev, connector);
1312 drm_modeset_unlock_all(dev);
1313
1314 drm_kms_helper_connector_hotplug_event(connector);
1315 }
1316
1317unlock:
1318 mutex_unlock(&aconnector->hpd_lock);
1319
1320 kfree(wr_buf);
1321 return size;
1322}
1323
1324/* function: read DSC status on the connector
1325 *
1326 * The read function: dp_dsc_clock_en_read
1327 * returns current status of DSC clock on the connector.
1328 * The return is a boolean flag: 1 or 0.
1329 *
1330 * Access it with the following command (you need to specify
1331 * connector like DP-1):
1332 *
1333 * cat /sys/kernel/debug/dri/0/DP-X/dsc_clock_en
1334 *
1335 * Expected output:
1336 * 1 - means that DSC is currently enabled
1337 * 0 - means that DSC is disabled
1338 */
1339static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
1340 size_t size, loff_t *pos)
1341{
1342 char *rd_buf = NULL;
1343 char *rd_buf_ptr = NULL;
1344 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1345 struct display_stream_compressor *dsc;
1346 struct dcn_dsc_state dsc_state = {0};
1347 const uint32_t rd_buf_size = 10;
1348 struct pipe_ctx *pipe_ctx;
1349 ssize_t result = 0;
1350 int i, r, str_len = 30;
1351
1352 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1353
1354 if (!rd_buf)
1355 return -ENOMEM;
1356
1357 rd_buf_ptr = rd_buf;
1358
1359 for (i = 0; i < MAX_PIPES; i++) {
1360 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1361 if (pipe_ctx && pipe_ctx->stream &&
1362 pipe_ctx->stream->link == aconnector->dc_link)
1363 break;
1364 }
1365
1366 if (!pipe_ctx) {
1367 kfree(rd_buf);
1368 return -ENXIO;
1369 }
1370
1371 dsc = pipe_ctx->stream_res.dsc;
1372 if (dsc)
1373 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1374
1375 snprintf(rd_buf_ptr, str_len,
1376 "%d\n",
1377 dsc_state.dsc_clock_en);
1378 rd_buf_ptr += str_len;
1379
1380 while (size) {
1381 if (*pos >= rd_buf_size)
1382 break;
1383
1384 r = put_user(*(rd_buf + result), buf);
1385 if (r) {
1386 kfree(rd_buf);
1387 return r; /* r = -EFAULT */
1388 }
1389
1390 buf += 1;
1391 size -= 1;
1392 *pos += 1;
1393 result += 1;
1394 }
1395
1396 kfree(rd_buf);
1397 return result;
1398}
1399
1400/* function: write force DSC on the connector
1401 *
1402 * The write function: dp_dsc_clock_en_write
1403 * enables to force DSC on the connector.
1404 * User can write to either force enable or force disable DSC
1405 * on the next modeset or set it to driver default
1406 *
1407 * Accepted inputs:
1408 * 0 - default DSC enablement policy
1409 * 1 - force enable DSC on the connector
1410 * 2 - force disable DSC on the connector (might cause fail in atomic_check)
1411 *
1412 * Writing DSC settings is done with the following command:
1413 * - To force enable DSC (you need to specify
1414 * connector like DP-1):
1415 *
1416 * echo 0x1 > /sys/kernel/debug/dri/0/DP-X/dsc_clock_en
1417 *
1418 * - To return to default state set the flag to zero and
1419 * let driver deal with DSC automatically
1420 * (you need to specify connector like DP-1):
1421 *
1422 * echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_clock_en
1423 *
1424 */
1425static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf,
1426 size_t size, loff_t *pos)
1427{
1428 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1429 struct drm_connector *connector = &aconnector->base;
1430 struct drm_device *dev = connector->dev;
1431 struct drm_crtc *crtc = NULL;
1432 struct dm_crtc_state *dm_crtc_state = NULL;
1433 struct pipe_ctx *pipe_ctx;
1434 int i;
1435 char *wr_buf = NULL;
1436 uint32_t wr_buf_size = 42;
1437 int max_param_num = 1;
1438 long param[1] = {0};
1439 uint8_t param_nums = 0;
1440
1441 if (size == 0)
1442 return -EINVAL;
1443
1444 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1445
1446 if (!wr_buf) {
1447 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1448 return -ENOSPC;
1449 }
1450
1451 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
1452 (long *)param, buf,
1453 max_param_num,
1454 ¶m_nums)) {
1455 kfree(wr_buf);
1456 return -EINVAL;
1457 }
1458
1459 if (param_nums <= 0) {
1460 DRM_DEBUG_DRIVER("user data not be read\n");
1461 kfree(wr_buf);
1462 return -EINVAL;
1463 }
1464
1465 for (i = 0; i < MAX_PIPES; i++) {
1466 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1467 if (pipe_ctx && pipe_ctx->stream &&
1468 pipe_ctx->stream->link == aconnector->dc_link)
1469 break;
1470 }
1471
1472 if (!pipe_ctx || !pipe_ctx->stream)
1473 goto done;
1474
1475 // Get CRTC state
1476 mutex_lock(&dev->mode_config.mutex);
1477 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1478
1479 if (connector->state == NULL)
1480 goto unlock;
1481
1482 crtc = connector->state->crtc;
1483 if (crtc == NULL)
1484 goto unlock;
1485
1486 drm_modeset_lock(&crtc->mutex, NULL);
1487 if (crtc->state == NULL)
1488 goto unlock;
1489
1490 dm_crtc_state = to_dm_crtc_state(crtc->state);
1491 if (dm_crtc_state->stream == NULL)
1492 goto unlock;
1493
1494 if (param[0] == 1)
1495 aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_ENABLE;
1496 else if (param[0] == 2)
1497 aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_DISABLE;
1498 else
1499 aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_DEFAULT;
1500
1501 dm_crtc_state->dsc_force_changed = true;
1502
1503unlock:
1504 if (crtc)
1505 drm_modeset_unlock(&crtc->mutex);
1506 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1507 mutex_unlock(&dev->mode_config.mutex);
1508
1509done:
1510 kfree(wr_buf);
1511 return size;
1512}
1513
1514/* function: read DSC slice width parameter on the connector
1515 *
1516 * The read function: dp_dsc_slice_width_read
1517 * returns dsc slice width used in the current configuration
1518 * The return is an integer: 0 or other positive number
1519 *
1520 * Access the status with the following command:
1521 *
1522 * cat /sys/kernel/debug/dri/0/DP-X/dsc_slice_width
1523 *
1524 * 0 - means that DSC is disabled
1525 *
1526 * Any other number more than zero represents the
1527 * slice width currently used by DSC in pixels
1528 *
1529 */
1530static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
1531 size_t size, loff_t *pos)
1532{
1533 char *rd_buf = NULL;
1534 char *rd_buf_ptr = NULL;
1535 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1536 struct display_stream_compressor *dsc;
1537 struct dcn_dsc_state dsc_state = {0};
1538 const uint32_t rd_buf_size = 100;
1539 struct pipe_ctx *pipe_ctx;
1540 ssize_t result = 0;
1541 int i, r, str_len = 30;
1542
1543 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1544
1545 if (!rd_buf)
1546 return -ENOMEM;
1547
1548 rd_buf_ptr = rd_buf;
1549
1550 for (i = 0; i < MAX_PIPES; i++) {
1551 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1552 if (pipe_ctx && pipe_ctx->stream &&
1553 pipe_ctx->stream->link == aconnector->dc_link)
1554 break;
1555 }
1556
1557 if (!pipe_ctx) {
1558 kfree(rd_buf);
1559 return -ENXIO;
1560 }
1561
1562 dsc = pipe_ctx->stream_res.dsc;
1563 if (dsc)
1564 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1565
1566 snprintf(rd_buf_ptr, str_len,
1567 "%d\n",
1568 dsc_state.dsc_slice_width);
1569 rd_buf_ptr += str_len;
1570
1571 while (size) {
1572 if (*pos >= rd_buf_size)
1573 break;
1574
1575 r = put_user(*(rd_buf + result), buf);
1576 if (r) {
1577 kfree(rd_buf);
1578 return r; /* r = -EFAULT */
1579 }
1580
1581 buf += 1;
1582 size -= 1;
1583 *pos += 1;
1584 result += 1;
1585 }
1586
1587 kfree(rd_buf);
1588 return result;
1589}
1590
1591/* function: write DSC slice width parameter
1592 *
1593 * The write function: dp_dsc_slice_width_write
1594 * overwrites automatically generated DSC configuration
1595 * of slice width.
1596 *
1597 * The user has to write the slice width divisible by the
1598 * picture width.
1599 *
1600 * Also the user has to write width in hexidecimal
1601 * rather than in decimal.
1602 *
1603 * Writing DSC settings is done with the following command:
1604 * - To force overwrite slice width: (example sets to 1920 pixels)
1605 *
1606 * echo 0x780 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_width
1607 *
1608 * - To stop overwriting and let driver find the optimal size,
1609 * set the width to zero:
1610 *
1611 * echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_width
1612 *
1613 */
1614static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf,
1615 size_t size, loff_t *pos)
1616{
1617 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1618 struct pipe_ctx *pipe_ctx;
1619 struct drm_connector *connector = &aconnector->base;
1620 struct drm_device *dev = connector->dev;
1621 struct drm_crtc *crtc = NULL;
1622 struct dm_crtc_state *dm_crtc_state = NULL;
1623 int i;
1624 char *wr_buf = NULL;
1625 uint32_t wr_buf_size = 42;
1626 int max_param_num = 1;
1627 long param[1] = {0};
1628 uint8_t param_nums = 0;
1629
1630 if (size == 0)
1631 return -EINVAL;
1632
1633 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1634
1635 if (!wr_buf) {
1636 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1637 return -ENOSPC;
1638 }
1639
1640 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
1641 (long *)param, buf,
1642 max_param_num,
1643 ¶m_nums)) {
1644 kfree(wr_buf);
1645 return -EINVAL;
1646 }
1647
1648 if (param_nums <= 0) {
1649 DRM_DEBUG_DRIVER("user data not be read\n");
1650 kfree(wr_buf);
1651 return -EINVAL;
1652 }
1653
1654 for (i = 0; i < MAX_PIPES; i++) {
1655 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1656 if (pipe_ctx && pipe_ctx->stream &&
1657 pipe_ctx->stream->link == aconnector->dc_link)
1658 break;
1659 }
1660
1661 if (!pipe_ctx || !pipe_ctx->stream)
1662 goto done;
1663
1664 // Safely get CRTC state
1665 mutex_lock(&dev->mode_config.mutex);
1666 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1667
1668 if (connector->state == NULL)
1669 goto unlock;
1670
1671 crtc = connector->state->crtc;
1672 if (crtc == NULL)
1673 goto unlock;
1674
1675 drm_modeset_lock(&crtc->mutex, NULL);
1676 if (crtc->state == NULL)
1677 goto unlock;
1678
1679 dm_crtc_state = to_dm_crtc_state(crtc->state);
1680 if (dm_crtc_state->stream == NULL)
1681 goto unlock;
1682
1683 if (param[0] > 0)
1684 aconnector->dsc_settings.dsc_num_slices_h = DIV_ROUND_UP(
1685 pipe_ctx->stream->timing.h_addressable,
1686 param[0]);
1687 else
1688 aconnector->dsc_settings.dsc_num_slices_h = 0;
1689
1690 dm_crtc_state->dsc_force_changed = true;
1691
1692unlock:
1693 if (crtc)
1694 drm_modeset_unlock(&crtc->mutex);
1695 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1696 mutex_unlock(&dev->mode_config.mutex);
1697
1698done:
1699 kfree(wr_buf);
1700 return size;
1701}
1702
1703/* function: read DSC slice height parameter on the connector
1704 *
1705 * The read function: dp_dsc_slice_height_read
1706 * returns dsc slice height used in the current configuration
1707 * The return is an integer: 0 or other positive number
1708 *
1709 * Access the status with the following command:
1710 *
1711 * cat /sys/kernel/debug/dri/0/DP-X/dsc_slice_height
1712 *
1713 * 0 - means that DSC is disabled
1714 *
1715 * Any other number more than zero represents the
1716 * slice height currently used by DSC in pixels
1717 *
1718 */
1719static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
1720 size_t size, loff_t *pos)
1721{
1722 char *rd_buf = NULL;
1723 char *rd_buf_ptr = NULL;
1724 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1725 struct display_stream_compressor *dsc;
1726 struct dcn_dsc_state dsc_state = {0};
1727 const uint32_t rd_buf_size = 100;
1728 struct pipe_ctx *pipe_ctx;
1729 ssize_t result = 0;
1730 int i, r, str_len = 30;
1731
1732 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1733
1734 if (!rd_buf)
1735 return -ENOMEM;
1736
1737 rd_buf_ptr = rd_buf;
1738
1739 for (i = 0; i < MAX_PIPES; i++) {
1740 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1741 if (pipe_ctx && pipe_ctx->stream &&
1742 pipe_ctx->stream->link == aconnector->dc_link)
1743 break;
1744 }
1745
1746 if (!pipe_ctx) {
1747 kfree(rd_buf);
1748 return -ENXIO;
1749 }
1750
1751 dsc = pipe_ctx->stream_res.dsc;
1752 if (dsc)
1753 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1754
1755 snprintf(rd_buf_ptr, str_len,
1756 "%d\n",
1757 dsc_state.dsc_slice_height);
1758 rd_buf_ptr += str_len;
1759
1760 while (size) {
1761 if (*pos >= rd_buf_size)
1762 break;
1763
1764 r = put_user(*(rd_buf + result), buf);
1765 if (r) {
1766 kfree(rd_buf);
1767 return r; /* r = -EFAULT */
1768 }
1769
1770 buf += 1;
1771 size -= 1;
1772 *pos += 1;
1773 result += 1;
1774 }
1775
1776 kfree(rd_buf);
1777 return result;
1778}
1779
1780/* function: write DSC slice height parameter
1781 *
1782 * The write function: dp_dsc_slice_height_write
1783 * overwrites automatically generated DSC configuration
1784 * of slice height.
1785 *
1786 * The user has to write the slice height divisible by the
1787 * picture height.
1788 *
1789 * Also the user has to write height in hexidecimal
1790 * rather than in decimal.
1791 *
1792 * Writing DSC settings is done with the following command:
1793 * - To force overwrite slice height (example sets to 128 pixels):
1794 *
1795 * echo 0x80 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_height
1796 *
1797 * - To stop overwriting and let driver find the optimal size,
1798 * set the height to zero:
1799 *
1800 * echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_height
1801 *
1802 */
1803static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf,
1804 size_t size, loff_t *pos)
1805{
1806 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1807 struct drm_connector *connector = &aconnector->base;
1808 struct drm_device *dev = connector->dev;
1809 struct drm_crtc *crtc = NULL;
1810 struct dm_crtc_state *dm_crtc_state = NULL;
1811 struct pipe_ctx *pipe_ctx;
1812 int i;
1813 char *wr_buf = NULL;
1814 uint32_t wr_buf_size = 42;
1815 int max_param_num = 1;
1816 uint8_t param_nums = 0;
1817 long param[1] = {0};
1818
1819 if (size == 0)
1820 return -EINVAL;
1821
1822 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1823
1824 if (!wr_buf) {
1825 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1826 return -ENOSPC;
1827 }
1828
1829 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
1830 (long *)param, buf,
1831 max_param_num,
1832 ¶m_nums)) {
1833 kfree(wr_buf);
1834 return -EINVAL;
1835 }
1836
1837 if (param_nums <= 0) {
1838 DRM_DEBUG_DRIVER("user data not be read\n");
1839 kfree(wr_buf);
1840 return -EINVAL;
1841 }
1842
1843 for (i = 0; i < MAX_PIPES; i++) {
1844 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1845 if (pipe_ctx && pipe_ctx->stream &&
1846 pipe_ctx->stream->link == aconnector->dc_link)
1847 break;
1848 }
1849
1850 if (!pipe_ctx || !pipe_ctx->stream)
1851 goto done;
1852
1853 // Get CRTC state
1854 mutex_lock(&dev->mode_config.mutex);
1855 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1856
1857 if (connector->state == NULL)
1858 goto unlock;
1859
1860 crtc = connector->state->crtc;
1861 if (crtc == NULL)
1862 goto unlock;
1863
1864 drm_modeset_lock(&crtc->mutex, NULL);
1865 if (crtc->state == NULL)
1866 goto unlock;
1867
1868 dm_crtc_state = to_dm_crtc_state(crtc->state);
1869 if (dm_crtc_state->stream == NULL)
1870 goto unlock;
1871
1872 if (param[0] > 0)
1873 aconnector->dsc_settings.dsc_num_slices_v = DIV_ROUND_UP(
1874 pipe_ctx->stream->timing.v_addressable,
1875 param[0]);
1876 else
1877 aconnector->dsc_settings.dsc_num_slices_v = 0;
1878
1879 dm_crtc_state->dsc_force_changed = true;
1880
1881unlock:
1882 if (crtc)
1883 drm_modeset_unlock(&crtc->mutex);
1884 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1885 mutex_unlock(&dev->mode_config.mutex);
1886
1887done:
1888 kfree(wr_buf);
1889 return size;
1890}
1891
1892/* function: read DSC target rate on the connector in bits per pixel
1893 *
1894 * The read function: dp_dsc_bits_per_pixel_read
1895 * returns target rate of compression in bits per pixel
1896 * The return is an integer: 0 or other positive integer
1897 *
1898 * Access it with the following command:
1899 *
1900 * cat /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
1901 *
1902 * 0 - means that DSC is disabled
1903 */
1904static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
1905 size_t size, loff_t *pos)
1906{
1907 char *rd_buf = NULL;
1908 char *rd_buf_ptr = NULL;
1909 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1910 struct display_stream_compressor *dsc;
1911 struct dcn_dsc_state dsc_state = {0};
1912 const uint32_t rd_buf_size = 100;
1913 struct pipe_ctx *pipe_ctx;
1914 ssize_t result = 0;
1915 int i, r, str_len = 30;
1916
1917 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1918
1919 if (!rd_buf)
1920 return -ENOMEM;
1921
1922 rd_buf_ptr = rd_buf;
1923
1924 for (i = 0; i < MAX_PIPES; i++) {
1925 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1926 if (pipe_ctx && pipe_ctx->stream &&
1927 pipe_ctx->stream->link == aconnector->dc_link)
1928 break;
1929 }
1930
1931 if (!pipe_ctx) {
1932 kfree(rd_buf);
1933 return -ENXIO;
1934 }
1935
1936 dsc = pipe_ctx->stream_res.dsc;
1937 if (dsc)
1938 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1939
1940 snprintf(rd_buf_ptr, str_len,
1941 "%d\n",
1942 dsc_state.dsc_bits_per_pixel);
1943 rd_buf_ptr += str_len;
1944
1945 while (size) {
1946 if (*pos >= rd_buf_size)
1947 break;
1948
1949 r = put_user(*(rd_buf + result), buf);
1950 if (r) {
1951 kfree(rd_buf);
1952 return r; /* r = -EFAULT */
1953 }
1954
1955 buf += 1;
1956 size -= 1;
1957 *pos += 1;
1958 result += 1;
1959 }
1960
1961 kfree(rd_buf);
1962 return result;
1963}
1964
1965/* function: write DSC target rate in bits per pixel
1966 *
1967 * The write function: dp_dsc_bits_per_pixel_write
1968 * overwrites automatically generated DSC configuration
1969 * of DSC target bit rate.
1970 *
1971 * Also the user has to write bpp in hexidecimal
1972 * rather than in decimal.
1973 *
1974 * Writing DSC settings is done with the following command:
1975 * - To force overwrite rate (example sets to 256 bpp x 1/16):
1976 *
1977 * echo 0x100 > /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
1978 *
1979 * - To stop overwriting and let driver find the optimal rate,
1980 * set the rate to zero:
1981 *
1982 * echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
1983 *
1984 */
1985static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *buf,
1986 size_t size, loff_t *pos)
1987{
1988 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1989 struct drm_connector *connector = &aconnector->base;
1990 struct drm_device *dev = connector->dev;
1991 struct drm_crtc *crtc = NULL;
1992 struct dm_crtc_state *dm_crtc_state = NULL;
1993 struct pipe_ctx *pipe_ctx;
1994 int i;
1995 char *wr_buf = NULL;
1996 uint32_t wr_buf_size = 42;
1997 int max_param_num = 1;
1998 uint8_t param_nums = 0;
1999 long param[1] = {0};
2000
2001 if (size == 0)
2002 return -EINVAL;
2003
2004 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
2005
2006 if (!wr_buf) {
2007 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
2008 return -ENOSPC;
2009 }
2010
2011 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
2012 (long *)param, buf,
2013 max_param_num,
2014 ¶m_nums)) {
2015 kfree(wr_buf);
2016 return -EINVAL;
2017 }
2018
2019 if (param_nums <= 0) {
2020 DRM_DEBUG_DRIVER("user data not be read\n");
2021 kfree(wr_buf);
2022 return -EINVAL;
2023 }
2024
2025 for (i = 0; i < MAX_PIPES; i++) {
2026 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2027 if (pipe_ctx && pipe_ctx->stream &&
2028 pipe_ctx->stream->link == aconnector->dc_link)
2029 break;
2030 }
2031
2032 if (!pipe_ctx || !pipe_ctx->stream)
2033 goto done;
2034
2035 // Get CRTC state
2036 mutex_lock(&dev->mode_config.mutex);
2037 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2038
2039 if (connector->state == NULL)
2040 goto unlock;
2041
2042 crtc = connector->state->crtc;
2043 if (crtc == NULL)
2044 goto unlock;
2045
2046 drm_modeset_lock(&crtc->mutex, NULL);
2047 if (crtc->state == NULL)
2048 goto unlock;
2049
2050 dm_crtc_state = to_dm_crtc_state(crtc->state);
2051 if (dm_crtc_state->stream == NULL)
2052 goto unlock;
2053
2054 aconnector->dsc_settings.dsc_bits_per_pixel = param[0];
2055
2056 dm_crtc_state->dsc_force_changed = true;
2057
2058unlock:
2059 if (crtc)
2060 drm_modeset_unlock(&crtc->mutex);
2061 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2062 mutex_unlock(&dev->mode_config.mutex);
2063
2064done:
2065 kfree(wr_buf);
2066 return size;
2067}
2068
2069/* function: read DSC picture width parameter on the connector
2070 *
2071 * The read function: dp_dsc_pic_width_read
2072 * returns dsc picture width used in the current configuration
2073 * It is the same as h_addressable of the current
2074 * display's timing
2075 * The return is an integer: 0 or other positive integer
2076 * If 0 then DSC is disabled.
2077 *
2078 * Access it with the following command:
2079 *
2080 * cat /sys/kernel/debug/dri/0/DP-X/dsc_pic_width
2081 *
2082 * 0 - means that DSC is disabled
2083 */
2084static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
2085 size_t size, loff_t *pos)
2086{
2087 char *rd_buf = NULL;
2088 char *rd_buf_ptr = NULL;
2089 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2090 struct display_stream_compressor *dsc;
2091 struct dcn_dsc_state dsc_state = {0};
2092 const uint32_t rd_buf_size = 100;
2093 struct pipe_ctx *pipe_ctx;
2094 ssize_t result = 0;
2095 int i, r, str_len = 30;
2096
2097 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2098
2099 if (!rd_buf)
2100 return -ENOMEM;
2101
2102 rd_buf_ptr = rd_buf;
2103
2104 for (i = 0; i < MAX_PIPES; i++) {
2105 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2106 if (pipe_ctx && pipe_ctx->stream &&
2107 pipe_ctx->stream->link == aconnector->dc_link)
2108 break;
2109 }
2110
2111 if (!pipe_ctx) {
2112 kfree(rd_buf);
2113 return -ENXIO;
2114 }
2115
2116 dsc = pipe_ctx->stream_res.dsc;
2117 if (dsc)
2118 dsc->funcs->dsc_read_state(dsc, &dsc_state);
2119
2120 snprintf(rd_buf_ptr, str_len,
2121 "%d\n",
2122 dsc_state.dsc_pic_width);
2123 rd_buf_ptr += str_len;
2124
2125 while (size) {
2126 if (*pos >= rd_buf_size)
2127 break;
2128
2129 r = put_user(*(rd_buf + result), buf);
2130 if (r) {
2131 kfree(rd_buf);
2132 return r; /* r = -EFAULT */
2133 }
2134
2135 buf += 1;
2136 size -= 1;
2137 *pos += 1;
2138 result += 1;
2139 }
2140
2141 kfree(rd_buf);
2142 return result;
2143}
2144
2145static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
2146 size_t size, loff_t *pos)
2147{
2148 char *rd_buf = NULL;
2149 char *rd_buf_ptr = NULL;
2150 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2151 struct display_stream_compressor *dsc;
2152 struct dcn_dsc_state dsc_state = {0};
2153 const uint32_t rd_buf_size = 100;
2154 struct pipe_ctx *pipe_ctx;
2155 ssize_t result = 0;
2156 int i, r, str_len = 30;
2157
2158 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2159
2160 if (!rd_buf)
2161 return -ENOMEM;
2162
2163 rd_buf_ptr = rd_buf;
2164
2165 for (i = 0; i < MAX_PIPES; i++) {
2166 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2167 if (pipe_ctx && pipe_ctx->stream &&
2168 pipe_ctx->stream->link == aconnector->dc_link)
2169 break;
2170 }
2171
2172 if (!pipe_ctx) {
2173 kfree(rd_buf);
2174 return -ENXIO;
2175 }
2176
2177 dsc = pipe_ctx->stream_res.dsc;
2178 if (dsc)
2179 dsc->funcs->dsc_read_state(dsc, &dsc_state);
2180
2181 snprintf(rd_buf_ptr, str_len,
2182 "%d\n",
2183 dsc_state.dsc_pic_height);
2184 rd_buf_ptr += str_len;
2185
2186 while (size) {
2187 if (*pos >= rd_buf_size)
2188 break;
2189
2190 r = put_user(*(rd_buf + result), buf);
2191 if (r) {
2192 kfree(rd_buf);
2193 return r; /* r = -EFAULT */
2194 }
2195
2196 buf += 1;
2197 size -= 1;
2198 *pos += 1;
2199 result += 1;
2200 }
2201
2202 kfree(rd_buf);
2203 return result;
2204}
2205
2206/* function: read DSC chunk size parameter on the connector
2207 *
2208 * The read function: dp_dsc_chunk_size_read
2209 * returns dsc chunk size set in the current configuration
2210 * The value is calculated automatically by DSC code
2211 * and depends on slice parameters and bpp target rate
2212 * The return is an integer: 0 or other positive integer
2213 * If 0 then DSC is disabled.
2214 *
2215 * Access it with the following command:
2216 *
2217 * cat /sys/kernel/debug/dri/0/DP-X/dsc_chunk_size
2218 *
2219 * 0 - means that DSC is disabled
2220 */
2221static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
2222 size_t size, loff_t *pos)
2223{
2224 char *rd_buf = NULL;
2225 char *rd_buf_ptr = NULL;
2226 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2227 struct display_stream_compressor *dsc;
2228 struct dcn_dsc_state dsc_state = {0};
2229 const uint32_t rd_buf_size = 100;
2230 struct pipe_ctx *pipe_ctx;
2231 ssize_t result = 0;
2232 int i, r, str_len = 30;
2233
2234 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2235
2236 if (!rd_buf)
2237 return -ENOMEM;
2238
2239 rd_buf_ptr = rd_buf;
2240
2241 for (i = 0; i < MAX_PIPES; i++) {
2242 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2243 if (pipe_ctx && pipe_ctx->stream &&
2244 pipe_ctx->stream->link == aconnector->dc_link)
2245 break;
2246 }
2247
2248 if (!pipe_ctx) {
2249 kfree(rd_buf);
2250 return -ENXIO;
2251 }
2252
2253 dsc = pipe_ctx->stream_res.dsc;
2254 if (dsc)
2255 dsc->funcs->dsc_read_state(dsc, &dsc_state);
2256
2257 snprintf(rd_buf_ptr, str_len,
2258 "%d\n",
2259 dsc_state.dsc_chunk_size);
2260 rd_buf_ptr += str_len;
2261
2262 while (size) {
2263 if (*pos >= rd_buf_size)
2264 break;
2265
2266 r = put_user(*(rd_buf + result), buf);
2267 if (r) {
2268 kfree(rd_buf);
2269 return r; /* r = -EFAULT */
2270 }
2271
2272 buf += 1;
2273 size -= 1;
2274 *pos += 1;
2275 result += 1;
2276 }
2277
2278 kfree(rd_buf);
2279 return result;
2280}
2281
2282/* function: read DSC slice bpg offset on the connector
2283 *
2284 * The read function: dp_dsc_slice_bpg_offset_read
2285 * returns dsc bpg slice offset set in the current configuration
2286 * The value is calculated automatically by DSC code
2287 * and depends on slice parameters and bpp target rate
2288 * The return is an integer: 0 or other positive integer
2289 * If 0 then DSC is disabled.
2290 *
2291 * Access it with the following command:
2292 *
2293 * cat /sys/kernel/debug/dri/0/DP-X/dsc_slice_bpg_offset
2294 *
2295 * 0 - means that DSC is disabled
2296 */
2297static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
2298 size_t size, loff_t *pos)
2299{
2300 char *rd_buf = NULL;
2301 char *rd_buf_ptr = NULL;
2302 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2303 struct display_stream_compressor *dsc;
2304 struct dcn_dsc_state dsc_state = {0};
2305 const uint32_t rd_buf_size = 100;
2306 struct pipe_ctx *pipe_ctx;
2307 ssize_t result = 0;
2308 int i, r, str_len = 30;
2309
2310 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2311
2312 if (!rd_buf)
2313 return -ENOMEM;
2314
2315 rd_buf_ptr = rd_buf;
2316
2317 for (i = 0; i < MAX_PIPES; i++) {
2318 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2319 if (pipe_ctx && pipe_ctx->stream &&
2320 pipe_ctx->stream->link == aconnector->dc_link)
2321 break;
2322 }
2323
2324 if (!pipe_ctx) {
2325 kfree(rd_buf);
2326 return -ENXIO;
2327 }
2328
2329 dsc = pipe_ctx->stream_res.dsc;
2330 if (dsc)
2331 dsc->funcs->dsc_read_state(dsc, &dsc_state);
2332
2333 snprintf(rd_buf_ptr, str_len,
2334 "%d\n",
2335 dsc_state.dsc_slice_bpg_offset);
2336 rd_buf_ptr += str_len;
2337
2338 while (size) {
2339 if (*pos >= rd_buf_size)
2340 break;
2341
2342 r = put_user(*(rd_buf + result), buf);
2343 if (r) {
2344 kfree(rd_buf);
2345 return r; /* r = -EFAULT */
2346 }
2347
2348 buf += 1;
2349 size -= 1;
2350 *pos += 1;
2351 result += 1;
2352 }
2353
2354 kfree(rd_buf);
2355 return result;
2356}
2357
2358
2359/*
2360 * function description: Read max_requested_bpc property from the connector
2361 *
2362 * Access it with the following command:
2363 *
2364 * cat /sys/kernel/debug/dri/0/DP-X/max_bpc
2365 *
2366 */
2367static ssize_t dp_max_bpc_read(struct file *f, char __user *buf,
2368 size_t size, loff_t *pos)
2369{
2370 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2371 struct drm_connector *connector = &aconnector->base;
2372 struct drm_device *dev = connector->dev;
2373 struct dm_connector_state *state;
2374 ssize_t result = 0;
2375 char *rd_buf = NULL;
2376 char *rd_buf_ptr = NULL;
2377 const uint32_t rd_buf_size = 10;
2378 int r;
2379
2380 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2381
2382 if (!rd_buf)
2383 return -ENOMEM;
2384
2385 mutex_lock(&dev->mode_config.mutex);
2386 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2387
2388 if (connector->state == NULL)
2389 goto unlock;
2390
2391 state = to_dm_connector_state(connector->state);
2392
2393 rd_buf_ptr = rd_buf;
2394 snprintf(rd_buf_ptr, rd_buf_size,
2395 "%u\n",
2396 state->base.max_requested_bpc);
2397
2398 while (size) {
2399 if (*pos >= rd_buf_size)
2400 break;
2401
2402 r = put_user(*(rd_buf + result), buf);
2403 if (r) {
2404 result = r; /* r = -EFAULT */
2405 goto unlock;
2406 }
2407 buf += 1;
2408 size -= 1;
2409 *pos += 1;
2410 result += 1;
2411 }
2412unlock:
2413 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2414 mutex_unlock(&dev->mode_config.mutex);
2415 kfree(rd_buf);
2416 return result;
2417}
2418
2419
2420/*
2421 * function description: Set max_requested_bpc property on the connector
2422 *
2423 * This function will not force the input BPC on connector, it will only
2424 * change the max value. This is equivalent to setting max_bpc through
2425 * xrandr.
2426 *
2427 * The BPC value written must be >= 6 and <= 16. Values outside of this
2428 * range will result in errors.
2429 *
2430 * BPC values:
2431 * 0x6 - 6 BPC
2432 * 0x8 - 8 BPC
2433 * 0xa - 10 BPC
2434 * 0xc - 12 BPC
2435 * 0x10 - 16 BPC
2436 *
2437 * Write the max_bpc in the following way:
2438 *
2439 * echo 0x6 > /sys/kernel/debug/dri/0/DP-X/max_bpc
2440 *
2441 */
2442static ssize_t dp_max_bpc_write(struct file *f, const char __user *buf,
2443 size_t size, loff_t *pos)
2444{
2445 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2446 struct drm_connector *connector = &aconnector->base;
2447 struct dm_connector_state *state;
2448 struct drm_device *dev = connector->dev;
2449 char *wr_buf = NULL;
2450 uint32_t wr_buf_size = 42;
2451 int max_param_num = 1;
2452 long param[1] = {0};
2453 uint8_t param_nums = 0;
2454
2455 if (size == 0)
2456 return -EINVAL;
2457
2458 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
2459
2460 if (!wr_buf) {
2461 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
2462 return -ENOSPC;
2463 }
2464
2465 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
2466 (long *)param, buf,
2467 max_param_num,
2468 ¶m_nums)) {
2469 kfree(wr_buf);
2470 return -EINVAL;
2471 }
2472
2473 if (param_nums <= 0) {
2474 DRM_DEBUG_DRIVER("user data not be read\n");
2475 kfree(wr_buf);
2476 return -EINVAL;
2477 }
2478
2479 if (param[0] < 6 || param[0] > 16) {
2480 DRM_DEBUG_DRIVER("bad max_bpc value\n");
2481 kfree(wr_buf);
2482 return -EINVAL;
2483 }
2484
2485 mutex_lock(&dev->mode_config.mutex);
2486 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2487
2488 if (connector->state == NULL)
2489 goto unlock;
2490
2491 state = to_dm_connector_state(connector->state);
2492 state->base.max_requested_bpc = param[0];
2493unlock:
2494 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2495 mutex_unlock(&dev->mode_config.mutex);
2496
2497 kfree(wr_buf);
2498 return size;
2499}
2500
2501/*
2502 * Backlight at this moment. Read only.
2503 * As written to display, taking ABM and backlight lut into account.
2504 * Ranges from 0x0 to 0x10000 (= 100% PWM)
2505 *
2506 * Example usage: cat /sys/kernel/debug/dri/0/eDP-1/current_backlight
2507 */
2508static int current_backlight_show(struct seq_file *m, void *unused)
2509{
2510 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(m->private);
2511 struct dc_link *link = aconnector->dc_link;
2512 unsigned int backlight;
2513
2514 backlight = dc_link_get_backlight_level(link);
2515 seq_printf(m, "0x%x\n", backlight);
2516
2517 return 0;
2518}
2519
2520/*
2521 * Backlight value that is being approached. Read only.
2522 * As written to display, taking ABM and backlight lut into account.
2523 * Ranges from 0x0 to 0x10000 (= 100% PWM)
2524 *
2525 * Example usage: cat /sys/kernel/debug/dri/0/eDP-1/target_backlight
2526 */
2527static int target_backlight_show(struct seq_file *m, void *unused)
2528{
2529 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(m->private);
2530 struct dc_link *link = aconnector->dc_link;
2531 unsigned int backlight;
2532
2533 backlight = dc_link_get_target_backlight_pwm(link);
2534 seq_printf(m, "0x%x\n", backlight);
2535
2536 return 0;
2537}
2538
2539DEFINE_SHOW_ATTRIBUTE(dp_dsc_fec_support);
2540DEFINE_SHOW_ATTRIBUTE(dmub_fw_state);
2541DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer);
2542DEFINE_SHOW_ATTRIBUTE(output_bpc);
2543DEFINE_SHOW_ATTRIBUTE(dp_lttpr_status);
2544#ifdef CONFIG_DRM_AMD_DC_HDCP
2545DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability);
2546#endif
2547DEFINE_SHOW_ATTRIBUTE(internal_display);
2548DEFINE_SHOW_ATTRIBUTE(psr_capability);
2549
2550static const struct file_operations dp_dsc_clock_en_debugfs_fops = {
2551 .owner = THIS_MODULE,
2552 .read = dp_dsc_clock_en_read,
2553 .write = dp_dsc_clock_en_write,
2554 .llseek = default_llseek
2555};
2556
2557static const struct file_operations dp_dsc_slice_width_debugfs_fops = {
2558 .owner = THIS_MODULE,
2559 .read = dp_dsc_slice_width_read,
2560 .write = dp_dsc_slice_width_write,
2561 .llseek = default_llseek
2562};
2563
2564static const struct file_operations dp_dsc_slice_height_debugfs_fops = {
2565 .owner = THIS_MODULE,
2566 .read = dp_dsc_slice_height_read,
2567 .write = dp_dsc_slice_height_write,
2568 .llseek = default_llseek
2569};
2570
2571static const struct file_operations dp_dsc_bits_per_pixel_debugfs_fops = {
2572 .owner = THIS_MODULE,
2573 .read = dp_dsc_bits_per_pixel_read,
2574 .write = dp_dsc_bits_per_pixel_write,
2575 .llseek = default_llseek
2576};
2577
2578static const struct file_operations dp_dsc_pic_width_debugfs_fops = {
2579 .owner = THIS_MODULE,
2580 .read = dp_dsc_pic_width_read,
2581 .llseek = default_llseek
2582};
2583
2584static const struct file_operations dp_dsc_pic_height_debugfs_fops = {
2585 .owner = THIS_MODULE,
2586 .read = dp_dsc_pic_height_read,
2587 .llseek = default_llseek
2588};
2589
2590static const struct file_operations dp_dsc_chunk_size_debugfs_fops = {
2591 .owner = THIS_MODULE,
2592 .read = dp_dsc_chunk_size_read,
2593 .llseek = default_llseek
2594};
2595
2596static const struct file_operations dp_dsc_slice_bpg_offset_debugfs_fops = {
2597 .owner = THIS_MODULE,
2598 .read = dp_dsc_slice_bpg_offset_read,
2599 .llseek = default_llseek
2600};
2601
2602static const struct file_operations trigger_hotplug_debugfs_fops = {
2603 .owner = THIS_MODULE,
2604 .write = trigger_hotplug,
2605 .llseek = default_llseek
2606};
2607
2608static const struct file_operations dp_link_settings_debugfs_fops = {
2609 .owner = THIS_MODULE,
2610 .read = dp_link_settings_read,
2611 .write = dp_link_settings_write,
2612 .llseek = default_llseek
2613};
2614
2615static const struct file_operations dp_phy_settings_debugfs_fop = {
2616 .owner = THIS_MODULE,
2617 .read = dp_phy_settings_read,
2618 .write = dp_phy_settings_write,
2619 .llseek = default_llseek
2620};
2621
2622static const struct file_operations dp_phy_test_pattern_fops = {
2623 .owner = THIS_MODULE,
2624 .write = dp_phy_test_pattern_debugfs_write,
2625 .llseek = default_llseek
2626};
2627
2628static const struct file_operations sdp_message_fops = {
2629 .owner = THIS_MODULE,
2630 .write = dp_sdp_message_debugfs_write,
2631 .llseek = default_llseek
2632};
2633
2634static const struct file_operations dp_dpcd_address_debugfs_fops = {
2635 .owner = THIS_MODULE,
2636 .write = dp_dpcd_address_write,
2637 .llseek = default_llseek
2638};
2639
2640static const struct file_operations dp_dpcd_size_debugfs_fops = {
2641 .owner = THIS_MODULE,
2642 .write = dp_dpcd_size_write,
2643 .llseek = default_llseek
2644};
2645
2646static const struct file_operations dp_dpcd_data_debugfs_fops = {
2647 .owner = THIS_MODULE,
2648 .read = dp_dpcd_data_read,
2649 .write = dp_dpcd_data_write,
2650 .llseek = default_llseek
2651};
2652
2653static const struct file_operations dp_max_bpc_debugfs_fops = {
2654 .owner = THIS_MODULE,
2655 .read = dp_max_bpc_read,
2656 .write = dp_max_bpc_write,
2657 .llseek = default_llseek
2658};
2659
2660static const struct file_operations dp_dsc_disable_passthrough_debugfs_fops = {
2661 .owner = THIS_MODULE,
2662 .write = dp_dsc_passthrough_set,
2663 .llseek = default_llseek
2664};
2665
2666static const struct {
2667 char *name;
2668 const struct file_operations *fops;
2669} dp_debugfs_entries[] = {
2670 {"link_settings", &dp_link_settings_debugfs_fops},
2671 {"phy_settings", &dp_phy_settings_debugfs_fop},
2672 {"lttpr_status", &dp_lttpr_status_fops},
2673 {"test_pattern", &dp_phy_test_pattern_fops},
2674#ifdef CONFIG_DRM_AMD_DC_HDCP
2675 {"hdcp_sink_capability", &hdcp_sink_capability_fops},
2676#endif
2677 {"sdp_message", &sdp_message_fops},
2678 {"aux_dpcd_address", &dp_dpcd_address_debugfs_fops},
2679 {"aux_dpcd_size", &dp_dpcd_size_debugfs_fops},
2680 {"aux_dpcd_data", &dp_dpcd_data_debugfs_fops},
2681 {"dsc_clock_en", &dp_dsc_clock_en_debugfs_fops},
2682 {"dsc_slice_width", &dp_dsc_slice_width_debugfs_fops},
2683 {"dsc_slice_height", &dp_dsc_slice_height_debugfs_fops},
2684 {"dsc_bits_per_pixel", &dp_dsc_bits_per_pixel_debugfs_fops},
2685 {"dsc_pic_width", &dp_dsc_pic_width_debugfs_fops},
2686 {"dsc_pic_height", &dp_dsc_pic_height_debugfs_fops},
2687 {"dsc_chunk_size", &dp_dsc_chunk_size_debugfs_fops},
2688 {"dsc_slice_bpg", &dp_dsc_slice_bpg_offset_debugfs_fops},
2689 {"dp_dsc_fec_support", &dp_dsc_fec_support_fops},
2690 {"max_bpc", &dp_max_bpc_debugfs_fops},
2691 {"dsc_disable_passthrough", &dp_dsc_disable_passthrough_debugfs_fops},
2692};
2693
2694#ifdef CONFIG_DRM_AMD_DC_HDCP
2695static const struct {
2696 char *name;
2697 const struct file_operations *fops;
2698} hdmi_debugfs_entries[] = {
2699 {"hdcp_sink_capability", &hdcp_sink_capability_fops}
2700};
2701#endif
2702/*
2703 * Force YUV420 output if available from the given mode
2704 */
2705static int force_yuv420_output_set(void *data, u64 val)
2706{
2707 struct amdgpu_dm_connector *connector = data;
2708
2709 connector->force_yuv420_output = (bool)val;
2710
2711 return 0;
2712}
2713
2714/*
2715 * Check if YUV420 is forced when available from the given mode
2716 */
2717static int force_yuv420_output_get(void *data, u64 *val)
2718{
2719 struct amdgpu_dm_connector *connector = data;
2720
2721 *val = connector->force_yuv420_output;
2722
2723 return 0;
2724}
2725
2726DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
2727 force_yuv420_output_set, "%llu\n");
2728
2729/*
2730 * Read PSR state
2731 */
2732static int psr_get(void *data, u64 *val)
2733{
2734 struct amdgpu_dm_connector *connector = data;
2735 struct dc_link *link = connector->dc_link;
2736 enum dc_psr_state state = PSR_STATE0;
2737
2738 dc_link_get_psr_state(link, &state);
2739
2740 *val = state;
2741
2742 return 0;
2743}
2744
2745/*
2746 * Set dmcub trace event IRQ enable or disable.
2747 * Usage to enable dmcub trace event IRQ: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en
2748 * Usage to disable dmcub trace event IRQ: echo 0 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en
2749 */
2750static int dmcub_trace_event_state_set(void *data, u64 val)
2751{
2752 struct amdgpu_device *adev = data;
2753
2754 if (val == 1 || val == 0) {
2755 dc_dmub_trace_event_control(adev->dm.dc, val);
2756 adev->dm.dmcub_trace_event_en = (bool)val;
2757 } else
2758 return 0;
2759
2760 return 0;
2761}
2762
2763/*
2764 * The interface doesn't need get function, so it will return the
2765 * value of zero
2766 * Usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en
2767 */
2768static int dmcub_trace_event_state_get(void *data, u64 *val)
2769{
2770 struct amdgpu_device *adev = data;
2771
2772 *val = adev->dm.dmcub_trace_event_en;
2773 return 0;
2774}
2775
2776DEFINE_DEBUGFS_ATTRIBUTE(dmcub_trace_event_state_fops, dmcub_trace_event_state_get,
2777 dmcub_trace_event_state_set, "%llu\n");
2778
2779DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n");
2780
2781DEFINE_SHOW_ATTRIBUTE(current_backlight);
2782DEFINE_SHOW_ATTRIBUTE(target_backlight);
2783
2784static const struct {
2785 char *name;
2786 const struct file_operations *fops;
2787} connector_debugfs_entries[] = {
2788 {"force_yuv420_output", &force_yuv420_output_fops},
2789 {"output_bpc", &output_bpc_fops},
2790 {"trigger_hotplug", &trigger_hotplug_debugfs_fops},
2791 {"internal_display", &internal_display_fops}
2792};
2793
2794/*
2795 * Returns supported customized link rates by this eDP panel.
2796 * Example usage: cat /sys/kernel/debug/dri/0/eDP-x/ilr_setting
2797 */
2798static int edp_ilr_show(struct seq_file *m, void *unused)
2799{
2800 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(m->private);
2801 struct dc_link *link = aconnector->dc_link;
2802 uint8_t supported_link_rates[16];
2803 uint32_t link_rate_in_khz;
2804 uint32_t entry = 0;
2805 uint8_t dpcd_rev;
2806
2807 memset(supported_link_rates, 0, sizeof(supported_link_rates));
2808 dm_helpers_dp_read_dpcd(link->ctx, link, DP_SUPPORTED_LINK_RATES,
2809 supported_link_rates, sizeof(supported_link_rates));
2810
2811 dpcd_rev = link->dpcd_caps.dpcd_rev.raw;
2812
2813 if (dpcd_rev >= DP_DPCD_REV_13 &&
2814 (supported_link_rates[entry+1] != 0 || supported_link_rates[entry] != 0)) {
2815
2816 for (entry = 0; entry < 16; entry += 2) {
2817 link_rate_in_khz = (supported_link_rates[entry+1] * 0x100 +
2818 supported_link_rates[entry]) * 200;
2819 seq_printf(m, "[%d] %d kHz\n", entry/2, link_rate_in_khz);
2820 }
2821 } else {
2822 seq_printf(m, "ILR is not supported by this eDP panel.\n");
2823 }
2824
2825 return 0;
2826}
2827
2828/*
2829 * Set supported customized link rate to eDP panel.
2830 *
2831 * echo <lane_count> <link_rate option> > ilr_setting
2832 *
2833 * for example, supported ILR : [0] 1620000 kHz [1] 2160000 kHz [2] 2430000 kHz ...
2834 * echo 4 1 > /sys/kernel/debug/dri/0/eDP-x/ilr_setting
2835 * to set 4 lanes and 2.16 GHz
2836 */
2837static ssize_t edp_ilr_write(struct file *f, const char __user *buf,
2838 size_t size, loff_t *pos)
2839{
2840 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
2841 struct dc_link *link = connector->dc_link;
2842 struct amdgpu_device *adev = drm_to_adev(connector->base.dev);
2843 struct dc *dc = (struct dc *)link->dc;
2844 struct dc_link_settings prefer_link_settings;
2845 char *wr_buf = NULL;
2846 const uint32_t wr_buf_size = 40;
2847 /* 0: lane_count; 1: link_rate */
2848 int max_param_num = 2;
2849 uint8_t param_nums = 0;
2850 long param[2];
2851 bool valid_input = true;
2852
2853 if (size == 0)
2854 return -EINVAL;
2855
2856 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
2857 if (!wr_buf)
2858 return -ENOMEM;
2859
2860 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
2861 (long *)param, buf,
2862 max_param_num,
2863 ¶m_nums)) {
2864 kfree(wr_buf);
2865 return -EINVAL;
2866 }
2867
2868 if (param_nums <= 0) {
2869 kfree(wr_buf);
2870 return -EINVAL;
2871 }
2872
2873 switch (param[0]) {
2874 case LANE_COUNT_ONE:
2875 case LANE_COUNT_TWO:
2876 case LANE_COUNT_FOUR:
2877 break;
2878 default:
2879 valid_input = false;
2880 break;
2881 }
2882
2883 if (param[1] >= link->dpcd_caps.edp_supported_link_rates_count)
2884 valid_input = false;
2885
2886 if (!valid_input) {
2887 kfree(wr_buf);
2888 DRM_DEBUG_DRIVER("Invalid Input value. No HW will be programmed\n");
2889 prefer_link_settings.use_link_rate_set = false;
2890 mutex_lock(&adev->dm.dc_lock);
2891 dc_link_set_preferred_training_settings(dc, NULL, NULL, link, false);
2892 mutex_unlock(&adev->dm.dc_lock);
2893 return size;
2894 }
2895
2896 /* save user force lane_count, link_rate to preferred settings
2897 * spread spectrum will not be changed
2898 */
2899 prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
2900 prefer_link_settings.lane_count = param[0];
2901 prefer_link_settings.use_link_rate_set = true;
2902 prefer_link_settings.link_rate_set = param[1];
2903 prefer_link_settings.link_rate = link->dpcd_caps.edp_supported_link_rates[param[1]];
2904
2905 mutex_lock(&adev->dm.dc_lock);
2906 dc_link_set_preferred_training_settings(dc, &prefer_link_settings,
2907 NULL, link, false);
2908 mutex_unlock(&adev->dm.dc_lock);
2909
2910 kfree(wr_buf);
2911 return size;
2912}
2913
2914static int edp_ilr_open(struct inode *inode, struct file *file)
2915{
2916 return single_open(file, edp_ilr_show, inode->i_private);
2917}
2918
2919static const struct file_operations edp_ilr_debugfs_fops = {
2920 .owner = THIS_MODULE,
2921 .open = edp_ilr_open,
2922 .read = seq_read,
2923 .llseek = seq_lseek,
2924 .release = single_release,
2925 .write = edp_ilr_write
2926};
2927
2928void connector_debugfs_init(struct amdgpu_dm_connector *connector)
2929{
2930 int i;
2931 struct dentry *dir = connector->base.debugfs_entry;
2932
2933 if (connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
2934 connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) {
2935 for (i = 0; i < ARRAY_SIZE(dp_debugfs_entries); i++) {
2936 debugfs_create_file(dp_debugfs_entries[i].name,
2937 0644, dir, connector,
2938 dp_debugfs_entries[i].fops);
2939 }
2940 }
2941 if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) {
2942 debugfs_create_file_unsafe("psr_capability", 0444, dir, connector, &psr_capability_fops);
2943 debugfs_create_file_unsafe("psr_state", 0444, dir, connector, &psr_fops);
2944 debugfs_create_file("amdgpu_current_backlight_pwm", 0444, dir, connector,
2945 ¤t_backlight_fops);
2946 debugfs_create_file("amdgpu_target_backlight_pwm", 0444, dir, connector,
2947 &target_backlight_fops);
2948 debugfs_create_file("ilr_setting", 0644, dir, connector,
2949 &edp_ilr_debugfs_fops);
2950 }
2951
2952 for (i = 0; i < ARRAY_SIZE(connector_debugfs_entries); i++) {
2953 debugfs_create_file(connector_debugfs_entries[i].name,
2954 0644, dir, connector,
2955 connector_debugfs_entries[i].fops);
2956 }
2957
2958 connector->debugfs_dpcd_address = 0;
2959 connector->debugfs_dpcd_size = 0;
2960
2961#ifdef CONFIG_DRM_AMD_DC_HDCP
2962 if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) {
2963 for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_entries); i++) {
2964 debugfs_create_file(hdmi_debugfs_entries[i].name,
2965 0644, dir, connector,
2966 hdmi_debugfs_entries[i].fops);
2967 }
2968 }
2969#endif
2970}
2971
2972#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
2973/*
2974 * Set crc window coordinate x start
2975 */
2976static int crc_win_x_start_set(void *data, u64 val)
2977{
2978 struct drm_crtc *crtc = data;
2979 struct drm_device *drm_dev = crtc->dev;
2980 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
2981
2982 spin_lock_irq(&drm_dev->event_lock);
2983 acrtc->dm_irq_params.crc_window.x_start = (uint16_t) val;
2984 acrtc->dm_irq_params.crc_window.update_win = false;
2985 spin_unlock_irq(&drm_dev->event_lock);
2986
2987 return 0;
2988}
2989
2990/*
2991 * Get crc window coordinate x start
2992 */
2993static int crc_win_x_start_get(void *data, u64 *val)
2994{
2995 struct drm_crtc *crtc = data;
2996 struct drm_device *drm_dev = crtc->dev;
2997 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
2998
2999 spin_lock_irq(&drm_dev->event_lock);
3000 *val = acrtc->dm_irq_params.crc_window.x_start;
3001 spin_unlock_irq(&drm_dev->event_lock);
3002
3003 return 0;
3004}
3005
3006DEFINE_DEBUGFS_ATTRIBUTE(crc_win_x_start_fops, crc_win_x_start_get,
3007 crc_win_x_start_set, "%llu\n");
3008
3009
3010/*
3011 * Set crc window coordinate y start
3012 */
3013static int crc_win_y_start_set(void *data, u64 val)
3014{
3015 struct drm_crtc *crtc = data;
3016 struct drm_device *drm_dev = crtc->dev;
3017 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3018
3019 spin_lock_irq(&drm_dev->event_lock);
3020 acrtc->dm_irq_params.crc_window.y_start = (uint16_t) val;
3021 acrtc->dm_irq_params.crc_window.update_win = false;
3022 spin_unlock_irq(&drm_dev->event_lock);
3023
3024 return 0;
3025}
3026
3027/*
3028 * Get crc window coordinate y start
3029 */
3030static int crc_win_y_start_get(void *data, u64 *val)
3031{
3032 struct drm_crtc *crtc = data;
3033 struct drm_device *drm_dev = crtc->dev;
3034 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3035
3036 spin_lock_irq(&drm_dev->event_lock);
3037 *val = acrtc->dm_irq_params.crc_window.y_start;
3038 spin_unlock_irq(&drm_dev->event_lock);
3039
3040 return 0;
3041}
3042
3043DEFINE_DEBUGFS_ATTRIBUTE(crc_win_y_start_fops, crc_win_y_start_get,
3044 crc_win_y_start_set, "%llu\n");
3045
3046/*
3047 * Set crc window coordinate x end
3048 */
3049static int crc_win_x_end_set(void *data, u64 val)
3050{
3051 struct drm_crtc *crtc = data;
3052 struct drm_device *drm_dev = crtc->dev;
3053 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3054
3055 spin_lock_irq(&drm_dev->event_lock);
3056 acrtc->dm_irq_params.crc_window.x_end = (uint16_t) val;
3057 acrtc->dm_irq_params.crc_window.update_win = false;
3058 spin_unlock_irq(&drm_dev->event_lock);
3059
3060 return 0;
3061}
3062
3063/*
3064 * Get crc window coordinate x end
3065 */
3066static int crc_win_x_end_get(void *data, u64 *val)
3067{
3068 struct drm_crtc *crtc = data;
3069 struct drm_device *drm_dev = crtc->dev;
3070 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3071
3072 spin_lock_irq(&drm_dev->event_lock);
3073 *val = acrtc->dm_irq_params.crc_window.x_end;
3074 spin_unlock_irq(&drm_dev->event_lock);
3075
3076 return 0;
3077}
3078
3079DEFINE_DEBUGFS_ATTRIBUTE(crc_win_x_end_fops, crc_win_x_end_get,
3080 crc_win_x_end_set, "%llu\n");
3081
3082/*
3083 * Set crc window coordinate y end
3084 */
3085static int crc_win_y_end_set(void *data, u64 val)
3086{
3087 struct drm_crtc *crtc = data;
3088 struct drm_device *drm_dev = crtc->dev;
3089 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3090
3091 spin_lock_irq(&drm_dev->event_lock);
3092 acrtc->dm_irq_params.crc_window.y_end = (uint16_t) val;
3093 acrtc->dm_irq_params.crc_window.update_win = false;
3094 spin_unlock_irq(&drm_dev->event_lock);
3095
3096 return 0;
3097}
3098
3099/*
3100 * Get crc window coordinate y end
3101 */
3102static int crc_win_y_end_get(void *data, u64 *val)
3103{
3104 struct drm_crtc *crtc = data;
3105 struct drm_device *drm_dev = crtc->dev;
3106 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3107
3108 spin_lock_irq(&drm_dev->event_lock);
3109 *val = acrtc->dm_irq_params.crc_window.y_end;
3110 spin_unlock_irq(&drm_dev->event_lock);
3111
3112 return 0;
3113}
3114
3115DEFINE_DEBUGFS_ATTRIBUTE(crc_win_y_end_fops, crc_win_y_end_get,
3116 crc_win_y_end_set, "%llu\n");
3117/*
3118 * Trigger to commit crc window
3119 */
3120static int crc_win_update_set(void *data, u64 val)
3121{
3122 struct drm_crtc *new_crtc = data;
3123 struct drm_crtc *old_crtc = NULL;
3124 struct amdgpu_crtc *new_acrtc, *old_acrtc;
3125 struct amdgpu_device *adev = drm_to_adev(new_crtc->dev);
3126 struct crc_rd_work *crc_rd_wrk = adev->dm.crc_rd_wrk;
3127
3128 if (!crc_rd_wrk)
3129 return 0;
3130
3131 if (val) {
3132 spin_lock_irq(&adev_to_drm(adev)->event_lock);
3133 spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
3134 if (crc_rd_wrk->crtc) {
3135 old_crtc = crc_rd_wrk->crtc;
3136 old_acrtc = to_amdgpu_crtc(old_crtc);
3137 }
3138 new_acrtc = to_amdgpu_crtc(new_crtc);
3139
3140 if (old_crtc && old_crtc != new_crtc) {
3141 old_acrtc->dm_irq_params.crc_window.activated = false;
3142 old_acrtc->dm_irq_params.crc_window.update_win = false;
3143 old_acrtc->dm_irq_params.crc_window.skip_frame_cnt = 0;
3144
3145 new_acrtc->dm_irq_params.crc_window.activated = true;
3146 new_acrtc->dm_irq_params.crc_window.update_win = true;
3147 new_acrtc->dm_irq_params.crc_window.skip_frame_cnt = 0;
3148 crc_rd_wrk->crtc = new_crtc;
3149 } else {
3150 new_acrtc->dm_irq_params.crc_window.activated = true;
3151 new_acrtc->dm_irq_params.crc_window.update_win = true;
3152 new_acrtc->dm_irq_params.crc_window.skip_frame_cnt = 0;
3153 crc_rd_wrk->crtc = new_crtc;
3154 }
3155 spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
3156 spin_unlock_irq(&adev_to_drm(adev)->event_lock);
3157 }
3158
3159 return 0;
3160}
3161
3162/*
3163 * Get crc window update flag
3164 */
3165static int crc_win_update_get(void *data, u64 *val)
3166{
3167 *val = 0;
3168 return 0;
3169}
3170
3171DEFINE_DEBUGFS_ATTRIBUTE(crc_win_update_fops, crc_win_update_get,
3172 crc_win_update_set, "%llu\n");
3173
3174void crtc_debugfs_init(struct drm_crtc *crtc)
3175{
3176 struct dentry *dir = debugfs_lookup("crc", crtc->debugfs_entry);
3177
3178 if (!dir)
3179 return;
3180
3181 debugfs_create_file_unsafe("crc_win_x_start", 0644, dir, crtc,
3182 &crc_win_x_start_fops);
3183 debugfs_create_file_unsafe("crc_win_y_start", 0644, dir, crtc,
3184 &crc_win_y_start_fops);
3185 debugfs_create_file_unsafe("crc_win_x_end", 0644, dir, crtc,
3186 &crc_win_x_end_fops);
3187 debugfs_create_file_unsafe("crc_win_y_end", 0644, dir, crtc,
3188 &crc_win_y_end_fops);
3189 debugfs_create_file_unsafe("crc_win_update", 0644, dir, crtc,
3190 &crc_win_update_fops);
3191
3192}
3193#endif
3194/*
3195 * Writes DTN log state to the user supplied buffer.
3196 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log
3197 */
3198static ssize_t dtn_log_read(
3199 struct file *f,
3200 char __user *buf,
3201 size_t size,
3202 loff_t *pos)
3203{
3204 struct amdgpu_device *adev = file_inode(f)->i_private;
3205 struct dc *dc = adev->dm.dc;
3206 struct dc_log_buffer_ctx log_ctx = { 0 };
3207 ssize_t result = 0;
3208
3209 if (!buf || !size)
3210 return -EINVAL;
3211
3212 if (!dc->hwss.log_hw_state)
3213 return 0;
3214
3215 dc->hwss.log_hw_state(dc, &log_ctx);
3216
3217 if (*pos < log_ctx.pos) {
3218 size_t to_copy = log_ctx.pos - *pos;
3219
3220 to_copy = min(to_copy, size);
3221
3222 if (!copy_to_user(buf, log_ctx.buf + *pos, to_copy)) {
3223 *pos += to_copy;
3224 result = to_copy;
3225 }
3226 }
3227
3228 kfree(log_ctx.buf);
3229
3230 return result;
3231}
3232
3233/*
3234 * Writes DTN log state to dmesg when triggered via a write.
3235 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log
3236 */
3237static ssize_t dtn_log_write(
3238 struct file *f,
3239 const char __user *buf,
3240 size_t size,
3241 loff_t *pos)
3242{
3243 struct amdgpu_device *adev = file_inode(f)->i_private;
3244 struct dc *dc = adev->dm.dc;
3245
3246 /* Write triggers log output via dmesg. */
3247 if (size == 0)
3248 return 0;
3249
3250 if (dc->hwss.log_hw_state)
3251 dc->hwss.log_hw_state(dc, NULL);
3252
3253 return size;
3254}
3255
3256static int mst_topo_show(struct seq_file *m, void *unused)
3257{
3258 struct amdgpu_device *adev = (struct amdgpu_device *)m->private;
3259 struct drm_device *dev = adev_to_drm(adev);
3260 struct drm_connector *connector;
3261 struct drm_connector_list_iter conn_iter;
3262 struct amdgpu_dm_connector *aconnector;
3263
3264 drm_connector_list_iter_begin(dev, &conn_iter);
3265 drm_for_each_connector_iter(connector, &conn_iter) {
3266 if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
3267 continue;
3268
3269 aconnector = to_amdgpu_dm_connector(connector);
3270
3271 /* Ensure we're only dumping the topology of a root mst node */
3272 if (!aconnector->mst_mgr.mst_state)
3273 continue;
3274
3275 seq_printf(m, "\nMST topology for connector %d\n", aconnector->connector_id);
3276 drm_dp_mst_dump_topology(m, &aconnector->mst_mgr);
3277 }
3278 drm_connector_list_iter_end(&conn_iter);
3279
3280 return 0;
3281}
3282
3283/*
3284 * Sets trigger hpd for MST topologies.
3285 * All connected connectors will be rediscovered and re started as needed if val of 1 is sent.
3286 * All topologies will be disconnected if val of 0 is set .
3287 * Usage to enable topologies: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_trigger_hpd_mst
3288 * Usage to disable topologies: echo 0 > /sys/kernel/debug/dri/0/amdgpu_dm_trigger_hpd_mst
3289 */
3290static int trigger_hpd_mst_set(void *data, u64 val)
3291{
3292 struct amdgpu_device *adev = data;
3293 struct drm_device *dev = adev_to_drm(adev);
3294 struct drm_connector_list_iter iter;
3295 struct amdgpu_dm_connector *aconnector;
3296 struct drm_connector *connector;
3297 struct dc_link *link = NULL;
3298
3299 if (val == 1) {
3300 drm_connector_list_iter_begin(dev, &iter);
3301 drm_for_each_connector_iter(connector, &iter) {
3302 aconnector = to_amdgpu_dm_connector(connector);
3303 if (aconnector->dc_link->type == dc_connection_mst_branch &&
3304 aconnector->mst_mgr.aux) {
3305 dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
3306 drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true);
3307 }
3308 }
3309 } else if (val == 0) {
3310 drm_connector_list_iter_begin(dev, &iter);
3311 drm_for_each_connector_iter(connector, &iter) {
3312 aconnector = to_amdgpu_dm_connector(connector);
3313 if (!aconnector->dc_link)
3314 continue;
3315
3316 if (!aconnector->mst_port)
3317 continue;
3318
3319 link = aconnector->dc_link;
3320 dp_receiver_power_ctrl(link, false);
3321 drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_port->mst_mgr, false);
3322 link->mst_stream_alloc_table.stream_count = 0;
3323 memset(link->mst_stream_alloc_table.stream_allocations, 0,
3324 sizeof(link->mst_stream_alloc_table.stream_allocations));
3325 }
3326 } else {
3327 return 0;
3328 }
3329 drm_kms_helper_hotplug_event(dev);
3330
3331 return 0;
3332}
3333
3334/*
3335 * The interface doesn't need get function, so it will return the
3336 * value of zero
3337 * Usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_trigger_hpd_mst
3338 */
3339static int trigger_hpd_mst_get(void *data, u64 *val)
3340{
3341 *val = 0;
3342 return 0;
3343}
3344
3345DEFINE_DEBUGFS_ATTRIBUTE(trigger_hpd_mst_ops, trigger_hpd_mst_get,
3346 trigger_hpd_mst_set, "%llu\n");
3347
3348
3349/*
3350 * Sets the force_timing_sync debug option from the given string.
3351 * All connected displays will be force synchronized immediately.
3352 * Usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_force_timing_sync
3353 */
3354static int force_timing_sync_set(void *data, u64 val)
3355{
3356 struct amdgpu_device *adev = data;
3357
3358 adev->dm.force_timing_sync = (bool)val;
3359
3360 amdgpu_dm_trigger_timing_sync(adev_to_drm(adev));
3361
3362 return 0;
3363}
3364
3365/*
3366 * Gets the force_timing_sync debug option value into the given buffer.
3367 * Usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_force_timing_sync
3368 */
3369static int force_timing_sync_get(void *data, u64 *val)
3370{
3371 struct amdgpu_device *adev = data;
3372
3373 *val = adev->dm.force_timing_sync;
3374
3375 return 0;
3376}
3377
3378DEFINE_DEBUGFS_ATTRIBUTE(force_timing_sync_ops, force_timing_sync_get,
3379 force_timing_sync_set, "%llu\n");
3380
3381
3382/*
3383 * Disables all HPD and HPD RX interrupt handling in the
3384 * driver when set to 1. Default is 0.
3385 */
3386static int disable_hpd_set(void *data, u64 val)
3387{
3388 struct amdgpu_device *adev = data;
3389
3390 adev->dm.disable_hpd_irq = (bool)val;
3391
3392 return 0;
3393}
3394
3395
3396/*
3397 * Returns 1 if HPD and HPRX interrupt handling is disabled,
3398 * 0 otherwise.
3399 */
3400static int disable_hpd_get(void *data, u64 *val)
3401{
3402 struct amdgpu_device *adev = data;
3403
3404 *val = adev->dm.disable_hpd_irq;
3405
3406 return 0;
3407}
3408
3409DEFINE_DEBUGFS_ATTRIBUTE(disable_hpd_ops, disable_hpd_get,
3410 disable_hpd_set, "%llu\n");
3411
3412/*
3413 * Temporary w/a to force sst sequence in M42D DP2 mst receiver
3414 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dp_set_mst_en_for_sst
3415 */
3416static int dp_force_sst_set(void *data, u64 val)
3417{
3418 struct amdgpu_device *adev = data;
3419
3420 adev->dm.dc->debug.set_mst_en_for_sst = val;
3421
3422 return 0;
3423}
3424
3425static int dp_force_sst_get(void *data, u64 *val)
3426{
3427 struct amdgpu_device *adev = data;
3428
3429 *val = adev->dm.dc->debug.set_mst_en_for_sst;
3430
3431 return 0;
3432}
3433DEFINE_DEBUGFS_ATTRIBUTE(dp_set_mst_en_for_sst_ops, dp_force_sst_get,
3434 dp_force_sst_set, "%llu\n");
3435
3436/*
3437 * Force DP2 sequence without VESA certified cable.
3438 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dp_ignore_cable_id
3439 */
3440static int dp_ignore_cable_id_set(void *data, u64 val)
3441{
3442 struct amdgpu_device *adev = data;
3443
3444 adev->dm.dc->debug.ignore_cable_id = val;
3445
3446 return 0;
3447}
3448
3449static int dp_ignore_cable_id_get(void *data, u64 *val)
3450{
3451 struct amdgpu_device *adev = data;
3452
3453 *val = adev->dm.dc->debug.ignore_cable_id;
3454
3455 return 0;
3456}
3457DEFINE_DEBUGFS_ATTRIBUTE(dp_ignore_cable_id_ops, dp_ignore_cable_id_get,
3458 dp_ignore_cable_id_set, "%llu\n");
3459
3460/*
3461 * Sets the DC visual confirm debug option from the given string.
3462 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_visual_confirm
3463 */
3464static int visual_confirm_set(void *data, u64 val)
3465{
3466 struct amdgpu_device *adev = data;
3467
3468 adev->dm.dc->debug.visual_confirm = (enum visual_confirm)val;
3469
3470 return 0;
3471}
3472
3473/*
3474 * Reads the DC visual confirm debug option value into the given buffer.
3475 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_visual_confirm
3476 */
3477static int visual_confirm_get(void *data, u64 *val)
3478{
3479 struct amdgpu_device *adev = data;
3480
3481 *val = adev->dm.dc->debug.visual_confirm;
3482
3483 return 0;
3484}
3485
3486DEFINE_SHOW_ATTRIBUTE(mst_topo);
3487DEFINE_DEBUGFS_ATTRIBUTE(visual_confirm_fops, visual_confirm_get,
3488 visual_confirm_set, "%llu\n");
3489
3490
3491/*
3492 * Sets the DC skip_detection_link_training debug option from the given string.
3493 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_skip_detection_link_training
3494 */
3495static int skip_detection_link_training_set(void *data, u64 val)
3496{
3497 struct amdgpu_device *adev = data;
3498
3499 if (val == 0)
3500 adev->dm.dc->debug.skip_detection_link_training = false;
3501 else
3502 adev->dm.dc->debug.skip_detection_link_training = true;
3503
3504 return 0;
3505}
3506
3507/*
3508 * Reads the DC skip_detection_link_training debug option value into the given buffer.
3509 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_skip_detection_link_training
3510 */
3511static int skip_detection_link_training_get(void *data, u64 *val)
3512{
3513 struct amdgpu_device *adev = data;
3514
3515 *val = adev->dm.dc->debug.skip_detection_link_training;
3516
3517 return 0;
3518}
3519
3520DEFINE_DEBUGFS_ATTRIBUTE(skip_detection_link_training_fops,
3521 skip_detection_link_training_get,
3522 skip_detection_link_training_set, "%llu\n");
3523
3524/*
3525 * Dumps the DCC_EN bit for each pipe.
3526 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dcc_en
3527 */
3528static ssize_t dcc_en_bits_read(
3529 struct file *f,
3530 char __user *buf,
3531 size_t size,
3532 loff_t *pos)
3533{
3534 struct amdgpu_device *adev = file_inode(f)->i_private;
3535 struct dc *dc = adev->dm.dc;
3536 char *rd_buf = NULL;
3537 const uint32_t rd_buf_size = 32;
3538 uint32_t result = 0;
3539 int offset = 0;
3540 int num_pipes = dc->res_pool->pipe_count;
3541 int *dcc_en_bits;
3542 int i, r;
3543
3544 dcc_en_bits = kcalloc(num_pipes, sizeof(int), GFP_KERNEL);
3545 if (!dcc_en_bits)
3546 return -ENOMEM;
3547
3548 if (!dc->hwss.get_dcc_en_bits) {
3549 kfree(dcc_en_bits);
3550 return 0;
3551 }
3552
3553 dc->hwss.get_dcc_en_bits(dc, dcc_en_bits);
3554
3555 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
3556 if (!rd_buf) {
3557 kfree(dcc_en_bits);
3558 return -ENOMEM;
3559 }
3560
3561 for (i = 0; i < num_pipes; i++)
3562 offset += snprintf(rd_buf + offset, rd_buf_size - offset,
3563 "%d ", dcc_en_bits[i]);
3564 rd_buf[strlen(rd_buf)] = '\n';
3565
3566 kfree(dcc_en_bits);
3567
3568 while (size) {
3569 if (*pos >= rd_buf_size)
3570 break;
3571 r = put_user(*(rd_buf + result), buf);
3572 if (r) {
3573 kfree(rd_buf);
3574 return r; /* r = -EFAULT */
3575 }
3576 buf += 1;
3577 size -= 1;
3578 *pos += 1;
3579 result += 1;
3580 }
3581
3582 kfree(rd_buf);
3583 return result;
3584}
3585
3586void dtn_debugfs_init(struct amdgpu_device *adev)
3587{
3588 static const struct file_operations dtn_log_fops = {
3589 .owner = THIS_MODULE,
3590 .read = dtn_log_read,
3591 .write = dtn_log_write,
3592 .llseek = default_llseek
3593 };
3594 static const struct file_operations dcc_en_bits_fops = {
3595 .owner = THIS_MODULE,
3596 .read = dcc_en_bits_read,
3597 .llseek = default_llseek
3598 };
3599
3600 struct drm_minor *minor = adev_to_drm(adev)->primary;
3601 struct dentry *root = minor->debugfs_root;
3602
3603 debugfs_create_file("amdgpu_mst_topology", 0444, root,
3604 adev, &mst_topo_fops);
3605 debugfs_create_file("amdgpu_dm_dtn_log", 0644, root, adev,
3606 &dtn_log_fops);
3607 debugfs_create_file("amdgpu_dm_dp_set_mst_en_for_sst", 0644, root, adev,
3608 &dp_set_mst_en_for_sst_ops);
3609 debugfs_create_file("amdgpu_dm_dp_ignore_cable_id", 0644, root, adev,
3610 &dp_ignore_cable_id_ops);
3611
3612 debugfs_create_file_unsafe("amdgpu_dm_visual_confirm", 0644, root, adev,
3613 &visual_confirm_fops);
3614
3615 debugfs_create_file_unsafe("amdgpu_dm_skip_detection_link_training", 0644, root, adev,
3616 &skip_detection_link_training_fops);
3617
3618 debugfs_create_file_unsafe("amdgpu_dm_dmub_tracebuffer", 0644, root,
3619 adev, &dmub_tracebuffer_fops);
3620
3621 debugfs_create_file_unsafe("amdgpu_dm_dmub_fw_state", 0644, root,
3622 adev, &dmub_fw_state_fops);
3623
3624 debugfs_create_file_unsafe("amdgpu_dm_force_timing_sync", 0644, root,
3625 adev, &force_timing_sync_ops);
3626
3627 debugfs_create_file_unsafe("amdgpu_dm_dmcub_trace_event_en", 0644, root,
3628 adev, &dmcub_trace_event_state_fops);
3629
3630 debugfs_create_file_unsafe("amdgpu_dm_trigger_hpd_mst", 0644, root,
3631 adev, &trigger_hpd_mst_ops);
3632
3633 debugfs_create_file_unsafe("amdgpu_dm_dcc_en", 0644, root, adev,
3634 &dcc_en_bits_fops);
3635
3636 debugfs_create_file_unsafe("amdgpu_dm_disable_hpd", 0644, root, adev,
3637 &disable_hpd_ops);
3638
3639}