Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbae03d9 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: dsi: make panel commands async for vid to cmd switch"

parents 8c63f1de 7ae1b254
Loading
Loading
Loading
Loading
+28 −27
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "dsi_clk.h"
#include "dsi_pwr.h"
#include "dsi_catalog.h"
#include "dsi_panel.h"

#include "sde_dbg.h"

@@ -1279,9 +1280,9 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl,
	}
}

static u32 dsi_ctrl_validate_msg_flags(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)
				u32 *flags)
{
	/*
	 * ASYNC command wait mode is not supported for
@@ -1291,20 +1292,20 @@ static u32 dsi_ctrl_validate_msg_flags(struct dsi_ctrl *dsi_ctrl,
	 *    - 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 ||
	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))
		flags &= ~DSI_CTRL_CMD_ASYNC_WAIT;

	return flags;
		(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)
			  u32 *flags)
{
	int rc = 0;
	struct mipi_dsi_packet packet;
@@ -1316,10 +1317,10 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
	u8 *cmdbuf;

	/* Select the tx mode to transfer the command */
	dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, &flags);
	dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, flags);

	/* Validate the mode before sending the command */
	rc = dsi_message_validate_tx_mode(dsi_ctrl, msg->tx_len, &flags);
	rc = dsi_message_validate_tx_mode(dsi_ctrl, msg->tx_len, flags);
	if (rc) {
		DSI_CTRL_ERR(dsi_ctrl,
			"Cmd tx validation failed, cannot transfer cmd\n");
@@ -1327,16 +1328,16 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
		goto error;
	}

	flags = dsi_ctrl_validate_msg_flags(dsi_ctrl, msg, flags);
	dsi_ctrl_validate_msg_flags(dsi_ctrl, msg, flags);

	if (dsi_ctrl->dma_wait_queued)
		dsi_ctrl_flush_cmd_dma_queue(dsi_ctrl);

	if (flags & DSI_CTRL_CMD_NON_EMBEDDED_MODE) {
	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) ?
		cmd_mem.en_broadcast = (*flags & DSI_CTRL_CMD_BROADCAST) ?
			true : false;
		cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ?
		cmd_mem.is_master = (*flags & DSI_CTRL_CMD_BROADCAST_MASTER) ?
			true : false;
		cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
			true : false;
@@ -1371,12 +1372,12 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
	if ((msg->flags & MIPI_DSI_MSG_LASTCOMMAND))
		buffer[3] |= BIT(7);//set the last cmd bit in header.

	if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
	if (*flags & DSI_CTRL_CMD_FETCH_MEMORY) {
		/* Embedded mode config is selected */
		cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
		cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
		cmd_mem.en_broadcast = (*flags & DSI_CTRL_CMD_BROADCAST) ?
			true : false;
		cmd_mem.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ?
		cmd_mem.is_master = (*flags & DSI_CTRL_CMD_BROADCAST_MASTER) ?
			true : false;
		cmd_mem.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
			true : false;
@@ -1396,19 +1397,19 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
			dsi_ctrl->cmd_len = 0;
		}

	} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
	} else if (*flags & DSI_CTRL_CMD_FIFO_STORE) {
		cmd.command =  (u32 *)buffer;
		cmd.size = length;
		cmd.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
		cmd.en_broadcast = (*flags & DSI_CTRL_CMD_BROADCAST) ?
				     true : false;
		cmd.is_master = (flags & DSI_CTRL_CMD_BROADCAST_MASTER) ?
		cmd.is_master = (*flags & DSI_CTRL_CMD_BROADCAST_MASTER) ?
				  true : false;
		cmd.use_lpm = (msg->flags & MIPI_DSI_MSG_USE_LPM) ?
				  true : false;
	}

kickoff:
	dsi_kickoff_msg_tx(dsi_ctrl, msg, &cmd, &cmd_mem, flags);
	dsi_kickoff_msg_tx(dsi_ctrl, msg, &cmd, &cmd_mem, *flags);
error:
	if (buffer)
		devm_kfree(&dsi_ctrl->pdev->dev, buffer);
