[v4] drm/mediatek: add dma buffer control for drm plane disable
Commit Message
dma buffer release before overlay disable, that will cause
m4u translation fault warning.
add dma buffer control flow in mediatek driver:
get dma buffer when drm plane disable
put dma buffer when overlay really disable
Fixes: 41016fe1028e4 ("drm: Rename plane->state variables in atomic update and disable")
Signed-off-by: Yongqiang Niu <yongqiang.niu@mediatek.com>
---
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 25 ++++++++++++++++++++++++
drivers/gpu/drm/mediatek/mtk_drm_plane.c | 12 ++++++++++++
drivers/gpu/drm/mediatek/mtk_drm_plane.h | 1 +
3 files changed, 38 insertions(+)
Comments
Il 04/07/23 11:04, Yongqiang Niu ha scritto:
> dma buffer release before overlay disable, that will cause
> m4u translation fault warning.
>
> add dma buffer control flow in mediatek driver:
> get dma buffer when drm plane disable
> put dma buffer when overlay really disable
>
> Fixes: 41016fe1028e4 ("drm: Rename plane->state variables in atomic update and disable")
> Signed-off-by: Yongqiang Niu <yongqiang.niu@mediatek.com>
Hello,
could you please rebase this over [1] for linux-next, while retaining this for
stable backports?
[1]:
https://lore.kernel.org/lkml/20230623094931.117918-1-angelogioacchino.delregno@collabora.com/
Thanks,
Angelo
> ---
> drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 25 ++++++++++++++++++++++++
> drivers/gpu/drm/mediatek/mtk_drm_plane.c | 12 ++++++++++++
> drivers/gpu/drm/mediatek/mtk_drm_plane.h | 1 +
> 3 files changed, 38 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index d40142842f85..49d671100785 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -4,6 +4,7 @@
> */
>
> #include <linux/clk.h>
> +#include <linux/dma-buf.h>
> #include <linux/dma-mapping.h>
> #include <linux/mailbox_controller.h>
> #include <linux/pm_runtime.h>
> @@ -283,6 +284,23 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
> return NULL;
> }
>
> +static void mtk_drm_dma_buf_put(struct mtk_drm_crtc *mtk_crtc)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < mtk_crtc->layer_nr; i++) {
> + struct drm_plane *plane = &mtk_crtc->planes[i];
> + struct mtk_plane_state *plane_state;
> +
> + plane_state = to_mtk_plane_state(plane->state);
> +
> + if (plane_state && plane_state->pending.dma_buf) {
> + dma_buf_put(plane_state->pending.dma_buf);
> + plane_state->pending.dma_buf = NULL;
> + }
> + }
> +}
> +
> #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
> {
> @@ -323,6 +341,8 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
> mtk_crtc->pending_async_planes = false;
> }
>
> + mtk_drm_dma_buf_put(mtk_crtc);
> +
> mtk_crtc->cmdq_vblank_cnt = 0;
> wake_up(&mtk_crtc->cb_blocking_queue);
> }
> @@ -624,9 +644,14 @@ static void mtk_crtc_ddp_irq(void *data)
> else if (mtk_crtc->cmdq_vblank_cnt > 0 && --mtk_crtc->cmdq_vblank_cnt == 0)
> DRM_ERROR("mtk_crtc %d CMDQ execute command timeout!\n",
> drm_crtc_index(&mtk_crtc->base));
> +
> + if (!mtk_crtc->cmdq_client.chan)
> + mtk_drm_dma_buf_put(mtk_crtc);
> #else
> if (!priv->data->shadow_register)
> mtk_crtc_ddp_config(crtc, NULL);
> +
> + mtk_drm_dma_buf_put(mtk_crtc);
> #endif
> mtk_drm_finish_page_flip(mtk_crtc);
> }
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> index 31f9420aff6f..66e6393e45ee 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> @@ -12,6 +12,7 @@
> #include <drm/drm_framebuffer.h>
> #include <drm/drm_gem_atomic_helper.h>
> #include <linux/align.h>
> +#include <linux/dma-buf.h>
>
> #include "mtk_drm_crtc.h"
> #include "mtk_drm_ddp_comp.h"
> @@ -266,6 +267,17 @@ static void mtk_plane_atomic_disable(struct drm_plane *plane,
> struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
> plane);
> struct mtk_plane_state *mtk_plane_state = to_mtk_plane_state(new_state);
> + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
> + plane);
> +
> + if (old_state && old_state->fb) {
> + struct drm_gem_object *gem = old_state->fb->obj[0];
> +
> + if (gem && gem->dma_buf) {
> + get_dma_buf(gem->dma_buf);
> + mtk_plane_state->pending.dma_buf = gem->dma_buf;
> + }
> + }
> mtk_plane_state->pending.enable = false;
> wmb(); /* Make sure the above parameter is set before update */
> mtk_plane_state->pending.dirty = true;
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.h b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
> index 99aff7da0831..3aba0b58ef3c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
> @@ -33,6 +33,7 @@ struct mtk_plane_pending_state {
> bool async_dirty;
> bool async_config;
> enum drm_color_encoding color_encoding;
> + struct dma_buf *dma_buf;
> };
>
> struct mtk_plane_state {
Hi Yongqiang,
kernel test robot noticed the following build errors:
[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on linus/master v6.4 next-20230704]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Yongqiang-Niu/drm-mediatek-add-dma-buffer-control-for-drm-plane-disable/20230704-170623
base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link: https://lore.kernel.org/r/20230704090432.5844-1-yongqiang.niu%40mediatek.com
patch subject: [v4, PATCH] drm/mediatek: add dma buffer control for drm plane disable
config: arm64-defconfig (https://download.01.org/0day-ci/archive/20230705/202307050325.QZv71se7-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230705/202307050325.QZv71se7-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202307050325.QZv71se7-lkp@intel.com/
All errors (new ones prefixed by >>, old ones prefixed by <<):
>> ERROR: modpost: module mediatek-drm uses symbol dma_buf_put from namespace DMA_BUF, but does not import it.
@@ -4,6 +4,7 @@
*/
#include <linux/clk.h>
+#include <linux/dma-buf.h>
#include <linux/dma-mapping.h>
#include <linux/mailbox_controller.h>
#include <linux/pm_runtime.h>
@@ -283,6 +284,23 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
return NULL;
}
+static void mtk_drm_dma_buf_put(struct mtk_drm_crtc *mtk_crtc)
+{
+ unsigned int i;
+
+ for (i = 0; i < mtk_crtc->layer_nr; i++) {
+ struct drm_plane *plane = &mtk_crtc->planes[i];
+ struct mtk_plane_state *plane_state;
+
+ plane_state = to_mtk_plane_state(plane->state);
+
+ if (plane_state && plane_state->pending.dma_buf) {
+ dma_buf_put(plane_state->pending.dma_buf);
+ plane_state->pending.dma_buf = NULL;
+ }
+ }
+}
+
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
{
@@ -323,6 +341,8 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
mtk_crtc->pending_async_planes = false;
}
+ mtk_drm_dma_buf_put(mtk_crtc);
+
mtk_crtc->cmdq_vblank_cnt = 0;
wake_up(&mtk_crtc->cb_blocking_queue);
}
@@ -624,9 +644,14 @@ static void mtk_crtc_ddp_irq(void *data)
else if (mtk_crtc->cmdq_vblank_cnt > 0 && --mtk_crtc->cmdq_vblank_cnt == 0)
DRM_ERROR("mtk_crtc %d CMDQ execute command timeout!\n",
drm_crtc_index(&mtk_crtc->base));
+
+ if (!mtk_crtc->cmdq_client.chan)
+ mtk_drm_dma_buf_put(mtk_crtc);
#else
if (!priv->data->shadow_register)
mtk_crtc_ddp_config(crtc, NULL);
+
+ mtk_drm_dma_buf_put(mtk_crtc);
#endif
mtk_drm_finish_page_flip(mtk_crtc);
}
@@ -12,6 +12,7 @@
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
#include <linux/align.h>
+#include <linux/dma-buf.h>
#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"
@@ -266,6 +267,17 @@ static void mtk_plane_atomic_disable(struct drm_plane *plane,
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
plane);
struct mtk_plane_state *mtk_plane_state = to_mtk_plane_state(new_state);
+ struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
+ plane);
+
+ if (old_state && old_state->fb) {
+ struct drm_gem_object *gem = old_state->fb->obj[0];
+
+ if (gem && gem->dma_buf) {
+ get_dma_buf(gem->dma_buf);
+ mtk_plane_state->pending.dma_buf = gem->dma_buf;
+ }
+ }
mtk_plane_state->pending.enable = false;
wmb(); /* Make sure the above parameter is set before update */
mtk_plane_state->pending.dirty = true;
@@ -33,6 +33,7 @@ struct mtk_plane_pending_state {
bool async_dirty;
bool async_config;
enum drm_color_encoding color_encoding;
+ struct dma_buf *dma_buf;
};
struct mtk_plane_state {