Mali-DP 500 supports rotations for both compressed/uncompressed buffers for all the layers. Mali-DP 550 supports rotations for both compressed/uncompressed buffers for VIDEO and GRAPHICS layers only. The SMART layer does not support any rotation. Mali-DP 650 supports rotations for both compressed/uncompressed buffers for VIDEO layers and compressed buffers only for GRAPHICS layer. SMART layer behaves similar to that of Malidp-550. Signed-off-by: Ayan Kumar halder <ayan.halder@xxxxxxx> Reviewed-by: Brian Starkey <brian.starkey@xxxxxxx> --- drivers/gpu/drm/arm/malidp_crtc.c | 31 ++++++++++++++---------- drivers/gpu/drm/arm/malidp_hw.c | 48 ++++++++++++++++++++++++++----------- drivers/gpu/drm/arm/malidp_hw.h | 10 +++++++- drivers/gpu/drm/arm/malidp_planes.c | 24 +++++++++++++------ 4 files changed, 79 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index fcc62bc..21c5d05 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, /* * check if there is enough rotation memory available for planes - * that need 90° and 270° rotation. Each plane has set its required - * memory size in the ->plane_check() callback, here we only make - * sure that the sums are less that the total usable memory. + * that need 90° and 270° rotion or planes that are compressed. + * Each plane has set its required memory size in the ->plane_check() + * callback, here we only make sure that the sums are less that the + * total usable memory. * * The rotation memory allocation algorithm (for each plane): - * a. If no more rotated planes exist, all remaining rotate - * memory in the bank is available for use by the plane. - * b. If other rotated planes exist, and plane's layer ID is - * DE_VIDEO1, it can use all the memory from first bank if - * secondary rotation memory bank is available, otherwise it can + * a. If no more rotated or compressed planes exist, all remaining + * rotate memory in the bank is available for use by the plane. + * b. If other rotated or compressed planes exist, and plane's + * layer ID is DE_VIDEO1, it can use all the memory from first bank + * if secondary rotation memory bank is available, otherwise it can * use up to half the bank's memory. - * c. If other rotated planes exist, and plane's layer ID is not - * DE_VIDEO1, it can use half of the available memory + * c. If other rotated or compressed planes exist, and plane's layer ID + * is not DE_VIDEO1, it can use half of the available memory. * * Note: this algorithm assumes that the order in which the planes are * checked always has DE_VIDEO1 plane first in the list if it is @@ -368,11 +369,15 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc, * place, under current DRM version things work, but if ever the order * in which drm_atomic_crtc_state_for_each_plane() iterates over planes * changes, we need to pre-sort the planes before validation. + * */ /* first count the number of rotated planes */ drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { - if (pstate->rotation & MALIDP_ROTATED_MASK) + struct malidp_plane_state *ms = to_malidp_plane_state(pstate); + struct drm_framebuffer *fb = ms->base.fb; + + if ((pstate->rotation & MALIDP_ROTATED_MASK) || fb->modifier) rotated_planes++; } @@ -388,8 +393,10 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc, drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { struct malidp_plane *mp = to_malidp_plane(plane); struct malidp_plane_state *ms = to_malidp_plane_state(pstate); + struct drm_framebuffer *fb = ms->base.fb; + + if ((pstate->rotation & MALIDP_ROTATED_MASK) || fb->modifier) { - if (pstate->rotation & MALIDP_ROTATED_MASK) { /* process current plane */ rotated_planes--; diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c index d789b46..4dbf39f 100644 --- a/drivers/gpu/drm/arm/malidp_hw.c +++ b/drivers/gpu/drm/arm/malidp_hw.c @@ -75,16 +75,34 @@ static const struct malidp_format_id malidp550_de_formats[] = { }; static const struct malidp_layer malidp500_layers[] = { - { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB }, - { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, - { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, + { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, + MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB, ROTATE_ANY }, + { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, + MALIDP_DE_LG_STRIDE, 0, ROTATE_ANY }, + { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, + MALIDP_DE_LG_STRIDE, 0, ROTATE_ANY }, }; static const struct malidp_layer malidp550_layers[] = { - { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB }, - { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, - { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB }, - { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE, 0 }, + { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, ROTATE_ANY }, + { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, + MALIDP_DE_LG_STRIDE, 0, ROTATE_ANY }, + { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, ROTATE_ANY }, + { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, + MALIDP550_DE_LS_R1_STRIDE, 0, ROTATE_NONE }, +}; + +static const struct malidp_layer malidp650_layers[] = { + { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, ROTATE_ANY }, + { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, + MALIDP_DE_LG_STRIDE, 0, ROTATE_COMPRESSED }, + { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, ROTATE_ANY }, + { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, + MALIDP550_DE_LS_R1_STRIDE, 0, ROTATE_NONE }, }; #define SE_N_SCALING_COEFFS 96 @@ -272,10 +290,11 @@ static void malidp500_modeset(struct malidp_hw_device *hwdev, struct videomode * malidp_hw_clearbits(hwdev, MALIDP_DISP_FUNC_ILACED, MALIDP_DE_DISPLAY_FUNC); } -static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt) +static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, + u16 h, u32 fmt, bool has_modifier) { - /* RGB888 or BGR888 can't be rotated */ - if ((fmt == DRM_FORMAT_RGB888) || (fmt == DRM_FORMAT_BGR888)) + /* raw RGB888 or BGR888 can't be rotated */ + if ((fmt == DRM_FORMAT_RGB888 || fmt == DRM_FORMAT_BGR888) && !has_modifier) return -EINVAL; /* @@ -496,12 +515,13 @@ static void malidp550_modeset(struct malidp_hw_device *hwdev, struct videomode * malidp_hw_clearbits(hwdev, MALIDP_DISP_FUNC_ILACED, MALIDP_DE_DISPLAY_FUNC); } -static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt) +static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, + u16 h, u32 fmt, bool has_modifier) { u32 bytes_per_col; /* raw RGB888 or BGR888 can't be rotated */ - if ((fmt == DRM_FORMAT_RGB888) || (fmt == DRM_FORMAT_BGR888)) + if ((fmt == DRM_FORMAT_RGB888 || fmt == DRM_FORMAT_BGR888) && !has_modifier) return -EINVAL; switch (fmt) { @@ -700,8 +720,8 @@ const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = { .dc_base = MALIDP550_DC_BASE, .out_depth_base = MALIDP550_DE_OUTPUT_DEPTH, .features = MALIDP_REGMAP_HAS_CLEARIRQ, - .n_layers = ARRAY_SIZE(malidp550_layers), - .layers = malidp550_layers, + .n_layers = ARRAY_SIZE(malidp650_layers), + .layers = malidp650_layers, .de_irq_map = { .irq_mask = MALIDP_DE_IRQ_UNDERRUN | MALIDP650_DE_IRQ_DRIFT | diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h index b5dd6c7..41f4521 100644 --- a/drivers/gpu/drm/arm/malidp_hw.h +++ b/drivers/gpu/drm/arm/malidp_hw.h @@ -54,12 +54,19 @@ struct malidp_irq_map { u32 vsync_irq; /* IRQ bit used for signaling during VSYNC */ }; +enum rotation_features { + ROTATE_ANY, /* supports rotation on any buffers */ + ROTATE_COMPRESSED, /* supports rotation only on compressed buffers */ + ROTATE_NONE, /* does not support rotation at all */ +}; + struct malidp_layer { u16 id; /* layer ID */ u16 base; /* address offset for the register bank */ u16 ptr; /* address offset for the pointer register */ u16 stride_offset; /* offset to the first stride register. */ s16 yuv2rgb_offset; /* offset to the YUV->RGB matrix entries */ + enum rotation_features rot; /* type of rotation supported */ }; enum malidp_scaling_coeff_set { @@ -168,7 +175,8 @@ struct malidp_hw { * Calculate the required rotation memory given the active area * and the buffer format. */ - int (*rotmem_required)(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt); + int (*rotmem_required)(struct malidp_hw_device *hwdev, u16 w, u16 h, + u32 fmt, bool has_modifier); int (*se_set_scaling_coeffs)(struct malidp_hw_device *hwdev, struct malidp_se_config *se_config, diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 7a44897..377382e 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -197,12 +197,19 @@ 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++) { + struct drm_gem_cma_object *obj; + u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated); if (fb->pitches[i] & (alignment - 1)) { DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n", fb->pitches[i], i); return -EINVAL; } + + obj = drm_fb_cma_get_gem_obj(fb, i); + + if (WARN_ON(!obj)) + return -EINVAL; } if ((state->crtc_w > mp->hwdev->max_line_size) || @@ -225,19 +232,22 @@ static int malidp_de_plane_check(struct drm_plane *plane, if (ret) return ret; - /* packed RGB888 / BGR888 can't be rotated or flipped */ - if (state->rotation != DRM_MODE_ROTATE_0 && - (fb->format->format == DRM_FORMAT_RGB888 || - fb->format->format == DRM_FORMAT_BGR888)) - return -EINVAL; + /* validate the rotation constraints for each layer */ + if (state->rotation != DRM_MODE_ROTATE_0) { + if (mp->layer->rot == ROTATE_NONE) + return -EINVAL; + else if ((mp->layer->rot == ROTATE_COMPRESSED) && (!fb->modifier)) + return -EINVAL; + } ms->rotmem_size = 0; - if (state->rotation & MALIDP_ROTATED_MASK) { + if (state->rotation != DRM_MODE_ROTATE_0 || fb->modifier) { int val; val = mp->hwdev->hw->rotmem_required(mp->hwdev, state->crtc_h, state->crtc_w, - fb->format->format); + fb->format->format, + !!(fb->modifier)); if (val < 0) return val; -- 2.7.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel