intel_sprite.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341
  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_atomic_helper.h>
  34. #include <drm/drm_crtc.h>
  35. #include <drm/drm_fourcc.h>
  36. #include <drm/drm_rect.h>
  37. #include <drm/drm_atomic.h>
  38. #include <drm/drm_plane_helper.h>
  39. #include "intel_drv.h"
  40. #include "intel_frontbuffer.h"
  41. #include <drm/i915_drm.h>
  42. #include "i915_drv.h"
  43. static bool
  44. format_is_yuv(uint32_t format)
  45. {
  46. switch (format) {
  47. case DRM_FORMAT_YUYV:
  48. case DRM_FORMAT_UYVY:
  49. case DRM_FORMAT_VYUY:
  50. case DRM_FORMAT_YVYU:
  51. return true;
  52. default:
  53. return false;
  54. }
  55. }
  56. int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
  57. int usecs)
  58. {
  59. /* paranoia */
  60. if (!adjusted_mode->crtc_htotal)
  61. return 1;
  62. return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
  63. 1000 * adjusted_mode->crtc_htotal);
  64. }
  65. /* FIXME: We should instead only take spinlocks once for the entire update
  66. * instead of once per mmio. */
  67. #if IS_ENABLED(CONFIG_PROVE_LOCKING)
  68. #define VBLANK_EVASION_TIME_US 250
  69. #else
  70. #define VBLANK_EVASION_TIME_US 100
  71. #endif
  72. /**
  73. * intel_pipe_update_start() - start update of a set of display registers
  74. * @new_crtc_state: the new crtc state
  75. *
  76. * Mark the start of an update to pipe registers that should be updated
  77. * atomically regarding vblank. If the next vblank will happens within
  78. * the next 100 us, this function waits until the vblank passes.
  79. *
  80. * After a successful call to this function, interrupts will be disabled
  81. * until a subsequent call to intel_pipe_update_end(). That is done to
  82. * avoid random delays.
  83. */
  84. void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
  85. {
  86. struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
  87. struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
  88. const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
  89. long timeout = msecs_to_jiffies_timeout(1);
  90. int scanline, min, max, vblank_start;
  91. wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
  92. bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
  93. intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
  94. DEFINE_WAIT(wait);
  95. vblank_start = adjusted_mode->crtc_vblank_start;
  96. if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
  97. vblank_start = DIV_ROUND_UP(vblank_start, 2);
  98. /* FIXME needs to be calibrated sensibly */
  99. min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
  100. VBLANK_EVASION_TIME_US);
  101. max = vblank_start - 1;
  102. local_irq_disable();
  103. if (min <= 0 || max <= 0)
  104. return;
  105. if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
  106. return;
  107. crtc->debug.min_vbl = min;
  108. crtc->debug.max_vbl = max;
  109. trace_i915_pipe_update_start(crtc);
  110. for (;;) {
  111. /*
  112. * prepare_to_wait() has a memory barrier, which guarantees
  113. * other CPUs can see the task state update by the time we
  114. * read the scanline.
  115. */
  116. prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
  117. scanline = intel_get_crtc_scanline(crtc);
  118. if (scanline < min || scanline > max)
  119. break;
  120. if (timeout <= 0) {
  121. DRM_ERROR("Potential atomic update failure on pipe %c\n",
  122. pipe_name(crtc->pipe));
  123. break;
  124. }
  125. local_irq_enable();
  126. timeout = schedule_timeout(timeout);
  127. local_irq_disable();
  128. }
  129. finish_wait(wq, &wait);
  130. drm_crtc_vblank_put(&crtc->base);
  131. /*
  132. * On VLV/CHV DSI the scanline counter would appear to
  133. * increment approx. 1/3 of a scanline before start of vblank.
  134. * The registers still get latched at start of vblank however.
  135. * This means we must not write any registers on the first
  136. * line of vblank (since not the whole line is actually in
  137. * vblank). And unfortunately we can't use the interrupt to
  138. * wait here since it will fire too soon. We could use the
  139. * frame start interrupt instead since it will fire after the
  140. * critical scanline, but that would require more changes
  141. * in the interrupt code. So for now we'll just do the nasty
  142. * thing and poll for the bad scanline to pass us by.
  143. *
  144. * FIXME figure out if BXT+ DSI suffers from this as well
  145. */
  146. while (need_vlv_dsi_wa && scanline == vblank_start)
  147. scanline = intel_get_crtc_scanline(crtc);
  148. crtc->debug.scanline_start = scanline;
  149. crtc->debug.start_vbl_time = ktime_get();
  150. crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
  151. trace_i915_pipe_update_vblank_evaded(crtc);
  152. }
  153. /**
  154. * intel_pipe_update_end() - end update of a set of display registers
  155. * @new_crtc_state: the new crtc state
  156. *
  157. * Mark the end of an update started with intel_pipe_update_start(). This
  158. * re-enables interrupts and verifies the update was actually completed
  159. * before a vblank.
  160. */
  161. void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
  162. {
  163. struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
  164. enum pipe pipe = crtc->pipe;
  165. int scanline_end = intel_get_crtc_scanline(crtc);
  166. u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
  167. ktime_t end_vbl_time = ktime_get();
  168. struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
  169. trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
  170. /* We're still in the vblank-evade critical section, this can't race.
  171. * Would be slightly nice to just grab the vblank count and arm the
  172. * event outside of the critical section - the spinlock might spin for a
  173. * while ... */
  174. if (new_crtc_state->base.event) {
  175. WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
  176. spin_lock(&crtc->base.dev->event_lock);
  177. drm_crtc_arm_vblank_event(&crtc->base, new_crtc_state->base.event);
  178. spin_unlock(&crtc->base.dev->event_lock);
  179. new_crtc_state->base.event = NULL;
  180. }
  181. local_irq_enable();
  182. if (intel_vgpu_active(dev_priv))
  183. return;
  184. if (crtc->debug.start_vbl_count &&
  185. crtc->debug.start_vbl_count != end_vbl_count) {
  186. DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n",
  187. pipe_name(pipe), crtc->debug.start_vbl_count,
  188. end_vbl_count,
  189. ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
  190. crtc->debug.min_vbl, crtc->debug.max_vbl,
  191. crtc->debug.scanline_start, scanline_end);
  192. }
  193. #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
  194. else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) >
  195. VBLANK_EVASION_TIME_US)
  196. DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
  197. pipe_name(pipe),
  198. ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
  199. VBLANK_EVASION_TIME_US);
  200. #endif
  201. }
  202. void
  203. skl_update_plane(struct intel_plane *plane,
  204. const struct intel_crtc_state *crtc_state,
  205. const struct intel_plane_state *plane_state)
  206. {
  207. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  208. const struct drm_framebuffer *fb = plane_state->base.fb;
  209. enum plane_id plane_id = plane->id;
  210. enum pipe pipe = plane->pipe;
  211. u32 plane_ctl = plane_state->ctl;
  212. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  213. u32 surf_addr = plane_state->main.offset;
  214. unsigned int rotation = plane_state->base.rotation;
  215. u32 stride = skl_plane_stride(fb, 0, rotation);
  216. u32 aux_stride = skl_plane_stride(fb, 1, rotation);
  217. int crtc_x = plane_state->base.dst.x1;
  218. int crtc_y = plane_state->base.dst.y1;
  219. uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
  220. uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
  221. uint32_t x = plane_state->main.x;
  222. uint32_t y = plane_state->main.y;
  223. uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
  224. uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
  225. unsigned long irqflags;
  226. /* Sizes are 0 based */
  227. src_w--;
  228. src_h--;
  229. crtc_w--;
  230. crtc_h--;
  231. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  232. if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
  233. I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
  234. plane_state->color_ctl);
  235. if (key->flags) {
  236. I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
  237. I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value);
  238. I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), key->channel_mask);
  239. }
  240. I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
  241. I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
  242. I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
  243. I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
  244. (plane_state->aux.offset - surf_addr) | aux_stride);
  245. I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
  246. (plane_state->aux.y << 16) | plane_state->aux.x);
  247. /* program plane scaler */
  248. if (plane_state->scaler_id >= 0) {
  249. int scaler_id = plane_state->scaler_id;
  250. const struct intel_scaler *scaler;
  251. scaler = &crtc_state->scaler_state.scalers[scaler_id];
  252. I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
  253. PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
  254. I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
  255. I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
  256. I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
  257. ((crtc_w + 1) << 16)|(crtc_h + 1));
  258. I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
  259. } else {
  260. I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
  261. }
  262. I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
  263. I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
  264. intel_plane_ggtt_offset(plane_state) + surf_addr);
  265. POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
  266. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  267. }
  268. void
  269. skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
  270. {
  271. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  272. enum plane_id plane_id = plane->id;
  273. enum pipe pipe = plane->pipe;
  274. unsigned long irqflags;
  275. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  276. I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
  277. I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
  278. POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
  279. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  280. }
  281. static void
  282. chv_update_csc(struct intel_plane *plane, uint32_t format)
  283. {
  284. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  285. enum plane_id plane_id = plane->id;
  286. /* Seems RGB data bypasses the CSC always */
  287. if (!format_is_yuv(format))
  288. return;
  289. /*
  290. * BT.601 limited range YCbCr -> full range RGB
  291. *
  292. * |r| | 6537 4769 0| |cr |
  293. * |g| = |-3330 4769 -1605| x |y-64|
  294. * |b| | 0 4769 8263| |cb |
  295. *
  296. * Cb and Cr apparently come in as signed already, so no
  297. * need for any offset. For Y we need to remove the offset.
  298. */
  299. I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(-64));
  300. I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
  301. I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
  302. I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(4769) | SPCSC_C0(6537));
  303. I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(-3330) | SPCSC_C0(0));
  304. I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(-1605) | SPCSC_C0(4769));
  305. I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(4769) | SPCSC_C0(0));
  306. I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(8263));
  307. I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(940) | SPCSC_IMIN(64));
  308. I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
  309. I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
  310. I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  311. I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  312. I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  313. }
  314. static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
  315. const struct intel_plane_state *plane_state)
  316. {
  317. const struct drm_framebuffer *fb = plane_state->base.fb;
  318. unsigned int rotation = plane_state->base.rotation;
  319. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  320. u32 sprctl;
  321. sprctl = SP_ENABLE | SP_GAMMA_ENABLE;
  322. switch (fb->format->format) {
  323. case DRM_FORMAT_YUYV:
  324. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
  325. break;
  326. case DRM_FORMAT_YVYU:
  327. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
  328. break;
  329. case DRM_FORMAT_UYVY:
  330. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
  331. break;
  332. case DRM_FORMAT_VYUY:
  333. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
  334. break;
  335. case DRM_FORMAT_RGB565:
  336. sprctl |= SP_FORMAT_BGR565;
  337. break;
  338. case DRM_FORMAT_XRGB8888:
  339. sprctl |= SP_FORMAT_BGRX8888;
  340. break;
  341. case DRM_FORMAT_ARGB8888:
  342. sprctl |= SP_FORMAT_BGRA8888;
  343. break;
  344. case DRM_FORMAT_XBGR2101010:
  345. sprctl |= SP_FORMAT_RGBX1010102;
  346. break;
  347. case DRM_FORMAT_ABGR2101010:
  348. sprctl |= SP_FORMAT_RGBA1010102;
  349. break;
  350. case DRM_FORMAT_XBGR8888:
  351. sprctl |= SP_FORMAT_RGBX8888;
  352. break;
  353. case DRM_FORMAT_ABGR8888:
  354. sprctl |= SP_FORMAT_RGBA8888;
  355. break;
  356. default:
  357. MISSING_CASE(fb->format->format);
  358. return 0;
  359. }
  360. if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  361. sprctl |= SP_TILED;
  362. if (rotation & DRM_MODE_ROTATE_180)
  363. sprctl |= SP_ROTATE_180;
  364. if (rotation & DRM_MODE_REFLECT_X)
  365. sprctl |= SP_MIRROR;
  366. if (key->flags & I915_SET_COLORKEY_SOURCE)
  367. sprctl |= SP_SOURCE_KEY;
  368. return sprctl;
  369. }
  370. static void
  371. vlv_update_plane(struct intel_plane *plane,
  372. const struct intel_crtc_state *crtc_state,
  373. const struct intel_plane_state *plane_state)
  374. {
  375. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  376. const struct drm_framebuffer *fb = plane_state->base.fb;
  377. enum pipe pipe = plane->pipe;
  378. enum plane_id plane_id = plane->id;
  379. u32 sprctl = plane_state->ctl;
  380. u32 sprsurf_offset = plane_state->main.offset;
  381. u32 linear_offset;
  382. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  383. int crtc_x = plane_state->base.dst.x1;
  384. int crtc_y = plane_state->base.dst.y1;
  385. uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
  386. uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
  387. uint32_t x = plane_state->main.x;
  388. uint32_t y = plane_state->main.y;
  389. unsigned long irqflags;
  390. /* Sizes are 0 based */
  391. crtc_w--;
  392. crtc_h--;
  393. linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
  394. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  395. if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
  396. chv_update_csc(plane, fb->format->format);
  397. if (key->flags) {
  398. I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
  399. I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
  400. I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
  401. }
  402. I915_WRITE_FW(SPSTRIDE(pipe, plane_id), fb->pitches[0]);
  403. I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
  404. if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  405. I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
  406. else
  407. I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
  408. I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
  409. I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
  410. I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
  411. I915_WRITE_FW(SPSURF(pipe, plane_id),
  412. intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
  413. POSTING_READ_FW(SPSURF(pipe, plane_id));
  414. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  415. }
  416. static void
  417. vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
  418. {
  419. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  420. enum pipe pipe = plane->pipe;
  421. enum plane_id plane_id = plane->id;
  422. unsigned long irqflags;
  423. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  424. I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
  425. I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
  426. POSTING_READ_FW(SPSURF(pipe, plane_id));
  427. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  428. }
  429. static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
  430. const struct intel_plane_state *plane_state)
  431. {
  432. struct drm_i915_private *dev_priv =
  433. to_i915(plane_state->base.plane->dev);
  434. const struct drm_framebuffer *fb = plane_state->base.fb;
  435. unsigned int rotation = plane_state->base.rotation;
  436. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  437. u32 sprctl;
  438. sprctl = SPRITE_ENABLE | SPRITE_GAMMA_ENABLE;
  439. if (IS_IVYBRIDGE(dev_priv))
  440. sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
  441. if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
  442. sprctl |= SPRITE_PIPE_CSC_ENABLE;
  443. switch (fb->format->format) {
  444. case DRM_FORMAT_XBGR8888:
  445. sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
  446. break;
  447. case DRM_FORMAT_XRGB8888:
  448. sprctl |= SPRITE_FORMAT_RGBX888;
  449. break;
  450. case DRM_FORMAT_YUYV:
  451. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
  452. break;
  453. case DRM_FORMAT_YVYU:
  454. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
  455. break;
  456. case DRM_FORMAT_UYVY:
  457. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
  458. break;
  459. case DRM_FORMAT_VYUY:
  460. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
  461. break;
  462. default:
  463. MISSING_CASE(fb->format->format);
  464. return 0;
  465. }
  466. if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  467. sprctl |= SPRITE_TILED;
  468. if (rotation & DRM_MODE_ROTATE_180)
  469. sprctl |= SPRITE_ROTATE_180;
  470. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  471. sprctl |= SPRITE_DEST_KEY;
  472. else if (key->flags & I915_SET_COLORKEY_SOURCE)
  473. sprctl |= SPRITE_SOURCE_KEY;
  474. return sprctl;
  475. }
  476. static void
  477. ivb_update_plane(struct intel_plane *plane,
  478. const struct intel_crtc_state *crtc_state,
  479. const struct intel_plane_state *plane_state)
  480. {
  481. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  482. const struct drm_framebuffer *fb = plane_state->base.fb;
  483. enum pipe pipe = plane->pipe;
  484. u32 sprctl = plane_state->ctl, sprscale = 0;
  485. u32 sprsurf_offset = plane_state->main.offset;
  486. u32 linear_offset;
  487. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  488. int crtc_x = plane_state->base.dst.x1;
  489. int crtc_y = plane_state->base.dst.y1;
  490. uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
  491. uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
  492. uint32_t x = plane_state->main.x;
  493. uint32_t y = plane_state->main.y;
  494. uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
  495. uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
  496. unsigned long irqflags;
  497. /* Sizes are 0 based */
  498. src_w--;
  499. src_h--;
  500. crtc_w--;
  501. crtc_h--;
  502. if (crtc_w != src_w || crtc_h != src_h)
  503. sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
  504. linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
  505. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  506. if (key->flags) {
  507. I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
  508. I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
  509. I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
  510. }
  511. I915_WRITE_FW(SPRSTRIDE(pipe), fb->pitches[0]);
  512. I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
  513. /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
  514. * register */
  515. if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
  516. I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
  517. else if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  518. I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
  519. else
  520. I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
  521. I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
  522. if (plane->can_scale)
  523. I915_WRITE_FW(SPRSCALE(pipe), sprscale);
  524. I915_WRITE_FW(SPRCTL(pipe), sprctl);
  525. I915_WRITE_FW(SPRSURF(pipe),
  526. intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
  527. POSTING_READ_FW(SPRSURF(pipe));
  528. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  529. }
  530. static void
  531. ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
  532. {
  533. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  534. enum pipe pipe = plane->pipe;
  535. unsigned long irqflags;
  536. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  537. I915_WRITE_FW(SPRCTL(pipe), 0);
  538. /* Can't leave the scaler enabled... */
  539. if (plane->can_scale)
  540. I915_WRITE_FW(SPRSCALE(pipe), 0);
  541. I915_WRITE_FW(SPRSURF(pipe), 0);
  542. POSTING_READ_FW(SPRSURF(pipe));
  543. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  544. }
  545. static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
  546. const struct intel_plane_state *plane_state)
  547. {
  548. struct drm_i915_private *dev_priv =
  549. to_i915(plane_state->base.plane->dev);
  550. const struct drm_framebuffer *fb = plane_state->base.fb;
  551. unsigned int rotation = plane_state->base.rotation;
  552. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  553. u32 dvscntr;
  554. dvscntr = DVS_ENABLE | DVS_GAMMA_ENABLE;
  555. if (IS_GEN6(dev_priv))
  556. dvscntr |= DVS_TRICKLE_FEED_DISABLE;
  557. switch (fb->format->format) {
  558. case DRM_FORMAT_XBGR8888:
  559. dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
  560. break;
  561. case DRM_FORMAT_XRGB8888:
  562. dvscntr |= DVS_FORMAT_RGBX888;
  563. break;
  564. case DRM_FORMAT_YUYV:
  565. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
  566. break;
  567. case DRM_FORMAT_YVYU:
  568. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
  569. break;
  570. case DRM_FORMAT_UYVY:
  571. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
  572. break;
  573. case DRM_FORMAT_VYUY:
  574. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
  575. break;
  576. default:
  577. MISSING_CASE(fb->format->format);
  578. return 0;
  579. }
  580. if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  581. dvscntr |= DVS_TILED;
  582. if (rotation & DRM_MODE_ROTATE_180)
  583. dvscntr |= DVS_ROTATE_180;
  584. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  585. dvscntr |= DVS_DEST_KEY;
  586. else if (key->flags & I915_SET_COLORKEY_SOURCE)
  587. dvscntr |= DVS_SOURCE_KEY;
  588. return dvscntr;
  589. }
  590. static void
  591. g4x_update_plane(struct intel_plane *plane,
  592. const struct intel_crtc_state *crtc_state,
  593. const struct intel_plane_state *plane_state)
  594. {
  595. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  596. const struct drm_framebuffer *fb = plane_state->base.fb;
  597. enum pipe pipe = plane->pipe;
  598. u32 dvscntr = plane_state->ctl, dvsscale = 0;
  599. u32 dvssurf_offset = plane_state->main.offset;
  600. u32 linear_offset;
  601. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  602. int crtc_x = plane_state->base.dst.x1;
  603. int crtc_y = plane_state->base.dst.y1;
  604. uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
  605. uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
  606. uint32_t x = plane_state->main.x;
  607. uint32_t y = plane_state->main.y;
  608. uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
  609. uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
  610. unsigned long irqflags;
  611. /* Sizes are 0 based */
  612. src_w--;
  613. src_h--;
  614. crtc_w--;
  615. crtc_h--;
  616. if (crtc_w != src_w || crtc_h != src_h)
  617. dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
  618. linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
  619. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  620. if (key->flags) {
  621. I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
  622. I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
  623. I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
  624. }
  625. I915_WRITE_FW(DVSSTRIDE(pipe), fb->pitches[0]);
  626. I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
  627. if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  628. I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
  629. else
  630. I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
  631. I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
  632. I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
  633. I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
  634. I915_WRITE_FW(DVSSURF(pipe),
  635. intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
  636. POSTING_READ_FW(DVSSURF(pipe));
  637. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  638. }
  639. static void
  640. g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
  641. {
  642. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  643. enum pipe pipe = plane->pipe;
  644. unsigned long irqflags;
  645. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  646. I915_WRITE_FW(DVSCNTR(pipe), 0);
  647. /* Disable the scaler */
  648. I915_WRITE_FW(DVSSCALE(pipe), 0);
  649. I915_WRITE_FW(DVSSURF(pipe), 0);
  650. POSTING_READ_FW(DVSSURF(pipe));
  651. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  652. }
  653. static int
  654. intel_check_sprite_plane(struct intel_plane *plane,
  655. struct intel_crtc_state *crtc_state,
  656. struct intel_plane_state *state)
  657. {
  658. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  659. struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
  660. struct drm_framebuffer *fb = state->base.fb;
  661. int crtc_x, crtc_y;
  662. unsigned int crtc_w, crtc_h;
  663. uint32_t src_x, src_y, src_w, src_h;
  664. struct drm_rect *src = &state->base.src;
  665. struct drm_rect *dst = &state->base.dst;
  666. const struct drm_rect *clip = &state->clip;
  667. int hscale, vscale;
  668. int max_scale, min_scale;
  669. bool can_scale;
  670. int ret;
  671. *src = drm_plane_state_src(&state->base);
  672. *dst = drm_plane_state_dest(&state->base);
  673. if (!fb) {
  674. state->base.visible = false;
  675. return 0;
  676. }
  677. /* Don't modify another pipe's plane */
  678. if (plane->pipe != crtc->pipe) {
  679. DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
  680. return -EINVAL;
  681. }
  682. /* FIXME check all gen limits */
  683. if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
  684. DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
  685. return -EINVAL;
  686. }
  687. /* setup can_scale, min_scale, max_scale */
  688. if (INTEL_GEN(dev_priv) >= 9) {
  689. /* use scaler when colorkey is not required */
  690. if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
  691. can_scale = 1;
  692. min_scale = 1;
  693. max_scale = skl_max_scale(crtc, crtc_state);
  694. } else {
  695. can_scale = 0;
  696. min_scale = DRM_PLANE_HELPER_NO_SCALING;
  697. max_scale = DRM_PLANE_HELPER_NO_SCALING;
  698. }
  699. } else {
  700. can_scale = plane->can_scale;
  701. max_scale = plane->max_downscale << 16;
  702. min_scale = plane->can_scale ? 1 : (1 << 16);
  703. }
  704. /*
  705. * FIXME the following code does a bunch of fuzzy adjustments to the
  706. * coordinates and sizes. We probably need some way to decide whether
  707. * more strict checking should be done instead.
  708. */
  709. drm_rect_rotate(src, fb->width << 16, fb->height << 16,
  710. state->base.rotation);
  711. hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
  712. BUG_ON(hscale < 0);
  713. vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
  714. BUG_ON(vscale < 0);
  715. state->base.visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
  716. crtc_x = dst->x1;
  717. crtc_y = dst->y1;
  718. crtc_w = drm_rect_width(dst);
  719. crtc_h = drm_rect_height(dst);
  720. if (state->base.visible) {
  721. /* check again in case clipping clamped the results */
  722. hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
  723. if (hscale < 0) {
  724. DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
  725. drm_rect_debug_print("src: ", src, true);
  726. drm_rect_debug_print("dst: ", dst, false);
  727. return hscale;
  728. }
  729. vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
  730. if (vscale < 0) {
  731. DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
  732. drm_rect_debug_print("src: ", src, true);
  733. drm_rect_debug_print("dst: ", dst, false);
  734. return vscale;
  735. }
  736. /* Make the source viewport size an exact multiple of the scaling factors. */
  737. drm_rect_adjust_size(src,
  738. drm_rect_width(dst) * hscale - drm_rect_width(src),
  739. drm_rect_height(dst) * vscale - drm_rect_height(src));
  740. drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
  741. state->base.rotation);
  742. /* sanity check to make sure the src viewport wasn't enlarged */
  743. WARN_ON(src->x1 < (int) state->base.src_x ||
  744. src->y1 < (int) state->base.src_y ||
  745. src->x2 > (int) state->base.src_x + state->base.src_w ||
  746. src->y2 > (int) state->base.src_y + state->base.src_h);
  747. /*
  748. * Hardware doesn't handle subpixel coordinates.
  749. * Adjust to (macro)pixel boundary, but be careful not to
  750. * increase the source viewport size, because that could
  751. * push the downscaling factor out of bounds.
  752. */
  753. src_x = src->x1 >> 16;
  754. src_w = drm_rect_width(src) >> 16;
  755. src_y = src->y1 >> 16;
  756. src_h = drm_rect_height(src) >> 16;
  757. if (format_is_yuv(fb->format->format)) {
  758. src_x &= ~1;
  759. src_w &= ~1;
  760. /*
  761. * Must keep src and dst the
  762. * same if we can't scale.
  763. */
  764. if (!can_scale)
  765. crtc_w &= ~1;
  766. if (crtc_w == 0)
  767. state->base.visible = false;
  768. }
  769. }
  770. /* Check size restrictions when scaling */
  771. if (state->base.visible && (src_w != crtc_w || src_h != crtc_h)) {
  772. unsigned int width_bytes;
  773. int cpp = fb->format->cpp[0];
  774. WARN_ON(!can_scale);
  775. /* FIXME interlacing min height is 6 */
  776. if (crtc_w < 3 || crtc_h < 3)
  777. state->base.visible = false;
  778. if (src_w < 3 || src_h < 3)
  779. state->base.visible = false;
  780. width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
  781. if (INTEL_GEN(dev_priv) < 9 && (src_w > 2048 || src_h > 2048 ||
  782. width_bytes > 4096 || fb->pitches[0] > 4096)) {
  783. DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
  784. return -EINVAL;
  785. }
  786. }
  787. if (state->base.visible) {
  788. src->x1 = src_x << 16;
  789. src->x2 = (src_x + src_w) << 16;
  790. src->y1 = src_y << 16;
  791. src->y2 = (src_y + src_h) << 16;
  792. }
  793. dst->x1 = crtc_x;
  794. dst->x2 = crtc_x + crtc_w;
  795. dst->y1 = crtc_y;
  796. dst->y2 = crtc_y + crtc_h;
  797. if (INTEL_GEN(dev_priv) >= 9) {
  798. ret = skl_check_plane_surface(state);
  799. if (ret)
  800. return ret;
  801. state->ctl = skl_plane_ctl(crtc_state, state);
  802. } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
  803. ret = i9xx_check_plane_surface(state);
  804. if (ret)
  805. return ret;
  806. state->ctl = vlv_sprite_ctl(crtc_state, state);
  807. } else if (INTEL_GEN(dev_priv) >= 7) {
  808. ret = i9xx_check_plane_surface(state);
  809. if (ret)
  810. return ret;
  811. state->ctl = ivb_sprite_ctl(crtc_state, state);
  812. } else {
  813. ret = i9xx_check_plane_surface(state);
  814. if (ret)
  815. return ret;
  816. state->ctl = g4x_sprite_ctl(crtc_state, state);
  817. }
  818. if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
  819. state->color_ctl = glk_plane_color_ctl(crtc_state, state);
  820. return 0;
  821. }
  822. int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
  823. struct drm_file *file_priv)
  824. {
  825. struct drm_i915_private *dev_priv = to_i915(dev);
  826. struct drm_intel_sprite_colorkey *set = data;
  827. struct drm_plane *plane;
  828. struct drm_plane_state *plane_state;
  829. struct drm_atomic_state *state;
  830. struct drm_modeset_acquire_ctx ctx;
  831. int ret = 0;
  832. /* Make sure we don't try to enable both src & dest simultaneously */
  833. if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
  834. return -EINVAL;
  835. if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
  836. set->flags & I915_SET_COLORKEY_DESTINATION)
  837. return -EINVAL;
  838. plane = drm_plane_find(dev, file_priv, set->plane_id);
  839. if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
  840. return -ENOENT;
  841. drm_modeset_acquire_init(&ctx, 0);
  842. state = drm_atomic_state_alloc(plane->dev);
  843. if (!state) {
  844. ret = -ENOMEM;
  845. goto out;
  846. }
  847. state->acquire_ctx = &ctx;
  848. while (1) {
  849. plane_state = drm_atomic_get_plane_state(state, plane);
  850. ret = PTR_ERR_OR_ZERO(plane_state);
  851. if (!ret) {
  852. to_intel_plane_state(plane_state)->ckey = *set;
  853. ret = drm_atomic_commit(state);
  854. }
  855. if (ret != -EDEADLK)
  856. break;
  857. drm_atomic_state_clear(state);
  858. drm_modeset_backoff(&ctx);
  859. }
  860. drm_atomic_state_put(state);
  861. out:
  862. drm_modeset_drop_locks(&ctx);
  863. drm_modeset_acquire_fini(&ctx);
  864. return ret;
  865. }
  866. static const uint32_t g4x_plane_formats[] = {
  867. DRM_FORMAT_XRGB8888,
  868. DRM_FORMAT_YUYV,
  869. DRM_FORMAT_YVYU,
  870. DRM_FORMAT_UYVY,
  871. DRM_FORMAT_VYUY,
  872. };
  873. static const uint64_t i9xx_plane_format_modifiers[] = {
  874. I915_FORMAT_MOD_X_TILED,
  875. DRM_FORMAT_MOD_LINEAR,
  876. DRM_FORMAT_MOD_INVALID
  877. };
  878. static const uint32_t snb_plane_formats[] = {
  879. DRM_FORMAT_XBGR8888,
  880. DRM_FORMAT_XRGB8888,
  881. DRM_FORMAT_YUYV,
  882. DRM_FORMAT_YVYU,
  883. DRM_FORMAT_UYVY,
  884. DRM_FORMAT_VYUY,
  885. };
  886. static const uint32_t vlv_plane_formats[] = {
  887. DRM_FORMAT_RGB565,
  888. DRM_FORMAT_ABGR8888,
  889. DRM_FORMAT_ARGB8888,
  890. DRM_FORMAT_XBGR8888,
  891. DRM_FORMAT_XRGB8888,
  892. DRM_FORMAT_XBGR2101010,
  893. DRM_FORMAT_ABGR2101010,
  894. DRM_FORMAT_YUYV,
  895. DRM_FORMAT_YVYU,
  896. DRM_FORMAT_UYVY,
  897. DRM_FORMAT_VYUY,
  898. };
  899. static uint32_t skl_plane_formats[] = {
  900. DRM_FORMAT_RGB565,
  901. DRM_FORMAT_ABGR8888,
  902. DRM_FORMAT_ARGB8888,
  903. DRM_FORMAT_XBGR8888,
  904. DRM_FORMAT_XRGB8888,
  905. DRM_FORMAT_YUYV,
  906. DRM_FORMAT_YVYU,
  907. DRM_FORMAT_UYVY,
  908. DRM_FORMAT_VYUY,
  909. };
  910. static const uint64_t skl_plane_format_modifiers[] = {
  911. I915_FORMAT_MOD_X_TILED,
  912. DRM_FORMAT_MOD_LINEAR,
  913. DRM_FORMAT_MOD_INVALID
  914. };
  915. static bool g4x_sprite_plane_format_mod_supported(struct drm_plane *plane,
  916. uint32_t format,
  917. uint64_t modifier)
  918. {
  919. switch (format) {
  920. case DRM_FORMAT_XBGR8888:
  921. case DRM_FORMAT_XRGB8888:
  922. case DRM_FORMAT_YUYV:
  923. case DRM_FORMAT_YVYU:
  924. case DRM_FORMAT_UYVY:
  925. case DRM_FORMAT_VYUY:
  926. if (modifier == DRM_FORMAT_MOD_LINEAR ||
  927. modifier == I915_FORMAT_MOD_X_TILED)
  928. return true;
  929. /* fall through */
  930. default:
  931. return false;
  932. }
  933. }
  934. static bool vlv_sprite_plane_format_mod_supported(struct drm_plane *plane,
  935. uint32_t format,
  936. uint64_t modifier)
  937. {
  938. switch (format) {
  939. case DRM_FORMAT_YUYV:
  940. case DRM_FORMAT_YVYU:
  941. case DRM_FORMAT_UYVY:
  942. case DRM_FORMAT_VYUY:
  943. case DRM_FORMAT_RGB565:
  944. case DRM_FORMAT_XRGB8888:
  945. case DRM_FORMAT_ARGB8888:
  946. case DRM_FORMAT_XBGR2101010:
  947. case DRM_FORMAT_ABGR2101010:
  948. case DRM_FORMAT_XBGR8888:
  949. case DRM_FORMAT_ABGR8888:
  950. if (modifier == DRM_FORMAT_MOD_LINEAR ||
  951. modifier == I915_FORMAT_MOD_X_TILED)
  952. return true;
  953. /* fall through */
  954. default:
  955. return false;
  956. }
  957. }
  958. static bool skl_sprite_plane_format_mod_supported(struct drm_plane *plane,
  959. uint32_t format,
  960. uint64_t modifier)
  961. {
  962. /* This is the same as primary plane since SKL has universal planes */
  963. switch (format) {
  964. case DRM_FORMAT_XRGB8888:
  965. case DRM_FORMAT_XBGR8888:
  966. case DRM_FORMAT_ARGB8888:
  967. case DRM_FORMAT_ABGR8888:
  968. case DRM_FORMAT_RGB565:
  969. case DRM_FORMAT_XRGB2101010:
  970. case DRM_FORMAT_XBGR2101010:
  971. case DRM_FORMAT_YUYV:
  972. case DRM_FORMAT_YVYU:
  973. case DRM_FORMAT_UYVY:
  974. case DRM_FORMAT_VYUY:
  975. if (modifier == I915_FORMAT_MOD_Yf_TILED)
  976. return true;
  977. /* fall through */
  978. case DRM_FORMAT_C8:
  979. if (modifier == DRM_FORMAT_MOD_LINEAR ||
  980. modifier == I915_FORMAT_MOD_X_TILED ||
  981. modifier == I915_FORMAT_MOD_Y_TILED)
  982. return true;
  983. /* fall through */
  984. default:
  985. return false;
  986. }
  987. }
  988. static bool intel_sprite_plane_format_mod_supported(struct drm_plane *plane,
  989. uint32_t format,
  990. uint64_t modifier)
  991. {
  992. struct drm_i915_private *dev_priv = to_i915(plane->dev);
  993. if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
  994. return false;
  995. if ((modifier >> 56) != DRM_FORMAT_MOD_VENDOR_INTEL &&
  996. modifier != DRM_FORMAT_MOD_LINEAR)
  997. return false;
  998. if (INTEL_GEN(dev_priv) >= 9)
  999. return skl_sprite_plane_format_mod_supported(plane, format, modifier);
  1000. else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
  1001. return vlv_sprite_plane_format_mod_supported(plane, format, modifier);
  1002. else
  1003. return g4x_sprite_plane_format_mod_supported(plane, format, modifier);
  1004. unreachable();
  1005. }
  1006. static const struct drm_plane_funcs intel_sprite_plane_funcs = {
  1007. .update_plane = drm_atomic_helper_update_plane,
  1008. .disable_plane = drm_atomic_helper_disable_plane,
  1009. .destroy = intel_plane_destroy,
  1010. .atomic_get_property = intel_plane_atomic_get_property,
  1011. .atomic_set_property = intel_plane_atomic_set_property,
  1012. .atomic_duplicate_state = intel_plane_duplicate_state,
  1013. .atomic_destroy_state = intel_plane_destroy_state,
  1014. .format_mod_supported = intel_sprite_plane_format_mod_supported,
  1015. };
  1016. struct intel_plane *
  1017. intel_sprite_plane_create(struct drm_i915_private *dev_priv,
  1018. enum pipe pipe, int plane)
  1019. {
  1020. struct intel_plane *intel_plane = NULL;
  1021. struct intel_plane_state *state = NULL;
  1022. unsigned long possible_crtcs;
  1023. const uint32_t *plane_formats;
  1024. const uint64_t *modifiers;
  1025. unsigned int supported_rotations;
  1026. int num_plane_formats;
  1027. int ret;
  1028. intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
  1029. if (!intel_plane) {
  1030. ret = -ENOMEM;
  1031. goto fail;
  1032. }
  1033. state = intel_create_plane_state(&intel_plane->base);
  1034. if (!state) {
  1035. ret = -ENOMEM;
  1036. goto fail;
  1037. }
  1038. intel_plane->base.state = &state->base;
  1039. if (INTEL_GEN(dev_priv) >= 10) {
  1040. intel_plane->can_scale = true;
  1041. state->scaler_id = -1;
  1042. intel_plane->update_plane = skl_update_plane;
  1043. intel_plane->disable_plane = skl_disable_plane;
  1044. plane_formats = skl_plane_formats;
  1045. num_plane_formats = ARRAY_SIZE(skl_plane_formats);
  1046. modifiers = skl_plane_format_modifiers;
  1047. } else if (INTEL_GEN(dev_priv) >= 9) {
  1048. intel_plane->can_scale = true;
  1049. state->scaler_id = -1;
  1050. intel_plane->update_plane = skl_update_plane;
  1051. intel_plane->disable_plane = skl_disable_plane;
  1052. plane_formats = skl_plane_formats;
  1053. num_plane_formats = ARRAY_SIZE(skl_plane_formats);
  1054. modifiers = skl_plane_format_modifiers;
  1055. } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
  1056. intel_plane->can_scale = false;
  1057. intel_plane->max_downscale = 1;
  1058. intel_plane->update_plane = vlv_update_plane;
  1059. intel_plane->disable_plane = vlv_disable_plane;
  1060. plane_formats = vlv_plane_formats;
  1061. num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
  1062. modifiers = i9xx_plane_format_modifiers;
  1063. } else if (INTEL_GEN(dev_priv) >= 7) {
  1064. if (IS_IVYBRIDGE(dev_priv)) {
  1065. intel_plane->can_scale = true;
  1066. intel_plane->max_downscale = 2;
  1067. } else {
  1068. intel_plane->can_scale = false;
  1069. intel_plane->max_downscale = 1;
  1070. }
  1071. intel_plane->update_plane = ivb_update_plane;
  1072. intel_plane->disable_plane = ivb_disable_plane;
  1073. plane_formats = snb_plane_formats;
  1074. num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1075. modifiers = i9xx_plane_format_modifiers;
  1076. } else {
  1077. intel_plane->can_scale = true;
  1078. intel_plane->max_downscale = 16;
  1079. intel_plane->update_plane = g4x_update_plane;
  1080. intel_plane->disable_plane = g4x_disable_plane;
  1081. modifiers = i9xx_plane_format_modifiers;
  1082. if (IS_GEN6(dev_priv)) {
  1083. plane_formats = snb_plane_formats;
  1084. num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1085. } else {
  1086. plane_formats = g4x_plane_formats;
  1087. num_plane_formats = ARRAY_SIZE(g4x_plane_formats);
  1088. }
  1089. }
  1090. if (INTEL_GEN(dev_priv) >= 9) {
  1091. supported_rotations =
  1092. DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
  1093. DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
  1094. } else if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
  1095. supported_rotations =
  1096. DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
  1097. DRM_MODE_REFLECT_X;
  1098. } else {
  1099. supported_rotations =
  1100. DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
  1101. }
  1102. intel_plane->pipe = pipe;
  1103. intel_plane->plane = plane;
  1104. intel_plane->id = PLANE_SPRITE0 + plane;
  1105. intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe, plane);
  1106. intel_plane->check_plane = intel_check_sprite_plane;
  1107. possible_crtcs = (1 << pipe);
  1108. if (INTEL_GEN(dev_priv) >= 9)
  1109. ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
  1110. possible_crtcs, &intel_sprite_plane_funcs,
  1111. plane_formats, num_plane_formats,
  1112. modifiers,
  1113. DRM_PLANE_TYPE_OVERLAY,
  1114. "plane %d%c", plane + 2, pipe_name(pipe));
  1115. else
  1116. ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
  1117. possible_crtcs, &intel_sprite_plane_funcs,
  1118. plane_formats, num_plane_formats,
  1119. modifiers,
  1120. DRM_PLANE_TYPE_OVERLAY,
  1121. "sprite %c", sprite_name(pipe, plane));
  1122. if (ret)
  1123. goto fail;
  1124. drm_plane_create_rotation_property(&intel_plane->base,
  1125. DRM_MODE_ROTATE_0,
  1126. supported_rotations);
  1127. drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
  1128. return intel_plane;
  1129. fail:
  1130. kfree(state);
  1131. kfree(intel_plane);
  1132. return ERR_PTR(ret);
  1133. }