intel_sprite.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722
  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 <jbarnes@virtuousgeek.org>
  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 <drm/drm_rect.h>
  36. #include "intel_drv.h"
  37. #include <drm/i915_drm.h>
  38. #include "i915_drv.h"
  39. static bool
  40. format_is_yuv(uint32_t format)
  41. {
  42. switch (format) {
  43. case DRM_FORMAT_YUYV:
  44. case DRM_FORMAT_UYVY:
  45. case DRM_FORMAT_VYUY:
  46. case DRM_FORMAT_YVYU:
  47. return true;
  48. default:
  49. return false;
  50. }
  51. }
  52. static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
  53. {
  54. /* paranoia */
  55. if (!mode->crtc_htotal)
  56. return 1;
  57. return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal);
  58. }
  59. static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
  60. {
  61. struct drm_device *dev = crtc->base.dev;
  62. const struct drm_display_mode *mode = &crtc->config.adjusted_mode;
  63. enum pipe pipe = crtc->pipe;
  64. long timeout = msecs_to_jiffies_timeout(1);
  65. int scanline, min, max, vblank_start;
  66. wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
  67. DEFINE_WAIT(wait);
  68. WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
  69. vblank_start = mode->crtc_vblank_start;
  70. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  71. vblank_start = DIV_ROUND_UP(vblank_start, 2);
  72. /* FIXME needs to be calibrated sensibly */
  73. min = vblank_start - usecs_to_scanlines(mode, 100);
  74. max = vblank_start - 1;
  75. if (min <= 0 || max <= 0)
  76. return false;
  77. if (WARN_ON(drm_vblank_get(dev, pipe)))
  78. return false;
  79. local_irq_disable();
  80. trace_i915_pipe_update_start(crtc, min, max);
  81. for (;;) {
  82. /*
  83. * prepare_to_wait() has a memory barrier, which guarantees
  84. * other CPUs can see the task state update by the time we
  85. * read the scanline.
  86. */
  87. prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
  88. scanline = intel_get_crtc_scanline(crtc);
  89. if (scanline < min || scanline > max)
  90. break;
  91. if (timeout <= 0) {
  92. DRM_ERROR("Potential atomic update failure on pipe %c\n",
  93. pipe_name(crtc->pipe));
  94. break;
  95. }
  96. local_irq_enable();
  97. timeout = schedule_timeout(timeout);
  98. local_irq_disable();
  99. }
  100. finish_wait(wq, &wait);
  101. drm_vblank_put(dev, pipe);
  102. *start_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
  103. trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count);
  104. return true;
  105. }
  106. static void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count)
  107. {
  108. struct drm_device *dev = crtc->base.dev;
  109. enum pipe pipe = crtc->pipe;
  110. u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
  111. trace_i915_pipe_update_end(crtc, end_vbl_count);
  112. local_irq_enable();
  113. if (start_vbl_count != end_vbl_count)
  114. DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n",
  115. pipe_name(pipe), start_vbl_count, end_vbl_count);
  116. }
  117. static void intel_update_primary_plane(struct intel_crtc *crtc)
  118. {
  119. struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
  120. int reg = DSPCNTR(crtc->plane);
  121. if (crtc->primary_enabled)
  122. I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
  123. else
  124. I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
  125. }
  126. static void
  127. skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
  128. struct drm_framebuffer *fb,
  129. struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  130. unsigned int crtc_w, unsigned int crtc_h,
  131. uint32_t x, uint32_t y,
  132. uint32_t src_w, uint32_t src_h)
  133. {
  134. struct drm_device *dev = drm_plane->dev;
  135. struct drm_i915_private *dev_priv = dev->dev_private;
  136. struct intel_plane *intel_plane = to_intel_plane(drm_plane);
  137. const int pipe = intel_plane->pipe;
  138. const int plane = intel_plane->plane + 1;
  139. u32 plane_ctl, stride;
  140. int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  141. plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
  142. /* Mask out pixel format bits in case we change it */
  143. plane_ctl &= ~PLANE_CTL_FORMAT_MASK;
  144. plane_ctl &= ~PLANE_CTL_ORDER_RGBX;
  145. plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK;
  146. plane_ctl &= ~PLANE_CTL_TILED_MASK;
  147. plane_ctl &= ~PLANE_CTL_ALPHA_MASK;
  148. plane_ctl &= ~PLANE_CTL_ROTATE_MASK;
  149. /* Trickle feed has to be enabled */
  150. plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE;
  151. switch (fb->pixel_format) {
  152. case DRM_FORMAT_RGB565:
  153. plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
  154. break;
  155. case DRM_FORMAT_XBGR8888:
  156. plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
  157. break;
  158. case DRM_FORMAT_XRGB8888:
  159. plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
  160. break;
  161. /*
  162. * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
  163. * to be already pre-multiplied. We need to add a knob (or a different
  164. * DRM_FORMAT) for user-space to configure that.
  165. */
  166. case DRM_FORMAT_ABGR8888:
  167. plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
  168. PLANE_CTL_ORDER_RGBX |
  169. PLANE_CTL_ALPHA_SW_PREMULTIPLY;
  170. break;
  171. case DRM_FORMAT_ARGB8888:
  172. plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
  173. PLANE_CTL_ALPHA_SW_PREMULTIPLY;
  174. break;
  175. case DRM_FORMAT_YUYV:
  176. plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
  177. break;
  178. case DRM_FORMAT_YVYU:
  179. plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
  180. break;
  181. case DRM_FORMAT_UYVY:
  182. plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
  183. break;
  184. case DRM_FORMAT_VYUY:
  185. plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
  186. break;
  187. default:
  188. BUG();
  189. }
  190. switch (obj->tiling_mode) {
  191. case I915_TILING_NONE:
  192. stride = fb->pitches[0] >> 6;
  193. break;
  194. case I915_TILING_X:
  195. plane_ctl |= PLANE_CTL_TILED_X;
  196. stride = fb->pitches[0] >> 9;
  197. break;
  198. default:
  199. BUG();
  200. }
  201. if (intel_plane->rotation == BIT(DRM_ROTATE_180))
  202. plane_ctl |= PLANE_CTL_ROTATE_180;
  203. plane_ctl |= PLANE_CTL_ENABLE;
  204. plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
  205. intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
  206. pixel_size, true,
  207. src_w != crtc_w || src_h != crtc_h);
  208. /* Sizes are 0 based */
  209. src_w--;
  210. src_h--;
  211. crtc_w--;
  212. crtc_h--;
  213. I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
  214. I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
  215. I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
  216. I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
  217. I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
  218. I915_WRITE(PLANE_SURF(pipe, plane), i915_gem_obj_ggtt_offset(obj));
  219. POSTING_READ(PLANE_SURF(pipe, plane));
  220. }
  221. static void
  222. skl_disable_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc)
  223. {
  224. struct drm_device *dev = drm_plane->dev;
  225. struct drm_i915_private *dev_priv = dev->dev_private;
  226. struct intel_plane *intel_plane = to_intel_plane(drm_plane);
  227. const int pipe = intel_plane->pipe;
  228. const int plane = intel_plane->plane + 1;
  229. I915_WRITE(PLANE_CTL(pipe, plane),
  230. I915_READ(PLANE_CTL(pipe, plane)) & ~PLANE_CTL_ENABLE);
  231. /* Activate double buffered register update */
  232. I915_WRITE(PLANE_CTL(pipe, plane), 0);
  233. POSTING_READ(PLANE_CTL(pipe, plane));
  234. intel_update_sprite_watermarks(drm_plane, crtc, 0, 0, 0, false, false);
  235. }
  236. static int
  237. skl_update_colorkey(struct drm_plane *drm_plane,
  238. struct drm_intel_sprite_colorkey *key)
  239. {
  240. struct drm_device *dev = drm_plane->dev;
  241. struct drm_i915_private *dev_priv = dev->dev_private;
  242. struct intel_plane *intel_plane = to_intel_plane(drm_plane);
  243. const int pipe = intel_plane->pipe;
  244. const int plane = intel_plane->plane;
  245. u32 plane_ctl;
  246. I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
  247. I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
  248. I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask);
  249. plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
  250. plane_ctl &= ~PLANE_CTL_KEY_ENABLE_MASK;
  251. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  252. plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
  253. else if (key->flags & I915_SET_COLORKEY_SOURCE)
  254. plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
  255. I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
  256. POSTING_READ(PLANE_CTL(pipe, plane));
  257. return 0;
  258. }
  259. static void
  260. skl_get_colorkey(struct drm_plane *drm_plane,
  261. struct drm_intel_sprite_colorkey *key)
  262. {
  263. struct drm_device *dev = drm_plane->dev;
  264. struct drm_i915_private *dev_priv = dev->dev_private;
  265. struct intel_plane *intel_plane = to_intel_plane(drm_plane);
  266. const int pipe = intel_plane->pipe;
  267. const int plane = intel_plane->plane;
  268. u32 plane_ctl;
  269. key->min_value = I915_READ(PLANE_KEYVAL(pipe, plane));
  270. key->max_value = I915_READ(PLANE_KEYMAX(pipe, plane));
  271. key->channel_mask = I915_READ(PLANE_KEYMSK(pipe, plane));
  272. plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
  273. switch (plane_ctl & PLANE_CTL_KEY_ENABLE_MASK) {
  274. case PLANE_CTL_KEY_ENABLE_DESTINATION:
  275. key->flags = I915_SET_COLORKEY_DESTINATION;
  276. break;
  277. case PLANE_CTL_KEY_ENABLE_SOURCE:
  278. key->flags = I915_SET_COLORKEY_SOURCE;
  279. break;
  280. default:
  281. key->flags = I915_SET_COLORKEY_NONE;
  282. }
  283. }
  284. static void
  285. chv_update_csc(struct intel_plane *intel_plane, uint32_t format)
  286. {
  287. struct drm_i915_private *dev_priv = intel_plane->base.dev->dev_private;
  288. int plane = intel_plane->plane;
  289. /* Seems RGB data bypasses the CSC always */
  290. if (!format_is_yuv(format))
  291. return;
  292. /*
  293. * BT.601 limited range YCbCr -> full range RGB
  294. *
  295. * |r| | 6537 4769 0| |cr |
  296. * |g| = |-3330 4769 -1605| x |y-64|
  297. * |b| | 0 4769 8263| |cb |
  298. *
  299. * Cb and Cr apparently come in as signed already, so no
  300. * need for any offset. For Y we need to remove the offset.
  301. */
  302. I915_WRITE(SPCSCYGOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(-64));
  303. I915_WRITE(SPCSCCBOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
  304. I915_WRITE(SPCSCCROFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
  305. I915_WRITE(SPCSCC01(plane), SPCSC_C1(4769) | SPCSC_C0(6537));
  306. I915_WRITE(SPCSCC23(plane), SPCSC_C1(-3330) | SPCSC_C0(0));
  307. I915_WRITE(SPCSCC45(plane), SPCSC_C1(-1605) | SPCSC_C0(4769));
  308. I915_WRITE(SPCSCC67(plane), SPCSC_C1(4769) | SPCSC_C0(0));
  309. I915_WRITE(SPCSCC8(plane), SPCSC_C0(8263));
  310. I915_WRITE(SPCSCYGICLAMP(plane), SPCSC_IMAX(940) | SPCSC_IMIN(64));
  311. I915_WRITE(SPCSCCBICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
  312. I915_WRITE(SPCSCCRICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
  313. I915_WRITE(SPCSCYGOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  314. I915_WRITE(SPCSCCBOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  315. I915_WRITE(SPCSCCROCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  316. }
  317. static void
  318. vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
  319. struct drm_framebuffer *fb,
  320. struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  321. unsigned int crtc_w, unsigned int crtc_h,
  322. uint32_t x, uint32_t y,
  323. uint32_t src_w, uint32_t src_h)
  324. {
  325. struct drm_device *dev = dplane->dev;
  326. struct drm_i915_private *dev_priv = dev->dev_private;
  327. struct intel_plane *intel_plane = to_intel_plane(dplane);
  328. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  329. int pipe = intel_plane->pipe;
  330. int plane = intel_plane->plane;
  331. u32 sprctl;
  332. unsigned long sprsurf_offset, linear_offset;
  333. int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  334. u32 start_vbl_count;
  335. bool atomic_update;
  336. sprctl = I915_READ(SPCNTR(pipe, plane));
  337. /* Mask out pixel format bits in case we change it */
  338. sprctl &= ~SP_PIXFORMAT_MASK;
  339. sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
  340. sprctl &= ~SP_TILED;
  341. sprctl &= ~SP_ROTATE_180;
  342. switch (fb->pixel_format) {
  343. case DRM_FORMAT_YUYV:
  344. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
  345. break;
  346. case DRM_FORMAT_YVYU:
  347. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
  348. break;
  349. case DRM_FORMAT_UYVY:
  350. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
  351. break;
  352. case DRM_FORMAT_VYUY:
  353. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
  354. break;
  355. case DRM_FORMAT_RGB565:
  356. sprctl |= SP_FORMAT_BGR565;
  357. break;
  358. case DRM_FORMAT_XRGB8888:
  359. sprctl |= SP_FORMAT_BGRX8888;
  360. break;
  361. case DRM_FORMAT_ARGB8888:
  362. sprctl |= SP_FORMAT_BGRA8888;
  363. break;
  364. case DRM_FORMAT_XBGR2101010:
  365. sprctl |= SP_FORMAT_RGBX1010102;
  366. break;
  367. case DRM_FORMAT_ABGR2101010:
  368. sprctl |= SP_FORMAT_RGBA1010102;
  369. break;
  370. case DRM_FORMAT_XBGR8888:
  371. sprctl |= SP_FORMAT_RGBX8888;
  372. break;
  373. case DRM_FORMAT_ABGR8888:
  374. sprctl |= SP_FORMAT_RGBA8888;
  375. break;
  376. default:
  377. /*
  378. * If we get here one of the upper layers failed to filter
  379. * out the unsupported plane formats
  380. */
  381. BUG();
  382. break;
  383. }
  384. /*
  385. * Enable gamma to match primary/cursor plane behaviour.
  386. * FIXME should be user controllable via propertiesa.
  387. */
  388. sprctl |= SP_GAMMA_ENABLE;
  389. if (obj->tiling_mode != I915_TILING_NONE)
  390. sprctl |= SP_TILED;
  391. sprctl |= SP_ENABLE;
  392. intel_update_sprite_watermarks(dplane, crtc, src_w, src_h,
  393. pixel_size, true,
  394. src_w != crtc_w || src_h != crtc_h);
  395. /* Sizes are 0 based */
  396. src_w--;
  397. src_h--;
  398. crtc_w--;
  399. crtc_h--;
  400. linear_offset = y * fb->pitches[0] + x * pixel_size;
  401. sprsurf_offset = intel_gen4_compute_page_offset(&x, &y,
  402. obj->tiling_mode,
  403. pixel_size,
  404. fb->pitches[0]);
  405. linear_offset -= sprsurf_offset;
  406. if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
  407. sprctl |= SP_ROTATE_180;
  408. x += src_w;
  409. y += src_h;
  410. linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
  411. }
  412. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  413. intel_update_primary_plane(intel_crtc);
  414. if (IS_CHERRYVIEW(dev) && pipe == PIPE_B)
  415. chv_update_csc(intel_plane, fb->pixel_format);
  416. I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
  417. I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
  418. if (obj->tiling_mode != I915_TILING_NONE)
  419. I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
  420. else
  421. I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
  422. I915_WRITE(SPCONSTALPHA(pipe, plane), 0);
  423. I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
  424. I915_WRITE(SPCNTR(pipe, plane), sprctl);
  425. I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
  426. sprsurf_offset);
  427. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  428. if (atomic_update)
  429. intel_pipe_update_end(intel_crtc, start_vbl_count);
  430. }
  431. static void
  432. vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
  433. {
  434. struct drm_device *dev = dplane->dev;
  435. struct drm_i915_private *dev_priv = dev->dev_private;
  436. struct intel_plane *intel_plane = to_intel_plane(dplane);
  437. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  438. int pipe = intel_plane->pipe;
  439. int plane = intel_plane->plane;
  440. u32 start_vbl_count;
  441. bool atomic_update;
  442. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  443. intel_update_primary_plane(intel_crtc);
  444. I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) &
  445. ~SP_ENABLE);
  446. /* Activate double buffered register update */
  447. I915_WRITE(SPSURF(pipe, plane), 0);
  448. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  449. if (atomic_update)
  450. intel_pipe_update_end(intel_crtc, start_vbl_count);
  451. intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
  452. }
  453. static int
  454. vlv_update_colorkey(struct drm_plane *dplane,
  455. struct drm_intel_sprite_colorkey *key)
  456. {
  457. struct drm_device *dev = dplane->dev;
  458. struct drm_i915_private *dev_priv = dev->dev_private;
  459. struct intel_plane *intel_plane = to_intel_plane(dplane);
  460. int pipe = intel_plane->pipe;
  461. int plane = intel_plane->plane;
  462. u32 sprctl;
  463. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  464. return -EINVAL;
  465. I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value);
  466. I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value);
  467. I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask);
  468. sprctl = I915_READ(SPCNTR(pipe, plane));
  469. sprctl &= ~SP_SOURCE_KEY;
  470. if (key->flags & I915_SET_COLORKEY_SOURCE)
  471. sprctl |= SP_SOURCE_KEY;
  472. I915_WRITE(SPCNTR(pipe, plane), sprctl);
  473. POSTING_READ(SPKEYMSK(pipe, plane));
  474. return 0;
  475. }
  476. static void
  477. vlv_get_colorkey(struct drm_plane *dplane,
  478. struct drm_intel_sprite_colorkey *key)
  479. {
  480. struct drm_device *dev = dplane->dev;
  481. struct drm_i915_private *dev_priv = dev->dev_private;
  482. struct intel_plane *intel_plane = to_intel_plane(dplane);
  483. int pipe = intel_plane->pipe;
  484. int plane = intel_plane->plane;
  485. u32 sprctl;
  486. key->min_value = I915_READ(SPKEYMINVAL(pipe, plane));
  487. key->max_value = I915_READ(SPKEYMAXVAL(pipe, plane));
  488. key->channel_mask = I915_READ(SPKEYMSK(pipe, plane));
  489. sprctl = I915_READ(SPCNTR(pipe, plane));
  490. if (sprctl & SP_SOURCE_KEY)
  491. key->flags = I915_SET_COLORKEY_SOURCE;
  492. else
  493. key->flags = I915_SET_COLORKEY_NONE;
  494. }
  495. static void
  496. ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  497. struct drm_framebuffer *fb,
  498. struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  499. unsigned int crtc_w, unsigned int crtc_h,
  500. uint32_t x, uint32_t y,
  501. uint32_t src_w, uint32_t src_h)
  502. {
  503. struct drm_device *dev = plane->dev;
  504. struct drm_i915_private *dev_priv = dev->dev_private;
  505. struct intel_plane *intel_plane = to_intel_plane(plane);
  506. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  507. int pipe = intel_plane->pipe;
  508. u32 sprctl, sprscale = 0;
  509. unsigned long sprsurf_offset, linear_offset;
  510. int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  511. u32 start_vbl_count;
  512. bool atomic_update;
  513. sprctl = I915_READ(SPRCTL(pipe));
  514. /* Mask out pixel format bits in case we change it */
  515. sprctl &= ~SPRITE_PIXFORMAT_MASK;
  516. sprctl &= ~SPRITE_RGB_ORDER_RGBX;
  517. sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
  518. sprctl &= ~SPRITE_TILED;
  519. sprctl &= ~SPRITE_ROTATE_180;
  520. switch (fb->pixel_format) {
  521. case DRM_FORMAT_XBGR8888:
  522. sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
  523. break;
  524. case DRM_FORMAT_XRGB8888:
  525. sprctl |= SPRITE_FORMAT_RGBX888;
  526. break;
  527. case DRM_FORMAT_YUYV:
  528. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
  529. break;
  530. case DRM_FORMAT_YVYU:
  531. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
  532. break;
  533. case DRM_FORMAT_UYVY:
  534. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
  535. break;
  536. case DRM_FORMAT_VYUY:
  537. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
  538. break;
  539. default:
  540. BUG();
  541. }
  542. /*
  543. * Enable gamma to match primary/cursor plane behaviour.
  544. * FIXME should be user controllable via propertiesa.
  545. */
  546. sprctl |= SPRITE_GAMMA_ENABLE;
  547. if (obj->tiling_mode != I915_TILING_NONE)
  548. sprctl |= SPRITE_TILED;
  549. if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  550. sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
  551. else
  552. sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
  553. sprctl |= SPRITE_ENABLE;
  554. if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  555. sprctl |= SPRITE_PIPE_CSC_ENABLE;
  556. intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size,
  557. true,
  558. src_w != crtc_w || src_h != crtc_h);
  559. /* Sizes are 0 based */
  560. src_w--;
  561. src_h--;
  562. crtc_w--;
  563. crtc_h--;
  564. if (crtc_w != src_w || crtc_h != src_h)
  565. sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
  566. linear_offset = y * fb->pitches[0] + x * pixel_size;
  567. sprsurf_offset =
  568. intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
  569. pixel_size, fb->pitches[0]);
  570. linear_offset -= sprsurf_offset;
  571. if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
  572. sprctl |= SPRITE_ROTATE_180;
  573. /* HSW and BDW does this automagically in hardware */
  574. if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
  575. x += src_w;
  576. y += src_h;
  577. linear_offset += src_h * fb->pitches[0] +
  578. src_w * pixel_size;
  579. }
  580. }
  581. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  582. intel_update_primary_plane(intel_crtc);
  583. I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
  584. I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
  585. /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
  586. * register */
  587. if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  588. I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
  589. else if (obj->tiling_mode != I915_TILING_NONE)
  590. I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
  591. else
  592. I915_WRITE(SPRLINOFF(pipe), linear_offset);
  593. I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
  594. if (intel_plane->can_scale)
  595. I915_WRITE(SPRSCALE(pipe), sprscale);
  596. I915_WRITE(SPRCTL(pipe), sprctl);
  597. I915_WRITE(SPRSURF(pipe),
  598. i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
  599. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  600. if (atomic_update)
  601. intel_pipe_update_end(intel_crtc, start_vbl_count);
  602. }
  603. static void
  604. ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
  605. {
  606. struct drm_device *dev = plane->dev;
  607. struct drm_i915_private *dev_priv = dev->dev_private;
  608. struct intel_plane *intel_plane = to_intel_plane(plane);
  609. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  610. int pipe = intel_plane->pipe;
  611. u32 start_vbl_count;
  612. bool atomic_update;
  613. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  614. intel_update_primary_plane(intel_crtc);
  615. I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
  616. /* Can't leave the scaler enabled... */
  617. if (intel_plane->can_scale)
  618. I915_WRITE(SPRSCALE(pipe), 0);
  619. /* Activate double buffered register update */
  620. I915_WRITE(SPRSURF(pipe), 0);
  621. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  622. if (atomic_update)
  623. intel_pipe_update_end(intel_crtc, start_vbl_count);
  624. /*
  625. * Avoid underruns when disabling the sprite.
  626. * FIXME remove once watermark updates are done properly.
  627. */
  628. intel_wait_for_vblank(dev, pipe);
  629. intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
  630. }
  631. static int
  632. ivb_update_colorkey(struct drm_plane *plane,
  633. struct drm_intel_sprite_colorkey *key)
  634. {
  635. struct drm_device *dev = plane->dev;
  636. struct drm_i915_private *dev_priv = dev->dev_private;
  637. struct intel_plane *intel_plane;
  638. u32 sprctl;
  639. int ret = 0;
  640. intel_plane = to_intel_plane(plane);
  641. I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value);
  642. I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value);
  643. I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask);
  644. sprctl = I915_READ(SPRCTL(intel_plane->pipe));
  645. sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY);
  646. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  647. sprctl |= SPRITE_DEST_KEY;
  648. else if (key->flags & I915_SET_COLORKEY_SOURCE)
  649. sprctl |= SPRITE_SOURCE_KEY;
  650. I915_WRITE(SPRCTL(intel_plane->pipe), sprctl);
  651. POSTING_READ(SPRKEYMSK(intel_plane->pipe));
  652. return ret;
  653. }
  654. static void
  655. ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
  656. {
  657. struct drm_device *dev = plane->dev;
  658. struct drm_i915_private *dev_priv = dev->dev_private;
  659. struct intel_plane *intel_plane;
  660. u32 sprctl;
  661. intel_plane = to_intel_plane(plane);
  662. key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe));
  663. key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe));
  664. key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe));
  665. key->flags = 0;
  666. sprctl = I915_READ(SPRCTL(intel_plane->pipe));
  667. if (sprctl & SPRITE_DEST_KEY)
  668. key->flags = I915_SET_COLORKEY_DESTINATION;
  669. else if (sprctl & SPRITE_SOURCE_KEY)
  670. key->flags = I915_SET_COLORKEY_SOURCE;
  671. else
  672. key->flags = I915_SET_COLORKEY_NONE;
  673. }
  674. static void
  675. ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  676. struct drm_framebuffer *fb,
  677. struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  678. unsigned int crtc_w, unsigned int crtc_h,
  679. uint32_t x, uint32_t y,
  680. uint32_t src_w, uint32_t src_h)
  681. {
  682. struct drm_device *dev = plane->dev;
  683. struct drm_i915_private *dev_priv = dev->dev_private;
  684. struct intel_plane *intel_plane = to_intel_plane(plane);
  685. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  686. int pipe = intel_plane->pipe;
  687. unsigned long dvssurf_offset, linear_offset;
  688. u32 dvscntr, dvsscale;
  689. int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  690. u32 start_vbl_count;
  691. bool atomic_update;
  692. dvscntr = I915_READ(DVSCNTR(pipe));
  693. /* Mask out pixel format bits in case we change it */
  694. dvscntr &= ~DVS_PIXFORMAT_MASK;
  695. dvscntr &= ~DVS_RGB_ORDER_XBGR;
  696. dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
  697. dvscntr &= ~DVS_TILED;
  698. dvscntr &= ~DVS_ROTATE_180;
  699. switch (fb->pixel_format) {
  700. case DRM_FORMAT_XBGR8888:
  701. dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
  702. break;
  703. case DRM_FORMAT_XRGB8888:
  704. dvscntr |= DVS_FORMAT_RGBX888;
  705. break;
  706. case DRM_FORMAT_YUYV:
  707. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
  708. break;
  709. case DRM_FORMAT_YVYU:
  710. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
  711. break;
  712. case DRM_FORMAT_UYVY:
  713. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
  714. break;
  715. case DRM_FORMAT_VYUY:
  716. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
  717. break;
  718. default:
  719. BUG();
  720. }
  721. /*
  722. * Enable gamma to match primary/cursor plane behaviour.
  723. * FIXME should be user controllable via propertiesa.
  724. */
  725. dvscntr |= DVS_GAMMA_ENABLE;
  726. if (obj->tiling_mode != I915_TILING_NONE)
  727. dvscntr |= DVS_TILED;
  728. if (IS_GEN6(dev))
  729. dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
  730. dvscntr |= DVS_ENABLE;
  731. intel_update_sprite_watermarks(plane, crtc, src_w, src_h,
  732. pixel_size, true,
  733. src_w != crtc_w || src_h != crtc_h);
  734. /* Sizes are 0 based */
  735. src_w--;
  736. src_h--;
  737. crtc_w--;
  738. crtc_h--;
  739. dvsscale = 0;
  740. if (crtc_w != src_w || crtc_h != src_h)
  741. dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
  742. linear_offset = y * fb->pitches[0] + x * pixel_size;
  743. dvssurf_offset =
  744. intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
  745. pixel_size, fb->pitches[0]);
  746. linear_offset -= dvssurf_offset;
  747. if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
  748. dvscntr |= DVS_ROTATE_180;
  749. x += src_w;
  750. y += src_h;
  751. linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
  752. }
  753. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  754. intel_update_primary_plane(intel_crtc);
  755. I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
  756. I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
  757. if (obj->tiling_mode != I915_TILING_NONE)
  758. I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
  759. else
  760. I915_WRITE(DVSLINOFF(pipe), linear_offset);
  761. I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
  762. I915_WRITE(DVSSCALE(pipe), dvsscale);
  763. I915_WRITE(DVSCNTR(pipe), dvscntr);
  764. I915_WRITE(DVSSURF(pipe),
  765. i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
  766. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  767. if (atomic_update)
  768. intel_pipe_update_end(intel_crtc, start_vbl_count);
  769. }
  770. static void
  771. ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
  772. {
  773. struct drm_device *dev = plane->dev;
  774. struct drm_i915_private *dev_priv = dev->dev_private;
  775. struct intel_plane *intel_plane = to_intel_plane(plane);
  776. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  777. int pipe = intel_plane->pipe;
  778. u32 start_vbl_count;
  779. bool atomic_update;
  780. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  781. intel_update_primary_plane(intel_crtc);
  782. I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
  783. /* Disable the scaler */
  784. I915_WRITE(DVSSCALE(pipe), 0);
  785. /* Flush double buffered register updates */
  786. I915_WRITE(DVSSURF(pipe), 0);
  787. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  788. if (atomic_update)
  789. intel_pipe_update_end(intel_crtc, start_vbl_count);
  790. /*
  791. * Avoid underruns when disabling the sprite.
  792. * FIXME remove once watermark updates are done properly.
  793. */
  794. intel_wait_for_vblank(dev, pipe);
  795. intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
  796. }
  797. static void
  798. intel_post_enable_primary(struct drm_crtc *crtc)
  799. {
  800. struct drm_device *dev = crtc->dev;
  801. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  802. /*
  803. * BDW signals flip done immediately if the plane
  804. * is disabled, even if the plane enable is already
  805. * armed to occur at the next vblank :(
  806. */
  807. if (IS_BROADWELL(dev))
  808. intel_wait_for_vblank(dev, intel_crtc->pipe);
  809. /*
  810. * FIXME IPS should be fine as long as one plane is
  811. * enabled, but in practice it seems to have problems
  812. * when going from primary only to sprite only and vice
  813. * versa.
  814. */
  815. hsw_enable_ips(intel_crtc);
  816. mutex_lock(&dev->struct_mutex);
  817. intel_update_fbc(dev);
  818. mutex_unlock(&dev->struct_mutex);
  819. }
  820. static void
  821. intel_pre_disable_primary(struct drm_crtc *crtc)
  822. {
  823. struct drm_device *dev = crtc->dev;
  824. struct drm_i915_private *dev_priv = dev->dev_private;
  825. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  826. mutex_lock(&dev->struct_mutex);
  827. if (dev_priv->fbc.plane == intel_crtc->plane)
  828. intel_disable_fbc(dev);
  829. mutex_unlock(&dev->struct_mutex);
  830. /*
  831. * FIXME IPS should be fine as long as one plane is
  832. * enabled, but in practice it seems to have problems
  833. * when going from primary only to sprite only and vice
  834. * versa.
  835. */
  836. hsw_disable_ips(intel_crtc);
  837. }
  838. static int
  839. ilk_update_colorkey(struct drm_plane *plane,
  840. struct drm_intel_sprite_colorkey *key)
  841. {
  842. struct drm_device *dev = plane->dev;
  843. struct drm_i915_private *dev_priv = dev->dev_private;
  844. struct intel_plane *intel_plane;
  845. u32 dvscntr;
  846. int ret = 0;
  847. intel_plane = to_intel_plane(plane);
  848. I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value);
  849. I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value);
  850. I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask);
  851. dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
  852. dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY);
  853. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  854. dvscntr |= DVS_DEST_KEY;
  855. else if (key->flags & I915_SET_COLORKEY_SOURCE)
  856. dvscntr |= DVS_SOURCE_KEY;
  857. I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr);
  858. POSTING_READ(DVSKEYMSK(intel_plane->pipe));
  859. return ret;
  860. }
  861. static void
  862. ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
  863. {
  864. struct drm_device *dev = plane->dev;
  865. struct drm_i915_private *dev_priv = dev->dev_private;
  866. struct intel_plane *intel_plane;
  867. u32 dvscntr;
  868. intel_plane = to_intel_plane(plane);
  869. key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe));
  870. key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe));
  871. key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe));
  872. key->flags = 0;
  873. dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
  874. if (dvscntr & DVS_DEST_KEY)
  875. key->flags = I915_SET_COLORKEY_DESTINATION;
  876. else if (dvscntr & DVS_SOURCE_KEY)
  877. key->flags = I915_SET_COLORKEY_SOURCE;
  878. else
  879. key->flags = I915_SET_COLORKEY_NONE;
  880. }
  881. static bool colorkey_enabled(struct intel_plane *intel_plane)
  882. {
  883. struct drm_intel_sprite_colorkey key;
  884. intel_plane->get_colorkey(&intel_plane->base, &key);
  885. return key.flags != I915_SET_COLORKEY_NONE;
  886. }
  887. static int
  888. intel_check_sprite_plane(struct drm_plane *plane,
  889. struct intel_plane_state *state)
  890. {
  891. struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc);
  892. struct intel_plane *intel_plane = to_intel_plane(plane);
  893. struct drm_framebuffer *fb = state->fb;
  894. struct drm_i915_gem_object *obj = intel_fb_obj(fb);
  895. int crtc_x, crtc_y;
  896. unsigned int crtc_w, crtc_h;
  897. uint32_t src_x, src_y, src_w, src_h;
  898. struct drm_rect *src = &state->src;
  899. struct drm_rect *dst = &state->dst;
  900. struct drm_rect *orig_src = &state->orig_src;
  901. const struct drm_rect *clip = &state->clip;
  902. int hscale, vscale;
  903. int max_scale, min_scale;
  904. int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  905. /* Don't modify another pipe's plane */
  906. if (intel_plane->pipe != intel_crtc->pipe) {
  907. DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
  908. return -EINVAL;
  909. }
  910. /* FIXME check all gen limits */
  911. if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
  912. DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
  913. return -EINVAL;
  914. }
  915. /* Sprite planes can be linear or x-tiled surfaces */
  916. switch (obj->tiling_mode) {
  917. case I915_TILING_NONE:
  918. case I915_TILING_X:
  919. break;
  920. default:
  921. DRM_DEBUG_KMS("Unsupported tiling mode\n");
  922. return -EINVAL;
  923. }
  924. /*
  925. * FIXME the following code does a bunch of fuzzy adjustments to the
  926. * coordinates and sizes. We probably need some way to decide whether
  927. * more strict checking should be done instead.
  928. */
  929. max_scale = intel_plane->max_downscale << 16;
  930. min_scale = intel_plane->can_scale ? 1 : (1 << 16);
  931. drm_rect_rotate(src, fb->width << 16, fb->height << 16,
  932. intel_plane->rotation);
  933. hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
  934. BUG_ON(hscale < 0);
  935. vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
  936. BUG_ON(vscale < 0);
  937. state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
  938. crtc_x = dst->x1;
  939. crtc_y = dst->y1;
  940. crtc_w = drm_rect_width(dst);
  941. crtc_h = drm_rect_height(dst);
  942. if (state->visible) {
  943. /* check again in case clipping clamped the results */
  944. hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
  945. if (hscale < 0) {
  946. DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
  947. drm_rect_debug_print(src, true);
  948. drm_rect_debug_print(dst, false);
  949. return hscale;
  950. }
  951. vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
  952. if (vscale < 0) {
  953. DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
  954. drm_rect_debug_print(src, true);
  955. drm_rect_debug_print(dst, false);
  956. return vscale;
  957. }
  958. /* Make the source viewport size an exact multiple of the scaling factors. */
  959. drm_rect_adjust_size(src,
  960. drm_rect_width(dst) * hscale - drm_rect_width(src),
  961. drm_rect_height(dst) * vscale - drm_rect_height(src));
  962. drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
  963. intel_plane->rotation);
  964. /* sanity check to make sure the src viewport wasn't enlarged */
  965. WARN_ON(src->x1 < (int) orig_src->x1 ||
  966. src->y1 < (int) orig_src->y1 ||
  967. src->x2 > (int) orig_src->x2 ||
  968. src->y2 > (int) orig_src->y2);
  969. /*
  970. * Hardware doesn't handle subpixel coordinates.
  971. * Adjust to (macro)pixel boundary, but be careful not to
  972. * increase the source viewport size, because that could
  973. * push the downscaling factor out of bounds.
  974. */
  975. src_x = src->x1 >> 16;
  976. src_w = drm_rect_width(src) >> 16;
  977. src_y = src->y1 >> 16;
  978. src_h = drm_rect_height(src) >> 16;
  979. if (format_is_yuv(fb->pixel_format)) {
  980. src_x &= ~1;
  981. src_w &= ~1;
  982. /*
  983. * Must keep src and dst the
  984. * same if we can't scale.
  985. */
  986. if (!intel_plane->can_scale)
  987. crtc_w &= ~1;
  988. if (crtc_w == 0)
  989. state->visible = false;
  990. }
  991. }
  992. /* Check size restrictions when scaling */
  993. if (state->visible && (src_w != crtc_w || src_h != crtc_h)) {
  994. unsigned int width_bytes;
  995. WARN_ON(!intel_plane->can_scale);
  996. /* FIXME interlacing min height is 6 */
  997. if (crtc_w < 3 || crtc_h < 3)
  998. state->visible = false;
  999. if (src_w < 3 || src_h < 3)
  1000. state->visible = false;
  1001. width_bytes = ((src_x * pixel_size) & 63) +
  1002. src_w * pixel_size;
  1003. if (src_w > 2048 || src_h > 2048 ||
  1004. width_bytes > 4096 || fb->pitches[0] > 4096) {
  1005. DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
  1006. return -EINVAL;
  1007. }
  1008. }
  1009. if (state->visible) {
  1010. src->x1 = src_x;
  1011. src->x2 = src_x + src_w;
  1012. src->y1 = src_y;
  1013. src->y2 = src_y + src_h;
  1014. }
  1015. dst->x1 = crtc_x;
  1016. dst->x2 = crtc_x + crtc_w;
  1017. dst->y1 = crtc_y;
  1018. dst->y2 = crtc_y + crtc_h;
  1019. return 0;
  1020. }
  1021. static int
  1022. intel_prepare_sprite_plane(struct drm_plane *plane,
  1023. struct intel_plane_state *state)
  1024. {
  1025. struct drm_device *dev = plane->dev;
  1026. struct drm_crtc *crtc = state->crtc;
  1027. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  1028. enum pipe pipe = intel_crtc->pipe;
  1029. struct drm_framebuffer *fb = state->fb;
  1030. struct drm_i915_gem_object *obj = intel_fb_obj(fb);
  1031. struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
  1032. int ret;
  1033. if (old_obj != obj) {
  1034. mutex_lock(&dev->struct_mutex);
  1035. /* Note that this will apply the VT-d workaround for scanouts,
  1036. * which is more restrictive than required for sprites. (The
  1037. * primary plane requires 256KiB alignment with 64 PTE padding,
  1038. * the sprite planes only require 128KiB alignment and 32 PTE
  1039. * padding.
  1040. */
  1041. ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
  1042. if (ret == 0)
  1043. i915_gem_track_fb(old_obj, obj,
  1044. INTEL_FRONTBUFFER_SPRITE(pipe));
  1045. mutex_unlock(&dev->struct_mutex);
  1046. if (ret)
  1047. return ret;
  1048. }
  1049. return 0;
  1050. }
  1051. static void
  1052. intel_commit_sprite_plane(struct drm_plane *plane,
  1053. struct intel_plane_state *state)
  1054. {
  1055. struct drm_device *dev = plane->dev;
  1056. struct drm_crtc *crtc = state->crtc;
  1057. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  1058. struct intel_plane *intel_plane = to_intel_plane(plane);
  1059. enum pipe pipe = intel_crtc->pipe;
  1060. struct drm_framebuffer *fb = state->fb;
  1061. struct drm_i915_gem_object *obj = intel_fb_obj(fb);
  1062. struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
  1063. int crtc_x, crtc_y;
  1064. unsigned int crtc_w, crtc_h;
  1065. uint32_t src_x, src_y, src_w, src_h;
  1066. struct drm_rect *dst = &state->dst;
  1067. const struct drm_rect *clip = &state->clip;
  1068. bool primary_enabled;
  1069. /*
  1070. * If the sprite is completely covering the primary plane,
  1071. * we can disable the primary and save power.
  1072. */
  1073. primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane);
  1074. WARN_ON(!primary_enabled && !state->visible && intel_crtc->active);
  1075. intel_plane->crtc_x = state->orig_dst.x1;
  1076. intel_plane->crtc_y = state->orig_dst.y1;
  1077. intel_plane->crtc_w = drm_rect_width(&state->orig_dst);
  1078. intel_plane->crtc_h = drm_rect_height(&state->orig_dst);
  1079. intel_plane->src_x = state->orig_src.x1;
  1080. intel_plane->src_y = state->orig_src.y1;
  1081. intel_plane->src_w = drm_rect_width(&state->orig_src);
  1082. intel_plane->src_h = drm_rect_height(&state->orig_src);
  1083. intel_plane->obj = obj;
  1084. if (intel_crtc->active) {
  1085. bool primary_was_enabled = intel_crtc->primary_enabled;
  1086. intel_crtc->primary_enabled = primary_enabled;
  1087. if (primary_was_enabled != primary_enabled)
  1088. intel_crtc_wait_for_pending_flips(crtc);
  1089. if (primary_was_enabled && !primary_enabled)
  1090. intel_pre_disable_primary(crtc);
  1091. if (state->visible) {
  1092. crtc_x = state->dst.x1;
  1093. crtc_y = state->dst.y1;
  1094. crtc_w = drm_rect_width(&state->dst);
  1095. crtc_h = drm_rect_height(&state->dst);
  1096. src_x = state->src.x1;
  1097. src_y = state->src.y1;
  1098. src_w = drm_rect_width(&state->src);
  1099. src_h = drm_rect_height(&state->src);
  1100. intel_plane->update_plane(plane, crtc, fb, obj,
  1101. crtc_x, crtc_y, crtc_w, crtc_h,
  1102. src_x, src_y, src_w, src_h);
  1103. } else {
  1104. intel_plane->disable_plane(plane, crtc);
  1105. }
  1106. intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe));
  1107. if (!primary_was_enabled && primary_enabled)
  1108. intel_post_enable_primary(crtc);
  1109. }
  1110. /* Unpin old obj after new one is active to avoid ugliness */
  1111. if (old_obj && old_obj != obj) {
  1112. /*
  1113. * It's fairly common to simply update the position of
  1114. * an existing object. In that case, we don't need to
  1115. * wait for vblank to avoid ugliness, we only need to
  1116. * do the pin & ref bookkeeping.
  1117. */
  1118. if (intel_crtc->active)
  1119. intel_wait_for_vblank(dev, intel_crtc->pipe);
  1120. mutex_lock(&dev->struct_mutex);
  1121. intel_unpin_fb_obj(old_obj);
  1122. mutex_unlock(&dev->struct_mutex);
  1123. }
  1124. }
  1125. static int
  1126. intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  1127. struct drm_framebuffer *fb, int crtc_x, int crtc_y,
  1128. unsigned int crtc_w, unsigned int crtc_h,
  1129. uint32_t src_x, uint32_t src_y,
  1130. uint32_t src_w, uint32_t src_h)
  1131. {
  1132. struct intel_plane_state state;
  1133. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  1134. int ret;
  1135. state.crtc = crtc;
  1136. state.fb = fb;
  1137. /* sample coordinates in 16.16 fixed point */
  1138. state.src.x1 = src_x;
  1139. state.src.x2 = src_x + src_w;
  1140. state.src.y1 = src_y;
  1141. state.src.y2 = src_y + src_h;
  1142. /* integer pixels */
  1143. state.dst.x1 = crtc_x;
  1144. state.dst.x2 = crtc_x + crtc_w;
  1145. state.dst.y1 = crtc_y;
  1146. state.dst.y2 = crtc_y + crtc_h;
  1147. state.clip.x1 = 0;
  1148. state.clip.y1 = 0;
  1149. state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0;
  1150. state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0;
  1151. state.orig_src = state.src;
  1152. state.orig_dst = state.dst;
  1153. ret = intel_check_sprite_plane(plane, &state);
  1154. if (ret)
  1155. return ret;
  1156. ret = intel_prepare_sprite_plane(plane, &state);
  1157. if (ret)
  1158. return ret;
  1159. intel_commit_sprite_plane(plane, &state);
  1160. return 0;
  1161. }
  1162. static int
  1163. intel_disable_plane(struct drm_plane *plane)
  1164. {
  1165. struct drm_device *dev = plane->dev;
  1166. struct intel_plane *intel_plane = to_intel_plane(plane);
  1167. struct intel_crtc *intel_crtc;
  1168. enum pipe pipe;
  1169. if (!plane->fb)
  1170. return 0;
  1171. if (WARN_ON(!plane->crtc))
  1172. return -EINVAL;
  1173. intel_crtc = to_intel_crtc(plane->crtc);
  1174. pipe = intel_crtc->pipe;
  1175. if (intel_crtc->active) {
  1176. bool primary_was_enabled = intel_crtc->primary_enabled;
  1177. intel_crtc->primary_enabled = true;
  1178. intel_plane->disable_plane(plane, plane->crtc);
  1179. if (!primary_was_enabled && intel_crtc->primary_enabled)
  1180. intel_post_enable_primary(plane->crtc);
  1181. }
  1182. if (intel_plane->obj) {
  1183. if (intel_crtc->active)
  1184. intel_wait_for_vblank(dev, intel_plane->pipe);
  1185. mutex_lock(&dev->struct_mutex);
  1186. intel_unpin_fb_obj(intel_plane->obj);
  1187. i915_gem_track_fb(intel_plane->obj, NULL,
  1188. INTEL_FRONTBUFFER_SPRITE(pipe));
  1189. mutex_unlock(&dev->struct_mutex);
  1190. intel_plane->obj = NULL;
  1191. }
  1192. return 0;
  1193. }
  1194. static void intel_destroy_plane(struct drm_plane *plane)
  1195. {
  1196. struct intel_plane *intel_plane = to_intel_plane(plane);
  1197. intel_disable_plane(plane);
  1198. drm_plane_cleanup(plane);
  1199. kfree(intel_plane);
  1200. }
  1201. int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
  1202. struct drm_file *file_priv)
  1203. {
  1204. struct drm_intel_sprite_colorkey *set = data;
  1205. struct drm_plane *plane;
  1206. struct intel_plane *intel_plane;
  1207. int ret = 0;
  1208. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1209. return -ENODEV;
  1210. /* Make sure we don't try to enable both src & dest simultaneously */
  1211. if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
  1212. return -EINVAL;
  1213. drm_modeset_lock_all(dev);
  1214. plane = drm_plane_find(dev, set->plane_id);
  1215. if (!plane) {
  1216. ret = -ENOENT;
  1217. goto out_unlock;
  1218. }
  1219. intel_plane = to_intel_plane(plane);
  1220. ret = intel_plane->update_colorkey(plane, set);
  1221. out_unlock:
  1222. drm_modeset_unlock_all(dev);
  1223. return ret;
  1224. }
  1225. int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
  1226. struct drm_file *file_priv)
  1227. {
  1228. struct drm_intel_sprite_colorkey *get = data;
  1229. struct drm_plane *plane;
  1230. struct intel_plane *intel_plane;
  1231. int ret = 0;
  1232. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1233. return -ENODEV;
  1234. drm_modeset_lock_all(dev);
  1235. plane = drm_plane_find(dev, get->plane_id);
  1236. if (!plane) {
  1237. ret = -ENOENT;
  1238. goto out_unlock;
  1239. }
  1240. intel_plane = to_intel_plane(plane);
  1241. intel_plane->get_colorkey(plane, get);
  1242. out_unlock:
  1243. drm_modeset_unlock_all(dev);
  1244. return ret;
  1245. }
  1246. int intel_plane_set_property(struct drm_plane *plane,
  1247. struct drm_property *prop,
  1248. uint64_t val)
  1249. {
  1250. struct drm_device *dev = plane->dev;
  1251. struct intel_plane *intel_plane = to_intel_plane(plane);
  1252. uint64_t old_val;
  1253. int ret = -ENOENT;
  1254. if (prop == dev->mode_config.rotation_property) {
  1255. /* exactly one rotation angle please */
  1256. if (hweight32(val & 0xf) != 1)
  1257. return -EINVAL;
  1258. if (intel_plane->rotation == val)
  1259. return 0;
  1260. old_val = intel_plane->rotation;
  1261. intel_plane->rotation = val;
  1262. ret = intel_plane_restore(plane);
  1263. if (ret)
  1264. intel_plane->rotation = old_val;
  1265. }
  1266. return ret;
  1267. }
  1268. int intel_plane_restore(struct drm_plane *plane)
  1269. {
  1270. struct intel_plane *intel_plane = to_intel_plane(plane);
  1271. if (!plane->crtc || !plane->fb)
  1272. return 0;
  1273. return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
  1274. intel_plane->crtc_x, intel_plane->crtc_y,
  1275. intel_plane->crtc_w, intel_plane->crtc_h,
  1276. intel_plane->src_x, intel_plane->src_y,
  1277. intel_plane->src_w, intel_plane->src_h);
  1278. }
  1279. void intel_plane_disable(struct drm_plane *plane)
  1280. {
  1281. if (!plane->crtc || !plane->fb)
  1282. return;
  1283. intel_disable_plane(plane);
  1284. }
  1285. static const struct drm_plane_funcs intel_plane_funcs = {
  1286. .update_plane = intel_update_plane,
  1287. .disable_plane = intel_disable_plane,
  1288. .destroy = intel_destroy_plane,
  1289. .set_property = intel_plane_set_property,
  1290. };
  1291. static uint32_t ilk_plane_formats[] = {
  1292. DRM_FORMAT_XRGB8888,
  1293. DRM_FORMAT_YUYV,
  1294. DRM_FORMAT_YVYU,
  1295. DRM_FORMAT_UYVY,
  1296. DRM_FORMAT_VYUY,
  1297. };
  1298. static uint32_t snb_plane_formats[] = {
  1299. DRM_FORMAT_XBGR8888,
  1300. DRM_FORMAT_XRGB8888,
  1301. DRM_FORMAT_YUYV,
  1302. DRM_FORMAT_YVYU,
  1303. DRM_FORMAT_UYVY,
  1304. DRM_FORMAT_VYUY,
  1305. };
  1306. static uint32_t vlv_plane_formats[] = {
  1307. DRM_FORMAT_RGB565,
  1308. DRM_FORMAT_ABGR8888,
  1309. DRM_FORMAT_ARGB8888,
  1310. DRM_FORMAT_XBGR8888,
  1311. DRM_FORMAT_XRGB8888,
  1312. DRM_FORMAT_XBGR2101010,
  1313. DRM_FORMAT_ABGR2101010,
  1314. DRM_FORMAT_YUYV,
  1315. DRM_FORMAT_YVYU,
  1316. DRM_FORMAT_UYVY,
  1317. DRM_FORMAT_VYUY,
  1318. };
  1319. static uint32_t skl_plane_formats[] = {
  1320. DRM_FORMAT_RGB565,
  1321. DRM_FORMAT_ABGR8888,
  1322. DRM_FORMAT_ARGB8888,
  1323. DRM_FORMAT_XBGR8888,
  1324. DRM_FORMAT_XRGB8888,
  1325. DRM_FORMAT_YUYV,
  1326. DRM_FORMAT_YVYU,
  1327. DRM_FORMAT_UYVY,
  1328. DRM_FORMAT_VYUY,
  1329. };
  1330. int
  1331. intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
  1332. {
  1333. struct intel_plane *intel_plane;
  1334. unsigned long possible_crtcs;
  1335. const uint32_t *plane_formats;
  1336. int num_plane_formats;
  1337. int ret;
  1338. if (INTEL_INFO(dev)->gen < 5)
  1339. return -ENODEV;
  1340. intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
  1341. if (!intel_plane)
  1342. return -ENOMEM;
  1343. switch (INTEL_INFO(dev)->gen) {
  1344. case 5:
  1345. case 6:
  1346. intel_plane->can_scale = true;
  1347. intel_plane->max_downscale = 16;
  1348. intel_plane->update_plane = ilk_update_plane;
  1349. intel_plane->disable_plane = ilk_disable_plane;
  1350. intel_plane->update_colorkey = ilk_update_colorkey;
  1351. intel_plane->get_colorkey = ilk_get_colorkey;
  1352. if (IS_GEN6(dev)) {
  1353. plane_formats = snb_plane_formats;
  1354. num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1355. } else {
  1356. plane_formats = ilk_plane_formats;
  1357. num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
  1358. }
  1359. break;
  1360. case 7:
  1361. case 8:
  1362. if (IS_IVYBRIDGE(dev)) {
  1363. intel_plane->can_scale = true;
  1364. intel_plane->max_downscale = 2;
  1365. } else {
  1366. intel_plane->can_scale = false;
  1367. intel_plane->max_downscale = 1;
  1368. }
  1369. if (IS_VALLEYVIEW(dev)) {
  1370. intel_plane->update_plane = vlv_update_plane;
  1371. intel_plane->disable_plane = vlv_disable_plane;
  1372. intel_plane->update_colorkey = vlv_update_colorkey;
  1373. intel_plane->get_colorkey = vlv_get_colorkey;
  1374. plane_formats = vlv_plane_formats;
  1375. num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
  1376. } else {
  1377. intel_plane->update_plane = ivb_update_plane;
  1378. intel_plane->disable_plane = ivb_disable_plane;
  1379. intel_plane->update_colorkey = ivb_update_colorkey;
  1380. intel_plane->get_colorkey = ivb_get_colorkey;
  1381. plane_formats = snb_plane_formats;
  1382. num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1383. }
  1384. break;
  1385. case 9:
  1386. /*
  1387. * FIXME: Skylake planes can be scaled (with some restrictions),
  1388. * but this is for another time.
  1389. */
  1390. intel_plane->can_scale = false;
  1391. intel_plane->max_downscale = 1;
  1392. intel_plane->update_plane = skl_update_plane;
  1393. intel_plane->disable_plane = skl_disable_plane;
  1394. intel_plane->update_colorkey = skl_update_colorkey;
  1395. intel_plane->get_colorkey = skl_get_colorkey;
  1396. plane_formats = skl_plane_formats;
  1397. num_plane_formats = ARRAY_SIZE(skl_plane_formats);
  1398. break;
  1399. default:
  1400. kfree(intel_plane);
  1401. return -ENODEV;
  1402. }
  1403. intel_plane->pipe = pipe;
  1404. intel_plane->plane = plane;
  1405. intel_plane->rotation = BIT(DRM_ROTATE_0);
  1406. possible_crtcs = (1 << pipe);
  1407. ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
  1408. &intel_plane_funcs,
  1409. plane_formats, num_plane_formats,
  1410. DRM_PLANE_TYPE_OVERLAY);
  1411. if (ret) {
  1412. kfree(intel_plane);
  1413. goto out;
  1414. }
  1415. if (!dev->mode_config.rotation_property)
  1416. dev->mode_config.rotation_property =
  1417. drm_mode_create_rotation_property(dev,
  1418. BIT(DRM_ROTATE_0) |
  1419. BIT(DRM_ROTATE_180));
  1420. if (dev->mode_config.rotation_property)
  1421. drm_object_attach_property(&intel_plane->base.base,
  1422. dev->mode_config.rotation_property,
  1423. intel_plane->rotation);
  1424. out:
  1425. return ret;
  1426. }