Skip to content

Commit

Permalink
Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danve…
Browse files Browse the repository at this point in the history
…t/drm-intel into drm-next

So here's my promised pile of fixes for 3.9. I've dropped the core prep
patches for vt-switchless suspend/resume as discussed on irc. Highlights:
- Fix dmar on g4x. Not really gfx related, but I'm fed up with getting
  blamed for dmar crapouts.
- Disable wc ptes updates on ilk when dmar is enabled (Chris). So again,
  dmar, but this time gfx related :(
- Reduced range support for hsw, using the pipe CSC (Ville).
- Fixup pll limits for gen3/4 (Patrick Jakobsson). The sdvo patch is
  already confirmed to fix 2 bug reports, so added cc: stable on that one.
- Regression fix for 8bit fb console (Ville).
- Preserve lane reversal bits on DDI/FDI ports (Damien).
- Page flip vs. gpu hang fixes (Ville). Unfortuntely not quite all of
  them, need to decide what to do with the currently still in-flight ones.
- Panel fitter regression fix from Mika Kuoppala (was accidentally left on
  on some pipes with the new modset code since 3.7). This also improves
  the modeset sequence and might help a few other unrelated issues with
  lvds.
- Write backlight regs even harder ... another installement in our eternal
  fight against the BIOS and backlights.
- Fixup lid notifier vs. suspend/resume races (Zhang Rui). Prep work for
  new ACPI stuff, but closing the race itself seems worthwile on its own.
- A few other small fixes and tiny cleanups all over.

Lots of the patches are cc: stable since I've stalled on a few
not-so-important fixes for 3.8 due to the grumpy noise Linus made.

* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel: (33 commits)
  intel/iommu: force writebuffer-flush quirk on Gen 4 Chipsets
  drm/i915: Disable WC PTE updates to w/a buggy IOMMU on ILK
  drm/i915: Implement pipe CSC based limited range RGB output
  drm/i915: inverted brightness quirk for Acer Aspire 4736Z
  drm/i915: Print the hw context status is debugfs
  drm/i915: Use HAS_L3_GPU_CACHE in i915_gem_l3_remap
  drm/i915: Fix PIPE_CONTROL DW/QW write through global GTT on IVB+
  drm/i915: Set i9xx sdvo clock limits according to specifications
  drm/i915: Set i9xx lvds clock limits according to specifications
  drm/i915: Preserve the DDI link reversal configuration
  drm/i915: Preserve the FDI line reversal override bit on CPT
  drm/i915: add missing \n to UTS_RELEASE in the error_state
  drm: Use C8 instead of RGB332 when determining the format from depth/bpp
  drm: Fill depth/bits_per_pixel for C8 format
  drm/i915: don't clflush gem objects in stolen memory
  drm/i915: Don't wait for page flips if there was GPU reset
  drm/i915: Kill obj->pending_flip
  drm/i915: Fix a typo in a intel_modeset_stage_output_state() comment
  drm/i915: remove bogus mutex_unlock from error-path
  drm/i915: Print the pipe control page GTT address
  ...
  • Loading branch information
Dave Airlie committed Feb 20, 2013
2 parents 35f8bad + 210561f commit b81e059
Show file tree
Hide file tree
Showing 24 changed files with 482 additions and 238 deletions.
42 changes: 39 additions & 3 deletions drivers/char/agp/intel-gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,40 @@ static void intel_gtt_cleanup(void)
intel_gtt_teardown_scratch_page();
}

/* Certain Gen5 chipsets require require idling the GPU before
* unmapping anything from the GTT when VT-d is enabled.
*/
static inline int needs_ilk_vtd_wa(void)
{
#ifdef CONFIG_INTEL_IOMMU
const unsigned short gpu_devid = intel_private.pcidev->device;

/* Query intel_iommu to see if we need the workaround. Presumably that
* was loaded first.
*/
if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB ||
gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
intel_iommu_gfx_mapped)
return 1;
#endif
return 0;
}

static bool intel_gtt_can_wc(void)
{
if (INTEL_GTT_GEN <= 2)
return false;

if (INTEL_GTT_GEN >= 6)
return false;

/* Reports of major corruption with ILK vt'd enabled */
if (needs_ilk_vtd_wa())
return false;

return true;
}

static int intel_gtt_init(void)
{
u32 gma_addr;
Expand Down Expand Up @@ -601,7 +635,7 @@ static int intel_gtt_init(void)
gtt_map_size = intel_private.gtt_total_entries * 4;

intel_private.gtt = NULL;
if (INTEL_GTT_GEN < 6 && INTEL_GTT_GEN > 2)
if (intel_gtt_can_wc())
intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr,
gtt_map_size);
if (intel_private.gtt == NULL)
Expand Down Expand Up @@ -1072,7 +1106,6 @@ static void i965_write_entry(dma_addr_t addr,
writel(addr | pte_flags, intel_private.gtt + entry);
}


static int i9xx_setup(void)
{
u32 reg_addr, gtt_addr;
Expand Down Expand Up @@ -1371,10 +1404,13 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
}
EXPORT_SYMBOL(intel_gmch_probe);

