intel_sprite.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323
  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 int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
  40. {
  41. /* paranoia */
  42. if (!mode->crtc_htotal)
  43. return 1;
  44. return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal);
  45. }
  46. static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
  47. {
  48. struct drm_device *dev = crtc->base.dev;
  49. const struct drm_display_mode *mode = &crtc->config.adjusted_mode;
  50. enum pipe pipe = crtc->pipe;
  51. long timeout = msecs_to_jiffies_timeout(1);
  52. int scanline, min, max, vblank_start;
  53. wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
  54. DEFINE_WAIT(wait);
  55. WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
  56. vblank_start = mode->crtc_vblank_start;
  57. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  58. vblank_start = DIV_ROUND_UP(vblank_start, 2);
  59. /* FIXME needs to be calibrated sensibly */
  60. min = vblank_start - usecs_to_scanlines(mode, 100);
  61. max = vblank_start - 1;
  62. if (min <= 0 || max <= 0)
  63. return false;
  64. if (WARN_ON(drm_vblank_get(dev, pipe)))
  65. return false;
  66. local_irq_disable();
  67. trace_i915_pipe_update_start(crtc, min, max);
  68. for (;;) {
  69. /*
  70. * prepare_to_wait() has a memory barrier, which guarantees
  71. * other CPUs can see the task state update by the time we
  72. * read the scanline.
  73. */
  74. prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
  75. scanline = intel_get_crtc_scanline(crtc);
  76. if (scanline < min || scanline > max)
  77. break;
  78. if (timeout <= 0) {
  79. DRM_ERROR("Potential atomic update failure on pipe %c\n",
  80. pipe_name(crtc->pipe));
  81. break;
  82. }
  83. local_irq_enable();
  84. timeout = schedule_timeout(timeout);
  85. local_irq_disable();
  86. }
  87. finish_wait(wq, &wait);
  88. drm_vblank_put(dev, pipe);
  89. *start_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
  90. trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count);
  91. return true;
  92. }
  93. static void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count)
  94. {
  95. struct drm_device *dev = crtc->base.dev;
  96. enum pipe pipe = crtc->pipe;
  97. u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
  98. trace_i915_pipe_update_end(crtc, end_vbl_count);
  99. local_irq_enable();
  100. if (start_vbl_count != end_vbl_count)
  101. DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n",
  102. pipe_name(pipe), start_vbl_count, end_vbl_count);
  103. }
  104. static void intel_update_primary_plane(struct intel_crtc *crtc)
  105. {
  106. struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
  107. int reg = DSPCNTR(crtc->plane);
  108. if (crtc->primary_enabled)
  109. I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
  110. else
  111. I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
  112. }
  113. static void
  114. vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
  115. struct drm_framebuffer *fb,
  116. struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  117. unsigned int crtc_w, unsigned int crtc_h,
  118. uint32_t x, uint32_t y,
  119. uint32_t src_w, uint32_t src_h)
  120. {
  121. struct drm_device *dev = dplane->dev;
  122. struct drm_i915_private *dev_priv = dev->dev_private;
  123. struct intel_plane *intel_plane = to_intel_plane(dplane);
  124. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  125. int pipe = intel_plane->pipe;
  126. int plane = intel_plane->plane;
  127. u32 sprctl;
  128. unsigned long sprsurf_offset, linear_offset;
  129. int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  130. u32 start_vbl_count;
  131. bool atomic_update;
  132. sprctl = I915_READ(SPCNTR(pipe, plane));
  133. /* Mask out pixel format bits in case we change it */
  134. sprctl &= ~SP_PIXFORMAT_MASK;
  135. sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
  136. sprctl &= ~SP_TILED;
  137. switch (fb->pixel_format) {
  138. case DRM_FORMAT_YUYV:
  139. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
  140. break;
  141. case DRM_FORMAT_YVYU:
  142. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
  143. break;
  144. case DRM_FORMAT_UYVY:
  145. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
  146. break;
  147. case DRM_FORMAT_VYUY:
  148. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
  149. break;
  150. case DRM_FORMAT_RGB565:
  151. sprctl |= SP_FORMAT_BGR565;
  152. break;
  153. case DRM_FORMAT_XRGB8888:
  154. sprctl |= SP_FORMAT_BGRX8888;
  155. break;
  156. case DRM_FORMAT_ARGB8888:
  157. sprctl |= SP_FORMAT_BGRA8888;
  158. break;
  159. case DRM_FORMAT_XBGR2101010:
  160. sprctl |= SP_FORMAT_RGBX1010102;
  161. break;
  162. case DRM_FORMAT_ABGR2101010:
  163. sprctl |= SP_FORMAT_RGBA1010102;
  164. break;
  165. case DRM_FORMAT_XBGR8888:
  166. sprctl |= SP_FORMAT_RGBX8888;
  167. break;
  168. case DRM_FORMAT_ABGR8888:
  169. sprctl |= SP_FORMAT_RGBA8888;
  170. break;
  171. default:
  172. /*
  173. * If we get here one of the upper layers failed to filter
  174. * out the unsupported plane formats
  175. */
  176. BUG();
  177. break;
  178. }
  179. /*
  180. * Enable gamma to match primary/cursor plane behaviour.
  181. * FIXME should be user controllable via propertiesa.
  182. */
  183. sprctl |= SP_GAMMA_ENABLE;
  184. if (obj->tiling_mode != I915_TILING_NONE)
  185. sprctl |= SP_TILED;
  186. sprctl |= SP_ENABLE;
  187. intel_update_sprite_watermarks(dplane, crtc, src_w, src_h,
  188. pixel_size, true,
  189. src_w != crtc_w || src_h != crtc_h);
  190. /* Sizes are 0 based */
  191. src_w--;
  192. src_h--;
  193. crtc_w--;
  194. crtc_h--;
  195. linear_offset = y * fb->pitches[0] + x * pixel_size;
  196. sprsurf_offset = intel_gen4_compute_page_offset(&x, &y,
  197. obj->tiling_mode,
  198. pixel_size,
  199. fb->pitches[0]);
  200. linear_offset -= sprsurf_offset;
  201. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  202. intel_update_primary_plane(intel_crtc);
  203. I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
  204. I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
  205. if (obj->tiling_mode != I915_TILING_NONE)
  206. I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
  207. else
  208. I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
  209. I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
  210. I915_WRITE(SPCNTR(pipe, plane), sprctl);
  211. I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
  212. sprsurf_offset);
  213. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  214. if (atomic_update)
  215. intel_pipe_update_end(intel_crtc, start_vbl_count);
  216. }
  217. static void
  218. vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
  219. {
  220. struct drm_device *dev = dplane->dev;
  221. struct drm_i915_private *dev_priv = dev->dev_private;
  222. struct intel_plane *intel_plane = to_intel_plane(dplane);
  223. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  224. int pipe = intel_plane->pipe;
  225. int plane = intel_plane->plane;
  226. u32 start_vbl_count;
  227. bool atomic_update;
  228. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  229. intel_update_primary_plane(intel_crtc);
  230. I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) &
  231. ~SP_ENABLE);
  232. /* Activate double buffered register update */
  233. I915_WRITE(SPSURF(pipe, plane), 0);
  234. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  235. if (atomic_update)
  236. intel_pipe_update_end(intel_crtc, start_vbl_count);
  237. intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
  238. }
  239. static int
  240. vlv_update_colorkey(struct drm_plane *dplane,
  241. struct drm_intel_sprite_colorkey *key)
  242. {
  243. struct drm_device *dev = dplane->dev;
  244. struct drm_i915_private *dev_priv = dev->dev_private;
  245. struct intel_plane *intel_plane = to_intel_plane(dplane);
  246. int pipe = intel_plane->pipe;
  247. int plane = intel_plane->plane;
  248. u32 sprctl;
  249. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  250. return -EINVAL;
  251. I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value);
  252. I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value);
  253. I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask);
  254. sprctl = I915_READ(SPCNTR(pipe, plane));
  255. sprctl &= ~SP_SOURCE_KEY;
  256. if (key->flags & I915_SET_COLORKEY_SOURCE)
  257. sprctl |= SP_SOURCE_KEY;
  258. I915_WRITE(SPCNTR(pipe, plane), sprctl);
  259. POSTING_READ(SPKEYMSK(pipe, plane));
  260. return 0;
  261. }
  262. static void
  263. vlv_get_colorkey(struct drm_plane *dplane,
  264. struct drm_intel_sprite_colorkey *key)
  265. {
  266. struct drm_device *dev = dplane->dev;
  267. struct drm_i915_private *dev_priv = dev->dev_private;
  268. struct intel_plane *intel_plane = to_intel_plane(dplane);
  269. int pipe = intel_plane->pipe;
  270. int plane = intel_plane->plane;
  271. u32 sprctl;
  272. key->min_value = I915_READ(SPKEYMINVAL(pipe, plane));
  273. key->max_value = I915_READ(SPKEYMAXVAL(pipe, plane));
  274. key->channel_mask = I915_READ(SPKEYMSK(pipe, plane));
  275. sprctl = I915_READ(SPCNTR(pipe, plane));
  276. if (sprctl & SP_SOURCE_KEY)
  277. key->flags = I915_SET_COLORKEY_SOURCE;
  278. else
  279. key->flags = I915_SET_COLORKEY_NONE;
  280. }
  281. static void
  282. ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  283. struct drm_framebuffer *fb,
  284. struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  285. unsigned int crtc_w, unsigned int crtc_h,
  286. uint32_t x, uint32_t y,
  287. uint32_t src_w, uint32_t src_h)
  288. {
  289. struct drm_device *dev = plane->dev;
  290. struct drm_i915_private *dev_priv = dev->dev_private;
  291. struct intel_plane *intel_plane = to_intel_plane(plane);
  292. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  293. int pipe = intel_plane->pipe;
  294. u32 sprctl, sprscale = 0;
  295. unsigned long sprsurf_offset, linear_offset;
  296. int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  297. u32 start_vbl_count;
  298. bool atomic_update;
  299. sprctl = I915_READ(SPRCTL(pipe));
  300. /* Mask out pixel format bits in case we change it */
  301. sprctl &= ~SPRITE_PIXFORMAT_MASK;
  302. sprctl &= ~SPRITE_RGB_ORDER_RGBX;
  303. sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
  304. sprctl &= ~SPRITE_TILED;
  305. switch (fb->pixel_format) {
  306. case DRM_FORMAT_XBGR8888:
  307. sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
  308. break;
  309. case DRM_FORMAT_XRGB8888:
  310. sprctl |= SPRITE_FORMAT_RGBX888;
  311. break;
  312. case DRM_FORMAT_YUYV:
  313. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
  314. break;
  315. case DRM_FORMAT_YVYU:
  316. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
  317. break;
  318. case DRM_FORMAT_UYVY:
  319. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
  320. break;
  321. case DRM_FORMAT_VYUY:
  322. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
  323. break;
  324. default:
  325. BUG();
  326. }
  327. /*
  328. * Enable gamma to match primary/cursor plane behaviour.
  329. * FIXME should be user controllable via propertiesa.
  330. */
  331. sprctl |= SPRITE_GAMMA_ENABLE;
  332. if (obj->tiling_mode != I915_TILING_NONE)
  333. sprctl |= SPRITE_TILED;
  334. if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  335. sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
  336. else
  337. sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
  338. sprctl |= SPRITE_ENABLE;
  339. if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  340. sprctl |= SPRITE_PIPE_CSC_ENABLE;
  341. intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size,
  342. true,
  343. src_w != crtc_w || src_h != crtc_h);
  344. /* Sizes are 0 based */
  345. src_w--;
  346. src_h--;
  347. crtc_w--;
  348. crtc_h--;
  349. if (crtc_w != src_w || crtc_h != src_h)
  350. sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
  351. linear_offset = y * fb->pitches[0] + x * pixel_size;
  352. sprsurf_offset =
  353. intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
  354. pixel_size, fb->pitches[0]);
  355. linear_offset -= sprsurf_offset;
  356. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  357. intel_update_primary_plane(intel_crtc);
  358. I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
  359. I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
  360. /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
  361. * register */
  362. if (IS_HASWELL(dev) || IS_BROADWELL(dev))
  363. I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
  364. else if (obj->tiling_mode != I915_TILING_NONE)
  365. I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
  366. else
  367. I915_WRITE(SPRLINOFF(pipe), linear_offset);
  368. I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
  369. if (intel_plane->can_scale)
  370. I915_WRITE(SPRSCALE(pipe), sprscale);
  371. I915_WRITE(SPRCTL(pipe), sprctl);
  372. I915_WRITE(SPRSURF(pipe),
  373. i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
  374. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  375. if (atomic_update)
  376. intel_pipe_update_end(intel_crtc, start_vbl_count);
  377. }
  378. static void
  379. ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
  380. {
  381. struct drm_device *dev = plane->dev;
  382. struct drm_i915_private *dev_priv = dev->dev_private;
  383. struct intel_plane *intel_plane = to_intel_plane(plane);
  384. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  385. int pipe = intel_plane->pipe;
  386. u32 start_vbl_count;
  387. bool atomic_update;
  388. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  389. intel_update_primary_plane(intel_crtc);
  390. I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
  391. /* Can't leave the scaler enabled... */
  392. if (intel_plane->can_scale)
  393. I915_WRITE(SPRSCALE(pipe), 0);
  394. /* Activate double buffered register update */
  395. I915_WRITE(SPRSURF(pipe), 0);
  396. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  397. if (atomic_update)
  398. intel_pipe_update_end(intel_crtc, start_vbl_count);
  399. /*
  400. * Avoid underruns when disabling the sprite.
  401. * FIXME remove once watermark updates are done properly.
  402. */
  403. intel_wait_for_vblank(dev, pipe);
  404. intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
  405. }
  406. static int
  407. ivb_update_colorkey(struct drm_plane *plane,
  408. struct drm_intel_sprite_colorkey *key)
  409. {
  410. struct drm_device *dev = plane->dev;
  411. struct drm_i915_private *dev_priv = dev->dev_private;
  412. struct intel_plane *intel_plane;
  413. u32 sprctl;
  414. int ret = 0;
  415. intel_plane = to_intel_plane(plane);
  416. I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value);
  417. I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value);
  418. I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask);
  419. sprctl = I915_READ(SPRCTL(intel_plane->pipe));
  420. sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY);
  421. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  422. sprctl |= SPRITE_DEST_KEY;
  423. else if (key->flags & I915_SET_COLORKEY_SOURCE)
  424. sprctl |= SPRITE_SOURCE_KEY;
  425. I915_WRITE(SPRCTL(intel_plane->pipe), sprctl);
  426. POSTING_READ(SPRKEYMSK(intel_plane->pipe));
  427. return ret;
  428. }
  429. static void
  430. ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
  431. {
  432. struct drm_device *dev = plane->dev;
  433. struct drm_i915_private *dev_priv = dev->dev_private;
  434. struct intel_plane *intel_plane;
  435. u32 sprctl;
  436. intel_plane = to_intel_plane(plane);
  437. key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe));
  438. key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe));
  439. key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe));
  440. key->flags = 0;
  441. sprctl = I915_READ(SPRCTL(intel_plane->pipe));
  442. if (sprctl & SPRITE_DEST_KEY)
  443. key->flags = I915_SET_COLORKEY_DESTINATION;
  444. else if (sprctl & SPRITE_SOURCE_KEY)
  445. key->flags = I915_SET_COLORKEY_SOURCE;
  446. else
  447. key->flags = I915_SET_COLORKEY_NONE;
  448. }
  449. static void
  450. ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  451. struct drm_framebuffer *fb,
  452. struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
  453. unsigned int crtc_w, unsigned int crtc_h,
  454. uint32_t x, uint32_t y,
  455. uint32_t src_w, uint32_t src_h)
  456. {
  457. struct drm_device *dev = plane->dev;
  458. struct drm_i915_private *dev_priv = dev->dev_private;
  459. struct intel_plane *intel_plane = to_intel_plane(plane);
  460. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  461. int pipe = intel_plane->pipe;
  462. unsigned long dvssurf_offset, linear_offset;
  463. u32 dvscntr, dvsscale;
  464. int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  465. u32 start_vbl_count;
  466. bool atomic_update;
  467. dvscntr = I915_READ(DVSCNTR(pipe));
  468. /* Mask out pixel format bits in case we change it */
  469. dvscntr &= ~DVS_PIXFORMAT_MASK;
  470. dvscntr &= ~DVS_RGB_ORDER_XBGR;
  471. dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
  472. dvscntr &= ~DVS_TILED;
  473. switch (fb->pixel_format) {
  474. case DRM_FORMAT_XBGR8888:
  475. dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
  476. break;
  477. case DRM_FORMAT_XRGB8888:
  478. dvscntr |= DVS_FORMAT_RGBX888;
  479. break;
  480. case DRM_FORMAT_YUYV:
  481. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
  482. break;
  483. case DRM_FORMAT_YVYU:
  484. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
  485. break;
  486. case DRM_FORMAT_UYVY:
  487. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
  488. break;
  489. case DRM_FORMAT_VYUY:
  490. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
  491. break;
  492. default:
  493. BUG();
  494. }
  495. /*
  496. * Enable gamma to match primary/cursor plane behaviour.
  497. * FIXME should be user controllable via propertiesa.
  498. */
  499. dvscntr |= DVS_GAMMA_ENABLE;
  500. if (obj->tiling_mode != I915_TILING_NONE)
  501. dvscntr |= DVS_TILED;
  502. if (IS_GEN6(dev))
  503. dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
  504. dvscntr |= DVS_ENABLE;
  505. intel_update_sprite_watermarks(plane, crtc, src_w, src_h,
  506. pixel_size, true,
  507. src_w != crtc_w || src_h != crtc_h);
  508. /* Sizes are 0 based */
  509. src_w--;
  510. src_h--;
  511. crtc_w--;
  512. crtc_h--;
  513. dvsscale = 0;
  514. if (crtc_w != src_w || crtc_h != src_h)
  515. dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
  516. linear_offset = y * fb->pitches[0] + x * pixel_size;
  517. dvssurf_offset =
  518. intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
  519. pixel_size, fb->pitches[0]);
  520. linear_offset -= dvssurf_offset;
  521. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  522. intel_update_primary_plane(intel_crtc);
  523. I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
  524. I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
  525. if (obj->tiling_mode != I915_TILING_NONE)
  526. I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
  527. else
  528. I915_WRITE(DVSLINOFF(pipe), linear_offset);
  529. I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
  530. I915_WRITE(DVSSCALE(pipe), dvsscale);
  531. I915_WRITE(DVSCNTR(pipe), dvscntr);
  532. I915_WRITE(DVSSURF(pipe),
  533. i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
  534. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  535. if (atomic_update)
  536. intel_pipe_update_end(intel_crtc, start_vbl_count);
  537. }
  538. static void
  539. ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
  540. {
  541. struct drm_device *dev = plane->dev;
  542. struct drm_i915_private *dev_priv = dev->dev_private;
  543. struct intel_plane *intel_plane = to_intel_plane(plane);
  544. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  545. int pipe = intel_plane->pipe;
  546. u32 start_vbl_count;
  547. bool atomic_update;
  548. atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
  549. intel_update_primary_plane(intel_crtc);
  550. I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
  551. /* Disable the scaler */
  552. I915_WRITE(DVSSCALE(pipe), 0);
  553. /* Flush double buffered register updates */
  554. I915_WRITE(DVSSURF(pipe), 0);
  555. intel_flush_primary_plane(dev_priv, intel_crtc->plane);
  556. if (atomic_update)
  557. intel_pipe_update_end(intel_crtc, start_vbl_count);
  558. /*
  559. * Avoid underruns when disabling the sprite.
  560. * FIXME remove once watermark updates are done properly.
  561. */
  562. intel_wait_for_vblank(dev, pipe);
  563. intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
  564. }
  565. static void
  566. intel_post_enable_primary(struct drm_crtc *crtc)
  567. {
  568. struct drm_device *dev = crtc->dev;
  569. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  570. /*
  571. * BDW signals flip done immediately if the plane
  572. * is disabled, even if the plane enable is already
  573. * armed to occur at the next vblank :(
  574. */
  575. if (IS_BROADWELL(dev))
  576. intel_wait_for_vblank(dev, intel_crtc->pipe);
  577. /*
  578. * FIXME IPS should be fine as long as one plane is
  579. * enabled, but in practice it seems to have problems
  580. * when going from primary only to sprite only and vice
  581. * versa.
  582. */
  583. hsw_enable_ips(intel_crtc);
  584. mutex_lock(&dev->struct_mutex);
  585. intel_update_fbc(dev);
  586. mutex_unlock(&dev->struct_mutex);
  587. }
  588. static void
  589. intel_pre_disable_primary(struct drm_crtc *crtc)
  590. {
  591. struct drm_device *dev = crtc->dev;
  592. struct drm_i915_private *dev_priv = dev->dev_private;
  593. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  594. mutex_lock(&dev->struct_mutex);
  595. if (dev_priv->fbc.plane == intel_crtc->plane)
  596. intel_disable_fbc(dev);
  597. mutex_unlock(&dev->struct_mutex);
  598. /*
  599. * FIXME IPS should be fine as long as one plane is
  600. * enabled, but in practice it seems to have problems
  601. * when going from primary only to sprite only and vice
  602. * versa.
  603. */
  604. hsw_disable_ips(intel_crtc);
  605. }
  606. static int
  607. ilk_update_colorkey(struct drm_plane *plane,
  608. struct drm_intel_sprite_colorkey *key)
  609. {
  610. struct drm_device *dev = plane->dev;
  611. struct drm_i915_private *dev_priv = dev->dev_private;
  612. struct intel_plane *intel_plane;
  613. u32 dvscntr;
  614. int ret = 0;
  615. intel_plane = to_intel_plane(plane);
  616. I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value);
  617. I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value);
  618. I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask);
  619. dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
  620. dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY);
  621. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  622. dvscntr |= DVS_DEST_KEY;
  623. else if (key->flags & I915_SET_COLORKEY_SOURCE)
  624. dvscntr |= DVS_SOURCE_KEY;
  625. I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr);
  626. POSTING_READ(DVSKEYMSK(intel_plane->pipe));
  627. return ret;
  628. }
  629. static void
  630. ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
  631. {
  632. struct drm_device *dev = plane->dev;
  633. struct drm_i915_private *dev_priv = dev->dev_private;
  634. struct intel_plane *intel_plane;
  635. u32 dvscntr;
  636. intel_plane = to_intel_plane(plane);
  637. key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe));
  638. key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe));
  639. key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe));
  640. key->flags = 0;
  641. dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
  642. if (dvscntr & DVS_DEST_KEY)
  643. key->flags = I915_SET_COLORKEY_DESTINATION;
  644. else if (dvscntr & DVS_SOURCE_KEY)
  645. key->flags = I915_SET_COLORKEY_SOURCE;
  646. else
  647. key->flags = I915_SET_COLORKEY_NONE;
  648. }
  649. static bool
  650. format_is_yuv(uint32_t format)
  651. {
  652. switch (format) {
  653. case DRM_FORMAT_YUYV:
  654. case DRM_FORMAT_UYVY:
  655. case DRM_FORMAT_VYUY:
  656. case DRM_FORMAT_YVYU:
  657. return true;
  658. default:
  659. return false;
  660. }
  661. }
  662. static bool colorkey_enabled(struct intel_plane *intel_plane)
  663. {
  664. struct drm_intel_sprite_colorkey key;
  665. intel_plane->get_colorkey(&intel_plane->base, &key);
  666. return key.flags != I915_SET_COLORKEY_NONE;
  667. }
  668. static int
  669. intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
  670. struct drm_framebuffer *fb, int crtc_x, int crtc_y,
  671. unsigned int crtc_w, unsigned int crtc_h,
  672. uint32_t src_x, uint32_t src_y,
  673. uint32_t src_w, uint32_t src_h)
  674. {
  675. struct drm_device *dev = plane->dev;
  676. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  677. struct intel_plane *intel_plane = to_intel_plane(plane);
  678. enum pipe pipe = intel_crtc->pipe;
  679. struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
  680. struct drm_i915_gem_object *obj = intel_fb->obj;
  681. struct drm_i915_gem_object *old_obj = intel_plane->obj;
  682. int ret;
  683. bool primary_enabled;
  684. bool visible;
  685. int hscale, vscale;
  686. int max_scale, min_scale;
  687. int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  688. struct drm_rect src = {
  689. /* sample coordinates in 16.16 fixed point */
  690. .x1 = src_x,
  691. .x2 = src_x + src_w,
  692. .y1 = src_y,
  693. .y2 = src_y + src_h,
  694. };
  695. struct drm_rect dst = {
  696. /* integer pixels */
  697. .x1 = crtc_x,
  698. .x2 = crtc_x + crtc_w,
  699. .y1 = crtc_y,
  700. .y2 = crtc_y + crtc_h,
  701. };
  702. const struct drm_rect clip = {
  703. .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
  704. .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
  705. };
  706. const struct {
  707. int crtc_x, crtc_y;
  708. unsigned int crtc_w, crtc_h;
  709. uint32_t src_x, src_y, src_w, src_h;
  710. } orig = {
  711. .crtc_x = crtc_x,
  712. .crtc_y = crtc_y,
  713. .crtc_w = crtc_w,
  714. .crtc_h = crtc_h,
  715. .src_x = src_x,
  716. .src_y = src_y,
  717. .src_w = src_w,
  718. .src_h = src_h,
  719. };
  720. /* Don't modify another pipe's plane */
  721. if (intel_plane->pipe != intel_crtc->pipe) {
  722. DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
  723. return -EINVAL;
  724. }
  725. /* FIXME check all gen limits */
  726. if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
  727. DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
  728. return -EINVAL;
  729. }
  730. /* Sprite planes can be linear or x-tiled surfaces */
  731. switch (obj->tiling_mode) {
  732. case I915_TILING_NONE:
  733. case I915_TILING_X:
  734. break;
  735. default:
  736. DRM_DEBUG_KMS("Unsupported tiling mode\n");
  737. return -EINVAL;
  738. }
  739. /*
  740. * FIXME the following code does a bunch of fuzzy adjustments to the
  741. * coordinates and sizes. We probably need some way to decide whether
  742. * more strict checking should be done instead.
  743. */
  744. max_scale = intel_plane->max_downscale << 16;
  745. min_scale = intel_plane->can_scale ? 1 : (1 << 16);
  746. hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale);
  747. BUG_ON(hscale < 0);
  748. vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale);
  749. BUG_ON(vscale < 0);
  750. visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale);
  751. crtc_x = dst.x1;
  752. crtc_y = dst.y1;
  753. crtc_w = drm_rect_width(&dst);
  754. crtc_h = drm_rect_height(&dst);
  755. if (visible) {
  756. /* check again in case clipping clamped the results */
  757. hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale);
  758. if (hscale < 0) {
  759. DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
  760. drm_rect_debug_print(&src, true);
  761. drm_rect_debug_print(&dst, false);
  762. return hscale;
  763. }
  764. vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale);
  765. if (vscale < 0) {
  766. DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
  767. drm_rect_debug_print(&src, true);
  768. drm_rect_debug_print(&dst, false);
  769. return vscale;
  770. }
  771. /* Make the source viewport size an exact multiple of the scaling factors. */
  772. drm_rect_adjust_size(&src,
  773. drm_rect_width(&dst) * hscale - drm_rect_width(&src),
  774. drm_rect_height(&dst) * vscale - drm_rect_height(&src));
  775. /* sanity check to make sure the src viewport wasn't enlarged */
  776. WARN_ON(src.x1 < (int) src_x ||
  777. src.y1 < (int) src_y ||
  778. src.x2 > (int) (src_x + src_w) ||
  779. src.y2 > (int) (src_y + src_h));
  780. /*
  781. * Hardware doesn't handle subpixel coordinates.
  782. * Adjust to (macro)pixel boundary, but be careful not to
  783. * increase the source viewport size, because that could
  784. * push the downscaling factor out of bounds.
  785. */
  786. src_x = src.x1 >> 16;
  787. src_w = drm_rect_width(&src) >> 16;
  788. src_y = src.y1 >> 16;
  789. src_h = drm_rect_height(&src) >> 16;
  790. if (format_is_yuv(fb->pixel_format)) {
  791. src_x &= ~1;
  792. src_w &= ~1;
  793. /*
  794. * Must keep src and dst the
  795. * same if we can't scale.
  796. */
  797. if (!intel_plane->can_scale)
  798. crtc_w &= ~1;
  799. if (crtc_w == 0)
  800. visible = false;
  801. }
  802. }
  803. /* Check size restrictions when scaling */
  804. if (visible && (src_w != crtc_w || src_h != crtc_h)) {
  805. unsigned int width_bytes;
  806. WARN_ON(!intel_plane->can_scale);
  807. /* FIXME interlacing min height is 6 */
  808. if (crtc_w < 3 || crtc_h < 3)
  809. visible = false;
  810. if (src_w < 3 || src_h < 3)
  811. visible = false;
  812. width_bytes = ((src_x * pixel_size) & 63) + src_w * pixel_size;
  813. if (src_w > 2048 || src_h > 2048 ||
  814. width_bytes > 4096 || fb->pitches[0] > 4096) {
  815. DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
  816. return -EINVAL;
  817. }
  818. }
  819. dst.x1 = crtc_x;
  820. dst.x2 = crtc_x + crtc_w;
  821. dst.y1 = crtc_y;
  822. dst.y2 = crtc_y + crtc_h;
  823. /*
  824. * If the sprite is completely covering the primary plane,
  825. * we can disable the primary and save power.
  826. */
  827. primary_enabled = !drm_rect_equals(&dst, &clip) || colorkey_enabled(intel_plane);
  828. WARN_ON(!primary_enabled && !visible && intel_crtc->active);
  829. mutex_lock(&dev->struct_mutex);
  830. /* Note that this will apply the VT-d workaround for scanouts,
  831. * which is more restrictive than required for sprites. (The
  832. * primary plane requires 256KiB alignment with 64 PTE padding,
  833. * the sprite planes only require 128KiB alignment and 32 PTE padding.
  834. */
  835. ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
  836. i915_gem_track_fb(old_obj, obj,
  837. INTEL_FRONTBUFFER_SPRITE(pipe));
  838. mutex_unlock(&dev->struct_mutex);
  839. if (ret)
  840. return ret;
  841. intel_plane->crtc_x = orig.crtc_x;
  842. intel_plane->crtc_y = orig.crtc_y;
  843. intel_plane->crtc_w = orig.crtc_w;
  844. intel_plane->crtc_h = orig.crtc_h;
  845. intel_plane->src_x = orig.src_x;
  846. intel_plane->src_y = orig.src_y;
  847. intel_plane->src_w = orig.src_w;
  848. intel_plane->src_h = orig.src_h;
  849. intel_plane->obj = obj;
  850. if (intel_crtc->active) {
  851. bool primary_was_enabled = intel_crtc->primary_enabled;
  852. intel_crtc->primary_enabled = primary_enabled;
  853. if (primary_was_enabled != primary_enabled)
  854. intel_crtc_wait_for_pending_flips(crtc);
  855. if (primary_was_enabled && !primary_enabled)
  856. intel_pre_disable_primary(crtc);
  857. if (visible)
  858. intel_plane->update_plane(plane, crtc, fb, obj,
  859. crtc_x, crtc_y, crtc_w, crtc_h,
  860. src_x, src_y, src_w, src_h);
  861. else
  862. intel_plane->disable_plane(plane, crtc);
  863. intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe));
  864. if (!primary_was_enabled && primary_enabled)
  865. intel_post_enable_primary(crtc);
  866. }
  867. /* Unpin old obj after new one is active to avoid ugliness */
  868. if (old_obj) {
  869. /*
  870. * It's fairly common to simply update the position of
  871. * an existing object. In that case, we don't need to
  872. * wait for vblank to avoid ugliness, we only need to
  873. * do the pin & ref bookkeeping.
  874. */
  875. if (old_obj != obj && intel_crtc->active)
  876. intel_wait_for_vblank(dev, intel_crtc->pipe);
  877. mutex_lock(&dev->struct_mutex);
  878. intel_unpin_fb_obj(old_obj);
  879. mutex_unlock(&dev->struct_mutex);
  880. }
  881. return 0;
  882. }
  883. static int
  884. intel_disable_plane(struct drm_plane *plane)
  885. {
  886. struct drm_device *dev = plane->dev;
  887. struct intel_plane *intel_plane = to_intel_plane(plane);
  888. struct intel_crtc *intel_crtc;
  889. enum pipe pipe;
  890. if (!plane->fb)
  891. return 0;
  892. if (WARN_ON(!plane->crtc))
  893. return -EINVAL;
  894. intel_crtc = to_intel_crtc(plane->crtc);
  895. pipe = intel_crtc->pipe;
  896. if (intel_crtc->active) {
  897. bool primary_was_enabled = intel_crtc->primary_enabled;
  898. intel_crtc->primary_enabled = true;
  899. intel_plane->disable_plane(plane, plane->crtc);
  900. if (!primary_was_enabled && intel_crtc->primary_enabled)
  901. intel_post_enable_primary(plane->crtc);
  902. }
  903. if (intel_plane->obj) {
  904. if (intel_crtc->active)
  905. intel_wait_for_vblank(dev, intel_plane->pipe);
  906. mutex_lock(&dev->struct_mutex);
  907. intel_unpin_fb_obj(intel_plane->obj);
  908. i915_gem_track_fb(intel_plane->obj, NULL,
  909. INTEL_FRONTBUFFER_SPRITE(pipe));
  910. mutex_unlock(&dev->struct_mutex);
  911. intel_plane->obj = NULL;
  912. }
  913. return 0;
  914. }
  915. static void intel_destroy_plane(struct drm_plane *plane)
  916. {
  917. struct intel_plane *intel_plane = to_intel_plane(plane);
  918. intel_disable_plane(plane);
  919. drm_plane_cleanup(plane);
  920. kfree(intel_plane);
  921. }
  922. int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
  923. struct drm_file *file_priv)
  924. {
  925. struct drm_intel_sprite_colorkey *set = data;
  926. struct drm_plane *plane;
  927. struct intel_plane *intel_plane;
  928. int ret = 0;
  929. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  930. return -ENODEV;
  931. /* Make sure we don't try to enable both src & dest simultaneously */
  932. if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
  933. return -EINVAL;
  934. drm_modeset_lock_all(dev);
  935. plane = drm_plane_find(dev, set->plane_id);
  936. if (!plane) {
  937. ret = -ENOENT;
  938. goto out_unlock;
  939. }
  940. intel_plane = to_intel_plane(plane);
  941. ret = intel_plane->update_colorkey(plane, set);
  942. out_unlock:
  943. drm_modeset_unlock_all(dev);
  944. return ret;
  945. }
  946. int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
  947. struct drm_file *file_priv)
  948. {
  949. struct drm_intel_sprite_colorkey *get = data;
  950. struct drm_plane *plane;
  951. struct intel_plane *intel_plane;
  952. int ret = 0;
  953. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  954. return -ENODEV;
  955. drm_modeset_lock_all(dev);
  956. plane = drm_plane_find(dev, get->plane_id);
  957. if (!plane) {
  958. ret = -ENOENT;
  959. goto out_unlock;
  960. }
  961. intel_plane = to_intel_plane(plane);
  962. intel_plane->get_colorkey(plane, get);
  963. out_unlock:
  964. drm_modeset_unlock_all(dev);
  965. return ret;
  966. }
  967. void intel_plane_restore(struct drm_plane *plane)
  968. {
  969. struct intel_plane *intel_plane = to_intel_plane(plane);
  970. if (!plane->crtc || !plane->fb)
  971. return;
  972. intel_update_plane(plane, plane->crtc, plane->fb,
  973. intel_plane->crtc_x, intel_plane->crtc_y,
  974. intel_plane->crtc_w, intel_plane->crtc_h,
  975. intel_plane->src_x, intel_plane->src_y,
  976. intel_plane->src_w, intel_plane->src_h);
  977. }
  978. void intel_plane_disable(struct drm_plane *plane)
  979. {
  980. if (!plane->crtc || !plane->fb)
  981. return;
  982. intel_disable_plane(plane);
  983. }
  984. static const struct drm_plane_funcs intel_plane_funcs = {
  985. .update_plane = intel_update_plane,
  986. .disable_plane = intel_disable_plane,
  987. .destroy = intel_destroy_plane,
  988. };
  989. static uint32_t ilk_plane_formats[] = {
  990. DRM_FORMAT_XRGB8888,
  991. DRM_FORMAT_YUYV,
  992. DRM_FORMAT_YVYU,
  993. DRM_FORMAT_UYVY,
  994. DRM_FORMAT_VYUY,
  995. };
  996. static uint32_t snb_plane_formats[] = {
  997. DRM_FORMAT_XBGR8888,
  998. DRM_FORMAT_XRGB8888,
  999. DRM_FORMAT_YUYV,
  1000. DRM_FORMAT_YVYU,
  1001. DRM_FORMAT_UYVY,
  1002. DRM_FORMAT_VYUY,
  1003. };
  1004. static uint32_t vlv_plane_formats[] = {
  1005. DRM_FORMAT_RGB565,
  1006. DRM_FORMAT_ABGR8888,
  1007. DRM_FORMAT_ARGB8888,
  1008. DRM_FORMAT_XBGR8888,
  1009. DRM_FORMAT_XRGB8888,
  1010. DRM_FORMAT_XBGR2101010,
  1011. DRM_FORMAT_ABGR2101010,
  1012. DRM_FORMAT_YUYV,
  1013. DRM_FORMAT_YVYU,
  1014. DRM_FORMAT_UYVY,
  1015. DRM_FORMAT_VYUY,
  1016. };
  1017. int
  1018. intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
  1019. {
  1020. struct intel_plane *intel_plane;
  1021. unsigned long possible_crtcs;
  1022. const uint32_t *plane_formats;
  1023. int num_plane_formats;
  1024. int ret;
  1025. if (INTEL_INFO(dev)->gen < 5)
  1026. return -ENODEV;
  1027. intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
  1028. if (!intel_plane)
  1029. return -ENOMEM;
  1030. switch (INTEL_INFO(dev)->gen) {
  1031. case 5:
  1032. case 6:
  1033. intel_plane->can_scale = true;
  1034. intel_plane->max_downscale = 16;
  1035. intel_plane->update_plane = ilk_update_plane;
  1036. intel_plane->disable_plane = ilk_disable_plane;
  1037. intel_plane->update_colorkey = ilk_update_colorkey;
  1038. intel_plane->get_colorkey = ilk_get_colorkey;
  1039. if (IS_GEN6(dev)) {
  1040. plane_formats = snb_plane_formats;
  1041. num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1042. } else {
  1043. plane_formats = ilk_plane_formats;
  1044. num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
  1045. }
  1046. break;
  1047. case 7:
  1048. case 8:
  1049. if (IS_IVYBRIDGE(dev)) {
  1050. intel_plane->can_scale = true;
  1051. intel_plane->max_downscale = 2;
  1052. } else {
  1053. intel_plane->can_scale = false;
  1054. intel_plane->max_downscale = 1;
  1055. }
  1056. if (IS_VALLEYVIEW(dev)) {
  1057. intel_plane->update_plane = vlv_update_plane;
  1058. intel_plane->disable_plane = vlv_disable_plane;
  1059. intel_plane->update_colorkey = vlv_update_colorkey;
  1060. intel_plane->get_colorkey = vlv_get_colorkey;
  1061. plane_formats = vlv_plane_formats;
  1062. num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
  1063. } else {
  1064. intel_plane->update_plane = ivb_update_plane;
  1065. intel_plane->disable_plane = ivb_disable_plane;
  1066. intel_plane->update_colorkey = ivb_update_colorkey;
  1067. intel_plane->get_colorkey = ivb_get_colorkey;
  1068. plane_formats = snb_plane_formats;
  1069. num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1070. }
  1071. break;
  1072. default:
  1073. kfree(intel_plane);
  1074. return -ENODEV;
  1075. }
  1076. intel_plane->pipe = pipe;
  1077. intel_plane->plane = plane;
  1078. possible_crtcs = (1 << pipe);
  1079. ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
  1080. &intel_plane_funcs,
  1081. plane_formats, num_plane_formats,
  1082. false);
  1083. if (ret)
  1084. kfree(intel_plane);
  1085. return ret;
  1086. }