Merge "drm: msm: dsi-staging: Add support for cmd fetch from AXI bus" into msm-4.9
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 39b797e..da7a7c0 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -879,14 +879,12 @@ 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;
-
- if (!(flags & DSI_CTRL_CMD_FIFO_STORE)) {
- pr_err("Memory DMA is not supported, use FIFO\n");
- goto error;
- }
+ u32 cnt = 0;
+ u8 *cmdbuf;
rc = mipi_dsi_create_packet(&packet, msg);
if (rc) {
@@ -894,7 +892,32 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl,
goto error;
}
- if (flags & DSI_CTRL_CMD_FIFO_STORE) {
+ if (flags & DSI_CTRL_CMD_FETCH_MEMORY) {
+ 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;
+ }
+
+ 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;
@@ -2171,14 +2199,14 @@ int dsi_ctrl_set_vid_engine_state(struct dsi_ctrl *dsi_ctrl,
}
/**
- * dsi_ctrl_set_ulps() - set ULPS state for DSI lanes.
- * @dsi_ctrl: DSI controller handle.
- * @enable: enable/disable ULPS.
- *
- * ULPS can be enabled/disabled after DSI host engine is turned on.
- *
- * Return: error code.
- */
+ * dsi_ctrl_set_ulps() - set ULPS state for DSI lanes.
+ * @dsi_ctrl: DSI controller handle.
+ * @enable: enable/disable ULPS.
+ *
+ * ULPS can be enabled/disabled after DSI host engine is turned on.
+ *
+ * Return: error code.
+ */
int dsi_ctrl_set_ulps(struct dsi_ctrl *dsi_ctrl, bool enable)
{
int rc = 0;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index f89cb68..7f36fde 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -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;
@@ -377,14 +384,14 @@ int dsi_ctrl_host_init(struct dsi_ctrl *dsi_ctrl);
int dsi_ctrl_host_deinit(struct dsi_ctrl *dsi_ctrl);
/**
- * dsi_ctrl_set_ulps() - set ULPS state for DSI lanes.
- * @dsi_ctrl: DSI controller handle.
- * @enable: enable/disable ULPS.
- *
- * ULPS can be enabled/disabled after DSI host engine is turned on.
- *
- * Return: error code.
- */
+ * dsi_ctrl_set_ulps() - set ULPS state for DSI lanes.
+ * @dsi_ctrl: DSI controller handle.
+ * @enable: enable/disable ULPS.
+ *
+ * ULPS can be enabled/disabled after DSI host engine is turned on.
+ *
+ * Return: error code.
+ */
int dsi_ctrl_set_ulps(struct dsi_ctrl *dsi_ctrl, bool enable);
/**
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index c2cf2cb..d6a7193 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -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:
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
index d2bc7d8..89f31af 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
@@ -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;