Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm: mali-dp: Enable Mali-DP tiled buffer formats

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

+36 -6
+11 -3
drivers/gpu/drm/arm/malidp_hw.c
··· 77 77 { DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) }, \ 78 78 { DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) }, \ 79 79 { DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) }, \ 80 - { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) } 80 + { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \ 81 + { DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)} 81 82 82 83 static const struct malidp_format_id malidp550_de_formats[] = { 83 84 MALIDP_COMMON_FORMATS, 85 + }; 86 + 87 + static const struct malidp_format_id malidp650_de_formats[] = { 88 + MALIDP_COMMON_FORMATS, 89 + { DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)}, 84 90 }; 85 91 86 92 static const struct malidp_layer malidp500_layers[] = { ··· 636 630 case DRM_FORMAT_BGR565: 637 631 case DRM_FORMAT_UYVY: 638 632 case DRM_FORMAT_YUYV: 633 + case DRM_FORMAT_X0L0: 634 + case DRM_FORMAT_X0L2: 639 635 bytes_per_col = 32; 640 636 break; 641 637 /* 16 lines at 1.5 bytes per pixel */ ··· 913 905 MALIDP550_DC_IRQ_SE, 914 906 .vsync_irq = MALIDP550_DC_IRQ_CONF_VALID, 915 907 }, 916 - .pixel_formats = malidp550_de_formats, 917 - .n_pixel_formats = ARRAY_SIZE(malidp550_de_formats), 908 + .pixel_formats = malidp650_de_formats, 909 + .n_pixel_formats = ARRAY_SIZE(malidp650_de_formats), 918 910 .bus_align_bytes = 16, 919 911 }, 920 912 .query_hw = malidp650_query_hw,
+25 -3
drivers/gpu/drm/arm/malidp_planes.c
··· 398 398 struct drm_framebuffer *fb; 399 399 u16 pixel_alpha = state->pixel_blend_mode; 400 400 int i, ret; 401 + unsigned int block_w, block_h; 401 402 402 403 if (!state->crtc || !state->fb) 403 404 return 0; ··· 414 413 ms->n_planes = fb->format->num_planes; 415 414 for (i = 0; i < ms->n_planes; i++) { 416 415 u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated); 417 - if (fb->pitches[i] & (alignment - 1)) { 416 + 417 + if ((fb->pitches[i] * drm_format_info_block_height(fb->format, i)) 418 + & (alignment - 1)) { 418 419 DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n", 419 420 fb->pitches[i], i); 420 421 return -EINVAL; 421 422 } 423 + } 424 + 425 + block_w = drm_format_info_block_width(fb->format, 0); 426 + block_h = drm_format_info_block_height(fb->format, 0); 427 + if (fb->width % block_w || fb->height % block_h) { 428 + DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes"); 429 + return -EINVAL; 430 + } 431 + if ((state->src_x >> 16) % block_w || (state->src_y >> 16) % block_h) { 432 + DRM_DEBUG_KMS("Plane src_x/src_y needs to be a multiple of tile sizes"); 433 + return -EINVAL; 422 434 } 423 435 424 436 if ((state->crtc_w > mp->hwdev->max_line_size) || ··· 506 492 num_strides = (mp->hwdev->hw->features & 507 493 MALIDP_DEVICE_LV_HAS_3_STRIDES) ? 3 : 2; 508 494 509 - for (i = 0; i < num_strides; ++i) 510 - malidp_hw_write(mp->hwdev, pitches[i], 495 + /* 496 + * The drm convention for pitch is that it needs to cover width * cpp, 497 + * but our hardware wants the pitch/stride to cover all rows included 498 + * in a tile. 499 + */ 500 + for (i = 0; i < num_strides; ++i) { 501 + unsigned int block_h = drm_format_info_block_height(mp->base.state->fb->format, i); 502 + 503 + malidp_hw_write(mp->hwdev, pitches[i] * block_h, 511 504 mp->layer->base + 512 505 mp->layer->stride_offset + i * 4); 506 + } 513 507 } 514 508 515 509 static const s16