brintos

brintos / linux-shallow public Read only

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