Skip to content

Commit

Permalink
Merge tag 'drm-intel-next-2013-08-23' of git://people.freedesktop.org…
Browse files Browse the repository at this point in the history
…/~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
  ...
  • Loading branch information
airlied committed Aug 29, 2013
2 parents 62f2104 + fb1ae91 commit efa27f9
Show file tree
Hide file tree
Showing 26 changed files with 1,060 additions and 385 deletions.
11 changes: 11 additions & 0 deletions drivers/gpu/drm/Kconfig
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/drm_mm.c
Expand Up @@ -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);

Expand Down
65 changes: 58 additions & 7 deletions drivers/gpu/drm/i915/i915_debugfs.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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),
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
Expand All @@ -229,19 +232,19 @@ 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++;
}
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);

Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)

Expand Down
28 changes: 27 additions & 1 deletion drivers/gpu/drm/i915/i915_dma.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down
19 changes: 17 additions & 2 deletions drivers/gpu/drm/i915/i915_drv.c
Expand Up @@ -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);
Expand All @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit efa27f9

Please sign in to comment.