aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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) {