kernel: bump 5.15 to 5.15.100
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.15 / 950-0635-drm-vc4-hdmi-Support-HDMI-YUV-output.patch
1 From ef94081204ede8c11a28b3c3713c54fee6bc6fea Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Fri, 4 Dec 2020 17:12:06 +0100
4 Subject: [PATCH] drm/vc4: hdmi: Support HDMI YUV output
5
6 In addition to the RGB444 output, the BCM2711 HDMI controller supports
7 the YUV444 and YUV422 output formats.
8
9 Let's add support for them in the driver, but still use RGB as the
10 preferred format.
11
12 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
13 ---
14 drivers/gpu/drm/vc4/vc4_hdmi.c | 289 ++++++++++++++++++++++++++--
15 drivers/gpu/drm/vc4/vc4_hdmi.h | 14 ++
16 drivers/gpu/drm/vc4/vc4_hdmi_regs.h | 6 +
17 drivers/gpu/drm/vc4/vc4_regs.h | 16 ++
18 4 files changed, 309 insertions(+), 16 deletions(-)
19
20 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
21 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
22 @@ -103,15 +103,30 @@
23
24 #define HDMI_14_MAX_TMDS_CLK (340 * 1000 * 1000)
25
26 +static const char * const output_format_str[] = {
27 + [VC4_HDMI_OUTPUT_RGB] = "RGB",
28 + [VC4_HDMI_OUTPUT_YUV420] = "YUV 4:2:0",
29 + [VC4_HDMI_OUTPUT_YUV422] = "YUV 4:2:2",
30 + [VC4_HDMI_OUTPUT_YUV444] = "YUV 4:4:4",
31 +};
32 +
33 +static const char *vc4_hdmi_output_fmt_str(enum vc4_hdmi_output_format fmt)
34 +{
35 + if (fmt >= ARRAY_SIZE(output_format_str))
36 + return "invalid";
37 +
38 + return output_format_str[fmt];
39 +}
40
41 static unsigned long long
42 vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode,
43 - unsigned int bpc);
44 + unsigned int bpc, enum vc4_hdmi_output_format fmt);
45
46 static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode,
47 - unsigned int bpc)
48 + unsigned int bpc,
49 + enum vc4_hdmi_output_format fmt)
50 {
51 - unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc);
52 + unsigned long long clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt);
53
54 return clock > HDMI_14_MAX_TMDS_CLK;
55 }
56 @@ -285,7 +300,7 @@ static int vc4_hdmi_connector_get_modes(
57 struct drm_display_mode *mode;
58
59 list_for_each_entry(mode, &connector->probed_modes, head) {
60 - if (vc4_hdmi_mode_needs_scrambling(mode, 8)) {
61 + if (vc4_hdmi_mode_needs_scrambling(mode, 8, VC4_HDMI_OUTPUT_RGB)) {
62 drm_warn_once(drm, "The core clock cannot reach frequencies high enough to support 4k @ 60Hz.");
63 drm_warn_once(drm, "Please change your config.txt file to add hdmi_enable_4kp60.");
64 }
65 @@ -342,6 +357,7 @@ static void vc4_hdmi_connector_reset(str
66
67 new_state->base.max_bpc = 8;
68 new_state->base.max_requested_bpc = 8;
69 + new_state->output_format = VC4_HDMI_OUTPUT_RGB;
70 drm_atomic_helper_connector_tv_reset(connector);
71 }
72
73 @@ -358,6 +374,7 @@ vc4_hdmi_connector_duplicate_state(struc
74
75 new_state->pixel_rate = vc4_state->pixel_rate;
76 new_state->output_bpc = vc4_state->output_bpc;
77 + new_state->output_format = vc4_state->output_format;
78 __drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
79
80 return &new_state->base;
81 @@ -511,11 +528,38 @@ static void vc4_hdmi_write_infoframe(str
82 DRM_ERROR("Failed to wait for infoframe to start: %d\n", ret);
83 }
84
85 +static void vc4_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame,
86 + enum vc4_hdmi_output_format fmt)
87 +{
88 + switch (fmt) {
89 + case VC4_HDMI_OUTPUT_RGB:
90 + frame->colorspace = HDMI_COLORSPACE_RGB;
91 + break;
92 +
93 + case VC4_HDMI_OUTPUT_YUV420:
94 + frame->colorspace = HDMI_COLORSPACE_YUV420;
95 + break;
96 +
97 + case VC4_HDMI_OUTPUT_YUV422:
98 + frame->colorspace = HDMI_COLORSPACE_YUV422;
99 + break;
100 +
101 + case VC4_HDMI_OUTPUT_YUV444:
102 + frame->colorspace = HDMI_COLORSPACE_YUV444;
103 + break;
104 +
105 + default:
106 + break;
107 + }
108 +}
109 +
110 static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
111 {
112 struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
113 struct drm_connector *connector = &vc4_hdmi->connector;
114 struct drm_connector_state *cstate = connector->state;
115 + struct vc4_hdmi_connector_state *vc4_state =
116 + conn_state_to_vc4_hdmi_conn_state(cstate);
117 const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
118 union hdmi_infoframe frame;
119 int ret;
120 @@ -535,6 +579,7 @@ static void vc4_hdmi_set_avi_infoframe(s
121 HDMI_QUANTIZATION_RANGE_FULL :
122 HDMI_QUANTIZATION_RANGE_LIMITED);
123 drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate);
124 + vc4_hdmi_avi_infoframe_colorspace(&frame.avi, vc4_state->output_format);
125 drm_hdmi_avi_infoframe_bars(&frame.avi, cstate);
126
127 vc4_hdmi_write_infoframe(encoder, &frame);
128 @@ -637,7 +682,9 @@ static void vc4_hdmi_enable_scrambling(s
129 if (!vc4_hdmi_supports_scrambling(encoder, mode))
130 return;
131
132 - if (!vc4_hdmi_mode_needs_scrambling(mode, vc4_hdmi->output_bpc))
133 + if (!vc4_hdmi_mode_needs_scrambling(mode,
134 + vc4_hdmi->output_bpc,
135 + vc4_hdmi->output_format))
136 return;
137
138 drm_scdc_set_high_tmds_clock_ratio(vc4_hdmi->ddc, true);
139 @@ -825,6 +872,38 @@ static const u16 vc5_hdmi_csc_full_rgb_t
140 { 0x0000, 0x0000, 0x1b80, 0x0400 },
141 };
142
143 +/*
144 + * Conversion between Full Range RGB and Full Range YUV422 using the
145 + * BT.709 Colorspace
146 + *
147 + * [ 0.212639 0.715169 0.072192 0 ]
148 + * [ -0.117208 -0.394207 0.511416 128 ]
149 + * [ 0.511416 -0.464524 -0.046891 128 ]
150 + *
151 + * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
152 + */
153 +static const u16 vc5_hdmi_csc_full_rgb_to_full_yuv422_bt709[3][4] = {
154 + { 0x06ce, 0x16e3, 0x024f, 0x0000 },
155 + { 0xfc41, 0xf364, 0x105e, 0x2000 },
156 + { 0x105e, 0xf124, 0xfe81, 0x2000 },
157 +};
158 +
159 +/*
160 + * Conversion between Full Range RGB and Full Range YUV444 using the
161 + * BT.709 Colorspace
162 + *
163 + * [ -0.117208 -0.394207 0.511416 128 ]
164 + * [ 0.511416 -0.464524 -0.046891 128 ]
165 + * [ 0.212639 0.715169 0.072192 0 ]
166 + *
167 + * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
168 + */
169 +static const u16 vc5_hdmi_csc_full_rgb_to_full_yuv444_bt709[3][4] = {
170 + { 0xfc41, 0xf364, 0x105e, 0x2000 },
171 + { 0x105e, 0xf124, 0xfe81, 0x2000 },
172 + { 0x06ce, 0x16e3, 0x024f, 0x0000 },
173 +};
174 +
175 static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi,
176 const u16 coeffs[3][4])
177 {
178 @@ -842,19 +921,53 @@ static void vc5_hdmi_csc_setup(struct vc
179 struct drm_connector_state *state,
180 const struct drm_display_mode *mode)
181 {
182 + struct vc4_hdmi_connector_state *vc4_state =
183 + conn_state_to_vc4_hdmi_conn_state(state);
184 unsigned long flags;
185 + u32 if_cfg = 0;
186 + u32 if_xbar = 0x543210;
187 + u32 csc_chan_ctl = 0;
188 u32 csc_ctl = VC5_MT_CP_CSC_CTL_ENABLE | VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
189 VC5_MT_CP_CSC_CTL_MODE);
190
191 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
192
193 - HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
194 + switch (vc4_state->output_format) {
195 + case VC4_HDMI_OUTPUT_YUV444:
196 + vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_full_yuv444_bt709);
197 + break;
198 +
199 + case VC4_HDMI_OUTPUT_YUV422:
200 + csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD,
201 + VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422) |
202 + VC5_MT_CP_CSC_CTL_USE_444_TO_422 |
203 + VC5_MT_CP_CSC_CTL_USE_RNG_SUPPRESSION;
204
205 - if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode))
206 - vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb);
207 - else
208 - vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity);
209 + csc_chan_ctl |= VC4_SET_FIELD(VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_LEGACY_STYLE,
210 + VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP);
211 +
212 + if_cfg |= VC4_SET_FIELD(VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY,
213 + VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422);
214 +
215 + vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_full_yuv422_bt709);
216 + break;
217
218 + case VC4_HDMI_OUTPUT_RGB:
219 + if_xbar = 0x354021;
220 +
221 + if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode))
222 + vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb);
223 + else
224 + vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity);
225 + break;
226 +
227 + default:
228 + break;
229 + }
230 +
231 + HDMI_WRITE(HDMI_VEC_INTERFACE_CFG, if_cfg);
232 + HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, if_xbar);
233 + HDMI_WRITE(HDMI_CSC_CHANNEL_CTL, csc_chan_ctl);
234 HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
235
236 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
237 @@ -981,6 +1094,15 @@ static void vc5_hdmi_set_timings(struct
238 break;
239 }
240
241 + /*
242 + * YCC422 is always 36-bit and not considered deep colour so
243 + * doesn't signal in GCP
244 + */
245 + if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) {
246 + gcp = 4;
247 + gcp_en = false;
248 + }
249 +
250 reg = HDMI_READ(HDMI_DEEP_COLOR_CONFIG_1);
251 reg &= ~(VC5_HDMI_DEEP_COLOR_CONFIG_1_INIT_PACK_PHASE_MASK |
252 VC5_HDMI_DEEP_COLOR_CONFIG_1_COLOR_DEPTH_MASK);
253 @@ -1260,12 +1382,97 @@ static void vc4_hdmi_encoder_atomic_mode
254
255 mutex_lock(&vc4_hdmi->mutex);
256 vc4_hdmi->output_bpc = vc4_state->output_bpc;
257 + vc4_hdmi->output_format = vc4_state->output_format;
258 memcpy(&vc4_hdmi->saved_adjusted_mode,
259 &crtc_state->adjusted_mode,
260 sizeof(vc4_hdmi->saved_adjusted_mode));
261 mutex_unlock(&vc4_hdmi->mutex);
262 }
263
264 +static bool
265 +vc4_hdmi_sink_supports_format_bpc(const struct vc4_hdmi *vc4_hdmi,
266 + const struct drm_display_info *info,
267 + const struct drm_display_mode *mode,
268 + unsigned int format, unsigned int bpc)
269 +{
270 + struct drm_device *dev = vc4_hdmi->connector.dev;
271 + u8 vic = drm_match_cea_mode(mode);
272 +
273 + if (vic == 1 && bpc != 8) {
274 + drm_dbg(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);
275 + return false;
276 + }
277 +
278 + if (!info->is_hdmi &&
279 + (format != VC4_HDMI_OUTPUT_RGB || bpc != 8)) {
280 + drm_dbg(dev, "DVI Monitors require an RGB output at 8 bpc\n");
281 + return false;
282 + }
283 +
284 + switch (format) {
285 + case VC4_HDMI_OUTPUT_RGB:
286 + drm_dbg(dev, "RGB Format, checking the constraints.\n");
287 +
288 + if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))
289 + return false;
290 +
291 + if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {
292 + drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
293 + return false;
294 + }
295 +
296 + if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {
297 + drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
298 + return false;
299 + }
300 +
301 + drm_dbg(dev, "RGB format supported in that configuration.\n");
302 +
303 + return true;
304 +
305 + case VC4_HDMI_OUTPUT_YUV422:
306 + drm_dbg(dev, "YUV422 format, checking the constraints.\n");
307 +
308 + if (!(info->color_formats & DRM_COLOR_FORMAT_YCRCB422)) {
309 + drm_dbg(dev, "Sink doesn't support YUV422.\n");
310 + return false;
311 + }
312 +
313 + if (bpc != 12) {
314 + drm_dbg(dev, "YUV422 only supports 12 bpc.\n");
315 + return false;
316 + }
317 +
318 + drm_dbg(dev, "YUV422 format supported in that configuration.\n");
319 +
320 + return true;
321 +
322 + case VC4_HDMI_OUTPUT_YUV444:
323 + drm_dbg(dev, "YUV444 format, checking the constraints.\n");
324 +
325 + if (!(info->color_formats & DRM_COLOR_FORMAT_YCRCB444)) {
326 + drm_dbg(dev, "Sink doesn't support YUV444.\n");
327 + return false;
328 + }
329 +
330 + if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {
331 + drm_dbg(dev, "10 BPC but sink doesn't support Deep Color 30.\n");
332 + return false;
333 + }
334 +
335 + if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {
336 + drm_dbg(dev, "12 BPC but sink doesn't support Deep Color 36.\n");
337 + return false;
338 + }
339 +
340 + drm_dbg(dev, "YUV444 format supported in that configuration.\n");
341 +
342 + return true;
343 + }
344 +
345 + return false;
346 +}
347 +
348 static enum drm_mode_status
349 vc4_hdmi_encoder_clock_valid(const struct vc4_hdmi *vc4_hdmi,
350 unsigned long long clock)
351 @@ -1287,13 +1494,17 @@ vc4_hdmi_encoder_clock_valid(const struc
352
353 static unsigned long long
354 vc4_hdmi_encoder_compute_mode_clock(const struct drm_display_mode *mode,
355 - unsigned int bpc)
356 + unsigned int bpc,
357 + enum vc4_hdmi_output_format fmt)
358 {
359 unsigned long long clock = mode->crtc_clock * 1000;
360
361 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
362 clock = clock * 2;
363
364 + if (fmt == VC4_HDMI_OUTPUT_YUV422)
365 + bpc = 8;
366 +
367 return clock * bpc / 8;
368 }
369
370 @@ -1301,11 +1512,11 @@ static int
371 vc4_hdmi_encoder_compute_clock(const struct vc4_hdmi *vc4_hdmi,
372 struct vc4_hdmi_connector_state *vc4_state,
373 const struct drm_display_mode *mode,
374 - unsigned int bpc)
375 + unsigned int bpc, unsigned int fmt)
376 {
377 unsigned long long clock;
378
379 - clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc);
380 + clock = vc4_hdmi_encoder_compute_mode_clock(mode, bpc, fmt);
381 if (vc4_hdmi_encoder_clock_valid(vc4_hdmi, clock) != MODE_OK)
382 return -EINVAL;
383
384 @@ -1315,10 +1526,55 @@ vc4_hdmi_encoder_compute_clock(const str
385 }
386
387 static int
388 +vc4_hdmi_encoder_compute_format(const struct vc4_hdmi *vc4_hdmi,
389 + struct vc4_hdmi_connector_state *vc4_state,
390 + const struct drm_display_mode *mode,
391 + unsigned int bpc)
392 +{
393 + struct drm_device *dev = vc4_hdmi->connector.dev;
394 + const struct drm_connector *connector = &vc4_hdmi->connector;
395 + const struct drm_display_info *info = &connector->display_info;
396 + unsigned int format;
397 +
398 + drm_dbg(dev, "Trying with an RGB output\n");
399 +
400 + format = VC4_HDMI_OUTPUT_RGB;
401 + if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) {
402 + int ret;
403 +
404 + ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state,
405 + mode, bpc, format);
406 + if (!ret) {
407 + vc4_state->output_format = format;
408 + return 0;
409 + }
410 + }
411 +
412 + drm_dbg(dev, "Failed, Trying with an YUV422 output\n");
413 +
414 + format = VC4_HDMI_OUTPUT_YUV422;
415 + if (vc4_hdmi_sink_supports_format_bpc(vc4_hdmi, info, mode, format, bpc)) {
416 + int ret;
417 +
418 + ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state,
419 + mode, bpc, format);
420 + if (!ret) {
421 + vc4_state->output_format = format;
422 + return 0;
423 + }
424 + }
425 +
426 + drm_dbg(dev, "Failed. No Format Supported for that bpc count.\n");
427 +
428 + return -EINVAL;
429 +}
430 +
431 +static int
432 vc4_hdmi_encoder_compute_config(const struct vc4_hdmi *vc4_hdmi,
433 struct vc4_hdmi_connector_state *vc4_state,
434 const struct drm_display_mode *mode)
435 {
436 + struct drm_device *dev = vc4_hdmi->connector.dev;
437 struct drm_connector_state *conn_state = &vc4_state->base;
438 unsigned int max_bpc = clamp_t(unsigned int, conn_state->max_bpc, 8, 12);
439 unsigned int bpc;
440 @@ -1327,17 +1583,18 @@ vc4_hdmi_encoder_compute_config(const st
441 for (bpc = max_bpc; bpc >= 8; bpc -= 2) {
442 drm_dbg(dev, "Trying with a %d bpc output\n", bpc);
443
444 - ret = vc4_hdmi_encoder_compute_clock(vc4_hdmi, vc4_state,
445 - mode, bpc);
446 + ret = vc4_hdmi_encoder_compute_format(vc4_hdmi, vc4_state,
447 + mode, bpc);
448 if (ret)
449 continue;
450
451 vc4_state->output_bpc = bpc;
452
453 drm_dbg(dev,
454 - "Mode %ux%u @ %uHz: Found configuration: bpc: %u, clock: %llu\n",
455 + "Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n",
456 mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
457 vc4_state->output_bpc,
458 + vc4_hdmi_output_fmt_str(vc4_state->output_format),
459 vc4_state->pixel_rate);
460
461 break;
462 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h
463 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
464 @@ -121,6 +121,13 @@ struct vc4_hdmi_audio {
465 bool streaming;
466 };
467
468 +enum vc4_hdmi_output_format {
469 + VC4_HDMI_OUTPUT_RGB,
470 + VC4_HDMI_OUTPUT_YUV422,
471 + VC4_HDMI_OUTPUT_YUV444,
472 + VC4_HDMI_OUTPUT_YUV420,
473 +};
474 +
475 /* General HDMI hardware state. */
476 struct vc4_hdmi {
477 struct vc4_hdmi_audio audio;
478 @@ -227,6 +234,12 @@ struct vc4_hdmi {
479 */
480 unsigned int output_bpc;
481
482 + /**
483 + * @output_format: Copy of @vc4_connector_state.output_format
484 + * for use outside of KMS hooks. Protected by @mutex.
485 + */
486 + enum vc4_hdmi_output_format output_format;
487 +
488 /* VC5 debugfs regset */
489 struct debugfs_regset32 cec_regset;
490 struct debugfs_regset32 csc_regset;
491 @@ -254,6 +267,7 @@ struct vc4_hdmi_connector_state {
492 struct drm_connector_state base;
493 unsigned long long pixel_rate;
494 unsigned int output_bpc;
495 + enum vc4_hdmi_output_format output_format;
496 };
497
498 static inline struct vc4_hdmi_connector_state *
499 --- a/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
500 +++ b/drivers/gpu/drm/vc4/vc4_hdmi_regs.h
501 @@ -54,6 +54,7 @@ enum vc4_hdmi_field {
502 HDMI_CSC_24_23,
503 HDMI_CSC_32_31,
504 HDMI_CSC_34_33,
505 + HDMI_CSC_CHANNEL_CTL,
506 HDMI_CSC_CTL,
507
508 /*
509 @@ -119,6 +120,7 @@ enum vc4_hdmi_field {
510 HDMI_TX_PHY_POWERDOWN_CTL,
511 HDMI_TX_PHY_RESET_CTL,
512 HDMI_TX_PHY_TMDS_CLK_WORD_SEL,
513 + HDMI_VEC_INTERFACE_CFG,
514 HDMI_VEC_INTERFACE_XBAR,
515 HDMI_VERTA0,
516 HDMI_VERTA1,
517 @@ -246,6 +248,7 @@ static const struct vc4_hdmi_register __
518 VC4_HDMI_REG(HDMI_SCRAMBLER_CTL, 0x1c4),
519
520 VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
521 + VC5_DVP_REG(HDMI_VEC_INTERFACE_CFG, 0x0ec),
522 VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0),
523
524 VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
525 @@ -291,6 +294,7 @@ static const struct vc4_hdmi_register __
526 VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
527 VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
528 VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
529 + VC5_CSC_REG(HDMI_CSC_CHANNEL_CTL, 0x02c),
530 };
531
532 static const struct vc4_hdmi_register __maybe_unused vc5_hdmi_hdmi1_fields[] = {
533 @@ -327,6 +331,7 @@ static const struct vc4_hdmi_register __
534 VC4_HDMI_REG(HDMI_SCRAMBLER_CTL, 0x1c4),
535
536 VC5_DVP_REG(HDMI_CLOCK_STOP, 0x0bc),
537 + VC5_DVP_REG(HDMI_VEC_INTERFACE_CFG, 0x0ec),
538 VC5_DVP_REG(HDMI_VEC_INTERFACE_XBAR, 0x0f0),
539
540 VC5_PHY_REG(HDMI_TX_PHY_RESET_CTL, 0x000),
541 @@ -372,6 +377,7 @@ static const struct vc4_hdmi_register __
542 VC5_CSC_REG(HDMI_CSC_24_23, 0x010),
543 VC5_CSC_REG(HDMI_CSC_32_31, 0x014),
544 VC5_CSC_REG(HDMI_CSC_34_33, 0x018),
545 + VC5_CSC_REG(HDMI_CSC_CHANNEL_CTL, 0x02c),
546 };
547
548 static inline
549 --- a/drivers/gpu/drm/vc4/vc4_regs.h
550 +++ b/drivers/gpu/drm/vc4/vc4_regs.h
551 @@ -810,11 +810,27 @@ enum {
552 # define VC4_HD_CSC_CTL_RGB2YCC BIT(1)
553 # define VC4_HD_CSC_CTL_ENABLE BIT(0)
554
555 +# define VC5_MT_CP_CSC_CTL_USE_444_TO_422 BIT(6)
556 +# define VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_MASK \
557 + VC4_MASK(5, 4)
558 +# define VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD \
559 + 3
560 +# define VC5_MT_CP_CSC_CTL_USE_RNG_SUPPRESSION BIT(3)
561 # define VC5_MT_CP_CSC_CTL_ENABLE BIT(2)
562 # define VC5_MT_CP_CSC_CTL_MODE_MASK VC4_MASK(1, 0)
563
564 +# define VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_MASK \
565 + VC4_MASK(7, 6)
566 +# define VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_LEGACY_STYLE \
567 + 2
568 +
569 # define VC4_DVP_HT_CLOCK_STOP_PIXEL BIT(1)
570
571 +# define VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_MASK \
572 + VC4_MASK(3, 2)
573 +# define VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY \
574 + 2
575 +
576 /* HVS display list information. */
577 #define HVS_BOOTLOADER_DLIST_END 32
578