diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index 707f85825996..1f51897acc5b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | |||
@@ -68,9 +68,75 @@ | |||
68 | */ | 68 | */ |
69 | int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) | 69 | int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) |
70 | { | 70 | { |
71 | return amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE, | 71 | int r; |
72 | AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.robj, | 72 | |
73 | &adev->gart.table_addr, &adev->gart.ptr); | 73 | if (adev->gart.robj == NULL) { |
74 | r = amdgpu_bo_create(adev, adev->gart.table_size, | ||
75 | PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, | ||
76 | AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | | ||
77 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, | ||
78 | NULL, NULL, 0, &adev->gart.robj); | ||
79 | if (r) { | ||
80 | return r; | ||
81 | } | ||
82 | } | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * amdgpu_gart_table_vram_pin - pin gart page table in vram | ||
88 | * | ||
89 | * @adev: amdgpu_device pointer | ||
90 | * | ||
91 | * Pin the GART page table in vram so it will not be moved | ||
92 | * by the memory manager (pcie r4xx, r5xx+). These asics require the | ||
93 | * gart table to be in video memory. | ||
94 | * Returns 0 for success, error for failure. | ||
95 | */ | ||
96 | int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev) | ||
97 | { | ||
98 | uint64_t gpu_addr; | ||
99 | int r; | ||
100 | |||
101 | r = amdgpu_bo_reserve(adev->gart.robj, false); | ||
102 | if (unlikely(r != 0)) | ||
103 | return r; | ||
104 | r = amdgpu_bo_pin(adev->gart.robj, | ||
105 | AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr); | ||
106 | if (r) { | ||
107 | amdgpu_bo_unreserve(adev->gart.robj); | ||
108 | return r; | ||
109 | } | ||
110 | r = amdgpu_bo_kmap(adev->gart.robj, &adev->gart.ptr); | ||
111 | if (r) | ||
112 | amdgpu_bo_unpin(adev->gart.robj); | ||
113 | amdgpu_bo_unreserve(adev->gart.robj); | ||
114 | adev->gart.table_addr = gpu_addr; | ||
115 | return r; | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * amdgpu_gart_table_vram_unpin - unpin gart page table in vram | ||
120 | * | ||
121 | * @adev: amdgpu_device pointer | ||
122 | * | ||
123 | * Unpin the GART page table in vram (pcie r4xx, r5xx+). | ||
124 | * These asics require the gart table to be in video memory. | ||
125 | */ | ||
126 | void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev) | ||
127 | { | ||
128 | int r; | ||
129 | |||
130 | if (adev->gart.robj == NULL) { | ||
131 | return; | ||
132 | } | ||
133 | r = amdgpu_bo_reserve(adev->gart.robj, true); | ||
134 | if (likely(r == 0)) { | ||
135 | amdgpu_bo_kunmap(adev->gart.robj); | ||
136 | amdgpu_bo_unpin(adev->gart.robj); | ||
137 | amdgpu_bo_unreserve(adev->gart.robj); | ||
138 | adev->gart.ptr = NULL; | ||
139 | } | ||
74 | } | 140 | } |
75 | 141 | ||
76 | /** | 142 | /** |
@@ -84,9 +150,10 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) | |||
84 | */ | 150 | */ |
85 | void amdgpu_gart_table_vram_free(struct amdgpu_device *adev) | 151 | void amdgpu_gart_table_vram_free(struct amdgpu_device *adev) |
86 | { | 152 | { |
87 | amdgpu_bo_free_kernel(&adev->gart.robj, | 153 | if (adev->gart.robj == NULL) { |
88 | &adev->gart.table_addr, | 154 | return; |
89 | &adev->gart.ptr); | 155 | } |
156 | amdgpu_bo_unref(&adev->gart.robj); | ||
90 | } | 157 | } |
91 | 158 | ||
92 | /* | 159 | /* |