aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h12
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c64
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c19
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c228
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h4
6 files changed, 291 insertions, 38 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 450dcf0d25c8..ca1ba42af566 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -536,6 +536,10 @@ typedef struct drm_i915_private {
536 /* indicate whether the LVDS_BORDER should be enabled or not */ 536 /* indicate whether the LVDS_BORDER should be enabled or not */
537 unsigned int lvds_border_bits; 537 unsigned int lvds_border_bits;
538 538
539 struct drm_crtc *plane_to_crtc_mapping[2];
540 struct drm_crtc *pipe_to_crtc_mapping[2];
541 wait_queue_head_t pending_flip_queue;
542
539 /* Reclocking support */ 543 /* Reclocking support */
540 bool render_reclock_avail; 544 bool render_reclock_avail;
541 bool lvds_downclock_avail; 545 bool lvds_downclock_avail;
@@ -639,6 +643,13 @@ struct drm_i915_gem_object {
639 * Advice: are the backing pages purgeable? 643 * Advice: are the backing pages purgeable?
640 */ 644 */
641 int madv; 645 int madv;
646
647 /**
648 * Number of crtcs where this object is currently the fb, but
649 * will be page flipped away on the next vblank. When it
650 * reaches 0, dev_priv->pending_flip_queue will be woken up.
651 */
652 atomic_t pending_flip;
642}; 653};
643 654
644/** 655/**
@@ -830,6 +841,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev);
830int i915_gem_object_get_pages(struct drm_gem_object *obj); 841int i915_gem_object_get_pages(struct drm_gem_object *obj);
831void i915_gem_object_put_pages(struct drm_gem_object *obj); 842void i915_gem_object_put_pages(struct drm_gem_object *obj);
832void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); 843void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
844void i915_gem_object_flush_write_domain(struct drm_gem_object *obj);
833 845
834void i915_gem_shrinker_init(void); 846void i915_gem_shrinker_init(void);
835void i915_gem_shrinker_exit(void); 847void i915_gem_shrinker_exit(void);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 481c0ab888c8..214fb1864710 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2771,6 +2771,22 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj)
2771 old_write_domain); 2771 old_write_domain);
2772} 2772}
2773 2773
2774void
2775i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
2776{
2777 switch (obj->write_domain) {
2778 case I915_GEM_DOMAIN_GTT:
2779 i915_gem_object_flush_gtt_write_domain(obj);
2780 break;
2781 case I915_GEM_DOMAIN_CPU:
2782 i915_gem_object_flush_cpu_write_domain(obj);
2783 break;
2784 default:
2785 i915_gem_object_flush_gpu_write_domain(obj);
2786 break;
2787 }
2788}
2789
2774/** 2790/**
2775 * Moves a single object to the GTT read, and possibly write domain. 2791 * Moves a single object to the GTT read, and possibly write domain.
2776 * 2792 *
@@ -3536,6 +3552,41 @@ i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec,
3536 return 0; 3552 return 0;
3537} 3553}
3538 3554
3555static int
3556i915_gem_wait_for_pending_flip(struct drm_device *dev,
3557 struct drm_gem_object **object_list,
3558 int count)
3559{
3560 drm_i915_private_t *dev_priv = dev->dev_private;
3561 struct drm_i915_gem_object *obj_priv;
3562 DEFINE_WAIT(wait);
3563 int i, ret = 0;
3564
3565 for (;;) {
3566 prepare_to_wait(&dev_priv->pending_flip_queue,
3567 &wait, TASK_INTERRUPTIBLE);
3568 for (i = 0; i < count; i++) {
3569 obj_priv = object_list[i]->driver_private;
3570 if (atomic_read(&obj_priv->pending_flip) > 0)
3571 break;
3572 }
3573 if (i == count)
3574 break;
3575
3576 if (!signal_pending(current)) {
3577 mutex_unlock(&dev->struct_mutex);
3578 schedule();
3579 mutex_lock(&dev->struct_mutex);
3580 continue;
3581 }
3582 ret = -ERESTARTSYS;
3583 break;
3584 }
3585 finish_wait(&dev_priv->pending_flip_queue, &wait);
3586
3587 return ret;
3588}
3589
3539int 3590int
3540i915_gem_execbuffer(struct drm_device *dev, void *data, 3591i915_gem_execbuffer(struct drm_device *dev, void *data,
3541 struct drm_file *file_priv) 3592 struct drm_file *file_priv)
@@ -3551,7 +3602,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
3551 int ret, ret2, i, pinned = 0; 3602 int ret, ret2, i, pinned = 0;
3552 uint64_t exec_offset; 3603 uint64_t exec_offset;
3553 uint32_t seqno, flush_domains, reloc_index; 3604 uint32_t seqno, flush_domains, reloc_index;
3554 int pin_tries; 3605 int pin_tries, flips;
3555 3606
3556#if WATCH_EXEC 3607#if WATCH_EXEC
3557 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", 3608 DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
@@ -3623,6 +3674,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
3623 } 3674 }
3624 3675
3625 /* Look up object handles */ 3676 /* Look up object handles */
3677 flips = 0;
3626 for (i = 0; i < args->buffer_count; i++) { 3678 for (i = 0; i < args->buffer_count; i++) {
3627 object_list[i] = drm_gem_object_lookup(dev, file_priv, 3679 object_list[i] = drm_gem_object_lookup(dev, file_priv,
3628 exec_list[i].handle); 3680 exec_list[i].handle);
@@ -3641,6 +3693,14 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
3641 goto err; 3693 goto err;
3642 } 3694 }
3643 obj_priv->in_execbuffer = true; 3695 obj_priv->in_execbuffer = true;
3696 flips += atomic_read(&obj_priv->pending_flip);
3697 }
3698
3699 if (flips > 0) {
3700 ret = i915_gem_wait_for_pending_flip(dev, object_list,
3701 args->buffer_count);
3702 if (ret)
3703 goto err;
3644 } 3704 }
3645 3705
3646 /* Pin and relocate */ 3706 /* Pin and relocate */
@@ -4625,8 +4685,8 @@ i915_gem_load(struct drm_device *dev)
4625 for (i = 0; i < 8; i++) 4685 for (i = 0; i < 8; i++)
4626 I915_WRITE(FENCE_REG_945_8 + (i * 4), 0); 4686 I915_WRITE(FENCE_REG_945_8 + (i * 4), 0);
4627 } 4687 }
4628
4629 i915_gem_detect_bit_6_swizzle(dev); 4688 i915_gem_detect_bit_6_swizzle(dev);
4689 init_waitqueue_head(&dev_priv->pending_flip_queue);
4630} 4690}
4631 4691
4632/* 4692/*
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 77bc1d28f744..e2d01b3fa171 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -43,10 +43,13 @@
43 * we leave them always unmasked in IMR and then control enabling them through 43 * we leave them always unmasked in IMR and then control enabling them through
44 * PIPESTAT alone. 44 * PIPESTAT alone.
45 */ 45 */
46#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ 46#define I915_INTERRUPT_ENABLE_FIX \
47 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ 47 (I915_ASLE_INTERRUPT | \
48 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \ 48 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
49 I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) 49 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \
50 I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | \
51 I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT | \
52 I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
50 53
51/** Interrupts that we mask and unmask at runtime. */ 54/** Interrupts that we mask and unmask at runtime. */
52#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) 55#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
@@ -643,14 +646,22 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
643 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); 646 mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
644 } 647 }
645 648
649 if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT)
650 intel_prepare_page_flip(dev, 0);
651
652 if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT)
653 intel_prepare_page_flip(dev, 1);
654
646 if (pipea_stats & vblank_status) { 655 if (pipea_stats & vblank_status) {
647 vblank++; 656 vblank++;
648 drm_handle_vblank(dev, 0); 657 drm_handle_vblank(dev, 0);
658 intel_finish_page_flip(dev, 0);
649 } 659 }
650 660
651 if (pipeb_stats & vblank_status) { 661 if (pipeb_stats & vblank_status) {
652 vblank++; 662 vblank++;
653 drm_handle_vblank(dev, 1); 663 drm_handle_vblank(dev, 1);
664 intel_finish_page_flip(dev, 1);
654 } 665 }
655 666
656 if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) || 667 if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d58f7ad91161..120c77dabcff 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -157,6 +157,8 @@
157#define MI_OVERLAY_ON (0x1<<21) 157#define MI_OVERLAY_ON (0x1<<21)
158#define MI_OVERLAY_OFF (0x2<<21) 158#define MI_OVERLAY_OFF (0x2<<21)
159#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0) 159#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
160#define MI_DISPLAY_FLIP MI_INSTR(0x14, 2)
161#define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20)
160#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) 162#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
161#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ 163#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
162#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) 164#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 002c07daf9b8..b63a25f0f86d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1191,6 +1191,51 @@ out_disable:
1191} 1191}
1192 1192
1193static int 1193static int
1194intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
1195{
1196 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1197 u32 alignment;
1198 int ret;
1199
1200 switch (obj_priv->tiling_mode) {
1201 case I915_TILING_NONE:
1202 alignment = 64 * 1024;
1203 break;
1204 case I915_TILING_X:
1205 /* pin() will align the object as required by fence */
1206 alignment = 0;
1207 break;
1208 case I915_TILING_Y:
1209 /* FIXME: Is this true? */
1210 DRM_ERROR("Y tiled not allowed for scan out buffers\n");
1211 return -EINVAL;
1212 default:
1213 BUG();
1214 }
1215
1216 alignment = 256 * 1024;
1217 ret = i915_gem_object_pin(obj, alignment);
1218 if (ret != 0)
1219 return ret;
1220
1221 /* Install a fence for tiled scan-out. Pre-i965 always needs a
1222 * fence, whereas 965+ only requires a fence if using
1223 * framebuffer compression. For simplicity, we always install
1224 * a fence as the cost is not that onerous.
1225 */
1226 if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
1227 obj_priv->tiling_mode != I915_TILING_NONE) {
1228 ret = i915_gem_object_get_fence_reg(obj);
1229 if (ret != 0) {
1230 i915_gem_object_unpin(obj);
1231 return ret;
1232 }
1233 }
1234
1235 return 0;
1236}
1237
1238static int
1194intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, 1239intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1195 struct drm_framebuffer *old_fb) 1240 struct drm_framebuffer *old_fb)
1196{ 1241{
@@ -1209,7 +1254,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1209 int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; 1254 int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
1210 int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF); 1255 int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
1211 int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; 1256 int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
1212 u32 dspcntr, alignment; 1257 u32 dspcntr;
1213 int ret; 1258 int ret;
1214 1259
1215 /* no fb bound */ 1260 /* no fb bound */
@@ -1231,24 +1276,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1231 obj = intel_fb->obj; 1276 obj = intel_fb->obj;
1232 obj_priv = obj->driver_private; 1277 obj_priv = obj->driver_private;
1233 1278
1234 switch (obj_priv->tiling_mode) {
1235 case I915_TILING_NONE:
1236 alignment = 64 * 1024;
1237 break;
1238 case I915_TILING_X:
1239 /* pin() will align the object as required by fence */
1240 alignment = 0;
1241 break;
1242 case I915_TILING_Y:
1243 /* FIXME: Is this true? */
1244 DRM_ERROR("Y tiled not allowed for scan out buffers\n");
1245 return -EINVAL;
1246 default:
1247 BUG();
1248 }
1249
1250 mutex_lock(&dev->struct_mutex); 1279 mutex_lock(&dev->struct_mutex);
1251 ret = i915_gem_object_pin(obj, alignment); 1280 ret = intel_pin_and_fence_fb_obj(dev, obj);
1252 if (ret != 0) { 1281 if (ret != 0) {
1253 mutex_unlock(&dev->struct_mutex); 1282 mutex_unlock(&dev->struct_mutex);
1254 return ret; 1283 return ret;
@@ -1261,20 +1290,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
1261 return ret; 1290 return ret;
1262 } 1291 }
1263 1292
1264 /* Install a fence for tiled scan-out. Pre-i965 always needs a fence,
1265 * whereas 965+ only requires a fence if using framebuffer compression.
1266 * For simplicity, we always install a fence as the cost is not that onerous.
1267 */
1268 if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
1269 obj_priv->tiling_mode != I915_TILING_NONE) {
1270 ret = i915_gem_object_get_fence_reg(obj);
1271 if (ret != 0) {
1272 i915_gem_object_unpin(obj);
1273 mutex_unlock(&dev->struct_mutex);
1274 return ret;
1275 }
1276 }
1277
1278 dspcntr = I915_READ(dspcntr_reg); 1293 dspcntr = I915_READ(dspcntr_reg);
1279 /* Mask out pixel format bits in case we change it */ 1294 /* Mask out pixel format bits in case we change it */
1280 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; 1295 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
@@ -4068,6 +4083,153 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
4068 kfree(intel_crtc); 4083 kfree(intel_crtc);
4069} 4084}
4070 4085
4086struct intel_unpin_work {
4087 struct work_struct work;
4088 struct drm_device *dev;
4089 struct drm_gem_object *obj;
4090 struct drm_pending_vblank_event *event;
4091 int pending;
4092};
4093
4094static void intel_unpin_work_fn(struct work_struct *__work)
4095{
4096 struct intel_unpin_work *work =
4097 container_of(__work, struct intel_unpin_work, work);
4098
4099 mutex_lock(&work->dev->struct_mutex);
4100 i915_gem_object_unpin(work->obj);
4101 drm_gem_object_unreference(work->obj);
4102 mutex_unlock(&work->dev->struct_mutex);
4103 kfree(work);
4104}
4105
4106void intel_finish_page_flip(struct drm_device *dev, int pipe)
4107{
4108 drm_i915_private_t *dev_priv = dev->dev_private;
4109 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
4110 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
4111 struct intel_unpin_work *work;
4112 struct drm_i915_gem_object *obj_priv;
4113 struct drm_pending_vblank_event *e;
4114 struct timeval now;
4115 unsigned long flags;
4116
4117 /* Ignore early vblank irqs */
4118 if (intel_crtc == NULL)
4119 return;
4120
4121 spin_lock_irqsave(&dev->event_lock, flags);
4122 work = intel_crtc->unpin_work;
4123 if (work == NULL || !work->pending) {
4124 spin_unlock_irqrestore(&dev->event_lock, flags);
4125 return;
4126 }
4127
4128 intel_crtc->unpin_work = NULL;
4129 drm_vblank_put(dev, intel_crtc->pipe);
4130
4131 if (work->event) {
4132 e = work->event;
4133 do_gettimeofday(&now);
4134 e->event.sequence = drm_vblank_count(dev, intel_crtc->pipe);
4135 e->event.tv_sec = now.tv_sec;
4136 e->event.tv_usec = now.tv_usec;
4137 list_add_tail(&e->base.link,
4138 &e->base.file_priv->event_list);
4139 wake_up_interruptible(&e->base.file_priv->event_wait);
4140 }
4141
4142 spin_unlock_irqrestore(&dev->event_lock, flags);
4143
4144 obj_priv = work->obj->driver_private;
4145 if (atomic_dec_and_test(&obj_priv->pending_flip))
4146 DRM_WAKEUP(&dev_priv->pending_flip_queue);
4147 schedule_work(&work->work);
4148}
4149
4150void intel_prepare_page_flip(struct drm_device *dev, int plane)
4151{
4152 drm_i915_private_t *dev_priv = dev->dev_private;
4153 struct intel_crtc *intel_crtc =
4154 to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]);
4155 unsigned long flags;
4156
4157 spin_lock_irqsave(&dev->event_lock, flags);
4158 if (intel_crtc->unpin_work)
4159 intel_crtc->unpin_work->pending = 1;
4160 spin_unlock_irqrestore(&dev->event_lock, flags);
4161}
4162
4163static int intel_crtc_page_flip(struct drm_crtc *crtc,
4164 struct drm_framebuffer *fb,
4165 struct drm_pending_vblank_event *event)
4166{
4167 struct drm_device *dev = crtc->dev;
4168 struct drm_i915_private *dev_priv = dev->dev_private;
4169 struct intel_framebuffer *intel_fb;
4170 struct drm_i915_gem_object *obj_priv;
4171 struct drm_gem_object *obj;
4172 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
4173 struct intel_unpin_work *work;
4174 unsigned long flags;
4175 int ret;
4176 RING_LOCALS;
4177
4178 work = kzalloc(sizeof *work, GFP_KERNEL);
4179 if (work == NULL)
4180 return -ENOMEM;
4181
4182 mutex_lock(&dev->struct_mutex);
4183
4184 work->event = event;
4185 work->dev = crtc->dev;
4186 intel_fb = to_intel_framebuffer(crtc->fb);
4187 work->obj = intel_fb->obj;
4188 INIT_WORK(&work->work, intel_unpin_work_fn);
4189
4190 /* We borrow the event spin lock for protecting unpin_work */
4191 spin_lock_irqsave(&dev->event_lock, flags);
4192 if (intel_crtc->unpin_work) {
4193 spin_unlock_irqrestore(&dev->event_lock, flags);
4194 kfree(work);
4195 mutex_unlock(&dev->struct_mutex);
4196 return -EBUSY;
4197 }
4198 intel_crtc->unpin_work = work;
4199 spin_unlock_irqrestore(&dev->event_lock, flags);
4200
4201 intel_fb = to_intel_framebuffer(fb);
4202 obj = intel_fb->obj;
4203
4204 ret = intel_pin_and_fence_fb_obj(dev, obj);
4205 if (ret != 0) {
4206 kfree(work);
4207 mutex_unlock(&dev->struct_mutex);
4208 return ret;
4209 }
4210
4211 /* Reference the old fb object for the scheduled work. */
4212 drm_gem_object_reference(work->obj);
4213
4214 crtc->fb = fb;
4215 i915_gem_object_flush_write_domain(obj);
4216 drm_vblank_get(dev, intel_crtc->pipe);
4217 obj_priv = obj->driver_private;
4218 atomic_inc(&obj_priv->pending_flip);
4219
4220 BEGIN_LP_RING(4);
4221 OUT_RING(MI_DISPLAY_FLIP |
4222 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
4223 OUT_RING(fb->pitch);
4224 OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
4225 OUT_RING((fb->width << 16) | fb->height);
4226 ADVANCE_LP_RING();
4227
4228 mutex_unlock(&dev->struct_mutex);
4229
4230 return 0;
4231}
4232
4071static const struct drm_crtc_helper_funcs intel_helper_funcs = { 4233static const struct drm_crtc_helper_funcs intel_helper_funcs = {
4072 .dpms = intel_crtc_dpms, 4234 .dpms = intel_crtc_dpms,
4073 .mode_fixup = intel_crtc_mode_fixup, 4235 .mode_fixup = intel_crtc_mode_fixup,
@@ -4084,12 +4246,14 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
4084 .gamma_set = intel_crtc_gamma_set, 4246 .gamma_set = intel_crtc_gamma_set,
4085 .set_config = drm_crtc_helper_set_config, 4247 .set_config = drm_crtc_helper_set_config,
4086 .destroy = intel_crtc_destroy, 4248 .destroy = intel_crtc_destroy,
4249 .page_flip = intel_crtc_page_flip,
4087}; 4250};
4088 4251
4089 4252
4090static void intel_crtc_init(struct drm_device *dev, int pipe) 4253static void intel_crtc_init(struct drm_device *dev, int pipe)
4091{ 4254{
4092 struct intel_crtc *intel_crtc; 4255 struct intel_crtc *intel_crtc;
4256 struct drm_i915_private *dev_priv = dev->dev_private;
4093 int i; 4257 int i;
4094 4258
4095 intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); 4259 intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 497240581c6a..8a22f2508899 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -148,6 +148,7 @@ struct intel_crtc {
148 struct timer_list idle_timer; 148 struct timer_list idle_timer;
149 bool lowfreq_avail; 149 bool lowfreq_avail;
150 struct intel_overlay *overlay; 150 struct intel_overlay *overlay;
151 struct intel_unpin_work *unpin_work;
151}; 152};
152 153
153#define to_intel_crtc(x) container_of(x, struct intel_crtc, base) 154#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -211,6 +212,9 @@ extern int intel_framebuffer_create(struct drm_device *dev,
211 struct drm_framebuffer **fb, 212 struct drm_framebuffer **fb,
212 struct drm_gem_object *obj); 213 struct drm_gem_object *obj);
213 214
215extern void intel_prepare_page_flip(struct drm_device *dev, int plane);
216extern void intel_finish_page_flip(struct drm_device *dev, int pipe);
217
214extern void intel_setup_overlay(struct drm_device *dev); 218extern void intel_setup_overlay(struct drm_device *dev);
215extern void intel_cleanup_overlay(struct drm_device *dev); 219extern void intel_cleanup_overlay(struct drm_device *dev);
216extern int intel_overlay_switch_off(struct intel_overlay *overlay); 220extern int intel_overlay_switch_off(struct intel_overlay *overlay);