Skip to content

Commit

Permalink
Merge tag 'drm-intel-next-2012-02-16-merge-resolved' of git://people.…
Browse files Browse the repository at this point in the history
…freedesktop.org/~danvet/drm-intel into drm-core-next

* tag 'drm-intel-next-2012-02-16-merge-resolved' of git://people.freedesktop.org/~danvet/drm-intel: (45 commits)
  Revert "drivers/gpu/drm/i915/intel_overlay.c needs seq_file.h"
  drm/i915/lvds: Always use the presence pin for LVDS on PCH
  drm/i915: Record the position of the request upon error
  drm/i915: Record the in-flight requests at the time of a hang
  drm/i915: Record the tail at each request and use it to estimate the head
  drm/i915: add missing SDVO bits for interlaced modes on ILK
  drm/i915: Fix race condition in accessing GMBUS
  drm/i915: add a "force-dvi" HDMI audio mode
  drm/i915: Don't lock panel registers when downclocking
  drm/i915: fix up locking inconsistency around gem_do_init
  drm/i915: enable forcewake voodoo also for gen6
  drm/i915: fixup seqno allocation logic for lazy_request
  drm/i915: outstanding_lazy_request is a u32
  drm/i915: check gtfifodbg after possibly failed writes
  drm/i915: catch gtfifo errors on forcewake_put
  drm/i915: use gtfifodbg
  drm/i915: set interlaced bits for TRANSCONF
  drm/i915: fixup overlay checks for interlaced modes
  drm/i915: allow interlaced mode output on the HDMI connector
  drm/i915: allow interlaced mode output on the SDVO connector
  ...
  • Loading branch information
Dave Airlie committed Feb 23, 2012
2 parents 019d96c + ff5f4b0 commit e5bcf23
Show file tree
Hide file tree
Showing 28 changed files with 1,044 additions and 230 deletions.
10 changes: 5 additions & 5 deletions drivers/char/agp/intel-gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ static struct _intel_private {
struct resource ifp_resource;
int resource_valid;
struct page *scratch_page;
dma_addr_t scratch_page_dma;
} intel_private;

#define INTEL_GTT_GEN intel_private.driver->gen
Expand Down Expand Up @@ -306,9 +305,9 @@ static int intel_gtt_setup_scratch_page(void)
if (pci_dma_mapping_error(intel_private.pcidev, dma_addr))
return -EINVAL;

intel_private.scratch_page_dma = dma_addr;
intel_private.base.scratch_page_dma = dma_addr;
} else
intel_private.scratch_page_dma = page_to_phys(page);
intel_private.base.scratch_page_dma = page_to_phys(page);

intel_private.scratch_page = page;

Expand Down Expand Up @@ -631,7 +630,7 @@ 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,
pci_unmap_page(intel_private.pcidev, intel_private.base.scratch_page_dma,
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
put_page(intel_private.scratch_page);
__free_page(intel_private.scratch_page);
Expand Down Expand Up @@ -681,6 +680,7 @@ static int intel_gtt_init(void)
iounmap(intel_private.registers);
return -ENOMEM;
}
intel_private.base.gtt = intel_private.gtt;

global_cache_flush(); /* FIXME: ? */

Expand Down Expand Up @@ -975,7 +975,7 @@ void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries)
unsigned int i;

for (i = first_entry; i < (first_entry + num_entries); i++) {
intel_private.driver->write_entry(intel_private.scratch_page_dma,
intel_private.driver->write_entry(intel_private.base.scratch_page_dma,
i, 0);
}
readl(intel_private.gtt+i-1);
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/drm_ioc32.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd,
if (err)
return err;

if (__get_user(c32.auth, &client->auth)
if (__get_user(c32.idx, &client->idx)
|| __get_user(c32.auth, &client->auth)
|| __get_user(c32.pid, &client->pid)
|| __get_user(c32.uid, &client->uid)
|| __get_user(c32.magic, &client->magic)
Expand Down
82 changes: 74 additions & 8 deletions drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,8 +721,14 @@ static void i915_ring_error_state(struct seq_file *m,
if (INTEL_INFO(dev)->gen >= 6) {
seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]);
seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]);
seq_printf(m, " SYNC_0: 0x%08x\n",
error->semaphore_mboxes[ring][0]);
seq_printf(m, " SYNC_1: 0x%08x\n",
error->semaphore_mboxes[ring][1]);
}
seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]);
seq_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]);
seq_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]);
}

static int i915_error_state(struct seq_file *m, void *unused)
Expand All @@ -732,7 +738,7 @@ static int i915_error_state(struct seq_file *m, void *unused)
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_error_state *error;
unsigned long flags;
int i, page, offset, elt;
int i, j, page, offset, elt;

spin_lock_irqsave(&dev_priv->error_lock, flags);
if (!dev_priv->first_error) {
Expand Down Expand Up @@ -772,10 +778,10 @@ static int i915_error_state(struct seq_file *m, void *unused)
error->pinned_bo,
error->pinned_bo_count);

