source: src/linux/universal/linux-4.9/drivers/gpu/drm/i915/i915_gem_stolen.c @ 31662

Last change on this file since 31662 was 31662, checked in by brainslayer, 2 weeks ago

use new squashfs in all kernels

File size: 19.9 KB
Line 
1/*
2 * Copyright © 2008-2012 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 *    Eric Anholt <eric@anholt.net>
25 *    Chris Wilson <chris@chris-wilson.co.uk>
26 *
27 */
28
29#include <drm/drmP.h>
30#include <drm/i915_drm.h>
31#include "i915_drv.h"
32
33#define KB(x) ((x) * 1024)
34#define MB(x) (KB(x) * 1024)
35
36/*
37 * The BIOS typically reserves some of the system's memory for the exclusive
38 * use of the integrated graphics. This memory is no longer available for
39 * use by the OS and so the user finds that his system has less memory
40 * available than he put in. We refer to this memory as stolen.
41 *
42 * The BIOS will allocate its framebuffer from the stolen memory. Our
43 * goal is try to reuse that object for our own fbcon which must always
44 * be available for panics. Anything else we can reuse the stolen memory
45 * for is a boon.
46 */
47
48int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
49                                         struct drm_mm_node *node, u64 size,
50                                         unsigned alignment, u64 start, u64 end)
51{
52        int ret;
53
54        if (!drm_mm_initialized(&dev_priv->mm.stolen))
55                return -ENODEV;
56
57        /* See the comment at the drm_mm_init() call for more about this check.
58         * WaSkipStolenMemoryFirstPage:bdw+ (incomplete)
59         */
60        if (start < 4096 && INTEL_GEN(dev_priv) >= 8)
61                start = 4096;
62
63        mutex_lock(&dev_priv->mm.stolen_lock);
64        ret = drm_mm_insert_node_in_range(&dev_priv->mm.stolen, node, size,
65                                          alignment, start, end,
66                                          DRM_MM_SEARCH_DEFAULT);
67        mutex_unlock(&dev_priv->mm.stolen_lock);
68
69        return ret;
70}
71
72int i915_gem_stolen_insert_node(struct drm_i915_private *dev_priv,
73                                struct drm_mm_node *node, u64 size,
74                                unsigned alignment)
75{
76        struct i915_ggtt *ggtt = &dev_priv->ggtt;
77
78        return i915_gem_stolen_insert_node_in_range(dev_priv, node, size,
79                                                    alignment, 0,
80                                                    ggtt->stolen_usable_size);
81}
82
83void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv,
84                                 struct drm_mm_node *node)
85{
86        mutex_lock(&dev_priv->mm.stolen_lock);
87        drm_mm_remove_node(node);
88        mutex_unlock(&dev_priv->mm.stolen_lock);
89}
90
91static unsigned long i915_stolen_to_physical(struct drm_device *dev)
92{
93        struct drm_i915_private *dev_priv = to_i915(dev);
94        struct pci_dev *pdev = dev_priv->drm.pdev;
95        struct i915_ggtt *ggtt = &dev_priv->ggtt;
96        struct resource *r;
97        u32 base;
98
99        /* Almost universally we can find the Graphics Base of Stolen Memory
100         * at register BSM (0x5c) in the igfx configuration space. On a few
101         * (desktop) machines this is also mirrored in the bridge device at
102         * different locations, or in the MCHBAR.
103         *
104         * On 865 we just check the TOUD register.
105         *
106         * On 830/845/85x the stolen memory base isn't available in any
107         * register. We need to calculate it as TOM-TSEG_SIZE-stolen_size.
108         *
109         */
110        base = 0;
111        if (INTEL_INFO(dev)->gen >= 3) {
112                u32 bsm;
113
114                pci_read_config_dword(pdev, INTEL_BSM, &bsm);
115
116                base = bsm & INTEL_BSM_MASK;
117        } else if (IS_I865G(dev)) {
118                u32 tseg_size = 0;
119                u16 toud = 0;
120                u8 tmp;
121
122                pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(0, 0),
123                                         I845_ESMRAMC, &tmp);
124
125                if (tmp & TSEG_ENABLE) {
126                        switch (tmp & I845_TSEG_SIZE_MASK) {
127                        case I845_TSEG_SIZE_512K:
128                                tseg_size = KB(512);
129                                break;
130                        case I845_TSEG_SIZE_1M:
131                                tseg_size = MB(1);
132                                break;
133                        }
134                }
135
136                pci_bus_read_config_word(pdev->bus, PCI_DEVFN(0, 0),
137                                         I865_TOUD, &toud);
138
139                base = (toud << 16) + tseg_size;
140        } else if (IS_I85X(dev)) {
141                u32 tseg_size = 0;
142                u32 tom;
143                u8 tmp;
144
145                pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(0, 0),
146                                         I85X_ESMRAMC, &tmp);
147
148                if (tmp & TSEG_ENABLE)
149                        tseg_size = MB(1);
150
151                pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(0, 1),
152                                         I85X_DRB3, &tmp);
153                tom = tmp * MB(32);
154
155                base = tom - tseg_size - ggtt->stolen_size;
156        } else if (IS_845G(dev)) {
157                u32 tseg_size = 0;
158                u32 tom;
159                u8 tmp;
160
161                pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(0, 0),
162                                         I845_ESMRAMC, &tmp);
163
164                if (tmp & TSEG_ENABLE) {
165                        switch (tmp & I845_TSEG_SIZE_MASK) {
166                        case I845_TSEG_SIZE_512K:
167                                tseg_size = KB(512);
168                                break;
169                        case I845_TSEG_SIZE_1M:
170                                tseg_size = MB(1);
171                                break;
172                        }
173                }
174
175                pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(0, 0),
176                                         I830_DRB3, &tmp);
177                tom = tmp * MB(32);
178
179                base = tom - tseg_size - ggtt->stolen_size;
180        } else if (IS_I830(dev)) {
181                u32 tseg_size = 0;
182                u32 tom;
183                u8 tmp;
184
185                pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(0, 0),
186                                         I830_ESMRAMC, &tmp);
187
188                if (tmp & TSEG_ENABLE) {
189                        if (tmp & I830_TSEG_SIZE_1M)
190                                tseg_size = MB(1);
191                        else
192                                tseg_size = KB(512);
193                }
194
195                pci_bus_read_config_byte(pdev->bus, PCI_DEVFN(0, 0),
196                                         I830_DRB3, &tmp);
197                tom = tmp * MB(32);
198
199                base = tom - tseg_size - ggtt->stolen_size;
200        }
201
202        if (base == 0)
203                return 0;
204
205        /* make sure we don't clobber the GTT if it's within stolen memory */
206        if (INTEL_INFO(dev)->gen <= 4 && !IS_G33(dev) && !IS_G4X(dev)) {
207                struct {
208                        u32 start, end;
209                } stolen[2] = {
210                        { .start = base, .end = base + ggtt->stolen_size, },
211                        { .start = base, .end = base + ggtt->stolen_size, },
212                };
213                u64 ggtt_start, ggtt_end;
214
215                ggtt_start = I915_READ(PGTBL_CTL);
216                if (IS_GEN4(dev))
217                        ggtt_start = (ggtt_start & PGTBL_ADDRESS_LO_MASK) |
218                                     (ggtt_start & PGTBL_ADDRESS_HI_MASK) << 28;
219                else
220                        ggtt_start &= PGTBL_ADDRESS_LO_MASK;
221                ggtt_end = ggtt_start + ggtt_total_entries(ggtt) * 4;
222
223                if (ggtt_start >= stolen[0].start && ggtt_start < stolen[0].end)
224                        stolen[0].end = ggtt_start;
225                if (ggtt_end > stolen[1].start && ggtt_end <= stolen[1].end)
226                        stolen[1].start = ggtt_end;
227
228                /* pick the larger of the two chunks */
229                if (stolen[0].end - stolen[0].start >
230                    stolen[1].end - stolen[1].start) {
231                        base = stolen[0].start;
232                        ggtt->stolen_size = stolen[0].end - stolen[0].start;
233                } else {
234                        base = stolen[1].start;
235                        ggtt->stolen_size = stolen[1].end - stolen[1].start;
236                }
237
238                if (stolen[0].start != stolen[1].start ||
239                    stolen[0].end != stolen[1].end) {
240                        DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n",
241                                      (unsigned long long)ggtt_start,
242                                      (unsigned long long)ggtt_end - 1);
243                        DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n",
244                                      base, base + (u32)ggtt->stolen_size - 1);
245                }
246        }
247
248
249        /* Verify that nothing else uses this physical address. Stolen
250         * memory should be reserved by the BIOS and hidden from the
251         * kernel. So if the region is already marked as busy, something
252         * is seriously wrong.
253         */
254        r = devm_request_mem_region(dev->dev, base, ggtt->stolen_size,
255                                    "Graphics Stolen Memory");
256        if (r == NULL) {
257                /*
258                 * One more attempt but this time requesting region from
259                 * base + 1, as we have seen that this resolves the region
260                 * conflict with the PCI Bus.
261                 * This is a BIOS w/a: Some BIOS wrap stolen in the root
262                 * PCI bus, but have an off-by-one error. Hence retry the
263                 * reservation starting from 1 instead of 0.
264                 */
265                r = devm_request_mem_region(dev->dev, base + 1,
266                                            ggtt->stolen_size - 1,
267                                            "Graphics Stolen Memory");
268                /*
269                 * GEN3 firmware likes to smash pci bridges into the stolen
270                 * range. Apparently this works.
271                 */
272                if (r == NULL && !IS_GEN3(dev)) {
273                        DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n",
274                                  base, base + (uint32_t)ggtt->stolen_size);
275                        base = 0;
276                }
277        }
278
279        return base;
280}
281
282void i915_gem_cleanup_stolen(struct drm_device *dev)
283{
284        struct drm_i915_private *dev_priv = to_i915(dev);
285
286        if (!drm_mm_initialized(&dev_priv->mm.stolen))
287                return;
288
289        drm_mm_takedown(&dev_priv->mm.stolen);
290}
291
292static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv,
293                                    unsigned long *base, unsigned long *size)
294{
295        struct i915_ggtt *ggtt = &dev_priv->ggtt;
296        uint32_t reg_val = I915_READ(IS_GM45(dev_priv) ?
297                                     CTG_STOLEN_RESERVED :
298                                     ELK_STOLEN_RESERVED);
299        unsigned long stolen_top = dev_priv->mm.stolen_base +
300                                   ggtt->stolen_size;
301
302        *base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16;
303
304        WARN_ON((reg_val & G4X_STOLEN_RESERVED_ADDR1_MASK) < *base);
305
306        /* On these platforms, the register doesn't have a size field, so the
307         * size is the distance between the base and the top of the stolen
308         * memory. We also have the genuine case where base is zero and there's
309         * nothing reserved. */
310        if (*base == 0)
311                *size = 0;
312        else
313                *size = stolen_top - *base;
314}
315
316static void gen6_get_stolen_reserved(struct drm_i915_private *dev_priv,
317                                     unsigned long *base, unsigned long *size)
318{
319        uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED);
320
321        *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
322
323        switch (reg_val & GEN6_STOLEN_RESERVED_SIZE_MASK) {
324        case GEN6_STOLEN_RESERVED_1M:
325                *size = 1024 * 1024;
326                break;
327        case GEN6_STOLEN_RESERVED_512K:
328                *size = 512 * 1024;
329                break;
330        case GEN6_STOLEN_RESERVED_256K:
331                *size = 256 * 1024;
332                break;
333        case GEN6_STOLEN_RESERVED_128K:
334                *size = 128 * 1024;
335                break;
336        default:
337                *size = 1024 * 1024;
338                MISSING_CASE(reg_val & GEN6_STOLEN_RESERVED_SIZE_MASK);
339        }
340}
341
342static void gen7_get_stolen_reserved(struct drm_i915_private *dev_priv,
343                                     unsigned long *base, unsigned long *size)
344{
345        uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED);
346
347        *base = reg_val & GEN7_STOLEN_RESERVED_ADDR_MASK;
348
349        switch (reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK) {
350        case GEN7_STOLEN_RESERVED_1M:
351                *size = 1024 * 1024;
352                break;
353        case GEN7_STOLEN_RESERVED_256K:
354                *size = 256 * 1024;
355                break;
356        default:
357                *size = 1024 * 1024;
358                MISSING_CASE(reg_val & GEN7_STOLEN_RESERVED_SIZE_MASK);
359        }
360}
361
362static void gen8_get_stolen_reserved(struct drm_i915_private *dev_priv,
363                                     unsigned long *base, unsigned long *size)
364{
365        uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED);
366
367        *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
368
369        switch (reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK) {
370        case GEN8_STOLEN_RESERVED_1M:
371                *size = 1024 * 1024;
372                break;
373        case GEN8_STOLEN_RESERVED_2M:
374                *size = 2 * 1024 * 1024;
375                break;
376        case GEN8_STOLEN_RESERVED_4M:
377                *size = 4 * 1024 * 1024;
378                break;
379        case GEN8_STOLEN_RESERVED_8M:
380                *size = 8 * 1024 * 1024;
381                break;
382        default:
383                *size = 8 * 1024 * 1024;
384                MISSING_CASE(reg_val & GEN8_STOLEN_RESERVED_SIZE_MASK);
385        }
386}
387
388static void bdw_get_stolen_reserved(struct drm_i915_private *dev_priv,
389                                    unsigned long *base, unsigned long *size)
390{
391        struct i915_ggtt *ggtt = &dev_priv->ggtt;
392        uint32_t reg_val = I915_READ(GEN6_STOLEN_RESERVED);
393        unsigned long stolen_top;
394
395        stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size;
396
397        *base = reg_val & GEN6_STOLEN_RESERVED_ADDR_MASK;
398
399        /* On these platforms, the register doesn't have a size field, so the
400         * size is the distance between the base and the top of the stolen
401         * memory. We also have the genuine case where base is zero and there's
402         * nothing reserved. */
403        if (*base == 0)
404                *size = 0;
405        else
406                *size = stolen_top - *base;
407}
408
409int i915_gem_init_stolen(struct drm_device *dev)
410{
411        struct drm_i915_private *dev_priv = to_i915(dev);
412        struct i915_ggtt *ggtt = &dev_priv->ggtt;
413        unsigned long reserved_total, reserved_base = 0, reserved_size;
414        unsigned long stolen_top;
415
416        mutex_init(&dev_priv->mm.stolen_lock);
417
418        if (intel_vgpu_active(dev_priv)) {
419                DRM_INFO("iGVT-g active, disabling use of stolen memory\n");
420                return 0;
421        }
422
423#ifdef CONFIG_INTEL_IOMMU
424        if (intel_iommu_gfx_mapped && INTEL_INFO(dev)->gen < 8) {
425                DRM_INFO("DMAR active, disabling use of stolen memory\n");
426                return 0;
427        }
428#endif
429
430        if (ggtt->stolen_size == 0)
431                return 0;
432
433        dev_priv->mm.stolen_base = i915_stolen_to_physical(dev);
434        if (dev_priv->mm.stolen_base == 0)
435                return 0;
436
437        stolen_top = dev_priv->mm.stolen_base + ggtt->stolen_size;
438
439        switch (INTEL_INFO(dev_priv)->gen) {
440        case 2:
441        case 3:
442                break;
443        case 4:
444                if (IS_G4X(dev))
445                        g4x_get_stolen_reserved(dev_priv, &reserved_base,
446                                                &reserved_size);
447                break;
448        case 5:
449                /* Assume the gen6 maximum for the older platforms. */
450                reserved_size = 1024 * 1024;
451                reserved_base = stolen_top - reserved_size;
452                break;
453        case 6:
454                gen6_get_stolen_reserved(dev_priv, &reserved_base,
455                                         &reserved_size);
456                break;
457        case 7:
458                gen7_get_stolen_reserved(dev_priv, &reserved_base,
459                                         &reserved_size);
460                break;
461        default:
462                if (IS_BROADWELL(dev_priv) ||
463                    IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev))
464                        bdw_get_stolen_reserved(dev_priv, &reserved_base,
465                                                &reserved_size);
466                else
467                        gen8_get_stolen_reserved(dev_priv, &reserved_base,
468                                                 &reserved_size);
469                break;
470        }
471
472        /* It is possible for the reserved base to be zero, but the register
473         * field for size doesn't have a zero option. */
474        if (reserved_base == 0) {
475                reserved_size = 0;
476                reserved_base = stolen_top;
477        }
478
479        if (reserved_base < dev_priv->mm.stolen_base ||
480            reserved_base + reserved_size > stolen_top) {
481                DRM_DEBUG_KMS("Stolen reserved area [0x%08lx - 0x%08lx] outside stolen memory [0x%08lx - 0x%08lx]\n",
482                              reserved_base, reserved_base + reserved_size,
483                              dev_priv->mm.stolen_base, stolen_top);
484                return 0;
485        }
486
487        ggtt->stolen_reserved_base = reserved_base;
488        ggtt->stolen_reserved_size = reserved_size;
489
490        /* It is possible for the reserved area to end before the end of stolen
491         * memory, so just consider the start. */
492        reserved_total = stolen_top - reserved_base;
493
494        DRM_DEBUG_KMS("Memory reserved for graphics device: %zuK, usable: %luK\n",
495                      ggtt->stolen_size >> 10,
496                      (ggtt->stolen_size - reserved_total) >> 10);
497
498        ggtt->stolen_usable_size = ggtt->stolen_size - reserved_total;
499
500        /*
501         * Basic memrange allocator for stolen space.
502         *
503         * TODO: Notice that some platforms require us to not use the first page
504         * of the stolen memory but their BIOSes may still put the framebuffer
505         * on the first page. So we don't reserve this page for now because of
506         * that. Our current solution is to just prevent new nodes from being
507         * inserted on the first page - see the check we have at
508         * i915_gem_stolen_insert_node_in_range(). We may want to fix the fbcon
509         * problem later.
510         */
511        drm_mm_init(&dev_priv->mm.stolen, 0, ggtt->stolen_usable_size);
512
513        return 0;
514}
515
516static struct sg_table *
517i915_pages_create_for_stolen(struct drm_device *dev,
518                             u32 offset, u32 size)
519{
520        struct drm_i915_private *dev_priv = to_i915(dev);
521        struct i915_ggtt *ggtt = &dev_priv->ggtt;
522        struct sg_table *st;
523        struct scatterlist *sg;
524
525        DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size);
526        BUG_ON(offset > ggtt->stolen_size - size);
527
528        /* We hide that we have no struct page backing our stolen object
529         * by wrapping the contiguous physical allocation with a fake
530         * dma mapping in a single scatterlist.
531         */
532
533        st = kmalloc(sizeof(*st), GFP_KERNEL);
534        if (st == NULL)
535                return NULL;
536
537        if (sg_alloc_table(st, 1, GFP_KERNEL)) {
538                kfree(st);
539                return NULL;
540        }
541
542        sg = st->sgl;
543        sg->offset = 0;
544        sg->length = size;
545
546        sg_dma_address(sg) = (dma_addr_t)dev_priv->mm.stolen_base + offset;
547        sg_dma_len(sg) = size;
548
549        return st;
550}
551
552static int i915_gem_object_get_pages_stolen(struct drm_i915_gem_object *obj)
553{
554        BUG();
555        return -EINVAL;
556}
557
558static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj)
559{
560        /* Should only be called during free */
561        sg_free_table(obj->pages);
562        kfree(obj->pages);
563}
564
565
566static void
567i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)
568{
569        struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
570
571        if (obj->stolen) {
572                i915_gem_stolen_remove_node(dev_priv, obj->stolen);
573                kfree(obj->stolen);
574                obj->stolen = NULL;
575        }
576}
577static const struct drm_i915_gem_object_ops i915_gem_object_stolen_ops = {
578        .get_pages = i915_gem_object_get_pages_stolen,
579        .put_pages = i915_gem_object_put_pages_stolen,
580        .release = i915_gem_object_release_stolen,
581};
582
583static struct drm_i915_gem_object *
584_i915_gem_object_create_stolen(struct drm_device *dev,
585                               struct drm_mm_node *stolen)
586{
587        struct drm_i915_gem_object *obj;
588
589        obj = i915_gem_object_alloc(dev);
590        if (obj == NULL)
591                return NULL;
592
593        drm_gem_private_object_init(dev, &obj->base, stolen->size);
594        i915_gem_object_init(obj, &i915_gem_object_stolen_ops);
595
596        obj->pages = i915_pages_create_for_stolen(dev,
597                                                  stolen->start, stolen->size);
598        if (obj->pages == NULL)
599                goto cleanup;
600
601        obj->get_page.sg = obj->pages->sgl;
602        obj->get_page.last = 0;
603
604        i915_gem_object_pin_pages(obj);
605        obj->stolen = stolen;
606
607        obj->base.read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
608        obj->cache_level = HAS_LLC(dev) ? I915_CACHE_LLC : I915_CACHE_NONE;
609
610        return obj;
611
612cleanup:
613        i915_gem_object_free(obj);
614        return NULL;
615}
616
617struct drm_i915_gem_object *
618i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
619{
620        struct drm_i915_private *dev_priv = to_i915(dev);
621        struct drm_i915_gem_object *obj;
622        struct drm_mm_node *stolen;
623        int ret;
624
625        if (!drm_mm_initialized(&dev_priv->mm.stolen))
626                return NULL;
627
628        DRM_DEBUG_KMS("creating stolen object: size=%x\n", size);
629        if (size == 0)
630                return NULL;
631
632        stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
633        if (!stolen)
634                return NULL;
635
636        ret = i915_gem_stolen_insert_node(dev_priv, stolen, size, 4096);
637        if (ret) {
638                kfree(stolen);
639                return NULL;
640        }
641
642        obj = _i915_gem_object_create_stolen(dev, stolen);
643        if (obj)
644                return obj;
645
646        i915_gem_stolen_remove_node(dev_priv, stolen);
647        kfree(stolen);
648        return NULL;
649}
650
651struct drm_i915_gem_object *
652i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
653                                               u32 stolen_offset,
654                                               u32 gtt_offset,
655                                               u32 size)
656{
657        struct drm_i915_private *dev_priv = to_i915(dev);
658        struct i915_ggtt *ggtt = &dev_priv->ggtt;
659        struct drm_i915_gem_object *obj;
660        struct drm_mm_node *stolen;
661        struct i915_vma *vma;
662        int ret;
663
664        if (!drm_mm_initialized(&dev_priv->mm.stolen))
665                return NULL;
666
667        lockdep_assert_held(&dev->struct_mutex);
668
669        DRM_DEBUG_KMS("creating preallocated stolen object: stolen_offset=%x, gtt_offset=%x, size=%x\n",
670                        stolen_offset, gtt_offset, size);
671
672        /* KISS and expect everything to be page-aligned */
673        if (WARN_ON(size == 0) || WARN_ON(size & 4095) ||
674            WARN_ON(stolen_offset & 4095))
675                return NULL;
676
677        stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
678        if (!stolen)
679                return NULL;
680
681        stolen->start = stolen_offset;
682        stolen->size = size;
683        mutex_lock(&dev_priv->mm.stolen_lock);
684        ret = drm_mm_reserve_node(&dev_priv->mm.stolen, stolen);
685        mutex_unlock(&dev_priv->mm.stolen_lock);
686        if (ret) {
687                DRM_DEBUG_KMS("failed to allocate stolen space\n");
688                kfree(stolen);
689                return NULL;
690        }
691
692        obj = _i915_gem_object_create_stolen(dev, stolen);
693        if (obj == NULL) {
694                DRM_DEBUG_KMS("failed to allocate stolen object\n");
695                i915_gem_stolen_remove_node(dev_priv, stolen);
696                kfree(stolen);
697                return NULL;
698        }
699
700        /* Some objects just need physical mem from stolen space */
701        if (gtt_offset == I915_GTT_OFFSET_NONE)
702                return obj;
703
704        vma = i915_gem_obj_lookup_or_create_vma(obj, &ggtt->base, NULL);
705        if (IS_ERR(vma)) {
706                ret = PTR_ERR(vma);
707                goto err;
708        }
709
710        /* To simplify the initialisation sequence between KMS and GTT,
711         * we allow construction of the stolen object prior to
712         * setting up the GTT space. The actual reservation will occur
713         * later.
714         */
715        vma->node.start = gtt_offset;
716        vma->node.size = size;
717
718        ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node);
719        if (ret) {
720                DRM_DEBUG_KMS("failed to allocate stolen GTT space\n");
721                goto err;
722        }
723
724        vma->pages = obj->pages;
725        vma->flags |= I915_VMA_GLOBAL_BIND;
726        __i915_vma_set_map_and_fenceable(vma);
727        list_move_tail(&vma->vm_link, &ggtt->base.inactive_list);
728        obj->bind_count++;
729
730        list_add_tail(&obj->global_list, &dev_priv->mm.bound_list);
731        i915_gem_object_pin_pages(obj);
732
733        return obj;
734
735err:
736        i915_gem_object_put(obj);
737        return NULL;
738}
Note: See TracBrowser for help on using the repository browser.