Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit efcebcf9 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-2016-02-14' of git://anongit.freedesktop.org/drm-intel into drm-next

- lots and lots of fbc work from Paulo
- max pixel clock checks from Mika Kahola
- prep work for nv12 offset handling from Ville
- piles of small fixes and refactorings all around

* tag 'drm-intel-next-2016-02-14' of git://anongit.freedesktop.org/drm-intel: (113 commits)
  drm/i915: Update DRIVER_DATE to 20160214
  drm/i915: edp resume/On time optimization.
  agp/intel-gtt: Only register fake agp driver for gen1
  drm/i915: TV pixel clock check
  drm/i915: CRT pixel clock check
  drm/i915: SDVO pixel clock check
  drm/i915: DisplayPort-MST pixel clock check
  drm/i915: HDMI pixel clock check
  drm/i915: DisplayPort pixel clock check
  drm/i915: check that rpm ref is held when accessing ringbuf in stolen mem
  drm/i915: fix error path in intel_setup_gmbus()
  drm/i915: Stop depending upon CONFIG_AGP_INTEL
  agp/intel-gtt: Don't leak the scratch page
  drm/i915: Capture PCI revision and subsytem details in error state
  drm/i915: fix context/engine cleanup order
  drm/i915: Handle PipeC fused off on IVB/HSW/BDW
  drm/i915/skl: Fix typo in DPLL_CFGCR1 definition
  drm/i915: Skip DDI PLL selection for DSI
  drm/i915/skl: Explicitly check for eDP in skl_ddi_pll_select()
  drm/i915/skl: Don't skip mst encoders in skl_ddi_pll_select()
  ...
parents 9d5d6752 59bbf84d
Loading
Loading
Loading
Loading
+18 −14
Original line number Diff line number Diff line
@@ -555,7 +555,9 @@ static unsigned int intel_gtt_mappable_entries(void)
static void intel_gtt_teardown_scratch_page(void)
{
	set_pages_wb(intel_private.scratch_page, 1);
	pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma,
	if (intel_private.needs_dmar)
		pci_unmap_page(intel_private.pcidev,
			       intel_private.scratch_page_dma,
			       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
	__free_page(intel_private.scratch_page);
}
@@ -1346,16 +1348,6 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
{
	int i, mask;

	/*
	 * Can be called from the fake agp driver but also directly from
	 * drm/i915.ko. Hence we need to check whether everything is set up
	 * already.
	 */
	if (intel_private.driver) {
		intel_private.refcount++;
		return 1;
	}

	for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) {
		if (gpu_pdev) {
			if (gpu_pdev->device ==
@@ -1376,16 +1368,26 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
	if (!intel_private.driver)
		return 0;

	intel_private.refcount++;

#if IS_ENABLED(CONFIG_AGP_INTEL)
	if (bridge) {
		if (INTEL_GTT_GEN > 1)
			return 0;

		bridge->driver = &intel_fake_agp_driver;
		bridge->dev_private_data = &intel_private;
		bridge->dev = bridge_pdev;
	}
#endif


	/*
	 * Can be called from the fake agp driver but also directly from
	 * drm/i915.ko. Hence we need to check whether everything is set up
	 * already.
	 */
	if (intel_private.refcount++)
		return 1;

	intel_private.bridge_dev = pci_dev_get(bridge_pdev);

	dev_info(&bridge_pdev->dev, "Intel %s Chipset\n", intel_gtt_chipsets[i].name);
@@ -1430,6 +1432,8 @@ void intel_gmch_remove(void)
	if (--intel_private.refcount)
		return;

	if (intel_private.scratch_page)
		intel_gtt_teardown_scratch_page();
	if (intel_private.pcidev)
		pci_dev_put(intel_private.pcidev);
	if (intel_private.bridge_dev)
+0 −2
Original line number Diff line number Diff line
@@ -2,9 +2,7 @@ config DRM_I915
	tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics"
	depends on DRM
	depends on X86 && PCI
	depends on (AGP || AGP=n)
	select INTEL_GTT
	select AGP_INTEL if AGP
	select INTERVAL_TREE
	# we need shmfs for the swappable backing store, and in particular
	# the shmem_readpage() which depends upon tmpfs
+20 −11
Original line number Diff line number Diff line
@@ -2463,9 +2463,9 @@ static void i915_guc_client_info(struct seq_file *m,

	for_each_ring(ring, dev_priv, i) {
		seq_printf(m, "\tSubmissions: %llu %s\n",
				client->submissions[i],
				client->submissions[ring->guc_id],
				ring->name);
		tot += client->submissions[i];
		tot += client->submissions[ring->guc_id];
	}
	seq_printf(m, "\tTotal: %llu\n", tot);
}
@@ -2502,10 +2502,10 @@ static int i915_guc_info(struct seq_file *m, void *data)

	seq_printf(m, "\nGuC submissions:\n");
	for_each_ring(ring, dev_priv, i) {
		seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x %9d\n",
			ring->name, guc.submissions[i],
			guc.last_seqno[i], guc.last_seqno[i]);
		total += guc.submissions[i];
		seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n",
			ring->name, guc.submissions[ring->guc_id],
			guc.last_seqno[ring->guc_id]);
		total += guc.submissions[ring->guc_id];
	}
	seq_printf(m, "\t%s: %llu\n", "Total", total);

@@ -2583,6 +2583,10 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
				enabled = true;
		}
	}

	seq_printf(m, "Main link in standby mode: %s\n",
		   yesno(dev_priv->psr.link_standby));

	seq_printf(m, "HW Enabled & Active bit: %s", yesno(enabled));

	if (!HAS_DDI(dev))
