From 08b22f65b309649057edfbae1d8772b04210b486 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 7 Nov 2019 10:43:06 +0100 Subject: drm/udl: Switch to SHMEM Udl's GEM code and the generic SHMEM are almost identical. Replace the former with SHMEM. The dmabuf support in udl is being replaced with generic GEM PRIME functions. The main difference is in the caching flags for mmap pages. By default, SHMEM always sets (uncached) write combining. In udl's memory management code, only imported buffers use write combining. Memory pages of locally created buffer objects are mmap'ed with caching enabled. To keep the optimization, udl provides its own mmap function for GEM objects where it fixes up the mapping flags. v3: - restore udl vmap that enables caching v2: - remove obsolete code in a separate patch Signed-off-by: Thomas Zimmermann Acked-by: Gerd Hoffmann Link: https://patchwork.freedesktop.org/patch/msgid/20191107094307.19870-4-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_fb.c | 66 ++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index ef3504d06343..f8153b726343 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "udl_drv.h" @@ -94,16 +95,14 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, if (!fb->active_16) return 0; - if (!fb->obj->vmapping) { - ret = udl_gem_vmap(fb->obj); - if (ret == -ENOMEM) { + if (!fb->shmem->vaddr) { + void *vaddr; + + vaddr = drm_gem_shmem_vmap(&fb->shmem->base); + if (IS_ERR(vaddr)) { DRM_ERROR("failed to vmap fb\n"); return 0; } - if (!fb->obj->vmapping) { - DRM_ERROR("failed to vmapping\n"); - return 0; - } } aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); @@ -127,7 +126,7 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, const int byte_offset = line_offset + (x << log_bpp); const int dev_byte_offset = (fb->base.width * i + x) << log_bpp; if (udl_render_hline(dev, log_bpp, &urb, - (char *) fb->obj->vmapping, + (char *) fb->shmem->vaddr, &cmd, byte_offset, dev_byte_offset, width << log_bpp, &bytes_identical, &bytes_sent)) @@ -281,6 +280,7 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, unsigned num_clips) { struct udl_framebuffer *ufb = to_udl_fb(fb); + struct dma_buf_attachment *import_attach; int i; int ret = 0; @@ -289,8 +289,10 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, if (!ufb->active_16) goto unlock; - if (ufb->obj->base.import_attach) { - ret = dma_buf_begin_cpu_access(ufb->obj->base.import_attach->dmabuf, + import_attach = ufb->shmem->base.import_attach; + + if (import_attach) { + ret = dma_buf_begin_cpu_access(import_attach->dmabuf, DMA_FROM_DEVICE); if (ret) goto unlock; @@ -304,10 +306,9 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, break; } - if (ufb->obj->base.import_attach) { - ret = dma_buf_end_cpu_access(ufb->obj->base.import_attach->dmabuf, + if (import_attach) + ret = dma_buf_end_cpu_access(import_attach->dmabuf, DMA_FROM_DEVICE); - } unlock: drm_modeset_unlock_all(fb->dev); @@ -319,8 +320,8 @@ static void udl_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct udl_framebuffer *ufb = to_udl_fb(fb); - if (ufb->obj) - drm_gem_object_put_unlocked(&ufb->obj->base); + if (ufb->shmem) + drm_gem_object_put_unlocked(&ufb->shmem->base); drm_framebuffer_cleanup(fb); kfree(ufb); @@ -336,11 +337,11 @@ static int udl_framebuffer_init(struct drm_device *dev, struct udl_framebuffer *ufb, const struct drm_mode_fb_cmd2 *mode_cmd, - struct udl_gem_object *obj) + struct drm_gem_shmem_object *shmem) { int ret; - ufb->obj = obj; + ufb->shmem = shmem; drm_helper_mode_fill_fb_struct(dev, &ufb->base, mode_cmd); ret = drm_framebuffer_init(dev, &ufb->base, &udlfb_funcs); return ret; @@ -356,7 +357,8 @@ static int udlfb_create(struct drm_fb_helper *helper, struct fb_info *info; struct drm_framebuffer *fb; struct drm_mode_fb_cmd2 mode_cmd; - struct udl_gem_object *obj; + struct drm_gem_shmem_object *shmem; + void *vaddr; uint32_t size; int ret = 0; @@ -373,12 +375,15 @@ static int udlfb_create(struct drm_fb_helper *helper, size = mode_cmd.pitches[0] * mode_cmd.height; size = ALIGN(size, PAGE_SIZE); - obj = udl_gem_alloc_object(dev, size); - if (!obj) + shmem = drm_gem_shmem_create(dev, size); + if (IS_ERR(shmem)) { + ret = PTR_ERR(shmem); goto out; + } - ret = udl_gem_vmap(obj); - if (ret) { + vaddr = drm_gem_shmem_vmap(&shmem->base); + if (IS_ERR(vaddr)) { + ret = PTR_ERR(vaddr); DRM_ERROR("failed to vmap fb\n"); goto out_gfree; } @@ -389,7 +394,7 @@ static int udlfb_create(struct drm_fb_helper *helper, goto out_gfree; } - ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, obj); + ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, shmem); if (ret) goto out_gfree; @@ -397,20 +402,20 @@ static int udlfb_create(struct drm_fb_helper *helper, ufbdev->helper.fb = fb; - info->screen_base = ufbdev->ufb.obj->vmapping; + info->screen_base = vaddr; info->fix.smem_len = size; - info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping; + info->fix.smem_start = (unsigned long)vaddr; info->fbops = &udlfb_ops; drm_fb_helper_fill_info(info, &ufbdev->helper, sizes); DRM_DEBUG_KMS("allocated %dx%d vmal %p\n", fb->width, fb->height, - ufbdev->ufb.obj->vmapping); + ufbdev->ufb.shmem->vaddr); return ret; out_gfree: - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); + drm_gem_object_put_unlocked(&ufbdev->ufb.shmem->base); out: return ret; } @@ -424,10 +429,10 @@ static void udl_fbdev_destroy(struct drm_device *dev, { drm_fb_helper_unregister_fbi(&ufbdev->helper); drm_fb_helper_fini(&ufbdev->helper); - if (ufbdev->ufb.obj) { + if (ufbdev->ufb.shmem) { drm_framebuffer_unregister_private(&ufbdev->ufb.base); drm_framebuffer_cleanup(&ufbdev->ufb.base); - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); + drm_gem_object_put_unlocked(&ufbdev->ufb.shmem->base); } } @@ -518,7 +523,8 @@ udl_fb_user_fb_create(struct drm_device *dev, if (ufb == NULL) return ERR_PTR(-ENOMEM); - ret = udl_framebuffer_init(dev, ufb, mode_cmd, to_udl_bo(obj)); + ret = udl_framebuffer_init(dev, ufb, mode_cmd, + to_drm_gem_shmem_obj(obj)); if (ret) { kfree(ufb); return ERR_PTR(-EINVAL); -- cgit From d0c4fc5a4814e431c15272935c8dc973c18073aa Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 14 Nov 2019 13:51:04 +0100 Subject: drm/udl: Replace fbdev code with generic emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The udl driver can use the generic fbdev implementation. Convert it. v5: * initialize console after registering device v4: * hardcode console bpp to 16 v3: * remove module parameter fb_bpp in favor of fbdev's video * call drm_fbdev_generic_setup() directly; remove udl_fbdev_init() * use default for struct drm_mode_config_funcs.output_poll_changed * use default for struct drm_driver.lastclose Signed-off-by: Thomas Zimmermann Reviewed-by: Noralf Trønnes Link: https://patchwork.freedesktop.org/patch/msgid/20191114125106.28347-2-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_drv.c | 8 +- drivers/gpu/drm/udl/udl_drv.h | 6 - drivers/gpu/drm/udl/udl_fb.c | 282 -------------------------------------- drivers/gpu/drm/udl/udl_main.c | 6 - drivers/gpu/drm/udl/udl_modeset.c | 1 - 5 files changed, 7 insertions(+), 296 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 563cc5809e56..d5783fa32c5b 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -107,8 +108,14 @@ static int udl_usb_probe(struct usb_interface *interface, DRM_INFO("Initialized udl on minor %d\n", udl->drm.primary->index); + r = drm_fbdev_generic_setup(&udl->drm, 16); + if (r) + goto err_drm_dev_unregister; + return 0; +err_drm_dev_unregister: + drm_dev_unregister(&udl->drm); err_free: drm_dev_put(&udl->drm); return r; @@ -119,7 +126,6 @@ static void udl_usb_disconnect(struct usb_interface *interface) struct drm_device *dev = usb_get_intfdata(interface); drm_kms_helper_poll_disable(dev); - udl_fbdev_unplug(dev); udl_drop_usb(dev); drm_dev_unplug(dev); drm_dev_put(dev); diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 987d99ae2dfa..be585e3e572d 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -47,8 +47,6 @@ struct urb_list { size_t size; }; -struct udl_fbdev; - struct udl_device { struct drm_device drm; struct device *dev; @@ -62,7 +60,6 @@ struct udl_device { struct urb_list urbs; atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ - struct udl_fbdev *fbdev; char mode_buf[1024]; uint32_t mode_buf_len; atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ @@ -97,9 +94,6 @@ void udl_urb_completion(struct urb *urb); int udl_init(struct udl_device *udl); void udl_fini(struct drm_device *dev); -int udl_fbdev_init(struct drm_device *dev); -void udl_fbdev_cleanup(struct drm_device *dev); -void udl_fbdev_unplug(struct drm_device *dev); struct drm_framebuffer * udl_fb_user_fb_create(struct drm_device *dev, struct drm_file *file, diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index f8153b726343..8fe4d8cf3212 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -13,27 +13,12 @@ #include #include -#include #include #include #include #include "udl_drv.h" -#define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */ - -static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */ -static int fb_bpp = 16; - -module_param(fb_bpp, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); -module_param(fb_defio, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); - -struct udl_fbdev { - struct drm_fb_helper helper; /* must be first */ - struct udl_framebuffer ufb; - int fb_count; -}; - #define DL_ALIGN_UP(x, a) ALIGN(x, a) #define DL_ALIGN_DOWN(x, a) ALIGN_DOWN(x, a) @@ -156,123 +141,6 @@ error: return 0; } -static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - unsigned long start = vma->vm_start; - unsigned long size = vma->vm_end - vma->vm_start; - unsigned long offset; - unsigned long page, pos; - - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) - return -EINVAL; - - offset = vma->vm_pgoff << PAGE_SHIFT; - - if (offset > info->fix.smem_len || size > info->fix.smem_len - offset) - return -EINVAL; - - pos = (unsigned long)info->fix.smem_start + offset; - - pr_debug("mmap() framebuffer addr:%lu size:%lu\n", - pos, size); - - /* We don't want the framebuffer to be mapped encrypted */ - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); - - while (size > 0) { - page = vmalloc_to_pfn((void *)pos); - if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) - return -EAGAIN; - - start += PAGE_SIZE; - pos += PAGE_SIZE; - if (size > PAGE_SIZE) - size -= PAGE_SIZE; - else - size = 0; - } - - /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ - return 0; -} - -/* - * It's common for several clients to have framebuffer open simultaneously. - * e.g. both fbcon and X. Makes things interesting. - * Assumes caller is holding info->lock (for open and release at least) - */ -static int udl_fb_open(struct fb_info *info, int user) -{ - struct udl_fbdev *ufbdev = info->par; - struct drm_device *dev = ufbdev->ufb.base.dev; - struct udl_device *udl = to_udl(dev); - - /* If the USB device is gone, we don't accept new opens */ - if (drm_dev_is_unplugged(&udl->drm)) - return -ENODEV; - - ufbdev->fb_count++; - -#ifdef CONFIG_DRM_FBDEV_EMULATION - if (fb_defio && (info->fbdefio == NULL)) { - /* enable defio at last moment if not disabled by client */ - - struct fb_deferred_io *fbdefio; - - fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); - - if (fbdefio) { - fbdefio->delay = DL_DEFIO_WRITE_DELAY; - fbdefio->deferred_io = drm_fb_helper_deferred_io; - } - - info->fbdefio = fbdefio; - fb_deferred_io_init(info); - } -#endif - - pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d\n", - info->node, user, info, ufbdev->fb_count); - - return 0; -} - - -/* - * Assumes caller is holding info->lock mutex (for open and release at least) - */ -static int udl_fb_release(struct fb_info *info, int user) -{ - struct udl_fbdev *ufbdev = info->par; - - ufbdev->fb_count--; - -#ifdef CONFIG_DRM_FBDEV_EMULATION - if ((ufbdev->fb_count == 0) && (info->fbdefio)) { - fb_deferred_io_cleanup(info); - kfree(info->fbdefio); - info->fbdefio = NULL; - info->fbops->fb_mmap = udl_fb_mmap; - } -#endif - - pr_debug("released /dev/fb%d user=%d count=%d\n", - info->node, user, ufbdev->fb_count); - - return 0; -} - -static struct fb_ops udlfb_ops = { - .owner = THIS_MODULE, - DRM_FB_HELPER_DEFAULT_OPS, - .fb_fillrect = drm_fb_helper_sys_fillrect, - .fb_copyarea = drm_fb_helper_sys_copyarea, - .fb_imageblit = drm_fb_helper_sys_imageblit, - .fb_mmap = udl_fb_mmap, - .fb_open = udl_fb_open, - .fb_release = udl_fb_release, -}; - static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, struct drm_file *file, unsigned flags, unsigned color, @@ -347,156 +215,6 @@ udl_framebuffer_init(struct drm_device *dev, return ret; } - -static int udlfb_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct udl_fbdev *ufbdev = - container_of(helper, struct udl_fbdev, helper); - struct drm_device *dev = ufbdev->helper.dev; - struct fb_info *info; - struct drm_framebuffer *fb; - struct drm_mode_fb_cmd2 mode_cmd; - struct drm_gem_shmem_object *shmem; - void *vaddr; - uint32_t size; - int ret = 0; - - if (sizes->surface_bpp == 24) - sizes->surface_bpp = 32; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); - - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - - size = mode_cmd.pitches[0] * mode_cmd.height; - size = ALIGN(size, PAGE_SIZE); - - shmem = drm_gem_shmem_create(dev, size); - if (IS_ERR(shmem)) { - ret = PTR_ERR(shmem); - goto out; - } - - vaddr = drm_gem_shmem_vmap(&shmem->base); - if (IS_ERR(vaddr)) { - ret = PTR_ERR(vaddr); - DRM_ERROR("failed to vmap fb\n"); - goto out_gfree; - } - - info = drm_fb_helper_alloc_fbi(helper); - if (IS_ERR(info)) { - ret = PTR_ERR(info); - goto out_gfree; - } - - ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, shmem); - if (ret) - goto out_gfree; - - fb = &ufbdev->ufb.base; - - ufbdev->helper.fb = fb; - - info->screen_base = vaddr; - info->fix.smem_len = size; - info->fix.smem_start = (unsigned long)vaddr; - - info->fbops = &udlfb_ops; - drm_fb_helper_fill_info(info, &ufbdev->helper, sizes); - - DRM_DEBUG_KMS("allocated %dx%d vmal %p\n", - fb->width, fb->height, - ufbdev->ufb.shmem->vaddr); - - return ret; -out_gfree: - drm_gem_object_put_unlocked(&ufbdev->ufb.shmem->base); -out: - return ret; -} - -static const struct drm_fb_helper_funcs udl_fb_helper_funcs = { - .fb_probe = udlfb_create, -}; - -static void udl_fbdev_destroy(struct drm_device *dev, - struct udl_fbdev *ufbdev) -{ - drm_fb_helper_unregister_fbi(&ufbdev->helper); - drm_fb_helper_fini(&ufbdev->helper); - if (ufbdev->ufb.shmem) { - drm_framebuffer_unregister_private(&ufbdev->ufb.base); - drm_framebuffer_cleanup(&ufbdev->ufb.base); - drm_gem_object_put_unlocked(&ufbdev->ufb.shmem->base); - } -} - -int udl_fbdev_init(struct drm_device *dev) -{ - struct udl_device *udl = to_udl(dev); - int bpp_sel = fb_bpp; - struct udl_fbdev *ufbdev; - int ret; - - ufbdev = kzalloc(sizeof(struct udl_fbdev), GFP_KERNEL); - if (!ufbdev) - return -ENOMEM; - - udl->fbdev = ufbdev; - - drm_fb_helper_prepare(dev, &ufbdev->helper, &udl_fb_helper_funcs); - - ret = drm_fb_helper_init(dev, &ufbdev->helper, 1); - if (ret) - goto free; - - ret = drm_fb_helper_single_add_all_connectors(&ufbdev->helper); - if (ret) - goto fini; - - /* disable all the possible outputs/crtcs before entering KMS mode */ - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel); - if (ret) - goto fini; - - return 0; - -fini: - drm_fb_helper_fini(&ufbdev->helper); -free: - kfree(ufbdev); - return ret; -} - -void udl_fbdev_cleanup(struct drm_device *dev) -{ - struct udl_device *udl = to_udl(dev); - if (!udl->fbdev) - return; - - udl_fbdev_destroy(dev, udl->fbdev); - kfree(udl->fbdev); - udl->fbdev = NULL; -} - -void udl_fbdev_unplug(struct drm_device *dev) -{ - struct udl_device *udl = to_udl(dev); - struct udl_fbdev *ufbdev; - if (!udl->fbdev) - return; - - ufbdev = udl->fbdev; - drm_fb_helper_unlink_fbi(&ufbdev->helper); -} - struct drm_framebuffer * udl_fb_user_fb_create(struct drm_device *dev, struct drm_file *file, diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index 4e854e017390..9b091b5b063e 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -338,10 +338,6 @@ int udl_init(struct udl_device *udl) if (ret) goto err; - ret = udl_fbdev_init(dev); - if (ret) - goto err; - drm_kms_helper_poll_init(dev); return 0; @@ -367,6 +363,4 @@ void udl_fini(struct drm_device *dev) if (udl->urbs.count) udl_free_urb_list(dev); - - udl_fbdev_cleanup(dev); } diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index bc1ab6060dc6..6582c9d27a87 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -422,7 +422,6 @@ static int udl_crtc_init(struct drm_device *dev) static const struct drm_mode_config_funcs udl_mode_funcs = { .fb_create = udl_fb_user_fb_create, - .output_poll_changed = NULL, }; int udl_modeset_init(struct drm_device *dev) -- cgit From 6c44e30ae130b740441ac0c65d5fa12dd6586942 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 14 Nov 2019 15:10:21 +0100 Subject: drm/udl: Unmap buffer object after damage update Udl keeps a BO mapped for its entire lifetime if it has been used in a damage update at least once. The BO's free callback release the mapping before it frees the BO. Change this behaviour to unmap immediately after the damage update, so SHMEM's implementation of free can be used. Signed-off-by: Thomas Zimmermann Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20191114141025.32198-2-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_fb.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 8fe4d8cf3212..a9e6ec360b16 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -73,6 +73,7 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, struct urb *urb; int aligned_x; int log_bpp; + void *vaddr; BUG_ON(!is_power_of_2(fb->base.format->cpp[0])); log_bpp = __ffs(fb->base.format->cpp[0]); @@ -80,14 +81,10 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, if (!fb->active_16) return 0; - if (!fb->shmem->vaddr) { - void *vaddr; - - vaddr = drm_gem_shmem_vmap(&fb->shmem->base); - if (IS_ERR(vaddr)) { - DRM_ERROR("failed to vmap fb\n"); - return 0; - } + vaddr = drm_gem_shmem_vmap(&fb->shmem->base); + if (IS_ERR(vaddr)) { + DRM_ERROR("failed to vmap fb\n"); + return 0; } aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); @@ -96,22 +93,23 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, if ((width <= 0) || (x + width > fb->base.width) || - (y + height > fb->base.height)) - return -EINVAL; + (y + height > fb->base.height)) { + ret = -EINVAL; + goto err_drm_gem_shmem_vunmap; + } start_cycles = get_cycles(); urb = udl_get_urb(dev); if (!urb) - return 0; + goto out; cmd = urb->transfer_buffer; for (i = y; i < y + height ; i++) { const int line_offset = fb->base.pitches[0] * i; const int byte_offset = line_offset + (x << log_bpp); const int dev_byte_offset = (fb->base.width * i + x) << log_bpp; - if (udl_render_hline(dev, log_bpp, &urb, - (char *) fb->shmem->vaddr, + if (udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, &cmd, byte_offset, dev_byte_offset, width << log_bpp, &bytes_identical, &bytes_sent)) @@ -138,7 +136,14 @@ error: >> 10)), /* Kcycles */ &udl->cpu_kcycles_used); +out: + drm_gem_shmem_vunmap(&fb->shmem->base, vaddr); + return 0; + +err_drm_gem_shmem_vunmap: + drm_gem_shmem_vunmap(&fb->shmem->base, vaddr); + return ret; } static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, -- cgit From ba59b015a0145330e2bf7ab20d504bc624fd618a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 14 Nov 2019 15:10:23 +0100 Subject: drm/udl: Store active framebuffer in device structure The framebuffer's 'active_16' flag signals which framebuffer to flush to device memory. Moving the 'active_16' state from struct udl_framebuffer into struct udl_device prepares for using the generic GEM framebuffer. Signed-off-by: Thomas Zimmermann Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20191114141025.32198-4-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_drv.h | 5 ++++- drivers/gpu/drm/udl/udl_fb.c | 13 +++++++++++-- drivers/gpu/drm/udl/udl_main.c | 3 +++ drivers/gpu/drm/udl/udl_modeset.c | 18 +++++++----------- 4 files changed, 25 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index be585e3e572d..a0946b955739 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -53,6 +53,10 @@ struct udl_device { struct usb_device *udev; struct drm_crtc *crtc; + /* active framebuffer on the 16-bit channel */ + const struct drm_framebuffer *active_fb_16; + spinlock_t active_fb_16_lock; + struct mutex gem_lock; int sku_pixel_limit; @@ -73,7 +77,6 @@ struct udl_device { struct udl_framebuffer { struct drm_framebuffer base; struct drm_gem_shmem_object *shmem; - bool active_16; /* active on the 16-bit channel */ }; #define to_udl_fb(x) container_of(x, struct udl_framebuffer, base) diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index a9e6ec360b16..e9a4bbd5b195 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -78,8 +78,12 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, BUG_ON(!is_power_of_2(fb->base.format->cpp[0])); log_bpp = __ffs(fb->base.format->cpp[0]); - if (!fb->active_16) + spin_lock(&udl->active_fb_16_lock); + if (udl->active_fb_16 != &fb->base) { + spin_unlock(&udl->active_fb_16_lock); return 0; + } + spin_unlock(&udl->active_fb_16_lock); vaddr = drm_gem_shmem_vmap(&fb->shmem->base); if (IS_ERR(vaddr)) { @@ -153,14 +157,19 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, unsigned num_clips) { struct udl_framebuffer *ufb = to_udl_fb(fb); + struct udl_device *udl = fb->dev->dev_private; struct dma_buf_attachment *import_attach; int i; int ret = 0; drm_modeset_lock_all(fb->dev); - if (!ufb->active_16) + spin_lock(&udl->active_fb_16_lock); + if (udl->active_fb_16 != fb) { + spin_unlock(&udl->active_fb_16_lock); goto unlock; + } + spin_unlock(&udl->active_fb_16_lock); import_attach = ufb->shmem->base.import_attach; diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index 9b091b5b063e..a23218fc7d8e 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -317,6 +317,9 @@ int udl_init(struct udl_device *udl) DRM_DEBUG("\n"); + udl->active_fb_16 = NULL; + spin_lock_init(&udl->active_fb_16_lock); + mutex_init(&udl->gem_lock); if (!udl_parse_vendor_descriptor(dev, udl->udev)) { diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 6582c9d27a87..44a741f463c9 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -332,11 +332,9 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc, wrptr = udl_dummy_render(wrptr); - if (old_fb) { - struct udl_framebuffer *uold_fb = to_udl_fb(old_fb); - uold_fb->active_16 = false; - } - ufb->active_16 = true; + spin_lock(&udl->active_fb_16_lock); + udl->active_fb_16 = &ufb->base; + spin_unlock(&udl->active_fb_16_lock); udl->mode_buf_len = wrptr - buf; /* damage all of it */ @@ -364,13 +362,11 @@ static int udl_crtc_page_flip(struct drm_crtc *crtc, { struct udl_framebuffer *ufb = to_udl_fb(fb); struct drm_device *dev = crtc->dev; + struct udl_device *udl = dev->dev_private; - struct drm_framebuffer *old_fb = crtc->primary->fb; - if (old_fb) { - struct udl_framebuffer *uold_fb = to_udl_fb(old_fb); - uold_fb->active_16 = false; - } - ufb->active_16 = true; + spin_lock(&udl->active_fb_16_lock); + udl->active_fb_16 = fb; + spin_unlock(&udl->active_fb_16_lock); udl_handle_damage(ufb, 0, 0, fb->width, fb->height); -- cgit From 8344603534e17f9926253a65088f59b787222bc5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 14 Nov 2019 15:10:24 +0100 Subject: drm/udl: Call udl_handle_damage() with DRM framebuffer Simplifying the udl code before replacing struct udl_framebuffer. Signed-off-by: Thomas Zimmermann Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20191114141025.32198-5-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_drv.h | 2 +- drivers/gpu/drm/udl/udl_fb.c | 35 ++++++++++++++++++----------------- drivers/gpu/drm/udl/udl_modeset.c | 15 +++++++-------- 3 files changed, 26 insertions(+), 26 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index a0946b955739..c5e3160392cb 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -110,7 +110,7 @@ int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, struct drm_gem_object *udl_driver_gem_create_object(struct drm_device *dev, size_t size); -int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, +int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, int width, int height); int udl_drop_usb(struct drm_device *dev); diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index e9a4bbd5b195..ad7bf165b59b 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -60,10 +60,10 @@ static uint16_t rgb16(uint32_t col) } #endif -int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, +int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, int width, int height) { - struct drm_device *dev = fb->base.dev; + struct drm_device *dev = fb->dev; struct udl_device *udl = to_udl(dev); int i, ret; char *cmd; @@ -75,17 +75,19 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, int log_bpp; void *vaddr; - BUG_ON(!is_power_of_2(fb->base.format->cpp[0])); - log_bpp = __ffs(fb->base.format->cpp[0]); + if (WARN_ON(!is_power_of_2(fb->format->cpp[0]))) + return -EINVAL; + + log_bpp = __ffs(fb->format->cpp[0]); spin_lock(&udl->active_fb_16_lock); - if (udl->active_fb_16 != &fb->base) { + if (udl->active_fb_16 != fb) { spin_unlock(&udl->active_fb_16_lock); return 0; } spin_unlock(&udl->active_fb_16_lock); - vaddr = drm_gem_shmem_vmap(&fb->shmem->base); + vaddr = drm_gem_shmem_vmap(fb->obj[0]); if (IS_ERR(vaddr)) { DRM_ERROR("failed to vmap fb\n"); return 0; @@ -96,8 +98,8 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, x = aligned_x; if ((width <= 0) || - (x + width > fb->base.width) || - (y + height > fb->base.height)) { + (x + width > fb->width) || + (y + height > fb->height)) { ret = -EINVAL; goto err_drm_gem_shmem_vunmap; } @@ -110,9 +112,9 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, cmd = urb->transfer_buffer; for (i = y; i < y + height ; i++) { - const int line_offset = fb->base.pitches[0] * i; + const int line_offset = fb->pitches[0] * i; const int byte_offset = line_offset + (x << log_bpp); - const int dev_byte_offset = (fb->base.width * i + x) << log_bpp; + const int dev_byte_offset = (fb->width * i + x) << log_bpp; if (udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, &cmd, byte_offset, dev_byte_offset, width << log_bpp, @@ -141,12 +143,12 @@ error: &udl->cpu_kcycles_used); out: - drm_gem_shmem_vunmap(&fb->shmem->base, vaddr); + drm_gem_shmem_vunmap(fb->obj[0], vaddr); return 0; err_drm_gem_shmem_vunmap: - drm_gem_shmem_vunmap(&fb->shmem->base, vaddr); + drm_gem_shmem_vunmap(fb->obj[0], vaddr); return ret; } @@ -156,7 +158,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, struct drm_clip_rect *clips, unsigned num_clips) { - struct udl_framebuffer *ufb = to_udl_fb(fb); struct udl_device *udl = fb->dev->dev_private; struct dma_buf_attachment *import_attach; int i; @@ -171,7 +172,7 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, } spin_unlock(&udl->active_fb_16_lock); - import_attach = ufb->shmem->base.import_attach; + import_attach = fb->obj[0]->import_attach; if (import_attach) { ret = dma_buf_begin_cpu_access(import_attach->dmabuf, @@ -181,9 +182,9 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, } for (i = 0; i < num_clips; i++) { - ret = udl_handle_damage(ufb, clips[i].x1, clips[i].y1, - clips[i].x2 - clips[i].x1, - clips[i].y2 - clips[i].y1); + ret = udl_handle_damage(fb, clips[i].x1, clips[i].y1, + clips[i].x2 - clips[i].x1, + clips[i].y2 - clips[i].y1); if (ret) break; } diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 44a741f463c9..91af25caed64 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -301,7 +301,7 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; - struct udl_framebuffer *ufb = to_udl_fb(crtc->primary->fb); + struct drm_framebuffer *fb = crtc->primary->fb; struct udl_device *udl = dev->dev_private; char *buf; char *wrptr; @@ -333,12 +333,12 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc, wrptr = udl_dummy_render(wrptr); spin_lock(&udl->active_fb_16_lock); - udl->active_fb_16 = &ufb->base; + udl->active_fb_16 = fb; spin_unlock(&udl->active_fb_16_lock); udl->mode_buf_len = wrptr - buf; /* damage all of it */ - udl_handle_damage(ufb, 0, 0, ufb->base.width, ufb->base.height); + udl_handle_damage(fb, 0, 0, fb->width, fb->height); return 0; } @@ -360,7 +360,6 @@ static int udl_crtc_page_flip(struct drm_crtc *crtc, uint32_t page_flip_flags, struct drm_modeset_acquire_ctx *ctx) { - struct udl_framebuffer *ufb = to_udl_fb(fb); struct drm_device *dev = crtc->dev; struct udl_device *udl = dev->dev_private; @@ -368,7 +367,7 @@ static int udl_crtc_page_flip(struct drm_crtc *crtc, udl->active_fb_16 = fb; spin_unlock(&udl->active_fb_16_lock); - udl_handle_damage(ufb, 0, 0, fb->width, fb->height); + udl_handle_damage(fb, 0, 0, fb->width, fb->height); spin_lock_irq(&dev->event_lock); if (event) @@ -448,13 +447,13 @@ int udl_modeset_init(struct drm_device *dev) void udl_modeset_restore(struct drm_device *dev) { struct udl_device *udl = dev->dev_private; - struct udl_framebuffer *ufb; + struct drm_framebuffer *fb; if (!udl->crtc || !udl->crtc->primary->fb) return; udl_crtc_commit(udl->crtc); - ufb = to_udl_fb(udl->crtc->primary->fb); - udl_handle_damage(ufb, 0, 0, ufb->base.width, ufb->base.height); + fb = udl->crtc->primary->fb; + udl_handle_damage(fb, 0, 0, fb->width, fb->height); } void udl_modeset_cleanup(struct drm_device *dev) -- cgit From 8ed447744bec60b05acf452af889f56934275c99 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 14 Nov 2019 15:10:25 +0100 Subject: drm/udl: Replace struct udl_framebuffer with generic implementation The udl driver's struct udl_framebuffer stores a DRM framebuffer with an associated GEM object. This functionality is also provided by generic code. Switch udl over. Signed-off-by: Thomas Zimmermann Acked-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20191114141025.32198-6-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_drv.h | 7 ----- drivers/gpu/drm/udl/udl_fb.c | 62 +++++-------------------------------------- 2 files changed, 6 insertions(+), 63 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index c5e3160392cb..66cbe04f832a 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -74,13 +74,6 @@ struct udl_device { #define to_udl(x) container_of(x, struct udl_device, drm) -struct udl_framebuffer { - struct drm_framebuffer base; - struct drm_gem_shmem_object *shmem; -}; - -#define to_udl_fb(x) container_of(x, struct udl_framebuffer, base) - /* modeset */ int udl_modeset_init(struct drm_device *dev); void udl_modeset_restore(struct drm_device *dev); diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index ad7bf165b59b..c1996ac73a1f 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -199,68 +200,17 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, return ret; } -static void udl_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct udl_framebuffer *ufb = to_udl_fb(fb); - - if (ufb->shmem) - drm_gem_object_put_unlocked(&ufb->shmem->base); - - drm_framebuffer_cleanup(fb); - kfree(ufb); -} - static const struct drm_framebuffer_funcs udlfb_funcs = { - .destroy = udl_user_framebuffer_destroy, - .dirty = udl_user_framebuffer_dirty, + .destroy = drm_gem_fb_destroy, + .create_handle = drm_gem_fb_create_handle, + .dirty = udl_user_framebuffer_dirty, }; - -static int -udl_framebuffer_init(struct drm_device *dev, - struct udl_framebuffer *ufb, - const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_shmem_object *shmem) -{ - int ret; - - ufb->shmem = shmem; - drm_helper_mode_fill_fb_struct(dev, &ufb->base, mode_cmd); - ret = drm_framebuffer_init(dev, &ufb->base, &udlfb_funcs); - return ret; -} - struct drm_framebuffer * udl_fb_user_fb_create(struct drm_device *dev, struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd) { - struct drm_gem_object *obj; - struct udl_framebuffer *ufb; - int ret; - uint32_t size; - - obj = drm_gem_object_lookup(file, mode_cmd->handles[0]); - if (obj == NULL) - return ERR_PTR(-ENOENT); - - size = mode_cmd->pitches[0] * mode_cmd->height; - size = ALIGN(size, PAGE_SIZE); - - if (size > obj->size) { - DRM_ERROR("object size not sufficient for fb %d %zu %d %d\n", size, obj->size, mode_cmd->pitches[0], mode_cmd->height); - return ERR_PTR(-ENOMEM); - } - - ufb = kzalloc(sizeof(*ufb), GFP_KERNEL); - if (ufb == NULL) - return ERR_PTR(-ENOMEM); - - ret = udl_framebuffer_init(dev, ufb, mode_cmd, - to_drm_gem_shmem_obj(obj)); - if (ret) { - kfree(ufb); - return ERR_PTR(-EINVAL); - } - return &ufb->base; + return drm_gem_fb_create_with_funcs(dev, file, mode_cmd, + &udlfb_funcs); } -- cgit From 3f1939b531cf99fc8766b6b24059c58eef3d2e7b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 6 Dec 2019 09:59:48 +0100 Subject: drm/udl: Remove unused statistics counters None of the udl driver's statistics counters is used anywhere. Remove them. Signed-off-by: Thomas Zimmermann Reviewed-by: Emil Velikov Acked-by: Gerd Hoffmann Link: https://patchwork.freedesktop.org/patch/msgid/20191206085954.9697-2-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_drv.h | 4 ---- drivers/gpu/drm/udl/udl_fb.c | 14 +------------- 2 files changed, 1 insertion(+), 17 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 66cbe04f832a..42426407c318 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -66,10 +66,6 @@ struct udl_device { char mode_buf[1024]; uint32_t mode_buf_len; - atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ - atomic_t bytes_identical; /* saved effort with backbuffer comparison */ - atomic_t bytes_sent; /* to usb, after compression including overhead */ - atomic_t cpu_kcycles_used; /* transpired during pixel processing */ }; #define to_udl(x) container_of(x, struct udl_device, drm) diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index c1996ac73a1f..bc033779f6e4 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -68,7 +68,6 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, struct udl_device *udl = to_udl(dev); int i, ret; char *cmd; - cycles_t start_cycles, end_cycles; int bytes_sent = 0; int bytes_identical = 0; struct urb *urb; @@ -105,8 +104,6 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, goto err_drm_gem_shmem_vunmap; } - start_cycles = get_cycles(); - urb = udl_get_urb(dev); if (!urb) goto out; @@ -120,7 +117,7 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, &cmd, byte_offset, dev_byte_offset, width << log_bpp, &bytes_identical, &bytes_sent)) - goto error; + goto out; } if (cmd > (char *) urb->transfer_buffer) { @@ -134,15 +131,6 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, } else udl_urb_completion(urb); -error: - atomic_add(bytes_sent, &udl->bytes_sent); - atomic_add(bytes_identical, &udl->bytes_identical); - atomic_add((width * height) << log_bpp, &udl->bytes_rendered); - end_cycles = get_cycles(); - atomic_add(((unsigned int) ((end_cycles - start_cycles) - >> 10)), /* Kcycles */ - &udl->cpu_kcycles_used); - out: drm_gem_shmem_vunmap(fb->obj[0], vaddr); -- cgit From d15e35dafb1e8f246e86963c22f1dfca01851ba8 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 6 Dec 2019 09:59:49 +0100 Subject: drm/udl: Don't track number of identical and sent pixels per line A call to udl_render_hline() returns the number of identical and sent pixels. None of these values is used. Remove the parameters. Signed-off-by: Thomas Zimmermann Reviewed-by: Emil Velikov Acked-by: Gerd Hoffmann Link: https://patchwork.freedesktop.org/patch/msgid/20191206085954.9697-3-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_drv.h | 3 +-- drivers/gpu/drm/udl/udl_fb.c | 6 +----- drivers/gpu/drm/udl/udl_transfer.c | 4 +--- 3 files changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 42426407c318..d732c9e47812 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -93,8 +93,7 @@ udl_fb_user_fb_create(struct drm_device *dev, int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, - u32 byte_offset, u32 device_byte_offset, u32 byte_width, - int *ident_ptr, int *sent_ptr); + u32 byte_offset, u32 device_byte_offset, u32 byte_width); struct drm_gem_object *udl_driver_gem_create_object(struct drm_device *dev, size_t size); diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index bc033779f6e4..ed6d9476b25b 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -68,8 +68,6 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, struct udl_device *udl = to_udl(dev); int i, ret; char *cmd; - int bytes_sent = 0; - int bytes_identical = 0; struct urb *urb; int aligned_x; int log_bpp; @@ -115,8 +113,7 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, const int dev_byte_offset = (fb->width * i + x) << log_bpp; if (udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, &cmd, byte_offset, dev_byte_offset, - width << log_bpp, - &bytes_identical, &bytes_sent)) + width << log_bpp)) goto out; } @@ -127,7 +124,6 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, *cmd++ = 0xAF; len = cmd - (char *) urb->transfer_buffer; ret = udl_submit_urb(dev, urb, len); - bytes_sent += len; } else udl_urb_completion(urb); diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c index 1973a4c1e358..686358d1f669 100644 --- a/drivers/gpu/drm/udl/udl_transfer.c +++ b/drivers/gpu/drm/udl/udl_transfer.c @@ -212,8 +212,7 @@ static void udl_compress_hline16( int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, u32 byte_offset, u32 device_byte_offset, - u32 byte_width, - int *ident_ptr, int *sent_ptr) + u32 byte_width) { const u8 *line_start, *line_end, *next_pixel; u32 base16 = 0 + (device_byte_offset >> log_bpp) * 2; @@ -237,7 +236,6 @@ int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, int len = cmd - (u8 *) urb->transfer_buffer; if (udl_submit_urb(dev, urb, len)) return 1; /* lost pixels is set */ - *sent_ptr += len; urb = udl_get_urb(dev); if (!urb) return 1; /* lost_pixels is set */ -- cgit From 2d2bebb8332317551ef6fe168396b09337af67df Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 6 Dec 2019 09:59:50 +0100 Subject: drm/udl: Vmap framebuffer after all tests succeeded in damage handling We now do the fast tests before the potentially expensive vmap operation. Signed-off-by: Thomas Zimmermann Reviewed-by: Emil Velikov Acked-by: Gerd Hoffmann Link: https://patchwork.freedesktop.org/patch/msgid/20191206085954.9697-4-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_fb.c | 19 +++++++------------ drivers/gpu/drm/udl/udl_transfer.c | 1 - 2 files changed, 7 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index ed6d9476b25b..dd7ba7f63214 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -85,12 +85,6 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, } spin_unlock(&udl->active_fb_16_lock); - vaddr = drm_gem_shmem_vmap(fb->obj[0]); - if (IS_ERR(vaddr)) { - DRM_ERROR("failed to vmap fb\n"); - return 0; - } - aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long)); x = aligned_x; @@ -98,8 +92,13 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, if ((width <= 0) || (x + width > fb->width) || (y + height > fb->height)) { - ret = -EINVAL; - goto err_drm_gem_shmem_vunmap; + return -EINVAL; + } + + vaddr = drm_gem_shmem_vmap(fb->obj[0]); + if (IS_ERR(vaddr)) { + DRM_ERROR("failed to vmap fb\n"); + return 0; } urb = udl_get_urb(dev); @@ -131,10 +130,6 @@ out: drm_gem_shmem_vunmap(fb->obj[0], vaddr); return 0; - -err_drm_gem_shmem_vunmap: - drm_gem_shmem_vunmap(fb->obj[0], vaddr); - return ret; } static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c index 686358d1f669..5fae48723286 100644 --- a/drivers/gpu/drm/udl/udl_transfer.c +++ b/drivers/gpu/drm/udl/udl_transfer.c @@ -249,4 +249,3 @@ int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, return 0; } - -- cgit From ffc90486e320ba68f63de39fe04d757ce0cf49e5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 6 Dec 2019 09:59:51 +0100 Subject: drm/udl: Move clip-rectangle code out of udl_handle_damage() Computing the clip rectable in a separate helper function makes the damage-handler code more readable. Signed-off-by: Thomas Zimmermann Reviewed-by: Emil Velikov Acked-by: Gerd Hoffmann Link: https://patchwork.freedesktop.org/patch/msgid/20191206085954.9697-5-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_fb.c | 48 +++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 16 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index dd7ba7f63214..cc2a09a995b8 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -20,9 +20,6 @@ #include "udl_drv.h" -#define DL_ALIGN_UP(x, a) ALIGN(x, a) -#define DL_ALIGN_DOWN(x, a) ALIGN_DOWN(x, a) - /** Read the red component (0..255) of a 32 bpp colour. */ #define DLO_RGB_GETRED(col) (uint8_t)((col) & 0xFF) @@ -61,6 +58,28 @@ static uint16_t rgb16(uint32_t col) } #endif +static int udl_aligned_damage_clip(struct drm_rect *clip, int x, int y, + int width, int height) +{ + int x1, x2; + + if (WARN_ON_ONCE(x < 0) || + WARN_ON_ONCE(y < 0) || + WARN_ON_ONCE(width < 0) || + WARN_ON_ONCE(height < 0)) + return -EINVAL; + + x1 = ALIGN_DOWN(x, sizeof(unsigned long)); + x2 = ALIGN(width + (x - x1), sizeof(unsigned long)) + x1; + + clip->x1 = x1; + clip->y1 = y; + clip->x2 = x2; + clip->y2 = y + height; + + return 0; +} + int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, int width, int height) { @@ -69,7 +88,7 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, int i, ret; char *cmd; struct urb *urb; - int aligned_x; + struct drm_rect clip; int log_bpp; void *vaddr; @@ -85,15 +104,11 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, } spin_unlock(&udl->active_fb_16_lock); - aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); - width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long)); - x = aligned_x; - - if ((width <= 0) || - (x + width > fb->width) || - (y + height > fb->height)) { + ret = udl_aligned_damage_clip(&clip, x, y, width, height); + if (ret) + return ret; + else if ((clip.x2 > fb->width) || (clip.y2 > fb->height)) return -EINVAL; - } vaddr = drm_gem_shmem_vmap(fb->obj[0]); if (IS_ERR(vaddr)) { @@ -106,13 +121,14 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, goto out; cmd = urb->transfer_buffer; - for (i = y; i < y + height ; i++) { + for (i = clip.y1; i < clip.y2; i++) { const int line_offset = fb->pitches[0] * i; - const int byte_offset = line_offset + (x << log_bpp); - const int dev_byte_offset = (fb->width * i + x) << log_bpp; + const int byte_offset = line_offset + (clip.x1 << log_bpp); + const int dev_byte_offset = (fb->width * i + clip.x1) << log_bpp; + const int byte_width = (clip.x2 - clip.x1) << log_bpp; if (udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, &cmd, byte_offset, dev_byte_offset, - width << log_bpp)) + byte_width)) goto out; } -- cgit From cd45e30a7099e5fcbc25fcfa035fa604255afdee Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 6 Dec 2019 09:59:52 +0100 Subject: drm/udl: Move log-cpp code out of udl_damage_handler() Computing the cpp value's logarithm in a separate helper function makes the damage-handler code more readable. Signed-off-by: Thomas Zimmermann Reviewed-by: Emil Velikov Acked-by: Gerd Hoffmann Link: https://patchwork.freedesktop.org/patch/msgid/20191206085954.9697-6-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_fb.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index cc2a09a995b8..482786eeea6c 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -58,6 +58,13 @@ static uint16_t rgb16(uint32_t col) } #endif +static long udl_log_cpp(unsigned int cpp) +{ + if (WARN_ON(!is_power_of_2(cpp))) + return -EINVAL; + return __ffs(cpp); +} + static int udl_aligned_damage_clip(struct drm_rect *clip, int x, int y, int width, int height) { @@ -92,11 +99,6 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, int log_bpp; void *vaddr; - if (WARN_ON(!is_power_of_2(fb->format->cpp[0]))) - return -EINVAL; - - log_bpp = __ffs(fb->format->cpp[0]); - spin_lock(&udl->active_fb_16_lock); if (udl->active_fb_16 != fb) { spin_unlock(&udl->active_fb_16_lock); @@ -104,6 +106,11 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, } spin_unlock(&udl->active_fb_16_lock); + ret = udl_log_cpp(fb->format->cpp[0]); + if (ret < 0) + return ret; + log_bpp = ret; + ret = udl_aligned_damage_clip(&clip, x, y, width, height); if (ret) return ret; -- cgit From 798ce3fe1c3a9819f46a5fb930b24a19ccf59c89 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 6 Dec 2019 09:59:53 +0100 Subject: drm/udl: Begin/end access to imported buffers in damage-handler The damage-handler code now invokes dma_buf_{begin,end}_access() for imported buffers. These calls were missing from the page-flip and modesetting code paths. The patch also fixes an bug in the original where an error code was overwritten by the result of dma_buf_end_cpu_access(). v2: * only return an error code from dma_buf_end_cpu_access() if no other error code has been set before Signed-off-by: Thomas Zimmermann Reviewed-by: Emil Velikov Acked-by: Gerd Hoffmann Link: https://patchwork.freedesktop.org/patch/msgid/20191206085954.9697-7-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_fb.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 482786eeea6c..0f83a6fc1056 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -92,7 +92,8 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, { struct drm_device *dev = fb->dev; struct udl_device *udl = to_udl(dev); - int i, ret; + struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach; + int i, ret, tmp_ret; char *cmd; struct urb *urb; struct drm_rect clip; @@ -117,15 +118,22 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, else if ((clip.x2 > fb->width) || (clip.y2 > fb->height)) return -EINVAL; + if (import_attach) { + ret = dma_buf_begin_cpu_access(import_attach->dmabuf, + DMA_FROM_DEVICE); + if (ret) + return ret; + } + vaddr = drm_gem_shmem_vmap(fb->obj[0]); if (IS_ERR(vaddr)) { DRM_ERROR("failed to vmap fb\n"); - return 0; + goto out_dma_buf_end_cpu_access; } urb = udl_get_urb(dev); if (!urb) - goto out; + goto out_drm_gem_shmem_vunmap; cmd = urb->transfer_buffer; for (i = clip.y1; i < clip.y2; i++) { @@ -136,7 +144,7 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, if (udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, &cmd, byte_offset, dev_byte_offset, byte_width)) - goto out; + goto out_drm_gem_shmem_vunmap; } if (cmd > (char *) urb->transfer_buffer) { @@ -149,10 +157,19 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, } else udl_urb_completion(urb); -out: + ret = 0; + +out_drm_gem_shmem_vunmap: drm_gem_shmem_vunmap(fb->obj[0], vaddr); +out_dma_buf_end_cpu_access: + if (import_attach) { + tmp_ret = dma_buf_end_cpu_access(import_attach->dmabuf, + DMA_FROM_DEVICE); + if (tmp_ret && !ret) + ret = tmp_ret; /* only update ret if not set yet */ + } - return 0; + return ret; } static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, @@ -162,7 +179,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, unsigned num_clips) { struct udl_device *udl = fb->dev->dev_private; - struct dma_buf_attachment *import_attach; int i; int ret = 0; @@ -175,15 +191,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, } spin_unlock(&udl->active_fb_16_lock); - import_attach = fb->obj[0]->import_attach; - - if (import_attach) { - ret = dma_buf_begin_cpu_access(import_attach->dmabuf, - DMA_FROM_DEVICE); - if (ret) - goto unlock; - } - for (i = 0; i < num_clips; i++) { ret = udl_handle_damage(fb, clips[i].x1, clips[i].y1, clips[i].x2 - clips[i].x1, @@ -192,10 +199,6 @@ static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, break; } - if (import_attach) - ret = dma_buf_end_cpu_access(import_attach->dmabuf, - DMA_FROM_DEVICE); - unlock: drm_modeset_unlock_all(fb->dev); -- cgit From 1ca3fd96f958291daa50693b4a50cd3df4b411f1 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 6 Dec 2019 09:59:54 +0100 Subject: drm/udl: Remove field lost_pixels from struct udl_device The field lost_pixels in struct udl_device was supposed to signal an error during USB transfers of the framebuffer data. The driver would have to schedule a re-transfer at a later point. This code was never implemented. Remove lost_pixels and return regular error codes instead. Signed-off-by: Thomas Zimmermann Reviewed-by: Emil Velikov Acked-by: Gerd Hoffmann Link: https://patchwork.freedesktop.org/patch/msgid/20191206085954.9697-8-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_drv.h | 1 - drivers/gpu/drm/udl/udl_fb.c | 7 ++++--- drivers/gpu/drm/udl/udl_main.c | 3 --- drivers/gpu/drm/udl/udl_transfer.c | 7 ++++--- 4 files changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index d732c9e47812..4de00bddef39 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -62,7 +62,6 @@ struct udl_device { int sku_pixel_limit; struct urb_list urbs; - atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ char mode_buf[1024]; uint32_t mode_buf_len; diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 0f83a6fc1056..32a4551447b5 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -141,9 +141,10 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, const int byte_offset = line_offset + (clip.x1 << log_bpp); const int dev_byte_offset = (fb->width * i + clip.x1) << log_bpp; const int byte_width = (clip.x2 - clip.x1) << log_bpp; - if (udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, - &cmd, byte_offset, dev_byte_offset, - byte_width)) + ret = udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, + &cmd, byte_offset, dev_byte_offset, + byte_width); + if (ret) goto out_drm_gem_shmem_vunmap; } diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index a23218fc7d8e..ff3e98666e8c 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -140,7 +140,6 @@ void udl_urb_completion(struct urb *urb) urb->status == -ESHUTDOWN)) { DRM_ERROR("%s - nonzero write bulk status received: %d\n", __func__, urb->status); - atomic_set(&udl->lost_pixels, 1); } } @@ -271,7 +270,6 @@ struct urb *udl_get_urb(struct drm_device *dev) /* Wait for an in-flight buffer to complete and get re-queued */ ret = down_timeout(&udl->urbs.limit_sem, GET_URB_TIMEOUT); if (ret) { - atomic_set(&udl->lost_pixels, 1); DRM_INFO("wait for urb interrupted: %x available: %d\n", ret, udl->urbs.available); goto error; @@ -304,7 +302,6 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len) ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret) { udl_urb_completion(urb); /* because no one else will */ - atomic_set(&udl->lost_pixels, 1); DRM_ERROR("usb_submit_urb error %x\n", ret); } return ret; diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c index 5fae48723286..971927669d6b 100644 --- a/drivers/gpu/drm/udl/udl_transfer.c +++ b/drivers/gpu/drm/udl/udl_transfer.c @@ -234,11 +234,12 @@ int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, if (cmd >= cmd_end) { int len = cmd - (u8 *) urb->transfer_buffer; - if (udl_submit_urb(dev, urb, len)) - return 1; /* lost pixels is set */ + int ret = udl_submit_urb(dev, urb, len); + if (ret) + return ret; urb = udl_get_urb(dev); if (!urb) - return 1; /* lost_pixels is set */ + return -EAGAIN; *urb_ptr = urb; cmd = urb->transfer_buffer; cmd_end = &cmd[urb->transfer_buffer_length]; -- cgit From 230b8b04d74958ebc5892510475e510b1284f14f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 10 Dec 2019 09:49:02 +0100 Subject: drm/udl: Convert to drm_atomic_helper_dirtyfb() The infrastruture for atomic modesetting allows us to use the generic code for dirty-FB and damage handling. Switch over udl and remove the driver's implementation. The simple-pipe's update function now picks up the primary plane's damage and updates a minimal region of the screen. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Reviewed-by: Emil Velikov Link: https://patchwork.freedesktop.org/patch/msgid/20191210084905.5570-7-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_drv.h | 5 ---- drivers/gpu/drm/udl/udl_fb.c | 52 --------------------------------------- drivers/gpu/drm/udl/udl_modeset.c | 11 ++++++--- 3 files changed, 8 insertions(+), 60 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 89c0539c758e..1ade917cd8d7 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -83,11 +83,6 @@ void udl_urb_completion(struct urb *urb); int udl_init(struct udl_device *udl); void udl_fini(struct drm_device *dev); -struct drm_framebuffer * -udl_fb_user_fb_create(struct drm_device *dev, - struct drm_file *file, - const struct drm_mode_fb_cmd2 *mode_cmd); - int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, u32 byte_offset, u32 device_byte_offset, u32 byte_width); diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 32a4551447b5..98cc2ab3a916 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -11,12 +11,8 @@ #include #include -#include -#include #include -#include #include -#include #include "udl_drv.h" @@ -172,51 +168,3 @@ out_dma_buf_end_cpu_access: return ret; } - -static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, - struct drm_file *file, - unsigned flags, unsigned color, - struct drm_clip_rect *clips, - unsigned num_clips) -{ - struct udl_device *udl = fb->dev->dev_private; - int i; - int ret = 0; - - drm_modeset_lock_all(fb->dev); - - spin_lock(&udl->active_fb_16_lock); - if (udl->active_fb_16 != fb) { - spin_unlock(&udl->active_fb_16_lock); - goto unlock; - } - spin_unlock(&udl->active_fb_16_lock); - - for (i = 0; i < num_clips; i++) { - ret = udl_handle_damage(fb, clips[i].x1, clips[i].y1, - clips[i].x2 - clips[i].x1, - clips[i].y2 - clips[i].y1); - if (ret) - break; - } - - unlock: - drm_modeset_unlock_all(fb->dev); - - return ret; -} - -static const struct drm_framebuffer_funcs udlfb_funcs = { - .destroy = drm_gem_fb_destroy, - .create_handle = drm_gem_fb_create_handle, - .dirty = udl_user_framebuffer_dirty, -}; - -struct drm_framebuffer * -udl_fb_user_fb_create(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, - &udlfb_funcs); -} diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 067f626bb65b..c02e383afabe 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -332,7 +333,9 @@ udl_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, { struct drm_device *dev = pipe->crtc.dev; struct udl_device *udl = dev->dev_private; - struct drm_framebuffer *fb = pipe->plane.state->fb; + struct drm_plane_state *state = pipe->plane.state; + struct drm_framebuffer *fb = state->fb; + struct drm_rect rect; spin_lock(&udl->active_fb_16_lock); udl->active_fb_16 = fb; @@ -341,7 +344,9 @@ udl_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, if (!fb) return; - udl_handle_damage(fb, 0, 0, fb->width, fb->height); + if (drm_atomic_helper_damage_merged(old_plane_state, state, &rect)) + udl_handle_damage(fb, rect.x1, rect.y1, rect.x2 - rect.x1, + rect.y2 - rect.y1); } static const @@ -359,7 +364,7 @@ struct drm_simple_display_pipe_funcs udl_simple_display_pipe_funcs = { */ static const struct drm_mode_config_funcs udl_mode_funcs = { - .fb_create = udl_fb_user_fb_create, + .fb_create = drm_gem_fb_create_with_dirty, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; -- cgit From eb3deeceaa5d066a5819fb45876de4d262a8f210 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 10 Dec 2019 09:49:03 +0100 Subject: drm/udl: Remove struct udl_device.active_fb_16 The udl driver stores the currently active framebuffer to know from where to accept damage updates. With the conversion to plane-state damage handling, this is not necessary any longer. The currently active framebuffer and damaged area are always stored in the plane state. Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Reviewed-by: Emil Velikov Link: https://patchwork.freedesktop.org/patch/msgid/20191210084905.5570-8-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_drv.h | 4 ---- drivers/gpu/drm/udl/udl_fb.c | 8 -------- drivers/gpu/drm/udl/udl_main.c | 3 --- drivers/gpu/drm/udl/udl_modeset.c | 9 --------- 4 files changed, 24 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 1ade917cd8d7..dd58b9a51669 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -54,10 +54,6 @@ struct udl_device { struct drm_simple_display_pipe display_pipe; - /* active framebuffer on the 16-bit channel */ - const struct drm_framebuffer *active_fb_16; - spinlock_t active_fb_16_lock; - struct mutex gem_lock; int sku_pixel_limit; diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 98cc2ab3a916..397c62142978 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -87,7 +87,6 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, int width, int height) { struct drm_device *dev = fb->dev; - struct udl_device *udl = to_udl(dev); struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach; int i, ret, tmp_ret; char *cmd; @@ -96,13 +95,6 @@ int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, int log_bpp; void *vaddr; - spin_lock(&udl->active_fb_16_lock); - if (udl->active_fb_16 != fb) { - spin_unlock(&udl->active_fb_16_lock); - return 0; - } - spin_unlock(&udl->active_fb_16_lock); - ret = udl_log_cpp(fb->format->cpp[0]); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index ff3e98666e8c..538718919916 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -314,9 +314,6 @@ int udl_init(struct udl_device *udl) DRM_DEBUG("\n"); - udl->active_fb_16 = NULL; - spin_lock_init(&udl->active_fb_16_lock); - mutex_init(&udl->gem_lock); if (!udl_parse_vendor_descriptor(dev, udl->udev)) { diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index c02e383afabe..35fa7b11c681 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -284,9 +284,6 @@ udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe, wrptr = udl_dummy_render(wrptr); - spin_lock(&udl->active_fb_16_lock); - udl->active_fb_16 = fb; - spin_unlock(&udl->active_fb_16_lock); udl->mode_buf_len = wrptr - buf; udl_handle_damage(fb, 0, 0, fb->width, fb->height); @@ -331,16 +328,10 @@ static void udl_simple_display_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_plane_state) { - struct drm_device *dev = pipe->crtc.dev; - struct udl_device *udl = dev->dev_private; struct drm_plane_state *state = pipe->plane.state; struct drm_framebuffer *fb = state->fb; struct drm_rect rect; - spin_lock(&udl->active_fb_16_lock); - udl->active_fb_16 = fb; - spin_unlock(&udl->active_fb_16_lock); - if (!fb) return; -- cgit From a8109f5bc4bd6dc037bd15651c6c7f1ac00ed235 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 10 Dec 2019 09:49:04 +0100 Subject: drm/udl: Move udl_handle_damage() into udl_modeset.c The only caller of udl_handle_damage() in the plane-update function in udl_modeset.c. Move udl_handle_damage() there. v2: * remove udl_fb.c in a separate patch Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Reviewed-by: Emil Velikov Link: https://patchwork.freedesktop.org/patch/msgid/20191210084905.5570-9-tzimmermann@suse.de --- drivers/gpu/drm/udl/udl_drv.h | 3 - drivers/gpu/drm/udl/udl_fb.c | 111 ------------------------------------- drivers/gpu/drm/udl/udl_modeset.c | 112 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 114 deletions(-) (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index dd58b9a51669..e67227c44cc4 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -86,9 +86,6 @@ int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, struct drm_gem_object *udl_driver_gem_create_object(struct drm_device *dev, size_t size); -int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, - int width, int height); - int udl_drop_usb(struct drm_device *dev); #define CMD_WRITE_RAW8 "\xAF\x60" /**< 8 bit raw write command. */ diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 397c62142978..84cff9d9edbe 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -9,10 +9,6 @@ */ #include -#include - -#include -#include #include "udl_drv.h" @@ -53,110 +49,3 @@ static uint16_t rgb16(uint32_t col) return (DLO_RG16(red, grn) << 8) + DLO_GB16(grn, blu); } #endif - -static long udl_log_cpp(unsigned int cpp) -{ - if (WARN_ON(!is_power_of_2(cpp))) - return -EINVAL; - return __ffs(cpp); -} - -static int udl_aligned_damage_clip(struct drm_rect *clip, int x, int y, - int width, int height) -{ - int x1, x2; - - if (WARN_ON_ONCE(x < 0) || - WARN_ON_ONCE(y < 0) || - WARN_ON_ONCE(width < 0) || - WARN_ON_ONCE(height < 0)) - return -EINVAL; - - x1 = ALIGN_DOWN(x, sizeof(unsigned long)); - x2 = ALIGN(width + (x - x1), sizeof(unsigned long)) + x1; - - clip->x1 = x1; - clip->y1 = y; - clip->x2 = x2; - clip->y2 = y + height; - - return 0; -} - -int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, - int width, int height) -{ - struct drm_device *dev = fb->dev; - struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach; - int i, ret, tmp_ret; - char *cmd; - struct urb *urb; - struct drm_rect clip; - int log_bpp; - void *vaddr; - - ret = udl_log_cpp(fb->format->cpp[0]); - if (ret < 0) - return ret; - log_bpp = ret; - - ret = udl_aligned_damage_clip(&clip, x, y, width, height); - if (ret) - return ret; - else if ((clip.x2 > fb->width) || (clip.y2 > fb->height)) - return -EINVAL; - - if (import_attach) { - ret = dma_buf_begin_cpu_access(import_attach->dmabuf, - DMA_FROM_DEVICE); - if (ret) - return ret; - } - - vaddr = drm_gem_shmem_vmap(fb->obj[0]); - if (IS_ERR(vaddr)) { - DRM_ERROR("failed to vmap fb\n"); - goto out_dma_buf_end_cpu_access; - } - - urb = udl_get_urb(dev); - if (!urb) - goto out_drm_gem_shmem_vunmap; - cmd = urb->transfer_buffer; - - for (i = clip.y1; i < clip.y2; i++) { - const int line_offset = fb->pitches[0] * i; - const int byte_offset = line_offset + (clip.x1 << log_bpp); - const int dev_byte_offset = (fb->width * i + clip.x1) << log_bpp; - const int byte_width = (clip.x2 - clip.x1) << log_bpp; - ret = udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, - &cmd, byte_offset, dev_byte_offset, - byte_width); - if (ret) - goto out_drm_gem_shmem_vunmap; - } - - if (cmd > (char *) urb->transfer_buffer) { - /* Send partial buffer remaining before exiting */ - int len; - if (cmd < (char *) urb->transfer_buffer + urb->transfer_buffer_length) - *cmd++ = 0xAF; - len = cmd - (char *) urb->transfer_buffer; - ret = udl_submit_urb(dev, urb, len); - } else - udl_urb_completion(urb); - - ret = 0; - -out_drm_gem_shmem_vunmap: - drm_gem_shmem_vunmap(fb->obj[0], vaddr); -out_dma_buf_end_cpu_access: - if (import_attach) { - tmp_ret = dma_buf_end_cpu_access(import_attach->dmabuf, - DMA_FROM_DEVICE); - if (tmp_ret && !ret) - ret = tmp_ret; /* only update ret if not set yet */ - } - - return ret; -} diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 35fa7b11c681..22af17959053 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -9,10 +9,14 @@ */ +#include + #include #include #include +#include #include +#include #include #include @@ -233,6 +237,114 @@ static int udl_crtc_write_mode_to_hw(struct drm_crtc *crtc) return retval; } +static long udl_log_cpp(unsigned int cpp) +{ + if (WARN_ON(!is_power_of_2(cpp))) + return -EINVAL; + return __ffs(cpp); +} + +static int udl_aligned_damage_clip(struct drm_rect *clip, int x, int y, + int width, int height) +{ + int x1, x2; + + if (WARN_ON_ONCE(x < 0) || + WARN_ON_ONCE(y < 0) || + WARN_ON_ONCE(width < 0) || + WARN_ON_ONCE(height < 0)) + return -EINVAL; + + x1 = ALIGN_DOWN(x, sizeof(unsigned long)); + x2 = ALIGN(width + (x - x1), sizeof(unsigned long)) + x1; + + clip->x1 = x1; + clip->y1 = y; + clip->x2 = x2; + clip->y2 = y + height; + + return 0; +} + +int udl_handle_damage(struct drm_framebuffer *fb, int x, int y, + int width, int height) +{ + struct drm_device *dev = fb->dev; + struct dma_buf_attachment *import_attach = fb->obj[0]->import_attach; + int i, ret, tmp_ret; + char *cmd; + struct urb *urb; + struct drm_rect clip; + int log_bpp; + void *vaddr; + + ret = udl_log_cpp(fb->format->cpp[0]); + if (ret < 0) + return ret; + log_bpp = ret; + + ret = udl_aligned_damage_clip(&clip, x, y, width, height); + if (ret) + return ret; + else if ((clip.x2 > fb->width) || (clip.y2 > fb->height)) + return -EINVAL; + + if (import_attach) { + ret = dma_buf_begin_cpu_access(import_attach->dmabuf, + DMA_FROM_DEVICE); + if (ret) + return ret; + } + + vaddr = drm_gem_shmem_vmap(fb->obj[0]); + if (IS_ERR(vaddr)) { + DRM_ERROR("failed to vmap fb\n"); + goto out_dma_buf_end_cpu_access; + } + + urb = udl_get_urb(dev); + if (!urb) + goto out_drm_gem_shmem_vunmap; + cmd = urb->transfer_buffer; + + for (i = clip.y1; i < clip.y2; i++) { + const int line_offset = fb->pitches[0] * i; + const int byte_offset = line_offset + (clip.x1 << log_bpp); + const int dev_byte_offset = (fb->width * i + clip.x1) << log_bpp; + const int byte_width = (clip.x2 - clip.x1) << log_bpp; + ret = udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, + &cmd, byte_offset, dev_byte_offset, + byte_width); + if (ret) + goto out_drm_gem_shmem_vunmap; + } + + if (cmd > (char *)urb->transfer_buffer) { + /* Send partial buffer remaining before exiting */ + int len; + if (cmd < (char *)urb->transfer_buffer + urb->transfer_buffer_length) + *cmd++ = 0xAF; + len = cmd - (char *)urb->transfer_buffer; + ret = udl_submit_urb(dev, urb, len); + } else { + udl_urb_completion(urb); + } + + ret = 0; + +out_drm_gem_shmem_vunmap: + drm_gem_shmem_vunmap(fb->obj[0], vaddr); +out_dma_buf_end_cpu_access: + if (import_attach) { + tmp_ret = dma_buf_end_cpu_access(import_attach->dmabuf, + DMA_FROM_DEVICE); + if (tmp_ret && !ret) + ret = tmp_ret; /* only update ret if not set yet */ + } + + return ret; +} + /* * Simple display pipeline */ -- cgit From 14856e9efb87381ab3ff71085ae8129ee4b2607e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 10 Dec 2019 09:49:05 +0100 Subject: drm/udl: Remove udl_fb.c The remaining code in udl_fb.c is unused. Remove the file entirely. Signed-off-by: Thomas Zimmermann Reviewed-by: Emil Velikov Link: https://patchwork.freedesktop.org/patch/msgid/20191210084905.5570-10-tzimmermann@suse.de --- drivers/gpu/drm/udl/Makefile | 2 +- drivers/gpu/drm/udl/udl_fb.c | 51 -------------------------------------------- 2 files changed, 1 insertion(+), 52 deletions(-) delete mode 100644 drivers/gpu/drm/udl/udl_fb.c (limited to 'drivers/gpu/drm/udl/udl_fb.c') diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile index 177ce74f4cf4..b50179bb4de0 100644 --- a/drivers/gpu/drm/udl/Makefile +++ b/drivers/gpu/drm/udl/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_main.o udl_fb.o udl_transfer.o udl_gem.o +udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_main.o udl_transfer.o udl_gem.o obj-$(CONFIG_DRM_UDL) := udl.o diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c deleted file mode 100644 index 84cff9d9edbe..000000000000 --- a/drivers/gpu/drm/udl/udl_fb.c +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2012 Red Hat - * - * based in parts on udlfb.c: - * Copyright (C) 2009 Roberto De Ioris - * Copyright (C) 2009 Jaya Kumar - * Copyright (C) 2009 Bernie Thompson - */ - -#include - -#include "udl_drv.h" - -/** Read the red component (0..255) of a 32 bpp colour. */ -#define DLO_RGB_GETRED(col) (uint8_t)((col) & 0xFF) - -/** Read the green component (0..255) of a 32 bpp colour. */ -#define DLO_RGB_GETGRN(col) (uint8_t)(((col) >> 8) & 0xFF) - -/** Read the blue component (0..255) of a 32 bpp colour. */ -#define DLO_RGB_GETBLU(col) (uint8_t)(((col) >> 16) & 0xFF) - -/** Return red/green component of a 16 bpp colour number. */ -#define DLO_RG16(red, grn) (uint8_t)((((red) & 0xF8) | ((grn) >> 5)) & 0xFF) - -/** Return green/blue component of a 16 bpp colour number. */ -#define DLO_GB16(grn, blu) (uint8_t)(((((grn) & 0x1C) << 3) | ((blu) >> 3)) & 0xFF) - -/** Return 8 bpp colour number from red, green and blue components. */ -#define DLO_RGB8(red, grn, blu) ((((red) << 5) | (((grn) & 3) << 3) | ((blu) & 7)) & 0xFF) - -#if 0 -static uint8_t rgb8(uint32_t col) -{ - uint8_t red = DLO_RGB_GETRED(col); - uint8_t grn = DLO_RGB_GETGRN(col); - uint8_t blu = DLO_RGB_GETBLU(col); - - return DLO_RGB8(red, grn, blu); -} - -static uint16_t rgb16(uint32_t col) -{ - uint8_t red = DLO_RGB_GETRED(col); - uint8_t grn = DLO_RGB_GETGRN(col); - uint8_t blu = DLO_RGB_GETBLU(col); - - return (DLO_RG16(red, grn) << 8) + DLO_GB16(grn, blu); -} -#endif -- cgit