void intel_gtt_get(size_t *gtt_total, size_t *stolen_size)
void intel_gtt_get(size_t *gtt_total, size_t *stolen_size,
phys_addr_t *mappable_base, unsigned long *mappable_end)
{
*gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT;
*stolen_size = intel_private.stolen_size;
*mappable_base = intel_private.gma_bus_addr;
*mappable_end = intel_private.gtt_mappable_entries << PAGE_SHIFT;
}
EXPORT_SYMBOL(intel_gtt_get);

Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2267,7 +2267,7 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth)

switch (bpp) {
case 8:
fmt = DRM_FORMAT_RGB332;
fmt = DRM_FORMAT_C8;
break;
case 16:
if (depth == 15)
Expand Down Expand Up @@ -3870,6 +3870,7 @@ void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
int *bpp)
{
switch (format) {
case DRM_FORMAT_C8:
case DRM_FORMAT_RGB332:
case DRM_FORMAT_BGR233:
*depth = 8;
Expand Down
13 changes: 11 additions & 2 deletions drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ static int i915_error_state(struct seq_file *m, void *unused)

seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
error->time.tv_usec);
seq_printf(m, "Kernel: " UTS_RELEASE);
seq_printf(m, "Kernel: " UTS_RELEASE "\n");
seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
seq_printf(m, "EIR: 0x%08x\n", error->eir);
seq_printf(m, "IER: 0x%08x\n", error->ier);
Expand Down Expand Up @@ -1484,7 +1484,8 @@ static int i915_context_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;
drm_i915_private_t *dev_priv = dev->dev_private;
int ret;
struct intel_ring_buffer *ring;
int ret, i;

ret = mutex_lock_interruptible(&dev->mode_config.mutex);
if (ret)
Expand All @@ -1502,6 +1503,14 @@ static int i915_context_status(struct seq_file *m, void *unused)
seq_printf(m, "\n");
}

for_each_ring(ring, dev_priv, i) {
if (ring->default_context) {
seq_printf(m, "HW default context %s ring ", ring->name);
describe_obj(m, ring->default_context->obj);
seq_printf(m, "\n");
}
}

mutex_unlock(&dev->mode_config.mutex);

return 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
mutex_init(&dev_priv->dpio_lock);

mutex_init(&dev_priv->rps.hw_lock);
mutex_init(&dev_priv->modeset_restore_lock);

