Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
intel_sprite.c
Go to the documentation of this file.
1 /*
2  * Copyright © 2011 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  *
23  * Authors:
24  * Jesse Barnes <[email protected]>
25  *
26  * New plane/sprite handling.
27  *
28  * The older chips had a separate interface for programming plane related
29  * registers; newer ones are much simpler and we can use the new DRM plane
30  * support.
31  */
32 #include <drm/drmP.h>
33 #include <drm/drm_crtc.h>
34 #include <drm/drm_fourcc.h>
35 #include "intel_drv.h"
36 #include <drm/i915_drm.h>
37 #include "i915_drv.h"
38 
39 static void
40 ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
41  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
42  unsigned int crtc_w, unsigned int crtc_h,
44  uint32_t src_w, uint32_t src_h)
45 {
46  struct drm_device *dev = plane->dev;
47  struct drm_i915_private *dev_priv = dev->dev_private;
48  struct intel_plane *intel_plane = to_intel_plane(plane);
49  int pipe = intel_plane->pipe;
50  u32 sprctl, sprscale = 0;
51  int pixel_size;
52 
53  sprctl = I915_READ(SPRCTL(pipe));
54 
55  /* Mask out pixel format bits in case we change it */
56  sprctl &= ~SPRITE_PIXFORMAT_MASK;
57  sprctl &= ~SPRITE_RGB_ORDER_RGBX;
58  sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
59  sprctl &= ~SPRITE_TILED;
60 
61  switch (fb->pixel_format) {
64  pixel_size = 4;
65  break;
67  sprctl |= SPRITE_FORMAT_RGBX888;
68  pixel_size = 4;
69  break;
70  case DRM_FORMAT_YUYV:
72  pixel_size = 2;
73  break;
74  case DRM_FORMAT_YVYU:
76  pixel_size = 2;
77  break;
78  case DRM_FORMAT_UYVY:
80  pixel_size = 2;
81  break;
82  case DRM_FORMAT_VYUY:
84  pixel_size = 2;
85  break;
86  default:
87  DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
88  sprctl |= SPRITE_FORMAT_RGBX888;
89  pixel_size = 4;
90  break;
91  }
92 
93  if (obj->tiling_mode != I915_TILING_NONE)
94  sprctl |= SPRITE_TILED;
95 
96  /* must disable */
98  sprctl |= SPRITE_ENABLE;
99 
100  /* Sizes are 0 based */
101  src_w--;
102  src_h--;
103  crtc_w--;
104  crtc_h--;
105 
106  intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size);
107 
108  /*
109  * IVB workaround: must disable low power watermarks for at least
110  * one frame before enabling scaling. LP watermarks can be re-enabled
111  * when scaling is disabled.
112  */
113  if (crtc_w != src_w || crtc_h != src_h) {
114  if (!dev_priv->sprite_scaling_enabled) {
115  dev_priv->sprite_scaling_enabled = true;
117  intel_wait_for_vblank(dev, pipe);
118  }
119  sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
120  } else {
121  if (dev_priv->sprite_scaling_enabled) {
122  dev_priv->sprite_scaling_enabled = false;
123  /* potentially re-enable LP watermarks */
125  }
126  }
127 
128  I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
129  I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
130  if (obj->tiling_mode != I915_TILING_NONE) {
131  I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
132  } else {
133  unsigned long offset;
134 
135  offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
136  I915_WRITE(SPRLINOFF(pipe), offset);
137  }
138  I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
139  I915_WRITE(SPRSCALE(pipe), sprscale);
140  I915_WRITE(SPRCTL(pipe), sprctl);
142  POSTING_READ(SPRSURF(pipe));
143 }
144 
145 static void
146 ivb_disable_plane(struct drm_plane *plane)
147 {
148  struct drm_device *dev = plane->dev;
149  struct drm_i915_private *dev_priv = dev->dev_private;
150  struct intel_plane *intel_plane = to_intel_plane(plane);
151  int pipe = intel_plane->pipe;
152 
153  I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
154  /* Can't leave the scaler enabled... */
155  I915_WRITE(SPRSCALE(pipe), 0);
156  /* Activate double buffered register update */
157  I915_MODIFY_DISPBASE(SPRSURF(pipe), 0);
158  POSTING_READ(SPRSURF(pipe));
159 
160  dev_priv->sprite_scaling_enabled = false;
162 }
163 
164 static int
165 ivb_update_colorkey(struct drm_plane *plane,
167 {
168  struct drm_device *dev = plane->dev;
169  struct drm_i915_private *dev_priv = dev->dev_private;
170  struct intel_plane *intel_plane;
171  u32 sprctl;
172  int ret = 0;
173 
174  intel_plane = to_intel_plane(plane);
175 
176  I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value);
177  I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value);
178  I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask);
179 
180  sprctl = I915_READ(SPRCTL(intel_plane->pipe));
181  sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY);
183  sprctl |= SPRITE_DEST_KEY;
184  else if (key->flags & I915_SET_COLORKEY_SOURCE)
185  sprctl |= SPRITE_SOURCE_KEY;
186  I915_WRITE(SPRCTL(intel_plane->pipe), sprctl);
187 
188  POSTING_READ(SPRKEYMSK(intel_plane->pipe));
189 
190  return ret;
191 }
192 
193 static void
194 ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
195 {
196  struct drm_device *dev = plane->dev;
197  struct drm_i915_private *dev_priv = dev->dev_private;
198  struct intel_plane *intel_plane;
199  u32 sprctl;
200 
201  intel_plane = to_intel_plane(plane);
202 
203  key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe));
204  key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe));
205  key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe));
206  key->flags = 0;
207 
208  sprctl = I915_READ(SPRCTL(intel_plane->pipe));
209 
210  if (sprctl & SPRITE_DEST_KEY)
212  else if (sprctl & SPRITE_SOURCE_KEY)
214  else
216 }
217 
218 static void
219 ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
220  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
221  unsigned int crtc_w, unsigned int crtc_h,
222  uint32_t x, uint32_t y,
223  uint32_t src_w, uint32_t src_h)
224 {
225  struct drm_device *dev = plane->dev;
226  struct drm_i915_private *dev_priv = dev->dev_private;
227  struct intel_plane *intel_plane = to_intel_plane(plane);
228  int pipe = intel_plane->pipe, pixel_size;
229  u32 dvscntr, dvsscale;
230 
231  dvscntr = I915_READ(DVSCNTR(pipe));
232 
233  /* Mask out pixel format bits in case we change it */
234  dvscntr &= ~DVS_PIXFORMAT_MASK;
235  dvscntr &= ~DVS_RGB_ORDER_XBGR;
236  dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
237  dvscntr &= ~DVS_TILED;
238 
239  switch (fb->pixel_format) {
240  case DRM_FORMAT_XBGR8888:
242  pixel_size = 4;
243  break;
244  case DRM_FORMAT_XRGB8888:
245  dvscntr |= DVS_FORMAT_RGBX888;
246  pixel_size = 4;
247  break;
248  case DRM_FORMAT_YUYV:
250  pixel_size = 2;
251  break;
252  case DRM_FORMAT_YVYU:
254  pixel_size = 2;
255  break;
256  case DRM_FORMAT_UYVY:
258  pixel_size = 2;
259  break;
260  case DRM_FORMAT_VYUY:
262  pixel_size = 2;
263  break;
264  default:
265  DRM_DEBUG_DRIVER("bad pixel format, assuming RGBX888\n");
266  dvscntr |= DVS_FORMAT_RGBX888;
267  pixel_size = 4;
268  break;
269  }
270 
271  if (obj->tiling_mode != I915_TILING_NONE)
272  dvscntr |= DVS_TILED;
273 
274  if (IS_GEN6(dev))
275  dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
276  dvscntr |= DVS_ENABLE;
277 
278  /* Sizes are 0 based */
279  src_w--;
280  src_h--;
281  crtc_w--;
282  crtc_h--;
283 
284  intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size);
285 
286  dvsscale = 0;
287  if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h)
288  dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
289 
290  I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
291  I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
292  if (obj->tiling_mode != I915_TILING_NONE) {
293  I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
294  } else {
295  unsigned long offset;
296 
297  offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
298  I915_WRITE(DVSLINOFF(pipe), offset);
299  }
300  I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
301  I915_WRITE(DVSSCALE(pipe), dvsscale);
302  I915_WRITE(DVSCNTR(pipe), dvscntr);
304  POSTING_READ(DVSSURF(pipe));
305 }
306 
307 static void
308 ilk_disable_plane(struct drm_plane *plane)
309 {
310  struct drm_device *dev = plane->dev;
311  struct drm_i915_private *dev_priv = dev->dev_private;
312  struct intel_plane *intel_plane = to_intel_plane(plane);
313  int pipe = intel_plane->pipe;
314 
315  I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
316  /* Disable the scaler */
317  I915_WRITE(DVSSCALE(pipe), 0);
318  /* Flush double buffered register updates */
319  I915_MODIFY_DISPBASE(DVSSURF(pipe), 0);
320  POSTING_READ(DVSSURF(pipe));
321 }
322 
323 static void
324 intel_enable_primary(struct drm_crtc *crtc)
325 {
326  struct drm_device *dev = crtc->dev;
327  struct drm_i915_private *dev_priv = dev->dev_private;
328  struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
329  int reg = DSPCNTR(intel_crtc->plane);
330 
331  if (!intel_crtc->primary_disabled)
332  return;
333 
334  intel_crtc->primary_disabled = false;
335  intel_update_fbc(dev);
336 
338 }
339 
340 static void
341 intel_disable_primary(struct drm_crtc *crtc)
342 {
343  struct drm_device *dev = crtc->dev;
344  struct drm_i915_private *dev_priv = dev->dev_private;
345  struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
346  int reg = DSPCNTR(intel_crtc->plane);
347 
348  if (intel_crtc->primary_disabled)
349  return;
350 
352 
353  intel_crtc->primary_disabled = true;
354  intel_update_fbc(dev);
355 }
356 
357 static int
358 ilk_update_colorkey(struct drm_plane *plane,
359  struct drm_intel_sprite_colorkey *key)
360 {
361  struct drm_device *dev = plane->dev;
362  struct drm_i915_private *dev_priv = dev->dev_private;
363  struct intel_plane *intel_plane;
364  u32 dvscntr;
365  int ret = 0;
366 
367  intel_plane = to_intel_plane(plane);
368 
369  I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value);
370  I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value);
371  I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask);
372 
373  dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
374  dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY);
376  dvscntr |= DVS_DEST_KEY;
377  else if (key->flags & I915_SET_COLORKEY_SOURCE)
378  dvscntr |= DVS_SOURCE_KEY;
379  I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr);
380 
381  POSTING_READ(DVSKEYMSK(intel_plane->pipe));
382 
383  return ret;
384 }
385 
386 static void
387 ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
388 {
389  struct drm_device *dev = plane->dev;
390  struct drm_i915_private *dev_priv = dev->dev_private;
391  struct intel_plane *intel_plane;
392  u32 dvscntr;
393 
394  intel_plane = to_intel_plane(plane);
395 
396  key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe));
397  key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe));
398  key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe));
399  key->flags = 0;
400 
401  dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
402 
403  if (dvscntr & DVS_DEST_KEY)
405  else if (dvscntr & DVS_SOURCE_KEY)
407  else
409 }
410 
411 static int
412 intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
413  struct drm_framebuffer *fb, int crtc_x, int crtc_y,
414  unsigned int crtc_w, unsigned int crtc_h,
415  uint32_t src_x, uint32_t src_y,
416  uint32_t src_w, uint32_t src_h)
417 {
418  struct drm_device *dev = plane->dev;
419  struct drm_i915_private *dev_priv = dev->dev_private;
420  struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
421  struct intel_plane *intel_plane = to_intel_plane(plane);
422  struct intel_framebuffer *intel_fb;
423  struct drm_i915_gem_object *obj, *old_obj;
424  int pipe = intel_plane->pipe;
425  int ret = 0;
426  int x = src_x >> 16, y = src_y >> 16;
427  int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay;
428  bool disable_primary = false;
429 
430  intel_fb = to_intel_framebuffer(fb);
431  obj = intel_fb->obj;
432 
433  old_obj = intel_plane->obj;
434 
435  src_w = src_w >> 16;
436  src_h = src_h >> 16;
437 
438  /* Pipe must be running... */
439  if (!(I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE))
440  return -EINVAL;
441 
442  if (crtc_x >= primary_w || crtc_y >= primary_h)
443  return -EINVAL;
444 
445  /* Don't modify another pipe's plane */
446  if (intel_plane->pipe != intel_crtc->pipe)
447  return -EINVAL;
448 
449  /*
450  * Clamp the width & height into the visible area. Note we don't
451  * try to scale the source if part of the visible region is offscreen.
452  * The caller must handle that by adjusting source offset and size.
453  */
454  if ((crtc_x < 0) && ((crtc_x + crtc_w) > 0)) {
455  crtc_w += crtc_x;
456  crtc_x = 0;
457  }
458  if ((crtc_x + crtc_w) <= 0) /* Nothing to display */
459  goto out;
460  if ((crtc_x + crtc_w) > primary_w)
461  crtc_w = primary_w - crtc_x;
462 
463  if ((crtc_y < 0) && ((crtc_y + crtc_h) > 0)) {
464  crtc_h += crtc_y;
465  crtc_y = 0;
466  }
467  if ((crtc_y + crtc_h) <= 0) /* Nothing to display */
468  goto out;
469  if (crtc_y + crtc_h > primary_h)
470  crtc_h = primary_h - crtc_y;
471 
472  if (!crtc_w || !crtc_h) /* Again, nothing to display */
473  goto out;
474 
475  /*
476  * We can take a larger source and scale it down, but
477  * only so much... 16x is the max on SNB.
478  */
479  if (((src_w * src_h) / (crtc_w * crtc_h)) > intel_plane->max_downscale)
480  return -EINVAL;
481 
482  /*
483  * If the sprite is completely covering the primary plane,
484  * we can disable the primary and save power.
485  */
486  if ((crtc_x == 0) && (crtc_y == 0) &&
487  (crtc_w == primary_w) && (crtc_h == primary_h))
488  disable_primary = true;
489 
490  mutex_lock(&dev->struct_mutex);
491 
492  ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
493  if (ret)
494  goto out_unlock;
495 
496  intel_plane->obj = obj;
497 
498  /*
499  * Be sure to re-enable the primary before the sprite is no longer
500  * covering it fully.
501  */
502  if (!disable_primary)
503  intel_enable_primary(crtc);
504 
505  intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y,
506  crtc_w, crtc_h, x, y, src_w, src_h);
507 
508  if (disable_primary)
509  intel_disable_primary(crtc);
510 
511  /* Unpin old obj after new one is active to avoid ugliness */
512  if (old_obj) {
513  /*
514  * It's fairly common to simply update the position of
515  * an existing object. In that case, we don't need to
516  * wait for vblank to avoid ugliness, we only need to
517  * do the pin & ref bookkeeping.
518  */
519  if (old_obj != obj) {
520  mutex_unlock(&dev->struct_mutex);
521  intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
522  mutex_lock(&dev->struct_mutex);
523  }
524  intel_unpin_fb_obj(old_obj);
525  }
526 
527 out_unlock:
528  mutex_unlock(&dev->struct_mutex);
529 out:
530  return ret;
531 }
532 
533 static int
534 intel_disable_plane(struct drm_plane *plane)
535 {
536  struct drm_device *dev = plane->dev;
537  struct intel_plane *intel_plane = to_intel_plane(plane);
538  int ret = 0;
539 
540  if (plane->crtc)
541  intel_enable_primary(plane->crtc);
542  intel_plane->disable_plane(plane);
543 
544  if (!intel_plane->obj)
545  goto out;
546 
547  mutex_lock(&dev->struct_mutex);
548  intel_unpin_fb_obj(intel_plane->obj);
549  intel_plane->obj = NULL;
550  mutex_unlock(&dev->struct_mutex);
551 out:
552 
553  return ret;
554 }
555 
556 static void intel_destroy_plane(struct drm_plane *plane)
557 {
558  struct intel_plane *intel_plane = to_intel_plane(plane);
559  intel_disable_plane(plane);
560  drm_plane_cleanup(plane);
561  kfree(intel_plane);
562 }
563 
565  struct drm_file *file_priv)
566 {
567  struct drm_intel_sprite_colorkey *set = data;
568  struct drm_mode_object *obj;
569  struct drm_plane *plane;
570  struct intel_plane *intel_plane;
571  int ret = 0;
572 
573  if (!drm_core_check_feature(dev, DRIVER_MODESET))
574  return -ENODEV;
575 
576  /* Make sure we don't try to enable both src & dest simultaneously */
578  return -EINVAL;
579 
580  mutex_lock(&dev->mode_config.mutex);
581 
582  obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
583  if (!obj) {
584  ret = -EINVAL;
585  goto out_unlock;
586  }
587 
588  plane = obj_to_plane(obj);
589  intel_plane = to_intel_plane(plane);
590  ret = intel_plane->update_colorkey(plane, set);
591 
592 out_unlock:
593  mutex_unlock(&dev->mode_config.mutex);
594  return ret;
595 }
596 
598  struct drm_file *file_priv)
599 {
600  struct drm_intel_sprite_colorkey *get = data;
601  struct drm_mode_object *obj;
602  struct drm_plane *plane;
603  struct intel_plane *intel_plane;
604  int ret = 0;
605 
606  if (!drm_core_check_feature(dev, DRIVER_MODESET))
607  return -ENODEV;
608 
609  mutex_lock(&dev->mode_config.mutex);
610 
611  obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
612  if (!obj) {
613  ret = -EINVAL;
614  goto out_unlock;
615  }
616 
617  plane = obj_to_plane(obj);
618  intel_plane = to_intel_plane(plane);
619  intel_plane->get_colorkey(plane, get);
620 
621 out_unlock:
622  mutex_unlock(&dev->mode_config.mutex);
623  return ret;
624 }
625 
626 static const struct drm_plane_funcs intel_plane_funcs = {
627  .update_plane = intel_update_plane,
628  .disable_plane = intel_disable_plane,
629  .destroy = intel_destroy_plane,
630 };
631 
632 static uint32_t ilk_plane_formats[] = {
638 };
639 
640 static uint32_t snb_plane_formats[] = {
647 };
648 
649 int
650 intel_plane_init(struct drm_device *dev, enum pipe pipe)
651 {
652  struct intel_plane *intel_plane;
653  unsigned long possible_crtcs;
654  const uint32_t *plane_formats;
655  int num_plane_formats;
656  int ret;
657 
658  if (INTEL_INFO(dev)->gen < 5)
659  return -ENODEV;
660 
661  intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL);
662  if (!intel_plane)
663  return -ENOMEM;
664 
665  switch (INTEL_INFO(dev)->gen) {
666  case 5:
667  case 6:
668  intel_plane->max_downscale = 16;
669  intel_plane->update_plane = ilk_update_plane;
670  intel_plane->disable_plane = ilk_disable_plane;
671  intel_plane->update_colorkey = ilk_update_colorkey;
672  intel_plane->get_colorkey = ilk_get_colorkey;
673 
674  if (IS_GEN6(dev)) {
675  plane_formats = snb_plane_formats;
676  num_plane_formats = ARRAY_SIZE(snb_plane_formats);
677  } else {
678  plane_formats = ilk_plane_formats;
679  num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
680  }
681  break;
682 
683  case 7:
684  intel_plane->max_downscale = 2;
685  intel_plane->update_plane = ivb_update_plane;
686  intel_plane->disable_plane = ivb_disable_plane;
687  intel_plane->update_colorkey = ivb_update_colorkey;
688  intel_plane->get_colorkey = ivb_get_colorkey;
689 
690  plane_formats = snb_plane_formats;
691  num_plane_formats = ARRAY_SIZE(snb_plane_formats);
692  break;
693 
694  default:
695  kfree(intel_plane);
696  return -ENODEV;
697  }
698 
699  intel_plane->pipe = pipe;
700  possible_crtcs = (1 << pipe);
701  ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
702  &intel_plane_funcs,
703  plane_formats, num_plane_formats,
704  false);
705  if (ret)
706  kfree(intel_plane);
707 
708  return ret;
709 }