diff options
-rw-r--r-- | drivers/gpu/drm/arm/malidp_crtc.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_hw.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_hw.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_planes.c | 19 |
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 | ||
86 | static const struct malidp_layer malidp500_layers[] = { | 86 | static 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 | ||
98 | static const struct malidp_layer malidp550_layers[] = { | 98 | static 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 | ||
112 | static const struct malidp_layer malidp650_layers[] = { | 112 | static 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 | ||
318 | static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt) | 321 | static 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 | ||
39 | enum 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 | |||
39 | struct malidp_format_id { | 45 | struct 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 | ||
68 | enum malidp_scaling_coeff_set { | 75 | enum 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) { |