disp: msm: dsi: add support for DMA CMD scheduling for CMD mode panels

The change allows for configuring a command DMA window during which
the command is triggered. The DMA window must not intersect with the
MDP tear check window. Once the command transfer is successful, the
trigger control needs to reset to the default DMA trigger specified
by the panel.

Change-Id: I5485ca1f8e141ed92dc8c77c2daf579634271022
Signed-off-by: Satya Rama Aditya Pinapala <psraditya30@codeaurora.org>
This commit is contained in:
Satya Rama Aditya Pinapala
2020-05-28 19:44:06 -07:00
parent 32e305e278
commit 50af1eb43b
9 changed files with 341 additions and 37 deletions

View File

@@ -673,8 +673,10 @@ static int dsi_display_read_status(struct dsi_display_ctrl *ctrl,
lenp = config->status_valid_params ?: config->status_cmds_rlen;
count = config->status_cmd.count;
cmds = config->status_cmd.cmds;
flags |= (DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_READ |
DSI_CTRL_CMD_CUSTOM_DMA_SCHED);
flags |= (DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_READ);
if (ctrl->ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE)
flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED;
for (i = 0; i < count; ++i) {
memset(config->status_buf, 0x0, SZ_4K);
@@ -682,6 +684,10 @@ static int dsi_display_read_status(struct dsi_display_ctrl *ctrl,
cmds[i].msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
flags |= DSI_CTRL_CMD_LAST_COMMAND;
}
if ((cmds[i].msg.flags & MIPI_DSI_MSG_CMD_DMA_SCHED) &&
(panel->panel_initialized))
flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED;
if (config->status_cmd.state == DSI_CMD_SET_STATE_LP)
cmds[i].msg.flags |= MIPI_DSI_MSG_USE_LPM;
cmds[i].msg.rx_buf = config->status_buf;
@@ -916,6 +922,9 @@ static int dsi_display_cmd_prepare(const char *cmd_buf, u32 cmd_buf_len,
return -EINVAL;
}
if (cmd->last_command)
cmd->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;
for (i = 0; i < cmd->msg.tx_len; i++)
payload[i] = cmd_buf[7 + i];
@@ -972,8 +981,12 @@ static int dsi_display_cmd_rx(struct dsi_display *display,
goto error;
}
flags |= (DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_READ |
DSI_CTRL_CMD_CUSTOM_DMA_SCHED);
flags |= (DSI_CTRL_CMD_FETCH_MEMORY | DSI_CTRL_CMD_READ);
if ((m_ctrl->ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE) ||
((cmd->msg.flags & MIPI_DSI_MSG_CMD_DMA_SCHED) &&
(display->panel->panel_initialized)))
flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED;
rc = dsi_ctrl_cmd_transfer(m_ctrl->ctrl, &cmd->msg, &flags);
if (rc <= 0)
DSI_ERR("rx cmd transfer failed rc = %d\n", rc);
@@ -1617,6 +1630,107 @@ error:
return len;
}
static ssize_t debugfs_update_cmd_scheduling_params(struct file *file,
const char __user *user_buf,
size_t user_len,
loff_t *ppos)
{
struct dsi_display *display = file->private_data;
struct dsi_display_ctrl *display_ctrl;
char *buf;
int rc = 0;
u32 line = 0, window = 0;
size_t len;
int i;
if (!display)
return -ENODEV;
if (*ppos)
return 0;
buf = kzalloc(256, GFP_KERNEL);
if (ZERO_OR_NULL_PTR(buf))
return -ENOMEM;
len = min_t(size_t, user_len, 255);
if (copy_from_user(buf, user_buf, len)) {
rc = -EINVAL;
goto error;
}
buf[len] = '\0'; /* terminate the string */
if (sscanf(buf, "%d %d", &line, &window) != 2)
return -EFAULT;
display_for_each_ctrl(i, display) {
struct dsi_ctrl *ctrl;
display_ctrl = &display->ctrl[i];
if (!display_ctrl->ctrl)
continue;
ctrl = display_ctrl->ctrl;
ctrl->host_config.common_config.dma_sched_line = line;
ctrl->host_config.common_config.dma_sched_window = window;
}
rc = len;
error:
kfree(buf);
return rc;
}
static ssize_t debugfs_read_cmd_scheduling_params(struct file *file,
char __user *user_buf,
size_t user_len,
loff_t *ppos)
{
struct dsi_display *display = file->private_data;
struct dsi_display_ctrl *m_ctrl;
struct dsi_ctrl *ctrl;
char *buf;
u32 len = 0;
int rc = 0;
size_t max_len = min_t(size_t, user_len, SZ_4K);
if (!display)
return -ENODEV;
if (*ppos)
return 0;
m_ctrl = &display->ctrl[display->cmd_master_idx];
ctrl = m_ctrl->ctrl;
buf = kzalloc(max_len, GFP_KERNEL);
if (ZERO_OR_NULL_PTR(buf))
return -ENOMEM;
len += scnprintf(buf, max_len, "Schedule command window start: %d\n",
ctrl->host_config.common_config.dma_sched_line);
len += scnprintf((buf + len), max_len - len,
"Schedule command window width: %d\n",
ctrl->host_config.common_config.dma_sched_window);
if (len > max_len)
len = max_len;
if (copy_to_user(user_buf, buf, len)) {
rc = -EFAULT;
goto error;
}
*ppos += len;
error:
kfree(buf);
return len;
}
static const struct file_operations dump_info_fops = {
.open = simple_open,
.read = debugfs_dump_info_read,
@@ -1639,6 +1753,12 @@ static const struct file_operations esd_check_mode_fops = {
.read = debugfs_read_esd_check_mode,
};
static const struct file_operations dsi_command_scheduling_fops = {
.open = simple_open,
.write = debugfs_update_cmd_scheduling_params,
.read = debugfs_read_cmd_scheduling_params,
};
static int dsi_display_debugfs_init(struct dsi_display *display)
{
int rc = 0;
@@ -1690,6 +1810,18 @@ static int dsi_display_debugfs_init(struct dsi_display *display)
goto error_remove_dir;
}
dump_file = debugfs_create_file("cmd_sched_params",
0644,
dir,
display,
&dsi_command_scheduling_fops);
if (IS_ERR_OR_NULL(dump_file)) {
rc = PTR_ERR(dump_file);
DSI_ERR("[%s] debugfs for cmd scheduling file failed, rc=%d\n",
display->name, rc);
goto error_remove_dir;
}
misr_data = debugfs_create_file("misr_data",
0600,
dir,
@@ -2855,6 +2987,12 @@ static int dsi_display_broadcast_cmd(struct dsi_display *display,
m_flags |= DSI_CTRL_CMD_LAST_COMMAND;
}
if ((msg->flags & MIPI_DSI_MSG_CMD_DMA_SCHED) &&
(display->panel->panel_initialized)) {
flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED;
m_flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED;
}
if (display->queue_cmd_waits ||
msg->flags & MIPI_DSI_MSG_ASYNC_OVERRIDE) {
flags |= DSI_CTRL_CMD_ASYNC_WAIT;
@@ -3023,6 +3161,10 @@ 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->flags & MIPI_DSI_MSG_CMD_DMA_SCHED) &&
(display->panel->panel_initialized))
cmd_flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED;
rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg,
&cmd_flags);
if (rc) {