@@ -3221,9 +3225,11 @@ static int i915_wa_registers(struct seq_file *m, void *unused)
{
	int i;
	int ret;
	struct intel_engine_cs *ring;
	struct drm_info_node *node = (struct drm_info_node *) m->private;
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct i915_workarounds *workarounds = &dev_priv->workarounds;

	ret = mutex_lock_interruptible(&dev->struct_mutex);
	if (ret)
@@ -3231,15 +3237,18 @@ static int i915_wa_registers(struct seq_file *m, void *unused)

	intel_runtime_pm_get(dev_priv);

	seq_printf(m, "Workarounds applied: %d\n", dev_priv->workarounds.count);
	for (i = 0; i < dev_priv->workarounds.count; ++i) {
	seq_printf(m, "Workarounds applied: %d\n", workarounds->count);
	for_each_ring(ring, dev_priv, i)
		seq_printf(m, "HW whitelist count for %s: %d\n",
			   ring->name, workarounds->hw_whitelist_count[i]);
	for (i = 0; i < workarounds->count; ++i) {
		i915_reg_t addr;
		u32 mask, value, read;
		bool ok;

		addr = dev_priv->workarounds.reg[i].addr;
		mask = dev_priv->workarounds.reg[i].mask;
		value = dev_priv->workarounds.reg[i].value;
		addr = workarounds->reg[i].addr;
		mask = workarounds->reg[i].mask;
		value = workarounds->reg[i].value;
		read = I915_READ(addr);
		ok = (value & mask) == (read & mask);
		seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X, read: 0x%08x, status: %s\n",
+156 −106
Original line number Diff line number Diff line
@@ -391,20 +391,13 @@ static int i915_load_modeset_init(struct drm_device *dev)
	if (ret)
		goto cleanup_vga_client;

	/* Initialise stolen first so that we may reserve preallocated
	 * objects for the BIOS to KMS transition.
	 */
	ret = i915_gem_init_stolen(dev);
	if (ret)
		goto cleanup_vga_switcheroo;

	intel_power_domains_init_hw(dev_priv, false);

	intel_csr_ucode_init(dev_priv);

	ret = intel_irq_install(dev_priv);
	if (ret)
		goto cleanup_gem_stolen;
		goto cleanup_csr;

	intel_setup_gmbus(dev);

@@ -451,16 +444,15 @@ static int i915_load_modeset_init(struct drm_device *dev)

cleanup_gem:
	mutex_lock(&dev->struct_mutex);
	i915_gem_cleanup_ringbuffer(dev);
	i915_gem_context_fini(dev);
	i915_gem_cleanup_engines(dev);
	mutex_unlock(&dev->struct_mutex);
cleanup_irq:
	intel_guc_ucode_fini(dev);
	drm_irq_uninstall(dev);
	intel_teardown_gmbus(dev);
cleanup_gem_stolen:
	i915_gem_cleanup_stolen(dev);
cleanup_vga_switcheroo:
cleanup_csr:
	intel_csr_ucode_fini(dev_priv);
	vga_switcheroo_unregister_client(dev->pdev);
cleanup_vga_client:
	vga_client_register(dev->pdev, NULL, NULL, NULL);
@@ -816,7 +808,41 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
		     !(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 && INTEL_INFO(dev)->gen == 9) {
		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 */
@@ -855,6 +881,94 @@ static void intel_init_dpio(struct drm_i915_private *dev_priv)
	}
}

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);
}

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_load - setup chip and create an initial config
 * @dev: DRM device