@@ -1436,7 +1437,7 @@ static int dsi_set_max_return_size(struct dsi_ctrl *dsi_ctrl,
	dflags &= ~BIT(3);
	msg.flags = dflags;

	rc = dsi_message_tx(dsi_ctrl, &msg, flags);
	rc = dsi_message_tx(dsi_ctrl, &msg, &flags);
	if (rc)
		DSI_CTRL_ERR(dsi_ctrl, "failed to send max return size packet, rc=%d\n",
				rc);
@@ -1498,7 +1499,7 @@ static int dsi_parse_long_read_resp(const struct mipi_dsi_msg *msg,

static int dsi_message_rx(struct dsi_ctrl *dsi_ctrl,
			  const struct mipi_dsi_msg *msg,
			  u32 flags)
			  u32 *flags)
{
	int rc = 0;
	u32 rd_pkt_size, total_read_len, hw_read_cnt;
@@ -3129,7 +3130,7 @@ int dsi_ctrl_validate_timing(struct dsi_ctrl *dsi_ctrl,
 */
int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl,
			  const struct mipi_dsi_msg *msg,
			  u32 flags)
			  u32 *flags)
{
	int rc = 0;

@@ -3147,7 +3148,7 @@ int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl,
		goto error;
	}

	if (flags & DSI_CTRL_CMD_READ) {
	if (*flags & DSI_CTRL_CMD_READ) {
		rc = dsi_message_rx(dsi_ctrl, msg, flags);
		if (rc <= 0)
			DSI_CTRL_ERR(dsi_ctrl, "read message failed read length, rc=%d\n",
+2 −2
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _DSI_CTRL_H_
@@ -564,7 +564,7 @@ int dsi_ctrl_set_tpg_state(struct dsi_ctrl *dsi_ctrl, bool on);
 */
int dsi_ctrl_cmd_transfer(struct dsi_ctrl *dsi_ctrl,
			  const struct mipi_dsi_msg *msg,
			  u32 flags);
			  u32 *flags);

/**
 * dsi_ctrl_cmd_tx_trigger() - Trigger a deferred command.
+59 −8
Original line number Diff line number Diff line
@@ -677,7 +677,7 @@ static int dsi_display_read_status(struct dsi_display_ctrl *ctrl,
			cmds[i].msg.flags |= MIPI_DSI_MSG_USE_LPM;
		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);
		rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, &cmds[i].msg, &flags);
		if (rc <= 0) {
			DSI_ERR("rx cmd transfer failed rc=%d\n", rc);
			return rc;
@@ -2714,7 +2714,8 @@ static int dsi_display_broadcast_cmd(struct dsi_display *display,
		m_flags |= DSI_CTRL_CMD_LAST_COMMAND;
	}

	if (display->queue_cmd_waits) {
	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;
	}
@@ -2724,7 +2725,7 @@ static int dsi_display_broadcast_cmd(struct dsi_display *display,
	 * 2. Trigger commands
	 */
	m_ctrl = &display->ctrl[display->cmd_master_idx];
	rc = dsi_ctrl_cmd_transfer(m_ctrl->ctrl, msg, m_flags);
	rc = dsi_ctrl_cmd_transfer(m_ctrl->ctrl, msg, &m_flags);
	if (rc) {
		DSI_ERR("[%s] cmd transfer failed on master,rc=%d\n",
		       display->name, rc);
@@ -2736,7 +2737,7 @@ static int dsi_display_broadcast_cmd(struct dsi_display *display,
		if (ctrl == m_ctrl)
			continue;

		rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, msg, flags);
		rc = dsi_ctrl_cmd_transfer(ctrl->ctrl, msg, &flags);
		if (rc) {
			DSI_ERR("[%s] cmd transfer failed, rc=%d\n",
			       display->name, rc);
@@ -2874,11 +2875,12 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
				msg->ctrl : 0;
		u32 cmd_flags = DSI_CTRL_CMD_FETCH_MEMORY;

		if (display->queue_cmd_waits)
		if (display->queue_cmd_waits ||
				msg->flags & MIPI_DSI_MSG_ASYNC_OVERRIDE)
			cmd_flags |= DSI_CTRL_CMD_ASYNC_WAIT;

		rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg,
				cmd_flags);
				&cmd_flags);
		if (rc) {
			DSI_ERR("[%s] cmd transfer failed, rc=%d\n",
			       display->name, rc);
@@ -7478,14 +7480,44 @@ int dsi_display_pre_disable(struct dsi_display *display)
		if (display->config.panel_mode == DSI_OP_CMD_MODE)
			dsi_panel_pre_mode_switch_to_video(display->panel);

		if (display->config.panel_mode == DSI_OP_VIDEO_MODE)
		if (display->config.panel_mode == DSI_OP_VIDEO_MODE) {
			/*
			 * Add unbalanced vote for clock & cmd engine to enable
			 * async trigger of pre video to cmd mode switch.
			 */
			rc = dsi_display_clk_ctrl(display->dsi_clk_handle,
					DSI_ALL_CLKS, DSI_CLK_ON);
			if (rc) {
				DSI_ERR("[%s]failed to enable all clocks,rc=%d",
						display->name, rc);
				goto exit;
			}

			rc = dsi_display_cmd_engine_enable(display);
			if (rc) {
				DSI_ERR("[%s]failed to enable cmd engine,rc=%d",
						display->name, rc);
				goto error_disable_clks;
			}

			dsi_panel_pre_mode_switch_to_cmd(display->panel);
		}
	} else {
		rc = dsi_panel_pre_disable(display->panel);
		if (rc)
			DSI_ERR("[%s] panel pre-disable failed, rc=%d\n",
				display->name, rc);
	}
	goto exit;

error_disable_clks:
	rc = dsi_display_clk_ctrl(display->dsi_clk_handle,
			DSI_ALL_CLKS, DSI_CLK_OFF);
	if (rc)
		DSI_ERR("[%s] failed to disable all DSI clocks, rc=%d\n",
		       display->name, rc);

exit:
	mutex_unlock(&display->display_lock);
	return rc;
}
@@ -7552,7 +7584,8 @@ int dsi_display_update_pps(char *pps_cmd, void *disp)

int dsi_display_unprepare(struct dsi_display *display)
{
	int rc = 0;
	int rc = 0, i;
	struct dsi_display_ctrl *ctrl;

	if (!display) {
		DSI_ERR("Invalid params\n");
@@ -7572,6 +7605,24 @@ int dsi_display_unprepare(struct dsi_display *display)
			DSI_ERR("[%s] panel unprepare failed, rc=%d\n",
			       display->name, rc);
	}

	/* Remove additional vote added for pre_mode_switch_to_cmd */
	if (display->poms_pending &&
			display->config.panel_mode == DSI_OP_VIDEO_MODE) {
		display_for_each_ctrl(i, display) {
			ctrl = &display->ctrl[i];
			if (!ctrl->ctrl || !ctrl->ctrl->dma_wait_queued)
				continue;
			flush_workqueue(display->dma_cmd_workq);
			cancel_work_sync(&ctrl->ctrl->dma_cmd_wait);
			ctrl->ctrl->dma_wait_queued = false;
		}

		dsi_display_cmd_engine_disable(display);
		dsi_display_clk_ctrl(display->dsi_clk_handle,
				DSI_ALL_CLKS, DSI_CLK_OFF);
	}

	rc = dsi_display_ctrl_host_disable(display);
	if (rc)
		DSI_ERR("[%s] failed to disable DSI host, rc=%d\n",
+4 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/delay.h>
@@ -552,6 +552,9 @@ static int dsi_panel_tx_cmd_set(struct dsi_panel *panel,
		if (cmds->last_command)
			cmds->msg.flags |= MIPI_DSI_MSG_LASTCOMMAND;

		if (type == DSI_CMD_SET_VID_TO_CMD_SWITCH)
			cmds->msg.flags |= MIPI_DSI_MSG_ASYNC_OVERRIDE;

		len = ops->transfer(panel->host, &cmds->msg);
		if (len < 0) {
			rc = len;
+8 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _DSI_PANEL_H_
@@ -28,6 +28,13 @@

#define DSI_MODE_MAX 32

/*
 * Defining custom dsi msg flag,
 * continued from drm_mipi_dsi.h
 * Override to use async transfer
 */
#define MIPI_DSI_MSG_ASYNC_OVERRIDE BIT(4)

enum dsi_panel_rotation {
	DSI_PANEL_ROTATE_NONE = 0,
	DSI_PANEL_ROTATE_HV_FLIP,