diff options
Diffstat (limited to 'include/drm/ttm')
-rw-r--r-- | include/drm/ttm/ttm_bo_api.h | 46 | ||||
-rw-r--r-- | include/drm/ttm/ttm_bo_driver.h | 85 | ||||
-rw-r--r-- | include/drm/ttm/ttm_page_alloc.h | 74 |
3 files changed, 151 insertions, 54 deletions
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 81eb9f45883..267a86c74e2 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -66,6 +66,26 @@ struct ttm_placement { const uint32_t *busy_placement; }; +/** + * struct ttm_bus_placement + * + * @addr: mapped virtual address + * @base: bus base address + * @is_iomem: is this io memory ? + * @size: size in byte + * @offset: offset from the base address + * + * Structure indicating the bus placement of an object. + */ +struct ttm_bus_placement { + void *addr; + unsigned long base; + unsigned long size; + unsigned long offset; + bool is_iomem; + bool io_reserved; +}; + /** * struct ttm_mem_reg @@ -75,6 +95,7 @@ struct ttm_placement { * @num_pages: Actual size of memory region in pages. * @page_alignment: Page alignment. * @placement: Placement flags. + * @bus: Placement on io bus accessible to the CPU * * Structure indicating the placement and space resources used by a * buffer object. @@ -87,6 +108,7 @@ struct ttm_mem_reg { uint32_t page_alignment; uint32_t mem_type; uint32_t placement; + struct ttm_bus_placement bus; }; /** @@ -274,6 +296,7 @@ struct ttm_bo_kmap_obj { ttm_bo_map_kmap = 3, ttm_bo_map_premapped = 4 | TTM_BO_MAP_IOMEM_MASK, } bo_kmap_type; + struct ttm_buffer_object *bo; }; /** @@ -313,7 +336,8 @@ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy, * @bo: The buffer object. * @placement: Proposed placement for the buffer object. * @interruptible: Sleep interruptible if sleeping. - * @no_wait: Return immediately if the buffer is busy. + * @no_wait_reserve: Return immediately if other buffers are busy. + * @no_wait_gpu: Return immediately if the GPU is busy. * * Changes placement and caching policy of the buffer object * according proposed placement. @@ -325,7 +349,8 @@ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy, */ extern int ttm_bo_validate(struct ttm_buffer_object *bo, struct ttm_placement *placement, - bool interruptible, bool no_wait); + bool interruptible, bool no_wait_reserve, + bool no_wait_gpu); /** * ttm_bo_unref @@ -337,6 +362,23 @@ extern int ttm_bo_validate(struct ttm_buffer_object *bo, extern void ttm_bo_unref(struct ttm_buffer_object **bo); /** + * ttm_bo_lock_delayed_workqueue + * + * Prevent the delayed workqueue from running. + * Returns + * True if the workqueue was queued at the time + */ +extern int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev); + +/** + * ttm_bo_unlock_delayed_workqueue + * + * Allows the delayed workqueue to run. + */ +extern void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev, + int resched); + +/** * ttm_bo_synccpu_write_grab * * @bo: The buffer object: diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index e929c27ede2..0ea602da43e 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -176,8 +176,6 @@ struct ttm_tt { #define TTM_MEMTYPE_FLAG_FIXED (1 << 0) /* Fixed (on-card) PCI memory */ #define TTM_MEMTYPE_FLAG_MAPPABLE (1 << 1) /* Memory mappable */ -#define TTM_MEMTYPE_FLAG_NEEDS_IOREMAP (1 << 2) /* Fixed memory needs ioremap - before kernel access. */ #define TTM_MEMTYPE_FLAG_CMA (1 << 3) /* Can't map aperture */ /** @@ -189,13 +187,6 @@ struct ttm_tt { * managed by this memory type. * @gpu_offset: If used, the GPU offset of the first managed page of * fixed memory or the first managed location in an aperture. - * @io_offset: The io_offset of the first managed page of IO memory or - * the first managed location in an aperture. For TTM_MEMTYPE_FLAG_CMA - * memory, this should be set to NULL. - * @io_size: The size of a managed IO region (fixed memory or aperture). - * @io_addr: Virtual kernel address if the io region is pre-mapped. For - * TTM_MEMTYPE_FLAG_NEEDS_IOREMAP there is no pre-mapped io map and - * @io_addr should be set to NULL. * @size: Size of the managed region. * @available_caching: A mask of available caching types, TTM_PL_FLAG_XX, * as defined in ttm_placement_common.h @@ -221,9 +212,6 @@ struct ttm_mem_type_manager { bool use_type; uint32_t flags; unsigned long gpu_offset; - unsigned long io_offset; - unsigned long io_size; - void *io_addr; uint64_t size; uint32_t available_caching; uint32_t default_caching; @@ -311,7 +299,8 @@ struct ttm_bo_driver { */ int (*move) (struct ttm_buffer_object *bo, bool evict, bool interruptible, - bool no_wait, struct ttm_mem_reg *new_mem); + bool no_wait_reserve, bool no_wait_gpu, + struct ttm_mem_reg *new_mem); /** * struct ttm_bo_driver_member verify_access @@ -351,12 +340,21 @@ struct ttm_bo_driver { struct ttm_mem_reg *new_mem); /* notify the driver we are taking a fault on this BO * and have reserved it */ - void (*fault_reserve_notify)(struct ttm_buffer_object *bo); + int (*fault_reserve_notify)(struct ttm_buffer_object *bo); /** * notify the driver that we're about to swap out this bo */ void (*swap_notify) (struct ttm_buffer_object *bo); + + /** + * Driver callback on when mapping io memory (for bo_move_memcpy + * for instance). TTM will take care to call io_mem_free whenever + * the mapping is not use anymore. io_mem_reserve & io_mem_free + * are balanced. + */ + int (*io_mem_reserve)(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem); + void (*io_mem_free)(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem); }; /** @@ -633,7 +631,8 @@ extern bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, * @proposed_placement: Proposed new placement for the buffer object. * @mem: A struct ttm_mem_reg. * @interruptible: Sleep interruptible when sliping. - * @no_wait: Don't sleep waiting for space to become available. + * @no_wait_reserve: Return immediately if other buffers are busy. + * @no_wait_gpu: Return immediately if the GPU is busy. * * Allocate memory space for the buffer object pointed to by @bo, using * the placement flags in @mem, potentially evicting other idle buffer objects. @@ -647,7 +646,8 @@ extern bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, extern int ttm_bo_mem_space(struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_mem_reg *mem, - bool interruptible, bool no_wait); + bool interruptible, + bool no_wait_reserve, bool no_wait_gpu); /** * ttm_bo_wait_for_cpu * @@ -682,6 +682,11 @@ extern int ttm_bo_pci_offset(struct ttm_bo_device *bdev, unsigned long *bus_offset, unsigned long *bus_size); +extern int ttm_mem_io_reserve(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem); +extern void ttm_mem_io_free(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem); + extern void ttm_bo_global_release(struct ttm_global_reference *ref); extern int ttm_bo_global_init(struct ttm_global_reference *ref); @@ -789,34 +794,6 @@ extern void ttm_bo_unreserve(struct ttm_buffer_object *bo); extern int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo, bool interruptible); -/** - * ttm_bo_block_reservation - * - * @bo: A pointer to a struct ttm_buffer_object. - * @interruptible: Use interruptible sleep when waiting. - * @no_wait: Don't sleep, but rather return -EBUSY. - * - * Block reservation for validation by simply reserving the buffer. - * This is intended for single buffer use only without eviction, - * and thus needs no deadlock protection. - * - * Returns: - * -EBUSY: If no_wait == 1 and the buffer is already reserved. - * -ERESTARTSYS: If interruptible == 1 and the process received a signal - * while sleeping. - */ -extern int ttm_bo_block_reservation(struct ttm_buffer_object *bo, - bool interruptible, bool no_wait); - -/** - * ttm_bo_unblock_reservation - * - * @bo: A pointer to a struct ttm_buffer_object. - * - * Unblocks reservation leaving lru lists untouched. - */ -extern void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo); - /* * ttm_bo_util.c */ @@ -826,7 +803,8 @@ extern void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo); * * @bo: A pointer to a struct ttm_buffer_object. * @evict: 1: This is an eviction. Don't try to pipeline. - * @no_wait: Never sleep, but rather return with -EBUSY. + * @no_wait_reserve: Return immediately if other buffers are busy. + * @no_wait_gpu: Return immediately if the GPU is busy. * @new_mem: struct ttm_mem_reg indicating where to move. * * Optimized move function for a buffer object with both old and @@ -840,15 +818,16 @@ extern void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo); */ extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, - bool evict, bool no_wait, - struct ttm_mem_reg *new_mem); + bool evict, bool no_wait_reserve, + bool no_wait_gpu, struct ttm_mem_reg *new_mem); /** * ttm_bo_move_memcpy * * @bo: A pointer to a struct ttm_buffer_object. * @evict: 1: This is an eviction. Don't try to pipeline. - * @no_wait: Never sleep, but rather return with -EBUSY. + * @no_wait_reserve: Return immediately if other buffers are busy. + * @no_wait_gpu: Return immediately if the GPU is busy. * @new_mem: struct ttm_mem_reg indicating where to move. * * Fallback move function for a mappable buffer object in mappable memory. @@ -862,8 +841,8 @@ extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, */ extern int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, - bool evict, - bool no_wait, struct ttm_mem_reg *new_mem); + bool evict, bool no_wait_reserve, + bool no_wait_gpu, struct ttm_mem_reg *new_mem); /** * ttm_bo_free_old_node @@ -882,7 +861,8 @@ extern void ttm_bo_free_old_node(struct ttm_buffer_object *bo); * @sync_obj_arg: An argument to pass to the sync object idle / wait * functions. * @evict: This is an evict move. Don't return until the buffer is idle. - * @no_wait: Never sleep, but rather return with -EBUSY. + * @no_wait_reserve: Return immediately if other buffers are busy. + * @no_wait_gpu: Return immediately if the GPU is busy. * @new_mem: struct ttm_mem_reg indicating where to move. * * Accelerated move function to be called when an accelerated move @@ -896,7 +876,8 @@ extern void ttm_bo_free_old_node(struct ttm_buffer_object *bo); extern int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, void *sync_obj, void *sync_obj_arg, - bool evict, bool no_wait, + bool evict, bool no_wait_reserve, + bool no_wait_gpu, struct ttm_mem_reg *new_mem); /** * ttm_io_prot diff --git a/include/drm/ttm/ttm_page_alloc.h b/include/drm/ttm/ttm_page_alloc.h new file mode 100644 index 00000000000..8bb4de567b2 --- /dev/null +++ b/include/drm/ttm/ttm_page_alloc.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) Red Hat Inc. + + * 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 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. + * + * Authors: Dave Airlie <airlied@redhat.com> + * Jerome Glisse <jglisse@redhat.com> + */ +#ifndef TTM_PAGE_ALLOC +#define TTM_PAGE_ALLOC + +#include "ttm_bo_driver.h" +#include "ttm_memory.h" + +/** + * Get count number of pages from pool to pages list. + * + * @pages: heado of empty linked list where pages are filled. + * @flags: ttm flags for page allocation. + * @cstate: ttm caching state for the page. + * @count: number of pages to allocate. + */ +int ttm_get_pages(struct list_head *pages, + int flags, + enum ttm_caching_state cstate, + unsigned count); +/** + * Put linked list of pages to pool. + * + * @pages: list of pages to free. + * @page_count: number of pages in the list. Zero can be passed for unknown + * count. + * @flags: ttm flags for page allocation. + * @cstate: ttm caching state. + */ +void ttm_put_pages(struct list_head *pages, + unsigned page_count, + int flags, + enum ttm_caching_state cstate); +/** + * Initialize pool allocator. + * + * Pool allocator is internaly reference counted so it can be initialized + * multiple times but ttm_page_alloc_fini has to be called same number of + * times. + */ +int ttm_page_alloc_init(struct ttm_mem_global *glob, unsigned max_pages); +/** + * Free pool allocator. + */ +void ttm_page_alloc_fini(void); + +/** + * Output the state of pools to debugfs file + */ +extern int ttm_page_alloc_debugfs(struct seq_file *m, void *data); +#endif |