@@ -870,7 +984,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
{
	struct drm_i915_private *dev_priv;
	struct intel_device_info *info, *device_info;
	int ret = 0, mmio_bar, mmio_size;
	int ret = 0;
	uint32_t aperture_size;

	info = (struct intel_device_info *) flags;
@@ -897,6 +1011,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	mutex_init(&dev_priv->modeset_restore_lock);
	mutex_init(&dev_priv->av_mutex);

	ret = i915_workqueues_init(dev_priv);
	if (ret < 0)
		goto out_free_priv;

	intel_pm_setup(dev);

	intel_runtime_pm_get(dev_priv);
@@ -915,28 +1033,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)

	if (i915_get_bridge_dev(dev)) {
		ret = -EIO;
		goto free_priv;
		goto out_runtime_pm_put;
	}

	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 (info->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) {
		DRM_ERROR("failed to map registers\n");
		ret = -EIO;
	ret = i915_mmio_setup(dev);
	if (ret < 0)
		goto put_bridge;
	}

	/* This must be called before any calls to HAS_PCH_* */
	intel_detect_pch(dev);
@@ -945,7 +1047,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)

	ret = i915_gem_gtt_init(dev);
	if (ret)
		goto out_freecsr;
		goto out_uncore_fini;

	/* WARNING: Apparently we must kick fbdev drivers before vgacon,
	 * otherwise the vga fbdev driver falls over. */
@@ -991,49 +1093,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base,
					      aperture_size);

	/* 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) {
		DRM_ERROR("Failed to create our workqueue.\n");
		ret = -ENOMEM;
		goto out_mtrrfree;
	}

	dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0);
	if (dev_priv->hotplug.dp_wq == NULL) {
		DRM_ERROR("Failed to create our dp workqueue.\n");
		ret = -ENOMEM;
		goto out_freewq;
	}

	dev_priv->gpu_error.hangcheck_wq =
		alloc_ordered_workqueue("i915-hangcheck", 0);
	if (dev_priv->gpu_error.hangcheck_wq == NULL) {
		DRM_ERROR("Failed to create our hangcheck workqueue.\n");
		ret = -ENOMEM;
		goto out_freedpwq;
	}

	intel_irq_init(dev_priv);
	intel_uncore_sanitize(dev);

	/* Try to make sure MCHBAR is enabled before poking at it */
	intel_setup_mchbar(dev);
	intel_opregion_setup(dev);

	i915_gem_load(dev);
	i915_gem_load_init(dev);
	i915_gem_shrinker_init(dev_priv);

	/* On the 945G/GM, the chipset reports the MSI capability on the
	 * integrated graphics even though the support isn't actually there
@@ -1046,8 +1112,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	 * be lost or delayed, but we use them anyways to avoid
	 * stuck interrupts on some machines.
	 */
	if (!IS_I945G(dev) && !IS_I945GM(dev))
		pci_enable_msi(dev->pdev);
	if (!IS_I945G(dev) && !IS_I945GM(dev)) {
		if (pci_enable_msi(dev->pdev) < 0)
			DRM_DEBUG_DRIVER("can't enable MSI");
	}

	intel_device_info_runtime_init(dev);

@@ -1097,38 +1165,29 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	intel_power_domains_fini(dev_priv);
	drm_vblank_cleanup(dev);
out_gem_unload:
	WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier));
	unregister_shrinker(&dev_priv->mm.shrinker);
	i915_gem_shrinker_cleanup(dev_priv);

	if (dev->pdev->msi_enabled)
		pci_disable_msi(dev->pdev);

	intel_teardown_mchbar(dev);
	pm_qos_remove_request(&dev_priv->pm_qos);
	destroy_workqueue(dev_priv->gpu_error.hangcheck_wq);
out_freedpwq:
	destroy_workqueue(dev_priv->hotplug.dp_wq);
out_freewq:
	destroy_workqueue(dev_priv->wq);
out_mtrrfree:
	arch_phys_wc_del(dev_priv->gtt.mtrr);
	io_mapping_free(dev_priv->gtt.mappable);
out_gtt:
	i915_global_gtt_cleanup(dev);
