diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch b/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch new file mode 100644 index 0000000000..a4d5afe406 --- /dev/null +++ b/target/linux/bcm27xx/patches-5.4/950-0595-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch @@ -0,0 +1,174 @@ +From 87c4b03b9d1180c2f878b19363ec0609b5f24c75 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson <dave.stevenson@raspberrypi.com> +Date: Fri, 24 Jan 2020 14:25:41 +0000 +Subject: [PATCH] drm/vc4: Add support for DRM_FORMAT_P030 to vc4 + planes + +This currently doesn't handle non-zero source rectangles correctly, +but add support for DRM_FORMAT_P030 with DRM_FORMAT_MOD_BROADCOM_SAND128 +modifier to planes when running on HVS5. + +WIP still for source cropping SAND/P030 formats + +Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> +--- + drivers/gpu/drm/vc4/vc4_plane.c | 83 +++++++++++++++++++++++---------- + 1 file changed, 59 insertions(+), 24 deletions(-) + +--- a/drivers/gpu/drm/vc4/vc4_plane.c ++++ b/drivers/gpu/drm/vc4/vc4_plane.c +@@ -33,6 +33,7 @@ static const struct hvs_format { + u32 hvs; /* HVS_FORMAT_* */ + u32 pixel_order; + u32 pixel_order_hvs5; ++ bool hvs5_only; + } hvs_formats[] = { + { + .drm = DRM_FORMAT_XRGB8888, +@@ -128,6 +129,12 @@ static const struct hvs_format { + .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_2PLANE, + .pixel_order = HVS_PIXEL_ORDER_XYCRCB, + }, ++ { ++ .drm = DRM_FORMAT_P030, ++ .hvs = HVS_PIXEL_FORMAT_YCBCR_10BIT, ++ .pixel_order = HVS_PIXEL_ORDER_XYCBCR, ++ .hvs5_only = true, ++ }, + }; + + static const struct hvs_format *vc4_get_hvs_format(u32 drm_format) +@@ -809,27 +816,33 @@ static int vc4_plane_mode_set(struct drm + uint32_t param = fourcc_mod_broadcom_param(fb->modifier); + u32 tile_w, tile, x_off, pix_per_tile; + +- hvs_format = HVS_PIXEL_FORMAT_H264; +- +- switch (base_format_mod) { +- case DRM_FORMAT_MOD_BROADCOM_SAND64: +- tiling = SCALER_CTL0_TILING_64B; +- tile_w = 64; +- break; +- case DRM_FORMAT_MOD_BROADCOM_SAND128: ++ if (fb->format->format == DRM_FORMAT_P030) { ++ hvs_format = HVS_PIXEL_FORMAT_YCBCR_10BIT; + tiling = SCALER_CTL0_TILING_128B; +- tile_w = 128; +- break; +- case DRM_FORMAT_MOD_BROADCOM_SAND256: +- tiling = SCALER_CTL0_TILING_256B_OR_T; +- tile_w = 256; +- break; +- default: +- break; +- } ++ tile_w = 96; ++ } else { ++ hvs_format = HVS_PIXEL_FORMAT_H264; + ++ switch (base_format_mod) { ++ case DRM_FORMAT_MOD_BROADCOM_SAND64: ++ tiling = SCALER_CTL0_TILING_64B; ++ tile_w = 64; ++ break; ++ case DRM_FORMAT_MOD_BROADCOM_SAND128: ++ tiling = SCALER_CTL0_TILING_128B; ++ tile_w = 128; ++ break; ++ case DRM_FORMAT_MOD_BROADCOM_SAND256: ++ tiling = SCALER_CTL0_TILING_256B_OR_T; ++ tile_w = 256; ++ break; ++ default: ++ break; ++ } ++ } + if (param > SCALER_TILE_HEIGHT_MASK) { +- DRM_DEBUG_KMS("SAND height too large (%d)\n", param); ++ DRM_DEBUG_KMS("SAND height too large (%d)\n", ++ param); + return -EINVAL; + } + +@@ -839,6 +852,13 @@ static int vc4_plane_mode_set(struct drm + + /* Adjust the base pointer to the first pixel to be scanned + * out. ++ * ++ * For P030, y_ptr [31:4] is the 128bit word for the start pixel ++ * y_ptr [3:0] is the pixel (0-11) contained within that 128bit ++ * word that should be taken as the first pixel. ++ * Ditto uv_ptr [31:4] vs [3:0], however [3:0] contains the ++ * element within the 128bit word, eg for pixel 3 the value ++ * should be 6. + */ + for (i = 0; i < num_planes; i++) { + vc4_state->offsets[i] += param * tile_w * tile; +@@ -951,8 +971,8 @@ static int vc4_plane_mode_set(struct drm + vc4_dlist_write(vc4_state, + VC4_SET_FIELD(state->alpha >> 4, + SCALER5_CTL2_ALPHA) | +- fb->format->has_alpha ? +- SCALER5_CTL2_ALPHA_PREMULT : 0 | ++ (fb->format->has_alpha ? ++ SCALER5_CTL2_ALPHA_PREMULT : 0) | + (mix_plane_alpha ? + SCALER5_CTL2_ALPHA_MIX : 0) | + VC4_SET_FIELD(fb->format->has_alpha ? +@@ -1000,7 +1020,8 @@ static int vc4_plane_mode_set(struct drm + + /* Pitch word 1/2 */ + for (i = 1; i < num_planes; i++) { +- if (hvs_format != HVS_PIXEL_FORMAT_H264) { ++ if (hvs_format != HVS_PIXEL_FORMAT_H264 && ++ hvs_format != HVS_PIXEL_FORMAT_YCBCR_10BIT) { + vc4_dlist_write(vc4_state, + VC4_SET_FIELD(fb->pitches[i], + SCALER_SRC_PITCH)); +@@ -1371,6 +1392,13 @@ static bool vc4_format_mod_supported(str + default: + return false; + } ++ case DRM_FORMAT_P030: ++ switch (fourcc_mod_broadcom_mod(modifier)) { ++ case DRM_FORMAT_MOD_BROADCOM_SAND128: ++ return true; ++ default: ++ return false; ++ } + case DRM_FORMAT_RGBX1010102: + case DRM_FORMAT_BGRX1010102: + case DRM_FORMAT_RGBA1010102: +@@ -1403,8 +1431,11 @@ struct drm_plane *vc4_plane_init(struct + struct drm_plane *plane = NULL; + struct vc4_plane *vc4_plane; + u32 formats[ARRAY_SIZE(hvs_formats)]; ++ int num_formats = 0; + int ret = 0; + unsigned i; ++ bool hvs5 = of_device_is_compatible(dev->dev->of_node, ++ "brcm,bcm2711-vc5"); + static const uint64_t modifiers[] = { + DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, + DRM_FORMAT_MOD_BROADCOM_SAND128, +@@ -1419,13 +1450,17 @@ struct drm_plane *vc4_plane_init(struct + if (!vc4_plane) + return ERR_PTR(-ENOMEM); + +- for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) +- formats[i] = hvs_formats[i].drm; ++ for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) { ++ if (hvs_formats[i].hvs5_only || hvs5) { ++ formats[num_formats] = hvs_formats[i].drm; ++ num_formats++; ++ } ++ } + + plane = &vc4_plane->base; + ret = drm_universal_plane_init(dev, plane, 0, + &vc4_plane_funcs, +- formats, ARRAY_SIZE(formats), ++ formats, num_formats, + modifiers, type, NULL); + + drm_plane_helper_add(plane, &vc4_plane_helper_funcs); |