diff options
author | Dave Airlie <airlied@redhat.com> | 2019-05-28 00:25:46 +0200 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2019-05-28 00:59:11 +0200 |
commit | 88cd7a2c1b29f61a2a3fab76216a43f3b779e0cd (patch) | |
tree | b8a4311c8f7edfc92c1055b6a5a86b1a5552878e /drivers/gpu/drm/ast | |
parent | Linux 5.2-rc2 (diff) | |
parent | dt-bindings: fix up for vendor prefixes file conversion (diff) | |
download | linux-88cd7a2c1b29f61a2a3fab76216a43f3b779e0cd.tar.xz linux-88cd7a2c1b29f61a2a3fab76216a43f3b779e0cd.zip |
Merge tag 'drm-misc-next-2019-05-24' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v5.3, try #2:
UAPI Changes:
- Add HDR source metadata property.
- Make drm.h compile on GNU/kFreeBSD by including stdint.h
- Clarify how the userspace reviewer has to review new kernel UAPI.
- Clarify that for using new UAPI, merging to drm-next or drm-misc-next should be enough.
Cross-subsystem Changes:
- video/hdmi: Add unpack function for DRM infoframes.
- Device tree bindings:
* Updating a property for Mali Midgard GPUs
* Updating a property for STM32 DSI panel
* Adding support for FriendlyELEC HD702E 800x1280 panel
* Adding support for Evervision VGG804821 800x480 5.0" WVGA TFT panel
* Adding support for the EDT ET035012DM6 3.5" 320x240 QVGA 24-bit RGB TFT.
* Adding support for Three Five displays TFC S9700RTWV43TR-01B 800x480 panel
with resistive touch found on TI's AM335X-EVM.
* Adding support for EDT ETM0430G0DH6 480x272 panel.
- Add OSD101T2587-53TS driver with DT bindings.
- Add Samsung S6E63M0 panel driver with DT bindings.
- Add VXT VL050-8048NT-C01 800x480 panel with DT bindings.
- Dma-buf:
- Make mmap callback actually optional.
- Documentation updates.
- Fix debugfs refcount inbalance.
- Remove unused sync_dump function.
- Fix device tree bindings in drm-misc-next after a botched merge.
Core Changes:
- Add support for HDR infoframes and related EDID parsing.
- Remove prime sg_table caching, now done inside dma-buf.
- Add shiny new drm_gem_vram helpers for simple VRAM drivers;
with some fixes to the new API on top.
- Small fix to job cleanup without timeout handler.
- Documentation fixes to drm_fourcc.
- Replace lookups of drm_format with struct drm_format_info;
remove functions that become obsolete by this conversion.
- Remove double include in bridge/panel.c and some drivers.
- Remove drmP.h include from drm/edid and drm/dp.
- Fix null pointer deref in drm_fb_helper_hotplug_event().
- Remove most members from drm_fb_helper_crtc, only mode_set is kept.
- Remove race of fb helpers with userspace; only restore mode
when userspace is not master.
- Move legacy setup from drm_file.c to drm_legacy_misc.c
- Rework scheduler job destruction.
- drm/bus was removed, remove from TODO.
- Add __drm_atomic_helper_crtc_reset() to subclass crtc_state,
and convert some drivers to use it (conversion is not complete yet).
- Bump vblank timeout wait to 100 ms for atomic.
- Docbook fix for drm_hdmi_infoframe_set_hdr_metadata.
Driver Changes:
- sun4i: Use DRM_GEM_CMA_VMAP_DRIVER_OPS instead of definining manually.
- v3d: Small cleanups, adding support for compute shaders,
reservation/synchronization fixes and job management refactoring,
fixes MMU and debugfs.
- lima: Fix null pointer in irq handler on startup, set default timeout for scheduled jobs.
- stm/ltdc: Assorted fixes and adding FB modifier support.
- amdgpu: Avoid hw reset if guilty job was already signaled.
- virtio: Add seqno to fences, add trace events, use correct flags for fence allocation.
- Convert AST, bochs, mgag200, vboxvideo, hisilicon to the new drm_gem_vram API.
- sun6i_mipi_dsi: Support DSI GENERIC_SHORT_WRITE_2 transfers.
- bochs: Small fix to use PTR_RET_OR_ZERO and driver unload.
- gma500: header fixes
- cirrus: Remove unused files.
- mediatek: Fix compiler warning after merging the HDR series.
- vc4: Rework binner bo handling.
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/052875a5-27ba-3832-60c2-193d950afdff@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/ast')
-rw-r--r-- | drivers/gpu/drm/ast/Kconfig | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_drv.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_drv.h | 71 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_fb.c | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_main.c | 77 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_mode.c | 132 | ||||
-rw-r--r-- | drivers/gpu/drm/ast/ast_ttm.c | 302 |
7 files changed, 120 insertions, 519 deletions
diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig index ac47ecfe7801..829620d5326c 100644 --- a/drivers/gpu/drm/ast/Kconfig +++ b/drivers/gpu/drm/ast/Kconfig @@ -2,9 +2,8 @@ config DRM_AST tristate "AST server chips" depends on DRM && PCI && MMU - select DRM_TTM select DRM_KMS_HELPER - select DRM_TTM + select DRM_VRAM_HELPER help Say yes for experimental AST GPU driver. Do not enable this driver without having a working -modesetting, diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index 3871b39d4dea..3811997e78c4 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c @@ -205,13 +205,7 @@ static struct pci_driver ast_pci_driver = { static const struct file_operations ast_fops = { .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - .mmap = ast_mmap, - .poll = drm_poll, - .compat_ioctl = drm_compat_ioctl, - .read = drm_read, + DRM_VRAM_MM_FILE_OPERATIONS }; static struct drm_driver driver = { @@ -228,10 +222,7 @@ static struct drm_driver driver = { .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, - .gem_free_object_unlocked = ast_gem_free_object, - .dumb_create = ast_dumb_create, - .dumb_map_offset = ast_dumb_mmap_offset, - + DRM_GEM_VRAM_DRIVER }; static int __init ast_init(void) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 1cf0c75e411d..b6cac9511796 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -31,13 +31,10 @@ #include <drm/drm_encoder.h> #include <drm/drm_fb_helper.h> -#include <drm/ttm/ttm_bo_api.h> -#include <drm/ttm/ttm_bo_driver.h> -#include <drm/ttm/ttm_placement.h> -#include <drm/ttm/ttm_memory.h> -#include <drm/ttm/ttm_module.h> - #include <drm/drm_gem.h> +#include <drm/drm_gem_vram_helper.h> + +#include <drm/drm_vram_mm_helper.h> #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> @@ -103,10 +100,6 @@ struct ast_private { int fb_mtrr; - struct { - struct ttm_bo_device bdev; - } ttm; - struct drm_gem_object *cursor_cache; uint64_t cursor_cache_gpu_addr; /* Acces to this cache is protected by the crtc->mutex of the only crtc @@ -263,7 +256,6 @@ struct ast_fbdev { struct ast_framebuffer afb; void *sysram; int size; - struct ttm_bo_kmap_obj mapping; int x1, y1, x2, y2; /* dirty rect */ spinlock_t dirty_lock; }; @@ -321,73 +313,16 @@ void ast_fbdev_fini(struct drm_device *dev); void ast_fbdev_set_suspend(struct drm_device *dev, int state); void ast_fbdev_set_base(struct ast_private *ast, unsigned long gpu_addr); -struct ast_bo { - struct ttm_buffer_object bo; - struct ttm_placement placement; - struct ttm_bo_kmap_obj kmap; - struct drm_gem_object gem; - struct ttm_place placements[3]; - int pin_count; -}; -#define gem_to_ast_bo(gobj) container_of((gobj), struct ast_bo, gem) - -static inline struct ast_bo * -ast_bo(struct ttm_buffer_object *bo) -{ - return container_of(bo, struct ast_bo, bo); -} - - -#define to_ast_obj(x) container_of(x, struct ast_gem_object, base) - #define AST_MM_ALIGN_SHIFT 4 #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1) -extern int ast_dumb_create(struct drm_file *file, - struct drm_device *dev, - struct drm_mode_create_dumb *args); - -extern void ast_gem_free_object(struct drm_gem_object *obj); -extern int ast_dumb_mmap_offset(struct drm_file *file, - struct drm_device *dev, - uint32_t handle, - uint64_t *offset); - int ast_mm_init(struct ast_private *ast); void ast_mm_fini(struct ast_private *ast); -int ast_bo_create(struct drm_device *dev, int size, int align, - uint32_t flags, struct ast_bo **pastbo); - int ast_gem_create(struct drm_device *dev, u32 size, bool iskernel, struct drm_gem_object **obj); -int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr); -int ast_bo_unpin(struct ast_bo *bo); - -static inline int ast_bo_reserve(struct ast_bo *bo, bool no_wait) -{ - int ret; - - ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL); - if (ret) { - if (ret != -ERESTARTSYS && ret != -EBUSY) - DRM_ERROR("reserve failed %p\n", bo); - return ret; - } - return 0; -} - -static inline void ast_bo_unreserve(struct ast_bo *bo) -{ - ttm_bo_unreserve(&bo->bo); -} - -void ast_ttm_placement(struct ast_bo *bo, int domain); -int ast_bo_push_sysram(struct ast_bo *bo); -int ast_mmap(struct file *filp, struct vm_area_struct *vma); - /* ast post */ void ast_enable_vga(struct drm_device *dev); void ast_enable_mmio(struct drm_device *dev); diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index e718d0f60d6b..05f45222b702 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c @@ -49,25 +49,25 @@ static void ast_dirty_update(struct ast_fbdev *afbdev, { int i; struct drm_gem_object *obj; - struct ast_bo *bo; + struct drm_gem_vram_object *gbo; int src_offset, dst_offset; int bpp = afbdev->afb.base.format->cpp[0]; int ret = -EBUSY; + u8 *dst; bool unmap = false; bool store_for_later = false; int x2, y2; unsigned long flags; obj = afbdev->afb.obj; - bo = gem_to_ast_bo(obj); + gbo = drm_gem_vram_of_gem(obj); - /* - * try and reserve the BO, if we fail with busy - * then the BO is being moved and we should - * store up the damage until later. + /* Try to lock the BO. If we fail with -EBUSY then + * the BO is being moved and we should store up the + * damage until later. */ if (drm_can_sleep()) - ret = ast_bo_reserve(bo, true); + ret = drm_gem_vram_lock(gbo, true); if (ret) { if (ret != -EBUSY) return; @@ -101,25 +101,32 @@ static void ast_dirty_update(struct ast_fbdev *afbdev, afbdev->x2 = afbdev->y2 = 0; spin_unlock_irqrestore(&afbdev->dirty_lock, flags); - if (!bo->kmap.virtual) { - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); - if (ret) { + dst = drm_gem_vram_kmap(gbo, false, NULL); + if (IS_ERR(dst)) { + DRM_ERROR("failed to kmap fb updates\n"); + goto out; + } else if (!dst) { + dst = drm_gem_vram_kmap(gbo, true, NULL); + if (IS_ERR(dst)) { DRM_ERROR("failed to kmap fb updates\n"); - ast_bo_unreserve(bo); - return; + goto out; } unmap = true; } + for (i = y; i <= y2; i++) { /* assume equal stride for now */ - src_offset = dst_offset = i * afbdev->afb.base.pitches[0] + (x * bpp); - memcpy_toio(bo->kmap.virtual + src_offset, afbdev->sysram + src_offset, (x2 - x + 1) * bpp); - + src_offset = dst_offset = + i * afbdev->afb.base.pitches[0] + (x * bpp); + memcpy_toio(dst + dst_offset, afbdev->sysram + src_offset, + (x2 - x + 1) * bpp); } + if (unmap) - ttm_bo_kunmap(&bo->kmap); + drm_gem_vram_kunmap(gbo); - ast_bo_unreserve(bo); +out: + drm_gem_vram_unlock(gbo); } static void ast_fillrect(struct fb_info *info, diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 2854399856ba..4c7e31cb45ff 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -593,7 +593,7 @@ int ast_gem_create(struct drm_device *dev, u32 size, bool iskernel, struct drm_gem_object **obj) { - struct ast_bo *astbo; + struct drm_gem_vram_object *gbo; int ret; *obj = NULL; @@ -602,80 +602,13 @@ int ast_gem_create(struct drm_device *dev, if (size == 0) return -EINVAL; - ret = ast_bo_create(dev, size, 0, 0, &astbo); - if (ret) { + gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, size, 0, false); + if (IS_ERR(gbo)) { + ret = PTR_ERR(gbo); if (ret != -ERESTARTSYS) DRM_ERROR("failed to allocate GEM object\n"); return ret; } - *obj = &astbo->gem; + *obj = &gbo->gem; return 0; } - -int ast_dumb_create(struct drm_file *file, - struct drm_device *dev, - struct drm_mode_create_dumb *args) -{ - int ret; - struct drm_gem_object *gobj; - u32 handle; - - args->pitch = args->width * ((args->bpp + 7) / 8); - args->size = args->pitch * args->height; - - ret = ast_gem_create(dev, args->size, false, - &gobj); - if (ret) - return ret; - - ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_put_unlocked(gobj); - if (ret) - return ret; - - args->handle = handle; - return 0; -} - -static void ast_bo_unref(struct ast_bo **bo) -{ - if ((*bo) == NULL) - return; - ttm_bo_put(&((*bo)->bo)); - *bo = NULL; -} - -void ast_gem_free_object(struct drm_gem_object *obj) -{ - struct ast_bo *ast_bo = gem_to_ast_bo(obj); - - ast_bo_unref(&ast_bo); -} - - -static inline u64 ast_bo_mmap_offset(struct ast_bo *bo) -{ - return drm_vma_node_offset_addr(&bo->bo.vma_node); -} -int -ast_dumb_mmap_offset(struct drm_file *file, - struct drm_device *dev, - uint32_t handle, - uint64_t *offset) -{ - struct drm_gem_object *obj; - struct ast_bo *bo; - - obj = drm_gem_object_lookup(file, handle); - if (obj == NULL) - return -ENOENT; - - bo = gem_to_ast_bo(obj); - *offset = ast_bo_mmap_offset(bo); - - drm_gem_object_put_unlocked(obj); - - return 0; - -} - diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 97fed0627d1c..fb700d620b64 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -521,7 +521,6 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) } } -/* ast is different - we will force move buffers out of VRAM */ static int ast_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic) @@ -529,50 +528,54 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc, struct ast_private *ast = crtc->dev->dev_private; struct drm_gem_object *obj; struct ast_framebuffer *ast_fb; - struct ast_bo *bo; + struct drm_gem_vram_object *gbo; int ret; - u64 gpu_addr; + s64 gpu_addr; + void *base; - /* push the previous fb to system ram */ if (!atomic && fb) { ast_fb = to_ast_framebuffer(fb); obj = ast_fb->obj; - bo = gem_to_ast_bo(obj); - ret = ast_bo_reserve(bo, false); - if (ret) - return ret; - ast_bo_push_sysram(bo); - ast_bo_unreserve(bo); + gbo = drm_gem_vram_of_gem(obj); + + /* unmap if console */ + if (&ast->fbdev->afb == ast_fb) + drm_gem_vram_kunmap(gbo); + drm_gem_vram_unpin(gbo); } ast_fb = to_ast_framebuffer(crtc->primary->fb); obj = ast_fb->obj; - bo = gem_to_ast_bo(obj); + gbo = drm_gem_vram_of_gem(obj); - ret = ast_bo_reserve(bo, false); + ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); if (ret) return ret; - - ret = ast_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); - if (ret) { - ast_bo_unreserve(bo); - return ret; + gpu_addr = drm_gem_vram_offset(gbo); + if (gpu_addr < 0) { + ret = (int)gpu_addr; + goto err_drm_gem_vram_unpin; } if (&ast->fbdev->afb == ast_fb) { /* if pushing console in kmap it */ - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); - if (ret) + base = drm_gem_vram_kmap(gbo, true, NULL); + if (IS_ERR(base)) { + ret = PTR_ERR(base); DRM_ERROR("failed to kmap fbcon\n"); - else + } else { ast_fbdev_set_base(ast, gpu_addr); + } } - ast_bo_unreserve(bo); ast_set_offset_reg(crtc); ast_set_start_address_crt1(crtc, (u32)gpu_addr); return 0; + +err_drm_gem_vram_unpin: + drm_gem_vram_unpin(gbo); + return ret; } static int ast_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, @@ -618,21 +621,18 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc, static void ast_crtc_disable(struct drm_crtc *crtc) { - int ret; - DRM_DEBUG_KMS("\n"); ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); if (crtc->primary->fb) { + struct ast_private *ast = crtc->dev->dev_private; struct ast_framebuffer *ast_fb = to_ast_framebuffer(crtc->primary->fb); struct drm_gem_object *obj = ast_fb->obj; - struct ast_bo *bo = gem_to_ast_bo(obj); - - ret = ast_bo_reserve(bo, false); - if (ret) - return; + struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(obj); - ast_bo_push_sysram(bo); - ast_bo_unreserve(bo); + /* unmap if console */ + if (&ast->fbdev->afb == ast_fb) + drm_gem_vram_kunmap(gbo); + drm_gem_vram_unpin(gbo); } crtc->primary->fb = NULL; } @@ -918,28 +918,32 @@ static int ast_cursor_init(struct drm_device *dev) int size; int ret; struct drm_gem_object *obj; - struct ast_bo *bo; - uint64_t gpu_addr; + struct drm_gem_vram_object *gbo; + s64 gpu_addr; + void *base; size = (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE) * AST_DEFAULT_HWC_NUM; ret = ast_gem_create(dev, size, true, &obj); if (ret) return ret; - bo = gem_to_ast_bo(obj); - ret = ast_bo_reserve(bo, false); - if (unlikely(ret != 0)) - goto fail; - - ret = ast_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); - ast_bo_unreserve(bo); + gbo = drm_gem_vram_of_gem(obj); + ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); if (ret) goto fail; + gpu_addr = drm_gem_vram_offset(gbo); + if (gpu_addr < 0) { + drm_gem_vram_unpin(gbo); + ret = (int)gpu_addr; + goto fail; + } /* kmap the object */ - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &ast->cache_kmap); - if (ret) + base = drm_gem_vram_kmap_at(gbo, true, NULL, &ast->cache_kmap); + if (IS_ERR(base)) { + ret = PTR_ERR(base); goto fail; + } ast->cursor_cache = obj; ast->cursor_cache_gpu_addr = gpu_addr; @@ -952,7 +956,9 @@ fail: static void ast_cursor_fini(struct drm_device *dev) { struct ast_private *ast = dev->dev_private; - ttm_bo_kunmap(&ast->cache_kmap); + struct drm_gem_vram_object *gbo = + drm_gem_vram_of_gem(ast->cursor_cache); + drm_gem_vram_kunmap_at(gbo, &ast->cache_kmap); drm_gem_object_put_unlocked(ast->cursor_cache); } @@ -1173,8 +1179,8 @@ static int ast_cursor_set(struct drm_crtc *crtc, struct ast_private *ast = crtc->dev->dev_private; struct ast_crtc *ast_crtc = to_ast_crtc(crtc); struct drm_gem_object *obj; - struct ast_bo *bo; - uint64_t gpu_addr; + struct drm_gem_vram_object *gbo; + s64 gpu_addr; u32 csum; int ret; struct ttm_bo_kmap_obj uobj_map; @@ -1193,19 +1199,27 @@ static int ast_cursor_set(struct drm_crtc *crtc, DRM_ERROR("Cannot find cursor object %x for crtc\n", handle); return -ENOENT; } - bo = gem_to_ast_bo(obj); + gbo = drm_gem_vram_of_gem(obj); - ret = ast_bo_reserve(bo, false); + ret = drm_gem_vram_lock(gbo, false); if (ret) goto fail; - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map); - - src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem); - dst = ttm_kmap_obj_virtual(&ast->cache_kmap, &dst_isiomem); - + memset(&uobj_map, 0, sizeof(uobj_map)); + src = drm_gem_vram_kmap_at(gbo, true, &src_isiomem, &uobj_map); + if (IS_ERR(src)) { + ret = PTR_ERR(src); + goto fail_unlock; + } if (src_isiomem == true) DRM_ERROR("src cursor bo should be in main memory\n"); + + dst = drm_gem_vram_kmap_at(drm_gem_vram_of_gem(ast->cursor_cache), + false, &dst_isiomem, &ast->cache_kmap); + if (IS_ERR(dst)) { + ret = PTR_ERR(dst); + goto fail_unlock; + } if (dst_isiomem == false) DRM_ERROR("dst bo should be in VRAM\n"); @@ -1214,11 +1228,14 @@ static int ast_cursor_set(struct drm_crtc *crtc, /* do data transfer to cursor cache */ csum = copy_cursor_image(src, dst, width, height); + drm_gem_vram_kunmap_at(gbo, &uobj_map); + drm_gem_vram_unlock(gbo); + /* write checksum + signature */ - ttm_bo_kunmap(&uobj_map); - ast_bo_unreserve(bo); { - u8 *dst = (u8 *)ast->cache_kmap.virtual + (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE; + u8 *dst = drm_gem_vram_kmap_at(drm_gem_vram_of_gem(ast->cursor_cache), + false, NULL, &ast->cache_kmap); + dst += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE; writel(csum, dst); writel(width, dst + AST_HWC_SIGNATURE_SizeX); writel(height, dst + AST_HWC_SIGNATURE_SizeY); @@ -1244,6 +1261,9 @@ static int ast_cursor_set(struct drm_crtc *crtc, drm_gem_object_put_unlocked(obj); return 0; + +fail_unlock: + drm_gem_vram_unlock(gbo); fail: drm_gem_object_put_unlocked(obj); return ret; @@ -1257,7 +1277,9 @@ static int ast_cursor_move(struct drm_crtc *crtc, int x_offset, y_offset; u8 *sig; - sig = (u8 *)ast->cache_kmap.virtual + (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE; + sig = drm_gem_vram_kmap_at(drm_gem_vram_of_gem(ast->cursor_cache), + false, NULL, &ast->cache_kmap); + sig += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE; writel(x, sig + AST_HWC_SIGNATURE_X); writel(y, sig + AST_HWC_SIGNATURE_Y); diff --git a/drivers/gpu/drm/ast/ast_ttm.c b/drivers/gpu/drm/ast/ast_ttm.c index 75d477b37854..779c53efee8e 100644 --- a/drivers/gpu/drm/ast/ast_ttm.c +++ b/drivers/gpu/drm/ast/ast_ttm.c @@ -26,168 +26,21 @@ * Authors: Dave Airlie <airlied@redhat.com> */ #include <drm/drmP.h> -#include <drm/ttm/ttm_page_alloc.h> #include "ast_drv.h" -static inline struct ast_private * -ast_bdev(struct ttm_bo_device *bd) -{ - return container_of(bd, struct ast_private, ttm.bdev); -} - -static void ast_bo_ttm_destroy(struct ttm_buffer_object *tbo) -{ - struct ast_bo *bo; - - bo = container_of(tbo, struct ast_bo, bo); - - drm_gem_object_release(&bo->gem); - kfree(bo); -} - -static bool ast_ttm_bo_is_ast_bo(struct ttm_buffer_object *bo) -{ - if (bo->destroy == &ast_bo_ttm_destroy) - return true; - return false; -} - -static int -ast_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, - struct ttm_mem_type_manager *man) -{ - switch (type) { - case TTM_PL_SYSTEM: - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_MASK_CACHING; - man->default_caching = TTM_PL_FLAG_CACHED; - break; - case TTM_PL_VRAM: - man->func = &ttm_bo_manager_func; - man->flags = TTM_MEMTYPE_FLAG_FIXED | - TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_UNCACHED | - TTM_PL_FLAG_WC; - man->default_caching = TTM_PL_FLAG_WC; - break; - default: - DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); - return -EINVAL; - } - return 0; -} - -static void -ast_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) -{ - struct ast_bo *astbo = ast_bo(bo); - - if (!ast_ttm_bo_is_ast_bo(bo)) - return; - - ast_ttm_placement(astbo, TTM_PL_FLAG_SYSTEM); - *pl = astbo->placement; -} - -static int ast_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp) -{ - struct ast_bo *astbo = ast_bo(bo); - - return drm_vma_node_verify_access(&astbo->gem.vma_node, - filp->private_data); -} - -static int ast_ttm_io_mem_reserve(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem) -{ - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - struct ast_private *ast = ast_bdev(bdev); - - mem->bus.addr = NULL; - mem->bus.offset = 0; - mem->bus.size = mem->num_pages << PAGE_SHIFT; - mem->bus.base = 0; - mem->bus.is_iomem = false; - if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) - return -EINVAL; - switch (mem->mem_type) { - case TTM_PL_SYSTEM: - /* system memory */ - return 0; - case TTM_PL_VRAM: - mem->bus.offset = mem->start << PAGE_SHIFT; - mem->bus.base = pci_resource_start(ast->dev->pdev, 0); - mem->bus.is_iomem = true; - break; - default: - return -EINVAL; - break; - } - return 0; -} - -static void ast_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) -{ -} - -static void ast_ttm_backend_destroy(struct ttm_tt *tt) -{ - ttm_tt_fini(tt); - kfree(tt); -} - -static struct ttm_backend_func ast_tt_backend_func = { - .destroy = &ast_ttm_backend_destroy, -}; - - -static struct ttm_tt *ast_ttm_tt_create(struct ttm_buffer_object *bo, - uint32_t page_flags) -{ - struct ttm_tt *tt; - - tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL); - if (tt == NULL) - return NULL; - tt->func = &ast_tt_backend_func; - if (ttm_tt_init(tt, bo, page_flags)) { - kfree(tt); - return NULL; - } - return tt; -} - -struct ttm_bo_driver ast_bo_driver = { - .ttm_tt_create = ast_ttm_tt_create, - .init_mem_type = ast_bo_init_mem_type, - .eviction_valuable = ttm_bo_eviction_valuable, - .evict_flags = ast_bo_evict_flags, - .move = NULL, - .verify_access = ast_bo_verify_access, - .io_mem_reserve = &ast_ttm_io_mem_reserve, - .io_mem_free = &ast_ttm_io_mem_free, -}; - int ast_mm_init(struct ast_private *ast) { + struct drm_vram_mm *vmm; int ret; struct drm_device *dev = ast->dev; - struct ttm_bo_device *bdev = &ast->ttm.bdev; - - ret = ttm_bo_device_init(&ast->ttm.bdev, - &ast_bo_driver, - dev->anon_inode->i_mapping, - true); - if (ret) { - DRM_ERROR("Error initialising bo driver; %d\n", ret); - return ret; - } - ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM, - ast->vram_size >> PAGE_SHIFT); - if (ret) { - DRM_ERROR("Failed ttm VRAM init: %d\n", ret); + vmm = drm_vram_helper_alloc_mm( + dev, pci_resource_start(dev->pdev, 0), + ast->vram_size, &drm_gem_vram_mm_funcs); + if (IS_ERR(vmm)) { + ret = PTR_ERR(vmm); + DRM_ERROR("Error initializing VRAM MM; %d\n", ret); return ret; } @@ -203,148 +56,9 @@ void ast_mm_fini(struct ast_private *ast) { struct drm_device *dev = ast->dev; - ttm_bo_device_release(&ast->ttm.bdev); + drm_vram_helper_release_mm(dev); arch_phys_wc_del(ast->fb_mtrr); arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0), pci_resource_len(dev->pdev, 0)); } - -void ast_ttm_placement(struct ast_bo *bo, int domain) -{ - u32 c = 0; - unsigned i; - - bo->placement.placement = bo->placements; - bo->placement.busy_placement = bo->placements; - if (domain & TTM_PL_FLAG_VRAM) - bo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM; - if (domain & TTM_PL_FLAG_SYSTEM) - bo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM; - if (!c) - bo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM; - bo->placement.num_placement = c; - bo->placement.num_busy_placement = c; - for (i = 0; i < c; ++i) { - bo->placements[i].fpfn = 0; - bo->placements[i].lpfn = 0; - } -} - -int ast_bo_create(struct drm_device *dev, int size, int align, - uint32_t flags, struct ast_bo **pastbo) -{ - struct ast_private *ast = dev->dev_private; - struct ast_bo *astbo; - size_t acc_size; - int ret; - - astbo = kzalloc(sizeof(struct ast_bo), GFP_KERNEL); - if (!astbo) - return -ENOMEM; - - ret = drm_gem_object_init(dev, &astbo->gem, size); - if (ret) - goto error; - - astbo->bo.bdev = &ast->ttm.bdev; - - ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); - - acc_size = ttm_bo_dma_acc_size(&ast->ttm.bdev, size, - sizeof(struct ast_bo)); - - ret = ttm_bo_init(&ast->ttm.bdev, &astbo->bo, size, - ttm_bo_type_device, &astbo->placement, - align >> PAGE_SHIFT, false, acc_size, - NULL, NULL, ast_bo_ttm_destroy); - if (ret) - goto error; - - *pastbo = astbo; - return 0; -error: - kfree(astbo); - return ret; -} - -static inline u64 ast_bo_gpu_offset(struct ast_bo *bo) -{ - return bo->bo.offset; -} - -int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i, ret; - - if (bo->pin_count) { - bo->pin_count++; - if (gpu_addr) - *gpu_addr = ast_bo_gpu_offset(bo); - } - - ast_ttm_placement(bo, pl_flag); - for (i = 0; i < bo->placement.num_placement; i++) - bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; - ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - if (ret) - return ret; - - bo->pin_count = 1; - if (gpu_addr) - *gpu_addr = ast_bo_gpu_offset(bo); - return 0; -} - -int ast_bo_unpin(struct ast_bo *bo) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i; - if (!bo->pin_count) { - DRM_ERROR("unpin bad %p\n", bo); - return 0; - } - bo->pin_count--; - if (bo->pin_count) - return 0; - - for (i = 0; i < bo->placement.num_placement ; i++) - bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; - return ttm_bo_validate(&bo->bo, &bo->placement, &ctx); -} - -int ast_bo_push_sysram(struct ast_bo *bo) -{ - struct ttm_operation_ctx ctx = { false, false }; - int i, ret; - if (!bo->pin_count) { - DRM_ERROR("unpin bad %p\n", bo); - return 0; - } - bo->pin_count--; - if (bo->pin_count) - return 0; - - if (bo->kmap.virtual) - ttm_bo_kunmap(&bo->kmap); - - ast_ttm_placement(bo, TTM_PL_FLAG_SYSTEM); - for (i = 0; i < bo->placement.num_placement ; i++) - bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; - - ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx); - if (ret) { - DRM_ERROR("pushing to VRAM failed\n"); - return ret; - } - return 0; -} - -int ast_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct drm_file *file_priv = filp->private_data; - struct ast_private *ast = file_priv->minor->dev->dev_private; - - return ttm_bo_mmap(filp, vma, &ast->ttm.bdev); -} |