if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
dev_priv->num_pipe = 3;
Expand Down
13 changes: 8 additions & 5 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,11 @@ static int i915_drm_freeze(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;

/* ignore lid events during suspend */
mutex_lock(&dev_priv->modeset_restore_lock);
dev_priv->modeset_restore = MODESET_SUSPENDED;
mutex_unlock(&dev_priv->modeset_restore_lock);

intel_set_power_well(dev, true);

drm_kms_helper_poll_disable(dev);
Expand All @@ -496,9 +501,6 @@ static int i915_drm_freeze(struct drm_device *dev)

intel_opregion_fini(dev);

/* Modeset on resume, not lid events */
dev_priv->modeset_on_lid = 0;

console_lock();
intel_fbdev_set_suspend(dev, 1);
console_unlock();
Expand Down Expand Up @@ -574,8 +576,6 @@ static int __i915_drm_thaw(struct drm_device *dev)

intel_opregion_init(dev);

dev_priv->modeset_on_lid = 0;

/*
* The console lock can be pretty contented on resume due
* to all the printk activity. Try to keep it out of the hot
Expand All @@ -588,6 +588,9 @@ static int __i915_drm_thaw(struct drm_device *dev)
schedule_work(&dev_priv->console_resume_work);
}

mutex_lock(&dev_priv->modeset_restore_lock);
dev_priv->modeset_restore = MODESET_DONE;
mutex_unlock(&dev_priv->modeset_restore_lock);
return error;
}

Expand Down
24 changes: 12 additions & 12 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,8 @@ struct i915_gtt {

/* global gtt ops */
int (*gtt_probe)(struct drm_device *dev, size_t *gtt_total,
size_t *stolen);
size_t *stolen, phys_addr_t *mappable_base,
unsigned long *mappable_end);
void (*gtt_remove)(struct drm_device *dev);
void (*gtt_clear_range)(struct drm_device *dev,
unsigned int first_entry,
Expand Down Expand Up @@ -846,6 +847,12 @@ struct i915_gpu_error {
unsigned int stop_rings;
};

enum modeset_restore {
MODESET_ON_LID_OPEN,
MODESET_DONE,
MODESET_SUSPENDED,
};

typedef struct drm_i915_private {
struct drm_device *dev;
struct kmem_cache *slab;
Expand Down Expand Up @@ -919,7 +926,7 @@ typedef struct drm_i915_private {

/* overlay */
struct intel_overlay *overlay;
bool sprite_scaling_enabled;
unsigned int sprite_scaling_enabled;

/* LVDS info */
int backlight_level; /* restore backlight to this value */
Expand Down Expand Up @@ -967,8 +974,8 @@ typedef struct drm_i915_private {

unsigned long quirks;

/* Register state */
bool modeset_on_lid;
enum modeset_restore modeset_restore;
struct mutex modeset_restore_lock;

struct i915_gtt gtt;

Expand Down Expand Up @@ -1033,7 +1040,7 @@ typedef struct drm_i915_private {
bool hw_contexts_disabled;
uint32_t hw_context_size;

bool fdi_rx_polarity_reversed;
u32 fdi_rx_config;

struct i915_suspend_saved_registers regfile;

Expand Down Expand Up @@ -1208,13 +1215,6 @@ struct drm_i915_gem_object {

/** for phy allocated objects */
struct drm_i915_gem_phys_object *phys_obj;

/**
* Number of crtcs where this object is currently the fb, but
* will be page flipped away on the next vblank. When it
* reaches 0, dev_priv->pending_flip_queue will be woken up.
*/
atomic_t pending_flip;
};
#define to_gem_object(obj) (&((struct drm_i915_gem_object *)(obj))->base)

Expand Down
62 changes: 42 additions & 20 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -3021,6 +3021,13 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj)
if (obj->pages == NULL)
return;

/*
* Stolen memory is always coherent with the GPU as it is explicitly
* marked as wc by the system, or the system is cache-coherent.
*/
if (obj->stolen)
return;

/* If the GPU is snooping the contents of the CPU cache,
* we do not need to manually clear the CPU cache lines. However,
* the caches are only snooped when the render cache is
Expand Down Expand Up @@ -3865,7 +3872,7 @@ void i915_gem_l3_remap(struct drm_device *dev)
u32 misccpctl;
int i;

if (!IS_IVYBRIDGE(dev))
if (!HAS_L3_GPU_CACHE(dev))
return;

if (!dev_priv->l3_parity.remap_info)
Expand Down Expand Up @@ -3930,22 +3937,11 @@ intel_enable_blt(struct drm_device *dev)
return true;
}

int
i915_gem_init_hw(struct drm_device *dev)
static int i915_gem_init_rings(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_private *dev_priv = dev->dev_private;
int ret;

if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
return -EIO;

if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1))
I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000);

i915_gem_l3_remap(dev);

i915_gem_init_swizzling(dev);

ret = intel_init_render_ring_buffer(dev);
if (ret)
return ret;
Expand All @@ -3963,6 +3959,38 @@ i915_gem_init_hw(struct drm_device *dev)
}

ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000));
if (ret)
goto cleanup_blt_ring;

return 0;

cleanup_blt_ring:
intel_cleanup_ring_buffer(&dev_priv->ring[BCS]);
cleanup_bsd_ring:
intel_cleanup_ring_buffer(&dev_priv->ring[VCS]);
cleanup_render_ring:
intel_cleanup_ring_buffer(&dev_priv->ring[RCS]);

return ret;
}

int
i915_gem_init_hw(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
int ret;

if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt())
return -EIO;

if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1))
I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000);

i915_gem_l3_remap(dev);

i915_gem_init_swizzling(dev);

ret = i915_gem_init_rings(dev);
if (ret)
return ret;

Expand All @@ -3974,12 +4002,6 @@ i915_gem_init_hw(struct drm_device *dev)
i915_gem_init_ppgtt(dev);

return 0;

cleanup_bsd_ring:
intel_cleanup_ring_buffer(&dev_priv->ring[VCS]);
cleanup_render_ring:
intel_cleanup_ring_buffer(&dev_priv->ring[RCS]);
return ret;
}

int i915_gem_init(struct drm_device *dev)
Expand Down
12 changes: 2 additions & 10 deletions drivers/gpu/drm/i915/i915_gem_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,8 @@ static int get_context_size(struct drm_device *dev)

static void do_destroy(struct i915_hw_context *ctx)
{
struct drm_device *dev = ctx->obj->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;

if (ctx->file_priv)
idr_remove(&ctx->file_priv->context_idr, ctx->id);
else
BUG_ON(ctx != dev_priv->ring[RCS].default_context);

drm_gem_object_unreference(&ctx->obj->base);
kfree(ctx);
Expand Down Expand Up @@ -242,7 +237,6 @@ static int create_default_context(struct drm_i915_private *dev_priv)
void i915_gem_context_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t ctx_size;

if (!HAS_HW_CONTEXTS(dev)) {
dev_priv->hw_contexts_disabled = true;
Expand All @@ -254,11 +248,9 @@ void i915_gem_context_init(struct drm_device *dev)
dev_priv->ring[RCS].default_context)
return;

ctx_size = get_context_size(dev);
dev_priv->hw_context_size = get_context_size(dev);
dev_priv->hw_context_size = round_up(dev_priv->hw_context_size, 4096);
dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);

if (ctx_size <= 0 || ctx_size > (1<<20)) {
if (dev_priv->hw_context_size > (1<<20)) {
dev_priv->hw_contexts_disabled = true;
return;
}
Expand Down
Loading

0 comments on commit b81e059

Please sign in to comment.