intel_overlay.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459
  1. /*
  2. * Copyright © 2009
  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. * Daniel Vetter <daniel@ffwll.ch>
  25. *
  26. * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
  27. */
  28. #include <linux/seq_file.h>
  29. #include "drmP.h"
  30. #include "drm.h"
  31. #include "i915_drm.h"
  32. #include "i915_drv.h"
  33. #include "i915_reg.h"
  34. #include "intel_drv.h"
  35. /* Limits for overlay size. According to intel doc, the real limits are:
  36. * Y width: 4095, UV width (planar): 2047, Y height: 2047,
  37. * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use
  38. * the mininum of both. */
  39. #define IMAGE_MAX_WIDTH 2048
  40. #define IMAGE_MAX_HEIGHT 2046 /* 2 * 1023 */
  41. /* on 830 and 845 these large limits result in the card hanging */
  42. #define IMAGE_MAX_WIDTH_LEGACY 1024
  43. #define IMAGE_MAX_HEIGHT_LEGACY 1088
  44. /* overlay register definitions */
  45. /* OCMD register */
  46. #define OCMD_TILED_SURFACE (0x1<<19)
  47. #define OCMD_MIRROR_MASK (0x3<<17)
  48. #define OCMD_MIRROR_MODE (0x3<<17)
  49. #define OCMD_MIRROR_HORIZONTAL (0x1<<17)
  50. #define OCMD_MIRROR_VERTICAL (0x2<<17)
  51. #define OCMD_MIRROR_BOTH (0x3<<17)
  52. #define OCMD_BYTEORDER_MASK (0x3<<14) /* zero for YUYV or FOURCC YUY2 */
  53. #define OCMD_UV_SWAP (0x1<<14) /* YVYU */
  54. #define OCMD_Y_SWAP (0x2<<14) /* UYVY or FOURCC UYVY */
  55. #define OCMD_Y_AND_UV_SWAP (0x3<<14) /* VYUY */
  56. #define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
  57. #define OCMD_RGB_888 (0x1<<10) /* not in i965 Intel docs */
  58. #define OCMD_RGB_555 (0x2<<10) /* not in i965 Intel docs */
  59. #define OCMD_RGB_565 (0x3<<10) /* not in i965 Intel docs */
  60. #define OCMD_YUV_422_PACKED (0x8<<10)
  61. #define OCMD_YUV_411_PACKED (0x9<<10) /* not in i965 Intel docs */
  62. #define OCMD_YUV_420_PLANAR (0xc<<10)
  63. #define OCMD_YUV_422_PLANAR (0xd<<10)
  64. #define OCMD_YUV_410_PLANAR (0xe<<10) /* also 411 */
  65. #define OCMD_TVSYNCFLIP_PARITY (0x1<<9)
  66. #define OCMD_TVSYNCFLIP_ENABLE (0x1<<7)
  67. #define OCMD_BUF_TYPE_MASK (0x1<<5)
  68. #define OCMD_BUF_TYPE_FRAME (0x0<<5)
  69. #define OCMD_BUF_TYPE_FIELD (0x1<<5)
  70. #define OCMD_TEST_MODE (0x1<<4)
  71. #define OCMD_BUFFER_SELECT (0x3<<2)
  72. #define OCMD_BUFFER0 (0x0<<2)
  73. #define OCMD_BUFFER1 (0x1<<2)
  74. #define OCMD_FIELD_SELECT (0x1<<2)
  75. #define OCMD_FIELD0 (0x0<<1)
  76. #define OCMD_FIELD1 (0x1<<1)
  77. #define OCMD_ENABLE (0x1<<0)
  78. /* OCONFIG register */
  79. #define OCONF_PIPE_MASK (0x1<<18)
  80. #define OCONF_PIPE_A (0x0<<18)
  81. #define OCONF_PIPE_B (0x1<<18)
  82. #define OCONF_GAMMA2_ENABLE (0x1<<16)
  83. #define OCONF_CSC_MODE_BT601 (0x0<<5)
  84. #define OCONF_CSC_MODE_BT709 (0x1<<5)
  85. #define OCONF_CSC_BYPASS (0x1<<4)
  86. #define OCONF_CC_OUT_8BIT (0x1<<3)
  87. #define OCONF_TEST_MODE (0x1<<2)
  88. #define OCONF_THREE_LINE_BUFFER (0x1<<0)
  89. #define OCONF_TWO_LINE_BUFFER (0x0<<0)
  90. /* DCLRKM (dst-key) register */
  91. #define DST_KEY_ENABLE (0x1<<31)
  92. #define CLK_RGB24_MASK 0x0
  93. #define CLK_RGB16_MASK 0x070307
  94. #define CLK_RGB15_MASK 0x070707
  95. #define CLK_RGB8I_MASK 0xffffff
  96. #define RGB16_TO_COLORKEY(c) \
  97. (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
  98. #define RGB15_TO_COLORKEY(c) \
  99. (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
  100. /* overlay flip addr flag */
  101. #define OFC_UPDATE 0x1
  102. /* polyphase filter coefficients */
  103. #define N_HORIZ_Y_TAPS 5
  104. #define N_VERT_Y_TAPS 3
  105. #define N_HORIZ_UV_TAPS 3
  106. #define N_VERT_UV_TAPS 3
  107. #define N_PHASES 17
  108. #define MAX_TAPS 5
  109. /* memory bufferd overlay registers */
  110. struct overlay_registers {
  111. u32 OBUF_0Y;
  112. u32 OBUF_1Y;
  113. u32 OBUF_0U;
  114. u32 OBUF_0V;
  115. u32 OBUF_1U;
  116. u32 OBUF_1V;
  117. u32 OSTRIDE;
  118. u32 YRGB_VPH;
  119. u32 UV_VPH;
  120. u32 HORZ_PH;
  121. u32 INIT_PHS;
  122. u32 DWINPOS;
  123. u32 DWINSZ;
  124. u32 SWIDTH;
  125. u32 SWIDTHSW;
  126. u32 SHEIGHT;
  127. u32 YRGBSCALE;
  128. u32 UVSCALE;
  129. u32 OCLRC0;
  130. u32 OCLRC1;
  131. u32 DCLRKV;
  132. u32 DCLRKM;
  133. u32 SCLRKVH;
  134. u32 SCLRKVL;
  135. u32 SCLRKEN;
  136. u32 OCONFIG;
  137. u32 OCMD;
  138. u32 RESERVED1; /* 0x6C */
  139. u32 OSTART_0Y;
  140. u32 OSTART_1Y;
  141. u32 OSTART_0U;
  142. u32 OSTART_0V;
  143. u32 OSTART_1U;
  144. u32 OSTART_1V;
  145. u32 OTILEOFF_0Y;
  146. u32 OTILEOFF_1Y;
  147. u32 OTILEOFF_0U;
  148. u32 OTILEOFF_0V;
  149. u32 OTILEOFF_1U;
  150. u32 OTILEOFF_1V;
  151. u32 FASTHSCALE; /* 0xA0 */
  152. u32 UVSCALEV; /* 0xA4 */
  153. u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */
  154. u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */
  155. u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES];
  156. u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */
  157. u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES];
  158. u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */
  159. u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES];
  160. u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */
  161. u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
  162. };
  163. static struct overlay_registers *
  164. intel_overlay_map_regs_atomic(struct intel_overlay *overlay,
  165. int slot)
  166. {
  167. drm_i915_private_t *dev_priv = overlay->dev->dev_private;
  168. struct overlay_registers *regs;
  169. if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
  170. regs = overlay->reg_bo->phys_obj->handle->vaddr;
  171. else
  172. regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
  173. overlay->reg_bo->gtt_offset,
  174. slot);
  175. return regs;
  176. }
  177. static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
  178. int slot,
  179. struct overlay_registers *regs)
  180. {
  181. if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
  182. io_mapping_unmap_atomic(regs, slot);
  183. }
  184. static struct overlay_registers *
  185. intel_overlay_map_regs(struct intel_overlay *overlay)
  186. {
  187. drm_i915_private_t *dev_priv = overlay->dev->dev_private;
  188. struct overlay_registers *regs;
  189. if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
  190. regs = overlay->reg_bo->phys_obj->handle->vaddr;
  191. else
  192. regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping,
  193. overlay->reg_bo->gtt_offset);
  194. return regs;
  195. }
  196. static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
  197. struct overlay_registers *regs)
  198. {
  199. if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
  200. io_mapping_unmap(regs);
  201. }
  202. static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
  203. bool interruptible,
  204. int stage)
  205. {
  206. struct drm_device *dev = overlay->dev;
  207. drm_i915_private_t *dev_priv = dev->dev_private;
  208. int ret;
  209. overlay->last_flip_req =
  210. i915_add_request(dev, NULL, &dev_priv->render_ring);
  211. if (overlay->last_flip_req == 0)
  212. return -ENOMEM;
  213. overlay->hw_wedged = stage;
  214. ret = i915_do_wait_request(dev,
  215. overlay->last_flip_req, true,
  216. &dev_priv->render_ring);
  217. if (ret)
  218. return ret;
  219. overlay->hw_wedged = 0;
  220. overlay->last_flip_req = 0;
  221. return 0;
  222. }
  223. /* overlay needs to be disable in OCMD reg */
  224. static int intel_overlay_on(struct intel_overlay *overlay)
  225. {
  226. struct drm_device *dev = overlay->dev;
  227. BUG_ON(overlay->active);
  228. overlay->active = 1;
  229. BEGIN_LP_RING(4);
  230. OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON);
  231. OUT_RING(overlay->flip_addr | OFC_UPDATE);
  232. OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
  233. OUT_RING(MI_NOOP);
  234. ADVANCE_LP_RING();
  235. return intel_overlay_do_wait_request(overlay, true,
  236. NEEDS_WAIT_FOR_FLIP);
  237. }
  238. /* overlay needs to be enabled in OCMD reg */
  239. static void intel_overlay_continue(struct intel_overlay *overlay,
  240. bool load_polyphase_filter)
  241. {
  242. struct drm_device *dev = overlay->dev;
  243. drm_i915_private_t *dev_priv = dev->dev_private;
  244. u32 flip_addr = overlay->flip_addr;
  245. u32 tmp;
  246. BUG_ON(!overlay->active);
  247. if (load_polyphase_filter)
  248. flip_addr |= OFC_UPDATE;
  249. /* check for underruns */
  250. tmp = I915_READ(DOVSTA);
  251. if (tmp & (1 << 17))
  252. DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
  253. BEGIN_LP_RING(2);
  254. OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
  255. OUT_RING(flip_addr);
  256. ADVANCE_LP_RING();
  257. overlay->last_flip_req =
  258. i915_add_request(dev, NULL, &dev_priv->render_ring);
  259. }
  260. /* overlay needs to be disabled in OCMD reg */
  261. static int intel_overlay_off(struct intel_overlay *overlay)
  262. {
  263. u32 flip_addr = overlay->flip_addr;
  264. struct drm_device *dev = overlay->dev;
  265. BUG_ON(!overlay->active);
  266. /* According to intel docs the overlay hw may hang (when switching
  267. * off) without loading the filter coeffs. It is however unclear whether
  268. * this applies to the disabling of the overlay or to the switching off
  269. * of the hw. Do it in both cases */
  270. flip_addr |= OFC_UPDATE;
  271. BEGIN_LP_RING(6);
  272. /* wait for overlay to go idle */
  273. OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
  274. OUT_RING(flip_addr);
  275. OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
  276. /* turn overlay off */
  277. OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
  278. OUT_RING(flip_addr);
  279. OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
  280. ADVANCE_LP_RING();
  281. return intel_overlay_do_wait_request(overlay, true, SWITCH_OFF);
  282. }
  283. static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
  284. {
  285. struct drm_gem_object *obj = &overlay->old_vid_bo->base;
  286. i915_gem_object_unpin(obj);
  287. drm_gem_object_unreference(obj);
  288. overlay->old_vid_bo = NULL;
  289. }
  290. static void intel_overlay_off_tail(struct intel_overlay *overlay)
  291. {
  292. struct drm_gem_object *obj;
  293. /* never have the overlay hw on without showing a frame */
  294. BUG_ON(!overlay->vid_bo);
  295. obj = &overlay->vid_bo->base;
  296. i915_gem_object_unpin(obj);
  297. drm_gem_object_unreference(obj);
  298. overlay->vid_bo = NULL;
  299. overlay->crtc->overlay = NULL;
  300. overlay->crtc = NULL;
  301. overlay->active = 0;
  302. }
  303. /* recover from an interruption due to a signal
  304. * We have to be careful not to repeat work forever an make forward progess. */
  305. int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
  306. bool interruptible)
  307. {
  308. struct drm_device *dev = overlay->dev;
  309. drm_i915_private_t *dev_priv = dev->dev_private;
  310. int ret;
  311. if (overlay->hw_wedged == HW_WEDGED)
  312. return -EIO;
  313. ret = i915_do_wait_request(dev, overlay->last_flip_req,
  314. interruptible, &dev_priv->render_ring);
  315. if (ret)
  316. return ret;
  317. switch (overlay->hw_wedged) {
  318. case RELEASE_OLD_VID:
  319. intel_overlay_release_old_vid_tail(overlay);
  320. break;
  321. case SWITCH_OFF:
  322. intel_overlay_off_tail(overlay);
  323. break;
  324. default:
  325. BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP);
  326. }
  327. overlay->hw_wedged = 0;
  328. overlay->last_flip_req = 0;
  329. return 0;
  330. }
  331. /* Wait for pending overlay flip and release old frame.
  332. * Needs to be called before the overlay register are changed
  333. * via intel_overlay_(un)map_regs
  334. */
  335. static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
  336. {
  337. struct drm_device *dev = overlay->dev;
  338. drm_i915_private_t *dev_priv = dev->dev_private;
  339. int ret;
  340. /* Only wait if there is actually an old frame to release to
  341. * guarantee forward progress.
  342. */
  343. if (!overlay->old_vid_bo)
  344. return 0;
  345. if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
  346. /* synchronous slowpath */
  347. BEGIN_LP_RING(2);
  348. OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
  349. OUT_RING(MI_NOOP);
  350. ADVANCE_LP_RING();
  351. ret = intel_overlay_do_wait_request(overlay, true,
  352. RELEASE_OLD_VID);
  353. if (ret)
  354. return ret;
  355. }
  356. intel_overlay_release_old_vid_tail(overlay);
  357. return 0;
  358. }
  359. struct put_image_params {
  360. int format;
  361. short dst_x;
  362. short dst_y;
  363. short dst_w;
  364. short dst_h;
  365. short src_w;
  366. short src_scan_h;
  367. short src_scan_w;
  368. short src_h;
  369. short stride_Y;
  370. short stride_UV;
  371. int offset_Y;
  372. int offset_U;
  373. int offset_V;
  374. };
  375. static int packed_depth_bytes(u32 format)
  376. {
  377. switch (format & I915_OVERLAY_DEPTH_MASK) {
  378. case I915_OVERLAY_YUV422:
  379. return 4;
  380. case I915_OVERLAY_YUV411:
  381. /* return 6; not implemented */
  382. default:
  383. return -EINVAL;
  384. }
  385. }
  386. static int packed_width_bytes(u32 format, short width)
  387. {
  388. switch (format & I915_OVERLAY_DEPTH_MASK) {
  389. case I915_OVERLAY_YUV422:
  390. return width << 1;
  391. default:
  392. return -EINVAL;
  393. }
  394. }
  395. static int uv_hsubsampling(u32 format)
  396. {
  397. switch (format & I915_OVERLAY_DEPTH_MASK) {
  398. case I915_OVERLAY_YUV422:
  399. case I915_OVERLAY_YUV420:
  400. return 2;
  401. case I915_OVERLAY_YUV411:
  402. case I915_OVERLAY_YUV410:
  403. return 4;
  404. default:
  405. return -EINVAL;
  406. }
  407. }
  408. static int uv_vsubsampling(u32 format)
  409. {
  410. switch (format & I915_OVERLAY_DEPTH_MASK) {
  411. case I915_OVERLAY_YUV420:
  412. case I915_OVERLAY_YUV410:
  413. return 2;
  414. case I915_OVERLAY_YUV422:
  415. case I915_OVERLAY_YUV411:
  416. return 1;
  417. default:
  418. return -EINVAL;
  419. }
  420. }
  421. static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
  422. {
  423. u32 mask, shift, ret;
  424. if (IS_I9XX(dev)) {
  425. mask = 0x3f;
  426. shift = 6;
  427. } else {
  428. mask = 0x1f;
  429. shift = 5;
  430. }
  431. ret = ((offset + width + mask) >> shift) - (offset >> shift);
  432. if (IS_I9XX(dev))
  433. ret <<= 1;
  434. ret -=1;
  435. return ret << 2;
  436. }
  437. static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
  438. 0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
  439. 0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
  440. 0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
  441. 0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
  442. 0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
  443. 0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
  444. 0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
  445. 0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
  446. 0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
  447. 0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
  448. 0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
  449. 0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
  450. 0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
  451. 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
  452. 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
  453. 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
  454. 0xb000, 0x3000, 0x0800, 0x3000, 0xb000
  455. };
  456. static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
  457. 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
  458. 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
  459. 0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
  460. 0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
  461. 0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
  462. 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
  463. 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
  464. 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
  465. 0x3000, 0x0800, 0x3000
  466. };
  467. static void update_polyphase_filter(struct overlay_registers *regs)
  468. {
  469. memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs));
  470. memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs));
  471. }
  472. static bool update_scaling_factors(struct intel_overlay *overlay,
  473. struct overlay_registers *regs,
  474. struct put_image_params *params)
  475. {
  476. /* fixed point with a 12 bit shift */
  477. u32 xscale, yscale, xscale_UV, yscale_UV;
  478. #define FP_SHIFT 12
  479. #define FRACT_MASK 0xfff
  480. bool scale_changed = false;
  481. int uv_hscale = uv_hsubsampling(params->format);
  482. int uv_vscale = uv_vsubsampling(params->format);
  483. if (params->dst_w > 1)
  484. xscale = ((params->src_scan_w - 1) << FP_SHIFT)
  485. /(params->dst_w);
  486. else
  487. xscale = 1 << FP_SHIFT;
  488. if (params->dst_h > 1)
  489. yscale = ((params->src_scan_h - 1) << FP_SHIFT)
  490. /(params->dst_h);
  491. else
  492. yscale = 1 << FP_SHIFT;
  493. /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
  494. xscale_UV = xscale/uv_hscale;
  495. yscale_UV = yscale/uv_vscale;
  496. /* make the Y scale to UV scale ratio an exact multiply */
  497. xscale = xscale_UV * uv_hscale;
  498. yscale = yscale_UV * uv_vscale;
  499. /*} else {
  500. xscale_UV = 0;
  501. yscale_UV = 0;
  502. }*/
  503. if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
  504. scale_changed = true;
  505. overlay->old_xscale = xscale;
  506. overlay->old_yscale = yscale;
  507. regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) |
  508. ((xscale >> FP_SHIFT) << 16) |
  509. ((xscale & FRACT_MASK) << 3));
  510. regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) |
  511. ((xscale_UV >> FP_SHIFT) << 16) |
  512. ((xscale_UV & FRACT_MASK) << 3));
  513. regs->UVSCALEV = ((((yscale >> FP_SHIFT) << 16) |
  514. ((yscale_UV >> FP_SHIFT) << 0)));
  515. if (scale_changed)
  516. update_polyphase_filter(regs);
  517. return scale_changed;
  518. }
  519. static void update_colorkey(struct intel_overlay *overlay,
  520. struct overlay_registers *regs)
  521. {
  522. u32 key = overlay->color_key;
  523. switch (overlay->crtc->base.fb->bits_per_pixel) {
  524. case 8:
  525. regs->DCLRKV = 0;
  526. regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE;
  527. break;
  528. case 16:
  529. if (overlay->crtc->base.fb->depth == 15) {
  530. regs->DCLRKV = RGB15_TO_COLORKEY(key);
  531. regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE;
  532. } else {
  533. regs->DCLRKV = RGB16_TO_COLORKEY(key);
  534. regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE;
  535. }
  536. break;
  537. case 24:
  538. case 32:
  539. regs->DCLRKV = key;
  540. regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE;
  541. break;
  542. }
  543. }
  544. static u32 overlay_cmd_reg(struct put_image_params *params)
  545. {
  546. u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0;
  547. if (params->format & I915_OVERLAY_YUV_PLANAR) {
  548. switch (params->format & I915_OVERLAY_DEPTH_MASK) {
  549. case I915_OVERLAY_YUV422:
  550. cmd |= OCMD_YUV_422_PLANAR;
  551. break;
  552. case I915_OVERLAY_YUV420:
  553. cmd |= OCMD_YUV_420_PLANAR;
  554. break;
  555. case I915_OVERLAY_YUV411:
  556. case I915_OVERLAY_YUV410:
  557. cmd |= OCMD_YUV_410_PLANAR;
  558. break;
  559. }
  560. } else { /* YUV packed */
  561. switch (params->format & I915_OVERLAY_DEPTH_MASK) {
  562. case I915_OVERLAY_YUV422:
  563. cmd |= OCMD_YUV_422_PACKED;
  564. break;
  565. case I915_OVERLAY_YUV411:
  566. cmd |= OCMD_YUV_411_PACKED;
  567. break;
  568. }
  569. switch (params->format & I915_OVERLAY_SWAP_MASK) {
  570. case I915_OVERLAY_NO_SWAP:
  571. break;
  572. case I915_OVERLAY_UV_SWAP:
  573. cmd |= OCMD_UV_SWAP;
  574. break;
  575. case I915_OVERLAY_Y_SWAP:
  576. cmd |= OCMD_Y_SWAP;
  577. break;
  578. case I915_OVERLAY_Y_AND_UV_SWAP:
  579. cmd |= OCMD_Y_AND_UV_SWAP;
  580. break;
  581. }
  582. }
  583. return cmd;
  584. }
  585. int intel_overlay_do_put_image(struct intel_overlay *overlay,
  586. struct drm_gem_object *new_bo,
  587. struct put_image_params *params)
  588. {
  589. int ret, tmp_width;
  590. struct overlay_registers *regs;
  591. bool scale_changed = false;
  592. struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo);
  593. struct drm_device *dev = overlay->dev;
  594. BUG_ON(!mutex_is_locked(&dev->struct_mutex));
  595. BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
  596. BUG_ON(!overlay);
  597. ret = intel_overlay_release_old_vid(overlay);
  598. if (ret != 0)
  599. return ret;
  600. ret = i915_gem_object_pin(new_bo, PAGE_SIZE);
  601. if (ret != 0)
  602. return ret;
  603. ret = i915_gem_object_set_to_gtt_domain(new_bo, 0);
  604. if (ret != 0)
  605. goto out_unpin;
  606. if (!overlay->active) {
  607. regs = intel_overlay_map_regs(overlay);
  608. if (!regs) {
  609. ret = -ENOMEM;
  610. goto out_unpin;
  611. }
  612. regs->OCONFIG = OCONF_CC_OUT_8BIT;
  613. if (IS_I965GM(overlay->dev))
  614. regs->OCONFIG |= OCONF_CSC_MODE_BT709;
  615. regs->OCONFIG |= overlay->crtc->pipe == 0 ?
  616. OCONF_PIPE_A : OCONF_PIPE_B;
  617. intel_overlay_unmap_regs(overlay, regs);
  618. ret = intel_overlay_on(overlay);
  619. if (ret != 0)
  620. goto out_unpin;
  621. }
  622. regs = intel_overlay_map_regs(overlay);
  623. if (!regs) {
  624. ret = -ENOMEM;
  625. goto out_unpin;
  626. }
  627. regs->DWINPOS = (params->dst_y << 16) | params->dst_x;
  628. regs->DWINSZ = (params->dst_h << 16) | params->dst_w;
  629. if (params->format & I915_OVERLAY_YUV_PACKED)
  630. tmp_width = packed_width_bytes(params->format, params->src_w);
  631. else
  632. tmp_width = params->src_w;
  633. regs->SWIDTH = params->src_w;
  634. regs->SWIDTHSW = calc_swidthsw(overlay->dev,
  635. params->offset_Y, tmp_width);
  636. regs->SHEIGHT = params->src_h;
  637. regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y;
  638. regs->OSTRIDE = params->stride_Y;
  639. if (params->format & I915_OVERLAY_YUV_PLANAR) {
  640. int uv_hscale = uv_hsubsampling(params->format);
  641. int uv_vscale = uv_vsubsampling(params->format);
  642. u32 tmp_U, tmp_V;
  643. regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
  644. tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
  645. params->src_w/uv_hscale);
  646. tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
  647. params->src_w/uv_hscale);
  648. regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16;
  649. regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
  650. regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U;
  651. regs->OBUF_0V = bo_priv->gtt_offset + params->offset_V;
  652. regs->OSTRIDE |= params->stride_UV << 16;
  653. }
  654. scale_changed = update_scaling_factors(overlay, regs, params);
  655. update_colorkey(overlay, regs);
  656. regs->OCMD = overlay_cmd_reg(params);
  657. intel_overlay_unmap_regs(overlay, regs);
  658. intel_overlay_continue(overlay, scale_changed);
  659. overlay->old_vid_bo = overlay->vid_bo;
  660. overlay->vid_bo = to_intel_bo(new_bo);
  661. return 0;
  662. out_unpin:
  663. i915_gem_object_unpin(new_bo);
  664. return ret;
  665. }
  666. int intel_overlay_switch_off(struct intel_overlay *overlay)
  667. {
  668. int ret;
  669. struct overlay_registers *regs;
  670. struct drm_device *dev = overlay->dev;
  671. BUG_ON(!mutex_is_locked(&dev->struct_mutex));
  672. BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
  673. if (overlay->hw_wedged) {
  674. ret = intel_overlay_recover_from_interrupt(overlay, 1);
  675. if (ret != 0)
  676. return ret;
  677. }
  678. if (!overlay->active)
  679. return 0;
  680. ret = intel_overlay_release_old_vid(overlay);
  681. if (ret != 0)
  682. return ret;
  683. regs = intel_overlay_map_regs(overlay);
  684. regs->OCMD = 0;
  685. intel_overlay_unmap_regs(overlay, regs);
  686. ret = intel_overlay_off(overlay);
  687. if (ret != 0)
  688. return ret;
  689. intel_overlay_off_tail(overlay);
  690. return 0;
  691. }
  692. static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
  693. struct intel_crtc *crtc)
  694. {
  695. drm_i915_private_t *dev_priv = overlay->dev->dev_private;
  696. u32 pipeconf;
  697. int pipeconf_reg = (crtc->pipe == 0) ? PIPEACONF : PIPEBCONF;
  698. if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON)
  699. return -EINVAL;
  700. pipeconf = I915_READ(pipeconf_reg);
  701. /* can't use the overlay with double wide pipe */
  702. if (!IS_I965G(overlay->dev) && pipeconf & PIPEACONF_DOUBLE_WIDE)
  703. return -EINVAL;
  704. return 0;
  705. }
  706. static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
  707. {
  708. struct drm_device *dev = overlay->dev;
  709. drm_i915_private_t *dev_priv = dev->dev_private;
  710. u32 pfit_control = I915_READ(PFIT_CONTROL);
  711. u32 ratio;
  712. /* XXX: This is not the same logic as in the xorg driver, but more in
  713. * line with the intel documentation for the i965
  714. */
  715. if (!IS_I965G(dev)) {
  716. if (pfit_control & VERT_AUTO_SCALE)
  717. ratio = I915_READ(PFIT_AUTO_RATIOS);
  718. else
  719. ratio = I915_READ(PFIT_PGM_RATIOS);
  720. ratio >>= PFIT_VERT_SCALE_SHIFT;
  721. } else { /* on i965 use the PGM reg to read out the autoscaler values */
  722. ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
  723. }
  724. overlay->pfit_vscale_ratio = ratio;
  725. }
  726. static int check_overlay_dst(struct intel_overlay *overlay,
  727. struct drm_intel_overlay_put_image *rec)
  728. {
  729. struct drm_display_mode *mode = &overlay->crtc->base.mode;
  730. if (rec->dst_x < mode->crtc_hdisplay &&
  731. rec->dst_x + rec->dst_width <= mode->crtc_hdisplay &&
  732. rec->dst_y < mode->crtc_vdisplay &&
  733. rec->dst_y + rec->dst_height <= mode->crtc_vdisplay)
  734. return 0;
  735. else
  736. return -EINVAL;
  737. }
  738. static int check_overlay_scaling(struct put_image_params *rec)
  739. {
  740. u32 tmp;
  741. /* downscaling limit is 8.0 */
  742. tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16;
  743. if (tmp > 7)
  744. return -EINVAL;
  745. tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16;
  746. if (tmp > 7)
  747. return -EINVAL;
  748. return 0;
  749. }
  750. static int check_overlay_src(struct drm_device *dev,
  751. struct drm_intel_overlay_put_image *rec,
  752. struct drm_gem_object *new_bo)
  753. {
  754. int uv_hscale = uv_hsubsampling(rec->flags);
  755. int uv_vscale = uv_vsubsampling(rec->flags);
  756. u32 stride_mask, depth, tmp;
  757. /* check src dimensions */
  758. if (IS_845G(dev) || IS_I830(dev)) {
  759. if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
  760. rec->src_width > IMAGE_MAX_WIDTH_LEGACY)
  761. return -EINVAL;
  762. } else {
  763. if (rec->src_height > IMAGE_MAX_HEIGHT ||
  764. rec->src_width > IMAGE_MAX_WIDTH)
  765. return -EINVAL;
  766. }
  767. /* better safe than sorry, use 4 as the maximal subsampling ratio */
  768. if (rec->src_height < N_VERT_Y_TAPS*4 ||
  769. rec->src_width < N_HORIZ_Y_TAPS*4)
  770. return -EINVAL;
  771. /* check alignment constraints */
  772. switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
  773. case I915_OVERLAY_RGB:
  774. /* not implemented */
  775. return -EINVAL;
  776. case I915_OVERLAY_YUV_PACKED:
  777. if (uv_vscale != 1)
  778. return -EINVAL;
  779. depth = packed_depth_bytes(rec->flags);
  780. if (depth < 0)
  781. return depth;
  782. /* ignore UV planes */
  783. rec->stride_UV = 0;
  784. rec->offset_U = 0;
  785. rec->offset_V = 0;
  786. /* check pixel alignment */
  787. if (rec->offset_Y % depth)
  788. return -EINVAL;
  789. break;
  790. case I915_OVERLAY_YUV_PLANAR:
  791. if (uv_vscale < 0 || uv_hscale < 0)
  792. return -EINVAL;
  793. /* no offset restrictions for planar formats */
  794. break;
  795. default:
  796. return -EINVAL;
  797. }
  798. if (rec->src_width % uv_hscale)
  799. return -EINVAL;
  800. /* stride checking */
  801. if (IS_I830(dev) || IS_845G(dev))
  802. stride_mask = 255;
  803. else
  804. stride_mask = 63;
  805. if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
  806. return -EINVAL;
  807. if (IS_I965G(dev) && rec->stride_Y < 512)
  808. return -EINVAL;
  809. tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
  810. 4096 : 8192;
  811. if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
  812. return -EINVAL;
  813. /* check buffer dimensions */
  814. switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
  815. case I915_OVERLAY_RGB:
  816. case I915_OVERLAY_YUV_PACKED:
  817. /* always 4 Y values per depth pixels */
  818. if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
  819. return -EINVAL;
  820. tmp = rec->stride_Y*rec->src_height;
  821. if (rec->offset_Y + tmp > new_bo->size)
  822. return -EINVAL;
  823. break;
  824. case I915_OVERLAY_YUV_PLANAR:
  825. if (rec->src_width > rec->stride_Y)
  826. return -EINVAL;
  827. if (rec->src_width/uv_hscale > rec->stride_UV)
  828. return -EINVAL;
  829. tmp = rec->stride_Y * rec->src_height;
  830. if (rec->offset_Y + tmp > new_bo->size)
  831. return -EINVAL;
  832. tmp = rec->stride_UV * (rec->src_height / uv_vscale);
  833. if (rec->offset_U + tmp > new_bo->size ||
  834. rec->offset_V + tmp > new_bo->size)
  835. return -EINVAL;
  836. break;
  837. }
  838. return 0;
  839. }
  840. int intel_overlay_put_image(struct drm_device *dev, void *data,
  841. struct drm_file *file_priv)
  842. {
  843. struct drm_intel_overlay_put_image *put_image_rec = data;
  844. drm_i915_private_t *dev_priv = dev->dev_private;
  845. struct intel_overlay *overlay;
  846. struct drm_mode_object *drmmode_obj;
  847. struct intel_crtc *crtc;
  848. struct drm_gem_object *new_bo;
  849. struct put_image_params *params;
  850. int ret;
  851. if (!dev_priv) {
  852. DRM_ERROR("called with no initialization\n");
  853. return -EINVAL;
  854. }
  855. overlay = dev_priv->overlay;
  856. if (!overlay) {
  857. DRM_DEBUG("userspace bug: no overlay\n");
  858. return -ENODEV;
  859. }
  860. if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
  861. mutex_lock(&dev->mode_config.mutex);
  862. mutex_lock(&dev->struct_mutex);
  863. ret = intel_overlay_switch_off(overlay);
  864. mutex_unlock(&dev->struct_mutex);
  865. mutex_unlock(&dev->mode_config.mutex);
  866. return ret;
  867. }
  868. params = kmalloc(sizeof(struct put_image_params), GFP_KERNEL);
  869. if (!params)
  870. return -ENOMEM;
  871. drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
  872. DRM_MODE_OBJECT_CRTC);
  873. if (!drmmode_obj) {
  874. ret = -ENOENT;
  875. goto out_free;
  876. }
  877. crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
  878. new_bo = drm_gem_object_lookup(dev, file_priv,
  879. put_image_rec->bo_handle);
  880. if (!new_bo) {
  881. ret = -ENOENT;
  882. goto out_free;
  883. }
  884. mutex_lock(&dev->mode_config.mutex);
  885. mutex_lock(&dev->struct_mutex);
  886. if (overlay->hw_wedged) {
  887. ret = intel_overlay_recover_from_interrupt(overlay, 1);
  888. if (ret != 0)
  889. goto out_unlock;
  890. }
  891. if (overlay->crtc != crtc) {
  892. struct drm_display_mode *mode = &crtc->base.mode;
  893. ret = intel_overlay_switch_off(overlay);
  894. if (ret != 0)
  895. goto out_unlock;
  896. ret = check_overlay_possible_on_crtc(overlay, crtc);
  897. if (ret != 0)
  898. goto out_unlock;
  899. overlay->crtc = crtc;
  900. crtc->overlay = overlay;
  901. if (intel_panel_fitter_pipe(dev) == crtc->pipe
  902. /* and line to wide, i.e. one-line-mode */
  903. && mode->hdisplay > 1024) {
  904. overlay->pfit_active = 1;
  905. update_pfit_vscale_ratio(overlay);
  906. } else
  907. overlay->pfit_active = 0;
  908. }
  909. ret = check_overlay_dst(overlay, put_image_rec);
  910. if (ret != 0)
  911. goto out_unlock;
  912. if (overlay->pfit_active) {
  913. params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
  914. overlay->pfit_vscale_ratio);
  915. /* shifting right rounds downwards, so add 1 */
  916. params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
  917. overlay->pfit_vscale_ratio) + 1;
  918. } else {
  919. params->dst_y = put_image_rec->dst_y;
  920. params->dst_h = put_image_rec->dst_height;
  921. }
  922. params->dst_x = put_image_rec->dst_x;
  923. params->dst_w = put_image_rec->dst_width;
  924. params->src_w = put_image_rec->src_width;
  925. params->src_h = put_image_rec->src_height;
  926. params->src_scan_w = put_image_rec->src_scan_width;
  927. params->src_scan_h = put_image_rec->src_scan_height;
  928. if (params->src_scan_h > params->src_h ||
  929. params->src_scan_w > params->src_w) {
  930. ret = -EINVAL;
  931. goto out_unlock;
  932. }
  933. ret = check_overlay_src(dev, put_image_rec, new_bo);
  934. if (ret != 0)
  935. goto out_unlock;
  936. params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK;
  937. params->stride_Y = put_image_rec->stride_Y;
  938. params->stride_UV = put_image_rec->stride_UV;
  939. params->offset_Y = put_image_rec->offset_Y;
  940. params->offset_U = put_image_rec->offset_U;
  941. params->offset_V = put_image_rec->offset_V;
  942. /* Check scaling after src size to prevent a divide-by-zero. */
  943. ret = check_overlay_scaling(params);
  944. if (ret != 0)
  945. goto out_unlock;
  946. ret = intel_overlay_do_put_image(overlay, new_bo, params);
  947. if (ret != 0)
  948. goto out_unlock;
  949. mutex_unlock(&dev->struct_mutex);
  950. mutex_unlock(&dev->mode_config.mutex);
  951. kfree(params);
  952. return 0;
  953. out_unlock:
  954. mutex_unlock(&dev->struct_mutex);
  955. mutex_unlock(&dev->mode_config.mutex);
  956. drm_gem_object_unreference_unlocked(new_bo);
  957. out_free:
  958. kfree(params);
  959. return ret;
  960. }
  961. static void update_reg_attrs(struct intel_overlay *overlay,
  962. struct overlay_registers *regs)
  963. {
  964. regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff);
  965. regs->OCLRC1 = overlay->saturation;
  966. }
  967. static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
  968. {
  969. int i;
  970. if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
  971. return false;
  972. for (i = 0; i < 3; i++) {
  973. if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
  974. return false;
  975. }
  976. return true;
  977. }
  978. static bool check_gamma5_errata(u32 gamma5)
  979. {
  980. int i;
  981. for (i = 0; i < 3; i++) {
  982. if (((gamma5 >> i*8) & 0xff) == 0x80)
  983. return false;
  984. }
  985. return true;
  986. }
  987. static int check_gamma(struct drm_intel_overlay_attrs *attrs)
  988. {
  989. if (!check_gamma_bounds(0, attrs->gamma0) ||
  990. !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
  991. !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
  992. !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
  993. !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
  994. !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
  995. !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
  996. return -EINVAL;
  997. if (!check_gamma5_errata(attrs->gamma5))
  998. return -EINVAL;
  999. return 0;
  1000. }
  1001. int intel_overlay_attrs(struct drm_device *dev, void *data,
  1002. struct drm_file *file_priv)
  1003. {
  1004. struct drm_intel_overlay_attrs *attrs = data;
  1005. drm_i915_private_t *dev_priv = dev->dev_private;
  1006. struct intel_overlay *overlay;
  1007. struct overlay_registers *regs;
  1008. int ret;
  1009. if (!dev_priv) {
  1010. DRM_ERROR("called with no initialization\n");
  1011. return -EINVAL;
  1012. }
  1013. overlay = dev_priv->overlay;
  1014. if (!overlay) {
  1015. DRM_DEBUG("userspace bug: no overlay\n");
  1016. return -ENODEV;
  1017. }
  1018. mutex_lock(&dev->mode_config.mutex);
  1019. mutex_lock(&dev->struct_mutex);
  1020. ret = -EINVAL;
  1021. if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
  1022. attrs->color_key = overlay->color_key;
  1023. attrs->brightness = overlay->brightness;
  1024. attrs->contrast = overlay->contrast;
  1025. attrs->saturation = overlay->saturation;
  1026. if (IS_I9XX(dev)) {
  1027. attrs->gamma0 = I915_READ(OGAMC0);
  1028. attrs->gamma1 = I915_READ(OGAMC1);
  1029. attrs->gamma2 = I915_READ(OGAMC2);
  1030. attrs->gamma3 = I915_READ(OGAMC3);
  1031. attrs->gamma4 = I915_READ(OGAMC4);
  1032. attrs->gamma5 = I915_READ(OGAMC5);
  1033. }
  1034. } else {
  1035. if (attrs->brightness < -128 || attrs->brightness > 127)
  1036. goto out_unlock;
  1037. if (attrs->contrast > 255)
  1038. goto out_unlock;
  1039. if (attrs->saturation > 1023)
  1040. goto out_unlock;
  1041. overlay->color_key = attrs->color_key;
  1042. overlay->brightness = attrs->brightness;
  1043. overlay->contrast = attrs->contrast;
  1044. overlay->saturation = attrs->saturation;
  1045. regs = intel_overlay_map_regs(overlay);
  1046. if (!regs) {
  1047. ret = -ENOMEM;
  1048. goto out_unlock;
  1049. }
  1050. update_reg_attrs(overlay, regs);
  1051. intel_overlay_unmap_regs(overlay, regs);
  1052. if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
  1053. if (!IS_I9XX(dev))
  1054. goto out_unlock;
  1055. if (overlay->active) {
  1056. ret = -EBUSY;
  1057. goto out_unlock;
  1058. }
  1059. ret = check_gamma(attrs);
  1060. if (ret)
  1061. goto out_unlock;
  1062. I915_WRITE(OGAMC0, attrs->gamma0);
  1063. I915_WRITE(OGAMC1, attrs->gamma1);
  1064. I915_WRITE(OGAMC2, attrs->gamma2);
  1065. I915_WRITE(OGAMC3, attrs->gamma3);
  1066. I915_WRITE(OGAMC4, attrs->gamma4);
  1067. I915_WRITE(OGAMC5, attrs->gamma5);
  1068. }
  1069. }
  1070. ret = 0;
  1071. out_unlock:
  1072. mutex_unlock(&dev->struct_mutex);
  1073. mutex_unlock(&dev->mode_config.mutex);
  1074. return ret;
  1075. }
  1076. void intel_setup_overlay(struct drm_device *dev)
  1077. {
  1078. drm_i915_private_t *dev_priv = dev->dev_private;
  1079. struct intel_overlay *overlay;
  1080. struct drm_gem_object *reg_bo;
  1081. struct overlay_registers *regs;
  1082. int ret;
  1083. if (!HAS_OVERLAY(dev))
  1084. return;
  1085. overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
  1086. if (!overlay)
  1087. return;
  1088. overlay->dev = dev;
  1089. reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
  1090. if (!reg_bo)
  1091. goto out_free;
  1092. overlay->reg_bo = to_intel_bo(reg_bo);
  1093. if (OVERLAY_NEEDS_PHYSICAL(dev)) {
  1094. ret = i915_gem_attach_phys_object(dev, reg_bo,
  1095. I915_GEM_PHYS_OVERLAY_REGS,
  1096. PAGE_SIZE);
  1097. if (ret) {
  1098. DRM_ERROR("failed to attach phys overlay regs\n");
  1099. goto out_free_bo;
  1100. }
  1101. overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr;
  1102. } else {
  1103. ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
  1104. if (ret) {
  1105. DRM_ERROR("failed to pin overlay register bo\n");
  1106. goto out_free_bo;
  1107. }
  1108. overlay->flip_addr = overlay->reg_bo->gtt_offset;
  1109. ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
  1110. if (ret) {
  1111. DRM_ERROR("failed to move overlay register bo into the GTT\n");
  1112. goto out_unpin_bo;
  1113. }
  1114. }
  1115. /* init all values */
  1116. overlay->color_key = 0x0101fe;
  1117. overlay->brightness = -19;
  1118. overlay->contrast = 75;
  1119. overlay->saturation = 146;
  1120. regs = intel_overlay_map_regs(overlay);
  1121. if (!regs)
  1122. goto out_free_bo;
  1123. memset(regs, 0, sizeof(struct overlay_registers));
  1124. update_polyphase_filter(regs);
  1125. update_reg_attrs(overlay, regs);
  1126. intel_overlay_unmap_regs(overlay, regs);
  1127. dev_priv->overlay = overlay;
  1128. DRM_INFO("initialized overlay support\n");
  1129. return;
  1130. out_unpin_bo:
  1131. i915_gem_object_unpin(reg_bo);
  1132. out_free_bo:
  1133. drm_gem_object_unreference(reg_bo);
  1134. out_free:
  1135. kfree(overlay);
  1136. return;
  1137. }
  1138. void intel_cleanup_overlay(struct drm_device *dev)
  1139. {
  1140. drm_i915_private_t *dev_priv = dev->dev_private;
  1141. if (!dev_priv->overlay)
  1142. return;
  1143. /* The bo's should be free'd by the generic code already.
  1144. * Furthermore modesetting teardown happens beforehand so the
  1145. * hardware should be off already */
  1146. BUG_ON(dev_priv->overlay->active);
  1147. drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
  1148. kfree(dev_priv->overlay);
  1149. }
  1150. struct intel_overlay_error_state {
  1151. struct overlay_registers regs;
  1152. unsigned long base;
  1153. u32 dovsta;
  1154. u32 isr;
  1155. };
  1156. struct intel_overlay_error_state *
  1157. intel_overlay_capture_error_state(struct drm_device *dev)
  1158. {
  1159. drm_i915_private_t *dev_priv = dev->dev_private;
  1160. struct intel_overlay *overlay = dev_priv->overlay;
  1161. struct intel_overlay_error_state *error;
  1162. struct overlay_registers __iomem *regs;
  1163. if (!overlay || !overlay->active)
  1164. return NULL;
  1165. error = kmalloc(sizeof(*error), GFP_ATOMIC);
  1166. if (error == NULL)
  1167. return NULL;
  1168. error->dovsta = I915_READ(DOVSTA);
  1169. error->isr = I915_READ(ISR);
  1170. if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
  1171. error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
  1172. else
  1173. error->base = (long) overlay->reg_bo->gtt_offset;
  1174. regs = intel_overlay_map_regs_atomic(overlay, KM_IRQ0);
  1175. if (!regs)
  1176. goto err;
  1177. memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
  1178. intel_overlay_unmap_regs_atomic(overlay, KM_IRQ0, regs);
  1179. return error;
  1180. err:
  1181. kfree(error);
  1182. return NULL;
  1183. }
  1184. void
  1185. intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error)
  1186. {
  1187. seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n",
  1188. error->dovsta, error->isr);
  1189. seq_printf(m, " Register file at 0x%08lx:\n",
  1190. error->base);
  1191. #define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x)
  1192. P(OBUF_0Y);
  1193. P(OBUF_1Y);
  1194. P(OBUF_0U);
  1195. P(OBUF_0V);
  1196. P(OBUF_1U);
  1197. P(OBUF_1V);
  1198. P(OSTRIDE);
  1199. P(YRGB_VPH);
  1200. P(UV_VPH);
  1201. P(HORZ_PH);
  1202. P(INIT_PHS);
  1203. P(DWINPOS);
  1204. P(DWINSZ);
  1205. P(SWIDTH);
  1206. P(SWIDTHSW);
  1207. P(SHEIGHT);
  1208. P(YRGBSCALE);
  1209. P(UVSCALE);
  1210. P(OCLRC0);
  1211. P(OCLRC1);
  1212. P(DCLRKV);
  1213. P(DCLRKM);
  1214. P(SCLRKVH);
  1215. P(SCLRKVL);
  1216. P(SCLRKEN);
  1217. P(OCONFIG);
  1218. P(OCMD);
  1219. P(OSTART_0Y);
  1220. P(OSTART_1Y);
  1221. P(OSTART_0U);
  1222. P(OSTART_0V);
  1223. P(OSTART_1U);
  1224. P(OSTART_1V);
  1225. P(OTILEOFF_0Y);
  1226. P(OTILEOFF_1Y);
  1227. P(OTILEOFF_0U);
  1228. P(OTILEOFF_0V);
  1229. P(OTILEOFF_1U);
  1230. P(OTILEOFF_1V);
  1231. P(FASTHSCALE);
  1232. P(UVSCALEV);
  1233. #undef P
  1234. }