for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) {
if (error->batchbuffer[i]) {
struct drm_i915_error_object *obj = error->batchbuffer[i];
for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
struct drm_i915_error_object *obj;

if ((obj = error->ring[i].batchbuffer)) {
seq_printf(m, "%s --- gtt_offset = 0x%08x\n",
dev_priv->ring[i].name,
obj->gtt_offset);
Expand All @@ -787,11 +793,20 @@ static int i915_error_state(struct seq_file *m, void *unused)
}
}
}
}

for (i = 0; i < ARRAY_SIZE(error->ringbuffer); i++) {
if (error->ringbuffer[i]) {
struct drm_i915_error_object *obj = error->ringbuffer[i];
if (error->ring[i].num_requests) {
seq_printf(m, "%s --- %d requests\n",
dev_priv->ring[i].name,
error->ring[i].num_requests);
for (j = 0; j < error->ring[i].num_requests; j++) {
seq_printf(m, " seqno 0x%08x, emitted %ld, tail 0x%08x\n",
error->ring[i].requests[j].seqno,
error->ring[i].requests[j].jiffies,
error->ring[i].requests[j].tail);
}
}

if ((obj = error->ring[i].ringbuffer)) {
seq_printf(m, "%s --- ringbuffer = 0x%08x\n",
dev_priv->ring[i].name,
obj->gtt_offset);
Expand Down Expand Up @@ -1431,7 +1446,57 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
I915_READ16(C0DRB3));
seq_printf(m, "C1DRB3 = 0x%04x\n",
I915_READ16(C1DRB3));
} else if (IS_GEN6(dev) || IS_GEN7(dev)) {
seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n",
I915_READ(MAD_DIMM_C0));
seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n",
I915_READ(MAD_DIMM_C1));
seq_printf(m, "MAD_DIMM_C2 = 0x%08x\n",
I915_READ(MAD_DIMM_C2));
seq_printf(m, "TILECTL = 0x%08x\n",
I915_READ(TILECTL));
seq_printf(m, "ARB_MODE = 0x%08x\n",
I915_READ(ARB_MODE));
seq_printf(m, "DISP_ARB_CTL = 0x%08x\n",
I915_READ(DISP_ARB_CTL));
}
mutex_unlock(&dev->struct_mutex);

return 0;
}

static int i915_ppgtt_info(struct seq_file *m, void *data)
{
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 intel_ring_buffer *ring;
int i, ret;


ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret)
return ret;
if (INTEL_INFO(dev)->gen == 6)
seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE));

for (i = 0; i < I915_NUM_RINGS; i++) {
ring = &dev_priv->ring[i];

seq_printf(m, "%s\n", ring->name);
if (INTEL_INFO(dev)->gen == 7)
seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring)));
seq_printf(m, "PP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(ring)));
seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", I915_READ(RING_PP_DIR_BASE_READ(ring)));
seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", I915_READ(RING_PP_DIR_DCLV(ring)));
}
if (dev_priv->mm.aliasing_ppgtt) {
struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;

seq_printf(m, "aliasing PPGTT:\n");
seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
}
seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
mutex_unlock(&dev->struct_mutex);

return 0;
Expand Down Expand Up @@ -1778,6 +1843,7 @@ static struct drm_info_list i915_debugfs_list[] = {
{"i915_context_status", i915_context_status, 0},
{"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0},
{"i915_swizzle_info", i915_swizzle_info, 0},
{"i915_ppgtt_info", i915_ppgtt_info, 0},
};
#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)

Expand Down
45 changes: 32 additions & 13 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,22 +1196,39 @@ static int i915_load_gem_init(struct drm_device *dev)
/* Basic memrange allocator for stolen space */
drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size);

/* Let GEM Manage all of the aperture.
*
* However, leave one page at the end still bound to the scratch page.
* There are a number of places where the hardware apparently
* prefetches past the end of the object, and we've seen multiple
* hangs with the GPU head pointer stuck in a batchbuffer bound
* at the last page of the aperture. One page should be enough to
* keep any prefetching inside of the aperture.
*/
i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE);

mutex_lock(&dev->struct_mutex);
ret = i915_gem_init_ringbuffer(dev);
if (i915_enable_ppgtt && HAS_ALIASING_PPGTT(dev)) {
/* PPGTT pdes are stolen from global gtt ptes, so shrink the
* aperture accordingly when using aliasing ppgtt. */
gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE;
/* For paranoia keep the guard page in between. */
gtt_size -= PAGE_SIZE;

i915_gem_do_init(dev, 0, mappable_size, gtt_size);

ret = i915_gem_init_aliasing_ppgtt(dev);
if (ret)
return ret;
} else {
/* Let GEM Manage all of the aperture.
*
* However, leave one page at the end still bound to the scratch
* page. There are a number of places where the hardware
* apparently prefetches past the end of the object, and we've
* seen multiple hangs with the GPU head pointer stuck in a
* batchbuffer bound at the last page of the aperture. One page
* should be enough to keep any prefetching inside of the
* aperture.
*/
i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE);
}

