aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiviu Dudau <Liviu.Dudau@arm.com>2018-10-02 07:11:00 -0400
committerLiviu Dudau <Liviu.Dudau@arm.com>2018-10-02 07:11:00 -0400
commit66da13a519b33143932df5dc89973781c027c827 (patch)
tree10a59d19a43846cf8bf058fc2aab82c037b052dc
parent1f23a56a46b81de50eb8b898f06296ca06720a99 (diff)
drm/arm/malidp: Validate rotations for compressed/uncompressed framebuffers for each layer
Add support for compressed framebuffers that are described using the framebuffer's modifier field. Mali DP uses the rotation memory for the decompressor of the format, so we need to check for space when the modifiers are present. Signed-off-by: Ayan Kumar Halder <ayan.halder@arm.com> Reviewed-by: Brian Starkey <brian.starkey@arm.com> [re-worded commit, rebased, cleaned up duplicated checks for RGB888 and BGR888 and removed additional parameter for rotmem_required function hook] Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
-rw-r--r--drivers/gpu/drm/arm/malidp_crtc.c28
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.c39
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.h7
-rw-r--r--drivers/gpu/drm/arm/malidp_planes.c19
4 files changed, 54 insertions, 39 deletions
diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c
index ef44202fb43f..e1b72782848c 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -348,19 +348,20 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
348 348
349 /* 349 /*
350 * check if there is enough rotation memory available for planes 350 * check if there is enough rotation memory available for planes
351 * that need 90° and 270° rotation. Each plane has set its required 351 * that need 90° and 270° rotion or planes that are compressed.
352 * memory size in the ->plane_check() callback, here we only make 352 * Each plane has set its required memory size in the ->plane_check()
353 * sure that the sums are less that the total usable memory. 353 * callback, here we only make sure that the sums are less that the
354 * total usable memory.
354 * 355 *
355 * The rotation memory allocation algorithm (for each plane): 356 * The rotation memory allocation algorithm (for each plane):
356 * a. If no more rotated planes exist, all remaining rotate 357 * a. If no more rotated or compressed planes exist, all remaining
357 * memory in the bank is available for use by the plane. 358 * rotate memory in the bank is available for use by the plane.
358 * b. If other rotated planes exist, and plane's layer ID is 359 * b. If other rotated or compressed planes exist, and plane's
359 * DE_VIDEO1, it can use all the memory from first bank if 360 * layer ID is DE_VIDEO1, it can use all the memory from first bank
360 * secondary rotation memory bank is available, otherwise it can 361 * if secondary rotation memory bank is available, otherwise it can
361 * use up to half the bank's memory. 362 * use up to half the bank's memory.
362 * c. If other rotated planes exist, and plane's layer ID is not 363 * c. If other rotated or compressed planes exist, and plane's layer ID
363 * DE_VIDEO1, it can use half of the available memory 364 * is not DE_VIDEO1, it can use half of the available memory.
364 * 365 *
365 * Note: this algorithm assumes that the order in which the planes are 366 * Note: this algorithm assumes that the order in which the planes are
366 * checked always has DE_VIDEO1 plane first in the list if it is 367 * checked always has DE_VIDEO1 plane first in the list if it is
@@ -372,7 +373,9 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
372 373
373 /* first count the number of rotated planes */ 374 /* first count the number of rotated planes */
374 drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { 375 drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
375 if (pstate->rotation & MALIDP_ROTATED_MASK) 376 struct drm_framebuffer *fb = pstate->fb;
377
378 if ((pstate->rotation & MALIDP_ROTATED_MASK) || fb->modifier)
376 rotated_planes++; 379 rotated_planes++;
377 } 380 }
378 381
@@ -388,8 +391,9 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc,
388 drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { 391 drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
389 struct malidp_plane *mp = to_malidp_plane(plane); 392 struct malidp_plane *mp = to_malidp_plane(plane);
390 struct malidp_plane_state *ms = to_malidp_plane_state(pstate); 393 struct malidp_plane_state *ms = to_malidp_plane_state(pstate);
394 struct drm_framebuffer *fb = pstate->fb;
391 395
392 if (pstate->rotation & MALIDP_ROTATED_MASK) { 396 if ((pstate->rotation & MALIDP_ROTATED_MASK) || fb->modifier) {
393 /* process current plane */ 397 /* process current plane */
394 rotated_planes--; 398 rotated_planes--;
395 399
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index c874ef4ac005..7aad7dd80d8c 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -85,44 +85,47 @@ static const struct malidp_format_id malidp550_de_formats[] = {
85 85
86static const struct malidp_layer malidp500_layers[] = { 86static const struct malidp_layer malidp500_layers[] = {
87 /* id, base address, fb pointer address base, stride offset, 87 /* id, base address, fb pointer address base, stride offset,
88 * yuv2rgb matrix offset, mmu control register offset 88 * yuv2rgb matrix offset, mmu control register offset, rotation_features
89 */ 89 */
90 { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, 90 { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE,
91 MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB, 0 }, 91 MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB, 0, ROTATE_ANY },
92 { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, 92 { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE,
93 MALIDP_DE_LG_STRIDE, 0, 0 }, 93 MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY },
94 { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, 94 { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE,
95 MALIDP_DE_LG_STRIDE, 0, 0 }, 95 MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY },
96}; 96};
97 97
98static const struct malidp_layer malidp550_layers[] = { 98static const struct malidp_layer malidp550_layers[] = {
99 /* id, base address, fb pointer address base, stride offset, 99 /* id, base address, fb pointer address base, stride offset,
100 * yuv2rgb matrix offset, mmu control register offset 100 * yuv2rgb matrix offset, mmu control register offset, rotation_features
101 */ 101 */
102 { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, 102 { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE,
103 MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0 }, 103 MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0, ROTATE_ANY },
104 { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, 104 { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE,
105 MALIDP_DE_LG_STRIDE, 0, 0 }, 105 MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY },
106 { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, 106 { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE,
107 MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0 }, 107 MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0, ROTATE_ANY },
108 { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, 108 { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE,
109 MALIDP550_DE_LS_R1_STRIDE, 0, 0 }, 109 MALIDP550_DE_LS_R1_STRIDE, 0, 0, ROTATE_NONE },
110}; 110};
111 111
112static const struct malidp_layer malidp650_layers[] = { 112static const struct malidp_layer malidp650_layers[] = {
113 /* id, base address, fb pointer address base, stride offset, 113 /* id, base address, fb pointer address base, stride offset,
114 * yuv2rgb matrix offset, mmu control register offset 114 * yuv2rgb matrix offset, mmu control register offset,
115 * rotation_features
115 */ 116 */
116 { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, 117 { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE,
117 MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 118 MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB,
118 MALIDP650_DE_LV_MMU_CTRL }, 119 MALIDP650_DE_LV_MMU_CTRL, ROTATE_ANY },
119 { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, 120 { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE,
120 MALIDP_DE_LG_STRIDE, 0, MALIDP650_DE_LG_MMU_CTRL }, 121 MALIDP_DE_LG_STRIDE, 0, MALIDP650_DE_LG_MMU_CTRL,
122 ROTATE_COMPRESSED },
121 { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, 123 { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE,
122 MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 124 MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB,
123 MALIDP650_DE_LV_MMU_CTRL }, 125 MALIDP650_DE_LV_MMU_CTRL, ROTATE_ANY },
124 { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, 126 { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE,
125 MALIDP550_DE_LS_R1_STRIDE, 0, MALIDP650_DE_LS_MMU_CTRL }, 127 MALIDP550_DE_LS_R1_STRIDE, 0, MALIDP650_DE_LS_MMU_CTRL,
128 ROTATE_NONE },
126}; 129};
127 130
128#define SE_N_SCALING_COEFFS 96 131#define SE_N_SCALING_COEFFS 96
@@ -317,10 +320,6 @@ static void malidp500_modeset(struct malidp_hw_device *hwdev, struct videomode *
317 320
318static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt) 321static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt)
319{ 322{
320 /* RGB888 or BGR888 can't be rotated */
321 if ((fmt == DRM_FORMAT_RGB888) || (fmt == DRM_FORMAT_BGR888))
322 return -EINVAL;
323
324 /* 323 /*
325 * Each layer needs enough rotation memory to fit 8 lines 324 * Each layer needs enough rotation memory to fit 8 lines
326 * worth of pixel data. Required size is then: 325 * worth of pixel data. Required size is then:
@@ -608,10 +607,6 @@ static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16
608{ 607{
609 u32 bytes_per_col; 608 u32 bytes_per_col;
610 609
611 /* raw RGB888 or BGR888 can't be rotated */
612 if ((fmt == DRM_FORMAT_RGB888) || (fmt == DRM_FORMAT_BGR888))
613 return -EINVAL;
614
615 switch (fmt) { 610 switch (fmt) {
616 /* 8 lines at 4 bytes per pixel */ 611 /* 8 lines at 4 bytes per pixel */
617 case DRM_FORMAT_ARGB2101010: 612 case DRM_FORMAT_ARGB2101010:
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h
index 0d7f9ea0ade8..3ab133d49bba 100644
--- a/drivers/gpu/drm/arm/malidp_hw.h
+++ b/drivers/gpu/drm/arm/malidp_hw.h
@@ -36,6 +36,12 @@ enum {
36 SE_MEMWRITE = BIT(5), 36 SE_MEMWRITE = BIT(5),
37}; 37};
38 38
39enum rotation_features {
40 ROTATE_NONE, /* does not support rotation at all */
41 ROTATE_ANY, /* supports rotation on any buffers */
42 ROTATE_COMPRESSED, /* supports rotation only on compressed buffers */
43};
44
39struct malidp_format_id { 45struct malidp_format_id {
40 u32 format; /* DRM fourcc */ 46 u32 format; /* DRM fourcc */
41 u8 layer; /* bitmask of layers supporting it */ 47 u8 layer; /* bitmask of layers supporting it */
@@ -63,6 +69,7 @@ struct malidp_layer {
63 u16 stride_offset; /* offset to the first stride register. */ 69 u16 stride_offset; /* offset to the first stride register. */
64 s16 yuv2rgb_offset; /* offset to the YUV->RGB matrix entries */ 70 s16 yuv2rgb_offset; /* offset to the YUV->RGB matrix entries */
65 u16 mmu_ctrl_offset; /* offset to the MMU control register */ 71 u16 mmu_ctrl_offset; /* offset to the MMU control register */
72 enum rotation_features rot; /* type of rotation supported */
66}; 73};
67 74
68enum malidp_scaling_coeff_set { 75enum malidp_scaling_coeff_set {
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index 76aafc296e1b..837a24d56675 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -440,11 +440,20 @@ static int malidp_de_plane_check(struct drm_plane *plane,
440 if (ret) 440 if (ret)
441 return ret; 441 return ret;
442 442
443 /* packed RGB888 / BGR888 can't be rotated or flipped */ 443 /* validate the rotation constraints for each layer */
444 if (state->rotation != DRM_MODE_ROTATE_0 && 444 if (state->rotation != DRM_MODE_ROTATE_0) {
445 (fb->format->format == DRM_FORMAT_RGB888 || 445 if (mp->layer->rot == ROTATE_NONE)
446 fb->format->format == DRM_FORMAT_BGR888)) 446 return -EINVAL;
447 return -EINVAL; 447 if ((mp->layer->rot == ROTATE_COMPRESSED) && !(fb->modifier))
448 return -EINVAL;
449 /*
450 * packed RGB888 / BGR888 can't be rotated or flipped
451 * unless they are stored in a compressed way
452 */
453 if ((fb->format->format == DRM_FORMAT_RGB888 ||
454 fb->format->format == DRM_FORMAT_BGR888) && !(fb->modifier))
455 return -EINVAL;
456 }
448 457
449 ms->rotmem_size = 0; 458 ms->rotmem_size = 0;
450 if (state->rotation & MALIDP_ROTATED_MASK) { 459 if (state->rotation & MALIDP_ROTATED_MASK) {