3b94f268b05d532223a6beec3f4a298f51ddb237
[openwrt/staging/chunkeey.git] / target / linux / brcm2708 / patches-4.14 / 950-0357-drm-vc4-Add-support-for-SAND-modifier.patch
1 From 7d83a48b50ac24af7763e7ba5304e9a82f37f014 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Fri, 16 Mar 2018 15:04:35 -0700
4 Subject: [PATCH 357/454] drm/vc4: Add support for SAND modifier.
5
6 This is the format generated by VC4's H.264 engine, and preferred by
7 the ISP as well. By displaying SAND buffers directly, we can avoid
8 needing to use the ISP to rewrite the SAND H.264 output to linear
9 before display.
10
11 This is a joint effort by Dave Stevenson (who wrote the initial patch
12 and DRM demo) and Eric Anholt (drm_fourcc.h generalization, safety
13 checks, RGBA support).
14
15 v2: Make the parameter macro give all of the middle 48 bits (suggested
16 by Daniels). Fix fourcc_mod_broadcom_mod()'s bits/shift being
17 swapped. Mark NV12/21 as supported, not YUV420.
18
19 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
20 Signed-off-by: Eric Anholt <eric@anholt.net>
21 Cc: Daniel Vetter <daniel@ffwll.ch>
22 Acked-by: Daniel Stone <daniels@collabora.com> (v1)
23 Cc: Boris Brezillon <boris.brezillon@bootlin.com>
24 Cc: Maxime Ripard <maxime.ripard@bootlin.com>
25 Link: https://patchwork.freedesktop.org/patch/msgid/20180316220435.31416-3-eric@anholt.net
26 (cherry picked from commit e065a8dd30af703b4794dc740c0825ee12b92efd)
27 ---
28 drivers/gpu/drm/vc4/vc4_plane.c | 84 ++++++++++++++++++++++++++++++---
29 drivers/gpu/drm/vc4/vc4_regs.h | 6 +++
30 include/uapi/drm/drm_fourcc.h | 59 +++++++++++++++++++++++
31 3 files changed, 142 insertions(+), 7 deletions(-)
32
33 --- a/drivers/gpu/drm/vc4/vc4_plane.c
34 +++ b/drivers/gpu/drm/vc4/vc4_plane.c
35 @@ -466,11 +466,13 @@ static int vc4_plane_mode_set(struct drm
36 struct drm_framebuffer *fb = state->fb;
37 u32 ctl0_offset = vc4_state->dlist_count;
38 const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
39 + u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier);
40 int num_planes = drm_format_num_planes(format->drm);
41 bool covers_screen;
42 u32 scl0, scl1, pitch0;
43 u32 lbm_size, tiling;
44 unsigned long irqflags;
45 + u32 hvs_format = format->hvs;
46 int ret, i;
47
48 ret = vc4_plane_setup_clipping_and_scaling(state);
49 @@ -510,7 +512,7 @@ static int vc4_plane_mode_set(struct drm
50 scl1 = vc4_get_scl_field(state, 0);
51 }
52
53 - switch (fb->modifier) {
54 + switch (base_format_mod) {
55 case DRM_FORMAT_MOD_LINEAR:
56 tiling = SCALER_CTL0_TILING_LINEAR;
57 pitch0 = VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH);
58 @@ -533,6 +535,49 @@ static int vc4_plane_mode_set(struct drm
59 break;
60 }
61
62 + case DRM_FORMAT_MOD_BROADCOM_SAND64:
63 + case DRM_FORMAT_MOD_BROADCOM_SAND128:
64 + case DRM_FORMAT_MOD_BROADCOM_SAND256: {
65 + uint32_t param = fourcc_mod_broadcom_param(fb->modifier);
66 +
67 + /* Column-based NV12 or RGBA.
68 + */
69 + if (fb->format->num_planes > 1) {
70 + if (hvs_format != HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE) {
71 + DRM_DEBUG_KMS("SAND format only valid for NV12/21");
72 + return -EINVAL;
73 + }
74 + hvs_format = HVS_PIXEL_FORMAT_H264;
75 + } else {
76 + if (base_format_mod == DRM_FORMAT_MOD_BROADCOM_SAND256) {
77 + DRM_DEBUG_KMS("SAND256 format only valid for H.264");
78 + return -EINVAL;
79 + }
80 + }
81 +
82 + switch (base_format_mod) {
83 + case DRM_FORMAT_MOD_BROADCOM_SAND64:
84 + tiling = SCALER_CTL0_TILING_64B;
85 + break;
86 + case DRM_FORMAT_MOD_BROADCOM_SAND128:
87 + tiling = SCALER_CTL0_TILING_128B;
88 + break;
89 + case DRM_FORMAT_MOD_BROADCOM_SAND256:
90 + tiling = SCALER_CTL0_TILING_256B_OR_T;
91 + break;
92 + default:
93 + break;
94 + }
95 +
96 + if (param > SCALER_TILE_HEIGHT_MASK) {
97 + DRM_DEBUG_KMS("SAND height too large (%d)\n", param);
98 + return -EINVAL;
99 + }
100 +
101 + pitch0 = VC4_SET_FIELD(param, SCALER_TILE_HEIGHT);
102 + break;
103 + }
104 +
105 default:
106 DRM_DEBUG_KMS("Unsupported FB tiling flag 0x%16llx",
107 (long long)fb->modifier);
108 @@ -543,7 +588,7 @@ static int vc4_plane_mode_set(struct drm
109 vc4_dlist_write(vc4_state,
110 SCALER_CTL0_VALID |
111 (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
112 - (format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
113 + (hvs_format << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
114 VC4_SET_FIELD(tiling, SCALER_CTL0_TILING) |
115 (vc4_state->is_unity ? SCALER_CTL0_UNITY : 0) |
116 VC4_SET_FIELD(scl0, SCALER_CTL0_SCL0) |
117 @@ -597,8 +642,13 @@ static int vc4_plane_mode_set(struct drm
118
119 /* Pitch word 1/2 */
120 for (i = 1; i < num_planes; i++) {
121 - vc4_dlist_write(vc4_state,
122 - VC4_SET_FIELD(fb->pitches[i], SCALER_SRC_PITCH));
123 + if (hvs_format != HVS_PIXEL_FORMAT_H264) {
124 + vc4_dlist_write(vc4_state,
125 + VC4_SET_FIELD(fb->pitches[i],
126 + SCALER_SRC_PITCH));
127 + } else {
128 + vc4_dlist_write(vc4_state, pitch0);
129 + }
130 }
131
132 /* Colorspace conversion words */
133 @@ -881,13 +931,30 @@ static bool vc4_format_mod_supported(str
134 case DRM_FORMAT_BGR565:
135 case DRM_FORMAT_ARGB1555:
136 case DRM_FORMAT_XRGB1555:
137 - return true;
138 + switch (fourcc_mod_broadcom_mod(modifier)) {
139 + case DRM_FORMAT_MOD_LINEAR:
140 + case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
141 + case DRM_FORMAT_MOD_BROADCOM_SAND64:
142 + case DRM_FORMAT_MOD_BROADCOM_SAND128:
143 + return true;
144 + default:
145 + return false;
146 + }
147 + case DRM_FORMAT_NV12:
148 + case DRM_FORMAT_NV21:
149 + switch (fourcc_mod_broadcom_mod(modifier)) {
150 + case DRM_FORMAT_MOD_LINEAR:
151 + case DRM_FORMAT_MOD_BROADCOM_SAND64:
152 + case DRM_FORMAT_MOD_BROADCOM_SAND128:
153 + case DRM_FORMAT_MOD_BROADCOM_SAND256:
154 + return true;
155 + default:
156 + return false;
157 + }
158 case DRM_FORMAT_YUV422:
159 case DRM_FORMAT_YVU422:
160 case DRM_FORMAT_YUV420:
161 case DRM_FORMAT_YVU420:
162 - case DRM_FORMAT_NV12:
163 - case DRM_FORMAT_NV21:
164 case DRM_FORMAT_NV16:
165 case DRM_FORMAT_NV61:
166 default:
167 @@ -917,6 +984,9 @@ struct drm_plane *vc4_plane_init(struct
168 unsigned i;
169 static const uint64_t modifiers[] = {
170 DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
171 + DRM_FORMAT_MOD_BROADCOM_SAND128,
172 + DRM_FORMAT_MOD_BROADCOM_SAND64,
173 + DRM_FORMAT_MOD_BROADCOM_SAND256,
174 DRM_FORMAT_MOD_LINEAR,
175 DRM_FORMAT_MOD_INVALID
176 };
177 --- a/drivers/gpu/drm/vc4/vc4_regs.h
178 +++ b/drivers/gpu/drm/vc4/vc4_regs.h
179 @@ -1059,6 +1059,12 @@ enum hvs_pixel_format {
180 #define SCALER_SRC_PITCH_MASK VC4_MASK(15, 0)
181 #define SCALER_SRC_PITCH_SHIFT 0
182
183 +/* PITCH0/1/2 fields for tiled (SAND). */
184 +#define SCALER_TILE_SKIP_0_MASK VC4_MASK(18, 16)
185 +#define SCALER_TILE_SKIP_0_SHIFT 16
186 +#define SCALER_TILE_HEIGHT_MASK VC4_MASK(15, 0)
187 +#define SCALER_TILE_HEIGHT_SHIFT 0
188 +
189 /* PITCH0 fields for T-tiled. */
190 #define SCALER_PITCH0_TILE_WIDTH_L_MASK VC4_MASK(22, 16)
191 #define SCALER_PITCH0_TILE_WIDTH_L_SHIFT 16
192 --- a/include/uapi/drm/drm_fourcc.h
193 +++ b/include/uapi/drm/drm_fourcc.h
194 @@ -383,6 +383,23 @@ extern "C" {
195 #define NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(v) fourcc_mod_tegra_code(2, v)
196
197 /*
198 + * Some Broadcom modifiers take parameters, for example the number of
199 + * vertical lines in the image. Reserve the lower 32 bits for modifier
200 + * type, and the next 24 bits for parameters. Top 8 bits are the
201 + * vendor code.
202 + */
203 +#define __fourcc_mod_broadcom_param_shift 8
204 +#define __fourcc_mod_broadcom_param_bits 48
205 +#define fourcc_mod_broadcom_code(val, params) \
206 + fourcc_mod_code(BROADCOM, ((((__u64)params) << __fourcc_mod_broadcom_param_shift) | val))
207 +#define fourcc_mod_broadcom_param(m) \
208 + ((int)(((m) >> __fourcc_mod_broadcom_param_shift) & \
209 + ((1ULL << __fourcc_mod_broadcom_param_bits) - 1)))
210 +#define fourcc_mod_broadcom_mod(m) \
211 + ((m) & ~(((1ULL << __fourcc_mod_broadcom_param_bits) - 1) << \
212 + __fourcc_mod_broadcom_param_shift))
213 +
214 +/*
215 * Broadcom VC4 "T" format
216 *
217 * This is the primary layout that the V3D GPU can texture from (it
218 @@ -403,6 +420,48 @@ extern "C" {
219 */
220 #define DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED fourcc_mod_code(BROADCOM, 1)
221
222 +/*
223 + * Broadcom SAND format
224 + *
225 + * This is the native format that the H.264 codec block uses. For VC4
226 + * HVS, it is only valid for H.264 (NV12/21) and RGBA modes.
227 + *
228 + * The image can be considered to be split into columns, and the
229 + * columns are placed consecutively into memory. The width of those
230 + * columns can be either 32, 64, 128, or 256 pixels, but in practice
231 + * only 128 pixel columns are used.
232 + *
233 + * The pitch between the start of each column is set to optimally
234 + * switch between SDRAM banks. This is passed as the number of lines
235 + * of column width in the modifier (we can't use the stride value due
236 + * to various core checks that look at it , so you should set the
237 + * stride to width*cpp).
238 + *
239 + * Note that the column height for this format modifier is the same
240 + * for all of the planes, assuming that each column contains both Y
241 + * and UV. Some SAND-using hardware stores UV in a separate tiled
242 + * image from Y to reduce the column height, which is not supported
243 + * with these modifiers.
244 + */
245 +
246 +#define DRM_FORMAT_MOD_BROADCOM_SAND32_COL_HEIGHT(v) \
247 + fourcc_mod_broadcom_code(2, v)
248 +#define DRM_FORMAT_MOD_BROADCOM_SAND64_COL_HEIGHT(v) \
249 + fourcc_mod_broadcom_code(3, v)
250 +#define DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(v) \
251 + fourcc_mod_broadcom_code(4, v)
252 +#define DRM_FORMAT_MOD_BROADCOM_SAND256_COL_HEIGHT(v) \
253 + fourcc_mod_broadcom_code(5, v)
254 +
255 +#define DRM_FORMAT_MOD_BROADCOM_SAND32 \
256 + DRM_FORMAT_MOD_BROADCOM_SAND32_COL_HEIGHT(0)
257 +#define DRM_FORMAT_MOD_BROADCOM_SAND64 \
258 + DRM_FORMAT_MOD_BROADCOM_SAND64_COL_HEIGHT(0)
259 +#define DRM_FORMAT_MOD_BROADCOM_SAND128 \
260 + DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(0)
261 +#define DRM_FORMAT_MOD_BROADCOM_SAND256 \
262 + DRM_FORMAT_MOD_BROADCOM_SAND256_COL_HEIGHT(0)
263 +
264 #if defined(__cplusplus)
265 }
266 #endif