intel_sprite.c 37 KB

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