This patch adds ast specific codes for DRM prime feature, this is to allow for offloading of rending in one direction and outputs in other.
v1->v2: - Fix the comment.
Signed-off-by: oushixiong oushixiong@kylinos.cn --- drivers/gpu/drm/ast/ast_drv.c | 22 ++++++ drivers/gpu/drm/ast/ast_mode.c | 125 ++++++++++++++++++++++++++++++++- 2 files changed, 146 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 7465c4f0156a..6c1f75174368 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -28,6 +28,7 @@
#include <linux/module.h> #include <linux/pci.h> +#include <linux/dma-buf.h>
#include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> @@ -50,6 +51,23 @@ module_param_named(modeset, ast_modeset, int, 0400);
DEFINE_DRM_GEM_FOPS(ast_fops);
+static struct drm_gem_object *ast_gem_prime_import_sg_table(struct drm_device *dev, + struct dma_buf_attachment *attach, + struct sg_table *sg) +{ + struct drm_gem_vram_object *gbo; + struct dma_resv *resv = attach->dmabuf->resv; + + ww_mutex_lock(&resv->lock, NULL); + gbo = drm_gem_vram_create(dev, attach->dmabuf->size, 0); + ww_mutex_unlock(&resv->lock); + + if (IS_ERR(gbo)) + return NULL; + + return &gbo->bo.base; +} + static const struct drm_driver ast_driver = { .driver_features = DRIVER_ATOMIC | DRIVER_GEM | @@ -63,6 +81,10 @@ static const struct drm_driver ast_driver = { .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL,
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_import_sg_table = ast_gem_prime_import_sg_table, + DRM_GEM_VRAM_DRIVER };
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 45b56b39ad47..ebe732705e34 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -48,6 +48,8 @@ #include "ast_drv.h" #include "ast_tables.h"
+MODULE_IMPORT_NS(DMA_BUF); + static inline void ast_load_palette_index(struct ast_private *ast, u8 index, u8 red, u8 green, u8 blue) @@ -1535,8 +1537,129 @@ static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs = .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, };
+static int ast_handle_damage(struct drm_framebuffer *fb, int x, int y, + int width, int height) +{ + struct drm_gem_vram_object *dst_bo = NULL; + void *dst = NULL; + int ret = 0, i; + unsigned long offset = 0; + bool unmap = false; + unsigned int bytesPerPixel; + struct iosys_map map; + struct iosys_map dmabuf_map; + + bytesPerPixel = fb->format->cpp[0]; + + if (!fb->obj[0]->import_attach) + return -EINVAL; + + if (!fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr) { + ret = dma_buf_vmap(fb->obj[0]->import_attach->dmabuf, &dmabuf_map); + if (ret) + return 0; + } else + dmabuf_map.vaddr = fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr; + + dst_bo = drm_gem_vram_of_gem(fb->obj[0]); + + ret = drm_gem_vram_pin(dst_bo, 0); + if (ret) { + DRM_ERROR("ast_bo_pin failed\n"); + goto error; + } + + if (!dst_bo->map.vaddr) { + ret = drm_gem_vram_vmap(dst_bo, &map); + if (ret) { + DRM_ERROR("failed to vmap fbcon\n"); + drm_gem_vram_unpin(dst_bo); + goto error; + } + unmap = true; + } + dst = dst_bo->map.vaddr; + + for (i = y; i < y + height; i++) { + offset = i * fb->pitches[0] + (x * bytesPerPixel); + memcpy_toio(dst + offset, dmabuf_map.vaddr + offset, + width * bytesPerPixel); + } + + if (unmap) + drm_gem_vram_vunmap(dst_bo, &map); + + drm_gem_vram_unpin(dst_bo); +error: + return 0; +} + + +static int ast_user_framebuffer_dirty(struct drm_framebuffer *fb, + struct drm_file *file, + unsigned int flags, + unsigned int color, + struct drm_clip_rect *clips, + unsigned int num_clips) +{ + int i, ret = 0; + + drm_modeset_lock_all(fb->dev); + if (fb->obj[0]->import_attach) { + ret = dma_buf_begin_cpu_access(fb->obj[0]->import_attach->dmabuf, + DMA_FROM_DEVICE); + if (ret) + goto unlock; + } + + for (i = 0; i < num_clips; i++) { + ret = ast_handle_damage(fb, clips[i].x1, clips[i].y1, + clips[i].x2 - clips[i].x1, clips[i].y2 - clips[i].y1); + if (ret) + break; + } + + if (fb->obj[0]->import_attach) { + dma_buf_end_cpu_access(fb->obj[0]->import_attach->dmabuf, + DMA_FROM_DEVICE); + } + +unlock: + drm_modeset_unlock_all(fb->dev); + + return ret; +} + +static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb) +{ + struct iosys_map dmabuf_map; + + if (fb->obj[0]->import_attach) { + dmabuf_map.vaddr = fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr; + if (dmabuf_map.vaddr) + dma_buf_vunmap(fb->obj[0]->import_attach->dmabuf, + &dmabuf_map); + } + + drm_gem_fb_destroy(fb); +} + +static const struct drm_framebuffer_funcs ast_gem_fb_funcs_dirtyfb = { + .destroy = ast_user_framebuffer_destroy, + .create_handle = drm_gem_fb_create_handle, + .dirty = ast_user_framebuffer_dirty, +}; + +static struct drm_framebuffer * +ast_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file, + const struct drm_mode_fb_cmd2 *mode_cmd) +{ + return drm_gem_fb_create_with_funcs(dev, file, mode_cmd, + &ast_gem_fb_funcs_dirtyfb); +} + static const struct drm_mode_config_funcs ast_mode_config_funcs = { - .fb_create = drm_gem_fb_create, + .fb_create = ast_gem_fb_create_with_dirty, .mode_valid = drm_vram_helper_mode_valid, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit,
Am 18.08.22 um 11:45 schrieb oushixiong:
This patch adds ast specific codes for DRM prime feature, this is to allow for offloading of rending in one direction and outputs in other.
v1->v2:
- Fix the comment.
 Signed-off-by: oushixiong oushixiong@kylinos.cn
drivers/gpu/drm/ast/ast_drv.c | 22 ++++++ drivers/gpu/drm/ast/ast_mode.c | 125 ++++++++++++++++++++++++++++++++- 2 files changed, 146 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 7465c4f0156a..6c1f75174368 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -28,6 +28,7 @@ #include <linux/module.h> #include <linux/pci.h> +#include <linux/dma-buf.h> #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> @@ -50,6 +51,23 @@ module_param_named(modeset, ast_modeset, int, 0400); DEFINE_DRM_GEM_FOPS(ast_fops); +static struct drm_gem_object *ast_gem_prime_import_sg_table(struct drm_device *dev,
struct dma_buf_attachment *attach,struct sg_table *sg)+{
- struct drm_gem_vram_object *gbo;
 - struct dma_resv *resv = attach->dmabuf->resv;
 - ww_mutex_lock(&resv->lock, NULL);
 - gbo = drm_gem_vram_create(dev, attach->dmabuf->size, 0);
 - ww_mutex_unlock(&resv->lock);
 - if (IS_ERR(gbo))
 return NULL;
Well where do you use the sg_table here?
Christian.
- return &gbo->bo.base;
 +}