ret = i915_gem_init_hw(dev);
mutex_unlock(&dev->struct_mutex);
if (ret)
if (ret) {
i915_gem_cleanup_aliasing_ppgtt(dev);
return ret;
}

/* Try to set up FBC with a reasonable compressed buffer size */
if (I915_HAS_FBC(dev) && i915_powersave) {
Expand Down Expand Up @@ -1298,6 +1315,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
mutex_lock(&dev->struct_mutex);
i915_gem_cleanup_ringbuffer(dev);
mutex_unlock(&dev->struct_mutex);
i915_gem_cleanup_aliasing_ppgtt(dev);
cleanup_vga_switcheroo:
vga_switcheroo_unregister_client(dev->pdev);
cleanup_vga_client:
Expand Down Expand Up @@ -2187,6 +2205,7 @@ int i915_driver_unload(struct drm_device *dev)
i915_gem_free_all_phys_object(dev);
i915_gem_cleanup_ringbuffer(dev);
mutex_unlock(&dev->struct_mutex);
i915_gem_cleanup_aliasing_ppgtt(dev);
if (I915_HAS_FBC(dev) && i915_powersave)
i915_cleanup_compression(dev);
drm_mm_takedown(&dev_priv->mm.stolen);
Expand Down
41 changes: 35 additions & 6 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ MODULE_PARM_DESC(enable_hangcheck,
"WARNING: Disabling this can cause system wide hangs. "
"(default: true)");

bool i915_enable_ppgtt __read_mostly = 1;
module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, bool, 0600);
MODULE_PARM_DESC(i915_enable_ppgtt,
"Enable PPGTT (default: true)");

static struct drm_driver driver;
extern int intel_agp_enabled;

Expand Down Expand Up @@ -380,16 +385,27 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}

static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
{
u32 gtfifodbg;
gtfifodbg = I915_READ_NOTRACE(GTFIFODBG);
if (WARN(gtfifodbg & GT_FIFO_CPU_ERROR_MASK,
"MMIO read or write has been dropped %x\n", gtfifodbg))
I915_WRITE_NOTRACE(GTFIFODBG, GT_FIFO_CPU_ERROR_MASK);
}

void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE, 0);
POSTING_READ(FORCEWAKE);
/* The below doubles as a POSTING_READ */
gen6_gt_check_fifodbg(dev_priv);
}

void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0);
POSTING_READ(FORCEWAKE_MT);
/* The below doubles as a POSTING_READ */
gen6_gt_check_fifodbg(dev_priv);
}

/*
Expand All @@ -405,19 +421,24 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
}

void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
{
int ret = 0;

if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
int loop = 500;
u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
udelay(10);
fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
}
WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES);
if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
++ret;
dev_priv->gt_fifo_count = fifo;
}
dev_priv->gt_fifo_count--;

return ret;
}

static int i915_drm_freeze(struct drm_device *dev)
Expand Down Expand Up @@ -498,7 +519,7 @@ static int i915_drm_thaw(struct drm_device *dev)
mutex_lock(&dev->struct_mutex);
dev_priv->mm.suspended = 0;

error = i915_gem_init_ringbuffer(dev);
error = i915_gem_init_hw(dev);
mutex_unlock(&dev->struct_mutex);

if (HAS_PCH_SPLIT(dev))
Expand Down Expand Up @@ -713,12 +734,16 @@ int i915_reset(struct drm_device *dev, u8 flags)
!dev_priv->mm.suspended) {
dev_priv->mm.suspended = 0;

i915_gem_init_swizzling(dev);

dev_priv->ring[RCS].init(&dev_priv->ring[RCS]);
if (HAS_BSD(dev))
dev_priv->ring[VCS].init(&dev_priv->ring[VCS]);
if (HAS_BLT(dev))
dev_priv->ring[BCS].init(&dev_priv->ring[BCS]);

i915_gem_init_ppgtt(dev);

mutex_unlock(&dev->struct_mutex);
drm_irq_uninstall(dev);
drm_mode_config_reset(dev);
Expand Down Expand Up @@ -981,11 +1006,15 @@ __i915_read(64, q)

#define __i915_write(x, y) \
void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
u32 __fifo_ret = 0; \
trace_i915_reg_rw(true, reg, val, sizeof(val)); \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
__gen6_gt_wait_for_fifo(dev_priv); \
__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
} \
write##y(val, dev_priv->regs + reg); \
if (unlikely(__fifo_ret)) { \
gen6_gt_check_fifodbg(dev_priv); \
} \
}
__i915_write(8, b)
__i915_write(16, w)
Expand Down
Loading

0 comments on commit e5bcf23

Please sign in to comment.