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