From 937f861def1a1d49abb92e041efaa5c259281fbf Mon Sep 17 00:00:00 2001 From: Yongqiang Niu Date: Wed, 27 Mar 2019 14:19:18 +0800 Subject: drm/mediatek: adjust ddp clock control flow display hardware clock will not unprepare when crtc is disable, until crtc is destroyed. with this patch, hard clock will disable and unprepare at the same time. Signed-off-by: Yongqiang Niu Signed-off-by: Hsin-Yi Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index acad088173da..529b8a4af715 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -98,10 +98,6 @@ static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc) static void mtk_drm_crtc_destroy(struct drm_crtc *crtc) { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); - int i; - - for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) - clk_unprepare(mtk_crtc->ddp_comp[i]->clk); mtk_disp_mutex_put(mtk_crtc->mutex); @@ -194,7 +190,7 @@ static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc) DRM_DEBUG_DRIVER("%s\n", __func__); for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { - ret = clk_enable(mtk_crtc->ddp_comp[i]->clk); + ret = clk_prepare_enable(mtk_crtc->ddp_comp[i]->clk); if (ret) { DRM_ERROR("Failed to enable clock %d: %d\n", i, ret); goto err; @@ -204,7 +200,7 @@ static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc) return 0; err: while (--i >= 0) - clk_disable(mtk_crtc->ddp_comp[i]->clk); + clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk); return ret; } @@ -214,7 +210,7 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc) DRM_DEBUG_DRIVER("%s\n", __func__); for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) - clk_disable(mtk_crtc->ddp_comp[i]->clk); + clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk); } static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc) @@ -585,15 +581,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, if (!comp) { dev_err(dev, "Component %pOF not initialized\n", node); ret = -ENODEV; - goto unprepare; - } - - ret = clk_prepare(comp->clk); - if (ret) { - dev_err(dev, - "Failed to prepare clock for component %pOF: %d\n", - node, ret); - goto unprepare; + return ret; } mtk_crtc->ddp_comp[i] = comp; @@ -611,23 +599,17 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, ret = mtk_plane_init(drm_dev, &mtk_crtc->planes[zpos], BIT(pipe), type); if (ret) - goto unprepare; + return ret; } ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, &mtk_crtc->planes[0], mtk_crtc->layer_nr > 1 ? &mtk_crtc->planes[1] : NULL, pipe); if (ret < 0) - goto unprepare; + return ret; drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE); drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, MTK_LUT_SIZE); priv->num_pipes++; return 0; - -unprepare: - while (--i >= 0) - clk_unprepare(mtk_crtc->ddp_comp[i]->clk); - - return ret; } -- cgit v1.2.3 From 46a3b9fce29386704a56fbfb22e0dcdbd813b4b5 Mon Sep 17 00:00:00 2001 From: Yongqiang Niu Date: Wed, 27 Mar 2019 14:19:20 +0800 Subject: drm/mediatek: respect page offset for PRIME mmap calls Respect page offset for PRIME mmap calls Signed-off-by: Yongqiang Niu Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_drm_gem.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 38483e9ee071..7eabdf335a79 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -144,7 +144,6 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj, * VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap(). */ vma->vm_flags &= ~VM_PFNMAP; - vma->vm_pgoff = 0; ret = dma_mmap_attrs(priv->dma_dev, vma, mtk_gem->cookie, mtk_gem->dma_addr, obj->size, mtk_gem->dma_attrs); @@ -176,6 +175,12 @@ int mtk_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) obj = vma->vm_private_data; + /* + * Set vm_pgoff (used as a fake buffer offset by DRM) to 0 and map the + * whole buffer from the start. + */ + vma->vm_pgoff = 0; + return mtk_drm_gem_object_mmap(obj, vma); } -- cgit v1.2.3 From 8fd7a37b191f93737f6280a9b5de65f98acc12c9 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Wed, 29 May 2019 18:25:52 +0800 Subject: drm/mediatek: fix unbind functions detatch panel in mtk_dsi_destroy_conn_enc(), since .bind will try to attach it again. Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver") Signed-off-by: Hsin-Yi Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_dsi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index b00eb2d2e086..1ae3be99e0ff 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -844,6 +844,8 @@ static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi) /* Skip connector cleanup if creation was delegated to the bridge */ if (dsi->conn.dev) drm_connector_cleanup(&dsi->conn); + if (dsi->panel) + drm_panel_detach(dsi->panel); } static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp) -- cgit v1.2.3 From f0fd848342802bc0f74620d387eead53e8905804 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Wed, 29 May 2019 18:25:53 +0800 Subject: drm/mediatek: unbind components in mtk_drm_unbind() Unbinding components (i.e. mtk_dsi and mtk_disp_ovl/rdma/color) will trigger master(mtk_drm)'s .unbind(), and currently mtk_drm's unbind won't actually unbind components. During the next bind, mtk_drm_kms_init() is called, and the components are added back. .unbind() should call mtk_drm_kms_deinit() to unbind components. And since component_master_del() in .remove() will trigger .unbind(), which will also unregister device, it's fine to remove original functions called here. Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.") Signed-off-by: Hsin-Yi Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 57ce4708ef1b..e7362bdafa82 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -397,6 +397,7 @@ static void mtk_drm_unbind(struct device *dev) struct mtk_drm_private *private = dev_get_drvdata(dev); drm_dev_unregister(private->drm); + mtk_drm_kms_deinit(private->drm); drm_dev_put(private->drm); private->drm = NULL; } @@ -568,13 +569,8 @@ err_node: static int mtk_drm_remove(struct platform_device *pdev) { struct mtk_drm_private *private = platform_get_drvdata(pdev); - struct drm_device *drm = private->drm; int i; - drm_dev_unregister(drm); - mtk_drm_kms_deinit(drm); - drm_dev_put(drm); - component_master_del(&pdev->dev, &mtk_drm_ops); pm_runtime_disable(&pdev->dev); of_node_put(private->mutex_node); -- cgit v1.2.3 From cf49b24ffa62766f8f04cd1c4cf17b75d29b240a Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Wed, 29 May 2019 18:25:54 +0800 Subject: drm/mediatek: call drm_atomic_helper_shutdown() when unbinding driver shutdown all CRTC when unbinding drm driver. Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.") Signed-off-by: Hsin-Yi Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index e7362bdafa82..8718d123ccaa 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -311,6 +311,7 @@ err_config_cleanup: static void mtk_drm_kms_deinit(struct drm_device *drm) { drm_kms_helper_poll_fini(drm); + drm_atomic_helper_shutdown(drm); component_unbind_all(drm->dev, drm); drm_mode_config_cleanup(drm); -- cgit v1.2.3 From a4cd1d2b016d5d043ab2c4b9c4ec50a5805f5396 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Wed, 29 May 2019 18:25:55 +0800 Subject: drm/mediatek: clear num_pipes when unbind driver num_pipes is used for mutex created in mtk_drm_crtc_create(). If we don't clear num_pipes count, when rebinding driver, the count will be accumulated. From mtk_disp_mutex_get(), there can only be at most 10 mutex id. Clear this number so it starts from 0 in every rebind. Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.") Signed-off-by: Hsin-Yi Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 8718d123ccaa..bbfe3a464aea 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -400,6 +400,7 @@ static void mtk_drm_unbind(struct device *dev) drm_dev_unregister(private->drm); mtk_drm_kms_deinit(private->drm); drm_dev_put(private->drm); + private->num_pipes = 0; private->drm = NULL; } -- cgit v1.2.3 From 2458d9d6d94be982b917e93c61a89b4426f32e31 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Thu, 30 May 2019 17:18:47 +0800 Subject: drm/mediatek: call mtk_dsi_stop() after mtk_drm_crtc_atomic_disable() mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), which needs ovl irq for drm_crtc_wait_one_vblank(), since after mtk_dsi_stop() is called, ovl irq will be disabled. If drm_crtc_wait_one_vblank() is called after last irq, it will timeout with this message: "vblank wait timed out on crtc 0". This happens sometimes when turning off the screen. In drm_atomic_helper.c#disable_outputs(), the calling sequence when turning off the screen is: 1. mtk_dsi_encoder_disable() --> mtk_output_dsi_disable() --> mtk_dsi_stop(); /* sometimes make vblank timeout in atomic_disable */ --> mtk_dsi_poweroff(); 2. mtk_drm_crtc_atomic_disable() --> drm_crtc_wait_one_vblank(); ... --> mtk_dsi_ddp_stop() --> mtk_dsi_poweroff(); mtk_dsi_poweroff() has reference count design, change to make mtk_dsi_stop() called in mtk_dsi_poweroff() when refcount is 0. Fixes: 0707632b5bac ("drm/mediatek: update DSI sub driver flow for sending commands to panel") Signed-off-by: Hsin-Yi Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_dsi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 1ae3be99e0ff..179f2b080342 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -630,6 +630,15 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi) if (--dsi->refcount != 0) return; + /* + * mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since + * mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(), + * which needs irq for vblank, and mtk_dsi_stop() will disable irq. + * mtk_dsi_start() needs to be called in mtk_output_dsi_enable(), + * after dsi is fully set. + */ + mtk_dsi_stop(dsi); + if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) { if (dsi->panel) { if (drm_panel_unprepare(dsi->panel)) { @@ -696,7 +705,6 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi) } } - mtk_dsi_stop(dsi); mtk_dsi_poweroff(dsi); dsi->enabled = false; -- cgit v1.2.3