3644e1683f62a756f47f39a70898b228fac40764
[oweals/openwrt.git] /
1 From 6cf13bf5f3a3e03c7899a421ff8e9b39ce4ec8d0 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Tue, 9 Apr 2019 17:19:51 +0100
4 Subject: [PATCH 601/782] drm: vc4: Add support for H & V flips on each plane
5  for FKMS
6
7 They are near zero cost options for the HVS, therefore they
8 may as well be implemented, and it allows us to invert the
9 DSI display.
10
11 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
12 ---
13  drivers/gpu/drm/vc4/vc4_firmware_kms.c | 36 ++++++++++++++++++++++++++
14  1 file changed, 36 insertions(+)
15
16 --- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
17 +++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
18 @@ -61,8 +61,21 @@ struct set_plane {
19         u8 padding;
20  
21         u32 planes[4];  /* DMA address of each plane */
22 +
23 +       u32 transform;
24  };
25  
26 +/* Values for the transform field */
27 +#define TRANSFORM_NO_ROTATE    0
28 +#define TRANSFORM_ROTATE_180   BIT(1)
29 +#define TRANSFORM_FLIP_HRIZ    BIT(16)
30 +#define TRANSFORM_FLIP_VERT    BIT(17)
31 +
32 +#define SUPPORTED_ROTATIONS    (DRM_MODE_ROTATE_0 | \
33 +                                DRM_MODE_ROTATE_180 | \
34 +                                DRM_MODE_REFLECT_X | \
35 +                                DRM_MODE_REFLECT_Y)
36 +
37  struct mailbox_set_plane {
38         struct rpi_firmware_property_tag_header tag;
39         struct set_plane plane;
40 @@ -274,6 +287,7 @@ static void vc4_plane_atomic_update(stru
41         struct vc4_crtc *vc4_crtc = to_vc4_crtc(state->crtc);
42         int num_planes = fb->format->num_planes;
43         struct drm_display_mode *mode = &state->crtc->mode;
44 +       unsigned int rotation = SUPPORTED_ROTATIONS;
45  
46         mb->plane.vc_image_type = vc_fmt->vc_image;
47         mb->plane.width = fb->width;
48 @@ -294,6 +308,24 @@ static void vc4_plane_atomic_update(stru
49         mb->plane.is_vu = vc_fmt->is_vu;
50         mb->plane.planes[0] = bo->paddr + fb->offsets[0];
51  
52 +       rotation = drm_rotation_simplify(state->rotation, rotation);
53 +
54 +       switch (rotation) {
55 +       default:
56 +       case DRM_MODE_ROTATE_0:
57 +               mb->plane.transform = TRANSFORM_NO_ROTATE;
58 +               break;
59 +       case DRM_MODE_ROTATE_180:
60 +               mb->plane.transform = TRANSFORM_ROTATE_180;
61 +               break;
62 +       case DRM_MODE_REFLECT_X:
63 +               mb->plane.transform = TRANSFORM_FLIP_HRIZ;
64 +               break;
65 +       case DRM_MODE_REFLECT_Y:
66 +               mb->plane.transform = TRANSFORM_FLIP_VERT;
67 +               break;
68 +       }
69 +
70         /* FIXME: If the dest rect goes off screen then clip the src rect so we
71          * don't have off-screen pixels.
72          */
73 @@ -514,9 +546,13 @@ static struct drm_plane *vc4_fkms_plane_
74                                        formats, num_formats, modifiers,
75                                        type, NULL);
76  
77 +       /* FIXME: Do we need to be checking return values from all these calls?
78 +        */
79         drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
80  
81         drm_plane_create_alpha_property(plane);
82 +       drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
83 +                                          SUPPORTED_ROTATIONS);
84  
85         /*
86          * Default frame buffer setup is with FB on -127, and raspistill etc