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

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

Merge tag 'drm-intel-next-2013-08-23' of...

Merge tag 'drm-intel-next-2013-08-23' of git://people.freedesktop.org/~danvet/drm-intel into drm-next

Need to get my stuff out the door ;-) Highlights:
- pc8+ support from Paulo
- more vma patches from Ben.
- Kconfig option to enable preliminary support by default (Josh
  Triplett)
- Optimized cpu cache flush handling and support for write-through caching
  of display planes on Iris (Chris)
- rc6 tuning from Stéphane Marchesin for more stability
- VECS seqno wrap/semaphores fix (Ben)
- a pile of smaller cleanups and improvements all over

Note that I've ditched Ben's execbuf vma conversion for 3.12 since not yet
ready. But there's still other vma conversion stuff in here.

* tag 'drm-intel-next-2013-08-23' of git://people.freedesktop.org/~danvet/drm-intel: (62 commits)
  drm/i915: Print seqnos as unsigned in debugfs
  drm/i915: Fix context size calculation on SNB/IVB/VLV
  drm/i915: Use POSTING_READ in lcpll code
  drm/i915: enable Package C8+ by default
  drm/i915: add i915.pc8_timeout function
  drm/i915: add i915_pc8_status debugfs file
  drm/i915: allow package C8+ states on Haswell (disabled)
  drm/i915: fix SDEIMR assertion when disabling LCPLL
  drm/i915: grab force_wake when restoring LCPLL
  drm/i915: drop WaMbcDriverBootEnable workaround
  drm/i915: Cleaning up the relocate entry function
  drm/i915: merge HSW and SNB PM irq handlers
  drm/i915: fix how we mask PMIMR when adding work to the queue
  drm/i915: don't queue PM events we won't process
  drm/i915: don't disable/reenable IVB error interrupts when not needed
  drm/i915: add dev_priv->pm_irq_mask
  drm/i915: don't update GEN6_PMIMR when it's not needed
  drm/i915: wrap GEN6_PMIMR changes
  drm/i915: wrap GTIMR changes
  drm/i915: add the FCLK case to intel_ddi_get_cdclk_freq
  ...
parents 62f2104f fb1ae911
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -168,6 +168,17 @@ config DRM_I915_KMS
	  the driver to bind to PCI devices, which precludes loading things
	  like intelfb.

config DRM_I915_PRELIMINARY_HW_SUPPORT
	bool "Enable preliminary support for prerelease Intel hardware by default"
	depends on DRM_I915
	help
	  Choose this option if you have prerelease Intel hardware and want the
	  i915 driver to support it by default.  You can enable such support at
	  runtime with the module option i915.preliminary_hw_support=1; this
	  option changes the default for that module option.

	  If in doubt, say "N".

config DRM_MGA
	tristate "Matrox g200/g400"
	depends on DRM && PCI
+3 −0
Original line number Diff line number Diff line
@@ -254,6 +254,9 @@ void drm_mm_remove_node(struct drm_mm_node *node)
	struct drm_mm *mm = node->mm;
	struct drm_mm_node *prev_node;

	if (WARN_ON(!node->allocated))
		return;

	BUG_ON(node->scanned_block || node->scanned_prev_free
				   || node->scanned_next_free);

