Hi, On 05/08/2015 09:40 PM, Chandra Konduru wrote: > This patch is adding NV12 support to skylake primary plane > programming. It is covering linear/X/Y/Yf tiling formats > for 0 and 180 rotations. > > For 90/270 rotation, Y and UV subplanes should be treated > as separate surfaces and GTT remapping for rotation should > be done separately for each subplane. Once GEM adds support > for seperate remappings for two subplanes, 90/270 support > to be added to plane programming. > > v2: > -Use regular int instead of 16.16 in aux_offset calculations (me) > > Signed-off-by: Chandra Konduru <chandra.konduru@xxxxxxxxx> > Testcase: igt/kms_nv12 > --- > drivers/gpu/drm/i915/intel_atomic_plane.c | 2 ++ > drivers/gpu/drm/i915/intel_display.c | 38 +++++++++++++++++++++++++++++ > 2 files changed, 40 insertions(+) > > diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c > index 86ba4b2..119439d 100644 > --- a/drivers/gpu/drm/i915/intel_atomic_plane.c > +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c > @@ -185,10 +185,12 @@ static int intel_plane_atomic_check(struct drm_plane *plane, > * 90/270 is not allowed with RGB64 16:16:16:16, > * RGB 16-bit 5:6:5, and Indexed 8-bit. > * TBD: Add RGB64 case once its added in supported format list. > + * TBD: Remove NV12, once its 90/270 remapping is supported > */ > switch (state->fb->pixel_format) { > case DRM_FORMAT_C8: > case DRM_FORMAT_RGB565: > + case DRM_FORMAT_NV12: > DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", > drm_get_format_name(state->fb->pixel_format)); > return -EINVAL; > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 3ae646e..943a835 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -3015,6 +3015,9 @@ u32 skl_plane_ctl_format(uint32_t pixel_format) > case DRM_FORMAT_VYUY: > plane_ctl_format = PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY; > break; > + case DRM_FORMAT_NV12: > + plane_ctl_format = PLANE_CTL_FORMAT_NV12; > + break; > default: > BUG(); > } > @@ -3085,6 +3088,8 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, > int src_x = 0, src_y = 0, src_w = 0, src_h = 0; > int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0; > int scaler_id = -1; > + u32 aux_dist = 0, aux_x_offset = 0, aux_y_offset = 0, aux_stride = 0; > + u32 tile_row_adjustment = 0; > > plane_state = to_intel_plane_state(plane->state); > > @@ -3141,11 +3146,34 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, > x_offset = stride * tile_height - y - src_h; > y_offset = x; > plane_size = (src_w - 1) << 16 | (src_h - 1); > + /* > + * TBD: For NV12 90/270 rotation, Y and UV subplanes should > + * be treated as separate surfaces and GTT remapping for > + * rotation should be done separately for each subplane. > + * Enable support once seperate remappings are available. > + */ > } else { > stride = fb->pitches[0] / stride_div; > x_offset = x; > y_offset = y; > plane_size = (src_h - 1) << 16 | (src_w - 1); > + tile_height = PAGE_SIZE / stride_div; > + > + if (fb->pixel_format == DRM_FORMAT_NV12) { > + int height_in_mem = (fb->offsets[1]/fb->pitches[0]); > + /* > + * If UV starts from middle of a page, then UV start should > + * be programmed to beginning of that page. And offset into that > + * page to be programmed into y-offset > + */ > + tile_row_adjustment = height_in_mem % tile_height; > + aux_dist = fb->pitches[0] * (height_in_mem - tile_row_adjustment); > + aux_x_offset = DIV_ROUND_UP(x, 2); > + aux_y_offset = DIV_ROUND_UP(y, 2) + tile_row_adjustment; > + /* For tile-Yf, uv-subplane tile width is 2x of Y-subplane */ > + aux_stride = fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED ? > + stride / 2 : stride; > + } > } > plane_offset = y_offset << 16 | x_offset; > > @@ -3153,11 +3181,14 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, > I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset); > I915_WRITE(PLANE_SIZE(pipe, 0), plane_size); > I915_WRITE(PLANE_STRIDE(pipe, 0), stride); > + I915_WRITE(PLANE_AUX_DIST(pipe, 0), aux_dist | aux_stride); > + I915_WRITE(PLANE_AUX_OFFSET(pipe, 0), aux_y_offset << 16 | aux_x_offset); > > if (scaler_id >= 0) { > uint32_t ps_ctrl = 0; > > WARN_ON(!dst_w || !dst_h); > + > ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(0) | > crtc_state->scaler_state.scalers[scaler_id].mode; > I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl); > @@ -3166,6 +3197,7 @@ static void skylake_update_primary_plane(struct drm_crtc *crtc, > I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), (dst_w << 16) | dst_h); > I915_WRITE(PLANE_POS(pipe, 0), 0); > } else { > + WARN_ON(fb->pixel_format == DRM_FORMAT_NV12); > I915_WRITE(PLANE_POS(pipe, 0), (dst_y << 16) | dst_x); I've hit this WARN_ON with kms_rotation_crc by just changing the format of frame buffers it creates to NV12 (so even before any rotation happens). Small snippet: [ 906.408194] [drm:skl_update_scaler_users] PLANE:17 staged scaling request for 3200x1800->3200x1800 crtc_state = ffff880037348800 scaler_users = 0x1 [ 906.436759] ------------[ cut here ]------------ [ 906.442107] WARNING: CPU: 0 PID: 1709 at drivers/gpu/drm/i915/intel_display.c:3225 skylake_update_primary_plane+0x678/0x6e0 [i915]() [ 906.455620] WARN_ON(fb->pixel_format == DRM_FORMAT_NV12) [ 906.461451] Modules linked in: coretemp i915 drm_kms_helper drm i2c_algo_bit i2c_hid video pinctrl_sunrisepoint pinctrl_intel acpi_pad nls_iso8859_1 hid_generic usbhid hid e1000e ptp psmouse ahci pps_core libahci [ 906.483472] CPU: 0 PID: 1709 Comm: kms_rotation_cr Tainted: G U W 4.1.0-rc3-150511+ #12 [ 906.493638] Hardware name: Intel Corporation Skylake Client platform/Skylake Y LPDDR3 RVP3, BIOS SKLSE2R1.86C.X070.R01.1501282110 01/28/2015 [ 906.507938] 0000000000000c99 ffff88009bc979a8 ffffffff8161283d 0000000000000007 [ 906.516410] ffff88009bc979f8 ffff88009bc979e8 ffffffff81050062 ffff88009acd0000 [ 906.524874] ffff88009acd0000 ffff8800372356c0 0000000000000000 00000000c1802000 [ 906.533341] Call Trace: [ 906.536135] [<ffffffff8161283d>] dump_stack+0x4c/0x6e [ 906.541979] [<ffffffff81050062>] warn_slowpath_common+0xb2/0xe0 [ 906.548802] [<ffffffff81050146>] warn_slowpath_fmt+0x46/0x50 [ 906.555408] [<ffffffffa0242cf8>] skylake_update_primary_plane+0x678/0x6e0 [i915] [ 906.563980] [<ffffffffa023cca3>] intel_commit_primary_plane+0x93/0xb0 [i915] [ 906.572158] [<ffffffffa025fa49>] intel_plane_atomic_update+0x19/0x20 [i915] [ 906.580180] [<ffffffffa01b026a>] drm_atomic_helper_commit_planes+0x17a/0x210 [drm_kms_helper] [ 906.590029] [<ffffffffa0245de3>] __intel_set_mode+0xbf3/0xcd0 [i915] [ 906.597418] [<ffffffffa024bdae>] intel_crtc_set_config+0x4ee/0x650 [i915] [ 906.605277] [<ffffffffa014b549>] drm_mode_set_config_internal+0x69/0x120 [drm] [ 906.613618] [<ffffffffa0150b48>] drm_mode_setcrtc+0x558/0x650 [drm] [ 906.620856] [<ffffffffa0140f19>] drm_ioctl+0x3f9/0x650 [drm] [ 906.627419] [<ffffffffa01505f0>] ? drm_mode_setplane+0x200/0x200 [drm] [ 906.634939] [<ffffffff8116a1f3>] do_vfs_ioctl+0x543/0x5a0 [ 906.641170] [<ffffffff810a8576>] ? rcu_eqs_exit+0x96/0xb0 [ 906.647408] [<ffffffff81095f2d>] ? trace_hardirqs_on+0xd/0x10 [ 906.654038] [<ffffffff81175cd7>] ? __fget_light+0x57/0xa0 [ 906.660271] [<ffffffff8116a29c>] SyS_ioctl+0x4c/0x90 [ 906.666031] [<ffffffff8161aed7>] system_call_fastpath+0x12/0x6f [ 906.672854] ---[ end trace 599568c0e80eee2a ]--- [ 906.678235] [drm:intel_pipe_update_end [i915]] *ERROR* Atomic update failure on pipe A (start=10907 end=10921) [ 906.679305] [drm:intel_cpu_fifo_underrun_irq_handler [i915]] *ERROR* CPU pipe A FIFO underrun Machine even hard hangs in the process. Either way, it is probably bad that userspace can hit this WARN_ON just by trying to display a NV12 frame buffer. Regards, Tvrtko _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx