]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
Merge tags 'spi-nor/for-5.11' and 'nand/for-5.11' into mtd/next
[linux.git] / drivers / gpu / drm / amd / display / amdgpu_dm / amdgpu_dm_debugfs.c
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/uaccess.h>
27
28 #include <drm/drm_debugfs.h>
29
30 #include "dc.h"
31 #include "amdgpu.h"
32 #include "amdgpu_dm.h"
33 #include "amdgpu_dm_debugfs.h"
34 #include "dm_helpers.h"
35 #include "dmub/dmub_srv.h"
36 #include "resource.h"
37 #include "dsc.h"
38 #include "dc_link_dp.h"
39
40 struct dmub_debugfs_trace_header {
41         uint32_t entry_count;
42         uint32_t reserved[3];
43 };
44
45 struct dmub_debugfs_trace_entry {
46         uint32_t trace_code;
47         uint32_t tick_count;
48         uint32_t param0;
49         uint32_t param1;
50 };
51
52 static inline const char *yesno(bool v)
53 {
54         return v ? "yes" : "no";
55 }
56
57 /* parse_write_buffer_into_params - Helper function to parse debugfs write buffer into an array
58  *
59  * Function takes in attributes passed to debugfs write entry
60  * and writes into param array.
61  * The user passes max_param_num to identify maximum number of
62  * parameters that could be parsed.
63  *
64  */
65 static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,
66                                           long *param, const char __user *buf,
67                                           int max_param_num,
68                                           uint8_t *param_nums)
69 {
70         char *wr_buf_ptr = NULL;
71         uint32_t wr_buf_count = 0;
72         int r;
73         char *sub_str = NULL;
74         const char delimiter[3] = {' ', '\n', '\0'};
75         uint8_t param_index = 0;
76
77         *param_nums = 0;
78
79         wr_buf_ptr = wr_buf;
80
81         r = copy_from_user(wr_buf_ptr, buf, wr_buf_size);
82
83                 /* r is bytes not be copied */
84         if (r >= wr_buf_size) {
85                 DRM_DEBUG_DRIVER("user data not be read\n");
86                 return -EINVAL;
87         }
88
89         /* check number of parameters. isspace could not differ space and \n */
90         while ((*wr_buf_ptr != 0xa) && (wr_buf_count < wr_buf_size)) {
91                 /* skip space*/
92                 while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) {
93                         wr_buf_ptr++;
94                         wr_buf_count++;
95                         }
96
97                 if (wr_buf_count == wr_buf_size)
98                         break;
99
100                 /* skip non-space*/
101                 while ((!isspace(*wr_buf_ptr)) && (wr_buf_count < wr_buf_size)) {
102                         wr_buf_ptr++;
103                         wr_buf_count++;
104                 }
105
106                 (*param_nums)++;
107
108                 if (wr_buf_count == wr_buf_size)
109                         break;
110         }
111
112         if (*param_nums > max_param_num)
113                 *param_nums = max_param_num;
114
115         wr_buf_ptr = wr_buf; /* reset buf pointer */
116         wr_buf_count = 0; /* number of char already checked */
117
118         while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) {
119                 wr_buf_ptr++;
120                 wr_buf_count++;
121         }
122
123         while (param_index < *param_nums) {
124                 /* after strsep, wr_buf_ptr will be moved to after space */
125                 sub_str = strsep(&wr_buf_ptr, delimiter);
126
127                 r = kstrtol(sub_str, 16, &(param[param_index]));
128
129                 if (r)
130                         DRM_DEBUG_DRIVER("string to int convert error code: %d\n", r);
131
132                 param_index++;
133         }
134
135         return 0;
136 }
137
138 /* function description
139  * get/ set DP configuration: lane_count, link_rate, spread_spectrum
140  *
141  * valid lane count value: 1, 2, 4
142  * valid link rate value:
143  * 06h = 1.62Gbps per lane
144  * 0Ah = 2.7Gbps per lane
145  * 0Ch = 3.24Gbps per lane
146  * 14h = 5.4Gbps per lane
147  * 1Eh = 8.1Gbps per lane
148  *
149  * debugfs is located at /sys/kernel/debug/dri/0/DP-x/link_settings
150  *
151  * --- to get dp configuration
152  *
153  * cat link_settings
154  *
155  * It will list current, verified, reported, preferred dp configuration.
156  * current -- for current video mode
157  * verified --- maximum configuration which pass link training
158  * reported --- DP rx report caps (DPCD register offset 0, 1 2)
159  * preferred --- user force settings
160  *
161  * --- set (or force) dp configuration
162  *
163  * echo <lane_count>  <link_rate> > link_settings
164  *
165  * for example, to force to  2 lane, 2.7GHz,
166  * echo 4 0xa > link_settings
167  *
168  * spread_spectrum could not be changed dynamically.
169  *
170  * in case invalid lane count, link rate are force, no hw programming will be
171  * done. please check link settings after force operation to see if HW get
172  * programming.
173  *
174  * cat link_settings
175  *
176  * check current and preferred settings.
177  *
178  */
179 static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
180                                  size_t size, loff_t *pos)
181 {
182         struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
183         struct dc_link *link = connector->dc_link;
184         char *rd_buf = NULL;
185         char *rd_buf_ptr = NULL;
186         const uint32_t rd_buf_size = 100;
187         uint32_t result = 0;
188         uint8_t str_len = 0;
189         int r;
190
191         if (*pos & 3 || size & 3)
192                 return -EINVAL;
193
194         rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
195         if (!rd_buf)
196                 return 0;
197
198         rd_buf_ptr = rd_buf;
199
200         str_len = strlen("Current:  %d  %d  %d  ");
201         snprintf(rd_buf_ptr, str_len, "Current:  %d  %d  %d  ",
202                         link->cur_link_settings.lane_count,
203                         link->cur_link_settings.link_rate,
204                         link->cur_link_settings.link_spread);
205         rd_buf_ptr += str_len;
206
207         str_len = strlen("Verified:  %d  %d  %d  ");
208         snprintf(rd_buf_ptr, str_len, "Verified:  %d  %d  %d  ",
209                         link->verified_link_cap.lane_count,
210                         link->verified_link_cap.link_rate,
211                         link->verified_link_cap.link_spread);
212         rd_buf_ptr += str_len;
213
214         str_len = strlen("Reported:  %d  %d  %d  ");
215         snprintf(rd_buf_ptr, str_len, "Reported:  %d  %d  %d  ",
216                         link->reported_link_cap.lane_count,
217                         link->reported_link_cap.link_rate,
218                         link->reported_link_cap.link_spread);
219         rd_buf_ptr += str_len;
220
221         str_len = strlen("Preferred:  %d  %d  %d  ");
222         snprintf(rd_buf_ptr, str_len, "Preferred:  %d  %d  %d\n",
223                         link->preferred_link_setting.lane_count,
224                         link->preferred_link_setting.link_rate,
225                         link->preferred_link_setting.link_spread);
226
227         while (size) {
228                 if (*pos >= rd_buf_size)
229                         break;
230
231                 r = put_user(*(rd_buf + result), buf);
232                 if (r)
233                         return r; /* r = -EFAULT */
234
235                 buf += 1;
236                 size -= 1;
237                 *pos += 1;
238                 result += 1;
239         }
240
241         kfree(rd_buf);
242         return result;
243 }
244
245 static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
246                                  size_t size, loff_t *pos)
247 {
248         struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
249         struct dc_link *link = connector->dc_link;
250         struct dc *dc = (struct dc *)link->dc;
251         struct dc_link_settings prefer_link_settings;
252         char *wr_buf = NULL;
253         const uint32_t wr_buf_size = 40;
254         /* 0: lane_count; 1: link_rate */
255         int max_param_num = 2;
256         uint8_t param_nums = 0;
257         long param[2];
258         bool valid_input = false;
259
260         if (size == 0)
261                 return -EINVAL;
262
263         wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
264         if (!wr_buf)
265                 return -ENOSPC;
266
267         if (parse_write_buffer_into_params(wr_buf, size,
268                                            (long *)param, buf,
269                                            max_param_num,
270                                            &param_nums)) {
271                 kfree(wr_buf);
272                 return -EINVAL;
273         }
274
275         if (param_nums <= 0) {
276                 kfree(wr_buf);
277                 DRM_DEBUG_DRIVER("user data not be read\n");
278                 return -EINVAL;
279         }
280
281         switch (param[0]) {
282         case LANE_COUNT_ONE:
283         case LANE_COUNT_TWO:
284         case LANE_COUNT_FOUR:
285                 valid_input = true;
286                 break;
287         default:
288                 break;
289         }
290
291         switch (param[1]) {
292         case LINK_RATE_LOW:
293         case LINK_RATE_HIGH:
294         case LINK_RATE_RBR2:
295         case LINK_RATE_HIGH2:
296         case LINK_RATE_HIGH3:
297                 valid_input = true;
298                 break;
299         default:
300                 break;
301         }
302
303         if (!valid_input) {
304                 kfree(wr_buf);
305                 DRM_DEBUG_DRIVER("Invalid Input value No HW will be programmed\n");
306                 return size;
307         }
308
309         /* save user force lane_count, link_rate to preferred settings
310          * spread spectrum will not be changed
311          */
312         prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
313         prefer_link_settings.lane_count = param[0];
314         prefer_link_settings.link_rate = param[1];
315
316         dc_link_set_preferred_link_settings(dc, &prefer_link_settings, link);
317
318         kfree(wr_buf);
319         return size;
320 }
321
322 /* function: get current DP PHY settings: voltage swing, pre-emphasis,
323  * post-cursor2 (defined by VESA DP specification)
324  *
325  * valid values
326  * voltage swing: 0,1,2,3
327  * pre-emphasis : 0,1,2,3
328  * post cursor2 : 0,1,2,3
329  *
330  *
331  * how to use this debugfs
332  *
333  * debugfs is located at /sys/kernel/debug/dri/0/DP-x
334  *
335  * there will be directories, like DP-1, DP-2,DP-3, etc. for DP display
336  *
337  * To figure out which DP-x is the display for DP to be check,
338  * cd DP-x
339  * ls -ll
340  * There should be debugfs file, like link_settings, phy_settings.
341  * cat link_settings
342  * from lane_count, link_rate to figure which DP-x is for display to be worked
343  * on
344  *
345  * To get current DP PHY settings,
346  * cat phy_settings
347  *
348  * To change DP PHY settings,
349  * echo <voltage_swing> <pre-emphasis> <post_cursor2> > phy_settings
350  * for examle, to change voltage swing to 2, pre-emphasis to 3, post_cursor2 to
351  * 0,
352  * echo 2 3 0 > phy_settings
353  *
354  * To check if change be applied, get current phy settings by
355  * cat phy_settings
356  *
357  * In case invalid values are set by user, like
358  * echo 1 4 0 > phy_settings
359  *
360  * HW will NOT be programmed by these settings.
361  * cat phy_settings will show the previous valid settings.
362  */
363 static ssize_t dp_phy_settings_read(struct file *f, char __user *buf,
364                                  size_t size, loff_t *pos)
365 {
366         struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
367         struct dc_link *link = connector->dc_link;
368         char *rd_buf = NULL;
369         const uint32_t rd_buf_size = 20;
370         uint32_t result = 0;
371         int r;
372
373         if (*pos & 3 || size & 3)
374                 return -EINVAL;
375
376         rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
377         if (!rd_buf)
378                 return -EINVAL;
379
380         snprintf(rd_buf, rd_buf_size, "  %d  %d  %d  ",
381                         link->cur_lane_setting.VOLTAGE_SWING,
382                         link->cur_lane_setting.PRE_EMPHASIS,
383                         link->cur_lane_setting.POST_CURSOR2);
384
385         while (size) {
386                 if (*pos >= rd_buf_size)
387                         break;
388
389                 r = put_user((*(rd_buf + result)), buf);
390                 if (r)
391                         return r; /* r = -EFAULT */
392
393                 buf += 1;
394                 size -= 1;
395                 *pos += 1;
396                 result += 1;
397         }
398
399         kfree(rd_buf);
400         return result;
401 }
402
403 static ssize_t dp_phy_settings_write(struct file *f, const char __user *buf,
404                                  size_t size, loff_t *pos)
405 {
406         struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
407         struct dc_link *link = connector->dc_link;
408         struct dc *dc = (struct dc *)link->dc;
409         char *wr_buf = NULL;
410         uint32_t wr_buf_size = 40;
411         long param[3];
412         bool use_prefer_link_setting;
413         struct link_training_settings link_lane_settings;
414         int max_param_num = 3;
415         uint8_t param_nums = 0;
416         int r = 0;
417
418
419         if (size == 0)
420                 return -EINVAL;
421
422         wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
423         if (!wr_buf)
424                 return -ENOSPC;
425
426         if (parse_write_buffer_into_params(wr_buf, size,
427                                            (long *)param, buf,
428                                            max_param_num,
429                                            &param_nums)) {
430                 kfree(wr_buf);
431                 return -EINVAL;
432         }
433
434         if (param_nums <= 0) {
435                 kfree(wr_buf);
436                 DRM_DEBUG_DRIVER("user data not be read\n");
437                 return -EINVAL;
438         }
439
440         if ((param[0] > VOLTAGE_SWING_MAX_LEVEL) ||
441                         (param[1] > PRE_EMPHASIS_MAX_LEVEL) ||
442                         (param[2] > POST_CURSOR2_MAX_LEVEL)) {
443                 kfree(wr_buf);
444                 DRM_DEBUG_DRIVER("Invalid Input No HW will be programmed\n");
445                 return size;
446         }
447
448         /* get link settings: lane count, link rate */
449         use_prefer_link_setting =
450                 ((link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) &&
451                 (link->test_pattern_enabled));
452
453         memset(&link_lane_settings, 0, sizeof(link_lane_settings));
454
455         if (use_prefer_link_setting) {
456                 link_lane_settings.link_settings.lane_count =
457                                 link->preferred_link_setting.lane_count;
458                 link_lane_settings.link_settings.link_rate =
459                                 link->preferred_link_setting.link_rate;
460                 link_lane_settings.link_settings.link_spread =
461                                 link->preferred_link_setting.link_spread;
462         } else {
463                 link_lane_settings.link_settings.lane_count =
464                                 link->cur_link_settings.lane_count;
465                 link_lane_settings.link_settings.link_rate =
466                                 link->cur_link_settings.link_rate;
467                 link_lane_settings.link_settings.link_spread =
468                                 link->cur_link_settings.link_spread;
469         }
470
471         /* apply phy settings from user */
472         for (r = 0; r < link_lane_settings.link_settings.lane_count; r++) {
473                 link_lane_settings.lane_settings[r].VOLTAGE_SWING =
474                                 (enum dc_voltage_swing) (param[0]);
475                 link_lane_settings.lane_settings[r].PRE_EMPHASIS =
476                                 (enum dc_pre_emphasis) (param[1]);
477                 link_lane_settings.lane_settings[r].POST_CURSOR2 =
478                                 (enum dc_post_cursor2) (param[2]);
479         }
480
481         /* program ASIC registers and DPCD registers */
482         dc_link_set_drive_settings(dc, &link_lane_settings, link);
483
484         kfree(wr_buf);
485         return size;
486 }
487
488 /* function description
489  *
490  * set PHY layer or Link layer test pattern
491  * PHY test pattern is used for PHY SI check.
492  * Link layer test will not affect PHY SI.
493  *
494  * Reset Test Pattern:
495  * 0 = DP_TEST_PATTERN_VIDEO_MODE
496  *
497  * PHY test pattern supported:
498  * 1 = DP_TEST_PATTERN_D102
499  * 2 = DP_TEST_PATTERN_SYMBOL_ERROR
500  * 3 = DP_TEST_PATTERN_PRBS7
501  * 4 = DP_TEST_PATTERN_80BIT_CUSTOM
502  * 5 = DP_TEST_PATTERN_CP2520_1
503  * 6 = DP_TEST_PATTERN_CP2520_2 = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE
504  * 7 = DP_TEST_PATTERN_CP2520_3
505  *
506  * DP PHY Link Training Patterns
507  * 8 = DP_TEST_PATTERN_TRAINING_PATTERN1
508  * 9 = DP_TEST_PATTERN_TRAINING_PATTERN2
509  * a = DP_TEST_PATTERN_TRAINING_PATTERN3
510  * b = DP_TEST_PATTERN_TRAINING_PATTERN4
511  *
512  * DP Link Layer Test pattern
513  * c = DP_TEST_PATTERN_COLOR_SQUARES
514  * d = DP_TEST_PATTERN_COLOR_SQUARES_CEA
515  * e = DP_TEST_PATTERN_VERTICAL_BARS
516  * f = DP_TEST_PATTERN_HORIZONTAL_BARS
517  * 10= DP_TEST_PATTERN_COLOR_RAMP
518  *
519  * debugfs phy_test_pattern is located at /syskernel/debug/dri/0/DP-x
520  *
521  * --- set test pattern
522  * echo <test pattern #> > test_pattern
523  *
524  * If test pattern # is not supported, NO HW programming will be done.
525  * for DP_TEST_PATTERN_80BIT_CUSTOM, it needs extra 10 bytes of data
526  * for the user pattern. input 10 bytes data are separated by space
527  *
528  * echo 0x4 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x99 0xaa > test_pattern
529  *
530  * --- reset test pattern
531  * echo 0 > test_pattern
532  *
533  * --- HPD detection is disabled when set PHY test pattern
534  *
535  * when PHY test pattern (pattern # within [1,7]) is set, HPD pin of HW ASIC
536  * is disable. User could unplug DP display from DP connected and plug scope to
537  * check test pattern PHY SI.
538  * If there is need unplug scope and plug DP display back, do steps below:
539  * echo 0 > phy_test_pattern
540  * unplug scope
541  * plug DP display.
542  *
543  * "echo 0 > phy_test_pattern" will re-enable HPD pin again so that video sw
544  * driver could detect "unplug scope" and "plug DP display"
545  */
546 static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __user *buf,
547                                  size_t size, loff_t *pos)
548 {
549         struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
550         struct dc_link *link = connector->dc_link;
551         char *wr_buf = NULL;
552         uint32_t wr_buf_size = 100;
553         long param[11] = {0x0};
554         int max_param_num = 11;
555         enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
556         bool disable_hpd = false;
557         bool valid_test_pattern = false;
558         uint8_t param_nums = 0;
559         /* init with defalut 80bit custom pattern */
560         uint8_t custom_pattern[10] = {
561                         0x1f, 0x7c, 0xf0, 0xc1, 0x07,
562                         0x1f, 0x7c, 0xf0, 0xc1, 0x07
563                         };
564         struct dc_link_settings prefer_link_settings = {LANE_COUNT_UNKNOWN,
565                         LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED};
566         struct dc_link_settings cur_link_settings = {LANE_COUNT_UNKNOWN,
567                         LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED};
568         struct link_training_settings link_training_settings;
569         int i;
570
571         if (size == 0)
572                 return -EINVAL;
573
574         wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
575         if (!wr_buf)
576                 return -ENOSPC;
577
578         if (parse_write_buffer_into_params(wr_buf, size,
579                                            (long *)param, buf,
580                                            max_param_num,
581                                            &param_nums)) {
582                 kfree(wr_buf);
583                 return -EINVAL;
584         }
585
586         if (param_nums <= 0) {
587                 kfree(wr_buf);
588                 DRM_DEBUG_DRIVER("user data not be read\n");
589                 return -EINVAL;
590         }
591
592
593         test_pattern = param[0];
594
595         switch (test_pattern) {
596         case DP_TEST_PATTERN_VIDEO_MODE:
597         case DP_TEST_PATTERN_COLOR_SQUARES:
598         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
599         case DP_TEST_PATTERN_VERTICAL_BARS:
600         case DP_TEST_PATTERN_HORIZONTAL_BARS:
601         case DP_TEST_PATTERN_COLOR_RAMP:
602                 valid_test_pattern = true;
603                 break;
604
605         case DP_TEST_PATTERN_D102:
606         case DP_TEST_PATTERN_SYMBOL_ERROR:
607         case DP_TEST_PATTERN_PRBS7:
608         case DP_TEST_PATTERN_80BIT_CUSTOM:
609         case DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE:
610         case DP_TEST_PATTERN_TRAINING_PATTERN4:
611                 disable_hpd = true;
612                 valid_test_pattern = true;
613                 break;
614
615         default:
616                 valid_test_pattern = false;
617                 test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
618                 break;
619         }
620
621         if (!valid_test_pattern) {
622                 kfree(wr_buf);
623                 DRM_DEBUG_DRIVER("Invalid Test Pattern Parameters\n");
624                 return size;
625         }
626
627         if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) {
628                 for (i = 0; i < 10; i++) {
629                         if ((uint8_t) param[i + 1] != 0x0)
630                                 break;
631                 }
632
633                 if (i < 10) {
634                         /* not use default value */
635                         for (i = 0; i < 10; i++)
636                                 custom_pattern[i] = (uint8_t) param[i + 1];
637                 }
638         }
639
640         /* Usage: set DP physical test pattern using debugfs with normal DP
641          * panel. Then plug out DP panel and connect a scope to measure
642          * For normal video mode and test pattern generated from CRCT,
643          * they are visibile to user. So do not disable HPD.
644          * Video Mode is also set to clear the test pattern, so enable HPD
645          * because it might have been disabled after a test pattern was set.
646          * AUX depends on HPD * sequence dependent, do not move!
647          */
648         if (!disable_hpd)
649                 dc_link_enable_hpd(link);
650
651         prefer_link_settings.lane_count = link->verified_link_cap.lane_count;
652         prefer_link_settings.link_rate = link->verified_link_cap.link_rate;
653         prefer_link_settings.link_spread = link->verified_link_cap.link_spread;
654
655         cur_link_settings.lane_count = link->cur_link_settings.lane_count;
656         cur_link_settings.link_rate = link->cur_link_settings.link_rate;
657         cur_link_settings.link_spread = link->cur_link_settings.link_spread;
658
659         link_training_settings.link_settings = cur_link_settings;
660
661
662         if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
663                 if (prefer_link_settings.lane_count != LANE_COUNT_UNKNOWN &&
664                         prefer_link_settings.link_rate !=  LINK_RATE_UNKNOWN &&
665                         (prefer_link_settings.lane_count != cur_link_settings.lane_count ||
666                         prefer_link_settings.link_rate != cur_link_settings.link_rate))
667                         link_training_settings.link_settings = prefer_link_settings;
668         }
669
670         for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++)
671                 link_training_settings.lane_settings[i] = link->cur_lane_setting;
672
673         dc_link_set_test_pattern(
674                 link,
675                 test_pattern,
676                 DP_TEST_PATTERN_COLOR_SPACE_RGB,
677                 &link_training_settings,
678                 custom_pattern,
679                 10);
680
681         /* Usage: Set DP physical test pattern using AMDDP with normal DP panel
682          * Then plug out DP panel and connect a scope to measure DP PHY signal.
683          * Need disable interrupt to avoid SW driver disable DP output. This is
684          * done after the test pattern is set.
685          */
686         if (valid_test_pattern && disable_hpd)
687                 dc_link_disable_hpd(link);
688
689         kfree(wr_buf);
690
691         return size;
692 }
693
694 /**
695  * Returns the DMCUB tracebuffer contents.
696  * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dmub_tracebuffer
697  */
698 static int dmub_tracebuffer_show(struct seq_file *m, void *data)
699 {
700         struct amdgpu_device *adev = m->private;
701         struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
702         struct dmub_debugfs_trace_entry *entries;
703         uint8_t *tbuf_base;
704         uint32_t tbuf_size, max_entries, num_entries, i;
705
706         if (!fb_info)
707                 return 0;
708
709         tbuf_base = (uint8_t *)fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].cpu_addr;
710         if (!tbuf_base)
711                 return 0;
712
713         tbuf_size = fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].size;
714         max_entries = (tbuf_size - sizeof(struct dmub_debugfs_trace_header)) /
715                       sizeof(struct dmub_debugfs_trace_entry);
716
717         num_entries =
718                 ((struct dmub_debugfs_trace_header *)tbuf_base)->entry_count;
719
720         num_entries = min(num_entries, max_entries);
721
722         entries = (struct dmub_debugfs_trace_entry
723                            *)(tbuf_base +
724                               sizeof(struct dmub_debugfs_trace_header));
725
726         for (i = 0; i < num_entries; ++i) {
727                 struct dmub_debugfs_trace_entry *entry = &entries[i];
728
729                 seq_printf(m,
730                            "trace_code=%u tick_count=%u param0=%u param1=%u\n",
731                            entry->trace_code, entry->tick_count, entry->param0,
732                            entry->param1);
733         }
734
735         return 0;
736 }
737
738 /**
739  * Returns the DMCUB firmware state contents.
740  * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dmub_fw_state
741  */
742 static int dmub_fw_state_show(struct seq_file *m, void *data)
743 {
744         struct amdgpu_device *adev = m->private;
745         struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
746         uint8_t *state_base;
747         uint32_t state_size;
748
749         if (!fb_info)
750                 return 0;
751
752         state_base = (uint8_t *)fb_info->fb[DMUB_WINDOW_6_FW_STATE].cpu_addr;
753         if (!state_base)
754                 return 0;
755
756         state_size = fb_info->fb[DMUB_WINDOW_6_FW_STATE].size;
757
758         return seq_write(m, state_base, state_size);
759 }
760
761 /*
762  * Returns the current and maximum output bpc for the connector.
763  * Example usage: cat /sys/kernel/debug/dri/0/DP-1/output_bpc
764  */
765 static int output_bpc_show(struct seq_file *m, void *data)
766 {
767         struct drm_connector *connector = m->private;
768         struct drm_device *dev = connector->dev;
769         struct drm_crtc *crtc = NULL;
770         struct dm_crtc_state *dm_crtc_state = NULL;
771         int res = -ENODEV;
772         unsigned int bpc;
773
774         mutex_lock(&dev->mode_config.mutex);
775         drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
776
777         if (connector->state == NULL)
778                 goto unlock;
779
780         crtc = connector->state->crtc;
781         if (crtc == NULL)
782                 goto unlock;
783
784         drm_modeset_lock(&crtc->mutex, NULL);
785         if (crtc->state == NULL)
786                 goto unlock;
787
788         dm_crtc_state = to_dm_crtc_state(crtc->state);
789         if (dm_crtc_state->stream == NULL)
790                 goto unlock;
791
792         switch (dm_crtc_state->stream->timing.display_color_depth) {
793         case COLOR_DEPTH_666:
794                 bpc = 6;
795                 break;
796         case COLOR_DEPTH_888:
797                 bpc = 8;
798                 break;
799         case COLOR_DEPTH_101010:
800                 bpc = 10;
801                 break;
802         case COLOR_DEPTH_121212:
803                 bpc = 12;
804                 break;
805         case COLOR_DEPTH_161616:
806                 bpc = 16;
807                 break;
808         default:
809                 goto unlock;
810         }
811
812         seq_printf(m, "Current: %u\n", bpc);
813         seq_printf(m, "Maximum: %u\n", connector->display_info.bpc);
814         res = 0;
815
816 unlock:
817         if (crtc)
818                 drm_modeset_unlock(&crtc->mutex);
819
820         drm_modeset_unlock(&dev->mode_config.connection_mutex);
821         mutex_unlock(&dev->mode_config.mutex);
822
823         return res;
824 }
825
826 #ifdef CONFIG_DRM_AMD_DC_HDCP
827 /*
828  * Returns the HDCP capability of the Display (1.4 for now).
829  *
830  * NOTE* Not all HDMI displays report their HDCP caps even when they are capable.
831  * Since its rare for a display to not be HDCP 1.4 capable, we set HDMI as always capable.
832  *
833  * Example usage: cat /sys/kernel/debug/dri/0/DP-1/hdcp_sink_capability
834  *              or cat /sys/kernel/debug/dri/0/HDMI-A-1/hdcp_sink_capability
835  */
836 static int hdcp_sink_capability_show(struct seq_file *m, void *data)
837 {
838         struct drm_connector *connector = m->private;
839         struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
840         bool hdcp_cap, hdcp2_cap;
841
842         if (connector->status != connector_status_connected)
843                 return -ENODEV;
844
845         seq_printf(m, "%s:%d HDCP version: ", connector->name, connector->base.id);
846
847         hdcp_cap = dc_link_is_hdcp14(aconnector->dc_link, aconnector->dc_sink->sink_signal);
848         hdcp2_cap = dc_link_is_hdcp22(aconnector->dc_link, aconnector->dc_sink->sink_signal);
849
850
851         if (hdcp_cap)
852                 seq_printf(m, "%s ", "HDCP1.4");
853         if (hdcp2_cap)
854                 seq_printf(m, "%s ", "HDCP2.2");
855
856         if (!hdcp_cap && !hdcp2_cap)
857                 seq_printf(m, "%s ", "None");
858
859         seq_puts(m, "\n");
860
861         return 0;
862 }
863 #endif
864 /* function description
865  *
866  * generic SDP message access for testing
867  *
868  * debugfs sdp_message is located at /syskernel/debug/dri/0/DP-x
869  *
870  * SDP header
871  * Hb0 : Secondary-Data Packet ID
872  * Hb1 : Secondary-Data Packet type
873  * Hb2 : Secondary-Data-packet-specific header, Byte 0
874  * Hb3 : Secondary-Data-packet-specific header, Byte 1
875  *
876  * for using custom sdp message: input 4 bytes SDP header and 32 bytes raw data
877  */
878 static ssize_t dp_sdp_message_debugfs_write(struct file *f, const char __user *buf,
879                                  size_t size, loff_t *pos)
880 {
881         int r;
882         uint8_t data[36];
883         struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
884         struct dm_crtc_state *acrtc_state;
885         uint32_t write_size = 36;
886
887         if (connector->base.status != connector_status_connected)
888                 return -ENODEV;
889
890         if (size == 0)
891                 return 0;
892
893         acrtc_state = to_dm_crtc_state(connector->base.state->crtc->state);
894
895         r = copy_from_user(data, buf, write_size);
896
897         write_size -= r;
898
899         dc_stream_send_dp_sdp(acrtc_state->stream, data, write_size);
900
901         return write_size;
902 }
903
904 static ssize_t dp_dpcd_address_write(struct file *f, const char __user *buf,
905                                  size_t size, loff_t *pos)
906 {
907         int r;
908         struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
909
910         if (size < sizeof(connector->debugfs_dpcd_address))
911                 return -EINVAL;
912
913         r = copy_from_user(&connector->debugfs_dpcd_address,
914                         buf, sizeof(connector->debugfs_dpcd_address));
915
916         return size - r;
917 }
918
919 static ssize_t dp_dpcd_size_write(struct file *f, const char __user *buf,
920                                  size_t size, loff_t *pos)
921 {
922         int r;
923         struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
924
925         if (size < sizeof(connector->debugfs_dpcd_size))
926                 return -EINVAL;
927
928         r = copy_from_user(&connector->debugfs_dpcd_size,
929                         buf, sizeof(connector->debugfs_dpcd_size));
930
931         if (connector->debugfs_dpcd_size > 256)
932                 connector->debugfs_dpcd_size = 0;
933
934         return size - r;
935 }
936
937 static ssize_t dp_dpcd_data_write(struct file *f, const char __user *buf,
938                                  size_t size, loff_t *pos)
939 {
940         int r;
941         char *data;
942         struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
943         struct dc_link *link = connector->dc_link;
944         uint32_t write_size = connector->debugfs_dpcd_size;
945
946         if (!write_size || size < write_size)
947                 return -EINVAL;
948
949         data = kzalloc(write_size, GFP_KERNEL);
950         if (!data)
951                 return 0;
952
953         r = copy_from_user(data, buf, write_size);
954
955         dm_helpers_dp_write_dpcd(link->ctx, link,
956                         connector->debugfs_dpcd_address, data, write_size - r);
957         kfree(data);
958         return write_size - r;
959 }
960
961 static ssize_t dp_dpcd_data_read(struct file *f, char __user *buf,
962                                  size_t size, loff_t *pos)
963 {
964         int r;
965         char *data;
966         struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
967         struct dc_link *link = connector->dc_link;
968         uint32_t read_size = connector->debugfs_dpcd_size;
969
970         if (!read_size || size < read_size)
971                 return 0;
972
973         data = kzalloc(read_size, GFP_KERNEL);
974         if (!data)
975                 return 0;
976
977         dm_helpers_dp_read_dpcd(link->ctx, link,
978                         connector->debugfs_dpcd_address, data, read_size);
979
980         r = copy_to_user(buf, data, read_size);
981
982         kfree(data);
983         return read_size - r;
984 }
985
986 /* function: Read link's DSC & FEC capabilities
987  *
988  *
989  * Access it with the following command (you need to specify
990  * connector like DP-1):
991  *
992  *      cat /sys/kernel/debug/dri/0/DP-X/dp_dsc_fec_support
993  *
994  */
995 static int dp_dsc_fec_support_show(struct seq_file *m, void *data)
996 {
997         struct drm_connector *connector = m->private;
998         struct drm_modeset_acquire_ctx ctx;
999         struct drm_device *dev = connector->dev;
1000         struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
1001         int ret = 0;
1002         bool try_again = false;
1003         bool is_fec_supported = false;
1004         bool is_dsc_supported = false;
1005         struct dpcd_caps dpcd_caps;
1006
1007         drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
1008         do {
1009                 try_again = false;
1010                 ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx);
1011                 if (ret) {
1012                         if (ret == -EDEADLK) {
1013                                 ret = drm_modeset_backoff(&ctx);
1014                                 if (!ret) {
1015                                         try_again = true;
1016                                         continue;
1017                                 }
1018                         }
1019                         break;
1020                 }
1021                 if (connector->status != connector_status_connected) {
1022                         ret = -ENODEV;
1023                         break;
1024                 }
1025                 dpcd_caps = aconnector->dc_link->dpcd_caps;
1026                 if (aconnector->port) {
1027                         /* aconnector sets dsc_aux during get_modes call
1028                          * if MST connector has it means it can either
1029                          * enable DSC on the sink device or on MST branch
1030                          * its connected to.
1031                          */
1032                         if (aconnector->dsc_aux) {
1033                                 is_fec_supported = true;
1034                                 is_dsc_supported = true;
1035                         }
1036                 } else {
1037                         is_fec_supported = dpcd_caps.fec_cap.raw & 0x1;
1038                         is_dsc_supported = dpcd_caps.dsc_caps.dsc_basic_caps.raw[0] & 0x1;
1039                 }
1040         } while (try_again);
1041
1042         drm_modeset_drop_locks(&ctx);
1043         drm_modeset_acquire_fini(&ctx);
1044
1045         seq_printf(m, "FEC_Sink_Support: %s\n", yesno(is_fec_supported));
1046         seq_printf(m, "DSC_Sink_Support: %s\n", yesno(is_dsc_supported));
1047
1048         return ret;
1049 }
1050
1051 /* function: Trigger virtual HPD redetection on connector
1052  *
1053  * This function will perform link rediscovery, link disable
1054  * and enable, and dm connector state update.
1055  *
1056  * Retrigger HPD on an existing connector by echoing 1 into
1057  * its respectful "trigger_hotplug" debugfs entry:
1058  *
1059  *      echo 1 > /sys/kernel/debug/dri/0/DP-X/trigger_hotplug
1060  *
1061  * This function can perform HPD unplug:
1062  *
1063  *      echo 0 > /sys/kernel/debug/dri/0/DP-X/trigger_hotplug
1064  *
1065  */
1066 static ssize_t dp_trigger_hotplug(struct file *f, const char __user *buf,
1067                                                         size_t size, loff_t *pos)
1068 {
1069         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1070         struct drm_connector *connector = &aconnector->base;
1071         struct dc_link *link = NULL;
1072         struct drm_device *dev = connector->dev;
1073         enum dc_connection_type new_connection_type = dc_connection_none;
1074         char *wr_buf = NULL;
1075         uint32_t wr_buf_size = 42;
1076         int max_param_num = 1;
1077         long param[1] = {0};
1078         uint8_t param_nums = 0;
1079
1080         if (!aconnector || !aconnector->dc_link)
1081                 return -EINVAL;
1082
1083         if (size == 0)
1084                 return -EINVAL;
1085
1086         wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1087
1088         if (!wr_buf) {
1089                 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1090                 return -ENOSPC;
1091         }
1092
1093         if (parse_write_buffer_into_params(wr_buf, size,
1094                                                 (long *)param, buf,
1095                                                 max_param_num,
1096                                                 &param_nums)) {
1097                 kfree(wr_buf);
1098                 return -EINVAL;
1099         }
1100
1101         if (param_nums <= 0) {
1102                 DRM_DEBUG_DRIVER("user data not be read\n");
1103                 kfree(wr_buf);
1104                 return -EINVAL;
1105         }
1106
1107         if (param[0] == 1) {
1108                 mutex_lock(&aconnector->hpd_lock);
1109
1110                 if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type) &&
1111                         new_connection_type != dc_connection_none)
1112                         goto unlock;
1113
1114                 if (!dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD))
1115                         goto unlock;
1116
1117                 amdgpu_dm_update_connector_after_detect(aconnector);
1118
1119                 drm_modeset_lock_all(dev);
1120                 dm_restore_drm_connector_state(dev, connector);
1121                 drm_modeset_unlock_all(dev);
1122
1123                 drm_kms_helper_hotplug_event(dev);
1124         } else if (param[0] == 0) {
1125                 if (!aconnector->dc_link)
1126                         goto unlock;
1127
1128                 link = aconnector->dc_link;
1129
1130                 if (link->local_sink) {
1131                         dc_sink_release(link->local_sink);
1132                         link->local_sink = NULL;
1133                 }
1134
1135                 link->dpcd_sink_count = 0;
1136                 link->type = dc_connection_none;
1137                 link->dongle_max_pix_clk = 0;
1138
1139                 amdgpu_dm_update_connector_after_detect(aconnector);
1140
1141                 drm_modeset_lock_all(dev);
1142                 dm_restore_drm_connector_state(dev, connector);
1143                 drm_modeset_unlock_all(dev);
1144
1145                 drm_kms_helper_hotplug_event(dev);
1146         }
1147
1148 unlock:
1149         mutex_unlock(&aconnector->hpd_lock);
1150
1151         kfree(wr_buf);
1152         return size;
1153 }
1154
1155 /* function: read DSC status on the connector
1156  *
1157  * The read function: dp_dsc_clock_en_read
1158  * returns current status of DSC clock on the connector.
1159  * The return is a boolean flag: 1 or 0.
1160  *
1161  * Access it with the following command (you need to specify
1162  * connector like DP-1):
1163  *
1164  *      cat /sys/kernel/debug/dri/0/DP-X/dsc_clock_en
1165  *
1166  * Expected output:
1167  * 1 - means that DSC is currently enabled
1168  * 0 - means that DSC is disabled
1169  */
1170 static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
1171                                     size_t size, loff_t *pos)
1172 {
1173         char *rd_buf = NULL;
1174         char *rd_buf_ptr = NULL;
1175         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1176         struct display_stream_compressor *dsc;
1177         struct dcn_dsc_state dsc_state = {0};
1178         const uint32_t rd_buf_size = 10;
1179         struct pipe_ctx *pipe_ctx;
1180         ssize_t result = 0;
1181         int i, r, str_len = 30;
1182
1183         rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1184
1185         if (!rd_buf)
1186                 return -ENOMEM;
1187
1188         rd_buf_ptr = rd_buf;
1189
1190         for (i = 0; i < MAX_PIPES; i++) {
1191                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1192                         if (pipe_ctx && pipe_ctx->stream &&
1193                             pipe_ctx->stream->link == aconnector->dc_link)
1194                                 break;
1195         }
1196
1197         if (!pipe_ctx)
1198                 return -ENXIO;
1199
1200         dsc = pipe_ctx->stream_res.dsc;
1201         if (dsc)
1202                 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1203
1204         snprintf(rd_buf_ptr, str_len,
1205                 "%d\n",
1206                 dsc_state.dsc_clock_en);
1207         rd_buf_ptr += str_len;
1208
1209         while (size) {
1210                 if (*pos >= rd_buf_size)
1211                         break;
1212
1213                 r = put_user(*(rd_buf + result), buf);
1214                 if (r)
1215                         return r; /* r = -EFAULT */
1216
1217                 buf += 1;
1218                 size -= 1;
1219                 *pos += 1;
1220                 result += 1;
1221         }
1222
1223         kfree(rd_buf);
1224         return result;
1225 }
1226
1227 /* function: write force DSC on the connector
1228  *
1229  * The write function: dp_dsc_clock_en_write
1230  * enables to force DSC on the connector.
1231  * User can write to either force enable or force disable DSC
1232  * on the next modeset or set it to driver default
1233  *
1234  * Accepted inputs:
1235  * 0 - default DSC enablement policy
1236  * 1 - force enable DSC on the connector
1237  * 2 - force disable DSC on the connector (might cause fail in atomic_check)
1238  *
1239  * Writing DSC settings is done with the following command:
1240  * - To force enable DSC (you need to specify
1241  * connector like DP-1):
1242  *
1243  *      echo 0x1 > /sys/kernel/debug/dri/0/DP-X/dsc_clock_en
1244  *
1245  * - To return to default state set the flag to zero and
1246  * let driver deal with DSC automatically
1247  * (you need to specify connector like DP-1):
1248  *
1249  *      echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_clock_en
1250  *
1251  */
1252 static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf,
1253                                      size_t size, loff_t *pos)
1254 {
1255         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1256         struct pipe_ctx *pipe_ctx;
1257         int i;
1258         char *wr_buf = NULL;
1259         uint32_t wr_buf_size = 42;
1260         int max_param_num = 1;
1261         long param[1] = {0};
1262         uint8_t param_nums = 0;
1263
1264         if (size == 0)
1265                 return -EINVAL;
1266
1267         wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1268
1269         if (!wr_buf) {
1270                 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1271                 return -ENOSPC;
1272         }
1273
1274         if (parse_write_buffer_into_params(wr_buf, size,
1275                                             (long *)param, buf,
1276                                             max_param_num,
1277                                             &param_nums)) {
1278                 kfree(wr_buf);
1279                 return -EINVAL;
1280         }
1281
1282         if (param_nums <= 0) {
1283                 DRM_DEBUG_DRIVER("user data not be read\n");
1284                 kfree(wr_buf);
1285                 return -EINVAL;
1286         }
1287
1288         for (i = 0; i < MAX_PIPES; i++) {
1289                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1290                         if (pipe_ctx && pipe_ctx->stream &&
1291                             pipe_ctx->stream->link == aconnector->dc_link)
1292                                 break;
1293         }
1294
1295         if (!pipe_ctx || !pipe_ctx->stream)
1296                 goto done;
1297
1298         if (param[0] == 1)
1299                 aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_ENABLE;
1300         else if (param[0] == 2)
1301                 aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_DISABLE;
1302         else
1303                 aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_DEFAULT;
1304
1305 done:
1306         kfree(wr_buf);
1307         return size;
1308 }
1309
1310 /* function: read DSC slice width parameter on the connector
1311  *
1312  * The read function: dp_dsc_slice_width_read
1313  * returns dsc slice width used in the current configuration
1314  * The return is an integer: 0 or other positive number
1315  *
1316  * Access the status with the following command:
1317  *
1318  *      cat /sys/kernel/debug/dri/0/DP-X/dsc_slice_width
1319  *
1320  * 0 - means that DSC is disabled
1321  *
1322  * Any other number more than zero represents the
1323  * slice width currently used by DSC in pixels
1324  *
1325  */
1326 static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
1327                                     size_t size, loff_t *pos)
1328 {
1329         char *rd_buf = NULL;
1330         char *rd_buf_ptr = NULL;
1331         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1332         struct display_stream_compressor *dsc;
1333         struct dcn_dsc_state dsc_state = {0};
1334         const uint32_t rd_buf_size = 100;
1335         struct pipe_ctx *pipe_ctx;
1336         ssize_t result = 0;
1337         int i, r, str_len = 30;
1338
1339         rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1340
1341         if (!rd_buf)
1342                 return -ENOMEM;
1343
1344         rd_buf_ptr = rd_buf;
1345
1346         for (i = 0; i < MAX_PIPES; i++) {
1347                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1348                         if (pipe_ctx && pipe_ctx->stream &&
1349                             pipe_ctx->stream->link == aconnector->dc_link)
1350                                 break;
1351         }
1352
1353         if (!pipe_ctx)
1354                 return -ENXIO;
1355
1356         dsc = pipe_ctx->stream_res.dsc;
1357         if (dsc)
1358                 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1359
1360         snprintf(rd_buf_ptr, str_len,
1361                 "%d\n",
1362                 dsc_state.dsc_slice_width);
1363         rd_buf_ptr += str_len;
1364
1365         while (size) {
1366                 if (*pos >= rd_buf_size)
1367                         break;
1368
1369                 r = put_user(*(rd_buf + result), buf);
1370                 if (r)
1371                         return r; /* r = -EFAULT */
1372
1373                 buf += 1;
1374                 size -= 1;
1375                 *pos += 1;
1376                 result += 1;
1377         }
1378
1379         kfree(rd_buf);
1380         return result;
1381 }
1382
1383 /* function: write DSC slice width parameter
1384  *
1385  * The write function: dp_dsc_slice_width_write
1386  * overwrites automatically generated DSC configuration
1387  * of slice width.
1388  *
1389  * The user has to write the slice width divisible by the
1390  * picture width.
1391  *
1392  * Also the user has to write width in hexidecimal
1393  * rather than in decimal.
1394  *
1395  * Writing DSC settings is done with the following command:
1396  * - To force overwrite slice width: (example sets to 1920 pixels)
1397  *
1398  *      echo 0x780 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_width
1399  *
1400  *  - To stop overwriting and let driver find the optimal size,
1401  * set the width to zero:
1402  *
1403  *      echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_width
1404  *
1405  */
1406 static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf,
1407                                      size_t size, loff_t *pos)
1408 {
1409         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1410         struct pipe_ctx *pipe_ctx;
1411         int i;
1412         char *wr_buf = NULL;
1413         uint32_t wr_buf_size = 42;
1414         int max_param_num = 1;
1415         long param[1] = {0};
1416         uint8_t param_nums = 0;
1417
1418         if (size == 0)
1419                 return -EINVAL;
1420
1421         wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1422
1423         if (!wr_buf) {
1424                 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1425                 return -ENOSPC;
1426         }
1427
1428         if (parse_write_buffer_into_params(wr_buf, size,
1429                                             (long *)param, buf,
1430                                             max_param_num,
1431                                             &param_nums)) {
1432                 kfree(wr_buf);
1433                 return -EINVAL;
1434         }
1435
1436         if (param_nums <= 0) {
1437                 DRM_DEBUG_DRIVER("user data not be read\n");
1438                 kfree(wr_buf);
1439                 return -EINVAL;
1440         }
1441
1442         for (i = 0; i < MAX_PIPES; i++) {
1443                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1444                         if (pipe_ctx && pipe_ctx->stream &&
1445                             pipe_ctx->stream->link == aconnector->dc_link)
1446                                 break;
1447         }
1448
1449         if (!pipe_ctx || !pipe_ctx->stream)
1450                 goto done;
1451
1452         if (param[0] > 0)
1453                 aconnector->dsc_settings.dsc_num_slices_h = DIV_ROUND_UP(
1454                                         pipe_ctx->stream->timing.h_addressable,
1455                                         param[0]);
1456         else
1457                 aconnector->dsc_settings.dsc_num_slices_h = 0;
1458
1459 done:
1460         kfree(wr_buf);
1461         return size;
1462 }
1463
1464 /* function: read DSC slice height parameter on the connector
1465  *
1466  * The read function: dp_dsc_slice_height_read
1467  * returns dsc slice height used in the current configuration
1468  * The return is an integer: 0 or other positive number
1469  *
1470  * Access the status with the following command:
1471  *
1472  *      cat /sys/kernel/debug/dri/0/DP-X/dsc_slice_height
1473  *
1474  * 0 - means that DSC is disabled
1475  *
1476  * Any other number more than zero represents the
1477  * slice height currently used by DSC in pixels
1478  *
1479  */
1480 static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
1481                                     size_t size, loff_t *pos)
1482 {
1483         char *rd_buf = NULL;
1484         char *rd_buf_ptr = NULL;
1485         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1486         struct display_stream_compressor *dsc;
1487         struct dcn_dsc_state dsc_state = {0};
1488         const uint32_t rd_buf_size = 100;
1489         struct pipe_ctx *pipe_ctx;
1490         ssize_t result = 0;
1491         int i, r, str_len = 30;
1492
1493         rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1494
1495         if (!rd_buf)
1496                 return -ENOMEM;
1497
1498         rd_buf_ptr = rd_buf;
1499
1500         for (i = 0; i < MAX_PIPES; i++) {
1501                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1502                         if (pipe_ctx && pipe_ctx->stream &&
1503                             pipe_ctx->stream->link == aconnector->dc_link)
1504                                 break;
1505         }
1506
1507         if (!pipe_ctx)
1508                 return -ENXIO;
1509
1510         dsc = pipe_ctx->stream_res.dsc;
1511         if (dsc)
1512                 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1513
1514         snprintf(rd_buf_ptr, str_len,
1515                 "%d\n",
1516                 dsc_state.dsc_slice_height);
1517         rd_buf_ptr += str_len;
1518
1519         while (size) {
1520                 if (*pos >= rd_buf_size)
1521                         break;
1522
1523                 r = put_user(*(rd_buf + result), buf);
1524                 if (r)
1525                         return r; /* r = -EFAULT */
1526
1527                 buf += 1;
1528                 size -= 1;
1529                 *pos += 1;
1530                 result += 1;
1531         }
1532
1533         kfree(rd_buf);
1534         return result;
1535 }
1536
1537 /* function: write DSC slice height parameter
1538  *
1539  * The write function: dp_dsc_slice_height_write
1540  * overwrites automatically generated DSC configuration
1541  * of slice height.
1542  *
1543  * The user has to write the slice height divisible by the
1544  * picture height.
1545  *
1546  * Also the user has to write height in hexidecimal
1547  * rather than in decimal.
1548  *
1549  * Writing DSC settings is done with the following command:
1550  * - To force overwrite slice height (example sets to 128 pixels):
1551  *
1552  *      echo 0x80 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_height
1553  *
1554  *  - To stop overwriting and let driver find the optimal size,
1555  * set the height to zero:
1556  *
1557  *      echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_height
1558  *
1559  */
1560 static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf,
1561                                      size_t size, loff_t *pos)
1562 {
1563         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1564         struct pipe_ctx *pipe_ctx;
1565         int i;
1566         char *wr_buf = NULL;
1567         uint32_t wr_buf_size = 42;
1568         int max_param_num = 1;
1569         uint8_t param_nums = 0;
1570         long param[1] = {0};
1571
1572         if (size == 0)
1573                 return -EINVAL;
1574
1575         wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1576
1577         if (!wr_buf) {
1578                 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1579                 return -ENOSPC;
1580         }
1581
1582         if (parse_write_buffer_into_params(wr_buf, size,
1583                                             (long *)param, buf,
1584                                             max_param_num,
1585                                             &param_nums)) {
1586                 kfree(wr_buf);
1587                 return -EINVAL;
1588         }
1589
1590         if (param_nums <= 0) {
1591                 DRM_DEBUG_DRIVER("user data not be read\n");
1592                 kfree(wr_buf);
1593                 return -EINVAL;
1594         }
1595
1596         for (i = 0; i < MAX_PIPES; i++) {
1597                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1598                         if (pipe_ctx && pipe_ctx->stream &&
1599                             pipe_ctx->stream->link == aconnector->dc_link)
1600                                 break;
1601         }
1602
1603         if (!pipe_ctx || !pipe_ctx->stream)
1604                 goto done;
1605
1606         if (param[0] > 0)
1607                 aconnector->dsc_settings.dsc_num_slices_v = DIV_ROUND_UP(
1608                                         pipe_ctx->stream->timing.v_addressable,
1609                                         param[0]);
1610         else
1611                 aconnector->dsc_settings.dsc_num_slices_v = 0;
1612
1613 done:
1614         kfree(wr_buf);
1615         return size;
1616 }
1617
1618 /* function: read DSC target rate on the connector in bits per pixel
1619  *
1620  * The read function: dp_dsc_bits_per_pixel_read
1621  * returns target rate of compression in bits per pixel
1622  * The return is an integer: 0 or other positive integer
1623  *
1624  * Access it with the following command:
1625  *
1626  *      cat /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
1627  *
1628  *  0 - means that DSC is disabled
1629  */
1630 static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
1631                                     size_t size, loff_t *pos)
1632 {
1633         char *rd_buf = NULL;
1634         char *rd_buf_ptr = NULL;
1635         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1636         struct display_stream_compressor *dsc;
1637         struct dcn_dsc_state dsc_state = {0};
1638         const uint32_t rd_buf_size = 100;
1639         struct pipe_ctx *pipe_ctx;
1640         ssize_t result = 0;
1641         int i, r, str_len = 30;
1642
1643         rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1644
1645         if (!rd_buf)
1646                 return -ENOMEM;
1647
1648         rd_buf_ptr = rd_buf;
1649
1650         for (i = 0; i < MAX_PIPES; i++) {
1651                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1652                         if (pipe_ctx && pipe_ctx->stream &&
1653                             pipe_ctx->stream->link == aconnector->dc_link)
1654                                 break;
1655         }
1656
1657         if (!pipe_ctx)
1658                 return -ENXIO;
1659
1660         dsc = pipe_ctx->stream_res.dsc;
1661         if (dsc)
1662                 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1663
1664         snprintf(rd_buf_ptr, str_len,
1665                 "%d\n",
1666                 dsc_state.dsc_bits_per_pixel);
1667         rd_buf_ptr += str_len;
1668
1669         while (size) {
1670                 if (*pos >= rd_buf_size)
1671                         break;
1672
1673                 r = put_user(*(rd_buf + result), buf);
1674                 if (r)
1675                         return r; /* r = -EFAULT */
1676
1677                 buf += 1;
1678                 size -= 1;
1679                 *pos += 1;
1680                 result += 1;
1681         }
1682
1683         kfree(rd_buf);
1684         return result;
1685 }
1686
1687 /* function: write DSC target rate in bits per pixel
1688  *
1689  * The write function: dp_dsc_bits_per_pixel_write
1690  * overwrites automatically generated DSC configuration
1691  * of DSC target bit rate.
1692  *
1693  * Also the user has to write bpp in hexidecimal
1694  * rather than in decimal.
1695  *
1696  * Writing DSC settings is done with the following command:
1697  * - To force overwrite rate (example sets to 256 bpp x 1/16):
1698  *
1699  *      echo 0x100 > /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
1700  *
1701  *  - To stop overwriting and let driver find the optimal rate,
1702  * set the rate to zero:
1703  *
1704  *      echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
1705  *
1706  */
1707 static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *buf,
1708                                      size_t size, loff_t *pos)
1709 {
1710         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1711         struct pipe_ctx *pipe_ctx;
1712         int i;
1713         char *wr_buf = NULL;
1714         uint32_t wr_buf_size = 42;
1715         int max_param_num = 1;
1716         uint8_t param_nums = 0;
1717         long param[1] = {0};
1718
1719         if (size == 0)
1720                 return -EINVAL;
1721
1722         wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1723
1724         if (!wr_buf) {
1725                 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1726                 return -ENOSPC;
1727         }
1728
1729         if (parse_write_buffer_into_params(wr_buf, size,
1730                                             (long *)param, buf,
1731                                             max_param_num,
1732                                             &param_nums)) {
1733                 kfree(wr_buf);
1734                 return -EINVAL;
1735         }
1736
1737         if (param_nums <= 0) {
1738                 DRM_DEBUG_DRIVER("user data not be read\n");
1739                 kfree(wr_buf);
1740                 return -EINVAL;
1741         }
1742
1743         for (i = 0; i < MAX_PIPES; i++) {
1744                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1745                         if (pipe_ctx && pipe_ctx->stream &&
1746                             pipe_ctx->stream->link == aconnector->dc_link)
1747                                 break;
1748         }
1749
1750         if (!pipe_ctx || !pipe_ctx->stream)
1751                 goto done;
1752
1753         aconnector->dsc_settings.dsc_bits_per_pixel = param[0];
1754
1755 done:
1756         kfree(wr_buf);
1757         return size;
1758 }
1759
1760 /* function: read DSC picture width parameter on the connector
1761  *
1762  * The read function: dp_dsc_pic_width_read
1763  * returns dsc picture width used in the current configuration
1764  * It is the same as h_addressable of the current
1765  * display's timing
1766  * The return is an integer: 0 or other positive integer
1767  * If 0 then DSC is disabled.
1768  *
1769  * Access it with the following command:
1770  *
1771  *      cat /sys/kernel/debug/dri/0/DP-X/dsc_pic_width
1772  *
1773  * 0 - means that DSC is disabled
1774  */
1775 static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
1776                                     size_t size, loff_t *pos)
1777 {
1778         char *rd_buf = NULL;
1779         char *rd_buf_ptr = NULL;
1780         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1781         struct display_stream_compressor *dsc;
1782         struct dcn_dsc_state dsc_state = {0};
1783         const uint32_t rd_buf_size = 100;
1784         struct pipe_ctx *pipe_ctx;
1785         ssize_t result = 0;
1786         int i, r, str_len = 30;
1787
1788         rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1789
1790         if (!rd_buf)
1791                 return -ENOMEM;
1792
1793         rd_buf_ptr = rd_buf;
1794
1795         for (i = 0; i < MAX_PIPES; i++) {
1796                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1797                         if (pipe_ctx && pipe_ctx->stream &&
1798                             pipe_ctx->stream->link == aconnector->dc_link)
1799                                 break;
1800         }
1801
1802         if (!pipe_ctx)
1803                 return -ENXIO;
1804
1805         dsc = pipe_ctx->stream_res.dsc;
1806         if (dsc)
1807                 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1808
1809         snprintf(rd_buf_ptr, str_len,
1810                 "%d\n",
1811                 dsc_state.dsc_pic_width);
1812         rd_buf_ptr += str_len;
1813
1814         while (size) {
1815                 if (*pos >= rd_buf_size)
1816                         break;
1817
1818                 r = put_user(*(rd_buf + result), buf);
1819                 if (r)
1820                         return r; /* r = -EFAULT */
1821
1822                 buf += 1;
1823                 size -= 1;
1824                 *pos += 1;
1825                 result += 1;
1826         }
1827
1828         kfree(rd_buf);
1829         return result;
1830 }
1831
1832 static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
1833                                     size_t size, loff_t *pos)
1834 {
1835         char *rd_buf = NULL;
1836         char *rd_buf_ptr = NULL;
1837         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1838         struct display_stream_compressor *dsc;
1839         struct dcn_dsc_state dsc_state = {0};
1840         const uint32_t rd_buf_size = 100;
1841         struct pipe_ctx *pipe_ctx;
1842         ssize_t result = 0;
1843         int i, r, str_len = 30;
1844
1845         rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1846
1847         if (!rd_buf)
1848                 return -ENOMEM;
1849
1850         rd_buf_ptr = rd_buf;
1851
1852         for (i = 0; i < MAX_PIPES; i++) {
1853                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1854                         if (pipe_ctx && pipe_ctx->stream &&
1855                             pipe_ctx->stream->link == aconnector->dc_link)
1856                                 break;
1857         }
1858
1859         if (!pipe_ctx)
1860                 return -ENXIO;
1861
1862         dsc = pipe_ctx->stream_res.dsc;
1863         if (dsc)
1864                 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1865
1866         snprintf(rd_buf_ptr, str_len,
1867                 "%d\n",
1868                 dsc_state.dsc_pic_height);
1869         rd_buf_ptr += str_len;
1870
1871         while (size) {
1872                 if (*pos >= rd_buf_size)
1873                         break;
1874
1875                 r = put_user(*(rd_buf + result), buf);
1876                 if (r)
1877                         return r; /* r = -EFAULT */
1878
1879                 buf += 1;
1880                 size -= 1;
1881                 *pos += 1;
1882                 result += 1;
1883         }
1884
1885         kfree(rd_buf);
1886         return result;
1887 }
1888
1889 /* function: read DSC chunk size parameter on the connector
1890  *
1891  * The read function: dp_dsc_chunk_size_read
1892  * returns dsc chunk size set in the current configuration
1893  * The value is calculated automatically by DSC code
1894  * and depends on slice parameters and bpp target rate
1895  * The return is an integer: 0 or other positive integer
1896  * If 0 then DSC is disabled.
1897  *
1898  * Access it with the following command:
1899  *
1900  *      cat /sys/kernel/debug/dri/0/DP-X/dsc_chunk_size
1901  *
1902  * 0 - means that DSC is disabled
1903  */
1904 static ssize_t dp_dsc_chunk_size_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                 return -ENXIO;
1933
1934         dsc = pipe_ctx->stream_res.dsc;
1935         if (dsc)
1936                 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1937
1938         snprintf(rd_buf_ptr, str_len,
1939                 "%d\n",
1940                 dsc_state.dsc_chunk_size);
1941         rd_buf_ptr += str_len;
1942
1943         while (size) {
1944                 if (*pos >= rd_buf_size)
1945                         break;
1946
1947                 r = put_user(*(rd_buf + result), buf);
1948                 if (r)
1949                         return r; /* r = -EFAULT */
1950
1951                 buf += 1;
1952                 size -= 1;
1953                 *pos += 1;
1954                 result += 1;
1955         }
1956
1957         kfree(rd_buf);
1958         return result;
1959 }
1960
1961 /* function: read DSC slice bpg offset on the connector
1962  *
1963  * The read function: dp_dsc_slice_bpg_offset_read
1964  * returns dsc bpg slice offset set in the current configuration
1965  * The value is calculated automatically by DSC code
1966  * and depends on slice parameters and bpp target rate
1967  * The return is an integer: 0 or other positive integer
1968  * If 0 then DSC is disabled.
1969  *
1970  * Access it with the following command:
1971  *
1972  *      cat /sys/kernel/debug/dri/0/DP-X/dsc_slice_bpg_offset
1973  *
1974  * 0 - means that DSC is disabled
1975  */
1976 static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
1977                                     size_t size, loff_t *pos)
1978 {
1979         char *rd_buf = NULL;
1980         char *rd_buf_ptr = NULL;
1981         struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1982         struct display_stream_compressor *dsc;
1983         struct dcn_dsc_state dsc_state = {0};
1984         const uint32_t rd_buf_size = 100;
1985         struct pipe_ctx *pipe_ctx;
1986         ssize_t result = 0;
1987         int i, r, str_len = 30;
1988
1989         rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1990
1991         if (!rd_buf)
1992                 return -ENOMEM;
1993
1994         rd_buf_ptr = rd_buf;
1995
1996         for (i = 0; i < MAX_PIPES; i++) {
1997                 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1998                         if (pipe_ctx && pipe_ctx->stream &&
1999                             pipe_ctx->stream->link == aconnector->dc_link)
2000                                 break;
2001         }
2002
2003         if (!pipe_ctx)
2004                 return -ENXIO;
2005
2006         dsc = pipe_ctx->stream_res.dsc;
2007         if (dsc)
2008                 dsc->funcs->dsc_read_state(dsc, &dsc_state);
2009
2010         snprintf(rd_buf_ptr, str_len,
2011                 "%d\n",
2012                 dsc_state.dsc_slice_bpg_offset);
2013         rd_buf_ptr += str_len;
2014
2015         while (size) {
2016                 if (*pos >= rd_buf_size)
2017                         break;
2018
2019                 r = put_user(*(rd_buf + result), buf);
2020                 if (r)
2021                         return r; /* r = -EFAULT */
2022
2023                 buf += 1;
2024                 size -= 1;
2025                 *pos += 1;
2026                 result += 1;
2027         }
2028
2029         kfree(rd_buf);
2030         return result;
2031 }
2032
2033 DEFINE_SHOW_ATTRIBUTE(dp_dsc_fec_support);
2034 DEFINE_SHOW_ATTRIBUTE(dmub_fw_state);
2035 DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer);
2036 DEFINE_SHOW_ATTRIBUTE(output_bpc);
2037 #ifdef CONFIG_DRM_AMD_DC_HDCP
2038 DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability);
2039 #endif
2040
2041 static const struct file_operations dp_dsc_clock_en_debugfs_fops = {
2042         .owner = THIS_MODULE,
2043         .read = dp_dsc_clock_en_read,
2044         .write = dp_dsc_clock_en_write,
2045         .llseek = default_llseek
2046 };
2047
2048 static const struct file_operations dp_dsc_slice_width_debugfs_fops = {
2049         .owner = THIS_MODULE,
2050         .read = dp_dsc_slice_width_read,
2051         .write = dp_dsc_slice_width_write,
2052         .llseek = default_llseek
2053 };
2054
2055 static const struct file_operations dp_dsc_slice_height_debugfs_fops = {
2056         .owner = THIS_MODULE,
2057         .read = dp_dsc_slice_height_read,
2058         .write = dp_dsc_slice_height_write,
2059         .llseek = default_llseek
2060 };
2061
2062 static const struct file_operations dp_dsc_bits_per_pixel_debugfs_fops = {
2063         .owner = THIS_MODULE,
2064         .read = dp_dsc_bits_per_pixel_read,
2065         .write = dp_dsc_bits_per_pixel_write,
2066         .llseek = default_llseek
2067 };
2068
2069 static const struct file_operations dp_dsc_pic_width_debugfs_fops = {
2070         .owner = THIS_MODULE,
2071         .read = dp_dsc_pic_width_read,
2072         .llseek = default_llseek
2073 };
2074
2075 static const struct file_operations dp_dsc_pic_height_debugfs_fops = {
2076         .owner = THIS_MODULE,
2077         .read = dp_dsc_pic_height_read,
2078         .llseek = default_llseek
2079 };
2080
2081 static const struct file_operations dp_dsc_chunk_size_debugfs_fops = {
2082         .owner = THIS_MODULE,
2083         .read = dp_dsc_chunk_size_read,
2084         .llseek = default_llseek
2085 };
2086
2087 static const struct file_operations dp_dsc_slice_bpg_offset_debugfs_fops = {
2088         .owner = THIS_MODULE,
2089         .read = dp_dsc_slice_bpg_offset_read,
2090         .llseek = default_llseek
2091 };
2092
2093 static const struct file_operations dp_trigger_hotplug_debugfs_fops = {
2094         .owner = THIS_MODULE,
2095         .write = dp_trigger_hotplug,
2096         .llseek = default_llseek
2097 };
2098
2099 static const struct file_operations dp_link_settings_debugfs_fops = {
2100         .owner = THIS_MODULE,
2101         .read = dp_link_settings_read,
2102         .write = dp_link_settings_write,
2103         .llseek = default_llseek
2104 };
2105
2106 static const struct file_operations dp_phy_settings_debugfs_fop = {
2107         .owner = THIS_MODULE,
2108         .read = dp_phy_settings_read,
2109         .write = dp_phy_settings_write,
2110         .llseek = default_llseek
2111 };
2112
2113 static const struct file_operations dp_phy_test_pattern_fops = {
2114         .owner = THIS_MODULE,
2115         .write = dp_phy_test_pattern_debugfs_write,
2116         .llseek = default_llseek
2117 };
2118
2119 static const struct file_operations sdp_message_fops = {
2120         .owner = THIS_MODULE,
2121         .write = dp_sdp_message_debugfs_write,
2122         .llseek = default_llseek
2123 };
2124
2125 static const struct file_operations dp_dpcd_address_debugfs_fops = {
2126         .owner = THIS_MODULE,
2127         .write = dp_dpcd_address_write,
2128         .llseek = default_llseek
2129 };
2130
2131 static const struct file_operations dp_dpcd_size_debugfs_fops = {
2132         .owner = THIS_MODULE,
2133         .write = dp_dpcd_size_write,
2134         .llseek = default_llseek
2135 };
2136
2137 static const struct file_operations dp_dpcd_data_debugfs_fops = {
2138         .owner = THIS_MODULE,
2139         .read = dp_dpcd_data_read,
2140         .write = dp_dpcd_data_write,
2141         .llseek = default_llseek
2142 };
2143
2144 static const struct {
2145         char *name;
2146         const struct file_operations *fops;
2147 } dp_debugfs_entries[] = {
2148                 {"link_settings", &dp_link_settings_debugfs_fops},
2149                 {"trigger_hotplug", &dp_trigger_hotplug_debugfs_fops},
2150                 {"phy_settings", &dp_phy_settings_debugfs_fop},
2151                 {"test_pattern", &dp_phy_test_pattern_fops},
2152 #ifdef CONFIG_DRM_AMD_DC_HDCP
2153                 {"hdcp_sink_capability", &hdcp_sink_capability_fops},
2154 #endif
2155                 {"sdp_message", &sdp_message_fops},
2156                 {"aux_dpcd_address", &dp_dpcd_address_debugfs_fops},
2157                 {"aux_dpcd_size", &dp_dpcd_size_debugfs_fops},
2158                 {"aux_dpcd_data", &dp_dpcd_data_debugfs_fops},
2159                 {"dsc_clock_en", &dp_dsc_clock_en_debugfs_fops},
2160                 {"dsc_slice_width", &dp_dsc_slice_width_debugfs_fops},
2161                 {"dsc_slice_height", &dp_dsc_slice_height_debugfs_fops},
2162                 {"dsc_bits_per_pixel", &dp_dsc_bits_per_pixel_debugfs_fops},
2163                 {"dsc_pic_width", &dp_dsc_pic_width_debugfs_fops},
2164                 {"dsc_pic_height", &dp_dsc_pic_height_debugfs_fops},
2165                 {"dsc_chunk_size", &dp_dsc_chunk_size_debugfs_fops},
2166                 {"dsc_slice_bpg", &dp_dsc_slice_bpg_offset_debugfs_fops},
2167                 {"dp_dsc_fec_support", &dp_dsc_fec_support_fops}
2168 };
2169
2170 #ifdef CONFIG_DRM_AMD_DC_HDCP
2171 static const struct {
2172         char *name;
2173         const struct file_operations *fops;
2174 } hdmi_debugfs_entries[] = {
2175                 {"hdcp_sink_capability", &hdcp_sink_capability_fops}
2176 };
2177 #endif
2178 /*
2179  * Force YUV420 output if available from the given mode
2180  */
2181 static int force_yuv420_output_set(void *data, u64 val)
2182 {
2183         struct amdgpu_dm_connector *connector = data;
2184
2185         connector->force_yuv420_output = (bool)val;
2186
2187         return 0;
2188 }
2189
2190 /*
2191  * Check if YUV420 is forced when available from the given mode
2192  */
2193 static int force_yuv420_output_get(void *data, u64 *val)
2194 {
2195         struct amdgpu_dm_connector *connector = data;
2196
2197         *val = connector->force_yuv420_output;
2198
2199         return 0;
2200 }
2201
2202 DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
2203                          force_yuv420_output_set, "%llu\n");
2204
2205 /*
2206  *  Read PSR state
2207  */
2208 static int psr_get(void *data, u64 *val)
2209 {
2210         struct amdgpu_dm_connector *connector = data;
2211         struct dc_link *link = connector->dc_link;
2212         uint32_t psr_state = 0;
2213
2214         dc_link_get_psr_state(link, &psr_state);
2215
2216         *val = psr_state;
2217
2218         return 0;
2219 }
2220
2221
2222 DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n");
2223
2224 void connector_debugfs_init(struct amdgpu_dm_connector *connector)
2225 {
2226         int i;
2227         struct dentry *dir = connector->base.debugfs_entry;
2228
2229         if (connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
2230             connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) {
2231                 for (i = 0; i < ARRAY_SIZE(dp_debugfs_entries); i++) {
2232                         debugfs_create_file(dp_debugfs_entries[i].name,
2233                                             0644, dir, connector,
2234                                             dp_debugfs_entries[i].fops);
2235                 }
2236         }
2237         if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
2238                 debugfs_create_file_unsafe("psr_state", 0444, dir, connector, &psr_fops);
2239
2240         debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector,
2241                                    &force_yuv420_output_fops);
2242
2243         debugfs_create_file("output_bpc", 0644, dir, connector,
2244                             &output_bpc_fops);
2245
2246         connector->debugfs_dpcd_address = 0;
2247         connector->debugfs_dpcd_size = 0;
2248
2249 #ifdef CONFIG_DRM_AMD_DC_HDCP
2250         if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) {
2251                 for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_entries); i++) {
2252                         debugfs_create_file(hdmi_debugfs_entries[i].name,
2253                                             0644, dir, connector,
2254                                             hdmi_debugfs_entries[i].fops);
2255                 }
2256         }
2257 #endif
2258 }
2259
2260 /*
2261  * Writes DTN log state to the user supplied buffer.
2262  * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log
2263  */
2264 static ssize_t dtn_log_read(
2265         struct file *f,
2266         char __user *buf,
2267         size_t size,
2268         loff_t *pos)
2269 {
2270         struct amdgpu_device *adev = file_inode(f)->i_private;
2271         struct dc *dc = adev->dm.dc;
2272         struct dc_log_buffer_ctx log_ctx = { 0 };
2273         ssize_t result = 0;
2274
2275         if (!buf || !size)
2276                 return -EINVAL;
2277
2278         if (!dc->hwss.log_hw_state)
2279                 return 0;
2280
2281         dc->hwss.log_hw_state(dc, &log_ctx);
2282
2283         if (*pos < log_ctx.pos) {
2284                 size_t to_copy = log_ctx.pos - *pos;
2285
2286                 to_copy = min(to_copy, size);
2287
2288                 if (!copy_to_user(buf, log_ctx.buf + *pos, to_copy)) {
2289                         *pos += to_copy;
2290                         result = to_copy;
2291                 }
2292         }
2293
2294         kfree(log_ctx.buf);
2295
2296         return result;
2297 }
2298
2299 /*
2300  * Writes DTN log state to dmesg when triggered via a write.
2301  * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log
2302  */
2303 static ssize_t dtn_log_write(
2304         struct file *f,
2305         const char __user *buf,
2306         size_t size,
2307         loff_t *pos)
2308 {
2309         struct amdgpu_device *adev = file_inode(f)->i_private;
2310         struct dc *dc = adev->dm.dc;
2311
2312         /* Write triggers log output via dmesg. */
2313         if (size == 0)
2314                 return 0;
2315
2316         if (dc->hwss.log_hw_state)
2317                 dc->hwss.log_hw_state(dc, NULL);
2318
2319         return size;
2320 }
2321
2322 /*
2323  * Backlight at this moment.  Read only.
2324  * As written to display, taking ABM and backlight lut into account.
2325  * Ranges from 0x0 to 0x10000 (= 100% PWM)
2326  */
2327 static int current_backlight_read(struct seq_file *m, void *data)
2328 {
2329         struct drm_info_node *node = (struct drm_info_node *)m->private;
2330         struct drm_device *dev = node->minor->dev;
2331         struct amdgpu_device *adev = drm_to_adev(dev);
2332         struct amdgpu_display_manager *dm = &adev->dm;
2333
2334         unsigned int backlight = dc_link_get_backlight_level(dm->backlight_link);
2335
2336         seq_printf(m, "0x%x\n", backlight);
2337         return 0;
2338 }
2339
2340 /*
2341  * Backlight value that is being approached.  Read only.
2342  * As written to display, taking ABM and backlight lut into account.
2343  * Ranges from 0x0 to 0x10000 (= 100% PWM)
2344  */
2345 static int target_backlight_read(struct seq_file *m, void *data)
2346 {
2347         struct drm_info_node *node = (struct drm_info_node *)m->private;
2348         struct drm_device *dev = node->minor->dev;
2349         struct amdgpu_device *adev = drm_to_adev(dev);
2350         struct amdgpu_display_manager *dm = &adev->dm;
2351
2352         unsigned int backlight = dc_link_get_target_backlight_pwm(dm->backlight_link);
2353
2354         seq_printf(m, "0x%x\n", backlight);
2355         return 0;
2356 }
2357
2358 static int mst_topo(struct seq_file *m, void *unused)
2359 {
2360         struct drm_info_node *node = (struct drm_info_node *)m->private;
2361         struct drm_device *dev = node->minor->dev;
2362         struct drm_connector *connector;
2363         struct drm_connector_list_iter conn_iter;
2364         struct amdgpu_dm_connector *aconnector;
2365
2366         drm_connector_list_iter_begin(dev, &conn_iter);
2367         drm_for_each_connector_iter(connector, &conn_iter) {
2368                 if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
2369                         continue;
2370
2371                 aconnector = to_amdgpu_dm_connector(connector);
2372
2373                 seq_printf(m, "\nMST topology for connector %d\n", aconnector->connector_id);
2374                 drm_dp_mst_dump_topology(m, &aconnector->mst_mgr);
2375         }
2376         drm_connector_list_iter_end(&conn_iter);
2377
2378         return 0;
2379 }
2380
2381 static const struct drm_info_list amdgpu_dm_debugfs_list[] = {
2382         {"amdgpu_current_backlight_pwm", &current_backlight_read},
2383         {"amdgpu_target_backlight_pwm", &target_backlight_read},
2384         {"amdgpu_mst_topology", &mst_topo},
2385 };
2386
2387 /*
2388  * Sets the force_timing_sync debug optino from the given string.
2389  * All connected displays will be force synchronized immediately.
2390  * Usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_force_timing_sync
2391  */
2392 static int force_timing_sync_set(void *data, u64 val)
2393 {
2394         struct amdgpu_device *adev = data;
2395
2396         adev->dm.force_timing_sync = (bool)val;
2397
2398         amdgpu_dm_trigger_timing_sync(adev_to_drm(adev));
2399
2400         return 0;
2401 }
2402
2403 /*
2404  * Gets the force_timing_sync debug option value into the given buffer.
2405  * Usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_force_timing_sync
2406  */
2407 static int force_timing_sync_get(void *data, u64 *val)
2408 {
2409         struct amdgpu_device *adev = data;
2410
2411         *val = adev->dm.force_timing_sync;
2412
2413         return 0;
2414 }
2415
2416 DEFINE_DEBUGFS_ATTRIBUTE(force_timing_sync_ops, force_timing_sync_get,
2417                          force_timing_sync_set, "%llu\n");
2418
2419 /*
2420  * Sets the DC visual confirm debug option from the given string.
2421  * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_visual_confirm
2422  */
2423 static int visual_confirm_set(void *data, u64 val)
2424 {
2425         struct amdgpu_device *adev = data;
2426
2427         adev->dm.dc->debug.visual_confirm = (enum visual_confirm)val;
2428
2429         return 0;
2430 }
2431
2432 /*
2433  * Reads the DC visual confirm debug option value into the given buffer.
2434  * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_visual_confirm
2435  */
2436 static int visual_confirm_get(void *data, u64 *val)
2437 {
2438         struct amdgpu_device *adev = data;
2439
2440         *val = adev->dm.dc->debug.visual_confirm;
2441
2442         return 0;
2443 }
2444
2445 DEFINE_DEBUGFS_ATTRIBUTE(visual_confirm_fops, visual_confirm_get,
2446                          visual_confirm_set, "%llu\n");
2447
2448 int dtn_debugfs_init(struct amdgpu_device *adev)
2449 {
2450         static const struct file_operations dtn_log_fops = {
2451                 .owner = THIS_MODULE,
2452                 .read = dtn_log_read,
2453                 .write = dtn_log_write,
2454                 .llseek = default_llseek
2455         };
2456
2457         struct drm_minor *minor = adev_to_drm(adev)->primary;
2458         struct dentry *root = minor->debugfs_root;
2459         int ret;
2460
2461         ret = amdgpu_debugfs_add_files(adev, amdgpu_dm_debugfs_list,
2462                                 ARRAY_SIZE(amdgpu_dm_debugfs_list));
2463         if (ret)
2464                 return ret;
2465
2466         debugfs_create_file("amdgpu_dm_dtn_log", 0644, root, adev,
2467                             &dtn_log_fops);
2468
2469         debugfs_create_file_unsafe("amdgpu_dm_visual_confirm", 0644, root, adev,
2470                                    &visual_confirm_fops);
2471
2472         debugfs_create_file_unsafe("amdgpu_dm_dmub_tracebuffer", 0644, root,
2473                                    adev, &dmub_tracebuffer_fops);
2474
2475         debugfs_create_file_unsafe("amdgpu_dm_dmub_fw_state", 0644, root,
2476                                    adev, &dmub_fw_state_fops);
2477
2478         debugfs_create_file_unsafe("amdgpu_dm_force_timing_sync", 0644, root,
2479                                    adev, &force_timing_sync_ops);
2480
2481         return 0;
2482 }
This page took 0.186545 seconds and 4 git commands to generate.