From c3c683472d59339a17f7e92d5960e0b8eed4c3af Mon Sep 17 00:00:00 2001 From: Satya Rama Aditya Pinapala Date: Mon, 14 Dec 2020 10:49:17 -0800 Subject: [PATCH] disp: msm: dsi: remove custom upstream MSM DSI flags Change removes the use of custom MSM DSI flags that will not be available as part of GKI.2.0 Change-Id: I2337a54b1d6346ebdc18e9e6c3c8e7a07f421bdd Signed-off-by: Satya Rama Aditya Pinapala --- msm/dsi/dsi_ctrl.c | 136 ++++++---------------- msm/dsi/dsi_ctrl.h | 9 +- msm/dsi/dsi_defs.h | 19 ++- msm/dsi/dsi_display.c | 265 ++++++++++++++++++++++-------------------- msm/dsi/dsi_panel.c | 32 +++-- msm/dsi/dsi_panel.h | 8 +- 6 files changed, 218 insertions(+), 251 deletions(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 9170ee8a2e..c8ea6b77d9 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #include @@ -1216,32 +1216,6 @@ static void dsi_ctrl_wait_for_video_done(struct dsi_ctrl *dsi_ctrl) udelay(sleep_ms * 1000); } -void dsi_message_setup_tx_mode(struct dsi_ctrl *dsi_ctrl, - u32 cmd_len, - u32 *flags) -{ - /** - * Setup the mode of transmission - * override cmd fetch mode during secure session - */ - if (dsi_ctrl->secure_mode) { - SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_CASE1); - *flags &= ~DSI_CTRL_CMD_FETCH_MEMORY; - *flags |= DSI_CTRL_CMD_FIFO_STORE; - DSI_CTRL_DEBUG(dsi_ctrl, - "override to TPG during secure session\n"); - return; - } - - /* Check to see if cmd len plus header is greater than fifo size */ - if ((cmd_len + 4) > DSI_EMBEDDED_MODE_DMA_MAX_SIZE_BYTES) { - *flags |= DSI_CTRL_CMD_NON_EMBEDDED_MODE; - DSI_CTRL_DEBUG(dsi_ctrl, "override to non-embedded mode,cmd len =%d\n", - cmd_len); - return; - } -} - int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl, u32 cmd_len, u32 *flags) @@ -1395,8 +1369,7 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl, hw_flags |= (flags & DSI_CTRL_CMD_DEFER_TRIGGER) ? DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER : 0; - if ((msg->flags & MIPI_DSI_MSG_LASTCOMMAND) || - (flags & DSI_CTRL_CMD_LAST_COMMAND)) + if (flags & DSI_CTRL_CMD_LAST_COMMAND) hw_flags |= DSI_CTRL_CMD_LAST_COMMAND; if (flags & DSI_CTRL_CMD_DEFER_TRIGGER) { @@ -1482,44 +1455,21 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl, } } -static void dsi_ctrl_validate_msg_flags(struct dsi_ctrl *dsi_ctrl, - const struct mipi_dsi_msg *msg, - u32 *flags) -{ - /* - * ASYNC command wait mode is not supported for - * - commands sent using DSI FIFO memory - * - DSI read commands - * - DCS commands sent in non-embedded mode - * - whenever an explicit wait time is specificed for the command - * since the wait time cannot be guaranteed in async mode - * - video mode panels - * If async override is set, skip async flag reset - */ - if (((*flags & DSI_CTRL_CMD_FIFO_STORE) || - *flags & DSI_CTRL_CMD_READ || - *flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE || - msg->wait_ms || - (dsi_ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE)) && - !(msg->flags & MIPI_DSI_MSG_ASYNC_OVERRIDE)) - *flags &= ~DSI_CTRL_CMD_ASYNC_WAIT; -} - -static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, - const struct mipi_dsi_msg *msg, - u32 *flags) +static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, struct dsi_cmd_desc *cmd_desc) { int rc = 0; struct mipi_dsi_packet packet; struct dsi_ctrl_cmd_dma_fifo_info cmd; struct dsi_ctrl_cmd_dma_info cmd_mem; + const struct mipi_dsi_msg *msg; u32 length = 0; u8 *buffer = NULL; u32 cnt = 0; u8 *cmdbuf; + u32 *flags; - /* Select the tx mode to transfer the command */ - dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, flags); + msg = &cmd_desc->msg; + flags = &cmd_desc->ctrl_flags; /* Validate the mode before sending the command */ rc = dsi_message_validate_tx_mode(dsi_ctrl, msg->tx_len, flags); @@ -1530,10 +1480,7 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, goto error; } - dsi_ctrl_validate_msg_flags(dsi_ctrl, msg, flags); - SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_ENTRY, flags); - if (dsi_ctrl->dma_wait_queued) dsi_ctrl_flush_cmd_dma_queue(dsi_ctrl); @@ -1588,8 +1535,7 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, } } - if ((msg->flags & MIPI_DSI_MSG_LASTCOMMAND) || - (*flags & DSI_CTRL_CMD_LAST_COMMAND)) + if (*flags & DSI_CTRL_CMD_LAST_COMMAND) buffer[3] |= BIT(7);//set the last cmd bit in header. if (*flags & DSI_CTRL_CMD_FETCH_MEMORY) { @@ -1610,12 +1556,11 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, dsi_ctrl->cmd_len += length; - if (!(msg->flags & MIPI_DSI_MSG_LASTCOMMAND) && - !(*flags & DSI_CTRL_CMD_LAST_COMMAND)) { - goto error; - } else { + if (*flags & DSI_CTRL_CMD_LAST_COMMAND) { cmd_mem.length = dsi_ctrl->cmd_len; dsi_ctrl->cmd_len = 0; + } else { + goto error; } } else if (*flags & DSI_CTRL_CMD_FIFO_STORE) { @@ -1637,28 +1582,26 @@ error: return rc; } -static int dsi_set_max_return_size(struct dsi_ctrl *dsi_ctrl, - const struct mipi_dsi_msg *rx_msg, - u32 size) +static int dsi_set_max_return_size(struct dsi_ctrl *dsi_ctrl, struct dsi_cmd_desc *rx_cmd, u32 size) { int rc = 0; + const struct mipi_dsi_msg *rx_msg = &rx_cmd->msg; u8 tx[2] = { (u8)(size & 0xFF), (u8)(size >> 8) }; - u32 flags = DSI_CTRL_CMD_FETCH_MEMORY; u16 dflags = rx_msg->flags; - struct mipi_dsi_msg msg = { - .channel = rx_msg->channel, - .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, - .tx_len = 2, - .tx_buf = tx, - .flags = rx_msg->flags, + struct dsi_cmd_desc cmd= { + .msg.channel = rx_msg->channel, + .msg.type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, + .msg.tx_len = 2, + .msg.tx_buf = tx, + .msg.flags = rx_msg->flags, }; /* remove last message flag to batch max packet cmd to read command */ dflags &= ~BIT(3); - msg.flags = dflags; - - rc = dsi_message_tx(dsi_ctrl, &msg, &flags); + cmd.msg.flags = dflags; + cmd.ctrl_flags = DSI_CTRL_CMD_FETCH_MEMORY; + rc = dsi_message_tx(dsi_ctrl, &cmd); if (rc) DSI_CTRL_ERR(dsi_ctrl, "failed to send max return size packet, rc=%d\n", rc); @@ -1718,9 +1661,7 @@ static int dsi_parse_long_read_resp(const struct mipi_dsi_msg *msg, return msg->rx_len; } -static int dsi_message_rx(struct dsi_ctrl *dsi_ctrl, - const struct mipi_dsi_msg *msg, - u32 *flags) +static int dsi_message_rx(struct dsi_ctrl *dsi_ctrl, struct dsi_cmd_desc *cmd_desc) { int rc = 0; u32 rd_pkt_size, total_read_len, hw_read_cnt; @@ -1730,13 +1671,15 @@ static int dsi_message_rx(struct dsi_ctrl *dsi_ctrl, u32 dlen, diff, rlen; unsigned char *buff; char cmd; + const struct mipi_dsi_msg *msg; - if (!msg) { - DSI_CTRL_ERR(dsi_ctrl, "Invalid msg\n"); + if (!cmd_desc) { + DSI_CTRL_ERR(dsi_ctrl, "Invalid command\n"); rc = -EINVAL; goto error; } + msg = &cmd_desc->msg; rlen = msg->rx_len; if (msg->rx_len <= 2) { short_resp = true; @@ -1755,7 +1698,7 @@ static int dsi_message_rx(struct dsi_ctrl *dsi_ctrl, buff = msg->rx_buf; while (!read_done) { - rc = dsi_set_max_return_size(dsi_ctrl, msg, rd_pkt_size); + rc = dsi_set_max_return_size(dsi_ctrl, cmd_desc, rd_pkt_size); if (rc) { DSI_CTRL_ERR(dsi_ctrl, "Failed to set max return packet size, rc=%d\n", rc); @@ -1765,7 +1708,7 @@ static int dsi_message_rx(struct dsi_ctrl *dsi_ctrl, /* clear RDBK_DATA registers before proceeding */ dsi_ctrl->hw.ops.clear_rdbk_register(&dsi_ctrl->hw); - rc = dsi_message_tx(dsi_ctrl, msg, flags); + rc = dsi_message_tx(dsi_ctrl, cmd_desc); if (rc) { DSI_CTRL_ERR(dsi_ctrl, "Message transmission failed, rc=%d\n", rc); @@ -1775,9 +1718,9 @@ static int dsi_message_rx(struct dsi_ctrl *dsi_ctrl, * wait before reading rdbk_data register, if any delay is * required after sending the read command. */ - if (msg->wait_ms) - usleep_range(msg->wait_ms * 1000, - ((msg->wait_ms * 1000) + 10)); + if (cmd_desc->post_wait_ms) + usleep_range(cmd_desc->post_wait_ms * 1000, + ((cmd_desc->post_wait_ms * 1000) + 10)); dlen = dsi_ctrl->hw.ops.get_cmd_read_data(&dsi_ctrl->hw, buff, total_bytes_read, @@ -3339,8 +3282,7 @@ int dsi_ctrl_validate_timing(struct dsi_ctrl *dsi_ctrl, /** * dsi_ctrl_cmd_transfer() - Transfer commands on DSI link * @dsi_ctrl: DSI controller handle. - * @msg: Message to transfer on DSI link. - * @flags: Modifiers for message transfer. + * @cmd: Command description to transfer on DSI link. * * Command transfer can be done only when command engine is enabled. The * transfer API will block until either the command transfer finishes or @@ -3350,13 +3292,11 @@ int dsi_ctrl_validate_timing(struct dsi_ctrl *dsi_ctrl, * * Return: error code. */ -int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl, - const struct mipi_dsi_msg *msg, - u32 *flags) +int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl, struct dsi_cmd_desc *cmd) { int rc = 0; - if (!dsi_ctrl || !msg) { + if (!dsi_ctrl || !cmd) { DSI_CTRL_ERR(dsi_ctrl, "Invalid params\n"); return -EINVAL; } @@ -3370,13 +3310,13 @@ int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl, goto error; } - if (*flags & DSI_CTRL_CMD_READ) { - rc = dsi_message_rx(dsi_ctrl, msg, flags); + if (cmd->ctrl_flags & DSI_CTRL_CMD_READ) { + rc = dsi_message_rx(dsi_ctrl, cmd); if (rc <= 0) DSI_CTRL_ERR(dsi_ctrl, "read message failed read length, rc=%d\n", rc); } else { - rc = dsi_message_tx(dsi_ctrl, msg, flags); + rc = dsi_message_tx(dsi_ctrl, cmd); if (rc) DSI_CTRL_ERR(dsi_ctrl, "command msg transfer failed, rc = %d\n", rc); diff --git a/msm/dsi/dsi_ctrl.h b/msm/dsi/dsi_ctrl.h index a329075052..ec34cbd039 100644 --- a/msm/dsi/dsi_ctrl.h +++ b/msm/dsi/dsi_ctrl.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #ifndef _DSI_CTRL_H_ @@ -565,8 +565,7 @@ int dsi_ctrl_set_tpg_state(struct dsi_ctrl *dsi_ctrl, bool on); /** * dsi_ctrl_cmd_transfer() - Transfer commands on DSI link * @dsi_ctrl: DSI controller handle. - * @msg: Message to transfer on DSI link. - * @flags: Modifiers for message transfer. + * @cmd: Description of the cmd to be sent. * * Command transfer can be done only when command engine is enabled. The * transfer API will until either the command transfer finishes or the timeout @@ -575,9 +574,7 @@ int dsi_ctrl_set_tpg_state(struct dsi_ctrl *dsi_ctrl, bool on); * * Return: error code. */ -int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl, - const struct mipi_dsi_msg *msg, - u32 *flags); +int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl, struct dsi_cmd_desc *cmd); /** * dsi_ctrl_cmd_tx_trigger() - Trigger a deferred command. diff --git a/msm/dsi/dsi_defs.h b/msm/dsi/dsi_defs.h index 71c16c4780..fec47e87ee 100644 --- a/msm/dsi/dsi_defs.h +++ b/msm/dsi/dsi_defs.h @@ -358,14 +358,18 @@ enum dsi_video_traffic_mode { /** * struct dsi_cmd_desc - description of a dsi command - * @msg: dsi mipi msg packet - * @last_command: indicates whether the cmd is the last one to send - * @post_wait_ms: post wait duration + * @msg: dsi mipi msg packet + * @last_command: indicates whether the cmd is the last one to send + * @post_wait_ms: post wait duration + * @ctrl: index of DSI controller + * @ctrl_flags: controller flags */ struct dsi_cmd_desc { struct mipi_dsi_msg msg; bool last_command; u32 post_wait_ms; + u32 ctrl; + u32 ctrl_flags; }; /** @@ -786,4 +790,13 @@ static inline u64 dsi_h_total_dce(struct dsi_mode_info *mode) return h_total; } +/** + * dsi_host_transfer_sub() - transfers DSI commands from host to panel + * @host: pointer to the DSI mipi host device + * @cmd: DSI command to be transferred + * + * Return: error code. + */ +int dsi_host_transfer_sub(struct mipi_dsi_host *host, struct dsi_cmd_desc *cmd); + #endif /* _DSI_DEFS_H_ */ diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 37a691fda5..288ea6182b 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -653,17 +653,98 @@ static void dsi_display_parse_te_data(struct dsi_display *display) display->te_source = val; } +static void dsi_display_set_cmd_tx_ctrl_flags(struct dsi_display *display, + struct dsi_cmd_desc *cmd) +{ + struct dsi_display_ctrl *ctrl, *m_ctrl; + struct mipi_dsi_msg *msg = &cmd->msg; + u32 flags = 0; + int i = 0; + + m_ctrl = &display->ctrl[display->clk_master_idx]; + display_for_each_ctrl(i, display) { + ctrl = &display->ctrl[i]; + if (!ctrl->ctrl) + continue; + + /* + * Set cmd transfer mode flags. + * 1) Default selection is CMD fetch from memory. + * 2) In secure session override and use FIFO rather than + * memory. + * 3) If cmd_len is greater than FIFO size non embedded mode of + * tx is used. + */ + flags = DSI_CTRL_CMD_FETCH_MEMORY; + if (ctrl->ctrl->secure_mode) { + flags &= ~DSI_CTRL_CMD_FETCH_MEMORY; + flags |= DSI_CTRL_CMD_FIFO_STORE; + } else if (msg->tx_len > DSI_EMBEDDED_MODE_DMA_MAX_SIZE_BYTES) { + flags |= DSI_CTRL_CMD_NON_EMBEDDED_MODE; + } + + /* Set flags needed for broadcast. Read commands are always unicast */ + if (!(msg->flags & MIPI_DSI_MSG_UNICAST_COMMAND) && (display->ctrl_count > 1)) + flags |= DSI_CTRL_CMD_BROADCAST | DSI_CTRL_CMD_DEFER_TRIGGER; + + /* + * Set flags for command scheduling. + * 1) In video mode command DMA scheduling is default. + * 2) In command mode command DMA scheduling depends on message + * flag and TE needs to be running. + */ + if (display->panel->panel_mode == DSI_OP_VIDEO_MODE) { + flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED; + } else { + if (msg->flags & MIPI_DSI_MSG_CMD_DMA_SCHED) + flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED; + if (!display->enabled) + flags &= ~DSI_CTRL_CMD_CUSTOM_DMA_SCHED; + } + + /* Set flags for last command */ + if (!(msg->flags & MIPI_DSI_MSG_BATCH_COMMAND)) + flags |= DSI_CTRL_CMD_LAST_COMMAND; + + /* + * Set flags for asynchronous wait. + * Asynchronous wait is supported in the following scenarios + * 1) queue_cmd_waits is set by connector and + * - commands are not sent using DSI FIFO memory + * - commands are not sent in non-embedded mode + * - not a video mode panel + * - no explicit msg post_wait_ms is specified + * - not a read command + * 2) if async override msg flag is present + */ + if (display->queue_cmd_waits) + if (!(flags & DSI_CTRL_CMD_FIFO_STORE) && + !(flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) && + !(display->panel->panel_mode == DSI_OP_VIDEO_MODE) && + (cmd->post_wait_ms == 0) && + !(cmd->ctrl_flags & DSI_CTRL_CMD_READ)) + flags |= DSI_CTRL_CMD_ASYNC_WAIT; + if (msg->flags & MIPI_DSI_MSG_ASYNC_OVERRIDE) + flags |= DSI_CTRL_CMD_ASYNC_WAIT; + } + + cmd->ctrl_flags |= flags; +} + static int dsi_display_read_status(struct dsi_display_ctrl *ctrl, - struct dsi_panel *panel) + struct dsi_display *display) { int i, rc = 0, count = 0, start = 0, *lenp; struct drm_panel_esd_config *config; struct dsi_cmd_desc *cmds; + struct dsi_panel *panel; u32 flags = 0; - if (!panel || !ctrl || !ctrl->ctrl) + if (!display->panel || !ctrl || !ctrl->ctrl) return -EINVAL; + panel = display->panel; + /* * When DSI controller is not in initialized state, we do not want to * report a false ESD failure and hence we defer until next read @@ -676,26 +757,20 @@ 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); - - if (ctrl->ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE) - flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED; + flags = DSI_CTRL_CMD_READ; for (i = 0; i < count; ++i) { memset(config->status_buf, 0x0, SZ_4K); - if (cmds[i].last_command) { - 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.flags |= MIPI_DSI_MSG_UNICAST_COMMAND; cmds[i].msg.rx_buf = config->status_buf; cmds[i].msg.rx_len = config->status_cmds_rlen[i]; - rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, &cmds[i].msg, &flags); + cmds[i].ctrl_flags = flags; + dsi_display_set_cmd_tx_ctrl_flags(display,&cmds[i]); + rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, &cmds[i]); if (rc <= 0) { DSI_ERR("rx cmd transfer failed rc=%d\n", rc); return rc; @@ -710,11 +785,11 @@ static int dsi_display_read_status(struct dsi_display_ctrl *ctrl, } static int dsi_display_validate_status(struct dsi_display_ctrl *ctrl, - struct dsi_panel *panel) + struct dsi_display *display) { int rc = 0; - rc = dsi_display_read_status(ctrl, panel); + rc = dsi_display_read_status(ctrl, display); if (rc <= 0) { goto exit; } else { @@ -722,7 +797,7 @@ static int dsi_display_validate_status(struct dsi_display_ctrl *ctrl, * panel status read successfully. * check for validity of the data read back. */ - rc = dsi_display_validate_reg_read(panel); + rc = dsi_display_validate_reg_read(display->panel); if (!rc) { rc = -EINVAL; goto exit; @@ -756,7 +831,7 @@ static int dsi_display_status_reg_read(struct dsi_display *display) return -EPERM; } - rc = dsi_display_validate_status(m_ctrl, display->panel); + rc = dsi_display_validate_status(m_ctrl, display); if (rc <= 0) { DSI_ERR("[%s] read status failed on master,rc=%d\n", display->name, rc); @@ -771,7 +846,7 @@ static int dsi_display_status_reg_read(struct dsi_display *display) if (ctrl == m_ctrl) continue; - rc = dsi_display_validate_status(ctrl, display->panel); + rc = dsi_display_validate_status(ctrl, display); if (rc <= 0) { DSI_ERR("[%s] read status failed on slave,rc=%d\n", display->name, rc); @@ -913,36 +988,6 @@ release_panel_lock: return rc; } -static int dsi_display_cmd_prepare(const char *cmd_buf, u32 cmd_buf_len, - struct dsi_cmd_desc *cmd, u8 *payload, u32 payload_len) -{ - int i; - - memset(cmd, 0x00, sizeof(*cmd)); - cmd->msg.type = cmd_buf[0]; - cmd->last_command = (cmd_buf[1] == 1); - cmd->msg.channel = cmd_buf[2]; - cmd->msg.flags = cmd_buf[3]; - cmd->msg.ctrl = 0; - cmd->post_wait_ms = cmd->msg.wait_ms = cmd_buf[4]; - cmd->msg.tx_len = ((cmd_buf[5] << 8) | (cmd_buf[6])); - - if (cmd->msg.tx_len > payload_len) { - DSI_ERR("Incorrect payload length tx_len %zu, payload_len %d\n", - cmd->msg.tx_len, payload_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]; - - cmd->msg.tx_buf = payload; - return 0; -} - static int dsi_display_ctrl_get_host_init_state(struct dsi_display *dsi_display, bool *state) { @@ -992,13 +1037,11 @@ static int dsi_display_cmd_rx(struct dsi_display *display, goto error; } - 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->enabled))) - flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED; + flags = DSI_CTRL_CMD_READ; - rc = dsi_ctrl_cmd_transfer(m_ctrl->ctrl, &cmd->msg, &flags); + cmd->ctrl_flags = flags; + dsi_display_set_cmd_tx_ctrl_flags(display, cmd); + rc = dsi_ctrl_cmd_transfer(m_ctrl->ctrl, cmd); if (rc <= 0) DSI_ERR("rx cmd transfer failed rc = %d\n", rc); @@ -1030,7 +1073,7 @@ int dsi_display_cmd_transfer(struct drm_connector *connector, DSI_DEBUG("[DSI] Display command transfer\n"); - if ((cmd_buf[1]) || (cmd_buf[3] & MIPI_DSI_MSG_LASTCOMMAND)) + if (!(cmd_buf[3] & MIPI_DSI_MSG_BATCH_COMMAND)) transfer = true; mutex_lock(&dsi_display->display_lock); @@ -1087,10 +1130,7 @@ int dsi_display_cmd_transfer(struct drm_connector *connector, dsi_display->tx_cmd_buf_ndx = 0; for (i = 0; i < cnt; i++) { - if (cmds->last_command) - cmds->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND; - rc = dsi_display->host.ops->transfer(&dsi_display->host, - &cmds->msg); + rc = dsi_host_transfer_sub(&dsi_display->host, cmds); if (rc < 0) { DSI_ERR("failed to send command, rc=%d\n", rc); break; @@ -1143,7 +1183,6 @@ int dsi_display_cmd_receive(void *display, const char *cmd_buf, { struct dsi_display *dsi_display = display; struct dsi_cmd_desc cmd = {}; - u8 cmd_payload[MAX_CMD_PAYLOAD_SIZE] = {0}; bool state = false; int rc = -1; @@ -1152,15 +1191,15 @@ int dsi_display_cmd_receive(void *display, const char *cmd_buf, return -EINVAL; } - rc = dsi_display_cmd_prepare(cmd_buf, cmd_buf_len, - &cmd, cmd_payload, MAX_CMD_PAYLOAD_SIZE); + rc = dsi_panel_create_cmd_packets(cmd_buf, cmd_buf_len, 1, &cmd); if (rc) { - DSI_ERR("[DSI] command prepare failed, rc = %d\n", rc); + DSI_ERR("[DSI] command packet create failed, rc = %d\n", rc); return rc; } cmd.msg.rx_buf = recv_buf; cmd.msg.rx_len = recv_buf_len; + cmd.msg.flags |= MIPI_DSI_MSG_UNICAST_COMMAND; mutex_lock(&dsi_display->display_lock); rc = dsi_display_ctrl_get_host_init_state(dsi_display, &state); @@ -3096,66 +3135,41 @@ static void dsi_display_mask_overflow(struct dsi_display *display, u32 flags, } } -static int dsi_display_broadcast_cmd(struct dsi_display *display, - const struct mipi_dsi_msg *msg) +static int dsi_display_broadcast_cmd(struct dsi_display *display, struct dsi_cmd_desc *cmd) { int rc = 0; - u32 flags, m_flags; struct dsi_display_ctrl *ctrl, *m_ctrl; int i; - m_flags = (DSI_CTRL_CMD_BROADCAST | DSI_CTRL_CMD_BROADCAST_MASTER | - DSI_CTRL_CMD_DEFER_TRIGGER | DSI_CTRL_CMD_FETCH_MEMORY); - flags = (DSI_CTRL_CMD_BROADCAST | DSI_CTRL_CMD_DEFER_TRIGGER | - DSI_CTRL_CMD_FETCH_MEMORY); - - if ((msg->flags & MIPI_DSI_MSG_LASTCOMMAND)) { - flags |= DSI_CTRL_CMD_LAST_COMMAND; - m_flags |= DSI_CTRL_CMD_LAST_COMMAND; - } - - /* - * During broadcast command dma scheduling is always recommended. - * As long as the display is enabled and TE is running the - * DSI_CTRL_CMD_CUSTOM_DMA_SCHED flag should be set. - */ - if (display->enabled) { - 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; - m_flags |= DSI_CTRL_CMD_ASYNC_WAIT; - } - /* * 1. Setup commands in FIFO * 2. Trigger commands */ m_ctrl = &display->ctrl[display->cmd_master_idx]; - dsi_display_mask_overflow(display, m_flags, true); - rc = dsi_ctrl_cmd_transfer(m_ctrl->ctrl, msg, &m_flags); + dsi_display_mask_overflow(display, cmd->ctrl_flags, true); + + cmd->ctrl_flags |= DSI_CTRL_CMD_BROADCAST_MASTER; + rc = dsi_ctrl_cmd_transfer(m_ctrl->ctrl, cmd); if (rc) { DSI_ERR("[%s] cmd transfer failed on master,rc=%d\n", display->name, rc); goto error; } + cmd->ctrl_flags &= ~DSI_CTRL_CMD_BROADCAST_MASTER; display_for_each_ctrl(i, display) { ctrl = &display->ctrl[i]; if (ctrl == m_ctrl) continue; - rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, msg, &flags); + rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, cmd); if (rc) { DSI_ERR("[%s] cmd transfer failed, rc=%d\n", display->name, rc); goto error; } - rc = dsi_ctrl_cmd_tx_trigger(ctrl->ctrl, flags); + rc = dsi_ctrl_cmd_tx_trigger(ctrl->ctrl, cmd->ctrl_flags); if (rc) { DSI_ERR("[%s] cmd trigger failed, rc=%d\n", display->name, rc); @@ -3163,7 +3177,7 @@ static int dsi_display_broadcast_cmd(struct dsi_display *display, } } - rc = dsi_ctrl_cmd_tx_trigger(m_ctrl->ctrl, m_flags); + rc = dsi_ctrl_cmd_tx_trigger(m_ctrl->ctrl, cmd->ctrl_flags | DSI_CTRL_CMD_BROADCAST_MASTER); if (rc) { DSI_ERR("[%s] cmd trigger failed for master, rc=%d\n", display->name, rc); @@ -3171,7 +3185,7 @@ static int dsi_display_broadcast_cmd(struct dsi_display *display, } error: - dsi_display_mask_overflow(display, m_flags, false); + dsi_display_mask_overflow(display, cmd->ctrl_flags, false); return rc; } @@ -3229,13 +3243,12 @@ static int dsi_host_detach(struct mipi_dsi_host *host, return 0; } -static ssize_t dsi_host_transfer(struct mipi_dsi_host *host, - const struct mipi_dsi_msg *msg) +int dsi_host_transfer_sub(struct mipi_dsi_host *host, struct dsi_cmd_desc *cmd) { struct dsi_display *display; int rc = 0, ret = 0; - if (!host || !msg) { + if (!host || !cmd) { DSI_ERR("Invalid params\n"); return 0; } @@ -3278,28 +3291,18 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host, } } - if (display->ctrl_count > 1 && !(msg->flags & MIPI_DSI_MSG_UNICAST)) { - rc = dsi_display_broadcast_cmd(display, msg); + dsi_display_set_cmd_tx_ctrl_flags(display, cmd); + + if (cmd->ctrl_flags & DSI_CTRL_CMD_BROADCAST) { + rc = dsi_display_broadcast_cmd(display, cmd); if (rc) { - DSI_ERR("[%s] cmd broadcast failed, rc=%d\n", - display->name, rc); + DSI_ERR("[%s] cmd broadcast failed, rc=%d\n", display->name, rc); goto error_disable_cmd_engine; } } else { - int ctrl_idx = (msg->flags & MIPI_DSI_MSG_UNICAST) ? - msg->ctrl : 0; - u32 cmd_flags = DSI_CTRL_CMD_FETCH_MEMORY; + int idx = cmd->ctrl; - if (display->queue_cmd_waits || - msg->flags & MIPI_DSI_MSG_ASYNC_OVERRIDE) - cmd_flags |= DSI_CTRL_CMD_ASYNC_WAIT; - - if ((msg->flags & MIPI_DSI_MSG_CMD_DMA_SCHED) && - (display->enabled)) - cmd_flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED; - - rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg, - &cmd_flags); + rc = dsi_ctrl_cmd_transfer(display->ctrl[idx].ctrl, cmd); if (rc) { DSI_ERR("[%s] cmd transfer failed, rc=%d\n", display->name, rc); @@ -3324,6 +3327,26 @@ error: return rc; } +static ssize_t dsi_host_transfer(struct mipi_dsi_host *host, const struct mipi_dsi_msg *msg) +{ + int rc = 0; + struct dsi_cmd_desc cmd; + + if (!msg) { + DSI_ERR("Invalid params\n"); + return 0; + } + + memcpy(&cmd.msg, msg, sizeof(*msg)); + cmd.ctrl = 0; + cmd.post_wait_ms = 0; + cmd.ctrl_flags = 0; + + rc = dsi_host_transfer_sub(host, &cmd); + + return rc; +} + static struct mipi_dsi_host_ops dsi_host_ops = { .attach = dsi_host_attach, @@ -6223,10 +6246,6 @@ static int dsi_host_ext_attach(struct mipi_dsi_host *host, dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HFP; panel->video_config.pulse_mode_hsa_he = dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HSE; - panel->video_config.bllp_lp11_en = - dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BLLP; - panel->video_config.eof_bllp_lp11_en = - dsi->mode_flags & MIPI_DSI_MODE_VIDEO_EOF_BLLP; } else { panel->panel_mode = DSI_OP_CMD_MODE; DSI_ERR("command mode not supported by ext bridge\n"); diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index cbdc37fd24..b19fce6c61 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -417,7 +417,6 @@ static int dsi_panel_tx_cmd_set(struct dsi_panel *panel, u32 count; enum dsi_cmd_set_state state; struct dsi_display_mode *mode; - const struct mipi_dsi_host_ops *ops = panel->host->ops; if (!panel || !panel->cur_mode) return -EINVAL; @@ -439,13 +438,10 @@ static int dsi_panel_tx_cmd_set(struct dsi_panel *panel, if (state == DSI_CMD_SET_STATE_LP) cmds->msg.flags |= MIPI_DSI_MSG_USE_LPM; - if (cmds->last_command) - cmds->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND; - if (type == DSI_CMD_SET_VID_SWITCH_OUT) cmds->msg.flags |= MIPI_DSI_MSG_ASYNC_OVERRIDE; - len = ops->transfer(panel->host, &cmds->msg); + len = dsi_host_transfer_sub(panel->host, cmds); if (len < 0) { rc = len; DSI_ERR("failed to set cmds(%d), rc=%d\n", type, rc); @@ -1794,13 +1790,17 @@ int dsi_panel_create_cmd_packets(const char *data, u32 size; cmd[i].msg.type = data[0]; - cmd[i].last_command = (data[1] == 1); cmd[i].msg.channel = data[2]; cmd[i].msg.flags |= data[3]; - cmd[i].msg.ctrl = 0; - cmd[i].post_wait_ms = cmd[i].msg.wait_ms = data[4]; + cmd[i].ctrl = 0; + cmd[i].post_wait_ms = data[4]; cmd[i].msg.tx_len = ((data[5] << 8) | (data[6])); + if (cmd[i].msg.flags & MIPI_DSI_MSG_BATCH_COMMAND) + cmd[i].last_command = false; + else + cmd[i].last_command = true; + size = cmd[i].msg.tx_len * sizeof(u8); payload = kzalloc(size, GFP_KERNEL); @@ -1874,11 +1874,9 @@ static int dsi_panel_parse_cmd_sets_sub(struct dsi_panel_cmd_set *cmd, goto error; } - DSI_DEBUG("type=%d, name=%s, length=%d\n", type, - cmd_set_prop_map[type], length); + DSI_DEBUG("type=%d, name=%s, length=%d\n", type, cmd_set_prop_map[type], length); - print_hex_dump_debug("", DUMP_PREFIX_NONE, - 8, 1, data, length, false); + print_hex_dump_debug("", DUMP_PREFIX_NONE, 8, 1, data, length, false); rc = dsi_panel_get_cmd_pkt_count(data, length, &packet_count); if (rc) { @@ -4366,27 +4364,25 @@ static int dsi_panel_roi_prepare_dcs_cmds(struct dsi_panel_cmd_set *set, } set->cmds[0].msg.channel = 0; set->cmds[0].msg.type = MIPI_DSI_DCS_LONG_WRITE; - set->cmds[0].msg.flags = unicast ? MIPI_DSI_MSG_UNICAST : 0; - set->cmds[0].msg.ctrl = unicast ? ctrl_idx : 0; + set->cmds[0].msg.flags = unicast ? MIPI_DSI_MSG_UNICAST_COMMAND : 0; set->cmds[0].msg.tx_len = ROI_CMD_LEN; set->cmds[0].msg.tx_buf = caset; set->cmds[0].msg.rx_len = 0; set->cmds[0].msg.rx_buf = 0; - set->cmds[0].msg.wait_ms = 0; set->cmds[0].last_command = 0; set->cmds[0].post_wait_ms = 0; + set->cmds[0].ctrl = unicast ? ctrl_idx : 0; set->cmds[1].msg.channel = 0; set->cmds[1].msg.type = MIPI_DSI_DCS_LONG_WRITE; - set->cmds[1].msg.flags = unicast ? MIPI_DSI_MSG_UNICAST : 0; - set->cmds[1].msg.ctrl = unicast ? ctrl_idx : 0; + set->cmds[1].msg.flags = unicast ? MIPI_DSI_MSG_UNICAST_COMMAND : 0; set->cmds[1].msg.tx_len = ROI_CMD_LEN; set->cmds[1].msg.tx_buf = paset; set->cmds[1].msg.rx_len = 0; set->cmds[1].msg.rx_buf = 0; - set->cmds[1].msg.wait_ms = 0; set->cmds[1].last_command = 1; set->cmds[1].post_wait_ms = 0; + set->cmds[1].ctrl = unicast ? ctrl_idx : 0; goto exit; diff --git a/msm/dsi/dsi_panel.h b/msm/dsi/dsi_panel.h index 365b4d4991..b9707c3f2c 100644 --- a/msm/dsi/dsi_panel.h +++ b/msm/dsi/dsi_panel.h @@ -30,12 +30,14 @@ #define DSI_MODE_MAX 32 /* - * Defining custom dsi msg flag, - * continued from drm_mipi_dsi.h - * Override to use async transfer + * Defining custom dsi msg flag. + * Using upper byte of flag field for custom DSI flags. + * Lower byte flags specified in drm_mipi_dsi.h. */ #define MIPI_DSI_MSG_ASYNC_OVERRIDE BIT(4) #define MIPI_DSI_MSG_CMD_DMA_SCHED BIT(5) +#define MIPI_DSI_MSG_BATCH_COMMAND BIT(6) +#define MIPI_DSI_MSG_UNICAST_COMMAND BIT(7) enum dsi_panel_rotation { DSI_PANEL_ROTATE_NONE = 0,