fb_decoder.c 14 KB

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