out_freecsr:
	intel_csr_ucode_fini(dev_priv);
out_uncore_fini:
	intel_uncore_fini(dev);
	pci_iounmap(dev->pdev, dev_priv->regs);
	i915_mmio_cleanup(dev);
put_bridge:
	pci_dev_put(dev_priv->bridge_dev);
free_priv:
	kmem_cache_destroy(dev_priv->requests);
	kmem_cache_destroy(dev_priv->vmas);
	kmem_cache_destroy(dev_priv->objects);

	i915_gem_load_cleanup(dev);
out_runtime_pm_put:
	intel_runtime_pm_put(dev_priv);

	i915_workqueues_cleanup(dev_priv);
out_free_priv:
	kfree(dev_priv);

	return ret;
}

@@ -1153,8 +1212,7 @@ int i915_driver_unload(struct drm_device *dev)

	i915_teardown_sysfs(dev);

	WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier));
	unregister_shrinker(&dev_priv->mm.shrinker);
	i915_gem_shrinker_cleanup(dev_priv);

	io_mapping_free(dev_priv->gtt.mappable);
	arch_phys_wc_del(dev_priv->gtt.mtrr);
@@ -1182,6 +1240,8 @@ int i915_driver_unload(struct drm_device *dev)
	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);
@@ -1196,31 +1256,21 @@ int i915_driver_unload(struct drm_device *dev)

	intel_guc_ucode_fini(dev);
	mutex_lock(&dev->struct_mutex);
	i915_gem_cleanup_ringbuffer(dev);
	i915_gem_context_fini(dev);
	i915_gem_cleanup_engines(dev);
	mutex_unlock(&dev->struct_mutex);
	intel_fbc_cleanup_cfb(dev_priv);
	i915_gem_cleanup_stolen(dev);

	intel_csr_ucode_fini(dev_priv);

	intel_teardown_mchbar(dev);

	destroy_workqueue(dev_priv->hotplug.dp_wq);
	destroy_workqueue(dev_priv->wq);
	destroy_workqueue(dev_priv->gpu_error.hangcheck_wq);
	pm_qos_remove_request(&dev_priv->pm_qos);

	i915_global_gtt_cleanup(dev);

	intel_uncore_fini(dev);
	if (dev_priv->regs != NULL)
		pci_iounmap(dev->pdev, dev_priv->regs);
	i915_mmio_cleanup(dev);

	kmem_cache_destroy(dev_priv->requests);
	kmem_cache_destroy(dev_priv->vmas);
	kmem_cache_destroy(dev_priv->objects);
	i915_gem_load_cleanup(dev);
	pci_dev_put(dev_priv->bridge_dev);
	i915_workqueues_cleanup(dev_priv);
	kfree(dev_priv);

	return 0;
+63 −18
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@

#define DRIVER_NAME		"i915"
#define DRIVER_DESC		"Intel Graphics"
#define DRIVER_DATE		"20160124"
#define DRIVER_DATE		"20160214"

#undef WARN_ON
/* Many gcc seem to no see through this and fall over :( */
@@ -900,16 +900,15 @@ enum fb_op_origin {
	ORIGIN_DIRTYFB,
};

struct i915_fbc {
struct intel_fbc {
	/* This is always the inner lock when overlapping with struct_mutex and
	 * it's the outer lock when overlapping with stolen_lock. */
	struct mutex lock;
	unsigned threshold;
	unsigned int fb_id;
	unsigned int possible_framebuffer_bits;
	unsigned int busy_bits;
	unsigned int visible_pipes_mask;
	struct intel_crtc *crtc;
	int y;

