fb_decoder.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. /*
  2. * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
  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. * Kevin Tian <kevin.tian@intel.com>
  25. *
  26. * Contributors:
  27. * Bing Niu <bing.niu@intel.com>
  28. * Xu Han <xu.han@intel.com>
  29. * Ping Gao <ping.a.gao@intel.com>
  30. * Xiaoguang Chen <xiaoguang.chen@intel.com>
  31. * Yang Liu <yang2.liu@intel.com>
  32. * Tina Zhang <tina.zhang@intel.com>
  33. *
  34. */
  35. #include <uapi/drm/drm_fourcc.h>
  36. #include "i915_drv.h"
  37. #include "gvt.h"
  38. #include "i915_pvinfo.h"
  39. #define PRIMARY_FORMAT_NUM 16
  40. struct pixel_format {
  41. int drm_format; /* Pixel format in DRM definition */
  42. int bpp; /* Bits per pixel, 0 indicates invalid */
  43. char *desc; /* The description */
  44. };
  45. static struct pixel_format bdw_pixel_formats[] = {
  46. {DRM_FORMAT_C8, 8, "8-bit Indexed"},
  47. {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
  48. {DRM_FORMAT_XRGB8888, 32, "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
  49. {DRM_FORMAT_XBGR2101010, 32, "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
  50. {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
  51. {DRM_FORMAT_XBGR8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"},
  52. /* non-supported format has bpp default to 0 */
  53. {0, 0, NULL},
  54. };
  55. static struct pixel_format skl_pixel_formats[] = {
  56. {DRM_FORMAT_YUYV, 16, "16-bit packed YUYV (8:8:8:8 MSB-V:Y2:U:Y1)"},
  57. {DRM_FORMAT_UYVY, 16, "16-bit packed UYVY (8:8:8:8 MSB-Y2:V:Y1:U)"},
  58. {DRM_FORMAT_YVYU, 16, "16-bit packed YVYU (8:8:8:8 MSB-U:Y2:V:Y1)"},
  59. {DRM_FORMAT_VYUY, 16, "16-bit packed VYUY (8:8:8:8 MSB-Y2:U:Y1:V)"},
  60. {DRM_FORMAT_C8, 8, "8-bit Indexed"},
  61. {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
  62. {DRM_FORMAT_ABGR8888, 32, "32-bit RGBA (8:8:8:8 MSB-A:B:G:R)"},
  63. {DRM_FORMAT_XBGR8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"},
  64. {DRM_FORMAT_ARGB8888, 32, "32-bit BGRA (8:8:8:8 MSB-A:R:G:B)"},
  65. {DRM_FORMAT_XRGB8888, 32, "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
  66. {DRM_FORMAT_XBGR2101010, 32, "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
  67. {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
  68. /* non-supported format has bpp default to 0 */
  69. {0, 0, NULL},
  70. };
  71. static int bdw_format_to_drm(int format)
  72. {
  73. int bdw_pixel_formats_index = 6;
  74. switch (format) {
  75. case DISPPLANE_8BPP:
  76. bdw_pixel_formats_index = 0;
  77. break;
  78. case DISPPLANE_BGRX565:
  79. bdw_pixel_formats_index = 1;
  80. break;
  81. case DISPPLANE_BGRX888:
  82. bdw_pixel_formats_index = 2;
  83. break;
  84. case DISPPLANE_RGBX101010:
  85. bdw_pixel_formats_index = 3;
  86. break;
  87. case DISPPLANE_BGRX101010:
  88. bdw_pixel_formats_index = 4;
  89. break;
  90. case DISPPLANE_RGBX888:
  91. bdw_pixel_formats_index = 5;
  92. break;
  93. default:
  94. break;
  95. }
  96. return bdw_pixel_formats_index;
  97. }
  98. static int skl_format_to_drm(int format, bool rgb_order, bool alpha,
  99. int yuv_order)
  100. {
  101. int skl_pixel_formats_index = 12;
  102. switch (format) {
  103. case PLANE_CTL_FORMAT_INDEXED:
  104. skl_pixel_formats_index = 4;
  105. break;
  106. case PLANE_CTL_FORMAT_RGB_565:
  107. skl_pixel_formats_index = 5;
  108. break;
  109. case PLANE_CTL_FORMAT_XRGB_8888:
  110. if (rgb_order)
  111. skl_pixel_formats_index = alpha ? 6 : 7;
  112. else
  113. skl_pixel_formats_index = alpha ? 8 : 9;
  114. break;
  115. case PLANE_CTL_FORMAT_XRGB_2101010:
  116. skl_pixel_formats_index = rgb_order ? 10 : 11;
  117. break;
  118. case PLANE_CTL_FORMAT_YUV422:
  119. skl_pixel_formats_index = yuv_order >> 16;
  120. if (skl_pixel_formats_index > 3)
  121. return -EINVAL;
  122. break;
  123. default:
  124. break;
  125. }
  126. return skl_pixel_formats_index;
  127. }
  128. static u32 intel_vgpu_get_stride(struct intel_vgpu *vgpu, int pipe,
  129. u32 tiled, int stride_mask, int bpp)
  130. {
  131. struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
  132. u32 stride_reg = vgpu_vreg_t(vgpu, DSPSTRIDE(pipe)) & stride_mask;
  133. u32 stride = stride_reg;
  134. if (IS_SKYLAKE(dev_priv)
  135. || IS_KABYLAKE(dev_priv)
  136. || IS_BROXTON(dev_priv)) {
  137. switch (tiled) {
  138. case PLANE_CTL_TILED_LINEAR:
  139. stride = stride_reg * 64;
  140. break;
  141. case PLANE_CTL_TILED_X:
  142. stride = stride_reg * 512;
  143. break;
  144. case PLANE_CTL_TILED_Y:
  145. stride = stride_reg * 128;
  146. break;
  147. case PLANE_CTL_TILED_YF:
  148. if (bpp == 8)
  149. stride = stride_reg * 64;
  150. else if (bpp == 16 || bpp == 32 || bpp == 64)
  151. stride = stride_reg * 128;
  152. else
  153. gvt_dbg_core("skl: unsupported bpp:%d\n", bpp);
  154. break;
  155. default:
  156. gvt_dbg_core("skl: unsupported tile format:%x\n",
  157. tiled);
  158. }
  159. }
  160. return stride;
  161. }
  162. static int get_active_pipe(struct intel_vgpu *vgpu)
  163. {
  164. int i;
  165. for (i = 0; i < I915_MAX_PIPES; i++)
  166. if (pipe_is_enabled(vgpu, i))
  167. break;
  168. return i;
  169. }
  170. /**
  171. * intel_vgpu_decode_primary_plane - Decode primary plane
  172. * @vgpu: input vgpu
  173. * @plane: primary plane to save decoded info
  174. * This function is called for decoding plane
  175. *
  176. * Returns:
  177. * 0 on success, non-zero if failed.
  178. */
  179. int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
  180. struct intel_vgpu_primary_plane_format *plane)
  181. {
  182. u32 val, fmt;
  183. struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
  184. int pipe;
  185. pipe = get_active_pipe(vgpu);
  186. if (pipe >= I915_MAX_PIPES)
  187. return -ENODEV;
  188. val = vgpu_vreg_t(vgpu, DSPCNTR(pipe));
  189. plane->enabled = !!(val & DISPLAY_PLANE_ENABLE);
  190. if (!plane->enabled)
  191. return -ENODEV;
  192. if (IS_SKYLAKE(dev_priv)
  193. || IS_KABYLAKE(dev_priv)
  194. || IS_BROXTON(dev_priv)) {
  195. plane->tiled = val & PLANE_CTL_TILED_MASK;
  196. fmt = skl_format_to_drm(
  197. val & PLANE_CTL_FORMAT_MASK,
  198. val & PLANE_CTL_ORDER_RGBX,
  199. val & PLANE_CTL_ALPHA_MASK,
  200. val & PLANE_CTL_YUV422_ORDER_MASK);
  201. if (fmt >= ARRAY_SIZE(skl_pixel_formats)) {
  202. gvt_vgpu_err("Out-of-bounds pixel format index\n");
  203. return -EINVAL;
  204. }
  205. plane->bpp = skl_pixel_formats[fmt].bpp;
  206. plane->drm_format = skl_pixel_formats[fmt].drm_format;
  207. } else {
  208. plane->tiled = val & DISPPLANE_TILED;
  209. fmt = bdw_format_to_drm(val & DISPPLANE_PIXFORMAT_MASK);
  210. plane->bpp = bdw_pixel_formats[fmt].bpp;
  211. plane->drm_format = bdw_pixel_formats[fmt].drm_format;
  212. }
  213. if (!plane->bpp) {
  214. gvt_vgpu_err("Non-supported pixel format (0x%x)\n", fmt);
  215. return -EINVAL;
  216. }
  217. plane->hw_format = fmt;
  218. plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
  219. if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
  220. return -EINVAL;
  221. plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
  222. if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
  223. gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n",
  224. plane->base);
  225. return -EINVAL;
  226. }
  227. plane->stride = intel_vgpu_get_stride(vgpu, pipe, plane->tiled,
  228. (IS_SKYLAKE(dev_priv)
  229. || IS_KABYLAKE(dev_priv)
  230. || IS_BROXTON(dev_priv)) ?
  231. (_PRI_PLANE_STRIDE_MASK >> 6) :
  232. _PRI_PLANE_STRIDE_MASK, plane->bpp);
  233. plane->width = (vgpu_vreg_t(vgpu, PIPESRC(pipe)) & _PIPE_H_SRCSZ_MASK) >>
  234. _PIPE_H_SRCSZ_SHIFT;
  235. plane->width += 1;
  236. plane->height = (vgpu_vreg_t(vgpu, PIPESRC(pipe)) &
  237. _PIPE_V_SRCSZ_MASK) >> _PIPE_V_SRCSZ_SHIFT;
  238. plane->height += 1; /* raw height is one minus the real value */
  239. val = vgpu_vreg_t(vgpu, DSPTILEOFF(pipe));
  240. plane->x_offset = (val & _PRI_PLANE_X_OFF_MASK) >>
  241. _PRI_PLANE_X_OFF_SHIFT;
  242. plane->y_offset = (val & _PRI_PLANE_Y_OFF_MASK) >>
  243. _PRI_PLANE_Y_OFF_SHIFT;
  244. return 0;
  245. }
  246. #define CURSOR_FORMAT_NUM (1 << 6)
  247. struct cursor_mode_format {
  248. int drm_format; /* Pixel format in DRM definition */
  249. u8 bpp; /* Bits per pixel; 0 indicates invalid */
  250. u32 width; /* In pixel */
  251. u32 height; /* In lines */
  252. char *desc; /* The description */
  253. };
  254. static struct cursor_mode_format cursor_pixel_formats[] = {
  255. {DRM_FORMAT_ARGB8888, 32, 128, 128, "128x128 32bpp ARGB"},
  256. {DRM_FORMAT_ARGB8888, 32, 256, 256, "256x256 32bpp ARGB"},
  257. {DRM_FORMAT_ARGB8888, 32, 64, 64, "64x64 32bpp ARGB"},
  258. {DRM_FORMAT_ARGB8888, 32, 64, 64, "64x64 32bpp ARGB"},
  259. /* non-supported format has bpp default to 0 */
  260. {0, 0, 0, 0, NULL},
  261. };
  262. static int cursor_mode_to_drm(int mode)
  263. {
  264. int cursor_pixel_formats_index = 4;
  265. switch (mode) {
  266. case MCURSOR_MODE_128_ARGB_AX:
  267. cursor_pixel_formats_index = 0;
  268. break;
  269. case MCURSOR_MODE_256_ARGB_AX:
  270. cursor_pixel_formats_index = 1;
  271. break;
  272. case MCURSOR_MODE_64_ARGB_AX:
  273. cursor_pixel_formats_index = 2;
  274. break;
  275. case MCURSOR_MODE_64_32B_AX:
  276. cursor_pixel_formats_index = 3;
  277. break;
  278. default:
  279. break;
  280. }
  281. return cursor_pixel_formats_index;
  282. }
  283. /**
  284. * intel_vgpu_decode_cursor_plane - Decode sprite plane
  285. * @vgpu: input vgpu
  286. * @plane: cursor plane to save decoded info
  287. * This function is called for decoding plane
  288. *
  289. * Returns:
  290. * 0 on success, non-zero if failed.
  291. */
  292. int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
  293. struct intel_vgpu_cursor_plane_format *plane)
  294. {
  295. u32 val, mode, index;
  296. u32 alpha_plane, alpha_force;
  297. struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
  298. int pipe;
  299. pipe = get_active_pipe(vgpu);
  300. if (pipe >= I915_MAX_PIPES)
  301. return -ENODEV;
  302. val = vgpu_vreg_t(vgpu, CURCNTR(pipe));
  303. mode = val & MCURSOR_MODE;
  304. plane->enabled = (mode != MCURSOR_MODE_DISABLE);
  305. if (!plane->enabled)
  306. return -ENODEV;
  307. index = cursor_mode_to_drm(mode);
  308. if (!cursor_pixel_formats[index].bpp) {
  309. gvt_vgpu_err("Non-supported cursor mode (0x%x)\n", mode);
  310. return -EINVAL;
  311. }
  312. plane->mode = mode;
  313. plane->bpp = cursor_pixel_formats[index].bpp;
  314. plane->drm_format = cursor_pixel_formats[index].drm_format;
  315. plane->width = cursor_pixel_formats[index].width;
  316. plane->height = cursor_pixel_formats[index].height;
  317. alpha_plane = (val & _CURSOR_ALPHA_PLANE_MASK) >>
  318. _CURSOR_ALPHA_PLANE_SHIFT;
  319. alpha_force = (val & _CURSOR_ALPHA_FORCE_MASK) >>
  320. _CURSOR_ALPHA_FORCE_SHIFT;
  321. if (alpha_plane || alpha_force)
  322. gvt_dbg_core("alpha_plane=0x%x, alpha_force=0x%x\n",
  323. alpha_plane, alpha_force);
  324. plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
  325. if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
  326. return -EINVAL;
  327. plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
  328. if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
  329. gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n",
  330. plane->base);
  331. return -EINVAL;
  332. }
  333. val = vgpu_vreg_t(vgpu, CURPOS(pipe));
  334. plane->x_pos = (val & _CURSOR_POS_X_MASK) >> _CURSOR_POS_X_SHIFT;
  335. plane->x_sign = (val & _CURSOR_SIGN_X_MASK) >> _CURSOR_SIGN_X_SHIFT;
  336. plane->y_pos = (val & _CURSOR_POS_Y_MASK) >> _CURSOR_POS_Y_SHIFT;
  337. plane->y_sign = (val & _CURSOR_SIGN_Y_MASK) >> _CURSOR_SIGN_Y_SHIFT;
  338. plane->x_hot = vgpu_vreg_t(vgpu, vgtif_reg(cursor_x_hot));
  339. plane->y_hot = vgpu_vreg_t(vgpu, vgtif_reg(cursor_y_hot));
  340. return 0;
  341. }
  342. #define SPRITE_FORMAT_NUM (1 << 3)
  343. static struct pixel_format sprite_pixel_formats[SPRITE_FORMAT_NUM] = {
  344. [0x0] = {DRM_FORMAT_YUV422, 16, "YUV 16-bit 4:2:2 packed"},
  345. [0x1] = {DRM_FORMAT_XRGB2101010, 32, "RGB 32-bit 2:10:10:10"},
  346. [0x2] = {DRM_FORMAT_XRGB8888, 32, "RGB 32-bit 8:8:8:8"},
  347. [0x4] = {DRM_FORMAT_AYUV, 32,
  348. "YUV 32-bit 4:4:4 packed (8:8:8:8 MSB-X:Y:U:V)"},
  349. };
  350. /**
  351. * intel_vgpu_decode_sprite_plane - Decode sprite plane
  352. * @vgpu: input vgpu
  353. * @plane: sprite plane to save decoded info
  354. * This function is called for decoding plane
  355. *
  356. * Returns:
  357. * 0 on success, non-zero if failed.
  358. */
  359. int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
  360. struct intel_vgpu_sprite_plane_format *plane)
  361. {
  362. u32 val, fmt;
  363. u32 color_order, yuv_order;
  364. int drm_format;
  365. int pipe;
  366. pipe = get_active_pipe(vgpu);
  367. if (pipe >= I915_MAX_PIPES)
  368. return -ENODEV;
  369. val = vgpu_vreg_t(vgpu, SPRCTL(pipe));
  370. plane->enabled = !!(val & SPRITE_ENABLE);
  371. if (!plane->enabled)
  372. return -ENODEV;
  373. plane->tiled = !!(val & SPRITE_TILED);
  374. color_order = !!(val & SPRITE_RGB_ORDER_RGBX);
  375. yuv_order = (val & SPRITE_YUV_BYTE_ORDER_MASK) >>
  376. _SPRITE_YUV_ORDER_SHIFT;
  377. fmt = (val & SPRITE_PIXFORMAT_MASK) >> _SPRITE_FMT_SHIFT;
  378. if (!sprite_pixel_formats[fmt].bpp) {
  379. gvt_vgpu_err("Non-supported pixel format (0x%x)\n", fmt);
  380. return -EINVAL;
  381. }
  382. plane->hw_format = fmt;
  383. plane->bpp = sprite_pixel_formats[fmt].bpp;
  384. drm_format = sprite_pixel_formats[fmt].drm_format;
  385. /* Order of RGB values in an RGBxxx buffer may be ordered RGB or
  386. * BGR depending on the state of the color_order field
  387. */
  388. if (!color_order) {
  389. if (drm_format == DRM_FORMAT_XRGB2101010)
  390. drm_format = DRM_FORMAT_XBGR2101010;
  391. else if (drm_format == DRM_FORMAT_XRGB8888)
  392. drm_format = DRM_FORMAT_XBGR8888;
  393. }
  394. if (drm_format == DRM_FORMAT_YUV422) {
  395. switch (yuv_order) {
  396. case 0:
  397. drm_format = DRM_FORMAT_YUYV;
  398. break;
  399. case 1:
  400. drm_format = DRM_FORMAT_UYVY;
  401. break;
  402. case 2:
  403. drm_format = DRM_FORMAT_YVYU;
  404. break;
  405. case 3:
  406. drm_format = DRM_FORMAT_VYUY;
  407. break;
  408. default:
  409. /* yuv_order has only 2 bits */
  410. break;
  411. }
  412. }
  413. plane->drm_format = drm_format;
  414. plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
  415. if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
  416. return -EINVAL;
  417. plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
  418. if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
  419. gvt_vgpu_err("Translate sprite plane gma 0x%x to gpa fail\n",
  420. plane->base);
  421. return -EINVAL;
  422. }
  423. plane->stride = vgpu_vreg_t(vgpu, SPRSTRIDE(pipe)) &
  424. _SPRITE_STRIDE_MASK;
  425. val = vgpu_vreg_t(vgpu, SPRSIZE(pipe));
  426. plane->height = (val & _SPRITE_SIZE_HEIGHT_MASK) >>
  427. _SPRITE_SIZE_HEIGHT_SHIFT;
  428. plane->width = (val & _SPRITE_SIZE_WIDTH_MASK) >>
  429. _SPRITE_SIZE_WIDTH_SHIFT;
  430. plane->height += 1; /* raw height is one minus the real value */
  431. plane->width += 1; /* raw width is one minus the real value */
  432. val = vgpu_vreg_t(vgpu, SPRPOS(pipe));
  433. plane->x_pos = (val & _SPRITE_POS_X_MASK) >> _SPRITE_POS_X_SHIFT;
  434. plane->y_pos = (val & _SPRITE_POS_Y_MASK) >> _SPRITE_POS_Y_SHIFT;
  435. val = vgpu_vreg_t(vgpu, SPROFFSET(pipe));
  436. plane->x_offset = (val & _SPRITE_OFFSET_START_X_MASK) >>
  437. _SPRITE_OFFSET_START_X_SHIFT;
  438. plane->y_offset = (val & _SPRITE_OFFSET_START_Y_MASK) >>
  439. _SPRITE_OFFSET_START_Y_SHIFT;
  440. return 0;
  441. }