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

Commit 82109524 authored by Shashank Babu Chinta Venkata's avatar Shashank Babu Chinta Venkata Committed by Vara Reddy
Browse files

drm: msm: dsi-staging: Add support for cmd fetch from AXI bus



Certain panels have commands exceeding 64 bytes and FIFO TPG
cannot handle this requirement. This change adds support for
fetching commands over AXI bus which addresses sending
commands greater than 64 bytes

Change-Id: I125f60066871bb0a1c9ed8264ca688a6dd21b637
Signed-off-by: default avatarShashank Babu Chinta Venkata <sbchin@codeaurora.org>
parent ea5149e3
Loading
Loading
Loading
Loading
+43 −15
Original line number Diff line number Diff line
@@ -879,22 +879,45 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
	int rc = 0;
	struct mipi_dsi_packet packet;
	struct dsi_ctrl_cmd_dma_fifo_info cmd;
	struct dsi_ctrl_cmd_dma_info cmd_mem;
	u32 hw_flags = 0;
	u32 length = 0;
	u8 *buffer = NULL;
	u32 cnt = 0;
	u8 *cmdbuf;

	if (!(flags & DSI_CTRL_CMD_FIFO_STORE)) {
		pr_err("Memory DMA is not supported, use FIFO\n");
	rc = mipi_dsi_create_packet(&packet, msg);
	if (rc) {
		pr_err("Failed to create message packet, rc=%d\n", rc);
		goto error;
	}

	rc = mipi_dsi_create_packet(&packet, msg);
	if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
		rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl,
				&packet,
				&buffer,
				&length);

		if (rc) {
		pr_err("Failed to create message packet, rc=%d\n", rc);
			pr_err("[%s] failed to copy message, rc=%d\n",
					dsi_ctrl->name, rc);
			goto error;
		}

	if (flags & DSI_CTRL_CMD_FIFO_STORE) {
		cmd_mem.offset = dsi_ctrl->cmd_buffer_iova;
		cmd_mem.length = length;
		cmd_mem.en_broadcast = (flags & DSI_CTRL_CMD_BROADCAST) ?
			true : false;
		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;

		cmdbuf = (u8 *)(dsi_ctrl->vaddr);
		for (cnt = 0; cnt < length; cnt++)
			cmdbuf[cnt] = buffer[cnt];

	} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
		rc = dsi_ctrl_copy_and_pad_cmd(dsi_ctrl,
					       &packet,
					       &buffer,
@@ -920,10 +943,15 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
	if (!(flags & DSI_CTRL_CMD_DEFER_TRIGGER))
		reinit_completion(&dsi_ctrl->int_info.cmd_dma_done);

	if (flags & DSI_CTRL_CMD_FIFO_STORE)
	if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
		dsi_ctrl->hw.ops.kickoff_command(&dsi_ctrl->hw,
						&cmd_mem,
						hw_flags);
	} else if (flags & DSI_CTRL_CMD_FIFO_STORE) {
		dsi_ctrl->hw.ops.kickoff_fifo_command(&dsi_ctrl->hw,
						      &cmd,
						      hw_flags);
	}

	if (!(flags & DSI_CTRL_CMD_DEFER_TRIGGER)) {
		u32 retry = 10;
+15 −8
Original line number Diff line number Diff line
@@ -33,12 +33,15 @@
 * @DSI_CTRL_CMD_DEFER_TRIGGER:    Defer the command trigger to later.
 * @DSI_CTRL_CMD_FIFO_STORE:       Use FIFO for command transfer in place of
 *				   reading data from memory.
 * @DSI_CTRL_CMD_FETCH_MEMORY:     Fetch command from memory through AXI bus
 *				   and transfer it.
 */
#define DSI_CTRL_CMD_READ             0x1
#define DSI_CTRL_CMD_BROADCAST        0x2
#define DSI_CTRL_CMD_BROADCAST_MASTER 0x4
#define DSI_CTRL_CMD_DEFER_TRIGGER    0x8
#define DSI_CTRL_CMD_FIFO_STORE       0x10
#define DSI_CTRL_CMD_FETCH_MEMORY     0x20

/**
 * enum dsi_power_state - defines power states for dsi controller.
@@ -188,6 +191,8 @@ struct dsi_ctrl_interrupts {
 * @roi:                 Partial update region of interest.
 *                       Origin is top left of this CTRL.
 * @tx_cmd_buf:          Tx command buffer.
 * @cmd_buffer_iova:     cmd buffer mapped address.
 * @vaddr:		 CPU virtual address of cmd buffer.
 * @cmd_buffer_size:     Size of command buffer.
 * @debugfs_root:        Root for debugfs entries.
 */
@@ -221,6 +226,8 @@ struct dsi_ctrl {
	/* Command tx and rx */
	struct drm_gem_object *tx_cmd_buf;
	u32 cmd_buffer_size;
	u32 cmd_buffer_iova;
	void *vaddr;

	/* Debug Information */
	struct dentry *debugfs_root;
+50 −5
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include <linux/list.h>
#include <linux/of.h>
#include <linux/err.h>

#include "msm_drv.h"
#include "dsi_display.h"
@@ -1004,9 +1005,9 @@ static int dsi_display_broadcast_cmd(struct dsi_display *display,
	int i;

	m_flags = (DSI_CTRL_CMD_BROADCAST | DSI_CTRL_CMD_BROADCAST_MASTER |
		   DSI_CTRL_CMD_DEFER_TRIGGER | DSI_CTRL_CMD_FIFO_STORE);
		   DSI_CTRL_CMD_DEFER_TRIGGER | DSI_CTRL_CMD_FETCH_MEMORY);
	flags = (DSI_CTRL_CMD_BROADCAST | DSI_CTRL_CMD_DEFER_TRIGGER |
		 DSI_CTRL_CMD_FIFO_STORE);
		 DSI_CTRL_CMD_FETCH_MEMORY);

	/*
	 * 1. Setup commands in FIFO
@@ -1101,8 +1102,8 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
				 const struct mipi_dsi_msg *msg)
{
	struct dsi_display *display = to_dsi_display(host);

	int rc = 0;
	struct dsi_display_ctrl *display_ctrl;
	int rc = 0, cnt = 0;

	if (!host || !msg) {
		pr_err("Invalid params\n");
@@ -1131,6 +1132,44 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
		goto error_disable_clks;
	}

	if (display->tx_cmd_buf == NULL) {
		mutex_lock(&display->drm_dev->struct_mutex);
		display->tx_cmd_buf = msm_gem_new(display->drm_dev,
				SZ_4K,
				MSM_BO_UNCACHED);
		mutex_unlock(&display->drm_dev->struct_mutex);

		display->cmd_buffer_size = SZ_4K;

		if ((display->tx_cmd_buf) == NULL) {
			pr_err("value of display->tx_cmd_buf is NULL");
			goto error_disable_cmd_engine;
		}
		rc = msm_gem_get_iova(display->tx_cmd_buf, 0,
					&(display->cmd_buffer_iova));
		if (rc) {
			pr_err("failed to get the iova rc %d\n", rc);
			goto free_gem;
		}

		display->vaddr =
			(void *) msm_gem_get_vaddr(display->tx_cmd_buf);

		if (IS_ERR_OR_NULL(display->vaddr)) {
			pr_err("failed to get va rc %d\n", rc);
			rc = -EINVAL;
			goto put_iova;
		}

		for (cnt = 0; cnt < display->ctrl_count; cnt++) {
			display_ctrl = &display->ctrl[cnt];
			display_ctrl->ctrl->cmd_buffer_size = SZ_4K;
			display_ctrl->ctrl->cmd_buffer_iova =
						display->cmd_buffer_iova;
			display_ctrl->ctrl->vaddr = display->vaddr;
		}
	}

	if (display->ctrl_count > 1 && !(msg->flags & MIPI_DSI_MSG_UNICAST)) {
		rc = dsi_display_broadcast_cmd(display, msg);
		if (rc) {
@@ -1143,13 +1182,19 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
				msg->ctrl : 0;

		rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg,
					  DSI_CTRL_CMD_FIFO_STORE);
					  DSI_CTRL_CMD_FETCH_MEMORY);
		if (rc) {
			pr_err("[%s] cmd transfer failed, rc=%d\n",
			       display->name, rc);
			goto error_disable_cmd_engine;
		}
	}
	return rc;

put_iova:
	msm_gem_put_iova(display->tx_cmd_buf, 0);
free_gem:
	msm_gem_free_object(display->tx_cmd_buf);
error_disable_cmd_engine:
	(void)dsi_display_cmd_engine_disable(display);
error_disable_clks:
+4 −0
Original line number Diff line number Diff line
@@ -155,6 +155,10 @@ struct dsi_display {
	bool ulps_enabled;
	bool clamp_enabled;
	bool phy_idle_power_off;
	struct drm_gem_object *tx_cmd_buf;
	u32 cmd_buffer_size;
	u32 cmd_buffer_iova;
	void *vaddr;

	struct mipi_dsi_host host;
	struct dsi_bridge    *bridge;