drm/msm: dsi-ctrl: Remove extra buffer copy

Speed up command transfers by reducing unnecessary intermediate buffer
allocation. The buffer allocation is only needed if using FIFO command
transfer, but otherwise there's no need to allocate and memcpy into
intermediate buffers.

Bug: 136715342
Change-Id: Ie540c285655ec86deb046c187f1e27538fd17d1c
Signed-off-by: Adrian Salido <salidoa@google.com>
Signed-off-by: Adam W. Willis <return.of.octobot@gmail.com>
Signed-off-by: alk3pInjection <webmaster@raspii.tech>
Signed-off-by: azrim <mirzaspc@gmail.com>
This commit is contained in:
Adrian Salido 2019-07-29 17:30:48 -07:00 committed by azrim
parent f5a0e7bd38
commit cbe8927024
No known key found for this signature in database
GPG Key ID: 497F8FB059B45D1C

View File

@ -980,36 +980,25 @@ error:
return rc;
}
static int dsi_ctrl_copy_and_pad_cmd(struct dsi_ctrl *dsi_ctrl,
const struct mipi_dsi_packet *packet,
u8 **buffer,
u32 *size)
static int dsi_ctrl_copy_and_pad_cmd(const struct mipi_dsi_packet *packet,
u8 *buf, size_t len)
{
int rc = 0;
u8 *buf = NULL;
u32 len, i;
u8 cmd_type = 0;
len = packet->size;
len += 0x3; len &= ~0x03; /* Align to 32 bits */
if (unlikely(len < packet->size))
return -EINVAL;
buf = devm_kzalloc(&dsi_ctrl->pdev->dev, len * sizeof(u8), GFP_KERNEL);
if (!buf)
return -ENOMEM;
for (i = 0; i < len; i++) {
if (i >= packet->size)
buf[i] = 0xFF;
else if (i < sizeof(packet->header))
buf[i] = packet->header[i];
else
buf[i] = packet->payload[i - sizeof(packet->header)];
}
memcpy(buf, packet->header, sizeof(packet->header));
if (packet->payload_length)
memcpy(buf + sizeof(packet->header), packet->payload,
packet->payload_length);
if (packet->size < len)
memset(buf + packet->size, 0xFF, len - packet->size);
if (packet->payload_length > 0)
buf[3] |= BIT(6);
/* send embedded BTA for read commands */
cmd_type = buf[2] & 0x3f;
if ((cmd_type == MIPI_DSI_DCS_READ) ||
@ -1018,9 +1007,6 @@ static int dsi_ctrl_copy_and_pad_cmd(struct dsi_ctrl *dsi_ctrl,
(cmd_type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM))
buf[3] |= BIT(5);
*buffer = buf;
*size = len;
return rc;
}
@ -1141,11 +1127,13 @@ int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl,
pr_err("Cannot transfer,size is greater than 4096\n");
return -ENOTSUPP;
}
}
} else if (*flags & DSI_CTRL_CMD_FETCH_MEMORY) {
const size_t transfer_size = dsi_ctrl->cmd_len + cmd_len + 4;
if (*flags & DSI_CTRL_CMD_FETCH_MEMORY) {
if ((dsi_ctrl->cmd_len + cmd_len + 4) > SZ_4K) {
pr_err("Cannot transfer,size is greater than 4096\n");
if (transfer_size > DSI_EMBEDDED_MODE_DMA_MAX_SIZE_BYTES) {
pr_err("Cannot transfer, size: %zu is greater than %d\n",
transfer_size,
DSI_EMBEDDED_MODE_DMA_MAX_SIZE_BYTES);
return -ENOTSUPP;
}
}
@ -1162,9 +1150,9 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
struct dsi_ctrl_cmd_dma_fifo_info cmd;
struct dsi_ctrl_cmd_dma_info cmd_mem;
u32 hw_flags = 0;
u32 length = 0;
u32 length;
u8 *buffer = NULL;
u32 cnt = 0, line_no = 0x1;
u32 line_no = 0x1;
u8 *cmdbuf;
struct dsi_mode_info *timing;
struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops;
@ -1180,6 +1168,10 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
goto error;
}
pr_debug("cmd tx type=%02x cmd=%02x len=%d last=%d\n", msg->type,
msg->tx_len ? *((u8 *)msg->tx_buf) : 0, msg->tx_len,
(msg->flags & MIPI_DSI_MSG_LASTCOMMAND) != 0);
if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
@ -1205,20 +1197,22 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
goto error;
}
rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl,
&packet,
&buffer,
&length);
if (rc) {
pr_err("[%s] failed to copy message, rc=%d\n",
dsi_ctrl->name, rc);
goto error;
}
length = ALIGN(packet.size, 4);
if ((msg->flags & MIPI_DSI_MSG_LASTCOMMAND))
buffer[3] |= BIT(7);//set the last cmd bit in header.
packet.header[3] |= BIT(7);//set the last cmd bit in header.
if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
msm_gem_sync(dsi_ctrl->tx_cmd_buf);
cmdbuf = dsi_ctrl->vaddr + dsi_ctrl->cmd_len;
rc = dsi_ctrl_copy_and_pad_cmd(&packet, cmdbuf, length);
if (rc) {
pr_err("[%s] failed to copy message, rc=%d\n",
dsi_ctrl->name, rc);
goto error;
}
/* Embedded mode config is selected */
cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
@ -1228,12 +1222,6 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
true : false;
cmdbuf = (u8 *)(dsi_ctrl->vaddr);
msm_gem_sync(dsi_ctrl->tx_cmd_buf);
for (cnt = 0; cnt < length; cnt++)
cmdbuf[dsi_ctrl->cmd_len + cnt] = buffer[cnt];
dsi_ctrl->cmd_len += length;
if (!(msg->flags & MIPI_DSI_MSG_LASTCOMMAND)) {
@ -1244,6 +1232,20 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
}
} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
buffer = devm_kzalloc(&dsi_ctrl->pdev->dev, length,
GFP_KERNEL);
if (!buffer) {
rc = -ENOMEM;
goto error;
}
rc = dsi_ctrl_copy_and_pad_cmd(&packet, buffer, length);
if (rc) {
pr_err("[%s] failed to copy message, rc=%d\n",
dsi_ctrl->name, rc);
goto error;
}
cmd.command = (u32 *)buffer;
cmd.size = length;
cmd.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?