+58 −7
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/list_sort.h>
#include <asm/msr-index.h>
#include <drm/drmP.h>
#include "intel_drv.h"
#include "intel_ringbuffer.h"
@@ -99,7 +100,7 @@ static void
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
	struct i915_vma *vma;
	seq_printf(m, "%pK: %s%s%s %8zdKiB %02x %02x %d %d %d%s%s%s",
	seq_printf(m, "%pK: %s%s%s %8zdKiB %02x %02x %u %u %u%s%s%s",
		   &obj->base,
		   get_pin_flag(obj),
		   get_tiling_flag(obj),
@@ -117,6 +118,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
		seq_printf(m, " (name: %d)", obj->base.name);
	if (obj->pin_count)
		seq_printf(m, " (pinned x %d)", obj->pin_count);
	if (obj->pin_display)
		seq_printf(m, " (display)");
	if (obj->fence_reg != I915_FENCE_REG_NONE)
		seq_printf(m, " (fence: %d)", obj->fence_reg);
	list_for_each_entry(vma, &obj->vma_list, vma_link) {
@@ -193,9 +196,9 @@ static int obj_rank_by_stolen(void *priv,
			      struct list_head *A, struct list_head *B)
{
	struct drm_i915_gem_object *a =
		container_of(A, struct drm_i915_gem_object, exec_list);
		container_of(A, struct drm_i915_gem_object, obj_exec_link);
	struct drm_i915_gem_object *b =
		container_of(B, struct drm_i915_gem_object, exec_list);
		container_of(B, struct drm_i915_gem_object, obj_exec_link);

	return a->stolen->start - b->stolen->start;
}
@@ -219,7 +222,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
		if (obj->stolen == NULL)
			continue;

		list_add(&obj->exec_list, &stolen);
		list_add(&obj->obj_exec_link, &stolen);

		total_obj_size += obj->base.size;
		total_gtt_size += i915_gem_obj_ggtt_size(obj);
@@ -229,7 +232,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
		if (obj->stolen == NULL)
			continue;

		list_add(&obj->exec_list, &stolen);
		list_add(&obj->obj_exec_link, &stolen);

		total_obj_size += obj->base.size;
		count++;
@@ -237,11 +240,11 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data)
	list_sort(NULL, &stolen, obj_rank_by_stolen);
	seq_puts(m, "Stolen:\n");
	while (!list_empty(&stolen)) {
		obj = list_first_entry(&stolen, typeof(*obj), exec_list);
		obj = list_first_entry(&stolen, typeof(*obj), obj_exec_link);
		seq_puts(m, "   ");
		describe_obj(m, obj);
		seq_putc(m, '\n');
		list_del_init(&obj->exec_list);
		list_del_init(&obj->obj_exec_link);
	}
	mutex_unlock(&dev->struct_mutex);

@@ -1767,6 +1770,52 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
	return 0;
}

static int i915_energy_uJ(struct seq_file *m, void *data)
{
	struct drm_info_node *node = m->private;
	struct drm_device *dev = node->minor->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	u64 power;
	u32 units;

	if (INTEL_INFO(dev)->gen < 6)
		return -ENODEV;

	rdmsrl(MSR_RAPL_POWER_UNIT, power);
	power = (power & 0x1f00) >> 8;
	units = 1000000 / (1 << power); /* convert to uJ */
	power = I915_READ(MCH_SECP_NRG_STTS);
	power *= units;

	seq_printf(m, "%llu", (long long unsigned)power);

	return 0;
}

static int i915_pc8_status(struct seq_file *m, void *unused)
{
	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;

	if (!IS_HASWELL(dev)) {
		seq_puts(m, "not supported\n");
		return 0;
	}

	mutex_lock(&dev_priv->pc8.lock);
	seq_printf(m, "Requirements met: %s\n",
		   yesno(dev_priv->pc8.requirements_met));
	seq_printf(m, "GPU idle: %s\n", yesno(dev_priv->pc8.gpu_idle));
	seq_printf(m, "Disable count: %d\n", dev_priv->pc8.disable_count);
	seq_printf(m, "IRQs disabled: %s\n",
		   yesno(dev_priv->pc8.irqs_disabled));
	seq_printf(m, "Enabled: %s\n", yesno(dev_priv->pc8.enabled));
	mutex_unlock(&dev_priv->pc8.lock);

	return 0;
}

static int
i915_wedged_get(void *data, u64 *val)
{
@@ -2206,6 +2255,8 @@ static struct drm_info_list i915_debugfs_list[] = {
	{"i915_dpio", i915_dpio_info, 0},
	{"i915_llc", i915_llc, 0},
	{"i915_edp_psr_status", i915_edp_psr_status, 0},
	{"i915_energy_uJ", i915_energy_uJ, 0},
	{"i915_pc8_status", i915_pc8_status, 0},
};
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)

+27 −1
Original line number Diff line number Diff line
@@ -976,6 +976,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
	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 = dev_priv->mm.aliasing_ppgtt ? 1 : 0;
		break;
@@ -1483,8 +1486,24 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	mutex_init(&dev_priv->rps.hw_lock);
	mutex_init(&dev_priv->modeset_restore_lock);

	mutex_init(&dev_priv->pc8.lock);
	dev_priv->pc8.requirements_met = false;
	dev_priv->pc8.gpu_idle = false;
	dev_priv->pc8.irqs_disabled = false;
	dev_priv->pc8.enabled = false;
	dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */
	INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work);

	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))
		DRM_INFO("This is an early pre-production Haswell machine. "
			 "It may not be fully functional.\n");

	if (i915_get_bridge_dev(dev)) {
		ret = -EIO;
		goto free_priv;
@@ -1677,8 +1696,13 @@ int i915_driver_unload(struct drm_device *dev)

	intel_gpu_ips_teardown();

	if (HAS_POWER_WELL(dev))
	if (HAS_POWER_WELL(dev)) {
		/* The i915.ko module is still not prepared to be loaded when
		 * the power well is not enabled, so just enable it in case
		 * we're going to unload/reload. */
		intel_set_power_well(dev, true);
		i915_remove_power_well(dev);
	}

	i915_teardown_sysfs(dev);

@@ -1724,6 +1748,8 @@ int i915_driver_unload(struct drm_device *dev)
	cancel_work_sync(&dev_priv->gpu_error.work);
	i915_destroy_error_state(dev);

	cancel_delayed_work_sync(&dev_priv->pc8.enable_work);

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

+17 −2
Original line number Diff line number Diff line
@@ -122,10 +122,10 @@ int i915_enable_psr __read_mostly = 0;
module_param_named(enable_psr, i915_enable_psr, int, 0600);
MODULE_PARM_DESC(enable_psr, "Enable PSR (default: false)");

unsigned int i915_preliminary_hw_support __read_mostly = 0;
unsigned int i915_preliminary_hw_support __read_mostly = IS_ENABLED(CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT);
module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600);
MODULE_PARM_DESC(preliminary_hw_support,
		"Enable preliminary hardware support. (default: false)");
		"Enable preliminary hardware support.");

