Commit 4ff9d4cb authored by Archit Taneja's avatar Archit Taneja Committed by Rob Clark

drm/msm/dsi: Don't use iommu for command TX buffer for DSIv2

We currently use iommu allocated DMA buffers for sending DSI commands.
DSIv2 doesn't have a port connected to the MDP iommu. Therefore, it
can't use iommu allocated buffers to fetch DSI commands.

Use a regular contiguous DMA buffer if we are DSIv2.
Signed-off-by: default avatarArchit Taneja <architt@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent cea65dbd
...@@ -91,7 +91,7 @@ int msm_dsi_manager_phy_enable(int id, ...@@ -91,7 +91,7 @@ int msm_dsi_manager_phy_enable(int id,
u32 *clk_pre, u32 *clk_post); u32 *clk_pre, u32 *clk_post);
void msm_dsi_manager_phy_disable(int id); void msm_dsi_manager_phy_disable(int id);
int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg); int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg);
bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 iova, u32 len); bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len);
int msm_dsi_manager_register(struct msm_dsi *msm_dsi); int msm_dsi_manager_register(struct msm_dsi *msm_dsi);
void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi); void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi);
...@@ -145,7 +145,7 @@ int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host, ...@@ -145,7 +145,7 @@ int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host,
int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host, int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host,
const struct mipi_dsi_msg *msg); const struct mipi_dsi_msg *msg);
void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host, void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host,
u32 iova, u32 len); u32 dma_base, u32 len);
int msm_dsi_host_enable(struct mipi_dsi_host *host); int msm_dsi_host_enable(struct mipi_dsi_host *host);
int msm_dsi_host_disable(struct mipi_dsi_host *host); int msm_dsi_host_disable(struct mipi_dsi_host *host);
int msm_dsi_host_power_on(struct mipi_dsi_host *host); int msm_dsi_host_power_on(struct mipi_dsi_host *host);
......
...@@ -138,7 +138,15 @@ struct msm_dsi_host { ...@@ -138,7 +138,15 @@ struct msm_dsi_host {
struct work_struct err_work; struct work_struct err_work;
struct workqueue_struct *workqueue; struct workqueue_struct *workqueue;
/* DSI 6G TX buffer*/
struct drm_gem_object *tx_gem_obj; struct drm_gem_object *tx_gem_obj;
/* DSI v2 TX buffer */
void *tx_buf;
dma_addr_t tx_buf_paddr;
int tx_size;
u8 *rx_buf; u8 *rx_buf;
struct drm_display_mode *mode; struct drm_display_mode *mode;
...@@ -983,14 +991,17 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) ...@@ -983,14 +991,17 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host)
static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size) static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size)
{ {
struct drm_device *dev = msm_host->dev; struct drm_device *dev = msm_host->dev;
const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
int ret; int ret;
u32 iova; u32 iova;
if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
msm_host->tx_gem_obj = msm_gem_new(dev, size, MSM_BO_UNCACHED); msm_host->tx_gem_obj = msm_gem_new(dev, size, MSM_BO_UNCACHED);
if (IS_ERR(msm_host->tx_gem_obj)) { if (IS_ERR(msm_host->tx_gem_obj)) {
ret = PTR_ERR(msm_host->tx_gem_obj); ret = PTR_ERR(msm_host->tx_gem_obj);
pr_err("%s: failed to allocate gem, %d\n", __func__, ret); pr_err("%s: failed to allocate gem, %d\n",
__func__, ret);
msm_host->tx_gem_obj = NULL; msm_host->tx_gem_obj = NULL;
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return ret; return ret;
...@@ -1008,6 +1019,20 @@ static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size) ...@@ -1008,6 +1019,20 @@ static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size)
return -EINVAL; return -EINVAL;
} }
msm_host->tx_size = msm_host->tx_gem_obj->size;
} else {
msm_host->tx_buf = dma_alloc_coherent(dev->dev, size,
&msm_host->tx_buf_paddr, GFP_KERNEL);
if (!msm_host->tx_buf) {
ret = -ENOMEM;
pr_err("%s: failed to allocate tx buf, %d\n",
__func__, ret);
return ret;
}
msm_host->tx_size = size;
}
return 0; return 0;
} }
...@@ -1022,14 +1047,19 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host) ...@@ -1022,14 +1047,19 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
msm_host->tx_gem_obj = NULL; msm_host->tx_gem_obj = NULL;
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
} }
if (msm_host->tx_buf)
dma_free_coherent(dev->dev, msm_host->tx_size, msm_host->tx_buf,
msm_host->tx_buf_paddr);
} }
/* /*
* prepare cmd buffer to be txed * prepare cmd buffer to be txed
*/ */
static int dsi_cmd_dma_add(struct drm_gem_object *tx_gem, static int dsi_cmd_dma_add(struct msm_dsi_host *msm_host,
const struct mipi_dsi_msg *msg) const struct mipi_dsi_msg *msg)
{ {
const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
struct mipi_dsi_packet packet; struct mipi_dsi_packet packet;
int len; int len;
int ret; int ret;
...@@ -1042,18 +1072,21 @@ static int dsi_cmd_dma_add(struct drm_gem_object *tx_gem, ...@@ -1042,18 +1072,21 @@ static int dsi_cmd_dma_add(struct drm_gem_object *tx_gem,
} }
len = (packet.size + 3) & (~0x3); len = (packet.size + 3) & (~0x3);
if (len > tx_gem->size) { if (len > msm_host->tx_size) {
pr_err("%s: packet size is too big\n", __func__); pr_err("%s: packet size is too big\n", __func__);
return -EINVAL; return -EINVAL;
} }
data = msm_gem_vaddr(tx_gem); if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
data = msm_gem_vaddr(msm_host->tx_gem_obj);
if (IS_ERR(data)) { if (IS_ERR(data)) {
ret = PTR_ERR(data); ret = PTR_ERR(data);
pr_err("%s: get vaddr failed, %d\n", __func__, ret); pr_err("%s: get vaddr failed, %d\n", __func__, ret);
return ret; return ret;
} }
} else {
data = msm_host->tx_buf;
}
/* MSM specific command format in memory */ /* MSM specific command format in memory */
data[0] = packet.header[1]; data[0] = packet.header[1];
...@@ -1118,25 +1151,29 @@ static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg) ...@@ -1118,25 +1151,29 @@ static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg)
return msg->rx_len; return msg->rx_len;
} }
static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len) static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
{ {
const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
int ret; int ret;
u32 iova; u32 dma_base;
bool triggered; bool triggered;
ret = msm_gem_get_iova(msm_host->tx_gem_obj, 0, &iova); if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
ret = msm_gem_get_iova(msm_host->tx_gem_obj, 0, &dma_base);
if (ret) { if (ret) {
pr_err("%s: failed to get iova: %d\n", __func__, ret); pr_err("%s: failed to get iova: %d\n", __func__, ret);
return ret; return ret;
} }
} else {
dma_base = msm_host->tx_buf_paddr;
}
reinit_completion(&msm_host->dma_comp); reinit_completion(&msm_host->dma_comp);
dsi_wait4video_eng_busy(msm_host); dsi_wait4video_eng_busy(msm_host);
triggered = msm_dsi_manager_cmd_xfer_trigger( triggered = msm_dsi_manager_cmd_xfer_trigger(
msm_host->id, iova, len); msm_host->id, dma_base, len);
if (triggered) { if (triggered) {
ret = wait_for_completion_timeout(&msm_host->dma_comp, ret = wait_for_completion_timeout(&msm_host->dma_comp,
msecs_to_jiffies(200)); msecs_to_jiffies(200));
...@@ -1208,7 +1245,7 @@ static int dsi_cmds2buf_tx(struct msm_dsi_host *msm_host, ...@@ -1208,7 +1245,7 @@ static int dsi_cmds2buf_tx(struct msm_dsi_host *msm_host,
int bllp_len = msm_host->mode->hdisplay * int bllp_len = msm_host->mode->hdisplay *
dsi_get_bpp(msm_host->format) / 8; dsi_get_bpp(msm_host->format) / 8;
len = dsi_cmd_dma_add(msm_host->tx_gem_obj, msg); len = dsi_cmd_dma_add(msm_host, msg);
if (!len) { if (!len) {
pr_err("%s: failed to add cmd type = 0x%x\n", pr_err("%s: failed to add cmd type = 0x%x\n",
__func__, msg->type); __func__, msg->type);
...@@ -1898,11 +1935,12 @@ int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host, ...@@ -1898,11 +1935,12 @@ int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host,
return ret; return ret;
} }
void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host, u32 iova, u32 len) void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host, u32 dma_base,
u32 len)
{ {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host); struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
dsi_write(msm_host, REG_DSI_DMA_BASE, iova); dsi_write(msm_host, REG_DSI_DMA_BASE, dma_base);
dsi_write(msm_host, REG_DSI_DMA_LEN, len); dsi_write(msm_host, REG_DSI_DMA_LEN, len);
dsi_write(msm_host, REG_DSI_TRIG_DMA, 1); dsi_write(msm_host, REG_DSI_TRIG_DMA, 1);
......
...@@ -774,7 +774,7 @@ int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg) ...@@ -774,7 +774,7 @@ int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg)
return ret; return ret;
} }
bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 iova, u32 len) bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len)
{ {
struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0); struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
...@@ -784,9 +784,9 @@ bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 iova, u32 len) ...@@ -784,9 +784,9 @@ bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 iova, u32 len)
return false; return false;
if (IS_SYNC_NEEDED() && msm_dsi0) if (IS_SYNC_NEEDED() && msm_dsi0)
msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, iova, len); msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, dma_base, len);
msm_dsi_host_cmd_xfer_commit(host, iova, len); msm_dsi_host_cmd_xfer_commit(host, dma_base, len);
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment