bcm27xx: add support for linux v5.15
[openwrt/staging/chunkeey.git] / target / linux / bcm27xx / patches-5.15 / 950-0628-drm-vc4-hdmi-Define-colorspace-matrices.patch
1 From cbb71ade28d28e5fcb04171b6be283b150796e7a Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Wed, 13 Jan 2021 11:30:21 +0100
4 Subject: [PATCH] drm/vc4: hdmi: Define colorspace matrices
5
6 The current CSC setup code for the BCM2711 uses a sequence of register
7 writes to configure the CSC depending on whether we output using a full
8 or limited range.
9
10 However, with the upcoming introduction of the YUV output, we're going
11 to add new matrices to perform the conversions, so we should switch to
12 something a bit more flexible that takes the matrix as an argument and
13 programs the CSC accordingly.
14
15 Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
16 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
17 ---
18 drivers/gpu/drm/vc4/vc4_hdmi.c | 79 +++++++++++++++++++++-------------
19 1 file changed, 50 insertions(+), 29 deletions(-)
20
21 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
22 +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
23 @@ -781,6 +781,52 @@ static void vc4_hdmi_csc_setup(struct vc
24 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
25 }
26
27 +
28 +/*
29 + * If we need to output Full Range RGB, then use the unity matrix
30 + *
31 + * [ 1 0 0 0]
32 + * [ 0 1 0 0]
33 + * [ 0 0 1 0]
34 + *
35 + * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
36 + */
37 +static const u16 vc5_hdmi_csc_full_rgb_unity[3][4] = {
38 + { 0x2000, 0x0000, 0x0000, 0x0000 },
39 + { 0x0000, 0x2000, 0x0000, 0x0000 },
40 + { 0x0000, 0x0000, 0x2000, 0x0000 },
41 +};
42 +
43 +/*
44 + * CEA VICs other than #1 require limited range RGB output unless
45 + * overridden by an AVI infoframe. Apply a colorspace conversion to
46 + * squash 0-255 down to 16-235. The matrix here is:
47 + *
48 + * [ 0.8594 0 0 16]
49 + * [ 0 0.8594 0 16]
50 + * [ 0 0 0.8594 16]
51 + *
52 + * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
53 + */
54 +static const u16 vc5_hdmi_csc_full_rgb_to_limited_rgb[3][4] = {
55 + { 0x1b80, 0x0000, 0x0000, 0x0400 },
56 + { 0x0000, 0x1b80, 0x0000, 0x0400 },
57 + { 0x0000, 0x0000, 0x1b80, 0x0400 },
58 +};
59 +
60 +static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi,
61 + const u16 coeffs[3][4])
62 +{
63 + lockdep_assert_held(&vc4_hdmi->hw_lock);
64 +
65 + HDMI_WRITE(HDMI_CSC_12_11, (coeffs[0][1] << 16) | coeffs[0][0]);
66 + HDMI_WRITE(HDMI_CSC_14_13, (coeffs[0][3] << 16) | coeffs[0][2]);
67 + HDMI_WRITE(HDMI_CSC_22_21, (coeffs[1][1] << 16) | coeffs[1][0]);
68 + HDMI_WRITE(HDMI_CSC_24_23, (coeffs[1][3] << 16) | coeffs[1][2]);
69 + HDMI_WRITE(HDMI_CSC_32_31, (coeffs[2][1] << 16) | coeffs[2][0]);
70 + HDMI_WRITE(HDMI_CSC_34_33, (coeffs[2][3] << 16) | coeffs[2][2]);
71 +}
72 +
73 static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
74 const struct drm_display_mode *mode)
75 {
76 @@ -792,35 +838,10 @@ static void vc5_hdmi_csc_setup(struct vc
77
78 HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
79
80 - if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) {
81 - /* CEA VICs other than #1 requre limited range RGB
82 - * output unless overridden by an AVI infoframe.
83 - * Apply a colorspace conversion to squash 0-255 down
84 - * to 16-235. The matrix here is:
85 - *
86 - * [ 0.8594 0 0 16]
87 - * [ 0 0.8594 0 16]
88 - * [ 0 0 0.8594 16]
89 - * [ 0 0 0 1]
90 - * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
91 - */
92 - HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x1b80);
93 - HDMI_WRITE(HDMI_CSC_14_13, (0x0400 << 16) | 0x0000);
94 - HDMI_WRITE(HDMI_CSC_22_21, (0x1b80 << 16) | 0x0000);
95 - HDMI_WRITE(HDMI_CSC_24_23, (0x0400 << 16) | 0x0000);
96 - HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
97 - HDMI_WRITE(HDMI_CSC_34_33, (0x0400 << 16) | 0x1b80);
98 - } else {
99 - /* Still use the matrix for full range, but make it unity.
100 - * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
101 - */
102 - HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x2000);
103 - HDMI_WRITE(HDMI_CSC_14_13, (0x0000 << 16) | 0x0000);
104 - HDMI_WRITE(HDMI_CSC_22_21, (0x2000 << 16) | 0x0000);
105 - HDMI_WRITE(HDMI_CSC_24_23, (0x0000 << 16) | 0x0000);
106 - HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
107 - HDMI_WRITE(HDMI_CSC_34_33, (0x0000 << 16) | 0x2000);
108 - }
109 + if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode))
110 + vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb);
111 + else
112 + vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity);
113
114 HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
115