drivers/gpu/drm/openchrome/Makefile | 2 drivers/gpu/drm/openchrome/openchrome_crtc.c | 198 ++++++++--- drivers/gpu/drm/openchrome/openchrome_display.h | 2 drivers/gpu/drm/openchrome/openchrome_drv.c | 252 ++++++++++---- drivers/gpu/drm/openchrome/openchrome_drv.h | 95 +---- drivers/gpu/drm/openchrome/openchrome_fb.c | 117 ++++-- drivers/gpu/drm/openchrome/openchrome_gem.c | 120 ------ drivers/gpu/drm/openchrome/openchrome_init.c | 23 - drivers/gpu/drm/openchrome/openchrome_ioc32.c | 140 ++++---- drivers/gpu/drm/openchrome/openchrome_object.c | 233 +++++++++++++ drivers/gpu/drm/openchrome/openchrome_ttm.c | 417 +++++------------------- 11 files changed, 874 insertions(+), 725 deletions(-)
New commits: commit be8e17570db5bdea1c79fe238df4712e07145200 Author: Kevin Brace <kevinbr...@gmx.com> Date: Sat Mar 16 17:55:03 2019 -0700 drm/openchrome: Version bumped to 3.1.6 Replaced the TTM memory allocator code. Signed-off-by: Kevin Brace <kevinbr...@gmx.com> diff --git a/drivers/gpu/drm/openchrome/openchrome_drv.h b/drivers/gpu/drm/openchrome/openchrome_drv.h index af912336ed57..9a78de1ad4f2 100644 --- a/drivers/gpu/drm/openchrome/openchrome_drv.h +++ b/drivers/gpu/drm/openchrome/openchrome_drv.h @@ -51,7 +51,7 @@ #define DRIVER_MAJOR 3 #define DRIVER_MINOR 1 -#define DRIVER_PATCHLEVEL 5 +#define DRIVER_PATCHLEVEL 6 #define DRIVER_NAME "openchrome" #define DRIVER_DESC "OpenChrome DRM for VIA Technologies Chrome IGP" #define DRIVER_DATE "20190316" commit fb290240fd06172e034654b4b125497bed47b2f2 Author: Kevin Brace <kevinbr...@gmx.com> Date: Sat Mar 16 17:52:24 2019 -0700 drm/openchrome: New TTM memory allocator A basic implementation with no DMA support. Signed-off-by: Kevin Brace <kevinbr...@gmx.com> diff --git a/drivers/gpu/drm/openchrome/Makefile b/drivers/gpu/drm/openchrome/Makefile index 3ed2912e75f5..261c40f8e3eb 100644 --- a/drivers/gpu/drm/openchrome/Makefile +++ b/drivers/gpu/drm/openchrome/Makefile @@ -12,11 +12,11 @@ openchrome-y := openchrome_analog.o \ openchrome_encoder.o \ openchrome_fb.o \ openchrome_fp.o \ - openchrome_gem.o \ openchrome_hdmi.o \ openchrome_i2c.o \ openchrome_init.o \ openchrome_ioc32.o \ + openchrome_object.o \ openchrome_pm.o \ openchrome_sii164.o \ openchrome_tmds.o \ diff --git a/drivers/gpu/drm/openchrome/openchrome_crtc.c b/drivers/gpu/drm/openchrome/openchrome_crtc.c index 91d008213c23..9427b6ad163f 100644 --- a/drivers/gpu/drm/openchrome/openchrome_crtc.c +++ b/drivers/gpu/drm/openchrome/openchrome_crtc.c @@ -255,7 +255,7 @@ static void via_cursor_address(struct drm_crtc *crtc) struct openchrome_drm_private *dev_private = crtc->dev->dev_private; - if (!iga->cursor_kmap.bo) { + if (!iga->cursor_bo->kmap.bo) { return; } @@ -269,13 +269,13 @@ static void via_cursor_address(struct drm_crtc *crtc) case PCI_DEVICE_ID_VIA_VX900_VGA: /* Program the HI offset. */ if (iga->index) { - VIA_WRITE(HI_FBOFFSET, iga->cursor_kmap.bo->offset); + VIA_WRITE(HI_FBOFFSET, iga->cursor_bo->kmap.bo->offset); } else { - VIA_WRITE(PRIM_HI_FBOFFSET, iga->cursor_kmap.bo->offset); + VIA_WRITE(PRIM_HI_FBOFFSET, iga->cursor_bo->kmap.bo->offset); } break; default: - VIA_WRITE(HI_FBOFFSET, iga->cursor_kmap.bo->offset); + VIA_WRITE(HI_FBOFFSET, iga->cursor_bo->kmap.bo->offset); break; } } @@ -288,10 +288,11 @@ static int via_crtc_cursor_set(struct drm_crtc *crtc, struct via_crtc *iga = container_of(crtc, struct via_crtc, base); int max_height = 64, max_width = 64, ret = 0, i; struct drm_device *dev = crtc->dev; - struct drm_gem_object *obj = NULL; + struct drm_gem_object *gem; struct ttm_bo_kmap_obj user_kmap; + struct openchrome_bo *bo; - if (!iga->cursor_kmap.bo) + if (!iga->cursor_bo->kmap.bo) return -ENXIO; if (!handle) { @@ -312,20 +313,23 @@ static int via_crtc_cursor_set(struct drm_crtc *crtc, return -EINVAL; } - obj = drm_gem_object_lookup(file_priv, handle); - if (!obj) { + gem = drm_gem_object_lookup(file_priv, handle); + if (!gem) { DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, crtc->base.id); return -ENOENT; } - user_kmap.bo = ttm_gem_mapping(obj); - ret = ttm_bo_kmap(user_kmap.bo, 0, user_kmap.bo->num_pages, &user_kmap); + bo = container_of(gem, struct openchrome_bo, gem); + user_kmap.bo = &bo->ttm_bo; + ret = ttm_bo_kmap(user_kmap.bo, 0, user_kmap.bo->num_pages, + &user_kmap); if (!ret) { /* Copy data from userland to cursor memory region */ - u32 *dst = iga->cursor_kmap.virtual, *src = user_kmap.virtual; + u32 *dst = iga->cursor_bo->kmap.virtual, + *src = user_kmap.virtual; - memset_io(dst, 0x0, iga->cursor_kmap.bo->mem.size); + memset_io(dst, 0x0, iga->cursor_bo->kmap.bo->mem.size); for (i = 0; i < height; i++) { __iowrite32_copy(dst, src, width); dst += max_width; @@ -333,7 +337,7 @@ static int via_crtc_cursor_set(struct drm_crtc *crtc, } ttm_bo_kunmap(&user_kmap); } - drm_gem_object_put_unlocked(obj); + drm_gem_object_put_unlocked(gem); via_cursor_address(crtc); via_show_cursor(crtc); @@ -533,11 +537,27 @@ static int via_iga2_gamma_set(struct drm_crtc *crtc, static void via_crtc_destroy(struct drm_crtc *crtc) { struct via_crtc *iga = container_of(crtc, struct via_crtc, base); + int ret; + + if (iga->cursor_bo->kmap.bo) { + ret = ttm_bo_reserve(iga->cursor_bo->kmap.bo, + true, false, NULL); + if (ret) { + goto exit; + } + + ttm_bo_kunmap(&iga->cursor_bo->kmap); - if (iga->cursor_kmap.bo) { - via_bo_unpin(iga->cursor_kmap.bo, &iga->cursor_kmap); - ttm_bo_put(iga->cursor_kmap.bo); + ret = openchrome_bo_unpin(iga->cursor_bo); + ttm_bo_unreserve(iga->cursor_bo->kmap.bo); + if (ret) { + goto exit; + } + + ttm_bo_put(iga->cursor_bo->kmap.bo); } + +exit: drm_crtc_cleanup(crtc); } @@ -1876,12 +1896,13 @@ static int via_iga1_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { - struct ttm_buffer_object *bo; struct via_framebuffer *via_fb = container_of(crtc->primary->fb, struct via_framebuffer, fb); struct drm_framebuffer *new_fb = &via_fb->fb; - struct drm_gem_object *gem_obj = via_fb->gem_obj; + struct openchrome_bo *bo; + struct drm_gem_object *gem; int ret = 0; + int fake_ret = 0; DRM_DEBUG_KMS("Entered %s.\n", __func__); @@ -1892,11 +1913,18 @@ via_iga1_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, goto exit; } - gem_obj = via_fb->gem_obj; - bo = ttm_gem_mapping(gem_obj); + gem = via_fb->gem; + bo = container_of(gem, struct openchrome_bo, gem); - ret = via_bo_pin(bo, NULL); - if (unlikely(ret)) { + ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (ret) { + DRM_DEBUG_KMS("Failed to reserve FB.\n"); + goto exit; + } + + ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM); + ttm_bo_unreserve(&bo->ttm_bo); + if (ret) { DRM_DEBUG_KMS("Failed to pin FB.\n"); goto exit; } @@ -1906,19 +1934,34 @@ via_iga1_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, ENTER_ATOMIC_MODE_SET); if (unlikely(ret)) { DRM_DEBUG_KMS("Failed to set a new FB.\n"); - via_bo_unpin(bo, NULL); + fake_ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (fake_ret) { + goto exit; + } + + fake_ret = openchrome_bo_unpin(bo); + ttm_bo_unreserve(&bo->ttm_bo); goto exit; } - /* Free the old framebuffer if it exist */ + /* + * Free the old framebuffer if it exists. + */ if (old_fb) { via_fb = container_of(old_fb, struct via_framebuffer, fb); - gem_obj = via_fb->gem_obj; - bo = ttm_gem_mapping(gem_obj); + gem = via_fb->gem; + bo = container_of(gem, struct openchrome_bo, gem); - ret = via_bo_unpin(bo, NULL); - if (unlikely(ret)) { + ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (ret) { + DRM_DEBUG_KMS("FB still locked.\n"); + goto exit; + } + + ret = openchrome_bo_unpin(bo); + ttm_bo_unreserve(&bo->ttm_bo); + if (ret) { DRM_DEBUG_KMS("FB still locked.\n"); goto exit; } @@ -2032,8 +2075,9 @@ via_iga1_mode_set_base_atomic(struct drm_crtc *crtc, crtc->dev->dev_private; struct via_framebuffer *via_fb = container_of(fb, struct via_framebuffer, fb); - struct drm_gem_object *gem_obj = via_fb->gem_obj; - struct ttm_buffer_object *bo = ttm_gem_mapping(gem_obj); + struct drm_gem_object *gem = via_fb->gem; + struct openchrome_bo *bo = container_of(gem, + struct openchrome_bo, gem); if ((fb->format->depth != 8) && (fb->format->depth != 16) && (fb->format->depth != 24) && (fb->format->depth != 32)) { @@ -2050,7 +2094,7 @@ via_iga1_mode_set_base_atomic(struct drm_crtc *crtc, via_iga1_set_color_depth(dev_private, fb->format->depth); /* Set the framebuffer offset */ - addr = round_up(bo->offset + pitch, 16) >> 1; + addr = round_up(bo->ttm_bo.offset + pitch, 16) >> 1; vga_wcrt(VGABASE, 0x0D, addr & 0xFF); vga_wcrt(VGABASE, 0x0C, (addr >> 8) & 0xFF); /* Yes order of setting these registers matters on some hardware */ @@ -2155,12 +2199,13 @@ static int via_iga2_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { - struct ttm_buffer_object *bo; struct via_framebuffer *via_fb = container_of(crtc->primary->fb, struct via_framebuffer, fb); struct drm_framebuffer *new_fb = &via_fb->fb; - struct drm_gem_object *gem_obj = via_fb->gem_obj; + struct openchrome_bo *bo; + struct drm_gem_object *gem; int ret = 0; + int fake_ret = 0; DRM_DEBUG_KMS("Entered %s.\n", __func__); @@ -2171,11 +2216,18 @@ via_iga2_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, goto exit; } - gem_obj = via_fb->gem_obj; - bo = ttm_gem_mapping(gem_obj); + gem = via_fb->gem; + bo = container_of(gem, struct openchrome_bo, gem); - ret = via_bo_pin(bo, NULL); - if (unlikely(ret)) { + ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (ret) { + DRM_DEBUG_KMS("Failed to reserve FB.\n"); + goto exit; + } + + ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM); + ttm_bo_unreserve(&bo->ttm_bo); + if (ret) { DRM_DEBUG_KMS("Failed to pin FB.\n"); goto exit; } @@ -2184,19 +2236,34 @@ via_iga2_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, ENTER_ATOMIC_MODE_SET); if (unlikely(ret)) { DRM_DEBUG_KMS("Failed to set a new FB.\n"); - via_bo_unpin(bo, NULL); + fake_ret = ttm_bo_reserve(&bo->ttm_bo, true, false, + NULL); + if (fake_ret) { + goto exit; + } + + fake_ret = openchrome_bo_unpin(bo); + ttm_bo_unreserve(&bo->ttm_bo); goto exit; } - /* Free the old framebuffer if it exist */ + /* + * Free the old framebuffer if it exists. + */ if (old_fb) { via_fb = container_of(old_fb, - struct via_framebuffer, fb); - gem_obj = via_fb->gem_obj; - bo = ttm_gem_mapping(gem_obj); + struct via_framebuffer, fb); + gem = via_fb->gem; + bo = container_of(gem, struct openchrome_bo, gem); + ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (ret) { + DRM_DEBUG_KMS("FB still locked.\n"); + goto exit; + } - ret = via_bo_unpin(bo, NULL); - if (unlikely(ret)) { + ret = openchrome_bo_unpin(bo); + ttm_bo_unreserve(&bo->ttm_bo); + if (ret) { DRM_DEBUG_KMS("FB still locked.\n"); goto exit; } @@ -2342,8 +2409,9 @@ via_iga2_mode_set_base_atomic(struct drm_crtc *crtc, crtc->dev->dev_private; struct via_framebuffer *via_fb = container_of(fb, struct via_framebuffer, fb); - struct drm_gem_object *gem_obj = via_fb->gem_obj; - struct ttm_buffer_object *bo = ttm_gem_mapping(gem_obj); + struct drm_gem_object *gem = via_fb->gem; + struct openchrome_bo *bo = container_of(gem, + struct openchrome_bo, gem); if ((fb->format->depth != 8) && (fb->format->depth != 16) && (fb->format->depth != 24) && (fb->format->depth != 32)) { @@ -2360,7 +2428,7 @@ via_iga2_mode_set_base_atomic(struct drm_crtc *crtc, via_iga2_set_color_depth(dev_private, fb->format->depth); /* Set the framebuffer offset */ - addr = round_up(bo->offset + pitch, 16); + addr = round_up(bo->ttm_bo.offset + pitch, 16); /* Bits 9 to 3 of the frame buffer go into bits 7 to 1 * of the register. Bit 0 is for setting tile mode or * linear mode. A value of zero sets it to linear mode */ @@ -2408,6 +2476,7 @@ int via_crtc_init(struct drm_device *dev, int index) dev->dev_private; struct via_crtc *iga = &dev_private->iga[index]; struct drm_crtc *crtc = &iga->base; + struct openchrome_bo *bo; int cursor_size = 64 * 64 * 4, i; u16 *gamma; int ret; @@ -2582,11 +2651,36 @@ int via_crtc_init(struct drm_device *dev, int index) || dev->pdev->device == PCI_DEVICE_ID_VIA_KM400) cursor_size = 32 * 32 * 4; - ret = via_ttm_allocate_kernel_buffer(&dev_private->ttm.bdev, - cursor_size, 16, - TTM_PL_FLAG_VRAM, &iga->cursor_kmap); - if (ret) - DRM_ERROR("failed to create cursor\n"); + ret = openchrome_bo_create(dev, + &dev_private->bdev, + cursor_size, + ttm_bo_type_kernel, + TTM_PL_FLAG_VRAM, + &bo); + if (ret) { + DRM_ERROR("Failed to create cursor.\n"); + goto exit; + } + + ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (ret) { + goto exit; + } + ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM); + if (ret) { + ttm_bo_unreserve(&bo->ttm_bo); + goto exit; + } + + ret = ttm_bo_kmap(&bo->ttm_bo, 0, bo->ttm_bo.num_pages, + &bo->kmap); + ttm_bo_unreserve(&bo->ttm_bo); + if (ret) { + goto exit; + } + + iga->cursor_bo = bo; +exit: return ret; } diff --git a/drivers/gpu/drm/openchrome/openchrome_display.h b/drivers/gpu/drm/openchrome/openchrome_display.h index db34df3dd10d..29e7e8046ef8 100644 --- a/drivers/gpu/drm/openchrome/openchrome_display.h +++ b/drivers/gpu/drm/openchrome/openchrome_display.h @@ -88,7 +88,7 @@ typedef struct _via_fp_info { struct via_crtc { struct drm_crtc base; - struct ttm_bo_kmap_obj cursor_kmap; + struct openchrome_bo *cursor_bo; struct crtc_timings pixel_timings; struct crtc_timings timings; struct vga_registers display_queue; diff --git a/drivers/gpu/drm/openchrome/openchrome_drv.c b/drivers/gpu/drm/openchrome/openchrome_drv.c index babb593ddbbc..1a23111dbde9 100644 --- a/drivers/gpu/drm/openchrome/openchrome_drv.c +++ b/drivers/gpu/drm/openchrome/openchrome_drv.c @@ -50,65 +50,83 @@ MODULE_DEVICE_TABLE(pci, via_pci_table); #define SGDMA_MEMORY (256*1024) #define VQ_MEMORY (256*1024) -static int via_dumb_create(struct drm_file *filp, - struct drm_device *dev, - struct drm_mode_create_dumb *args) + +void openchrome_drm_driver_gem_free_object_unlocked ( + struct drm_gem_object *obj) { - struct openchrome_drm_private *dev_private = dev->dev_private; - struct drm_gem_object *obj; - int ret; + struct openchrome_bo *bo = container_of(obj, + struct openchrome_bo, gem); DRM_DEBUG_KMS("Entered %s.\n", __func__); - args->pitch = round_up(args->width * (args->bpp >> 3), 16); - args->size = args->pitch * args->height; - obj = ttm_gem_create(dev, &dev_private->ttm.bdev, args->size, - ttm_bo_type_device, TTM_PL_FLAG_VRAM, - 16, PAGE_SIZE, false); - if (IS_ERR(obj)) - return PTR_ERR(obj); - - ret = drm_gem_handle_create(filp, obj, &args->handle); - /* drop reference from allocate - handle holds it now */ - drm_gem_object_put_unlocked(obj); + ttm_bo_put(&bo->ttm_bo); DRM_DEBUG_KMS("Exiting %s.\n", __func__); - return ret; } -static int via_dumb_mmap(struct drm_file *filp, struct drm_device *dev, - uint32_t handle, uint64_t *offset_p) +static int openchrome_drm_driver_dumb_create( + struct drm_file *file_priv, + struct drm_device *dev, + struct drm_mode_create_dumb *args) { - struct ttm_buffer_object *bo; - struct drm_gem_object *obj; - int rc = -ENOENT; + struct openchrome_drm_private *dev_private = dev->dev_private; + struct openchrome_bo *bo; + u32 handle; + int ret; DRM_DEBUG_KMS("Entered %s.\n", __func__); - obj = drm_gem_object_lookup(filp, handle); - if (obj == NULL) - return rc; + /* + * Calculate the parameters for the dumb buffer. + */ + args->pitch = args->width * ((args->bpp + 7) >> 3); + args->size = args->pitch * args->height; - bo = ttm_gem_mapping(obj); - if (bo != NULL) { - *offset_p = drm_vma_node_offset_addr(&bo->vma_node); - rc = 0; + ret = openchrome_bo_create(dev, + &dev_private->bdev, + args->size, + ttm_bo_type_device, + TTM_PL_FLAG_VRAM, + &bo); + if (ret) { + goto exit; } - drm_gem_object_put_unlocked(obj); + ret = drm_gem_handle_create(file_priv, &bo->gem, &handle); + drm_gem_object_put_unlocked(&bo->gem); + if (ret) { + goto exit; + } + + args->handle = handle; +exit: DRM_DEBUG_KMS("Exiting %s.\n", __func__); - return rc; + return ret; } -static int gem_dumb_destroy(struct drm_file *filp, - struct drm_device *dev, uint32_t handle) +static int openchrome_drm_driver_dumb_map_offset( + struct drm_file *file_priv, + struct drm_device *dev, + uint32_t handle, + uint64_t *offset) { - int ret; + struct drm_gem_object *gem; + struct openchrome_bo *bo; + int ret = 0; DRM_DEBUG_KMS("Entered %s.\n", __func__); - ret = drm_gem_handle_delete(filp, handle); + gem = drm_gem_object_lookup(file_priv, handle); + if (!gem) { + ret = -ENOENT; + goto exit; + } + + bo = container_of(gem, struct openchrome_bo, gem); + *offset = drm_vma_node_offset_addr(&bo->ttm_bo.vma_node); + drm_gem_object_put_unlocked(gem); +exit: DRM_DEBUG_KMS("Exiting %s.\n", __func__); return ret; } @@ -116,29 +134,56 @@ static int gem_dumb_destroy(struct drm_file *filp, static void via_driver_unload(struct drm_device *dev) { struct openchrome_drm_private *dev_private = dev->dev_private; - struct ttm_buffer_object *bo; + int ret; DRM_DEBUG_KMS("Entered %s.\n", __func__); if (drm_core_check_feature(dev, DRIVER_MODESET)) via_modeset_fini(dev); - bo = dev_private->vq.bo; - if (bo) { - via_bo_unpin(bo, &dev_private->vq); - ttm_bo_put(bo); + if (dev_private->vq_bo) { + ret = ttm_bo_reserve(&dev_private->vq_bo->ttm_bo, + true, false, NULL); + if (ret) { + goto exit_vq; + } + + ttm_bo_kunmap(&dev_private->vq_bo->kmap); + + ret = openchrome_bo_unpin(dev_private->vq_bo); + ttm_bo_unreserve(&dev_private->vq_bo->ttm_bo); + if (ret) { + goto exit_vq; + } + + ttm_bo_put(&dev_private->vq_bo->ttm_bo); } - bo = dev_private->gart.bo; - if (bo) { +exit_vq: + if (dev_private->gart_bo) { /* enable gtt write */ if (pci_is_pcie(dev->pdev)) svga_wseq_mask(VGABASE, 0x6C, 0, BIT(7)); - via_bo_unpin(bo, &dev_private->gart); - ttm_bo_put(bo); + + ret = ttm_bo_reserve(&dev_private->gart_bo->ttm_bo, + true, false, NULL); + if (ret) { + goto exit_gart; + } + + ttm_bo_kunmap(&dev_private->gart_bo->kmap); + + ret = openchrome_bo_unpin(dev_private->gart_bo); + ttm_bo_unreserve(&dev_private->gart_bo->ttm_bo); + if (ret) { + goto exit_gart; + } + + ttm_bo_put(&dev_private->gart_bo->ttm_bo); } - via_mm_fini(dev); +exit_gart: + openchrome_mm_fini(dev_private); /* * Unmap VRAM. @@ -157,6 +202,7 @@ static int via_driver_load(struct drm_device *dev, unsigned long chipset) { struct openchrome_drm_private *dev_private; + struct openchrome_bo *bo; int ret = 0; DRM_DEBUG_KMS("Entered %s.\n", __func__); @@ -181,7 +227,7 @@ static int via_driver_load(struct drm_device *dev, goto init_error; } - ret = via_mm_init(dev_private); + ret = openchrome_mm_init(dev_private); if (ret) { DRM_ERROR("Failed to initialize TTM.\n"); goto init_error; @@ -191,34 +237,75 @@ static int via_driver_load(struct drm_device *dev, if (pci_is_pcie(dev->pdev)) { /* Allocate GART. */ - ret = via_ttm_allocate_kernel_buffer( - &dev_private->ttm.bdev, - SGDMA_MEMORY, 16, + ret = openchrome_bo_create(dev, + &dev_private->bdev, + SGDMA_MEMORY, + ttm_bo_type_kernel, TTM_PL_FLAG_VRAM, - &dev_private->gart); - if (likely(!ret)) { - DRM_INFO("Allocated %u KB of DMA memory.\n", - SGDMA_MEMORY >> 10); - } else { + &bo); + if (ret) { DRM_ERROR("Failed to allocate DMA memory.\n"); goto init_error; } + + ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (ret) { + goto init_error; + } + + ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM); + if (ret) { + ttm_bo_unreserve(&bo->ttm_bo); + goto init_error; + } + + ret = ttm_bo_kmap(&bo->ttm_bo, 0, bo->ttm_bo.num_pages, + &bo->kmap); + ttm_bo_unreserve(&bo->ttm_bo); + if (ret) { + goto init_error; + } + + dev_private->gart_bo = bo; + DRM_INFO("Allocated %u KB of DMA memory.\n", + SGDMA_MEMORY >> 10); } /* Allocate VQ. (Virtual Queue) */ - ret = via_ttm_allocate_kernel_buffer(&dev_private->ttm.bdev, - VQ_MEMORY, 16, + ret = openchrome_bo_create(dev, + &dev_private->bdev, + VQ_MEMORY, + ttm_bo_type_kernel, TTM_PL_FLAG_VRAM, - &dev_private->vq); - if (likely(!ret)) { - DRM_INFO("Allocated %u KB of VQ (Virtual Queue) " - "memory.\n", VQ_MEMORY >> 10); - } else { + &bo); + if (ret) { DRM_ERROR("Failed to allocate VQ (Virtual Queue) " "memory.\n"); goto init_error; } + ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (ret) { + goto init_error; + } + + ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM); + if (ret) { + ttm_bo_unreserve(&bo->ttm_bo); + goto init_error; + } + + ret = ttm_bo_kmap(&bo->ttm_bo, 0, bo->ttm_bo.num_pages, + &bo->kmap); + ttm_bo_unreserve(&bo->ttm_bo); + if (ret) { + goto init_error; + } + + dev_private->vq_bo = bo; + DRM_INFO("Allocated %u KB of VQ (Virtual Queue) memory.\n", + VQ_MEMORY >> 10); + via_engine_init(dev); if (drm_core_check_feature(dev, DRIVER_MODESET)) { @@ -249,6 +336,35 @@ static void via_driver_lastclose(struct drm_device *dev) DRM_DEBUG_KMS("Exiting %s.\n", __func__); } +static int openchrome_drm_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct drm_file *file_priv; + struct openchrome_drm_private *dev_private; + int ret = -EINVAL; + + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + if (vma->vm_pgoff < DRM_FILE_PAGE_OFFSET) { + DRM_DEBUG_KMS("VMA Error.\n"); + ret = -EINVAL; + goto exit; + } + + file_priv = filp->private_data; + dev_private = file_priv->minor->dev->dev_private; + if (!dev_private) { + DRM_DEBUG_KMS("No device private data.\n"); + ret = -EINVAL; + goto exit; + } + + ret = ttm_bo_mmap(filp, vma, &dev_private->bdev); +exit: + DRM_DEBUG_KMS("ret: %d\n", ret); + DRM_DEBUG_KMS("Exiting %s.\n", __func__); + return ret; +} + static const struct dev_pm_ops openchrome_dev_pm_ops = { .suspend = openchrome_dev_pm_ops_suspend, .resume = openchrome_dev_pm_ops_resume, @@ -259,7 +375,7 @@ static const struct file_operations via_driver_fops = { .open = drm_open, .release = drm_release, .unlocked_ioctl = drm_ioctl, - .mmap = ttm_mmap, + .mmap = openchrome_drm_mmap, .poll = drm_poll, .llseek = noop_llseek, }; @@ -271,11 +387,11 @@ static struct drm_driver via_driver = { .load = via_driver_load, .unload = via_driver_unload, .lastclose = via_driver_lastclose, - .gem_open_object = ttm_gem_open_object, - .gem_free_object = ttm_gem_free_object, - .dumb_create = via_dumb_create, - .dumb_map_offset = via_dumb_mmap, - .dumb_destroy = gem_dumb_destroy, + .gem_free_object_unlocked = + openchrome_drm_driver_gem_free_object_unlocked, + .dumb_create = openchrome_drm_driver_dumb_create, + .dumb_map_offset = + openchrome_drm_driver_dumb_map_offset, .ioctls = via_ioctls, .fops = &via_driver_fops, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/openchrome/openchrome_drv.h b/drivers/gpu/drm/openchrome/openchrome_drv.h index e4fc71f3963a..af912336ed57 100644 --- a/drivers/gpu/drm/openchrome/openchrome_drv.h +++ b/drivers/gpu/drm/openchrome/openchrome_drv.h @@ -58,6 +58,8 @@ #define DRIVER_AUTHOR "OpenChrome Project" +#define OPENCHROME_TTM_PL_NUM 2 + #define VIA_MM_ALIGN_SIZE 16 #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) @@ -96,30 +98,23 @@ struct via_state { struct vga_regset seq_regs[256]; }; -struct via_ttm { - struct ttm_bo_device bdev; -}; - -struct ttm_heap { - struct ttm_buffer_object bo; - struct ttm_place busy_placements[TTM_NUM_MEM_TYPES]; - struct ttm_place placements[TTM_NUM_MEM_TYPES]; -}; - -struct ttm_gem_object { - struct drm_gem_object gem; - struct ttm_heap *heap; +struct openchrome_bo { + struct ttm_buffer_object ttm_bo; + struct ttm_bo_kmap_obj kmap; + struct ttm_placement placement; + struct ttm_place placements[OPENCHROME_TTM_PL_NUM]; + struct drm_gem_object gem; }; struct via_framebuffer { - struct drm_framebuffer fb; - struct drm_gem_object *gem_obj; + struct drm_framebuffer fb; + struct drm_gem_object *gem; }; struct via_framebuffer_device { - struct drm_fb_helper helper; - struct ttm_bo_kmap_obj kmap; - struct via_framebuffer via_fb; + struct drm_fb_helper helper; + struct via_framebuffer via_fb; + struct openchrome_bo *bo; }; enum via_engine { @@ -133,12 +128,15 @@ enum via_engine { struct openchrome_drm_private { struct drm_device *dev; - struct via_ttm ttm; + struct ttm_bo_device bdev; + + /* Set this flag for ttm_bo_device_init. */ + bool need_dma32; int revision; - struct ttm_bo_kmap_obj gart; - struct ttm_bo_kmap_obj vq; + struct openchrome_bo *gart_bo; + struct openchrome_bo *vq_bo; struct via_framebuffer_device *via_fbdev; u8 vram_type; @@ -260,6 +258,8 @@ extern int via_max_ioctl; extern int via_hdmi_audio; +extern struct ttm_bo_driver openchrome_bo_driver; + int openchrome_mmio_init(struct openchrome_drm_private *dev_private); void openchrome_mmio_fini(struct openchrome_drm_private *dev_private); void openchrome_graphics_unlock( @@ -279,46 +279,19 @@ extern int openchrome_vram_init( extern void openchrome_vram_fini( struct openchrome_drm_private *dev_private); -extern int via_mm_init(struct openchrome_drm_private *dev_private); -void via_mm_fini(struct drm_device *dev); -extern void ttm_placement_from_domain(struct ttm_buffer_object *bo, - struct ttm_placement *placement, - u32 domains, struct ttm_bo_device *bdev); -extern int via_bo_create(struct ttm_bo_device *bdev, - struct ttm_buffer_object **p_bo, - unsigned long size, +void openchrome_bo_destroy(struct ttm_buffer_object *tbo); +void openchrome_ttm_domain_to_placement(struct openchrome_bo *bo, + uint32_t ttm_domain); +int openchrome_bo_create(struct drm_device *dev, + struct ttm_bo_device *bdev, + uint64_t size, enum ttm_bo_type type, - uint32_t domains, - uint32_t byte_alignment, - uint32_t page_alignment, - bool interruptible, - struct sg_table *sg, - struct reservation_object *resv); -extern int via_bo_pin(struct ttm_buffer_object *bo, - struct ttm_bo_kmap_obj *kmap); -extern int via_bo_unpin(struct ttm_buffer_object *bo, - struct ttm_bo_kmap_obj *kmap); -extern int via_ttm_allocate_kernel_buffer(struct ttm_bo_device *bdev, - unsigned long size, - uint32_t alignment, uint32_t domain, - struct ttm_bo_kmap_obj *kmap); - - -extern int ttm_mmap(struct file *filp, struct vm_area_struct *vma); - -extern int ttm_gem_open_object(struct drm_gem_object *obj, - struct drm_file *file_priv); -extern void ttm_gem_free_object(struct drm_gem_object *obj); -extern struct drm_gem_object* ttm_gem_create(struct drm_device *dev, - struct ttm_bo_device *bdev, - unsigned long size, - enum ttm_bo_type type, - uint32_t domains, - uint32_t byte_alignment, - uint32_t page_alignment, - bool interruptible); -extern struct ttm_buffer_object* ttm_gem_mapping( - struct drm_gem_object *obj); + uint32_t ttm_domain, + struct openchrome_bo **bo_ptr); +int openchrome_bo_pin(struct openchrome_bo *bo, uint32_t ttm_domain); +int openchrome_bo_unpin(struct openchrome_bo *bo); +int openchrome_mm_init(struct openchrome_drm_private *dev_private); +void openchrome_mm_fini(struct openchrome_drm_private *dev_private); void openchrome_transmitter_io_pad_state( struct openchrome_drm_private *dev_private, diff --git a/drivers/gpu/drm/openchrome/openchrome_fb.c b/drivers/gpu/drm/openchrome/openchrome_fb.c index ae4191131f37..2b4981ae23ab 100644 --- a/drivers/gpu/drm/openchrome/openchrome_fb.c +++ b/drivers/gpu/drm/openchrome/openchrome_fb.c @@ -951,27 +951,35 @@ via_user_framebuffer_create_handle(struct drm_framebuffer *fb, struct drm_file *file_priv, unsigned int *handle) { - struct via_framebuffer *via_fb = - container_of(fb, struct via_framebuffer, fb); - struct drm_gem_object *gem_obj = via_fb->gem_obj; + struct via_framebuffer *via_fb = container_of(fb, + struct via_framebuffer, fb); + int ret; + + DRM_DEBUG_KMS("Entered %s.\n", __func__); - return drm_gem_handle_create(file_priv, gem_obj, handle); + ret = drm_gem_handle_create(file_priv, via_fb->gem, handle); + + DRM_DEBUG_KMS("Exiting %s.\n", __func__); + return ret; } static void via_user_framebuffer_destroy(struct drm_framebuffer *fb) { - struct via_framebuffer *via_fb = - container_of(fb, struct via_framebuffer, fb); - struct drm_gem_object *gem_obj = via_fb->gem_obj; + struct via_framebuffer *via_fb = container_of(fb, + struct via_framebuffer, fb); - if (gem_obj) { - drm_gem_object_put_unlocked(gem_obj); - via_fb->gem_obj = NULL; + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + if (via_fb->gem) { + drm_gem_object_put_unlocked(via_fb->gem); + via_fb->gem = NULL; } drm_framebuffer_cleanup(fb); kfree(via_fb); + + DRM_DEBUG_KMS("Exiting %s.\n", __func__); } static const struct drm_framebuffer_funcs via_fb_funcs = { @@ -993,11 +1001,11 @@ via_user_framebuffer_create(struct drm_device *dev, const struct drm_mode_fb_cmd2 *mode_cmd) { struct via_framebuffer *via_fb; - struct drm_gem_object *gem_obj; + struct drm_gem_object *gem; int ret; - gem_obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); - if (!gem_obj) { + gem = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); + if (!gem) { DRM_ERROR("No GEM object found for handle 0x%08X\n", mode_cmd->handles[0]); return ERR_PTR(-ENOENT); @@ -1008,12 +1016,13 @@ via_user_framebuffer_create(struct drm_device *dev, return ERR_PTR(-ENOMEM); } - via_fb->gem_obj = gem_obj; + via_fb->gem = gem; drm_helper_mode_fill_fb_struct(dev, &via_fb->fb, mode_cmd); ret = drm_framebuffer_init(dev, &via_fb->fb, &via_fb_funcs); if (ret) { - drm_gem_object_put(gem_obj); + drm_gem_object_put_unlocked(via_fb->gem); + via_fb->gem = NULL; kfree(via_fb); return ERR_PTR(ret); } @@ -1087,15 +1096,15 @@ via_fb_probe(struct drm_fb_helper *helper, helper->dev->dev_private; struct via_framebuffer_device *via_fbdev = container_of(helper, struct via_framebuffer_device, helper); - struct ttm_bo_kmap_obj *kmap = &via_fbdev->kmap; struct via_framebuffer *via_fb = &via_fbdev->via_fb; struct drm_framebuffer *fb = &via_fbdev->via_fb.fb; struct fb_info *info = helper->fbdev; - struct drm_gem_object *gem_obj; + struct openchrome_bo *bo; struct drm_mode_fb_cmd2 mode_cmd; struct apertures_struct *ap; int size, cpp; int ret = 0; + int fake_ret = 0; DRM_DEBUG_KMS("Entered %s.\n", __func__); @@ -1110,24 +1119,36 @@ via_fb_probe(struct drm_fb_helper *helper, size = mode_cmd.pitches[0] * mode_cmd.height; size = ALIGN(size, PAGE_SIZE); - gem_obj = ttm_gem_create(dev, &dev_private->ttm.bdev, size, - ttm_bo_type_kernel, TTM_PL_FLAG_VRAM, - 1, PAGE_SIZE, false); - if (unlikely(IS_ERR(gem_obj))) { - ret = PTR_ERR(gem_obj); + ret = openchrome_bo_create(dev, + &dev_private->bdev, + size, + ttm_bo_type_kernel, + TTM_PL_FLAG_VRAM, + &bo); + if (ret) { + goto exit; + } + + ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (ret) { goto out_err; } - kmap->bo = ttm_gem_mapping(gem_obj); - if (!kmap->bo) { + ret = openchrome_bo_pin(bo, TTM_PL_FLAG_VRAM); + if (ret) { + ttm_bo_unreserve(&bo->ttm_bo); goto out_err; } - ret = via_bo_pin(kmap->bo, kmap); - if (unlikely(ret)) { + ret = ttm_bo_kmap(&bo->ttm_bo, 0, bo->ttm_bo.num_pages, + &bo->kmap); + ttm_bo_unreserve(&bo->ttm_bo); + if (ret) { goto out_err; } + via_fbdev->bo = bo; + info = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(info)) { ret = PTR_ERR(info); @@ -1143,7 +1164,7 @@ via_fb_probe(struct drm_fb_helper *helper, goto out_err; } - via_fb->gem_obj = gem_obj; + via_fb->gem = &bo->gem; via_fbdev->helper.fb = fb; via_fbdev->helper.fbdev = info; @@ -1152,10 +1173,10 @@ via_fb_probe(struct drm_fb_helper *helper, info->fbops = &via_fb_ops; - info->fix.smem_start = kmap->bo->mem.bus.base + - kmap->bo->mem.bus.offset; + info->fix.smem_start = bo->kmap.bo->mem.bus.base + + bo->kmap.bo->mem.bus.offset; info->fix.smem_len = size; - info->screen_base = kmap->virtual; + info->screen_base = bo->kmap.virtual; info->screen_size = size; /* Setup aperture base / size for takeover (i.e., vesafb). */ @@ -1165,9 +1186,9 @@ via_fb_probe(struct drm_fb_helper *helper, goto out_err; } - ap->ranges[0].size = kmap->bo->bdev-> - man[kmap->bo->mem.mem_type].size; - ap->ranges[0].base = kmap->bo->mem.bus.base; + ap->ranges[0].size = bo->kmap.bo->bdev-> + man[bo->kmap.bo->mem.mem_type].size; + ap->ranges[0].base = bo->kmap.bo->mem.bus.base; info->apertures = ap; drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); @@ -1175,14 +1196,26 @@ via_fb_probe(struct drm_fb_helper *helper, sizes->fb_width, sizes->fb_height); goto exit; out_err: - if (kmap->bo) { - via_bo_unpin(kmap->bo, kmap); - ttm_bo_put(kmap->bo); + if (bo->kmap.bo) { + fake_ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (fake_ret) { + goto exit; + } + + ttm_bo_kunmap(&bo->kmap); + + fake_ret = openchrome_bo_unpin(bo); + if (fake_ret) { + ttm_bo_unreserve(&bo->ttm_bo); + goto exit; + } + + ttm_bo_put(&bo->ttm_bo); } - if (gem_obj) { - drm_gem_object_put_unlocked(gem_obj); - via_fb->gem_obj = NULL; + if (via_fb->gem) { + drm_gem_object_put_unlocked(via_fb->gem); + via_fb->gem = NULL; } exit: DRM_DEBUG_KMS("Exiting %s.\n", __func__); @@ -1264,9 +1297,9 @@ void via_fbdev_fini(struct drm_device *dev) fb_helper->fbdev = NULL; } - if (via_fb->gem_obj) { - drm_gem_object_put_unlocked(via_fb->gem_obj); - via_fb->gem_obj = NULL; + if (via_fb->gem) { + drm_gem_object_put_unlocked(via_fb->gem); + via_fb->gem = NULL; } drm_fb_helper_fini(&dev_private->via_fbdev->helper); diff --git a/drivers/gpu/drm/openchrome/openchrome_gem.c b/drivers/gpu/drm/openchrome/openchrome_gem.c deleted file mode 100644 index bb18f957fe1c..000000000000 --- a/drivers/gpu/drm/openchrome/openchrome_gem.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2012 James Simmons <jsimm...@infradead.org>. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#include <drm/drmP.h> - -#include "openchrome_drv.h" - -/* - * initialize the gem buffer object - */ -int ttm_gem_open_object(struct drm_gem_object *obj, struct drm_file *file_priv) -{ - return 0; -} - -/* - * free the gem buffer object - */ -void ttm_gem_free_object(struct drm_gem_object *obj) -{ - struct ttm_gem_object *gem = container_of(obj, struct ttm_gem_object, gem); - struct ttm_buffer_object *bo; - - if (gem->heap != NULL) { - bo = &gem->heap->bo; - ttm_bo_put(bo); - gem->heap = NULL; - } - drm_gem_object_release(obj); - kfree(gem); -} - -struct ttm_buffer_object * -ttm_gem_mapping(struct drm_gem_object *obj) -{ - struct ttm_gem_object *gem; - - gem = container_of(obj, struct ttm_gem_object, gem); - if (gem->heap == NULL) - return NULL; - return &gem->heap->bo; -} - -/* - * file operation mmap - */ -int ttm_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct openchrome_drm_private *dev_private; - struct drm_file *file_priv; - - if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) - return -EINVAL; - - file_priv = filp->private_data; - dev_private = file_priv->minor->dev->dev_private; - if (!dev_private) - return -EINVAL; - - return ttm_bo_mmap(filp, vma, &dev_private->ttm.bdev); -} - -struct drm_gem_object * -ttm_gem_create(struct drm_device *dev, - struct ttm_bo_device *bdev, - unsigned long size, - enum ttm_bo_type type, - uint32_t domains, - uint32_t byte_alignment, - uint32_t page_alignment, - bool interruptible) -{ - struct ttm_buffer_object *bo = NULL; - struct ttm_gem_object *obj; - int ret; - - obj = kzalloc(sizeof(struct ttm_gem_object), GFP_KERNEL); - if (!obj) { - return ERR_PTR(-ENOMEM); - } - - size = round_up(size, byte_alignment); - size = ALIGN(size, page_alignment); - ret = via_bo_create(bdev, &bo, size, type, domains, - byte_alignment, page_alignment, - interruptible, NULL, NULL); - if (ret) { - DRM_ERROR("Failed to create buffer object\n"); - return ERR_PTR(ret); - } - - ret = drm_gem_object_init(dev, &obj->gem, size); - if (unlikely(ret)) { - ttm_bo_put(bo); - return ERR_PTR(ret); - } - - obj->heap = container_of(bo, struct ttm_heap, bo); - bo->persistent_swap_storage = obj->gem.filp; - return &obj->gem; -} diff --git a/drivers/gpu/drm/openchrome/openchrome_init.c b/drivers/gpu/drm/openchrome/openchrome_init.c index 6bcd434a464f..9b5aaef09640 100644 --- a/drivers/gpu/drm/openchrome/openchrome_init.c +++ b/drivers/gpu/drm/openchrome/openchrome_init.c @@ -259,6 +259,9 @@ void openchrome_flag_init(struct openchrome_drm_private *dev_private) { DRM_DEBUG_KMS("Entered %s.\n", __func__); + /* Set this flag for ttm_bo_device_init. */ + dev_private->need_dma32 = true; + /* * Special handling flags for a few special models. */ @@ -453,18 +456,18 @@ static void via_init_vq(struct openchrome_drm_private *dev_private) { unsigned long vq_start_addr, vq_end_addr, vqlen; unsigned long vqstartl, vqendl, vqstart_endh; - struct ttm_buffer_object *bo = dev_private->vq.bo; + struct openchrome_bo *bo = dev_private->vq_bo; - if (!bo) + if (!bo->kmap.bo) return; - vq_start_addr = bo->offset; - vq_end_addr = vq_start_addr + bo->mem.size - 1; + vq_start_addr = bo->kmap.bo->offset; + vq_end_addr = vq_start_addr + bo->kmap.bo->mem.size - 1; vqstartl = 0x70000000 | (vq_start_addr & 0xFFFFFF); vqendl = 0x71000000 | (vq_end_addr & 0xFFFFFF); vqstart_endh = 0x72000000 | ((vq_start_addr & 0xFF000000) >> 24) | ((vq_end_addr & 0xFF000000) >> 16); - vqlen = 0x73000000 | (bo->mem.size >> 3); + vqlen = 0x73000000 | (bo->kmap.bo->mem.size >> 3); VIA_WRITE(0x41c, 0x00100000); VIA_WRITE(0x420, vqstart_endh); @@ -479,24 +482,24 @@ static void via_init_pcie_gart_table( struct openchrome_drm_private *dev_private, struct pci_dev *pdev) { - struct ttm_buffer_object *bo = dev_private->gart.bo; + struct openchrome_bo *bo = dev_private->gart_bo; u8 value; - if (!pci_is_pcie(pdev) || !bo) + if (!pci_is_pcie(pdev) || !bo->kmap.bo) return; /* enable gtt write */ svga_wseq_mask(VGABASE, 0x6C, 0x00, BIT(7)); /* set the base address of gart table */ - value = (bo->offset & 0xff000) >> 12; + value = (bo->kmap.bo->offset & 0xff000) >> 12; vga_wseq(VGABASE, 0x6A, value); - value = (bo->offset & 0xff000) >> 20; + value = (bo->kmap.bo->offset & 0xff000) >> 20; vga_wseq(VGABASE, 0x6B, value); value = vga_rseq(VGABASE, 0x6C); - value |= ((bo->offset >> 28) & 0x01); + value |= ((bo->kmap.bo->offset >> 28) & 0x01); vga_wseq(VGABASE, 0x6C, value); /* flush the gtt cache */ diff --git a/drivers/gpu/drm/openchrome/openchrome_ioc32.c b/drivers/gpu/drm/openchrome/openchrome_ioc32.c index 4675249118c0..42bc54238da4 100644 --- a/drivers/gpu/drm/openchrome/openchrome_ioc32.c +++ b/drivers/gpu/drm/openchrome/openchrome_ioc32.c @@ -63,102 +63,132 @@ static int via_gem_alloc(struct drm_device *dev, void *data, struct drm_file *filp) { - struct openchrome_drm_private *dev_private = dev->dev_private; struct drm_via_gem_object *args = data; - struct drm_gem_object *obj; - int ret = -ENOMEM; - - obj = ttm_gem_create(dev, &dev_private->ttm.bdev, args->size, - ttm_bo_type_device, args->domains, - args->alignment, PAGE_SIZE, false); - if (obj != NULL) { - ret = drm_gem_handle_create(filp, obj, &args->handle); - /* drop reference from allocate - handle holds it now */ - drm_gem_object_put_unlocked(obj); - if (!ret) { - struct ttm_buffer_object *bo = ttm_gem_mapping(obj); + struct openchrome_drm_private *dev_private = dev->dev_private; + struct openchrome_bo *bo; + uint32_t handle; + int ret; - args->map_handle = drm_vma_node_offset_addr(&bo->vma_node); - args->domains = bo->mem.placement & TTM_PL_MASK_MEM; - args->offset = bo->offset; - args->size = bo->mem.size; - args->version = 1; - } + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + ret = openchrome_bo_create(dev, + &dev_private->bdev, + args->size, + ttm_bo_type_device, + args->domains, + &bo); + + if (ret) { + goto exit; + } + + ret = drm_gem_handle_create(filp, &bo->gem, + &handle); + + /* Drop reference from allocate; handle holds it now. */ + drm_gem_object_put_unlocked(&bo->gem); + + if (ret) { + ttm_bo_put(&bo->ttm_bo); + goto exit; } + + args->size = bo->ttm_bo.mem.size; + args->domains = bo->ttm_bo.mem.placement & + TTM_PL_MASK_MEM; + args->offset = bo->ttm_bo.offset; + args->map_handle = drm_vma_node_offset_addr( + &bo->ttm_bo.vma_node); + args->handle = handle; + args->version = 1; + +exit: + DRM_DEBUG_KMS("Exiting %s.\n", __func__); return ret; } static int via_gem_state(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_via_gem_object *args = data; - struct ttm_buffer_object *bo = NULL; - struct drm_gem_object *obj = NULL; - struct ttm_placement placement; struct ttm_operation_ctx ctx = {.interruptible = false, .no_wait_gpu = false}; + struct drm_gem_object *gem; + struct drm_via_gem_object *args = data; + struct openchrome_bo *bo; int ret = -EINVAL; - obj = drm_gem_object_lookup(file_priv, args->handle); - if (obj == NULL) - return ret; + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + gem = drm_gem_object_lookup(file_priv, args->handle); + if (!gem) { + goto exit; + } - bo = ttm_gem_mapping(obj); - if (bo == NULL) - return ret; + bo = container_of(gem, struct openchrome_bo, gem); /* Don't bother to migrate to same domain */ - args->domains &= ~(bo->mem.placement & TTM_PL_MASK_MEM); + args->domains &= ~(bo->ttm_bo.mem.placement & TTM_PL_MASK_MEM); if (args->domains) { - ret = ttm_bo_reserve(bo, true, false, NULL); - if (unlikely(ret)) - return ret; + ret = ttm_bo_reserve(&bo->ttm_bo, true, false, NULL); + if (ret) { + goto exit; + } - ttm_placement_from_domain(bo, &placement, args->domains, bo->bdev); - ret = ttm_bo_validate(bo, &placement, &ctx); - ttm_bo_unreserve(bo); + openchrome_ttm_domain_to_placement(bo, args->domains); + ret = ttm_bo_validate(&bo->ttm_bo, &bo->placement, + &ctx); + ttm_bo_unreserve(&bo->ttm_bo); if (!ret) { - args->map_handle = drm_vma_node_offset_addr(&bo->vma_node); - args->domains = bo->mem.placement & TTM_PL_MASK_MEM; - args->offset = bo->offset; - args->size = bo->mem.size; + args->size = bo->ttm_bo.mem.size; + args->domains = bo->ttm_bo.mem.placement & + TTM_PL_MASK_MEM; + args->offset = bo->ttm_bo.offset; + args->map_handle = drm_vma_node_offset_addr( + &bo->ttm_bo.vma_node); } } + mutex_lock(&dev->struct_mutex); - drm_gem_object_put(obj); + drm_gem_object_put(gem); mutex_unlock(&dev->struct_mutex); +exit: + DRM_DEBUG_KMS("Exiting %s.\n", __func__); return ret; } static int via_gem_wait(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_gem_object *gem; struct drm_via_gem_wait *args = data; - struct ttm_buffer_object *bo; - struct drm_gem_object *obj; + struct openchrome_bo *bo; int ret = -EINVAL; bool no_wait; - obj = drm_gem_object_lookup(file_priv, args->handle); - if (obj == NULL) - return ret; + DRM_DEBUG_KMS("Entered %s.\n", __func__); - bo = ttm_gem_mapping(obj); - if (bo == NULL) - return ret; + gem = drm_gem_object_lookup(file_priv, args->handle); + if (!gem) { + goto exit; + } + + bo = container_of(gem, struct openchrome_bo, gem); no_wait = (args->no_wait != 0); - ret = ttm_bo_reserve(bo, true, no_wait, NULL); - if (unlikely(ret != 0)) - return ret; + ret = ttm_bo_reserve(&bo->ttm_bo, true, no_wait, NULL); + if (ret) { + goto exit; + } - ret = ttm_bo_wait(bo, true, no_wait); - ttm_bo_unreserve(bo); + ret = ttm_bo_wait(&bo->ttm_bo, true, no_wait); + ttm_bo_unreserve(&bo->ttm_bo); mutex_lock(&dev->struct_mutex); - drm_gem_object_put(obj); + drm_gem_object_put(gem); mutex_unlock(&dev->struct_mutex); +exit: + DRM_DEBUG_KMS("Exiting %s.\n", __func__); return ret; } diff --git a/drivers/gpu/drm/openchrome/openchrome_object.c b/drivers/gpu/drm/openchrome/openchrome_object.c new file mode 100644 index 000000000000..2cd8d2ebe195 --- /dev/null +++ b/drivers/gpu/drm/openchrome/openchrome_object.c @@ -0,0 +1,233 @@ +/* + * Copyright © 2018-2019 Kevin Brace + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including + * the next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/* + * Author(s): + * + * Kevin Brace <kevinbr...@gmx.com> + */ +/* + * openchrome_object.c + * + * Manages Buffer Objects (BO) via TTM. + * Part of the TTM memory allocator. + * + */ + +#include <drm/ttm/ttm_bo_api.h> +#include <drm/ttm/ttm_bo_driver.h> + +#include "openchrome_drv.h" + + +void openchrome_bo_destroy(struct ttm_buffer_object *tbo) +{ + struct openchrome_bo *bo = container_of(tbo, + struct openchrome_bo, ttm_bo); + + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + drm_gem_object_release(&bo->gem); + kfree(bo); + + DRM_DEBUG_KMS("Exiting %s.\n", __func__); +} + +void openchrome_ttm_domain_to_placement(struct openchrome_bo *bo, + uint32_t ttm_domain) +{ + unsigned i = 0; + + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + bo->placement.placement = bo->placements; + bo->placement.busy_placement = bo->placements; + + if (ttm_domain & TTM_PL_FLAG_SYSTEM) { + bo->placements[i].fpfn = 0; + bo->placements[i].lpfn = 0; + bo->placements[i].flags = TTM_PL_FLAG_CACHED | + TTM_PL_FLAG_SYSTEM; + i++; + } + + if (ttm_domain & TTM_PL_FLAG_TT) { + bo->placements[i].fpfn = 0; + bo->placements[i].lpfn = 0; + bo->placements[i].flags = TTM_PL_FLAG_CACHED | + TTM_PL_FLAG_TT; + i++; + } + + if (ttm_domain & TTM_PL_FLAG_VRAM) { + bo->placements[i].fpfn = 0; + bo->placements[i].lpfn = 0; + bo->placements[i].flags = TTM_PL_FLAG_WC | + TTM_PL_FLAG_UNCACHED | + TTM_PL_FLAG_VRAM; + i++; + } + + bo->placement.num_placement = i; + bo->placement.num_busy_placement = i; + + DRM_DEBUG_KMS("Exiting %s.\n", __func__); +} + +int openchrome_bo_create(struct drm_device *dev, + struct ttm_bo_device *bdev, + uint64_t size, + enum ttm_bo_type type, + uint32_t ttm_domain, + struct openchrome_bo **bo_ptr) +{ + struct openchrome_drm_private *dev_private = dev->dev_private; + struct openchrome_bo *bo; + size_t acc_size; + int ret; + + DRM_DEBUG_KMS("Entered %s.\n", __func__); + +// bo = kzalloc(sizeof(struct openchrome_bo), GFP_KERNEL); + bo = kzalloc(sizeof(*bo), GFP_KERNEL); + if (!bo) { + DRM_ERROR("Cannot allocate a TTM buffer object.\n"); + ret = -ENOMEM; + goto exit; + } + + size = ALIGN(size, PAGE_SIZE); + openchrome_ttm_domain_to_placement(bo, ttm_domain); + acc_size = ttm_bo_dma_acc_size(&dev_private->bdev, size, + sizeof(struct openchrome_bo)); + ret = ttm_bo_init(&dev_private->bdev, + &bo->ttm_bo, + size, + type, + &bo->placement, + PAGE_SIZE, false, acc_size, + NULL, NULL, + openchrome_bo_destroy); + if (ret) { + DRM_ERROR("Cannot initialize a TTM object.\n"); + goto error; + } + + ret = drm_gem_object_init(dev, &bo->gem, size); + if (ret) { + ttm_bo_put(&bo->ttm_bo); + DRM_ERROR("Cannot initialize a GEM object.\n"); + goto error; + } + + *bo_ptr = bo; + goto exit; +error: + kfree(bo); +exit: + DRM_DEBUG_KMS("Exiting %s.\n", __func__); + return ret; +} + +int openchrome_bo_pin(struct openchrome_bo *bo, + uint32_t ttm_domain) +{ + struct ttm_operation_ctx ctx = {false, false}; + uint32_t i; + int ret; + + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + openchrome_ttm_domain_to_placement(bo, ttm_domain); + for (i = 0; i < bo->placement.num_placement; i++) { + bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT; + } + + ret = ttm_bo_validate(&bo->ttm_bo, &bo->placement, &ctx); + + DRM_DEBUG_KMS("Exiting %s.\n", __func__); + return ret; +} + +int openchrome_bo_unpin(struct openchrome_bo *bo) +{ + struct ttm_operation_ctx ctx = {false, false}; + uint32_t i; + int ret; + + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + for (i = 0; i < bo->placement.num_placement; i++) { + bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; + } + + ret = ttm_bo_validate(&bo->ttm_bo, &bo->placement, &ctx); + + DRM_DEBUG_KMS("Exiting %s.\n", __func__); + return ret; +} + +int openchrome_mm_init(struct openchrome_drm_private *dev_private) +{ + struct drm_device *dev = dev_private->dev; + int ret; + + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + /* + * Initialize bdev ttm_bo_device struct. + */ + ret = ttm_bo_device_init(&dev_private->bdev, + &openchrome_bo_driver, + dev->anon_inode->i_mapping, + DRM_FILE_PAGE_OFFSET, + dev_private->need_dma32); + if (ret) { + DRM_ERROR("Failed initializing buffer object driver.\n"); + goto exit; + } + + /* + * Initialize TTM memory manager for VRAM management. + */ + ret = ttm_bo_init_mm(&dev_private->bdev, TTM_PL_VRAM, + dev_private->vram_size >> PAGE_SHIFT); + if (ret) { + DRM_ERROR("Failed initializing TTM VRAM memory manager.\n"); + goto exit; + } + +exit: + DRM_DEBUG_KMS("Exiting %s.\n", __func__); + return ret; +} + +void openchrome_mm_fini(struct openchrome_drm_private *dev_private) +{ + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + ttm_bo_device_release(&dev_private->bdev); + + DRM_DEBUG_KMS("Exiting %s.\n", __func__); +} diff --git a/drivers/gpu/drm/openchrome/openchrome_ttm.c b/drivers/gpu/drm/openchrome/openchrome_ttm.c index 8baf1fce55ee..9a4bfdf4c86f 100644 --- a/drivers/gpu/drm/openchrome/openchrome_ttm.c +++ b/drivers/gpu/drm/openchrome/openchrome_ttm.c @@ -1,386 +1,173 @@ /* - * Copyright 2012 James Simmons <jsimm...@infradead.org>. All Rights Reserved. + * Copyright © 2018-2019 Kevin Brace * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. + * The above copyright notice and this permission notice (including + * the next paragraph) shall be included in all copies or substantial + * portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ +/* + * Author(s): + * + * Kevin Brace <kevinbr...@gmx.com> + */ +/* + * openchrome_ttm.c + * + * TTM code as part of the TTM memory allocator. + * Currently a basic implementation with no DMA support. + * + */ -#include <linux/dma-mapping.h> -#ifdef CONFIG_SWIOTLB -#include <linux/swiotlb.h> -#endif #include "openchrome_drv.h" -#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) - -static void via_ttm_bo_destroy(struct ttm_buffer_object *bo) +static int openchrome_bo_init_mem_type(struct ttm_bo_device *bdev, + uint32_t type, + struct ttm_mem_type_manager *man) { - struct ttm_heap *heap = container_of(bo, struct ttm_heap, bo); + int ret = 0; - kfree(heap); - heap = NULL; -} - -static int via_invalidate_caches(struct ttm_bo_device *bdev, - uint32_t flags) -{ - /* - * FIXME: Invalidate texture caches here. - */ - return 0; -} + DRM_DEBUG_KMS("Entered %s.\n", __func__); -static int via_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, - struct ttm_mem_type_manager *man) -{ switch (type) { case TTM_PL_SYSTEM: - /* System memory */ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_MASK_CACHING; + man->available_caching = TTM_PL_FLAG_CACHED; man->default_caching = TTM_PL_FLAG_CACHED; break; - - case TTM_PL_TT: - man->func = &ttm_bo_manager_func; - - /* By default we handle PCI/PCIe DMA. */ - man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | - TTM_MEMTYPE_FLAG_CMA; - man->available_caching = TTM_PL_MASK_CACHING; - man->default_caching = TTM_PL_FLAG_CACHED; - break; - case TTM_PL_VRAM: - /* "On-card" video ram */ - man->func = &ttm_bo_manager_func; man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE; + man->gpu_offset = 0; man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; man->default_caching = TTM_PL_FLAG_WC; - /* The display base address does not always equal the start of - * the memory region of the VRAM. In our case it is */ - man->gpu_offset = 0; - break; - - case TTM_PL_PRIV: - /* MMIO region */ man->func = &ttm_bo_manager_func; - man->flags = TTM_MEMTYPE_FLAG_FIXED | - TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_UNCACHED; - man->default_caching = TTM_PL_FLAG_UNCACHED; break; - default: - DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); - return -EINVAL; - } - return 0; -} - -static void via_evict_flags(struct ttm_buffer_object *bo, - struct ttm_placement *placement) -{ - switch (bo->mem.mem_type) { - case TTM_PL_VRAM: - ttm_placement_from_domain(bo, placement, - TTM_PL_FLAG_TT | TTM_PL_FLAG_SYSTEM, - bo->bdev); - break; - - case TTM_PL_TT: - default: - ttm_placement_from_domain(bo, placement, - TTM_PL_FLAG_SYSTEM, - bo->bdev); - break; - } -} - -static int via_ttm_io_mem_reserve(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem) -{ - struct openchrome_drm_private *dev_private = - container_of(bdev, - struct openchrome_drm_private, - ttm.bdev); - struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; - struct drm_device *dev = dev_private->dev; - - mem->bus.base = 0; - mem->bus.addr = NULL; - mem->bus.offset = mem->start << PAGE_SHIFT; - mem->bus.size = mem->num_pages << PAGE_SHIFT; - mem->bus.is_iomem = true; - if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) - return -EINVAL; - - switch (mem->mem_type) { - case TTM_PL_SYSTEM: - /* system memory */ - mem->bus.is_iomem = false; - mem->bus.offset = 0; - return 0; - - case TTM_PL_TT: + DRM_ERROR("Unsupported TTM memory type.\n"); + ret = -EINVAL; break; - - case TTM_PL_PRIV: - mem->bus.base = pci_resource_start(dev->pdev, 1); - break; - - case TTM_PL_VRAM: - if (dev->pdev->device == PCI_DEVICE_ID_VIA_VX900_VGA) - mem->bus.base = pci_resource_start(dev->pdev, 2); - else - mem->bus.base = pci_resource_start(dev->pdev, 0); - break; - - default: - return -EINVAL; } - return 0; -} -static void via_ttm_io_mem_free(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem) -{ -} - -static int via_verify_access(struct ttm_buffer_object *bo, - struct file *filp) -{ - return 0; + DRM_DEBUG_KMS("Exiting %s.\n", __func__); + return ret; } -static struct ttm_bo_driver via_bo_driver = { - .invalidate_caches = via_invalidate_caches, - .init_mem_type = via_init_mem_type, - .evict_flags = via_evict_flags, - .verify_access = via_verify_access, - .io_mem_reserve = via_ttm_io_mem_reserve, - .io_mem_free = via_ttm_io_mem_free, -}; - -int via_mm_init(struct openchrome_drm_private *dev_private) +static void openchrome_bo_evict_flags(struct ttm_buffer_object *bo, + struct ttm_placement *placement) { - struct drm_device *dev = dev_private->dev; - int ret; + struct openchrome_bo *driver_bo = container_of(bo, + struct openchrome_bo, ttm_bo); DRM_DEBUG_KMS("Entered %s.\n", __func__); - dev_private->ttm.bdev.dev_mapping = dev->anon_inode->i_mapping; - - ret = ttm_bo_device_init(&dev_private->ttm.bdev, - &via_bo_driver, - dev->anon_inode->i_mapping, - DRM_FILE_PAGE_OFFSET, - false); - if (ret) { - DRM_ERROR("Error initialising bo driver: %d\n", ret); + if (bo->destroy == &openchrome_bo_destroy) { goto exit; } - ret = ttm_bo_init_mm(&dev_private->ttm.bdev, TTM_PL_VRAM, - dev_private->vram_size >> PAGE_SHIFT); - if (ret) { - DRM_ERROR("Failed to map video RAM: %d\n", ret); - goto exit; + switch (bo->mem.mem_type) { + case TTM_PL_VRAM: + openchrome_ttm_domain_to_placement(driver_bo, + TTM_PL_FLAG_VRAM); + break; + default: + openchrome_ttm_domain_to_placement(driver_bo, + TTM_PL_FLAG_SYSTEM); + break; } + *placement = driver_bo->placement; exit: DRM_DEBUG_KMS("Exiting %s.\n", __func__); - return ret; } -void via_mm_fini(struct drm_device *dev) +static int openchrome_bo_verify_access(struct ttm_buffer_object *bo, + struct file *filp) { - struct openchrome_drm_private *dev_private = dev->dev_private; - DRM_DEBUG_KMS("Entered %s.\n", __func__); - ttm_bo_device_release(&dev_private->ttm.bdev); - DRM_DEBUG_KMS("Exiting %s.\n", __func__); + return 0; } -/* - * the buffer object domain - */ -void ttm_placement_from_domain(struct ttm_buffer_object *bo, - struct ttm_placement *placement, - u32 domains, - struct ttm_bo_device *bdev) -{ - struct ttm_heap *heap = container_of(bo, struct ttm_heap, bo); - int cnt = 0, i = 0; - - if (!(domains & TTM_PL_MASK_MEM)) - domains = TTM_PL_FLAG_SYSTEM; - - do { - int domain = (domains & (1 << i)); - - if (domain) { - heap->busy_placements[cnt].flags = - (domain | bdev->man[i].default_caching); - heap->busy_placements[cnt].fpfn = - heap->busy_placements[cnt].lpfn = 0; - heap->placements[cnt].flags = - (domain | bdev->man[i].available_caching); - heap->placements[cnt].fpfn = - heap->placements[cnt].lpfn = 0; - cnt++; - } - } while (i++ < TTM_NUM_MEM_TYPES); - - placement->num_busy_placement = placement->num_placement = cnt; - placement->busy_placement = heap->busy_placements; - placement->placement = heap->placements; -} - -int via_bo_create(struct ttm_bo_device *bdev, - struct ttm_buffer_object **p_bo, - unsigned long size, - enum ttm_bo_type type, - uint32_t domains, - uint32_t byte_alignment, - uint32_t page_alignment, - bool interruptible, - struct sg_table *sg, - struct reservation_object *resv) +static int openchrome_bo_io_mem_reserve(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem) { - struct ttm_buffer_object *bo = NULL; - struct ttm_placement placement; - struct ttm_heap *heap; - size_t acc_size; - int ret = -ENOMEM; + struct openchrome_drm_private *dev_private = container_of(bdev, + struct openchrome_drm_private, bdev); + struct drm_device *dev = dev_private->dev; + struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; + int ret = 0; DRM_DEBUG_KMS("Entered %s.\n", __func__); - size = round_up(size, byte_alignment); - size = ALIGN(size, page_alignment); - - heap = kzalloc(sizeof(struct ttm_heap), GFP_KERNEL); - if (unlikely(!heap)) { - DRM_ERROR("Failed to allocate kernel memory."); + if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) { + ret= -EINVAL; goto exit; } - bo = &heap->bo; - - ttm_placement_from_domain(bo, &placement, domains, bdev); - - acc_size = ttm_bo_dma_acc_size(bdev, size, - sizeof(struct ttm_heap)); - - ret = ttm_bo_init(bdev, bo, size, type, &placement, - page_alignment >> PAGE_SHIFT, - interruptible, acc_size, - sg, NULL, via_ttm_bo_destroy); + switch (mem->mem_type) { + case TTM_PL_SYSTEM: + mem->bus.addr = NULL; + mem->bus.base = 0; + mem->bus.size = mem->num_pages << PAGE_SHIFT; + mem->bus.offset = 0; + mem->bus.is_iomem = false; + break; + case TTM_PL_VRAM: + mem->bus.addr = NULL; + if (dev->pdev->device == PCI_DEVICE_ID_VIA_VX900_VGA) { + mem->bus.base = pci_resource_start(dev->pdev, 2); + } else { + mem->bus.base = pci_resource_start(dev->pdev, 0); + } - if (unlikely(ret)) { - DRM_ERROR("Failed to initialize a TTM Buffer Object."); - goto error; + mem->bus.size = mem->num_pages << PAGE_SHIFT; + mem->bus.offset = mem->start << PAGE_SHIFT; + mem->bus.is_iomem = true; + break; + default: + ret = -EINVAL; + break; } - *p_bo = bo; - goto exit; -error: - kfree(heap); exit: DRM_DEBUG_KMS("Exiting %s.\n", __func__); return ret; } -int via_bo_pin(struct ttm_buffer_object *bo, - struct ttm_bo_kmap_obj *kmap) -{ - struct ttm_heap *heap = container_of(bo, struct ttm_heap, bo); - struct ttm_placement placement; - struct ttm_operation_ctx ctx = { - .interruptible = false, - .no_wait_gpu = false - }; - int ret; - - ret = ttm_bo_reserve(bo, true, false, NULL); - if (!ret) { - placement.placement = heap->placements; - placement.num_placement = 1; - - heap->placements[0].flags = (bo->mem.placement | TTM_PL_FLAG_NO_EVICT); - ret = ttm_bo_validate(bo, &placement, &ctx); - if (!ret && kmap) - ret = ttm_bo_kmap(bo, 0, bo->num_pages, kmap); - ttm_bo_unreserve(bo); - } - return ret; -} - -int via_bo_unpin(struct ttm_buffer_object *bo, - struct ttm_bo_kmap_obj *kmap) +static void openchrome_bo_io_mem_free(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem) { - struct ttm_heap *heap = container_of(bo, struct ttm_heap, bo); - struct ttm_placement placement; - struct ttm_operation_ctx ctx = { - .interruptible = false, - .no_wait_gpu = false - }; - int ret; - - ret = ttm_bo_reserve(bo, true, false, NULL); - if (!ret) { - if (kmap) - ttm_bo_kunmap(kmap); - - placement.placement = heap->placements; - placement.num_placement = 1; + DRM_DEBUG_KMS("Entered %s.\n", __func__); - heap->placements[0].flags = (bo->mem.placement & ~TTM_PL_FLAG_NO_EVICT); - ret = ttm_bo_validate(bo, &placement, &ctx); - ttm_bo_unreserve(bo); - } - return ret; + DRM_DEBUG_KMS("Exiting %s.\n", __func__); } -int via_ttm_allocate_kernel_buffer(struct ttm_bo_device *bdev, - unsigned long size, - uint32_t alignment, - uint32_t domain, - struct ttm_bo_kmap_obj *kmap) -{ - int ret = via_bo_create(bdev, &kmap->bo, size, - ttm_bo_type_kernel, domain, - alignment, PAGE_SIZE, - false, NULL, NULL); - if (likely(!ret)) { - ret = via_bo_pin(kmap->bo, kmap); - if (unlikely(ret)) { - DRM_ERROR("failed to mmap the buffer\n"); - ttm_bo_put(kmap->bo); - kmap->bo = NULL; - } - } - return ret; -} +struct ttm_bo_driver openchrome_bo_driver = { + .init_mem_type = openchrome_bo_init_mem_type, + .eviction_valuable = ttm_bo_eviction_valuable, + .evict_flags = openchrome_bo_evict_flags, + .verify_access = openchrome_bo_verify_access, + .io_mem_reserve = openchrome_bo_io_mem_reserve, + .io_mem_free = openchrome_bo_io_mem_free, +}; _______________________________________________ openchrome-devel mailing list openchrome-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/openchrome-devel