intel_sprite.c 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615
  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->base.crtc);
  916. struct intel_plane *intel_plane = to_intel_plane(plane);
  917. struct drm_framebuffer *fb = state->base.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;
  929. if (!fb) {
  930. state->visible = false;
  931. return 0;
  932. }
  933. /* Don't modify another pipe's plane */
  934. if (intel_plane->pipe != intel_crtc->pipe) {
  935. DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
  936. return -EINVAL;
  937. }
  938. /* FIXME check all gen limits */
  939. if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
  940. DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
  941. return -EINVAL;
  942. }
  943. /* Sprite planes can be linear or x-tiled surfaces */
  944. switch (obj->tiling_mode) {
  945. case I915_TILING_NONE:
  946. case I915_TILING_X:
  947. break;
  948. default:
  949. DRM_DEBUG_KMS("Unsupported tiling mode\n");
  950. return -EINVAL;
  951. }
  952. /*
  953. * FIXME the following code does a bunch of fuzzy adjustments to the
  954. * coordinates and sizes. We probably need some way to decide whether
  955. * more strict checking should be done instead.
  956. */
  957. max_scale = intel_plane->max_downscale << 16;
  958. min_scale = intel_plane->can_scale ? 1 : (1 << 16);
  959. drm_rect_rotate(src, fb->width << 16, fb->height << 16,
  960. intel_plane->rotation);
  961. hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
  962. BUG_ON(hscale < 0);
  963. vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
  964. BUG_ON(vscale < 0);
  965. state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
  966. crtc_x = dst->x1;
  967. crtc_y = dst->y1;
  968. crtc_w = drm_rect_width(dst);
  969. crtc_h = drm_rect_height(dst);
  970. if (state->visible) {
  971. /* check again in case clipping clamped the results */
  972. hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
  973. if (hscale < 0) {
  974. DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
  975. drm_rect_debug_print(src, true);
  976. drm_rect_debug_print(dst, false);
  977. return hscale;
  978. }
  979. vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
  980. if (vscale < 0) {
  981. DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
  982. drm_rect_debug_print(src, true);
  983. drm_rect_debug_print(dst, false);
  984. return vscale;
  985. }
  986. /* Make the source viewport size an exact multiple of the scaling factors. */
  987. drm_rect_adjust_size(src,
  988. drm_rect_width(dst) * hscale - drm_rect_width(src),
  989. drm_rect_height(dst) * vscale - drm_rect_height(src));
  990. drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
  991. intel_plane->rotation);
  992. /* sanity check to make sure the src viewport wasn't enlarged */
  993. WARN_ON(src->x1 < (int) orig_src->x1 ||
  994. src->y1 < (int) orig_src->y1 ||
  995. src->x2 > (int) orig_src->x2 ||
  996. src->y2 > (int) orig_src->y2);
  997. /*
  998. * Hardware doesn't handle subpixel coordinates.
  999. * Adjust to (macro)pixel boundary, but be careful not to
  1000. * increase the source viewport size, because that could
  1001. * push the downscaling factor out of bounds.
  1002. */
  1003. src_x = src->x1 >> 16;
  1004. src_w = drm_rect_width(src) >> 16;
  1005. src_y = src->y1 >> 16;
  1006. src_h = drm_rect_height(src) >> 16;
  1007. if (format_is_yuv(fb->pixel_format)) {
  1008. src_x &= ~1;
  1009. src_w &= ~1;
  1010. /*
  1011. * Must keep src and dst the
  1012. * same if we can't scale.
  1013. */
  1014. if (!intel_plane->can_scale)
  1015. crtc_w &= ~1;
  1016. if (crtc_w == 0)
  1017. state->visible = false;
  1018. }
  1019. }
  1020. /* Check size restrictions when scaling */
  1021. if (state->visible && (src_w != crtc_w || src_h != crtc_h)) {
  1022. unsigned int width_bytes;
  1023. WARN_ON(!intel_plane->can_scale);
  1024. /* FIXME interlacing min height is 6 */
  1025. if (crtc_w < 3 || crtc_h < 3)
  1026. state->visible = false;
  1027. if (src_w < 3 || src_h < 3)
  1028. state->visible = false;
  1029. pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
  1030. width_bytes = ((src_x * pixel_size) & 63) +
  1031. src_w * pixel_size;
  1032. if (src_w > 2048 || src_h > 2048 ||
  1033. width_bytes > 4096 || fb->pitches[0] > 4096) {
  1034. DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
  1035. return -EINVAL;
  1036. }
  1037. }
  1038. if (state->visible) {
  1039. src->x1 = src_x;
  1040. src->x2 = src_x + src_w;
  1041. src->y1 = src_y;
  1042. src->y2 = src_y + src_h;
  1043. }
  1044. dst->x1 = crtc_x;
  1045. dst->x2 = crtc_x + crtc_w;
  1046. dst->y1 = crtc_y;
  1047. dst->y2 = crtc_y + crtc_h;
  1048. return 0;
  1049. }
  1050. static void
  1051. intel_commit_sprite_plane(struct drm_plane *plane,
  1052. struct intel_plane_state *state)
  1053. {
  1054. struct drm_device *dev = plane->dev;
  1055. struct drm_crtc *crtc = state->base.crtc;
  1056. struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  1057. struct intel_plane *intel_plane = to_intel_plane(plane);
  1058. enum pipe pipe = intel_crtc->pipe;
  1059. struct drm_framebuffer *fb = state->base.fb;
  1060. struct drm_i915_gem_object *obj = intel_fb_obj(fb);
  1061. int crtc_x, crtc_y;
  1062. unsigned int crtc_w, crtc_h;
  1063. uint32_t src_x, src_y, src_w, src_h;
  1064. struct drm_rect *dst = &state->dst;
  1065. const struct drm_rect *clip = &state->clip;
  1066. bool primary_enabled;
  1067. /*
  1068. * 'prepare' is never called when plane is being disabled, so we need
  1069. * to handle frontbuffer tracking here
  1070. */
  1071. if (!fb) {
  1072. mutex_lock(&dev->struct_mutex);
  1073. i915_gem_track_fb(intel_fb_obj(plane->fb), NULL,
  1074. INTEL_FRONTBUFFER_SPRITE(pipe));
  1075. mutex_unlock(&dev->struct_mutex);
  1076. }
  1077. /*
  1078. * If the sprite is completely covering the primary plane,
  1079. * we can disable the primary and save power.
  1080. */
  1081. primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane);
  1082. WARN_ON(!primary_enabled && !state->visible && intel_crtc->active);
  1083. intel_plane->crtc_x = state->orig_dst.x1;
  1084. intel_plane->crtc_y = state->orig_dst.y1;
  1085. intel_plane->crtc_w = drm_rect_width(&state->orig_dst);
  1086. intel_plane->crtc_h = drm_rect_height(&state->orig_dst);
  1087. intel_plane->src_x = state->orig_src.x1;
  1088. intel_plane->src_y = state->orig_src.y1;
  1089. intel_plane->src_w = drm_rect_width(&state->orig_src);
  1090. intel_plane->src_h = drm_rect_height(&state->orig_src);
  1091. intel_plane->obj = obj;
  1092. if (intel_crtc->active) {
  1093. bool primary_was_enabled = intel_crtc->primary_enabled;
  1094. intel_crtc->primary_enabled = primary_enabled;
  1095. if (primary_was_enabled != primary_enabled)
  1096. intel_crtc_wait_for_pending_flips(crtc);
  1097. if (primary_was_enabled && !primary_enabled)
  1098. intel_pre_disable_primary(crtc);
  1099. if (state->visible) {
  1100. crtc_x = state->dst.x1;
  1101. crtc_y = state->dst.y1;
  1102. crtc_w = drm_rect_width(&state->dst);
  1103. crtc_h = drm_rect_height(&state->dst);
  1104. src_x = state->src.x1;
  1105. src_y = state->src.y1;
  1106. src_w = drm_rect_width(&state->src);
  1107. src_h = drm_rect_height(&state->src);
  1108. intel_plane->update_plane(plane, crtc, fb, obj,
  1109. crtc_x, crtc_y, crtc_w, crtc_h,
  1110. src_x, src_y, src_w, src_h);
  1111. } else {
  1112. intel_plane->disable_plane(plane, crtc);
  1113. }
  1114. intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe));
  1115. if (!primary_was_enabled && primary_enabled)
  1116. intel_post_enable_primary(crtc);
  1117. }
  1118. }
  1119. static void intel_destroy_plane(struct drm_plane *plane)
  1120. {
  1121. struct intel_plane *intel_plane = to_intel_plane(plane);
  1122. intel_disable_plane(plane);
  1123. drm_plane_cleanup(plane);
  1124. kfree(intel_plane);
  1125. }
  1126. int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
  1127. struct drm_file *file_priv)
  1128. {
  1129. struct drm_intel_sprite_colorkey *set = data;
  1130. struct drm_plane *plane;
  1131. struct intel_plane *intel_plane;
  1132. int ret = 0;
  1133. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1134. return -ENODEV;
  1135. /* Make sure we don't try to enable both src & dest simultaneously */
  1136. if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
  1137. return -EINVAL;
  1138. drm_modeset_lock_all(dev);
  1139. plane = drm_plane_find(dev, set->plane_id);
  1140. if (!plane) {
  1141. ret = -ENOENT;
  1142. goto out_unlock;
  1143. }
  1144. intel_plane = to_intel_plane(plane);
  1145. ret = intel_plane->update_colorkey(plane, set);
  1146. out_unlock:
  1147. drm_modeset_unlock_all(dev);
  1148. return ret;
  1149. }
  1150. int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
  1151. struct drm_file *file_priv)
  1152. {
  1153. struct drm_intel_sprite_colorkey *get = data;
  1154. struct drm_plane *plane;
  1155. struct intel_plane *intel_plane;
  1156. int ret = 0;
  1157. if (!drm_core_check_feature(dev, DRIVER_MODESET))
  1158. return -ENODEV;
  1159. drm_modeset_lock_all(dev);
  1160. plane = drm_plane_find(dev, get->plane_id);
  1161. if (!plane) {
  1162. ret = -ENOENT;
  1163. goto out_unlock;
  1164. }
  1165. intel_plane = to_intel_plane(plane);
  1166. intel_plane->get_colorkey(plane, get);
  1167. out_unlock:
  1168. drm_modeset_unlock_all(dev);
  1169. return ret;
  1170. }
  1171. int intel_plane_set_property(struct drm_plane *plane,
  1172. struct drm_property *prop,
  1173. uint64_t val)
  1174. {
  1175. struct drm_device *dev = plane->dev;
  1176. struct intel_plane *intel_plane = to_intel_plane(plane);
  1177. uint64_t old_val;
  1178. int ret = -ENOENT;
  1179. if (prop == dev->mode_config.rotation_property) {
  1180. /* exactly one rotation angle please */
  1181. if (hweight32(val & 0xf) != 1)
  1182. return -EINVAL;
  1183. if (intel_plane->rotation == val)
  1184. return 0;
  1185. old_val = intel_plane->rotation;
  1186. intel_plane->rotation = val;
  1187. ret = intel_plane_restore(plane);
  1188. if (ret)
  1189. intel_plane->rotation = old_val;
  1190. }
  1191. return ret;
  1192. }
  1193. int intel_plane_restore(struct drm_plane *plane)
  1194. {
  1195. struct intel_plane *intel_plane = to_intel_plane(plane);
  1196. if (!plane->crtc || !plane->fb)
  1197. return 0;
  1198. return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
  1199. intel_plane->crtc_x, intel_plane->crtc_y,
  1200. intel_plane->crtc_w, intel_plane->crtc_h,
  1201. intel_plane->src_x, intel_plane->src_y,
  1202. intel_plane->src_w, intel_plane->src_h);
  1203. }
  1204. static const struct drm_plane_funcs intel_plane_funcs = {
  1205. .update_plane = intel_update_plane,
  1206. .disable_plane = intel_disable_plane,
  1207. .destroy = intel_destroy_plane,
  1208. .set_property = intel_plane_set_property,
  1209. };
  1210. static uint32_t ilk_plane_formats[] = {
  1211. DRM_FORMAT_XRGB8888,
  1212. DRM_FORMAT_YUYV,
  1213. DRM_FORMAT_YVYU,
  1214. DRM_FORMAT_UYVY,
  1215. DRM_FORMAT_VYUY,
  1216. };
  1217. static uint32_t snb_plane_formats[] = {
  1218. DRM_FORMAT_XBGR8888,
  1219. DRM_FORMAT_XRGB8888,
  1220. DRM_FORMAT_YUYV,
  1221. DRM_FORMAT_YVYU,
  1222. DRM_FORMAT_UYVY,
  1223. DRM_FORMAT_VYUY,
  1224. };
  1225. static uint32_t vlv_plane_formats[] = {
  1226. DRM_FORMAT_RGB565,
  1227. DRM_FORMAT_ABGR8888,
  1228. DRM_FORMAT_ARGB8888,
  1229. DRM_FORMAT_XBGR8888,
  1230. DRM_FORMAT_XRGB8888,
  1231. DRM_FORMAT_XBGR2101010,
  1232. DRM_FORMAT_ABGR2101010,
  1233. DRM_FORMAT_YUYV,
  1234. DRM_FORMAT_YVYU,
  1235. DRM_FORMAT_UYVY,
  1236. DRM_FORMAT_VYUY,
  1237. };
  1238. static uint32_t skl_plane_formats[] = {
  1239. DRM_FORMAT_RGB565,
  1240. DRM_FORMAT_ABGR8888,
  1241. DRM_FORMAT_ARGB8888,
  1242. DRM_FORMAT_XBGR8888,
  1243. DRM_FORMAT_XRGB8888,
  1244. DRM_FORMAT_YUYV,
  1245. DRM_FORMAT_YVYU,
  1246. DRM_FORMAT_UYVY,
  1247. DRM_FORMAT_VYUY,
  1248. };
  1249. int
  1250. intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
  1251. {
  1252. struct intel_plane *intel_plane;
  1253. unsigned long possible_crtcs;
  1254. const uint32_t *plane_formats;
  1255. int num_plane_formats;
  1256. int ret;
  1257. if (INTEL_INFO(dev)->gen < 5)
  1258. return -ENODEV;
  1259. intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
  1260. if (!intel_plane)
  1261. return -ENOMEM;
  1262. switch (INTEL_INFO(dev)->gen) {
  1263. case 5:
  1264. case 6:
  1265. intel_plane->can_scale = true;
  1266. intel_plane->max_downscale = 16;
  1267. intel_plane->update_plane = ilk_update_plane;
  1268. intel_plane->disable_plane = ilk_disable_plane;
  1269. intel_plane->update_colorkey = ilk_update_colorkey;
  1270. intel_plane->get_colorkey = ilk_get_colorkey;
  1271. if (IS_GEN6(dev)) {
  1272. plane_formats = snb_plane_formats;
  1273. num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1274. } else {
  1275. plane_formats = ilk_plane_formats;
  1276. num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
  1277. }
  1278. break;
  1279. case 7:
  1280. case 8:
  1281. if (IS_IVYBRIDGE(dev)) {
  1282. intel_plane->can_scale = true;
  1283. intel_plane->max_downscale = 2;
  1284. } else {
  1285. intel_plane->can_scale = false;
  1286. intel_plane->max_downscale = 1;
  1287. }
  1288. if (IS_VALLEYVIEW(dev)) {
  1289. intel_plane->update_plane = vlv_update_plane;
  1290. intel_plane->disable_plane = vlv_disable_plane;
  1291. intel_plane->update_colorkey = vlv_update_colorkey;
  1292. intel_plane->get_colorkey = vlv_get_colorkey;
  1293. plane_formats = vlv_plane_formats;
  1294. num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
  1295. } else {
  1296. intel_plane->update_plane = ivb_update_plane;
  1297. intel_plane->disable_plane = ivb_disable_plane;
  1298. intel_plane->update_colorkey = ivb_update_colorkey;
  1299. intel_plane->get_colorkey = ivb_get_colorkey;
  1300. plane_formats = snb_plane_formats;
  1301. num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1302. }
  1303. break;
  1304. case 9:
  1305. /*
  1306. * FIXME: Skylake planes can be scaled (with some restrictions),
  1307. * but this is for another time.
  1308. */
  1309. intel_plane->can_scale = false;
  1310. intel_plane->max_downscale = 1;
  1311. intel_plane->update_plane = skl_update_plane;
  1312. intel_plane->disable_plane = skl_disable_plane;
  1313. intel_plane->update_colorkey = skl_update_colorkey;
  1314. intel_plane->get_colorkey = skl_get_colorkey;
  1315. plane_formats = skl_plane_formats;
  1316. num_plane_formats = ARRAY_SIZE(skl_plane_formats);
  1317. break;
  1318. default:
  1319. kfree(intel_plane);
  1320. return -ENODEV;
  1321. }
  1322. intel_plane->pipe = pipe;
  1323. intel_plane->plane = plane;
  1324. intel_plane->rotation = BIT(DRM_ROTATE_0);
  1325. intel_plane->check_plane = intel_check_sprite_plane;
  1326. intel_plane->commit_plane = intel_commit_sprite_plane;
  1327. possible_crtcs = (1 << pipe);
  1328. ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
  1329. &intel_plane_funcs,
  1330. plane_formats, num_plane_formats,
  1331. DRM_PLANE_TYPE_OVERLAY);
  1332. if (ret) {
  1333. kfree(intel_plane);
  1334. goto out;
  1335. }
  1336. if (!dev->mode_config.rotation_property)
  1337. dev->mode_config.rotation_property =
  1338. drm_mode_create_rotation_property(dev,
  1339. BIT(DRM_ROTATE_0) |
  1340. BIT(DRM_ROTATE_180));
  1341. if (dev->mode_config.rotation_property)
  1342. drm_object_attach_property(&intel_plane->base.base,
  1343. dev->mode_config.rotation_property,
  1344. intel_plane->rotation);
  1345. out:
  1346. return ret;
  1347. }