在 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 <[email protected]> > > --- > > 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; > > }
