bcm27xx: update patches from RPi foundation
[oweals/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0603-drm-vc4-Add-support-for-DRM_FORMAT_P030-to-vc4-plane.patch
1 From 87c4b03b9d1180c2f878b19363ec0609b5f24c75 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Fri, 24 Jan 2020 14:25:41 +0000
4 Subject: [PATCH] drm/vc4: Add support for DRM_FORMAT_P030 to vc4
5  planes
6
7 This currently doesn't handle non-zero source rectangles correctly,
8 but add support for DRM_FORMAT_P030 with DRM_FORMAT_MOD_BROADCOM_SAND128
9 modifier to planes when running on HVS5.
10
11 WIP still for source cropping SAND/P030 formats
12
13 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
14 ---
15  drivers/gpu/drm/vc4/vc4_plane.c | 83 +++++++++++++++++++++++----------
16  1 file changed, 59 insertions(+), 24 deletions(-)
17
18 --- a/drivers/gpu/drm/vc4/vc4_plane.c
19 +++ b/drivers/gpu/drm/vc4/vc4_plane.c
20 @@ -33,6 +33,7 @@ static const struct hvs_format {
21         u32 hvs; /* HVS_FORMAT_* */
22         u32 pixel_order;
23         u32 pixel_order_hvs5;
24 +       bool hvs5_only;
25  } hvs_formats[] = {
26         {
27                 .drm = DRM_FORMAT_XRGB8888,
28 @@ -128,6 +129,12 @@ static const struct hvs_format {
29                 .hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_2PLANE,
30                 .pixel_order = HVS_PIXEL_ORDER_XYCRCB,
31         },
32 +       {
33 +               .drm = DRM_FORMAT_P030,
34 +               .hvs = HVS_PIXEL_FORMAT_YCBCR_10BIT,
35 +               .pixel_order = HVS_PIXEL_ORDER_XYCBCR,
36 +               .hvs5_only = true,
37 +       },
38  };
39  
40  static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
41 @@ -801,27 +808,33 @@ static int vc4_plane_mode_set(struct drm
42                 uint32_t param = fourcc_mod_broadcom_param(fb->modifier);
43                 u32 tile_w, tile, x_off, pix_per_tile;
44  
45 -               hvs_format = HVS_PIXEL_FORMAT_H264;
46 -
47 -               switch (base_format_mod) {
48 -               case DRM_FORMAT_MOD_BROADCOM_SAND64:
49 -                       tiling = SCALER_CTL0_TILING_64B;
50 -                       tile_w = 64;
51 -                       break;
52 -               case DRM_FORMAT_MOD_BROADCOM_SAND128:
53 +               if (fb->format->format == DRM_FORMAT_P030) {
54 +                       hvs_format = HVS_PIXEL_FORMAT_YCBCR_10BIT;
55                         tiling = SCALER_CTL0_TILING_128B;
56 -                       tile_w = 128;
57 -                       break;
58 -               case DRM_FORMAT_MOD_BROADCOM_SAND256:
59 -                       tiling = SCALER_CTL0_TILING_256B_OR_T;
60 -                       tile_w = 256;
61 -                       break;
62 -               default:
63 -                       break;
64 -               }
65 +                       tile_w = 96;
66 +               } else {
67 +                       hvs_format = HVS_PIXEL_FORMAT_H264;
68  
69 +                       switch (base_format_mod) {
70 +                       case DRM_FORMAT_MOD_BROADCOM_SAND64:
71 +                               tiling = SCALER_CTL0_TILING_64B;
72 +                               tile_w = 64;
73 +                               break;
74 +                       case DRM_FORMAT_MOD_BROADCOM_SAND128:
75 +                               tiling = SCALER_CTL0_TILING_128B;
76 +                               tile_w = 128;
77 +                               break;
78 +                       case DRM_FORMAT_MOD_BROADCOM_SAND256:
79 +                               tiling = SCALER_CTL0_TILING_256B_OR_T;
80 +                               tile_w = 256;
81 +                               break;
82 +                       default:
83 +                               break;
84 +                       }
85 +               }
86                 if (param > SCALER_TILE_HEIGHT_MASK) {
87 -                       DRM_DEBUG_KMS("SAND height too large (%d)\n", param);
88 +                       DRM_DEBUG_KMS("SAND height too large (%d)\n",
89 +                                     param);
90                         return -EINVAL;
91                 }
92  
93 @@ -831,6 +844,13 @@ static int vc4_plane_mode_set(struct drm
94  
95                 /* Adjust the base pointer to the first pixel to be scanned
96                  * out.
97 +                *
98 +                * For P030, y_ptr [31:4] is the 128bit word for the start pixel
99 +                * y_ptr [3:0] is the pixel (0-11) contained within that 128bit
100 +                * word that should be taken as the first pixel.
101 +                * Ditto uv_ptr [31:4] vs [3:0], however [3:0] contains the
102 +                * element within the 128bit word, eg for pixel 3 the value
103 +                * should be 6.
104                  */
105                 for (i = 0; i < num_planes; i++) {
106                         vc4_state->offsets[i] += param * tile_w * tile;
107 @@ -943,8 +963,8 @@ static int vc4_plane_mode_set(struct drm
108                 vc4_dlist_write(vc4_state,
109                                 VC4_SET_FIELD(state->alpha >> 4,
110                                               SCALER5_CTL2_ALPHA) |
111 -                               fb->format->has_alpha ?
112 -                                       SCALER5_CTL2_ALPHA_PREMULT : 0 |
113 +                               (fb->format->has_alpha ?
114 +                                       SCALER5_CTL2_ALPHA_PREMULT : 0) |
115                                 (mix_plane_alpha ?
116                                         SCALER5_CTL2_ALPHA_MIX : 0) |
117                                 VC4_SET_FIELD(fb->format->has_alpha ?
118 @@ -992,7 +1012,8 @@ static int vc4_plane_mode_set(struct drm
119  
120         /* Pitch word 1/2 */
121         for (i = 1; i < num_planes; i++) {
122 -               if (hvs_format != HVS_PIXEL_FORMAT_H264) {
123 +               if (hvs_format != HVS_PIXEL_FORMAT_H264 &&
124 +                   hvs_format != HVS_PIXEL_FORMAT_YCBCR_10BIT) {
125                         vc4_dlist_write(vc4_state,
126                                         VC4_SET_FIELD(fb->pitches[i],
127                                                       SCALER_SRC_PITCH));
128 @@ -1361,6 +1382,13 @@ static bool vc4_format_mod_supported(str
129                 default:
130                         return false;
131                 }
132 +       case DRM_FORMAT_P030:
133 +               switch (fourcc_mod_broadcom_mod(modifier)) {
134 +               case DRM_FORMAT_MOD_BROADCOM_SAND128:
135 +                       return true;
136 +               default:
137 +                       return false;
138 +               }
139         case DRM_FORMAT_RGBX1010102:
140         case DRM_FORMAT_BGRX1010102:
141         case DRM_FORMAT_RGBA1010102:
142 @@ -1393,8 +1421,11 @@ struct drm_plane *vc4_plane_init(struct
143         struct drm_plane *plane = NULL;
144         struct vc4_plane *vc4_plane;
145         u32 formats[ARRAY_SIZE(hvs_formats)];
146 +       int num_formats = 0;
147         int ret = 0;
148         unsigned i;
149 +       bool hvs5 = of_device_is_compatible(dev->dev->of_node,
150 +                                           "brcm,bcm2711-vc5");
151         static const uint64_t modifiers[] = {
152                 DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
153                 DRM_FORMAT_MOD_BROADCOM_SAND128,
154 @@ -1409,13 +1440,17 @@ struct drm_plane *vc4_plane_init(struct
155         if (!vc4_plane)
156                 return ERR_PTR(-ENOMEM);
157  
158 -       for (i = 0; i < ARRAY_SIZE(hvs_formats); i++)
159 -               formats[i] = hvs_formats[i].drm;
160 +       for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) {
161 +               if (hvs_formats[i].hvs5_only || hvs5) {
162 +                       formats[num_formats] = hvs_formats[i].drm;
163 +                       num_formats++;
164 +               }
165 +       }
166  
167         plane = &vc4_plane->base;
168         ret = drm_universal_plane_init(dev, plane, 0,
169                                        &vc4_plane_funcs,
170 -                                      formats, ARRAY_SIZE(formats),
171 +                                      formats, num_formats,
172                                        modifiers, type, NULL);
173  
174         drm_plane_helper_add(plane, &vc4_plane_helper_funcs);