]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
drm: mali-dp: Enable Mali-DP tiled buffer formats
authorAlexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
Thu, 1 Nov 2018 15:11:31 +0000 (15:11 +0000)
committerAlexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
Fri, 2 Nov 2018 09:57:27 +0000 (09:57 +0000)
Enable the following formats
- DRM_FORMAT_X0L0: DP650
- DRM_FORMAT_X0L2: DP550, DP650

Reviewed-by: Brian Starkey <brian.starkey@arm.com>
Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181101151051.1509-4-alexandru-cosmin.gheorghe@arm.com
drivers/gpu/drm/arm/malidp_hw.c
drivers/gpu/drm/arm/malidp_planes.c

index 7aad7dd80d8c40313d59e992a7cac12b844c7ff6..b9bed1138fa31b5c50610f1226347592104f821b 100644 (file)
@@ -77,12 +77,18 @@ static const struct malidp_format_id malidp500_de_formats[] = {
        { DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) },    \
        { DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) },    \
        { DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) },      \
-       { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }
+       { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \
+       { DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}
 
 static const struct malidp_format_id malidp550_de_formats[] = {
        MALIDP_COMMON_FORMATS,
 };
 
+static const struct malidp_format_id malidp650_de_formats[] = {
+       MALIDP_COMMON_FORMATS,
+       { DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)},
+};
+
 static const struct malidp_layer malidp500_layers[] = {
        /* id, base address, fb pointer address base, stride offset,
         *      yuv2rgb matrix offset, mmu control register offset, rotation_features
@@ -630,6 +636,8 @@ static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
        case DRM_FORMAT_BGR565:
        case DRM_FORMAT_UYVY:
        case DRM_FORMAT_YUYV:
+       case DRM_FORMAT_X0L0:
+       case DRM_FORMAT_X0L2:
                bytes_per_col = 32;
                break;
        /* 16 lines at 1.5 bytes per pixel */
@@ -905,8 +913,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
                                            MALIDP550_DC_IRQ_SE,
                                .vsync_irq = MALIDP550_DC_IRQ_CONF_VALID,
                        },
-                       .pixel_formats = malidp550_de_formats,
-                       .n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
+                       .pixel_formats = malidp650_de_formats,
+                       .n_pixel_formats = ARRAY_SIZE(malidp650_de_formats),
                        .bus_align_bytes = 16,
                },
                .query_hw = malidp650_query_hw,
index 837a24d566757c91f3f5152bb62a938bc04bd2dd..c9a6d3e0cada6860a8c6aab04398de6e4672aedf 100644 (file)
@@ -398,6 +398,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
        struct drm_framebuffer *fb;
        u16 pixel_alpha = state->pixel_blend_mode;
        int i, ret;
+       unsigned int block_w, block_h;
 
        if (!state->crtc || !state->fb)
                return 0;
@@ -413,13 +414,26 @@ static int malidp_de_plane_check(struct drm_plane *plane,
        ms->n_planes = fb->format->num_planes;
        for (i = 0; i < ms->n_planes; i++) {
                u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
-               if (fb->pitches[i] & (alignment - 1)) {
+
+               if ((fb->pitches[i] * drm_format_info_block_height(fb->format, i))
+                               & (alignment - 1)) {
                        DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
                                      fb->pitches[i], i);
                        return -EINVAL;
                }
        }
 
+       block_w = drm_format_info_block_width(fb->format, 0);
+       block_h = drm_format_info_block_height(fb->format, 0);
+       if (fb->width % block_w || fb->height % block_h) {
+               DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
+               return -EINVAL;
+       }
+       if ((state->src_x >> 16) % block_w || (state->src_y >> 16) % block_h) {
+               DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile sizes");
+               return -EINVAL;
+       }
+
        if ((state->crtc_w > mp->hwdev->max_line_size) ||
            (state->crtc_h > mp->hwdev->max_line_size) ||
            (state->crtc_w < mp->hwdev->min_line_size) ||
@@ -492,10 +506,18 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
                num_strides = (mp->hwdev->hw->features &
                               MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2;
 
-       for (i = 0; i < num_strides; ++i)
-               malidp_hw_write(mp->hwdev, pitches[i],
+       /*
+        * The drm convention for pitch is that it needs to cover width * cpp,
+        * but our hardware wants the pitch/stride to cover all rows included
+        * in a tile.
+        */
+       for (i = 0; i < num_strides; ++i) {
+               unsigned int block_h = drm_format_info_block_height(mp->base.state->fb->format, i);
+
+               malidp_hw_write(mp->hwdev, pitches[i] * block_h,
                                mp->layer->base +
                                mp->layer->stride_offset + i * 4);
+       }
 }
 
 static const s16