Rev 3764 | Rev 4126 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3764 | Rev 4104 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | #include |
33 | #include |
34 | #include "i915_drv.h" |
34 | #include "i915_drv.h" |
35 | #include "i915_trace.h" |
35 | #include "i915_trace.h" |
36 | #include "intel_drv.h" |
36 | #include "intel_drv.h" |
Line 37... | Line 37... | ||
37 | 37 | ||
- | 38 | #define GEN6_PPGTT_PD_ENTRIES 512 |
|
Line 38... | Line 39... | ||
38 | typedef uint32_t gen6_gtt_pte_t; |
39 | #define I915_PPGTT_PT_ENTRIES (PAGE_SIZE / sizeof(gen6_gtt_pte_t)) |
39 | 40 | ||
- | 41 | /* PPGTT stuff */ |
|
Line 40... | Line 42... | ||
40 | /* PPGTT stuff */ |
42 | #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) |
41 | #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) |
43 | #define HSW_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0x7f0)) |
42 | 44 | ||
Line 43... | Line 45... | ||
43 | #define GEN6_PDE_VALID (1 << 0) |
45 | #define GEN6_PDE_VALID (1 << 0) |
44 | /* gen6+ has bit 11-4 for physical addr bit 39-32 */ |
46 | /* gen6+ has bit 11-4 for physical addr bit 39-32 */ |
45 | #define GEN6_PDE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) |
47 | #define GEN6_PDE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) |
46 | 48 | ||
47 | #define GEN6_PTE_VALID (1 << 0) |
49 | #define GEN6_PTE_VALID (1 << 0) |
48 | #define GEN6_PTE_UNCACHED (1 << 1) |
50 | #define GEN6_PTE_UNCACHED (1 << 1) |
- | 51 | #define HSW_PTE_UNCACHED (0) |
|
Line -... | Line 52... | ||
- | 52 | #define GEN6_PTE_CACHE_LLC (2 << 1) |
|
49 | #define HSW_PTE_UNCACHED (0) |
53 | #define GEN7_PTE_CACHE_L3_LLC (3 << 1) |
- | 54 | #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) |
|
- | 55 | #define HSW_PTE_ADDR_ENCODE(addr) HSW_GTT_ADDR_ENCODE(addr) |
|
50 | #define GEN6_PTE_CACHE_LLC (2 << 1) |
56 | |
- | 57 | /* Cacheability Control is a 4-bit value. The low three bits are stored in * |
|
- | 58 | * bits 3:1 of the PTE, while the fourth bit is stored in bit 11 of the PTE. |
|
- | 59 | */ |
|
- | 60 | #define HSW_CACHEABILITY_CONTROL(bits) ((((bits) & 0x7) << 1) | \ |
|
- | 61 | (((bits) & 0x8) << (11 - 3))) |
|
- | 62 | #define HSW_WB_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x2) |
|
51 | #define GEN6_PTE_CACHE_LLC_MLC (3 << 1) |
63 | #define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3) |
52 | #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) |
64 | #define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) |
53 | 65 | #define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6) |
|
54 | static inline gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev, |
66 | |
Line 55... | Line 67... | ||
55 | dma_addr_t addr, |
67 | static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr, |
56 | enum i915_cache_level level) |
68 | enum i915_cache_level level) |
57 | { |
- | |
58 | gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
69 | { |
59 | pte |= GEN6_PTE_ADDR_ENCODE(addr); |
70 | gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
- | 71 | pte |= GEN6_PTE_ADDR_ENCODE(addr); |
|
- | 72 | ||
- | 73 | switch (level) { |
|
60 | 74 | case I915_CACHE_L3_LLC: |
|
- | 75 | case I915_CACHE_LLC: |
|
- | 76 | pte |= GEN6_PTE_CACHE_LLC; |
|
- | 77 | break; |
|
- | 78 | case I915_CACHE_NONE: |
|
- | 79 | pte |= GEN6_PTE_UNCACHED; |
|
- | 80 | break; |
|
- | 81 | default: |
|
- | 82 | WARN_ON(1); |
|
- | 83 | } |
|
- | 84 | ||
- | 85 | return pte; |
|
- | 86 | } |
|
- | 87 | ||
- | 88 | static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr, |
|
- | 89 | enum i915_cache_level level) |
|
61 | switch (level) { |
90 | { |
62 | case I915_CACHE_LLC_MLC: |
91 | gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
63 | /* Haswell doesn't set L3 this way */ |
92 | pte |= GEN6_PTE_ADDR_ENCODE(addr); |
64 | if (IS_HASWELL(dev)) |
93 | |
65 | pte |= GEN6_PTE_CACHE_LLC; |
94 | switch (level) { |
66 | else |
95 | case I915_CACHE_L3_LLC: |
67 | pte |= GEN6_PTE_CACHE_LLC_MLC; |
- | |
68 | break; |
- | |
69 | case I915_CACHE_LLC: |
- | |
70 | pte |= GEN6_PTE_CACHE_LLC; |
96 | pte |= GEN7_PTE_CACHE_L3_LLC; |
71 | break; |
97 | break; |
72 | case I915_CACHE_NONE: |
98 | case I915_CACHE_LLC: |
73 | if (IS_HASWELL(dev)) |
99 | pte |= GEN6_PTE_CACHE_LLC; |
74 | pte |= HSW_PTE_UNCACHED; |
100 | break; |
Line 75... | Line 101... | ||
75 | else |
101 | case I915_CACHE_NONE: |
76 | pte |= GEN6_PTE_UNCACHED; |
102 | pte |= GEN6_PTE_UNCACHED; |
Line -... | Line 103... | ||
- | 103 | break; |
|
- | 104 | default: |
|
- | 105 | WARN_ON(1); |
|
77 | break; |
106 | } |
- | 107 | ||
78 | default: |
108 | return pte; |
79 | BUG(); |
109 | } |
- | 110 | ||
- | 111 | #define BYT_PTE_WRITEABLE (1 << 1) |
|
- | 112 | #define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2) |
|
- | 113 | ||
- | 114 | static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr, |
|
- | 115 | enum i915_cache_level level) |
|
- | 116 | { |
|
- | 117 | gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
|
- | 118 | pte |= GEN6_PTE_ADDR_ENCODE(addr); |
|
- | 119 | ||
- | 120 | /* Mark the page as writeable. Other platforms don't have a |
|
- | 121 | * setting for read-only/writable, so this matches that behavior. |
|
- | 122 | */ |
|
- | 123 | pte |= BYT_PTE_WRITEABLE; |
|
- | 124 | ||
- | 125 | if (level != I915_CACHE_NONE) |
|
- | 126 | pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES; |
|
- | 127 | ||
- | 128 | return pte; |
|
- | 129 | } |
|
- | 130 | ||
- | 131 | static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr, |
|
80 | } |
132 | enum i915_cache_level level) |
- | 133 | { |
|
- | 134 | gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
|
- | 135 | pte |= HSW_PTE_ADDR_ENCODE(addr); |
|
- | 136 | ||
- | 137 | if (level != I915_CACHE_NONE) |
|
- | 138 | pte |= HSW_WB_LLC_AGE3; |
|
81 | 139 | ||
- | 140 | return pte; |
|
- | 141 | } |
|
- | 142 | ||
- | 143 | static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr, |
|
- | 144 | enum i915_cache_level level) |
|
- | 145 | { |
|
- | 146 | gen6_gtt_pte_t pte = GEN6_PTE_VALID; |
|
- | 147 | pte |= HSW_PTE_ADDR_ENCODE(addr); |
|
- | 148 | ||
- | 149 | switch (level) { |
|
- | 150 | case I915_CACHE_NONE: |
|
- | 151 | break; |
|
- | 152 | case I915_CACHE_WT: |
|
- | 153 | pte |= HSW_WT_ELLC_LLC_AGE0; |
|
- | 154 | break; |
|
- | 155 | default: |
|
- | 156 | pte |= HSW_WB_ELLC_LLC_AGE0; |
|
82 | return pte; |
157 | break; |
83 | } |
158 | } |
84 | 159 | ||
85 | static int gen6_ppgtt_enable(struct drm_device *dev) |
160 | return pte; |
Line -... | Line 161... | ||
- | 161 | } |
|
86 | { |
162 | |
87 | drm_i915_private_t *dev_priv = dev->dev_private; |
163 | static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt) |
88 | uint32_t pd_offset; |
164 | { |
89 | struct intel_ring_buffer *ring; |
165 | struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private; |
Line 102... | Line 178... | ||
102 | pd_entry |= GEN6_PDE_VALID; |
178 | pd_entry |= GEN6_PDE_VALID; |
Line 103... | Line 179... | ||
103 | 179 | ||
104 | writel(pd_entry, pd_addr + i); |
180 | writel(pd_entry, pd_addr + i); |
105 | } |
181 | } |
- | 182 | readl(pd_addr); |
|
- | 183 | } |
|
- | 184 | ||
- | 185 | static int gen6_ppgtt_enable(struct drm_device *dev) |
|
- | 186 | { |
|
- | 187 | drm_i915_private_t *dev_priv = dev->dev_private; |
|
- | 188 | uint32_t pd_offset; |
|
- | 189 | struct intel_ring_buffer *ring; |
|
- | 190 | struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; |
|
- | 191 | int i; |
|
- | 192 | ||
- | 193 | BUG_ON(ppgtt->pd_offset & 0x3f); |
|
- | 194 | ||
Line 106... | Line 195... | ||
106 | readl(pd_addr); |
195 | gen6_write_pdes(ppgtt); |
107 | 196 | ||
108 | pd_offset = ppgtt->pd_offset; |
197 | pd_offset = ppgtt->pd_offset; |
Line 150... | Line 239... | ||
150 | } |
239 | } |
151 | return 0; |
240 | return 0; |
152 | } |
241 | } |
Line 153... | Line 242... | ||
153 | 242 | ||
154 | /* PPGTT support for Sandybdrige/Gen6 and later */ |
243 | /* PPGTT support for Sandybdrige/Gen6 and later */ |
155 | static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, |
244 | static void gen6_ppgtt_clear_range(struct i915_address_space *vm, |
156 | unsigned first_entry, |
245 | unsigned first_entry, |
157 | unsigned num_entries) |
246 | unsigned num_entries) |
- | 247 | { |
|
- | 248 | struct i915_hw_ppgtt *ppgtt = |
|
158 | { |
249 | container_of(vm, struct i915_hw_ppgtt, base); |
159 | gen6_gtt_pte_t *pt_vaddr, scratch_pte; |
250 | gen6_gtt_pte_t *pt_vaddr, scratch_pte; |
160 | unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; |
251 | unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; |
161 | unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; |
252 | unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; |
Line 162... | Line 253... | ||
162 | unsigned last_pte, i; |
253 | unsigned last_pte, i; |
163 | - | ||
164 | scratch_pte = gen6_pte_encode(ppgtt->dev, |
- | |
Line 165... | Line 254... | ||
165 | ppgtt->scratch_page_dma_addr, |
254 | |
Line 166... | Line 255... | ||
166 | I915_CACHE_LLC); |
255 | scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC); |
167 | 256 | ||
Line 186... | Line 275... | ||
186 | }; |
275 | }; |
Line 187... | Line 276... | ||
187 | 276 | ||
188 | FreeKernelSpace(pt_vaddr); |
277 | FreeKernelSpace(pt_vaddr); |
Line 189... | Line 278... | ||
189 | } |
278 | } |
190 | 279 | ||
191 | static void gen6_ppgtt_insert_entries(struct i915_hw_ppgtt *ppgtt, |
280 | static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, |
192 | struct sg_table *pages, |
281 | struct sg_table *pages, |
193 | unsigned first_entry, |
282 | unsigned first_entry, |
- | 283 | enum i915_cache_level cache_level) |
|
- | 284 | { |
|
194 | enum i915_cache_level cache_level) |
285 | struct i915_hw_ppgtt *ppgtt = |
195 | { |
286 | container_of(vm, struct i915_hw_ppgtt, base); |
196 | gen6_gtt_pte_t *pt_vaddr; |
287 | gen6_gtt_pte_t *pt_vaddr; |
197 | unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; |
288 | unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES; |
198 | unsigned act_pte = first_entry % I915_PPGTT_PT_ENTRIES; |
289 | unsigned act_pte = first_entry % I915_PPGTT_PT_ENTRIES; |
Line 208... | Line 299... | ||
208 | MapPage(pt_vaddr,(addr_t)(ppgtt->pt_pages[act_pt]), 3); |
299 | MapPage(pt_vaddr,(addr_t)(ppgtt->pt_pages[act_pt]), 3); |
209 | for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) { |
300 | for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) { |
210 | dma_addr_t page_addr; |
301 | dma_addr_t page_addr; |
Line 211... | Line 302... | ||
211 | 302 | ||
212 | page_addr = sg_page_iter_dma_address(&sg_iter); |
303 | page_addr = sg_page_iter_dma_address(&sg_iter); |
213 | pt_vaddr[act_pte] = gen6_pte_encode(ppgtt->dev, page_addr, |
- | |
214 | cache_level); |
304 | pt_vaddr[act_pte] = vm->pte_encode(page_addr, cache_level); |
215 | if (++act_pte == I915_PPGTT_PT_ENTRIES) { |
305 | if (++act_pte == I915_PPGTT_PT_ENTRIES) { |
216 | act_pt++; |
306 | act_pt++; |
217 | MapPage(pt_vaddr,(addr_t)(ppgtt->pt_pages[act_pt]), 3); |
307 | MapPage(pt_vaddr,(addr_t)(ppgtt->pt_pages[act_pt]), 3); |
Line 218... | Line 308... | ||
218 | act_pte = 0; |
308 | act_pte = 0; |
219 | 309 | ||
220 | } |
310 | } |
221 | } |
311 | } |
Line 222... | Line 312... | ||
222 | FreeKernelSpace(pt_vaddr); |
312 | FreeKernelSpace(pt_vaddr); |
223 | } |
313 | } |
- | 314 | ||
- | 315 | static void gen6_ppgtt_cleanup(struct i915_address_space *vm) |
|
224 | 316 | { |
|
Line -... | Line 317... | ||
- | 317 | struct i915_hw_ppgtt *ppgtt = |
|
- | 318 | container_of(vm, struct i915_hw_ppgtt, base); |
|
225 | static void gen6_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) |
319 | int i; |
226 | { |
320 | |
227 | int i; |
321 | drm_mm_takedown(&ppgtt->base.mm); |
228 | 322 | ||
229 | if (ppgtt->pt_dma_addr) { |
323 | if (ppgtt->pt_dma_addr) { |
230 | for (i = 0; i < ppgtt->num_pd_entries; i++) |
324 | for (i = 0; i < ppgtt->num_pd_entries; i++) |
Line 231... | Line 325... | ||
231 | pci_unmap_page(ppgtt->dev->pdev, |
325 | pci_unmap_page(ppgtt->base.dev->pdev, |
Line 240... | Line 334... | ||
240 | kfree(ppgtt); |
334 | kfree(ppgtt); |
241 | } |
335 | } |
Line 242... | Line 336... | ||
242 | 336 | ||
243 | static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) |
337 | static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) |
244 | { |
338 | { |
245 | struct drm_device *dev = ppgtt->dev; |
339 | struct drm_device *dev = ppgtt->base.dev; |
246 | struct drm_i915_private *dev_priv = dev->dev_private; |
340 | struct drm_i915_private *dev_priv = dev->dev_private; |
247 | unsigned first_pd_entry_in_global_pt; |
341 | unsigned first_pd_entry_in_global_pt; |
248 | int i; |
342 | int i; |
Line 249... | Line 343... | ||
249 | int ret = -ENOMEM; |
343 | int ret = -ENOMEM; |
250 | 344 | ||
251 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 |
345 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 |
252 | * entries. For aliasing ppgtt support we just steal them at the end for |
346 | * entries. For aliasing ppgtt support we just steal them at the end for |
Line -... | Line 347... | ||
- | 347 | * now. */ |
|
253 | * now. */ |
348 | first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt); |
254 | first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt); |
349 | |
255 | 350 | ppgtt->base.pte_encode = dev_priv->gtt.base.pte_encode; |
|
256 | ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; |
351 | ppgtt->num_pd_entries = GEN6_PPGTT_PD_ENTRIES; |
257 | ppgtt->enable = gen6_ppgtt_enable; |
352 | ppgtt->enable = gen6_ppgtt_enable; |
- | 353 | ppgtt->base.clear_range = gen6_ppgtt_clear_range; |
|
258 | ppgtt->clear_range = gen6_ppgtt_clear_range; |
354 | ppgtt->base.insert_entries = gen6_ppgtt_insert_entries; |
259 | ppgtt->insert_entries = gen6_ppgtt_insert_entries; |
355 | ppgtt->base.cleanup = gen6_ppgtt_cleanup; |
260 | ppgtt->cleanup = gen6_ppgtt_cleanup; |
356 | ppgtt->base.scratch = dev_priv->gtt.base.scratch; |
261 | ppgtt->pt_pages = kzalloc(sizeof(struct page *)*ppgtt->num_pd_entries, |
357 | ppgtt->pt_pages = kzalloc(sizeof(struct page *)*ppgtt->num_pd_entries, |
Line 281... | Line 377... | ||
281 | PCI_DMA_BIDIRECTIONAL); |
377 | PCI_DMA_BIDIRECTIONAL); |
Line 282... | Line 378... | ||
282 | 378 | ||
283 | ppgtt->pt_dma_addr[i] = pt_addr; |
379 | ppgtt->pt_dma_addr[i] = pt_addr; |
Line 284... | Line 380... | ||
284 | } |
380 | } |
285 | 381 | ||
Line 286... | Line 382... | ||
286 | ppgtt->clear_range(ppgtt, 0, |
382 | ppgtt->base.clear_range(&ppgtt->base, 0, |
Line 287... | Line 383... | ||
287 | ppgtt->num_pd_entries*I915_PPGTT_PT_ENTRIES); |
383 | ppgtt->num_pd_entries*I915_PPGTT_PT_ENTRIES); |
Line 315... | Line 411... | ||
315 | 411 | ||
316 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); |
412 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); |
317 | if (!ppgtt) |
413 | if (!ppgtt) |
Line 318... | Line 414... | ||
318 | return -ENOMEM; |
414 | return -ENOMEM; |
319 | - | ||
Line 320... | Line 415... | ||
320 | ppgtt->dev = dev; |
415 | |
321 | ppgtt->scratch_page_dma_addr = dev_priv->gtt.scratch_page_dma; |
416 | ppgtt->base.dev = dev; |
322 | 417 | ||
323 | if (INTEL_INFO(dev)->gen < 8) |
418 | if (INTEL_INFO(dev)->gen < 8) |
Line 324... | Line 419... | ||
324 | ret = gen6_ppgtt_init(ppgtt); |
419 | ret = gen6_ppgtt_init(ppgtt); |
325 | else |
420 | else |
326 | BUG(); |
421 | BUG(); |
327 | 422 | ||
- | 423 | if (ret) |
|
- | 424 | kfree(ppgtt); |
|
- | 425 | else { |
|
Line 328... | Line 426... | ||
328 | if (ret) |
426 | dev_priv->mm.aliasing_ppgtt = ppgtt; |
329 | kfree(ppgtt); |
427 | drm_mm_init(&ppgtt->base.mm, ppgtt->base.start, |
Line 330... | Line 428... | ||
330 | else |
428 | ppgtt->base.total); |
Line 339... | Line 437... | ||
339 | struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; |
437 | struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; |
Line 340... | Line 438... | ||
340 | 438 | ||
341 | if (!ppgtt) |
439 | if (!ppgtt) |
Line 342... | Line 440... | ||
342 | return; |
440 | return; |
343 | 441 | ||
344 | ppgtt->cleanup(ppgtt); |
442 | ppgtt->base.cleanup(&ppgtt->base); |
Line 345... | Line 443... | ||
345 | dev_priv->mm.aliasing_ppgtt = NULL; |
443 | dev_priv->mm.aliasing_ppgtt = NULL; |
346 | } |
444 | } |
347 | 445 | ||
348 | void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, |
446 | void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, |
349 | struct drm_i915_gem_object *obj, |
447 | struct drm_i915_gem_object *obj, |
350 | enum i915_cache_level cache_level) |
448 | enum i915_cache_level cache_level) |
351 | { |
449 | { |
352 | ppgtt->insert_entries(ppgtt, obj->pages, |
450 | ppgtt->base.insert_entries(&ppgtt->base, obj->pages, |
Line 353... | Line 451... | ||
353 | obj->gtt_space->start >> PAGE_SHIFT, |
451 | i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, |
354 | cache_level); |
452 | cache_level); |
355 | } |
453 | } |
356 | 454 | ||
357 | void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, |
455 | void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, |
358 | struct drm_i915_gem_object *obj) |
456 | struct drm_i915_gem_object *obj) |
359 | { |
457 | { |
Line 360... | Line 458... | ||
360 | ppgtt->clear_range(ppgtt, |
458 | ppgtt->base.clear_range(&ppgtt->base, |
361 | obj->gtt_space->start >> PAGE_SHIFT, |
459 | i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT, |
Line 404... | Line 502... | ||
404 | { |
502 | { |
405 | struct drm_i915_private *dev_priv = dev->dev_private; |
503 | struct drm_i915_private *dev_priv = dev->dev_private; |
406 | struct drm_i915_gem_object *obj; |
504 | struct drm_i915_gem_object *obj; |
Line 407... | Line 505... | ||
407 | 505 | ||
408 | /* First fill our portion of the GTT with scratch pages */ |
506 | /* First fill our portion of the GTT with scratch pages */ |
- | 507 | dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, |
|
409 | dev_priv->gtt.gtt_clear_range(dev, dev_priv->gtt.start / PAGE_SIZE, |
508 | dev_priv->gtt.base.start / PAGE_SIZE, |
Line 410... | Line 509... | ||
410 | dev_priv->gtt.total / PAGE_SIZE); |
509 | dev_priv->gtt.base.total / PAGE_SIZE); |
411 | 510 | ||
412 | list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) { |
511 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { |
413 | i915_gem_clflush_object(obj); |
512 | i915_gem_clflush_object(obj, obj->pin_display); |
Line 414... | Line 513... | ||
414 | i915_gem_gtt_bind_object(obj, obj->cache_level); |
513 | i915_gem_gtt_bind_object(obj, obj->cache_level); |
415 | } |
514 | } |
Line 434... | Line 533... | ||
434 | * Binds an object into the global gtt with the specified cache level. The object |
533 | * Binds an object into the global gtt with the specified cache level. The object |
435 | * will be accessible to the GPU via commands whose operands reference offsets |
534 | * will be accessible to the GPU via commands whose operands reference offsets |
436 | * within the global GTT as well as accessible by the GPU through the GMADR |
535 | * within the global GTT as well as accessible by the GPU through the GMADR |
437 | * mapped BAR (dev_priv->mm.gtt->gtt). |
536 | * mapped BAR (dev_priv->mm.gtt->gtt). |
438 | */ |
537 | */ |
439 | static void gen6_ggtt_insert_entries(struct drm_device *dev, |
538 | static void gen6_ggtt_insert_entries(struct i915_address_space *vm, |
440 | struct sg_table *st, |
539 | struct sg_table *st, |
441 | unsigned int first_entry, |
540 | unsigned int first_entry, |
442 | enum i915_cache_level level) |
541 | enum i915_cache_level level) |
443 | { |
542 | { |
444 | struct drm_i915_private *dev_priv = dev->dev_private; |
543 | struct drm_i915_private *dev_priv = vm->dev->dev_private; |
445 | gen6_gtt_pte_t __iomem *gtt_entries = |
544 | gen6_gtt_pte_t __iomem *gtt_entries = |
446 | (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry; |
545 | (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry; |
447 | int i = 0; |
546 | int i = 0; |
448 | struct sg_page_iter sg_iter; |
547 | struct sg_page_iter sg_iter; |
449 | dma_addr_t addr; |
548 | dma_addr_t addr; |
Line 450... | Line 549... | ||
450 | 549 | ||
451 | for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) { |
550 | for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) { |
452 | addr = sg_page_iter_dma_address(&sg_iter); |
551 | addr = sg_page_iter_dma_address(&sg_iter); |
453 | iowrite32(gen6_pte_encode(dev, addr, level), >t_entries[i]); |
552 | iowrite32(vm->pte_encode(addr, level), >t_entries[i]); |
454 | i++; |
553 | i++; |
Line 455... | Line 554... | ||
455 | } |
554 | } |
456 | 555 | ||
457 | /* XXX: This serves as a posting read to make sure that the PTE has |
556 | /* XXX: This serves as a posting read to make sure that the PTE has |
458 | * actually been updated. There is some concern that even though |
557 | * actually been updated. There is some concern that even though |
459 | * registers and PTEs are within the same BAR that they are potentially |
558 | * registers and PTEs are within the same BAR that they are potentially |
460 | * of NUMA access patterns. Therefore, even with the way we assume |
559 | * of NUMA access patterns. Therefore, even with the way we assume |
461 | * hardware should work, we must keep this posting read for paranoia. |
560 | * hardware should work, we must keep this posting read for paranoia. |
462 | */ |
561 | */ |
463 | if (i != 0) |
562 | if (i != 0) |
Line 464... | Line 563... | ||
464 | WARN_ON(readl(>t_entries[i-1]) |
563 | WARN_ON(readl(>t_entries[i-1]) != |
465 | != gen6_pte_encode(dev, addr, level)); |
564 | vm->pte_encode(addr, level)); |
466 | 565 | ||
467 | /* This next bit makes the above posting read even more important. We |
566 | /* This next bit makes the above posting read even more important. We |
468 | * want to flush the TLBs only after we're certain all the PTE updates |
567 | * want to flush the TLBs only after we're certain all the PTE updates |
469 | * have finished. |
568 | * have finished. |
470 | */ |
569 | */ |
Line 471... | Line 570... | ||
471 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); |
570 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); |
472 | POSTING_READ(GFX_FLSH_CNTL_GEN6); |
571 | POSTING_READ(GFX_FLSH_CNTL_GEN6); |
473 | } |
572 | } |
474 | 573 | ||
475 | static void gen6_ggtt_clear_range(struct drm_device *dev, |
574 | static void gen6_ggtt_clear_range(struct i915_address_space *vm, |
476 | unsigned int first_entry, |
575 | unsigned int first_entry, |
477 | unsigned int num_entries) |
576 | unsigned int num_entries) |
478 | { |
577 | { |
479 | struct drm_i915_private *dev_priv = dev->dev_private; |
578 | struct drm_i915_private *dev_priv = vm->dev->dev_private; |
Line 486... | Line 585... | ||
486 | // "First entry = %d; Num entries = %d (max=%d)\n", |
585 | // "First entry = %d; Num entries = %d (max=%d)\n", |
487 | // first_entry, num_entries, max_entries)) |
586 | // first_entry, num_entries, max_entries)) |
488 | if (num_entries > max_entries) |
587 | if (num_entries > max_entries) |
489 | num_entries = max_entries; |
588 | num_entries = max_entries; |
Line 490... | Line 589... | ||
490 | 589 | ||
491 | scratch_pte = gen6_pte_encode(dev, dev_priv->gtt.scratch_page_dma, |
- | |
492 | I915_CACHE_LLC); |
590 | scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC); |
493 | for (i = 0; i < num_entries; i++) |
591 | for (i = 0; i < num_entries; i++) |
494 | iowrite32(scratch_pte, >t_base[i]); |
592 | iowrite32(scratch_pte, >t_base[i]); |
495 | readl(gtt_base); |
593 | readl(gtt_base); |
Line 496... | Line 594... | ||
496 | } |
594 | } |
497 | 595 | ||
498 | 596 | ||
499 | static void i915_ggtt_insert_entries(struct drm_device *dev, |
597 | static void i915_ggtt_insert_entries(struct i915_address_space *vm, |
500 | struct sg_table *st, |
598 | struct sg_table *st, |
501 | unsigned int pg_start, |
599 | unsigned int pg_start, |
Line 506... | Line 604... | ||
506 | 604 | ||
Line 507... | Line 605... | ||
507 | intel_gtt_insert_sg_entries(st, pg_start, flags); |
605 | intel_gtt_insert_sg_entries(st, pg_start, flags); |
Line 508... | Line 606... | ||
508 | 606 | ||
509 | } |
607 | } |
510 | 608 | ||
511 | static void i915_ggtt_clear_range(struct drm_device *dev, |
609 | static void i915_ggtt_clear_range(struct i915_address_space *vm, |
512 | unsigned int first_entry, |
610 | unsigned int first_entry, |
513 | unsigned int num_entries) |
611 | unsigned int num_entries) |
Line 519... | Line 617... | ||
519 | void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj, |
617 | void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj, |
520 | enum i915_cache_level cache_level) |
618 | enum i915_cache_level cache_level) |
521 | { |
619 | { |
522 | struct drm_device *dev = obj->base.dev; |
620 | struct drm_device *dev = obj->base.dev; |
523 | struct drm_i915_private *dev_priv = dev->dev_private; |
621 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | 622 | const unsigned long entry = i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT; |
|
Line 524... | Line 623... | ||
524 | 623 | ||
525 | dev_priv->gtt.gtt_insert_entries(dev, obj->pages, |
624 | dev_priv->gtt.base.insert_entries(&dev_priv->gtt.base, obj->pages, |
526 | obj->gtt_space->start >> PAGE_SHIFT, |
625 | entry, |
Line 527... | Line 626... | ||
527 | cache_level); |
626 | cache_level); |
528 | 627 | ||
Line 529... | Line 628... | ||
529 | obj->has_global_gtt_mapping = 1; |
628 | obj->has_global_gtt_mapping = 1; |
530 | } |
629 | } |
531 | 630 | ||
532 | void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj) |
631 | void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj) |
- | 632 | { |
|
Line 533... | Line 633... | ||
533 | { |
633 | struct drm_device *dev = obj->base.dev; |
534 | struct drm_device *dev = obj->base.dev; |
634 | struct drm_i915_private *dev_priv = dev->dev_private; |
535 | struct drm_i915_private *dev_priv = dev->dev_private; |
635 | const unsigned long entry = i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT; |
Line 536... | Line 636... | ||
536 | 636 | ||
537 | dev_priv->gtt.gtt_clear_range(obj->base.dev, |
637 | dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, |
Line 585... | Line 685... | ||
585 | * past the end of the object, and we've seen multiple hangs with the |
685 | * past the end of the object, and we've seen multiple hangs with the |
586 | * GPU head pointer stuck in a batchbuffer bound at the last page of the |
686 | * GPU head pointer stuck in a batchbuffer bound at the last page of the |
587 | * aperture. One page should be enough to keep any prefetching inside |
687 | * aperture. One page should be enough to keep any prefetching inside |
588 | * of the aperture. |
688 | * of the aperture. |
589 | */ |
689 | */ |
590 | drm_i915_private_t *dev_priv = dev->dev_private; |
690 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | 691 | struct i915_address_space *ggtt_vm = &dev_priv->gtt.base; |
|
591 | struct drm_mm_node *entry; |
692 | struct drm_mm_node *entry; |
592 | struct drm_i915_gem_object *obj; |
693 | struct drm_i915_gem_object *obj; |
593 | unsigned long hole_start, hole_end; |
694 | unsigned long hole_start, hole_end; |
Line 594... | Line 695... | ||
594 | 695 | ||
Line 595... | Line 696... | ||
595 | BUG_ON(mappable_end > end); |
696 | BUG_ON(mappable_end > end); |
596 | 697 | ||
597 | /* Subtract the guard page ... */ |
698 | /* Subtract the guard page ... */ |
598 | drm_mm_init(&dev_priv->mm.gtt_space, start, end - start - PAGE_SIZE); |
699 | drm_mm_init(&ggtt_vm->mm, start, end - start - PAGE_SIZE); |
Line 599... | Line 700... | ||
599 | if (!HAS_LLC(dev)) |
700 | if (!HAS_LLC(dev)) |
600 | dev_priv->mm.gtt_space.color_adjust = i915_gtt_color_adjust; |
701 | dev_priv->gtt.base.mm.color_adjust = i915_gtt_color_adjust; |
- | 702 | ||
- | 703 | /* Mark any preallocated objects as occupied */ |
|
601 | 704 | list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { |
|
602 | /* Mark any preallocated objects as occupied */ |
705 | struct i915_vma *vma = i915_gem_obj_to_vma(obj, ggtt_vm); |
603 | list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list) { |
706 | int ret; |
604 | DRM_DEBUG_KMS("reserving preallocated space: %x + %zx\n", |
707 | DRM_DEBUG_KMS("reserving preallocated space: %lx + %zx\n", |
605 | obj->gtt_offset, obj->base.size); |
708 | i915_gem_obj_ggtt_offset(obj), obj->base.size); |
606 | 709 | ||
607 | BUG_ON(obj->gtt_space != I915_GTT_RESERVED); |
710 | WARN_ON(i915_gem_obj_ggtt_bound(obj)); |
608 | obj->gtt_space = drm_mm_create_block(&dev_priv->mm.gtt_space, |
- | |
609 | obj->gtt_offset, |
711 | ret = drm_mm_reserve_node(&ggtt_vm->mm, &vma->node); |
- | 712 | if (ret) |
|
610 | obj->base.size, |
713 | DRM_DEBUG_KMS("Reservation failed\n"); |
Line 611... | Line 714... | ||
611 | false); |
714 | obj->has_global_gtt_mapping = 1; |
612 | obj->has_global_gtt_mapping = 1; |
715 | list_add(&vma->vma_link, &obj->vma_list); |
Line 613... | Line 716... | ||
613 | } |
716 | } |
614 | 717 | ||
615 | dev_priv->gtt.start = start; |
718 | dev_priv->gtt.base.start = start; |
616 | dev_priv->gtt.total = end - start; |
719 | dev_priv->gtt.base.total = end - start; |
617 | 720 | ||
618 | /* Clear any non-preallocated blocks */ |
721 | /* Clear any non-preallocated blocks */ |
619 | drm_mm_for_each_hole(entry, &dev_priv->mm.gtt_space, |
- | |
620 | hole_start, hole_end) { |
722 | drm_mm_for_each_hole(entry, &ggtt_vm->mm, hole_start, hole_end) { |
Line 621... | Line 723... | ||
621 | DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", |
723 | const unsigned long count = (hole_end - hole_start) / PAGE_SIZE; |
622 | hole_start, hole_end); |
724 | DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", |
623 | dev_priv->gtt.gtt_clear_range(dev, hole_start / PAGE_SIZE, |
725 | hole_start, hole_end); |
Line 624... | Line 726... | ||
624 | (hole_end-hole_start) / PAGE_SIZE); |
726 | ggtt_vm->clear_range(ggtt_vm, hole_start / PAGE_SIZE, count); |
625 | } |
727 | } |
626 | 728 | ||
Line 646... | Line 748... | ||
646 | void i915_gem_init_global_gtt(struct drm_device *dev) |
748 | void i915_gem_init_global_gtt(struct drm_device *dev) |
647 | { |
749 | { |
648 | struct drm_i915_private *dev_priv = dev->dev_private; |
750 | struct drm_i915_private *dev_priv = dev->dev_private; |
649 | unsigned long gtt_size, mappable_size; |
751 | unsigned long gtt_size, mappable_size; |
Line 650... | Line 752... | ||
650 | 752 | ||
651 | gtt_size = dev_priv->gtt.total; |
753 | gtt_size = dev_priv->gtt.base.total; |
Line 652... | Line 754... | ||
652 | mappable_size = dev_priv->gtt.mappable_end; |
754 | mappable_size = dev_priv->gtt.mappable_end; |
653 | 755 | ||
654 | #if 0 |
756 | #if 0 |
Line 655... | Line 757... | ||
655 | if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) { |
757 | if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) { |
656 | int ret; |
758 | int ret; |
657 | 759 | ||
658 | if (INTEL_INFO(dev)->gen <= 7) { |
760 | if (INTEL_INFO(dev)->gen <= 7) { |
659 | /* PPGTT pdes are stolen from global gtt ptes, so shrink the |
761 | /* PPGTT pdes are stolen from global gtt ptes, so shrink the |
Line 660... | Line 762... | ||
660 | * aperture accordingly when using aliasing ppgtt. */ |
762 | * aperture accordingly when using aliasing ppgtt. */ |
Line 661... | Line 763... | ||
661 | gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; |
763 | gtt_size -= GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE; |
662 | } |
764 | } |
663 | 765 | ||
Line 664... | Line 766... | ||
664 | i915_gem_setup_global_gtt(dev, LFB_SIZE, mappable_size, gtt_size); |
766 | i915_gem_setup_global_gtt(dev, LFB_SIZE, mappable_size, gtt_size-LFB_SIZE); |
665 | 767 | ||
666 | ret = i915_gem_init_aliasing_ppgtt(dev); |
768 | ret = i915_gem_init_aliasing_ppgtt(dev); |
667 | if (!ret) |
769 | if (!ret) |
668 | return; |
770 | return; |
Line 669... | Line 771... | ||
669 | 771 | ||
670 | DRM_ERROR("Aliased PPGTT setup failed %d\n", ret); |
772 | DRM_ERROR("Aliased PPGTT setup failed %d\n", ret); |
Line 671... | Line 773... | ||
671 | drm_mm_takedown(&dev_priv->mm.gtt_space); |
773 | drm_mm_takedown(&dev_priv->gtt.base.mm); |
672 | gtt_size += I915_PPGTT_PD_ENTRIES*PAGE_SIZE; |
774 | gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE; |
673 | } |
775 | } |
Line 694... | Line 796... | ||
694 | if (pci_dma_mapping_error(dev->pdev, dma_addr)) |
796 | if (pci_dma_mapping_error(dev->pdev, dma_addr)) |
695 | return -EINVAL; |
797 | return -EINVAL; |
696 | #else |
798 | #else |
697 | dma_addr = page_to_phys(page); |
799 | dma_addr = page_to_phys(page); |
698 | #endif |
800 | #endif |
699 | dev_priv->gtt.scratch_page = page; |
801 | dev_priv->gtt.base.scratch.page = page; |
700 | dev_priv->gtt.scratch_page_dma = dma_addr; |
802 | dev_priv->gtt.base.scratch.addr = dma_addr; |
Line 701... | Line 803... | ||
701 | 803 | ||
702 | return 0; |
804 | return 0; |
Line 703... | Line 805... | ||
703 | } |
805 | } |
704 | 806 | ||
705 | static void teardown_scratch_page(struct drm_device *dev) |
807 | static void teardown_scratch_page(struct drm_device *dev) |
706 | { |
808 | { |
- | 809 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 810 | struct page *page = dev_priv->gtt.base.scratch.page; |
|
707 | struct drm_i915_private *dev_priv = dev->dev_private; |
811 | |
708 | set_pages_wb(dev_priv->gtt.scratch_page, 1); |
812 | set_pages_wb(page, 1); |
709 | pci_unmap_page(dev->pdev, dev_priv->gtt.scratch_page_dma, |
813 | pci_unmap_page(dev->pdev, dev_priv->gtt.base.scratch.addr, |
710 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
814 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
711 | put_page(dev_priv->gtt.scratch_page); |
815 | put_page(page); |
Line 712... | Line 816... | ||
712 | __free_page(dev_priv->gtt.scratch_page); |
816 | __free_page(page); |
713 | } |
817 | } |
714 | 818 | ||
Line 770... | Line 874... | ||
770 | 874 | ||
771 | ret = setup_scratch_page(dev); |
875 | ret = setup_scratch_page(dev); |
772 | if (ret) |
876 | if (ret) |
Line 773... | Line 877... | ||
773 | DRM_ERROR("Scratch setup failed\n"); |
877 | DRM_ERROR("Scratch setup failed\n"); |
774 | 878 | ||
Line 775... | Line 879... | ||
775 | dev_priv->gtt.gtt_clear_range = gen6_ggtt_clear_range; |
879 | dev_priv->gtt.base.clear_range = gen6_ggtt_clear_range; |
776 | dev_priv->gtt.gtt_insert_entries = gen6_ggtt_insert_entries; |
880 | dev_priv->gtt.base.insert_entries = gen6_ggtt_insert_entries; |
Line 777... | Line 881... | ||
777 | 881 | ||
778 | return ret; |
882 | return ret; |
- | 883 | } |
|
779 | } |
884 | |
780 | 885 | static void gen6_gmch_remove(struct i915_address_space *vm) |
|
781 | static void gen6_gmch_remove(struct drm_device *dev) |
886 | { |
782 | { |
887 | |
Line 783... | Line 888... | ||
783 | struct drm_i915_private *dev_priv = dev->dev_private; |
888 | struct i915_gtt *gtt = container_of(vm, struct i915_gtt, base); |
784 | iounmap(dev_priv->gtt.gsm); |
889 | iounmap(gtt->gsm); |
785 | teardown_scratch_page(dev_priv->dev); |
890 | teardown_scratch_page(vm->dev); |
Line 801... | Line 906... | ||
801 | } |
906 | } |
Line 802... | Line 907... | ||
802 | 907 | ||
Line 803... | Line 908... | ||
803 | intel_gtt_get(gtt_total, stolen, mappable_base, mappable_end); |
908 | intel_gtt_get(gtt_total, stolen, mappable_base, mappable_end); |
804 | 909 | ||
805 | dev_priv->gtt.do_idle_maps = needs_idle_maps(dev_priv->dev); |
910 | dev_priv->gtt.do_idle_maps = needs_idle_maps(dev_priv->dev); |
Line 806... | Line 911... | ||
806 | dev_priv->gtt.gtt_clear_range = i915_ggtt_clear_range; |
911 | dev_priv->gtt.base.clear_range = i915_ggtt_clear_range; |
807 | dev_priv->gtt.gtt_insert_entries = i915_ggtt_insert_entries; |
912 | dev_priv->gtt.base.insert_entries = i915_ggtt_insert_entries; |
Line 808... | Line 913... | ||
808 | 913 | ||
809 | return 0; |
914 | return 0; |
810 | } |
915 | } |
811 | 916 | ||
Line 812... | Line 917... | ||
812 | static void i915_gmch_remove(struct drm_device *dev) |
917 | static void i915_gmch_remove(struct i915_address_space *vm) |
Line 819... | Line 924... | ||
819 | struct drm_i915_private *dev_priv = dev->dev_private; |
924 | struct drm_i915_private *dev_priv = dev->dev_private; |
820 | struct i915_gtt *gtt = &dev_priv->gtt; |
925 | struct i915_gtt *gtt = &dev_priv->gtt; |
821 | int ret; |
926 | int ret; |
Line 822... | Line 927... | ||
822 | 927 | ||
823 | if (INTEL_INFO(dev)->gen <= 5) { |
928 | if (INTEL_INFO(dev)->gen <= 5) { |
824 | dev_priv->gtt.gtt_probe = i915_gmch_probe; |
929 | gtt->gtt_probe = i915_gmch_probe; |
825 | dev_priv->gtt.gtt_remove = i915_gmch_remove; |
930 | gtt->base.cleanup = i915_gmch_remove; |
826 | } else { |
931 | } else { |
827 | dev_priv->gtt.gtt_probe = gen6_gmch_probe; |
932 | gtt->gtt_probe = gen6_gmch_probe; |
- | 933 | gtt->base.cleanup = gen6_gmch_remove; |
|
- | 934 | if (IS_HASWELL(dev) && dev_priv->ellc_size) |
|
- | 935 | gtt->base.pte_encode = iris_pte_encode; |
|
- | 936 | else if (IS_HASWELL(dev)) |
|
- | 937 | gtt->base.pte_encode = hsw_pte_encode; |
|
- | 938 | else if (IS_VALLEYVIEW(dev)) |
|
- | 939 | gtt->base.pte_encode = byt_pte_encode; |
|
- | 940 | else if (INTEL_INFO(dev)->gen >= 7) |
|
- | 941 | gtt->base.pte_encode = ivb_pte_encode; |
|
- | 942 | else |
|
828 | dev_priv->gtt.gtt_remove = gen6_gmch_remove; |
943 | gtt->base.pte_encode = snb_pte_encode; |
Line 829... | Line 944... | ||
829 | } |
944 | } |
830 | - | ||
831 | ret = dev_priv->gtt.gtt_probe(dev, &dev_priv->gtt.total, |
- | |
832 | &dev_priv->gtt.stolen_size, |
945 | |
833 | >t->mappable_base, |
946 | ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size, |
834 | >t->mappable_end); |
947 | >t->mappable_base, >t->mappable_end); |
Line -... | Line 948... | ||
- | 948 | if (ret) |
|
- | 949 | return ret; |
|
835 | if (ret) |
950 | |
836 | return ret; |
951 | gtt->base.dev = dev; |
837 | 952 | ||
838 | /* GMADR is the PCI mmio aperture into the global GTT. */ |
953 | /* GMADR is the PCI mmio aperture into the global GTT. */ |
839 | DRM_INFO("Memory usable by graphics device = %zdM\n", |
- | |
840 | dev_priv->gtt.total >> 20); |
954 | DRM_INFO("Memory usable by graphics device = %zdM\n", |
841 | DRM_DEBUG_DRIVER("GMADR size = %ldM\n", |
- | |
Line 842... | Line 955... | ||
842 | dev_priv->gtt.mappable_end >> 20); |
955 | gtt->base.total >> 20); |
843 | DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", |
956 | DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20); |
Line 844... | Line 957... | ||
844 | dev_priv->gtt.stolen_size >> 20); |
957 | DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20); |