11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 30d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie/* 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All Rights Reserved. 6bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * 7bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * Permission is hereby granted, free of charge, to any person obtaining a 8bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * copy of this software and associated documentation files (the 9bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * "Software"), to deal in the Software without restriction, including 10bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * without limitation the rights to use, copy, modify, merge, publish, 11bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * distribute, sub license, and/or sell copies of the Software, and to 12bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * permit persons to whom the Software is furnished to do so, subject to 13bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * the following conditions: 14bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * 15bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * The above copyright notice and this permission notice (including the 16bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * next paragraph) shall be included in all copies or substantial portions 17bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * of the Software. 18bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * 19bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 23bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26bc54fd1ad3c5972be339a08528ab631326ed2b38Dave Airlie * 270d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie */ 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "drmP.h" 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "drm.h" 3179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes#include "drm_crtc_helper.h" 32785b93ef8c309730c2de84ce9c229e40e2d01480Dave Airlie#include "drm_fb_helper.h" 3379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes#include "intel_drv.h" 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "i915_drm.h" 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "i915_drv.h" 361c5d22f76dc721f3acb7a3dadc657a221e487fb7Chris Wilson#include "i915_trace.h" 3763ee41d794d9c555f84205517a68509848988760Eric Anholt#include "../../../platform/x86/intel_ips.h" 38dcdb167402cbdca1d021bdfa5f63995ee0a79317Jordan Crouse#include <linux/pci.h> 3928d520433b6375740990ab99d69b0d0067fd656bDave Airlie#include <linux/vgaarb.h> 40c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang#include <linux/acpi.h> 41c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang#include <linux/pnp.h> 426a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie#include <linux/vga_switcheroo.h> 435a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 44e0cd3608135b2ed8eddbe3fdf048d22e0593d836Paul Gortmaker#include <linux/module.h> 4544834a67c0082e2cf74b16be91e49108b1432d65Chris Wilson#include <acpi/video.h> 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 474cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilsonstatic void i915_write_hws_pga(struct drm_device *dev) 484cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson{ 494cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson drm_i915_private_t *dev_priv = dev->dev_private; 504cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson u32 addr; 514cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson 524cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson addr = dev_priv->status_page_dmah->busaddr; 534cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson if (INTEL_INFO(dev)->gen >= 4) 544cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0; 554cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson I915_WRITE(HWS_PGA, addr); 564cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson} 574cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson 58398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard/** 59398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * Sets up the hardware status page for devices that need a physical address 60398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * in the register. 61398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard */ 623043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholtstatic int i915_init_phys_hws(struct drm_device *dev) 63398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard{ 64398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard drm_i915_private_t *dev_priv = dev->dev_private; 651ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson 66398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard /* Program Hardware Status Page */ 67398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard dev_priv->status_page_dmah = 68e6be8d9d17bd44061116f601fe2609b3ace7aa69Zhenyu Wang drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE); 69398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard 70398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard if (!dev_priv->status_page_dmah) { 71398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard DRM_ERROR("Can not allocate hardware status page\n"); 72398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard return -ENOMEM; 73398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard } 74398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard 75f3234706a77bd6e1592ae71fb3268e04cb030dbaKeith Packard memset_io((void __force __iomem *)dev_priv->status_page_dmah->vaddr, 76f3234706a77bd6e1592ae71fb3268e04cb030dbaKeith Packard 0, PAGE_SIZE); 77398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard 784cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson i915_write_hws_pga(dev); 799b974cc17166d31afed2638d56bdbf9829afbfaaZhenyu Wang 808a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("Enabled hardware status page\n"); 81398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard return 0; 82398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard} 83398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard 84398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard/** 85398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * Frees the hardware status page, whether it's a physical address or a virtual 86398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard * address set up by the X Server. 87398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard */ 883043c60c485ad694392d3f71bd7ef9f5c5f7cfddEric Anholtstatic void i915_free_hws(struct drm_device *dev) 89398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard{ 90398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard drm_i915_private_t *dev_priv = dev->dev_private; 911ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson struct intel_ring_buffer *ring = LP_RING(dev_priv); 921ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson 93398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard if (dev_priv->status_page_dmah) { 94398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard drm_pci_free(dev, dev_priv->status_page_dmah); 95398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard dev_priv->status_page_dmah = NULL; 96398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard } 97398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard 981ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson if (ring->status_page.gfx_addr) { 991ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson ring->status_page.gfx_addr = 0; 100398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard drm_core_ioremapfree(&dev_priv->hws_map, dev); 101398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard } 102398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard 103398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard /* Need to rewrite hardware status page */ 104398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard I915_WRITE(HWS_PGA, 0x1ffff000); 105398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard} 106398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard 10784b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlievoid i915_kernel_lost_context(struct drm_device * dev) 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 1107c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_i915_master_private *master_priv; 1111ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson struct intel_ring_buffer *ring = LP_RING(dev_priv); 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes /* 11479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * We should never lose context on the ring with modesetting 11579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * as we don't expose it to userspace 11679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes */ 11779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes if (drm_core_check_feature(dev, DRIVER_MODESET)) 11879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes return; 11979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 1208168bd48bb863c00747497aadf13884b2d69d287Chris Wilson ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; 1218168bd48bb863c00747497aadf13884b2d69d287Chris Wilson ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ring->space = ring->head - (ring->tail + 8); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ring->space < 0) 1248187a2b70e34c727a06617441f74f202b6fefaf9Zou Nan hai ring->space += ring->size; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1267c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (!dev->primary->master) 1277c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return; 1287c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 1297c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master_priv = dev->primary->master->driver_priv; 1307c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (ring->head == ring->tail && master_priv->sarea_priv) 1317c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13484b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dma_cleanup(struct drm_device * dev) 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 136ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_i915_private_t *dev_priv = dev->dev_private; 1371ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson int i; 1381ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make sure interrupts are disabled here because the uninstall ioctl 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * may not have been called from userspace and after dev_private 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is freed, it's too late. 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 143ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt if (dev->irq_enabled) 144b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie drm_irq_uninstall(dev); 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 146ee0c6bfbd602cdad2ab1780061b3b1a9108cbd6cDan Carpenter mutex_lock(&dev->struct_mutex); 1471ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson for (i = 0; i < I915_NUM_RINGS; i++) 1481ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson intel_cleanup_ring_buffer(&dev_priv->ring[i]); 149ee0c6bfbd602cdad2ab1780061b3b1a9108cbd6cDan Carpenter mutex_unlock(&dev->struct_mutex); 150dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 151398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard /* Clear the HWS virtual address at teardown */ 152398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard if (I915_NEED_GFX_HWS(dev)) 153398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard i915_free_hws(dev); 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 158ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnesstatic int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 160ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_i915_private_t *dev_priv = dev->dev_private; 1617c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; 162e8616b6ced6137085e6657cc63bc2fe3900b8616Chris Wilson int ret; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1643a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie master_priv->sarea = drm_getsarea(dev); 1653a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie if (master_priv->sarea) { 1663a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie master_priv->sarea_priv = (drm_i915_sarea_t *) 1673a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie ((u8 *)master_priv->sarea->handle + init->sarea_priv_offset); 1683a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie } else { 1698a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("sarea not found assuming DRI2 userspace\n"); 1703a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie } 1713a03ac1a0223f779a3de313523408ddb099e5679Dave Airlie 172673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt if (init->ring_size != 0) { 173e8616b6ced6137085e6657cc63bc2fe3900b8616Chris Wilson if (LP_RING(dev_priv)->obj != NULL) { 174673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt i915_dma_cleanup(dev); 175673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt DRM_ERROR("Client tried to initialize ringbuffer in " 176673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt "GEM mode\n"); 177673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt return -EINVAL; 178673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt } 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 180e8616b6ced6137085e6657cc63bc2fe3900b8616Chris Wilson ret = intel_render_ring_init_dri(dev, 181e8616b6ced6137085e6657cc63bc2fe3900b8616Chris Wilson init->ring_start, 182e8616b6ced6137085e6657cc63bc2fe3900b8616Chris Wilson init->ring_size); 183e8616b6ced6137085e6657cc63bc2fe3900b8616Chris Wilson if (ret) { 184673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt i915_dma_cleanup(dev); 185e8616b6ced6137085e6657cc63bc2fe3900b8616Chris Wilson return ret; 186673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt } 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 189a6b54f3f5050c0cbc0c35dd48064846c6302706bMichel Dänzer dev_priv->cpp = init->cpp; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->back_offset = init->back_offset; 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->front_offset = init->front_offset; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->current_page = 0; 1937c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (master_priv->sarea_priv) 1947c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master_priv->sarea_priv->pf_current_page = 0; 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allow hardware batchbuffers unless told otherwise. 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_priv->allow_batchbuffer = 1; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 20384b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dma_resume(struct drm_device * dev) 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 2061ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson struct intel_ring_buffer *ring = LP_RING(dev_priv); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2088a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("%s\n", __func__); 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2108187a2b70e34c727a06617441f74f202b6fefaf9Zou Nan hai if (ring->map.handle == NULL) { 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("can not ioremap virtual address for" 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " ring buffer\n"); 21320caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -ENOMEM; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Program Hardware Status Page */ 2178187a2b70e34c727a06617441f74f202b6fefaf9Zou Nan hai if (!ring->status_page.page_addr) { 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("Can not find hardware status page\n"); 21920caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2218a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("hw status page @ %p\n", 2228187a2b70e34c727a06617441f74f202b6fefaf9Zou Nan hai ring->status_page.page_addr); 2238187a2b70e34c727a06617441f74f202b6fefaf9Zou Nan hai if (ring->status_page.gfx_addr != 0) 22478501eac34f372bfbeb4e1d9de688c13efa916f6Chris Wilson intel_ring_setup_status_page(ring); 225dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu else 2264cbf74ccf8362e99b2bdf1e66112a480c79ecacfChris Wilson i915_write_hws_pga(dev); 2278187a2b70e34c727a06617441f74f202b6fefaf9Zou Nan hai 2288a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("Enabled hardware status page\n"); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 233c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_dma_init(struct drm_device *dev, void *data, 234c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 236c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_init_t *init = data; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retcode = 0; 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 239c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt switch (init->func) { 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_INIT_DMA: 241ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes retcode = i915_initialize(dev, init); 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_CLEANUP_DMA: 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retcode = i915_dma_cleanup(dev); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_RESUME_DMA: 2470d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie retcode = i915_dma_resume(dev); 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 25020caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt retcode = -EINVAL; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retcode; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Implement basically the same security restrictions as hardware does 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for MI_BATCH_NON_SECURE. These can be made stricter at any time. 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Most of the calculations below involve calculating the size of a 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * particular instruction. It's important to get the size right as 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that tells us where the next instruction to check is. Any illegal 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * instruction detected will be given a size of zero, which is a 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * signal to abort the rest of the buffer. 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 266e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilsonstatic int validate_cmd(int cmd) 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (((cmd >> 29) & 0x7)) { 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x0: 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch ((cmd >> 23) & 0x3f) { 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x0: 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; /* MI_NOOP */ 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x4: 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; /* MI_FLUSH */ 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; /* disallow everything else */ 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1: 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; /* reserved */ 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x2: 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0xff) + 2; /* 2d commands */ 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x3: 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((cmd >> 24) & 0x1f) <= 0x18) 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch ((cmd >> 24) & 0x1f) { 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1c: 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1d: 291b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie switch ((cmd >> 16) & 0xff) { 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x3: 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0x1f) + 2; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x4: 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0xf) + 2; 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0xffff) + 2; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1e: 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd & (1 << 23)) 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0xffff) + 1; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1f: 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cmd & (1 << 23)) == 0) /* inline vertices */ 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cmd & 0x1ffff) + 2; 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (cmd & (1 << 17)) /* indirect random */ 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cmd & 0xffff) == 0) 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; /* unknown length, too hard */ 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (((cmd & 0xffff) + 1) / 2) + 1; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 2; /* indirect sequential */ 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 324201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholtstatic int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 327e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson int i, ret; 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3291ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson if ((dwords+1) * sizeof(int) >= LP_RING(dev_priv)->size - 8) 33020caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 331de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < dwords;) { 333e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson int sz = validate_cmd(buffer[i]); 334e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson if (sz == 0 || i + sz > dwords) 33520caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 336e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson i += sz; 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 339e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ret = BEGIN_LP_RING((dwords+1)&~1); 340e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson if (ret) 341e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson return ret; 342e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson 343e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson for (i = 0; i < dwords; i++) 344e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(buffer[i]); 345de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie if (dwords & 1) 346de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie OUT_RING(0); 347de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 348de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie ADVANCE_LP_RING(); 349de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 353673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholtint 354673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholti915_emit_box(struct drm_device *dev, 355c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson struct drm_clip_rect *box, 356c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson int DR1, int DR4) 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 358e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson struct drm_i915_private *dev_priv = dev->dev_private; 359e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson int ret; 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 361c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson if (box->y2 <= box->y1 || box->x2 <= box->x1 || 362c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson box->y2 <= 0 || box->x2 <= 0) { 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("Bad box %d,%d..%d,%d\n", 364c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson box->x1, box->y1, box->x2, box->y2); 36520caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 368a6c45cf013a57e32ddae43dd4ac911eb4a3919fdChris Wilson if (INTEL_INFO(dev)->gen >= 4) { 369e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ret = BEGIN_LP_RING(4); 370e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson if (ret) 371e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson return ret; 372e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson 373c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(GFX_OP_DRAWRECT_INFO_I965); 374c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); 375c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); 376c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(DR4); 377c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane } else { 378e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ret = BEGIN_LP_RING(6); 379e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson if (ret) 380e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson return ret; 381e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson 382c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(GFX_OP_DRAWRECT_INFO); 383c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(DR1); 384c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); 385c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); 386c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(DR4); 387c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane OUT_RING(0); 388c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane } 389e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ADVANCE_LP_RING(); 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 394c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane/* XXX: Emitting the counter should really be moved to part of the IRQ 395c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane * emit. For now, do it in both places: 396c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane */ 397c29b669caae4ed1630ef479e54bdde126a0378ecAlan Hourihane 39884b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic void i915_emit_breadcrumb(struct drm_device *dev) 399de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie{ 400de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie drm_i915_private_t *dev_priv = dev->dev_private; 4017c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; 402de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 403c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg dev_priv->counter++; 404af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie if (dev_priv->counter > 0x7FFFFFFFUL) 405c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg dev_priv->counter = 0; 4067c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (master_priv->sarea_priv) 4077c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master_priv->sarea_priv->last_enqueue = dev_priv->counter; 408de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 409e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson if (BEGIN_LP_RING(4) == 0) { 410e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(MI_STORE_DWORD_INDEX); 411e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); 412e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(dev_priv->counter); 413e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(0); 414e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ADVANCE_LP_RING(); 415e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson } 416de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie} 417de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie 41884b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dispatch_cmdbuffer(struct drm_device * dev, 419201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt drm_i915_cmdbuffer_t *cmd, 420201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt struct drm_clip_rect *cliprects, 421201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt void *cmdbuf) 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int nbox = cmd->num_cliprects; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 0, count, ret; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cmd->sz & 0x3) { 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("alignment"); 42820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i915_kernel_lost_context(dev); 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = nbox ? nbox : 1; 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < count; i++) { 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i < nbox) { 437c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson ret = i915_emit_box(dev, &cliprects[i], 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd->DR1, cmd->DR4); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret) 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 443201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt ret = i915_emit_cmds(dev, cmdbuf, cmd->sz / 4); 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret) 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 448de227f5f32775d86e5c780a7cffdd2e08574f7fbDave Airlie i915_emit_breadcrumb(dev); 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45284b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airliestatic int i915_dispatch_batchbuffer(struct drm_device * dev, 453201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt drm_i915_batchbuffer_t * batch, 454201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt struct drm_clip_rect *cliprects) 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 456e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson struct drm_i915_private *dev_priv = dev->dev_private; 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int nbox = batch->num_cliprects; 458e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson int i, count, ret; 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((batch->start | batch->used) & 0x7) { 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("alignment"); 46220caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i915_kernel_lost_context(dev); 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = nbox ? nbox : 1; 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < count; i++) { 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i < nbox) { 470c4e7a4146798ce22c229dd21ed31f59f07c4119eChris Wilson ret = i915_emit_box(dev, &cliprects[i], 471e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson batch->DR1, batch->DR4); 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret) 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4760790d5e148c0747499742a3c09ba5f1c07f9ed0dKeith Packard if (!IS_I830(dev) && !IS_845G(dev)) { 477e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ret = BEGIN_LP_RING(2); 478e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson if (ret) 479e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson return ret; 480e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson 481a6c45cf013a57e32ddae43dd4ac911eb4a3919fdChris Wilson if (INTEL_INFO(dev)->gen >= 4) { 48221f16289270447673a7263ccc0b22d562fb01ecbDave Airlie OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); 48321f16289270447673a7263ccc0b22d562fb01ecbDave Airlie OUT_RING(batch->start); 48421f16289270447673a7263ccc0b22d562fb01ecbDave Airlie } else { 48521f16289270447673a7263ccc0b22d562fb01ecbDave Airlie OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); 48621f16289270447673a7263ccc0b22d562fb01ecbDave Airlie OUT_RING(batch->start | MI_BATCH_NON_SECURE); 48721f16289270447673a7263ccc0b22d562fb01ecbDave Airlie } 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 489e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ret = BEGIN_LP_RING(4); 490e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson if (ret) 491e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson return ret; 492e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OUT_RING(MI_BATCH_BUFFER); 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OUT_RING(batch->start | MI_BATCH_NON_SECURE); 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OUT_RING(batch->start + batch->used - 4); 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds OUT_RING(0); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 498e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ADVANCE_LP_RING(); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5011cafd34731cd14e5a72edaf0f41717c8126cfce9Zou Nan hai 502f00a3ddf91d596bece5fa31e8ce2e8a3b4c0623bChris Wilson if (IS_G4X(dev) || IS_GEN5(dev)) { 503e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson if (BEGIN_LP_RING(2) == 0) { 504e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); 505e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(MI_NOOP); 506e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ADVANCE_LP_RING(); 507e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson } 5081cafd34731cd14e5a72edaf0f41717c8126cfce9Zou Nan hai } 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 510e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson i915_emit_breadcrumb(dev); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 514af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airliestatic int i915_dispatch_flip(struct drm_device * dev) 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 5177c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_i915_master_private *master_priv = 5187c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie dev->primary->master->driver_priv; 519e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson int ret; 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5217c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (!master_priv->sarea_priv) 522c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg return -EINVAL; 523c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg 5248a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n", 525be25ed9c5cc06e1d17aa97e41daf88f0b46143e6yakui_zhao __func__, 526be25ed9c5cc06e1d17aa97e41daf88f0b46143e6yakui_zhao dev_priv->current_page, 527be25ed9c5cc06e1d17aa97e41daf88f0b46143e6yakui_zhao master_priv->sarea_priv->pf_current_page); 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 529af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie i915_kernel_lost_context(dev); 530af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie 531e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ret = BEGIN_LP_RING(10); 532e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson if (ret) 533e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson return ret; 534e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson 535585fb111348f7cdc30c6a1b903987612ddeafb23Jesse Barnes OUT_RING(MI_FLUSH | MI_READ_FLUSH); 536af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(0); 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 538af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); 539af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(0); 540af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie if (dev_priv->current_page == 0) { 541af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(dev_priv->back_offset); 542af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie dev_priv->current_page = 1; 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 544af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(dev_priv->front_offset); 545af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie dev_priv->current_page = 0; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 547af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(0); 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 549af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); 550af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie OUT_RING(0); 551e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson 552af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie ADVANCE_LP_RING(); 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5547c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master_priv->sarea_priv->last_enqueue = dev_priv->counter++; 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 556e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson if (BEGIN_LP_RING(4) == 0) { 557e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(MI_STORE_DWORD_INDEX); 558e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); 559e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(dev_priv->counter); 560e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson OUT_RING(0); 561e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson ADVANCE_LP_RING(); 562e1f99ce6cac3b6a95551642be5ddb5d9c46bea76Chris Wilson } 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5647c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master_priv->sarea_priv->pf_current_page = dev_priv->current_page; 565af6061af0d9f84a4665f88186dc1ff9e4fb78330Dave Airlie return 0; 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5681ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilsonstatic int i915_quiescent(struct drm_device *dev) 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5701ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson struct intel_ring_buffer *ring = LP_RING(dev->dev_private); 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i915_kernel_lost_context(dev); 57396f298aa9c9fc9b7c8a2ebaf8c195d178f570e09Ben Widawsky return intel_wait_ring_idle(ring); 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 576c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_flush_ioctl(struct drm_device *dev, void *data, 577c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 579546b0974c39657017407c86fe79811100b60700dEric Anholt int ret; 580546b0974c39657017407c86fe79811100b60700dEric Anholt 581546b0974c39657017407c86fe79811100b60700dEric Anholt RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 583546b0974c39657017407c86fe79811100b60700dEric Anholt mutex_lock(&dev->struct_mutex); 584546b0974c39657017407c86fe79811100b60700dEric Anholt ret = i915_quiescent(dev); 585546b0974c39657017407c86fe79811100b60700dEric Anholt mutex_unlock(&dev->struct_mutex); 586546b0974c39657017407c86fe79811100b60700dEric Anholt 587546b0974c39657017407c86fe79811100b60700dEric Anholt return ret; 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 590c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_batchbuffer(struct drm_device *dev, void *data, 591c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 5947c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 5967c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master_priv->sarea_priv; 597c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_batchbuffer_t *batch = data; 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 599201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt struct drm_clip_rect *cliprects = NULL; 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv->allow_batchbuffer) { 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("Batchbuffer ioctl disabled\n"); 60320caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6068a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("i915 batchbuffer, start %x used %d cliprects %d\n", 607be25ed9c5cc06e1d17aa97e41daf88f0b46143e6yakui_zhao batch->start, batch->used, batch->num_cliprects); 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 609546b0974c39657017407c86fe79811100b60700dEric Anholt RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt if (batch->num_cliprects < 0) 612201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt return -EINVAL; 613201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt 614201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt if (batch->num_cliprects) { 6159a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt cliprects = kcalloc(batch->num_cliprects, 6169a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt sizeof(struct drm_clip_rect), 6179a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt GFP_KERNEL); 618201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt if (cliprects == NULL) 619201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt return -ENOMEM; 620201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt 621201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt ret = copy_from_user(cliprects, batch->cliprects, 622201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt batch->num_cliprects * 623201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt sizeof(struct drm_clip_rect)); 6249927a403ca8c97798129953fa9cbb5dc259c7cb9Dan Carpenter if (ret != 0) { 6259927a403ca8c97798129953fa9cbb5dc259c7cb9Dan Carpenter ret = -EFAULT; 626201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt goto fail_free; 6279927a403ca8c97798129953fa9cbb5dc259c7cb9Dan Carpenter } 628201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt } 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 630546b0974c39657017407c86fe79811100b60700dEric Anholt mutex_lock(&dev->struct_mutex); 631201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt ret = i915_dispatch_batchbuffer(dev, batch, cliprects); 632546b0974c39657017407c86fe79811100b60700dEric Anholt mutex_unlock(&dev->struct_mutex); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 634c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg if (sarea_priv) 6350baf823a10bd4131f70e9712d1f02de3c247f1dfKeith Packard sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 636201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt 637201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholtfail_free: 6389a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(cliprects); 639201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 643c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_cmdbuffer(struct drm_device *dev, void *data, 644c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 6477c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 6497c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master_priv->sarea_priv; 650c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_cmdbuffer_t *cmdbuf = data; 651201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt struct drm_clip_rect *cliprects = NULL; 652201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt void *batch_data; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6558a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("i915 cmdbuffer, buf %p sz %d cliprects %d\n", 656be25ed9c5cc06e1d17aa97e41daf88f0b46143e6yakui_zhao cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 658546b0974c39657017407c86fe79811100b60700dEric Anholt RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 660201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt if (cmdbuf->num_cliprects < 0) 661201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt return -EINVAL; 662201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt 6639a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt batch_data = kmalloc(cmdbuf->sz, GFP_KERNEL); 664201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt if (batch_data == NULL) 665201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt return -ENOMEM; 666201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt 667201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz); 6689927a403ca8c97798129953fa9cbb5dc259c7cb9Dan Carpenter if (ret != 0) { 6699927a403ca8c97798129953fa9cbb5dc259c7cb9Dan Carpenter ret = -EFAULT; 670201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt goto fail_batch_free; 6719927a403ca8c97798129953fa9cbb5dc259c7cb9Dan Carpenter } 672201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt 673201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt if (cmdbuf->num_cliprects) { 6749a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt cliprects = kcalloc(cmdbuf->num_cliprects, 6759a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt sizeof(struct drm_clip_rect), GFP_KERNEL); 676a40e8d3139e9eb54bf1d29f91639a6c5e05f652eOwain Ainsworth if (cliprects == NULL) { 677a40e8d3139e9eb54bf1d29f91639a6c5e05f652eOwain Ainsworth ret = -ENOMEM; 678201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt goto fail_batch_free; 679a40e8d3139e9eb54bf1d29f91639a6c5e05f652eOwain Ainsworth } 680201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt 681201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt ret = copy_from_user(cliprects, cmdbuf->cliprects, 682201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt cmdbuf->num_cliprects * 683201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt sizeof(struct drm_clip_rect)); 6849927a403ca8c97798129953fa9cbb5dc259c7cb9Dan Carpenter if (ret != 0) { 6859927a403ca8c97798129953fa9cbb5dc259c7cb9Dan Carpenter ret = -EFAULT; 686201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt goto fail_clip_free; 6879927a403ca8c97798129953fa9cbb5dc259c7cb9Dan Carpenter } 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 690546b0974c39657017407c86fe79811100b60700dEric Anholt mutex_lock(&dev->struct_mutex); 691201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt ret = i915_dispatch_cmdbuffer(dev, cmdbuf, cliprects, batch_data); 692546b0974c39657017407c86fe79811100b60700dEric Anholt mutex_unlock(&dev->struct_mutex); 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret) { 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); 695355d7f370b51bbb6f31aaf9f98861057e1e6bbb2Chris Wright goto fail_clip_free; 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 698c99b058f132388a666544d293392d52d1def6b12Kristian Høgsberg if (sarea_priv) 6990baf823a10bd4131f70e9712d1f02de3c247f1dfKeith Packard sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 700201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt 701201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholtfail_clip_free: 7029a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(cliprects); 703355d7f370b51bbb6f31aaf9f98861057e1e6bbb2Chris Wrightfail_batch_free: 7049a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(batch_data); 705201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt 706201361a54ed187d8595a283e3a4ddb213bc8323bEric Anholt return ret; 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 709c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_flip_bufs(struct drm_device *dev, void *data, 710c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 712546b0974c39657017407c86fe79811100b60700dEric Anholt int ret; 713546b0974c39657017407c86fe79811100b60700dEric Anholt 7148a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("%s\n", __func__); 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 716546b0974c39657017407c86fe79811100b60700dEric Anholt RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 718546b0974c39657017407c86fe79811100b60700dEric Anholt mutex_lock(&dev->struct_mutex); 719546b0974c39657017407c86fe79811100b60700dEric Anholt ret = i915_dispatch_flip(dev); 720546b0974c39657017407c86fe79811100b60700dEric Anholt mutex_unlock(&dev->struct_mutex); 721546b0974c39657017407c86fe79811100b60700dEric Anholt 722546b0974c39657017407c86fe79811100b60700dEric Anholt return ret; 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 725c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_getparam(struct drm_device *dev, void *data, 726c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 729c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_getparam_t *param = data; 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int value; 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv) { 7333e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh DRM_ERROR("called with no initialization\n"); 73420caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 737c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt switch (param->param) { 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_PARAM_IRQ_ACTIVE: 7390a3e67a4caac273a3bfc4ced3da364830b1ab241Jesse Barnes value = dev->pdev->irq ? 1 : 0; 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_PARAM_ALLOW_BATCHBUFFER: 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = dev_priv->allow_batchbuffer ? 1 : 0; 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7440d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie case I915_PARAM_LAST_DISPATCH: 7450d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie value = READ_BREADCRUMB(dev_priv); 7460d6aa60b4ac9689b750e35cd66f5d7c053aff0f4Dave Airlie break; 747ed4c9c4acf948b42b138747fcb8843ecb1a24ce4Kristian Høgsberg case I915_PARAM_CHIPSET_ID: 748ed4c9c4acf948b42b138747fcb8843ecb1a24ce4Kristian Høgsberg value = dev->pci_device; 749ed4c9c4acf948b42b138747fcb8843ecb1a24ce4Kristian Høgsberg break; 750673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt case I915_PARAM_HAS_GEM: 751ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie value = dev_priv->has_gem; 752673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt break; 7530f973f27888e4664b253ab2cf69c67c2eb80ab1bJesse Barnes case I915_PARAM_NUM_FENCES_AVAIL: 7540f973f27888e4664b253ab2cf69c67c2eb80ab1bJesse Barnes value = dev_priv->num_fence_regs - dev_priv->fence_reg_start; 7550f973f27888e4664b253ab2cf69c67c2eb80ab1bJesse Barnes break; 75602e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter case I915_PARAM_HAS_OVERLAY: 75702e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter value = dev_priv->overlay ? 1 : 0; 75802e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter break; 759e9560f7cb20722e0e7db46bbb6f43c2194a238d5Jesse Barnes case I915_PARAM_HAS_PAGEFLIPPING: 760e9560f7cb20722e0e7db46bbb6f43c2194a238d5Jesse Barnes value = 1; 761e9560f7cb20722e0e7db46bbb6f43c2194a238d5Jesse Barnes break; 76276446cac68568fc7f5168a27deaf803ed22a4360Jesse Barnes case I915_PARAM_HAS_EXECBUF2: 76376446cac68568fc7f5168a27deaf803ed22a4360Jesse Barnes /* depends on GEM */ 76476446cac68568fc7f5168a27deaf803ed22a4360Jesse Barnes value = dev_priv->has_gem; 76576446cac68568fc7f5168a27deaf803ed22a4360Jesse Barnes break; 766e3a815fcd38043b8f1bb526123d8ab6ae01deb77Zou Nan hai case I915_PARAM_HAS_BSD: 767e3a815fcd38043b8f1bb526123d8ab6ae01deb77Zou Nan hai value = HAS_BSD(dev); 768e3a815fcd38043b8f1bb526123d8ab6ae01deb77Zou Nan hai break; 769549f7365820a212a1cfd0871d377b1ad0d1e5723Chris Wilson case I915_PARAM_HAS_BLT: 770549f7365820a212a1cfd0871d377b1ad0d1e5723Chris Wilson value = HAS_BLT(dev); 771549f7365820a212a1cfd0871d377b1ad0d1e5723Chris Wilson break; 772a00b10c360b35d6431a94cbf130a4e162870d661Chris Wilson case I915_PARAM_HAS_RELAXED_FENCING: 773a00b10c360b35d6431a94cbf130a4e162870d661Chris Wilson value = 1; 774a00b10c360b35d6431a94cbf130a4e162870d661Chris Wilson break; 775bbf0c6b3620b3872929ef7d3c392ce436889110fDaniel Vetter case I915_PARAM_HAS_COHERENT_RINGS: 776bbf0c6b3620b3872929ef7d3c392ce436889110fDaniel Vetter value = 1; 777bbf0c6b3620b3872929ef7d3c392ce436889110fDaniel Vetter break; 77872bfa19c8deb4d1db5ad068c34fd580cb295cbe8Chris Wilson case I915_PARAM_HAS_EXEC_CONSTANTS: 77972bfa19c8deb4d1db5ad068c34fd580cb295cbe8Chris Wilson value = INTEL_INFO(dev)->gen >= 4; 78072bfa19c8deb4d1db5ad068c34fd580cb295cbe8Chris Wilson break; 781271d81b84171d84723357ae6d172ec16b0d8139cChris Wilson case I915_PARAM_HAS_RELAXED_DELTA: 782271d81b84171d84723357ae6d172ec16b0d8139cChris Wilson value = 1; 783271d81b84171d84723357ae6d172ec16b0d8139cChris Wilson break; 784ae662d31264979e52581bd2573bf0b82812f52abEric Anholt case I915_PARAM_HAS_GEN7_SOL_RESET: 785ae662d31264979e52581bd2573bf0b82812f52abEric Anholt value = 1; 786ae662d31264979e52581bd2573bf0b82812f52abEric Anholt break; 7873d29b842e58fbca2c13a9f458fddbaa535c6e578Eugeni Dodonov case I915_PARAM_HAS_LLC: 7883d29b842e58fbca2c13a9f458fddbaa535c6e578Eugeni Dodonov value = HAS_LLC(dev); 7893d29b842e58fbca2c13a9f458fddbaa535c6e578Eugeni Dodonov break; 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 7918a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("Unknown parameter %d\n", 79276446cac68568fc7f5168a27deaf803ed22a4360Jesse Barnes param->param); 79320caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 796c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DRM_ERROR("DRM_COPY_TO_USER failed\n"); 79820caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EFAULT; 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 804c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_setparam(struct drm_device *dev, void *data, 805c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drm_i915_private_t *dev_priv = dev->dev_private; 808c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_setparam_t *param = data; 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dev_priv) { 8113e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh DRM_ERROR("called with no initialization\n"); 81220caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 815c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt switch (param->param) { 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_SETPARAM_USE_MI_BATCHBUFFER_START: 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY: 819c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt dev_priv->tex_lru_log_granularity = param->value; 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case I915_SETPARAM_ALLOW_BATCHBUFFER: 822c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt dev_priv->allow_batchbuffer = param->value; 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8240f973f27888e4664b253ab2cf69c67c2eb80ab1bJesse Barnes case I915_SETPARAM_NUM_USED_FENCES: 8250f973f27888e4664b253ab2cf69c67c2eb80ab1bJesse Barnes if (param->value > dev_priv->num_fence_regs || 8260f973f27888e4664b253ab2cf69c67c2eb80ab1bJesse Barnes param->value < 0) 8270f973f27888e4664b253ab2cf69c67c2eb80ab1bJesse Barnes return -EINVAL; 8280f973f27888e4664b253ab2cf69c67c2eb80ab1bJesse Barnes /* Userspace can use first N regs */ 8290f973f27888e4664b253ab2cf69c67c2eb80ab1bJesse Barnes dev_priv->fence_reg_start = param->value; 8300f973f27888e4664b253ab2cf69c67c2eb80ab1bJesse Barnes break; 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 8328a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("unknown parameter %d\n", 833be25ed9c5cc06e1d17aa97e41daf88f0b46143e6yakui_zhao param->param); 83420caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 840c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstatic int i915_set_status_page(struct drm_device *dev, void *data, 841c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt struct drm_file *file_priv) 842dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu{ 843dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu drm_i915_private_t *dev_priv = dev->dev_private; 844c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt drm_i915_hws_addr_t *hws = data; 8451ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson struct intel_ring_buffer *ring = LP_RING(dev_priv); 846b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang 847b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang if (!I915_NEED_GFX_HWS(dev)) 848b39d50e53b1bb27f6c29f88a697a4af78427dffdZhenyu Wang return -EINVAL; 849dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 850dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu if (!dev_priv) { 8513e684eae586a9b210a4517da5637a255b1ff5a92Márton Németh DRM_ERROR("called with no initialization\n"); 85220caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -EINVAL; 853dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu } 854dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 85579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes if (drm_core_check_feature(dev, DRIVER_MODESET)) { 85679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes WARN(1, "tried to set status page when mode setting active\n"); 85779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes return 0; 85879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes } 85979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 8608a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr); 861c153f45f9b7e30289157bba3ff5682291df16caaEric Anholt 8628187a2b70e34c727a06617441f74f202b6fefaf9Zou Nan hai ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); 863dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 8648b40958032fd236194de57d29be9cf2c1f2643eeEric Anholt dev_priv->hws_map.offset = dev->agp->base + hws->addr; 865dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->hws_map.size = 4*1024; 866dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->hws_map.type = 0; 867dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->hws_map.flags = 0; 868dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu dev_priv->hws_map.mtrr = 0; 869dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 870dd0910b3c71b253c08111110f0399b924a8d5853Dave Airlie drm_core_ioremap_wc(&dev_priv->hws_map, dev); 871dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu if (dev_priv->hws_map.handle == NULL) { 872dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu i915_dma_cleanup(dev); 873e20f9c64c79e2282f9eb531509181965ec8f0a92Eric Anholt ring->status_page.gfx_addr = 0; 874dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu DRM_ERROR("can not ioremap virtual address for" 875dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu " G33 hw status page\n"); 87620caafa6ecb2487d9b223aa33e7cc704f912a758Eric Anholt return -ENOMEM; 877dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu } 878311bd68e024f9006db66cbadc3bd9f62fd663f4bChris Wilson ring->status_page.page_addr = 879311bd68e024f9006db66cbadc3bd9f62fd663f4bChris Wilson (void __force __iomem *)dev_priv->hws_map.handle; 880311bd68e024f9006db66cbadc3bd9f62fd663f4bChris Wilson memset_io(ring->status_page.page_addr, 0, PAGE_SIZE); 8818187a2b70e34c727a06617441f74f202b6fefaf9Zou Nan hai I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); 882dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 8838a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", 884e20f9c64c79e2282f9eb531509181965ec8f0a92Eric Anholt ring->status_page.gfx_addr); 8858a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("load hws at %p\n", 886e20f9c64c79e2282f9eb531509181965ec8f0a92Eric Anholt ring->status_page.page_addr); 887dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu return 0; 888dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu} 889dc7a93190c21edbf3ed23e678ad04f852b9cff28Wang Zhenyu 890ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airliestatic int i915_get_bridge_dev(struct drm_device *dev) 891ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie{ 892ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie struct drm_i915_private *dev_priv = dev->dev_private; 893ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie 8940206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); 895ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie if (!dev_priv->bridge_dev) { 896ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie DRM_ERROR("bridge device not found\n"); 897ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie return -1; 898ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie } 899ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie return 0; 900ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie} 901ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie 902c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang#define MCHBAR_I915 0x44 903c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang#define MCHBAR_I965 0x48 904c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang#define MCHBAR_SIZE (4*4096) 905c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 906c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang#define DEVEN_REG 0x54 907c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang#define DEVEN_MCHBAR_EN (1 << 28) 908c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 909c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang/* Allocate space for the MCH regs if needed, return nonzero on error */ 910c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wangstatic int 911c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wangintel_alloc_mchbar_resource(struct drm_device *dev) 912c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang{ 913c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang drm_i915_private_t *dev_priv = dev->dev_private; 914a6c45cf013a57e32ddae43dd4ac911eb4a3919fdChris Wilson int reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; 915c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang u32 temp_lo, temp_hi = 0; 916c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang u64 mchbar_addr; 917a25c25c2a2aa55e609099a9f74453c518aec29a6Chris Wilson int ret; 918c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 919a6c45cf013a57e32ddae43dd4ac911eb4a3919fdChris Wilson if (INTEL_INFO(dev)->gen >= 4) 920c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); 921c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo); 922c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang mchbar_addr = ((u64)temp_hi << 32) | temp_lo; 923c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 924c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang /* If ACPI doesn't have it, assume we need to allocate it ourselves */ 925c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang#ifdef CONFIG_PNP 926c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang if (mchbar_addr && 927a25c25c2a2aa55e609099a9f74453c518aec29a6Chris Wilson pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) 928a25c25c2a2aa55e609099a9f74453c518aec29a6Chris Wilson return 0; 929c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang#endif 930c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 931c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang /* Get some space for it */ 932a25c25c2a2aa55e609099a9f74453c518aec29a6Chris Wilson dev_priv->mch_res.name = "i915 MCHBAR"; 933a25c25c2a2aa55e609099a9f74453c518aec29a6Chris Wilson dev_priv->mch_res.flags = IORESOURCE_MEM; 934a25c25c2a2aa55e609099a9f74453c518aec29a6Chris Wilson ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, 935a25c25c2a2aa55e609099a9f74453c518aec29a6Chris Wilson &dev_priv->mch_res, 936c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang MCHBAR_SIZE, MCHBAR_SIZE, 937c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang PCIBIOS_MIN_MEM, 938a25c25c2a2aa55e609099a9f74453c518aec29a6Chris Wilson 0, pcibios_align_resource, 939c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang dev_priv->bridge_dev); 940c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang if (ret) { 941c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); 942c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang dev_priv->mch_res.start = 0; 943a25c25c2a2aa55e609099a9f74453c518aec29a6Chris Wilson return ret; 944c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang } 945c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 946a6c45cf013a57e32ddae43dd4ac911eb4a3919fdChris Wilson if (INTEL_INFO(dev)->gen >= 4) 947c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_write_config_dword(dev_priv->bridge_dev, reg + 4, 948c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang upper_32_bits(dev_priv->mch_res.start)); 949c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 950c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_write_config_dword(dev_priv->bridge_dev, reg, 951c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang lower_32_bits(dev_priv->mch_res.start)); 952a25c25c2a2aa55e609099a9f74453c518aec29a6Chris Wilson return 0; 953c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang} 954c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 955c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang/* Setup MCHBAR if possible, return true if we should disable it again */ 956c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wangstatic void 957c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wangintel_setup_mchbar(struct drm_device *dev) 958c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang{ 959c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang drm_i915_private_t *dev_priv = dev->dev_private; 960a6c45cf013a57e32ddae43dd4ac911eb4a3919fdChris Wilson int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; 961c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang u32 temp; 962c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang bool enabled; 963c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 964c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang dev_priv->mchbar_need_disable = false; 965c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 966c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang if (IS_I915G(dev) || IS_I915GM(dev)) { 967c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); 968c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang enabled = !!(temp & DEVEN_MCHBAR_EN); 969c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang } else { 970c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); 971c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang enabled = temp & 1; 972c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang } 973c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 974c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang /* If it's already enabled, don't have to do anything */ 975c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang if (enabled) 976c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang return; 977c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 978c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang if (intel_alloc_mchbar_resource(dev)) 979c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang return; 980c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 981c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang dev_priv->mchbar_need_disable = true; 982c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 983c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang /* Space is allocated or reserved, so enable it. */ 984c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang if (IS_I915G(dev) || IS_I915GM(dev)) { 985c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, 986c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang temp | DEVEN_MCHBAR_EN); 987c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang } else { 988c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); 989c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1); 990c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang } 991c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang} 992c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 993c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wangstatic void 994c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wangintel_teardown_mchbar(struct drm_device *dev) 995c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang{ 996c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang drm_i915_private_t *dev_priv = dev->dev_private; 997a6c45cf013a57e32ddae43dd4ac911eb4a3919fdChris Wilson int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; 998c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang u32 temp; 999c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 1000c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang if (dev_priv->mchbar_need_disable) { 1001c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang if (IS_I915G(dev) || IS_I915GM(dev)) { 1002c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); 1003c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang temp &= ~DEVEN_MCHBAR_EN; 1004c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp); 1005c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang } else { 1006c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); 1007c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang temp &= ~1; 1008c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp); 1009c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang } 1010c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang } 1011c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 1012c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang if (dev_priv->mch_res.start) 1013c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang release_resource(&dev_priv->mch_res); 1014c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang} 1015c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 10168082400327d8d2ca54254b593644942bed0edd25Jesse Barnes#define PTE_ADDRESS_MASK 0xfffff000 10178082400327d8d2ca54254b593644942bed0edd25Jesse Barnes#define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */ 10188082400327d8d2ca54254b593644942bed0edd25Jesse Barnes#define PTE_MAPPING_TYPE_UNCACHED (0 << 1) 10198082400327d8d2ca54254b593644942bed0edd25Jesse Barnes#define PTE_MAPPING_TYPE_DCACHE (1 << 1) /* i830 only */ 10208082400327d8d2ca54254b593644942bed0edd25Jesse Barnes#define PTE_MAPPING_TYPE_CACHED (3 << 1) 10218082400327d8d2ca54254b593644942bed0edd25Jesse Barnes#define PTE_MAPPING_TYPE_MASK (3 << 1) 10228082400327d8d2ca54254b593644942bed0edd25Jesse Barnes#define PTE_VALID (1 << 0) 10238082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 10248082400327d8d2ca54254b593644942bed0edd25Jesse Barnes/** 1025fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson * i915_stolen_to_phys - take an offset into stolen memory and turn it into 1026fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson * a physical one 10278082400327d8d2ca54254b593644942bed0edd25Jesse Barnes * @dev: drm device 1028fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson * @offset: address to translate 10298082400327d8d2ca54254b593644942bed0edd25Jesse Barnes * 1030fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson * Some chip functions require allocations from stolen space and need the 1031fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson * physical address of the memory in question. 10328082400327d8d2ca54254b593644942bed0edd25Jesse Barnes */ 1033fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilsonstatic unsigned long i915_stolen_to_phys(struct drm_device *dev, u32 offset) 10348082400327d8d2ca54254b593644942bed0edd25Jesse Barnes{ 1035fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson struct drm_i915_private *dev_priv = dev->dev_private; 1036fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson struct pci_dev *pdev = dev_priv->bridge_dev; 1037fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson u32 base; 1038fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson 1039fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson#if 0 1040fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson /* On the machines I have tested the Graphics Base of Stolen Memory 1041fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson * is unreliable, so compute the base by subtracting the stolen memory 1042fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson * from the Top of Low Usable DRAM which is where the BIOS places 1043fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson * the graphics stolen memory. 1044fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson */ 1045fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { 1046fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson /* top 32bits are reserved = 0 */ 1047fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson pci_read_config_dword(pdev, 0xA4, &base); 10488082400327d8d2ca54254b593644942bed0edd25Jesse Barnes } else { 1049fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson /* XXX presume 8xx is the same as i915 */ 1050fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson pci_bus_read_config_dword(pdev->bus, 2, 0x5C, &base); 1051fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson } 1052fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson#else 1053fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { 1054fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson u16 val; 1055fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson pci_read_config_word(pdev, 0xb0, &val); 1056fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson base = val >> 4 << 20; 1057fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson } else { 1058fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson u8 val; 1059fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson pci_read_config_byte(pdev, 0x9c, &val); 1060fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson base = val >> 3 << 27; 10618082400327d8d2ca54254b593644942bed0edd25Jesse Barnes } 1062c64f7ba5f1006d8c20eacafecf98d4d00a6902a0Chris Wilson base -= dev_priv->mm.gtt->stolen_size; 1063fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson#endif 10648082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 1065fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson return base + offset; 10668082400327d8d2ca54254b593644942bed0edd25Jesse Barnes} 10678082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 10688082400327d8d2ca54254b593644942bed0edd25Jesse Barnesstatic void i915_warn_stolen(struct drm_device *dev) 10698082400327d8d2ca54254b593644942bed0edd25Jesse Barnes{ 10708082400327d8d2ca54254b593644942bed0edd25Jesse Barnes DRM_ERROR("not enough stolen space for compressed buffer, disabling\n"); 10718082400327d8d2ca54254b593644942bed0edd25Jesse Barnes DRM_ERROR("hint: you may be able to increase stolen memory size in the BIOS to avoid this\n"); 10728082400327d8d2ca54254b593644942bed0edd25Jesse Barnes} 10738082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 10748082400327d8d2ca54254b593644942bed0edd25Jesse Barnesstatic void i915_setup_compression(struct drm_device *dev, int size) 10758082400327d8d2ca54254b593644942bed0edd25Jesse Barnes{ 10768082400327d8d2ca54254b593644942bed0edd25Jesse Barnes struct drm_i915_private *dev_priv = dev->dev_private; 1077132b6aab90d2673af67c414878da241a197e00fbPrarit Bhargava struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb); 107829bd0ae25f8cb96b63560c2cbccec77b425e1603Andrew Morton unsigned long cfb_base; 107929bd0ae25f8cb96b63560c2cbccec77b425e1603Andrew Morton unsigned long ll_base = 0; 10808082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 108143a9539fa9e780f16c0d1e4bc91a2701f1ce178fChris Wilson /* Just in case the BIOS is doing something questionable. */ 108243a9539fa9e780f16c0d1e4bc91a2701f1ce178fChris Wilson intel_disable_fbc(dev); 108343a9539fa9e780f16c0d1e4bc91a2701f1ce178fChris Wilson 1084fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0); 1085fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson if (compressed_fb) 1086fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); 1087fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson if (!compressed_fb) 1088fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson goto err; 10898082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 1090fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson cfb_base = i915_stolen_to_phys(dev, compressed_fb->start); 1091fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson if (!cfb_base) 1092fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson goto err_fb; 10938082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 10949c04f015ebc2cc2cca5a4a576deb82a311578edcYuanhan Liu if (!(IS_GM45(dev) || HAS_PCH_SPLIT(dev))) { 1095fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen, 1096fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson 4096, 4096, 0); 1097fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson if (compressed_llb) 1098fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson compressed_llb = drm_mm_get_block(compressed_llb, 1099fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson 4096, 4096); 1100fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson if (!compressed_llb) 1101fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson goto err_fb; 110274dff282237ea8c0a5df1afd8526eac4b6cee063Jesse Barnes 1103fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson ll_base = i915_stolen_to_phys(dev, compressed_llb->start); 1104fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson if (!ll_base) 1105fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson goto err_llb; 11068082400327d8d2ca54254b593644942bed0edd25Jesse Barnes } 11078082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 11088082400327d8d2ca54254b593644942bed0edd25Jesse Barnes dev_priv->cfb_size = size; 11098082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 111020bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes dev_priv->compressed_fb = compressed_fb; 11119c04f015ebc2cc2cca5a4a576deb82a311578edcYuanhan Liu if (HAS_PCH_SPLIT(dev)) 1112b52eb4dcab23fe0c52a437276258e0afcf913ef5Zhao Yakui I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); 1113b52eb4dcab23fe0c52a437276258e0afcf913ef5Zhao Yakui else if (IS_GM45(dev)) { 111474dff282237ea8c0a5df1afd8526eac4b6cee063Jesse Barnes I915_WRITE(DPFC_CB_BASE, compressed_fb->start); 111574dff282237ea8c0a5df1afd8526eac4b6cee063Jesse Barnes } else { 111674dff282237ea8c0a5df1afd8526eac4b6cee063Jesse Barnes I915_WRITE(FBC_CFB_BASE, cfb_base); 111774dff282237ea8c0a5df1afd8526eac4b6cee063Jesse Barnes I915_WRITE(FBC_LL_BASE, ll_base); 111820bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes dev_priv->compressed_llb = compressed_llb; 11198082400327d8d2ca54254b593644942bed0edd25Jesse Barnes } 11208082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 1121fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", 1122fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson cfb_base, ll_base, size >> 20); 1123fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson return; 1124fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson 1125fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilsonerr_llb: 1126fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson drm_mm_put_block(compressed_llb); 1127fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilsonerr_fb: 1128fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson drm_mm_put_block(compressed_fb); 1129fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilsonerr: 1130fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; 1131fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson i915_warn_stolen(dev); 11328082400327d8d2ca54254b593644942bed0edd25Jesse Barnes} 11338082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 113420bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnesstatic void i915_cleanup_compression(struct drm_device *dev) 113520bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes{ 113620bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes struct drm_i915_private *dev_priv = dev->dev_private; 113720bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes 113820bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes drm_mm_put_block(dev_priv->compressed_fb); 1139aebf0dafee1a0a22b3d25db8107c6479db4aaebeJesse Barnes if (dev_priv->compressed_llb) 114020bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes drm_mm_put_block(dev_priv->compressed_llb); 114120bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes} 114220bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes 114328d520433b6375740990ab99d69b0d0067fd656bDave Airlie/* true = enable decode, false = disable decoder */ 114428d520433b6375740990ab99d69b0d0067fd656bDave Airliestatic unsigned int i915_vga_set_decode(void *cookie, bool state) 114528d520433b6375740990ab99d69b0d0067fd656bDave Airlie{ 114628d520433b6375740990ab99d69b0d0067fd656bDave Airlie struct drm_device *dev = cookie; 114728d520433b6375740990ab99d69b0d0067fd656bDave Airlie 114828d520433b6375740990ab99d69b0d0067fd656bDave Airlie intel_modeset_vga_set_state(dev, state); 114928d520433b6375740990ab99d69b0d0067fd656bDave Airlie if (state) 115028d520433b6375740990ab99d69b0d0067fd656bDave Airlie return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | 115128d520433b6375740990ab99d69b0d0067fd656bDave Airlie VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 115228d520433b6375740990ab99d69b0d0067fd656bDave Airlie else 115328d520433b6375740990ab99d69b0d0067fd656bDave Airlie return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 115428d520433b6375740990ab99d69b0d0067fd656bDave Airlie} 115528d520433b6375740990ab99d69b0d0067fd656bDave Airlie 11566a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airliestatic void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) 11576a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie{ 11586a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie struct drm_device *dev = pci_get_drvdata(pdev); 11596a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; 11606a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie if (state == VGA_SWITCHEROO_ON) { 1161fbf81762e385d3d45acad057b654d56972acf58cDave Airlie printk(KERN_INFO "i915: switched on\n"); 11625bcf719b7db0f9366cedaf102b081f99b1c325aeDave Airlie dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 11636a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie /* i915 resume handler doesn't set to D0 */ 11646a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie pci_set_power_state(dev->pdev, PCI_D0); 11656a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie i915_resume(dev); 11665bcf719b7db0f9366cedaf102b081f99b1c325aeDave Airlie dev->switch_power_state = DRM_SWITCH_POWER_ON; 11676a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie } else { 11686a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie printk(KERN_ERR "i915: switched off\n"); 11695bcf719b7db0f9366cedaf102b081f99b1c325aeDave Airlie dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 11706a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie i915_suspend(dev, pmm); 11715bcf719b7db0f9366cedaf102b081f99b1c325aeDave Airlie dev->switch_power_state = DRM_SWITCH_POWER_OFF; 11726a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie } 11736a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie} 11746a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie 11756a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airliestatic bool i915_switcheroo_can_switch(struct pci_dev *pdev) 11766a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie{ 11776a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie struct drm_device *dev = pci_get_drvdata(pdev); 11786a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie bool can_switch; 11796a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie 11806a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie spin_lock(&dev->count_lock); 11816a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie can_switch = (dev->open_count == 0); 11826a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie spin_unlock(&dev->count_lock); 11836a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie return can_switch; 11846a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie} 11856a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie 1186650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetterstatic bool 1187650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetterintel_enable_ppgtt(struct drm_device *dev) 1188650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter{ 1189650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter if (i915_enable_ppgtt >= 0) 1190650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter return i915_enable_ppgtt; 1191650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter 1192650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter#ifdef CONFIG_INTEL_IOMMU 1193650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter /* Disable ppgtt on SNB if VT-d is on. */ 1194650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) 1195650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter return false; 1196650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter#endif 1197650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter 1198650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter return true; 1199650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter} 1200650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter 12012c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilsonstatic int i915_load_gem_init(struct drm_device *dev) 120279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes{ 120379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes struct drm_i915_private *dev_priv = dev->dev_private; 120453984635a659e360f206a81ada4ae813152d72f1Daniel Vetter unsigned long prealloc_size, gtt_size, mappable_size; 12052c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson int ret; 120679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 1207c64f7ba5f1006d8c20eacafecf98d4d00a6902a0Chris Wilson prealloc_size = dev_priv->mm.gtt->stolen_size; 120853984635a659e360f206a81ada4ae813152d72f1Daniel Vetter gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT; 120953984635a659e360f206a81ada4ae813152d72f1Daniel Vetter mappable_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; 121053984635a659e360f206a81ada4ae813152d72f1Daniel Vetter 1211fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson /* Basic memrange allocator for stolen space */ 1212fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size); 121379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 1214d3ae08109d628d26615d7f7f4d8d53cdd8d71fd0Daniel Vetter mutex_lock(&dev->struct_mutex); 1215650dc07ec3b0eba8ff21da706d2b1876ada59fc3Daniel Vetter if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) { 12161d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter /* PPGTT pdes are stolen from global gtt ptes, so shrink the 12171d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter * aperture accordingly when using aliasing ppgtt. */ 12181d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; 12191d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter /* For paranoia keep the guard page in between. */ 12201d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter gtt_size -= PAGE_SIZE; 12211d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter 12221d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter i915_gem_do_init(dev, 0, mappable_size, gtt_size); 12231d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter 12241d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter ret = i915_gem_init_aliasing_ppgtt(dev); 1225e02f14cd48a5da0ebaecf88c93dbd54a81e0deadDaniel Vetter if (ret) { 1226e02f14cd48a5da0ebaecf88c93dbd54a81e0deadDaniel Vetter mutex_unlock(&dev->struct_mutex); 12271d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter return ret; 1228e02f14cd48a5da0ebaecf88c93dbd54a81e0deadDaniel Vetter } 12291d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter } else { 12301d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter /* Let GEM Manage all of the aperture. 12311d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter * 12321d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter * However, leave one page at the end still bound to the scratch 12331d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter * page. There are a number of places where the hardware 12341d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter * apparently prefetches past the end of the object, and we've 12351d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter * seen multiple hangs with the GPU head pointer stuck in a 12361d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter * batchbuffer bound at the last page of the aperture. One page 12371d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter * should be enough to keep any prefetching inside of the 12381d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter * aperture. 12391d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter */ 12401d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); 12411d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter } 124279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 1243f691e2f4cec334e906f971471b3bf1460c6256d4Daniel Vetter ret = i915_gem_init_hw(dev); 124411ed50ec2a316928c2bacc1149bded86c6a96068Ben Gamari mutex_unlock(&dev->struct_mutex); 12451d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter if (ret) { 12461d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter i915_gem_cleanup_aliasing_ppgtt(dev); 12472c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson return ret; 12481d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter } 124979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 12508082400327d8d2ca54254b593644942bed0edd25Jesse Barnes /* Try to set up FBC with a reasonable compressed buffer size */ 12519216d44dc13b5e858253f06d83ceea25a9b72f4fShaohua Li if (I915_HAS_FBC(dev) && i915_powersave) { 12528082400327d8d2ca54254b593644942bed0edd25Jesse Barnes int cfb_size; 12538082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 1254fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson /* Leave 1M for line length buffer & misc. */ 1255fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson 1256fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson /* Try to get a 32M buffer... */ 1257fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson if (prealloc_size > (36*1024*1024)) 1258fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson cfb_size = 32*1024*1024; 12598082400327d8d2ca54254b593644942bed0edd25Jesse Barnes else /* fall back to 7/8 of the stolen space */ 12608082400327d8d2ca54254b593644942bed0edd25Jesse Barnes cfb_size = prealloc_size * 7 / 8; 12618082400327d8d2ca54254b593644942bed0edd25Jesse Barnes i915_setup_compression(dev, cfb_size); 12628082400327d8d2ca54254b593644942bed0edd25Jesse Barnes } 12638082400327d8d2ca54254b593644942bed0edd25Jesse Barnes 1264fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson /* Allow hardware batchbuffers unless told otherwise. */ 126579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes dev_priv->allow_batchbuffer = 1; 12662c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson return 0; 12672c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson} 12682c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson 12692c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilsonstatic int i915_load_modeset_init(struct drm_device *dev) 12702c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson{ 12712c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson struct drm_i915_private *dev_priv = dev->dev_private; 12722c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson int ret; 127379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 12746d139a87b747aaebc969ac5f4eb8db766fcd9cbdBryan Freed ret = intel_parse_bios(dev); 127579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes if (ret) 127679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes DRM_INFO("failed to find VBIOS tables\n"); 127779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 1278934f992c763ae1e5eefcce8af769c16444085df7Chris Wilson /* If we have > 1 VGA cards, then we need to arbitrate access 1279934f992c763ae1e5eefcce8af769c16444085df7Chris Wilson * to the common VGA resources. 1280934f992c763ae1e5eefcce8af769c16444085df7Chris Wilson * 1281934f992c763ae1e5eefcce8af769c16444085df7Chris Wilson * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA), 1282934f992c763ae1e5eefcce8af769c16444085df7Chris Wilson * then we do not take part in VGA arbitration and the 1283934f992c763ae1e5eefcce8af769c16444085df7Chris Wilson * vga_client_register() fails with -ENODEV. 1284934f992c763ae1e5eefcce8af769c16444085df7Chris Wilson */ 128528d520433b6375740990ab99d69b0d0067fd656bDave Airlie ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); 1286934f992c763ae1e5eefcce8af769c16444085df7Chris Wilson if (ret && ret != -ENODEV) 12872c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson goto out; 128828d520433b6375740990ab99d69b0d0067fd656bDave Airlie 1289723bfd707a97fee06eb3ba4d3e8b4714c29a1064Jesse Barnes intel_register_dsm_handler(); 1290723bfd707a97fee06eb3ba4d3e8b4714c29a1064Jesse Barnes 12916a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie ret = vga_switcheroo_register_client(dev->pdev, 12926a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie i915_switcheroo_set_state, 12938d608aa6295242fe4c4b6105b8c59c6a5b232d89Dave Airlie NULL, 12946a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie i915_switcheroo_can_switch); 12956a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie if (ret) 12965a79395b2791cc70442ab8434aed1b5206683e7cChris Wilson goto cleanup_vga_client; 12976a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie 12981afe3e9d4335bf3bc5615e37243dc8fef65dac8fJesse Barnes /* IIR "flip pending" bit means done if this bit is set */ 12991afe3e9d4335bf3bc5615e37243dc8fef65dac8fJesse Barnes if (IS_GEN3(dev) && (I915_READ(ECOSKPD) & ECO_FLIP_DONE)) 13001afe3e9d4335bf3bc5615e37243dc8fef65dac8fJesse Barnes dev_priv->flip_pending_is_done = true; 13011afe3e9d4335bf3bc5615e37243dc8fef65dac8fJesse Barnes 1302b01f2c3a4a37d09a47ad73ccbb46d554d21cfeb0Jesse Barnes intel_modeset_init(dev); 1303b01f2c3a4a37d09a47ad73ccbb46d554d21cfeb0Jesse Barnes 13042c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson ret = i915_load_gem_init(dev); 130579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes if (ret) 13065a79395b2791cc70442ab8434aed1b5206683e7cChris Wilson goto cleanup_vga_switcheroo; 130779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 13082c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson intel_modeset_gem_init(dev); 13092c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson 13102c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson ret = drm_irq_install(dev); 13112c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson if (ret) 13122c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson goto cleanup_gem; 13132c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson 131479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes /* Always safe in the mode setting case. */ 131579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes /* FIXME: do pre/post-mode set stuff in core KMS code */ 131679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes dev->vblank_disable_allowed = 1; 131779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 13185a79395b2791cc70442ab8434aed1b5206683e7cChris Wilson ret = intel_fbdev_init(dev); 13195a79395b2791cc70442ab8434aed1b5206683e7cChris Wilson if (ret) 13205a79395b2791cc70442ab8434aed1b5206683e7cChris Wilson goto cleanup_irq; 13215a79395b2791cc70442ab8434aed1b5206683e7cChris Wilson 1322eb1f8e4f3be898df808e2dfc131099f5831d491dDave Airlie drm_kms_helper_poll_init(dev); 132387acb0a550694ff1a7725ea3a73b80d8ccf56180Chris Wilson 132487acb0a550694ff1a7725ea3a73b80d8ccf56180Chris Wilson /* We're off and running w/KMS */ 132587acb0a550694ff1a7725ea3a73b80d8ccf56180Chris Wilson dev_priv->mm.suspended = 0; 132687acb0a550694ff1a7725ea3a73b80d8ccf56180Chris Wilson 132779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes return 0; 132879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 13295a79395b2791cc70442ab8434aed1b5206683e7cChris Wilsoncleanup_irq: 13305a79395b2791cc70442ab8434aed1b5206683e7cChris Wilson drm_irq_uninstall(dev); 13312c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilsoncleanup_gem: 13322c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson mutex_lock(&dev->struct_mutex); 13332c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson i915_gem_cleanup_ringbuffer(dev); 13342c7111dbaec72b01c804afb8ad77c6c7523986fdChris Wilson mutex_unlock(&dev->struct_mutex); 13351d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter i915_gem_cleanup_aliasing_ppgtt(dev); 13365a79395b2791cc70442ab8434aed1b5206683e7cChris Wilsoncleanup_vga_switcheroo: 13375a79395b2791cc70442ab8434aed1b5206683e7cChris Wilson vga_switcheroo_unregister_client(dev->pdev); 13385a79395b2791cc70442ab8434aed1b5206683e7cChris Wilsoncleanup_vga_client: 13395a79395b2791cc70442ab8434aed1b5206683e7cChris Wilson vga_client_register(dev->pdev, NULL, NULL, NULL); 134079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnesout: 134179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes return ret; 134279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes} 134379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 13447c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlieint i915_master_create(struct drm_device *dev, struct drm_master *master) 13457c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 13467c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_i915_master_private *master_priv; 13477c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 13489a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL); 13497c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (!master_priv) 13507c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return -ENOMEM; 13517c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 13527c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master->driver_priv = master_priv; 13537c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return 0; 13547c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 13557c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 13567c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlievoid i915_master_destroy(struct drm_device *dev, struct drm_master *master) 13577c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie{ 13587c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie struct drm_i915_master_private *master_priv = master->driver_priv; 13597c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 13607c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie if (!master_priv) 13617c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie return; 13627c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 13639a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(master_priv); 13647c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 13657c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie master->driver_priv = NULL; 13667c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie} 13677c1c2871a6a3a114853ec6836e9035ac1c0c7f7aDave Airlie 13687648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesstatic void i915_pineview_get_mem_freq(struct drm_device *dev) 13697662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li{ 13707662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li drm_i915_private_t *dev_priv = dev->dev_private; 13717662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li u32 tmp; 13727662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li 13737662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li tmp = I915_READ(CLKCFG); 13747662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li 13757662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li switch (tmp & CLKCFG_FSB_MASK) { 13767662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li case CLKCFG_FSB_533: 13777662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li dev_priv->fsb_freq = 533; /* 133*4 */ 13787662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li break; 13797662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li case CLKCFG_FSB_800: 13807662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li dev_priv->fsb_freq = 800; /* 200*4 */ 13817662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li break; 13827662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li case CLKCFG_FSB_667: 13837662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li dev_priv->fsb_freq = 667; /* 167*4 */ 13847662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li break; 13857662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li case CLKCFG_FSB_400: 13867662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li dev_priv->fsb_freq = 400; /* 100*4 */ 13877662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li break; 13887662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li } 13897662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li 13907662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li switch (tmp & CLKCFG_MEM_MASK) { 13917662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li case CLKCFG_MEM_533: 13927662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li dev_priv->mem_freq = 533; 13937662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li break; 13947662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li case CLKCFG_MEM_667: 13957662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li dev_priv->mem_freq = 667; 13967662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li break; 13977662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li case CLKCFG_MEM_800: 13987662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li dev_priv->mem_freq = 800; 13997662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li break; 14007662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li } 14019553426372eef71c849499fb1d232f4b0577c0f9Li Peng 14029553426372eef71c849499fb1d232f4b0577c0f9Li Peng /* detect pineview DDR3 setting */ 14039553426372eef71c849499fb1d232f4b0577c0f9Li Peng tmp = I915_READ(CSHRDDR3CTL); 14049553426372eef71c849499fb1d232f4b0577c0f9Li Peng dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0; 14057662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li} 14067662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li 14077648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesstatic void i915_ironlake_get_mem_freq(struct drm_device *dev) 14087648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 14097648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes drm_i915_private_t *dev_priv = dev->dev_private; 14107648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes u16 ddrpll, csipll; 14117648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 14127648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes ddrpll = I915_READ16(DDRMPLL1); 14137648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes csipll = I915_READ16(CSIPLL0); 14147648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 14157648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes switch (ddrpll & 0xff) { 14167648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0xc: 14177648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->mem_freq = 800; 14187648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14197648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0x10: 14207648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->mem_freq = 1066; 14217648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14227648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0x14: 14237648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->mem_freq = 1333; 14247648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14257648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0x18: 14267648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->mem_freq = 1600; 14277648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14287648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes default: 14297648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes DRM_DEBUG_DRIVER("unknown memory frequency 0x%02x\n", 14307648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes ddrpll & 0xff); 14317648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->mem_freq = 0; 14327648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14337648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } 14347648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 14357648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->r_t = dev_priv->mem_freq; 14367648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 14377648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes switch (csipll & 0x3ff) { 14387648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0x00c: 14397648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->fsb_freq = 3200; 14407648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14417648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0x00e: 14427648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->fsb_freq = 3733; 14437648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14447648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0x010: 14457648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->fsb_freq = 4266; 14467648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14477648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0x012: 14487648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->fsb_freq = 4800; 14497648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14507648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0x014: 14517648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->fsb_freq = 5333; 14527648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14537648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0x016: 14547648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->fsb_freq = 5866; 14557648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14567648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes case 0x018: 14577648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->fsb_freq = 6400; 14587648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14597648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes default: 14607648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes DRM_DEBUG_DRIVER("unknown fsb frequency 0x%04x\n", 14617648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes csipll & 0x3ff); 14627648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->fsb_freq = 0; 14637648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 14647648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } 14657648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 14667648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (dev_priv->fsb_freq == 3200) { 14677648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->c_m = 0; 14687648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) { 14697648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->c_m = 1; 14707648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } else { 14717648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->c_m = 2; 14727648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } 14737648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 14747648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 1475faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilsonstatic const struct cparams { 1476faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson u16 i; 1477faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson u16 t; 1478faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson u16 m; 1479faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson u16 c; 1480faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson} cparams[] = { 14817648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes { 1, 1333, 301, 28664 }, 14827648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes { 1, 1066, 294, 24460 }, 14837648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes { 1, 800, 294, 25192 }, 14847648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes { 0, 1333, 276, 27605 }, 14857648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes { 0, 1066, 276, 27605 }, 14867648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes { 0, 800, 231, 23784 }, 14877648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes}; 14887648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 14897648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesunsigned long i915_chipset_val(struct drm_i915_private *dev_priv) 14907648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 14917648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes u64 total_count, diff, ret; 14927648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes u32 count1, count2, count3, m = 0, c = 0; 14937648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes unsigned long now = jiffies_to_msecs(jiffies), diff1; 14947648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes int i; 14957648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 14967648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes diff1 = now - dev_priv->last_time1; 14977648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 14984ed0b577457eb6aeb7cdc7e7316576e63d15abb2Eugeni Dodonov /* Prevent division-by-zero if we are asking too fast. 14994ed0b577457eb6aeb7cdc7e7316576e63d15abb2Eugeni Dodonov * Also, we don't get interesting results if we are polling 15004ed0b577457eb6aeb7cdc7e7316576e63d15abb2Eugeni Dodonov * faster than once in 10ms, so just return the saved value 15014ed0b577457eb6aeb7cdc7e7316576e63d15abb2Eugeni Dodonov * in such cases. 15024ed0b577457eb6aeb7cdc7e7316576e63d15abb2Eugeni Dodonov */ 15034ed0b577457eb6aeb7cdc7e7316576e63d15abb2Eugeni Dodonov if (diff1 <= 10) 15044ed0b577457eb6aeb7cdc7e7316576e63d15abb2Eugeni Dodonov return dev_priv->chipset_power; 15054ed0b577457eb6aeb7cdc7e7316576e63d15abb2Eugeni Dodonov 15067648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes count1 = I915_READ(DMIEC); 15077648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes count2 = I915_READ(DDREC); 15087648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes count3 = I915_READ(CSIEC); 15097648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 15107648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes total_count = count1 + count2 + count3; 15117648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 15127648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes /* FIXME: handle per-counter overflow */ 15137648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (total_count < dev_priv->last_count1) { 15147648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes diff = ~0UL - dev_priv->last_count1; 15157648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes diff += total_count; 15167648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } else { 15177648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes diff = total_count - dev_priv->last_count1; 15187648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } 15197648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 15207648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes for (i = 0; i < ARRAY_SIZE(cparams); i++) { 15217648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (cparams[i].i == dev_priv->c_m && 15227648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes cparams[i].t == dev_priv->r_t) { 15237648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes m = cparams[i].m; 15247648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes c = cparams[i].c; 15257648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes break; 15267648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } 15277648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } 15287648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 1529d270ae34eb77c58dea60e5b1e300a698d2ce39acJesse Barnes diff = div_u64(diff, diff1); 15307648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes ret = ((m * diff) + c); 1531d270ae34eb77c58dea60e5b1e300a698d2ce39acJesse Barnes ret = div_u64(ret, 10); 15327648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 15337648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->last_count1 = total_count; 15347648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->last_time1 = now; 15357648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 15364ed0b577457eb6aeb7cdc7e7316576e63d15abb2Eugeni Dodonov dev_priv->chipset_power = ret; 15374ed0b577457eb6aeb7cdc7e7316576e63d15abb2Eugeni Dodonov 15387648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes return ret; 15397648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 15407648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 15417648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesunsigned long i915_mch_val(struct drm_i915_private *dev_priv) 15427648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 15437648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes unsigned long m, x, b; 15447648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes u32 tsfs; 15457648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 15467648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes tsfs = I915_READ(TSFS); 15477648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 15487648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT); 15497648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes x = I915_READ8(TR1); 15507648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 15517648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes b = tsfs & TSFS_INTR_MASK; 15527648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 15537648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes return ((m * x) / 127) - b; 15547648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 15557648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 1556faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilsonstatic u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) 15577648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 1558faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson static const struct v_table { 1559faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson u16 vd; /* in .1 mil */ 1560faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson u16 vm; /* in .1 mil */ 1561faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson } v_table[] = { 1562faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 0, 0, }, 1563faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 375, 0, }, 1564faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 500, 0, }, 1565faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 625, 0, }, 1566faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 750, 0, }, 1567faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 875, 0, }, 1568faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 1000, 0, }, 1569faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 1125, 0, }, 1570faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1571faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1572faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1573faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1574faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1575faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1576faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1577faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1578faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1579faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1580faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1581faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1582faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1583faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1584faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1585faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1586faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1587faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1588faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1589faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1590faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1591faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1592faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1593faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4125, 3000, }, 1594faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4250, 3125, }, 1595faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4375, 3250, }, 1596faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4500, 3375, }, 1597faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4625, 3500, }, 1598faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4750, 3625, }, 1599faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 4875, 3750, }, 1600faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 5000, 3875, }, 1601faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 5125, 4000, }, 1602faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 5250, 4125, }, 1603faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 5375, 4250, }, 1604faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 5500, 4375, }, 1605faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 5625, 4500, }, 1606faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 5750, 4625, }, 1607faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 5875, 4750, }, 1608faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 6000, 4875, }, 1609faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 6125, 5000, }, 1610faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 6250, 5125, }, 1611faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 6375, 5250, }, 1612faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 6500, 5375, }, 1613faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 6625, 5500, }, 1614faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 6750, 5625, }, 1615faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 6875, 5750, }, 1616faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 7000, 5875, }, 1617faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 7125, 6000, }, 1618faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 7250, 6125, }, 1619faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 7375, 6250, }, 1620faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 7500, 6375, }, 1621faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 7625, 6500, }, 1622faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 7750, 6625, }, 1623faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 7875, 6750, }, 1624faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 8000, 6875, }, 1625faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 8125, 7000, }, 1626faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 8250, 7125, }, 1627faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 8375, 7250, }, 1628faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 8500, 7375, }, 1629faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 8625, 7500, }, 1630faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 8750, 7625, }, 1631faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 8875, 7750, }, 1632faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 9000, 7875, }, 1633faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 9125, 8000, }, 1634faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 9250, 8125, }, 1635faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 9375, 8250, }, 1636faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 9500, 8375, }, 1637faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 9625, 8500, }, 1638faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 9750, 8625, }, 1639faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 9875, 8750, }, 1640faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 10000, 8875, }, 1641faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 10125, 9000, }, 1642faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 10250, 9125, }, 1643faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 10375, 9250, }, 1644faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 10500, 9375, }, 1645faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 10625, 9500, }, 1646faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 10750, 9625, }, 1647faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 10875, 9750, }, 1648faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 11000, 9875, }, 1649faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 11125, 10000, }, 1650faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 11250, 10125, }, 1651faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 11375, 10250, }, 1652faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 11500, 10375, }, 1653faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 11625, 10500, }, 1654faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 11750, 10625, }, 1655faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 11875, 10750, }, 1656faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 12000, 10875, }, 1657faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 12125, 11000, }, 1658faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 12250, 11125, }, 1659faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 12375, 11250, }, 1660faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 12500, 11375, }, 1661faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 12625, 11500, }, 1662faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 12750, 11625, }, 1663faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 12875, 11750, }, 1664faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 13000, 11875, }, 1665faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 13125, 12000, }, 1666faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 13250, 12125, }, 1667faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 13375, 12250, }, 1668faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 13500, 12375, }, 1669faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 13625, 12500, }, 1670faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 13750, 12625, }, 1671faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 13875, 12750, }, 1672faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 14000, 12875, }, 1673faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 14125, 13000, }, 1674faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 14250, 13125, }, 1675faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 14375, 13250, }, 1676faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 14500, 13375, }, 1677faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 14625, 13500, }, 1678faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 14750, 13625, }, 1679faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 14875, 13750, }, 1680faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 15000, 13875, }, 1681faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 15125, 14000, }, 1682faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 15250, 14125, }, 1683faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 15375, 14250, }, 1684faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 15500, 14375, }, 1685faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 15625, 14500, }, 1686faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 15750, 14625, }, 1687faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 15875, 14750, }, 1688faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 16000, 14875, }, 1689faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson { 16125, 15000, }, 1690faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson }; 1691faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson if (dev_priv->info->is_mobile) 1692faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson return v_table[pxvid].vm; 1693faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson else 1694faa60c4174d943696b9478c5de6438c4f0fecba6Chris Wilson return v_table[pxvid].vd; 16957648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 16967648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 16977648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesvoid i915_update_gfx_val(struct drm_i915_private *dev_priv) 16987648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 16997648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes struct timespec now, diff1; 17007648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes u64 diff; 17017648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes unsigned long diffms; 17027648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes u32 count; 17037648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 1704e90f3b61f4432e3c5bb6b57f4b3e8d8cba747541Chris Wilson if (dev_priv->info->gen != 5) 1705e90f3b61f4432e3c5bb6b57f4b3e8d8cba747541Chris Wilson return; 1706e90f3b61f4432e3c5bb6b57f4b3e8d8cba747541Chris Wilson 17077648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes getrawmonotonic(&now); 17087648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes diff1 = timespec_sub(now, dev_priv->last_time2); 17097648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17107648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes /* Don't divide by 0 */ 17117648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000; 17127648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (!diffms) 17137648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes return; 17147648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17157648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes count = I915_READ(GFXEC); 17167648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17177648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (count < dev_priv->last_count2) { 17187648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes diff = ~0UL - dev_priv->last_count2; 17197648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes diff += count; 17207648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } else { 17217648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes diff = count - dev_priv->last_count2; 17227648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } 17237648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17247648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->last_count2 = count; 17257648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->last_time2 = now; 17267648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17277648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes /* More magic constants... */ 17287648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes diff = diff * 1181; 1729d270ae34eb77c58dea60e5b1e300a698d2ce39acJesse Barnes diff = div_u64(diff, diffms * 10); 17307648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->gfx_power = diff; 17317648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 17327648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17337648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesunsigned long i915_gfx_val(struct drm_i915_private *dev_priv) 17347648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 17357648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes unsigned long t, corr, state1, corr2, state2; 17367648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes u32 pxvid, ext_v; 17377648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17387648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4)); 17397648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes pxvid = (pxvid >> 24) & 0x7f; 17407648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes ext_v = pvid_to_extvid(dev_priv, pxvid); 17417648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17427648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes state1 = ext_v; 17437648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17447648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes t = i915_mch_val(dev_priv); 17457648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17467648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes /* Revel in the empirically derived constants */ 17477648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17487648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes /* Correction factor in 1/100000 units */ 17497648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (t > 80) 17507648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes corr = ((t * 2349) + 135940); 17517648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes else if (t >= 50) 17527648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes corr = ((t * 964) + 29317); 17537648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes else /* < 50 */ 17547648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes corr = ((t * 301) + 1004); 17557648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17567648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes corr = corr * ((150142 * state1) / 10000 - 78642); 17577648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes corr /= 100000; 17587648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes corr2 = (corr * dev_priv->corr); 17597648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17607648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes state2 = (corr2 * state1) / 10000; 17617648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes state2 /= 100; /* convert to mW */ 17627648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17637648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes i915_update_gfx_val(dev_priv); 17647648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17657648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes return dev_priv->gfx_power + state2; 17667648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 17677648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17687648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes/* Global for IPS driver to get at the current i915 device */ 17697648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesstatic struct drm_i915_private *i915_mch_dev; 17707648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes/* 17717648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * Lock protecting IPS related data structures 17727648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * - i915_mch_dev 17737648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * - dev_priv->max_delay 17747648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * - dev_priv->min_delay 17757648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * - dev_priv->fmax 17767648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * - dev_priv->gpu_busy 17777648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes */ 1778995b6762f0fd54377bbfafdf5328b12de698bfa8Chris Wilsonstatic DEFINE_SPINLOCK(mchdev_lock); 17797648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17807648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes/** 17817648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * i915_read_mch_val - return value for IPS use 17827648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * 17837648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * Calculate and return a value for the IPS driver to use when deciding whether 17847648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * we have thermal and power headroom to increase CPU or GPU power budget. 17857648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes */ 17867648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesunsigned long i915_read_mch_val(void) 17877648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 17880206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi struct drm_i915_private *dev_priv; 17897648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes unsigned long chipset_val, graphics_val, ret = 0; 17907648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17910206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi spin_lock(&mchdev_lock); 17927648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (!i915_mch_dev) 17937648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes goto out_unlock; 17947648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv = i915_mch_dev; 17957648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17967648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes chipset_val = i915_chipset_val(dev_priv); 17977648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes graphics_val = i915_gfx_val(dev_priv); 17987648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 17997648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes ret = chipset_val + graphics_val; 18007648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18017648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesout_unlock: 18020206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi spin_unlock(&mchdev_lock); 18037648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18040206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi return ret; 18057648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 18067648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse BarnesEXPORT_SYMBOL_GPL(i915_read_mch_val); 18077648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18087648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes/** 18097648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * i915_gpu_raise - raise GPU frequency limit 18107648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * 18117648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * Raise the limit; IPS indicates we have thermal headroom. 18127648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes */ 18137648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesbool i915_gpu_raise(void) 18147648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 18150206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi struct drm_i915_private *dev_priv; 18167648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes bool ret = true; 18177648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18180206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi spin_lock(&mchdev_lock); 18197648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (!i915_mch_dev) { 18207648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes ret = false; 18217648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes goto out_unlock; 18227648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } 18237648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv = i915_mch_dev; 18247648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18257648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (dev_priv->max_delay > dev_priv->fmax) 18267648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->max_delay--; 18277648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18287648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesout_unlock: 18290206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi spin_unlock(&mchdev_lock); 18307648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18310206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi return ret; 18327648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 18337648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse BarnesEXPORT_SYMBOL_GPL(i915_gpu_raise); 18347648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18357648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes/** 18367648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * i915_gpu_lower - lower GPU frequency limit 18377648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * 18387648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * IPS indicates we're close to a thermal limit, so throttle back the GPU 18397648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * frequency maximum. 18407648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes */ 18417648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesbool i915_gpu_lower(void) 18427648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 18430206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi struct drm_i915_private *dev_priv; 18447648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes bool ret = true; 18457648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18460206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi spin_lock(&mchdev_lock); 18477648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (!i915_mch_dev) { 18487648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes ret = false; 18497648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes goto out_unlock; 18507648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } 18517648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv = i915_mch_dev; 18527648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18537648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (dev_priv->max_delay < dev_priv->min_delay) 18547648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->max_delay++; 18557648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18567648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesout_unlock: 18570206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi spin_unlock(&mchdev_lock); 18587648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18590206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi return ret; 18607648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 18617648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse BarnesEXPORT_SYMBOL_GPL(i915_gpu_lower); 18627648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18637648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes/** 18647648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * i915_gpu_busy - indicate GPU business to IPS 18657648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * 18667648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * Tell the IPS driver whether or not the GPU is busy. 18677648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes */ 18687648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesbool i915_gpu_busy(void) 18697648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 18700206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi struct drm_i915_private *dev_priv; 18717648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes bool ret = false; 18727648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18730206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi spin_lock(&mchdev_lock); 18747648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (!i915_mch_dev) 18757648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes goto out_unlock; 18767648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv = i915_mch_dev; 18777648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18787648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes ret = dev_priv->busy; 18797648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18807648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesout_unlock: 18810206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi spin_unlock(&mchdev_lock); 18827648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18830206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi return ret; 18847648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 18857648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse BarnesEXPORT_SYMBOL_GPL(i915_gpu_busy); 18867648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18877648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes/** 18887648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * i915_gpu_turbo_disable - disable graphics turbo 18897648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * 18907648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * Disable graphics turbo by resetting the max frequency and setting the 18917648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes * current frequency to the default. 18927648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes */ 18937648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesbool i915_gpu_turbo_disable(void) 18947648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes{ 18950206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi struct drm_i915_private *dev_priv; 18967648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes bool ret = true; 18977648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 18980206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi spin_lock(&mchdev_lock); 18997648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (!i915_mch_dev) { 19007648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes ret = false; 19017648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes goto out_unlock; 19027648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes } 19037648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv = i915_mch_dev; 19047648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 19057648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes dev_priv->max_delay = dev_priv->fstart; 19067648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 19077648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (!ironlake_set_drps(dev_priv->dev, dev_priv->fstart)) 19087648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes ret = false; 19097648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 19107648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnesout_unlock: 19110206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi spin_unlock(&mchdev_lock); 19127648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 19130206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi return ret; 19147648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes} 19157648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse BarnesEXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); 19167648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 191779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes/** 191863ee41d794d9c555f84205517a68509848988760Eric Anholt * Tells the intel_ips driver that the i915 driver is now loaded, if 191963ee41d794d9c555f84205517a68509848988760Eric Anholt * IPS got loaded first. 192063ee41d794d9c555f84205517a68509848988760Eric Anholt * 192163ee41d794d9c555f84205517a68509848988760Eric Anholt * This awkward dance is so that neither module has to depend on the 192263ee41d794d9c555f84205517a68509848988760Eric Anholt * other in order for IPS to do the appropriate communication of 192363ee41d794d9c555f84205517a68509848988760Eric Anholt * GPU turbo limits to i915. 192463ee41d794d9c555f84205517a68509848988760Eric Anholt */ 192563ee41d794d9c555f84205517a68509848988760Eric Anholtstatic void 192663ee41d794d9c555f84205517a68509848988760Eric Anholtips_ping_for_i915_load(void) 192763ee41d794d9c555f84205517a68509848988760Eric Anholt{ 192863ee41d794d9c555f84205517a68509848988760Eric Anholt void (*link)(void); 192963ee41d794d9c555f84205517a68509848988760Eric Anholt 193063ee41d794d9c555f84205517a68509848988760Eric Anholt link = symbol_get(ips_link_to_i915_driver); 193163ee41d794d9c555f84205517a68509848988760Eric Anholt if (link) { 193263ee41d794d9c555f84205517a68509848988760Eric Anholt link(); 193363ee41d794d9c555f84205517a68509848988760Eric Anholt symbol_put(ips_link_to_i915_driver); 193463ee41d794d9c555f84205517a68509848988760Eric Anholt } 193563ee41d794d9c555f84205517a68509848988760Eric Anholt} 193663ee41d794d9c555f84205517a68509848988760Eric Anholt 193763ee41d794d9c555f84205517a68509848988760Eric Anholt/** 193879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * i915_driver_load - setup chip and create an initial config 193979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * @dev: DRM device 194079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * @flags: startup flags 194179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * 194279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * The driver load routine has to do several things: 194379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * - drive output discovery via intel_modeset_init() 194479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * - initialize the memory manager 194579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * - allocate initial config memory 194679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * - setup the DRM framebuffer with the allocated memory 194779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes */ 194884b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_driver_load(struct drm_device *dev, unsigned long flags) 194922eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie{ 1950ea059a1ec4496a10f94ca9d0c1b530faf1b85dceLuca Tettamanti struct drm_i915_private *dev_priv; 1951cfdf1fa23f4074c9f8766dc67a928bbf680b1ac9Kristian Høgsberg int ret = 0, mmio_bar; 1952fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson uint32_t agp_size; 1953fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson 195422eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie /* i915 has 4 more counters */ 195522eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie dev->counters += 4; 195622eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie dev->types[6] = _DRM_STAT_IRQ; 195722eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie dev->types[7] = _DRM_STAT_PRIMARY; 195822eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie dev->types[8] = _DRM_STAT_SECONDARY; 195922eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie dev->types[9] = _DRM_STAT_DMA; 196022eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie 19619a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt dev_priv = kzalloc(sizeof(drm_i915_private_t), GFP_KERNEL); 1962ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes if (dev_priv == NULL) 1963ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes return -ENOMEM; 1964ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 1965ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes dev->dev_private = (void *)dev_priv; 1966673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt dev_priv->dev = dev; 1967cfdf1fa23f4074c9f8766dc67a928bbf680b1ac9Kristian Høgsberg dev_priv->info = (struct intel_device_info *) flags; 1968ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 1969ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie if (i915_get_bridge_dev(dev)) { 1970ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie ret = -EIO; 1971ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie goto free_priv; 1972ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie } 1973ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie 1974466e69b8b03b8c1987367912782bc12988ad8794Dave Airlie pci_set_master(dev->pdev); 1975466e69b8b03b8c1987367912782bc12988ad8794Dave Airlie 19769f82d23846146990d475f6753be733e55788d88dDaniel Vetter /* overlay on gen2 is broken and can't address above 1G */ 19779f82d23846146990d475f6753be733e55788d88dDaniel Vetter if (IS_GEN2(dev)) 19789f82d23846146990d475f6753be733e55788d88dDaniel Vetter dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); 19799f82d23846146990d475f6753be733e55788d88dDaniel Vetter 19806927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann /* 965GM sometimes incorrectly writes to hardware status page (HWS) 19816927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann * using 32bit addressing, overwriting memory if HWS is located 19826927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann * above 4GB. 19836927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann * 19846927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann * The documentation also mentions an issue with undefined 19856927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann * behaviour if any general state is accessed within a page above 4GB, 19866927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann * which also needs to be handled carefully. 19876927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann */ 19886927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) 19896927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); 19906927faf30920b8c03dfa007e732642a1f1f20089Jan Niehusmann 1991b4ce0f85159f77f208a62930f67b4e548576a5a3Chris Wilson mmio_bar = IS_GEN2(dev) ? 1 : 0; 1992b4ce0f85159f77f208a62930f67b4e548576a5a3Chris Wilson dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0); 1993b4ce0f85159f77f208a62930f67b4e548576a5a3Chris Wilson if (!dev_priv->regs) { 1994b4ce0f85159f77f208a62930f67b4e548576a5a3Chris Wilson DRM_ERROR("failed to map registers\n"); 1995b4ce0f85159f77f208a62930f67b4e548576a5a3Chris Wilson ret = -EIO; 1996b4ce0f85159f77f208a62930f67b4e548576a5a3Chris Wilson goto put_bridge; 1997b4ce0f85159f77f208a62930f67b4e548576a5a3Chris Wilson } 1998b4ce0f85159f77f208a62930f67b4e548576a5a3Chris Wilson 199971e9339c3389de6a685ecb26261a81b8a583aa1cChris Wilson dev_priv->mm.gtt = intel_gtt_get(); 200071e9339c3389de6a685ecb26261a81b8a583aa1cChris Wilson if (!dev_priv->mm.gtt) { 200171e9339c3389de6a685ecb26261a81b8a583aa1cChris Wilson DRM_ERROR("Failed to initialize GTT\n"); 200271e9339c3389de6a685ecb26261a81b8a583aa1cChris Wilson ret = -ENODEV; 2003a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packard goto out_rmmap; 200471e9339c3389de6a685ecb26261a81b8a583aa1cChris Wilson } 200571e9339c3389de6a685ecb26261a81b8a583aa1cChris Wilson 200671e9339c3389de6a685ecb26261a81b8a583aa1cChris Wilson agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; 200771e9339c3389de6a685ecb26261a81b8a583aa1cChris Wilson 20080206e353a0416ad63ce07f53c807c2c725633b87Akshay Joshi dev_priv->mm.gtt_mapping = 200971e9339c3389de6a685ecb26261a81b8a583aa1cChris Wilson io_mapping_create_wc(dev->agp->base, agp_size); 20106644107d57a8fa82b47e4c55da4d9d91a612f29cVenkatesh Pallipadi if (dev_priv->mm.gtt_mapping == NULL) { 20116644107d57a8fa82b47e4c55da4d9d91a612f29cVenkatesh Pallipadi ret = -EIO; 20126644107d57a8fa82b47e4c55da4d9d91a612f29cVenkatesh Pallipadi goto out_rmmap; 20136644107d57a8fa82b47e4c55da4d9d91a612f29cVenkatesh Pallipadi } 20146644107d57a8fa82b47e4c55da4d9d91a612f29cVenkatesh Pallipadi 2015ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt /* Set up a WC MTRR for non-PAT systems. This is more common than 2016ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt * one would think, because the kernel disables PAT on first 2017ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt * generation Core chips because WC PAT gets overridden by a UC 2018ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt * MTRR if present. Even if a UC MTRR isn't present. 2019ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt */ 2020ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base, 202171e9339c3389de6a685ecb26261a81b8a583aa1cChris Wilson agp_size, 2022ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt MTRR_TYPE_WRCOMB, 1); 2023ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt if (dev_priv->mm.gtt_mtrr < 0) { 2024040aefa263aa9cd7bd5df50586c35e1e15e77f84Eric Anholt DRM_INFO("MTRR allocation failed. Graphics " 2025ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt "performance may suffer.\n"); 2026ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt } 202719966754328d99ee003ddfc7a8c31ceb115483acDaniel Vetter 2028e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson /* The i915 workqueue is primarily used for batched retirement of 2029e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson * requests (and thus managing bo) once the task has been completed 2030e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson * by the GPU. i915_gem_retire_requests() is called directly when we 2031e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson * need high-priority retirement, such as waiting for an explicit 2032e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson * bo. 2033e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson * 2034e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson * It is also used for periodic low-priority events, such as 2035df9c2042858e85ab46731c13e708a5b0799db848Eric Anholt * idle-timers and recording error state. 2036e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson * 2037e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson * All tasks on the workqueue are expected to acquire the dev mutex 2038e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson * so there is no point in running more than one instance of the 2039e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson * workqueue at any time: max_active = 1 and NON_REENTRANT. 2040e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson */ 2041e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson dev_priv->wq = alloc_workqueue("i915", 2042e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson WQ_UNBOUND | WQ_NON_REENTRANT, 2043e642abbf303741b245375b2e3f8f00e900d462dcChris Wilson 1); 20449c9fe1f841745184bbc5460c6f3909fded3b929bEric Anholt if (dev_priv->wq == NULL) { 20459c9fe1f841745184bbc5460c6f3909fded3b929bEric Anholt DRM_ERROR("Failed to create our workqueue.\n"); 20469c9fe1f841745184bbc5460c6f3909fded3b929bEric Anholt ret = -ENOMEM; 2047a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packard goto out_mtrrfree; 20489c9fe1f841745184bbc5460c6f3909fded3b929bEric Anholt } 20499c9fe1f841745184bbc5460c6f3909fded3b929bEric Anholt 2050ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie /* enable GEM by default */ 2051ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie dev_priv->has_gem = 1; 2052ac5c4e76180a74c7f922f6fa71ace0cef45fa433Dave Airlie 2053f71d4af4cd475aced6d9ec9730b03885ac80b833Jesse Barnes intel_irq_init(dev); 20549880b7a527ffbb52f65c2de0a8d4eea86e24775eJesse Barnes 2055c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang /* Try to make sure MCHBAR is enabled before poking at it */ 2056c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang intel_setup_mchbar(dev); 2057f899fc64cda8569d0529452aafc0da31c042df2eChris Wilson intel_setup_gmbus(dev); 205844834a67c0082e2cf74b16be91e49108b1432d65Chris Wilson intel_opregion_setup(dev); 2059c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 20606d139a87b747aaebc969ac5f4eb8db766fcd9cbdBryan Freed /* Make sure the bios did its job and set up vital registers */ 20616d139a87b747aaebc969ac5f4eb8db766fcd9cbdBryan Freed intel_setup_bios(dev); 20626d139a87b747aaebc969ac5f4eb8db766fcd9cbdBryan Freed 2063673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt i915_gem_load(dev); 2064673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 2065398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard /* Init HWS */ 2066398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard if (!I915_NEED_GFX_HWS(dev)) { 2067398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard ret = i915_init_phys_hws(dev); 206856e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilson if (ret) 206956e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilson goto out_gem_unload; 2070398c9cb20b5c6c5d1313912b937d653a46fec578Keith Packard } 2071ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt 20727648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes if (IS_PINEVIEW(dev)) 20737648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes i915_pineview_get_mem_freq(dev); 2074f00a3ddf91d596bece5fa31e8ce2e8a3b4c0623bChris Wilson else if (IS_GEN5(dev)) 20757648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes i915_ironlake_get_mem_freq(dev); 20767662c8bd6545c12ac7b2b39e4554c3ba34789c50Shaohua Li 2077ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt /* On the 945G/GM, the chipset reports the MSI capability on the 2078ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt * integrated graphics even though the support isn't actually there 2079ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt * according to the published specs. It doesn't appear to function 2080ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt * correctly in testing on 945G. 2081ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt * This may be a side effect of MSI having been made available for PEG 2082ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt * and the registers being closely associated. 2083d1ed629f44b3a4108d5c445971535f05f441fce7Keith Packard * 2084d1ed629f44b3a4108d5c445971535f05f441fce7Keith Packard * According to chipset errata, on the 965GM, MSI interrupts may 2085b60678a75d44fa9d5969f79781bd856ad5858609Keith Packard * be lost or delayed, but we use them anyways to avoid 2086b60678a75d44fa9d5969f79781bd856ad5858609Keith Packard * stuck interrupts on some machines. 2087ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt */ 2088b60678a75d44fa9d5969f79781bd856ad5858609Keith Packard if (!IS_I945G(dev) && !IS_I945GM(dev)) 2089d3e74d0237b102d34979015fbf6df02ca4413074Eric Anholt pci_enable_msi(dev->pdev); 2090ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt 20919f1f46a45a681d357d1ceedecec3671a5ae957f4Daniel Vetter spin_lock_init(&dev_priv->gt_lock); 20921ec14ad3132702694f2e1a90b30641cf111183b9Chris Wilson spin_lock_init(&dev_priv->irq_lock); 209363eeaf38251183ec2b1caee11e4a2c040cb5ce6cJesse Barnes spin_lock_init(&dev_priv->error_lock); 20944912d04193733a825216b926ffd290fada88ab07Ben Widawsky spin_lock_init(&dev_priv->rps_lock); 2095ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt 209627f8227b1e2b326a9a0995dd9c1f14893c61ee01Jesse Barnes if (IS_IVYBRIDGE(dev)) 209727f8227b1e2b326a9a0995dd9c1f14893c61ee01Jesse Barnes dev_priv->num_pipe = 3; 209827f8227b1e2b326a9a0995dd9c1f14893c61ee01Jesse Barnes else if (IS_MOBILE(dev) || !IS_GEN2(dev)) 20999db4a9c7b2a3bd5b4952846bc0c2f58daa80ddd7Jesse Barnes dev_priv->num_pipe = 2; 21009db4a9c7b2a3bd5b4952846bc0c2f58daa80ddd7Jesse Barnes else 21019db4a9c7b2a3bd5b4952846bc0c2f58daa80ddd7Jesse Barnes dev_priv->num_pipe = 1; 21029db4a9c7b2a3bd5b4952846bc0c2f58daa80ddd7Jesse Barnes 21039db4a9c7b2a3bd5b4952846bc0c2f58daa80ddd7Jesse Barnes ret = drm_vblank_init(dev, dev_priv->num_pipe); 210456e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilson if (ret) 210556e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilson goto out_gem_unload; 210652440211dcdc52c0b757f8b34d122e11b12cdd50Keith Packard 210711ed50ec2a316928c2bacc1149bded86c6a96068Ben Gamari /* Start out suspended */ 210811ed50ec2a316928c2bacc1149bded86c6a96068Ben Gamari dev_priv->mm.suspended = 1; 210911ed50ec2a316928c2bacc1149bded86c6a96068Ben Gamari 21103bad0781832e4e8c9a532f1169bfcd7257bcfd9eZhenyu Wang intel_detect_pch(dev); 21113bad0781832e4e8c9a532f1169bfcd7257bcfd9eZhenyu Wang 211279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes if (drm_core_check_feature(dev, DRIVER_MODESET)) { 211353984635a659e360f206a81ada4ae813152d72f1Daniel Vetter ret = i915_load_modeset_init(dev); 211479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes if (ret < 0) { 211579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes DRM_ERROR("failed to init modeset\n"); 211656e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilson goto out_gem_unload; 211779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes } 211879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes } 211979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 212074a365b3f354fafc537efa5867deb7a9fadbfe27Matthew Garrett /* Must be done after probing outputs */ 212144834a67c0082e2cf74b16be91e49108b1432d65Chris Wilson intel_opregion_init(dev); 212244834a67c0082e2cf74b16be91e49108b1432d65Chris Wilson acpi_video_register(); 212374a365b3f354fafc537efa5867deb7a9fadbfe27Matthew Garrett 2124f65d94211e2bcba17faf05a6a3809af0e4217767Ben Gamari setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, 2125f65d94211e2bcba17faf05a6a3809af0e4217767Ben Gamari (unsigned long) dev); 21267648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 2127e90f3b61f4432e3c5bb6b57f4b3e8d8cba747541Chris Wilson if (IS_GEN5(dev)) { 2128e90f3b61f4432e3c5bb6b57f4b3e8d8cba747541Chris Wilson spin_lock(&mchdev_lock); 2129e90f3b61f4432e3c5bb6b57f4b3e8d8cba747541Chris Wilson i915_mch_dev = dev_priv; 2130e90f3b61f4432e3c5bb6b57f4b3e8d8cba747541Chris Wilson dev_priv->mchdev_lock = &mchdev_lock; 2131e90f3b61f4432e3c5bb6b57f4b3e8d8cba747541Chris Wilson spin_unlock(&mchdev_lock); 21327648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 2133e90f3b61f4432e3c5bb6b57f4b3e8d8cba747541Chris Wilson ips_ping_for_i915_load(); 2134e90f3b61f4432e3c5bb6b57f4b3e8d8cba747541Chris Wilson } 213563ee41d794d9c555f84205517a68509848988760Eric Anholt 213679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes return 0; 213779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 213856e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilsonout_gem_unload: 2139a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packard if (dev_priv->mm.inactive_shrinker.shrink) 2140a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packard unregister_shrinker(&dev_priv->mm.inactive_shrinker); 2141a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packard 214256e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilson if (dev->pdev->msi_enabled) 214356e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilson pci_disable_msi(dev->pdev); 214456e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilson 214556e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilson intel_teardown_gmbus(dev); 214656e2ea346ab4c2ea159ecdec85fffc24f50c2903Chris Wilson intel_teardown_mchbar(dev); 21479c9fe1f841745184bbc5460c6f3909fded3b929bEric Anholt destroy_workqueue(dev_priv->wq); 2148a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packardout_mtrrfree: 2149a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packard if (dev_priv->mm.gtt_mtrr >= 0) { 2150a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packard mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, 2151a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packard dev->agp->agp_info.aper_size * 1024 * 1024); 2152a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packard dev_priv->mm.gtt_mtrr = -1; 2153a7b85d2aa63ed09cd5a4a640772b3272f5ac7caaKeith Packard } 21546644107d57a8fa82b47e4c55da4d9d91a612f29cVenkatesh Pallipadi io_mapping_free(dev_priv->mm.gtt_mapping); 215579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnesout_rmmap: 21566dda569fe0fb71a03e2a2e815761796f98232cdbChris Wilson pci_iounmap(dev->pdev, dev_priv->regs); 2157ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlieput_bridge: 2158ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie pci_dev_put(dev_priv->bridge_dev); 215979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnesfree_priv: 21609a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(dev_priv); 2161ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes return ret; 2162ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes} 2163ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 2164ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnesint i915_driver_unload(struct drm_device *dev) 2165ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes{ 2166ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes struct drm_i915_private *dev_priv = dev->dev_private; 2167c911fc1c6ad61b56869ee521f1a477c741b039daDaniel Vetter int ret; 2168ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 21697648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes spin_lock(&mchdev_lock); 21707648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes i915_mch_dev = NULL; 21717648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes spin_unlock(&mchdev_lock); 21727648fa99eb77a2e1a90b7beaa420e07d819b9c11Jesse Barnes 217317250b71553680bc6e927497aa619ab06ab1015bChris Wilson if (dev_priv->mm.inactive_shrinker.shrink) 217417250b71553680bc6e927497aa619ab06ab1015bChris Wilson unregister_shrinker(&dev_priv->mm.inactive_shrinker); 217517250b71553680bc6e927497aa619ab06ab1015bChris Wilson 2176c911fc1c6ad61b56869ee521f1a477c741b039daDaniel Vetter mutex_lock(&dev->struct_mutex); 2177b93f9cf14e714c20ce9a544ed1a6070ee7604588Ben Widawsky ret = i915_gpu_idle(dev, true); 2178c911fc1c6ad61b56869ee521f1a477c741b039daDaniel Vetter if (ret) 2179c911fc1c6ad61b56869ee521f1a477c741b039daDaniel Vetter DRM_ERROR("failed to idle hardware: %d\n", ret); 2180c911fc1c6ad61b56869ee521f1a477c741b039daDaniel Vetter mutex_unlock(&dev->struct_mutex); 2181c911fc1c6ad61b56869ee521f1a477c741b039daDaniel Vetter 218275ef9da2cdb64e7926404dd2b755bbbfe98eaeafDaniel Vetter /* Cancel the retire work handler, which should be idle now. */ 218375ef9da2cdb64e7926404dd2b755bbbfe98eaeafDaniel Vetter cancel_delayed_work_sync(&dev_priv->mm.retire_work); 218475ef9da2cdb64e7926404dd2b755bbbfe98eaeafDaniel Vetter 2185ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt io_mapping_free(dev_priv->mm.gtt_mapping); 2186ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt if (dev_priv->mm.gtt_mtrr >= 0) { 2187ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, 2188ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt dev->agp->agp_info.aper_size * 1024 * 1024); 2189ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt dev_priv->mm.gtt_mtrr = -1; 2190ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt } 2191ab657db12d7020629f26f30d287558a8d0e32b41Eric Anholt 219244834a67c0082e2cf74b16be91e49108b1432d65Chris Wilson acpi_video_unregister(); 219344834a67c0082e2cf74b16be91e49108b1432d65Chris Wilson 219479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes if (drm_core_check_feature(dev, DRIVER_MODESET)) { 21957b4f3990a22fbe800945f12001bc30db374d0af5Chris Wilson intel_fbdev_fini(dev); 21963d8620cc5f8538364ee152811e2bd8713abb1d58Jesse Barnes intel_modeset_cleanup(dev); 21973d8620cc5f8538364ee152811e2bd8713abb1d58Jesse Barnes 21986363ee6f496eb7e3b3f78dc105e522c7b496089bZhao Yakui /* 21996363ee6f496eb7e3b3f78dc105e522c7b496089bZhao Yakui * free the memory space allocated for the child device 22006363ee6f496eb7e3b3f78dc105e522c7b496089bZhao Yakui * config parsed from VBT 22016363ee6f496eb7e3b3f78dc105e522c7b496089bZhao Yakui */ 22026363ee6f496eb7e3b3f78dc105e522c7b496089bZhao Yakui if (dev_priv->child_dev && dev_priv->child_dev_num) { 22036363ee6f496eb7e3b3f78dc105e522c7b496089bZhao Yakui kfree(dev_priv->child_dev); 22046363ee6f496eb7e3b3f78dc105e522c7b496089bZhao Yakui dev_priv->child_dev = NULL; 22056363ee6f496eb7e3b3f78dc105e522c7b496089bZhao Yakui dev_priv->child_dev_num = 0; 22066363ee6f496eb7e3b3f78dc105e522c7b496089bZhao Yakui } 22076c0d93500eb50098e4e35b8b79e073f2f2f5b773Daniel Vetter 22086a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie vga_switcheroo_unregister_client(dev->pdev); 220928d520433b6375740990ab99d69b0d0067fd656bDave Airlie vga_client_register(dev->pdev, NULL, NULL, NULL); 221079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes } 221179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 2212a8b4899e4658e53c0c8f4206af105e358e39ee93Daniel Vetter /* Free error state after interrupts are fully disabled. */ 2213bc0c7f14432f7f94b16f972f2d23b8c1248249b4Daniel Vetter del_timer_sync(&dev_priv->hangcheck_timer); 2214bc0c7f14432f7f94b16f972f2d23b8c1248249b4Daniel Vetter cancel_work_sync(&dev_priv->error_work); 2215a8b4899e4658e53c0c8f4206af105e358e39ee93Daniel Vetter i915_destroy_error_state(dev); 2216bc0c7f14432f7f94b16f972f2d23b8c1248249b4Daniel Vetter 2217ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt if (dev->pdev->msi_enabled) 2218ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt pci_disable_msi(dev->pdev); 2219ed4cb4142b242d8090d3811d5eb4abf6aa985bc8Eric Anholt 222044834a67c0082e2cf74b16be91e49108b1432d65Chris Wilson intel_opregion_fini(dev); 22218ee1c3db9075cb3211352e737e0feb98fd733b20Matthew Garrett 222279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes if (drm_core_check_feature(dev, DRIVER_MODESET)) { 222367e77c5ae8bff6f805d207541f1315051248a87bDaniel Vetter /* Flush any outstanding unpin_work. */ 222467e77c5ae8bff6f805d207541f1315051248a87bDaniel Vetter flush_workqueue(dev_priv->wq); 222567e77c5ae8bff6f805d207541f1315051248a87bDaniel Vetter 222679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes mutex_lock(&dev->struct_mutex); 2227ecbec53b1d00ba582f71b210ed96cafc05ebd189Hugh Dickins i915_gem_free_all_phys_object(dev); 222879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes i915_gem_cleanup_ringbuffer(dev); 222979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes mutex_unlock(&dev->struct_mutex); 22301d2a314c97ceaf383de8e23cdde46729927d433cDaniel Vetter i915_gem_cleanup_aliasing_ppgtt(dev); 223120bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes if (I915_HAS_FBC(dev) && i915_powersave) 223220bf377e679208ba9ae0edcb8c70a8f6d33d17f9Jesse Barnes i915_cleanup_compression(dev); 2233fe669bf88e9108b96a847385df08c9b1e98c1420Chris Wilson drm_mm_takedown(&dev_priv->mm.stolen); 223402e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter 223502e792fbaadb75dec8e476a05b610e49908fc6a4Daniel Vetter intel_cleanup_overlay(dev); 2236c2873e9633fe908dccd36dbb1d370e9c59a1ca62Keith Packard 2237c2873e9633fe908dccd36dbb1d370e9c59a1ca62Keith Packard if (!I915_NEED_GFX_HWS(dev)) 2238c2873e9633fe908dccd36dbb1d370e9c59a1ca62Keith Packard i915_free_hws(dev); 223979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes } 224079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes 2241701394cc534a4a7883ddc4f8f82fb438b3d664ffDaniel Vetter if (dev_priv->regs != NULL) 22426dda569fe0fb71a03e2a2e815761796f98232cdbChris Wilson pci_iounmap(dev->pdev, dev_priv->regs); 2243701394cc534a4a7883ddc4f8f82fb438b3d664ffDaniel Vetter 2244f899fc64cda8569d0529452aafc0da31c042df2eChris Wilson intel_teardown_gmbus(dev); 2245c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang intel_teardown_mchbar(dev); 2246c4804411691bdd7d8a57e942cbb502fd52a90074Zhenyu Wang 2247bc0c7f14432f7f94b16f972f2d23b8c1248249b4Daniel Vetter destroy_workqueue(dev_priv->wq); 2248bc0c7f14432f7f94b16f972f2d23b8c1248249b4Daniel Vetter 2249ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372Dave Airlie pci_dev_put(dev_priv->bridge_dev); 22509a298b2acd771d8a5c0004d8f8e4156c65b11f6bEric Anholt kfree(dev->dev_private); 2251ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 225222eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie return 0; 225322eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie} 225422eae947bf76e236ba972f2f11cfd1b083b736adDave Airlie 2255f787a5f59e1b0e320a6b0a37e9a2e306551d1e40Chris Wilsonint i915_driver_open(struct drm_device *dev, struct drm_file *file) 2256673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt{ 2257f787a5f59e1b0e320a6b0a37e9a2e306551d1e40Chris Wilson struct drm_i915_file_private *file_priv; 2258673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 22598a4c47f346cc7a12d0897c05eb3cc1add26b487fZhao Yakui DRM_DEBUG_DRIVER("\n"); 2260f787a5f59e1b0e320a6b0a37e9a2e306551d1e40Chris Wilson file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL); 2261f787a5f59e1b0e320a6b0a37e9a2e306551d1e40Chris Wilson if (!file_priv) 2262673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt return -ENOMEM; 2263673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 2264f787a5f59e1b0e320a6b0a37e9a2e306551d1e40Chris Wilson file->driver_priv = file_priv; 2265673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 22661c25595f8d31392b8c36b54c624d01591dbfb87bChris Wilson spin_lock_init(&file_priv->mm.lock); 2267f787a5f59e1b0e320a6b0a37e9a2e306551d1e40Chris Wilson INIT_LIST_HEAD(&file_priv->mm.request_list); 2268673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 2269673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt return 0; 2270673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt} 2271673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 227279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes/** 227379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * i915_driver_lastclose - clean up after all DRM clients have exited 227479e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * @dev: DRM device 227579e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * 227679e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * Take care of cleaning up after all DRM clients have exited. In the 227779e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * mode setting case, we want to restore the kernel's initial mode (just 227879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * in case the last client left us in a bad state). 227979e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * 228079e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * Additionally, in the non-mode setting case, we'll tear down the AGP 228179e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * and DMA structures, since the kernel won't be using them, and clea 228279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes * up any GEM state. 228379e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes */ 228484b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlievoid i915_driver_lastclose(struct drm_device * dev) 22851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2286ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes drm_i915_private_t *dev_priv = dev->dev_private; 2287ba8bbcf6ff4650712f64c0ef61139c73898e2165Jesse Barnes 228879e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { 2289e8e7a2b8ccfdae0d4cb6bd25824bbedcd42da316Dave Airlie intel_fb_restore_mode(dev); 22906a9ee8af344e3bd7dbd61e67037096cdf7f83289Dave Airlie vga_switcheroo_process_delayed_switch(); 2291144a75fa1faa4a81530bded2e59872ef80d496b6Dave Airlie return; 229279e539453b34e35f39299a899d263b0a1f1670bdJesse Barnes } 2293144a75fa1faa4a81530bded2e59872ef80d496b6Dave Airlie 2294673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt i915_gem_lastclose(dev); 2295673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 2296b5e89ed53ed8d24f83ba1941c07382af00ed238eDave Airlie i915_dma_cleanup(dev); 22971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 22981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22996c340eac0285f3d62406d2d902d0e96fbf2a5dc0Eric Anholtvoid i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) 23001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2301b962442e46a9340bdbc6711982c59ff0cc2b5afbEric Anholt i915_gem_release(dev, file_priv); 23021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2304f787a5f59e1b0e320a6b0a37e9a2e306551d1e40Chris Wilsonvoid i915_driver_postclose(struct drm_device *dev, struct drm_file *file) 2305673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt{ 2306f787a5f59e1b0e320a6b0a37e9a2e306551d1e40Chris Wilson struct drm_i915_file_private *file_priv = file->driver_priv; 2307673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 2308f787a5f59e1b0e320a6b0a37e9a2e306551d1e40Chris Wilson kfree(file_priv); 2309673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt} 2310673a394b1e3b69be886ff24abfd6df97c52e8d08Eric Anholt 2311c153f45f9b7e30289157bba3ff5682291df16caaEric Anholtstruct drm_ioctl_desc i915_ioctls[] = { 23121b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 23131b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_FLUSH, i915_flush_ioctl, DRM_AUTH), 23141b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_FLIP, i915_flip_bufs, DRM_AUTH), 23151b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), 23161b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), 23171b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), 23181b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), 23191b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 2320b2c606fe1defd1fb79612b48b528b2568c97def7Daniel Vetter DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH), 2321b2c606fe1defd1fb79612b48b528b2568c97def7Daniel Vetter DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH), 2322b2c606fe1defd1fb79612b48b528b2568c97def7Daniel Vetter DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 23231b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), 2324b2c606fe1defd1fb79612b48b528b2568c97def7Daniel Vetter DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 23251b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 23261b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), 23271b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), 23281b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 23291b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), 23301b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), 23311b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), 23321b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), 23331b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), 23341b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), 23351b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), 23361b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), 23371b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), 23381b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), 23391b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), 23401b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), 23411b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), 23421b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), 23431b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), 23441b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), 23451b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), 23461b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), 23471b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), 23481b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), 23491b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), 23501b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 23511b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 23528ea30864229e54b01ac0e9fe88c4b733a940ec4eJesse Barnes DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 23538ea30864229e54b01ac0e9fe88c4b733a940ec4eJesse Barnes DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, intel_sprite_get_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), 2354c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie}; 2355c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlie 2356c94f70298529d99ac6e1ee7709f61eab00adeb39Dave Airlieint i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); 2357cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie 2358cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie/** 2359cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * Determine if the device really is AGP or not. 2360cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * 2361cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * All Intel graphics chipsets are treated as AGP, even if they are really 2362cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * PCI-e. 2363cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * 2364cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * \param dev The device to be tested. 2365cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * 2366cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * \returns 2367cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie * A value of 1 is always retured to indictate every i9x5 is AGP. 2368cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie */ 236984b1fd103dbbe01b5905db1444d3fc8afa9a7207Dave Airlieint i915_driver_device_is_agp(struct drm_device * dev) 2370cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie{ 2371cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie return 1; 2372cda173806644d2af22ffd9896eed8ef99b97d356Dave Airlie} 2373