When the DSI is in video mode, all commands are rejected.

Detect current DSI mode in mtk_dsi_host_transfer() and switch modes
temporarily to allow commands to be sent.

Signed-off-by: Julien STEPHAN <[email protected]>
Signed-off-by: Mattijs Korpershoek <[email protected]>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 34 ++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5d90d2eb0019..7d66fdc7f81d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -891,24 +891,34 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host 
*host,
        u8 read_data[16];
        void *src_addr;
        u8 irq_flag = CMD_DONE_INT_FLAG;
-
-       if (readl(dsi->regs + DSI_MODE_CTRL) & MODE) {
-               DRM_ERROR("dsi engine is not command mode\n");
-               return -EINVAL;
+       u32 dsi_mode;
+
+       dsi_mode = readl(dsi->regs + DSI_MODE_CTRL);
+       if (dsi_mode & MODE) {
+               mtk_dsi_stop(dsi);
+               if (mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
+                       recv_cnt = -EINVAL;
+                       goto restore_dsi_mode;
+               }
        }
 
        if (MTK_DSI_HOST_IS_READ(msg->type))
                irq_flag |= LPRX_RD_RDY_INT_FLAG;
 
-       if (mtk_dsi_host_send_cmd(dsi, msg, irq_flag) < 0)
-               return -ETIME;
+       if (mtk_dsi_host_send_cmd(dsi, msg, irq_flag) < 0) {
+               recv_cnt = -ETIME;
+               goto restore_dsi_mode;
+       }
 
-       if (!MTK_DSI_HOST_IS_READ(msg->type))
-               return 0;
+       if (!MTK_DSI_HOST_IS_READ(msg->type)) {
+               recv_cnt = 0;
+               goto restore_dsi_mode;
+       }
 
        if (!msg->rx_buf) {
                DRM_ERROR("dsi receive buffer size may be NULL\n");
-               return -EINVAL;
+               recv_cnt = -EINVAL;
+               goto restore_dsi_mode;
        }
 
        for (i = 0; i < 16; i++)
@@ -933,6 +943,12 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host 
*host,
        DRM_INFO("dsi get %d byte data from the panel address(0x%x)\n",
                 recv_cnt, *((u8 *)(msg->tx_buf)));
 
+restore_dsi_mode:
+       if (dsi_mode & MODE) {
+               mtk_dsi_set_mode(dsi);
+               mtk_dsi_start(dsi);
+       }
+
        return recv_cnt;
 }
 
-- 
2.34.1

Reply via email to