Messages in this thread Patch in this message |  | | From | Dominique Belhachemi <> | | Subject | [PATCH] drm: verisilicon: support non-coherent DMA framebuffers | | Date | Tue, 5 May 2026 04:26:31 +0000 |
| |
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
|  |