cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

amdgpu_dm_debugfs.c (93863B)


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