intel_sprite.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916
  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. int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
  44. int usecs)
  45. {
  46. /* paranoia */
  47. if (!adjusted_mode->crtc_htotal)
  48. return 1;
  49. return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
  50. 1000 * adjusted_mode->crtc_htotal);
  51. }
  52. /* FIXME: We should instead only take spinlocks once for the entire update
  53. * instead of once per mmio. */
  54. #if IS_ENABLED(CONFIG_PROVE_LOCKING)
  55. #define VBLANK_EVASION_TIME_US 250
  56. #else
  57. #define VBLANK_EVASION_TIME_US 100
  58. #endif
  59. /**
  60. * intel_pipe_update_start() - start update of a set of display registers
  61. * @new_crtc_state: the new crtc state
  62. *
  63. * Mark the start of an update to pipe registers that should be updated
  64. * atomically regarding vblank. If the next vblank will happens within
  65. * the next 100 us, this function waits until the vblank passes.
  66. *
  67. * After a successful call to this function, interrupts will be disabled
  68. * until a subsequent call to intel_pipe_update_end(). That is done to
  69. * avoid random delays.
  70. */
  71. void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
  72. {
  73. struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
  74. struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
  75. const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
  76. long timeout = msecs_to_jiffies_timeout(1);
  77. int scanline, min, max, vblank_start;
  78. wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
  79. bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
  80. intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
  81. DEFINE_WAIT(wait);
  82. u32 psr_status;
  83. vblank_start = adjusted_mode->crtc_vblank_start;
  84. if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
  85. vblank_start = DIV_ROUND_UP(vblank_start, 2);
  86. /* FIXME needs to be calibrated sensibly */
  87. min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
  88. VBLANK_EVASION_TIME_US);
  89. max = vblank_start - 1;
  90. if (min <= 0 || max <= 0)
  91. goto irq_disable;
  92. if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
  93. goto irq_disable;
  94. /*
  95. * Wait for psr to idle out after enabling the VBL interrupts
  96. * VBL interrupts will start the PSR exit and prevent a PSR
  97. * re-entry as well.
  98. */
  99. if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
  100. DRM_ERROR("PSR idle timed out 0x%x, atomic update may fail\n",
  101. psr_status);
  102. local_irq_disable();
  103. crtc->debug.min_vbl = min;
  104. crtc->debug.max_vbl = max;
  105. trace_i915_pipe_update_start(crtc);
  106. for (;;) {
  107. /*
  108. * prepare_to_wait() has a memory barrier, which guarantees
  109. * other CPUs can see the task state update by the time we
  110. * read the scanline.
  111. */
  112. prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
  113. scanline = intel_get_crtc_scanline(crtc);
  114. if (scanline < min || scanline > max)
  115. break;
  116. if (!timeout) {
  117. DRM_ERROR("Potential atomic update failure on pipe %c\n",
  118. pipe_name(crtc->pipe));
  119. break;
  120. }
  121. local_irq_enable();
  122. timeout = schedule_timeout(timeout);
  123. local_irq_disable();
  124. }
  125. finish_wait(wq, &wait);
  126. drm_crtc_vblank_put(&crtc->base);
  127. /*
  128. * On VLV/CHV DSI the scanline counter would appear to
  129. * increment approx. 1/3 of a scanline before start of vblank.
  130. * The registers still get latched at start of vblank however.
  131. * This means we must not write any registers on the first
  132. * line of vblank (since not the whole line is actually in
  133. * vblank). And unfortunately we can't use the interrupt to
  134. * wait here since it will fire too soon. We could use the
  135. * frame start interrupt instead since it will fire after the
  136. * critical scanline, but that would require more changes
  137. * in the interrupt code. So for now we'll just do the nasty
  138. * thing and poll for the bad scanline to pass us by.
  139. *
  140. * FIXME figure out if BXT+ DSI suffers from this as well
  141. */
  142. while (need_vlv_dsi_wa && scanline == vblank_start)
  143. scanline = intel_get_crtc_scanline(crtc);
  144. crtc->debug.scanline_start = scanline;
  145. crtc->debug.start_vbl_time = ktime_get();
  146. crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
  147. trace_i915_pipe_update_vblank_evaded(crtc);
  148. return;
  149. irq_disable:
  150. local_irq_disable();
  151. }
  152. /**
  153. * intel_pipe_update_end() - end update of a set of display registers
  154. * @new_crtc_state: the new crtc state
  155. *
  156. * Mark the end of an update started with intel_pipe_update_start(). This
  157. * re-enables interrupts and verifies the update was actually completed
  158. * before a vblank.
  159. */
  160. void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
  161. {
  162. struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
  163. enum pipe pipe = crtc->pipe;
  164. int scanline_end = intel_get_crtc_scanline(crtc);
  165. u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
  166. ktime_t end_vbl_time = ktime_get();
  167. struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
  168. trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
  169. /* We're still in the vblank-evade critical section, this can't race.
  170. * Would be slightly nice to just grab the vblank count and arm the
  171. * event outside of the critical section - the spinlock might spin for a
  172. * while ... */
  173. if (new_crtc_state->base.event) {
  174. WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
  175. spin_lock(&crtc->base.dev->event_lock);
  176. drm_crtc_arm_vblank_event(&crtc->base, new_crtc_state->base.event);
  177. spin_unlock(&crtc->base.dev->event_lock);
  178. new_crtc_state->base.event = NULL;
  179. }
  180. local_irq_enable();
  181. if (intel_vgpu_active(dev_priv))
  182. return;
  183. if (crtc->debug.start_vbl_count &&
  184. crtc->debug.start_vbl_count != end_vbl_count) {
  185. 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",
  186. pipe_name(pipe), crtc->debug.start_vbl_count,
  187. end_vbl_count,
  188. ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
  189. crtc->debug.min_vbl, crtc->debug.max_vbl,
  190. crtc->debug.scanline_start, scanline_end);
  191. }
  192. #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
  193. else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) >
  194. VBLANK_EVASION_TIME_US)
  195. DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
  196. pipe_name(pipe),
  197. ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
  198. VBLANK_EVASION_TIME_US);
  199. #endif
  200. }
  201. int intel_plane_check_stride(const struct intel_plane_state *plane_state)
  202. {
  203. struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
  204. const struct drm_framebuffer *fb = plane_state->base.fb;
  205. unsigned int rotation = plane_state->base.rotation;
  206. u32 stride, max_stride;
  207. /* FIXME other color planes? */
  208. stride = plane_state->color_plane[0].stride;
  209. max_stride = plane->max_stride(plane, fb->format->format,
  210. fb->modifier, rotation);
  211. if (stride > max_stride) {
  212. DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
  213. fb->base.id, stride,
  214. plane->base.base.id, plane->base.name, max_stride);
  215. return -EINVAL;
  216. }
  217. return 0;
  218. }
  219. int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
  220. {
  221. const struct drm_framebuffer *fb = plane_state->base.fb;
  222. struct drm_rect *src = &plane_state->base.src;
  223. u32 src_x, src_y, src_w, src_h;
  224. /*
  225. * Hardware doesn't handle subpixel coordinates.
  226. * Adjust to (macro)pixel boundary, but be careful not to
  227. * increase the source viewport size, because that could
  228. * push the downscaling factor out of bounds.
  229. */
  230. src_x = src->x1 >> 16;
  231. src_w = drm_rect_width(src) >> 16;
  232. src_y = src->y1 >> 16;
  233. src_h = drm_rect_height(src) >> 16;
  234. src->x1 = src_x << 16;
  235. src->x2 = (src_x + src_w) << 16;
  236. src->y1 = src_y << 16;
  237. src->y2 = (src_y + src_h) << 16;
  238. if (fb->format->is_yuv &&
  239. fb->format->format != DRM_FORMAT_NV12 &&
  240. (src_x & 1 || src_w & 1)) {
  241. DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
  242. src_x, src_w);
  243. return -EINVAL;
  244. }
  245. return 0;
  246. }
  247. unsigned int
  248. skl_plane_max_stride(struct intel_plane *plane,
  249. u32 pixel_format, u64 modifier,
  250. unsigned int rotation)
  251. {
  252. int cpp = drm_format_plane_cpp(pixel_format, 0);
  253. /*
  254. * "The stride in bytes must not exceed the
  255. * of the size of 8K pixels and 32K bytes."
  256. */
  257. if (drm_rotation_90_or_270(rotation))
  258. return min(8192, 32768 / cpp);
  259. else
  260. return min(8192 * cpp, 32768);
  261. }
  262. static void
  263. skl_program_scaler(struct intel_plane *plane,
  264. const struct intel_crtc_state *crtc_state,
  265. const struct intel_plane_state *plane_state)
  266. {
  267. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  268. enum pipe pipe = plane->pipe;
  269. int scaler_id = plane_state->scaler_id;
  270. const struct intel_scaler *scaler =
  271. &crtc_state->scaler_state.scalers[scaler_id];
  272. int crtc_x = plane_state->base.dst.x1;
  273. int crtc_y = plane_state->base.dst.y1;
  274. uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
  275. uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
  276. u16 y_hphase, uv_rgb_hphase;
  277. u16 y_vphase, uv_rgb_vphase;
  278. int hscale, vscale;
  279. hscale = drm_rect_calc_hscale(&plane_state->base.src,
  280. &plane_state->base.dst,
  281. 0, INT_MAX);
  282. vscale = drm_rect_calc_vscale(&plane_state->base.src,
  283. &plane_state->base.dst,
  284. 0, INT_MAX);
  285. /* TODO: handle sub-pixel coordinates */
  286. if (plane_state->base.fb->format->format == DRM_FORMAT_NV12) {
  287. y_hphase = skl_scaler_calc_phase(1, hscale, false);
  288. y_vphase = skl_scaler_calc_phase(1, vscale, false);
  289. /* MPEG2 chroma siting convention */
  290. uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
  291. uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
  292. } else {
  293. /* not used */
  294. y_hphase = 0;
  295. y_vphase = 0;
  296. uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
  297. uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
  298. }
  299. I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
  300. PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
  301. I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
  302. I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
  303. PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
  304. I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
  305. PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
  306. I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
  307. I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
  308. }
  309. void
  310. skl_update_plane(struct intel_plane *plane,
  311. const struct intel_crtc_state *crtc_state,
  312. const struct intel_plane_state *plane_state)
  313. {
  314. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  315. enum plane_id plane_id = plane->id;
  316. enum pipe pipe = plane->pipe;
  317. u32 plane_ctl = plane_state->ctl;
  318. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  319. u32 surf_addr = plane_state->color_plane[0].offset;
  320. u32 stride = skl_plane_stride(plane_state, 0);
  321. u32 aux_stride = skl_plane_stride(plane_state, 1);
  322. int crtc_x = plane_state->base.dst.x1;
  323. int crtc_y = plane_state->base.dst.y1;
  324. uint32_t x = plane_state->color_plane[0].x;
  325. uint32_t y = plane_state->color_plane[0].y;
  326. uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
  327. uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
  328. unsigned long irqflags;
  329. /* Sizes are 0 based */
  330. src_w--;
  331. src_h--;
  332. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  333. if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
  334. I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
  335. plane_state->color_ctl);
  336. if (key->flags) {
  337. I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
  338. I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value);
  339. I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), key->channel_mask);
  340. }
  341. I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
  342. I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
  343. I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
  344. I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
  345. (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
  346. I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
  347. (plane_state->color_plane[1].y << 16) |
  348. plane_state->color_plane[1].x);
  349. if (plane_state->scaler_id >= 0) {
  350. skl_program_scaler(plane, crtc_state, plane_state);
  351. I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
  352. } else {
  353. I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
  354. }
  355. I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
  356. I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
  357. intel_plane_ggtt_offset(plane_state) + surf_addr);
  358. POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
  359. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  360. }
  361. void
  362. skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
  363. {
  364. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  365. enum plane_id plane_id = plane->id;
  366. enum pipe pipe = plane->pipe;
  367. unsigned long irqflags;
  368. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  369. I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
  370. I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
  371. POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
  372. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  373. }
  374. bool
  375. skl_plane_get_hw_state(struct intel_plane *plane,
  376. enum pipe *pipe)
  377. {
  378. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  379. enum intel_display_power_domain power_domain;
  380. enum plane_id plane_id = plane->id;
  381. bool ret;
  382. power_domain = POWER_DOMAIN_PIPE(plane->pipe);
  383. if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
  384. return false;
  385. ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
  386. *pipe = plane->pipe;
  387. intel_display_power_put(dev_priv, power_domain);
  388. return ret;
  389. }
  390. static void
  391. chv_update_csc(const struct intel_plane_state *plane_state)
  392. {
  393. struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
  394. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  395. const struct drm_framebuffer *fb = plane_state->base.fb;
  396. enum plane_id plane_id = plane->id;
  397. /*
  398. * |r| | c0 c1 c2 | |cr|
  399. * |g| = | c3 c4 c5 | x |y |
  400. * |b| | c6 c7 c8 | |cb|
  401. *
  402. * Coefficients are s3.12.
  403. *
  404. * Cb and Cr apparently come in as signed already, and
  405. * we always get full range data in on account of CLRC0/1.
  406. */
  407. static const s16 csc_matrix[][9] = {
  408. /* BT.601 full range YCbCr -> full range RGB */
  409. [DRM_COLOR_YCBCR_BT601] = {
  410. 5743, 4096, 0,
  411. -2925, 4096, -1410,
  412. 0, 4096, 7258,
  413. },
  414. /* BT.709 full range YCbCr -> full range RGB */
  415. [DRM_COLOR_YCBCR_BT709] = {
  416. 6450, 4096, 0,
  417. -1917, 4096, -767,
  418. 0, 4096, 7601,
  419. },
  420. };
  421. const s16 *csc = csc_matrix[plane_state->base.color_encoding];
  422. /* Seems RGB data bypasses the CSC always */
  423. if (!fb->format->is_yuv)
  424. return;
  425. I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
  426. I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
  427. I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
  428. I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
  429. I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
  430. I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
  431. I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
  432. I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
  433. I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
  434. I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
  435. I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
  436. I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  437. I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  438. I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
  439. }
  440. #define SIN_0 0
  441. #define COS_0 1
  442. static void
  443. vlv_update_clrc(const struct intel_plane_state *plane_state)
  444. {
  445. struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
  446. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  447. const struct drm_framebuffer *fb = plane_state->base.fb;
  448. enum pipe pipe = plane->pipe;
  449. enum plane_id plane_id = plane->id;
  450. int contrast, brightness, sh_scale, sh_sin, sh_cos;
  451. if (fb->format->is_yuv &&
  452. plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
  453. /*
  454. * Expand limited range to full range:
  455. * Contrast is applied first and is used to expand Y range.
  456. * Brightness is applied second and is used to remove the
  457. * offset from Y. Saturation/hue is used to expand CbCr range.
  458. */
  459. contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
  460. brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
  461. sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
  462. sh_sin = SIN_0 * sh_scale;
  463. sh_cos = COS_0 * sh_scale;
  464. } else {
  465. /* Pass-through everything. */
  466. contrast = 1 << 6;
  467. brightness = 0;
  468. sh_scale = 1 << 7;
  469. sh_sin = SIN_0 * sh_scale;
  470. sh_cos = COS_0 * sh_scale;
  471. }
  472. /* FIXME these register are single buffered :( */
  473. I915_WRITE_FW(SPCLRC0(pipe, plane_id),
  474. SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
  475. I915_WRITE_FW(SPCLRC1(pipe, plane_id),
  476. SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
  477. }
  478. static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
  479. const struct intel_plane_state *plane_state)
  480. {
  481. const struct drm_framebuffer *fb = plane_state->base.fb;
  482. unsigned int rotation = plane_state->base.rotation;
  483. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  484. u32 sprctl;
  485. sprctl = SP_ENABLE | SP_GAMMA_ENABLE;
  486. switch (fb->format->format) {
  487. case DRM_FORMAT_YUYV:
  488. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
  489. break;
  490. case DRM_FORMAT_YVYU:
  491. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
  492. break;
  493. case DRM_FORMAT_UYVY:
  494. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
  495. break;
  496. case DRM_FORMAT_VYUY:
  497. sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
  498. break;
  499. case DRM_FORMAT_RGB565:
  500. sprctl |= SP_FORMAT_BGR565;
  501. break;
  502. case DRM_FORMAT_XRGB8888:
  503. sprctl |= SP_FORMAT_BGRX8888;
  504. break;
  505. case DRM_FORMAT_ARGB8888:
  506. sprctl |= SP_FORMAT_BGRA8888;
  507. break;
  508. case DRM_FORMAT_XBGR2101010:
  509. sprctl |= SP_FORMAT_RGBX1010102;
  510. break;
  511. case DRM_FORMAT_ABGR2101010:
  512. sprctl |= SP_FORMAT_RGBA1010102;
  513. break;
  514. case DRM_FORMAT_XBGR8888:
  515. sprctl |= SP_FORMAT_RGBX8888;
  516. break;
  517. case DRM_FORMAT_ABGR8888:
  518. sprctl |= SP_FORMAT_RGBA8888;
  519. break;
  520. default:
  521. MISSING_CASE(fb->format->format);
  522. return 0;
  523. }
  524. if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
  525. sprctl |= SP_YUV_FORMAT_BT709;
  526. if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  527. sprctl |= SP_TILED;
  528. if (rotation & DRM_MODE_ROTATE_180)
  529. sprctl |= SP_ROTATE_180;
  530. if (rotation & DRM_MODE_REFLECT_X)
  531. sprctl |= SP_MIRROR;
  532. if (key->flags & I915_SET_COLORKEY_SOURCE)
  533. sprctl |= SP_SOURCE_KEY;
  534. return sprctl;
  535. }
  536. static void
  537. vlv_update_plane(struct intel_plane *plane,
  538. const struct intel_crtc_state *crtc_state,
  539. const struct intel_plane_state *plane_state)
  540. {
  541. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  542. const struct drm_framebuffer *fb = plane_state->base.fb;
  543. enum pipe pipe = plane->pipe;
  544. enum plane_id plane_id = plane->id;
  545. u32 sprctl = plane_state->ctl;
  546. u32 sprsurf_offset = plane_state->color_plane[0].offset;
  547. u32 linear_offset;
  548. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  549. int crtc_x = plane_state->base.dst.x1;
  550. int crtc_y = plane_state->base.dst.y1;
  551. uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
  552. uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
  553. uint32_t x = plane_state->color_plane[0].x;
  554. uint32_t y = plane_state->color_plane[0].y;
  555. unsigned long irqflags;
  556. /* Sizes are 0 based */
  557. crtc_w--;
  558. crtc_h--;
  559. linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
  560. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  561. vlv_update_clrc(plane_state);
  562. if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
  563. chv_update_csc(plane_state);
  564. if (key->flags) {
  565. I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
  566. I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
  567. I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
  568. }
  569. I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
  570. plane_state->color_plane[0].stride);
  571. I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
  572. if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  573. I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
  574. else
  575. I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
  576. I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
  577. I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
  578. I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
  579. I915_WRITE_FW(SPSURF(pipe, plane_id),
  580. intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
  581. POSTING_READ_FW(SPSURF(pipe, plane_id));
  582. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  583. }
  584. static void
  585. vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
  586. {
  587. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  588. enum pipe pipe = plane->pipe;
  589. enum plane_id plane_id = plane->id;
  590. unsigned long irqflags;
  591. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  592. I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
  593. I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
  594. POSTING_READ_FW(SPSURF(pipe, plane_id));
  595. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  596. }
  597. static bool
  598. vlv_plane_get_hw_state(struct intel_plane *plane,
  599. enum pipe *pipe)
  600. {
  601. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  602. enum intel_display_power_domain power_domain;
  603. enum plane_id plane_id = plane->id;
  604. bool ret;
  605. power_domain = POWER_DOMAIN_PIPE(plane->pipe);
  606. if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
  607. return false;
  608. ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
  609. *pipe = plane->pipe;
  610. intel_display_power_put(dev_priv, power_domain);
  611. return ret;
  612. }
  613. static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
  614. const struct intel_plane_state *plane_state)
  615. {
  616. struct drm_i915_private *dev_priv =
  617. to_i915(plane_state->base.plane->dev);
  618. const struct drm_framebuffer *fb = plane_state->base.fb;
  619. unsigned int rotation = plane_state->base.rotation;
  620. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  621. u32 sprctl;
  622. sprctl = SPRITE_ENABLE | SPRITE_GAMMA_ENABLE;
  623. if (IS_IVYBRIDGE(dev_priv))
  624. sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
  625. if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
  626. sprctl |= SPRITE_PIPE_CSC_ENABLE;
  627. switch (fb->format->format) {
  628. case DRM_FORMAT_XBGR8888:
  629. sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
  630. break;
  631. case DRM_FORMAT_XRGB8888:
  632. sprctl |= SPRITE_FORMAT_RGBX888;
  633. break;
  634. case DRM_FORMAT_YUYV:
  635. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
  636. break;
  637. case DRM_FORMAT_YVYU:
  638. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
  639. break;
  640. case DRM_FORMAT_UYVY:
  641. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
  642. break;
  643. case DRM_FORMAT_VYUY:
  644. sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
  645. break;
  646. default:
  647. MISSING_CASE(fb->format->format);
  648. return 0;
  649. }
  650. if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
  651. sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
  652. if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
  653. sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
  654. if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  655. sprctl |= SPRITE_TILED;
  656. if (rotation & DRM_MODE_ROTATE_180)
  657. sprctl |= SPRITE_ROTATE_180;
  658. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  659. sprctl |= SPRITE_DEST_KEY;
  660. else if (key->flags & I915_SET_COLORKEY_SOURCE)
  661. sprctl |= SPRITE_SOURCE_KEY;
  662. return sprctl;
  663. }
  664. static void
  665. ivb_update_plane(struct intel_plane *plane,
  666. const struct intel_crtc_state *crtc_state,
  667. const struct intel_plane_state *plane_state)
  668. {
  669. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  670. const struct drm_framebuffer *fb = plane_state->base.fb;
  671. enum pipe pipe = plane->pipe;
  672. u32 sprctl = plane_state->ctl, sprscale = 0;
  673. u32 sprsurf_offset = plane_state->color_plane[0].offset;
  674. u32 linear_offset;
  675. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  676. int crtc_x = plane_state->base.dst.x1;
  677. int crtc_y = plane_state->base.dst.y1;
  678. uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
  679. uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
  680. uint32_t x = plane_state->color_plane[0].x;
  681. uint32_t y = plane_state->color_plane[0].y;
  682. uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
  683. uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
  684. unsigned long irqflags;
  685. /* Sizes are 0 based */
  686. src_w--;
  687. src_h--;
  688. crtc_w--;
  689. crtc_h--;
  690. if (crtc_w != src_w || crtc_h != src_h)
  691. sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
  692. linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
  693. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  694. if (key->flags) {
  695. I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
  696. I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
  697. I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
  698. }
  699. I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
  700. I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
  701. /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
  702. * register */
  703. if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
  704. I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
  705. else if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  706. I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
  707. else
  708. I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
  709. I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
  710. if (IS_IVYBRIDGE(dev_priv))
  711. I915_WRITE_FW(SPRSCALE(pipe), sprscale);
  712. I915_WRITE_FW(SPRCTL(pipe), sprctl);
  713. I915_WRITE_FW(SPRSURF(pipe),
  714. intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
  715. POSTING_READ_FW(SPRSURF(pipe));
  716. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  717. }
  718. static void
  719. ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
  720. {
  721. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  722. enum pipe pipe = plane->pipe;
  723. unsigned long irqflags;
  724. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  725. I915_WRITE_FW(SPRCTL(pipe), 0);
  726. /* Can't leave the scaler enabled... */
  727. if (IS_IVYBRIDGE(dev_priv))
  728. I915_WRITE_FW(SPRSCALE(pipe), 0);
  729. I915_WRITE_FW(SPRSURF(pipe), 0);
  730. POSTING_READ_FW(SPRSURF(pipe));
  731. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  732. }
  733. static bool
  734. ivb_plane_get_hw_state(struct intel_plane *plane,
  735. enum pipe *pipe)
  736. {
  737. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  738. enum intel_display_power_domain power_domain;
  739. bool ret;
  740. power_domain = POWER_DOMAIN_PIPE(plane->pipe);
  741. if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
  742. return false;
  743. ret = I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
  744. *pipe = plane->pipe;
  745. intel_display_power_put(dev_priv, power_domain);
  746. return ret;
  747. }
  748. static unsigned int
  749. g4x_sprite_max_stride(struct intel_plane *plane,
  750. u32 pixel_format, u64 modifier,
  751. unsigned int rotation)
  752. {
  753. return 16384;
  754. }
  755. static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
  756. const struct intel_plane_state *plane_state)
  757. {
  758. struct drm_i915_private *dev_priv =
  759. to_i915(plane_state->base.plane->dev);
  760. const struct drm_framebuffer *fb = plane_state->base.fb;
  761. unsigned int rotation = plane_state->base.rotation;
  762. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  763. u32 dvscntr;
  764. dvscntr = DVS_ENABLE | DVS_GAMMA_ENABLE;
  765. if (IS_GEN6(dev_priv))
  766. dvscntr |= DVS_TRICKLE_FEED_DISABLE;
  767. switch (fb->format->format) {
  768. case DRM_FORMAT_XBGR8888:
  769. dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
  770. break;
  771. case DRM_FORMAT_XRGB8888:
  772. dvscntr |= DVS_FORMAT_RGBX888;
  773. break;
  774. case DRM_FORMAT_YUYV:
  775. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
  776. break;
  777. case DRM_FORMAT_YVYU:
  778. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
  779. break;
  780. case DRM_FORMAT_UYVY:
  781. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
  782. break;
  783. case DRM_FORMAT_VYUY:
  784. dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
  785. break;
  786. default:
  787. MISSING_CASE(fb->format->format);
  788. return 0;
  789. }
  790. if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
  791. dvscntr |= DVS_YUV_FORMAT_BT709;
  792. if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
  793. dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
  794. if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  795. dvscntr |= DVS_TILED;
  796. if (rotation & DRM_MODE_ROTATE_180)
  797. dvscntr |= DVS_ROTATE_180;
  798. if (key->flags & I915_SET_COLORKEY_DESTINATION)
  799. dvscntr |= DVS_DEST_KEY;
  800. else if (key->flags & I915_SET_COLORKEY_SOURCE)
  801. dvscntr |= DVS_SOURCE_KEY;
  802. return dvscntr;
  803. }
  804. static void
  805. g4x_update_plane(struct intel_plane *plane,
  806. const struct intel_crtc_state *crtc_state,
  807. const struct intel_plane_state *plane_state)
  808. {
  809. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  810. const struct drm_framebuffer *fb = plane_state->base.fb;
  811. enum pipe pipe = plane->pipe;
  812. u32 dvscntr = plane_state->ctl, dvsscale = 0;
  813. u32 dvssurf_offset = plane_state->color_plane[0].offset;
  814. u32 linear_offset;
  815. const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  816. int crtc_x = plane_state->base.dst.x1;
  817. int crtc_y = plane_state->base.dst.y1;
  818. uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
  819. uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
  820. uint32_t x = plane_state->color_plane[0].x;
  821. uint32_t y = plane_state->color_plane[0].y;
  822. uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
  823. uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
  824. unsigned long irqflags;
  825. /* Sizes are 0 based */
  826. src_w--;
  827. src_h--;
  828. crtc_w--;
  829. crtc_h--;
  830. if (crtc_w != src_w || crtc_h != src_h)
  831. dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
  832. linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
  833. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  834. if (key->flags) {
  835. I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
  836. I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
  837. I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
  838. }
  839. I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
  840. I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
  841. if (fb->modifier == I915_FORMAT_MOD_X_TILED)
  842. I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
  843. else
  844. I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
  845. I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
  846. I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
  847. I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
  848. I915_WRITE_FW(DVSSURF(pipe),
  849. intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
  850. POSTING_READ_FW(DVSSURF(pipe));
  851. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  852. }
  853. static void
  854. g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
  855. {
  856. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  857. enum pipe pipe = plane->pipe;
  858. unsigned long irqflags;
  859. spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
  860. I915_WRITE_FW(DVSCNTR(pipe), 0);
  861. /* Disable the scaler */
  862. I915_WRITE_FW(DVSSCALE(pipe), 0);
  863. I915_WRITE_FW(DVSSURF(pipe), 0);
  864. POSTING_READ_FW(DVSSURF(pipe));
  865. spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
  866. }
  867. static bool
  868. g4x_plane_get_hw_state(struct intel_plane *plane,
  869. enum pipe *pipe)
  870. {
  871. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  872. enum intel_display_power_domain power_domain;
  873. bool ret;
  874. power_domain = POWER_DOMAIN_PIPE(plane->pipe);
  875. if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
  876. return false;
  877. ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
  878. *pipe = plane->pipe;
  879. intel_display_power_put(dev_priv, power_domain);
  880. return ret;
  881. }
  882. static int
  883. g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
  884. struct intel_plane_state *plane_state)
  885. {
  886. const struct drm_framebuffer *fb = plane_state->base.fb;
  887. const struct drm_rect *src = &plane_state->base.src;
  888. const struct drm_rect *dst = &plane_state->base.dst;
  889. int src_x, src_y, src_w, src_h, crtc_w, crtc_h;
  890. const struct drm_display_mode *adjusted_mode =
  891. &crtc_state->base.adjusted_mode;
  892. unsigned int cpp = fb->format->cpp[0];
  893. unsigned int width_bytes;
  894. int min_width, min_height;
  895. crtc_w = drm_rect_width(dst);
  896. crtc_h = drm_rect_height(dst);
  897. src_x = src->x1 >> 16;
  898. src_y = src->y1 >> 16;
  899. src_w = drm_rect_width(src) >> 16;
  900. src_h = drm_rect_height(src) >> 16;
  901. if (src_w == crtc_w && src_h == crtc_h)
  902. return 0;
  903. min_width = 3;
  904. if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
  905. if (src_h & 1) {
  906. DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
  907. return -EINVAL;
  908. }
  909. min_height = 6;
  910. } else {
  911. min_height = 3;
  912. }
  913. width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
  914. if (src_w < min_width || src_h < min_height ||
  915. src_w > 2048 || src_h > 2048) {
  916. DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
  917. src_w, src_h, min_width, min_height, 2048, 2048);
  918. return -EINVAL;
  919. }
  920. if (width_bytes > 4096) {
  921. DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
  922. width_bytes, 4096);
  923. return -EINVAL;
  924. }
  925. if (width_bytes > 4096 || fb->pitches[0] > 4096) {
  926. DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
  927. fb->pitches[0], 4096);
  928. return -EINVAL;
  929. }
  930. return 0;
  931. }
  932. static int
  933. g4x_sprite_check(struct intel_crtc_state *crtc_state,
  934. struct intel_plane_state *plane_state)
  935. {
  936. struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
  937. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  938. int max_scale, min_scale;
  939. int ret;
  940. if (INTEL_GEN(dev_priv) < 7) {
  941. min_scale = 1;
  942. max_scale = 16 << 16;
  943. } else if (IS_IVYBRIDGE(dev_priv)) {
  944. min_scale = 1;
  945. max_scale = 2 << 16;
  946. } else {
  947. min_scale = DRM_PLANE_HELPER_NO_SCALING;
  948. max_scale = DRM_PLANE_HELPER_NO_SCALING;
  949. }
  950. ret = drm_atomic_helper_check_plane_state(&plane_state->base,
  951. &crtc_state->base,
  952. min_scale, max_scale,
  953. true, true);
  954. if (ret)
  955. return ret;
  956. if (!plane_state->base.visible)
  957. return 0;
  958. ret = intel_plane_check_src_coordinates(plane_state);
  959. if (ret)
  960. return ret;
  961. ret = g4x_sprite_check_scaling(crtc_state, plane_state);
  962. if (ret)
  963. return ret;
  964. ret = i9xx_check_plane_surface(plane_state);
  965. if (ret)
  966. return ret;
  967. if (INTEL_GEN(dev_priv) >= 7)
  968. plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
  969. else
  970. plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
  971. return 0;
  972. }
  973. int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
  974. {
  975. struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
  976. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  977. unsigned int rotation = plane_state->base.rotation;
  978. /* CHV ignores the mirror bit when the rotate bit is set :( */
  979. if (IS_CHERRYVIEW(dev_priv) &&
  980. rotation & DRM_MODE_ROTATE_180 &&
  981. rotation & DRM_MODE_REFLECT_X) {
  982. DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
  983. return -EINVAL;
  984. }
  985. return 0;
  986. }
  987. static int
  988. vlv_sprite_check(struct intel_crtc_state *crtc_state,
  989. struct intel_plane_state *plane_state)
  990. {
  991. int ret;
  992. ret = chv_plane_check_rotation(plane_state);
  993. if (ret)
  994. return ret;
  995. ret = drm_atomic_helper_check_plane_state(&plane_state->base,
  996. &crtc_state->base,
  997. DRM_PLANE_HELPER_NO_SCALING,
  998. DRM_PLANE_HELPER_NO_SCALING,
  999. true, true);
  1000. if (ret)
  1001. return ret;
  1002. if (!plane_state->base.visible)
  1003. return 0;
  1004. ret = intel_plane_check_src_coordinates(plane_state);
  1005. if (ret)
  1006. return ret;
  1007. ret = i9xx_check_plane_surface(plane_state);
  1008. if (ret)
  1009. return ret;
  1010. plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
  1011. return 0;
  1012. }
  1013. static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
  1014. const struct intel_plane_state *plane_state)
  1015. {
  1016. const struct drm_framebuffer *fb = plane_state->base.fb;
  1017. unsigned int rotation = plane_state->base.rotation;
  1018. struct drm_format_name_buf format_name;
  1019. if (!fb)
  1020. return 0;
  1021. if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
  1022. is_ccs_modifier(fb->modifier)) {
  1023. DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
  1024. rotation);
  1025. return -EINVAL;
  1026. }
  1027. if (rotation & DRM_MODE_REFLECT_X &&
  1028. fb->modifier == DRM_FORMAT_MOD_LINEAR) {
  1029. DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
  1030. return -EINVAL;
  1031. }
  1032. if (drm_rotation_90_or_270(rotation)) {
  1033. if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
  1034. fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
  1035. DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
  1036. return -EINVAL;
  1037. }
  1038. /*
  1039. * 90/270 is not allowed with RGB64 16:16:16:16,
  1040. * RGB 16-bit 5:6:5, and Indexed 8-bit.
  1041. * TBD: Add RGB64 case once its added in supported format list.
  1042. */
  1043. switch (fb->format->format) {
  1044. case DRM_FORMAT_C8:
  1045. case DRM_FORMAT_RGB565:
  1046. DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
  1047. drm_get_format_name(fb->format->format,
  1048. &format_name));
  1049. return -EINVAL;
  1050. default:
  1051. break;
  1052. }
  1053. }
  1054. /* Y-tiling is not supported in IF-ID Interlace mode */
  1055. if (crtc_state->base.enable &&
  1056. crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
  1057. (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
  1058. fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
  1059. fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
  1060. fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) {
  1061. DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
  1062. return -EINVAL;
  1063. }
  1064. return 0;
  1065. }
  1066. static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
  1067. const struct intel_plane_state *plane_state)
  1068. {
  1069. struct drm_i915_private *dev_priv =
  1070. to_i915(plane_state->base.plane->dev);
  1071. int crtc_x = plane_state->base.dst.x1;
  1072. int crtc_w = drm_rect_width(&plane_state->base.dst);
  1073. int pipe_src_w = crtc_state->pipe_src_w;
  1074. /*
  1075. * Display WA #1175: cnl,glk
  1076. * Planes other than the cursor may cause FIFO underflow and display
  1077. * corruption if starting less than 4 pixels from the right edge of
  1078. * the screen.
  1079. * Besides the above WA fix the similar problem, where planes other
  1080. * than the cursor ending less than 4 pixels from the left edge of the
  1081. * screen may cause FIFO underflow and display corruption.
  1082. */
  1083. if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
  1084. (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
  1085. DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
  1086. crtc_x + crtc_w < 4 ? "end" : "start",
  1087. crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
  1088. 4, pipe_src_w - 4);
  1089. return -ERANGE;
  1090. }
  1091. return 0;
  1092. }
  1093. int skl_plane_check(struct intel_crtc_state *crtc_state,
  1094. struct intel_plane_state *plane_state)
  1095. {
  1096. struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
  1097. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  1098. int max_scale, min_scale;
  1099. int ret;
  1100. ret = skl_plane_check_fb(crtc_state, plane_state);
  1101. if (ret)
  1102. return ret;
  1103. /* use scaler when colorkey is not required */
  1104. if (!plane_state->ckey.flags) {
  1105. const struct drm_framebuffer *fb = plane_state->base.fb;
  1106. min_scale = 1;
  1107. max_scale = skl_max_scale(crtc_state,
  1108. fb ? fb->format->format : 0);
  1109. } else {
  1110. min_scale = DRM_PLANE_HELPER_NO_SCALING;
  1111. max_scale = DRM_PLANE_HELPER_NO_SCALING;
  1112. }
  1113. ret = drm_atomic_helper_check_plane_state(&plane_state->base,
  1114. &crtc_state->base,
  1115. min_scale, max_scale,
  1116. true, true);
  1117. if (ret)
  1118. return ret;
  1119. if (!plane_state->base.visible)
  1120. return 0;
  1121. ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
  1122. if (ret)
  1123. return ret;
  1124. ret = intel_plane_check_src_coordinates(plane_state);
  1125. if (ret)
  1126. return ret;
  1127. ret = skl_check_plane_surface(plane_state);
  1128. if (ret)
  1129. return ret;
  1130. plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
  1131. if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
  1132. plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
  1133. plane_state);
  1134. return 0;
  1135. }
  1136. static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
  1137. {
  1138. return INTEL_GEN(dev_priv) >= 9;
  1139. }
  1140. static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
  1141. const struct drm_intel_sprite_colorkey *set)
  1142. {
  1143. struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
  1144. struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
  1145. struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
  1146. *key = *set;
  1147. /*
  1148. * We want src key enabled on the
  1149. * sprite and not on the primary.
  1150. */
  1151. if (plane->id == PLANE_PRIMARY &&
  1152. set->flags & I915_SET_COLORKEY_SOURCE)
  1153. key->flags = 0;
  1154. /*
  1155. * On SKL+ we want dst key enabled on
  1156. * the primary and not on the sprite.
  1157. */
  1158. if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
  1159. set->flags & I915_SET_COLORKEY_DESTINATION)
  1160. key->flags = 0;
  1161. }
  1162. int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
  1163. struct drm_file *file_priv)
  1164. {
  1165. struct drm_i915_private *dev_priv = to_i915(dev);
  1166. struct drm_intel_sprite_colorkey *set = data;
  1167. struct drm_plane *plane;
  1168. struct drm_plane_state *plane_state;
  1169. struct drm_atomic_state *state;
  1170. struct drm_modeset_acquire_ctx ctx;
  1171. int ret = 0;
  1172. /* ignore the pointless "none" flag */
  1173. set->flags &= ~I915_SET_COLORKEY_NONE;
  1174. if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
  1175. return -EINVAL;
  1176. /* Make sure we don't try to enable both src & dest simultaneously */
  1177. if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
  1178. return -EINVAL;
  1179. if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
  1180. set->flags & I915_SET_COLORKEY_DESTINATION)
  1181. return -EINVAL;
  1182. plane = drm_plane_find(dev, file_priv, set->plane_id);
  1183. if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
  1184. return -ENOENT;
  1185. /*
  1186. * SKL+ only plane 2 can do destination keying against plane 1.
  1187. * Also multiple planes can't do destination keying on the same
  1188. * pipe simultaneously.
  1189. */
  1190. if (INTEL_GEN(dev_priv) >= 9 &&
  1191. to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
  1192. set->flags & I915_SET_COLORKEY_DESTINATION)
  1193. return -EINVAL;
  1194. drm_modeset_acquire_init(&ctx, 0);
  1195. state = drm_atomic_state_alloc(plane->dev);
  1196. if (!state) {
  1197. ret = -ENOMEM;
  1198. goto out;
  1199. }
  1200. state->acquire_ctx = &ctx;
  1201. while (1) {
  1202. plane_state = drm_atomic_get_plane_state(state, plane);
  1203. ret = PTR_ERR_OR_ZERO(plane_state);
  1204. if (!ret)
  1205. intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
  1206. /*
  1207. * On some platforms we have to configure
  1208. * the dst colorkey on the primary plane.
  1209. */
  1210. if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
  1211. struct intel_crtc *crtc =
  1212. intel_get_crtc_for_pipe(dev_priv,
  1213. to_intel_plane(plane)->pipe);
  1214. plane_state = drm_atomic_get_plane_state(state,
  1215. crtc->base.primary);
  1216. ret = PTR_ERR_OR_ZERO(plane_state);
  1217. if (!ret)
  1218. intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
  1219. }
  1220. if (!ret)
  1221. ret = drm_atomic_commit(state);
  1222. if (ret != -EDEADLK)
  1223. break;
  1224. drm_atomic_state_clear(state);
  1225. drm_modeset_backoff(&ctx);
  1226. }
  1227. drm_atomic_state_put(state);
  1228. out:
  1229. drm_modeset_drop_locks(&ctx);
  1230. drm_modeset_acquire_fini(&ctx);
  1231. return ret;
  1232. }
  1233. static const uint32_t g4x_plane_formats[] = {
  1234. DRM_FORMAT_XRGB8888,
  1235. DRM_FORMAT_YUYV,
  1236. DRM_FORMAT_YVYU,
  1237. DRM_FORMAT_UYVY,
  1238. DRM_FORMAT_VYUY,
  1239. };
  1240. static const uint64_t i9xx_plane_format_modifiers[] = {
  1241. I915_FORMAT_MOD_X_TILED,
  1242. DRM_FORMAT_MOD_LINEAR,
  1243. DRM_FORMAT_MOD_INVALID
  1244. };
  1245. static const uint32_t snb_plane_formats[] = {
  1246. DRM_FORMAT_XBGR8888,
  1247. DRM_FORMAT_XRGB8888,
  1248. DRM_FORMAT_YUYV,
  1249. DRM_FORMAT_YVYU,
  1250. DRM_FORMAT_UYVY,
  1251. DRM_FORMAT_VYUY,
  1252. };
  1253. static const uint32_t vlv_plane_formats[] = {
  1254. DRM_FORMAT_RGB565,
  1255. DRM_FORMAT_ABGR8888,
  1256. DRM_FORMAT_ARGB8888,
  1257. DRM_FORMAT_XBGR8888,
  1258. DRM_FORMAT_XRGB8888,
  1259. DRM_FORMAT_XBGR2101010,
  1260. DRM_FORMAT_ABGR2101010,
  1261. DRM_FORMAT_YUYV,
  1262. DRM_FORMAT_YVYU,
  1263. DRM_FORMAT_UYVY,
  1264. DRM_FORMAT_VYUY,
  1265. };
  1266. static uint32_t skl_plane_formats[] = {
  1267. DRM_FORMAT_RGB565,
  1268. DRM_FORMAT_ABGR8888,
  1269. DRM_FORMAT_ARGB8888,
  1270. DRM_FORMAT_XBGR8888,
  1271. DRM_FORMAT_XRGB8888,
  1272. DRM_FORMAT_YUYV,
  1273. DRM_FORMAT_YVYU,
  1274. DRM_FORMAT_UYVY,
  1275. DRM_FORMAT_VYUY,
  1276. };
  1277. static uint32_t skl_planar_formats[] = {
  1278. DRM_FORMAT_RGB565,
  1279. DRM_FORMAT_ABGR8888,
  1280. DRM_FORMAT_ARGB8888,
  1281. DRM_FORMAT_XBGR8888,
  1282. DRM_FORMAT_XRGB8888,
  1283. DRM_FORMAT_YUYV,
  1284. DRM_FORMAT_YVYU,
  1285. DRM_FORMAT_UYVY,
  1286. DRM_FORMAT_VYUY,
  1287. DRM_FORMAT_NV12,
  1288. };
  1289. static const uint64_t skl_plane_format_modifiers_noccs[] = {
  1290. I915_FORMAT_MOD_Yf_TILED,
  1291. I915_FORMAT_MOD_Y_TILED,
  1292. I915_FORMAT_MOD_X_TILED,
  1293. DRM_FORMAT_MOD_LINEAR,
  1294. DRM_FORMAT_MOD_INVALID
  1295. };
  1296. static const uint64_t skl_plane_format_modifiers_ccs[] = {
  1297. I915_FORMAT_MOD_Yf_TILED_CCS,
  1298. I915_FORMAT_MOD_Y_TILED_CCS,
  1299. I915_FORMAT_MOD_Yf_TILED,
  1300. I915_FORMAT_MOD_Y_TILED,
  1301. I915_FORMAT_MOD_X_TILED,
  1302. DRM_FORMAT_MOD_LINEAR,
  1303. DRM_FORMAT_MOD_INVALID
  1304. };
  1305. static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
  1306. u32 format, u64 modifier)
  1307. {
  1308. switch (modifier) {
  1309. case DRM_FORMAT_MOD_LINEAR:
  1310. case I915_FORMAT_MOD_X_TILED:
  1311. break;
  1312. default:
  1313. return false;
  1314. }
  1315. switch (format) {
  1316. case DRM_FORMAT_XRGB8888:
  1317. case DRM_FORMAT_YUYV:
  1318. case DRM_FORMAT_YVYU:
  1319. case DRM_FORMAT_UYVY:
  1320. case DRM_FORMAT_VYUY:
  1321. if (modifier == DRM_FORMAT_MOD_LINEAR ||
  1322. modifier == I915_FORMAT_MOD_X_TILED)
  1323. return true;
  1324. /* fall through */
  1325. default:
  1326. return false;
  1327. }
  1328. }
  1329. static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
  1330. u32 format, u64 modifier)
  1331. {
  1332. switch (modifier) {
  1333. case DRM_FORMAT_MOD_LINEAR:
  1334. case I915_FORMAT_MOD_X_TILED:
  1335. break;
  1336. default:
  1337. return false;
  1338. }
  1339. switch (format) {
  1340. case DRM_FORMAT_XRGB8888:
  1341. case DRM_FORMAT_XBGR8888:
  1342. case DRM_FORMAT_YUYV:
  1343. case DRM_FORMAT_YVYU:
  1344. case DRM_FORMAT_UYVY:
  1345. case DRM_FORMAT_VYUY:
  1346. if (modifier == DRM_FORMAT_MOD_LINEAR ||
  1347. modifier == I915_FORMAT_MOD_X_TILED)
  1348. return true;
  1349. /* fall through */
  1350. default:
  1351. return false;
  1352. }
  1353. }
  1354. static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
  1355. u32 format, u64 modifier)
  1356. {
  1357. switch (modifier) {
  1358. case DRM_FORMAT_MOD_LINEAR:
  1359. case I915_FORMAT_MOD_X_TILED:
  1360. break;
  1361. default:
  1362. return false;
  1363. }
  1364. switch (format) {
  1365. case DRM_FORMAT_RGB565:
  1366. case DRM_FORMAT_ABGR8888:
  1367. case DRM_FORMAT_ARGB8888:
  1368. case DRM_FORMAT_XBGR8888:
  1369. case DRM_FORMAT_XRGB8888:
  1370. case DRM_FORMAT_XBGR2101010:
  1371. case DRM_FORMAT_ABGR2101010:
  1372. case DRM_FORMAT_YUYV:
  1373. case DRM_FORMAT_YVYU:
  1374. case DRM_FORMAT_UYVY:
  1375. case DRM_FORMAT_VYUY:
  1376. if (modifier == DRM_FORMAT_MOD_LINEAR ||
  1377. modifier == I915_FORMAT_MOD_X_TILED)
  1378. return true;
  1379. /* fall through */
  1380. default:
  1381. return false;
  1382. }
  1383. }
  1384. static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
  1385. u32 format, u64 modifier)
  1386. {
  1387. struct intel_plane *plane = to_intel_plane(_plane);
  1388. switch (modifier) {
  1389. case DRM_FORMAT_MOD_LINEAR:
  1390. case I915_FORMAT_MOD_X_TILED:
  1391. case I915_FORMAT_MOD_Y_TILED:
  1392. case I915_FORMAT_MOD_Yf_TILED:
  1393. break;
  1394. case I915_FORMAT_MOD_Y_TILED_CCS:
  1395. case I915_FORMAT_MOD_Yf_TILED_CCS:
  1396. if (!plane->has_ccs)
  1397. return false;
  1398. break;
  1399. default:
  1400. return false;
  1401. }
  1402. switch (format) {
  1403. case DRM_FORMAT_XRGB8888:
  1404. case DRM_FORMAT_XBGR8888:
  1405. case DRM_FORMAT_ARGB8888:
  1406. case DRM_FORMAT_ABGR8888:
  1407. if (is_ccs_modifier(modifier))
  1408. return true;
  1409. /* fall through */
  1410. case DRM_FORMAT_RGB565:
  1411. case DRM_FORMAT_XRGB2101010:
  1412. case DRM_FORMAT_XBGR2101010:
  1413. case DRM_FORMAT_YUYV:
  1414. case DRM_FORMAT_YVYU:
  1415. case DRM_FORMAT_UYVY:
  1416. case DRM_FORMAT_VYUY:
  1417. case DRM_FORMAT_NV12:
  1418. if (modifier == I915_FORMAT_MOD_Yf_TILED)
  1419. return true;
  1420. /* fall through */
  1421. case DRM_FORMAT_C8:
  1422. if (modifier == DRM_FORMAT_MOD_LINEAR ||
  1423. modifier == I915_FORMAT_MOD_X_TILED ||
  1424. modifier == I915_FORMAT_MOD_Y_TILED)
  1425. return true;
  1426. /* fall through */
  1427. default:
  1428. return false;
  1429. }
  1430. }
  1431. static const struct drm_plane_funcs g4x_sprite_funcs = {
  1432. .update_plane = drm_atomic_helper_update_plane,
  1433. .disable_plane = drm_atomic_helper_disable_plane,
  1434. .destroy = intel_plane_destroy,
  1435. .atomic_get_property = intel_plane_atomic_get_property,
  1436. .atomic_set_property = intel_plane_atomic_set_property,
  1437. .atomic_duplicate_state = intel_plane_duplicate_state,
  1438. .atomic_destroy_state = intel_plane_destroy_state,
  1439. .format_mod_supported = g4x_sprite_format_mod_supported,
  1440. };
  1441. static const struct drm_plane_funcs snb_sprite_funcs = {
  1442. .update_plane = drm_atomic_helper_update_plane,
  1443. .disable_plane = drm_atomic_helper_disable_plane,
  1444. .destroy = intel_plane_destroy,
  1445. .atomic_get_property = intel_plane_atomic_get_property,
  1446. .atomic_set_property = intel_plane_atomic_set_property,
  1447. .atomic_duplicate_state = intel_plane_duplicate_state,
  1448. .atomic_destroy_state = intel_plane_destroy_state,
  1449. .format_mod_supported = snb_sprite_format_mod_supported,
  1450. };
  1451. static const struct drm_plane_funcs vlv_sprite_funcs = {
  1452. .update_plane = drm_atomic_helper_update_plane,
  1453. .disable_plane = drm_atomic_helper_disable_plane,
  1454. .destroy = intel_plane_destroy,
  1455. .atomic_get_property = intel_plane_atomic_get_property,
  1456. .atomic_set_property = intel_plane_atomic_set_property,
  1457. .atomic_duplicate_state = intel_plane_duplicate_state,
  1458. .atomic_destroy_state = intel_plane_destroy_state,
  1459. .format_mod_supported = vlv_sprite_format_mod_supported,
  1460. };
  1461. static const struct drm_plane_funcs skl_plane_funcs = {
  1462. .update_plane = drm_atomic_helper_update_plane,
  1463. .disable_plane = drm_atomic_helper_disable_plane,
  1464. .destroy = intel_plane_destroy,
  1465. .atomic_get_property = intel_plane_atomic_get_property,
  1466. .atomic_set_property = intel_plane_atomic_set_property,
  1467. .atomic_duplicate_state = intel_plane_duplicate_state,
  1468. .atomic_destroy_state = intel_plane_destroy_state,
  1469. .format_mod_supported = skl_plane_format_mod_supported,
  1470. };
  1471. bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
  1472. enum pipe pipe, enum plane_id plane_id)
  1473. {
  1474. if (plane_id == PLANE_CURSOR)
  1475. return false;
  1476. if (INTEL_GEN(dev_priv) >= 10)
  1477. return true;
  1478. if (IS_GEMINILAKE(dev_priv))
  1479. return pipe != PIPE_C;
  1480. return pipe != PIPE_C &&
  1481. (plane_id == PLANE_PRIMARY ||
  1482. plane_id == PLANE_SPRITE0);
  1483. }
  1484. struct intel_plane *
  1485. intel_sprite_plane_create(struct drm_i915_private *dev_priv,
  1486. enum pipe pipe, int plane)
  1487. {
  1488. struct intel_plane *intel_plane = NULL;
  1489. struct intel_plane_state *state = NULL;
  1490. const struct drm_plane_funcs *plane_funcs;
  1491. unsigned long possible_crtcs;
  1492. const uint32_t *plane_formats;
  1493. const uint64_t *modifiers;
  1494. unsigned int supported_rotations;
  1495. int num_plane_formats;
  1496. int ret;
  1497. intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
  1498. if (!intel_plane) {
  1499. ret = -ENOMEM;
  1500. goto fail;
  1501. }
  1502. state = intel_create_plane_state(&intel_plane->base);
  1503. if (!state) {
  1504. ret = -ENOMEM;
  1505. goto fail;
  1506. }
  1507. intel_plane->base.state = &state->base;
  1508. if (INTEL_GEN(dev_priv) >= 9) {
  1509. state->scaler_id = -1;
  1510. intel_plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe,
  1511. PLANE_SPRITE0 + plane);
  1512. intel_plane->max_stride = skl_plane_max_stride;
  1513. intel_plane->update_plane = skl_update_plane;
  1514. intel_plane->disable_plane = skl_disable_plane;
  1515. intel_plane->get_hw_state = skl_plane_get_hw_state;
  1516. intel_plane->check_plane = skl_plane_check;
  1517. if (skl_plane_has_planar(dev_priv, pipe,
  1518. PLANE_SPRITE0 + plane)) {
  1519. plane_formats = skl_planar_formats;
  1520. num_plane_formats = ARRAY_SIZE(skl_planar_formats);
  1521. } else {
  1522. plane_formats = skl_plane_formats;
  1523. num_plane_formats = ARRAY_SIZE(skl_plane_formats);
  1524. }
  1525. if (intel_plane->has_ccs)
  1526. modifiers = skl_plane_format_modifiers_ccs;
  1527. else
  1528. modifiers = skl_plane_format_modifiers_noccs;
  1529. plane_funcs = &skl_plane_funcs;
  1530. } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
  1531. intel_plane->max_stride = i9xx_plane_max_stride;
  1532. intel_plane->update_plane = vlv_update_plane;
  1533. intel_plane->disable_plane = vlv_disable_plane;
  1534. intel_plane->get_hw_state = vlv_plane_get_hw_state;
  1535. intel_plane->check_plane = vlv_sprite_check;
  1536. plane_formats = vlv_plane_formats;
  1537. num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
  1538. modifiers = i9xx_plane_format_modifiers;
  1539. plane_funcs = &vlv_sprite_funcs;
  1540. } else if (INTEL_GEN(dev_priv) >= 7) {
  1541. intel_plane->max_stride = g4x_sprite_max_stride;
  1542. intel_plane->update_plane = ivb_update_plane;
  1543. intel_plane->disable_plane = ivb_disable_plane;
  1544. intel_plane->get_hw_state = ivb_plane_get_hw_state;
  1545. intel_plane->check_plane = g4x_sprite_check;
  1546. plane_formats = snb_plane_formats;
  1547. num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1548. modifiers = i9xx_plane_format_modifiers;
  1549. plane_funcs = &snb_sprite_funcs;
  1550. } else {
  1551. intel_plane->max_stride = g4x_sprite_max_stride;
  1552. intel_plane->update_plane = g4x_update_plane;
  1553. intel_plane->disable_plane = g4x_disable_plane;
  1554. intel_plane->get_hw_state = g4x_plane_get_hw_state;
  1555. intel_plane->check_plane = g4x_sprite_check;
  1556. modifiers = i9xx_plane_format_modifiers;
  1557. if (IS_GEN6(dev_priv)) {
  1558. plane_formats = snb_plane_formats;
  1559. num_plane_formats = ARRAY_SIZE(snb_plane_formats);
  1560. plane_funcs = &snb_sprite_funcs;
  1561. } else {
  1562. plane_formats = g4x_plane_formats;
  1563. num_plane_formats = ARRAY_SIZE(g4x_plane_formats);
  1564. plane_funcs = &g4x_sprite_funcs;
  1565. }
  1566. }
  1567. if (INTEL_GEN(dev_priv) >= 9) {
  1568. supported_rotations =
  1569. DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
  1570. DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
  1571. } else if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
  1572. supported_rotations =
  1573. DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
  1574. DRM_MODE_REFLECT_X;
  1575. } else {
  1576. supported_rotations =
  1577. DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
  1578. }
  1579. intel_plane->pipe = pipe;
  1580. intel_plane->i9xx_plane = plane;
  1581. intel_plane->id = PLANE_SPRITE0 + plane;
  1582. intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, intel_plane->id);
  1583. possible_crtcs = (1 << pipe);
  1584. if (INTEL_GEN(dev_priv) >= 9)
  1585. ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
  1586. possible_crtcs, plane_funcs,
  1587. plane_formats, num_plane_formats,
  1588. modifiers,
  1589. DRM_PLANE_TYPE_OVERLAY,
  1590. "plane %d%c", plane + 2, pipe_name(pipe));
  1591. else
  1592. ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
  1593. possible_crtcs, plane_funcs,
  1594. plane_formats, num_plane_formats,
  1595. modifiers,
  1596. DRM_PLANE_TYPE_OVERLAY,
  1597. "sprite %c", sprite_name(pipe, plane));
  1598. if (ret)
  1599. goto fail;
  1600. drm_plane_create_rotation_property(&intel_plane->base,
  1601. DRM_MODE_ROTATE_0,
  1602. supported_rotations);
  1603. drm_plane_create_color_properties(&intel_plane->base,
  1604. BIT(DRM_COLOR_YCBCR_BT601) |
  1605. BIT(DRM_COLOR_YCBCR_BT709),
  1606. BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
  1607. BIT(DRM_COLOR_YCBCR_FULL_RANGE),
  1608. DRM_COLOR_YCBCR_BT709,
  1609. DRM_COLOR_YCBCR_LIMITED_RANGE);
  1610. drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
  1611. return intel_plane;
  1612. fail:
  1613. kfree(state);
  1614. kfree(intel_plane);
  1615. return ERR_PTR(ret);
  1616. }