1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright 2018 Advanced Micro Devices, Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors: AMD
24 *
25 */
26
27 #include <linux/string_helpers.h>
28 #include <linux/uaccess.h>
29 #include <media/cec-notifier.h>
30
31 #include "dc.h"
32 #include "amdgpu.h"
33 #include "amdgpu_dm.h"
34 #include "amdgpu_dm_debugfs.h"
35 #include "amdgpu_dm_replay.h"
36 #include "dm_helpers.h"
37 #include "dmub/dmub_srv.h"
38 #include "resource.h"
39 #include "dsc.h"
40 #include "link_hwss.h"
41 #include "dc/dc_dmub_srv.h"
42 #include "link/protocols/link_dp_capability.h"
43 #include "inc/hw/dchubbub.h"
44
45 #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
46 #include "amdgpu_dm_psr.h"
47 #endif
48
49 struct dmub_debugfs_trace_header {
50 uint32_t entry_count;
51 uint32_t reserved[3];
52 };
53
54 struct dmub_debugfs_trace_entry {
55 uint32_t trace_code;
56 uint32_t tick_count;
57 uint32_t param0;
58 uint32_t param1;
59 };
60
61 static const char *const mst_progress_status[] = {
62 "probe",
63 "remote_edid",
64 "allocate_new_payload",
65 "clear_allocated_payload",
66 };
67
68 /* parse_write_buffer_into_params - Helper function to parse debugfs write buffer into an array
69 *
70 * Function takes in attributes passed to debugfs write entry
71 * and writes into param array.
72 * The user passes max_param_num to identify maximum number of
73 * parameters that could be parsed.
74 *
75 */
parse_write_buffer_into_params(char * wr_buf,uint32_t wr_buf_size,long * param,const char __user * buf,int max_param_num,uint8_t * param_nums)76 static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,
77 long *param, const char __user *buf,
78 int max_param_num,
79 uint8_t *param_nums)
80 {
81 char *wr_buf_ptr = NULL;
82 uint32_t wr_buf_count = 0;
83 int r;
84 char *sub_str = NULL;
85 const char delimiter[3] = {' ', '\n', '\0'};
86 uint8_t param_index = 0;
87
88 *param_nums = 0;
89
90 wr_buf_ptr = wr_buf;
91
92 /* r is bytes not be copied */
93 if (copy_from_user(wr_buf_ptr, buf, wr_buf_size)) {
94 DRM_DEBUG_DRIVER("user data could not be read successfully\n");
95 return -EFAULT;
96 }
97
98 /* check number of parameters. isspace could not differ space and \n */
99 while ((*wr_buf_ptr != 0xa) && (wr_buf_count < wr_buf_size)) {
100 /* skip space*/
101 while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) {
102 wr_buf_ptr++;
103 wr_buf_count++;
104 }
105
106 if (wr_buf_count == wr_buf_size)
107 break;
108
109 /* skip non-space*/
110 while ((!isspace(*wr_buf_ptr)) && (wr_buf_count < wr_buf_size)) {
111 wr_buf_ptr++;
112 wr_buf_count++;
113 }
114
115 (*param_nums)++;
116
117 if (wr_buf_count == wr_buf_size)
118 break;
119 }
120
121 if (*param_nums > max_param_num)
122 *param_nums = max_param_num;
123
124 wr_buf_ptr = wr_buf; /* reset buf pointer */
125 wr_buf_count = 0; /* number of char already checked */
126
127 while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) {
128 wr_buf_ptr++;
129 wr_buf_count++;
130 }
131
132 while (param_index < *param_nums) {
133 /* after strsep, wr_buf_ptr will be moved to after space */
134 sub_str = strsep(&wr_buf_ptr, delimiter);
135
136 r = kstrtol(sub_str, 16, &(param[param_index]));
137
138 if (r)
139 DRM_DEBUG_DRIVER("string to int convert error code: %d\n", r);
140
141 param_index++;
142 }
143
144 return 0;
145 }
146
147 /* function description
148 * get/ set DP configuration: lane_count, link_rate, spread_spectrum
149 *
150 * valid lane count value: 1, 2, 4
151 * valid link rate value:
152 * 06h = 1.62Gbps per lane
153 * 0Ah = 2.7Gbps per lane
154 * 0Ch = 3.24Gbps per lane
155 * 14h = 5.4Gbps per lane
156 * 1Eh = 8.1Gbps per lane
157 *
158 * debugfs is located at /sys/kernel/debug/dri/0/DP-x/link_settings
159 *
160 * --- to get dp configuration
161 *
162 * cat /sys/kernel/debug/dri/0/DP-x/link_settings
163 *
164 * It will list current, verified, reported, preferred dp configuration.
165 * current -- for current video mode
166 * verified --- maximum configuration which pass link training
167 * reported --- DP rx report caps (DPCD register offset 0, 1 2)
168 * preferred --- user force settings
169 *
170 * --- set (or force) dp configuration
171 *
172 * echo <lane_count> <link_rate> > link_settings
173 *
174 * for example, to force to 2 lane, 2.7GHz,
175 * echo 4 0xa > /sys/kernel/debug/dri/0/DP-x/link_settings
176 *
177 * spread_spectrum could not be changed dynamically.
178 *
179 * in case invalid lane count, link rate are force, no hw programming will be
180 * done. please check link settings after force operation to see if HW get
181 * programming.
182 *
183 * cat /sys/kernel/debug/dri/0/DP-x/link_settings
184 *
185 * check current and preferred settings.
186 *
187 */
dp_link_settings_read(struct file * f,char __user * buf,size_t size,loff_t * pos)188 static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
189 size_t size, loff_t *pos)
190 {
191 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
192 struct dc_link *link = connector->dc_link;
193 char *rd_buf = NULL;
194 char *rd_buf_ptr = NULL;
195 const uint32_t rd_buf_size = 100;
196 uint32_t result = 0;
197 uint8_t str_len = 0;
198 int r;
199
200 if (*pos & 3 || size & 3)
201 return -EINVAL;
202
203 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
204 if (!rd_buf)
205 return 0;
206
207 rd_buf_ptr = rd_buf;
208
209 str_len = strlen("Current: %d 0x%x %d ");
210 snprintf(rd_buf_ptr, str_len, "Current: %d 0x%x %d ",
211 link->cur_link_settings.lane_count,
212 link->cur_link_settings.link_rate,
213 link->cur_link_settings.link_spread);
214 rd_buf_ptr += str_len;
215
216 str_len = strlen("Verified: %d 0x%x %d ");
217 snprintf(rd_buf_ptr, str_len, "Verified: %d 0x%x %d ",
218 link->verified_link_cap.lane_count,
219 link->verified_link_cap.link_rate,
220 link->verified_link_cap.link_spread);
221 rd_buf_ptr += str_len;
222
223 str_len = strlen("Reported: %d 0x%x %d ");
224 snprintf(rd_buf_ptr, str_len, "Reported: %d 0x%x %d ",
225 link->reported_link_cap.lane_count,
226 link->reported_link_cap.link_rate,
227 link->reported_link_cap.link_spread);
228 rd_buf_ptr += str_len;
229
230 str_len = strlen("Preferred: %d 0x%x %d ");
231 snprintf(rd_buf_ptr, str_len, "Preferred: %d 0x%x %d\n",
232 link->preferred_link_setting.lane_count,
233 link->preferred_link_setting.link_rate,
234 link->preferred_link_setting.link_spread);
235
236 while (size) {
237 if (*pos >= rd_buf_size)
238 break;
239
240 r = put_user(*(rd_buf + result), buf);
241 if (r) {
242 kfree(rd_buf);
243 return r; /* r = -EFAULT */
244 }
245
246 buf += 1;
247 size -= 1;
248 *pos += 1;
249 result += 1;
250 }
251
252 kfree(rd_buf);
253 return result;
254 }
255
dp_link_settings_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)256 static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
257 size_t size, loff_t *pos)
258 {
259 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
260 struct dc_link *link = connector->dc_link;
261 struct amdgpu_device *adev = drm_to_adev(connector->base.dev);
262 struct dc *dc = (struct dc *)link->dc;
263 struct dc_link_settings prefer_link_settings = {0};
264 char *wr_buf = NULL;
265 const uint32_t wr_buf_size = 40;
266 /* 0: lane_count; 1: link_rate */
267 int max_param_num = 2;
268 uint8_t param_nums = 0;
269 long param[2];
270 bool valid_input = true;
271
272 if (size == 0)
273 return -EINVAL;
274
275 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
276 if (!wr_buf)
277 return -ENOSPC;
278
279 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
280 (long *)param, buf,
281 max_param_num,
282 ¶m_nums)) {
283 kfree(wr_buf);
284 return -EINVAL;
285 }
286
287 if (param_nums <= 0) {
288 kfree(wr_buf);
289 DRM_DEBUG_DRIVER("user data not be read\n");
290 return -EINVAL;
291 }
292
293 switch (param[0]) {
294 case LANE_COUNT_ONE:
295 case LANE_COUNT_TWO:
296 case LANE_COUNT_FOUR:
297 break;
298 default:
299 valid_input = false;
300 break;
301 }
302
303 switch (param[1]) {
304 case LINK_RATE_LOW:
305 case LINK_RATE_HIGH:
306 case LINK_RATE_RBR2:
307 case LINK_RATE_HIGH2:
308 case LINK_RATE_HIGH3:
309 case LINK_RATE_UHBR10:
310 case LINK_RATE_UHBR13_5:
311 case LINK_RATE_UHBR20:
312 break;
313 default:
314 valid_input = false;
315 break;
316 }
317
318 if (!valid_input) {
319 kfree(wr_buf);
320 DRM_DEBUG_DRIVER("Invalid Input value No HW will be programmed\n");
321 mutex_lock(&adev->dm.dc_lock);
322 dc_link_set_preferred_training_settings(dc, NULL, NULL, link, false);
323 mutex_unlock(&adev->dm.dc_lock);
324 return size;
325 }
326
327 /* save user force lane_count, link_rate to preferred settings
328 * spread spectrum will not be changed
329 */
330 prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
331 prefer_link_settings.use_link_rate_set = false;
332 prefer_link_settings.lane_count = param[0];
333 prefer_link_settings.link_rate = param[1];
334
335 mutex_lock(&adev->dm.dc_lock);
336 dc_link_set_preferred_training_settings(dc, &prefer_link_settings, NULL, link, false);
337 mutex_unlock(&adev->dm.dc_lock);
338
339 kfree(wr_buf);
340 return size;
341 }
342
dp_mst_is_end_device(struct amdgpu_dm_connector * aconnector)343 static bool dp_mst_is_end_device(struct amdgpu_dm_connector *aconnector)
344 {
345 bool is_end_device = false;
346 struct drm_dp_mst_topology_mgr *mgr = NULL;
347 struct drm_dp_mst_port *port = NULL;
348
349 if (aconnector->mst_root && aconnector->mst_root->mst_mgr.mst_state) {
350 mgr = &aconnector->mst_root->mst_mgr;
351 port = aconnector->mst_output_port;
352
353 drm_modeset_lock(&mgr->base.lock, NULL);
354 if (port->pdt == DP_PEER_DEVICE_SST_SINK ||
355 port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV)
356 is_end_device = true;
357 drm_modeset_unlock(&mgr->base.lock);
358 }
359
360 return is_end_device;
361 }
362
363 /* Change MST link setting
364 *
365 * valid lane count value: 1, 2, 4
366 * valid link rate value:
367 * 06h = 1.62Gbps per lane
368 * 0Ah = 2.7Gbps per lane
369 * 0Ch = 3.24Gbps per lane
370 * 14h = 5.4Gbps per lane
371 * 1Eh = 8.1Gbps per lane
372 * 3E8h = 10.0Gbps per lane
373 * 546h = 13.5Gbps per lane
374 * 7D0h = 20.0Gbps per lane
375 *
376 * debugfs is located at /sys/kernel/debug/dri/0/DP-x/mst_link_settings
377 *
378 * for example, to force to 2 lane, 10.0GHz,
379 * echo 2 0x3e8 > /sys/kernel/debug/dri/0/DP-x/mst_link_settings
380 *
381 * Valid input will trigger hotplug event to get new link setting applied
382 * Invalid input will trigger training setting reset
383 *
384 * The usage can be referred to link_settings entry
385 *
386 */
dp_mst_link_setting(struct file * f,const char __user * buf,size_t size,loff_t * pos)387 static ssize_t dp_mst_link_setting(struct file *f, const char __user *buf,
388 size_t size, loff_t *pos)
389 {
390 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
391 struct dc_link *link = aconnector->dc_link;
392 struct amdgpu_device *adev = drm_to_adev(aconnector->base.dev);
393 struct dc *dc = (struct dc *)link->dc;
394 struct dc_link_settings prefer_link_settings = {0};
395 char *wr_buf = NULL;
396 const uint32_t wr_buf_size = 40;
397 /* 0: lane_count; 1: link_rate */
398 int max_param_num = 2;
399 uint8_t param_nums = 0;
400 long param[2];
401 bool valid_input = true;
402
403 if (!dp_mst_is_end_device(aconnector))
404 return -EINVAL;
405
406 if (size == 0)
407 return -EINVAL;
408
409 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
410 if (!wr_buf)
411 return -ENOSPC;
412
413 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
414 (long *)param, buf,
415 max_param_num,
416 ¶m_nums)) {
417 kfree(wr_buf);
418 return -EINVAL;
419 }
420
421 if (param_nums <= 0) {
422 kfree(wr_buf);
423 DRM_DEBUG_DRIVER("user data not be read\n");
424 return -EINVAL;
425 }
426
427 switch (param[0]) {
428 case LANE_COUNT_ONE:
429 case LANE_COUNT_TWO:
430 case LANE_COUNT_FOUR:
431 break;
432 default:
433 valid_input = false;
434 break;
435 }
436
437 switch (param[1]) {
438 case LINK_RATE_LOW:
439 case LINK_RATE_HIGH:
440 case LINK_RATE_RBR2:
441 case LINK_RATE_HIGH2:
442 case LINK_RATE_HIGH3:
443 case LINK_RATE_UHBR10:
444 case LINK_RATE_UHBR13_5:
445 case LINK_RATE_UHBR20:
446 break;
447 default:
448 valid_input = false;
449 break;
450 }
451
452 if (!valid_input) {
453 kfree(wr_buf);
454 DRM_DEBUG_DRIVER("Invalid Input value No HW will be programmed\n");
455 mutex_lock(&adev->dm.dc_lock);
456 dc_link_set_preferred_training_settings(dc, NULL, NULL, link, false);
457 mutex_unlock(&adev->dm.dc_lock);
458 return -EINVAL;
459 }
460
461 /* save user force lane_count, link_rate to preferred settings
462 * spread spectrum will not be changed
463 */
464 prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
465 prefer_link_settings.use_link_rate_set = false;
466 prefer_link_settings.lane_count = param[0];
467 prefer_link_settings.link_rate = param[1];
468
469 /* skip immediate retrain, and train to new link setting after hotplug event triggered */
470 mutex_lock(&adev->dm.dc_lock);
471 dc_link_set_preferred_training_settings(dc, &prefer_link_settings, NULL, link, true);
472 mutex_unlock(&adev->dm.dc_lock);
473
474 mutex_lock(&aconnector->base.dev->mode_config.mutex);
475 aconnector->base.force = DRM_FORCE_OFF;
476 mutex_unlock(&aconnector->base.dev->mode_config.mutex);
477 drm_kms_helper_hotplug_event(aconnector->base.dev);
478
479 msleep(100);
480
481 mutex_lock(&aconnector->base.dev->mode_config.mutex);
482 aconnector->base.force = DRM_FORCE_UNSPECIFIED;
483 mutex_unlock(&aconnector->base.dev->mode_config.mutex);
484 drm_kms_helper_hotplug_event(aconnector->base.dev);
485
486 kfree(wr_buf);
487 return size;
488 }
489
490 /* function: get current DP PHY settings: voltage swing, pre-emphasis,
491 * post-cursor2 (defined by VESA DP specification)
492 *
493 * valid values
494 * voltage swing: 0,1,2,3
495 * pre-emphasis : 0,1,2,3
496 * post cursor2 : 0,1,2,3
497 *
498 *
499 * how to use this debugfs
500 *
501 * debugfs is located at /sys/kernel/debug/dri/0/DP-x
502 *
503 * there will be directories, like DP-1, DP-2,DP-3, etc. for DP display
504 *
505 * To figure out which DP-x is the display for DP to be check,
506 * cd DP-x
507 * ls -ll
508 * There should be debugfs file, like link_settings, phy_settings.
509 * cat link_settings
510 * from lane_count, link_rate to figure which DP-x is for display to be worked
511 * on
512 *
513 * To get current DP PHY settings,
514 * cat phy_settings
515 *
516 * To change DP PHY settings,
517 * echo <voltage_swing> <pre-emphasis> <post_cursor2> > phy_settings
518 * for examle, to change voltage swing to 2, pre-emphasis to 3, post_cursor2 to
519 * 0,
520 * echo 2 3 0 > phy_settings
521 *
522 * To check if change be applied, get current phy settings by
523 * cat phy_settings
524 *
525 * In case invalid values are set by user, like
526 * echo 1 4 0 > phy_settings
527 *
528 * HW will NOT be programmed by these settings.
529 * cat phy_settings will show the previous valid settings.
530 */
dp_phy_settings_read(struct file * f,char __user * buf,size_t size,loff_t * pos)531 static ssize_t dp_phy_settings_read(struct file *f, char __user *buf,
532 size_t size, loff_t *pos)
533 {
534 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
535 struct dc_link *link = connector->dc_link;
536 char *rd_buf = NULL;
537 const uint32_t rd_buf_size = 20;
538 uint32_t result = 0;
539 int r;
540
541 if (*pos & 3 || size & 3)
542 return -EINVAL;
543
544 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
545 if (!rd_buf)
546 return -EINVAL;
547
548 snprintf(rd_buf, rd_buf_size, " %d %d %d\n",
549 link->cur_lane_setting[0].VOLTAGE_SWING,
550 link->cur_lane_setting[0].PRE_EMPHASIS,
551 link->cur_lane_setting[0].POST_CURSOR2);
552
553 while (size) {
554 if (*pos >= rd_buf_size)
555 break;
556
557 r = put_user((*(rd_buf + result)), buf);
558 if (r) {
559 kfree(rd_buf);
560 return r; /* r = -EFAULT */
561 }
562
563 buf += 1;
564 size -= 1;
565 *pos += 1;
566 result += 1;
567 }
568
569 kfree(rd_buf);
570 return result;
571 }
572
dp_lttpr_status_show(struct seq_file * m,void * unused)573 static int dp_lttpr_status_show(struct seq_file *m, void *unused)
574 {
575 struct drm_connector *connector = m->private;
576 struct amdgpu_dm_connector *aconnector =
577 to_amdgpu_dm_connector(connector);
578 struct dc_lttpr_caps caps = aconnector->dc_link->dpcd_caps.lttpr_caps;
579
580 if (connector->status != connector_status_connected)
581 return -ENODEV;
582
583 seq_printf(m, "phy repeater count: %u (raw: 0x%x)\n",
584 dp_parse_lttpr_repeater_count(caps.phy_repeater_cnt),
585 caps.phy_repeater_cnt);
586
587 seq_puts(m, "phy repeater mode: ");
588
589 switch (caps.mode) {
590 case DP_PHY_REPEATER_MODE_TRANSPARENT:
591 seq_puts(m, "transparent");
592 break;
593 case DP_PHY_REPEATER_MODE_NON_TRANSPARENT:
594 seq_puts(m, "non-transparent");
595 break;
596 case 0x00:
597 seq_puts(m, "non lttpr");
598 break;
599 default:
600 seq_printf(m, "read error (raw: 0x%x)", caps.mode);
601 break;
602 }
603
604 seq_puts(m, "\n");
605 return 0;
606 }
607
dp_phy_settings_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)608 static ssize_t dp_phy_settings_write(struct file *f, const char __user *buf,
609 size_t size, loff_t *pos)
610 {
611 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
612 struct dc_link *link = connector->dc_link;
613 struct dc *dc = (struct dc *)link->dc;
614 char *wr_buf = NULL;
615 uint32_t wr_buf_size = 40;
616 long param[3];
617 bool use_prefer_link_setting;
618 struct link_training_settings link_lane_settings = {0};
619 int max_param_num = 3;
620 uint8_t param_nums = 0;
621 int r = 0;
622
623
624 if (size == 0)
625 return -EINVAL;
626
627 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
628 if (!wr_buf)
629 return -ENOSPC;
630
631 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
632 (long *)param, buf,
633 max_param_num,
634 ¶m_nums)) {
635 kfree(wr_buf);
636 return -EINVAL;
637 }
638
639 if (param_nums <= 0) {
640 kfree(wr_buf);
641 DRM_DEBUG_DRIVER("user data not be read\n");
642 return -EINVAL;
643 }
644
645 if ((param[0] > VOLTAGE_SWING_MAX_LEVEL) ||
646 (param[1] > PRE_EMPHASIS_MAX_LEVEL) ||
647 (param[2] > POST_CURSOR2_MAX_LEVEL)) {
648 kfree(wr_buf);
649 DRM_DEBUG_DRIVER("Invalid Input No HW will be programmed\n");
650 return size;
651 }
652
653 /* get link settings: lane count, link rate */
654 use_prefer_link_setting =
655 ((link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) &&
656 (link->test_pattern_enabled));
657
658 memset(&link_lane_settings, 0, sizeof(link_lane_settings));
659
660 if (use_prefer_link_setting) {
661 link_lane_settings.link_settings.lane_count =
662 link->preferred_link_setting.lane_count;
663 link_lane_settings.link_settings.link_rate =
664 link->preferred_link_setting.link_rate;
665 link_lane_settings.link_settings.link_spread =
666 link->preferred_link_setting.link_spread;
667 } else {
668 link_lane_settings.link_settings.lane_count =
669 link->cur_link_settings.lane_count;
670 link_lane_settings.link_settings.link_rate =
671 link->cur_link_settings.link_rate;
672 link_lane_settings.link_settings.link_spread =
673 link->cur_link_settings.link_spread;
674 }
675
676 /* apply phy settings from user */
677 for (r = 0; r < link_lane_settings.link_settings.lane_count; r++) {
678 link_lane_settings.hw_lane_settings[r].VOLTAGE_SWING =
679 (enum dc_voltage_swing) (param[0]);
680 link_lane_settings.hw_lane_settings[r].PRE_EMPHASIS =
681 (enum dc_pre_emphasis) (param[1]);
682 link_lane_settings.hw_lane_settings[r].POST_CURSOR2 =
683 (enum dc_post_cursor2) (param[2]);
684 }
685
686 /* program ASIC registers and DPCD registers */
687 dc_link_set_drive_settings(dc, &link_lane_settings, link);
688
689 kfree(wr_buf);
690 return size;
691 }
692
693 /* function description
694 *
695 * set PHY layer or Link layer test pattern
696 * PHY test pattern is used for PHY SI check.
697 * Link layer test will not affect PHY SI.
698 *
699 * Reset Test Pattern:
700 * 0 = DP_TEST_PATTERN_VIDEO_MODE
701 *
702 * PHY test pattern supported:
703 * 1 = DP_TEST_PATTERN_D102
704 * 2 = DP_TEST_PATTERN_SYMBOL_ERROR
705 * 3 = DP_TEST_PATTERN_PRBS7
706 * 4 = DP_TEST_PATTERN_80BIT_CUSTOM
707 * 5 = DP_TEST_PATTERN_CP2520_1
708 * 6 = DP_TEST_PATTERN_CP2520_2 = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE
709 * 7 = DP_TEST_PATTERN_CP2520_3
710 *
711 * DP PHY Link Training Patterns
712 * 8 = DP_TEST_PATTERN_TRAINING_PATTERN1
713 * 9 = DP_TEST_PATTERN_TRAINING_PATTERN2
714 * a = DP_TEST_PATTERN_TRAINING_PATTERN3
715 * b = DP_TEST_PATTERN_TRAINING_PATTERN4
716 *
717 * DP Link Layer Test pattern
718 * c = DP_TEST_PATTERN_COLOR_SQUARES
719 * d = DP_TEST_PATTERN_COLOR_SQUARES_CEA
720 * e = DP_TEST_PATTERN_VERTICAL_BARS
721 * f = DP_TEST_PATTERN_HORIZONTAL_BARS
722 * 10= DP_TEST_PATTERN_COLOR_RAMP
723 *
724 * debugfs phy_test_pattern is located at /syskernel/debug/dri/0/DP-x
725 *
726 * --- set test pattern
727 * echo <test pattern #> > test_pattern
728 *
729 * If test pattern # is not supported, NO HW programming will be done.
730 * for DP_TEST_PATTERN_80BIT_CUSTOM, it needs extra 10 bytes of data
731 * for the user pattern. input 10 bytes data are separated by space
732 *
733 * echo 0x4 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x99 0xaa > test_pattern
734 *
735 * --- reset test pattern
736 * echo 0 > test_pattern
737 *
738 * --- HPD detection is disabled when set PHY test pattern
739 *
740 * when PHY test pattern (pattern # within [1,7]) is set, HPD pin of HW ASIC
741 * is disable. User could unplug DP display from DP connected and plug scope to
742 * check test pattern PHY SI.
743 * If there is need unplug scope and plug DP display back, do steps below:
744 * echo 0 > phy_test_pattern
745 * unplug scope
746 * plug DP display.
747 *
748 * "echo 0 > phy_test_pattern" will re-enable HPD pin again so that video sw
749 * driver could detect "unplug scope" and "plug DP display"
750 */
dp_phy_test_pattern_debugfs_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)751 static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __user *buf,
752 size_t size, loff_t *pos)
753 {
754 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
755 struct dc_link *link = connector->dc_link;
756 char *wr_buf = NULL;
757 uint32_t wr_buf_size = 100;
758 long param[11] = {0x0};
759 int max_param_num = 11;
760 enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
761 bool disable_hpd = false;
762 bool valid_test_pattern = false;
763 uint8_t param_nums = 0;
764 /* init with default 80bit custom pattern */
765 uint8_t custom_pattern[10] = {
766 0x1f, 0x7c, 0xf0, 0xc1, 0x07,
767 0x1f, 0x7c, 0xf0, 0xc1, 0x07
768 };
769 struct dc_link_settings prefer_link_settings = {LANE_COUNT_UNKNOWN,
770 LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED};
771 struct dc_link_settings cur_link_settings = {LANE_COUNT_UNKNOWN,
772 LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED};
773 struct link_training_settings link_training_settings = {0};
774 int i;
775
776 if (size == 0)
777 return -EINVAL;
778
779 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
780 if (!wr_buf)
781 return -ENOSPC;
782
783 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
784 (long *)param, buf,
785 max_param_num,
786 ¶m_nums)) {
787 kfree(wr_buf);
788 return -EINVAL;
789 }
790
791 if (param_nums <= 0) {
792 kfree(wr_buf);
793 DRM_DEBUG_DRIVER("user data not be read\n");
794 return -EINVAL;
795 }
796
797
798 test_pattern = param[0];
799
800 switch (test_pattern) {
801 case DP_TEST_PATTERN_VIDEO_MODE:
802 case DP_TEST_PATTERN_COLOR_SQUARES:
803 case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
804 case DP_TEST_PATTERN_VERTICAL_BARS:
805 case DP_TEST_PATTERN_HORIZONTAL_BARS:
806 case DP_TEST_PATTERN_COLOR_RAMP:
807 valid_test_pattern = true;
808 break;
809
810 case DP_TEST_PATTERN_D102:
811 case DP_TEST_PATTERN_SYMBOL_ERROR:
812 case DP_TEST_PATTERN_PRBS7:
813 case DP_TEST_PATTERN_80BIT_CUSTOM:
814 case DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE:
815 case DP_TEST_PATTERN_TRAINING_PATTERN4:
816 disable_hpd = true;
817 valid_test_pattern = true;
818 break;
819
820 default:
821 valid_test_pattern = false;
822 test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
823 break;
824 }
825
826 if (!valid_test_pattern) {
827 kfree(wr_buf);
828 DRM_DEBUG_DRIVER("Invalid Test Pattern Parameters\n");
829 return size;
830 }
831
832 if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) {
833 for (i = 0; i < 10; i++) {
834 if ((uint8_t) param[i + 1] != 0x0)
835 break;
836 }
837
838 if (i < 10) {
839 /* not use default value */
840 for (i = 0; i < 10; i++)
841 custom_pattern[i] = (uint8_t) param[i + 1];
842 }
843 }
844
845 /* Usage: set DP physical test pattern using debugfs with normal DP
846 * panel. Then plug out DP panel and connect a scope to measure
847 * For normal video mode and test pattern generated from CRCT,
848 * they are visibile to user. So do not disable HPD.
849 * Video Mode is also set to clear the test pattern, so enable HPD
850 * because it might have been disabled after a test pattern was set.
851 * AUX depends on HPD * sequence dependent, do not move!
852 */
853 if (!disable_hpd)
854 dc_link_enable_hpd(link);
855
856 prefer_link_settings.lane_count = link->verified_link_cap.lane_count;
857 prefer_link_settings.link_rate = link->verified_link_cap.link_rate;
858 prefer_link_settings.link_spread = link->verified_link_cap.link_spread;
859
860 cur_link_settings.lane_count = link->cur_link_settings.lane_count;
861 cur_link_settings.link_rate = link->cur_link_settings.link_rate;
862 cur_link_settings.link_spread = link->cur_link_settings.link_spread;
863
864 link_training_settings.link_settings = cur_link_settings;
865
866
867 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
868 if (prefer_link_settings.lane_count != LANE_COUNT_UNKNOWN &&
869 prefer_link_settings.link_rate != LINK_RATE_UNKNOWN &&
870 (prefer_link_settings.lane_count != cur_link_settings.lane_count ||
871 prefer_link_settings.link_rate != cur_link_settings.link_rate))
872 link_training_settings.link_settings = prefer_link_settings;
873 }
874
875 for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++)
876 link_training_settings.hw_lane_settings[i] = link->cur_lane_setting[i];
877
878 dc_link_dp_set_test_pattern(
879 link,
880 test_pattern,
881 DP_TEST_PATTERN_COLOR_SPACE_RGB,
882 &link_training_settings,
883 custom_pattern,
884 10);
885
886 /* Usage: Set DP physical test pattern using AMDDP with normal DP panel
887 * Then plug out DP panel and connect a scope to measure DP PHY signal.
888 * Need disable interrupt to avoid SW driver disable DP output. This is
889 * done after the test pattern is set.
890 */
891 if (valid_test_pattern && disable_hpd)
892 dc_link_disable_hpd(link);
893
894 kfree(wr_buf);
895
896 return size;
897 }
898
899 /*
900 * Returns the DMCUB tracebuffer contents.
901 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dmub_tracebuffer
902 */
dmub_tracebuffer_show(struct seq_file * m,void * data)903 static int dmub_tracebuffer_show(struct seq_file *m, void *data)
904 {
905 struct amdgpu_device *adev = m->private;
906 struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
907 struct dmub_fw_meta_info *fw_meta_info = NULL;
908 struct dmub_debugfs_trace_entry *entries;
909 uint8_t *tbuf_base;
910 uint32_t tbuf_size, max_entries, num_entries, first_entry, i;
911
912 if (!fb_info)
913 return 0;
914
915 tbuf_base = (uint8_t *)fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].cpu_addr;
916 if (!tbuf_base)
917 return 0;
918
919 if (adev->dm.dmub_srv)
920 fw_meta_info = &adev->dm.dmub_srv->meta_info;
921
922 tbuf_size = fw_meta_info ? fw_meta_info->trace_buffer_size :
923 DMUB_TRACE_BUFFER_SIZE;
924 max_entries = (tbuf_size - sizeof(struct dmub_debugfs_trace_header)) /
925 sizeof(struct dmub_debugfs_trace_entry);
926
927 num_entries =
928 ((struct dmub_debugfs_trace_header *)tbuf_base)->entry_count;
929
930 /* DMCUB tracebuffer is a ring. If it rolled over, print a hint that
931 * entries are being overwritten.
932 */
933 if (num_entries > max_entries)
934 seq_printf(m, "...\n");
935
936 first_entry = num_entries % max_entries;
937 num_entries = min(num_entries, max_entries);
938
939 entries = (struct dmub_debugfs_trace_entry
940 *)(tbuf_base +
941 sizeof(struct dmub_debugfs_trace_header));
942
943 /* To print entries chronologically, start from the first entry till the
944 * top of buffer, then from base of buffer to first entry.
945 */
946 for (i = first_entry; i < num_entries; ++i) {
947 struct dmub_debugfs_trace_entry *entry = &entries[i];
948
949 seq_printf(m,
950 "trace_code=%u tick_count=%u param0=%u param1=%u\n",
951 entry->trace_code, entry->tick_count, entry->param0,
952 entry->param1);
953 }
954 for (i = 0; i < first_entry; ++i) {
955 struct dmub_debugfs_trace_entry *entry = &entries[i];
956
957 seq_printf(m,
958 "trace_code=%u tick_count=%u param0=%u param1=%u\n",
959 entry->trace_code, entry->tick_count, entry->param0,
960 entry->param1);
961 }
962
963 return 0;
964 }
965
966 /*
967 * Returns the DMCUB firmware state contents.
968 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dmub_fw_state
969 */
dmub_fw_state_show(struct seq_file * m,void * data)970 static int dmub_fw_state_show(struct seq_file *m, void *data)
971 {
972 struct amdgpu_device *adev = m->private;
973 struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
974 uint8_t *state_base;
975 uint32_t state_size;
976
977 if (!fb_info)
978 return 0;
979
980 state_base = (uint8_t *)fb_info->fb[DMUB_WINDOW_6_FW_STATE].cpu_addr;
981 if (!state_base)
982 return 0;
983
984 state_size = fb_info->fb[DMUB_WINDOW_6_FW_STATE].size;
985
986 return seq_write(m, state_base, state_size);
987 }
988
989 /* replay_capability_show() - show eDP panel replay capability
990 *
991 * The read function: replay_capability_show
992 * Shows if sink and driver has Replay capability or not.
993 *
994 * cat /sys/kernel/debug/dri/0/eDP-X/replay_capability
995 *
996 * Expected output:
997 * "Sink support: no\n" - if panel doesn't support Replay
998 * "Sink support: yes\n" - if panel supports Replay
999 * "Driver support: no\n" - if driver doesn't support Replay
1000 * "Driver support: yes\n" - if driver supports Replay
1001 */
replay_capability_show(struct seq_file * m,void * data)1002 static int replay_capability_show(struct seq_file *m, void *data)
1003 {
1004 struct drm_connector *connector = m->private;
1005 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
1006 struct dc_link *link = aconnector->dc_link;
1007 bool sink_support_replay = false;
1008 bool driver_support_replay = false;
1009
1010 if (!link)
1011 return -ENODEV;
1012
1013 if (link->type == dc_connection_none)
1014 return -ENODEV;
1015
1016 if (!(link->connector_signal & SIGNAL_TYPE_EDP))
1017 return -ENODEV;
1018
1019 /* If Replay is already set to support, skip the checks */
1020 if (link->replay_settings.config.replay_supported) {
1021 sink_support_replay = true;
1022 driver_support_replay = true;
1023 } else if ((amdgpu_dc_debug_mask & DC_DISABLE_REPLAY)) {
1024 sink_support_replay = amdgpu_dm_link_supports_replay(link, aconnector);
1025 } else {
1026 struct dc *dc = link->ctx->dc;
1027
1028 sink_support_replay = amdgpu_dm_link_supports_replay(link, aconnector);
1029 if (dc->ctx->dmub_srv && dc->ctx->dmub_srv->dmub)
1030 driver_support_replay =
1031 (bool)dc->ctx->dmub_srv->dmub->feature_caps.replay_supported;
1032 }
1033
1034 seq_printf(m, "Sink support: %s\n", str_yes_no(sink_support_replay));
1035 seq_printf(m, "Driver support: %s\n", str_yes_no(driver_support_replay));
1036 seq_printf(m, "Config support: %s\n", str_yes_no(link->replay_settings.config.replay_supported));
1037
1038 return 0;
1039 }
1040
1041 /* psr_capability_show() - show eDP panel PSR capability
1042 *
1043 * The read function: sink_psr_capability_show
1044 * Shows if sink has PSR capability or not.
1045 * If yes - the PSR version is appended
1046 *
1047 * cat /sys/kernel/debug/dri/0/eDP-X/psr_capability
1048 *
1049 * Expected output:
1050 * "Sink support: no\n" - if panel doesn't support PSR
1051 * "Sink support: yes [0x01]\n" - if panel supports PSR1
1052 * "Driver support: no\n" - if driver doesn't support PSR
1053 * "Driver support: yes [0x01]\n" - if driver supports PSR1
1054 */
psr_capability_show(struct seq_file * m,void * data)1055 static int psr_capability_show(struct seq_file *m, void *data)
1056 {
1057 struct drm_connector *connector = m->private;
1058 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
1059 struct dc_link *link = aconnector->dc_link;
1060
1061 if (!link)
1062 return -ENODEV;
1063
1064 if (link->type == dc_connection_none)
1065 return -ENODEV;
1066
1067 if (!(link->connector_signal & SIGNAL_TYPE_EDP))
1068 return -ENODEV;
1069
1070 seq_printf(m, "Sink support: %s", str_yes_no(link->dpcd_caps.psr_info.psr_version != 0));
1071 if (link->dpcd_caps.psr_info.psr_version)
1072 seq_printf(m, " [0x%02x]", link->dpcd_caps.psr_info.psr_version);
1073 seq_puts(m, "\n");
1074
1075 seq_printf(m, "Driver support: %s", str_yes_no(link->psr_settings.psr_feature_enabled));
1076 if (link->psr_settings.psr_version)
1077 seq_printf(m, " [0x%02x]", link->psr_settings.psr_version);
1078 seq_puts(m, "\n");
1079
1080 return 0;
1081 }
1082
1083 /*
1084 * Returns the current bpc for the crtc.
1085 * Example usage: cat /sys/kernel/debug/dri/0/crtc-0/amdgpu_current_bpc
1086 */
amdgpu_current_bpc_show(struct seq_file * m,void * data)1087 static int amdgpu_current_bpc_show(struct seq_file *m, void *data)
1088 {
1089 struct drm_crtc *crtc = m->private;
1090 struct drm_device *dev = crtc->dev;
1091 struct dm_crtc_state *dm_crtc_state = NULL;
1092 int res = -ENODEV;
1093 unsigned int bpc;
1094
1095 mutex_lock(&dev->mode_config.mutex);
1096 drm_modeset_lock(&crtc->mutex, NULL);
1097 if (crtc->state == NULL)
1098 goto unlock;
1099
1100 dm_crtc_state = to_dm_crtc_state(crtc->state);
1101 if (dm_crtc_state->stream == NULL)
1102 goto unlock;
1103
1104 switch (dm_crtc_state->stream->timing.display_color_depth) {
1105 case COLOR_DEPTH_666:
1106 bpc = 6;
1107 break;
1108 case COLOR_DEPTH_888:
1109 bpc = 8;
1110 break;
1111 case COLOR_DEPTH_101010:
1112 bpc = 10;
1113 break;
1114 case COLOR_DEPTH_121212:
1115 bpc = 12;
1116 break;
1117 case COLOR_DEPTH_161616:
1118 bpc = 16;
1119 break;
1120 default:
1121 goto unlock;
1122 }
1123
1124 seq_printf(m, "Current: %u\n", bpc);
1125 res = 0;
1126
1127 unlock:
1128 drm_modeset_unlock(&crtc->mutex);
1129 mutex_unlock(&dev->mode_config.mutex);
1130
1131 return res;
1132 }
1133 DEFINE_SHOW_ATTRIBUTE(amdgpu_current_bpc);
1134
1135 /*
1136 * Returns the current colorspace for the crtc.
1137 * Example usage: cat /sys/kernel/debug/dri/0/crtc-0/amdgpu_current_colorspace
1138 */
amdgpu_current_colorspace_show(struct seq_file * m,void * data)1139 static int amdgpu_current_colorspace_show(struct seq_file *m, void *data)
1140 {
1141 struct drm_crtc *crtc = m->private;
1142 struct drm_device *dev = crtc->dev;
1143 struct dm_crtc_state *dm_crtc_state = NULL;
1144 int res = -ENODEV;
1145
1146 mutex_lock(&dev->mode_config.mutex);
1147 drm_modeset_lock(&crtc->mutex, NULL);
1148 if (crtc->state == NULL)
1149 goto unlock;
1150
1151 dm_crtc_state = to_dm_crtc_state(crtc->state);
1152 if (dm_crtc_state->stream == NULL)
1153 goto unlock;
1154
1155 switch (dm_crtc_state->stream->output_color_space) {
1156 case COLOR_SPACE_SRGB:
1157 seq_puts(m, "sRGB");
1158 break;
1159 case COLOR_SPACE_YCBCR601:
1160 case COLOR_SPACE_YCBCR601_LIMITED:
1161 seq_puts(m, "BT601_YCC");
1162 break;
1163 case COLOR_SPACE_YCBCR709:
1164 case COLOR_SPACE_YCBCR709_LIMITED:
1165 seq_puts(m, "BT709_YCC");
1166 break;
1167 case COLOR_SPACE_ADOBERGB:
1168 seq_puts(m, "opRGB");
1169 break;
1170 case COLOR_SPACE_2020_RGB_FULLRANGE:
1171 seq_puts(m, "BT2020_RGB");
1172 break;
1173 case COLOR_SPACE_2020_YCBCR_LIMITED:
1174 seq_puts(m, "BT2020_YCC");
1175 break;
1176 default:
1177 goto unlock;
1178 }
1179 res = 0;
1180
1181 unlock:
1182 drm_modeset_unlock(&crtc->mutex);
1183 mutex_unlock(&dev->mode_config.mutex);
1184
1185 return res;
1186 }
1187 DEFINE_SHOW_ATTRIBUTE(amdgpu_current_colorspace);
1188
1189
1190 /*
1191 * Example usage:
1192 * Disable dsc passthrough, i.e.,: have dsc decoding at converver, not external RX
1193 * echo 1 /sys/kernel/debug/dri/0/DP-1/dsc_disable_passthrough
1194 * Enable dsc passthrough, i.e.,: have dsc passthrough to external RX
1195 * echo 0 /sys/kernel/debug/dri/0/DP-1/dsc_disable_passthrough
1196 */
dp_dsc_passthrough_set(struct file * f,const char __user * buf,size_t size,loff_t * pos)1197 static ssize_t dp_dsc_passthrough_set(struct file *f, const char __user *buf,
1198 size_t size, loff_t *pos)
1199 {
1200 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1201 char *wr_buf = NULL;
1202 uint32_t wr_buf_size = 42;
1203 int max_param_num = 1;
1204 long param;
1205 uint8_t param_nums = 0;
1206
1207 if (size == 0)
1208 return -EINVAL;
1209
1210 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1211
1212 if (!wr_buf) {
1213 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1214 return -ENOSPC;
1215 }
1216
1217 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
1218 ¶m, buf,
1219 max_param_num,
1220 ¶m_nums)) {
1221 kfree(wr_buf);
1222 return -EINVAL;
1223 }
1224
1225 aconnector->dsc_settings.dsc_force_disable_passthrough = param;
1226
1227 kfree(wr_buf);
1228 return 0;
1229 }
1230
1231 /*
1232 * Returns the HDCP capability of the Display (1.4 for now).
1233 *
1234 * NOTE* Not all HDMI displays report their HDCP caps even when they are capable.
1235 * Since its rare for a display to not be HDCP 1.4 capable, we set HDMI as always capable.
1236 *
1237 * Example usage: cat /sys/kernel/debug/dri/0/DP-1/hdcp_sink_capability
1238 * or cat /sys/kernel/debug/dri/0/HDMI-A-1/hdcp_sink_capability
1239 */
hdcp_sink_capability_show(struct seq_file * m,void * data)1240 static int hdcp_sink_capability_show(struct seq_file *m, void *data)
1241 {
1242 struct drm_connector *connector = m->private;
1243 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
1244 bool hdcp_cap, hdcp2_cap;
1245
1246 if (connector->status != connector_status_connected)
1247 return -ENODEV;
1248
1249 seq_printf(m, "%s:%d HDCP version: ", connector->name, connector->base.id);
1250
1251 hdcp_cap = dc_link_is_hdcp14(aconnector->dc_link, aconnector->dc_sink->sink_signal);
1252 hdcp2_cap = dc_link_is_hdcp22(aconnector->dc_link, aconnector->dc_sink->sink_signal);
1253
1254
1255 if (hdcp_cap)
1256 seq_printf(m, "%s ", "HDCP1.4");
1257 if (hdcp2_cap)
1258 seq_printf(m, "%s ", "HDCP2.2");
1259
1260 if (!hdcp_cap && !hdcp2_cap)
1261 seq_printf(m, "%s ", "None");
1262
1263 seq_puts(m, "\n");
1264
1265 return 0;
1266 }
1267
1268 /*
1269 * Returns whether the connected display is internal and not hotpluggable.
1270 * Example usage: cat /sys/kernel/debug/dri/0/DP-1/internal_display
1271 */
internal_display_show(struct seq_file * m,void * data)1272 static int internal_display_show(struct seq_file *m, void *data)
1273 {
1274 struct drm_connector *connector = m->private;
1275 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
1276 struct dc_link *link = aconnector->dc_link;
1277
1278 seq_printf(m, "Internal: %u\n", link->is_internal_display);
1279
1280 return 0;
1281 }
1282
1283 /*
1284 * Returns the number of segments used if ODM Combine mode is enabled.
1285 * Example usage: cat /sys/kernel/debug/dri/0/DP-1/odm_combine_segments
1286 */
odm_combine_segments_show(struct seq_file * m,void * unused)1287 static int odm_combine_segments_show(struct seq_file *m, void *unused)
1288 {
1289 struct drm_connector *connector = m->private;
1290 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
1291 struct dc_link *link = aconnector->dc_link;
1292 struct pipe_ctx *pipe_ctx = NULL;
1293 int i, segments = -EOPNOTSUPP;
1294
1295 for (i = 0; i < MAX_PIPES; i++) {
1296 pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
1297 if (pipe_ctx->stream &&
1298 pipe_ctx->stream->link == link)
1299 break;
1300 }
1301
1302 if (connector->status != connector_status_connected)
1303 return -ENODEV;
1304
1305 if (pipe_ctx && pipe_ctx->stream_res.tg &&
1306 pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments)
1307 pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments(pipe_ctx->stream_res.tg, &segments);
1308
1309 seq_printf(m, "%d\n", segments);
1310 return 0;
1311 }
1312
1313 /* function description
1314 *
1315 * generic SDP message access for testing
1316 *
1317 * debugfs sdp_message is located at /syskernel/debug/dri/0/DP-x
1318 *
1319 * SDP header
1320 * Hb0 : Secondary-Data Packet ID
1321 * Hb1 : Secondary-Data Packet type
1322 * Hb2 : Secondary-Data-packet-specific header, Byte 0
1323 * Hb3 : Secondary-Data-packet-specific header, Byte 1
1324 *
1325 * for using custom sdp message: input 4 bytes SDP header and 32 bytes raw data
1326 */
dp_sdp_message_debugfs_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)1327 static ssize_t dp_sdp_message_debugfs_write(struct file *f, const char __user *buf,
1328 size_t size, loff_t *pos)
1329 {
1330 int r;
1331 uint8_t data[36] = {0};
1332 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
1333 struct dm_crtc_state *acrtc_state;
1334 uint32_t write_size = 36;
1335
1336 if (connector->base.status != connector_status_connected)
1337 return -ENODEV;
1338
1339 if (size == 0)
1340 return 0;
1341
1342 acrtc_state = to_dm_crtc_state(connector->base.state->crtc->state);
1343
1344 r = copy_from_user(data, buf, write_size);
1345
1346 write_size -= r;
1347
1348 dc_stream_send_dp_sdp(acrtc_state->stream, data, write_size);
1349
1350 return write_size;
1351 }
1352
1353 /* function: Read link's DSC & FEC capabilities
1354 *
1355 *
1356 * Access it with the following command (you need to specify
1357 * connector like DP-1):
1358 *
1359 * cat /sys/kernel/debug/dri/0/DP-X/dp_dsc_fec_support
1360 *
1361 */
dp_dsc_fec_support_show(struct seq_file * m,void * data)1362 static int dp_dsc_fec_support_show(struct seq_file *m, void *data)
1363 {
1364 struct drm_connector *connector = m->private;
1365 struct drm_modeset_acquire_ctx ctx;
1366 struct drm_device *dev = connector->dev;
1367 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
1368 int ret = 0;
1369 bool try_again = false;
1370 bool is_fec_supported = false;
1371 bool is_dsc_supported = false;
1372 struct dpcd_caps dpcd_caps;
1373
1374 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
1375 do {
1376 try_again = false;
1377 ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx);
1378 if (ret) {
1379 if (ret == -EDEADLK) {
1380 ret = drm_modeset_backoff(&ctx);
1381 if (!ret) {
1382 try_again = true;
1383 continue;
1384 }
1385 }
1386 break;
1387 }
1388 if (connector->status != connector_status_connected) {
1389 ret = -ENODEV;
1390 break;
1391 }
1392 dpcd_caps = aconnector->dc_link->dpcd_caps;
1393 if (aconnector->mst_output_port) {
1394 /* aconnector sets dsc_aux during get_modes call
1395 * if MST connector has it means it can either
1396 * enable DSC on the sink device or on MST branch
1397 * its connected to.
1398 */
1399 if (aconnector->dsc_aux) {
1400 is_fec_supported = true;
1401 is_dsc_supported = true;
1402 }
1403 } else {
1404 is_fec_supported = dpcd_caps.fec_cap.raw & 0x1;
1405 is_dsc_supported = dpcd_caps.dsc_caps.dsc_basic_caps.raw[0] & 0x1;
1406 }
1407 } while (try_again);
1408
1409 drm_modeset_drop_locks(&ctx);
1410 drm_modeset_acquire_fini(&ctx);
1411
1412 seq_printf(m, "FEC_Sink_Support: %s\n", str_yes_no(is_fec_supported));
1413 seq_printf(m, "DSC_Sink_Support: %s\n", str_yes_no(is_dsc_supported));
1414
1415 return ret;
1416 }
1417
1418 /* function: Trigger virtual HPD redetection on connector
1419 *
1420 * This function will perform link rediscovery, link disable
1421 * and enable, and dm connector state update.
1422 *
1423 * Retrigger HPD on an existing connector by echoing 1 into
1424 * its respectful "trigger_hotplug" debugfs entry:
1425 *
1426 * echo 1 > /sys/kernel/debug/dri/0/DP-X/trigger_hotplug
1427 *
1428 * This function can perform HPD unplug:
1429 *
1430 * echo 0 > /sys/kernel/debug/dri/0/DP-X/trigger_hotplug
1431 *
1432 */
trigger_hotplug(struct file * f,const char __user * buf,size_t size,loff_t * pos)1433 static ssize_t trigger_hotplug(struct file *f, const char __user *buf,
1434 size_t size, loff_t *pos)
1435 {
1436 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1437 struct drm_connector *connector = &aconnector->base;
1438 struct dc_link *link = NULL;
1439 struct drm_device *dev = connector->dev;
1440 struct amdgpu_device *adev = drm_to_adev(dev);
1441 enum dc_connection_type new_connection_type = dc_connection_none;
1442 char *wr_buf = NULL;
1443 uint32_t wr_buf_size = 42;
1444 int max_param_num = 1;
1445 long param[1] = {0};
1446 uint8_t param_nums = 0;
1447 bool ret = false;
1448
1449 if (!aconnector->dc_link)
1450 return -EINVAL;
1451
1452 if (size == 0)
1453 return -EINVAL;
1454
1455 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1456
1457 if (!wr_buf) {
1458 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1459 return -ENOSPC;
1460 }
1461
1462 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
1463 (long *)param, buf,
1464 max_param_num,
1465 ¶m_nums)) {
1466 kfree(wr_buf);
1467 return -EINVAL;
1468 }
1469
1470 kfree(wr_buf);
1471
1472 if (param_nums <= 0) {
1473 DRM_DEBUG_DRIVER("user data not be read\n");
1474 return -EINVAL;
1475 }
1476
1477 mutex_lock(&aconnector->hpd_lock);
1478
1479 /* Don't support for mst end device*/
1480 if (aconnector->mst_root) {
1481 mutex_unlock(&aconnector->hpd_lock);
1482 return -EINVAL;
1483 }
1484
1485 if (param[0] == 1) {
1486
1487 if (!dc_link_detect_connection_type(aconnector->dc_link, &new_connection_type) &&
1488 new_connection_type != dc_connection_none)
1489 goto unlock;
1490
1491 mutex_lock(&adev->dm.dc_lock);
1492 ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
1493 mutex_unlock(&adev->dm.dc_lock);
1494
1495 if (!ret)
1496 goto unlock;
1497
1498 amdgpu_dm_update_connector_after_detect(aconnector);
1499
1500 drm_modeset_lock_all(dev);
1501 dm_restore_drm_connector_state(dev, connector);
1502 drm_modeset_unlock_all(dev);
1503
1504 drm_kms_helper_connector_hotplug_event(connector);
1505 } else if (param[0] == 0) {
1506 if (!aconnector->dc_link)
1507 goto unlock;
1508
1509 link = aconnector->dc_link;
1510
1511 if (link->local_sink) {
1512 dc_sink_release(link->local_sink);
1513 link->local_sink = NULL;
1514 }
1515
1516 link->dpcd_sink_count = 0;
1517 link->type = dc_connection_none;
1518 link->dongle_max_pix_clk = 0;
1519
1520 amdgpu_dm_update_connector_after_detect(aconnector);
1521
1522 /* If the aconnector is the root node in mst topology */
1523 if (aconnector->mst_mgr.mst_state == true)
1524 dc_link_reset_cur_dp_mst_topology(link);
1525
1526 drm_modeset_lock_all(dev);
1527 dm_restore_drm_connector_state(dev, connector);
1528 drm_modeset_unlock_all(dev);
1529
1530 drm_kms_helper_connector_hotplug_event(connector);
1531 }
1532
1533 unlock:
1534 mutex_unlock(&aconnector->hpd_lock);
1535
1536 return size;
1537 }
1538
1539 /* function: read DSC status on the connector
1540 *
1541 * The read function: dp_dsc_clock_en_read
1542 * returns current status of DSC clock on the connector.
1543 * The return is a boolean flag: 1 or 0.
1544 *
1545 * Access it with the following command (you need to specify
1546 * connector like DP-1):
1547 *
1548 * cat /sys/kernel/debug/dri/0/DP-X/dsc_clock_en
1549 *
1550 * Expected output:
1551 * 1 - means that DSC is currently enabled
1552 * 0 - means that DSC is disabled
1553 */
dp_dsc_clock_en_read(struct file * f,char __user * buf,size_t size,loff_t * pos)1554 static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
1555 size_t size, loff_t *pos)
1556 {
1557 char *rd_buf = NULL;
1558 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1559 struct display_stream_compressor *dsc;
1560 struct dcn_dsc_state dsc_state = {0};
1561 const uint32_t rd_buf_size = 10;
1562 struct pipe_ctx *pipe_ctx;
1563 ssize_t result = 0;
1564 int i, r, str_len = 10;
1565
1566 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1567
1568 if (!rd_buf)
1569 return -ENOMEM;
1570
1571 for (i = 0; i < MAX_PIPES; i++) {
1572 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1573 if (pipe_ctx->stream &&
1574 pipe_ctx->stream->link == aconnector->dc_link &&
1575 pipe_ctx->stream->sink &&
1576 pipe_ctx->stream->sink == aconnector->dc_sink)
1577 break;
1578 }
1579
1580 dsc = pipe_ctx->stream_res.dsc;
1581 if (dsc)
1582 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1583
1584 snprintf(rd_buf, str_len,
1585 "%d\n",
1586 dsc_state.dsc_clock_en);
1587
1588 while (size) {
1589 if (*pos >= rd_buf_size)
1590 break;
1591
1592 r = put_user(*(rd_buf + result), buf);
1593 if (r) {
1594 kfree(rd_buf);
1595 return r; /* r = -EFAULT */
1596 }
1597
1598 buf += 1;
1599 size -= 1;
1600 *pos += 1;
1601 result += 1;
1602 }
1603
1604 kfree(rd_buf);
1605 return result;
1606 }
1607
1608 /* function: write force DSC on the connector
1609 *
1610 * The write function: dp_dsc_clock_en_write
1611 * enables to force DSC on the connector.
1612 * User can write to either force enable or force disable DSC
1613 * on the next modeset or set it to driver default
1614 *
1615 * Accepted inputs:
1616 * 0 - default DSC enablement policy
1617 * 1 - force enable DSC on the connector
1618 * 2 - force disable DSC on the connector (might cause fail in atomic_check)
1619 *
1620 * Writing DSC settings is done with the following command:
1621 * - To force enable DSC (you need to specify
1622 * connector like DP-1):
1623 *
1624 * echo 0x1 > /sys/kernel/debug/dri/0/DP-X/dsc_clock_en
1625 *
1626 * - To return to default state set the flag to zero and
1627 * let driver deal with DSC automatically
1628 * (you need to specify connector like DP-1):
1629 *
1630 * echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_clock_en
1631 *
1632 */
dp_dsc_clock_en_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)1633 static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf,
1634 size_t size, loff_t *pos)
1635 {
1636 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1637 struct drm_connector *connector = &aconnector->base;
1638 struct drm_device *dev = connector->dev;
1639 struct drm_crtc *crtc = NULL;
1640 struct dm_crtc_state *dm_crtc_state = NULL;
1641 struct pipe_ctx *pipe_ctx;
1642 int i;
1643 char *wr_buf = NULL;
1644 uint32_t wr_buf_size = 42;
1645 int max_param_num = 1;
1646 long param[1] = {0};
1647 uint8_t param_nums = 0;
1648
1649 if (size == 0)
1650 return -EINVAL;
1651
1652 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1653
1654 if (!wr_buf) {
1655 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1656 return -ENOSPC;
1657 }
1658
1659 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
1660 (long *)param, buf,
1661 max_param_num,
1662 ¶m_nums)) {
1663 kfree(wr_buf);
1664 return -EINVAL;
1665 }
1666
1667 if (param_nums <= 0) {
1668 DRM_DEBUG_DRIVER("user data not be read\n");
1669 kfree(wr_buf);
1670 return -EINVAL;
1671 }
1672
1673 for (i = 0; i < MAX_PIPES; i++) {
1674 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1675 if (pipe_ctx->stream &&
1676 pipe_ctx->stream->link == aconnector->dc_link &&
1677 pipe_ctx->stream->sink &&
1678 pipe_ctx->stream->sink == aconnector->dc_sink)
1679 break;
1680 }
1681
1682 if (!pipe_ctx->stream)
1683 goto done;
1684
1685 // Get CRTC state
1686 mutex_lock(&dev->mode_config.mutex);
1687 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1688
1689 if (connector->state == NULL)
1690 goto unlock;
1691
1692 crtc = connector->state->crtc;
1693 if (crtc == NULL)
1694 goto unlock;
1695
1696 drm_modeset_lock(&crtc->mutex, NULL);
1697 if (crtc->state == NULL)
1698 goto unlock;
1699
1700 dm_crtc_state = to_dm_crtc_state(crtc->state);
1701 if (dm_crtc_state->stream == NULL)
1702 goto unlock;
1703
1704 if (param[0] == 1)
1705 aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_ENABLE;
1706 else if (param[0] == 2)
1707 aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_DISABLE;
1708 else
1709 aconnector->dsc_settings.dsc_force_enable = DSC_CLK_FORCE_DEFAULT;
1710
1711 dm_crtc_state->dsc_force_changed = true;
1712
1713 unlock:
1714 if (crtc)
1715 drm_modeset_unlock(&crtc->mutex);
1716 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1717 mutex_unlock(&dev->mode_config.mutex);
1718
1719 done:
1720 kfree(wr_buf);
1721 return size;
1722 }
1723
1724 /* function: read DSC slice width parameter on the connector
1725 *
1726 * The read function: dp_dsc_slice_width_read
1727 * returns dsc slice width used in the current configuration
1728 * The return is an integer: 0 or other positive number
1729 *
1730 * Access the status with the following command:
1731 *
1732 * cat /sys/kernel/debug/dri/0/DP-X/dsc_slice_width
1733 *
1734 * 0 - means that DSC is disabled
1735 *
1736 * Any other number more than zero represents the
1737 * slice width currently used by DSC in pixels
1738 *
1739 */
dp_dsc_slice_width_read(struct file * f,char __user * buf,size_t size,loff_t * pos)1740 static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
1741 size_t size, loff_t *pos)
1742 {
1743 char *rd_buf = NULL;
1744 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1745 struct display_stream_compressor *dsc;
1746 struct dcn_dsc_state dsc_state = {0};
1747 const uint32_t rd_buf_size = 100;
1748 struct pipe_ctx *pipe_ctx;
1749 ssize_t result = 0;
1750 int i, r, str_len = 30;
1751
1752 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1753
1754 if (!rd_buf)
1755 return -ENOMEM;
1756
1757 for (i = 0; i < MAX_PIPES; i++) {
1758 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1759 if (pipe_ctx->stream &&
1760 pipe_ctx->stream->link == aconnector->dc_link &&
1761 pipe_ctx->stream->sink &&
1762 pipe_ctx->stream->sink == aconnector->dc_sink)
1763 break;
1764 }
1765
1766 dsc = pipe_ctx->stream_res.dsc;
1767 if (dsc)
1768 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1769
1770 snprintf(rd_buf, str_len,
1771 "%d\n",
1772 dsc_state.dsc_slice_width);
1773
1774 while (size) {
1775 if (*pos >= rd_buf_size)
1776 break;
1777
1778 r = put_user(*(rd_buf + result), buf);
1779 if (r) {
1780 kfree(rd_buf);
1781 return r; /* r = -EFAULT */
1782 }
1783
1784 buf += 1;
1785 size -= 1;
1786 *pos += 1;
1787 result += 1;
1788 }
1789
1790 kfree(rd_buf);
1791 return result;
1792 }
1793
1794 /* function: write DSC slice width parameter
1795 *
1796 * The write function: dp_dsc_slice_width_write
1797 * overwrites automatically generated DSC configuration
1798 * of slice width.
1799 *
1800 * The user has to write the slice width divisible by the
1801 * picture width.
1802 *
1803 * Also the user has to write width in hexidecimal
1804 * rather than in decimal.
1805 *
1806 * Writing DSC settings is done with the following command:
1807 * - To force overwrite slice width: (example sets to 1920 pixels)
1808 *
1809 * echo 0x780 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_width
1810 *
1811 * - To stop overwriting and let driver find the optimal size,
1812 * set the width to zero:
1813 *
1814 * echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_width
1815 *
1816 */
dp_dsc_slice_width_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)1817 static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf,
1818 size_t size, loff_t *pos)
1819 {
1820 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1821 struct pipe_ctx *pipe_ctx;
1822 struct drm_connector *connector = &aconnector->base;
1823 struct drm_device *dev = connector->dev;
1824 struct drm_crtc *crtc = NULL;
1825 struct dm_crtc_state *dm_crtc_state = NULL;
1826 int i;
1827 char *wr_buf = NULL;
1828 uint32_t wr_buf_size = 42;
1829 int max_param_num = 1;
1830 long param[1] = {0};
1831 uint8_t param_nums = 0;
1832
1833 if (size == 0)
1834 return -EINVAL;
1835
1836 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
1837
1838 if (!wr_buf) {
1839 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
1840 return -ENOSPC;
1841 }
1842
1843 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
1844 (long *)param, buf,
1845 max_param_num,
1846 ¶m_nums)) {
1847 kfree(wr_buf);
1848 return -EINVAL;
1849 }
1850
1851 if (param_nums <= 0) {
1852 DRM_DEBUG_DRIVER("user data not be read\n");
1853 kfree(wr_buf);
1854 return -EINVAL;
1855 }
1856
1857 for (i = 0; i < MAX_PIPES; i++) {
1858 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1859 if (pipe_ctx->stream &&
1860 pipe_ctx->stream->link == aconnector->dc_link &&
1861 pipe_ctx->stream->sink &&
1862 pipe_ctx->stream->sink == aconnector->dc_sink)
1863 break;
1864 }
1865
1866 if (!pipe_ctx->stream)
1867 goto done;
1868
1869 // Safely get CRTC state
1870 mutex_lock(&dev->mode_config.mutex);
1871 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1872
1873 if (connector->state == NULL)
1874 goto unlock;
1875
1876 crtc = connector->state->crtc;
1877 if (crtc == NULL)
1878 goto unlock;
1879
1880 drm_modeset_lock(&crtc->mutex, NULL);
1881 if (crtc->state == NULL)
1882 goto unlock;
1883
1884 dm_crtc_state = to_dm_crtc_state(crtc->state);
1885 if (dm_crtc_state->stream == NULL)
1886 goto unlock;
1887
1888 if (param[0] > 0)
1889 aconnector->dsc_settings.dsc_num_slices_h = DIV_ROUND_UP(
1890 pipe_ctx->stream->timing.h_addressable,
1891 param[0]);
1892 else
1893 aconnector->dsc_settings.dsc_num_slices_h = 0;
1894
1895 dm_crtc_state->dsc_force_changed = true;
1896
1897 unlock:
1898 if (crtc)
1899 drm_modeset_unlock(&crtc->mutex);
1900 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1901 mutex_unlock(&dev->mode_config.mutex);
1902
1903 done:
1904 kfree(wr_buf);
1905 return size;
1906 }
1907
1908 /* function: read DSC slice height parameter on the connector
1909 *
1910 * The read function: dp_dsc_slice_height_read
1911 * returns dsc slice height used in the current configuration
1912 * The return is an integer: 0 or other positive number
1913 *
1914 * Access the status with the following command:
1915 *
1916 * cat /sys/kernel/debug/dri/0/DP-X/dsc_slice_height
1917 *
1918 * 0 - means that DSC is disabled
1919 *
1920 * Any other number more than zero represents the
1921 * slice height currently used by DSC in pixels
1922 *
1923 */
dp_dsc_slice_height_read(struct file * f,char __user * buf,size_t size,loff_t * pos)1924 static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
1925 size_t size, loff_t *pos)
1926 {
1927 char *rd_buf = NULL;
1928 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1929 struct display_stream_compressor *dsc;
1930 struct dcn_dsc_state dsc_state = {0};
1931 const uint32_t rd_buf_size = 100;
1932 struct pipe_ctx *pipe_ctx;
1933 ssize_t result = 0;
1934 int i, r, str_len = 30;
1935
1936 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1937
1938 if (!rd_buf)
1939 return -ENOMEM;
1940
1941 for (i = 0; i < MAX_PIPES; i++) {
1942 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1943 if (pipe_ctx->stream &&
1944 pipe_ctx->stream->link == aconnector->dc_link &&
1945 pipe_ctx->stream->sink &&
1946 pipe_ctx->stream->sink == aconnector->dc_sink)
1947 break;
1948 }
1949
1950 dsc = pipe_ctx->stream_res.dsc;
1951 if (dsc)
1952 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1953
1954 snprintf(rd_buf, str_len,
1955 "%d\n",
1956 dsc_state.dsc_slice_height);
1957
1958 while (size) {
1959 if (*pos >= rd_buf_size)
1960 break;
1961
1962 r = put_user(*(rd_buf + result), buf);
1963 if (r) {
1964 kfree(rd_buf);
1965 return r; /* r = -EFAULT */
1966 }
1967
1968 buf += 1;
1969 size -= 1;
1970 *pos += 1;
1971 result += 1;
1972 }
1973
1974 kfree(rd_buf);
1975 return result;
1976 }
1977
1978 /* function: write DSC slice height parameter
1979 *
1980 * The write function: dp_dsc_slice_height_write
1981 * overwrites automatically generated DSC configuration
1982 * of slice height.
1983 *
1984 * The user has to write the slice height divisible by the
1985 * picture height.
1986 *
1987 * Also the user has to write height in hexidecimal
1988 * rather than in decimal.
1989 *
1990 * Writing DSC settings is done with the following command:
1991 * - To force overwrite slice height (example sets to 128 pixels):
1992 *
1993 * echo 0x80 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_height
1994 *
1995 * - To stop overwriting and let driver find the optimal size,
1996 * set the height to zero:
1997 *
1998 * echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_slice_height
1999 *
2000 */
dp_dsc_slice_height_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)2001 static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf,
2002 size_t size, loff_t *pos)
2003 {
2004 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2005 struct drm_connector *connector = &aconnector->base;
2006 struct drm_device *dev = connector->dev;
2007 struct drm_crtc *crtc = NULL;
2008 struct dm_crtc_state *dm_crtc_state = NULL;
2009 struct pipe_ctx *pipe_ctx;
2010 int i;
2011 char *wr_buf = NULL;
2012 uint32_t wr_buf_size = 42;
2013 int max_param_num = 1;
2014 uint8_t param_nums = 0;
2015 long param[1] = {0};
2016
2017 if (size == 0)
2018 return -EINVAL;
2019
2020 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
2021
2022 if (!wr_buf) {
2023 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
2024 return -ENOSPC;
2025 }
2026
2027 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
2028 (long *)param, buf,
2029 max_param_num,
2030 ¶m_nums)) {
2031 kfree(wr_buf);
2032 return -EINVAL;
2033 }
2034
2035 if (param_nums <= 0) {
2036 DRM_DEBUG_DRIVER("user data not be read\n");
2037 kfree(wr_buf);
2038 return -EINVAL;
2039 }
2040
2041 for (i = 0; i < MAX_PIPES; i++) {
2042 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2043 if (pipe_ctx->stream &&
2044 pipe_ctx->stream->link == aconnector->dc_link &&
2045 pipe_ctx->stream->sink &&
2046 pipe_ctx->stream->sink == aconnector->dc_sink)
2047 break;
2048 }
2049
2050 if (!pipe_ctx->stream)
2051 goto done;
2052
2053 // Get CRTC state
2054 mutex_lock(&dev->mode_config.mutex);
2055 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2056
2057 if (connector->state == NULL)
2058 goto unlock;
2059
2060 crtc = connector->state->crtc;
2061 if (crtc == NULL)
2062 goto unlock;
2063
2064 drm_modeset_lock(&crtc->mutex, NULL);
2065 if (crtc->state == NULL)
2066 goto unlock;
2067
2068 dm_crtc_state = to_dm_crtc_state(crtc->state);
2069 if (dm_crtc_state->stream == NULL)
2070 goto unlock;
2071
2072 if (param[0] > 0)
2073 aconnector->dsc_settings.dsc_num_slices_v = DIV_ROUND_UP(
2074 pipe_ctx->stream->timing.v_addressable,
2075 param[0]);
2076 else
2077 aconnector->dsc_settings.dsc_num_slices_v = 0;
2078
2079 dm_crtc_state->dsc_force_changed = true;
2080
2081 unlock:
2082 if (crtc)
2083 drm_modeset_unlock(&crtc->mutex);
2084 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2085 mutex_unlock(&dev->mode_config.mutex);
2086
2087 done:
2088 kfree(wr_buf);
2089 return size;
2090 }
2091
2092 /* function: read DSC target rate on the connector in bits per pixel
2093 *
2094 * The read function: dp_dsc_bits_per_pixel_read
2095 * returns target rate of compression in bits per pixel
2096 * The return is an integer: 0 or other positive integer
2097 *
2098 * Access it with the following command:
2099 *
2100 * cat /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
2101 *
2102 * 0 - means that DSC is disabled
2103 */
dp_dsc_bits_per_pixel_read(struct file * f,char __user * buf,size_t size,loff_t * pos)2104 static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
2105 size_t size, loff_t *pos)
2106 {
2107 char *rd_buf = NULL;
2108 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2109 struct display_stream_compressor *dsc;
2110 struct dcn_dsc_state dsc_state = {0};
2111 const uint32_t rd_buf_size = 100;
2112 struct pipe_ctx *pipe_ctx;
2113 ssize_t result = 0;
2114 int i, r, str_len = 30;
2115
2116 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2117
2118 if (!rd_buf)
2119 return -ENOMEM;
2120
2121 for (i = 0; i < MAX_PIPES; i++) {
2122 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2123 if (pipe_ctx->stream &&
2124 pipe_ctx->stream->link == aconnector->dc_link &&
2125 pipe_ctx->stream->sink &&
2126 pipe_ctx->stream->sink == aconnector->dc_sink)
2127 break;
2128 }
2129
2130 dsc = pipe_ctx->stream_res.dsc;
2131 if (dsc)
2132 dsc->funcs->dsc_read_state(dsc, &dsc_state);
2133
2134 snprintf(rd_buf, str_len,
2135 "%d\n",
2136 dsc_state.dsc_bits_per_pixel);
2137
2138 while (size) {
2139 if (*pos >= rd_buf_size)
2140 break;
2141
2142 r = put_user(*(rd_buf + result), buf);
2143 if (r) {
2144 kfree(rd_buf);
2145 return r; /* r = -EFAULT */
2146 }
2147
2148 buf += 1;
2149 size -= 1;
2150 *pos += 1;
2151 result += 1;
2152 }
2153
2154 kfree(rd_buf);
2155 return result;
2156 }
2157
2158 /* function: write DSC target rate in bits per pixel
2159 *
2160 * The write function: dp_dsc_bits_per_pixel_write
2161 * overwrites automatically generated DSC configuration
2162 * of DSC target bit rate.
2163 *
2164 * Also the user has to write bpp in hexidecimal
2165 * rather than in decimal.
2166 *
2167 * Writing DSC settings is done with the following command:
2168 * - To force overwrite rate (example sets to 256 bpp x 1/16):
2169 *
2170 * echo 0x100 > /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
2171 *
2172 * - To stop overwriting and let driver find the optimal rate,
2173 * set the rate to zero:
2174 *
2175 * echo 0x0 > /sys/kernel/debug/dri/0/DP-X/dsc_bits_per_pixel
2176 *
2177 */
dp_dsc_bits_per_pixel_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)2178 static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *buf,
2179 size_t size, loff_t *pos)
2180 {
2181 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2182 struct drm_connector *connector = &aconnector->base;
2183 struct drm_device *dev = connector->dev;
2184 struct drm_crtc *crtc = NULL;
2185 struct dm_crtc_state *dm_crtc_state = NULL;
2186 struct pipe_ctx *pipe_ctx;
2187 int i;
2188 char *wr_buf = NULL;
2189 uint32_t wr_buf_size = 42;
2190 int max_param_num = 1;
2191 uint8_t param_nums = 0;
2192 long param[1] = {0};
2193
2194 if (size == 0)
2195 return -EINVAL;
2196
2197 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
2198
2199 if (!wr_buf) {
2200 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
2201 return -ENOSPC;
2202 }
2203
2204 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
2205 (long *)param, buf,
2206 max_param_num,
2207 ¶m_nums)) {
2208 kfree(wr_buf);
2209 return -EINVAL;
2210 }
2211
2212 if (param_nums <= 0) {
2213 DRM_DEBUG_DRIVER("user data not be read\n");
2214 kfree(wr_buf);
2215 return -EINVAL;
2216 }
2217
2218 for (i = 0; i < MAX_PIPES; i++) {
2219 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2220 if (pipe_ctx->stream &&
2221 pipe_ctx->stream->link == aconnector->dc_link &&
2222 pipe_ctx->stream->sink &&
2223 pipe_ctx->stream->sink == aconnector->dc_sink)
2224 break;
2225 }
2226
2227 if (!pipe_ctx->stream)
2228 goto done;
2229
2230 // Get CRTC state
2231 mutex_lock(&dev->mode_config.mutex);
2232 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2233
2234 if (connector->state == NULL)
2235 goto unlock;
2236
2237 crtc = connector->state->crtc;
2238 if (crtc == NULL)
2239 goto unlock;
2240
2241 drm_modeset_lock(&crtc->mutex, NULL);
2242 if (crtc->state == NULL)
2243 goto unlock;
2244
2245 dm_crtc_state = to_dm_crtc_state(crtc->state);
2246 if (dm_crtc_state->stream == NULL)
2247 goto unlock;
2248
2249 aconnector->dsc_settings.dsc_bits_per_pixel = param[0];
2250
2251 dm_crtc_state->dsc_force_changed = true;
2252
2253 unlock:
2254 if (crtc)
2255 drm_modeset_unlock(&crtc->mutex);
2256 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2257 mutex_unlock(&dev->mode_config.mutex);
2258
2259 done:
2260 kfree(wr_buf);
2261 return size;
2262 }
2263
2264 /* function: read DSC picture width parameter on the connector
2265 *
2266 * The read function: dp_dsc_pic_width_read
2267 * returns dsc picture width used in the current configuration
2268 * It is the same as h_addressable of the current
2269 * display's timing
2270 * The return is an integer: 0 or other positive integer
2271 * If 0 then DSC is disabled.
2272 *
2273 * Access it with the following command:
2274 *
2275 * cat /sys/kernel/debug/dri/0/DP-X/dsc_pic_width
2276 *
2277 * 0 - means that DSC is disabled
2278 */
dp_dsc_pic_width_read(struct file * f,char __user * buf,size_t size,loff_t * pos)2279 static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
2280 size_t size, loff_t *pos)
2281 {
2282 char *rd_buf = NULL;
2283 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2284 struct display_stream_compressor *dsc;
2285 struct dcn_dsc_state dsc_state = {0};
2286 const uint32_t rd_buf_size = 100;
2287 struct pipe_ctx *pipe_ctx;
2288 ssize_t result = 0;
2289 int i, r, str_len = 30;
2290
2291 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2292
2293 if (!rd_buf)
2294 return -ENOMEM;
2295
2296 for (i = 0; i < MAX_PIPES; i++) {
2297 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2298 if (pipe_ctx->stream &&
2299 pipe_ctx->stream->link == aconnector->dc_link &&
2300 pipe_ctx->stream->sink &&
2301 pipe_ctx->stream->sink == aconnector->dc_sink)
2302 break;
2303 }
2304
2305 dsc = pipe_ctx->stream_res.dsc;
2306 if (dsc)
2307 dsc->funcs->dsc_read_state(dsc, &dsc_state);
2308
2309 snprintf(rd_buf, str_len,
2310 "%d\n",
2311 dsc_state.dsc_pic_width);
2312
2313 while (size) {
2314 if (*pos >= rd_buf_size)
2315 break;
2316
2317 r = put_user(*(rd_buf + result), buf);
2318 if (r) {
2319 kfree(rd_buf);
2320 return r; /* r = -EFAULT */
2321 }
2322
2323 buf += 1;
2324 size -= 1;
2325 *pos += 1;
2326 result += 1;
2327 }
2328
2329 kfree(rd_buf);
2330 return result;
2331 }
2332
dp_dsc_pic_height_read(struct file * f,char __user * buf,size_t size,loff_t * pos)2333 static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
2334 size_t size, loff_t *pos)
2335 {
2336 char *rd_buf = NULL;
2337 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2338 struct display_stream_compressor *dsc;
2339 struct dcn_dsc_state dsc_state = {0};
2340 const uint32_t rd_buf_size = 100;
2341 struct pipe_ctx *pipe_ctx;
2342 ssize_t result = 0;
2343 int i, r, str_len = 30;
2344
2345 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2346
2347 if (!rd_buf)
2348 return -ENOMEM;
2349
2350 for (i = 0; i < MAX_PIPES; i++) {
2351 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2352 if (pipe_ctx->stream &&
2353 pipe_ctx->stream->link == aconnector->dc_link &&
2354 pipe_ctx->stream->sink &&
2355 pipe_ctx->stream->sink == aconnector->dc_sink)
2356 break;
2357 }
2358
2359 dsc = pipe_ctx->stream_res.dsc;
2360 if (dsc)
2361 dsc->funcs->dsc_read_state(dsc, &dsc_state);
2362
2363 snprintf(rd_buf, str_len,
2364 "%d\n",
2365 dsc_state.dsc_pic_height);
2366
2367 while (size) {
2368 if (*pos >= rd_buf_size)
2369 break;
2370
2371 r = put_user(*(rd_buf + result), buf);
2372 if (r) {
2373 kfree(rd_buf);
2374 return r; /* r = -EFAULT */
2375 }
2376
2377 buf += 1;
2378 size -= 1;
2379 *pos += 1;
2380 result += 1;
2381 }
2382
2383 kfree(rd_buf);
2384 return result;
2385 }
2386
2387 /* function: read DSC chunk size parameter on the connector
2388 *
2389 * The read function: dp_dsc_chunk_size_read
2390 * returns dsc chunk size set in the current configuration
2391 * The value is calculated automatically by DSC code
2392 * and depends on slice parameters and bpp target rate
2393 * The return is an integer: 0 or other positive integer
2394 * If 0 then DSC is disabled.
2395 *
2396 * Access it with the following command:
2397 *
2398 * cat /sys/kernel/debug/dri/0/DP-X/dsc_chunk_size
2399 *
2400 * 0 - means that DSC is disabled
2401 */
dp_dsc_chunk_size_read(struct file * f,char __user * buf,size_t size,loff_t * pos)2402 static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
2403 size_t size, loff_t *pos)
2404 {
2405 char *rd_buf = NULL;
2406 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2407 struct display_stream_compressor *dsc;
2408 struct dcn_dsc_state dsc_state = {0};
2409 const uint32_t rd_buf_size = 100;
2410 struct pipe_ctx *pipe_ctx;
2411 ssize_t result = 0;
2412 int i, r, str_len = 30;
2413
2414 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2415
2416 if (!rd_buf)
2417 return -ENOMEM;
2418
2419 for (i = 0; i < MAX_PIPES; i++) {
2420 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2421 if (pipe_ctx->stream &&
2422 pipe_ctx->stream->link == aconnector->dc_link &&
2423 pipe_ctx->stream->sink &&
2424 pipe_ctx->stream->sink == aconnector->dc_sink)
2425 break;
2426 }
2427
2428 dsc = pipe_ctx->stream_res.dsc;
2429 if (dsc)
2430 dsc->funcs->dsc_read_state(dsc, &dsc_state);
2431
2432 snprintf(rd_buf, str_len,
2433 "%d\n",
2434 dsc_state.dsc_chunk_size);
2435
2436 while (size) {
2437 if (*pos >= rd_buf_size)
2438 break;
2439
2440 r = put_user(*(rd_buf + result), buf);
2441 if (r) {
2442 kfree(rd_buf);
2443 return r; /* r = -EFAULT */
2444 }
2445
2446 buf += 1;
2447 size -= 1;
2448 *pos += 1;
2449 result += 1;
2450 }
2451
2452 kfree(rd_buf);
2453 return result;
2454 }
2455
2456 /* function: read DSC slice bpg offset on the connector
2457 *
2458 * The read function: dp_dsc_slice_bpg_offset_read
2459 * returns dsc bpg slice offset set in the current configuration
2460 * The value is calculated automatically by DSC code
2461 * and depends on slice parameters and bpp target rate
2462 * The return is an integer: 0 or other positive integer
2463 * If 0 then DSC is disabled.
2464 *
2465 * Access it with the following command:
2466 *
2467 * cat /sys/kernel/debug/dri/0/DP-X/dsc_slice_bpg_offset
2468 *
2469 * 0 - means that DSC is disabled
2470 */
dp_dsc_slice_bpg_offset_read(struct file * f,char __user * buf,size_t size,loff_t * pos)2471 static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
2472 size_t size, loff_t *pos)
2473 {
2474 char *rd_buf = NULL;
2475 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2476 struct display_stream_compressor *dsc;
2477 struct dcn_dsc_state dsc_state = {0};
2478 const uint32_t rd_buf_size = 100;
2479 struct pipe_ctx *pipe_ctx;
2480 ssize_t result = 0;
2481 int i, r, str_len = 30;
2482
2483 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2484
2485 if (!rd_buf)
2486 return -ENOMEM;
2487
2488 for (i = 0; i < MAX_PIPES; i++) {
2489 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
2490 if (pipe_ctx->stream &&
2491 pipe_ctx->stream->link == aconnector->dc_link &&
2492 pipe_ctx->stream->sink &&
2493 pipe_ctx->stream->sink == aconnector->dc_sink)
2494 break;
2495 }
2496
2497 dsc = pipe_ctx->stream_res.dsc;
2498 if (dsc)
2499 dsc->funcs->dsc_read_state(dsc, &dsc_state);
2500
2501 snprintf(rd_buf, str_len,
2502 "%d\n",
2503 dsc_state.dsc_slice_bpg_offset);
2504
2505 while (size) {
2506 if (*pos >= rd_buf_size)
2507 break;
2508
2509 r = put_user(*(rd_buf + result), buf);
2510 if (r) {
2511 kfree(rd_buf);
2512 return r; /* r = -EFAULT */
2513 }
2514
2515 buf += 1;
2516 size -= 1;
2517 *pos += 1;
2518 result += 1;
2519 }
2520
2521 kfree(rd_buf);
2522 return result;
2523 }
2524
2525
2526 /*
2527 * function description: Read max_requested_bpc property from the connector
2528 *
2529 * Access it with the following command:
2530 *
2531 * cat /sys/kernel/debug/dri/0/DP-X/max_bpc
2532 *
2533 */
dp_max_bpc_read(struct file * f,char __user * buf,size_t size,loff_t * pos)2534 static ssize_t dp_max_bpc_read(struct file *f, char __user *buf,
2535 size_t size, loff_t *pos)
2536 {
2537 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2538 struct drm_connector *connector = &aconnector->base;
2539 struct drm_device *dev = connector->dev;
2540 struct dm_connector_state *state;
2541 ssize_t result = 0;
2542 char *rd_buf = NULL;
2543 char *rd_buf_ptr = NULL;
2544 const uint32_t rd_buf_size = 10;
2545 int r;
2546
2547 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
2548
2549 if (!rd_buf)
2550 return -ENOMEM;
2551
2552 mutex_lock(&dev->mode_config.mutex);
2553 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2554
2555 if (connector->state == NULL)
2556 goto unlock;
2557
2558 state = to_dm_connector_state(connector->state);
2559
2560 rd_buf_ptr = rd_buf;
2561 snprintf(rd_buf_ptr, rd_buf_size,
2562 "%u\n",
2563 state->base.max_requested_bpc);
2564
2565 while (size) {
2566 if (*pos >= rd_buf_size)
2567 break;
2568
2569 r = put_user(*(rd_buf + result), buf);
2570 if (r) {
2571 result = r; /* r = -EFAULT */
2572 goto unlock;
2573 }
2574 buf += 1;
2575 size -= 1;
2576 *pos += 1;
2577 result += 1;
2578 }
2579 unlock:
2580 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2581 mutex_unlock(&dev->mode_config.mutex);
2582 kfree(rd_buf);
2583 return result;
2584 }
2585
2586
2587 /*
2588 * function description: Set max_requested_bpc property on the connector
2589 *
2590 * This function will not force the input BPC on connector, it will only
2591 * change the max value. This is equivalent to setting max_bpc through
2592 * xrandr.
2593 *
2594 * The BPC value written must be >= 6 and <= 16. Values outside of this
2595 * range will result in errors.
2596 *
2597 * BPC values:
2598 * 0x6 - 6 BPC
2599 * 0x8 - 8 BPC
2600 * 0xa - 10 BPC
2601 * 0xc - 12 BPC
2602 * 0x10 - 16 BPC
2603 *
2604 * Write the max_bpc in the following way:
2605 *
2606 * echo 0x6 > /sys/kernel/debug/dri/0/DP-X/max_bpc
2607 *
2608 */
dp_max_bpc_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)2609 static ssize_t dp_max_bpc_write(struct file *f, const char __user *buf,
2610 size_t size, loff_t *pos)
2611 {
2612 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2613 struct drm_connector *connector = &aconnector->base;
2614 struct dm_connector_state *state;
2615 struct drm_device *dev = connector->dev;
2616 char *wr_buf = NULL;
2617 uint32_t wr_buf_size = 42;
2618 int max_param_num = 1;
2619 long param[1] = {0};
2620 uint8_t param_nums = 0;
2621
2622 if (size == 0)
2623 return -EINVAL;
2624
2625 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
2626
2627 if (!wr_buf) {
2628 DRM_DEBUG_DRIVER("no memory to allocate write buffer\n");
2629 return -ENOSPC;
2630 }
2631
2632 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
2633 (long *)param, buf,
2634 max_param_num,
2635 ¶m_nums)) {
2636 kfree(wr_buf);
2637 return -EINVAL;
2638 }
2639
2640 if (param_nums <= 0) {
2641 DRM_DEBUG_DRIVER("user data not be read\n");
2642 kfree(wr_buf);
2643 return -EINVAL;
2644 }
2645
2646 if (param[0] < 6 || param[0] > 16) {
2647 DRM_DEBUG_DRIVER("bad max_bpc value\n");
2648 kfree(wr_buf);
2649 return -EINVAL;
2650 }
2651
2652 mutex_lock(&dev->mode_config.mutex);
2653 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2654
2655 if (connector->state == NULL)
2656 goto unlock;
2657
2658 state = to_dm_connector_state(connector->state);
2659 state->base.max_requested_bpc = param[0];
2660 unlock:
2661 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2662 mutex_unlock(&dev->mode_config.mutex);
2663
2664 kfree(wr_buf);
2665 return size;
2666 }
2667
2668 /*
2669 * IPS status. Read only.
2670 *
2671 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_ips_status
2672 */
ips_status_show(struct seq_file * m,void * unused)2673 static int ips_status_show(struct seq_file *m, void *unused)
2674 {
2675 struct amdgpu_device *adev = m->private;
2676 struct dc *dc = adev->dm.dc;
2677 struct dc_dmub_srv *dc_dmub_srv;
2678
2679 seq_printf(m, "IPS config: %d\n", dc->config.disable_ips);
2680 seq_printf(m, "Idle optimization: %d\n", dc->idle_optimizations_allowed);
2681
2682 if (adev->dm.idle_workqueue) {
2683 seq_printf(m, "Idle workqueue - enabled: %d\n", adev->dm.idle_workqueue->enable);
2684 seq_printf(m, "Idle workqueue - running: %d\n", adev->dm.idle_workqueue->running);
2685 }
2686
2687 dc_dmub_srv = dc->ctx->dmub_srv;
2688 if (dc_dmub_srv && dc_dmub_srv->dmub) {
2689 uint32_t rcg_count, ips1_count, ips2_count;
2690 volatile const struct dmub_shared_state_ips_fw *ips_fw =
2691 &dc_dmub_srv->dmub->shared_state[DMUB_SHARED_SHARE_FEATURE__IPS_FW].data.ips_fw;
2692 rcg_count = ips_fw->rcg_entry_count;
2693 ips1_count = ips_fw->ips1_entry_count;
2694 ips2_count = ips_fw->ips2_entry_count;
2695 seq_printf(m, "entry counts: rcg=%u ips1=%u ips2=%u\n",
2696 rcg_count,
2697 ips1_count,
2698 ips2_count);
2699 rcg_count = ips_fw->rcg_exit_count;
2700 ips1_count = ips_fw->ips1_exit_count;
2701 ips2_count = ips_fw->ips2_exit_count;
2702 seq_printf(m, "exit counts: rcg=%u ips1=%u ips2=%u",
2703 rcg_count,
2704 ips1_count,
2705 ips2_count);
2706 seq_puts(m, "\n");
2707 }
2708 return 0;
2709 }
2710
2711 /*
2712 * Backlight at this moment. Read only.
2713 * As written to display, taking ABM and backlight lut into account.
2714 * Ranges from 0x0 to 0x10000 (= 100% PWM)
2715 *
2716 * Example usage: cat /sys/kernel/debug/dri/0/eDP-1/current_backlight
2717 */
current_backlight_show(struct seq_file * m,void * unused)2718 static int current_backlight_show(struct seq_file *m, void *unused)
2719 {
2720 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(m->private);
2721 struct dc_link *link = aconnector->dc_link;
2722 unsigned int backlight;
2723
2724 backlight = dc_link_get_backlight_level(link);
2725 seq_printf(m, "0x%x\n", backlight);
2726
2727 return 0;
2728 }
2729
2730 /*
2731 * Backlight value that is being approached. Read only.
2732 * As written to display, taking ABM and backlight lut into account.
2733 * Ranges from 0x0 to 0x10000 (= 100% PWM)
2734 *
2735 * Example usage: cat /sys/kernel/debug/dri/0/eDP-1/target_backlight
2736 */
target_backlight_show(struct seq_file * m,void * unused)2737 static int target_backlight_show(struct seq_file *m, void *unused)
2738 {
2739 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(m->private);
2740 struct dc_link *link = aconnector->dc_link;
2741 unsigned int backlight;
2742
2743 backlight = dc_link_get_target_backlight_pwm(link);
2744 seq_printf(m, "0x%x\n", backlight);
2745
2746 return 0;
2747 }
2748
2749 /*
2750 * function description: Determine if the connector is mst connector
2751 *
2752 * This function helps to determine whether a connector is a mst connector.
2753 * - "root" stands for the root connector of the topology
2754 * - "branch" stands for branch device of the topology
2755 * - "end" stands for leaf node connector of the topology
2756 * - "no" stands for the connector is not a device of a mst topology
2757 * Access it with the following command:
2758 *
2759 * cat /sys/kernel/debug/dri/0/DP-X/is_mst_connector
2760 *
2761 */
dp_is_mst_connector_show(struct seq_file * m,void * unused)2762 static int dp_is_mst_connector_show(struct seq_file *m, void *unused)
2763 {
2764 struct drm_connector *connector = m->private;
2765 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
2766 struct drm_dp_mst_topology_mgr *mgr = NULL;
2767 struct drm_dp_mst_port *port = NULL;
2768 char *role = NULL;
2769
2770 mutex_lock(&aconnector->hpd_lock);
2771
2772 if (aconnector->mst_mgr.mst_state) {
2773 role = "root";
2774 } else if (aconnector->mst_root &&
2775 aconnector->mst_root->mst_mgr.mst_state) {
2776
2777 role = "end";
2778
2779 mgr = &aconnector->mst_root->mst_mgr;
2780 port = aconnector->mst_output_port;
2781
2782 drm_modeset_lock(&mgr->base.lock, NULL);
2783 if (port->pdt == DP_PEER_DEVICE_MST_BRANCHING &&
2784 port->mcs)
2785 role = "branch";
2786 drm_modeset_unlock(&mgr->base.lock);
2787
2788 } else {
2789 role = "no";
2790 }
2791
2792 seq_printf(m, "%s\n", role);
2793
2794 mutex_unlock(&aconnector->hpd_lock);
2795
2796 return 0;
2797 }
2798
2799 /*
2800 * function description: Read out the mst progress status
2801 *
2802 * This function helps to determine the mst progress status of
2803 * a mst connector.
2804 *
2805 * Access it with the following command:
2806 *
2807 * cat /sys/kernel/debug/dri/0/DP-X/mst_progress_status
2808 *
2809 */
dp_mst_progress_status_show(struct seq_file * m,void * unused)2810 static int dp_mst_progress_status_show(struct seq_file *m, void *unused)
2811 {
2812 struct drm_connector *connector = m->private;
2813 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
2814 struct amdgpu_device *adev = drm_to_adev(connector->dev);
2815 int i;
2816
2817 mutex_lock(&aconnector->hpd_lock);
2818 mutex_lock(&adev->dm.dc_lock);
2819
2820 if (aconnector->mst_status == MST_STATUS_DEFAULT) {
2821 seq_puts(m, "disabled\n");
2822 } else {
2823 for (i = 0; i < sizeof(mst_progress_status)/sizeof(char *); i++)
2824 seq_printf(m, "%s:%s\n",
2825 mst_progress_status[i],
2826 aconnector->mst_status & BIT(i) ? "done" : "not_done");
2827 }
2828
2829 mutex_unlock(&adev->dm.dc_lock);
2830 mutex_unlock(&aconnector->hpd_lock);
2831
2832 return 0;
2833 }
2834
2835 /*
2836 * Reports whether the connected display is a USB4 DPIA tunneled display
2837 * Example usage: cat /sys/kernel/debug/dri/0/DP-8/is_dpia_link
2838 */
is_dpia_link_show(struct seq_file * m,void * data)2839 static int is_dpia_link_show(struct seq_file *m, void *data)
2840 {
2841 struct drm_connector *connector = m->private;
2842 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
2843 struct dc_link *link = aconnector->dc_link;
2844
2845 if (connector->status != connector_status_connected)
2846 return -ENODEV;
2847
2848 seq_printf(m, "%s\n", (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) ? "yes" :
2849 (link->ep_type == DISPLAY_ENDPOINT_PHY) ? "no" : "unknown");
2850
2851 return 0;
2852 }
2853
2854 /**
2855 * hdmi_cec_state_show - Read out the HDMI-CEC feature status
2856 * @m: sequence file.
2857 * @data: unused.
2858 *
2859 * Return 0 on success
2860 */
hdmi_cec_state_show(struct seq_file * m,void * data)2861 static int hdmi_cec_state_show(struct seq_file *m, void *data)
2862 {
2863 struct drm_connector *connector = m->private;
2864 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
2865
2866 seq_printf(m, "%s:%d\n", connector->name, connector->base.id);
2867 seq_printf(m, "HDMI-CEC status: %d\n", aconnector->notifier ? 1 : 0);
2868
2869 return 0;
2870 }
2871
2872 /**
2873 * hdmi_cec_state_write - Enable/Disable HDMI-CEC feature from driver side
2874 * @f: file structure.
2875 * @buf: userspace buffer. set to '1' to enable; '0' to disable cec feature.
2876 * @size: size of buffer from userpsace.
2877 * @pos: unused.
2878 *
2879 * Return size on success, error code on failure
2880 */
hdmi_cec_state_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)2881 static ssize_t hdmi_cec_state_write(struct file *f, const char __user *buf,
2882 size_t size, loff_t *pos)
2883 {
2884 int ret;
2885 bool enable;
2886 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
2887 struct drm_device *ddev = aconnector->base.dev;
2888
2889 if (size == 0)
2890 return -EINVAL;
2891
2892 ret = kstrtobool_from_user(buf, size, &enable);
2893 if (ret) {
2894 drm_dbg_driver(ddev, "invalid user data !\n");
2895 return ret;
2896 }
2897
2898 if (enable) {
2899 if (aconnector->notifier)
2900 return -EINVAL;
2901 ret = amdgpu_dm_initialize_hdmi_connector(aconnector);
2902 if (ret)
2903 return ret;
2904 hdmi_cec_set_edid(aconnector);
2905 } else {
2906 if (!aconnector->notifier)
2907 return -EINVAL;
2908 cec_notifier_conn_unregister(aconnector->notifier);
2909 aconnector->notifier = NULL;
2910 }
2911
2912 return size;
2913 }
2914
2915 DEFINE_SHOW_ATTRIBUTE(dp_dsc_fec_support);
2916 DEFINE_SHOW_ATTRIBUTE(dmub_fw_state);
2917 DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer);
2918 DEFINE_SHOW_ATTRIBUTE(dp_lttpr_status);
2919 DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability);
2920 DEFINE_SHOW_ATTRIBUTE(internal_display);
2921 DEFINE_SHOW_ATTRIBUTE(odm_combine_segments);
2922 DEFINE_SHOW_ATTRIBUTE(replay_capability);
2923 DEFINE_SHOW_ATTRIBUTE(psr_capability);
2924 DEFINE_SHOW_ATTRIBUTE(dp_is_mst_connector);
2925 DEFINE_SHOW_ATTRIBUTE(dp_mst_progress_status);
2926 DEFINE_SHOW_ATTRIBUTE(is_dpia_link);
2927 DEFINE_SHOW_STORE_ATTRIBUTE(hdmi_cec_state);
2928
2929 static const struct file_operations dp_dsc_clock_en_debugfs_fops = {
2930 .owner = THIS_MODULE,
2931 .read = dp_dsc_clock_en_read,
2932 .write = dp_dsc_clock_en_write,
2933 .llseek = default_llseek
2934 };
2935
2936 static const struct file_operations dp_dsc_slice_width_debugfs_fops = {
2937 .owner = THIS_MODULE,
2938 .read = dp_dsc_slice_width_read,
2939 .write = dp_dsc_slice_width_write,
2940 .llseek = default_llseek
2941 };
2942
2943 static const struct file_operations dp_dsc_slice_height_debugfs_fops = {
2944 .owner = THIS_MODULE,
2945 .read = dp_dsc_slice_height_read,
2946 .write = dp_dsc_slice_height_write,
2947 .llseek = default_llseek
2948 };
2949
2950 static const struct file_operations dp_dsc_bits_per_pixel_debugfs_fops = {
2951 .owner = THIS_MODULE,
2952 .read = dp_dsc_bits_per_pixel_read,
2953 .write = dp_dsc_bits_per_pixel_write,
2954 .llseek = default_llseek
2955 };
2956
2957 static const struct file_operations dp_dsc_pic_width_debugfs_fops = {
2958 .owner = THIS_MODULE,
2959 .read = dp_dsc_pic_width_read,
2960 .llseek = default_llseek
2961 };
2962
2963 static const struct file_operations dp_dsc_pic_height_debugfs_fops = {
2964 .owner = THIS_MODULE,
2965 .read = dp_dsc_pic_height_read,
2966 .llseek = default_llseek
2967 };
2968
2969 static const struct file_operations dp_dsc_chunk_size_debugfs_fops = {
2970 .owner = THIS_MODULE,
2971 .read = dp_dsc_chunk_size_read,
2972 .llseek = default_llseek
2973 };
2974
2975 static const struct file_operations dp_dsc_slice_bpg_offset_debugfs_fops = {
2976 .owner = THIS_MODULE,
2977 .read = dp_dsc_slice_bpg_offset_read,
2978 .llseek = default_llseek
2979 };
2980
2981 static const struct file_operations trigger_hotplug_debugfs_fops = {
2982 .owner = THIS_MODULE,
2983 .write = trigger_hotplug,
2984 .llseek = default_llseek
2985 };
2986
2987 static const struct file_operations dp_link_settings_debugfs_fops = {
2988 .owner = THIS_MODULE,
2989 .read = dp_link_settings_read,
2990 .write = dp_link_settings_write,
2991 .llseek = default_llseek
2992 };
2993
2994 static const struct file_operations dp_phy_settings_debugfs_fop = {
2995 .owner = THIS_MODULE,
2996 .read = dp_phy_settings_read,
2997 .write = dp_phy_settings_write,
2998 .llseek = default_llseek
2999 };
3000
3001 static const struct file_operations dp_phy_test_pattern_fops = {
3002 .owner = THIS_MODULE,
3003 .write = dp_phy_test_pattern_debugfs_write,
3004 .llseek = default_llseek
3005 };
3006
3007 static const struct file_operations sdp_message_fops = {
3008 .owner = THIS_MODULE,
3009 .write = dp_sdp_message_debugfs_write,
3010 .llseek = default_llseek
3011 };
3012
3013 static const struct file_operations dp_max_bpc_debugfs_fops = {
3014 .owner = THIS_MODULE,
3015 .read = dp_max_bpc_read,
3016 .write = dp_max_bpc_write,
3017 .llseek = default_llseek
3018 };
3019
3020 static const struct file_operations dp_dsc_disable_passthrough_debugfs_fops = {
3021 .owner = THIS_MODULE,
3022 .write = dp_dsc_passthrough_set,
3023 .llseek = default_llseek
3024 };
3025
3026 static const struct file_operations dp_mst_link_settings_debugfs_fops = {
3027 .owner = THIS_MODULE,
3028 .write = dp_mst_link_setting,
3029 .llseek = default_llseek
3030 };
3031
3032 static const struct {
3033 char *name;
3034 const struct file_operations *fops;
3035 } dp_debugfs_entries[] = {
3036 {"link_settings", &dp_link_settings_debugfs_fops},
3037 {"phy_settings", &dp_phy_settings_debugfs_fop},
3038 {"lttpr_status", &dp_lttpr_status_fops},
3039 {"test_pattern", &dp_phy_test_pattern_fops},
3040 {"hdcp_sink_capability", &hdcp_sink_capability_fops},
3041 {"sdp_message", &sdp_message_fops},
3042 {"dsc_clock_en", &dp_dsc_clock_en_debugfs_fops},
3043 {"dsc_slice_width", &dp_dsc_slice_width_debugfs_fops},
3044 {"dsc_slice_height", &dp_dsc_slice_height_debugfs_fops},
3045 {"dsc_bits_per_pixel", &dp_dsc_bits_per_pixel_debugfs_fops},
3046 {"dsc_pic_width", &dp_dsc_pic_width_debugfs_fops},
3047 {"dsc_pic_height", &dp_dsc_pic_height_debugfs_fops},
3048 {"dsc_chunk_size", &dp_dsc_chunk_size_debugfs_fops},
3049 {"dsc_slice_bpg", &dp_dsc_slice_bpg_offset_debugfs_fops},
3050 {"dp_dsc_fec_support", &dp_dsc_fec_support_fops},
3051 {"max_bpc", &dp_max_bpc_debugfs_fops},
3052 {"dsc_disable_passthrough", &dp_dsc_disable_passthrough_debugfs_fops},
3053 {"is_mst_connector", &dp_is_mst_connector_fops},
3054 {"mst_progress_status", &dp_mst_progress_status_fops},
3055 {"is_dpia_link", &is_dpia_link_fops},
3056 {"mst_link_settings", &dp_mst_link_settings_debugfs_fops}
3057 };
3058
3059 static const struct {
3060 char *name;
3061 const struct file_operations *fops;
3062 } hdmi_debugfs_entries[] = {
3063 {"hdcp_sink_capability", &hdcp_sink_capability_fops},
3064 {"hdmi_cec_state", &hdmi_cec_state_fops}
3065 };
3066
3067 /*
3068 * Force YUV420 output if available from the given mode
3069 */
force_yuv420_output_set(void * data,u64 val)3070 static int force_yuv420_output_set(void *data, u64 val)
3071 {
3072 struct amdgpu_dm_connector *connector = data;
3073
3074 connector->force_yuv420_output = (bool)val;
3075
3076 return 0;
3077 }
3078
3079 /*
3080 * Check if YUV420 is forced when available from the given mode
3081 */
force_yuv420_output_get(void * data,u64 * val)3082 static int force_yuv420_output_get(void *data, u64 *val)
3083 {
3084 struct amdgpu_dm_connector *connector = data;
3085
3086 *val = connector->force_yuv420_output;
3087
3088 return 0;
3089 }
3090
3091 DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
3092 force_yuv420_output_set, "%llu\n");
3093
3094 /*
3095 * Read Replay state
3096 */
replay_get_state(void * data,u64 * val)3097 static int replay_get_state(void *data, u64 *val)
3098 {
3099 struct amdgpu_dm_connector *connector = data;
3100 struct dc_link *link = connector->dc_link;
3101 uint64_t state = REPLAY_STATE_INVALID;
3102
3103 dc_link_get_replay_state(link, &state);
3104
3105 *val = state;
3106
3107 return 0;
3108 }
3109
3110 /*
3111 * Start / Stop capture Replay residency
3112 */
replay_set_residency(void * data,u64 val)3113 static int replay_set_residency(void *data, u64 val)
3114 {
3115 struct amdgpu_dm_connector *connector = data;
3116 struct dc_link *link = connector->dc_link;
3117 bool is_start = (val != 0);
3118 u32 residency = 0;
3119
3120 link->dc->link_srv->edp_replay_residency(link, &residency, is_start, PR_RESIDENCY_MODE_PHY);
3121 return 0;
3122 }
3123
3124 /*
3125 * Read Replay residency
3126 */
replay_get_residency(void * data,u64 * val)3127 static int replay_get_residency(void *data, u64 *val)
3128 {
3129 struct amdgpu_dm_connector *connector = data;
3130 struct dc_link *link = connector->dc_link;
3131 u32 residency = 0;
3132
3133 link->dc->link_srv->edp_replay_residency(link, &residency, false, PR_RESIDENCY_MODE_PHY);
3134 *val = (u64)residency;
3135
3136 return 0;
3137 }
3138
3139 /*
3140 * Read PSR state
3141 */
psr_get(void * data,u64 * val)3142 static int psr_get(void *data, u64 *val)
3143 {
3144 struct amdgpu_dm_connector *connector = data;
3145 struct dc_link *link = connector->dc_link;
3146 enum dc_psr_state state = PSR_STATE0;
3147
3148 dc_link_get_psr_state(link, &state);
3149
3150 *val = state;
3151
3152 return 0;
3153 }
3154
3155 /*
3156 * Read PSR state residency
3157 */
psr_read_residency(void * data,u64 * val)3158 static int psr_read_residency(void *data, u64 *val)
3159 {
3160 struct amdgpu_dm_connector *connector = data;
3161 struct dc_link *link = connector->dc_link;
3162 u32 residency = 0;
3163
3164 link->dc->link_srv->edp_get_psr_residency(link, &residency, PSR_RESIDENCY_MODE_PHY);
3165
3166 *val = (u64)residency;
3167
3168 return 0;
3169 }
3170
3171 /* read allow_edp_hotplug_detection */
allow_edp_hotplug_detection_get(void * data,u64 * val)3172 static int allow_edp_hotplug_detection_get(void *data, u64 *val)
3173 {
3174 struct amdgpu_dm_connector *aconnector = data;
3175 struct drm_connector *connector = &aconnector->base;
3176 struct drm_device *dev = connector->dev;
3177 struct amdgpu_device *adev = drm_to_adev(dev);
3178
3179 *val = adev->dm.dc->config.allow_edp_hotplug_detection;
3180
3181 return 0;
3182 }
3183
3184 /* set allow_edp_hotplug_detection */
allow_edp_hotplug_detection_set(void * data,u64 val)3185 static int allow_edp_hotplug_detection_set(void *data, u64 val)
3186 {
3187 struct amdgpu_dm_connector *aconnector = data;
3188 struct drm_connector *connector = &aconnector->base;
3189 struct drm_device *dev = connector->dev;
3190 struct amdgpu_device *adev = drm_to_adev(dev);
3191
3192 adev->dm.dc->config.allow_edp_hotplug_detection = (uint32_t) val;
3193
3194 return 0;
3195 }
3196
3197 /* check if kernel disallow eDP enter psr state
3198 * cat /sys/kernel/debug/dri/0/eDP-X/disallow_edp_enter_psr
3199 * 0: allow edp enter psr; 1: disallow
3200 */
disallow_edp_enter_psr_get(void * data,u64 * val)3201 static int disallow_edp_enter_psr_get(void *data, u64 *val)
3202 {
3203 struct amdgpu_dm_connector *aconnector = data;
3204
3205 *val = (u64) aconnector->disallow_edp_enter_psr;
3206 return 0;
3207 }
3208
3209 /* set kernel disallow eDP enter psr state
3210 * echo 0x0 /sys/kernel/debug/dri/0/eDP-X/disallow_edp_enter_psr
3211 * 0: allow edp enter psr; 1: disallow
3212 *
3213 * usage: test app read crc from PSR eDP rx.
3214 *
3215 * during kernel boot up, kernel write dpcd 0x170 = 5.
3216 * this notify eDP rx psr enable and let rx check crc.
3217 * rx fw will start checking crc for rx internal logic.
3218 * crc read count within dpcd 0x246 is not updated and
3219 * value is 0. when eDP tx driver wants to read rx crc
3220 * from dpcd 0x246, 0x270, read count 0 lead tx driver
3221 * timeout.
3222 *
3223 * to avoid this, we add this debugfs to let test app to disbable
3224 * rx crc checking for rx internal logic. then test app can read
3225 * non-zero crc read count.
3226 *
3227 * expected app sequence is as below:
3228 * 1. disable eDP PHY and notify eDP rx with dpcd 0x600 = 2.
3229 * 2. echo 0x1 /sys/kernel/debug/dri/0/eDP-X/disallow_edp_enter_psr
3230 * 3. enable eDP PHY and notify eDP rx with dpcd 0x600 = 1 but
3231 * without dpcd 0x170 = 5.
3232 * 4. read crc from rx dpcd 0x270, 0x246, etc.
3233 * 5. echo 0x0 /sys/kernel/debug/dri/0/eDP-X/disallow_edp_enter_psr.
3234 * this will let eDP back to normal with psr setup dpcd 0x170 = 5.
3235 */
disallow_edp_enter_psr_set(void * data,u64 val)3236 static int disallow_edp_enter_psr_set(void *data, u64 val)
3237 {
3238 struct amdgpu_dm_connector *aconnector = data;
3239
3240 aconnector->disallow_edp_enter_psr = val ? true : false;
3241 return 0;
3242 }
3243
dmub_trace_mask_set(void * data,u64 val)3244 static int dmub_trace_mask_set(void *data, u64 val)
3245 {
3246 struct amdgpu_device *adev = data;
3247 struct dmub_srv *srv = adev->dm.dc->ctx->dmub_srv->dmub;
3248 enum dmub_gpint_command cmd;
3249 u64 mask = 0xffff;
3250 u8 shift = 0;
3251 u32 res;
3252 int i;
3253
3254 if (!srv->fw_version)
3255 return -EINVAL;
3256
3257 for (i = 0; i < 4; i++) {
3258 res = (val & mask) >> shift;
3259
3260 switch (i) {
3261 case 0:
3262 cmd = DMUB_GPINT__SET_TRACE_BUFFER_MASK_WORD0;
3263 break;
3264 case 1:
3265 cmd = DMUB_GPINT__SET_TRACE_BUFFER_MASK_WORD1;
3266 break;
3267 case 2:
3268 cmd = DMUB_GPINT__SET_TRACE_BUFFER_MASK_WORD2;
3269 break;
3270 case 3:
3271 cmd = DMUB_GPINT__SET_TRACE_BUFFER_MASK_WORD3;
3272 break;
3273 }
3274
3275 if (!dc_wake_and_execute_gpint(adev->dm.dc->ctx, cmd, res, NULL, DM_DMUB_WAIT_TYPE_WAIT))
3276 return -EIO;
3277
3278 usleep_range(100, 1000);
3279
3280 mask <<= 16;
3281 shift += 16;
3282 }
3283
3284 return 0;
3285 }
3286
dmub_trace_mask_show(void * data,u64 * val)3287 static int dmub_trace_mask_show(void *data, u64 *val)
3288 {
3289 enum dmub_gpint_command cmd = DMUB_GPINT__GET_TRACE_BUFFER_MASK_WORD0;
3290 struct amdgpu_device *adev = data;
3291 struct dmub_srv *srv = adev->dm.dc->ctx->dmub_srv->dmub;
3292 u8 shift = 0;
3293 u64 raw = 0;
3294 u64 res = 0;
3295 int i = 0;
3296
3297 if (!srv->fw_version)
3298 return -EINVAL;
3299
3300 while (i < 4) {
3301 uint32_t response;
3302
3303 if (!dc_wake_and_execute_gpint(adev->dm.dc->ctx, cmd, 0, &response, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
3304 return -EIO;
3305
3306 raw = response;
3307 usleep_range(100, 1000);
3308
3309 cmd++;
3310 res |= (raw << shift);
3311 shift += 16;
3312 i++;
3313 }
3314
3315 *val = res;
3316
3317 return 0;
3318 }
3319
3320 DEFINE_DEBUGFS_ATTRIBUTE(dmub_trace_mask_fops, dmub_trace_mask_show,
3321 dmub_trace_mask_set, "0x%llx\n");
3322
3323 /*
3324 * Set dmcub trace event IRQ enable or disable.
3325 * Usage to enable dmcub trace event IRQ: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en
3326 * Usage to disable dmcub trace event IRQ: echo 0 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en
3327 */
dmcub_trace_event_state_set(void * data,u64 val)3328 static int dmcub_trace_event_state_set(void *data, u64 val)
3329 {
3330 struct amdgpu_device *adev = data;
3331
3332 if (val == 1 || val == 0) {
3333 dc_dmub_trace_event_control(adev->dm.dc, val);
3334 adev->dm.dmcub_trace_event_en = (bool)val;
3335 } else
3336 return 0;
3337
3338 return 0;
3339 }
3340
3341 /*
3342 * The interface doesn't need get function, so it will return the
3343 * value of zero
3344 * Usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en
3345 */
dmcub_trace_event_state_get(void * data,u64 * val)3346 static int dmcub_trace_event_state_get(void *data, u64 *val)
3347 {
3348 struct amdgpu_device *adev = data;
3349
3350 *val = adev->dm.dmcub_trace_event_en;
3351 return 0;
3352 }
3353
3354 DEFINE_DEBUGFS_ATTRIBUTE(dmcub_trace_event_state_fops, dmcub_trace_event_state_get,
3355 dmcub_trace_event_state_set, "%llu\n");
3356
3357 DEFINE_DEBUGFS_ATTRIBUTE(replay_state_fops, replay_get_state, NULL, "%llu\n");
3358 DEFINE_DEBUGFS_ATTRIBUTE(replay_residency_fops, replay_get_residency, replay_set_residency,
3359 "%llu\n");
3360 DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n");
3361 DEFINE_DEBUGFS_ATTRIBUTE(psr_residency_fops, psr_read_residency, NULL,
3362 "%llu\n");
3363
3364 DEFINE_DEBUGFS_ATTRIBUTE(allow_edp_hotplug_detection_fops,
3365 allow_edp_hotplug_detection_get,
3366 allow_edp_hotplug_detection_set, "%llu\n");
3367
3368 DEFINE_DEBUGFS_ATTRIBUTE(disallow_edp_enter_psr_fops,
3369 disallow_edp_enter_psr_get,
3370 disallow_edp_enter_psr_set, "%llu\n");
3371
3372 DEFINE_SHOW_ATTRIBUTE(current_backlight);
3373 DEFINE_SHOW_ATTRIBUTE(target_backlight);
3374 DEFINE_SHOW_ATTRIBUTE(ips_status);
3375
3376 static const struct {
3377 char *name;
3378 const struct file_operations *fops;
3379 } connector_debugfs_entries[] = {
3380 {"force_yuv420_output", &force_yuv420_output_fops},
3381 {"trigger_hotplug", &trigger_hotplug_debugfs_fops},
3382 {"internal_display", &internal_display_fops},
3383 {"odm_combine_segments", &odm_combine_segments_fops}
3384 };
3385
3386 /*
3387 * Returns supported customized link rates by this eDP panel.
3388 * Example usage: cat /sys/kernel/debug/dri/0/eDP-x/ilr_setting
3389 */
edp_ilr_show(struct seq_file * m,void * unused)3390 static int edp_ilr_show(struct seq_file *m, void *unused)
3391 {
3392 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(m->private);
3393 struct dc_link *link = aconnector->dc_link;
3394 uint8_t supported_link_rates[16];
3395 uint32_t link_rate_in_khz;
3396 uint32_t entry = 0;
3397 uint8_t dpcd_rev;
3398
3399 memset(supported_link_rates, 0, sizeof(supported_link_rates));
3400 dm_helpers_dp_read_dpcd(link->ctx, link, DP_SUPPORTED_LINK_RATES,
3401 supported_link_rates, sizeof(supported_link_rates));
3402
3403 dpcd_rev = link->dpcd_caps.dpcd_rev.raw;
3404
3405 if (dpcd_rev >= DP_DPCD_REV_13 &&
3406 (supported_link_rates[entry+1] != 0 || supported_link_rates[entry] != 0)) {
3407
3408 for (entry = 0; entry < 16; entry += 2) {
3409 link_rate_in_khz = (supported_link_rates[entry+1] * 0x100 +
3410 supported_link_rates[entry]) * 200;
3411 seq_printf(m, "[%d] %d kHz\n", entry/2, link_rate_in_khz);
3412 }
3413 } else {
3414 seq_puts(m, "ILR is not supported by this eDP panel.\n");
3415 }
3416
3417 return 0;
3418 }
3419
3420 /*
3421 * Set supported customized link rate to eDP panel.
3422 *
3423 * echo <lane_count> <link_rate option> > ilr_setting
3424 *
3425 * for example, supported ILR : [0] 1620000 kHz [1] 2160000 kHz [2] 2430000 kHz ...
3426 * echo 4 1 > /sys/kernel/debug/dri/0/eDP-x/ilr_setting
3427 * to set 4 lanes and 2.16 GHz
3428 */
edp_ilr_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)3429 static ssize_t edp_ilr_write(struct file *f, const char __user *buf,
3430 size_t size, loff_t *pos)
3431 {
3432 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
3433 struct dc_link *link = connector->dc_link;
3434 struct amdgpu_device *adev = drm_to_adev(connector->base.dev);
3435 struct dc *dc = (struct dc *)link->dc;
3436 struct dc_link_settings prefer_link_settings;
3437 char *wr_buf = NULL;
3438 const uint32_t wr_buf_size = 40;
3439 /* 0: lane_count; 1: link_rate */
3440 int max_param_num = 2;
3441 uint8_t param_nums = 0;
3442 long param[2];
3443 bool valid_input = true;
3444
3445 if (size == 0)
3446 return -EINVAL;
3447
3448 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
3449 if (!wr_buf)
3450 return -ENOMEM;
3451
3452 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
3453 (long *)param, buf,
3454 max_param_num,
3455 ¶m_nums)) {
3456 kfree(wr_buf);
3457 return -EINVAL;
3458 }
3459
3460 if (param_nums <= 0) {
3461 kfree(wr_buf);
3462 return -EINVAL;
3463 }
3464
3465 switch (param[0]) {
3466 case LANE_COUNT_ONE:
3467 case LANE_COUNT_TWO:
3468 case LANE_COUNT_FOUR:
3469 break;
3470 default:
3471 valid_input = false;
3472 break;
3473 }
3474
3475 if (param[1] >= link->dpcd_caps.edp_supported_link_rates_count)
3476 valid_input = false;
3477
3478 if (!valid_input) {
3479 kfree(wr_buf);
3480 DRM_DEBUG_DRIVER("Invalid Input value. No HW will be programmed\n");
3481 prefer_link_settings.use_link_rate_set = false;
3482 mutex_lock(&adev->dm.dc_lock);
3483 dc_link_set_preferred_training_settings(dc, NULL, NULL, link, false);
3484 mutex_unlock(&adev->dm.dc_lock);
3485 return size;
3486 }
3487
3488 /* save user force lane_count, link_rate to preferred settings
3489 * spread spectrum will not be changed
3490 */
3491 prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
3492 prefer_link_settings.lane_count = param[0];
3493 prefer_link_settings.use_link_rate_set = true;
3494 prefer_link_settings.link_rate_set = param[1];
3495 prefer_link_settings.link_rate = link->dpcd_caps.edp_supported_link_rates[param[1]];
3496
3497 mutex_lock(&adev->dm.dc_lock);
3498 dc_link_set_preferred_training_settings(dc, &prefer_link_settings,
3499 NULL, link, false);
3500 mutex_unlock(&adev->dm.dc_lock);
3501
3502 kfree(wr_buf);
3503 return size;
3504 }
3505
edp_ilr_open(struct inode * inode,struct file * file)3506 static int edp_ilr_open(struct inode *inode, struct file *file)
3507 {
3508 return single_open(file, edp_ilr_show, inode->i_private);
3509 }
3510
3511 static const struct file_operations edp_ilr_debugfs_fops = {
3512 .owner = THIS_MODULE,
3513 .open = edp_ilr_open,
3514 .read = seq_read,
3515 .llseek = seq_lseek,
3516 .release = single_release,
3517 .write = edp_ilr_write
3518 };
3519
connector_debugfs_init(struct amdgpu_dm_connector * connector)3520 void connector_debugfs_init(struct amdgpu_dm_connector *connector)
3521 {
3522 int i;
3523 struct dentry *dir = connector->base.debugfs_entry;
3524
3525 if (connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
3526 connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) {
3527 for (i = 0; i < ARRAY_SIZE(dp_debugfs_entries); i++) {
3528 debugfs_create_file(dp_debugfs_entries[i].name,
3529 0644, dir, connector,
3530 dp_debugfs_entries[i].fops);
3531 }
3532 }
3533 if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) {
3534 debugfs_create_file("replay_capability", 0444, dir, connector,
3535 &replay_capability_fops);
3536 debugfs_create_file("replay_state", 0444, dir, connector, &replay_state_fops);
3537 debugfs_create_file_unsafe("replay_residency", 0444, dir,
3538 connector, &replay_residency_fops);
3539 debugfs_create_file_unsafe("psr_capability", 0444, dir, connector, &psr_capability_fops);
3540 debugfs_create_file_unsafe("psr_state", 0444, dir, connector, &psr_fops);
3541 debugfs_create_file_unsafe("psr_residency", 0444, dir,
3542 connector, &psr_residency_fops);
3543 debugfs_create_file("amdgpu_current_backlight_pwm", 0444, dir, connector,
3544 ¤t_backlight_fops);
3545 debugfs_create_file("amdgpu_target_backlight_pwm", 0444, dir, connector,
3546 &target_backlight_fops);
3547 debugfs_create_file("ilr_setting", 0644, dir, connector,
3548 &edp_ilr_debugfs_fops);
3549 debugfs_create_file("allow_edp_hotplug_detection", 0644, dir, connector,
3550 &allow_edp_hotplug_detection_fops);
3551 debugfs_create_file("disallow_edp_enter_psr", 0644, dir, connector,
3552 &disallow_edp_enter_psr_fops);
3553 }
3554
3555 for (i = 0; i < ARRAY_SIZE(connector_debugfs_entries); i++) {
3556 debugfs_create_file(connector_debugfs_entries[i].name,
3557 0644, dir, connector,
3558 connector_debugfs_entries[i].fops);
3559 }
3560
3561 if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) {
3562 for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_entries); i++) {
3563 debugfs_create_file(hdmi_debugfs_entries[i].name,
3564 0644, dir, connector,
3565 hdmi_debugfs_entries[i].fops);
3566 }
3567 }
3568 }
3569
3570 #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
3571 /*
3572 * Set crc window coordinate x start
3573 */
crc_win_x_start_set(void * data,u64 val)3574 static int crc_win_x_start_set(void *data, u64 val)
3575 {
3576 struct drm_crtc *crtc = data;
3577 struct drm_device *drm_dev = crtc->dev;
3578 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3579
3580 spin_lock_irq(&drm_dev->event_lock);
3581 acrtc->dm_irq_params.window_param[0].x_start = (uint16_t) val;
3582 acrtc->dm_irq_params.window_param[0].update_win = false;
3583 spin_unlock_irq(&drm_dev->event_lock);
3584
3585 return 0;
3586 }
3587
3588 /*
3589 * Get crc window coordinate x start
3590 */
crc_win_x_start_get(void * data,u64 * val)3591 static int crc_win_x_start_get(void *data, u64 *val)
3592 {
3593 struct drm_crtc *crtc = data;
3594 struct drm_device *drm_dev = crtc->dev;
3595 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3596
3597 spin_lock_irq(&drm_dev->event_lock);
3598 *val = acrtc->dm_irq_params.window_param[0].x_start;
3599 spin_unlock_irq(&drm_dev->event_lock);
3600
3601 return 0;
3602 }
3603
3604 DEFINE_DEBUGFS_ATTRIBUTE(crc_win_x_start_fops, crc_win_x_start_get,
3605 crc_win_x_start_set, "%llu\n");
3606
3607
3608 /*
3609 * Set crc window coordinate y start
3610 */
crc_win_y_start_set(void * data,u64 val)3611 static int crc_win_y_start_set(void *data, u64 val)
3612 {
3613 struct drm_crtc *crtc = data;
3614 struct drm_device *drm_dev = crtc->dev;
3615 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3616
3617 spin_lock_irq(&drm_dev->event_lock);
3618 acrtc->dm_irq_params.window_param[0].y_start = (uint16_t) val;
3619 acrtc->dm_irq_params.window_param[0].update_win = false;
3620 spin_unlock_irq(&drm_dev->event_lock);
3621
3622 return 0;
3623 }
3624
3625 /*
3626 * Get crc window coordinate y start
3627 */
crc_win_y_start_get(void * data,u64 * val)3628 static int crc_win_y_start_get(void *data, u64 *val)
3629 {
3630 struct drm_crtc *crtc = data;
3631 struct drm_device *drm_dev = crtc->dev;
3632 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3633
3634 spin_lock_irq(&drm_dev->event_lock);
3635 *val = acrtc->dm_irq_params.window_param[0].y_start;
3636 spin_unlock_irq(&drm_dev->event_lock);
3637
3638 return 0;
3639 }
3640
3641 DEFINE_DEBUGFS_ATTRIBUTE(crc_win_y_start_fops, crc_win_y_start_get,
3642 crc_win_y_start_set, "%llu\n");
3643
3644 /*
3645 * Set crc window coordinate x end
3646 */
crc_win_x_end_set(void * data,u64 val)3647 static int crc_win_x_end_set(void *data, u64 val)
3648 {
3649 struct drm_crtc *crtc = data;
3650 struct drm_device *drm_dev = crtc->dev;
3651 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3652
3653 spin_lock_irq(&drm_dev->event_lock);
3654 acrtc->dm_irq_params.window_param[0].x_end = (uint16_t) val;
3655 acrtc->dm_irq_params.window_param[0].update_win = false;
3656 spin_unlock_irq(&drm_dev->event_lock);
3657
3658 return 0;
3659 }
3660
3661 /*
3662 * Get crc window coordinate x end
3663 */
crc_win_x_end_get(void * data,u64 * val)3664 static int crc_win_x_end_get(void *data, u64 *val)
3665 {
3666 struct drm_crtc *crtc = data;
3667 struct drm_device *drm_dev = crtc->dev;
3668 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3669
3670 spin_lock_irq(&drm_dev->event_lock);
3671 *val = acrtc->dm_irq_params.window_param[0].x_end;
3672 spin_unlock_irq(&drm_dev->event_lock);
3673
3674 return 0;
3675 }
3676
3677 DEFINE_DEBUGFS_ATTRIBUTE(crc_win_x_end_fops, crc_win_x_end_get,
3678 crc_win_x_end_set, "%llu\n");
3679
3680 /*
3681 * Set crc window coordinate y end
3682 */
crc_win_y_end_set(void * data,u64 val)3683 static int crc_win_y_end_set(void *data, u64 val)
3684 {
3685 struct drm_crtc *crtc = data;
3686 struct drm_device *drm_dev = crtc->dev;
3687 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3688
3689 spin_lock_irq(&drm_dev->event_lock);
3690 acrtc->dm_irq_params.window_param[0].y_end = (uint16_t) val;
3691 acrtc->dm_irq_params.window_param[0].update_win = false;
3692 spin_unlock_irq(&drm_dev->event_lock);
3693
3694 return 0;
3695 }
3696
3697 /*
3698 * Get crc window coordinate y end
3699 */
crc_win_y_end_get(void * data,u64 * val)3700 static int crc_win_y_end_get(void *data, u64 *val)
3701 {
3702 struct drm_crtc *crtc = data;
3703 struct drm_device *drm_dev = crtc->dev;
3704 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
3705
3706 spin_lock_irq(&drm_dev->event_lock);
3707 *val = acrtc->dm_irq_params.window_param[0].y_end;
3708 spin_unlock_irq(&drm_dev->event_lock);
3709
3710 return 0;
3711 }
3712
3713 DEFINE_DEBUGFS_ATTRIBUTE(crc_win_y_end_fops, crc_win_y_end_get,
3714 crc_win_y_end_set, "%llu\n");
3715 /*
3716 * Trigger to commit crc window
3717 */
crc_win_update_set(void * data,u64 val)3718 static int crc_win_update_set(void *data, u64 val)
3719 {
3720 struct drm_crtc *crtc = data;
3721 struct amdgpu_crtc *acrtc;
3722 struct amdgpu_device *adev = drm_to_adev(crtc->dev);
3723
3724 if (val) {
3725 acrtc = to_amdgpu_crtc(crtc);
3726 mutex_lock(&adev->dm.dc_lock);
3727 /* PSR may write to OTG CRC window control register,
3728 * so close it before starting secure_display.
3729 */
3730 amdgpu_dm_psr_disable(acrtc->dm_irq_params.stream, true);
3731
3732 spin_lock_irq(&adev_to_drm(adev)->event_lock);
3733
3734 acrtc->dm_irq_params.window_param[0].enable = true;
3735 acrtc->dm_irq_params.window_param[0].update_win = true;
3736 acrtc->dm_irq_params.window_param[0].skip_frame_cnt = 0;
3737 acrtc->dm_irq_params.crc_window_activated = true;
3738
3739 spin_unlock_irq(&adev_to_drm(adev)->event_lock);
3740 mutex_unlock(&adev->dm.dc_lock);
3741 }
3742
3743 return 0;
3744 }
3745
3746 /*
3747 * Get crc window update flag
3748 */
crc_win_update_get(void * data,u64 * val)3749 static int crc_win_update_get(void *data, u64 *val)
3750 {
3751 *val = 0;
3752 return 0;
3753 }
3754
3755 DEFINE_DEBUGFS_ATTRIBUTE(crc_win_update_fops, crc_win_update_get,
3756 crc_win_update_set, "%llu\n");
3757 #endif
crtc_debugfs_init(struct drm_crtc * crtc)3758 void crtc_debugfs_init(struct drm_crtc *crtc)
3759 {
3760 #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
3761 struct dentry *dir = debugfs_lookup("crc", crtc->debugfs_entry);
3762
3763 if (!dir)
3764 return;
3765
3766 debugfs_create_file_unsafe("crc_win_x_start", 0644, dir, crtc,
3767 &crc_win_x_start_fops);
3768 debugfs_create_file_unsafe("crc_win_y_start", 0644, dir, crtc,
3769 &crc_win_y_start_fops);
3770 debugfs_create_file_unsafe("crc_win_x_end", 0644, dir, crtc,
3771 &crc_win_x_end_fops);
3772 debugfs_create_file_unsafe("crc_win_y_end", 0644, dir, crtc,
3773 &crc_win_y_end_fops);
3774 debugfs_create_file_unsafe("crc_win_update", 0644, dir, crtc,
3775 &crc_win_update_fops);
3776 dput(dir);
3777 #endif
3778 debugfs_create_file("amdgpu_current_bpc", 0644, crtc->debugfs_entry,
3779 crtc, &amdgpu_current_bpc_fops);
3780 debugfs_create_file("amdgpu_current_colorspace", 0644, crtc->debugfs_entry,
3781 crtc, &amdgpu_current_colorspace_fops);
3782 }
3783
3784 /*
3785 * Writes DTN log state to the user supplied buffer.
3786 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log
3787 */
dtn_log_read(struct file * f,char __user * buf,size_t size,loff_t * pos)3788 static ssize_t dtn_log_read(
3789 struct file *f,
3790 char __user *buf,
3791 size_t size,
3792 loff_t *pos)
3793 {
3794 struct amdgpu_device *adev = file_inode(f)->i_private;
3795 struct dc *dc = adev->dm.dc;
3796 struct dc_log_buffer_ctx log_ctx = { 0 };
3797 ssize_t result = 0;
3798
3799 if (!buf || !size)
3800 return -EINVAL;
3801
3802 if (!dc->hwss.log_hw_state)
3803 return 0;
3804
3805 dc->hwss.log_hw_state(dc, &log_ctx);
3806
3807 if (*pos < log_ctx.pos) {
3808 size_t to_copy = log_ctx.pos - *pos;
3809
3810 to_copy = min(to_copy, size);
3811
3812 if (!copy_to_user(buf, log_ctx.buf + *pos, to_copy)) {
3813 *pos += to_copy;
3814 result = to_copy;
3815 }
3816 }
3817
3818 kfree(log_ctx.buf);
3819
3820 return result;
3821 }
3822
3823 /*
3824 * Writes DTN log state to dmesg when triggered via a write.
3825 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log
3826 */
dtn_log_write(struct file * f,const char __user * buf,size_t size,loff_t * pos)3827 static ssize_t dtn_log_write(
3828 struct file *f,
3829 const char __user *buf,
3830 size_t size,
3831 loff_t *pos)
3832 {
3833 struct amdgpu_device *adev = file_inode(f)->i_private;
3834 struct dc *dc = adev->dm.dc;
3835
3836 /* Write triggers log output via dmesg. */
3837 if (size == 0)
3838 return 0;
3839
3840 if (dc->hwss.log_hw_state)
3841 dc->hwss.log_hw_state(dc, NULL);
3842
3843 return size;
3844 }
3845
mst_topo_show(struct seq_file * m,void * unused)3846 static int mst_topo_show(struct seq_file *m, void *unused)
3847 {
3848 struct amdgpu_device *adev = (struct amdgpu_device *)m->private;
3849 struct drm_device *dev = adev_to_drm(adev);
3850 struct drm_connector *connector;
3851 struct drm_connector_list_iter conn_iter;
3852 struct amdgpu_dm_connector *aconnector;
3853
3854 drm_connector_list_iter_begin(dev, &conn_iter);
3855 drm_for_each_connector_iter(connector, &conn_iter) {
3856 if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
3857 continue;
3858
3859 aconnector = to_amdgpu_dm_connector(connector);
3860
3861 /* Ensure we're only dumping the topology of a root mst node */
3862 if (!aconnector->mst_mgr.mst_state)
3863 continue;
3864
3865 seq_printf(m, "\nMST topology for connector %d\n", aconnector->connector_id);
3866 drm_dp_mst_dump_topology(m, &aconnector->mst_mgr);
3867 }
3868 drm_connector_list_iter_end(&conn_iter);
3869
3870 return 0;
3871 }
3872
3873 /*
3874 * Sets trigger hpd for MST topologies.
3875 * All connected connectors will be rediscovered and re started as needed if val of 1 is sent.
3876 * All topologies will be disconnected if val of 0 is set .
3877 * Usage to enable topologies: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_trigger_hpd_mst
3878 * Usage to disable topologies: echo 0 > /sys/kernel/debug/dri/0/amdgpu_dm_trigger_hpd_mst
3879 */
trigger_hpd_mst_set(void * data,u64 val)3880 static int trigger_hpd_mst_set(void *data, u64 val)
3881 {
3882 struct amdgpu_device *adev = data;
3883 struct drm_device *dev = adev_to_drm(adev);
3884 struct drm_connector_list_iter iter;
3885 struct amdgpu_dm_connector *aconnector;
3886 struct drm_connector *connector;
3887 struct dc_link *link = NULL;
3888 int ret;
3889
3890 if (val == 1) {
3891 drm_connector_list_iter_begin(dev, &iter);
3892 drm_for_each_connector_iter(connector, &iter) {
3893 aconnector = to_amdgpu_dm_connector(connector);
3894 if (aconnector->dc_link->type == dc_connection_mst_branch &&
3895 aconnector->mst_mgr.aux) {
3896 mutex_lock(&adev->dm.dc_lock);
3897 ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
3898 mutex_unlock(&adev->dm.dc_lock);
3899
3900 if (!ret)
3901 DRM_ERROR("DM_MST: Failed to detect dc link!");
3902
3903 ret = drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true);
3904 if (ret < 0)
3905 DRM_ERROR("DM_MST: Failed to set the device into MST mode!");
3906 }
3907 }
3908 } else if (val == 0) {
3909 drm_connector_list_iter_begin(dev, &iter);
3910 drm_for_each_connector_iter(connector, &iter) {
3911 aconnector = to_amdgpu_dm_connector(connector);
3912 if (!aconnector->dc_link)
3913 continue;
3914
3915 if (!aconnector->mst_root)
3916 continue;
3917
3918 link = aconnector->dc_link;
3919 dc_link_dp_receiver_power_ctrl(link, false);
3920 drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_root->mst_mgr, false);
3921 link->mst_stream_alloc_table.stream_count = 0;
3922 memset(link->mst_stream_alloc_table.stream_allocations, 0,
3923 sizeof(link->mst_stream_alloc_table.stream_allocations));
3924 }
3925 } else {
3926 return 0;
3927 }
3928 drm_kms_helper_hotplug_event(dev);
3929
3930 return 0;
3931 }
3932
3933 /*
3934 * The interface doesn't need get function, so it will return the
3935 * value of zero
3936 * Usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_trigger_hpd_mst
3937 */
trigger_hpd_mst_get(void * data,u64 * val)3938 static int trigger_hpd_mst_get(void *data, u64 *val)
3939 {
3940 *val = 0;
3941 return 0;
3942 }
3943
3944 DEFINE_DEBUGFS_ATTRIBUTE(trigger_hpd_mst_ops, trigger_hpd_mst_get,
3945 trigger_hpd_mst_set, "%llu\n");
3946
3947
3948 /*
3949 * Sets the force_timing_sync debug option from the given string.
3950 * All connected displays will be force synchronized immediately.
3951 * Usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_force_timing_sync
3952 */
force_timing_sync_set(void * data,u64 val)3953 static int force_timing_sync_set(void *data, u64 val)
3954 {
3955 struct amdgpu_device *adev = data;
3956
3957 adev->dm.force_timing_sync = (bool)val;
3958
3959 amdgpu_dm_trigger_timing_sync(adev_to_drm(adev));
3960
3961 return 0;
3962 }
3963
3964 /*
3965 * Gets the force_timing_sync debug option value into the given buffer.
3966 * Usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_force_timing_sync
3967 */
force_timing_sync_get(void * data,u64 * val)3968 static int force_timing_sync_get(void *data, u64 *val)
3969 {
3970 struct amdgpu_device *adev = data;
3971
3972 *val = adev->dm.force_timing_sync;
3973
3974 return 0;
3975 }
3976
3977 DEFINE_DEBUGFS_ATTRIBUTE(force_timing_sync_ops, force_timing_sync_get,
3978 force_timing_sync_set, "%llu\n");
3979
3980
3981 /*
3982 * Disables all HPD and HPD RX interrupt handling in the
3983 * driver when set to 1. Default is 0.
3984 */
disable_hpd_set(void * data,u64 val)3985 static int disable_hpd_set(void *data, u64 val)
3986 {
3987 struct amdgpu_device *adev = data;
3988
3989 adev->dm.disable_hpd_irq = (bool)val;
3990
3991 return 0;
3992 }
3993
3994
3995 /*
3996 * Returns 1 if HPD and HPRX interrupt handling is disabled,
3997 * 0 otherwise.
3998 */
disable_hpd_get(void * data,u64 * val)3999 static int disable_hpd_get(void *data, u64 *val)
4000 {
4001 struct amdgpu_device *adev = data;
4002
4003 *val = adev->dm.disable_hpd_irq;
4004
4005 return 0;
4006 }
4007
4008 DEFINE_DEBUGFS_ATTRIBUTE(disable_hpd_ops, disable_hpd_get,
4009 disable_hpd_set, "%llu\n");
4010
4011 /*
4012 * Prints hardware capabilities. These are used for IGT testing.
4013 */
capabilities_show(struct seq_file * m,void * unused)4014 static int capabilities_show(struct seq_file *m, void *unused)
4015 {
4016 struct amdgpu_device *adev = (struct amdgpu_device *)m->private;
4017 struct dc *dc = adev->dm.dc;
4018 bool mall_supported = dc->caps.mall_size_total;
4019 bool subvp_supported = dc->caps.subvp_fw_processing_delay_us;
4020 unsigned int mall_in_use = false;
4021 unsigned int subvp_in_use = false;
4022
4023 struct hubbub *hubbub = dc->res_pool->hubbub;
4024
4025 if (hubbub && hubbub->funcs->get_mall_en)
4026 hubbub->funcs->get_mall_en(hubbub, &mall_in_use);
4027
4028 if (dc->cap_funcs.get_subvp_en)
4029 subvp_in_use = dc->cap_funcs.get_subvp_en(dc, dc->current_state);
4030
4031 seq_printf(m, "mall supported: %s, enabled: %s\n",
4032 mall_supported ? "yes" : "no", mall_in_use ? "yes" : "no");
4033 seq_printf(m, "sub-viewport supported: %s, enabled: %s\n",
4034 subvp_supported ? "yes" : "no", subvp_in_use ? "yes" : "no");
4035
4036 return 0;
4037 }
4038
4039 DEFINE_SHOW_ATTRIBUTE(capabilities);
4040
4041 /*
4042 * Temporary w/a to force sst sequence in M42D DP2 mst receiver
4043 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dp_set_mst_en_for_sst
4044 */
dp_force_sst_set(void * data,u64 val)4045 static int dp_force_sst_set(void *data, u64 val)
4046 {
4047 struct amdgpu_device *adev = data;
4048
4049 adev->dm.dc->debug.set_mst_en_for_sst = val;
4050
4051 return 0;
4052 }
4053
dp_force_sst_get(void * data,u64 * val)4054 static int dp_force_sst_get(void *data, u64 *val)
4055 {
4056 struct amdgpu_device *adev = data;
4057
4058 *val = adev->dm.dc->debug.set_mst_en_for_sst;
4059
4060 return 0;
4061 }
4062 DEFINE_DEBUGFS_ATTRIBUTE(dp_set_mst_en_for_sst_ops, dp_force_sst_get,
4063 dp_force_sst_set, "%llu\n");
4064
4065 /*
4066 * Force DP2 sequence without VESA certified cable.
4067 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dp_ignore_cable_id
4068 */
dp_ignore_cable_id_set(void * data,u64 val)4069 static int dp_ignore_cable_id_set(void *data, u64 val)
4070 {
4071 struct amdgpu_device *adev = data;
4072
4073 adev->dm.dc->debug.ignore_cable_id = val;
4074
4075 return 0;
4076 }
4077
dp_ignore_cable_id_get(void * data,u64 * val)4078 static int dp_ignore_cable_id_get(void *data, u64 *val)
4079 {
4080 struct amdgpu_device *adev = data;
4081
4082 *val = adev->dm.dc->debug.ignore_cable_id;
4083
4084 return 0;
4085 }
4086 DEFINE_DEBUGFS_ATTRIBUTE(dp_ignore_cable_id_ops, dp_ignore_cable_id_get,
4087 dp_ignore_cable_id_set, "%llu\n");
4088
4089 /*
4090 * Sets the DC visual confirm debug option from the given string.
4091 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_visual_confirm
4092 */
visual_confirm_set(void * data,u64 val)4093 static int visual_confirm_set(void *data, u64 val)
4094 {
4095 struct amdgpu_device *adev = data;
4096
4097 adev->dm.dc->debug.visual_confirm = (enum visual_confirm)val;
4098
4099 return 0;
4100 }
4101
4102 /*
4103 * Reads the DC visual confirm debug option value into the given buffer.
4104 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_visual_confirm
4105 */
visual_confirm_get(void * data,u64 * val)4106 static int visual_confirm_get(void *data, u64 *val)
4107 {
4108 struct amdgpu_device *adev = data;
4109
4110 *val = adev->dm.dc->debug.visual_confirm;
4111
4112 return 0;
4113 }
4114
4115 DEFINE_SHOW_ATTRIBUTE(mst_topo);
4116 DEFINE_DEBUGFS_ATTRIBUTE(visual_confirm_fops, visual_confirm_get,
4117 visual_confirm_set, "%llu\n");
4118
4119
4120 /*
4121 * Sets the DC skip_detection_link_training debug option from the given string.
4122 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_skip_detection_link_training
4123 */
skip_detection_link_training_set(void * data,u64 val)4124 static int skip_detection_link_training_set(void *data, u64 val)
4125 {
4126 struct amdgpu_device *adev = data;
4127
4128 if (val == 0)
4129 adev->dm.dc->debug.skip_detection_link_training = false;
4130 else
4131 adev->dm.dc->debug.skip_detection_link_training = true;
4132
4133 return 0;
4134 }
4135
4136 /*
4137 * Reads the DC skip_detection_link_training debug option value into the given buffer.
4138 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_skip_detection_link_training
4139 */
skip_detection_link_training_get(void * data,u64 * val)4140 static int skip_detection_link_training_get(void *data, u64 *val)
4141 {
4142 struct amdgpu_device *adev = data;
4143
4144 *val = adev->dm.dc->debug.skip_detection_link_training;
4145
4146 return 0;
4147 }
4148
4149 DEFINE_DEBUGFS_ATTRIBUTE(skip_detection_link_training_fops,
4150 skip_detection_link_training_get,
4151 skip_detection_link_training_set, "%llu\n");
4152
4153 /*
4154 * Dumps the DCC_EN bit for each pipe.
4155 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dcc_en
4156 */
dcc_en_bits_read(struct file * f,char __user * buf,size_t size,loff_t * pos)4157 static ssize_t dcc_en_bits_read(
4158 struct file *f,
4159 char __user *buf,
4160 size_t size,
4161 loff_t *pos)
4162 {
4163 struct amdgpu_device *adev = file_inode(f)->i_private;
4164 struct dc *dc = adev->dm.dc;
4165 char *rd_buf = NULL;
4166 const uint32_t rd_buf_size = 32;
4167 uint32_t result = 0;
4168 int offset = 0;
4169 int num_pipes = dc->res_pool->pipe_count;
4170 int *dcc_en_bits;
4171 int i, r;
4172
4173 dcc_en_bits = kcalloc(num_pipes, sizeof(int), GFP_KERNEL);
4174 if (!dcc_en_bits)
4175 return -ENOMEM;
4176
4177 if (!dc->hwss.get_dcc_en_bits) {
4178 kfree(dcc_en_bits);
4179 return 0;
4180 }
4181
4182 dc->hwss.get_dcc_en_bits(dc, dcc_en_bits);
4183
4184 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
4185 if (!rd_buf) {
4186 kfree(dcc_en_bits);
4187 return -ENOMEM;
4188 }
4189
4190 for (i = 0; i < num_pipes; i++)
4191 offset += snprintf(rd_buf + offset, rd_buf_size - offset,
4192 "%d ", dcc_en_bits[i]);
4193 rd_buf[strlen(rd_buf)] = '\n';
4194
4195 kfree(dcc_en_bits);
4196
4197 while (size) {
4198 if (*pos >= rd_buf_size)
4199 break;
4200 r = put_user(*(rd_buf + result), buf);
4201 if (r) {
4202 kfree(rd_buf);
4203 return r; /* r = -EFAULT */
4204 }
4205 buf += 1;
4206 size -= 1;
4207 *pos += 1;
4208 result += 1;
4209 }
4210
4211 kfree(rd_buf);
4212 return result;
4213 }
4214
dtn_debugfs_init(struct amdgpu_device * adev)4215 void dtn_debugfs_init(struct amdgpu_device *adev)
4216 {
4217 static const struct file_operations dtn_log_fops = {
4218 .owner = THIS_MODULE,
4219 .read = dtn_log_read,
4220 .write = dtn_log_write,
4221 .llseek = default_llseek
4222 };
4223 static const struct file_operations dcc_en_bits_fops = {
4224 .owner = THIS_MODULE,
4225 .read = dcc_en_bits_read,
4226 .llseek = default_llseek
4227 };
4228
4229 struct drm_minor *minor = adev_to_drm(adev)->primary;
4230 struct dentry *root = minor->debugfs_root;
4231
4232 debugfs_create_file("amdgpu_mst_topology", 0444, root,
4233 adev, &mst_topo_fops);
4234 debugfs_create_file("amdgpu_dm_capabilities", 0444, root,
4235 adev, &capabilities_fops);
4236 debugfs_create_file("amdgpu_dm_dtn_log", 0644, root, adev,
4237 &dtn_log_fops);
4238 debugfs_create_file("amdgpu_dm_dp_set_mst_en_for_sst", 0644, root, adev,
4239 &dp_set_mst_en_for_sst_ops);
4240 debugfs_create_file("amdgpu_dm_dp_ignore_cable_id", 0644, root, adev,
4241 &dp_ignore_cable_id_ops);
4242
4243 debugfs_create_file_unsafe("amdgpu_dm_visual_confirm", 0644, root, adev,
4244 &visual_confirm_fops);
4245
4246 debugfs_create_file_unsafe("amdgpu_dm_skip_detection_link_training", 0644, root, adev,
4247 &skip_detection_link_training_fops);
4248
4249 debugfs_create_file_unsafe("amdgpu_dm_dmub_tracebuffer", 0644, root,
4250 adev, &dmub_tracebuffer_fops);
4251
4252 debugfs_create_file_unsafe("amdgpu_dm_dmub_fw_state", 0644, root,
4253 adev, &dmub_fw_state_fops);
4254
4255 debugfs_create_file_unsafe("amdgpu_dm_force_timing_sync", 0644, root,
4256 adev, &force_timing_sync_ops);
4257
4258 debugfs_create_file_unsafe("amdgpu_dm_dmub_trace_mask", 0644, root,
4259 adev, &dmub_trace_mask_fops);
4260
4261 debugfs_create_file_unsafe("amdgpu_dm_dmcub_trace_event_en", 0644, root,
4262 adev, &dmcub_trace_event_state_fops);
4263
4264 debugfs_create_file_unsafe("amdgpu_dm_trigger_hpd_mst", 0644, root,
4265 adev, &trigger_hpd_mst_ops);
4266
4267 debugfs_create_file_unsafe("amdgpu_dm_dcc_en", 0644, root, adev,
4268 &dcc_en_bits_fops);
4269
4270 debugfs_create_file_unsafe("amdgpu_dm_disable_hpd", 0644, root, adev,
4271 &disable_hpd_ops);
4272
4273 if (adev->dm.dc->caps.ips_support)
4274 debugfs_create_file_unsafe("amdgpu_dm_ips_status", 0644, root, adev,
4275 &ips_status_fops);
4276 }
4277