disp: msm: Add DispUtil tool to motUtil Debugfs
Add the Display Utility(DispUtil) support to the motUtil Debugfs Framework.
This dispUtil tool will send a command from the motUtil debugfs to the panel
or it can read any information from panel back.
The 1st byte (set to 0) will indicate for the displUtil tool.
DispUtil Format:
1st 2nd 3rd 4th 5th 6th
0=DispUtil 0=Pri Disp 0=write 0=HS 0=DCS number byte to read
1=Sec Disp 1=read 1=LP 1=Generic
7th 8th 9th....
payldLen_u payldLen_l payload
Port from: 79ee37d
Change-Id: Ib95d46342915543f942926df167e915cdd733252
Signed-off-by: Bang Nguyen <bangnguyen@motorola.com>
Reviewed-on: https://gerrit.mot.com/1444398
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Submit-Approved: Jira Key
Reviewed-on: https://gerrit.mot.com/1509800
Reviewed-by: Hua Tan <tanhua1@motorola.com>
This commit is contained in:
1 parent
2e4c31c1e8
commit
912a0498c8
6 files changed
+294
-1
No files matched your search
@@ -928,6 +928,166 @@ static int dsi_display_cmd_prepare(const char *cmd_buf, u32 cmd_buf_len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int dsi_display_dispUtil_get_datatype (char dsi_cmd, u8 cmd_type,
|
||||
size_t tx_len, u8 *tx_data_type)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
*tx_data_type = 0;
|
||||
|
||||
/* cmd_type = 0 : DSI DCS cmd;
|
||||
* cmd_type = 1 : DSI Generic cmd */
|
||||
if (cmd_type > DISPUTIL_DSI_GENERIC) {
|
||||
DSI_ERR("%s: Invalid DSI package type[%d] = 0x%x\n",
|
||||
__func__, DISPUTIL_MIPI_CMD_TYPE,
|
||||
cmd_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DSI_DEBUG("dsi_cmd =0x%x cmd_type=0x%x tx_len=0x%x\n",
|
||||
dsi_cmd, cmd_type, (u32)tx_len);
|
||||
|
||||
if (dsi_cmd == DISPUTIL_DSI_WRITE) {
|
||||
/* This is a DSI write command */
|
||||
switch(tx_len) {
|
||||
case 1:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* write, generic, no param */
|
||||
*tx_data_type = 0x3;
|
||||
else if (cmd_type == DISPUTIL_DSI_DCS)
|
||||
/* write, DCS, no param */
|
||||
*tx_data_type = 0x5;
|
||||
break;
|
||||
case 2:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* Write, generic, 1 param */
|
||||
*tx_data_type = 0x13;
|
||||
else if (cmd_type == DISPUTIL_DSI_DCS)
|
||||
/* write, DCS, 1 param */
|
||||
*tx_data_type = 0x15;
|
||||
break;
|
||||
default:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* Write, generic, long*/
|
||||
*tx_data_type = 0x29;
|
||||
else if (cmd_type == DISPUTIL_DSI_DCS)
|
||||
/* write, DCS, long*/
|
||||
*tx_data_type = 0x39;
|
||||
break;
|
||||
}
|
||||
} else if (dsi_cmd == DISPUTIL_DSI_READ) {
|
||||
if ((cmd_type == DISPUTIL_DSI_DCS) && (tx_len > 1)) {
|
||||
/* Note: tx_len will include read command and payload */
|
||||
/* DCS read */
|
||||
DSI_ERR("DCS read supports no parameter. tx_len=%d\n",
|
||||
(u32)tx_len);
|
||||
rc = -EINVAL;
|
||||
} else {
|
||||
switch(tx_len) {
|
||||
case 1:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* Read, generic, no param */
|
||||
*tx_data_type = 0x4;
|
||||
else if (cmd_type == DISPUTIL_DSI_DCS)
|
||||
/* Read, DCS, no param */
|
||||
*tx_data_type = 0x6;
|
||||
break;
|
||||
case 2:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* Read, Generic, 1 param */
|
||||
*tx_data_type = 0x14;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
if (cmd_type == DISPUTIL_DSI_GENERIC)
|
||||
/* read, generic, 2 params */
|
||||
*tx_data_type = 0x24;
|
||||
break;
|
||||
default:
|
||||
DSI_ERR("Invalid for tx_len= %d\n", (u32)tx_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
rc = -EINVAL;
|
||||
|
||||
if (rc)
|
||||
DSI_ERR("Invalid input data: dsi_cmd=0x%x tx_data_type =0x%x for tx_len=0x%x\n",
|
||||
dsi_cmd, *tx_data_type, (u32)tx_len);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_display_dispUtil_prepare(const char *cmd_buf, u32 cmd_buf_len,
|
||||
struct dsi_cmd_desc *cmd, u8 *payload, u32 payload_len_max,
|
||||
struct motUtil *motUtil_data)
|
||||
{
|
||||
int rc, i;
|
||||
u8 tx_data_type;
|
||||
|
||||
memset(cmd, 0x00, sizeof(*cmd));
|
||||
|
||||
/*
|
||||
* DISPUTIL_PAYLOAD_LEN_U and SDE_MOT_UTIL_PAYLOAD_LEN_L to
|
||||
* indicate number of payload in bytes
|
||||
*/
|
||||
cmd->msg.tx_len = ((cmd_buf[DISPUTIL_PAYLOAD_LEN_U] << 8) |
|
||||
(cmd_buf[DISPUTIL_PAYLOAD_LEN_L]));
|
||||
rc = dsi_display_dispUtil_get_datatype(cmd_buf[DISPUTIL_CMD_TYPE],
|
||||
cmd_buf[DISPUTIL_MIPI_CMD_TYPE],
|
||||
cmd->msg.tx_len, &tx_data_type);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
cmd->msg.type = tx_data_type;
|
||||
cmd->msg.channel = 0;
|
||||
cmd->last_command = 1;
|
||||
cmd->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
|
||||
|
||||
/* DISPUTIL_CMD_TYPE = 1 for DSI write cmd
|
||||
* DISPUTIL_CMD_TYPE = 0 for DSI read cmd */
|
||||
if (cmd_buf[DISPUTIL_CMD_TYPE] == DISPUTIL_DSI_READ) {
|
||||
cmd->msg.flags |= MIPI_DSI_MSG_READ; /* This is a read DSI */
|
||||
cmd->msg.rx_buf = motUtil_data->rd_buf;
|
||||
/* cmd_buf[3] = number bytes host wants to read */
|
||||
cmd->msg.rx_len = cmd_buf[DISPUTIL_NUM_BYTE_RD];
|
||||
|
||||
motUtil_data->read_cmd = true;
|
||||
} else
|
||||
motUtil_data->read_cmd = false;
|
||||
|
||||
/*
|
||||
* DISPUTIL_CMD_XFER_MODE = 0: DSI cmd transfers at HS mode
|
||||
* DISPUTIL_CMD_XFER_MODE = 1: DSI cmd transfers at LP mode
|
||||
*/
|
||||
if (cmd_buf[DISPUTIL_CMD_XFER_MODE] == DISPUTIL_DSI_LP_MODE)
|
||||
cmd->msg.flags |= MIPI_DSI_MSG_USE_LPM;
|
||||
|
||||
cmd->msg.ctrl = 0;
|
||||
cmd->post_wait_ms = 0;
|
||||
|
||||
/*
|
||||
* msg.tx_len is number of bytes of the payload.
|
||||
* Checking msg.tx_len with the payload, DISPUTIL_PAYLOAD,
|
||||
* to make sure they are matched
|
||||
*/
|
||||
if ((cmd->msg.tx_len > (cmd_buf_len - DISPUTIL_PAYLOAD)) ||
|
||||
(cmd->msg.tx_len > payload_len_max)) {
|
||||
DSI_ERR("Incorrect payload length tx_len:%ld, payload_len_max=%d cmd_buf_len=%d\n",
|
||||
cmd->msg.tx_len, payload_len_max, cmd_buf_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < cmd->msg.tx_len; i++)
|
||||
payload[i] = cmd_buf[DISPUTIL_PAYLOAD + i];
|
||||
|
||||
cmd->msg.tx_buf = payload;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int dsi_display_ctrl_get_host_init_state(struct dsi_display *dsi_display,
|
||||
bool *state)
|
||||
{
|
||||
@@ -1021,6 +1181,51 @@ static void _dsi_display_continuous_clk_ctrl(struct dsi_display *display,
|
||||
}
|
||||
}
|
||||
|
||||
int dsi_display_motUtil_transfer(void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len, struct motUtil *motUtil_data)
|
||||
{
|
||||
struct dsi_display *dsi_display = display;
|
||||
struct dsi_cmd_desc cmd;
|
||||
u8 cmd_payload[MAX_CMD_PAYLOAD_SIZE];
|
||||
int rc = 0;
|
||||
bool state = false;
|
||||
|
||||
if (!dsi_display || !cmd_buf) {
|
||||
DSI_ERR("[DSI] invalid params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DSI_INFO("[DSI] Display dispUtil transfer\n");
|
||||
|
||||
rc = dsi_display_dispUtil_prepare(cmd_buf, cmd_buf_len,
|
||||
&cmd, cmd_payload, MAX_CMD_PAYLOAD_SIZE,
|
||||
motUtil_data);
|
||||
if (rc) {
|
||||
DSI_ERR("[DSI] command prepare failed. rc %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
mutex_lock(&dsi_display->display_lock);
|
||||
rc = dsi_display_ctrl_get_host_init_state(dsi_display, &state);
|
||||
if (rc || !state) {
|
||||
DSI_ERR("[DSI] Invalid host state %d rc %d\n",
|
||||
state, rc);
|
||||
rc = -EPERM;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* rc will be returned from ops->transfer, which will be 0 or 1 for
|
||||
* DSI write command. rc will be returned for number of read bytes
|
||||
* for DSI read commad
|
||||
*/
|
||||
rc = dsi_display->host.ops->transfer(&dsi_display->host,
|
||||
&cmd.msg);
|
||||
end:
|
||||
mutex_unlock(&dsi_display->display_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int dsi_display_soft_reset(void *display)
|
||||
{
|
||||
struct dsi_display *dsi_display;
|
||||
@@ -2974,6 +3179,8 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
|
||||
msg->flags & MIPI_DSI_MSG_ASYNC_OVERRIDE)
|
||||
cmd_flags |= DSI_CTRL_CMD_ASYNC_WAIT;
|
||||
|
||||
if (msg->rx_buf)
|
||||
flags |= DSI_CTRL_CMD_READ;
|
||||
rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg,
|
||||
&cmd_flags);
|
||||
if (rc) {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include "dsi_ctrl.h"
|
||||
#include "dsi_phy.h"
|
||||
#include "dsi_panel.h"
|
||||
#include "sde_connector.h"
|
||||
#include "sde_motUtil.h"
|
||||
|
||||
#define MAX_DSI_CTRLS_PER_DISPLAY 2
|
||||
#define DSI_CLIENT_NAME_SIZE 20
|
||||
@@ -656,6 +658,18 @@ int dsi_display_cmd_transfer(struct drm_connector *connector,
|
||||
void *display, const char *cmd_buffer,
|
||||
u32 cmd_buf_len);
|
||||
|
||||
/**
|
||||
* dsi_display_motUtil_transfer() - Convert motUtil data and transfer command
|
||||
* to the panel
|
||||
* @display: Handle to display.
|
||||
* @cmd_buf: Command buffer
|
||||
* @cmd_buf_len: Command buffer length in bytes
|
||||
* @motUtil_data: motUtil data information
|
||||
*/
|
||||
int dsi_display_motUtil_transfer(void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len, struct motUtil *motUtil_data);
|
||||
|
||||
|
||||
/**
|
||||
* dsi_display_soft_reset() - perform a soft reset on DSI controller
|
||||
* @display: Handle to display
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "msm_prop.h"
|
||||
#include "sde_kms.h"
|
||||
#include "sde_fence.h"
|
||||
#include "sde_motUtil.h"
|
||||
|
||||
#define SDE_CONNECTOR_NAME_SIZE 16
|
||||
#define SDE_CONNECTOR_DHDR_MEMPOOL_MAX_SIZE SZ_32
|
||||
@@ -264,6 +265,18 @@ struct sde_connector_ops {
|
||||
void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len);
|
||||
|
||||
/**
|
||||
* motUtil_transfer - Convert motUtil data and Transfer command
|
||||
* to the connected display panel
|
||||
* @display: Pointer to private display handle
|
||||
* @cmd_buf: Command buffer
|
||||
* @cmd_buf_len: Command buffer length in bytes
|
||||
* @motUtil_data: motUtil data information
|
||||
* Returns: Zero for success, negetive for failure
|
||||
*/
|
||||
int (*motUtil_transfer)(void *display, const char *cmd_buf,
|
||||
u32 cmd_buf_len, struct motUtil *motUtil_data);
|
||||
|
||||
/**
|
||||
* config_hdr - configure HDR
|
||||
* @connector: Pointer to drm connector structure
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <soc/qcom/scm.h>
|
||||
|
||||
@@ -55,6 +57,8 @@
|
||||
#include "soc/qcom/secure_buffer.h"
|
||||
#include "soc/qcom/qtee_shmbridge.h"
|
||||
|
||||
#include "sde_motUtil.h"
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "sde_trace.h"
|
||||
|
||||
@@ -1431,6 +1435,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
||||
.post_kickoff = dsi_conn_post_kickoff,
|
||||
.check_status = dsi_display_check_status,
|
||||
.enable_event = dsi_conn_enable_event,
|
||||
.motUtil_transfer = dsi_display_motUtil_transfer,
|
||||
.cmd_transfer = dsi_display_cmd_transfer,
|
||||
.cont_splash_config = dsi_display_cont_splash_config,
|
||||
.get_panel_vfp = dsi_display_get_panel_vfp,
|
||||
|
||||
+30
-1
@@ -93,6 +93,7 @@ static struct sde_connector *_sde_debugfs_motUtil_get_sde_conn(
|
||||
struct sde_connector *sde_conn = NULL;
|
||||
int found_conn = 0;
|
||||
enum sde_motUtil_disp_cmd panel_type = input[DISPUTIL_PANEL_TYPE];
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
@@ -177,6 +178,14 @@ static ssize_t _sde_debugfs_motUtil_exe_command(struct sde_kms *kms,
|
||||
enum sde_motUtil_type motUtil_type = input[0];
|
||||
|
||||
motUtil_data.motUtil_type = motUtil_type;
|
||||
switch (motUtil_type) {
|
||||
case MOTUTIL_DISP_UTIL:
|
||||
ret = _sde_debugfs_motUtil_transfer(kms, count, input);
|
||||
break;
|
||||
default:
|
||||
SDE_ERROR("Un-support motUtil type = %d\n", motUtil_type);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -217,6 +226,23 @@ static ssize_t _sde_debugfs_motUtil_write(struct file *file,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_dispUtil_read(char *buffer)
|
||||
{
|
||||
int blen = 0, i;
|
||||
|
||||
if (motUtil_data.read_len) {
|
||||
blen = snprintf(buffer, 16, "motUtil_read: ");
|
||||
for (i = 0; i < motUtil_data.read_len; i ++)
|
||||
blen += snprintf((buffer + blen) , 6, "0x%02x ",
|
||||
*motUtil_data.rd_buf++);
|
||||
|
||||
blen += snprintf((buffer + blen), 2, "\n");
|
||||
} else
|
||||
SDE_ERROR("motUtil failed to read from panel\n");
|
||||
|
||||
return blen;
|
||||
}
|
||||
|
||||
static ssize_t _sde_debugfs_motUtil_read(struct file *file,
|
||||
char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
@@ -227,10 +253,13 @@ static ssize_t _sde_debugfs_motUtil_read(struct file *file,
|
||||
return 0;
|
||||
|
||||
mutex_lock(&motUtil_data.lock);
|
||||
if (!motUtil_data.read_cmd)
|
||||
if (!motUtil_data.read_cmd) {
|
||||
blen = snprintf(buffer, MAX_CMD_PAYLOAD_SIZE,
|
||||
"motUtil_status: 0x%x\n",
|
||||
motUtil_data.last_cmd_tx_status);
|
||||
} else if (motUtil_data.motUtil_type == MOTUTIL_DISP_UTIL) {
|
||||
blen = _sde_debugfs_motUtil_dispUtil_read(buffer);
|
||||
}
|
||||
|
||||
SDE_INFO("%s\n", buffer);
|
||||
|
||||
|
||||
@@ -19,6 +19,19 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
enum sde_motUtil_type {
|
||||
MOTUTIL_DISP_UTIL = 0,
|
||||
};
|
||||
|
||||
enum sde_motUtil_disp_cmd {
|
||||
DISPUTIL_TYPE = 0,
|
||||
DISPUTIL_PANEL_TYPE,
|
||||
DISPUTIL_CMD_TYPE,
|
||||
DISPUTIL_CMD_XFER_MODE,
|
||||
DISPUTIL_MIPI_CMD_TYPE,
|
||||
DISPUTIL_NUM_BYTE_RD,
|
||||
DISPUTIL_PAYLOAD_LEN_U,
|
||||
DISPUTIL_PAYLOAD_LEN_L,
|
||||
DISPUTIL_PAYLOAD,
|
||||
};
|
||||
|
||||
struct motUtil {
|
||||
@@ -32,6 +45,18 @@ struct motUtil {
|
||||
bool te_enable;
|
||||
};
|
||||
|
||||
#define DISPUTIL_DSI_WRITE 0
|
||||
#define DISPUTIL_DSI_READ 1
|
||||
|
||||
#define DISPUTIL_DSI_DCS 0
|
||||
#define DISPUTIL_DSI_GENERIC 1
|
||||
|
||||
#define DISPUTIL_DSI_HS_MODE 0
|
||||
#define DISPUTIL_DSI_LP_MODE 1
|
||||
|
||||
#define MOTUTIL_MAIN_DISP 0
|
||||
#define MOTUTIL_CLI_DISP 1
|
||||
|
||||
int sde_debugfs_mot_util_init(struct sde_kms *sde_kms,
|
||||
struct dentry *parent);
|
||||
|
||||
|
||||
Reference in new issue
Block a user