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:
@@ -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) {
|
||||
|
Reference in New Issue
Block a user