- static const struct drm_driver ast_driver = { .driver_features = DRIVER_ATOMIC | DRIVER_GEM |
 @@ -63,6 +81,10 @@ static const struct drm_driver ast_driver = { .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL,
- .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 - .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 - .gem_prime_import_sg_table = ast_gem_prime_import_sg_table,
 - DRM_GEM_VRAM_DRIVER };
 diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 45b56b39ad47..ebe732705e34 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -48,6 +48,8 @@ #include "ast_drv.h" #include "ast_tables.h" +MODULE_IMPORT_NS(DMA_BUF);
- static inline void ast_load_palette_index(struct ast_private *ast, u8 index, u8 red, u8 green, u8 blue)
 @@ -1535,8 +1537,129 @@ static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs = .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, }; +static int ast_handle_damage(struct drm_framebuffer *fb, int x, int y,
int width, int height)+{
- struct drm_gem_vram_object *dst_bo = NULL;
 - void *dst = NULL;
 - int ret = 0, i;
 - unsigned long offset = 0;
 - bool unmap = false;
 - unsigned int bytesPerPixel;
 - struct iosys_map map;
 - struct iosys_map dmabuf_map;
 - bytesPerPixel = fb->format->cpp[0];
 - if (!fb->obj[0]->import_attach)
 return -EINVAL;- if (!fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr) {
 ret = dma_buf_vmap(fb->obj[0]->import_attach->dmabuf, &dmabuf_map);if (ret)return 0;- } else
 dmabuf_map.vaddr = fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr;- dst_bo = drm_gem_vram_of_gem(fb->obj[0]);
 - ret = drm_gem_vram_pin(dst_bo, 0);
 - if (ret) {
 DRM_ERROR("ast_bo_pin failed\n");goto error;- }
 - if (!dst_bo->map.vaddr) {
 ret = drm_gem_vram_vmap(dst_bo, &map);if (ret) {DRM_ERROR("failed to vmap fbcon\n");drm_gem_vram_unpin(dst_bo);goto error;}unmap = true;- }
 - dst = dst_bo->map.vaddr;
 - for (i = y; i < y + height; i++) {
 offset = i * fb->pitches[0] + (x * bytesPerPixel);memcpy_toio(dst + offset, dmabuf_map.vaddr + offset,width * bytesPerPixel);- }
 - if (unmap)
 drm_gem_vram_vunmap(dst_bo, &map);- drm_gem_vram_unpin(dst_bo);
 +error:
- return 0;
 +}
