aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem_gtt.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-15 18:52:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-15 18:52:01 -0500
commit988adfdffdd43cfd841df734664727993076d7cb (patch)
tree6794f7bba8f595500c2b7d33376ad6614adcfaf2 /drivers/gpu/drm/i915/i915_gem_gtt.c
parent26178ec11ef3c6c814bf16a0a2b9c2f7242e3c64 (diff)
parent4e0cd68115620bc3236ff4e58e4c073948629b41 (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.c96
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
36static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) 36static 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
1531static void i915_ggtt_clear_range(struct i915_address_space *vm, 1545static 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
1653int i915_gem_setup_global_gtt(struct drm_device *dev, 1667static 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
1874static 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
1862static int ggtt_probe_common(struct drm_device *dev, 1886static 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: