openwrt/target/linux/bcm27xx/patches-4.19/950-0732-drm-vc4-Add-support-for-H-V-flips.patch
Adrian Schmutzler 7d7aa2fd92 brcm2708: rename target to bcm27xx
This change makes the names of Broadcom targets consistent by using
the common notation based on SoC/CPU ID (which is used internally
anyway), bcmXXXX instead of brcmXXXX.
This is even used for target TITLE in make menuconfig already,
only the short target name used brcm so far.

Despite, since subtargets range from bcm2708 to bcm2711, it seems
appropriate to use bcm27xx instead of bcm2708 (again, as already done
for BOARDNAME).

This also renames the packages brcm2708-userland and brcm2708-gpu-fw.

Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
2020-02-14 14:10:51 +01:00

136 lines
4.4 KiB
Diff

From 1246d16c393a2f5790e5492053f26e6b0b62cec8 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
Date: Tue, 17 Sep 2019 18:36:32 +0100
Subject: [PATCH] drm/vc4: Add support for H & V flips
The HVS supports horizontal and vertical flips whilst composing.
Expose these through the standard DRM rotation property.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
---
drivers/gpu/drm/vc4/vc4_plane.c | 54 +++++++++++++++++++++++++++------
1 file changed, 45 insertions(+), 9 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -560,7 +560,9 @@ static int vc4_plane_mode_set(struct drm
const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier);
int num_planes = drm_format_num_planes(format->drm);
+ bool hflip = false, vflip = false;
u32 h_subsample, v_subsample;
+ unsigned int rotation;
bool mix_plane_alpha;
bool covers_screen;
u32 scl0, scl1, pitch0;
@@ -568,11 +570,26 @@ static int vc4_plane_mode_set(struct drm
unsigned long irqflags;
u32 hvs_format = format->hvs;
int ret, i;
+ u32 src_y;
ret = vc4_plane_setup_clipping_and_scaling(state);
if (ret)
return ret;
+ rotation = drm_rotation_simplify(state->rotation,
+ DRM_MODE_ROTATE_0 |
+ DRM_MODE_REFLECT_X |
+ DRM_MODE_REFLECT_Y);
+
+ if ((rotation & DRM_MODE_ROTATE_MASK) == DRM_MODE_ROTATE_180) {
+ hflip = true;
+ vflip = true;
+ }
+ if (rotation & DRM_MODE_REFLECT_X)
+ hflip ^= true;
+ if (rotation & DRM_MODE_REFLECT_Y)
+ vflip ^= true;
+
/* Allocate the LBM memory that the HVS will use for temporary
* storage due to our scaling/format conversion.
*/
@@ -609,6 +626,16 @@ static int vc4_plane_mode_set(struct drm
h_subsample = drm_format_horz_chroma_subsampling(format->drm);
v_subsample = drm_format_vert_chroma_subsampling(format->drm);
+ if (!vflip)
+ src_y = vc4_state->src_y;
+ else
+ /* When vflipped the image offset needs to be
+ * the start of the last line of the image, and
+ * the pitch will be subtracted from the offset.
+ */
+ src_y = vc4_state->src_y +
+ vc4_state->src_h[0] - 1;
+
switch (base_format_mod) {
case DRM_FORMAT_MOD_LINEAR:
tiling = SCALER_CTL0_TILING_LINEAR;
@@ -618,12 +645,13 @@ static int vc4_plane_mode_set(struct drm
* out.
*/
for (i = 0; i < num_planes; i++) {
- vc4_state->offsets[i] += vc4_state->src_y /
+ vc4_state->offsets[i] += src_y /
(i ? v_subsample : 1) *
fb->pitches[i];
+
vc4_state->offsets[i] += vc4_state->src_x /
- (i ? h_subsample : 1) *
- fb->format->cpp[i];
+ (i ? h_subsample : 1) *
+ fb->format->cpp[i];
}
break;
@@ -651,11 +679,11 @@ static int vc4_plane_mode_set(struct drm
* SCALER_PITCH0_TILE_Y_OFFSET tells HVS how to walk from that
* base address).
*/
- u32 tile_y = (vc4_state->src_y >> 4) & 1;
- u32 subtile_y = (vc4_state->src_y >> 2) & 3;
- u32 utile_y = vc4_state->src_y & 3;
+ u32 tile_y = (src_y >> 4) & 1;
+ u32 subtile_y = (src_y >> 2) & 3;
+ u32 utile_y = src_y & 3;
u32 x_off = vc4_state->src_x & tile_w_mask;
- u32 y_off = vc4_state->src_y & tile_h_mask;
+ u32 y_off = src_y & tile_h_mask;
tiling = SCALER_CTL0_TILING_256B_OR_T;
pitch0 = (VC4_SET_FIELD(x_off, SCALER_PITCH0_SINK_PIX) |
@@ -732,7 +760,7 @@ static int vc4_plane_mode_set(struct drm
*/
for (i = 0; i < num_planes; i++) {
vc4_state->offsets[i] += param * tile_w * tile;
- vc4_state->offsets[i] += vc4_state->src_y /
+ vc4_state->offsets[i] += src_y /
(i ? v_subsample : 1) *
tile_w;
vc4_state->offsets[i] += x_off /
@@ -759,7 +787,9 @@ static int vc4_plane_mode_set(struct drm
VC4_SET_FIELD(tiling, SCALER_CTL0_TILING) |
(vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) |
VC4_SET_FIELD(scl0, SCALER_CTL0_SCL0) |
- VC4_SET_FIELD(scl1, SCALER_CTL0_SCL1));
+ VC4_SET_FIELD(scl1, SCALER_CTL0_SCL1) |
+ (vflip ? SCALER_CTL0_VFLIP : 0) |
+ (hflip ? SCALER_CTL0_HFLIP : 0));
/* Position Word 0: Image Positions and Alpha Value */
vc4_state->pos0_offset = vc4_state->dlist_count;
@@ -1203,5 +1233,11 @@ struct drm_plane *vc4_plane_init(struct
DRM_COLOR_YCBCR_BT709,
DRM_COLOR_YCBCR_LIMITED_RANGE);
+ drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
+ DRM_MODE_ROTATE_0 |
+ DRM_MODE_ROTATE_180 |
+ DRM_MODE_REFLECT_X |
+ DRM_MODE_REFLECT_Y);
+
return plane;
}