29 #include <drm/i915_drm.h>
38 #define IMAGE_MAX_WIDTH 2048
39 #define IMAGE_MAX_HEIGHT 2046
41 #define IMAGE_MAX_WIDTH_LEGACY 1024
42 #define IMAGE_MAX_HEIGHT_LEGACY 1088
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)
53 #define OCMD_UV_SWAP (0x1<<14)
54 #define OCMD_Y_SWAP (0x2<<14)
55 #define OCMD_Y_AND_UV_SWAP (0x3<<14)
56 #define OCMD_SOURCE_FORMAT_MASK (0xf<<10)
57 #define OCMD_RGB_888 (0x1<<10)
58 #define OCMD_RGB_555 (0x2<<10)
59 #define OCMD_RGB_565 (0x3<<10)
60 #define OCMD_YUV_422_PACKED (0x8<<10)
61 #define OCMD_YUV_411_PACKED (0x9<<10)
62 #define OCMD_YUV_420_PLANAR (0xc<<10)
63 #define OCMD_YUV_422_PLANAR (0xd<<10)
64 #define OCMD_YUV_410_PLANAR (0xe<<10)
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)
80 #define OCONF_PIPE_MASK (0x1<<18)
81 #define OCONF_PIPE_A (0x0<<18)
82 #define OCONF_PIPE_B (0x1<<18)
83 #define OCONF_GAMMA2_ENABLE (0x1<<16)
84 #define OCONF_CSC_MODE_BT601 (0x0<<5)
85 #define OCONF_CSC_MODE_BT709 (0x1<<5)
86 #define OCONF_CSC_BYPASS (0x1<<4)
87 #define OCONF_CC_OUT_8BIT (0x1<<3)
88 #define OCONF_TEST_MODE (0x1<<2)
89 #define OCONF_THREE_LINE_BUFFER (0x1<<0)
90 #define OCONF_TWO_LINE_BUFFER (0x0<<0)
93 #define DST_KEY_ENABLE (0x1<<31)
94 #define CLK_RGB24_MASK 0x0
95 #define CLK_RGB16_MASK 0x070307
96 #define CLK_RGB15_MASK 0x070707
97 #define CLK_RGB8I_MASK 0xffffff
99 #define RGB16_TO_COLORKEY(c) \
100 (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
101 #define RGB15_TO_COLORKEY(c) \
102 (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
105 #define OFC_UPDATE 0x1
108 #define N_HORIZ_Y_TAPS 5
109 #define N_VERT_Y_TAPS 3
110 #define N_HORIZ_UV_TAPS 3
111 #define N_VERT_UV_TAPS 3
198 regs = io_mapping_map_wc(dev_priv->
mm.gtt_mapping,
199 overlay->
reg_bo->gtt_offset);
208 io_mapping_unmap(regs);
211 static int intel_overlay_do_wait_request(
struct intel_overlay *overlay,
254 intel_ring_emit(ring,
MI_NOOP);
257 return intel_overlay_do_wait_request(overlay,
NULL);
261 static int intel_overlay_continue(
struct intel_overlay *overlay,
262 bool load_polyphase_filter)
273 if (load_polyphase_filter)
279 DRM_DEBUG(
"overlay underrun, DOVSTA: %x\n", tmp);
286 intel_ring_emit(ring, flip_addr);
292 static void intel_overlay_release_old_vid_tail(
struct intel_overlay *overlay)
297 drm_gem_object_unreference(&obj->
base);
302 static void intel_overlay_off_tail(
struct intel_overlay *overlay)
310 drm_gem_object_unreference(&obj->
base);
341 intel_ring_emit(ring, flip_addr);
347 intel_ring_emit(ring,
MI_NOOP);
348 intel_ring_emit(ring,
MI_NOOP);
349 intel_ring_emit(ring,
MI_NOOP);
352 intel_ring_emit(ring, flip_addr);
357 return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
362 static int intel_overlay_recover_from_interrupt(
struct intel_overlay *overlay)
388 static int intel_overlay_release_old_vid(
struct intel_overlay *overlay)
408 intel_ring_emit(ring,
MI_NOOP);
411 ret = intel_overlay_do_wait_request(overlay,
412 intel_overlay_release_old_vid_tail);
417 intel_overlay_release_old_vid_tail(overlay);
438 static int packed_depth_bytes(
u32 format)
460 static int uv_hsubsampling(
u32 format)
474 static int uv_vsubsampling(
u32 format)
498 ret = ((offset + width +
mask) >> shift) - (offset >> shift);
506 0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0,
507 0x3000, 0xb500, 0x19d0, 0x1880, 0xb440,
508 0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0,
509 0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380,
510 0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320,
511 0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0,
512 0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260,
513 0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200,
514 0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0,
515 0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160,
516 0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120,
517 0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0,
518 0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0,
519 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
520 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
521 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
522 0xb000, 0x3000, 0x0800, 0x3000, 0xb000
526 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
527 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
528 0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880,
529 0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00,
530 0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0,
531 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
532 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
533 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
534 0x3000, 0x0800, 0x3000
539 memcpy_toio(regs->Y_HCOEFS, y_static_hcoeffs,
sizeof(y_static_hcoeffs));
541 sizeof(uv_static_hcoeffs));
544 static bool update_scaling_factors(
struct intel_overlay *overlay,
549 u32 xscale, yscale, xscale_UV, yscale_UV;
551 #define FRACT_MASK 0xfff
552 bool scale_changed =
false;
553 int uv_hscale = uv_hsubsampling(params->
format);
554 int uv_vscale = uv_vsubsampling(params->
format);
556 if (params->
dst_w > 1)
557 xscale = ((params->
src_scan_w - 1) << FP_SHIFT)
562 if (params->
dst_h > 1)
563 yscale = ((params->
src_scan_h - 1) << FP_SHIFT)
569 xscale_UV = xscale/uv_hscale;
570 yscale_UV = yscale/uv_vscale;
572 xscale = xscale_UV * uv_hscale;
573 yscale = yscale_UV * uv_vscale;
580 scale_changed =
true;
584 iowrite32(((yscale & FRACT_MASK) << 20) |
585 ((xscale >> FP_SHIFT) << 16) |
586 ((xscale & FRACT_MASK) << 3),
589 iowrite32(((yscale_UV & FRACT_MASK) << 20) |
590 ((xscale_UV >> FP_SHIFT) << 16) |
591 ((xscale_UV & FRACT_MASK) << 3),
594 iowrite32((((yscale >> FP_SHIFT) << 16) |
595 ((yscale_UV >> FP_SHIFT) << 0)),
599 update_polyphase_filter(regs);
601 return scale_changed;
609 switch (overlay->
crtc->base.fb->bits_per_pixel) {
616 if (overlay->
crtc->base.fb->depth == 15) {
680 static int intel_overlay_do_put_image(
struct intel_overlay *overlay,
686 bool scale_changed =
false;
688 u32 swidth, swidthsw, sheight, ostride;
690 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
691 BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
694 ret = intel_overlay_release_old_vid(overlay);
708 regs = intel_overlay_map_regs(overlay);
716 oconfig |= overlay->
crtc->pipe == 0 ?
719 intel_overlay_unmap_regs(overlay, regs);
721 ret = intel_overlay_on(overlay);
726 regs = intel_overlay_map_regs(overlay);
736 tmp_width = packed_width_bytes(params->
format, params->
src_w);
738 tmp_width = params->
src_w;
740 swidth = params->
src_w;
741 swidthsw = calc_swidthsw(overlay->
dev, params->
offset_Y, tmp_width);
742 sheight = params->
src_h;
747 int uv_hscale = uv_hsubsampling(params->
format);
748 int uv_vscale = uv_vsubsampling(params->
format);
750 swidth |= (params->
src_w/uv_hscale) << 16;
751 tmp_U = calc_swidthsw(overlay->
dev, params->
offset_U,
752 params->
src_w/uv_hscale);
753 tmp_V = calc_swidthsw(overlay->
dev, params->
offset_V,
754 params->
src_w/uv_hscale);
755 swidthsw |=
max_t(
u32, tmp_U, tmp_V) << 16;
756 sheight |= (params->
src_h/uv_vscale) << 16;
767 scale_changed = update_scaling_factors(overlay, regs, params);
769 update_colorkey(overlay, regs);
773 intel_overlay_unmap_regs(overlay, regs);
775 ret = intel_overlay_continue(overlay, scale_changed);
795 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
796 BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
798 ret = intel_overlay_recover_from_interrupt(overlay);
805 ret = intel_overlay_release_old_vid(overlay);
809 regs = intel_overlay_map_regs(overlay);
811 intel_overlay_unmap_regs(overlay, regs);
813 ret = intel_overlay_off(overlay);
817 intel_overlay_off_tail(overlay);
821 static int check_overlay_possible_on_crtc(
struct intel_overlay *overlay,
837 static void update_pfit_vscale_ratio(
struct intel_overlay *overlay)
890 static int check_overlay_src(
struct drm_device *dev,
894 int uv_hscale = uv_hsubsampling(rec->
flags);
895 int uv_vscale = uv_vsubsampling(rec->
flags);
926 depth = packed_depth_bytes(rec->
flags);
940 if (uv_vscale < 0 || uv_hscale < 0)
1005 static int intel_panel_fitter_pipe(
struct drm_device *dev)
1022 return (pfit_control >> 29) & 0x3;
1029 struct drm_file *file_priv)
1043 DRM_DEBUG(
"userspace bug: no overlay\n");
1082 DRM_ERROR(
"buffer used for overlay image can not be tiled\n");
1087 ret = intel_overlay_recover_from_interrupt(overlay);
1091 if (overlay->
crtc != crtc) {
1097 ret = check_overlay_possible_on_crtc(overlay, crtc);
1101 overlay->
crtc = crtc;
1106 intel_panel_fitter_pipe(dev) == crtc->
pipe) {
1108 update_pfit_vscale_ratio(overlay);
1113 ret = check_overlay_dst(overlay, put_image_rec);
1140 ret = check_overlay_src(dev, put_image_rec, new_bo);
1151 ret = check_overlay_scaling(params);
1155 ret = intel_overlay_do_put_image(overlay, new_bo, params);
1169 drm_gem_object_unreference_unlocked(&new_bo->
base);
1188 if (gamma1 & 0xff000000 || gamma2 & 0xff000000)
1191 for (i = 0; i < 3; i++) {
1192 if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
1199 static bool check_gamma5_errata(
u32 gamma5)
1203 for (i = 0; i < 3; i++) {
1204 if (((gamma5 >> i*8) & 0xff) == 0x80)
1213 if (!check_gamma_bounds(0, attrs->
gamma0) ||
1219 !check_gamma_bounds(attrs->
gamma5, 0x00ffffff))
1222 if (!check_gamma5_errata(attrs->
gamma5))
1229 struct drm_file *file_priv)
1240 DRM_DEBUG(
"userspace bug: no overlay\n");
1275 regs = intel_overlay_map_regs(overlay);
1281 update_reg_attrs(overlay, regs);
1283 intel_overlay_unmap_regs(overlay, regs);
1294 ret = check_gamma(attrs);
1339 overlay->
reg_bo = reg_bo;
1346 DRM_ERROR(
"failed to attach phys overlay regs\n");
1353 DRM_ERROR(
"failed to pin overlay register bo\n");
1360 DRM_ERROR(
"failed to move overlay register bo into the GTT\n");
1371 regs = intel_overlay_map_regs(overlay);
1376 update_polyphase_filter(regs);
1377 update_reg_attrs(overlay, regs);
1379 intel_overlay_unmap_regs(overlay, regs);
1383 DRM_INFO(
"initialized overlay support\n");
1390 drm_gem_object_unreference(®_bo->
base);
1409 drm_gem_object_unreference_unlocked(&dev_priv->
overlay->reg_bo->base);
1413 #ifdef CONFIG_DEBUG_FS
1416 struct intel_overlay_error_state {
1424 intel_overlay_map_regs_atomic(
struct intel_overlay *overlay)
1433 overlay->
reg_bo->phys_obj->handle->vaddr;
1435 regs = io_mapping_map_atomic_wc(dev_priv->
mm.gtt_mapping,
1436 overlay->
reg_bo->gtt_offset);
1441 static void intel_overlay_unmap_regs_atomic(
struct intel_overlay *overlay,
1445 io_mapping_unmap_atomic(regs);
1449 struct intel_overlay_error_state *
1450 intel_overlay_capture_error_state(
struct drm_device *dev)
1454 struct intel_overlay_error_state *
error;
1457 if (!overlay || !overlay->
active)
1469 error->base = overlay->
reg_bo->gtt_offset;
1471 regs = intel_overlay_map_regs_atomic(overlay);
1476 intel_overlay_unmap_regs_atomic(overlay, regs);
1486 intel_overlay_print_error_state(
struct seq_file *
m,
struct intel_overlay_error_state *error)
1488 seq_printf(m,
"Overlay, status: 0x%08x, interrupt: 0x%08x\n",
1489 error->dovsta, error->isr);
1490 seq_printf(m,
" Register file at 0x%08lx:\n",
1493 #define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x)