intel_sprite.c 48 KB

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