mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-27 01:25:35 +07:00
drm/amd/display: Add debugfs dpcd interface
[Why] We need arbitrary read/write over DP AUX DPCD for debugging [How] Three debugfs entries Set the target address by writing to "aux_dpcd_address" (The first four bytes written are used) Set the transaction size in bytes by writing to "aux_dpcd_size" (The first four bytes written are used) Start a transaction by reading/writing "aux_dpcd_data" Do note: there is no concerrency protection at all Accessing these entries in quick succession can lead to strange behaviour Signed-off-by: David Francis <David.Francis@amd.com> Reviewed-by: Harry Wentland <Harry.Wentland@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
c7ba3653e9
commit
f258fee6c3
@ -4395,6 +4395,8 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
|
||||
DRM_ERROR("Failed to create debugfs for connector");
|
||||
goto out_free;
|
||||
}
|
||||
aconnector->debugfs_dpcd_address = 0;
|
||||
aconnector->debugfs_dpcd_size = 0;
|
||||
#endif
|
||||
|
||||
if (connector_type == DRM_MODE_CONNECTOR_DisplayPort
|
||||
|
@ -238,6 +238,10 @@ struct amdgpu_dm_connector {
|
||||
struct mutex hpd_lock;
|
||||
|
||||
bool fake_enable;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
uint32_t debugfs_dpcd_address;
|
||||
uint32_t debugfs_dpcd_size;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_dm.h"
|
||||
#include "amdgpu_dm_debugfs.h"
|
||||
#include "dm_helpers.h"
|
||||
|
||||
/* function description
|
||||
* get/ set DP configuration: lane_count, link_rate, spread_spectrum
|
||||
@ -731,6 +732,88 @@ static ssize_t dp_sdp_message_debugfs_write(struct file *f, const char __user *b
|
||||
|
||||
DEFINE_SHOW_ATTRIBUTE(vrr_range);
|
||||
|
||||
static ssize_t dp_dpcd_address_write(struct file *f, const char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
int r;
|
||||
struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
|
||||
|
||||
if (size < sizeof(connector->debugfs_dpcd_address))
|
||||
return 0;
|
||||
|
||||
r = copy_from_user(&connector->debugfs_dpcd_address,
|
||||
buf, sizeof(connector->debugfs_dpcd_address));
|
||||
|
||||
return size - r;
|
||||
}
|
||||
|
||||
static ssize_t dp_dpcd_size_write(struct file *f, const char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
int r;
|
||||
struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
|
||||
|
||||
if (size < sizeof(connector->debugfs_dpcd_size))
|
||||
return 0;
|
||||
|
||||
r = copy_from_user(&connector->debugfs_dpcd_size,
|
||||
buf, sizeof(connector->debugfs_dpcd_size));
|
||||
|
||||
if (connector->debugfs_dpcd_size > 256)
|
||||
connector->debugfs_dpcd_size = 0;
|
||||
|
||||
return size - r;
|
||||
}
|
||||
|
||||
static ssize_t dp_dpcd_data_write(struct file *f, const char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
int r;
|
||||
char *data;
|
||||
struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
|
||||
struct dc_link *link = connector->dc_link;
|
||||
uint32_t write_size = connector->debugfs_dpcd_size;
|
||||
|
||||
if (size < write_size)
|
||||
return 0;
|
||||
|
||||
data = kzalloc(write_size, GFP_KERNEL);
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
r = copy_from_user(data, buf, write_size);
|
||||
|
||||
dm_helpers_dp_write_dpcd(link->ctx, link,
|
||||
connector->debugfs_dpcd_address, data, write_size - r);
|
||||
kfree(data);
|
||||
return write_size - r;
|
||||
}
|
||||
|
||||
static ssize_t dp_dpcd_data_read(struct file *f, char __user *buf,
|
||||
size_t size, loff_t *pos)
|
||||
{
|
||||
int r;
|
||||
char *data;
|
||||
struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
|
||||
struct dc_link *link = connector->dc_link;
|
||||
uint32_t read_size = connector->debugfs_dpcd_size;
|
||||
|
||||
if (size < read_size)
|
||||
return 0;
|
||||
|
||||
data = kzalloc(read_size, GFP_KERNEL);
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
dm_helpers_dp_read_dpcd(link->ctx, link,
|
||||
connector->debugfs_dpcd_address, data, read_size);
|
||||
|
||||
r = copy_to_user(buf, data, read_size);
|
||||
|
||||
kfree(data);
|
||||
return read_size - r;
|
||||
}
|
||||
|
||||
static const struct file_operations dp_link_settings_debugfs_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = dp_link_settings_read,
|
||||
@ -757,6 +840,25 @@ static const struct file_operations sdp_message_fops = {
|
||||
.llseek = default_llseek
|
||||
};
|
||||
|
||||
static const struct file_operations dp_dpcd_address_debugfs_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.write = dp_dpcd_address_write,
|
||||
.llseek = default_llseek
|
||||
};
|
||||
|
||||
static const struct file_operations dp_dpcd_size_debugfs_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.write = dp_dpcd_size_write,
|
||||
.llseek = default_llseek
|
||||
};
|
||||
|
||||
static const struct file_operations dp_dpcd_data_debugfs_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = dp_dpcd_data_read,
|
||||
.write = dp_dpcd_data_write,
|
||||
.llseek = default_llseek
|
||||
};
|
||||
|
||||
static const struct {
|
||||
char *name;
|
||||
const struct file_operations *fops;
|
||||
@ -765,7 +867,10 @@ static const struct {
|
||||
{"phy_settings", &dp_phy_settings_debugfs_fop},
|
||||
{"test_pattern", &dp_phy_test_pattern_fops},
|
||||
{"vrr_range", &vrr_range_fops},
|
||||
{"sdp_message", &sdp_message_fops}
|
||||
{"sdp_message", &sdp_message_fops},
|
||||
{"aux_dpcd_address", &dp_dpcd_address_debugfs_fops},
|
||||
{"aux_dpcd_size", &dp_dpcd_size_debugfs_fops},
|
||||
{"aux_dpcd_data", &dp_dpcd_data_debugfs_fops}
|
||||
};
|
||||
|
||||
int connector_debugfs_init(struct amdgpu_dm_connector *connector)
|
||||
|
Loading…
Reference in New Issue
Block a user