diff options
Diffstat (limited to 'drivers/gpu/drm/mediatek')
-rw-r--r-- | drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/mediatek/mtk_drm_drv.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/mediatek/mtk_drm_gem.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/mediatek/mtk_drm_gem.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/mediatek/mtk_dsi.c | 33 |
5 files changed, 46 insertions, 14 deletions
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 188c94cc08a5..ede435d2c1ef 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -55,6 +55,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; @@ -313,6 +314,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 @@ -699,6 +701,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); @@ -977,6 +986,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_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index b147797177c6..838297f9d45d 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -236,6 +236,9 @@ static int mtk_drm_kms_init(struct drm_device *drm) struct device *dma_dev; int ret; + if (drm_firmware_drivers_only()) + return -ENODEV; + if (!iommu_present(&platform_bus_type)) return -EPROBE_DEFER; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index d0544962cfc1..139d7724c6d0 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -220,7 +220,7 @@ struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev, return &mtk_gem->base; } -int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) +int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) { struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj); struct sg_table *sgt = NULL; @@ -247,12 +247,13 @@ int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map) out: kfree(sgt); - dma_buf_map_set_vaddr(map, mtk_gem->kvaddr); + iosys_map_set_vaddr(map, mtk_gem->kvaddr); return 0; } -void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map) +void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, + struct iosys_map *map) { struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj); void *vaddr = map->vaddr; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.h b/drivers/gpu/drm/mediatek/mtk_drm_gem.h index 9a359a06cb73..78f23b07a02e 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.h @@ -42,7 +42,8 @@ int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj); struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sg); -int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map *map); -void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map); +int mtk_drm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map); +void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, + struct iosys_map *map); #endif diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index bced4c7d668e..ccb0511b9cd5 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -974,24 +974,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++) @@ -1016,7 +1025,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 = { |