diff options
author | Rob Clark <robdclark@gmail.com> | 2015-03-03 15:04:25 -0500 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2015-04-01 19:29:33 -0400 |
commit | 072f1f9168ed67d6ddc94bb76b1dfc04795062b4 (patch) | |
tree | b817aa6b4980b0fedc19e34007429a7b340cbc72 /drivers/gpu/drm/msm/msm_gem.c | |
parent | 5bf9c0b614542d69fb9a8681a0411715cc3e8ba8 (diff) |
drm/msm: add support for "stolen" mem
Add support to use the VRAM carveout (if specified in dtb) for fbdev
scanout buffer. This allows drm/msm to take over a bootloader splash-
screen, and avoids corruption on screen that results if the kernel uses
memory that is still being scanned out for itself.
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 49dea4fb55ac..479d8af72bcb 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
@@ -32,6 +32,12 @@ static dma_addr_t physaddr(struct drm_gem_object *obj) | |||
32 | priv->vram.paddr; | 32 | priv->vram.paddr; |
33 | } | 33 | } |
34 | 34 | ||
35 | static bool use_pages(struct drm_gem_object *obj) | ||
36 | { | ||
37 | struct msm_gem_object *msm_obj = to_msm_bo(obj); | ||
38 | return !msm_obj->vram_node; | ||
39 | } | ||
40 | |||
35 | /* allocate pages from VRAM carveout, used when no IOMMU: */ | 41 | /* allocate pages from VRAM carveout, used when no IOMMU: */ |
36 | static struct page **get_pages_vram(struct drm_gem_object *obj, | 42 | static struct page **get_pages_vram(struct drm_gem_object *obj, |
37 | int npages) | 43 | int npages) |
@@ -72,7 +78,7 @@ static struct page **get_pages(struct drm_gem_object *obj) | |||
72 | struct page **p; | 78 | struct page **p; |
73 | int npages = obj->size >> PAGE_SHIFT; | 79 | int npages = obj->size >> PAGE_SHIFT; |
74 | 80 | ||
75 | if (iommu_present(&platform_bus_type)) | 81 | if (use_pages(obj)) |
76 | p = drm_gem_get_pages(obj); | 82 | p = drm_gem_get_pages(obj); |
77 | else | 83 | else |
78 | p = get_pages_vram(obj, npages); | 84 | p = get_pages_vram(obj, npages); |
@@ -116,7 +122,7 @@ static void put_pages(struct drm_gem_object *obj) | |||
116 | sg_free_table(msm_obj->sgt); | 122 | sg_free_table(msm_obj->sgt); |
117 | kfree(msm_obj->sgt); | 123 | kfree(msm_obj->sgt); |
118 | 124 | ||
119 | if (iommu_present(&platform_bus_type)) | 125 | if (use_pages(obj)) |
120 | drm_gem_put_pages(obj, msm_obj->pages, true, false); | 126 | drm_gem_put_pages(obj, msm_obj->pages, true, false); |
121 | else { | 127 | else { |
122 | drm_mm_remove_node(msm_obj->vram_node); | 128 | drm_mm_remove_node(msm_obj->vram_node); |
@@ -580,6 +586,7 @@ static int msm_gem_new_impl(struct drm_device *dev, | |||
580 | struct msm_drm_private *priv = dev->dev_private; | 586 | struct msm_drm_private *priv = dev->dev_private; |
581 | struct msm_gem_object *msm_obj; | 587 | struct msm_gem_object *msm_obj; |
582 | unsigned sz; | 588 | unsigned sz; |
589 | bool use_vram = false; | ||
583 | 590 | ||
584 | switch (flags & MSM_BO_CACHE_MASK) { | 591 | switch (flags & MSM_BO_CACHE_MASK) { |
585 | case MSM_BO_UNCACHED: | 592 | case MSM_BO_UNCACHED: |
@@ -592,15 +599,23 @@ static int msm_gem_new_impl(struct drm_device *dev, | |||
592 | return -EINVAL; | 599 | return -EINVAL; |
593 | } | 600 | } |
594 | 601 | ||
595 | sz = sizeof(*msm_obj); | ||
596 | if (!iommu_present(&platform_bus_type)) | 602 | if (!iommu_present(&platform_bus_type)) |
603 | use_vram = true; | ||
604 | else if ((flags & MSM_BO_STOLEN) && priv->vram.size) | ||
605 | use_vram = true; | ||
606 | |||
607 | if (WARN_ON(use_vram && !priv->vram.size)) | ||
608 | return -EINVAL; | ||
609 | |||
610 | sz = sizeof(*msm_obj); | ||
611 | if (use_vram) | ||
597 | sz += sizeof(struct drm_mm_node); | 612 | sz += sizeof(struct drm_mm_node); |
598 | 613 | ||
599 | msm_obj = kzalloc(sz, GFP_KERNEL); | 614 | msm_obj = kzalloc(sz, GFP_KERNEL); |
600 | if (!msm_obj) | 615 | if (!msm_obj) |
601 | return -ENOMEM; | 616 | return -ENOMEM; |
602 | 617 | ||
603 | if (!iommu_present(&platform_bus_type)) | 618 | if (use_vram) |
604 | msm_obj->vram_node = (void *)&msm_obj[1]; | 619 | msm_obj->vram_node = (void *)&msm_obj[1]; |
605 | 620 | ||
606 | msm_obj->flags = flags; | 621 | msm_obj->flags = flags; |
@@ -630,7 +645,7 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, | |||
630 | if (ret) | 645 | if (ret) |
631 | goto fail; | 646 | goto fail; |
632 | 647 | ||
633 | if (iommu_present(&platform_bus_type)) { | 648 | if (use_pages(obj)) { |
634 | ret = drm_gem_object_init(dev, obj, size); | 649 | ret = drm_gem_object_init(dev, obj, size); |
635 | if (ret) | 650 | if (ret) |
636 | goto fail; | 651 | goto fail; |