Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 218336
b: refs/heads/master
c: 549f736
h: refs/heads/master
v: v3
  • Loading branch information
Chris Wilson committed Oct 21, 2010
1 parent b9eb63c commit f3ea07c
Show file tree
Hide file tree
Showing 12 changed files with 176 additions and 64 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e36c1cd7292efcb8daca26cd6331481736544742
refs/heads/master: 549f7365820a212a1cfd0871d377b1ad0d1e5723
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ static int i915_capabilities(struct seq_file *m, void *data)
B(has_overlay);
B(overlay_needs_physical);
B(supports_tv);
B(has_bsd_ring);
B(has_blt_ring);
#undef B

return 0;
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ static int i915_dma_cleanup(struct drm_device * dev)
mutex_lock(&dev->struct_mutex);
intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring);
mutex_unlock(&dev->struct_mutex);

/* Clear the HWS virtual address at teardown */
Expand Down Expand Up @@ -763,6 +764,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_BSD:
value = HAS_BSD(dev);
break;
case I915_PARAM_HAS_BLT:
value = HAS_BLT(dev);
break;
default:
DRM_DEBUG_DRIVER("Unknown parameter %d\n",
param->param);
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,14 @@ static const struct intel_device_info intel_sandybridge_d_info = {
.gen = 6,
.need_gfx_hws = 1, .has_hotplug = 1,
.has_bsd_ring = 1,
.has_blt_ring = 1,
};

static const struct intel_device_info intel_sandybridge_m_info = {
.gen = 6, .is_mobile = 1,
.need_gfx_hws = 1, .has_hotplug = 1,
.has_bsd_ring = 1,
.has_blt_ring = 1,
};

