aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch174
1 files changed, 174 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch b/target/linux/bcm27xx/patches-5.4/950-0603-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch
new file mode 100644
index 0000000000..9d83d8a3dd
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0603-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)
+@@ -801,27 +808,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;
+ }
+
+@@ -831,6 +844,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;
+@@ -943,8 +963,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 ?
+@@ -992,7 +1012,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));
+@@ -1361,6 +1382,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:
+@@ -1393,8 +1421,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,
+@@ -1409,13 +1440,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);