+static int ast_user_framebuffer_dirty(struct drm_framebuffer *fb,
struct drm_file *file,unsigned int flags,unsigned int color,struct drm_clip_rect *clips,unsigned int num_clips)+{
- int i, ret = 0;
 - drm_modeset_lock_all(fb->dev);
 - if (fb->obj[0]->import_attach) {
 ret = dma_buf_begin_cpu_access(fb->obj[0]->import_attach->dmabuf,DMA_FROM_DEVICE);if (ret)goto unlock;- }
 - for (i = 0; i < num_clips; i++) {
 ret = ast_handle_damage(fb, clips[i].x1, clips[i].y1,clips[i].x2 - clips[i].x1, clips[i].y2 - clips[i].y1);if (ret)break;- }
 - if (fb->obj[0]->import_attach) {
 dma_buf_end_cpu_access(fb->obj[0]->import_attach->dmabuf,DMA_FROM_DEVICE);- }
 +unlock:
- drm_modeset_unlock_all(fb->dev);
 - return ret;
 +}
+static void ast_user_framebuffer_destroy(struct drm_framebuffer *fb) +{
- struct iosys_map dmabuf_map;
 - if (fb->obj[0]->import_attach) {
 dmabuf_map.vaddr = fb->obj[0]->import_attach->dmabuf->vmap_ptr.vaddr;if (dmabuf_map.vaddr)dma_buf_vunmap(fb->obj[0]->import_attach->dmabuf,&dmabuf_map);- }
 - drm_gem_fb_destroy(fb);
 +}
+static const struct drm_framebuffer_funcs ast_gem_fb_funcs_dirtyfb = {
- .destroy = ast_user_framebuffer_destroy,
 - .create_handle = drm_gem_fb_create_handle,
 - .dirty = ast_user_framebuffer_dirty,
 +};
+static struct drm_framebuffer * +ast_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file,
const struct drm_mode_fb_cmd2 *mode_cmd)+{
- return drm_gem_fb_create_with_funcs(dev, file, mode_cmd,
 &ast_gem_fb_funcs_dirtyfb);+}
- static const struct drm_mode_config_funcs ast_mode_config_funcs = {
 
- .fb_create = drm_gem_fb_create,
 
- .fb_create = ast_gem_fb_create_with_dirty, .mode_valid = drm_vram_helper_mode_valid, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit,
 
linaro-mm-sig@lists.linaro.org