int i915_disable_power_well __read_mostly = 1;
module_param_named(disable_power_well, i915_disable_power_well, int, 0600);
@@ -141,6 +141,14 @@ module_param_named(fastboot, i915_fastboot, bool, 0600);
MODULE_PARM_DESC(fastboot, "Try to skip unnecessary mode sets at boot time "
		 "(default: false)");

int i915_enable_pc8 __read_mostly = 1;
module_param_named(enable_pc8, i915_enable_pc8, int, 0600);
MODULE_PARM_DESC(enable_pc8, "Enable support for low power package C states (PC8+) (default: true)");

int i915_pc8_timeout __read_mostly = 5000;
module_param_named(pc8_timeout, i915_pc8_timeout, int, 0600);
MODULE_PARM_DESC(pc8_timeout, "Number of msecs of idleness required to enter PC8+ (default: 5000)");

bool i915_prefault_disable __read_mostly;
module_param_named(prefault_disable, i915_prefault_disable, bool, 0600);
MODULE_PARM_DESC(prefault_disable,
@@ -557,6 +565,9 @@ static int i915_drm_freeze(struct drm_device *dev)
	dev_priv->modeset_restore = MODESET_SUSPENDED;
	mutex_unlock(&dev_priv->modeset_restore_lock);

	/* We do a lot of poking in a lot of registers, make sure they work
	 * properly. */
	hsw_disable_package_c8(dev_priv);
	intel_set_power_well(dev, true);

	drm_kms_helper_poll_disable(dev);
@@ -713,6 +724,10 @@ static int __i915_drm_thaw(struct drm_device *dev)
		schedule_work(&dev_priv->console_resume_work);
	}

	/* Undo what we did at i915_drm_freeze so the refcount goes back to the
	 * expected level. */
	hsw_enable_package_c8(dev_priv);

	mutex_lock(&dev_priv->modeset_restore_lock);
	dev_priv->modeset_restore = MODESET_DONE;
	mutex_unlock(&dev_priv->modeset_restore_lock);
Loading