[PATCH] drm: verisilicon: support non-coherent DMA framebuffers

Dominique Belhachemi posted 1 patch 1 month, 2 weeks ago
drivers/gpu/drm/verisilicon/vs_drm.c          | 31 +++++++++++++++++--
drivers/gpu/drm/verisilicon/vs_drm.h          |  7 +++++
.../gpu/drm/verisilicon/vs_primary_plane.c    | 11 ++++++-
3 files changed, 46 insertions(+), 3 deletions(-)
[PATCH] drm: verisilicon: support non-coherent DMA framebuffers
Posted by Dominique Belhachemi 1 month, 2 weeks ago
Wire up the standard non-coherent path matching the ingenic DRM
driver.

Tested on StarFive JH7110 (VisionFive 2 v1.3B).

Signed-off-by: Dominique Belhachemi <domibel@debian.org>
---
 drivers/gpu/drm/verisilicon/vs_drm.c          | 31 +++++++++++++++++--
 drivers/gpu/drm/verisilicon/vs_drm.h          |  7 +++++
 .../gpu/drm/verisilicon/vs_primary_plane.c    | 11 ++++++-
 3 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/verisilicon/vs_drm.c b/drivers/gpu/drm/verisilicon/vs_drm.c
index fd259d53f49f..52d8749445df 100644
--- a/drivers/gpu/drm/verisilicon/vs_drm.c
+++ b/drivers/gpu/drm/verisilicon/vs_drm.c
@@ -4,7 +4,7 @@
  */
 
 #include <linux/aperture.h>
