disp: msm: sde: Add motUtil Debugfs framework

Adding the motUtil debugfs in /d/dri/0/debug to provide a tool for
developer/tester to interface with the Display driver framework

Port from: 890aa1c9

Change-Id: I5ca8fbd5f8aa17233683d82a66fe6ed45e722305
Signed-off-by: Bang Nguyen <bangnguyen@motorola.com>
Reviewed-on: https://gerrit.mot.com/1697292
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Guobin Zhang <zhanggb@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Bang Nguyen 2019-07-31 08:32:50 -05:00 • committed by tongkun1
commit 047e987980
4 changed files with 311 additions and 0 deletions

View file

@ -42,6 +42,7 @@ msm_drm-$(CONFIG_DRM_MSM_SDE) += sde/sde_crtc.o \
sde/sde_core_perf.o \
sde/sde_rm.o \
sde/sde_kms_utils.o \
sde/sde_motUtil.o \
sde/sde_kms.o \
sde/sde_plane.o \
sde/sde_connector.o \

View file

@ -152,6 +152,7 @@ static int _sde_debugfs_init(struct sde_kms *sde_kms)
(void) sde_debugfs_vbif_init(sde_kms, debugfs_root);
(void) sde_debugfs_core_irq_init(sde_kms, debugfs_root);
(void) sde_debugfs_mot_util_init(sde_kms, debugfs_root);
rc = sde_core_perf_debugfs_init(&sde_kms->perf, debugfs_root);
if (rc) {

271
msm/sde/sde_motUtil.c Normal file
View file

@ -0,0 +1,271 @@
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#define pr_fmt(fmt) "motUtil:[%s]" fmt, __func__
#include <linux/debugfs.h>
#include <linux/string.h>
#include <linux/slab.h>
#include "sde_connector.h"
#include "sde_encoder.h"
#include "sde_motUtil.h"
#include "dsi_display.h"
#define MAIN_DSI_CONN_NAME "DSI-1"
#define CLI_DSI_CONN_NAME "DSI-2"
struct motUtil motUtil_data;
static ssize_t _sde_debugfs_motUtil_string2num(const char __user *buf,
size_t count, char buffer[])
{
char *input, *input_copy, *token, *input_dup = NULL;
const char *delim =" ";
u32 buf_size = 0;
int rc=0, strtoint;
/*copy the data from user space*/
input = kmalloc(count + 1, GFP_KERNEL);
if (!input)
return -ENOMEM;
if (copy_from_user(input, buf, count)) {
SDE_ERROR("copy from user failed\n");
rc = -EFAULT;
goto end;
}
input[count]='\0';
SDE_INFO("input_cmd = %s\n", input);
input_copy = kstrdup(input, GFP_KERNEL);
if (!input_copy) {
rc = -ENOMEM;
goto end;
}
input_dup = input_copy,
token = strsep(&input_copy, delim);
while (token) {
rc = kstrtoint(token, 0, &strtoint);
if (rc) {
SDE_ERROR("input buffer conversion failed\n");
goto end;
}
if (buf_size >= MAX_CMD_PAYLOAD_SIZE) {
SDE_ERROR("buffer size exceeding the limit %d\n",
MAX_CMD_PAYLOAD_SIZE);
goto end;
}
buffer[buf_size++] = (strtoint & 0xff);
token = strsep(&input_copy, delim);
}
SDE_DEBUG("command packet size in bytes: %u\n", buf_size);
rc = buf_size;
end:
kfree(input_dup);
kfree(input);
return rc;
}
static struct sde_connector *_sde_debugfs_motUtil_get_sde_conn(
struct sde_kms *kms,
size_t count, char input[])
{
struct drm_device *dev = kms->dev;
struct drm_connector *conn = NULL;
struct sde_connector *sde_conn = NULL;
int found_conn = 0;
enum sde_motUtil_disp_cmd panel_type = input[DISPUTIL_PANEL_TYPE];
mutex_lock(&dev->mode_config.mutex);
drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(conn, &conn_iter) {
if (panel_type == MOTUTIL_MAIN_DISP) {
if (!strncmp(conn->name, MAIN_DSI_CONN_NAME, 5)) {
SDE_DEBUG("found MAIN disp conn\n");
found_conn = 1;
break;
}
} else if (panel_type == MOTUTIL_CLI_DISP) {
if (!strncmp(conn->name, CLI_DSI_CONN_NAME, 5)) {
SDE_DEBUG("found CLI disp conn\n");
found_conn = 1;
break;
}
}
}
if (found_conn) {
SDE_DEBUG("found SDE Connector for %s\n",
(panel_type == MOTUTIL_MAIN_DISP) ?
"Main Display" : "CLI Display");
sde_conn = to_sde_connector(conn);
} else {
SDE_ERROR("Can not find SDE Connector for %s\n",
(panel_type == MOTUTIL_MAIN_DISP) ?
"Main Display" : "CLI Display");
}
drm_connector_list_iter_end(&conn_iter);
mutex_unlock(&dev->mode_config.mutex);
return sde_conn;
}
static int _sde_debugfs_motUtil_transfer(struct sde_kms *kms,
size_t count, char input[])
{
struct sde_connector *sde_conn = NULL;
int ret = 0;
enum sde_motUtil_disp_cmd panel_type = input[DISPUTIL_PANEL_TYPE];
if (panel_type > MOTUTIL_CLI_DISP) {
SDE_ERROR("Invalid panel number = %d\n", panel_type);
return -EINVAL;
}
sde_conn = _sde_debugfs_motUtil_get_sde_conn(kms, count, input);
if (!sde_conn) {
ret = -EINVAL;
goto end;
}
if (sde_conn && !sde_conn->ops.motUtil_transfer) {
SDE_ERROR("no motUtil_transfer support for connector name %s\n",
sde_conn->name);
ret = -ENOENT;
goto end;
}
if (motUtil_data.rd_buf) {
mutex_lock(&sde_conn->lock);
ret = sde_conn->ops.motUtil_transfer(sde_conn->display,
input, count, &motUtil_data);
motUtil_data.last_cmd_tx_status = !ret ? true : false;
motUtil_data.read_len = ret;
mutex_unlock(&sde_conn->lock);
ret = count;
} else
ret = -ENOMEM;
end:
return ret;
}
static ssize_t _sde_debugfs_motUtil_exe_command(struct sde_kms *kms,
size_t count, char input[])
{
int ret = 0;
enum sde_motUtil_type motUtil_type = input[0];
motUtil_data.motUtil_type = motUtil_type;
return ret;
}
static int _sde_debugfs_motUtil_open(struct inode *inode,
struct file *file)
{
if (!inode || !file)
return -EINVAL;
/* non-seekable */
file->private_data = inode->i_private;
return nonseekable_open(inode, file);
}
static ssize_t _sde_debugfs_motUtil_write(struct file *file,
const char __user *buf, size_t count, loff_t *ppos)
{
u32 buf_size = 0;
char buffer[MAX_CMD_PAYLOAD_SIZE];
struct sde_kms *kms = (struct sde_kms *)file->private_data;
if (*ppos || !kms) {
SDE_ERROR("invalid argument(s)\n");
return 0;
}
buf_size = _sde_debugfs_motUtil_string2num(buf, count, buffer);
if (!buf_size){
SDE_ERROR("invalid input\n");
return count;
}
mutex_lock(&motUtil_data.lock);
_sde_debugfs_motUtil_exe_command(kms, count, buffer);
mutex_unlock(&motUtil_data.lock);
return count;
}
static ssize_t _sde_debugfs_motUtil_read(struct file *file,
char __user *buf, size_t count, loff_t *ppos)
{
int blen = 0;
char buffer[MAX_CMD_PAYLOAD_SIZE];
if (*ppos)
return 0;
mutex_lock(&motUtil_data.lock);
if (!motUtil_data.read_cmd)
blen = snprintf(buffer, MAX_CMD_PAYLOAD_SIZE,
"motUtil_status: 0x%x\n",
motUtil_data.last_cmd_tx_status);
SDE_INFO("%s\n", buffer);
if (blen <= 0) {
SDE_ERROR("snprintf failed, blen %d\n", blen);
return 0;
}
if (copy_to_user(buf, buffer, min(count, (size_t)blen+1))) {
SDE_ERROR("copy to user buffer failed\n");
return -EFAULT;
}
*ppos += blen;
mutex_unlock(&motUtil_data.lock);
return blen;
}
static const struct file_operations sde_debugfs_motUtil_fops = {
.open = _sde_debugfs_motUtil_open,
.read = _sde_debugfs_motUtil_read,
.write = _sde_debugfs_motUtil_write,
};
int sde_debugfs_mot_util_init(struct sde_kms *sde_kms,
struct dentry *parent)
{
debugfs_create_file("motUtil", 0606, parent,
sde_kms, &sde_debugfs_motUtil_fops);
motUtil_data.rd_buf = kzalloc(SZ_4K, GFP_KERNEL);
if (!motUtil_data.rd_buf)
return -ENOMEM;
motUtil_data.te_enable = true;
mutex_init(&motUtil_data.lock);
return 0;
}

38
msm/sde/sde_motUtil.h Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __MOTUTIL_H__
#define __MOTUTIL_H__
#include <linux/debugfs.h>
#include <linux/types.h>
enum sde_motUtil_type {
};
struct motUtil {
struct mutex lock;
enum sde_motUtil_type motUtil_type;
bool read_cmd;
bool last_cmd_tx_status;
u16 read_len;
u8 *rd_buf;
int val;
bool te_enable;
};
int sde_debugfs_mot_util_init(struct sde_kms *sde_kms,
struct dentry *parent);
#endif /* __MOTUTIL_H__ */