2 * Copyright 2018 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
26 #include <linux/uaccess.h>
28 #include <drm/drm_debugfs.h>
32 #include "amdgpu_dm.h"
33 #include "amdgpu_dm_debugfs.h"
34 #include "dm_helpers.h"
35 #include "dmub/dmub_srv.h"
39 struct dmub_debugfs_trace_header {
44 struct dmub_debugfs_trace_entry {
52 /* parse_write_buffer_into_params - Helper function to parse debugfs write buffer into an array
54 * Function takes in attributes passed to debugfs write entry
55 * and writes into param array.
56 * The user passes max_param_num to identify maximum number of
57 * parameters that could be parsed.
60 static int parse_write_buffer_into_params(char *wr_buf, uint32_t wr_buf_size,
61 long *param, const char __user *buf,
65 char *wr_buf_ptr = NULL;
66 uint32_t wr_buf_count = 0;
69 const char delimiter[3] = {' ', '\n', '\0'};
70 uint8_t param_index = 0;
76 r = copy_from_user(wr_buf_ptr, buf, wr_buf_size);
78 /* r is bytes not be copied */
79 if (r >= wr_buf_size) {
80 DRM_DEBUG_DRIVER("user data not be read\n");
84 /* check number of parameters. isspace could not differ space and \n */
85 while ((*wr_buf_ptr != 0xa) && (wr_buf_count < wr_buf_size)) {
87 while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) {
92 if (wr_buf_count == wr_buf_size)
96 while ((!isspace(*wr_buf_ptr)) && (wr_buf_count < wr_buf_size)) {
103 if (wr_buf_count == wr_buf_size)
107 if (*param_nums > max_param_num)
108 *param_nums = max_param_num;
111 wr_buf_ptr = wr_buf; /* reset buf pointer */
112 wr_buf_count = 0; /* number of char already checked */
114 while (isspace(*wr_buf_ptr) && (wr_buf_count < wr_buf_size)) {
119 while (param_index < *param_nums) {
120 /* after strsep, wr_buf_ptr will be moved to after space */
121 sub_str = strsep(&wr_buf_ptr, delimiter);
123 r = kstrtol(sub_str, 16, &(param[param_index]));
126 DRM_DEBUG_DRIVER("string to int convert error code: %d\n", r);
134 /* function description
135 * get/ set DP configuration: lane_count, link_rate, spread_spectrum
137 * valid lane count value: 1, 2, 4
138 * valid link rate value:
139 * 06h = 1.62Gbps per lane
140 * 0Ah = 2.7Gbps per lane
141 * 0Ch = 3.24Gbps per lane
142 * 14h = 5.4Gbps per lane
143 * 1Eh = 8.1Gbps per lane
145 * debugfs is located at /sys/kernel/debug/dri/0/DP-x/link_settings
147 * --- to get dp configuration
151 * It will list current, verified, reported, preferred dp configuration.
152 * current -- for current video mode
153 * verified --- maximum configuration which pass link training
154 * reported --- DP rx report caps (DPCD register offset 0, 1 2)
155 * preferred --- user force settings
157 * --- set (or force) dp configuration
159 * echo <lane_count> <link_rate> > link_settings
161 * for example, to force to 2 lane, 2.7GHz,
162 * echo 4 0xa > link_settings
164 * spread_spectrum could not be changed dynamically.
166 * in case invalid lane count, link rate are force, no hw programming will be
167 * done. please check link settings after force operation to see if HW get
172 * check current and preferred settings.
175 static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
176 size_t size, loff_t *pos)
178 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
179 struct dc_link *link = connector->dc_link;
181 char *rd_buf_ptr = NULL;
182 const uint32_t rd_buf_size = 100;
187 if (*pos & 3 || size & 3)
190 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
196 str_len = strlen("Current: %d %d %d ");
197 snprintf(rd_buf_ptr, str_len, "Current: %d %d %d ",
198 link->cur_link_settings.lane_count,
199 link->cur_link_settings.link_rate,
200 link->cur_link_settings.link_spread);
201 rd_buf_ptr += str_len;
203 str_len = strlen("Verified: %d %d %d ");
204 snprintf(rd_buf_ptr, str_len, "Verified: %d %d %d ",
205 link->verified_link_cap.lane_count,
206 link->verified_link_cap.link_rate,
207 link->verified_link_cap.link_spread);
208 rd_buf_ptr += str_len;
210 str_len = strlen("Reported: %d %d %d ");
211 snprintf(rd_buf_ptr, str_len, "Reported: %d %d %d ",
212 link->reported_link_cap.lane_count,
213 link->reported_link_cap.link_rate,
214 link->reported_link_cap.link_spread);
215 rd_buf_ptr += str_len;
217 str_len = strlen("Preferred: %d %d %d ");
218 snprintf(rd_buf_ptr, str_len, "Preferred: %d %d %d\n",
219 link->preferred_link_setting.lane_count,
220 link->preferred_link_setting.link_rate,
221 link->preferred_link_setting.link_spread);
224 if (*pos >= rd_buf_size)
227 r = put_user(*(rd_buf + result), buf);
229 return r; /* r = -EFAULT */
241 static ssize_t dp_link_settings_write(struct file *f, const char __user *buf,
242 size_t size, loff_t *pos)
244 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
245 struct dc_link *link = connector->dc_link;
246 struct dc *dc = (struct dc *)link->dc;
247 struct dc_link_settings prefer_link_settings;
249 const uint32_t wr_buf_size = 40;
250 /* 0: lane_count; 1: link_rate */
251 int max_param_num = 2;
252 uint8_t param_nums = 0;
254 bool valid_input = false;
259 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
263 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
271 if (param_nums <= 0) {
273 DRM_DEBUG_DRIVER("user data not be read\n");
280 case LANE_COUNT_FOUR:
291 case LINK_RATE_HIGH2:
292 case LINK_RATE_HIGH3:
301 DRM_DEBUG_DRIVER("Invalid Input value No HW will be programmed\n");
305 /* save user force lane_count, link_rate to preferred settings
306 * spread spectrum will not be changed
308 prefer_link_settings.link_spread = link->cur_link_settings.link_spread;
309 prefer_link_settings.lane_count = param[0];
310 prefer_link_settings.link_rate = param[1];
312 dc_link_set_preferred_link_settings(dc, &prefer_link_settings, link);
318 /* function: get current DP PHY settings: voltage swing, pre-emphasis,
319 * post-cursor2 (defined by VESA DP specification)
322 * voltage swing: 0,1,2,3
323 * pre-emphasis : 0,1,2,3
324 * post cursor2 : 0,1,2,3
327 * how to use this debugfs
329 * debugfs is located at /sys/kernel/debug/dri/0/DP-x
331 * there will be directories, like DP-1, DP-2,DP-3, etc. for DP display
333 * To figure out which DP-x is the display for DP to be check,
336 * There should be debugfs file, like link_settings, phy_settings.
338 * from lane_count, link_rate to figure which DP-x is for display to be worked
341 * To get current DP PHY settings,
344 * To change DP PHY settings,
345 * echo <voltage_swing> <pre-emphasis> <post_cursor2> > phy_settings
346 * for examle, to change voltage swing to 2, pre-emphasis to 3, post_cursor2 to
348 * echo 2 3 0 > phy_settings
350 * To check if change be applied, get current phy settings by
353 * In case invalid values are set by user, like
354 * echo 1 4 0 > phy_settings
356 * HW will NOT be programmed by these settings.
357 * cat phy_settings will show the previous valid settings.
359 static ssize_t dp_phy_settings_read(struct file *f, char __user *buf,
360 size_t size, loff_t *pos)
362 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
363 struct dc_link *link = connector->dc_link;
365 const uint32_t rd_buf_size = 20;
369 if (*pos & 3 || size & 3)
372 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
376 snprintf(rd_buf, rd_buf_size, " %d %d %d ",
377 link->cur_lane_setting.VOLTAGE_SWING,
378 link->cur_lane_setting.PRE_EMPHASIS,
379 link->cur_lane_setting.POST_CURSOR2);
382 if (*pos >= rd_buf_size)
385 r = put_user((*(rd_buf + result)), buf);
387 return r; /* r = -EFAULT */
399 static ssize_t dp_phy_settings_write(struct file *f, const char __user *buf,
400 size_t size, loff_t *pos)
402 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
403 struct dc_link *link = connector->dc_link;
404 struct dc *dc = (struct dc *)link->dc;
406 uint32_t wr_buf_size = 40;
408 bool use_prefer_link_setting;
409 struct link_training_settings link_lane_settings;
410 int max_param_num = 3;
411 uint8_t param_nums = 0;
418 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
422 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
430 if (param_nums <= 0) {
432 DRM_DEBUG_DRIVER("user data not be read\n");
436 if ((param[0] > VOLTAGE_SWING_MAX_LEVEL) ||
437 (param[1] > PRE_EMPHASIS_MAX_LEVEL) ||
438 (param[2] > POST_CURSOR2_MAX_LEVEL)) {
440 DRM_DEBUG_DRIVER("Invalid Input No HW will be programmed\n");
444 /* get link settings: lane count, link rate */
445 use_prefer_link_setting =
446 ((link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) &&
447 (link->test_pattern_enabled));
449 memset(&link_lane_settings, 0, sizeof(link_lane_settings));
451 if (use_prefer_link_setting) {
452 link_lane_settings.link_settings.lane_count =
453 link->preferred_link_setting.lane_count;
454 link_lane_settings.link_settings.link_rate =
455 link->preferred_link_setting.link_rate;
456 link_lane_settings.link_settings.link_spread =
457 link->preferred_link_setting.link_spread;
459 link_lane_settings.link_settings.lane_count =
460 link->cur_link_settings.lane_count;
461 link_lane_settings.link_settings.link_rate =
462 link->cur_link_settings.link_rate;
463 link_lane_settings.link_settings.link_spread =
464 link->cur_link_settings.link_spread;
467 /* apply phy settings from user */
468 for (r = 0; r < link_lane_settings.link_settings.lane_count; r++) {
469 link_lane_settings.lane_settings[r].VOLTAGE_SWING =
470 (enum dc_voltage_swing) (param[0]);
471 link_lane_settings.lane_settings[r].PRE_EMPHASIS =
472 (enum dc_pre_emphasis) (param[1]);
473 link_lane_settings.lane_settings[r].POST_CURSOR2 =
474 (enum dc_post_cursor2) (param[2]);
477 /* program ASIC registers and DPCD registers */
478 dc_link_set_drive_settings(dc, &link_lane_settings, link);
484 /* function description
486 * set PHY layer or Link layer test pattern
487 * PHY test pattern is used for PHY SI check.
488 * Link layer test will not affect PHY SI.
490 * Reset Test Pattern:
491 * 0 = DP_TEST_PATTERN_VIDEO_MODE
493 * PHY test pattern supported:
494 * 1 = DP_TEST_PATTERN_D102
495 * 2 = DP_TEST_PATTERN_SYMBOL_ERROR
496 * 3 = DP_TEST_PATTERN_PRBS7
497 * 4 = DP_TEST_PATTERN_80BIT_CUSTOM
498 * 5 = DP_TEST_PATTERN_CP2520_1
499 * 6 = DP_TEST_PATTERN_CP2520_2 = DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE
500 * 7 = DP_TEST_PATTERN_CP2520_3
502 * DP PHY Link Training Patterns
503 * 8 = DP_TEST_PATTERN_TRAINING_PATTERN1
504 * 9 = DP_TEST_PATTERN_TRAINING_PATTERN2
505 * a = DP_TEST_PATTERN_TRAINING_PATTERN3
506 * b = DP_TEST_PATTERN_TRAINING_PATTERN4
508 * DP Link Layer Test pattern
509 * c = DP_TEST_PATTERN_COLOR_SQUARES
510 * d = DP_TEST_PATTERN_COLOR_SQUARES_CEA
511 * e = DP_TEST_PATTERN_VERTICAL_BARS
512 * f = DP_TEST_PATTERN_HORIZONTAL_BARS
513 * 10= DP_TEST_PATTERN_COLOR_RAMP
515 * debugfs phy_test_pattern is located at /syskernel/debug/dri/0/DP-x
517 * --- set test pattern
518 * echo <test pattern #> > test_pattern
520 * If test pattern # is not supported, NO HW programming will be done.
521 * for DP_TEST_PATTERN_80BIT_CUSTOM, it needs extra 10 bytes of data
522 * for the user pattern. input 10 bytes data are separated by space
524 * echo 0x4 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x99 0xaa > test_pattern
526 * --- reset test pattern
527 * echo 0 > test_pattern
529 * --- HPD detection is disabled when set PHY test pattern
531 * when PHY test pattern (pattern # within [1,7]) is set, HPD pin of HW ASIC
532 * is disable. User could unplug DP display from DP connected and plug scope to
533 * check test pattern PHY SI.
534 * If there is need unplug scope and plug DP display back, do steps below:
535 * echo 0 > phy_test_pattern
539 * "echo 0 > phy_test_pattern" will re-enable HPD pin again so that video sw
540 * driver could detect "unplug scope" and "plug DP display"
542 static ssize_t dp_phy_test_pattern_debugfs_write(struct file *f, const char __user *buf,
543 size_t size, loff_t *pos)
545 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
546 struct dc_link *link = connector->dc_link;
548 uint32_t wr_buf_size = 100;
549 long param[11] = {0x0};
550 int max_param_num = 11;
551 enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
552 bool disable_hpd = false;
553 bool valid_test_pattern = false;
554 uint8_t param_nums = 0;
555 /* init with defalut 80bit custom pattern */
556 uint8_t custom_pattern[10] = {
557 0x1f, 0x7c, 0xf0, 0xc1, 0x07,
558 0x1f, 0x7c, 0xf0, 0xc1, 0x07
560 struct dc_link_settings prefer_link_settings = {LANE_COUNT_UNKNOWN,
561 LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED};
562 struct dc_link_settings cur_link_settings = {LANE_COUNT_UNKNOWN,
563 LINK_RATE_UNKNOWN, LINK_SPREAD_DISABLED};
564 struct link_training_settings link_training_settings;
570 wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL);
574 if (parse_write_buffer_into_params(wr_buf, wr_buf_size,
582 if (param_nums <= 0) {
584 DRM_DEBUG_DRIVER("user data not be read\n");
589 test_pattern = param[0];
591 switch (test_pattern) {
592 case DP_TEST_PATTERN_VIDEO_MODE:
593 case DP_TEST_PATTERN_COLOR_SQUARES:
594 case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
595 case DP_TEST_PATTERN_VERTICAL_BARS:
596 case DP_TEST_PATTERN_HORIZONTAL_BARS:
597 case DP_TEST_PATTERN_COLOR_RAMP:
598 valid_test_pattern = true;
601 case DP_TEST_PATTERN_D102:
602 case DP_TEST_PATTERN_SYMBOL_ERROR:
603 case DP_TEST_PATTERN_PRBS7:
604 case DP_TEST_PATTERN_80BIT_CUSTOM:
605 case DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE:
606 case DP_TEST_PATTERN_TRAINING_PATTERN4:
608 valid_test_pattern = true;
612 valid_test_pattern = false;
613 test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
617 if (!valid_test_pattern) {
619 DRM_DEBUG_DRIVER("Invalid Test Pattern Parameters\n");
623 if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) {
624 for (i = 0; i < 10; i++) {
625 if ((uint8_t) param[i + 1] != 0x0)
630 /* not use default value */
631 for (i = 0; i < 10; i++)
632 custom_pattern[i] = (uint8_t) param[i + 1];
636 /* Usage: set DP physical test pattern using debugfs with normal DP
637 * panel. Then plug out DP panel and connect a scope to measure
638 * For normal video mode and test pattern generated from CRCT,
639 * they are visibile to user. So do not disable HPD.
640 * Video Mode is also set to clear the test pattern, so enable HPD
641 * because it might have been disabled after a test pattern was set.
642 * AUX depends on HPD * sequence dependent, do not move!
645 dc_link_enable_hpd(link);
647 prefer_link_settings.lane_count = link->verified_link_cap.lane_count;
648 prefer_link_settings.link_rate = link->verified_link_cap.link_rate;
649 prefer_link_settings.link_spread = link->verified_link_cap.link_spread;
651 cur_link_settings.lane_count = link->cur_link_settings.lane_count;
652 cur_link_settings.link_rate = link->cur_link_settings.link_rate;
653 cur_link_settings.link_spread = link->cur_link_settings.link_spread;
655 link_training_settings.link_settings = cur_link_settings;
658 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
659 if (prefer_link_settings.lane_count != LANE_COUNT_UNKNOWN &&
660 prefer_link_settings.link_rate != LINK_RATE_UNKNOWN &&
661 (prefer_link_settings.lane_count != cur_link_settings.lane_count ||
662 prefer_link_settings.link_rate != cur_link_settings.link_rate))
663 link_training_settings.link_settings = prefer_link_settings;
666 for (i = 0; i < (unsigned int)(link_training_settings.link_settings.lane_count); i++)
667 link_training_settings.lane_settings[i] = link->cur_lane_setting;
669 dc_link_set_test_pattern(
672 DP_TEST_PATTERN_COLOR_SPACE_RGB,
673 &link_training_settings,
677 /* Usage: Set DP physical test pattern using AMDDP with normal DP panel
678 * Then plug out DP panel and connect a scope to measure DP PHY signal.
679 * Need disable interrupt to avoid SW driver disable DP output. This is
680 * done after the test pattern is set.
682 if (valid_test_pattern && disable_hpd)
683 dc_link_disable_hpd(link);
691 * Returns the DMCUB tracebuffer contents.
692 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dmub_tracebuffer
694 static int dmub_tracebuffer_show(struct seq_file *m, void *data)
696 struct amdgpu_device *adev = m->private;
697 struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
698 struct dmub_debugfs_trace_entry *entries;
700 uint32_t tbuf_size, max_entries, num_entries, i;
705 tbuf_base = (uint8_t *)fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].cpu_addr;
709 tbuf_size = fb_info->fb[DMUB_WINDOW_5_TRACEBUFF].size;
710 max_entries = (tbuf_size - sizeof(struct dmub_debugfs_trace_header)) /
711 sizeof(struct dmub_debugfs_trace_entry);
714 ((struct dmub_debugfs_trace_header *)tbuf_base)->entry_count;
716 num_entries = min(num_entries, max_entries);
718 entries = (struct dmub_debugfs_trace_entry
720 sizeof(struct dmub_debugfs_trace_header));
722 for (i = 0; i < num_entries; ++i) {
723 struct dmub_debugfs_trace_entry *entry = &entries[i];
726 "trace_code=%u tick_count=%u param0=%u param1=%u\n",
727 entry->trace_code, entry->tick_count, entry->param0,
735 * Returns the DMCUB firmware state contents.
736 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dmub_fw_state
738 static int dmub_fw_state_show(struct seq_file *m, void *data)
740 struct amdgpu_device *adev = m->private;
741 struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info;
748 state_base = (uint8_t *)fb_info->fb[DMUB_WINDOW_6_FW_STATE].cpu_addr;
752 state_size = fb_info->fb[DMUB_WINDOW_6_FW_STATE].size;
754 return seq_write(m, state_base, state_size);
758 * Returns the current and maximum output bpc for the connector.
759 * Example usage: cat /sys/kernel/debug/dri/0/DP-1/output_bpc
761 static int output_bpc_show(struct seq_file *m, void *data)
763 struct drm_connector *connector = m->private;
764 struct drm_device *dev = connector->dev;
765 struct drm_crtc *crtc = NULL;
766 struct dm_crtc_state *dm_crtc_state = NULL;
770 mutex_lock(&dev->mode_config.mutex);
771 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
773 if (connector->state == NULL)
776 crtc = connector->state->crtc;
780 drm_modeset_lock(&crtc->mutex, NULL);
781 if (crtc->state == NULL)
784 dm_crtc_state = to_dm_crtc_state(crtc->state);
785 if (dm_crtc_state->stream == NULL)
788 switch (dm_crtc_state->stream->timing.display_color_depth) {
789 case COLOR_DEPTH_666:
792 case COLOR_DEPTH_888:
795 case COLOR_DEPTH_101010:
798 case COLOR_DEPTH_121212:
801 case COLOR_DEPTH_161616:
808 seq_printf(m, "Current: %u\n", bpc);
809 seq_printf(m, "Maximum: %u\n", connector->display_info.bpc);
814 drm_modeset_unlock(&crtc->mutex);
816 drm_modeset_unlock(&dev->mode_config.connection_mutex);
817 mutex_unlock(&dev->mode_config.mutex);
822 #ifdef CONFIG_DRM_AMD_DC_HDCP
824 * Returns the HDCP capability of the Display (1.4 for now).
826 * NOTE* Not all HDMI displays report their HDCP caps even when they are capable.
827 * Since its rare for a display to not be HDCP 1.4 capable, we set HDMI as always capable.
829 * Example usage: cat /sys/kernel/debug/dri/0/DP-1/hdcp_sink_capability
830 * or cat /sys/kernel/debug/dri/0/HDMI-A-1/hdcp_sink_capability
832 static int hdcp_sink_capability_show(struct seq_file *m, void *data)
834 struct drm_connector *connector = m->private;
835 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
836 bool hdcp_cap, hdcp2_cap;
838 if (connector->status != connector_status_connected)
841 seq_printf(m, "%s:%d HDCP version: ", connector->name, connector->base.id);
843 hdcp_cap = dc_link_is_hdcp14(aconnector->dc_link, aconnector->dc_sink->sink_signal);
844 hdcp2_cap = dc_link_is_hdcp22(aconnector->dc_link, aconnector->dc_sink->sink_signal);
848 seq_printf(m, "%s ", "HDCP1.4");
850 seq_printf(m, "%s ", "HDCP2.2");
852 if (!hdcp_cap && !hdcp2_cap)
853 seq_printf(m, "%s ", "None");
860 /* function description
862 * generic SDP message access for testing
864 * debugfs sdp_message is located at /syskernel/debug/dri/0/DP-x
867 * Hb0 : Secondary-Data Packet ID
868 * Hb1 : Secondary-Data Packet type
869 * Hb2 : Secondary-Data-packet-specific header, Byte 0
870 * Hb3 : Secondary-Data-packet-specific header, Byte 1
872 * for using custom sdp message: input 4 bytes SDP header and 32 bytes raw data
874 static ssize_t dp_sdp_message_debugfs_write(struct file *f, const char __user *buf,
875 size_t size, loff_t *pos)
879 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
880 struct dm_crtc_state *acrtc_state;
881 uint32_t write_size = 36;
883 if (connector->base.status != connector_status_connected)
889 acrtc_state = to_dm_crtc_state(connector->base.state->crtc->state);
891 r = copy_from_user(data, buf, write_size);
895 dc_stream_send_dp_sdp(acrtc_state->stream, data, write_size);
900 static ssize_t dp_dpcd_address_write(struct file *f, const char __user *buf,
901 size_t size, loff_t *pos)
904 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
906 if (size < sizeof(connector->debugfs_dpcd_address))
909 r = copy_from_user(&connector->debugfs_dpcd_address,
910 buf, sizeof(connector->debugfs_dpcd_address));
915 static ssize_t dp_dpcd_size_write(struct file *f, const char __user *buf,
916 size_t size, loff_t *pos)
919 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
921 if (size < sizeof(connector->debugfs_dpcd_size))
924 r = copy_from_user(&connector->debugfs_dpcd_size,
925 buf, sizeof(connector->debugfs_dpcd_size));
927 if (connector->debugfs_dpcd_size > 256)
928 connector->debugfs_dpcd_size = 0;
933 static ssize_t dp_dpcd_data_write(struct file *f, const char __user *buf,
934 size_t size, loff_t *pos)
938 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
939 struct dc_link *link = connector->dc_link;
940 uint32_t write_size = connector->debugfs_dpcd_size;
942 if (size < write_size)
945 data = kzalloc(write_size, GFP_KERNEL);
949 r = copy_from_user(data, buf, write_size);
951 dm_helpers_dp_write_dpcd(link->ctx, link,
952 connector->debugfs_dpcd_address, data, write_size - r);
954 return write_size - r;
957 static ssize_t dp_dpcd_data_read(struct file *f, char __user *buf,
958 size_t size, loff_t *pos)
962 struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
963 struct dc_link *link = connector->dc_link;
964 uint32_t read_size = connector->debugfs_dpcd_size;
966 if (size < read_size)
969 data = kzalloc(read_size, GFP_KERNEL);
973 dm_helpers_dp_read_dpcd(link->ctx, link,
974 connector->debugfs_dpcd_address, data, read_size);
976 r = copy_to_user(buf, data, read_size);
979 return read_size - r;
982 static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
983 size_t size, loff_t *pos)
986 char *rd_buf_ptr = NULL;
987 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
988 struct display_stream_compressor *dsc;
989 struct dcn_dsc_state dsc_state = {0};
990 const uint32_t rd_buf_size = 10;
991 struct pipe_ctx *pipe_ctx;
993 int i, r, str_len = 30;
995 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1000 rd_buf_ptr = rd_buf;
1002 for (i = 0; i < MAX_PIPES; i++) {
1003 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1004 if (pipe_ctx && pipe_ctx->stream &&
1005 pipe_ctx->stream->link == aconnector->dc_link)
1012 dsc = pipe_ctx->stream_res.dsc;
1014 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1016 snprintf(rd_buf_ptr, str_len,
1018 dsc_state.dsc_clock_en);
1019 rd_buf_ptr += str_len;
1022 if (*pos >= rd_buf_size)
1025 r = put_user(*(rd_buf + result), buf);
1027 return r; /* r = -EFAULT */
1039 static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
1040 size_t size, loff_t *pos)
1042 char *rd_buf = NULL;
1043 char *rd_buf_ptr = NULL;
1044 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1045 struct display_stream_compressor *dsc;
1046 struct dcn_dsc_state dsc_state = {0};
1047 const uint32_t rd_buf_size = 100;
1048 struct pipe_ctx *pipe_ctx;
1050 int i, r, str_len = 30;
1052 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1057 rd_buf_ptr = rd_buf;
1059 for (i = 0; i < MAX_PIPES; i++) {
1060 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1061 if (pipe_ctx && pipe_ctx->stream &&
1062 pipe_ctx->stream->link == aconnector->dc_link)
1069 dsc = pipe_ctx->stream_res.dsc;
1071 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1073 snprintf(rd_buf_ptr, str_len,
1075 dsc_state.dsc_slice_width);
1076 rd_buf_ptr += str_len;
1079 if (*pos >= rd_buf_size)
1082 r = put_user(*(rd_buf + result), buf);
1084 return r; /* r = -EFAULT */
1096 static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
1097 size_t size, loff_t *pos)
1099 char *rd_buf = NULL;
1100 char *rd_buf_ptr = NULL;
1101 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1102 struct display_stream_compressor *dsc;
1103 struct dcn_dsc_state dsc_state = {0};
1104 const uint32_t rd_buf_size = 100;
1105 struct pipe_ctx *pipe_ctx;
1107 int i, r, str_len = 30;
1109 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1114 rd_buf_ptr = rd_buf;
1116 for (i = 0; i < MAX_PIPES; i++) {
1117 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1118 if (pipe_ctx && pipe_ctx->stream &&
1119 pipe_ctx->stream->link == aconnector->dc_link)
1126 dsc = pipe_ctx->stream_res.dsc;
1128 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1130 snprintf(rd_buf_ptr, str_len,
1132 dsc_state.dsc_slice_height);
1133 rd_buf_ptr += str_len;
1136 if (*pos >= rd_buf_size)
1139 r = put_user(*(rd_buf + result), buf);
1141 return r; /* r = -EFAULT */
1153 static ssize_t dp_dsc_bytes_per_pixel_read(struct file *f, char __user *buf,
1154 size_t size, loff_t *pos)
1156 char *rd_buf = NULL;
1157 char *rd_buf_ptr = NULL;
1158 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1159 struct display_stream_compressor *dsc;
1160 struct dcn_dsc_state dsc_state = {0};
1161 const uint32_t rd_buf_size = 100;
1162 struct pipe_ctx *pipe_ctx;
1164 int i, r, str_len = 30;
1166 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1171 rd_buf_ptr = rd_buf;
1173 for (i = 0; i < MAX_PIPES; i++) {
1174 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1175 if (pipe_ctx && pipe_ctx->stream &&
1176 pipe_ctx->stream->link == aconnector->dc_link)
1183 dsc = pipe_ctx->stream_res.dsc;
1185 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1187 snprintf(rd_buf_ptr, str_len,
1189 dsc_state.dsc_bytes_per_pixel);
1190 rd_buf_ptr += str_len;
1193 if (*pos >= rd_buf_size)
1196 r = put_user(*(rd_buf + result), buf);
1198 return r; /* r = -EFAULT */
1210 static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
1211 size_t size, loff_t *pos)
1213 char *rd_buf = NULL;
1214 char *rd_buf_ptr = NULL;
1215 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1216 struct display_stream_compressor *dsc;
1217 struct dcn_dsc_state dsc_state = {0};
1218 const uint32_t rd_buf_size = 100;
1219 struct pipe_ctx *pipe_ctx;
1221 int i, r, str_len = 30;
1223 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1228 rd_buf_ptr = rd_buf;
1230 for (i = 0; i < MAX_PIPES; i++) {
1231 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1232 if (pipe_ctx && pipe_ctx->stream &&
1233 pipe_ctx->stream->link == aconnector->dc_link)
1240 dsc = pipe_ctx->stream_res.dsc;
1242 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1244 snprintf(rd_buf_ptr, str_len,
1246 dsc_state.dsc_pic_width);
1247 rd_buf_ptr += str_len;
1250 if (*pos >= rd_buf_size)
1253 r = put_user(*(rd_buf + result), buf);
1255 return r; /* r = -EFAULT */
1267 static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
1268 size_t size, loff_t *pos)
1270 char *rd_buf = NULL;
1271 char *rd_buf_ptr = NULL;
1272 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1273 struct display_stream_compressor *dsc;
1274 struct dcn_dsc_state dsc_state = {0};
1275 const uint32_t rd_buf_size = 100;
1276 struct pipe_ctx *pipe_ctx;
1278 int i, r, str_len = 30;
1280 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1285 rd_buf_ptr = rd_buf;
1287 for (i = 0; i < MAX_PIPES; i++) {
1288 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1289 if (pipe_ctx && pipe_ctx->stream &&
1290 pipe_ctx->stream->link == aconnector->dc_link)
1297 dsc = pipe_ctx->stream_res.dsc;
1299 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1301 snprintf(rd_buf_ptr, str_len,
1303 dsc_state.dsc_pic_height);
1304 rd_buf_ptr += str_len;
1307 if (*pos >= rd_buf_size)
1310 r = put_user(*(rd_buf + result), buf);
1312 return r; /* r = -EFAULT */
1324 static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
1325 size_t size, loff_t *pos)
1327 char *rd_buf = NULL;
1328 char *rd_buf_ptr = NULL;
1329 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1330 struct display_stream_compressor *dsc;
1331 struct dcn_dsc_state dsc_state = {0};
1332 const uint32_t rd_buf_size = 100;
1333 struct pipe_ctx *pipe_ctx;
1335 int i, r, str_len = 30;
1337 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1342 rd_buf_ptr = rd_buf;
1344 for (i = 0; i < MAX_PIPES; i++) {
1345 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1346 if (pipe_ctx && pipe_ctx->stream &&
1347 pipe_ctx->stream->link == aconnector->dc_link)
1354 dsc = pipe_ctx->stream_res.dsc;
1356 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1358 snprintf(rd_buf_ptr, str_len,
1360 dsc_state.dsc_chunk_size);
1361 rd_buf_ptr += str_len;
1364 if (*pos >= rd_buf_size)
1367 r = put_user(*(rd_buf + result), buf);
1369 return r; /* r = -EFAULT */
1381 static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
1382 size_t size, loff_t *pos)
1384 char *rd_buf = NULL;
1385 char *rd_buf_ptr = NULL;
1386 struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private;
1387 struct display_stream_compressor *dsc;
1388 struct dcn_dsc_state dsc_state = {0};
1389 const uint32_t rd_buf_size = 100;
1390 struct pipe_ctx *pipe_ctx;
1392 int i, r, str_len = 30;
1394 rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
1399 rd_buf_ptr = rd_buf;
1401 for (i = 0; i < MAX_PIPES; i++) {
1402 pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
1403 if (pipe_ctx && pipe_ctx->stream &&
1404 pipe_ctx->stream->link == aconnector->dc_link)
1411 dsc = pipe_ctx->stream_res.dsc;
1413 dsc->funcs->dsc_read_state(dsc, &dsc_state);
1415 snprintf(rd_buf_ptr, str_len,
1417 dsc_state.dsc_slice_bpg_offset);
1418 rd_buf_ptr += str_len;
1421 if (*pos >= rd_buf_size)
1424 r = put_user(*(rd_buf + result), buf);
1426 return r; /* r = -EFAULT */
1438 DEFINE_SHOW_ATTRIBUTE(dmub_fw_state);
1439 DEFINE_SHOW_ATTRIBUTE(dmub_tracebuffer);
1440 DEFINE_SHOW_ATTRIBUTE(output_bpc);
1441 #ifdef CONFIG_DRM_AMD_DC_HDCP
1442 DEFINE_SHOW_ATTRIBUTE(hdcp_sink_capability);
1445 static const struct file_operations dp_dsc_clock_en_debugfs_fops = {
1446 .owner = THIS_MODULE,
1447 .read = dp_dsc_clock_en_read,
1448 .llseek = default_llseek
1451 static const struct file_operations dp_dsc_slice_width_debugfs_fops = {
1452 .owner = THIS_MODULE,
1453 .read = dp_dsc_slice_width_read,
1454 .llseek = default_llseek
1457 static const struct file_operations dp_dsc_slice_height_debugfs_fops = {
1458 .owner = THIS_MODULE,
1459 .read = dp_dsc_slice_height_read,
1460 .llseek = default_llseek
1463 static const struct file_operations dp_dsc_bytes_per_pixel_debugfs_fops = {
1464 .owner = THIS_MODULE,
1465 .read = dp_dsc_bytes_per_pixel_read,
1466 .llseek = default_llseek
1469 static const struct file_operations dp_dsc_pic_width_debugfs_fops = {
1470 .owner = THIS_MODULE,
1471 .read = dp_dsc_pic_width_read,
1472 .llseek = default_llseek
1475 static const struct file_operations dp_dsc_pic_height_debugfs_fops = {
1476 .owner = THIS_MODULE,
1477 .read = dp_dsc_pic_height_read,
1478 .llseek = default_llseek
1481 static const struct file_operations dp_dsc_chunk_size_debugfs_fops = {
1482 .owner = THIS_MODULE,
1483 .read = dp_dsc_chunk_size_read,
1484 .llseek = default_llseek
1487 static const struct file_operations dp_dsc_slice_bpg_offset_debugfs_fops = {
1488 .owner = THIS_MODULE,
1489 .read = dp_dsc_slice_bpg_offset_read,
1490 .llseek = default_llseek
1493 static const struct file_operations dp_link_settings_debugfs_fops = {
1494 .owner = THIS_MODULE,
1495 .read = dp_link_settings_read,
1496 .write = dp_link_settings_write,
1497 .llseek = default_llseek
1500 static const struct file_operations dp_phy_settings_debugfs_fop = {
1501 .owner = THIS_MODULE,
1502 .read = dp_phy_settings_read,
1503 .write = dp_phy_settings_write,
1504 .llseek = default_llseek
1507 static const struct file_operations dp_phy_test_pattern_fops = {
1508 .owner = THIS_MODULE,
1509 .write = dp_phy_test_pattern_debugfs_write,
1510 .llseek = default_llseek
1513 static const struct file_operations sdp_message_fops = {
1514 .owner = THIS_MODULE,
1515 .write = dp_sdp_message_debugfs_write,
1516 .llseek = default_llseek
1519 static const struct file_operations dp_dpcd_address_debugfs_fops = {
1520 .owner = THIS_MODULE,
1521 .write = dp_dpcd_address_write,
1522 .llseek = default_llseek
1525 static const struct file_operations dp_dpcd_size_debugfs_fops = {
1526 .owner = THIS_MODULE,
1527 .write = dp_dpcd_size_write,
1528 .llseek = default_llseek
1531 static const struct file_operations dp_dpcd_data_debugfs_fops = {
1532 .owner = THIS_MODULE,
1533 .read = dp_dpcd_data_read,
1534 .write = dp_dpcd_data_write,
1535 .llseek = default_llseek
1538 static const struct {
1540 const struct file_operations *fops;
1541 } dp_debugfs_entries[] = {
1542 {"link_settings", &dp_link_settings_debugfs_fops},
1543 {"phy_settings", &dp_phy_settings_debugfs_fop},
1544 {"test_pattern", &dp_phy_test_pattern_fops},
1545 #ifdef CONFIG_DRM_AMD_DC_HDCP
1546 {"hdcp_sink_capability", &hdcp_sink_capability_fops},
1548 {"sdp_message", &sdp_message_fops},
1549 {"aux_dpcd_address", &dp_dpcd_address_debugfs_fops},
1550 {"aux_dpcd_size", &dp_dpcd_size_debugfs_fops},
1551 {"aux_dpcd_data", &dp_dpcd_data_debugfs_fops},
1552 {"dsc_clock_en", &dp_dsc_clock_en_debugfs_fops},
1553 {"dsc_slice_width", &dp_dsc_slice_width_debugfs_fops},
1554 {"dsc_slice_height", &dp_dsc_slice_height_debugfs_fops},
1555 {"dsc_bytes_per_pixel", &dp_dsc_bytes_per_pixel_debugfs_fops},
1556 {"dsc_pic_width", &dp_dsc_pic_width_debugfs_fops},
1557 {"dsc_pic_height", &dp_dsc_pic_height_debugfs_fops},
1558 {"dsc_chunk_size", &dp_dsc_chunk_size_debugfs_fops},
1559 {"dsc_slice_bpg", &dp_dsc_slice_bpg_offset_debugfs_fops}
1562 #ifdef CONFIG_DRM_AMD_DC_HDCP
1563 static const struct {
1565 const struct file_operations *fops;
1566 } hdmi_debugfs_entries[] = {
1567 {"hdcp_sink_capability", &hdcp_sink_capability_fops}
1571 * Force YUV420 output if available from the given mode
1573 static int force_yuv420_output_set(void *data, u64 val)
1575 struct amdgpu_dm_connector *connector = data;
1577 connector->force_yuv420_output = (bool)val;
1583 * Check if YUV420 is forced when available from the given mode
1585 static int force_yuv420_output_get(void *data, u64 *val)
1587 struct amdgpu_dm_connector *connector = data;
1589 *val = connector->force_yuv420_output;
1594 DEFINE_DEBUGFS_ATTRIBUTE(force_yuv420_output_fops, force_yuv420_output_get,
1595 force_yuv420_output_set, "%llu\n");
1600 static int psr_get(void *data, u64 *val)
1602 struct amdgpu_dm_connector *connector = data;
1603 struct dc_link *link = connector->dc_link;
1604 uint32_t psr_state = 0;
1606 dc_link_get_psr_state(link, &psr_state);
1614 DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n");
1616 void connector_debugfs_init(struct amdgpu_dm_connector *connector)
1619 struct dentry *dir = connector->base.debugfs_entry;
1621 if (connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
1622 connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) {
1623 for (i = 0; i < ARRAY_SIZE(dp_debugfs_entries); i++) {
1624 debugfs_create_file(dp_debugfs_entries[i].name,
1625 0644, dir, connector,
1626 dp_debugfs_entries[i].fops);
1629 if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
1630 debugfs_create_file_unsafe("psr_state", 0444, dir, connector, &psr_fops);
1632 debugfs_create_file_unsafe("force_yuv420_output", 0644, dir, connector,
1633 &force_yuv420_output_fops);
1635 debugfs_create_file("output_bpc", 0644, dir, connector,
1638 connector->debugfs_dpcd_address = 0;
1639 connector->debugfs_dpcd_size = 0;
1641 #ifdef CONFIG_DRM_AMD_DC_HDCP
1642 if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA) {
1643 for (i = 0; i < ARRAY_SIZE(hdmi_debugfs_entries); i++) {
1644 debugfs_create_file(hdmi_debugfs_entries[i].name,
1645 0644, dir, connector,
1646 hdmi_debugfs_entries[i].fops);
1653 * Writes DTN log state to the user supplied buffer.
1654 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log
1656 static ssize_t dtn_log_read(
1662 struct amdgpu_device *adev = file_inode(f)->i_private;
1663 struct dc *dc = adev->dm.dc;
1664 struct dc_log_buffer_ctx log_ctx = { 0 };
1670 if (!dc->hwss.log_hw_state)
1673 dc->hwss.log_hw_state(dc, &log_ctx);
1675 if (*pos < log_ctx.pos) {
1676 size_t to_copy = log_ctx.pos - *pos;
1678 to_copy = min(to_copy, size);
1680 if (!copy_to_user(buf, log_ctx.buf + *pos, to_copy)) {
1692 * Writes DTN log state to dmesg when triggered via a write.
1693 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dtn_log
1695 static ssize_t dtn_log_write(
1697 const char __user *buf,
1701 struct amdgpu_device *adev = file_inode(f)->i_private;
1702 struct dc *dc = adev->dm.dc;
1704 /* Write triggers log output via dmesg. */
1708 if (dc->hwss.log_hw_state)
1709 dc->hwss.log_hw_state(dc, NULL);
1715 * Backlight at this moment. Read only.
1716 * As written to display, taking ABM and backlight lut into account.
1717 * Ranges from 0x0 to 0x10000 (= 100% PWM)
1719 static int current_backlight_read(struct seq_file *m, void *data)
1721 struct drm_info_node *node = (struct drm_info_node *)m->private;
1722 struct drm_device *dev = node->minor->dev;
1723 struct amdgpu_device *adev = dev->dev_private;
1724 struct amdgpu_display_manager *dm = &adev->dm;
1726 unsigned int backlight = dc_link_get_backlight_level(dm->backlight_link);
1728 seq_printf(m, "0x%x\n", backlight);
1733 * Backlight value that is being approached. Read only.
1734 * As written to display, taking ABM and backlight lut into account.
1735 * Ranges from 0x0 to 0x10000 (= 100% PWM)
1737 static int target_backlight_read(struct seq_file *m, void *data)
1739 struct drm_info_node *node = (struct drm_info_node *)m->private;
1740 struct drm_device *dev = node->minor->dev;
1741 struct amdgpu_device *adev = dev->dev_private;
1742 struct amdgpu_display_manager *dm = &adev->dm;
1744 unsigned int backlight = dc_link_get_target_backlight_pwm(dm->backlight_link);
1746 seq_printf(m, "0x%x\n", backlight);
1750 static int mst_topo(struct seq_file *m, void *unused)
1752 struct drm_info_node *node = (struct drm_info_node *)m->private;
1753 struct drm_device *dev = node->minor->dev;
1754 struct drm_connector *connector;
1755 struct drm_connector_list_iter conn_iter;
1756 struct amdgpu_dm_connector *aconnector;
1758 drm_connector_list_iter_begin(dev, &conn_iter);
1759 drm_for_each_connector_iter(connector, &conn_iter) {
1760 if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
1763 aconnector = to_amdgpu_dm_connector(connector);
1765 seq_printf(m, "\nMST topology for connector %d\n", aconnector->connector_id);
1766 drm_dp_mst_dump_topology(m, &aconnector->mst_mgr);
1768 drm_connector_list_iter_end(&conn_iter);
1773 static const struct drm_info_list amdgpu_dm_debugfs_list[] = {
1774 {"amdgpu_current_backlight_pwm", ¤t_backlight_read},
1775 {"amdgpu_target_backlight_pwm", &target_backlight_read},
1776 {"amdgpu_mst_topology", &mst_topo},
1780 * Sets the DC visual confirm debug option from the given string.
1781 * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_visual_confirm
1783 static int visual_confirm_set(void *data, u64 val)
1785 struct amdgpu_device *adev = data;
1787 adev->dm.dc->debug.visual_confirm = (enum visual_confirm)val;
1793 * Reads the DC visual confirm debug option value into the given buffer.
1794 * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_visual_confirm
1796 static int visual_confirm_get(void *data, u64 *val)
1798 struct amdgpu_device *adev = data;
1800 *val = adev->dm.dc->debug.visual_confirm;
1805 DEFINE_DEBUGFS_ATTRIBUTE(visual_confirm_fops, visual_confirm_get,
1806 visual_confirm_set, "%llu\n");
1808 int dtn_debugfs_init(struct amdgpu_device *adev)
1810 static const struct file_operations dtn_log_fops = {
1811 .owner = THIS_MODULE,
1812 .read = dtn_log_read,
1813 .write = dtn_log_write,
1814 .llseek = default_llseek
1817 struct drm_minor *minor = adev->ddev->primary;
1818 struct dentry *root = minor->debugfs_root;
1821 ret = amdgpu_debugfs_add_files(adev, amdgpu_dm_debugfs_list,
1822 ARRAY_SIZE(amdgpu_dm_debugfs_list));
1826 debugfs_create_file("amdgpu_dm_dtn_log", 0644, root, adev,
1829 debugfs_create_file_unsafe("amdgpu_dm_visual_confirm", 0644, root, adev,
1830 &visual_confirm_fops);
1832 debugfs_create_file_unsafe("amdgpu_dm_dmub_tracebuffer", 0644, root,
1833 adev, &dmub_tracebuffer_fops);
1835 debugfs_create_file_unsafe("amdgpu_dm_dmub_fw_state", 0644, root,
1836 adev, &dmub_fw_state_fops);