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,