diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-15 18:52:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-15 18:52:01 -0500 |
commit | 988adfdffdd43cfd841df734664727993076d7cb (patch) | |
tree | 6794f7bba8f595500c2b7d33376ad6614adcfaf2 /drivers/gpu/drm/i915/i915_gem_gtt.c | |
parent | 26178ec11ef3c6c814bf16a0a2b9c2f7242e3c64 (diff) | |
parent | 4e0cd68115620bc3236ff4e58e4c073948629b41 (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"Highlights:
- AMD KFD driver merge
This is the AMD HSA interface for exposing a lowlevel interface for
GPGPU use. They have an open source userspace built on top of this
interface, and the code looks as good as it was going to get out of
tree.
- Initial atomic modesetting work
The need for an atomic modesetting interface to allow userspace to
try and send a complete set of modesetting state to the driver has
arisen, and been suffering from neglect this past year. No more,
the start of the common code and changes for msm driver to use it
are in this tree. Ongoing work to get the userspace ioctl finished
and the code clean will probably wait until next kernel.
- DisplayID 1.3 and tiled monitor exposed to userspace.
Tiled monitor property is now exposed for userspace to make use of.
- Rockchip drm driver merged.
- imx gpu driver moved out of staging
Other stuff:
- core:
panel - MIPI DSI + new panels.
expose suggested x/y properties for virtual GPUs
- i915:
Initial Skylake (SKL) support
gen3/4 reset work
start of dri1/ums removal
infoframe tracking
fixes for lots of things.
- nouveau:
tegra k1 voltage support
GM204 modesetting support
GT21x memory reclocking work
- radeon:
CI dpm fixes
GPUVM improvements
Initial DPM fan control
- rcar-du:
HDMI support added
removed some support for old boards
slave encoder driver for Analog Devices adv7511
- exynos:
Exynos4415 SoC support
- msm:
a4xx gpu support
atomic helper conversion
- tegra:
iommu support
universal plane support
ganged-mode DSI support
- sti:
HDMI i2c improvements
- vmwgfx:
some late fixes.
- qxl:
use suggested x/y properties"
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (969 commits)
drm: sti: fix module compilation issue
drm/i915: save/restore GMBUS freq across suspend/resume on gen4
drm: sti: correctly cleanup CRTC and planes
drm: sti: add HQVDP plane
drm: sti: add cursor plane
drm: sti: enable auxiliary CRTC
drm: sti: fix delay in VTG programming
drm: sti: prepare sti_tvout to support auxiliary crtc
drm: sti: use drm_crtc_vblank_{on/off} instead of drm_vblank_{on/off}
drm: sti: fix hdmi avi infoframe
drm: sti: remove event lock while disabling vblank
drm: sti: simplify gdp code
drm: sti: clear all mixer control
drm: sti: remove gpio for HDMI hot plug detection
drm: sti: allow to change hdmi ddc i2c adapter
drm/doc: Document drm_add_modes_noedid() usage
drm/i915: Remove '& 0xffff' from the mask given to WA_REG()
drm/i915: Invert the mask and val arguments in wa_add() and WA_REG()
drm: Zero out DRM object memory upon cleanup
drm/i915/bdw: Fix the write setting up the WIZ hashing mode
...
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_gtt.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 96 |
1 files changed, 66 insertions, 30 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 728938f02341..171f6eafdeee 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -35,13 +35,26 @@ static void chv_setup_private_ppat(struct drm_i915_private *dev_priv); | |||
35 | 35 | ||
36 | static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) | 36 | static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) |
37 | { | 37 | { |
38 | if (enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev)) | 38 | bool has_aliasing_ppgtt; |
39 | bool has_full_ppgtt; | ||
40 | |||
41 | has_aliasing_ppgtt = INTEL_INFO(dev)->gen >= 6; | ||
42 | has_full_ppgtt = INTEL_INFO(dev)->gen >= 7; | ||
43 | if (IS_GEN8(dev)) | ||
44 | has_full_ppgtt = false; /* XXX why? */ | ||
45 | |||
46 | /* | ||
47 | * We don't allow disabling PPGTT for gen9+ as it's a requirement for | ||
48 | * execlists, the sole mechanism available to submit work. | ||
49 | */ | ||
50 | if (INTEL_INFO(dev)->gen < 9 && | ||
51 | (enable_ppgtt == 0 || !has_aliasing_ppgtt)) | ||
39 | return 0; | 52 | return 0; |
40 | 53 | ||
41 | if (enable_ppgtt == 1) | 54 | if (enable_ppgtt == 1) |
42 | return 1; | 55 | return 1; |
43 | 56 | ||
44 | if (enable_ppgtt == 2 && HAS_PPGTT(dev)) | 57 | if (enable_ppgtt == 2 && has_full_ppgtt) |
45 | return 2; | 58 | return 2; |
46 | 59 | ||
47 | #ifdef CONFIG_INTEL_IOMMU | 60 | #ifdef CONFIG_INTEL_IOMMU |
@@ -59,7 +72,7 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) | |||
59 | return 0; | 72 | return 0; |
60 | } | 73 | } |
61 | 74 | ||
62 | return HAS_ALIASING_PPGTT(dev) ? 1 : 0; | 75 | return has_aliasing_ppgtt ? 1 : 0; |
63 | } | 76 | } |
64 | 77 | ||
65 | 78 | ||
@@ -156,9 +169,6 @@ static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr, | |||
156 | gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; | 169 | gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; |
157 | pte |= GEN6_PTE_ADDR_ENCODE(addr); | 170 | pte |= GEN6_PTE_ADDR_ENCODE(addr); |
158 | 171 | ||
159 | /* Mark the page as writeable. Other platforms don't have a | ||
160 | * setting for read-only/writable, so this matches that behavior. | ||
161 | */ | ||
162 | if (!(flags & PTE_READ_ONLY)) | 172 | if (!(flags & PTE_READ_ONLY)) |
163 | pte |= BYT_PTE_WRITEABLE; | 173 | pte |= BYT_PTE_WRITEABLE; |
164 | 174 | ||
@@ -1092,7 +1102,7 @@ static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) | |||
1092 | 1102 | ||
1093 | if (INTEL_INFO(dev)->gen < 8) | 1103 | if (INTEL_INFO(dev)->gen < 8) |
1094 | return gen6_ppgtt_init(ppgtt); | 1104 | return gen6_ppgtt_init(ppgtt); |
1095 | else if (IS_GEN8(dev)) | 1105 | else if (IS_GEN8(dev) || IS_GEN9(dev)) |
1096 | return gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total); | 1106 | return gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total); |
1097 | else | 1107 | else |
1098 | BUG(); | 1108 | BUG(); |
@@ -1166,6 +1176,8 @@ i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv) | |||
1166 | 1176 | ||
1167 | ppgtt->file_priv = fpriv; | 1177 | ppgtt->file_priv = fpriv; |
1168 | 1178 | ||
1179 | trace_i915_ppgtt_create(&ppgtt->base); | ||
1180 | |||
1169 | return ppgtt; | 1181 | return ppgtt; |
1170 | } | 1182 | } |
1171 | 1183 | ||
@@ -1174,6 +1186,8 @@ void i915_ppgtt_release(struct kref *kref) | |||
1174 | struct i915_hw_ppgtt *ppgtt = | 1186 | struct i915_hw_ppgtt *ppgtt = |
1175 | container_of(kref, struct i915_hw_ppgtt, ref); | 1187 | container_of(kref, struct i915_hw_ppgtt, ref); |
1176 | 1188 | ||
1189 | trace_i915_ppgtt_release(&ppgtt->base); | ||
1190 | |||
1177 | /* vmas should already be unbound */ | 1191 | /* vmas should already be unbound */ |
1178 | WARN_ON(!list_empty(&ppgtt->base.active_list)); | 1192 | WARN_ON(!list_empty(&ppgtt->base.active_list)); |
1179 | WARN_ON(!list_empty(&ppgtt->base.inactive_list)); | 1193 | WARN_ON(!list_empty(&ppgtt->base.inactive_list)); |
@@ -1258,7 +1272,7 @@ void i915_check_and_clear_faults(struct drm_device *dev) | |||
1258 | fault_reg = I915_READ(RING_FAULT_REG(ring)); | 1272 | fault_reg = I915_READ(RING_FAULT_REG(ring)); |
1259 | if (fault_reg & RING_FAULT_VALID) { | 1273 | if (fault_reg & RING_FAULT_VALID) { |
1260 | DRM_DEBUG_DRIVER("Unexpected fault\n" | 1274 | DRM_DEBUG_DRIVER("Unexpected fault\n" |
1261 | "\tAddr: 0x%08lx\\n" | 1275 | "\tAddr: 0x%08lx\n" |
1262 | "\tAddress space: %s\n" | 1276 | "\tAddress space: %s\n" |
1263 | "\tSource ID: %d\n" | 1277 | "\tSource ID: %d\n" |
1264 | "\tType: %d\n", | 1278 | "\tType: %d\n", |
@@ -1328,7 +1342,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) | |||
1328 | * Unfortunately above, we've just wiped out the mappings | 1342 | * Unfortunately above, we've just wiped out the mappings |
1329 | * without telling our object about it. So we need to fake it. | 1343 | * without telling our object about it. So we need to fake it. |
1330 | */ | 1344 | */ |
1331 | obj->has_global_gtt_mapping = 0; | 1345 | vma->bound &= ~GLOBAL_BIND; |
1332 | vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND); | 1346 | vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND); |
1333 | } | 1347 | } |
1334 | 1348 | ||
@@ -1525,7 +1539,7 @@ static void i915_ggtt_bind_vma(struct i915_vma *vma, | |||
1525 | 1539 | ||
1526 | BUG_ON(!i915_is_ggtt(vma->vm)); | 1540 | BUG_ON(!i915_is_ggtt(vma->vm)); |
1527 | intel_gtt_insert_sg_entries(vma->obj->pages, entry, flags); | 1541 | intel_gtt_insert_sg_entries(vma->obj->pages, entry, flags); |
1528 | vma->obj->has_global_gtt_mapping = 1; | 1542 | vma->bound = GLOBAL_BIND; |
1529 | } | 1543 | } |
1530 | 1544 | ||
1531 | static void i915_ggtt_clear_range(struct i915_address_space *vm, | 1545 | static void i915_ggtt_clear_range(struct i915_address_space *vm, |
@@ -1544,7 +1558,7 @@ static void i915_ggtt_unbind_vma(struct i915_vma *vma) | |||
1544 | const unsigned int size = vma->obj->base.size >> PAGE_SHIFT; | 1558 | const unsigned int size = vma->obj->base.size >> PAGE_SHIFT; |
1545 | 1559 | ||
1546 | BUG_ON(!i915_is_ggtt(vma->vm)); | 1560 | BUG_ON(!i915_is_ggtt(vma->vm)); |
1547 | vma->obj->has_global_gtt_mapping = 0; | 1561 | vma->bound = 0; |
1548 | intel_gtt_clear_range(first, size); | 1562 | intel_gtt_clear_range(first, size); |
1549 | } | 1563 | } |
1550 | 1564 | ||
@@ -1572,24 +1586,24 @@ static void ggtt_bind_vma(struct i915_vma *vma, | |||
1572 | * flags. At all other times, the GPU will use the aliasing PPGTT. | 1586 | * flags. At all other times, the GPU will use the aliasing PPGTT. |
1573 | */ | 1587 | */ |
1574 | if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) { | 1588 | if (!dev_priv->mm.aliasing_ppgtt || flags & GLOBAL_BIND) { |
1575 | if (!obj->has_global_gtt_mapping || | 1589 | if (!(vma->bound & GLOBAL_BIND) || |
1576 | (cache_level != obj->cache_level)) { | 1590 | (cache_level != obj->cache_level)) { |
1577 | vma->vm->insert_entries(vma->vm, obj->pages, | 1591 | vma->vm->insert_entries(vma->vm, obj->pages, |
1578 | vma->node.start, | 1592 | vma->node.start, |
1579 | cache_level, flags); | 1593 | cache_level, flags); |
1580 | obj->has_global_gtt_mapping = 1; | 1594 | vma->bound |= GLOBAL_BIND; |
1581 | } | 1595 | } |
1582 | } | 1596 | } |
1583 | 1597 | ||
1584 | if (dev_priv->mm.aliasing_ppgtt && | 1598 | if (dev_priv->mm.aliasing_ppgtt && |
1585 | (!obj->has_aliasing_ppgtt_mapping || | 1599 | (!(vma->bound & LOCAL_BIND) || |
1586 | (cache_level != obj->cache_level))) { | 1600 | (cache_level != obj->cache_level))) { |
1587 | struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; | 1601 | struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; |
1588 | appgtt->base.insert_entries(&appgtt->base, | 1602 | appgtt->base.insert_entries(&appgtt->base, |
1589 | vma->obj->pages, | 1603 | vma->obj->pages, |
1590 | vma->node.start, | 1604 | vma->node.start, |
1591 | cache_level, flags); | 1605 | cache_level, flags); |
1592 | vma->obj->has_aliasing_ppgtt_mapping = 1; | 1606 | vma->bound |= LOCAL_BIND; |
1593 | } | 1607 | } |
1594 | } | 1608 | } |
1595 | 1609 | ||
@@ -1599,21 +1613,21 @@ static void ggtt_unbind_vma(struct i915_vma *vma) | |||
1599 | struct drm_i915_private *dev_priv = dev->dev_private; | 1613 | struct drm_i915_private *dev_priv = dev->dev_private; |
1600 | struct drm_i915_gem_object *obj = vma->obj; | 1614 | struct drm_i915_gem_object *obj = vma->obj; |
1601 | 1615 | ||
1602 | if (obj->has_global_gtt_mapping) { | 1616 | if (vma->bound & GLOBAL_BIND) { |
1603 | vma->vm->clear_range(vma->vm, | 1617 | vma->vm->clear_range(vma->vm, |
1604 | vma->node.start, | 1618 | vma->node.start, |
1605 | obj->base.size, | 1619 | obj->base.size, |
1606 | true); | 1620 | true); |
1607 | obj->has_global_gtt_mapping = 0; | 1621 | vma->bound &= ~GLOBAL_BIND; |
1608 | } | 1622 | } |
1609 | 1623 | ||
1610 | if (obj->has_aliasing_ppgtt_mapping) { | 1624 | if (vma->bound & LOCAL_BIND) { |
1611 | struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; | 1625 | struct i915_hw_ppgtt *appgtt = dev_priv->mm.aliasing_ppgtt; |
1612 | appgtt->base.clear_range(&appgtt->base, | 1626 | appgtt->base.clear_range(&appgtt->base, |
1613 | vma->node.start, | 1627 | vma->node.start, |
1614 | obj->base.size, | 1628 | obj->base.size, |
1615 | true); | 1629 | true); |
1616 | obj->has_aliasing_ppgtt_mapping = 0; | 1630 | vma->bound &= ~LOCAL_BIND; |
1617 | } | 1631 | } |
1618 | } | 1632 | } |
1619 | 1633 | ||
@@ -1650,10 +1664,10 @@ static void i915_gtt_color_adjust(struct drm_mm_node *node, | |||
1650 | } | 1664 | } |
1651 | } | 1665 | } |
1652 | 1666 | ||
1653 | int i915_gem_setup_global_gtt(struct drm_device *dev, | 1667 | static int i915_gem_setup_global_gtt(struct drm_device *dev, |
1654 | unsigned long start, | 1668 | unsigned long start, |
1655 | unsigned long mappable_end, | 1669 | unsigned long mappable_end, |
1656 | unsigned long end) | 1670 | unsigned long end) |
1657 | { | 1671 | { |
1658 | /* Let GEM Manage all of the aperture. | 1672 | /* Let GEM Manage all of the aperture. |
1659 | * | 1673 | * |
@@ -1691,7 +1705,7 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, | |||
1691 | DRM_DEBUG_KMS("Reservation failed: %i\n", ret); | 1705 | DRM_DEBUG_KMS("Reservation failed: %i\n", ret); |
1692 | return ret; | 1706 | return ret; |
1693 | } | 1707 | } |
1694 | obj->has_global_gtt_mapping = 1; | 1708 | vma->bound |= GLOBAL_BIND; |
1695 | } | 1709 | } |
1696 | 1710 | ||
1697 | dev_priv->gtt.base.start = start; | 1711 | dev_priv->gtt.base.start = start; |
@@ -1764,7 +1778,6 @@ static int setup_scratch_page(struct drm_device *dev) | |||
1764 | page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); | 1778 | page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); |
1765 | if (page == NULL) | 1779 | if (page == NULL) |
1766 | return -ENOMEM; | 1780 | return -ENOMEM; |
1767 | get_page(page); | ||
1768 | set_pages_uc(page, 1); | 1781 | set_pages_uc(page, 1); |
1769 | 1782 | ||
1770 | #ifdef CONFIG_INTEL_IOMMU | 1783 | #ifdef CONFIG_INTEL_IOMMU |
@@ -1789,7 +1802,6 @@ static void teardown_scratch_page(struct drm_device *dev) | |||
1789 | set_pages_wb(page, 1); | 1802 | set_pages_wb(page, 1); |
1790 | pci_unmap_page(dev->pdev, dev_priv->gtt.base.scratch.addr, | 1803 | pci_unmap_page(dev->pdev, dev_priv->gtt.base.scratch.addr, |
1791 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 1804 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
1792 | put_page(page); | ||
1793 | __free_page(page); | 1805 | __free_page(page); |
1794 | } | 1806 | } |
1795 | 1807 | ||
@@ -1859,6 +1871,18 @@ static size_t chv_get_stolen_size(u16 gmch_ctrl) | |||
1859 | return (gmch_ctrl - 0x17 + 9) << 22; | 1871 | return (gmch_ctrl - 0x17 + 9) << 22; |
1860 | } | 1872 | } |
1861 | 1873 | ||
1874 | static size_t gen9_get_stolen_size(u16 gen9_gmch_ctl) | ||
1875 | { | ||
1876 | gen9_gmch_ctl >>= BDW_GMCH_GMS_SHIFT; | ||
1877 | gen9_gmch_ctl &= BDW_GMCH_GMS_MASK; | ||
1878 | |||
1879 | if (gen9_gmch_ctl < 0xf0) | ||
1880 | return gen9_gmch_ctl << 25; /* 32 MB units */ | ||
1881 | else | ||
1882 | /* 4MB increments starting at 0xf0 for 4MB */ | ||
1883 | return (gen9_gmch_ctl - 0xf0 + 1) << 22; | ||
1884 | } | ||
1885 | |||
1862 | static int ggtt_probe_common(struct drm_device *dev, | 1886 | static int ggtt_probe_common(struct drm_device *dev, |
1863 | size_t gtt_size) | 1887 | size_t gtt_size) |
1864 | { | 1888 | { |
@@ -1934,9 +1958,17 @@ static void chv_setup_private_ppat(struct drm_i915_private *dev_priv) | |||
1934 | * Only the snoop bit has meaning for CHV, the rest is | 1958 | * Only the snoop bit has meaning for CHV, the rest is |
1935 | * ignored. | 1959 | * ignored. |
1936 | * | 1960 | * |
1937 | * Note that the harware enforces snooping for all page | 1961 | * The hardware will never snoop for certain types of accesses: |
1938 | * table accesses. The snoop bit is actually ignored for | 1962 | * - CPU GTT (GMADR->GGTT->no snoop->memory) |
1939 | * PDEs. | 1963 | * - PPGTT page tables |
1964 | * - some other special cycles | ||
1965 | * | ||
1966 | * As with BDW, we also need to consider the following for GT accesses: | ||
1967 | * "For GGTT, there is NO pat_sel[2:0] from the entry, | ||
1968 | * so RTL will always use the value corresponding to | ||
1969 | * pat_sel = 000". | ||
1970 | * Which means we must set the snoop bit in PAT entry 0 | ||
1971 | * in order to keep the global status page working. | ||
1940 | */ | 1972 | */ |
1941 | pat = GEN8_PPAT(0, CHV_PPAT_SNOOP) | | 1973 | pat = GEN8_PPAT(0, CHV_PPAT_SNOOP) | |
1942 | GEN8_PPAT(1, 0) | | 1974 | GEN8_PPAT(1, 0) | |
@@ -1971,7 +2003,10 @@ static int gen8_gmch_probe(struct drm_device *dev, | |||
1971 | 2003 | ||
1972 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); | 2004 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); |
1973 | 2005 | ||
1974 | if (IS_CHERRYVIEW(dev)) { | 2006 | if (INTEL_INFO(dev)->gen >= 9) { |
2007 | *stolen = gen9_get_stolen_size(snb_gmch_ctl); | ||
2008 | gtt_size = gen8_get_total_gtt_size(snb_gmch_ctl); | ||
2009 | } else if (IS_CHERRYVIEW(dev)) { | ||
1975 | *stolen = chv_get_stolen_size(snb_gmch_ctl); | 2010 | *stolen = chv_get_stolen_size(snb_gmch_ctl); |
1976 | gtt_size = chv_get_total_gtt_size(snb_gmch_ctl); | 2011 | gtt_size = chv_get_total_gtt_size(snb_gmch_ctl); |
1977 | } else { | 2012 | } else { |
@@ -2143,6 +2178,7 @@ static struct i915_vma *__i915_gem_vma_create(struct drm_i915_gem_object *obj, | |||
2143 | vma->obj = obj; | 2178 | vma->obj = obj; |
2144 | 2179 | ||
2145 | switch (INTEL_INFO(vm->dev)->gen) { | 2180 | switch (INTEL_INFO(vm->dev)->gen) { |
2181 | case 9: | ||
2146 | case 8: | 2182 | case 8: |
2147 | case 7: | 2183 | case 7: |
2148 | case 6: | 2184 | case 6: |