	struct drm_mm_node compressed_fb;
	struct drm_mm_node *compressed_llb;
@@ -919,18 +918,52 @@ struct i915_fbc {
	bool enabled;
	bool active;

	struct intel_fbc_state_cache {
		struct {
			unsigned int mode_flags;
			uint32_t hsw_bdw_pixel_rate;
		} crtc;

		struct {
			unsigned int rotation;
			int src_w;
			int src_h;
			bool visible;
		} plane;

		struct {
			u64 ilk_ggtt_offset;
			uint32_t pixel_format;
			unsigned int stride;
			int fence_reg;
			unsigned int tiling_mode;
		} fb;
	} state_cache;

	struct intel_fbc_reg_params {
		struct {
			enum pipe pipe;
			enum plane plane;
			unsigned int fence_y_offset;
		} crtc;

		struct {
			u64 ggtt_offset;
			uint32_t pixel_format;
			unsigned int stride;
			int fence_reg;
		} fb;

		int cfb_size;
	} params;

	struct intel_fbc_work {
		bool scheduled;
		u32 scheduled_vblank;
		struct work_struct work;
		struct drm_framebuffer *fb;
		unsigned long enable_jiffies;
	} work;

	const char *no_fbc_reason;

	bool (*is_active)(struct drm_i915_private *dev_priv);
	void (*activate)(struct intel_crtc *crtc);
	void (*deactivate)(struct drm_i915_private *dev_priv);
};

/**
@@ -970,6 +1003,7 @@ struct i915_psr {
	unsigned busy_frontbuffer_bits;
	bool psr2_support;
	bool aux_frame_sync;
	bool link_standby;
};

enum intel_pch {
@@ -1657,11 +1691,18 @@ struct i915_wa_reg {
	u32 mask;
};

#define I915_MAX_WA_REGS 16
/*
 * RING_MAX_NONPRIV_SLOTS is per-engine but at this point we are only
 * allowing it for RCS as we don't foresee any requirement of having
 * a whitelist for other engines. When it is really required for
 * other engines then the limit need to be increased.
 */
#define I915_MAX_WA_REGS (16 + RING_MAX_NONPRIV_SLOTS)

struct i915_workarounds {
	struct i915_wa_reg reg[I915_MAX_WA_REGS];
	u32 count;
	u32 hw_whitelist_count[I915_NUM_RINGS];
};

struct i915_virtual_gpu {
@@ -1758,7 +1799,7 @@ struct drm_i915_private {
	u32 pipestat_irq_mask[I915_MAX_PIPES];

	struct i915_hotplug hotplug;
	struct i915_fbc fbc;
	struct intel_fbc fbc;
	struct i915_drrs drrs;
	struct intel_opregion opregion;
	struct intel_vbt_data vbt;
@@ -1993,6 +2034,9 @@ enum hdmi_force_audio {
#define I915_GTT_OFFSET_NONE ((u32)-1)

struct drm_i915_gem_object_ops {
	unsigned int flags;
#define I915_GEM_OBJECT_HAS_STRUCT_PAGE 0x1

	/* Interface between the GEM object and its backing storage.
	 * get_pages() is called once prior to the use of the associated set
	 * of pages before to binding them into the GTT, and put_pages() is
@@ -2008,6 +2052,7 @@ struct drm_i915_gem_object_ops {
	 */
	int (*get_pages)(struct drm_i915_gem_object *);
	void (*put_pages)(struct drm_i915_gem_object *);

	int (*dmabuf_export)(struct drm_i915_gem_object *);
	void (*release)(struct drm_i915_gem_object *);
};
@@ -2841,7 +2886,8 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
				struct drm_file *file_priv);
int i915_gem_wait_ioctl(struct drm_device *dev, void *data,
			struct drm_file *file_priv);
void i915_gem_load(struct drm_device *dev);
void i915_gem_load_init(struct drm_device *dev);
void i915_gem_load_cleanup(struct drm_device *dev);
void *i915_gem_object_alloc(struct drm_device *dev);
void i915_gem_object_free(struct drm_i915_gem_object *obj);
void i915_gem_object_init(struct drm_i915_gem_object *obj,
@@ -3012,7 +3058,7 @@ int i915_gem_init_rings(struct drm_device *dev);
int __must_check i915_gem_init_hw(struct drm_device *dev);
int i915_gem_l3_remap(struct drm_i915_gem_request *req, int slice);
void i915_gem_init_swizzling(struct drm_device *dev);
void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
void i915_gem_cleanup_engines(struct drm_device *dev);
int __must_check i915_gpu_idle(struct drm_device *dev);
int __must_check i915_gem_suspend(struct drm_device *dev);
void __i915_add_request(struct drm_i915_gem_request *req,
@@ -3254,6 +3300,7 @@ unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv,
#define I915_SHRINK_ACTIVE 0x8
unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv);
void i915_gem_shrinker_init(struct drm_i915_private *dev_priv);
void i915_gem_shrinker_cleanup(struct drm_i915_private *dev_priv);


/* i915_gem_tiling.c */
@@ -3424,16 +3471,14 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val
u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);
void vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val);
u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg);
void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg);
void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, u8 port, u32 reg, u32 val);
u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg);
void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg);
void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg);
void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg);
void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg);
void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val);
u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
Loading