-#include <linux/dma-mapping.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/regmap.h>
@@ -49,6 +49,31 @@ static int vs_gem_dumb_create(struct drm_file *file_priv,
 
 DEFINE_DRM_GEM_FOPS(vs_drm_driver_fops);
 
+static struct drm_gem_object *vs_gem_create_object(struct drm_device *drm,
+						   size_t size)
+{
+	struct drm_gem_dma_object *obj;
+
+	obj = kzalloc_obj(*obj);
+	if (!obj)
+		return ERR_PTR(-ENOMEM);
+
+	obj->map_noncoherent = to_vs_drm_dev(drm)->noncoherent;
+
+	return &obj->base;
+}
+
+static struct drm_framebuffer *
+vs_gem_fb_create(struct drm_device *drm, struct drm_file *file,
+		 const struct drm_format_info *info,
+		 const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	if (to_vs_drm_dev(drm)->noncoherent)
+		return drm_gem_fb_create_with_dirty(drm, file, info, mode_cmd);
+
+	return drm_gem_fb_create(drm, file, info, mode_cmd);
+}
+
 static const struct drm_driver vs_drm_driver = {
 	.driver_features	= DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
 	.fops			= &vs_drm_driver_fops,
@@ -58,12 +83,13 @@ static const struct drm_driver vs_drm_driver = {
 	.minor	= DRIVER_MINOR,
 
 	/* GEM Operations */
+	.gem_create_object	= vs_gem_create_object,
 	DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vs_gem_dumb_create),
 	DRM_FBDEV_DMA_DRIVER_OPS,
 };
 
 static const struct drm_mode_config_funcs vs_mode_config_funcs = {
-	.fb_create		= drm_gem_fb_create,
+	.fb_create		= vs_gem_fb_create,
 	.atomic_check		= drm_atomic_helper_check,
 	.atomic_commit		= drm_atomic_helper_commit,
 };
@@ -98,6 +124,7 @@ int vs_drm_initialize(struct vs_dc *dc, struct platform_device *pdev)
 
 	drm = &vdrm->base;
 	vdrm->dc = dc;
+	vdrm->noncoherent = !of_dma_is_coherent(dev->of_node);
 	dc->drm_dev = vdrm;
 
 	ret = drmm_mode_config_init(drm);
diff --git a/drivers/gpu/drm/verisilicon/vs_drm.h b/drivers/gpu/drm/verisilicon/vs_drm.h
index 606338206a42..17704cd0df1d 100644
--- a/drivers/gpu/drm/verisilicon/vs_drm.h
+++ b/drivers/gpu/drm/verisilicon/vs_drm.h
@@ -18,8 +18,15 @@ struct vs_drm_dev {
 
 	struct vs_dc *dc;
 	struct vs_crtc *crtcs[VSDC_MAX_OUTPUTS];
+
+	bool noncoherent;
 };
 
+static inline struct vs_drm_dev *to_vs_drm_dev(struct drm_device *drm)
+{
+	return container_of(drm, struct vs_drm_dev, base);
+}
+
 int vs_drm_initialize(struct vs_dc *dc, struct platform_device *pdev);
 void vs_drm_finalize(struct vs_dc *dc);
 void vs_drm_shutdown_handler(struct vs_dc *dc);
diff --git a/drivers/gpu/drm/verisilicon/vs_primary_plane.c b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
index e8fcb5958615..0049737f492b 100644
--- a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
+++ b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
@@ -8,6 +8,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
+#include <drm/drm_fb_dma_helper.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_framebuffer.h>
 #include <drm/drm_gem_atomic_helper.h>
@@ -16,8 +17,9 @@
 #include <drm/drm_print.h>
 
 #include "vs_crtc.h"
-#include "vs_plane.h"
 #include "vs_dc.h"
+#include "vs_drm.h"
+#include "vs_plane.h"
 #include "vs_primary_plane_regs.h"
 
 static int vs_primary_plane_atomic_check(struct drm_plane *plane,
@@ -86,6 +88,8 @@ static void vs_primary_plane_atomic_disable(struct drm_plane *plane,
 static void vs_primary_plane_atomic_update(struct drm_plane *plane,
 					   struct drm_atomic_state *atomic_state)
 {
+	struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(atomic_state,
+									   plane);
 	struct drm_plane_state *state = drm_atomic_get_new_plane_state(atomic_state,
 								       plane);
 	struct drm_framebuffer *fb = state->fb;
@@ -101,6 +105,8 @@ static void vs_primary_plane_atomic_update(struct drm_plane *plane,
 		return;
 	}
 
+	drm_fb_dma_sync_non_coherent(plane->dev, old_state, state);
+
 	vcrtc = drm_crtc_to_vs_crtc(crtc);
 	output = vcrtc->id;
 	dc = vcrtc->dc;
@@ -169,5 +175,8 @@ struct drm_plane *vs_primary_plane_init(struct drm_device *drm_dev, struct vs_dc
 
 	drm_plane_helper_add(plane, &vs_primary_plane_helper_funcs);
 
+	if (to_vs_drm_dev(drm_dev)->noncoherent)
+		drm_plane_enable_fb_damage_clips(plane);
+
 	return plane;
 }
-- 
2.53.0
Re: [PATCH] drm: verisilicon: support non-coherent DMA framebuffers
Posted by Icenowy Zheng 1 month, 2 weeks ago
在 2026-05-05二的 04:26 +0000,Dominique Belhachemi写道:
> Wire up the standard non-coherent path matching the ingenic DRM
> driver.

Ah I forgot that my test platform is also noncoherent -- it uses
uncached memory map instead of cache maintenance.

Should some other facility to be wired in to check whether cache
maintenance or uncached mapping is available and use that
functionality?

Thanks,
Icenowy

> 
> Tested on StarFive JH7110 (VisionFive 2 v1.3B).
> 
> Signed-off-by: Dominique Belhachemi <domibel@debian.org>
> ---
>  drivers/gpu/drm/verisilicon/vs_drm.c          | 31
> +++++++++++++++++--
>  drivers/gpu/drm/verisilicon/vs_drm.h          |  7 +++++
>  .../gpu/drm/verisilicon/vs_primary_plane.c    | 11 ++++++-
>  3 files changed, 46 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/verisilicon/vs_drm.c
> b/drivers/gpu/drm/verisilicon/vs_drm.c
> index fd259d53f49f..52d8749445df 100644
> --- a/drivers/gpu/drm/verisilicon/vs_drm.c
> +++ b/drivers/gpu/drm/verisilicon/vs_drm.c
> @@ -4,7 +4,7 @@
>   */
>  
>  #include <linux/aperture.h>
> -#include <linux/dma-mapping.h>
> +#include <linux/of_address.h>
>  #include <linux/platform_device.h>
>  #include <linux/module.h>
>  #include <linux/regmap.h>
> @@ -49,6 +49,31 @@ static int vs_gem_dumb_create(struct drm_file
> *file_priv,
>  
>  DEFINE_DRM_GEM_FOPS(vs_drm_driver_fops);
>  
> +static struct drm_gem_object *vs_gem_create_object(struct drm_device
> *drm,
> +						   size_t size)
> +{
> +	struct drm_gem_dma_object *obj;
> +
> +	obj = kzalloc_obj(*obj);
> +	if (!obj)
> +		return ERR_PTR(-ENOMEM);
> +
> +	obj->map_noncoherent = to_vs_drm_dev(drm)->noncoherent;
> +
> +	return &obj->base;
> +}
> +
> +static struct drm_framebuffer *
> +vs_gem_fb_create(struct drm_device *drm, struct drm_file *file,
> +		 const struct drm_format_info *info,
> +		 const struct drm_mode_fb_cmd2 *mode_cmd)
> +{
> +	if (to_vs_drm_dev(drm)->noncoherent)
> +		return drm_gem_fb_create_with_dirty(drm, file, info,
> mode_cmd);
> +
> +	return drm_gem_fb_create(drm, file, info, mode_cmd);
> +}
> +
>  static const struct drm_driver vs_drm_driver = {
>  	.driver_features	= DRIVER_MODESET | DRIVER_GEM |
> DRIVER_ATOMIC,
>  	.fops			= &vs_drm_driver_fops,
> @@ -58,12 +83,13 @@ static const struct drm_driver vs_drm_driver = {
>  	.minor	= DRIVER_MINOR,
>  
>  	/* GEM Operations */
> +	.gem_create_object	= vs_gem_create_object,
>  	DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vs_gem_dumb_create),
>  	DRM_FBDEV_DMA_DRIVER_OPS,
>  };
>  
>  static const struct drm_mode_config_funcs vs_mode_config_funcs = {
> -	.fb_create		= drm_gem_fb_create,
> +	.fb_create		= vs_gem_fb_create,
>  	.atomic_check		= drm_atomic_helper_check,
>  	.atomic_commit		= drm_atomic_helper_commit,
>  };
> @@ -98,6 +124,7 @@ int vs_drm_initialize(struct vs_dc *dc, struct
> platform_device *pdev)
>  
>  	drm = &vdrm->base;
>  	vdrm->dc = dc;
> +	vdrm->noncoherent = !of_dma_is_coherent(dev->of_node);
>  	dc->drm_dev = vdrm;
>  
>  	ret = drmm_mode_config_init(drm);
> diff --git a/drivers/gpu/drm/verisilicon/vs_drm.h
> b/drivers/gpu/drm/verisilicon/vs_drm.h
> index 606338206a42..17704cd0df1d 100644
> --- a/drivers/gpu/drm/verisilicon/vs_drm.h
> +++ b/drivers/gpu/drm/verisilicon/vs_drm.h
> @@ -18,8 +18,15 @@ struct vs_drm_dev {
>  
>  	struct vs_dc *dc;
>  	struct vs_crtc *crtcs[VSDC_MAX_OUTPUTS];
> +
> +	bool noncoherent;
>  };
>  
> +static inline struct vs_drm_dev *to_vs_drm_dev(struct drm_device
> *drm)
> +{
> +	return container_of(drm, struct vs_drm_dev, base);
> +}
> +
>  int vs_drm_initialize(struct vs_dc *dc, struct platform_device
> *pdev);
>  void vs_drm_finalize(struct vs_dc *dc);
>  void vs_drm_shutdown_handler(struct vs_dc *dc);
> diff --git a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> index e8fcb5958615..0049737f492b 100644
> --- a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> +++ b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> @@ -8,6 +8,7 @@
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_crtc.h>
> +#include <drm/drm_fb_dma_helper.h>
>  #include <drm/drm_fourcc.h>
>  #include <drm/drm_framebuffer.h>
>  #include <drm/drm_gem_atomic_helper.h>
> @@ -16,8 +17,9 @@
>  #include <drm/drm_print.h>
>  
>  #include "vs_crtc.h"
> -#include "vs_plane.h"
>  #include "vs_dc.h"
> +#include "vs_drm.h"
> +#include "vs_plane.h"
>  #include "vs_primary_plane_regs.h"
>  
>  static int vs_primary_plane_atomic_check(struct drm_plane *plane,
> @@ -86,6 +88,8 @@ static void vs_primary_plane_atomic_disable(struct
> drm_plane *plane,
>  static void vs_primary_plane_atomic_update(struct drm_plane *plane,
>  					   struct drm_atomic_state
> *atomic_state)
>  {
> +	struct drm_plane_state *old_state =
> drm_atomic_get_old_plane_state(atomic_state,
> +								
> 	   plane);
>  	struct drm_plane_state *state =
> drm_atomic_get_new_plane_state(atomic_state,
>  								    
>    plane);
>  	struct drm_framebuffer *fb = state->fb;
> @@ -101,6 +105,8 @@ static void vs_primary_plane_atomic_update(struct
> drm_plane *plane,
>  		return;
>  	}
>  
> +	drm_fb_dma_sync_non_coherent(plane->dev, old_state, state);
> +
>  	vcrtc = drm_crtc_to_vs_crtc(crtc);
>  	output = vcrtc->id;
>  	dc = vcrtc->dc;
> @@ -169,5 +175,8 @@ struct drm_plane *vs_primary_plane_init(struct
> drm_device *drm_dev, struct vs_dc
>  
>  	drm_plane_helper_add(plane, &vs_primary_plane_helper_funcs);
>  
> +	if (to_vs_drm_dev(drm_dev)->noncoherent)
> +		drm_plane_enable_fb_damage_clips(plane);
> +
>  	return plane;
>  }
Re: [PATCH] drm: verisilicon: support non-coherent DMA framebuffers
Posted by Icenowy Zheng 1 month, 2 weeks ago
在 2026-05-05二的 17:05 +0800,Icenowy Zheng写道:
> 在 2026-05-05二的 04:26 +0000,Dominique Belhachemi写道:
> > Wire up the standard non-coherent path matching the ingenic DRM
> > driver.
> 
> Ah I forgot that my test platform is also noncoherent -- it uses
> uncached memory map instead of cache maintenance.
> 
> Should some other facility to be wired in to check whether cache
> maintenance or uncached mapping is available and use that
> functionality?

Ah forgot to mention that drm/imagination driver requires uncached
mapping too, and this seems to be difficult to lower (currently
impossible because the userspace only does Vulkan coherent map now).

Thanks,
Icenowy

> 
> Thanks,
> Icenowy
> 
> > 
> > Tested on StarFive JH7110 (VisionFive 2 v1.3B).
> > 
> > Signed-off-by: Dominique Belhachemi <domibel@debian.org>
> > ---
> >  drivers/gpu/drm/verisilicon/vs_drm.c          | 31
> > +++++++++++++++++--
> >  drivers/gpu/drm/verisilicon/vs_drm.h          |  7 +++++
> >  .../gpu/drm/verisilicon/vs_primary_plane.c    | 11 ++++++-
> >  3 files changed, 46 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/verisilicon/vs_drm.c
> > b/drivers/gpu/drm/verisilicon/vs_drm.c
> > index fd259d53f49f..52d8749445df 100644
> > --- a/drivers/gpu/drm/verisilicon/vs_drm.c
> > +++ b/drivers/gpu/drm/verisilicon/vs_drm.c
> > @@ -4,7 +4,7 @@
> >   */
> >  
> >  #include <linux/aperture.h>
> > -#include <linux/dma-mapping.h>
> > +#include <linux/of_address.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/module.h>
> >  #include <linux/regmap.h>
> > @@ -49,6 +49,31 @@ static int vs_gem_dumb_create(struct drm_file
> > *file_priv,
> >  
> >  DEFINE_DRM_GEM_FOPS(vs_drm_driver_fops);
> >  
> > +static struct drm_gem_object *vs_gem_create_object(struct
> > drm_device
> > *drm,
> > +						   size_t size)
> > +{
> > +	struct drm_gem_dma_object *obj;
> > +
> > +	obj = kzalloc_obj(*obj);
> > +	if (!obj)
> > +		return ERR_PTR(-ENOMEM);
> > +
> > +	obj->map_noncoherent = to_vs_drm_dev(drm)->noncoherent;
> > +
> > +	return &obj->base;
> > +}
> > +
> > +static struct drm_framebuffer *
> > +vs_gem_fb_create(struct drm_device *drm, struct drm_file *file,
> > +		 const struct drm_format_info *info,
> > +		 const struct drm_mode_fb_cmd2 *mode_cmd)
> > +{
> > +	if (to_vs_drm_dev(drm)->noncoherent)
> > +		return drm_gem_fb_create_with_dirty(drm, file,
> > info,
> > mode_cmd);
> > +
> > +	return drm_gem_fb_create(drm, file, info, mode_cmd);
> > +}
> > +
> >  static const struct drm_driver vs_drm_driver = {
> >  	.driver_features	= DRIVER_MODESET | DRIVER_GEM |
> > DRIVER_ATOMIC,
> >  	.fops			= &vs_drm_driver_fops,
> > @@ -58,12 +83,13 @@ static const struct drm_driver vs_drm_driver =
> > {
> >  	.minor	= DRIVER_MINOR,
> >  
> >  	/* GEM Operations */
> > +	.gem_create_object	= vs_gem_create_object,
> >  	DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vs_gem_dumb_create
> > ),
> >  	DRM_FBDEV_DMA_DRIVER_OPS,
> >  };
> >  
> >  static const struct drm_mode_config_funcs vs_mode_config_funcs = {
> > -	.fb_create		= drm_gem_fb_create,
> > +	.fb_create		= vs_gem_fb_create,
> >  	.atomic_check		= drm_atomic_helper_check,
> >  	.atomic_commit		= drm_atomic_helper_commit,
> >  };
> > @@ -98,6 +124,7 @@ int vs_drm_initialize(struct vs_dc *dc, struct
> > platform_device *pdev)
> >  
> >  	drm = &vdrm->base;
> >  	vdrm->dc = dc;
> > +	vdrm->noncoherent = !of_dma_is_coherent(dev->of_node);
> >  	dc->drm_dev = vdrm;
> >  
> >  	ret = drmm_mode_config_init(drm);
> > diff --git a/drivers/gpu/drm/verisilicon/vs_drm.h
> > b/drivers/gpu/drm/verisilicon/vs_drm.h
> > index 606338206a42..17704cd0df1d 100644
> > --- a/drivers/gpu/drm/verisilicon/vs_drm.h
> > +++ b/drivers/gpu/drm/verisilicon/vs_drm.h
> > @@ -18,8 +18,15 @@ struct vs_drm_dev {
> >  
> >  	struct vs_dc *dc;
> >  	struct vs_crtc *crtcs[VSDC_MAX_OUTPUTS];
> > +
> > +	bool noncoherent;
> >  };
> >  
> > +static inline struct vs_drm_dev *to_vs_drm_dev(struct drm_device
> > *drm)
> > +{
> > +	return container_of(drm, struct vs_drm_dev, base);
> > +}
> > +
> >  int vs_drm_initialize(struct vs_dc *dc, struct platform_device
> > *pdev);
> >  void vs_drm_finalize(struct vs_dc *dc);
> >  void vs_drm_shutdown_handler(struct vs_dc *dc);
> > diff --git a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> > b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> > index e8fcb5958615..0049737f492b 100644
> > --- a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> > +++ b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> > @@ -8,6 +8,7 @@
> >  #include <drm/drm_atomic.h>
> >  #include <drm/drm_atomic_helper.h>
> >  #include <drm/drm_crtc.h>
> > +#include <drm/drm_fb_dma_helper.h>
> >  #include <drm/drm_fourcc.h>
> >  #include <drm/drm_framebuffer.h>
> >  #include <drm/drm_gem_atomic_helper.h>
> > @@ -16,8 +17,9 @@
> >  #include <drm/drm_print.h>
> >  
> >  #include "vs_crtc.h"
> > -#include "vs_plane.h"
> >  #include "vs_dc.h"
> > +#include "vs_drm.h"
> > +#include "vs_plane.h"
> >  #include "vs_primary_plane_regs.h"
> >  
> >  static int vs_primary_plane_atomic_check(struct drm_plane *plane,
> > @@ -86,6 +88,8 @@ static void
> > vs_primary_plane_atomic_disable(struct
> > drm_plane *plane,
> >  static void vs_primary_plane_atomic_update(struct drm_plane
> > *plane,
> >  					   struct drm_atomic_state
> > *atomic_state)
> >  {
> > +	struct drm_plane_state *old_state =
> > drm_atomic_get_old_plane_state(atomic_state,
> > +								
> > 	   plane);
> >  	struct drm_plane_state *state =
> > drm_atomic_get_new_plane_state(atomic_state,
> >  								  
> >   
> >    plane);
> >  	struct drm_framebuffer *fb = state->fb;
> > @@ -101,6 +105,8 @@ static void
> > vs_primary_plane_atomic_update(struct
> > drm_plane *plane,
> >  		return;
> >  	}
> >  
> > +	drm_fb_dma_sync_non_coherent(plane->dev, old_state,
> > state);
> > +
> >  	vcrtc = drm_crtc_to_vs_crtc(crtc);
> >  	output = vcrtc->id;
> >  	dc = vcrtc->dc;
> > @@ -169,5 +175,8 @@ struct drm_plane *vs_primary_plane_init(struct
> > drm_device *drm_dev, struct vs_dc
> >  
> >  	drm_plane_helper_add(plane,
> > &vs_primary_plane_helper_funcs);
> >  
> > +	if (to_vs_drm_dev(drm_dev)->noncoherent)
> > +		drm_plane_enable_fb_damage_clips(plane);
> > +
> >  	return plane;
> >  }
Re: [PATCH] drm: verisilicon: support non-coherent DMA framebuffers
Posted by Icenowy Zheng 1 month, 2 weeks ago
在 2026-05-05二的 04:26 +0000,Dominique Belhachemi写道:
> Wire up the standard non-coherent path matching the ingenic DRM
> driver.
> 
> Tested on StarFive JH7110 (VisionFive 2 v1.3B).

Interesting, I am curious about other patches added to test this.

And this patch looks quite generic, should this code be added to the
corresponding helpers instead.

Thanks,
Icenowy

> 
> Signed-off-by: Dominique Belhachemi <domibel@debian.org>
> ---
>  drivers/gpu/drm/verisilicon/vs_drm.c          | 31
> +++++++++++++++++--
>  drivers/gpu/drm/verisilicon/vs_drm.h          |  7 +++++
>  .../gpu/drm/verisilicon/vs_primary_plane.c    | 11 ++++++-
>  3 files changed, 46 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/verisilicon/vs_drm.c
> b/drivers/gpu/drm/verisilicon/vs_drm.c
> index fd259d53f49f..52d8749445df 100644
> --- a/drivers/gpu/drm/verisilicon/vs_drm.c
> +++ b/drivers/gpu/drm/verisilicon/vs_drm.c
> @@ -4,7 +4,7 @@
>   */
>  
>  #include <linux/aperture.h>
> -#include <linux/dma-mapping.h>
> +#include <linux/of_address.h>
>  #include <linux/platform_device.h>
>  #include <linux/module.h>
>  #include <linux/regmap.h>
> @@ -49,6 +49,31 @@ static int vs_gem_dumb_create(struct drm_file
> *file_priv,
>  
>  DEFINE_DRM_GEM_FOPS(vs_drm_driver_fops);
>  
> +static struct drm_gem_object *vs_gem_create_object(struct drm_device
> *drm,
> +						   size_t size)
> +{
> +	struct drm_gem_dma_object *obj;
> +
> +	obj = kzalloc_obj(*obj);
> +	if (!obj)
> +		return ERR_PTR(-ENOMEM);
> +
> +	obj->map_noncoherent = to_vs_drm_dev(drm)->noncoherent;
> +
> +	return &obj->base;
> +}
> +
> +static struct drm_framebuffer *
> +vs_gem_fb_create(struct drm_device *drm, struct drm_file *file,
> +		 const struct drm_format_info *info,
> +		 const struct drm_mode_fb_cmd2 *mode_cmd)
> +{
> +	if (to_vs_drm_dev(drm)->noncoherent)
> +		return drm_gem_fb_create_with_dirty(drm, file, info,
> mode_cmd);
> +
> +	return drm_gem_fb_create(drm, file, info, mode_cmd);
> +}
> +
>  static const struct drm_driver vs_drm_driver = {
>  	.driver_features	= DRIVER_MODESET | DRIVER_GEM |
> DRIVER_ATOMIC,
>  	.fops			= &vs_drm_driver_fops,
> @@ -58,12 +83,13 @@ static const struct drm_driver vs_drm_driver = {
>  	.minor	= DRIVER_MINOR,
>  
>  	/* GEM Operations */
> +	.gem_create_object	= vs_gem_create_object,
>  	DRM_GEM_DMA_DRIVER_OPS_WITH_DUMB_CREATE(vs_gem_dumb_create),
>  	DRM_FBDEV_DMA_DRIVER_OPS,
>  };
>  
>  static const struct drm_mode_config_funcs vs_mode_config_funcs = {
> -	.fb_create		= drm_gem_fb_create,
> +	.fb_create		= vs_gem_fb_create,
>  	.atomic_check		= drm_atomic_helper_check,
>  	.atomic_commit		= drm_atomic_helper_commit,
>  };
> @@ -98,6 +124,7 @@ int vs_drm_initialize(struct vs_dc *dc, struct
> platform_device *pdev)
>  
>  	drm = &vdrm->base;
>  	vdrm->dc = dc;
> +	vdrm->noncoherent = !of_dma_is_coherent(dev->of_node);
>  	dc->drm_dev = vdrm;
>  
>  	ret = drmm_mode_config_init(drm);
> diff --git a/drivers/gpu/drm/verisilicon/vs_drm.h
> b/drivers/gpu/drm/verisilicon/vs_drm.h
> index 606338206a42..17704cd0df1d 100644
> --- a/drivers/gpu/drm/verisilicon/vs_drm.h
> +++ b/drivers/gpu/drm/verisilicon/vs_drm.h
> @@ -18,8 +18,15 @@ struct vs_drm_dev {
>  
>  	struct vs_dc *dc;
>  	struct vs_crtc *crtcs[VSDC_MAX_OUTPUTS];
> +
> +	bool noncoherent;
>  };
>  
> +static inline struct vs_drm_dev *to_vs_drm_dev(struct drm_device
> *drm)
> +{
> +	return container_of(drm, struct vs_drm_dev, base);
> +}
> +
>  int vs_drm_initialize(struct vs_dc *dc, struct platform_device
> *pdev);
>  void vs_drm_finalize(struct vs_dc *dc);
>  void vs_drm_shutdown_handler(struct vs_dc *dc);
> diff --git a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> index e8fcb5958615..0049737f492b 100644
> --- a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> +++ b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> @@ -8,6 +8,7 @@
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
>  #include <drm/drm_crtc.h>
> +#include <drm/drm_fb_dma_helper.h>
>  #include <drm/drm_fourcc.h>
>  #include <drm/drm_framebuffer.h>
>  #include <drm/drm_gem_atomic_helper.h>
> @@ -16,8 +17,9 @@
>  #include <drm/drm_print.h>
>  
>  #include "vs_crtc.h"
> -#include "vs_plane.h"
>  #include "vs_dc.h"
> +#include "vs_drm.h"
> +#include "vs_plane.h"
>  #include "vs_primary_plane_regs.h"
>  
>  static int vs_primary_plane_atomic_check(struct drm_plane *plane,
> @@ -86,6 +88,8 @@ static void vs_primary_plane_atomic_disable(struct
> drm_plane *plane,
>  static void vs_primary_plane_atomic_update(struct drm_plane *plane,
>  					   struct drm_atomic_state
> *atomic_state)
>  {
> +	struct drm_plane_state *old_state =
> drm_atomic_get_old_plane_state(atomic_state,
> +								
> 	   plane);
>  	struct drm_plane_state *state =
> drm_atomic_get_new_plane_state(atomic_state,
>  								    
>    plane);
>  	struct drm_framebuffer *fb = state->fb;
> @@ -101,6 +105,8 @@ static void vs_primary_plane_atomic_update(struct
> drm_plane *plane,
>  		return;
>  	}
>  
> +	drm_fb_dma_sync_non_coherent(plane->dev, old_state, state);
> +
>  	vcrtc = drm_crtc_to_vs_crtc(crtc);
>  	output = vcrtc->id;
>  	dc = vcrtc->dc;
> @@ -169,5 +175,8 @@ struct drm_plane *vs_primary_plane_init(struct
> drm_device *drm_dev, struct vs_dc
>  
>  	drm_plane_helper_add(plane, &vs_primary_plane_helper_funcs);
>  
> +	if (to_vs_drm_dev(drm_dev)->noncoherent)
> +		drm_plane_enable_fb_damage_clips(plane);
> +
>  	return plane;
>  }
Re: [PATCH] drm: verisilicon: support non-coherent DMA framebuffers
Posted by Dominique Belhachemi 1 month, 2 weeks ago
On Tue, May 5, 2026 at 5:03 AM Icenowy Zheng <zhengxingda@iscas.ac.cn> wrote:
>
> 在 2026-05-05二的 04:26 +0000,Dominique Belhachemi写道:
> > Wire up the standard non-coherent path matching the ingenic DRM
> > driver.
> >
> > Tested on StarFive JH7110 (VisionFive 2 v1.3B).
>
> Interesting, I am curious about other patches added to test this.
>
Hi,

I tested this on Debian unstable with a slightly patched 7.0.3 kernel [1].
The test branch contains your verisilicon series, Michal's JH7110
display series [2],
and a JH7110 ccache change [3], which was also required to communicate
with the BXE-4-32 firmware [4].

This change here is only used to remove the ugly framebuffer stripes
on the console and in the desktop environment.

[1] https://github.com/domibel/linux/tree/jh7110_dc8200_hdmi_v7.0.3
[2] https://lore.kernel.org/lkml/20251108-jh7110-clean-send-v1-0-06bf43bb76b1@samsung.com/
[3] https://lore.kernel.org/lkml/20260430035259.3402954-1-domibel@debian.org/
[4] https://github.com/domibel/linux/tree/powervr_on_jh7110_visionfive2_v7.0.3

Dominique
Re: [PATCH] drm: verisilicon: support non-coherent DMA framebuffers
Posted by Icenowy Zheng 1 month, 2 weeks ago
在 2026-05-05二的 18:25 -0400,Dominique Belhachemi写道:
> On Tue, May 5, 2026 at 5:03 AM Icenowy Zheng
> <zhengxingda@iscas.ac.cn> wrote:
> > 
> > 在 2026-05-05二的 04:26 +0000,Dominique Belhachemi写道:
> > > Wire up the standard non-coherent path matching the ingenic DRM
> > > driver.
> > > 
> > > Tested on StarFive JH7110 (VisionFive 2 v1.3B).
> > 
> > Interesting, I am curious about other patches added to test this.
> > 
> Hi,
> 
> I tested this on Debian unstable with a slightly patched 7.0.3 kernel
> [1].
> The test branch contains your verisilicon series, Michal's JH7110
> display series [2],
> and a JH7110 ccache change [3], which was also required to
> communicate
> with the BXE-4-32 firmware [4].

BTW did you run any rendering? I think the way currently powervr open
source driver works requires "coherent memory" (although it's usually
implemented as uncached memory).

> 
> This change here is only used to remove the ugly framebuffer stripes
> on the console and in the desktop environment.

But I still think it'd be better to implement proper uncached memory
support instead of flushing caches with dirty tracking.

> 
> [1] https://github.com/domibel/linux/tree/jh7110_dc8200_hdmi_v7.0.3
> [2]
> https://lore.kernel.org/lkml/20251108-jh7110-clean-send-v1-0-06bf43bb76b1@samsung.com/
> [3]
> https://lore.kernel.org/lkml/20260430035259.3402954-1-domibel@debian.org/
> [4]
> https://github.com/domibel/linux/tree/powervr_on_jh7110_visionfive2_v7.0.3

The POW_RASCALDUST thing looks quite interesting, maybe I should
investigate it further.

Thanks,
Icenowy
> 
> Dominique
Re: [PATCH] drm: verisilicon: support non-coherent DMA framebuffers
Posted by Dominique Belhachemi 1 month, 2 weeks ago
On Wed, May 6, 2026 at 1:14 PM Icenowy Zheng <zhengxingda@iscas.ac.cn> wrote:
>
> 在 2026-05-05二的 18:25 -0400,Dominique Belhachemi写道:
> > On Tue, May 5, 2026 at 5:03 AM Icenowy Zheng
> > <zhengxingda@iscas.ac.cn> wrote:
> > >
> > > 在 2026-05-05二的 04:26 +0000,Dominique Belhachemi写道:
> > > > Wire up the standard non-coherent path matching the ingenic DRM
> > > > driver.
> > > >
> > > > Tested on StarFive JH7110 (VisionFive 2 v1.3B).
> > >
> > > Interesting, I am curious about other patches added to test this.
> > >
> > Hi,
> >
> > I tested this on Debian unstable with a slightly patched 7.0.3 kernel
> > [1].
> > The test branch contains your verisilicon series, Michal's JH7110
> > display series [2],
> > and a JH7110 ccache change [3], which was also required to
> > communicate
> > with the BXE-4-32 firmware [4].
>
> BTW did you run any rendering? I think the way currently powervr open
> source driver works requires "coherent memory" (although it's usually
> implemented as uncached memory).

Yes, GPU dispatches run with [4].
Compute shaders run fine, but rendering crashes after a few frames.

> >
> > This change here is only used to remove the ugly framebuffer stripes
> > on the console and in the desktop environment.
>
> But I still think it'd be better to implement proper uncached memory
> support instead of flushing caches with dirty tracking.

Maybe, this patch is just a working alternative.

Dominique

> >
> > [1] https://github.com/domibel/linux/tree/jh7110_dc8200_hdmi_v7.0.3
> > [2]
> > https://lore.kernel.org/lkml/20251108-jh7110-clean-send-v1-0-06bf43bb76b1@samsung.com/
> > [3]
> > https://lore.kernel.org/lkml/20260430035259.3402954-1-domibel@debian.org/
> > [4]
> > https://github.com/domibel/linux/tree/powervr_on_jh7110_visionfive2_v7.0.3
>
> The POW_RASCALDUST thing looks quite interesting, maybe I should
> investigate it further.
>
> Thanks,
> Icenowy
> >
> > Dominique
>
>
Re: [PATCH] drm: verisilicon: support non-coherent DMA framebuffers
Posted by Icenowy Zheng 1 month, 2 weeks ago
在 2026-05-06三的 13:38 -0400,Dominique Belhachemi写道:
> On Wed, May 6, 2026 at 1:14 PM Icenowy Zheng
> <zhengxingda@iscas.ac.cn> wrote:
> > 
> > 在 2026-05-05二的 18:25 -0400,Dominique Belhachemi写道:
> > > On Tue, May 5, 2026 at 5:03 AM Icenowy Zheng
> > > <zhengxingda@iscas.ac.cn> wrote:
> > > > 
> > > > 在 2026-05-05二的 04:26 +0000,Dominique Belhachemi写道:
> > > > > Wire up the standard non-coherent path matching the ingenic
> > > > > DRM
> > > > > driver.
> > > > > 
> > > > > Tested on StarFive JH7110 (VisionFive 2 v1.3B).
> > > > 
> > > > Interesting, I am curious about other patches added to test
> > > > this.
> > > > 
> > > Hi,
> > > 
> > > I tested this on Debian unstable with a slightly patched 7.0.3
> > > kernel
> > > [1].
> > > The test branch contains your verisilicon series, Michal's JH7110
> > > display series [2],
> > > and a JH7110 ccache change [3], which was also required to
> > > communicate
> > > with the BXE-4-32 firmware [4].
> > 
> > BTW did you run any rendering? I think the way currently powervr
> > open
> > source driver works requires "coherent memory" (although it's
> > usually
> > implemented as uncached memory).
> 
> Yes, GPU dispatches run with [4].
> Compute shaders run fine, but rendering crashes after a few frames.
> 
> > > 
> > > This change here is only used to remove the ugly framebuffer
> > > stripes
> > > on the console and in the desktop environment.
> > 
> > But I still think it'd be better to implement proper uncached
> > memory
> > support instead of flushing caches with dirty tracking.
> 
> Maybe, this patch is just a working alternative.

I wonder whether it's possible to detect the availability of uncached
memory.

At least detecting using `of_dma_is_coherent()` isn't enough because it
will only be true when the device is fully coherent with the CPU
(snooping CPU cache).

Thanks,
Icenowy

> 
> Dominique
> 
> > > 
> > > [1]
> > > https://github.com/domibel/linux/tree/jh7110_dc8200_hdmi_v7.0.3
> > > [2]
> > > https://lore.kernel.org/lkml/20251108-jh7110-clean-send-v1-0-06bf43bb76b1@samsung.com/
> > > [3]
> > > https://lore.kernel.org/lkml/20260430035259.3402954-1-domibel@debian.org/
> > > [4]
> > > https://github.com/domibel/linux/tree/powervr_on_jh7110_visionfive2_v7.0.3
> > 
> > The POW_RASCALDUST thing looks quite interesting, maybe I should
> > investigate it further.
> > 
> > Thanks,
> > Icenowy
> > > 
> > > Dominique
> > 
> > 
Re: [PATCH] drm: verisilicon: support non-coherent DMA framebuffers
Posted by Chen-Yu Tsai 1 month, 2 weeks ago
On Tue, May 5, 2026 at 5:03 PM Icenowy Zheng <zhengxingda@iscas.ac.cn> wrote:
>
> 在 2026-05-05二的 04:26 +0000,Dominique Belhachemi写道:
> > Wire up the standard non-coherent path matching the ingenic DRM
> > driver.
> >
> > Tested on StarFive JH7110 (VisionFive 2 v1.3B).
>
> Interesting, I am curious about other patches added to test this.
>
> And this patch looks quite generic, should this code be added to the
> corresponding helpers instead.

This is pretty generic already. The helper functions are used where
they are needed.


ChenYu