[Intel-gfx] [PATCH 09/11] drm/i915: Merge i915_dma.c into i915_drv.c

Joonas Lahtinen joonas.lahtinen at linux.intel.com
Mon May 30 06:30:12 UTC 2016


On pe, 2016-05-27 at 15:00 +0100, Chris Wilson wrote:
> i915_dma.c used to contain the DRI1/UMS horror show, but now all that
> remains are the out-of-place driver level interfaces (such as
> allocating, initialising and registering the driver). These should be in
> i915_drv.c alongside similar routines for suspend/resume.
> 
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

Assuming this was NOP change,

Reviewed-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>

> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> ---
>  drivers/gpu/drm/i915/Makefile   |    3 -
>  drivers/gpu/drm/i915/i915_dma.c | 1680 --------------------------------
>  drivers/gpu/drm/i915/i915_drv.c | 2014 +++++++++++++++++++++++++++++++++++----
>  drivers/gpu/drm/i915/i915_drv.h |   16 +-
>  4 files changed, 1825 insertions(+), 1888 deletions(-)
>  delete mode 100644 drivers/gpu/drm/i915/i915_dma.c
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 7e2944406b8f..2ea7c245923e 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -101,9 +101,6 @@ i915-y += dvo_ch7017.o \
>  # virtual gpu code
>  i915-y += i915_vgpu.o
>  
> -# legacy horrors
> -i915-y += i915_dma.o
> -
>  obj-$(CONFIG_DRM_I915)  += i915.o
>  
>  CFLAGS_i915_trace_points.o := -I$(src)
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> deleted file mode 100644
> index 0ec785d4505e..000000000000
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ /dev/null
> @@ -1,1680 +0,0 @@
> -/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
> - */
> -/*
> - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
> - * All Rights Reserved.
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a
> - * copy of this software and associated documentation files (the
> - * "Software"), to deal in the Software without restriction, including
> - * without limitation the rights to use, copy, modify, merge, publish,
> - * distribute, sub license, and/or sell copies of the Software, and to
> - * permit persons to whom the Software is furnished to do so, subject to
> - * the following conditions:
> - *
> - * The above copyright notice and this permission notice (including the
> - * next paragraph) shall be included in all copies or substantial portions
> - * of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
> - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
> - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
> - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> - *
> - */
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> -
> -#include 
> -#include 
> -#include 
> -#include 
> -#include "intel_drv.h"
> -#include 
> -#include "i915_drv.h"
> -#include "i915_vgpu.h"
> -#include "i915_trace.h"
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -#include 
> -
> -static unsigned int i915_load_fail_count;
> -
> -bool __i915_inject_load_failure(const char *func, int line)
> -{
> -	if (i915_load_fail_count >= i915.inject_load_failure)
> -		return false;
> -
> -	if (++i915_load_fail_count == i915.inject_load_failure) {
> -		DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n",
> -			 i915.inject_load_failure, func, line);
> -		return true;
> -	}
> -
> -	return false;
> -}
> -
> -#define FDO_BUG_URL "https://bugs.freedesktop.org/enter_bug.cgi?product=DRI"
> -#define FDO_BUG_MSG "Please file a bug at " FDO_BUG_URL " against DRM/Intel " \
> -		    "providing the dmesg log by booting with drm.debug=0xf"
> -
> -void
> -__i915_printk(struct drm_i915_private *dev_priv, const char *level,
> -	      const char *fmt, ...)
> -{
> -	static bool shown_bug_once;
> -	struct device *dev = dev_priv->dev->dev;
> -	bool is_error = level[1] <= KERN_ERR[1];
> -	bool is_debug = level[1] == KERN_DEBUG[1];
> -	struct va_format vaf;
> -	va_list args;
> -
> -	if (is_debug && !(drm_debug & DRM_UT_DRIVER))
> -		return;
> -
> -	va_start(args, fmt);
> -
> -	vaf.fmt = fmt;
> -	vaf.va = &args;
> -
> -	dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV",
> -		   __builtin_return_address(0), &vaf);
> -
> -	if (is_error && !shown_bug_once) {
> -		dev_notice(dev, "%s", FDO_BUG_MSG);
> -		shown_bug_once = true;
> -	}
> -
> -	va_end(args);
> -}
> -
> -static bool i915_error_injected(struct drm_i915_private *dev_priv)
> -{
> -	return i915.inject_load_failure &&
> -	       i915_load_fail_count == i915.inject_load_failure;
> -}
> -
> -#define i915_load_error(dev_priv, fmt, ...)				     \
> -	__i915_printk(dev_priv,						     \
> -		      i915_error_injected(dev_priv) ? KERN_DEBUG : KERN_ERR, \
> -		      fmt, ##__VA_ARGS__)
> -
> -static int i915_getparam(struct drm_device *dev, void *data,
> -			 struct drm_file *file_priv)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	drm_i915_getparam_t *param = data;
> -	int value;
> -
> -	switch (param->param) {
> -	case I915_PARAM_IRQ_ACTIVE:
> -	case I915_PARAM_ALLOW_BATCHBUFFER:
> -	case I915_PARAM_LAST_DISPATCH:
> -		/* Reject all old ums/dri params. */
> -		return -ENODEV;
> -	case I915_PARAM_CHIPSET_ID:
> -		value = dev->pdev->device;
> -		break;
> -	case I915_PARAM_REVISION:
> -		value = dev->pdev->revision;
> -		break;
> -	case I915_PARAM_HAS_GEM:
> -		value = 1;
> -		break;
> -	case I915_PARAM_NUM_FENCES_AVAIL:
> -		value = dev_priv->num_fence_regs;
> -		break;
> -	case I915_PARAM_HAS_OVERLAY:
> -		value = dev_priv->overlay ? 1 : 0;
> -		break;
> -	case I915_PARAM_HAS_PAGEFLIPPING:
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_EXECBUF2:
> -		/* depends on GEM */
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_BSD:
> -		value = intel_engine_initialized(&dev_priv->engine[VCS]);
> -		break;
> -	case I915_PARAM_HAS_BLT:
> -		value = intel_engine_initialized(&dev_priv->engine[BCS]);
> -		break;
> -	case I915_PARAM_HAS_VEBOX:
> -		value = intel_engine_initialized(&dev_priv->engine[VECS]);
> -		break;
> -	case I915_PARAM_HAS_BSD2:
> -		value = intel_engine_initialized(&dev_priv->engine[VCS2]);
> -		break;
> -	case I915_PARAM_HAS_RELAXED_FENCING:
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_COHERENT_RINGS:
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_EXEC_CONSTANTS:
> -		value = INTEL_INFO(dev)->gen >= 4;
> -		break;
> -	case I915_PARAM_HAS_RELAXED_DELTA:
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_GEN7_SOL_RESET:
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_LLC:
> -		value = HAS_LLC(dev);
> -		break;
> -	case I915_PARAM_HAS_WT:
> -		value = HAS_WT(dev);
> -		break;
> -	case I915_PARAM_HAS_ALIASING_PPGTT:
> -		value = USES_PPGTT(dev);
> -		break;
> -	case I915_PARAM_HAS_WAIT_TIMEOUT:
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_SEMAPHORES:
> -		value = i915_semaphore_is_enabled(dev_priv);
> -		break;
> -	case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_SECURE_BATCHES:
> -		value = capable(CAP_SYS_ADMIN);
> -		break;
> -	case I915_PARAM_HAS_PINNED_BATCHES:
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_EXEC_NO_RELOC:
> -		value = 1;
> -		break;
> -	case I915_PARAM_HAS_EXEC_HANDLE_LUT:
> -		value = 1;
> -		break;
> -	case I915_PARAM_CMD_PARSER_VERSION:
> -		value = i915_cmd_parser_get_version(dev_priv);
> -		break;
> -	case I915_PARAM_HAS_COHERENT_PHYS_GTT:
> -		value = 1;
> -		break;
> -	case I915_PARAM_MMAP_VERSION:
> -		value = 1;
> -		break;
> -	case I915_PARAM_SUBSLICE_TOTAL:
> -		value = INTEL_INFO(dev)->subslice_total;
> -		if (!value)
> -			return -ENODEV;
> -		break;
> -	case I915_PARAM_EU_TOTAL:
> -		value = INTEL_INFO(dev)->eu_total;
> -		if (!value)
> -			return -ENODEV;
> -		break;
> -	case I915_PARAM_HAS_GPU_RESET:
> -		value = i915.enable_hangcheck && intel_has_gpu_reset(dev_priv);
> -		break;
> -	case I915_PARAM_HAS_RESOURCE_STREAMER:
> -		value = HAS_RESOURCE_STREAMER(dev);
> -		break;
> -	case I915_PARAM_HAS_EXEC_SOFTPIN:
> -		value = 1;
> -		break;
> -	default:
> -		DRM_DEBUG("Unknown parameter %d\n", param->param);
> -		return -EINVAL;
> -	}
> -
> -	if (copy_to_user(param->value, &value, sizeof(int))) {
> -		DRM_ERROR("copy_to_user failed\n");
> -		return -EFAULT;
> -	}
> -
> -	return 0;
> -}
> -
> -static int i915_get_bridge_dev(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -
> -	dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
> -	if (!dev_priv->bridge_dev) {
> -		DRM_ERROR("bridge device not found\n");
> -		return -1;
> -	}
> -	return 0;
> -}
> -
> -/* Allocate space for the MCH regs if needed, return nonzero on error */
> -static int
> -intel_alloc_mchbar_resource(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	int reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
> -	u32 temp_lo, temp_hi = 0;
> -	u64 mchbar_addr;
> -	int ret;
> -
> -	if (INTEL_INFO(dev)->gen >= 4)
> -		pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
> -	pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
> -	mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
> -
> -	/* If ACPI doesn't have it, assume we need to allocate it ourselves */
> -#ifdef CONFIG_PNP
> -	if (mchbar_addr &&
> -	    pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE))
> -		return 0;
> -#endif
> -
> -	/* Get some space for it */
> -	dev_priv->mch_res.name = "i915 MCHBAR";
> -	dev_priv->mch_res.flags = IORESOURCE_MEM;
> -	ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus,
> -				     &dev_priv->mch_res,
> -				     MCHBAR_SIZE, MCHBAR_SIZE,
> -				     PCIBIOS_MIN_MEM,
> -				     0, pcibios_align_resource,
> -				     dev_priv->bridge_dev);
> -	if (ret) {
> -		DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
> -		dev_priv->mch_res.start = 0;
> -		return ret;
> -	}
> -
> -	if (INTEL_INFO(dev)->gen >= 4)
> -		pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
> -				       upper_32_bits(dev_priv->mch_res.start));
> -
> -	pci_write_config_dword(dev_priv->bridge_dev, reg,
> -			       lower_32_bits(dev_priv->mch_res.start));
> -	return 0;
> -}
> -
> -/* Setup MCHBAR if possible, return true if we should disable it again */
> -static void
> -intel_setup_mchbar(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
> -	u32 temp;
> -	bool enabled;
> -
> -	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
> -		return;
> -
> -	dev_priv->mchbar_need_disable = false;
> -
> -	if (IS_I915G(dev) || IS_I915GM(dev)) {
> -		pci_read_config_dword(dev_priv->bridge_dev, DEVEN, &temp);
> -		enabled = !!(temp & DEVEN_MCHBAR_EN);
> -	} else {
> -		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
> -		enabled = temp & 1;
> -	}
> -
> -	/* If it's already enabled, don't have to do anything */
> -	if (enabled)
> -		return;
> -
> -	if (intel_alloc_mchbar_resource(dev))
> -		return;
> -
> -	dev_priv->mchbar_need_disable = true;
> -
> -	/* Space is allocated or reserved, so enable it. */
> -	if (IS_I915G(dev) || IS_I915GM(dev)) {
> -		pci_write_config_dword(dev_priv->bridge_dev, DEVEN,
> -				       temp | DEVEN_MCHBAR_EN);
> -	} else {
> -		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
> -		pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
> -	}
> -}
> -
> -static void
> -intel_teardown_mchbar(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
> -
> -	if (dev_priv->mchbar_need_disable) {
> -		if (IS_I915G(dev) || IS_I915GM(dev)) {
> -			u32 deven_val;
> -
> -			pci_read_config_dword(dev_priv->bridge_dev, DEVEN,
> -					      &deven_val);
> -			deven_val &= ~DEVEN_MCHBAR_EN;
> -			pci_write_config_dword(dev_priv->bridge_dev, DEVEN,
> -					       deven_val);
> -		} else {
> -			u32 mchbar_val;
> -
> -			pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg,
> -					      &mchbar_val);
> -			mchbar_val &= ~1;
> -			pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg,
> -					       mchbar_val);
> -		}
> -	}
> -
> -	if (dev_priv->mch_res.start)
> -		release_resource(&dev_priv->mch_res);
> -}
> -
> -/* true = enable decode, false = disable decoder */
> -static unsigned int i915_vga_set_decode(void *cookie, bool state)
> -{
> -	struct drm_device *dev = cookie;
> -
> -	intel_modeset_vga_set_state(dev, state);
> -	if (state)
> -		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
> -		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
> -	else
> -		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
> -}
> -
> -static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
> -{
> -	struct drm_device *dev = pci_get_drvdata(pdev);
> -	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
> -
> -	if (state == VGA_SWITCHEROO_ON) {
> -		pr_info("switched on\n");
> -		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
> -		/* i915 resume handler doesn't set to D0 */
> -		pci_set_power_state(dev->pdev, PCI_D0);
> -		i915_resume_switcheroo(dev);
> -		dev->switch_power_state = DRM_SWITCH_POWER_ON;
> -	} else {
> -		pr_info("switched off\n");
> -		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
> -		i915_suspend_switcheroo(dev, pmm);
> -		dev->switch_power_state = DRM_SWITCH_POWER_OFF;
> -	}
> -}
> -
> -static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
> -{
> -	struct drm_device *dev = pci_get_drvdata(pdev);
> -
> -	/*
> -	 * FIXME: open_count is protected by drm_global_mutex but that would lead to
> -	 * locking inversion with the driver load path. And the access here is
> -	 * completely racy anyway. So don't bother with locking for now.
> -	 */
> -	return dev->open_count == 0;
> -}
> -
> -static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
> -	.set_gpu_state = i915_switcheroo_set_state,
> -	.reprobe = NULL,
> -	.can_switch = i915_switcheroo_can_switch,
> -};
> -
> -static void i915_gem_fini(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -
> -	/*
> -	 * Neither the BIOS, ourselves or any other kernel
> -	 * expects the system to be in execlists mode on startup,
> -	 * so we need to reset the GPU back to legacy mode. And the only
> -	 * known way to disable logical contexts is through a GPU reset.
> -	 *
> -	 * So in order to leave the system in a known default configuration,
> -	 * always reset the GPU upon unload. Afterwards we then clean up the
> -	 * GEM state tracking, flushing off the requests and leaving the
> -	 * system in a known idle state.
> -	 *
> -	 * Note that is of the upmost importance that the GPU is idle and
> -	 * all stray writes are flushed *before* we dismantle the backing
> -	 * storage for the pinned objects.
> -	 *
> -	 * However, since we are uncertain that reseting the GPU on older
> -	 * machines is a good idea, we don't - just in case it leaves the
> -	 * machine in an unusable condition.
> -	 */
> -	if (HAS_HW_CONTEXTS(dev)) {
> -		int reset = intel_gpu_reset(dev_priv, ALL_ENGINES);
> -		WARN_ON(reset && reset != -ENODEV);
> -	}
> -
> -	mutex_lock(&dev->struct_mutex);
> -	i915_gem_reset(dev);
> -	i915_gem_cleanup_engines(dev);
> -	i915_gem_context_fini(dev);
> -	mutex_unlock(&dev->struct_mutex);
> -
> -	WARN_ON(!list_empty(&to_i915(dev)->context_list));
> -}
> -
> -static int i915_load_modeset_init(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	int ret;
> -
> -	if (i915_inject_load_failure())
> -		return -ENODEV;
> -
> -	ret = intel_bios_init(dev_priv);
> -	if (ret)
> -		DRM_INFO("failed to find VBIOS tables\n");
> -
> -	/* If we have > 1 VGA cards, then we need to arbitrate access
> -	 * to the common VGA resources.
> -	 *
> -	 * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA),
> -	 * then we do not take part in VGA arbitration and the
> -	 * vga_client_register() fails with -ENODEV.
> -	 */
> -	ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
> -	if (ret && ret != -ENODEV)
> -		goto out;
> -
> -	intel_register_dsm_handler();
> -
> -	ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops, false);
> -	if (ret)
> -		goto cleanup_vga_client;
> -
> -	/* must happen before intel_power_domains_init_hw() on VLV/CHV */
> -	intel_update_rawclk(dev_priv);
> -
> -	intel_power_domains_init_hw(dev_priv, false);
> -
> -	intel_csr_ucode_init(dev_priv);
> -
> -	ret = intel_irq_install(dev_priv);
> -	if (ret)
> -		goto cleanup_csr;
> -
> -	intel_setup_gmbus(dev);
> -
> -	/* Important: The output setup functions called by modeset_init need
> -	 * working irqs for e.g. gmbus and dp aux transfers. */
> -	intel_modeset_init(dev);
> -
> -	intel_guc_init(dev);
> -
> -	ret = i915_gem_init(dev);
> -	if (ret)
> -		goto cleanup_irq;
> -
> -	intel_modeset_gem_init(dev);
> -
> -	if (INTEL_INFO(dev)->num_pipes == 0)
> -		return 0;
> -
> -	ret = intel_fbdev_init(dev);
> -	if (ret)
> -		goto cleanup_gem;
> -
> -	/* Only enable hotplug handling once the fbdev is fully set up. */
> -	intel_hpd_init(dev_priv);
> -
> -	drm_kms_helper_poll_init(dev);
> -
> -	return 0;
> -
> -cleanup_gem:
> -	i915_gem_fini(dev);
> -cleanup_irq:
> -	intel_guc_fini(dev);
> -	drm_irq_uninstall(dev);
> -	intel_teardown_gmbus(dev);
> -cleanup_csr:
> -	intel_csr_ucode_fini(dev_priv);
> -	intel_power_domains_fini(dev_priv);
> -	vga_switcheroo_unregister_client(dev->pdev);
> -cleanup_vga_client:
> -	vga_client_register(dev->pdev, NULL, NULL, NULL);
> -out:
> -	return ret;
> -}
> -
> -#if IS_ENABLED(CONFIG_FB)
> -static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
> -{
> -	struct apertures_struct *ap;
> -	struct pci_dev *pdev = dev_priv->dev->pdev;
> -	struct i915_ggtt *ggtt = &dev_priv->ggtt;
> -	bool primary;
> -	int ret;
> -
> -	ap = alloc_apertures(1);
> -	if (!ap)
> -		return -ENOMEM;
> -
> -	ap->ranges[0].base = ggtt->mappable_base;
> -	ap->ranges[0].size = ggtt->mappable_end;
> -
> -	primary =
> -		pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
> -
> -	ret = remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
> -
> -	kfree(ap);
> -
> -	return ret;
> -}
> -#else
> -static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
> -{
> -	return 0;
> -}
> -#endif
> -
> -#if !defined(CONFIG_VGA_CONSOLE)
> -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
> -{
> -	return 0;
> -}
> -#elif !defined(CONFIG_DUMMY_CONSOLE)
> -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
> -{
> -	return -ENODEV;
> -}
> -#else
> -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
> -{
> -	int ret = 0;
> -
> -	DRM_INFO("Replacing VGA console driver\n");
> -
> -	console_lock();
> -	if (con_is_bound(&vga_con))
> -		ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
> -	if (ret == 0) {
> -		ret = do_unregister_con_driver(&vga_con);
> -
> -		/* Ignore "already unregistered". */
> -		if (ret == -ENODEV)
> -			ret = 0;
> -	}
> -	console_unlock();
> -
> -	return ret;
> -}
> -#endif
> -
> -static void i915_dump_device_info(struct drm_i915_private *dev_priv)
> -{
> -	const struct intel_device_info *info = &dev_priv->info;
> -
> -#define PRINT_S(name) "%s"
> -#define SEP_EMPTY
> -#define PRINT_FLAG(name) info->name ? #name "," : ""
> -#define SEP_COMMA ,
> -	DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x rev=0x%02x flags="
> -			 DEV_INFO_FOR_EACH_FLAG(PRINT_S, SEP_EMPTY),
> -			 info->gen,
> -			 dev_priv->dev->pdev->device,
> -			 dev_priv->dev->pdev->revision,
> -			 DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA));
> -#undef PRINT_S
> -#undef SEP_EMPTY
> -#undef PRINT_FLAG
> -#undef SEP_COMMA
> -}
> -
> -static void cherryview_sseu_info_init(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_device_info *info;
> -	u32 fuse, eu_dis;
> -
> -	info = (struct intel_device_info *)&dev_priv->info;
> -	fuse = I915_READ(CHV_FUSE_GT);
> -
> -	info->slice_total = 1;
> -
> -	if (!(fuse & CHV_FGT_DISABLE_SS0)) {
> -		info->subslice_per_slice++;
> -		eu_dis = fuse & (CHV_FGT_EU_DIS_SS0_R0_MASK |
> -				 CHV_FGT_EU_DIS_SS0_R1_MASK);
> -		info->eu_total += 8 - hweight32(eu_dis);
> -	}
> -
> -	if (!(fuse & CHV_FGT_DISABLE_SS1)) {
> -		info->subslice_per_slice++;
> -		eu_dis = fuse & (CHV_FGT_EU_DIS_SS1_R0_MASK |
> -				 CHV_FGT_EU_DIS_SS1_R1_MASK);
> -		info->eu_total += 8 - hweight32(eu_dis);
> -	}
> -
> -	info->subslice_total = info->subslice_per_slice;
> -	/*
> -	 * CHV expected to always have a uniform distribution of EU
> -	 * across subslices.
> -	*/
> -	info->eu_per_subslice = info->subslice_total ?
> -				info->eu_total / info->subslice_total :
> -				0;
> -	/*
> -	 * CHV supports subslice power gating on devices with more than
> -	 * one subslice, and supports EU power gating on devices with
> -	 * more than one EU pair per subslice.
> -	*/
> -	info->has_slice_pg = 0;
> -	info->has_subslice_pg = (info->subslice_total > 1);
> -	info->has_eu_pg = (info->eu_per_subslice > 2);
> -}
> -
> -static void gen9_sseu_info_init(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_device_info *info;
> -	int s_max = 3, ss_max = 4, eu_max = 8;
> -	int s, ss;
> -	u32 fuse2, s_enable, ss_disable, eu_disable;
> -	u8 eu_mask = 0xff;
> -
> -	info = (struct intel_device_info *)&dev_priv->info;
> -	fuse2 = I915_READ(GEN8_FUSE2);
> -	s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >>
> -		   GEN8_F2_S_ENA_SHIFT;
> -	ss_disable = (fuse2 & GEN9_F2_SS_DIS_MASK) >>
> -		     GEN9_F2_SS_DIS_SHIFT;
> -
> -	info->slice_total = hweight32(s_enable);
> -	/*
> -	 * The subslice disable field is global, i.e. it applies
> -	 * to each of the enabled slices.
> -	*/
> -	info->subslice_per_slice = ss_max - hweight32(ss_disable);
> -	info->subslice_total = info->slice_total *
> -			       info->subslice_per_slice;
> -
> -	/*
> -	 * Iterate through enabled slices and subslices to
> -	 * count the total enabled EU.
> -	*/
> -	for (s = 0; s < s_max; s++) {
> -		if (!(s_enable & (0x1 << s)))
> -			/* skip disabled slice */
> -			continue;
> -
> -		eu_disable = I915_READ(GEN9_EU_DISABLE(s));
> -		for (ss = 0; ss < ss_max; ss++) {
> -			int eu_per_ss;
> -
> -			if (ss_disable & (0x1 << ss))
> -				/* skip disabled subslice */
> -				continue;
> -
> -			eu_per_ss = eu_max - hweight8((eu_disable >> (ss*8)) &
> -						      eu_mask);
> -
> -			/*
> -			 * Record which subslice(s) has(have) 7 EUs. we
> -			 * can tune the hash used to spread work among
> -			 * subslices if they are unbalanced.
> -			 */
> -			if (eu_per_ss == 7)
> -				info->subslice_7eu[s] |= 1 << ss;
> -
> -			info->eu_total += eu_per_ss;
> -		}
> -	}
> -
> -	/*
> -	 * SKL is expected to always have a uniform distribution
> -	 * of EU across subslices with the exception that any one
> -	 * EU in any one subslice may be fused off for die
> -	 * recovery. BXT is expected to be perfectly uniform in EU
> -	 * distribution.
> -	*/
> -	info->eu_per_subslice = info->subslice_total ?
> -				DIV_ROUND_UP(info->eu_total,
> -					     info->subslice_total) : 0;
> -	/*
> -	 * SKL supports slice power gating on devices with more than
> -	 * one slice, and supports EU power gating on devices with
> -	 * more than one EU pair per subslice. BXT supports subslice
> -	 * power gating on devices with more than one subslice, and
> -	 * supports EU power gating on devices with more than one EU
> -	 * pair per subslice.
> -	*/
> -	info->has_slice_pg = ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) &&
> -			       (info->slice_total > 1));
> -	info->has_subslice_pg = (IS_BROXTON(dev) && (info->subslice_total > 1));
> -	info->has_eu_pg = (info->eu_per_subslice > 2);
> -}
> -
> -static void broadwell_sseu_info_init(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_device_info *info;
> -	const int s_max = 3, ss_max = 3, eu_max = 8;
> -	int s, ss;
> -	u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
> -
> -	fuse2 = I915_READ(GEN8_FUSE2);
> -	s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
> -	ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT;
> -
> -	eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK;
> -	eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) |
> -			((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) <<
> -			 (32 - GEN8_EU_DIS0_S1_SHIFT));
> -	eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) |
> -			((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) <<
> -			 (32 - GEN8_EU_DIS1_S2_SHIFT));
> -
> -
> -	info = (struct intel_device_info *)&dev_priv->info;
> -	info->slice_total = hweight32(s_enable);
> -
> -	/*
> -	 * The subslice disable field is global, i.e. it applies
> -	 * to each of the enabled slices.
> -	 */
> -	info->subslice_per_slice = ss_max - hweight32(ss_disable);
> -	info->subslice_total = info->slice_total * info->subslice_per_slice;
> -
> -	/*
> -	 * Iterate through enabled slices and subslices to
> -	 * count the total enabled EU.
> -	 */
> -	for (s = 0; s < s_max; s++) {
> -		if (!(s_enable & (0x1 << s)))
> -			/* skip disabled slice */
> -			continue;
> -
> -		for (ss = 0; ss < ss_max; ss++) {
> -			u32 n_disabled;
> -
> -			if (ss_disable & (0x1 << ss))
> -				/* skip disabled subslice */
> -				continue;
> -
> -			n_disabled = hweight8(eu_disable[s] >> (ss * eu_max));
> -
> -			/*
> -			 * Record which subslices have 7 EUs.
> -			 */
> -			if (eu_max - n_disabled == 7)
> -				info->subslice_7eu[s] |= 1 << ss;
> -
> -			info->eu_total += eu_max - n_disabled;
> -		}
> -	}
> -
> -	/*
> -	 * BDW is expected to always have a uniform distribution of EU across
> -	 * subslices with the exception that any one EU in any one subslice may
> -	 * be fused off for die recovery.
> -	 */
> -	info->eu_per_subslice = info->subslice_total ?
> -		DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
> -
> -	/*
> -	 * BDW supports slice power gating on devices with more than
> -	 * one slice.
> -	 */
> -	info->has_slice_pg = (info->slice_total > 1);
> -	info->has_subslice_pg = 0;
> -	info->has_eu_pg = 0;
> -}
> -
> -/*
> - * Determine various intel_device_info fields at runtime.
> - *
> - * Use it when either:
> - *   - it's judged too laborious to fill n static structures with the limit
> - *     when a simple if statement does the job,
> - *   - run-time checks (eg read fuse/strap registers) are needed.
> - *
> - * This function needs to be called:
> - *   - after the MMIO has been setup as we are reading registers,
> - *   - after the PCH has been detected,
> - *   - before the first usage of the fields it can tweak.
> - */
> -static void intel_device_info_runtime_init(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_device_info *info;
> -	enum pipe pipe;
> -
> -	info = (struct intel_device_info *)&dev_priv->info;
> -
> -	/*
> -	 * Skylake and Broxton currently don't expose the topmost plane as its
> -	 * use is exclusive with the legacy cursor and we only want to expose
> -	 * one of those, not both. Until we can safely expose the topmost plane
> -	 * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
> -	 * we don't expose the topmost plane at all to prevent ABI breakage
> -	 * down the line.
> -	 */
> -	if (IS_BROXTON(dev)) {
> -		info->num_sprites[PIPE_A] = 2;
> -		info->num_sprites[PIPE_B] = 2;
> -		info->num_sprites[PIPE_C] = 1;
> -	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
> -		for_each_pipe(dev_priv, pipe)
> -			info->num_sprites[pipe] = 2;
> -	else
> -		for_each_pipe(dev_priv, pipe)
> -			info->num_sprites[pipe] = 1;
> -
> -	if (i915.disable_display) {
> -		DRM_INFO("Display disabled (module parameter)\n");
> -		info->num_pipes = 0;
> -	} else if (info->num_pipes > 0 &&
> -		   (IS_GEN7(dev_priv) || IS_GEN8(dev_priv)) &&
> -		   HAS_PCH_SPLIT(dev)) {
> -		u32 fuse_strap = I915_READ(FUSE_STRAP);
> -		u32 sfuse_strap = I915_READ(SFUSE_STRAP);
> -
> -		/*
> -		 * SFUSE_STRAP is supposed to have a bit signalling the display
> -		 * is fused off. Unfortunately it seems that, at least in
> -		 * certain cases, fused off display means that PCH display
> -		 * reads don't land anywhere. In that case, we read 0s.
> -		 *
> -		 * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK
> -		 * should be set when taking over after the firmware.
> -		 */
> -		if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
> -		    sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
> -		    (dev_priv->pch_type == PCH_CPT &&
> -		     !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
> -			DRM_INFO("Display fused off, disabling\n");
> -			info->num_pipes = 0;
> -		} else if (fuse_strap & IVB_PIPE_C_DISABLE) {
> -			DRM_INFO("PipeC fused off\n");
> -			info->num_pipes -= 1;
> -		}
> -	} else if (info->num_pipes > 0 && IS_GEN9(dev_priv)) {
> -		u32 dfsm = I915_READ(SKL_DFSM);
> -		u8 disabled_mask = 0;
> -		bool invalid;
> -		int num_bits;
> -
> -		if (dfsm & SKL_DFSM_PIPE_A_DISABLE)
> -			disabled_mask |= BIT(PIPE_A);
> -		if (dfsm & SKL_DFSM_PIPE_B_DISABLE)
> -			disabled_mask |= BIT(PIPE_B);
> -		if (dfsm & SKL_DFSM_PIPE_C_DISABLE)
> -			disabled_mask |= BIT(PIPE_C);
> -
> -		num_bits = hweight8(disabled_mask);
> -
> -		switch (disabled_mask) {
> -		case BIT(PIPE_A):
> -		case BIT(PIPE_B):
> -		case BIT(PIPE_A) | BIT(PIPE_B):
> -		case BIT(PIPE_A) | BIT(PIPE_C):
> -			invalid = true;
> -			break;
> -		default:
> -			invalid = false;
> -		}
> -
> -		if (num_bits > info->num_pipes || invalid)
> -			DRM_ERROR("invalid pipe fuse configuration: 0x%x\n",
> -				  disabled_mask);
> -		else
> -			info->num_pipes -= num_bits;
> -	}
> -
> -	/* Initialize slice/subslice/EU info */
> -	if (IS_CHERRYVIEW(dev))
> -		cherryview_sseu_info_init(dev);
> -	else if (IS_BROADWELL(dev))
> -		broadwell_sseu_info_init(dev);
> -	else if (INTEL_INFO(dev)->gen >= 9)
> -		gen9_sseu_info_init(dev);
> -
> -	info->has_snoop = !info->has_llc;
> -
> -	/* Snooping is broken on BXT A stepping. */
> -	if (IS_BXT_REVID(dev, 0, BXT_REVID_A1))
> -		info->has_snoop = false;
> -
> -	DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total);
> -	DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total);
> -	DRM_DEBUG_DRIVER("subslice per slice: %u\n", info->subslice_per_slice);
> -	DRM_DEBUG_DRIVER("EU total: %u\n", info->eu_total);
> -	DRM_DEBUG_DRIVER("EU per subslice: %u\n", info->eu_per_subslice);
> -	DRM_DEBUG_DRIVER("has slice power gating: %s\n",
> -			 info->has_slice_pg ? "y" : "n");
> -	DRM_DEBUG_DRIVER("has subslice power gating: %s\n",
> -			 info->has_subslice_pg ? "y" : "n");
> -	DRM_DEBUG_DRIVER("has EU power gating: %s\n",
> -			 info->has_eu_pg ? "y" : "n");
> -
> -	i915.enable_execlists =
> -		intel_sanitize_enable_execlists(dev_priv,
> -					       	i915.enable_execlists);
> -
> -	/*
> -	 * i915.enable_ppgtt is read-only, so do an early pass to validate the
> -	 * user's requested state against the hardware/driver capabilities.  We
> -	 * do this now so that we can print out any log messages once rather
> -	 * than every time we check intel_enable_ppgtt().
> -	 */
> -	i915.enable_ppgtt =
> -		intel_sanitize_enable_ppgtt(dev_priv, i915.enable_ppgtt);
> -	DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt);
> -}
> -
> -static void intel_init_dpio(struct drm_i915_private *dev_priv)
> -{
> -	/*
> -	 * IOSF_PORT_DPIO is used for VLV x2 PHY (DP/HDMI B and C),
> -	 * CHV x1 PHY (DP/HDMI D)
> -	 * IOSF_PORT_DPIO_2 is used for CHV x2 PHY (DP/HDMI B and C)
> -	 */
> -	if (IS_CHERRYVIEW(dev_priv)) {
> -		DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO_2;
> -		DPIO_PHY_IOSF_PORT(DPIO_PHY1) = IOSF_PORT_DPIO;
> -	} else if (IS_VALLEYVIEW(dev_priv)) {
> -		DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO;
> -	}
> -}
> -
> -static int i915_workqueues_init(struct drm_i915_private *dev_priv)
> -{
> -	/*
> -	 * The i915 workqueue is primarily used for batched retirement of
> -	 * requests (and thus managing bo) once the task has been completed
> -	 * by the GPU. i915_gem_retire_requests() is called directly when we
> -	 * need high-priority retirement, such as waiting for an explicit
> -	 * bo.
> -	 *
> -	 * It is also used for periodic low-priority events, such as
> -	 * idle-timers and recording error state.
> -	 *
> -	 * All tasks on the workqueue are expected to acquire the dev mutex
> -	 * so there is no point in running more than one instance of the
> -	 * workqueue at any time.  Use an ordered one.
> -	 */
> -	dev_priv->wq = alloc_ordered_workqueue("i915", 0);
> -	if (dev_priv->wq == NULL)
> -		goto out_err;
> -
> -	dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0);
> -	if (dev_priv->hotplug.dp_wq == NULL)
> -		goto out_free_wq;
> -
> -	dev_priv->gpu_error.hangcheck_wq =
> -		alloc_ordered_workqueue("i915-hangcheck", 0);
> -	if (dev_priv->gpu_error.hangcheck_wq == NULL)
> -		goto out_free_dp_wq;
> -
> -	return 0;
> -
> -out_free_dp_wq:
> -	destroy_workqueue(dev_priv->hotplug.dp_wq);
> -out_free_wq:
> -	destroy_workqueue(dev_priv->wq);
> -out_err:
> -	DRM_ERROR("Failed to allocate workqueues.\n");
> -
> -	return -ENOMEM;
> -}
> -
> -static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv)
> -{
> -	destroy_workqueue(dev_priv->gpu_error.hangcheck_wq);
> -	destroy_workqueue(dev_priv->hotplug.dp_wq);
> -	destroy_workqueue(dev_priv->wq);
> -}
> -
> -/**
> - * i915_driver_init_early - setup state not requiring device access
> - * @dev_priv: device private
> - *
> - * Initialize everything that is a "SW-only" state, that is state not
> - * requiring accessing the device or exposing the driver via kernel internal
> - * or userspace interfaces. Example steps belonging here: lock initialization,
> - * system memory allocation, setting up device specific attributes and
> - * function hooks not requiring accessing the device.
> - */
> -static int i915_driver_init_early(struct drm_i915_private *dev_priv,
> -				  const struct pci_device_id *ent)
> -{
> -	const struct intel_device_info *match_info =
> -		(struct intel_device_info *)ent->driver_data;
> -	struct intel_device_info *device_info;
> -	int ret = 0;
> -
> -	if (i915_inject_load_failure())
> -		return -ENODEV;
> -
> -	/* Setup the write-once "constant" device info */
> -	device_info = (struct intel_device_info *)&dev_priv->info;
> -	memcpy(device_info, match_info, sizeof(*device_info));
> -	device_info->device_id = dev_priv->drm.pdev->device;
> -
> -	BUG_ON(device_info->gen > sizeof(device_info->gen_mask) * BITS_PER_BYTE);
> -	device_info->gen_mask = BIT(device_info->gen - 1);
> -
> -	spin_lock_init(&dev_priv->irq_lock);
> -	spin_lock_init(&dev_priv->gpu_error.lock);
> -	mutex_init(&dev_priv->backlight_lock);
> -	spin_lock_init(&dev_priv->uncore.lock);
> -	spin_lock_init(&dev_priv->mm.object_stat_lock);
> -	spin_lock_init(&dev_priv->mmio_flip_lock);
> -	mutex_init(&dev_priv->sb_lock);
> -	mutex_init(&dev_priv->modeset_restore_lock);
> -	mutex_init(&dev_priv->av_mutex);
> -	mutex_init(&dev_priv->wm.wm_mutex);
> -	mutex_init(&dev_priv->pps_mutex);
> -
> -	ret = i915_workqueues_init(dev_priv);
> -	if (ret < 0)
> -		return ret;
> -
> -	/* This must be called before any calls to HAS_PCH_* */
> -	intel_detect_pch(&dev_priv->drm);
> -
> -	intel_pm_setup(&dev_priv->drm);
> -	intel_init_dpio(dev_priv);
> -	intel_power_domains_init(dev_priv);
> -	intel_irq_init(dev_priv);
> -	intel_init_display_hooks(dev_priv);
> -	intel_init_clock_gating_hooks(dev_priv);
> -	intel_init_audio_hooks(dev_priv);
> -	i915_gem_load_init(&dev_priv->drm);
> -
> -	intel_display_crc_init(&dev_priv->drm);
> -
> -	i915_dump_device_info(dev_priv);
> -
> -	/* Not all pre-production machines fall into this category, only the
> -	 * very first ones. Almost everything should work, except for maybe
> -	 * suspend/resume. And we don't implement workarounds that affect only
> -	 * pre-production machines. */
> -	if (IS_HSW_EARLY_SDV(dev_priv))
> -		DRM_INFO("This is an early pre-production Haswell machine. "
> -			 "It may not be fully functional.\n");
> -
> -	return 0;
> -}
> -
> -/**
> - * i915_driver_cleanup_early - cleanup the setup done in i915_driver_init_early()
> - * @dev_priv: device private
> - */
> -static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
> -{
> -	i915_gem_load_cleanup(dev_priv->dev);
> -	i915_workqueues_cleanup(dev_priv);
> -}
> -
> -static int i915_mmio_setup(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -	int mmio_bar;
> -	int mmio_size;
> -
> -	mmio_bar = IS_GEN2(dev) ? 1 : 0;
> -	/*
> -	 * Before gen4, the registers and the GTT are behind different BARs.
> -	 * However, from gen4 onwards, the registers and the GTT are shared
> -	 * in the same BAR, so we want to restrict this ioremap from
> -	 * clobbering the GTT which we want ioremap_wc instead. Fortunately,
> -	 * the register BAR remains the same size for all the earlier
> -	 * generations up to Ironlake.
> -	 */
> -	if (INTEL_INFO(dev)->gen < 5)
> -		mmio_size = 512 * 1024;
> -	else
> -		mmio_size = 2 * 1024 * 1024;
> -	dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size);
> -	if (dev_priv->regs == NULL) {
> -		DRM_ERROR("failed to map registers\n");
> -
> -		return -EIO;
> -	}
> -
> -	/* Try to make sure MCHBAR is enabled before poking at it */
> -	intel_setup_mchbar(dev);
> -
> -	return 0;
> -}
> -
> -static void i915_mmio_cleanup(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> -
> -	intel_teardown_mchbar(dev);
> -	pci_iounmap(dev->pdev, dev_priv->regs);
> -}
> -
> -/**
> - * i915_driver_init_mmio - setup device MMIO
> - * @dev_priv: device private
> - *
> - * Setup minimal device state necessary for MMIO accesses later in the
> - * initialization sequence. The setup here should avoid any other device-wide
> - * side effects or exposing the driver via kernel internal or user space
> - * interfaces.
> - */
> -static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)
> -{
> -	struct drm_device *dev = dev_priv->dev;
> -	int ret;
> -
> -	if (i915_inject_load_failure())
> -		return -ENODEV;
> -
> -	if (i915_get_bridge_dev(dev))
> -		return -EIO;
> -
> -	ret = i915_mmio_setup(dev);
> -	if (ret < 0)
> -		goto put_bridge;
> -
> -	intel_uncore_init(dev_priv);
> -
> -	return 0;
> -
> -put_bridge:
> -	pci_dev_put(dev_priv->bridge_dev);
> -
> -	return ret;
> -}
> -
> -/**
> - * i915_driver_cleanup_mmio - cleanup the setup done in i915_driver_init_mmio()
> - * @dev_priv: device private
> - */
> -static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv)
> -{
> -	struct drm_device *dev = dev_priv->dev;
> -
> -	intel_uncore_fini(dev_priv);
> -	i915_mmio_cleanup(dev);
> -	pci_dev_put(dev_priv->bridge_dev);
> -}
> -
> -/**
> - * i915_driver_init_hw - setup state requiring device access
> - * @dev_priv: device private
> - *
> - * Setup state that requires accessing the device, but doesn't require
> - * exposing the driver via kernel internal or userspace interfaces.
> - */
> -static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
> -{
> -	struct drm_device *dev = dev_priv->dev;
> -	struct i915_ggtt *ggtt = &dev_priv->ggtt;
> -	uint32_t aperture_size;
> -	int ret;
> -
> -	if (i915_inject_load_failure())
> -		return -ENODEV;
> -
> -	intel_device_info_runtime_init(dev);
> -
> -	ret = i915_ggtt_init_hw(dev);
> -	if (ret)
> -		return ret;
> -
> -	ret = i915_ggtt_enable_hw(dev);
> -	if (ret) {
> -		DRM_ERROR("failed to enable GGTT\n");
> -		goto out_ggtt;
> -	}
> -
> -	/* WARNING: Apparently we must kick fbdev drivers before vgacon,
> -	 * otherwise the vga fbdev driver falls over. */
> -	ret = i915_kick_out_firmware_fb(dev_priv);
> -	if (ret) {
> -		DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
> -		goto out_ggtt;
> -	}
> -
> -	ret = i915_kick_out_vgacon(dev_priv);
> -	if (ret) {
> -		DRM_ERROR("failed to remove conflicting VGA console\n");
> -		goto out_ggtt;
> -	}
> -
> -	pci_set_master(dev->pdev);
> -
> -	/* overlay on gen2 is broken and can't address above 1G */
> -	if (IS_GEN2(dev)) {
> -		ret = dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
> -		if (ret) {
> -			DRM_ERROR("failed to set DMA mask\n");
> -
> -			goto out_ggtt;
> -		}
> -	}
> -
> -
> -	/* 965GM sometimes incorrectly writes to hardware status page (HWS)
> -	 * using 32bit addressing, overwriting memory if HWS is located
> -	 * above 4GB.
> -	 *
> -	 * The documentation also mentions an issue with undefined
> -	 * behaviour if any general state is accessed within a page above 4GB,
> -	 * which also needs to be handled carefully.
> -	 */
> -	if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) {
> -		ret = dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32));
> -
> -		if (ret) {
> -			DRM_ERROR("failed to set DMA mask\n");
> -
> -			goto out_ggtt;
> -		}
> -	}
> -
> -	aperture_size = ggtt->mappable_end;
> -
> -	ggtt->mappable =
> -		io_mapping_create_wc(ggtt->mappable_base,
> -				     aperture_size);
> -	if (!ggtt->mappable) {
> -		ret = -EIO;
> -		goto out_ggtt;
> -	}
> -
> -	ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base,
> -					      aperture_size);
> -
> -	pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY,
> -			   PM_QOS_DEFAULT_VALUE);
> -
> -	intel_uncore_sanitize(dev_priv);
> -
> -	intel_opregion_setup(dev_priv);
> -
> -	i915_gem_load_init_fences(dev_priv);
> -
> -	/* On the 945G/GM, the chipset reports the MSI capability on the
> -	 * integrated graphics even though the support isn't actually there
> -	 * according to the published specs.  It doesn't appear to function
> -	 * correctly in testing on 945G.
> -	 * This may be a side effect of MSI having been made available for PEG
> -	 * and the registers being closely associated.
> -	 *
> -	 * According to chipset errata, on the 965GM, MSI interrupts may
> -	 * be lost or delayed, but we use them anyways to avoid
> -	 * stuck interrupts on some machines.
> -	 */
> -	if (!IS_I945G(dev) && !IS_I945GM(dev)) {
> -		if (pci_enable_msi(dev->pdev) < 0)
> -			DRM_DEBUG_DRIVER("can't enable MSI");
> -	}
> -
> -	return 0;
> -
> -out_ggtt:
> -	i915_ggtt_cleanup_hw(dev);
> -
> -	return ret;
> -}
> -
> -/**
> - * i915_driver_cleanup_hw - cleanup the setup done in i915_driver_init_hw()
> - * @dev_priv: device private
> - */
> -static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv)
> -{
> -	struct drm_device *dev = dev_priv->dev;
> -	struct i915_ggtt *ggtt = &dev_priv->ggtt;
> -
> -	if (dev->pdev->msi_enabled)
> -		pci_disable_msi(dev->pdev);
> -
> -	pm_qos_remove_request(&dev_priv->pm_qos);
> -	arch_phys_wc_del(ggtt->mtrr);
> -	io_mapping_free(ggtt->mappable);
> -	i915_ggtt_cleanup_hw(dev);
> -}
> -
> -/**
> - * i915_driver_register - register the driver with the rest of the system
> - * @dev_priv: device private
> - *
> - * Perform any steps necessary to make the driver available via kernel
> - * internal or userspace interfaces.
> - */
> -static void i915_driver_register(struct drm_i915_private *dev_priv)
> -{
> -	struct drm_device *dev = dev_priv->dev;
> -
> -	i915_gem_shrinker_init(dev_priv);
> -
> -	/*
> -	 * Notify a valid surface after modesetting,
> -	 * when running inside a VM.
> -	 */
> -	if (intel_vgpu_active(dev_priv))
> -		I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY);
> -
> -	/* Reveal our presence to userspace */
> -	if (drm_dev_register(dev, 0) == 0) {
> -		i915_debugfs_register(dev_priv);
> -		i915_setup_sysfs(dev);
> -		intel_modeset_register(dev_priv);
> -	} else
> -		DRM_ERROR("Failed to register driver for userspace access!\n");
> -
> -	if (INTEL_INFO(dev_priv)->num_pipes) {
> -		/* Must be done after probing outputs */
> -		intel_opregion_register(dev_priv);
> -		acpi_video_register();
> -	}
> -
> -	if (IS_GEN5(dev_priv))
> -		intel_gpu_ips_init(dev_priv);
> -
> -	i915_audio_component_init(dev_priv);
> -
> -	/*
> -	 * Some ports require correctly set-up hpd registers for detection to
> -	 * work properly (leading to ghost connected connector status), e.g. VGA
> -	 * on gm45.  Hence we can only set up the initial fbdev config after hpd
> -	 * irqs are fully enabled. Now we should scan for the initial config
> -	 * only once hotplug handling is enabled, but due to screwed-up locking
> -	 * around kms/fbdev init we can't protect the fdbev initial config
> -	 * scanning against hotplug events. Hence do this first and ignore the
> -	 * tiny window where we will loose hotplug notifactions.
> -	 */
> -	intel_fbdev_initial_config_async(dev);
> -}
> -
> -/**
> - * i915_driver_unregister - cleanup the registration done in i915_driver_regiser()
> - * @dev_priv: device private
> - */
> -static void i915_driver_unregister(struct drm_i915_private *dev_priv)
> -{
> -	i915_audio_component_cleanup(dev_priv);
> -
> -	intel_gpu_ips_teardown();
> -	acpi_video_unregister();
> -	intel_opregion_unregister(dev_priv);
> -
> -	intel_modeset_unregister(dev_priv);
> -	i915_teardown_sysfs(dev_priv->dev);
> -	i915_debugfs_unregister(dev_priv);
> -	drm_dev_unregister(dev_priv->dev);
> -
> -	i915_gem_shrinker_cleanup(dev_priv);
> -}
> -
> -/**
> - * i915_driver_load - setup chip and create an initial config
> - * @dev: DRM device
> - * @flags: startup flags
> - *
> - * The driver load routine has to do several things:
> - *   - drive output discovery via intel_modeset_init()
> - *   - initialize the memory manager
> - *   - allocate initial config memory
> - *   - setup the DRM framebuffer with the allocated memory
> - */
> -int i915_driver_load(struct pci_dev *pdev,
> -		     const struct pci_device_id *ent,
> -		     struct drm_driver *driver)
> -{
> -	struct drm_i915_private *dev_priv;
> -	int ret;
> -
> -	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
> -	if (dev_priv == NULL)
> -		return -ENOMEM;
> -
> -	ret = drm_dev_init(&dev_priv->drm, driver, &pdev->dev);
> -	if (ret)
> -		goto out_free_priv;
> -
> -	/* Must be set before calling __i915_printk */
> -	dev_priv->drm.pdev = pdev;
> -	dev_priv->drm.dev_private = dev_priv;
> -	dev_priv->dev = &dev_priv->drm;
> -
> -	ret = i915_driver_init_early(dev_priv, ent);
> -	if (ret < 0)
> -		goto out_free_priv;
> -
> -	ret = pci_enable_device(pdev);
> -	if (ret)
> -		goto out_cleanup_early;
> -
> -	pci_set_drvdata(pdev, &dev_priv->drm);
> -
> -	intel_runtime_pm_get(dev_priv);
> -
> -	ret = i915_driver_init_mmio(dev_priv);
> -	if (ret < 0)
> -		goto out_runtime_pm_put;
> -
> -	ret = i915_driver_init_hw(dev_priv);
> -	if (ret < 0)
> -		goto out_cleanup_mmio;
> -
> -	/*
> -	 * TODO: move the vblank init and parts of modeset init steps into one
> -	 * of the i915_driver_init_/i915_driver_register functions according
> -	 * to the role/effect of the given init step.
> -	 */
> -	if (INTEL_INFO(dev_priv)->num_pipes) {
> -		ret = drm_vblank_init(dev_priv->dev,
> -				      INTEL_INFO(dev_priv)->num_pipes);
> -		if (ret)
> -			goto out_cleanup_hw;
> -	}
> -
> -	ret = i915_load_modeset_init(dev_priv->dev);
> -	if (ret < 0)
> -		goto out_cleanup_vblank;
> -
> -	i915_driver_register(dev_priv);
> -
> -	intel_runtime_pm_enable(dev_priv);
> -
> -	intel_runtime_pm_put(dev_priv);
> -
> -	return 0;
> -
> -out_cleanup_vblank:
> -	drm_vblank_cleanup(dev_priv->dev);
> -out_cleanup_hw:
> -	i915_driver_cleanup_hw(dev_priv);
> -out_cleanup_mmio:
> -	i915_driver_cleanup_mmio(dev_priv);
> -out_runtime_pm_put:
> -	intel_runtime_pm_put(dev_priv);
> -	pci_disable_device(pdev);
> -out_cleanup_early:
> -	i915_driver_cleanup_early(dev_priv);
> -out_free_priv:
> -	i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret);
> -
> -	kfree(dev_priv);
> -
> -	return ret;
> -}
> -
> -int i915_driver_unload(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	int ret;
> -
> -	intel_fbdev_fini(dev);
> -
> -	ret = i915_gem_suspend(dev);
> -	if (ret) {
> -		DRM_ERROR("failed to idle hardware: %d\n", ret);
> -		return ret;
> -	}
> -
> -	intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
> -
> -	i915_driver_unregister(dev_priv);
> -
> -	drm_vblank_cleanup(dev);
> -
> -	intel_modeset_cleanup(dev);
> -
> -	/*
> -	 * free the memory space allocated for the child device
> -	 * config parsed from VBT
> -	 */
> -	if (dev_priv->vbt.child_dev && dev_priv->vbt.child_dev_num) {
> -		kfree(dev_priv->vbt.child_dev);
> -		dev_priv->vbt.child_dev = NULL;
> -		dev_priv->vbt.child_dev_num = 0;
> -	}
> -	kfree(dev_priv->vbt.sdvo_lvds_vbt_mode);
> -	dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
> -	kfree(dev_priv->vbt.lfp_lvds_vbt_mode);
> -	dev_priv->vbt.lfp_lvds_vbt_mode = NULL;
> -
> -	vga_switcheroo_unregister_client(dev->pdev);
> -	vga_client_register(dev->pdev, NULL, NULL, NULL);
> -
> -	intel_csr_ucode_fini(dev_priv);
> -
> -	/* Free error state after interrupts are fully disabled. */
> -	cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
> -	i915_destroy_error_state(dev);
> -
> -	/* Flush any outstanding unpin_work. */
> -	flush_workqueue(dev_priv->wq);
> -
> -	intel_guc_fini(dev);
> -	i915_gem_fini(dev);
> -	intel_fbc_cleanup_cfb(dev_priv);
> -
> -	intel_power_domains_fini(dev_priv);
> -
> -	i915_driver_cleanup_hw(dev_priv);
> -	i915_driver_cleanup_mmio(dev_priv);
> -
> -	intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
> -
> -	i915_driver_cleanup_early(dev_priv);
> -
> -	return 0;
> -}
> -
> -int i915_driver_open(struct drm_device *dev, struct drm_file *file)
> -{
> -	int ret;
> -
> -	ret = i915_gem_open(dev, file);
> -	if (ret)
> -		return ret;
> -
> -	return 0;
> -}
> -
> -/**
> - * i915_driver_lastclose - clean up after all DRM clients have exited
> - * @dev: DRM device
> - *
> - * Take care of cleaning up after all DRM clients have exited.  In the
> - * mode setting case, we want to restore the kernel's initial mode (just
> - * in case the last client left us in a bad state).
> - *
> - * Additionally, in the non-mode setting case, we'll tear down the GTT
> - * and DMA structures, since the kernel won't be using them, and clea
> - * up any GEM state.
> - */
> -void i915_driver_lastclose(struct drm_device *dev)
> -{
> -	intel_fbdev_restore_mode(dev);
> -	vga_switcheroo_process_delayed_switch();
> -}
> -
> -void i915_driver_preclose(struct drm_device *dev, struct drm_file *file)
> -{
> -	mutex_lock(&dev->struct_mutex);
> -	i915_gem_context_close(dev, file);
> -	i915_gem_release(dev, file);
> -	mutex_unlock(&dev->struct_mutex);
> -}
> -
> -void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
> -{
> -	struct drm_i915_file_private *file_priv = file->driver_priv;
> -
> -	kfree(file_priv);
> -}
> -
> -static int
> -i915_gem_reject_pin_ioctl(struct drm_device *dev, void *data,
> -			  struct drm_file *file)
> -{
> -	return -ENODEV;
> -}
> -
> -const struct drm_ioctl_desc i915_ioctls[] = {
> -	DRM_IOCTL_DEF_DRV(I915_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_FLUSH, drm_noop, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_FLIP, drm_noop, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, drm_noop, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, drm_noop, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, drm_noop, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH|DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_SETPARAM, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, drm_noop, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP,  drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE,  drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE,  drm_noop, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, drm_noop, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
> -};
> -
> -int i915_max_ioctl = ARRAY_SIZE(i915_ioctls);
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index b13d6751ebe4..e20f63ac73d3 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -27,21 +27,30 @@
>   *
>   */
>  
> -#include 
>  #include 
> -#include 
> -#include 
> -#include "i915_drv.h"
> -#include "i915_trace.h"
> -#include "intel_drv.h"
> -
>  #include 
>  #include 
> +#include 
> +#include 
>  #include 
> +#include 
> +#include 
>  #include 
> +#include 
> +#include 
>  #include 
>  #include 
> +#include 
> +#include 
> +
> +#include 
>  #include 
> +#include 
> +
> +#include "i915_drv.h"
> +#include "i915_trace.h"
> +#include "i915_vgpu.h"
> +#include "intel_drv.h"
>  
>  static struct drm_driver driver;
>  
> @@ -340,219 +349,1783 @@ static const struct intel_device_info intel_skylake_info = {
>  	.gen = 9,
>  };
>  
> -static const struct intel_device_info intel_skylake_gt3_info = {
> -	BDW_FEATURES,
> -	.is_skylake = 1,
> -	.gen = 9,
> -	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
> -};
> +static const struct intel_device_info intel_skylake_gt3_info = {
> +	BDW_FEATURES,
> +	.is_skylake = 1,
> +	.gen = 9,
> +	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
> +};
> +
> +static const struct intel_device_info intel_broxton_info = {
> +	.is_preliminary = 1,
> +	.is_broxton = 1,
> +	.gen = 9,
> +	.need_gfx_hws = 1, .has_hotplug = 1,
> +	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
> +	.num_pipes = 3,
> +	.has_ddi = 1,
> +	.has_fpga_dbg = 1,
> +	.has_fbc = 1,
> +	GEN_DEFAULT_PIPEOFFSETS,
> +	IVB_CURSOR_OFFSETS,
> +	BDW_COLORS,
> +};
> +
> +static const struct intel_device_info intel_kabylake_info = {
> +	BDW_FEATURES,
> +	.is_kabylake = 1,
> +	.gen = 9,
> +};
> +
> +static const struct intel_device_info intel_kabylake_gt3_info = {
> +	BDW_FEATURES,
> +	.is_kabylake = 1,
> +	.gen = 9,
> +	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
> +};
> +
> +/*
> + * Make sure any device matches here are from most specific to most
> + * general.  For example, since the Quanta match is based on the subsystem
> + * and subvendor IDs, we need it to come before the more general IVB
> + * PCI ID matches, otherwise we'll use the wrong info struct above.
> + */
> +static const struct pci_device_id pciidlist[] = {
> +	INTEL_I830_IDS(&intel_i830_info),
> +	INTEL_I845G_IDS(&intel_845g_info),
> +	INTEL_I85X_IDS(&intel_i85x_info),
> +	INTEL_I865G_IDS(&intel_i865g_info),
> +	INTEL_I915G_IDS(&intel_i915g_info),
> +	INTEL_I915GM_IDS(&intel_i915gm_info),
> +	INTEL_I945G_IDS(&intel_i945g_info),
> +	INTEL_I945GM_IDS(&intel_i945gm_info),
> +	INTEL_I965G_IDS(&intel_i965g_info),
> +	INTEL_G33_IDS(&intel_g33_info),
> +	INTEL_I965GM_IDS(&intel_i965gm_info),
> +	INTEL_GM45_IDS(&intel_gm45_info),
> +	INTEL_G45_IDS(&intel_g45_info),
> +	INTEL_PINEVIEW_IDS(&intel_pineview_info),
> +	INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info),
> +	INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info),
> +	INTEL_SNB_D_IDS(&intel_sandybridge_d_info),
> +	INTEL_SNB_M_IDS(&intel_sandybridge_m_info),
> +	INTEL_IVB_Q_IDS(&intel_ivybridge_q_info), /* must be first IVB */
> +	INTEL_IVB_M_IDS(&intel_ivybridge_m_info),
> +	INTEL_IVB_D_IDS(&intel_ivybridge_d_info),
> +	INTEL_HSW_D_IDS(&intel_haswell_d_info),
> +	INTEL_HSW_M_IDS(&intel_haswell_m_info),
> +	INTEL_VLV_M_IDS(&intel_valleyview_m_info),
> +	INTEL_VLV_D_IDS(&intel_valleyview_d_info),
> +	INTEL_BDW_GT12M_IDS(&intel_broadwell_m_info),
> +	INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info),
> +	INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info),
> +	INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info),
> +	INTEL_CHV_IDS(&intel_cherryview_info),
> +	INTEL_SKL_GT1_IDS(&intel_skylake_info),
> +	INTEL_SKL_GT2_IDS(&intel_skylake_info),
> +	INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info),
> +	INTEL_SKL_GT4_IDS(&intel_skylake_gt3_info),
> +	INTEL_BXT_IDS(&intel_broxton_info),
> +	INTEL_KBL_GT1_IDS(&intel_kabylake_info),
> +	INTEL_KBL_GT2_IDS(&intel_kabylake_info),
> +	INTEL_KBL_GT3_IDS(&intel_kabylake_gt3_info),
> +	INTEL_KBL_GT4_IDS(&intel_kabylake_gt3_info),
> +	{0, 0, 0}
> +};
> +MODULE_DEVICE_TABLE(pci, pciidlist);
> +
> +static unsigned int i915_load_fail_count;
> +
> +bool __i915_inject_load_failure(const char *func, int line)
> +{
> +	if (i915_load_fail_count >= i915.inject_load_failure)
> +		return false;
> +
> +	if (++i915_load_fail_count == i915.inject_load_failure) {
> +		DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n",
> +			 i915.inject_load_failure, func, line);
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +#define FDO_BUG_URL "https://bugs.freedesktop.org/enter_bug.cgi?product=DRI"
> +#define FDO_BUG_MSG "Please file a bug at " FDO_BUG_URL " against DRM/Intel " \
> +		    "providing the dmesg log by booting with drm.debug=0xf"
> +
> +void
> +__i915_printk(struct drm_i915_private *dev_priv, const char *level,
> +	      const char *fmt, ...)
> +{
> +	static bool shown_bug_once;
> +	struct device *dev = dev_priv->dev->dev;
> +	bool is_error = level[1] <= KERN_ERR[1];
> +	bool is_debug = level[1] == KERN_DEBUG[1];
> +	struct va_format vaf;
> +	va_list args;
> +
> +	if (is_debug && !(drm_debug & DRM_UT_DRIVER))
> +		return;
> +
> +	va_start(args, fmt);
> +
> +	vaf.fmt = fmt;
> +	vaf.va = &args;
> +
> +	dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV",
> +		   __builtin_return_address(0), &vaf);
> +
> +	if (is_error && !shown_bug_once) {
> +		dev_notice(dev, "%s", FDO_BUG_MSG);
> +		shown_bug_once = true;
> +	}
> +
> +	va_end(args);
> +}
> +
> +static bool i915_error_injected(struct drm_i915_private *dev_priv)
> +{
> +	return i915.inject_load_failure &&
> +	       i915_load_fail_count == i915.inject_load_failure;
> +}
> +
> +#define i915_load_error(dev_priv, fmt, ...)				     \
> +	__i915_printk(dev_priv,						     \
> +		      i915_error_injected(dev_priv) ? KERN_DEBUG : KERN_ERR, \
> +		      fmt, ##__VA_ARGS__)
> +
> +
> +static enum intel_pch intel_virt_detect_pch(struct drm_device *dev)
> +{
> +	enum intel_pch ret = PCH_NOP;
> +
> +	/*
> +	 * In a virtualized passthrough environment we can be in a
> +	 * setup where the ISA bridge is not able to be passed through.
> +	 * In this case, a south bridge can be emulated and we have to
> +	 * make an educated guess as to which PCH is really there.
> +	 */
> +
> +	if (IS_GEN5(dev)) {
> +		ret = PCH_IBX;
> +		DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n");
> +	} else if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
> +		ret = PCH_CPT;
> +		DRM_DEBUG_KMS("Assuming CouarPoint PCH\n");
> +	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
> +		ret = PCH_LPT;
> +		DRM_DEBUG_KMS("Assuming LynxPoint PCH\n");
> +	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
> +		ret = PCH_SPT;
> +		DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n");
> +	}
> +
> +	return ret;
> +}
> +
> +static void intel_detect_pch(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct pci_dev *pch = NULL;
> +
> +	/* In all current cases, num_pipes is equivalent to the PCH_NOP setting
> +	 * (which really amounts to a PCH but no South Display).
> +	 */
> +	if (INTEL_INFO(dev)->num_pipes == 0) {
> +		dev_priv->pch_type = PCH_NOP;
> +		return;
> +	}
> +
> +	/*
> +	 * The reason to probe ISA bridge instead of Dev31:Fun0 is to
> +	 * make graphics device passthrough work easy for VMM, that only
> +	 * need to expose ISA bridge to let driver know the real hardware
> +	 * underneath. This is a requirement from virtualization team.
> +	 *
> +	 * In some virtualized environments (e.g. XEN), there is irrelevant
> +	 * ISA bridge in the system. To work reliably, we should scan trhough
> +	 * all the ISA bridge devices and check for the first match, instead
> +	 * of only checking the first one.
> +	 */
> +	while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
> +		if (pch->vendor == PCI_VENDOR_ID_INTEL) {
> +			unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
> +			dev_priv->pch_id = id;
> +
> +			if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
> +				dev_priv->pch_type = PCH_IBX;
> +				DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
> +				WARN_ON(!IS_GEN5(dev));
> +			} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
> +				dev_priv->pch_type = PCH_CPT;
> +				DRM_DEBUG_KMS("Found CougarPoint PCH\n");
> +				WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
> +			} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
> +				/* PantherPoint is CPT compatible */
> +				dev_priv->pch_type = PCH_CPT;
> +				DRM_DEBUG_KMS("Found PantherPoint PCH\n");
> +				WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
> +			} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
> +				dev_priv->pch_type = PCH_LPT;
> +				DRM_DEBUG_KMS("Found LynxPoint PCH\n");
> +				WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev));
> +				WARN_ON(IS_HSW_ULT(dev) || IS_BDW_ULT(dev));
> +			} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
> +				dev_priv->pch_type = PCH_LPT;
> +				DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
> +				WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev));
> +				WARN_ON(!IS_HSW_ULT(dev) && !IS_BDW_ULT(dev));
> +			} else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
> +				dev_priv->pch_type = PCH_SPT;
> +				DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
> +				WARN_ON(!IS_SKYLAKE(dev) &&
> +					!IS_KABYLAKE(dev));
> +			} else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
> +				dev_priv->pch_type = PCH_SPT;
> +				DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
> +				WARN_ON(!IS_SKYLAKE(dev) &&
> +					!IS_KABYLAKE(dev));
> +			} else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) ||
> +				   (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) ||
> +				   ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) &&
> +				    pch->subsystem_vendor == 0x1af4 &&
> +				    pch->subsystem_device == 0x1100)) {
> +				dev_priv->pch_type = intel_virt_detect_pch(dev);
> +			} else
> +				continue;
> +
> +			break;
> +		}
> +	}
> +	if (!pch)
> +		DRM_DEBUG_KMS("No PCH found.\n");
> +
> +	pci_dev_put(pch);
> +}
> +
> +bool i915_semaphore_is_enabled(struct drm_i915_private *dev_priv)
> +{
> +	if (INTEL_GEN(dev_priv) < 6)
> +		return false;
> +
> +	if (i915.semaphores >= 0)
> +		return i915.semaphores;
> +
> +	/* TODO: make semaphores and Execlists play nicely together */
> +	if (i915.enable_execlists)
> +		return false;
> +
> +#ifdef CONFIG_INTEL_IOMMU
> +	/* Enable semaphores on SNB when IO remapping is off */
> +	if (IS_GEN6(dev_priv) && intel_iommu_gfx_mapped)
> +		return false;
> +#endif
> +
> +	return true;
> +}
> +
> +static int i915_getparam(struct drm_device *dev, void *data,
> +			 struct drm_file *file_priv)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	drm_i915_getparam_t *param = data;
> +	int value;
> +
> +	switch (param->param) {
> +	case I915_PARAM_IRQ_ACTIVE:
> +	case I915_PARAM_ALLOW_BATCHBUFFER:
> +	case I915_PARAM_LAST_DISPATCH:
> +		/* Reject all old ums/dri params. */
> +		return -ENODEV;
> +	case I915_PARAM_CHIPSET_ID:
> +		value = dev->pdev->device;
> +		break;
> +	case I915_PARAM_REVISION:
> +		value = dev->pdev->revision;
> +		break;
> +	case I915_PARAM_HAS_GEM:
> +		value = 1;
> +		break;
> +	case I915_PARAM_NUM_FENCES_AVAIL:
> +		value = dev_priv->num_fence_regs;
> +		break;
> +	case I915_PARAM_HAS_OVERLAY:
> +		value = dev_priv->overlay ? 1 : 0;
> +		break;
> +	case I915_PARAM_HAS_PAGEFLIPPING:
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_EXECBUF2:
> +		/* depends on GEM */
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_BSD:
> +		value = intel_engine_initialized(&dev_priv->engine[VCS]);
> +		break;
> +	case I915_PARAM_HAS_BLT:
> +		value = intel_engine_initialized(&dev_priv->engine[BCS]);
> +		break;
> +	case I915_PARAM_HAS_VEBOX:
> +		value = intel_engine_initialized(&dev_priv->engine[VECS]);
> +		break;
> +	case I915_PARAM_HAS_BSD2:
> +		value = intel_engine_initialized(&dev_priv->engine[VCS2]);
> +		break;
> +	case I915_PARAM_HAS_RELAXED_FENCING:
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_COHERENT_RINGS:
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_EXEC_CONSTANTS:
> +		value = INTEL_INFO(dev)->gen >= 4;
> +		break;
> +	case I915_PARAM_HAS_RELAXED_DELTA:
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_GEN7_SOL_RESET:
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_LLC:
> +		value = HAS_LLC(dev);
> +		break;
> +	case I915_PARAM_HAS_WT:
> +		value = HAS_WT(dev);
> +		break;
> +	case I915_PARAM_HAS_ALIASING_PPGTT:
> +		value = USES_PPGTT(dev);
> +		break;
> +	case I915_PARAM_HAS_WAIT_TIMEOUT:
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_SEMAPHORES:
> +		value = i915_semaphore_is_enabled(dev_priv);
> +		break;
> +	case I915_PARAM_HAS_PRIME_VMAP_FLUSH:
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_SECURE_BATCHES:
> +		value = capable(CAP_SYS_ADMIN);
> +		break;
> +	case I915_PARAM_HAS_PINNED_BATCHES:
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_EXEC_NO_RELOC:
> +		value = 1;
> +		break;
> +	case I915_PARAM_HAS_EXEC_HANDLE_LUT:
> +		value = 1;
> +		break;
> +	case I915_PARAM_CMD_PARSER_VERSION:
> +		value = i915_cmd_parser_get_version(dev_priv);
> +		break;
> +	case I915_PARAM_HAS_COHERENT_PHYS_GTT:
> +		value = 1;
> +		break;
> +	case I915_PARAM_MMAP_VERSION:
> +		value = 1;
> +		break;
> +	case I915_PARAM_SUBSLICE_TOTAL:
> +		value = INTEL_INFO(dev)->subslice_total;
> +		if (!value)
> +			return -ENODEV;
> +		break;
> +	case I915_PARAM_EU_TOTAL:
> +		value = INTEL_INFO(dev)->eu_total;
> +		if (!value)
> +			return -ENODEV;
> +		break;
> +	case I915_PARAM_HAS_GPU_RESET:
> +		value = i915.enable_hangcheck && intel_has_gpu_reset(dev_priv);
> +		break;
> +	case I915_PARAM_HAS_RESOURCE_STREAMER:
> +		value = HAS_RESOURCE_STREAMER(dev);
> +		break;
> +	case I915_PARAM_HAS_EXEC_SOFTPIN:
> +		value = 1;
> +		break;
> +	default:
> +		DRM_DEBUG("Unknown parameter %d\n", param->param);
> +		return -EINVAL;
> +	}
> +
> +	if (copy_to_user(param->value, &value, sizeof(int))) {
> +		DRM_ERROR("copy_to_user failed\n");
> +		return -EFAULT;
> +	}
> +
> +	return 0;
> +}
> +
> +static int i915_get_bridge_dev(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +
> +	dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
> +	if (!dev_priv->bridge_dev) {
> +		DRM_ERROR("bridge device not found\n");
> +		return -1;
> +	}
> +	return 0;
> +}
> +
> +/* Allocate space for the MCH regs if needed, return nonzero on error */
> +static int
> +intel_alloc_mchbar_resource(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	int reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
> +	u32 temp_lo, temp_hi = 0;
> +	u64 mchbar_addr;
> +	int ret;
> +
> +	if (INTEL_INFO(dev)->gen >= 4)
> +		pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
> +	pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
> +	mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
> +
> +	/* If ACPI doesn't have it, assume we need to allocate it ourselves */
> +#ifdef CONFIG_PNP
> +	if (mchbar_addr &&
> +	    pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE))
> +		return 0;
> +#endif
> +
> +	/* Get some space for it */
> +	dev_priv->mch_res.name = "i915 MCHBAR";
> +	dev_priv->mch_res.flags = IORESOURCE_MEM;
> +	ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus,
> +				     &dev_priv->mch_res,
> +				     MCHBAR_SIZE, MCHBAR_SIZE,
> +				     PCIBIOS_MIN_MEM,
> +				     0, pcibios_align_resource,
> +				     dev_priv->bridge_dev);
> +	if (ret) {
> +		DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret);
> +		dev_priv->mch_res.start = 0;
> +		return ret;
> +	}
> +
> +	if (INTEL_INFO(dev)->gen >= 4)
> +		pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
> +				       upper_32_bits(dev_priv->mch_res.start));
> +
> +	pci_write_config_dword(dev_priv->bridge_dev, reg,
> +			       lower_32_bits(dev_priv->mch_res.start));
> +	return 0;
> +}
> +
> +/* Setup MCHBAR if possible, return true if we should disable it again */
> +static void
> +intel_setup_mchbar(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
> +	u32 temp;
> +	bool enabled;
> +
> +	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
> +		return;
> +
> +	dev_priv->mchbar_need_disable = false;
> +
> +	if (IS_I915G(dev) || IS_I915GM(dev)) {
> +		pci_read_config_dword(dev_priv->bridge_dev, DEVEN, &temp);
> +		enabled = !!(temp & DEVEN_MCHBAR_EN);
> +	} else {
> +		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
> +		enabled = temp & 1;
> +	}
> +
> +	/* If it's already enabled, don't have to do anything */
> +	if (enabled)
> +		return;
> +
> +	if (intel_alloc_mchbar_resource(dev))
> +		return;
> +
> +	dev_priv->mchbar_need_disable = true;
> +
> +	/* Space is allocated or reserved, so enable it. */
> +	if (IS_I915G(dev) || IS_I915GM(dev)) {
> +		pci_write_config_dword(dev_priv->bridge_dev, DEVEN,
> +				       temp | DEVEN_MCHBAR_EN);
> +	} else {
> +		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
> +		pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
> +	}
> +}
> +
> +static void
> +intel_teardown_mchbar(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915;
> +
> +	if (dev_priv->mchbar_need_disable) {
> +		if (IS_I915G(dev) || IS_I915GM(dev)) {
> +			u32 deven_val;
> +
> +			pci_read_config_dword(dev_priv->bridge_dev, DEVEN,
> +					      &deven_val);
> +			deven_val &= ~DEVEN_MCHBAR_EN;
> +			pci_write_config_dword(dev_priv->bridge_dev, DEVEN,
> +					       deven_val);
> +		} else {
> +			u32 mchbar_val;
> +
> +			pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg,
> +					      &mchbar_val);
> +			mchbar_val &= ~1;
> +			pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg,
> +					       mchbar_val);
> +		}
> +	}
> +
> +	if (dev_priv->mch_res.start)
> +		release_resource(&dev_priv->mch_res);
> +}
> +
> +/* true = enable decode, false = disable decoder */
> +static unsigned int i915_vga_set_decode(void *cookie, bool state)
> +{
> +	struct drm_device *dev = cookie;
> +
> +	intel_modeset_vga_set_state(dev, state);
> +	if (state)
> +		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
> +		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
> +	else
> +		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
> +}
> +
> +static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state)
> +{
> +	struct drm_device *dev = pci_get_drvdata(pdev);
> +	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
> +
> +	if (state == VGA_SWITCHEROO_ON) {
> +		pr_info("switched on\n");
> +		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
> +		/* i915 resume handler doesn't set to D0 */
> +		pci_set_power_state(dev->pdev, PCI_D0);
> +		i915_resume_switcheroo(dev);
> +		dev->switch_power_state = DRM_SWITCH_POWER_ON;
> +	} else {
> +		pr_info("switched off\n");
> +		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
> +		i915_suspend_switcheroo(dev, pmm);
> +		dev->switch_power_state = DRM_SWITCH_POWER_OFF;
> +	}
> +}
> +
> +static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
> +{
> +	struct drm_device *dev = pci_get_drvdata(pdev);
> +
> +	/*
> +	 * FIXME: open_count is protected by drm_global_mutex but that would lead to
> +	 * locking inversion with the driver load path. And the access here is
> +	 * completely racy anyway. So don't bother with locking for now.
> +	 */
> +	return dev->open_count == 0;
> +}
> +
> +static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
> +	.set_gpu_state = i915_switcheroo_set_state,
> +	.reprobe = NULL,
> +	.can_switch = i915_switcheroo_can_switch,
> +};
> +
> +static void i915_gem_fini(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +
> +	/*
> +	 * Neither the BIOS, ourselves or any other kernel
> +	 * expects the system to be in execlists mode on startup,
> +	 * so we need to reset the GPU back to legacy mode. And the only
> +	 * known way to disable logical contexts is through a GPU reset.
> +	 *
> +	 * So in order to leave the system in a known default configuration,
> +	 * always reset the GPU upon unload. Afterwards we then clean up the
> +	 * GEM state tracking, flushing off the requests and leaving the
> +	 * system in a known idle state.
> +	 *
> +	 * Note that is of the upmost importance that the GPU is idle and
> +	 * all stray writes are flushed *before* we dismantle the backing
> +	 * storage for the pinned objects.
> +	 *
> +	 * However, since we are uncertain that reseting the GPU on older
> +	 * machines is a good idea, we don't - just in case it leaves the
> +	 * machine in an unusable condition.
> +	 */
> +	if (HAS_HW_CONTEXTS(dev)) {
> +		int reset = intel_gpu_reset(dev_priv, ALL_ENGINES);
> +		WARN_ON(reset && reset != -ENODEV);
> +	}
> +
> +	mutex_lock(&dev->struct_mutex);
> +	i915_gem_reset(dev);
> +	i915_gem_cleanup_engines(dev);
> +	i915_gem_context_fini(dev);
> +	mutex_unlock(&dev->struct_mutex);
> +
> +	WARN_ON(!list_empty(&to_i915(dev)->context_list));
> +}
> +
> +static int i915_load_modeset_init(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	int ret;
> +
> +	if (i915_inject_load_failure())
> +		return -ENODEV;
> +
> +	ret = intel_bios_init(dev_priv);
> +	if (ret)
> +		DRM_INFO("failed to find VBIOS tables\n");
> +
> +	/* If we have > 1 VGA cards, then we need to arbitrate access
> +	 * to the common VGA resources.
> +	 *
> +	 * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA),
> +	 * then we do not take part in VGA arbitration and the
> +	 * vga_client_register() fails with -ENODEV.
> +	 */
> +	ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
> +	if (ret && ret != -ENODEV)
> +		goto out;
> +
> +	intel_register_dsm_handler();
> +
> +	ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops, false);
> +	if (ret)
> +		goto cleanup_vga_client;
> +
> +	/* must happen before intel_power_domains_init_hw() on VLV/CHV */
> +	intel_update_rawclk(dev_priv);
> +
> +	intel_power_domains_init_hw(dev_priv, false);
> +
> +	intel_csr_ucode_init(dev_priv);
> +
> +	ret = intel_irq_install(dev_priv);
> +	if (ret)
> +		goto cleanup_csr;
> +
> +	intel_setup_gmbus(dev);
> +
> +	/* Important: The output setup functions called by modeset_init need
> +	 * working irqs for e.g. gmbus and dp aux transfers. */
> +	intel_modeset_init(dev);
> +
> +	intel_guc_init(dev);
> +
> +	ret = i915_gem_init(dev);
> +	if (ret)
> +		goto cleanup_irq;
> +
> +	intel_modeset_gem_init(dev);
> +
> +	if (INTEL_INFO(dev)->num_pipes == 0)
> +		return 0;
> +
> +	ret = intel_fbdev_init(dev);
> +	if (ret)
> +		goto cleanup_gem;
> +
> +	/* Only enable hotplug handling once the fbdev is fully set up. */
> +	intel_hpd_init(dev_priv);
> +
> +	drm_kms_helper_poll_init(dev);
> +
> +	return 0;
> +
> +cleanup_gem:
> +	i915_gem_fini(dev);
> +cleanup_irq:
> +	intel_guc_fini(dev);
> +	drm_irq_uninstall(dev);
> +	intel_teardown_gmbus(dev);
> +cleanup_csr:
> +	intel_csr_ucode_fini(dev_priv);
> +	intel_power_domains_fini(dev_priv);
> +	vga_switcheroo_unregister_client(dev->pdev);
> +cleanup_vga_client:
> +	vga_client_register(dev->pdev, NULL, NULL, NULL);
> +out:
> +	return ret;
> +}
> +
> +#if IS_ENABLED(CONFIG_FB)
> +static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
> +{
> +	struct apertures_struct *ap;
> +	struct pci_dev *pdev = dev_priv->dev->pdev;
> +	struct i915_ggtt *ggtt = &dev_priv->ggtt;
> +	bool primary;
> +	int ret;
> +
> +	ap = alloc_apertures(1);
> +	if (!ap)
> +		return -ENOMEM;
> +
> +	ap->ranges[0].base = ggtt->mappable_base;
> +	ap->ranges[0].size = ggtt->mappable_end;
> +
> +	primary =
> +		pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
> +
> +	ret = remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
> +
> +	kfree(ap);
> +
> +	return ret;
> +}
> +#else
> +static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
> +{
> +	return 0;
> +}
> +#endif
> +
> +#if !defined(CONFIG_VGA_CONSOLE)
> +static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
> +{
> +	return 0;
> +}
> +#elif !defined(CONFIG_DUMMY_CONSOLE)
> +static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
> +{
> +	return -ENODEV;
> +}
> +#else
> +static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
> +{
> +	int ret = 0;
> +
> +	DRM_INFO("Replacing VGA console driver\n");
> +
> +	console_lock();
> +	if (con_is_bound(&vga_con))
> +		ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
> +	if (ret == 0) {
> +		ret = do_unregister_con_driver(&vga_con);
> +
> +		/* Ignore "already unregistered". */
> +		if (ret == -ENODEV)
> +			ret = 0;
> +	}
> +	console_unlock();
> +
> +	return ret;
> +}
> +#endif
> +
> +static void i915_dump_device_info(struct drm_i915_private *dev_priv)
> +{
> +	const struct intel_device_info *info = &dev_priv->info;
> +
> +#define PRINT_S(name) "%s"
> +#define SEP_EMPTY
> +#define PRINT_FLAG(name) info->name ? #name "," : ""
> +#define SEP_COMMA ,
> +	DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x rev=0x%02x flags="
> +			 DEV_INFO_FOR_EACH_FLAG(PRINT_S, SEP_EMPTY),
> +			 info->gen,
> +			 dev_priv->dev->pdev->device,
> +			 dev_priv->dev->pdev->revision,
> +			 DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA));
> +#undef PRINT_S
> +#undef SEP_EMPTY
> +#undef PRINT_FLAG
> +#undef SEP_COMMA
> +}
> +
> +static void cherryview_sseu_info_init(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_device_info *info;
> +	u32 fuse, eu_dis;
> +
> +	info = (struct intel_device_info *)&dev_priv->info;
> +	fuse = I915_READ(CHV_FUSE_GT);
> +
> +	info->slice_total = 1;
> +
> +	if (!(fuse & CHV_FGT_DISABLE_SS0)) {
> +		info->subslice_per_slice++;
> +		eu_dis = fuse & (CHV_FGT_EU_DIS_SS0_R0_MASK |
> +				 CHV_FGT_EU_DIS_SS0_R1_MASK);
> +		info->eu_total += 8 - hweight32(eu_dis);
> +	}
> +
> +	if (!(fuse & CHV_FGT_DISABLE_SS1)) {
> +		info->subslice_per_slice++;
> +		eu_dis = fuse & (CHV_FGT_EU_DIS_SS1_R0_MASK |
> +				 CHV_FGT_EU_DIS_SS1_R1_MASK);
> +		info->eu_total += 8 - hweight32(eu_dis);
> +	}
> +
> +	info->subslice_total = info->subslice_per_slice;
> +	/*
> +	 * CHV expected to always have a uniform distribution of EU
> +	 * across subslices.
> +	*/
> +	info->eu_per_subslice = info->subslice_total ?
> +				info->eu_total / info->subslice_total :
> +				0;
> +	/*
> +	 * CHV supports subslice power gating on devices with more than
> +	 * one subslice, and supports EU power gating on devices with
> +	 * more than one EU pair per subslice.
> +	*/
> +	info->has_slice_pg = 0;
> +	info->has_subslice_pg = (info->subslice_total > 1);
> +	info->has_eu_pg = (info->eu_per_subslice > 2);
> +}
> +
> +static void gen9_sseu_info_init(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_device_info *info;
> +	int s_max = 3, ss_max = 4, eu_max = 8;
> +	int s, ss;
> +	u32 fuse2, s_enable, ss_disable, eu_disable;
> +	u8 eu_mask = 0xff;
> +
> +	info = (struct intel_device_info *)&dev_priv->info;
> +	fuse2 = I915_READ(GEN8_FUSE2);
> +	s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >>
> +		   GEN8_F2_S_ENA_SHIFT;
> +	ss_disable = (fuse2 & GEN9_F2_SS_DIS_MASK) >>
> +		     GEN9_F2_SS_DIS_SHIFT;
> +
> +	info->slice_total = hweight32(s_enable);
> +	/*
> +	 * The subslice disable field is global, i.e. it applies
> +	 * to each of the enabled slices.
> +	*/
> +	info->subslice_per_slice = ss_max - hweight32(ss_disable);
> +	info->subslice_total = info->slice_total *
> +			       info->subslice_per_slice;
> +
> +	/*
> +	 * Iterate through enabled slices and subslices to
> +	 * count the total enabled EU.
> +	*/
> +	for (s = 0; s < s_max; s++) {
> +		if (!(s_enable & (0x1 << s)))
> +			/* skip disabled slice */
> +			continue;
> +
> +		eu_disable = I915_READ(GEN9_EU_DISABLE(s));
> +		for (ss = 0; ss < ss_max; ss++) {
> +			int eu_per_ss;
> +
> +			if (ss_disable & (0x1 << ss))
> +				/* skip disabled subslice */
> +				continue;
> +
> +			eu_per_ss = eu_max - hweight8((eu_disable >> (ss*8)) &
> +						      eu_mask);
> +
> +			/*
> +			 * Record which subslice(s) has(have) 7 EUs. we
> +			 * can tune the hash used to spread work among
> +			 * subslices if they are unbalanced.
> +			 */
> +			if (eu_per_ss == 7)
> +				info->subslice_7eu[s] |= 1 << ss;
> +
> +			info->eu_total += eu_per_ss;
> +		}
> +	}
> +
> +	/*
> +	 * SKL is expected to always have a uniform distribution
> +	 * of EU across subslices with the exception that any one
> +	 * EU in any one subslice may be fused off for die
> +	 * recovery. BXT is expected to be perfectly uniform in EU
> +	 * distribution.
> +	*/
> +	info->eu_per_subslice = info->subslice_total ?
> +				DIV_ROUND_UP(info->eu_total,
> +					     info->subslice_total) : 0;
> +	/*
> +	 * SKL supports slice power gating on devices with more than
> +	 * one slice, and supports EU power gating on devices with
> +	 * more than one EU pair per subslice. BXT supports subslice
> +	 * power gating on devices with more than one subslice, and
> +	 * supports EU power gating on devices with more than one EU
> +	 * pair per subslice.
> +	*/
> +	info->has_slice_pg = ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) &&
> +			       (info->slice_total > 1));
> +	info->has_subslice_pg = (IS_BROXTON(dev) && (info->subslice_total > 1));
> +	info->has_eu_pg = (info->eu_per_subslice > 2);
> +}
> +
> +static void broadwell_sseu_info_init(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_device_info *info;
> +	const int s_max = 3, ss_max = 3, eu_max = 8;
> +	int s, ss;
> +	u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
> +
> +	fuse2 = I915_READ(GEN8_FUSE2);
> +	s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
> +	ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT;
> +
> +	eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK;
> +	eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) |
> +			((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) <<
> +			 (32 - GEN8_EU_DIS0_S1_SHIFT));
> +	eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) |
> +			((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) <<
> +			 (32 - GEN8_EU_DIS1_S2_SHIFT));
> +
> +
> +	info = (struct intel_device_info *)&dev_priv->info;
> +	info->slice_total = hweight32(s_enable);
> +
> +	/*
> +	 * The subslice disable field is global, i.e. it applies
> +	 * to each of the enabled slices.
> +	 */
> +	info->subslice_per_slice = ss_max - hweight32(ss_disable);
> +	info->subslice_total = info->slice_total * info->subslice_per_slice;
> +
> +	/*
> +	 * Iterate through enabled slices and subslices to
> +	 * count the total enabled EU.
> +	 */
> +	for (s = 0; s < s_max; s++) {
> +		if (!(s_enable & (0x1 << s)))
> +			/* skip disabled slice */
> +			continue;
> +
> +		for (ss = 0; ss < ss_max; ss++) {
> +			u32 n_disabled;
> +
> +			if (ss_disable & (0x1 << ss))
> +				/* skip disabled subslice */
> +				continue;
> +
> +			n_disabled = hweight8(eu_disable[s] >> (ss * eu_max));
> +
> +			/*
> +			 * Record which subslices have 7 EUs.
> +			 */
> +			if (eu_max - n_disabled == 7)
> +				info->subslice_7eu[s] |= 1 << ss;
> +
> +			info->eu_total += eu_max - n_disabled;
> +		}
> +	}
> +
> +	/*
> +	 * BDW is expected to always have a uniform distribution of EU across
> +	 * subslices with the exception that any one EU in any one subslice may
> +	 * be fused off for die recovery.
> +	 */
> +	info->eu_per_subslice = info->subslice_total ?
> +		DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
> +
> +	/*
> +	 * BDW supports slice power gating on devices with more than
> +	 * one slice.
> +	 */
> +	info->has_slice_pg = (info->slice_total > 1);
> +	info->has_subslice_pg = 0;
> +	info->has_eu_pg = 0;
> +}
> +
> +/*
> + * Determine various intel_device_info fields at runtime.
> + *
> + * Use it when either:
> + *   - it's judged too laborious to fill n static structures with the limit
> + *     when a simple if statement does the job,
> + *   - run-time checks (eg read fuse/strap registers) are needed.
> + *
> + * This function needs to be called:
> + *   - after the MMIO has been setup as we are reading registers,
> + *   - after the PCH has been detected,
> + *   - before the first usage of the fields it can tweak.
> + */
> +static void intel_device_info_runtime_init(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_device_info *info;
> +	enum pipe pipe;
> +
> +	info = (struct intel_device_info *)&dev_priv->info;
> +
> +	/*
> +	 * Skylake and Broxton currently don't expose the topmost plane as its
> +	 * use is exclusive with the legacy cursor and we only want to expose
> +	 * one of those, not both. Until we can safely expose the topmost plane
> +	 * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported,
> +	 * we don't expose the topmost plane at all to prevent ABI breakage
> +	 * down the line.
> +	 */
> +	if (IS_BROXTON(dev)) {
> +		info->num_sprites[PIPE_A] = 2;
> +		info->num_sprites[PIPE_B] = 2;
> +		info->num_sprites[PIPE_C] = 1;
> +	} else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev))
> +		for_each_pipe(dev_priv, pipe)
> +			info->num_sprites[pipe] = 2;
> +	else
> +		for_each_pipe(dev_priv, pipe)
> +			info->num_sprites[pipe] = 1;
> +
> +	if (i915.disable_display) {
> +		DRM_INFO("Display disabled (module parameter)\n");
> +		info->num_pipes = 0;
> +	} else if (info->num_pipes > 0 &&
> +		   (IS_GEN7(dev_priv) || IS_GEN8(dev_priv)) &&
> +		   HAS_PCH_SPLIT(dev)) {
> +		u32 fuse_strap = I915_READ(FUSE_STRAP);
> +		u32 sfuse_strap = I915_READ(SFUSE_STRAP);
> +
> +		/*
> +		 * SFUSE_STRAP is supposed to have a bit signalling the display
> +		 * is fused off. Unfortunately it seems that, at least in
> +		 * certain cases, fused off display means that PCH display
> +		 * reads don't land anywhere. In that case, we read 0s.
> +		 *
> +		 * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK
> +		 * should be set when taking over after the firmware.
> +		 */
> +		if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
> +		    sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
> +		    (dev_priv->pch_type == PCH_CPT &&
> +		     !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
> +			DRM_INFO("Display fused off, disabling\n");
> +			info->num_pipes = 0;
> +		} else if (fuse_strap & IVB_PIPE_C_DISABLE) {
> +			DRM_INFO("PipeC fused off\n");
> +			info->num_pipes -= 1;
> +		}
> +	} else if (info->num_pipes > 0 && IS_GEN9(dev_priv)) {
> +		u32 dfsm = I915_READ(SKL_DFSM);
> +		u8 disabled_mask = 0;
> +		bool invalid;
> +		int num_bits;
> +
> +		if (dfsm & SKL_DFSM_PIPE_A_DISABLE)
> +			disabled_mask |= BIT(PIPE_A);
> +		if (dfsm & SKL_DFSM_PIPE_B_DISABLE)
> +			disabled_mask |= BIT(PIPE_B);
> +		if (dfsm & SKL_DFSM_PIPE_C_DISABLE)
> +			disabled_mask |= BIT(PIPE_C);
> +
> +		num_bits = hweight8(disabled_mask);
> +
> +		switch (disabled_mask) {
> +		case BIT(PIPE_A):
> +		case BIT(PIPE_B):
> +		case BIT(PIPE_A) | BIT(PIPE_B):
> +		case BIT(PIPE_A) | BIT(PIPE_C):
> +			invalid = true;
> +			break;
> +		default:
> +			invalid = false;
> +		}
> +
> +		if (num_bits > info->num_pipes || invalid)
> +			DRM_ERROR("invalid pipe fuse configuration: 0x%x\n",
> +				  disabled_mask);
> +		else
> +			info->num_pipes -= num_bits;
> +	}
> +
> +	/* Initialize slice/subslice/EU info */
> +	if (IS_CHERRYVIEW(dev))
> +		cherryview_sseu_info_init(dev);
> +	else if (IS_BROADWELL(dev))
> +		broadwell_sseu_info_init(dev);
> +	else if (INTEL_INFO(dev)->gen >= 9)
> +		gen9_sseu_info_init(dev);
> +
> +	info->has_snoop = !info->has_llc;
> +
> +	/* Snooping is broken on BXT A stepping. */
> +	if (IS_BXT_REVID(dev, 0, BXT_REVID_A1))
> +		info->has_snoop = false;
> +
> +	DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total);
> +	DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total);
> +	DRM_DEBUG_DRIVER("subslice per slice: %u\n", info->subslice_per_slice);
> +	DRM_DEBUG_DRIVER("EU total: %u\n", info->eu_total);
> +	DRM_DEBUG_DRIVER("EU per subslice: %u\n", info->eu_per_subslice);
> +	DRM_DEBUG_DRIVER("has slice power gating: %s\n",
> +			 info->has_slice_pg ? "y" : "n");
> +	DRM_DEBUG_DRIVER("has subslice power gating: %s\n",
> +			 info->has_subslice_pg ? "y" : "n");
> +	DRM_DEBUG_DRIVER("has EU power gating: %s\n",
> +			 info->has_eu_pg ? "y" : "n");
> +
> +	i915.enable_execlists =
> +		intel_sanitize_enable_execlists(dev_priv,
> +					       	i915.enable_execlists);
> +
> +	/*
> +	 * i915.enable_ppgtt is read-only, so do an early pass to validate the
> +	 * user's requested state against the hardware/driver capabilities.  We
> +	 * do this now so that we can print out any log messages once rather
> +	 * than every time we check intel_enable_ppgtt().
> +	 */
> +	i915.enable_ppgtt =
> +		intel_sanitize_enable_ppgtt(dev_priv, i915.enable_ppgtt);
> +	DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt);
> +}
> +
> +static void intel_init_dpio(struct drm_i915_private *dev_priv)
> +{
> +	/*
> +	 * IOSF_PORT_DPIO is used for VLV x2 PHY (DP/HDMI B and C),
> +	 * CHV x1 PHY (DP/HDMI D)
> +	 * IOSF_PORT_DPIO_2 is used for CHV x2 PHY (DP/HDMI B and C)
> +	 */
> +	if (IS_CHERRYVIEW(dev_priv)) {
> +		DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO_2;
> +		DPIO_PHY_IOSF_PORT(DPIO_PHY1) = IOSF_PORT_DPIO;
> +	} else if (IS_VALLEYVIEW(dev_priv)) {
> +		DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO;
> +	}
> +}
> +
> +static int i915_workqueues_init(struct drm_i915_private *dev_priv)
> +{
> +	/*
> +	 * The i915 workqueue is primarily used for batched retirement of
> +	 * requests (and thus managing bo) once the task has been completed
> +	 * by the GPU. i915_gem_retire_requests() is called directly when we
> +	 * need high-priority retirement, such as waiting for an explicit
> +	 * bo.
> +	 *
> +	 * It is also used for periodic low-priority events, such as
> +	 * idle-timers and recording error state.
> +	 *
> +	 * All tasks on the workqueue are expected to acquire the dev mutex
> +	 * so there is no point in running more than one instance of the
> +	 * workqueue at any time.  Use an ordered one.
> +	 */
> +	dev_priv->wq = alloc_ordered_workqueue("i915", 0);
> +	if (dev_priv->wq == NULL)
> +		goto out_err;
> +
> +	dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0);
> +	if (dev_priv->hotplug.dp_wq == NULL)
> +		goto out_free_wq;
> +
> +	dev_priv->gpu_error.hangcheck_wq =
> +		alloc_ordered_workqueue("i915-hangcheck", 0);
> +	if (dev_priv->gpu_error.hangcheck_wq == NULL)
> +		goto out_free_dp_wq;
> +
> +	return 0;
> +
> +out_free_dp_wq:
> +	destroy_workqueue(dev_priv->hotplug.dp_wq);
> +out_free_wq:
> +	destroy_workqueue(dev_priv->wq);
> +out_err:
> +	DRM_ERROR("Failed to allocate workqueues.\n");
> +
> +	return -ENOMEM;
> +}
> +
> +static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv)
> +{
> +	destroy_workqueue(dev_priv->gpu_error.hangcheck_wq);
> +	destroy_workqueue(dev_priv->hotplug.dp_wq);
> +	destroy_workqueue(dev_priv->wq);
> +}
> +
> +/**
> + * i915_driver_init_early - setup state not requiring device access
> + * @dev_priv: device private
> + *
> + * Initialize everything that is a "SW-only" state, that is state not
> + * requiring accessing the device or exposing the driver via kernel internal
> + * or userspace interfaces. Example steps belonging here: lock initialization,
> + * system memory allocation, setting up device specific attributes and
> + * function hooks not requiring accessing the device.
> + */
> +static int i915_driver_init_early(struct drm_i915_private *dev_priv,
> +				  const struct pci_device_id *ent)
> +{
> +	const struct intel_device_info *match_info =
> +		(struct intel_device_info *)ent->driver_data;
> +	struct intel_device_info *device_info;
> +	int ret = 0;
> +
> +	if (i915_inject_load_failure())
> +		return -ENODEV;
> +
> +	/* Setup the write-once "constant" device info */
> +	device_info = (struct intel_device_info *)&dev_priv->info;
> +	memcpy(device_info, match_info, sizeof(*device_info));
> +	device_info->device_id = dev_priv->drm.pdev->device;
> +
> +	BUG_ON(device_info->gen > sizeof(device_info->gen_mask) * BITS_PER_BYTE);
> +	device_info->gen_mask = BIT(device_info->gen - 1);
> +
> +	spin_lock_init(&dev_priv->irq_lock);
> +	spin_lock_init(&dev_priv->gpu_error.lock);
> +	mutex_init(&dev_priv->backlight_lock);
> +	spin_lock_init(&dev_priv->uncore.lock);
> +	spin_lock_init(&dev_priv->mm.object_stat_lock);
> +	spin_lock_init(&dev_priv->mmio_flip_lock);
> +	mutex_init(&dev_priv->sb_lock);
> +	mutex_init(&dev_priv->modeset_restore_lock);
> +	mutex_init(&dev_priv->av_mutex);
> +	mutex_init(&dev_priv->wm.wm_mutex);
> +	mutex_init(&dev_priv->pps_mutex);
> +
> +	ret = i915_workqueues_init(dev_priv);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* This must be called before any calls to HAS_PCH_* */
> +	intel_detect_pch(&dev_priv->drm);
> +
> +	intel_pm_setup(&dev_priv->drm);
> +	intel_init_dpio(dev_priv);
> +	intel_power_domains_init(dev_priv);
> +	intel_irq_init(dev_priv);
> +	intel_init_display_hooks(dev_priv);
> +	intel_init_clock_gating_hooks(dev_priv);
> +	intel_init_audio_hooks(dev_priv);
> +	i915_gem_load_init(&dev_priv->drm);
> +
> +	intel_display_crc_init(&dev_priv->drm);
> +
> +	i915_dump_device_info(dev_priv);
> +
> +	/* Not all pre-production machines fall into this category, only the
> +	 * very first ones. Almost everything should work, except for maybe
> +	 * suspend/resume. And we don't implement workarounds that affect only
> +	 * pre-production machines. */
> +	if (IS_HSW_EARLY_SDV(dev_priv))
> +		DRM_INFO("This is an early pre-production Haswell machine. "
> +			 "It may not be fully functional.\n");
> +
> +	return 0;
> +}
> +
> +/**
> + * i915_driver_cleanup_early - cleanup the setup done in i915_driver_init_early()
> + * @dev_priv: device private
> + */
> +static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
> +{
> +	i915_gem_load_cleanup(dev_priv->dev);
> +	i915_workqueues_cleanup(dev_priv);
> +}
> +
> +static int i915_mmio_setup(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +	int mmio_bar;
> +	int mmio_size;
> +
> +	mmio_bar = IS_GEN2(dev) ? 1 : 0;
> +	/*
> +	 * Before gen4, the registers and the GTT are behind different BARs.
> +	 * However, from gen4 onwards, the registers and the GTT are shared
> +	 * in the same BAR, so we want to restrict this ioremap from
> +	 * clobbering the GTT which we want ioremap_wc instead. Fortunately,
> +	 * the register BAR remains the same size for all the earlier
> +	 * generations up to Ironlake.
> +	 */
> +	if (INTEL_INFO(dev)->gen < 5)
> +		mmio_size = 512 * 1024;
> +	else
> +		mmio_size = 2 * 1024 * 1024;
> +	dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size);
> +	if (dev_priv->regs == NULL) {
> +		DRM_ERROR("failed to map registers\n");
> +
> +		return -EIO;
> +	}
> +
> +	/* Try to make sure MCHBAR is enabled before poking at it */
> +	intel_setup_mchbar(dev);
> +
> +	return 0;
> +}
> +
> +static void i915_mmio_cleanup(struct drm_device *dev)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(dev);
> +
> +	intel_teardown_mchbar(dev);
> +	pci_iounmap(dev->pdev, dev_priv->regs);
> +}
> +
> +/**
> + * i915_driver_init_mmio - setup device MMIO
> + * @dev_priv: device private
> + *
> + * Setup minimal device state necessary for MMIO accesses later in the
> + * initialization sequence. The setup here should avoid any other device-wide
> + * side effects or exposing the driver via kernel internal or user space
> + * interfaces.
> + */
> +static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	int ret;
> +
> +	if (i915_inject_load_failure())
> +		return -ENODEV;
> +
> +	if (i915_get_bridge_dev(dev))
> +		return -EIO;
> +
> +	ret = i915_mmio_setup(dev);
> +	if (ret < 0)
> +		goto put_bridge;
> +
> +	intel_uncore_init(dev_priv);
> +
> +	return 0;
> +
> +put_bridge:
> +	pci_dev_put(dev_priv->bridge_dev);
> +
> +	return ret;
> +}
> +
> +/**
> + * i915_driver_cleanup_mmio - cleanup the setup done in i915_driver_init_mmio()
> + * @dev_priv: device private
> + */
> +static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +
> +	intel_uncore_fini(dev_priv);
> +	i915_mmio_cleanup(dev);
> +	pci_dev_put(dev_priv->bridge_dev);
> +}
> +
> +/**
> + * i915_driver_init_hw - setup state requiring device access
> + * @dev_priv: device private
> + *
> + * Setup state that requires accessing the device, but doesn't require
> + * exposing the driver via kernel internal or userspace interfaces.
> + */
> +static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	struct i915_ggtt *ggtt = &dev_priv->ggtt;
> +	uint32_t aperture_size;
> +	int ret;
> +
> +	if (i915_inject_load_failure())
> +		return -ENODEV;
> +
> +	intel_device_info_runtime_init(dev);
> +
> +	ret = i915_ggtt_init_hw(dev);
> +	if (ret)
> +		return ret;
> +
> +	ret = i915_ggtt_enable_hw(dev);
> +	if (ret) {
> +		DRM_ERROR("failed to enable GGTT\n");
> +		goto out_ggtt;
> +	}
> +
> +	/* WARNING: Apparently we must kick fbdev drivers before vgacon,
> +	 * otherwise the vga fbdev driver falls over. */
> +	ret = i915_kick_out_firmware_fb(dev_priv);
> +	if (ret) {
> +		DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
> +		goto out_ggtt;
> +	}
> +
> +	ret = i915_kick_out_vgacon(dev_priv);
> +	if (ret) {
> +		DRM_ERROR("failed to remove conflicting VGA console\n");
> +		goto out_ggtt;
> +	}
> +
> +	pci_set_master(dev->pdev);
> +
> +	/* overlay on gen2 is broken and can't address above 1G */
> +	if (IS_GEN2(dev)) {
> +		ret = dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
> +		if (ret) {
> +			DRM_ERROR("failed to set DMA mask\n");
> +
> +			goto out_ggtt;
> +		}
> +	}
> +
> +
> +	/* 965GM sometimes incorrectly writes to hardware status page (HWS)
> +	 * using 32bit addressing, overwriting memory if HWS is located
> +	 * above 4GB.
> +	 *
> +	 * The documentation also mentions an issue with undefined
> +	 * behaviour if any general state is accessed within a page above 4GB,
> +	 * which also needs to be handled carefully.
> +	 */
> +	if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) {
> +		ret = dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32));
> +
> +		if (ret) {
> +			DRM_ERROR("failed to set DMA mask\n");
> +
> +			goto out_ggtt;
> +		}
> +	}
> +
> +	aperture_size = ggtt->mappable_end;
> +
> +	ggtt->mappable =
> +		io_mapping_create_wc(ggtt->mappable_base,
> +				     aperture_size);
> +	if (!ggtt->mappable) {
> +		ret = -EIO;
> +		goto out_ggtt;
> +	}
> +
> +	ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base,
> +					      aperture_size);
> +
> +	pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY,
> +			   PM_QOS_DEFAULT_VALUE);
> +
> +	intel_uncore_sanitize(dev_priv);
> +
> +	intel_opregion_setup(dev_priv);
> +
> +	i915_gem_load_init_fences(dev_priv);
> +
> +	/* On the 945G/GM, the chipset reports the MSI capability on the
> +	 * integrated graphics even though the support isn't actually there
> +	 * according to the published specs.  It doesn't appear to function
> +	 * correctly in testing on 945G.
> +	 * This may be a side effect of MSI having been made available for PEG
> +	 * and the registers being closely associated.
> +	 *
> +	 * According to chipset errata, on the 965GM, MSI interrupts may
> +	 * be lost or delayed, but we use them anyways to avoid
> +	 * stuck interrupts on some machines.
> +	 */
> +	if (!IS_I945G(dev) && !IS_I945GM(dev)) {
> +		if (pci_enable_msi(dev->pdev) < 0)
> +			DRM_DEBUG_DRIVER("can't enable MSI");
> +	}
> +
> +	return 0;
> +
> +out_ggtt:
> +	i915_ggtt_cleanup_hw(dev);
> +
> +	return ret;
> +}
> +
> +/**
> + * i915_driver_cleanup_hw - cleanup the setup done in i915_driver_init_hw()
> + * @dev_priv: device private
> + */
> +static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +	struct i915_ggtt *ggtt = &dev_priv->ggtt;
> +
> +	if (dev->pdev->msi_enabled)
> +		pci_disable_msi(dev->pdev);
> +
> +	pm_qos_remove_request(&dev_priv->pm_qos);
> +	arch_phys_wc_del(ggtt->mtrr);
> +	io_mapping_free(ggtt->mappable);
> +	i915_ggtt_cleanup_hw(dev);
> +}
> +
> +/**
> + * i915_driver_register - register the driver with the rest of the system
> + * @dev_priv: device private
> + *
> + * Perform any steps necessary to make the driver available via kernel
> + * internal or userspace interfaces.
> + */
> +static void i915_driver_register(struct drm_i915_private *dev_priv)
> +{
> +	struct drm_device *dev = dev_priv->dev;
> +
> +	i915_gem_shrinker_init(dev_priv);
>  
> -static const struct intel_device_info intel_broxton_info = {
> -	.is_preliminary = 1,
> -	.is_broxton = 1,
> -	.gen = 9,
> -	.need_gfx_hws = 1, .has_hotplug = 1,
> -	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
> -	.num_pipes = 3,
> -	.has_ddi = 1,
> -	.has_fpga_dbg = 1,
> -	.has_fbc = 1,
> -	GEN_DEFAULT_PIPEOFFSETS,
> -	IVB_CURSOR_OFFSETS,
> -	BDW_COLORS,
> -};
> +	/*
> +	 * Notify a valid surface after modesetting,
> +	 * when running inside a VM.
> +	 */
> +	if (intel_vgpu_active(dev_priv))
> +		I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY);
> +
> +	/* Reveal our presence to userspace */
> +	if (drm_dev_register(dev, 0) == 0) {
> +		i915_debugfs_register(dev_priv);
> +		i915_setup_sysfs(dev);
> +		intel_modeset_register(dev_priv);
> +	} else
> +		DRM_ERROR("Failed to register driver for userspace access!\n");
> +
> +	if (INTEL_INFO(dev_priv)->num_pipes) {
> +		/* Must be done after probing outputs */
> +		intel_opregion_register(dev_priv);
> +		acpi_video_register();
> +	}
>  
> -static const struct intel_device_info intel_kabylake_info = {
> -	BDW_FEATURES,
> -	.is_kabylake = 1,
> -	.gen = 9,
> -};
> +	if (IS_GEN5(dev_priv))
> +		intel_gpu_ips_init(dev_priv);
>  
> -static const struct intel_device_info intel_kabylake_gt3_info = {
> -	BDW_FEATURES,
> -	.is_kabylake = 1,
> -	.gen = 9,
> -	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
> -};
> +	i915_audio_component_init(dev_priv);
>  
> -/*
> - * Make sure any device matches here are from most specific to most
> - * general.  For example, since the Quanta match is based on the subsystem
> - * and subvendor IDs, we need it to come before the more general IVB
> - * PCI ID matches, otherwise we'll use the wrong info struct above.
> +	/*
> +	 * Some ports require correctly set-up hpd registers for detection to
> +	 * work properly (leading to ghost connected connector status), e.g. VGA
> +	 * on gm45.  Hence we can only set up the initial fbdev config after hpd
> +	 * irqs are fully enabled. Now we should scan for the initial config
> +	 * only once hotplug handling is enabled, but due to screwed-up locking
> +	 * around kms/fbdev init we can't protect the fdbev initial config
> +	 * scanning against hotplug events. Hence do this first and ignore the
> +	 * tiny window where we will loose hotplug notifactions.
> +	 */
> +	intel_fbdev_initial_config_async(dev);
> +}
> +
> +/**
> + * i915_driver_unregister - cleanup the registration done in i915_driver_regiser()
> + * @dev_priv: device private
>   */
> -static const struct pci_device_id pciidlist[] = {
> -	INTEL_I830_IDS(&intel_i830_info),
> -	INTEL_I845G_IDS(&intel_845g_info),
> -	INTEL_I85X_IDS(&intel_i85x_info),
> -	INTEL_I865G_IDS(&intel_i865g_info),
> -	INTEL_I915G_IDS(&intel_i915g_info),
> -	INTEL_I915GM_IDS(&intel_i915gm_info),
> -	INTEL_I945G_IDS(&intel_i945g_info),
> -	INTEL_I945GM_IDS(&intel_i945gm_info),
> -	INTEL_I965G_IDS(&intel_i965g_info),
> -	INTEL_G33_IDS(&intel_g33_info),
> -	INTEL_I965GM_IDS(&intel_i965gm_info),
> -	INTEL_GM45_IDS(&intel_gm45_info),
> -	INTEL_G45_IDS(&intel_g45_info),
> -	INTEL_PINEVIEW_IDS(&intel_pineview_info),
> -	INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info),
> -	INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info),
> -	INTEL_SNB_D_IDS(&intel_sandybridge_d_info),
> -	INTEL_SNB_M_IDS(&intel_sandybridge_m_info),
> -	INTEL_IVB_Q_IDS(&intel_ivybridge_q_info), /* must be first IVB */
> -	INTEL_IVB_M_IDS(&intel_ivybridge_m_info),
> -	INTEL_IVB_D_IDS(&intel_ivybridge_d_info),
> -	INTEL_HSW_D_IDS(&intel_haswell_d_info),
> -	INTEL_HSW_M_IDS(&intel_haswell_m_info),
> -	INTEL_VLV_M_IDS(&intel_valleyview_m_info),
> -	INTEL_VLV_D_IDS(&intel_valleyview_d_info),
> -	INTEL_BDW_GT12M_IDS(&intel_broadwell_m_info),
> -	INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info),
> -	INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info),
> -	INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info),
> -	INTEL_CHV_IDS(&intel_cherryview_info),
> -	INTEL_SKL_GT1_IDS(&intel_skylake_info),
> -	INTEL_SKL_GT2_IDS(&intel_skylake_info),
> -	INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info),
> -	INTEL_SKL_GT4_IDS(&intel_skylake_gt3_info),
> -	INTEL_BXT_IDS(&intel_broxton_info),
> -	INTEL_KBL_GT1_IDS(&intel_kabylake_info),
> -	INTEL_KBL_GT2_IDS(&intel_kabylake_info),
> -	INTEL_KBL_GT3_IDS(&intel_kabylake_gt3_info),
> -	INTEL_KBL_GT4_IDS(&intel_kabylake_gt3_info),
> -	{0, 0, 0}
> -};
> +static void i915_driver_unregister(struct drm_i915_private *dev_priv)
> +{
> +	i915_audio_component_cleanup(dev_priv);
>  
> -MODULE_DEVICE_TABLE(pci, pciidlist);
> +	intel_gpu_ips_teardown();
> +	acpi_video_unregister();
> +	intel_opregion_unregister(dev_priv);
>  
> -static enum intel_pch intel_virt_detect_pch(struct drm_device *dev)
> +	intel_modeset_unregister(dev_priv);
> +	i915_teardown_sysfs(dev_priv->dev);
> +	i915_debugfs_unregister(dev_priv);
> +	drm_dev_unregister(dev_priv->dev);
> +
> +	i915_gem_shrinker_cleanup(dev_priv);
> +}
> +
> +/**
> + * i915_driver_load - setup chip and create an initial config
> + * @dev: DRM device
> + * @flags: startup flags
> + *
> + * The driver load routine has to do several things:
> + *   - drive output discovery via intel_modeset_init()
> + *   - initialize the memory manager
> + *   - allocate initial config memory
> + *   - setup the DRM framebuffer with the allocated memory
> + */
> +static int i915_driver_load(struct pci_dev *pdev,
> +			    const struct pci_device_id *ent)
>  {
> -	enum intel_pch ret = PCH_NOP;
> +	struct drm_i915_private *dev_priv;
> +	int ret;
> +
> +	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
> +	if (dev_priv == NULL)
> +		return -ENOMEM;
> +
> +	ret = drm_dev_init(&dev_priv->drm, &driver, &pdev->dev);
> +	if (ret)
> +		goto out_free_priv;
> +
> +	/* Must be set before calling __i915_printk */
> +	dev_priv->drm.pdev = pdev;
> +	dev_priv->drm.dev_private = dev_priv;
> +	dev_priv->dev = &dev_priv->drm;
> +
> +	ret = i915_driver_init_early(dev_priv, ent);
> +	if (ret < 0)
> +		goto out_free_priv;
> +
> +	ret = pci_enable_device(pdev);
> +	if (ret)
> +		goto out_cleanup_early;
> +
> +	pci_set_drvdata(pdev, &dev_priv->drm);
> +
> +	intel_runtime_pm_get(dev_priv);
> +
> +	ret = i915_driver_init_mmio(dev_priv);
> +	if (ret < 0)
> +		goto out_runtime_pm_put;
> +
> +	ret = i915_driver_init_hw(dev_priv);
> +	if (ret < 0)
> +		goto out_cleanup_mmio;
>  
>  	/*
> -	 * In a virtualized passthrough environment we can be in a
> -	 * setup where the ISA bridge is not able to be passed through.
> -	 * In this case, a south bridge can be emulated and we have to
> -	 * make an educated guess as to which PCH is really there.
> +	 * TODO: move the vblank init and parts of modeset init steps into one
> +	 * of the i915_driver_init_/i915_driver_register functions according
> +	 * to the role/effect of the given init step.
>  	 */
> -
> -	if (IS_GEN5(dev)) {
> -		ret = PCH_IBX;
> -		DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n");
> -	} else if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
> -		ret = PCH_CPT;
> -		DRM_DEBUG_KMS("Assuming CouarPoint PCH\n");
> -	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
> -		ret = PCH_LPT;
> -		DRM_DEBUG_KMS("Assuming LynxPoint PCH\n");
> -	} else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
> -		ret = PCH_SPT;
> -		DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n");
> +	if (INTEL_INFO(dev_priv)->num_pipes) {
> +		ret = drm_vblank_init(dev_priv->dev,
> +				      INTEL_INFO(dev_priv)->num_pipes);
> +		if (ret)
> +			goto out_cleanup_hw;
>  	}
>  
> +	ret = i915_load_modeset_init(dev_priv->dev);
> +	if (ret < 0)
> +		goto out_cleanup_vblank;
> +
> +	i915_driver_register(dev_priv);
> +
> +	intel_runtime_pm_enable(dev_priv);
> +
> +	intel_runtime_pm_put(dev_priv);
> +
> +	return 0;
> +
> +out_cleanup_vblank:
> +	drm_vblank_cleanup(dev_priv->dev);
> +out_cleanup_hw:
> +	i915_driver_cleanup_hw(dev_priv);
> +out_cleanup_mmio:
> +	i915_driver_cleanup_mmio(dev_priv);
> +out_runtime_pm_put:
> +	intel_runtime_pm_put(dev_priv);
> +	pci_disable_device(pdev);
> +out_cleanup_early:
> +	i915_driver_cleanup_early(dev_priv);
> +out_free_priv:
> +	i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret);
> +
> +	kfree(dev_priv);
> +
>  	return ret;
>  }
>  
> -void intel_detect_pch(struct drm_device *dev)
> +static int i915_driver_unload(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct pci_dev *pch = NULL;
> +	int ret;
>  
> -	/* In all current cases, num_pipes is equivalent to the PCH_NOP setting
> -	 * (which really amounts to a PCH but no South Display).
> -	 */
> -	if (INTEL_INFO(dev)->num_pipes == 0) {
> -		dev_priv->pch_type = PCH_NOP;
> -		return;
> +	intel_fbdev_fini(dev);
> +
> +	ret = i915_gem_suspend(dev);
> +	if (ret) {
> +		DRM_ERROR("failed to idle hardware: %d\n", ret);
> +		return ret;
>  	}
>  
> +	intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
> +
> +	i915_driver_unregister(dev_priv);
> +
> +	drm_vblank_cleanup(dev);
> +
> +	intel_modeset_cleanup(dev);
> +
>  	/*
> -	 * The reason to probe ISA bridge instead of Dev31:Fun0 is to
> -	 * make graphics device passthrough work easy for VMM, that only
> -	 * need to expose ISA bridge to let driver know the real hardware
> -	 * underneath. This is a requirement from virtualization team.
> -	 *
> -	 * In some virtualized environments (e.g. XEN), there is irrelevant
> -	 * ISA bridge in the system. To work reliably, we should scan trhough
> -	 * all the ISA bridge devices and check for the first match, instead
> -	 * of only checking the first one.
> +	 * free the memory space allocated for the child device
> +	 * config parsed from VBT
>  	 */
> -	while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
> -		if (pch->vendor == PCI_VENDOR_ID_INTEL) {
> -			unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
> -			dev_priv->pch_id = id;
> +	if (dev_priv->vbt.child_dev && dev_priv->vbt.child_dev_num) {
> +		kfree(dev_priv->vbt.child_dev);
> +		dev_priv->vbt.child_dev = NULL;
> +		dev_priv->vbt.child_dev_num = 0;
> +	}
> +	kfree(dev_priv->vbt.sdvo_lvds_vbt_mode);
> +	dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
> +	kfree(dev_priv->vbt.lfp_lvds_vbt_mode);
> +	dev_priv->vbt.lfp_lvds_vbt_mode = NULL;
>  
> -			if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
> -				dev_priv->pch_type = PCH_IBX;
> -				DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
> -				WARN_ON(!IS_GEN5(dev));
> -			} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
> -				dev_priv->pch_type = PCH_CPT;
> -				DRM_DEBUG_KMS("Found CougarPoint PCH\n");
> -				WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
> -			} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
> -				/* PantherPoint is CPT compatible */
> -				dev_priv->pch_type = PCH_CPT;
> -				DRM_DEBUG_KMS("Found PantherPoint PCH\n");
> -				WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
> -			} else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
> -				dev_priv->pch_type = PCH_LPT;
> -				DRM_DEBUG_KMS("Found LynxPoint PCH\n");
> -				WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev));
> -				WARN_ON(IS_HSW_ULT(dev) || IS_BDW_ULT(dev));
> -			} else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
> -				dev_priv->pch_type = PCH_LPT;
> -				DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
> -				WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev));
> -				WARN_ON(!IS_HSW_ULT(dev) && !IS_BDW_ULT(dev));
> -			} else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
> -				dev_priv->pch_type = PCH_SPT;
> -				DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
> -				WARN_ON(!IS_SKYLAKE(dev) &&
> -					!IS_KABYLAKE(dev));
> -			} else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
> -				dev_priv->pch_type = PCH_SPT;
> -				DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
> -				WARN_ON(!IS_SKYLAKE(dev) &&
> -					!IS_KABYLAKE(dev));
> -			} else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) ||
> -				   (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) ||
> -				   ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) &&
> -				    pch->subsystem_vendor == 0x1af4 &&
> -				    pch->subsystem_device == 0x1100)) {
> -				dev_priv->pch_type = intel_virt_detect_pch(dev);
> -			} else
> -				continue;
> +	vga_switcheroo_unregister_client(dev->pdev);
> +	vga_client_register(dev->pdev, NULL, NULL, NULL);
>  
> -			break;
> -		}
> -	}
> -	if (!pch)
> -		DRM_DEBUG_KMS("No PCH found.\n");
> +	intel_csr_ucode_fini(dev_priv);
>  
> -	pci_dev_put(pch);
> +	/* Free error state after interrupts are fully disabled. */
> +	cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
> +	i915_destroy_error_state(dev);
> +
> +	/* Flush any outstanding unpin_work. */
> +	flush_workqueue(dev_priv->wq);
> +
> +	intel_guc_fini(dev);
> +	i915_gem_fini(dev);
> +	intel_fbc_cleanup_cfb(dev_priv);
> +
> +	intel_power_domains_fini(dev_priv);
> +
> +	i915_driver_cleanup_hw(dev_priv);
> +	i915_driver_cleanup_mmio(dev_priv);
> +
> +	intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
> +
> +	i915_driver_cleanup_early(dev_priv);
> +
> +	return 0;
>  }
>  
> -bool i915_semaphore_is_enabled(struct drm_i915_private *dev_priv)
> +static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
>  {
> -	if (INTEL_GEN(dev_priv) < 6)
> -		return false;
> +	int ret;
>  
> -	if (i915.semaphores >= 0)
> -		return i915.semaphores;
> +	ret = i915_gem_open(dev, file);
> +	if (ret)
> +		return ret;
>  
> -	/* TODO: make semaphores and Execlists play nicely together */
> -	if (i915.enable_execlists)
> -		return false;
> +	return 0;
> +}
>  
> -#ifdef CONFIG_INTEL_IOMMU
> -	/* Enable semaphores on SNB when IO remapping is off */
> -	if (IS_GEN6(dev_priv) && intel_iommu_gfx_mapped)
> -		return false;
> -#endif
> +/**
> + * i915_driver_lastclose - clean up after all DRM clients have exited
> + * @dev: DRM device
> + *
> + * Take care of cleaning up after all DRM clients have exited.  In the
> + * mode setting case, we want to restore the kernel's initial mode (just
> + * in case the last client left us in a bad state).
> + *
> + * Additionally, in the non-mode setting case, we'll tear down the GTT
> + * and DMA structures, since the kernel won't be using them, and clea
> + * up any GEM state.
> + */
> +static void i915_driver_lastclose(struct drm_device *dev)
> +{
> +	intel_fbdev_restore_mode(dev);
> +	vga_switcheroo_process_delayed_switch();
> +}
>  
> -	return true;
> +static void i915_driver_preclose(struct drm_device *dev, struct drm_file *file)
> +{
> +	mutex_lock(&dev->struct_mutex);
> +	i915_gem_context_close(dev, file);
> +	i915_gem_release(dev, file);
> +	mutex_unlock(&dev->struct_mutex);
> +}
> +
> +static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
> +{
> +	struct drm_i915_file_private *file_priv = file->driver_priv;
> +
> +	kfree(file_priv);
>  }
>  
>  static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
> @@ -1039,7 +2612,7 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>  	    !vga_switcheroo_handler_flags())
>  		return -EPROBE_DEFER;
>  
> -	return i915_driver_load(pdev, ent, &driver);
> +	return i915_driver_load(pdev, ent);
>  }
>  
>  static void
> @@ -1747,6 +3320,68 @@ static const struct file_operations i915_driver_fops = {
>  	.llseek = noop_llseek,
>  };
>  
> +static int
> +i915_gem_reject_pin_ioctl(struct drm_device *dev, void *data,
> +			  struct drm_file *file)
> +{
> +	return -ENODEV;
> +}
> +
> +static const struct drm_ioctl_desc i915_ioctls[] = {
> +	DRM_IOCTL_DEF_DRV(I915_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_FLUSH, drm_noop, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_FLIP, drm_noop, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, drm_noop, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, drm_noop, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, drm_noop, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH|DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_SETPARAM, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, drm_noop, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP,  drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE,  drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE,  drm_noop, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, drm_noop, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW),
> +};
> +
>  static struct drm_driver driver = {
>  	/* Don't use MTRRs here; the Xserver or userspace app should
>  	 * deal with them for Intel hardware.
> @@ -1772,6 +3407,7 @@ static struct drm_driver driver = {
>  	.dumb_map_offset = i915_gem_mmap_gtt,
>  	.dumb_destroy = drm_gem_dumb_destroy,
>  	.ioctls = i915_ioctls,
> +	.num_ioctls = ARRAY_SIZE(i915_ioctls),
>  	.fops = &i915_driver_fops,
>  	.name = DRIVER_NAME,
>  	.desc = DRIVER_DESC,
> @@ -1791,8 +3427,6 @@ static struct pci_driver i915_pci_driver = {
>  
>  static int __init i915_init(void)
>  {
> -	driver.num_ioctls = i915_max_ioctl;
> -
>  	/*
>  	 * Enable KMS by default, unless explicitly overriden by
>  	 * either the i915.modeset prarameter or by the
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index b95a10fa002a..1df141e4ab6b 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2857,16 +2857,13 @@ struct drm_i915_cmd_table {
>  
>  #include "i915_trace.h"
>  
> -extern const struct drm_ioctl_desc i915_ioctls[];
> -extern int i915_max_ioctl;
> -
>  extern int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state);
>  extern int i915_resume_switcheroo(struct drm_device *dev);
>  
>  int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
>  			       	int enable_ppgtt);
>  
> -/* i915_dma.c */
> +/* i915_drv.c */
>  void __printf(3, 4)
>  __i915_printk(struct drm_i915_private *dev_priv, const char *level,
>  	      const char *fmt, ...);
> @@ -2874,16 +2871,6 @@ __i915_printk(struct drm_i915_private *dev_priv, const char *level,
>  #define i915_report_error(dev_priv, fmt, ...)				   \
>  	__i915_printk(dev_priv, KERN_ERR, fmt, ##__VA_ARGS__)
>  
> -extern int i915_driver_load(struct pci_dev *pdev,
> -			    const struct pci_device_id *ent,
> -			    struct drm_driver *driver);
> -extern int i915_driver_unload(struct drm_device *);
> -extern int i915_driver_open(struct drm_device *dev, struct drm_file *file);
> -extern void i915_driver_lastclose(struct drm_device * dev);
> -extern void i915_driver_preclose(struct drm_device *dev,
> -				 struct drm_file *file);
> -extern void i915_driver_postclose(struct drm_device *dev,
> -				  struct drm_file *file);
>  #ifdef CONFIG_COMPAT
>  extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
>  			      unsigned long arg);
> @@ -3689,7 +3676,6 @@ extern void intel_init_pch_refclk(struct drm_device *dev);
>  extern void intel_set_rps(struct drm_i915_private *dev_priv, u8 val);
>  extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv,
>  				  bool enable);
> -extern void intel_detect_pch(struct drm_device *dev);
>  
>  extern bool i915_semaphore_is_enabled(struct drm_i915_private *dev_priv);
>  int i915_reg_read_ioctl(struct drm_device *dev, void *data,
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation


More information about the Intel-gfx mailing list