static const struct pci_device_id pciidlist[] = { /* aka */
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ struct intel_device_info {
u8 overlay_needs_physical : 1;
u8 supports_tv : 1;
u8 has_bsd_ring : 1;
u8 has_blt_ring : 1;
};

enum no_fbc_reason {
Expand Down Expand Up @@ -255,6 +256,7 @@ typedef struct drm_i915_private {
struct pci_dev *bridge_dev;
struct intel_ring_buffer render_ring;
struct intel_ring_buffer bsd_ring;
struct intel_ring_buffer blt_ring;
uint32_t next_seqno;

drm_dma_handle_t *status_page_dmah;
Expand Down Expand Up @@ -1300,6 +1302,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,
#define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6)

#define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring)
#define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring)
#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws)

#define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay)
Expand Down
55 changes: 48 additions & 7 deletions trunk/drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1800,6 +1800,7 @@ void i915_gem_reset(struct drm_device *dev)

i915_gem_reset_ring_lists(dev_priv, &dev_priv->render_ring);
i915_gem_reset_ring_lists(dev_priv, &dev_priv->bsd_ring);
i915_gem_reset_ring_lists(dev_priv, &dev_priv->blt_ring);

/* Remove anything from the flushing lists. The GPU cache is likely
* to be lost on reset along with the data, so simply move the
Expand Down Expand Up @@ -1922,6 +1923,7 @@ i915_gem_retire_requests(struct drm_device *dev)

i915_gem_retire_requests_ring(dev, &dev_priv->render_ring);
i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring);
i915_gem_retire_requests_ring(dev, &dev_priv->blt_ring);
}

static void
Expand All @@ -1944,7 +1946,8 @@ i915_gem_retire_work_handler(struct work_struct *work)

if (!dev_priv->mm.suspended &&
(!list_empty(&dev_priv->render_ring.request_list) ||
!list_empty(&dev_priv->bsd_ring.request_list)))
!list_empty(&dev_priv->bsd_ring.request_list) ||
!list_empty(&dev_priv->blt_ring.request_list)))
queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ);
mutex_unlock(&dev->struct_mutex);
}
Expand Down Expand Up @@ -2063,6 +2066,10 @@ i915_gem_flush(struct drm_device *dev,
i915_gem_flush_ring(dev, file_priv,
&dev_priv->bsd_ring,
invalidate_domains, flush_domains);
if (flush_rings & RING_BLT)
i915_gem_flush_ring(dev, file_priv,
&dev_priv->blt_ring,
invalidate_domains, flush_domains);
}
}

Expand Down Expand Up @@ -2182,7 +2189,8 @@ i915_gpu_idle(struct drm_device *dev)

lists_empty = (list_empty(&dev_priv->mm.flushing_list) &&
list_empty(&dev_priv->render_ring.active_list) &&
list_empty(&dev_priv->bsd_ring.active_list));
list_empty(&dev_priv->bsd_ring.active_list) &&
list_empty(&dev_priv->blt_ring.active_list));
if (lists_empty)
return 0;

Expand All @@ -2195,6 +2203,10 @@ i915_gpu_idle(struct drm_device *dev)
if (ret)
return ret;

ret = i915_ring_idle(dev, &dev_priv->blt_ring);
if (ret)
return ret;

return 0;
}

Expand Down Expand Up @@ -3609,14 +3621,29 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
(int) args->buffers_ptr, args->buffer_count, args->batch_len);
#endif
if (args->flags & I915_EXEC_BSD) {
switch (args->flags & I915_EXEC_RING_MASK) {
case I915_EXEC_DEFAULT:
case I915_EXEC_RENDER:
ring = &dev_priv->render_ring;
break;
case I915_EXEC_BSD:
if (!HAS_BSD(dev)) {
DRM_ERROR("execbuf with wrong flag\n");
DRM_ERROR("execbuf with invalid ring (BSD)\n");
return -EINVAL;
}
ring = &dev_priv->bsd_ring;
} else {
ring = &dev_priv->render_ring;
break;
case I915_EXEC_BLT:
if (!HAS_BLT(dev)) {
DRM_ERROR("execbuf with invalid ring (BLT)\n");
return -EINVAL;
}
ring = &dev_priv->blt_ring;
break;
default:
DRM_ERROR("execbuf with unknown ring: %d\n",
(int)(args->flags & I915_EXEC_RING_MASK));
return -EINVAL;
}

if (args->buffer_count < 1) {
Expand Down Expand Up @@ -4482,10 +4509,18 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
goto cleanup_render_ring;
}

if (HAS_BLT(dev)) {
ret = intel_init_blt_ring_buffer(dev);
if (ret)
goto cleanup_bsd_ring;
}

dev_priv->next_seqno = 1;

return 0;

cleanup_bsd_ring:
intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
cleanup_render_ring:
intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
cleanup_pipe_control:
Expand All @@ -4501,6 +4536,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)

intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring);
if (HAS_PIPE_CONTROL(dev))
i915_gem_cleanup_pipe_control(dev);
}
Expand Down Expand Up @@ -4532,10 +4568,12 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
BUG_ON(!list_empty(&dev_priv->mm.active_list));
BUG_ON(!list_empty(&dev_priv->render_ring.active_list));
BUG_ON(!list_empty(&dev_priv->bsd_ring.active_list));
BUG_ON(!list_empty(&dev_priv->blt_ring.active_list));
BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
BUG_ON(!list_empty(&dev_priv->render_ring.request_list));
BUG_ON(!list_empty(&dev_priv->bsd_ring.request_list));
BUG_ON(!list_empty(&dev_priv->blt_ring.request_list));
mutex_unlock(&dev->struct_mutex);

ret = drm_irq_install(dev);
Expand Down Expand Up @@ -4594,6 +4632,8 @@ i915_gem_load(struct drm_device *dev)
INIT_LIST_HEAD(&dev_priv->render_ring.request_list);
INIT_LIST_HEAD(&dev_priv->bsd_ring.active_list);
INIT_LIST_HEAD(&dev_priv->bsd_ring.request_list);
INIT_LIST_HEAD(&dev_priv->blt_ring.active_list);
INIT_LIST_HEAD(&dev_priv->blt_ring.request_list);
for (i = 0; i < 16; i++)
INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list);
INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
Expand Down Expand Up @@ -4857,7 +4897,8 @@ i915_gpu_is_active(struct drm_device *dev)

lists_empty = list_empty(&dev_priv->mm.flushing_list) &&
list_empty(&dev_priv->render_ring.active_list) &&
list_empty(&dev_priv->bsd_ring.active_list);
list_empty(&dev_priv->bsd_ring.active_list) &&
list_empty(&dev_priv->blt_ring.active_list);

return !lists_empty;
}
Expand Down
6 changes: 4 additions & 2 deletions trunk/drivers/gpu/drm/i915/i915_gem_evict.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ i915_gem_evict_everything(struct drm_device *dev)
lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
list_empty(&dev_priv->mm.flushing_list) &&
list_empty(&dev_priv->render_ring.active_list) &&
list_empty(&dev_priv->bsd_ring.active_list));
list_empty(&dev_priv->bsd_ring.active_list) &&
list_empty(&dev_priv->blt_ring.active_list));
if (lists_empty)
return -ENOSPC;

Expand All @@ -184,7 +185,8 @@ i915_gem_evict_everything(struct drm_device *dev)
lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
list_empty(&dev_priv->mm.flushing_list) &&
list_empty(&dev_priv->render_ring.active_list) &&
list_empty(&dev_priv->bsd_ring.active_list));
list_empty(&dev_priv->bsd_ring.active_list) &&
list_empty(&dev_priv->blt_ring.active_list));
BUG_ON(!lists_empty);

return 0;
Expand Down
64 changes: 38 additions & 26 deletions trunk/drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,14 +293,26 @@ static void i915_handle_rps_change(struct drm_device *dev)
return;
}

static void notify_ring(struct drm_device *dev,
struct intel_ring_buffer *ring)
{
struct drm_i915_private *dev_priv = dev->dev_private;
u32 seqno = ring->get_seqno(dev, ring);
ring->irq_gem_seqno = seqno;
trace_i915_gem_request_complete(dev, seqno);
wake_up_all(&ring->irq_queue);
dev_priv->hangcheck_count = 0;
mod_timer(&dev_priv->hangcheck_timer,
jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD));
}

static irqreturn_t ironlake_irq_handler(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE;
u32 de_iir, gt_iir, de_ier, pch_iir;
u32 hotplug_mask;
struct drm_i915_master_private *master_priv;
struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT;

if (IS_GEN6(dev))
Expand Down Expand Up @@ -332,17 +344,12 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev)
READ_BREADCRUMB(dev_priv);
}

if (gt_iir & GT_PIPE_NOTIFY) {
u32 seqno = render_ring->get_seqno(dev, render_ring);
render_ring->irq_gem_seqno = seqno;
trace_i915_gem_request_complete(dev, seqno);
wake_up_all(&dev_priv->render_ring.irq_queue);
dev_priv->hangcheck_count = 0;
mod_timer(&dev_priv->hangcheck_timer,
jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD));
}
if (gt_iir & GT_PIPE_NOTIFY)
notify_ring(dev, &dev_priv->render_ring);
if (gt_iir & bsd_usr_interrupt)
wake_up_all(&dev_priv->bsd_ring.irq_queue);
notify_ring(dev, &dev_priv->bsd_ring);
if (HAS_BLT(dev) && gt_iir & GT_BLT_USER_INTERRUPT)
notify_ring(dev, &dev_priv->blt_ring);

if (de_iir & DE_GSE)
intel_opregion_gse_intr(dev);
Expand Down Expand Up @@ -881,6 +888,8 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
wake_up_all(&dev_priv->render_ring.irq_queue);
if (HAS_BSD(dev))
wake_up_all(&dev_priv->bsd_ring.irq_queue);
if (HAS_BLT(dev))
wake_up_all(&dev_priv->blt_ring.irq_queue);
}

queue_work(dev_priv->wq, &dev_priv->error_work);
Expand Down Expand Up @@ -941,7 +950,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
unsigned long irqflags;
int irq_received;
int ret = IRQ_NONE;
struct intel_ring_buffer *render_ring = &dev_priv->render_ring;

atomic_inc(&dev_priv->irq_received);

Expand Down Expand Up @@ -1018,18 +1026,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
READ_BREADCRUMB(dev_priv);
}

if (iir & I915_USER_INTERRUPT) {
u32 seqno = render_ring->get_seqno(dev, render_ring);
render_ring->irq_gem_seqno = seqno;
trace_i915_gem_request_complete(dev, seqno);
wake_up_all(&dev_priv->render_ring.irq_queue);
dev_priv->hangcheck_count = 0;
mod_timer(&dev_priv->hangcheck_timer,
jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD));
}

if (iir & I915_USER_INTERRUPT)
notify_ring(dev, &dev_priv->render_ring);
if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT))
wake_up_all(&dev_priv->bsd_ring.irq_queue);
notify_ring(dev, &dev_priv->bsd_ring);

if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) {
intel_prepare_page_flip(dev, 0);
Expand Down Expand Up @@ -1358,6 +1358,12 @@ void i915_hangcheck_elapsed(unsigned long data)
missed_wakeup = true;
}

if (dev_priv->blt_ring.waiting_gem_seqno &&
waitqueue_active(&dev_priv->blt_ring.irq_queue)) {
wake_up_all(&dev_priv->blt_ring.irq_queue);
missed_wakeup = true;
}

if (missed_wakeup)
DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n");
return;
Expand Down Expand Up @@ -1443,8 +1449,12 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
I915_WRITE(DEIER, dev_priv->de_irq_enable_reg);
(void) I915_READ(DEIER);

if (IS_GEN6(dev))
render_mask = GT_PIPE_NOTIFY | GT_GEN6_BSD_USER_INTERRUPT;
if (IS_GEN6(dev)) {
render_mask =
GT_PIPE_NOTIFY |
GT_GEN6_BSD_USER_INTERRUPT |
GT_BLT_USER_INTERRUPT;
}

dev_priv->gt_irq_mask_reg = ~render_mask;
dev_priv->gt_irq_enable_reg = render_mask;
Expand All @@ -1454,6 +1464,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
if (IS_GEN6(dev)) {
I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT);
I915_WRITE(GEN6_BSD_IMR, ~GEN6_BSD_IMR_USER_INTERRUPT);
I915_WRITE(GEN6_BLITTER_IMR, ~GEN6_BLITTER_USER_INTERRUPT);
}

I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg);
Expand Down Expand Up @@ -1523,9 +1534,10 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
u32 error_mask;

DRM_INIT_WAITQUEUE(&dev_priv->render_ring.irq_queue);

if (HAS_BSD(dev))
DRM_INIT_WAITQUEUE(&dev_priv->bsd_ring.irq_queue);
if (HAS_BLT(dev))
DRM_INIT_WAITQUEUE(&dev_priv->blt_ring.irq_queue);

dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;

Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@
#define RENDER_RING_BASE 0x02000
#define BSD_RING_BASE 0x04000
#define GEN6_BSD_RING_BASE 0x12000
#define BLT_RING_BASE 0x22000
#define RING_TAIL(base) ((base)+0x30)
#define RING_HEAD(base) ((base)+0x34)
#define RING_START(base) ((base)+0x38)
Expand Down Expand Up @@ -2561,6 +2562,7 @@
#define GT_USER_INTERRUPT (1 << 0)
#define GT_BSD_USER_INTERRUPT (1 << 5)
#define GT_GEN6_BSD_USER_INTERRUPT (1 << 12)
#define GT_BLT_USER_INTERRUPT (1 << 22)

#define GTISR 0x44010
#define GTIMR 0x44014
Expand Down
Loading

0 comments on commit f3ea07c

Please sign in to comment.