d230566e61a2011cfc4918dca822474285c5822c
[openwrt/staging/neocturne.git] /
1 From 81fe25670ae332380379026469c272e5d466c4cb Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Wed, 15 Dec 2021 10:17:39 +0100
4 Subject: [PATCH] drm/vc4: plane: Add support for YUV color encodings
5 and ranges
6
7 The BT601/BT709 color encoding and limited vs full
8 range properties were not being exposed, defaulting
9 always to BT601 limited range.
10
11 Expose the parameters and set the registers appropriately.
12
13 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
14 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
15 Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
16 Link: https://lore.kernel.org/r/20211215091739.135042-4-maxime@cerno.tech
17 ---
18 drivers/gpu/drm/vc4/vc4_plane.c | 71 +++++++++++++++++++++++++++++++--
19 drivers/gpu/drm/vc4/vc4_regs.h | 19 ++++++---
20 2 files changed, 82 insertions(+), 8 deletions(-)
21
22 --- a/drivers/gpu/drm/vc4/vc4_plane.c
23 +++ b/drivers/gpu/drm/vc4/vc4_plane.c
24 @@ -621,6 +621,51 @@ static int vc4_plane_allocate_lbm(struct
25 return 0;
26 }
27
28 +/*
29 + * The colorspace conversion matrices are held in 3 entries in the dlist.
30 + * Create an array of them, with entries for each full and limited mode, and
31 + * each supported colorspace.
32 + */
33 +static const u32 colorspace_coeffs[2][DRM_COLOR_ENCODING_MAX][3] = {
34 + {
35 + /* Limited range */
36 + {
37 + /* BT601 */
38 + SCALER_CSC0_ITR_R_601_5,
39 + SCALER_CSC1_ITR_R_601_5,
40 + SCALER_CSC2_ITR_R_601_5,
41 + }, {
42 + /* BT709 */
43 + SCALER_CSC0_ITR_R_709_3,
44 + SCALER_CSC1_ITR_R_709_3,
45 + SCALER_CSC2_ITR_R_709_3,
46 + }, {
47 + /* BT2020 */
48 + SCALER_CSC0_ITR_R_2020,
49 + SCALER_CSC1_ITR_R_2020,
50 + SCALER_CSC2_ITR_R_2020,
51 + }
52 + }, {
53 + /* Full range */
54 + {
55 + /* JFIF */
56 + SCALER_CSC0_JPEG_JFIF,
57 + SCALER_CSC1_JPEG_JFIF,
58 + SCALER_CSC2_JPEG_JFIF,
59 + }, {
60 + /* BT709 */
61 + SCALER_CSC0_ITR_R_709_3_FR,
62 + SCALER_CSC1_ITR_R_709_3_FR,
63 + SCALER_CSC2_ITR_R_709_3_FR,
64 + }, {
65 + /* BT2020 */
66 + SCALER_CSC0_ITR_R_2020_FR,
67 + SCALER_CSC1_ITR_R_2020_FR,
68 + SCALER_CSC2_ITR_R_2020_FR,
69 + }
70 + }
71 +};
72 +
73 /* Writes out a full display list for an active plane to the plane's
74 * private dlist state.
75 */
76 @@ -1015,9 +1060,20 @@ static int vc4_plane_mode_set(struct drm
77
78 /* Colorspace conversion words */
79 if (vc4_state->is_yuv) {
80 - vc4_dlist_write(vc4_state, SCALER_CSC0_ITR_R_601_5);
81 - vc4_dlist_write(vc4_state, SCALER_CSC1_ITR_R_601_5);
82 - vc4_dlist_write(vc4_state, SCALER_CSC2_ITR_R_601_5);
83 + enum drm_color_encoding color_encoding = state->color_encoding;
84 + enum drm_color_range color_range = state->color_range;
85 + const u32 *ccm;
86 +
87 + if (color_encoding >= DRM_COLOR_ENCODING_MAX)
88 + color_encoding = DRM_COLOR_YCBCR_BT601;
89 + if (color_range >= DRM_COLOR_RANGE_MAX)
90 + color_range = DRM_COLOR_YCBCR_LIMITED_RANGE;
91 +
92 + ccm = colorspace_coeffs[color_range][color_encoding];
93 +
94 + vc4_dlist_write(vc4_state, ccm[0]);
95 + vc4_dlist_write(vc4_state, ccm[1]);
96 + vc4_dlist_write(vc4_state, ccm[2]);
97 }
98
99 vc4_state->lbm_offset = 0;
100 @@ -1446,6 +1502,15 @@ struct drm_plane *vc4_plane_init(struct
101 DRM_MODE_REFLECT_X |
102 DRM_MODE_REFLECT_Y);
103
104 + drm_plane_create_color_properties(plane,
105 + BIT(DRM_COLOR_YCBCR_BT601) |
106 + BIT(DRM_COLOR_YCBCR_BT709) |
107 + BIT(DRM_COLOR_YCBCR_BT2020),
108 + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
109 + BIT(DRM_COLOR_YCBCR_FULL_RANGE),
110 + DRM_COLOR_YCBCR_BT709,
111 + DRM_COLOR_YCBCR_LIMITED_RANGE);
112 +
113 return plane;
114 }
115
116 --- a/drivers/gpu/drm/vc4/vc4_regs.h
117 +++ b/drivers/gpu/drm/vc4/vc4_regs.h
118 @@ -989,7 +989,10 @@ enum hvs_pixel_format {
119 #define SCALER_CSC0_COEF_CR_OFS_SHIFT 0
120 #define SCALER_CSC0_ITR_R_601_5 0x00f00000
121 #define SCALER_CSC0_ITR_R_709_3 0x00f00000
122 +#define SCALER_CSC0_ITR_R_2020 0x00f00000
123 #define SCALER_CSC0_JPEG_JFIF 0x00000000
124 +#define SCALER_CSC0_ITR_R_709_3_FR 0x00000000
125 +#define SCALER_CSC0_ITR_R_2020_FR 0x00000000
126
127 /* S2.8 contribution of Cb to Green */
128 #define SCALER_CSC1_COEF_CB_GRN_MASK VC4_MASK(31, 22)
129 @@ -1004,8 +1007,11 @@ enum hvs_pixel_format {
130 #define SCALER_CSC1_COEF_CR_BLU_MASK VC4_MASK(1, 0)
131 #define SCALER_CSC1_COEF_CR_BLU_SHIFT 0
132 #define SCALER_CSC1_ITR_R_601_5 0xe73304a8
133 -#define SCALER_CSC1_ITR_R_709_3 0xf2b784a8
134 -#define SCALER_CSC1_JPEG_JFIF 0xea34a400
135 +#define SCALER_CSC1_ITR_R_709_3 0xf27784a8
136 +#define SCALER_CSC1_ITR_R_2020 0xf43594a8
137 +#define SCALER_CSC1_JPEG_JFIF 0xea349400
138 +#define SCALER_CSC1_ITR_R_709_3_FR 0xf4388400
139 +#define SCALER_CSC1_ITR_R_2020_FR 0xf5b6d400
140
141 /* S2.8 contribution of Cb to Red */
142 #define SCALER_CSC2_COEF_CB_RED_MASK VC4_MASK(29, 20)
143 @@ -1016,9 +1022,12 @@ enum hvs_pixel_format {
144 /* S2.8 contribution of Cb to Blue */
145 #define SCALER_CSC2_COEF_CB_BLU_MASK VC4_MASK(19, 10)
146 #define SCALER_CSC2_COEF_CB_BLU_SHIFT 10
147 -#define SCALER_CSC2_ITR_R_601_5 0x00066204
148 -#define SCALER_CSC2_ITR_R_709_3 0x00072a1c
149 -#define SCALER_CSC2_JPEG_JFIF 0x000599c5
150 +#define SCALER_CSC2_ITR_R_601_5 0x00066604
151 +#define SCALER_CSC2_ITR_R_709_3 0x00072e1d
152 +#define SCALER_CSC2_ITR_R_2020 0x0006b624
153 +#define SCALER_CSC2_JPEG_JFIF 0x00059dc6
154 +#define SCALER_CSC2_ITR_R_709_3_FR 0x00064ddb
155 +#define SCALER_CSC2_ITR_R_2020_FR 0x0005e5e2
156
157 #define SCALER_TPZ0_VERT_RECALC BIT(31)
158 #define SCALER_TPZ0_SCALE_MASK VC4_MASK(28, 8)