drm/msm: add HDMI debugfs support to show edid modes
Extend the HDMI debugfs interface to show the EDID modes and also the extracted information from various data blocks of the EDID. Change-Id: I7cb7dbea290ec822e994c79430c6c2dbb39abc33 Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
This commit is contained in:
parent
ae930851e9
commit
dc3681c17f
1 changed files with 392 additions and 1 deletions
|
@ -85,16 +85,328 @@ static ssize_t _sde_hdmi_debugfs_dump_info_read(struct file *file,
|
|||
return len;
|
||||
}
|
||||
|
||||
static ssize_t _sde_hdmi_debugfs_edid_modes_read(struct file *file,
|
||||
char __user *buff,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct sde_hdmi *display = file->private_data;
|
||||
char *buf;
|
||||
u32 len = 0;
|
||||
struct drm_connector *connector;
|
||||
u32 mode_count = 0;
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
if (!display)
|
||||
return -ENODEV;
|
||||
|
||||
if (!display->ctrl.ctrl ||
|
||||
!display->ctrl.ctrl->connector) {
|
||||
SDE_ERROR("sde_hdmi=%p or hdmi or connector is NULL\n",
|
||||
display);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
||||
connector = display->ctrl.ctrl->connector;
|
||||
|
||||
list_for_each_entry(mode, &connector->modes, head) {
|
||||
mode_count++;
|
||||
}
|
||||
|
||||
/* Adding one more to store title */
|
||||
mode_count++;
|
||||
|
||||
buf = kzalloc((mode_count * sizeof(*mode)), GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
len += snprintf(buf + len, PAGE_SIZE - len,
|
||||
"name refresh (Hz) hdisp hss hse htot vdisp");
|
||||
|
||||
len += snprintf(buf + len, PAGE_SIZE - len,
|
||||
" vss vse vtot flags\n");
|
||||
|
||||
list_for_each_entry(mode, &connector->modes, head) {
|
||||
len += snprintf(buf + len, SZ_4K - len,
|
||||
"%s %d %d %d %d %d %d %d %d %d 0x%x\n",
|
||||
mode->name, mode->vrefresh, mode->hdisplay,
|
||||
mode->hsync_start, mode->hsync_end, mode->htotal,
|
||||
mode->vdisplay, mode->vsync_start, mode->vsync_end,
|
||||
mode->vtotal, mode->flags);
|
||||
}
|
||||
|
||||
if (copy_to_user(buff, buf, len)) {
|
||||
kfree(buf);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
*ppos += len;
|
||||
|
||||
kfree(buf);
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t _sde_hdmi_debugfs_edid_vsdb_info_read(struct file *file,
|
||||
char __user *buff,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct sde_hdmi *display = file->private_data;
|
||||
char buf[200];
|
||||
u32 len = 0;
|
||||
struct drm_connector *connector;
|
||||
|
||||
if (!display)
|
||||
return -ENODEV;
|
||||
|
||||
if (!display->ctrl.ctrl ||
|
||||
!display->ctrl.ctrl->connector) {
|
||||
SDE_ERROR("sde_hdmi=%p or hdmi or connector is NULL\n",
|
||||
display);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
SDE_HDMI_DEBUG("%s +", __func__);
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
||||
connector = display->ctrl.ctrl->connector;
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"max_tmds_clock = %d\n",
|
||||
connector->max_tmds_clock);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"latency_present %d %d\n",
|
||||
connector->latency_present[0],
|
||||
connector->latency_present[1]);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"video_latency %d %d\n",
|
||||
connector->video_latency[0],
|
||||
connector->video_latency[1]);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"audio_latency %d %d\n",
|
||||
connector->audio_latency[0],
|
||||
connector->audio_latency[1]);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"dvi_dual %d\n",
|
||||
(int)connector->dvi_dual);
|
||||
|
||||
if (copy_to_user(buff, buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
*ppos += len;
|
||||
SDE_HDMI_DEBUG("%s - ", __func__);
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t _sde_hdmi_debugfs_edid_hdr_info_read(struct file *file,
|
||||
char __user *buff,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct sde_hdmi *display = file->private_data;
|
||||
char buf[200];
|
||||
u32 len = 0;
|
||||
struct drm_connector *connector;
|
||||
|
||||
if (!display)
|
||||
return -ENODEV;
|
||||
|
||||
if (!display->ctrl.ctrl ||
|
||||
!display->ctrl.ctrl->connector) {
|
||||
SDE_ERROR("sde_hdmi=%p or hdmi or connector is NULL\n",
|
||||
display);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
SDE_HDMI_DEBUG("%s +", __func__);
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
||||
connector = display->ctrl.ctrl->connector;
|
||||
len += snprintf(buf, sizeof(buf), "hdr_eotf = %d\n"
|
||||
"hdr_metadata_type_one %d\n"
|
||||
"hdr_max_luminance %d\n"
|
||||
"hdr_avg_luminance %d\n"
|
||||
"hdr_min_luminance %d\n"
|
||||
"hdr_supported %d\n",
|
||||
connector->hdr_eotf,
|
||||
connector->hdr_metadata_type_one,
|
||||
connector->hdr_max_luminance,
|
||||
connector->hdr_avg_luminance,
|
||||
connector->hdr_min_luminance,
|
||||
(int)connector->hdr_supported);
|
||||
|
||||
if (copy_to_user(buff, buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
*ppos += len;
|
||||
SDE_HDMI_DEBUG("%s - ", __func__);
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t _sde_hdmi_debugfs_edid_hfvsdb_info_read(struct file *file,
|
||||
char __user *buff,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct sde_hdmi *display = file->private_data;
|
||||
char buf[200];
|
||||
u32 len = 0;
|
||||
struct drm_connector *connector;
|
||||
|
||||
if (!display)
|
||||
return -ENODEV;
|
||||
|
||||
if (!display->ctrl.ctrl ||
|
||||
!display->ctrl.ctrl->connector) {
|
||||
SDE_ERROR("sde_hdmi=%p or hdmi or connector is NULL\n",
|
||||
display);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
SDE_HDMI_DEBUG("%s +", __func__);
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
||||
connector = display->ctrl.ctrl->connector;
|
||||
len += snprintf(buf, PAGE_SIZE - len, "max_tmds_char = %d\n"
|
||||
"scdc_present %d\n"
|
||||
"rr_capable %d\n"
|
||||
"supports_scramble %d\n"
|
||||
"flags_3d %d\n",
|
||||
connector->max_tmds_char,
|
||||
(int)connector->scdc_present,
|
||||
(int)connector->rr_capable,
|
||||
(int)connector->supports_scramble,
|
||||
connector->flags_3d);
|
||||
|
||||
if (copy_to_user(buff, buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
*ppos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t _sde_hdmi_debugfs_edid_vcdb_info_read(struct file *file,
|
||||
char __user *buff,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct sde_hdmi *display = file->private_data;
|
||||
char buf[100];
|
||||
u32 len = 0;
|
||||
struct drm_connector *connector;
|
||||
|
||||
if (!display)
|
||||
return -ENODEV;
|
||||
|
||||
if (!display->ctrl.ctrl ||
|
||||
!display->ctrl.ctrl->connector) {
|
||||
SDE_ERROR("sde_hdmi=%p or hdmi or connector is NULL\n",
|
||||
display);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
SDE_HDMI_DEBUG("%s +", __func__);
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
||||
connector = display->ctrl.ctrl->connector;
|
||||
len += snprintf(buf, PAGE_SIZE - len, "pt_scan_info = %d\n"
|
||||
"it_scan_info = %d\n"
|
||||
"ce_scan_info = %d\n",
|
||||
(int)connector->pt_scan_info,
|
||||
(int)connector->it_scan_info,
|
||||
(int)connector->ce_scan_info);
|
||||
|
||||
if (copy_to_user(buff, buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
*ppos += len;
|
||||
SDE_HDMI_DEBUG("%s - ", __func__);
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t _sde_hdmi_edid_vendor_name_read(struct file *file,
|
||||
char __user *buff,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct sde_hdmi *display = file->private_data;
|
||||
char buf[100];
|
||||
u32 len = 0;
|
||||
struct drm_connector *connector;
|
||||
|
||||
if (!display)
|
||||
return -ENODEV;
|
||||
|
||||
if (!display->ctrl.ctrl ||
|
||||
!display->ctrl.ctrl->connector) {
|
||||
SDE_ERROR("sde_hdmi=%p or hdmi or connector is NULL\n",
|
||||
display);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
SDE_HDMI_DEBUG("%s +", __func__);
|
||||
if (*ppos)
|
||||
return 0;
|
||||
|
||||
connector = display->ctrl.ctrl->connector;
|
||||
len += snprintf(buf, PAGE_SIZE - len, "Vendor ID is %s\n",
|
||||
display->edid_ctrl->vendor_id);
|
||||
|
||||
if (copy_to_user(buff, buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
*ppos += len;
|
||||
SDE_HDMI_DEBUG("%s - ", __func__);
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct file_operations dump_info_fops = {
|
||||
.open = simple_open,
|
||||
.read = _sde_hdmi_debugfs_dump_info_read,
|
||||
};
|
||||
|
||||
static const struct file_operations edid_modes_fops = {
|
||||
.open = simple_open,
|
||||
.read = _sde_hdmi_debugfs_edid_modes_read,
|
||||
};
|
||||
|
||||
static const struct file_operations edid_vsdb_info_fops = {
|
||||
.open = simple_open,
|
||||
.read = _sde_hdmi_debugfs_edid_vsdb_info_read,
|
||||
};
|
||||
|
||||
static const struct file_operations edid_hdr_info_fops = {
|
||||
.open = simple_open,
|
||||
.read = _sde_hdmi_debugfs_edid_hdr_info_read,
|
||||
};
|
||||
|
||||
static const struct file_operations edid_hfvsdb_info_fops = {
|
||||
.open = simple_open,
|
||||
.read = _sde_hdmi_debugfs_edid_hfvsdb_info_read,
|
||||
};
|
||||
|
||||
static const struct file_operations edid_vcdb_info_fops = {
|
||||
.open = simple_open,
|
||||
.read = _sde_hdmi_debugfs_edid_vcdb_info_read,
|
||||
};
|
||||
|
||||
static const struct file_operations edid_vendor_name_fops = {
|
||||
.open = simple_open,
|
||||
.read = _sde_hdmi_edid_vendor_name_read,
|
||||
};
|
||||
|
||||
static int _sde_hdmi_debugfs_init(struct sde_hdmi *display)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dentry *dir, *dump_file;
|
||||
struct dentry *dir, *dump_file, *edid_modes;
|
||||
struct dentry *edid_vsdb_info, *edid_hdr_info, *edid_hfvsdb_info;
|
||||
struct dentry *edid_vcdb_info, *edid_vendor_name;
|
||||
|
||||
dir = debugfs_create_dir(display->name, NULL);
|
||||
if (!dir) {
|
||||
|
@ -116,6 +428,83 @@ static int _sde_hdmi_debugfs_init(struct sde_hdmi *display)
|
|||
goto error_remove_dir;
|
||||
}
|
||||
|
||||
edid_modes = debugfs_create_file("edid_modes",
|
||||
0444,
|
||||
dir,
|
||||
display,
|
||||
&edid_modes_fops);
|
||||
|
||||
if (IS_ERR_OR_NULL(edid_modes)) {
|
||||
rc = PTR_ERR(edid_modes);
|
||||
SDE_ERROR("[%s]debugfs create file failed, rc=%d\n",
|
||||
display->name, rc);
|
||||
goto error_remove_dir;
|
||||
}
|
||||
|
||||
edid_vsdb_info = debugfs_create_file("edid_vsdb_info",
|
||||
0444,
|
||||
dir,
|
||||
display,
|
||||
&edid_vsdb_info_fops);
|
||||
|
||||
if (IS_ERR_OR_NULL(edid_vsdb_info)) {
|
||||
rc = PTR_ERR(edid_vsdb_info);
|
||||
SDE_ERROR("[%s]debugfs create file failed, rc=%d\n",
|
||||
display->name, rc);
|
||||
goto error_remove_dir;
|
||||
}
|
||||
|
||||
edid_hdr_info = debugfs_create_file("edid_hdr_info",
|
||||
0444,
|
||||
dir,
|
||||
display,
|
||||
&edid_hdr_info_fops);
|
||||
if (IS_ERR_OR_NULL(edid_hdr_info)) {
|
||||
rc = PTR_ERR(edid_hdr_info);
|
||||
SDE_ERROR("[%s]debugfs create file failed, rc=%d\n",
|
||||
display->name, rc);
|
||||
goto error_remove_dir;
|
||||
}
|
||||
|
||||
edid_hfvsdb_info = debugfs_create_file("edid_hfvsdb_info",
|
||||
0444,
|
||||
dir,
|
||||
display,
|
||||
&edid_hfvsdb_info_fops);
|
||||
|
||||
if (IS_ERR_OR_NULL(edid_hfvsdb_info)) {
|
||||
rc = PTR_ERR(edid_hfvsdb_info);
|
||||
SDE_ERROR("[%s]debugfs create file failed, rc=%d\n",
|
||||
display->name, rc);
|
||||
goto error_remove_dir;
|
||||
}
|
||||
|
||||
edid_vcdb_info = debugfs_create_file("edid_vcdb_info",
|
||||
0444,
|
||||
dir,
|
||||
display,
|
||||
&edid_vcdb_info_fops);
|
||||
|
||||
if (IS_ERR_OR_NULL(edid_vcdb_info)) {
|
||||
rc = PTR_ERR(edid_vcdb_info);
|
||||
SDE_ERROR("[%s]debugfs create file failed, rc=%d\n",
|
||||
display->name, rc);
|
||||
goto error_remove_dir;
|
||||
}
|
||||
|
||||
edid_vendor_name = debugfs_create_file("edid_vendor_name",
|
||||
0444,
|
||||
dir,
|
||||
display,
|
||||
&edid_vendor_name_fops);
|
||||
|
||||
if (IS_ERR_OR_NULL(edid_vendor_name)) {
|
||||
rc = PTR_ERR(edid_vendor_name);
|
||||
SDE_ERROR("[%s]debugfs create file failed, rc=%d\n",
|
||||
display->name, rc);
|
||||
goto error_remove_dir;
|
||||
}
|
||||
|
||||
display->root = dir;
|
||||
return rc;
|
||||
error_remove_dir:
|
||||
|
@ -1193,6 +1582,8 @@ static int sde_hdmi_bind(struct device *dev, struct device *master, void *data)
|
|||
display_ctrl->ctrl = priv->hdmi;
|
||||
display->drm_dev = drm;
|
||||
|
||||
mutex_unlock(&display->display_lock);
|
||||
return rc;
|
||||
error:
|
||||
(void)_sde_hdmi_debugfs_deinit(display);
|
||||
debug_error:
|
||||
|
|
Loading…
Add table
Reference in a new issue