Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 174566
b: refs/heads/master
c: 6b95a20
h: refs/heads/master
v: v3
  • Loading branch information
Kristian Høgsberg authored and Eric Anholt committed Dec 1, 2009
1 parent 9a26272 commit 32ae734
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 39 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: f40d6817a5c2bf84f5fe7b5d1a83f1e8f8669951
refs/heads/master: 6b95a207c1fd552e7d017837c5eaf1b0173a48c9
12 changes: 12 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,10 @@ typedef struct drm_i915_private {
/* indicate whether the LVDS_BORDER should be enabled or not */
unsigned int lvds_border_bits;

struct drm_crtc *plane_to_crtc_mapping[2];
struct drm_crtc *pipe_to_crtc_mapping[2];
wait_queue_head_t pending_flip_queue;

/* Reclocking support */
bool render_reclock_avail;
bool lvds_downclock_avail;
Expand Down Expand Up @@ -639,6 +643,13 @@ struct drm_i915_gem_object {
* Advice: are the backing pages purgeable?
*/
int madv;

/**
* 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;
};

/**
Expand Down Expand Up @@ -830,6 +841,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev);
int i915_gem_object_get_pages(struct drm_gem_object *obj);
void i915_gem_object_put_pages(struct drm_gem_object *obj);
void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
void i915_gem_object_flush_write_domain(struct drm_gem_object *obj);

void i915_gem_shrinker_init(void);
void i915_gem_shrinker_exit(void);
Expand Down
64 changes: 62 additions & 2 deletions trunk/drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2771,6 +2771,22 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj)
old_write_domain);
}

void
i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
{
switch (obj->write_domain) {
case I915_GEM_DOMAIN_GTT:
i915_gem_object_flush_gtt_write_domain(obj);
break;
case I915_GEM_DOMAIN_CPU:
i915_gem_object_flush_cpu_write_domain(obj);
break;
default:
i915_gem_object_flush_gpu_write_domain(obj);
break;
}
}

/**
* Moves a single object to the GTT read, and possibly write domain.
*
Expand Down Expand Up @@ -3536,6 +3552,41 @@ i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec,
return 0;
}

static int
i915_gem_wait_for_pending_flip(struct drm_device *dev,
struct drm_gem_object **object_list,
int count)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv;
DEFINE_WAIT(wait);
int i, ret = 0;

for (;;) {
prepare_to_wait(&dev_priv->pending_flip_queue,
&wait, TASK_INTERRUPTIBLE);
for (i = 0; i < count; i++) {
obj_priv = object_list[i]->driver_private;
if (atomic_read(&obj_priv->pending_flip) > 0)
break;
}
if (i == count)
break;

if (!signal_pending(current)) {
mutex_unlock(&dev->struct_mutex);
schedule();
mutex_lock(&dev->struct_mutex);
continue;
}
ret = -ERESTARTSYS;
break;
}
finish_wait(&dev_priv->pending_flip_queue, &wait);

return ret;
}

int
i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv)
Expand All @@ -3551,7 +3602,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
int ret, ret2, i, pinned = 0;
uint64_t exec_offset;
uint32_t seqno, flush_domains, reloc_index;
int pin_tries;
int pin_tries, flips;

#if WATCH_EXEC
DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
Expand Down Expand Up @@ -3623,6 +3674,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
}

/* Look up object handles */
flips = 0;
for (i = 0; i < args->buffer_count; i++) {
object_list[i] = drm_gem_object_lookup(dev, file_priv,
exec_list[i].handle);
Expand All @@ -3641,6 +3693,14 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
goto err;
}
obj_priv->in_execbuffer = true;
flips += atomic_read(&obj_priv->pending_flip);
}

if (flips > 0) {
ret = i915_gem_wait_for_pending_flip(dev, object_list,
args->buffer_count);
if (ret)
goto err;
}

/* Pin and relocate */
Expand Down Expand Up @@ -4625,8 +4685,8 @@ i915_gem_load(struct drm_device *dev)
for (i = 0; i < 8; i++)
I915_WRITE(FENCE_REG_945_8 + (i * 4), 0);
}

i915_gem_detect_bit_6_swizzle(dev);
init_waitqueue_head(&dev_priv->pending_flip_queue);
}

/*
Expand Down
19 changes: 15 additions & 4 deletions trunk/drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@
* we leave them always unmasked in IMR and then control enabling them through
* PIPESTAT alone.
*/
#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \
I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \
I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
#define I915_INTERRUPT_ENABLE_FIX \
(I915_ASLE_INTERRUPT | \
I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \
I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | \
I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | \
I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)

/** Interrupts that we mask and unmask at runtime. */
#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
Expand Down Expand Up @@ -643,14 +646,22 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
}

if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT)
intel_prepare_page_flip(dev, 0);

if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT)
intel_prepare_page_flip(dev, 1);

if (pipea_stats & vblank_status) {
vblank++;
drm_handle_vblank(dev, 0);
intel_finish_page_flip(dev, 0);
}

if (pipeb_stats & vblank_status) {
vblank++;
drm_handle_vblank(dev, 1);
intel_finish_page_flip(dev, 1);
}

if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
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 @@ -157,6 +157,8 @@
#define MI_OVERLAY_ON (0x1<<21)
#define MI_OVERLAY_OFF (0x2<<21)
#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2)
#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
Expand Down
Loading

0 comments on commit 32ae734

Please sign in to comment.