From 3257ec797d3a8c5232389eb1952d4451e80f3931 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 17 May 2018 15:37:59 +0200 Subject: drm/vc4: plane: Expand the lower bits by repeating the higher bits The vc4 HVS uses an internal RGB888 representation of the frames, and will by default expand formats using a lower depth using zeros. This causes an issue when we try to use other compositing software such as pixman that fill the missing bits by repeating the higher significant bits. As such, we can't check the display output in a reliable way by doing a software composition and an hardware one and compare both. To prevent this, force the same behaviour so that we can do such things. Signed-off-by: Maxime Ripard Signed-off-by: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20180517133759.25626-1-maxime.ripard@bootlin.com --- drivers/gpu/drm/vc4/vc4_plane.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/vc4/vc4_plane.c') diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 3483c05cc3d6..6e8984aee613 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -544,6 +544,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, /* Control word */ vc4_dlist_write(vc4_state, SCALER_CTL0_VALID | + VC4_SET_FIELD(SCALER_CTL0_RGBA_EXPAND_ROUND, SCALER_CTL0_RGBA_EXPAND) | (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) | (format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) | VC4_SET_FIELD(tiling, SCALER_CTL0_TILING) | -- cgit From 1e871d65e375280757833d9fce91dda71980bdf5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 16 Mar 2018 15:04:34 -0700 Subject: drm/vc4: Add missing formats to vc4_format_mod_supported(). Daniel's format_mod_supported() patch predated Dave's for NV21/61, and I didn't catch that when rebasing. This is a problem since the formats are now getting validated before being passed to the driver's atomic hooks. Signed-off-by: Eric Anholt Acked-by: Daniel Stone Cc: Dave Stevenson Fixes: 423ad7b3cbd1 ("drm/vc4: Advertise supported modifiers for planes") Link: https://patchwork.freedesktop.org/patch/msgid/20180316220435.31416-2-eric@anholt.net --- drivers/gpu/drm/vc4/vc4_plane.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/vc4/vc4_plane.c') diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 6e8984aee613..6efd55bae8db 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -873,7 +873,9 @@ static bool vc4_format_mod_supported(struct drm_plane *plane, case DRM_FORMAT_YUV420: case DRM_FORMAT_YVU420: case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: case DRM_FORMAT_NV16: + case DRM_FORMAT_NV61: default: return (modifier == DRM_FORMAT_MOD_LINEAR); } -- cgit From e065a8dd30af703b4794dc740c0825ee12b92efd Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Fri, 16 Mar 2018 15:04:35 -0700 Subject: drm/vc4: Add support for SAND modifier. This is the format generated by VC4's H.264 engine, and preferred by the ISP as well. By displaying SAND buffers directly, we can avoid needing to use the ISP to rewrite the SAND H.264 output to linear before display. This is a joint effort by Dave Stevenson (who wrote the initial patch and DRM demo) and Eric Anholt (drm_fourcc.h generalization, safety checks, RGBA support). v2: Make the parameter macro give all of the middle 48 bits (suggested by Daniels). Fix fourcc_mod_broadcom_mod()'s bits/shift being swapped. Mark NV12/21 as supported, not YUV420. Signed-off-by: Dave Stevenson Signed-off-by: Eric Anholt Cc: Daniel Vetter Acked-by: Daniel Stone (v1) Cc: Boris Brezillon Cc: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20180316220435.31416-3-eric@anholt.net --- drivers/gpu/drm/vc4/vc4_plane.c | 84 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/vc4/vc4_plane.c') diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 6efd55bae8db..2575bd81a010 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -467,12 +467,14 @@ static int vc4_plane_mode_set(struct drm_plane *plane, struct drm_framebuffer *fb = state->fb; u32 ctl0_offset = vc4_state->dlist_count; const struct hvs_format *format = vc4_get_hvs_format(fb->format->format); + u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier); int num_planes = drm_format_num_planes(format->drm); bool mix_plane_alpha; bool covers_screen; u32 scl0, scl1, pitch0; u32 lbm_size, tiling; unsigned long irqflags; + u32 hvs_format = format->hvs; int ret, i; ret = vc4_plane_setup_clipping_and_scaling(state); @@ -512,7 +514,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, scl1 = vc4_get_scl_field(state, 0); } - switch (fb->modifier) { + switch (base_format_mod) { case DRM_FORMAT_MOD_LINEAR: tiling = SCALER_CTL0_TILING_LINEAR; pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH); @@ -535,6 +537,49 @@ static int vc4_plane_mode_set(struct drm_plane *plane, break; } + case DRM_FORMAT_MOD_BROADCOM_SAND64: + case DRM_FORMAT_MOD_BROADCOM_SAND128: + case DRM_FORMAT_MOD_BROADCOM_SAND256: { + uint32_t param = fourcc_mod_broadcom_param(fb->modifier); + + /* Column-based NV12 or RGBA. + */ + if (fb->format->num_planes > 1) { + if (hvs_format != HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE) { + DRM_DEBUG_KMS("SAND format only valid for NV12/21"); + return -EINVAL; + } + hvs_format = HVS_PIXEL_FORMAT_H264; + } else { + if (base_format_mod == DRM_FORMAT_MOD_BROADCOM_SAND256) { + DRM_DEBUG_KMS("SAND256 format only valid for H.264"); + return -EINVAL; + } + } + + switch (base_format_mod) { + case DRM_FORMAT_MOD_BROADCOM_SAND64: + tiling = SCALER_CTL0_TILING_64B; + break; + case DRM_FORMAT_MOD_BROADCOM_SAND128: + tiling = SCALER_CTL0_TILING_128B; + break; + case DRM_FORMAT_MOD_BROADCOM_SAND256: + tiling = SCALER_CTL0_TILING_256B_OR_T; + break; + default: + break; + } + + if (param > SCALER_TILE_HEIGHT_MASK) { + DRM_DEBUG_KMS("SAND height too large (%d)\n", param); + return -EINVAL; + } + + pitch0 = VC4_SET_FIELD(param, SCALER_TILE_HEIGHT); + break; + } + default: DRM_DEBUG_KMS("Unsupported FB tiling flag 0x%16llx", (long long)fb->modifier); @@ -546,7 +591,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, SCALER_CTL0_VALID | VC4_SET_FIELD(SCALER_CTL0_RGBA_EXPAND_ROUND, SCALER_CTL0_RGBA_EXPAND) | (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) | - (format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) | + (hvs_format << SCALER_CTL0_PIXEL_FORMAT_SHIFT) | VC4_SET_FIELD(tiling, SCALER_CTL0_TILING) | (vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) | VC4_SET_FIELD(scl0, SCALER_CTL0_SCL0) | @@ -608,8 +653,13 @@ static int vc4_plane_mode_set(struct drm_plane *plane, /* Pitch word 1/2 */ for (i = 1; i < num_planes; i++) { - vc4_dlist_write(vc4_state, - VC4_SET_FIELD(fb->pitches[i], SCALER_SRC_PITCH)); + if (hvs_format != HVS_PIXEL_FORMAT_H264) { + vc4_dlist_write(vc4_state, + VC4_SET_FIELD(fb->pitches[i], + SCALER_SRC_PITCH)); + } else { + vc4_dlist_write(vc4_state, pitch0); + } } /* Colorspace conversion words */ @@ -867,13 +917,30 @@ static bool vc4_format_mod_supported(struct drm_plane *plane, case DRM_FORMAT_BGR565: case DRM_FORMAT_ARGB1555: case DRM_FORMAT_XRGB1555: - return true; + switch (fourcc_mod_broadcom_mod(modifier)) { + case DRM_FORMAT_MOD_LINEAR: + case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED: + case DRM_FORMAT_MOD_BROADCOM_SAND64: + case DRM_FORMAT_MOD_BROADCOM_SAND128: + return true; + default: + return false; + } + case DRM_FORMAT_NV12: + case DRM_FORMAT_NV21: + switch (fourcc_mod_broadcom_mod(modifier)) { + case DRM_FORMAT_MOD_LINEAR: + case DRM_FORMAT_MOD_BROADCOM_SAND64: + case DRM_FORMAT_MOD_BROADCOM_SAND128: + case DRM_FORMAT_MOD_BROADCOM_SAND256: + return true; + default: + return false; + } case DRM_FORMAT_YUV422: case DRM_FORMAT_YVU422: case DRM_FORMAT_YUV420: case DRM_FORMAT_YVU420: - case DRM_FORMAT_NV12: - case DRM_FORMAT_NV21: case DRM_FORMAT_NV16: case DRM_FORMAT_NV61: default: @@ -903,6 +970,9 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, unsigned i; static const uint64_t modifiers[] = { DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, + DRM_FORMAT_MOD_BROADCOM_SAND128, + DRM_FORMAT_MOD_BROADCOM_SAND64, + DRM_FORMAT_MOD_BROADCOM_SAND256, DRM_FORMAT_MOD_LINEAR, DRM_FORMAT_MOD_INVALID }; -- cgit From 2227a7a219fdd2b925b1e861f36255efd149ff6d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 5 Apr 2018 17:44:48 +0200 Subject: drm/vc4: Always obey implicit sync Same justification as for drm_gem_fb_prepare_fb. Cc: Eric Anholt Reviewed-by: Eric Anholt Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180405154449.23038-9-daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20180409085134.27321-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/vc4/vc4_plane.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/vc4/vc4_plane.c') diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 2575bd81a010..3922f5f5807d 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -861,18 +861,21 @@ static int vc4_prepare_fb(struct drm_plane *plane, struct dma_fence *fence; int ret; - if ((plane->state->fb == state->fb) || !state->fb) + if (!state->fb) return 0; bo = to_vc4_bo(&drm_fb_cma_get_gem_obj(state->fb, 0)->base); + fence = reservation_object_get_excl_rcu(bo->resv); + drm_atomic_set_fence_for_plane(state, fence); + + if (plane->state->fb == state->fb) + return 0; + ret = vc4_bo_inc_usecnt(bo); if (ret) return ret; - fence = reservation_object_get_excl_rcu(bo->resv); - drm_atomic_set_fence_for_plane(state, fence); - return 0; } -- cgit