summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/mediatek
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2022-02-28 06:07:02 +0300
committerDave Airlie <airlied@redhat.com>2022-02-28 06:07:12 +0300
commit6d09e5cbc9633fa4df88544952614e9137d274af (patch)
tree5f730529865cd92b7551c29dd8228020093347fd /drivers/gpu/drm/mediatek
parent54f43c17d681f6d9523fcfaeefc9df77993802e1 (diff)
parentaa2d5f2f168c8b380d4e94a32149cef16ed60efc (diff)
downloadlinux-6d09e5cbc9633fa4df88544952614e9137d274af.tar.xz
Merge tag 'mediatek-drm-next-5.18' of https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux into drm-next
Mediatek DRM Next for Linux 5.18 1. Transfer display binding document to yaml format. 2. Add mt8195 display device binding. 3. Allow commands to be sent during video mode. 4. Add wait_for_event for crtc disable by cmdq. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Chun-Kuang Hu <chunkuang.hu@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/1645934583-2018-1-git-send-email-chunkuang.hu@kernel.org
Diffstat (limited to 'drivers/gpu/drm/mediatek')
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_crtc.c12
-rw-r--r--drivers/gpu/drm/mediatek/mtk_dsi.c33
2 files changed, 36 insertions, 9 deletions
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index d661edf7e0fe..8cc0a1283d7c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -56,6 +56,7 @@ struct mtk_drm_crtc {
struct cmdq_pkt cmdq_handle;
u32 cmdq_event;
u32 cmdq_vblank_cnt;
+ wait_queue_head_t cb_blocking_queue;
#endif
struct device *mmsys_dev;
@@ -314,6 +315,7 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
}
mtk_crtc->cmdq_vblank_cnt = 0;
+ wake_up(&mtk_crtc->cb_blocking_queue);
}
#endif
@@ -700,6 +702,13 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
mtk_crtc->pending_planes = true;
mtk_drm_crtc_update_config(mtk_crtc, false);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ /* Wait for planes to be disabled by cmdq */
+ if (mtk_crtc->cmdq_client.chan)
+ wait_event_timeout(mtk_crtc->cb_blocking_queue,
+ mtk_crtc->cmdq_vblank_cnt == 0,
+ msecs_to_jiffies(500));
+#endif
/* Wait for planes to be disabled */
drm_crtc_wait_one_vblank(crtc);
@@ -976,6 +985,9 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
mtk_crtc->cmdq_client.chan = NULL;
}
}
+
+ /* for sending blocking cmd in crtc disable */
+ init_waitqueue_head(&mtk_crtc->cb_blocking_queue);
}
#endif
return 0;
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5d90d2eb0019..abdd9cdebd86 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -891,24 +891,33 @@ 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;
+ u32 dsi_mode;
+ int ret;
- if (readl(dsi->regs + DSI_MODE_CTRL) & MODE) {
- DRM_ERROR("dsi engine is not command mode\n");
- return -EINVAL;
+ dsi_mode = readl(dsi->regs + DSI_MODE_CTRL);
+ if (dsi_mode & MODE) {
+ mtk_dsi_stop(dsi);
+ ret = mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
+ if (ret)
+ 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;
+ ret = mtk_dsi_host_send_cmd(dsi, msg, irq_flag);
+ if (ret)
+ 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;
+ ret = -EINVAL;
+ goto restore_dsi_mode;
}
for (i = 0; i < 16; i++)
@@ -933,7 +942,13 @@ 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)));
- return recv_cnt;
+restore_dsi_mode:
+ if (dsi_mode & MODE) {
+ mtk_dsi_set_mode(dsi);
+ mtk_dsi_start(dsi);
+ }
+
+ return ret < 0 ? ret : recv_cnt;
}
static const struct mipi_dsi_host_ops mtk_dsi_ops = {