diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gart.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gart.c | 71 |
1 files changed, 43 insertions, 28 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index fdc3a9a54bf..ba7ab79e12c 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -49,27 +49,27 @@ int radeon_gart_table_ram_alloc(struct radeon_device *rdev) | |||
49 | rdev->gart.table_size >> PAGE_SHIFT); | 49 | rdev->gart.table_size >> PAGE_SHIFT); |
50 | } | 50 | } |
51 | #endif | 51 | #endif |
52 | rdev->gart.table.ram.ptr = ptr; | 52 | rdev->gart.ptr = ptr; |
53 | memset((void *)rdev->gart.table.ram.ptr, 0, rdev->gart.table_size); | 53 | memset((void *)rdev->gart.ptr, 0, rdev->gart.table_size); |
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | 56 | ||
57 | void radeon_gart_table_ram_free(struct radeon_device *rdev) | 57 | void radeon_gart_table_ram_free(struct radeon_device *rdev) |
58 | { | 58 | { |
59 | if (rdev->gart.table.ram.ptr == NULL) { | 59 | if (rdev->gart.ptr == NULL) { |
60 | return; | 60 | return; |
61 | } | 61 | } |
62 | #ifdef CONFIG_X86 | 62 | #ifdef CONFIG_X86 |
63 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 || | 63 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480 || |
64 | rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { | 64 | rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { |
65 | set_memory_wb((unsigned long)rdev->gart.table.ram.ptr, | 65 | set_memory_wb((unsigned long)rdev->gart.ptr, |
66 | rdev->gart.table_size >> PAGE_SHIFT); | 66 | rdev->gart.table_size >> PAGE_SHIFT); |
67 | } | 67 | } |
68 | #endif | 68 | #endif |
69 | pci_free_consistent(rdev->pdev, rdev->gart.table_size, | 69 | pci_free_consistent(rdev->pdev, rdev->gart.table_size, |
70 | (void *)rdev->gart.table.ram.ptr, | 70 | (void *)rdev->gart.ptr, |
71 | rdev->gart.table_addr); | 71 | rdev->gart.table_addr); |
72 | rdev->gart.table.ram.ptr = NULL; | 72 | rdev->gart.ptr = NULL; |
73 | rdev->gart.table_addr = 0; | 73 | rdev->gart.table_addr = 0; |
74 | } | 74 | } |
75 | 75 | ||
@@ -77,10 +77,10 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev) | |||
77 | { | 77 | { |
78 | int r; | 78 | int r; |
79 | 79 | ||
80 | if (rdev->gart.table.vram.robj == NULL) { | 80 | if (rdev->gart.robj == NULL) { |
81 | r = radeon_bo_create(rdev, rdev->gart.table_size, | 81 | r = radeon_bo_create(rdev, rdev->gart.table_size, |
82 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 82 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
83 | &rdev->gart.table.vram.robj); | 83 | &rdev->gart.robj); |
84 | if (r) { | 84 | if (r) { |
85 | return r; | 85 | return r; |
86 | } | 86 | } |
@@ -93,38 +93,46 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev) | |||
93 | uint64_t gpu_addr; | 93 | uint64_t gpu_addr; |
94 | int r; | 94 | int r; |
95 | 95 | ||
96 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | 96 | r = radeon_bo_reserve(rdev->gart.robj, false); |
97 | if (unlikely(r != 0)) | 97 | if (unlikely(r != 0)) |
98 | return r; | 98 | return r; |
99 | r = radeon_bo_pin(rdev->gart.table.vram.robj, | 99 | r = radeon_bo_pin(rdev->gart.robj, |
100 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); | 100 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); |
101 | if (r) { | 101 | if (r) { |
102 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | 102 | radeon_bo_unreserve(rdev->gart.robj); |
103 | return r; | 103 | return r; |
104 | } | 104 | } |
105 | r = radeon_bo_kmap(rdev->gart.table.vram.robj, | 105 | r = radeon_bo_kmap(rdev->gart.robj, &rdev->gart.ptr); |
106 | (void **)&rdev->gart.table.vram.ptr); | ||
107 | if (r) | 106 | if (r) |
108 | radeon_bo_unpin(rdev->gart.table.vram.robj); | 107 | radeon_bo_unpin(rdev->gart.robj); |
109 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | 108 | radeon_bo_unreserve(rdev->gart.robj); |
110 | rdev->gart.table_addr = gpu_addr; | 109 | rdev->gart.table_addr = gpu_addr; |
111 | return r; | 110 | return r; |
112 | } | 111 | } |
113 | 112 | ||
114 | void radeon_gart_table_vram_free(struct radeon_device *rdev) | 113 | void radeon_gart_table_vram_unpin(struct radeon_device *rdev) |
115 | { | 114 | { |
116 | int r; | 115 | int r; |
117 | 116 | ||
118 | if (rdev->gart.table.vram.robj == NULL) { | 117 | if (rdev->gart.robj == NULL) { |
119 | return; | 118 | return; |
120 | } | 119 | } |
121 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); | 120 | r = radeon_bo_reserve(rdev->gart.robj, false); |
122 | if (likely(r == 0)) { | 121 | if (likely(r == 0)) { |
123 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | 122 | radeon_bo_kunmap(rdev->gart.robj); |
124 | radeon_bo_unpin(rdev->gart.table.vram.robj); | 123 | radeon_bo_unpin(rdev->gart.robj); |
125 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | 124 | radeon_bo_unreserve(rdev->gart.robj); |
125 | rdev->gart.ptr = NULL; | ||
126 | } | 126 | } |
127 | radeon_bo_unref(&rdev->gart.table.vram.robj); | 127 | } |
128 | |||
129 | void radeon_gart_table_vram_free(struct radeon_device *rdev) | ||
130 | { | ||
131 | if (rdev->gart.robj == NULL) { | ||
132 | return; | ||
133 | } | ||
134 | radeon_gart_table_vram_unpin(rdev); | ||
135 | radeon_bo_unref(&rdev->gart.robj); | ||
128 | } | 136 | } |
129 | 137 | ||
130 | 138 | ||
@@ -151,12 +159,14 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
151 | if (rdev->gart.pages[p]) { | 159 | if (rdev->gart.pages[p]) { |
152 | if (!rdev->gart.ttm_alloced[p]) | 160 | if (!rdev->gart.ttm_alloced[p]) |
153 | pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], | 161 | pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], |
154 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 162 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
155 | rdev->gart.pages[p] = NULL; | 163 | rdev->gart.pages[p] = NULL; |
156 | rdev->gart.pages_addr[p] = rdev->dummy_page.addr; | 164 | rdev->gart.pages_addr[p] = rdev->dummy_page.addr; |
157 | page_base = rdev->gart.pages_addr[p]; | 165 | page_base = rdev->gart.pages_addr[p]; |
158 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 166 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
159 | radeon_gart_set_page(rdev, t, page_base); | 167 | if (rdev->gart.ptr) { |
168 | radeon_gart_set_page(rdev, t, page_base); | ||
169 | } | ||
160 | page_base += RADEON_GPU_PAGE_SIZE; | 170 | page_base += RADEON_GPU_PAGE_SIZE; |
161 | } | 171 | } |
162 | } | 172 | } |
@@ -199,10 +209,12 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
199 | } | 209 | } |
200 | } | 210 | } |
201 | rdev->gart.pages[p] = pagelist[i]; | 211 | rdev->gart.pages[p] = pagelist[i]; |
202 | page_base = rdev->gart.pages_addr[p]; | 212 | if (rdev->gart.ptr) { |
203 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 213 | page_base = rdev->gart.pages_addr[p]; |
204 | radeon_gart_set_page(rdev, t, page_base); | 214 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
205 | page_base += RADEON_GPU_PAGE_SIZE; | 215 | radeon_gart_set_page(rdev, t, page_base); |
216 | page_base += RADEON_GPU_PAGE_SIZE; | ||
217 | } | ||
206 | } | 218 | } |
207 | } | 219 | } |
208 | mb(); | 220 | mb(); |
@@ -215,6 +227,9 @@ void radeon_gart_restore(struct radeon_device *rdev) | |||
215 | int i, j, t; | 227 | int i, j, t; |
216 | u64 page_base; | 228 | u64 page_base; |
217 | 229 | ||
230 | if (!rdev->gart.ptr) { | ||
231 | return; | ||
232 | } | ||
218 | for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) { | 233 | for (i = 0, t = 0; i < rdev->gart.num_cpu_pages; i++) { |
219 | page_base = rdev->gart.pages_addr[i]; | 234 | page_base = rdev->gart.pages_addr[i]; |
220 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 235 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |