diff --git a/drivers/gpu/drm/imx/dcss/dcss-plane.c b/drivers/gpu/drm/imx/dcss/dcss-plane.c index 0c19da086f5d..8c9070ca9af8 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-plane.c +++ b/drivers/gpu/drm/imx/dcss/dcss-plane.c @@ -1,5 +1,5 @@ /* - * Copyright 2017 NXP + * Copyright 2017-2018 NXP * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -177,6 +177,37 @@ static const struct drm_plane_funcs dcss_plane_funcs = { .format_mod_supported = dcss_plane_format_mod_supported, }; +static bool dcss_plane_can_rotate(u32 pixel_format, bool mod_present, + u64 modifier, unsigned int rotation) +{ + enum dcss_color_space cs = dcss_drm_fourcc_to_colorspace(pixel_format); + bool linear_format = !mod_present || + (mod_present && modifier == DRM_FORMAT_MOD_LINEAR); + u32 supported_rotation = DRM_MODE_ROTATE_0; + + if (cs == DCSS_COLORSPACE_RGB && linear_format) + supported_rotation = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | + DRM_MODE_REFLECT_MASK; + else if (cs == DCSS_COLORSPACE_RGB && + modifier == DRM_FORMAT_MOD_VIVANTE_TILED) + supported_rotation = DRM_MODE_ROTATE_MASK | + DRM_MODE_REFLECT_MASK; + else if (cs == DCSS_COLORSPACE_RGB && + modifier == DRM_FORMAT_MOD_VIVANTE_SUPER_TILED_FC) + supported_rotation = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | + DRM_MODE_REFLECT_MASK; + else if (cs == DCSS_COLORSPACE_YUV && linear_format && + (pixel_format == DRM_FORMAT_NV12 || + pixel_format == DRM_FORMAT_NV21)) + supported_rotation = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 | + DRM_MODE_REFLECT_MASK; + else if (cs == DCSS_COLORSPACE_YUV && linear_format && + pixel_format == DRM_FORMAT_P010) + supported_rotation = DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y; + + return !!(rotation & supported_rotation); +} + static int dcss_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { @@ -216,6 +247,14 @@ static int dcss_plane_atomic_check(struct drm_plane *plane, if (!drm_rect_intersect(&crtc_rect, &disp_rect)) return -EINVAL; + if (!dcss_plane_can_rotate(fb->format->format, + !!(fb->flags & DRM_MODE_FB_MODIFIERS), + fb->modifier, + state->rotation)) { + DRM_ERROR("requested rotation is not allowed!\n"); + return -EINVAL; + } + /* cropping is only available on overlay planes when DTRC is used */ if (state->crtc_x < 0 || state->crtc_y < 0 || state->crtc_x + state->crtc_w > hdisplay || @@ -388,7 +427,8 @@ static bool dcss_plane_needs_setup(struct drm_plane_state *state, state->src_w != old_state->src_w || state->src_h != old_state->src_h || fb->format->format != old_fb->format->format || - fb->modifier != old_fb->modifier; + fb->modifier != old_fb->modifier || + state->rotation != old_state->rotation; } static void dcss_plane_adjust(struct drm_rect *dis_rect, @@ -509,6 +549,8 @@ static void dcss_plane_atomic_update(struct drm_plane *plane, dcss_dpr_set_res(dcss_plane->dcss, dcss_plane->ch_num, src_w, src_h, adj_w, adj_h); + dcss_dpr_set_rotation(dcss_plane->dcss, dcss_plane->ch_num, + state->rotation); dcss_plane_atomic_set_base(dcss_plane); if (fb->modifier == DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED) { @@ -635,6 +677,15 @@ struct dcss_plane *dcss_plane_init(struct drm_device *drm, if (ret) return ERR_PTR(ret); + drm_plane_create_rotation_property(&dcss_plane->base, + DRM_MODE_ROTATE_0, + DRM_MODE_ROTATE_0 | + DRM_MODE_ROTATE_90 | + DRM_MODE_ROTATE_180 | + DRM_MODE_ROTATE_270 | + DRM_MODE_REFLECT_X | + DRM_MODE_REFLECT_Y); + dcss_plane->ch_num = 2 - zpos; dcss_plane->alpha_val = 255; diff --git a/drivers/gpu/imx/dcss/dcss-dpr.c b/drivers/gpu/imx/dcss/dcss-dpr.c index fee46bd71758..ef607ee3eef9 100644 --- a/drivers/gpu/imx/dcss/dcss-dpr.c +++ b/drivers/gpu/imx/dcss/dcss-dpr.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 NXP + * Copyright (C) 2017-2018 NXP * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -18,6 +18,7 @@ #include #include #include +#include #include #include