aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon.h
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2012-01-05 22:11:05 -0500
committerDave Airlie <airlied@redhat.com>2012-01-06 04:15:42 -0500
commit721604a15b934f0a8d1909acb8017f029128be2f (patch)
treeac1dc0f837d70616b36c9b57d22eb9678c5e68fc /drivers/gpu/drm/radeon/radeon.h
parent09b4ea47d1041612b101c369969db123ac2c1511 (diff)
drm/radeon: GPU virtual memory support v22
Virtual address space are per drm client (opener of /dev/drm). Client are in charge of virtual address space, they need to map bo into it by calling DRM_RADEON_GEM_VA ioctl. First 16M of virtual address space is reserved by the kernel. Once using 2 level page table we should be able to have a small vram memory footprint for each pt (there would be one pt for all gart, one for all vram and then one first level for each virtual address space). Plan include using the sub allocator for a common vm page table area and using memcpy to copy vm page table in & out. Or use a gart object and copy things in & out using dma. v2: agd5f fixes: - Add vram base offset for vram pages. The GPU physical address of a vram page is FB_OFFSET + page offset. FB_OFFSET is 0 on discrete cards and the physical bus address of the stolen memory on integrated chips. - VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR covers all vmid's >= 1 v3: agd5f: - integrate with the semaphore/multi-ring stuff v4: - rebase on top ttm dma & multi-ring stuff - userspace is now in charge of the address space - no more specific cs vm ioctl, instead cs ioctl has a new chunk v5: - properly handle mem == NULL case from move_notify callback - fix the vm cleanup path v6: - fix update of page table to only happen on valid mem placement v7: - add tlb flush for each vm context - add flags to define mapping property (readable, writeable, snooped) - make ring id implicit from ib->fence->ring, up to each asic callback to then do ring specific scheduling if vm ib scheduling function v8: - add query for ib limit and kernel reserved virtual space - rename vm->size to max_pfn (maximum number of page) - update gem_va ioctl to also allow unmap operation - bump kernel version to allow userspace to query for vm support v9: - rebuild page table only when bind and incrementaly depending on bo referenced by cs and that have been moved - allow virtual address space to grow - use sa allocator for vram page table - return invalid when querying vm limit on non cayman GPU - dump vm fault register on lockup v10: agd5f: - Move the vm schedule_ib callback to a standalone function, remove the callback and use the existing ib_execute callback for VM IBs. v11: - rebase on top of lastest Linus v12: agd5f: - remove spurious backslash - set IB vm_id to 0 in radeon_ib_get() v13: agd5f: - fix handling of RADEON_CHUNK_ID_FLAGS v14: - fix va destruction - fix suspend resume - forbid bo to have several different va in same vm v15: - rebase v16: - cleanup left over of vm init/fini v17: agd5f: - cs checker v18: agd5f: - reworks the CS ioctl to better support multiple rings and VM. Rather than adding a new chunk id for VM, just re-use the IB chunk id and add a new flags for VM mode. Also define additional dwords for the flags chunk id to define the what ring we want to use (gfx, compute, uvd, etc.) and the priority. v19: - fix cs fini in weird case of no ib - semi working flush fix for ni - rebase on top of sa allocator changes v20: agd5f: - further CS ioctl cleanups from Christian's comments v21: agd5f: - integrate CS checker improvements v22: agd5f: - final cleanups for release, only allow VM CS on cayman Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon.h')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h123
1 files changed, 117 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 374f9a4d94ef..5e3542384b21 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -118,6 +118,10 @@ extern int radeon_msi;
118#define CAYMAN_RING_TYPE_CP1_INDEX 1 118#define CAYMAN_RING_TYPE_CP1_INDEX 1
119#define CAYMAN_RING_TYPE_CP2_INDEX 2 119#define CAYMAN_RING_TYPE_CP2_INDEX 2
120 120
121/* hardcode those limit for now */
122#define RADEON_VA_RESERVED_SIZE (8 << 20)
123#define RADEON_IB_VM_MAX_SIZE (64 << 10)
124
121/* 125/*
122 * Errata workarounds. 126 * Errata workarounds.
123 */ 127 */
@@ -262,6 +266,21 @@ struct radeon_mman {
262 bool initialized; 266 bool initialized;
263}; 267};
264 268
269/* bo virtual address in a specific vm */
270struct radeon_bo_va {
271 /* bo list is protected by bo being reserved */
272 struct list_head bo_list;
273 /* vm list is protected by vm mutex */
274 struct list_head vm_list;
275 /* constant after initialization */
276 struct radeon_vm *vm;
277 struct radeon_bo *bo;
278 uint64_t soffset;
279 uint64_t eoffset;
280 uint32_t flags;
281 bool valid;
282};
283
265struct radeon_bo { 284struct radeon_bo {
266 /* Protected by gem.mutex */ 285 /* Protected by gem.mutex */
267 struct list_head list; 286 struct list_head list;
@@ -275,6 +294,10 @@ struct radeon_bo {
275 u32 tiling_flags; 294 u32 tiling_flags;
276 u32 pitch; 295 u32 pitch;
277 int surface_reg; 296 int surface_reg;
297 /* list of all virtual address to which this bo
298 * is associated to
299 */
300 struct list_head va;
278 /* Constant after initialization */ 301 /* Constant after initialization */
279 struct radeon_device *rdev; 302 struct radeon_device *rdev;
280 struct drm_gem_object gem_base; 303 struct drm_gem_object gem_base;
@@ -408,6 +431,7 @@ struct radeon_mc;
408#define RADEON_GPU_PAGE_SIZE 4096 431#define RADEON_GPU_PAGE_SIZE 4096
409#define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) 432#define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1)
410#define RADEON_GPU_PAGE_SHIFT 12 433#define RADEON_GPU_PAGE_SHIFT 12
434#define RADEON_GPU_PAGE_ALIGN(a) (((a) + RADEON_GPU_PAGE_MASK) & ~RADEON_GPU_PAGE_MASK)
411 435
412struct radeon_gart { 436struct radeon_gart {
413 dma_addr_t table_addr; 437 dma_addr_t table_addr;
@@ -565,6 +589,7 @@ struct radeon_ib {
565 uint64_t gpu_addr; 589 uint64_t gpu_addr;
566 uint32_t *ptr; 590 uint32_t *ptr;
567 struct radeon_fence *fence; 591 struct radeon_fence *fence;
592 unsigned vm_id;
568}; 593};
569 594
570/* 595/*
@@ -602,6 +627,56 @@ struct radeon_ring {
602}; 627};
603 628
604/* 629/*
630 * VM
631 */
632struct radeon_vm {
633 struct list_head list;
634 struct list_head va;
635 int id;
636 unsigned last_pfn;
637 u64 pt_gpu_addr;
638 u64 *pt;
639 struct radeon_sa_bo sa_bo;
640 struct mutex mutex;
641 /* last fence for cs using this vm */
642 struct radeon_fence *fence;
643};
644
645struct radeon_vm_funcs {
646 int (*init)(struct radeon_device *rdev);
647 void (*fini)(struct radeon_device *rdev);
648 /* cs mutex must be lock for schedule_ib */
649 int (*bind)(struct radeon_device *rdev, struct radeon_vm *vm, int id);
650 void (*unbind)(struct radeon_device *rdev, struct radeon_vm *vm);
651 void (*tlb_flush)(struct radeon_device *rdev, struct radeon_vm *vm);
652 uint32_t (*page_flags)(struct radeon_device *rdev,
653 struct radeon_vm *vm,
654 uint32_t flags);
655 void (*set_page)(struct radeon_device *rdev, struct radeon_vm *vm,
656 unsigned pfn, uint64_t addr, uint32_t flags);
657};
658
659struct radeon_vm_manager {
660 struct list_head lru_vm;
661 uint32_t use_bitmap;
662 struct radeon_sa_manager sa_manager;
663 uint32_t max_pfn;
664 /* fields constant after init */
665 const struct radeon_vm_funcs *funcs;
666 /* number of VMIDs */
667 unsigned nvm;
668 /* vram base address for page table entry */
669 u64 vram_base_offset;
670};
671
672/*
673 * file private structure
674 */
675struct radeon_fpriv {
676 struct radeon_vm vm;
677};
678
679/*
605 * R6xx+ IH ring 680 * R6xx+ IH ring
606 */ 681 */
607struct r600_ih { 682struct r600_ih {
@@ -691,12 +766,12 @@ struct radeon_cs_reloc {
691struct radeon_cs_chunk { 766struct radeon_cs_chunk {
692 uint32_t chunk_id; 767 uint32_t chunk_id;
693 uint32_t length_dw; 768 uint32_t length_dw;
694 int kpage_idx[2]; 769 int kpage_idx[2];
695 uint32_t *kpage[2]; 770 uint32_t *kpage[2];
696 uint32_t *kdata; 771 uint32_t *kdata;
697 void __user *user_ptr; 772 void __user *user_ptr;
698 int last_copied_page; 773 int last_copied_page;
699 int last_page_index; 774 int last_page_index;
700}; 775};
701 776
702struct radeon_cs_parser { 777struct radeon_cs_parser {
@@ -717,11 +792,14 @@ struct radeon_cs_parser {
717 /* indices of various chunks */ 792 /* indices of various chunks */
718 int chunk_ib_idx; 793 int chunk_ib_idx;
719 int chunk_relocs_idx; 794 int chunk_relocs_idx;
795 int chunk_flags_idx;
720 struct radeon_ib *ib; 796 struct radeon_ib *ib;
721 void *track; 797 void *track;
722 unsigned family; 798 unsigned family;
723 int parser_error; 799 int parser_error;
724 bool keep_tiling_flags; 800 u32 cs_flags;
801 u32 ring;
802 s32 priority;
725}; 803};
726 804
727extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx); 805extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx);
@@ -1018,6 +1096,7 @@ struct radeon_asic {
1018 1096
1019 struct { 1097 struct {
1020 void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); 1098 void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
1099 int (*ib_parse)(struct radeon_device *rdev, struct radeon_ib *ib);
1021 void (*emit_fence)(struct radeon_device *rdev, struct radeon_fence *fence); 1100 void (*emit_fence)(struct radeon_device *rdev, struct radeon_fence *fence);
1022 void (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, 1101 void (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp,
1023 struct radeon_semaphore *semaphore, bool emit_wait); 1102 struct radeon_semaphore *semaphore, bool emit_wait);
@@ -1255,6 +1334,8 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
1255 struct drm_file *filp); 1334 struct drm_file *filp);
1256int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, 1335int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
1257 struct drm_file *filp); 1336 struct drm_file *filp);
1337int radeon_gem_va_ioctl(struct drm_device *dev, void *data,
1338 struct drm_file *filp);
1258int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); 1339int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
1259int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, 1340int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
1260 struct drm_file *filp); 1341 struct drm_file *filp);
@@ -1404,6 +1485,8 @@ struct radeon_device {
1404 /* debugfs */ 1485 /* debugfs */
1405 struct radeon_debugfs debugfs[RADEON_DEBUGFS_MAX_COMPONENTS]; 1486 struct radeon_debugfs debugfs[RADEON_DEBUGFS_MAX_COMPONENTS];
1406 unsigned debugfs_count; 1487 unsigned debugfs_count;
1488 /* virtual memory */
1489 struct radeon_vm_manager vm_manager;
1407}; 1490};
1408 1491
1409int radeon_device_init(struct radeon_device *rdev, 1492int radeon_device_init(struct radeon_device *rdev,
@@ -1568,6 +1651,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
1568#define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) 1651#define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev))
1569#define radeon_ring_test(rdev, cp) (rdev)->asic->ring_test((rdev), (cp)) 1652#define radeon_ring_test(rdev, cp) (rdev)->asic->ring_test((rdev), (cp))
1570#define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)].ib_execute((rdev), (ib)) 1653#define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)].ib_execute((rdev), (ib))
1654#define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)].ib_parse((rdev), (ib))
1571#define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) 1655#define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev))
1572#define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) 1656#define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev))
1573#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) 1657#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc))
@@ -1627,6 +1711,33 @@ extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
1627extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); 1711extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size);
1628 1712
1629/* 1713/*
1714 * vm
1715 */
1716int radeon_vm_manager_init(struct radeon_device *rdev);
1717void radeon_vm_manager_fini(struct radeon_device *rdev);
1718int radeon_vm_manager_start(struct radeon_device *rdev);
1719int radeon_vm_manager_suspend(struct radeon_device *rdev);
1720int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm);
1721void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm);
1722int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm);
1723void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm);
1724int radeon_vm_bo_update_pte(struct radeon_device *rdev,
1725 struct radeon_vm *vm,
1726 struct radeon_bo *bo,
1727 struct ttm_mem_reg *mem);
1728void radeon_vm_bo_invalidate(struct radeon_device *rdev,
1729 struct radeon_bo *bo);
1730int radeon_vm_bo_add(struct radeon_device *rdev,
1731 struct radeon_vm *vm,
1732 struct radeon_bo *bo,
1733 uint64_t offset,
1734 uint32_t flags);
1735int radeon_vm_bo_rmv(struct radeon_device *rdev,
1736 struct radeon_vm *vm,
1737 struct radeon_bo *bo);
1738
1739
1740/*
1630 * R600 vram scratch functions 1741 * R600 vram scratch functions
1631 */ 1742 */
1632int r600_vram_scratch_init(struct radeon_device *rdev); 1743int r600_vram_scratch_init(struct radeon_device *rdev);