40
40
#define CTM_COEFF_ABS (coeff ) ((coeff) & (CTM_COEFF_SIGN - 1))
41
41
42
42
#define LEGACY_LUT_LENGTH 256
43
-
44
- /* Post offset values for RGB->YCBCR conversion */
45
- #define POSTOFF_RGB_TO_YUV_HI 0x800
46
- #define POSTOFF_RGB_TO_YUV_ME 0x100
47
- #define POSTOFF_RGB_TO_YUV_LO 0x800
48
-
49
- /*
50
- * These values are direct register values specified in the Bspec,
51
- * for RGB->YUV conversion matrix (colorspace BT709)
52
- */
53
- #define CSC_RGB_TO_YUV_RU_GU 0x2ba809d8
54
- #define CSC_RGB_TO_YUV_BU 0x37e80000
55
- #define CSC_RGB_TO_YUV_RY_GY 0x1e089cc0
56
- #define CSC_RGB_TO_YUV_BY 0xb5280000
57
- #define CSC_RGB_TO_YUV_RV_GV 0xbce89ad8
58
- #define CSC_RGB_TO_YUV_BV 0x1e080000
59
-
60
43
/*
61
44
* Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
62
45
* format). This macro takes the coefficient we want transformed and the
74
57
#define ILK_CSC_COEFF_1_0 \
75
58
((7 << 12) | ILK_CSC_COEFF_FP(CTM_COEFF_1_0, 8))
76
59
60
+ #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 * (1 << 12) / 255)
61
+
62
+ static const u16 ilk_csc_off_zero [3 ] = {};
63
+
64
+ static const u16 ilk_csc_postoff_limited_range [3 ] = {
65
+ ILK_CSC_POSTOFF_LIMITED_RANGE ,
66
+ ILK_CSC_POSTOFF_LIMITED_RANGE ,
67
+ ILK_CSC_POSTOFF_LIMITED_RANGE ,
68
+ };
69
+
70
+ /*
71
+ * These values are direct register values specified in the Bspec,
72
+ * for RGB->YUV conversion matrix (colorspace BT709)
73
+ */
74
+ static const u16 ilk_csc_coeff_rgb_to_ycbcr [9 ] = {
75
+ 0x1e08 , 0x9cc0 , 0xb528 ,
76
+ 0x2ba8 , 0x09d8 , 0x37e8 ,
77
+ 0xbce8 , 0x9ad8 , 0x1e08 ,
78
+ };
79
+
80
+ /* Post offset values for RGB->YCBCR conversion */
81
+ static const u16 ilk_csc_postoff_rgb_to_ycbcr [3 ] = {
82
+ 0x0800 , 0x0100 , 0x0800 ,
83
+ };
84
+
77
85
static bool lut_is_legacy (const struct drm_property_blob * lut )
78
86
{
79
87
return drm_color_lut_size (lut ) == LEGACY_LUT_LENGTH ;
@@ -113,54 +121,60 @@ static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
113
121
return result ;
114
122
}
115
123
116
- static void ilk_load_ycbcr_conversion_matrix (struct intel_crtc * crtc )
124
+ static void ilk_update_pipe_csc (struct intel_crtc * crtc ,
125
+ const u16 preoff [3 ],
126
+ const u16 coeff [9 ],
127
+ const u16 postoff [3 ])
117
128
{
118
129
struct drm_i915_private * dev_priv = to_i915 (crtc -> base .dev );
119
130
enum pipe pipe = crtc -> pipe ;
120
131
121
- if (INTEL_GEN (dev_priv ) < 11 ) {
122
- I915_WRITE (PIPE_CSC_PREOFF_HI (pipe ), 0 );
123
- I915_WRITE (PIPE_CSC_PREOFF_ME (pipe ), 0 );
124
- I915_WRITE (PIPE_CSC_PREOFF_LO (pipe ), 0 );
132
+ I915_WRITE (PIPE_CSC_PREOFF_HI (pipe ), preoff [0 ]);
133
+ I915_WRITE (PIPE_CSC_PREOFF_ME (pipe ), preoff [1 ]);
134
+ I915_WRITE (PIPE_CSC_PREOFF_LO (pipe ), preoff [2 ]);
125
135
126
- I915_WRITE (PIPE_CSC_COEFF_RU_GU (pipe ), CSC_RGB_TO_YUV_RU_GU );
127
- I915_WRITE (PIPE_CSC_COEFF_BU (pipe ), CSC_RGB_TO_YUV_BU );
136
+ I915_WRITE (PIPE_CSC_COEFF_RY_GY (pipe ), coeff [ 0 ] << 16 | coeff [ 1 ] );
137
+ I915_WRITE (PIPE_CSC_COEFF_BY (pipe ), coeff [ 2 ] << 16 );
128
138
129
- I915_WRITE (PIPE_CSC_COEFF_RY_GY (pipe ), CSC_RGB_TO_YUV_RY_GY );
130
- I915_WRITE (PIPE_CSC_COEFF_BY (pipe ), CSC_RGB_TO_YUV_BY );
139
+ I915_WRITE (PIPE_CSC_COEFF_RU_GU (pipe ), coeff [ 3 ] << 16 | coeff [ 4 ] );
140
+ I915_WRITE (PIPE_CSC_COEFF_BU (pipe ), coeff [ 5 ] << 16 );
131
141
132
- I915_WRITE (PIPE_CSC_COEFF_RV_GV (pipe ), CSC_RGB_TO_YUV_RV_GV );
133
- I915_WRITE (PIPE_CSC_COEFF_BV (pipe ), CSC_RGB_TO_YUV_BV );
142
+ I915_WRITE (PIPE_CSC_COEFF_RV_GV (pipe ), coeff [ 6 ] << 16 | coeff [ 7 ] );
143
+ I915_WRITE (PIPE_CSC_COEFF_BV (pipe ), coeff [ 8 ] << 16 );
134
144
135
- I915_WRITE (PIPE_CSC_POSTOFF_HI (pipe ), POSTOFF_RGB_TO_YUV_HI );
136
- I915_WRITE (PIPE_CSC_POSTOFF_ME (pipe ), POSTOFF_RGB_TO_YUV_ME );
137
- I915_WRITE (PIPE_CSC_POSTOFF_LO (pipe ), POSTOFF_RGB_TO_YUV_LO );
138
- } else {
139
- I915_WRITE (PIPE_CSC_OUTPUT_PREOFF_HI (pipe ), 0 );
140
- I915_WRITE (PIPE_CSC_OUTPUT_PREOFF_ME (pipe ), 0 );
141
- I915_WRITE (PIPE_CSC_OUTPUT_PREOFF_LO (pipe ), 0 );
142
-
143
- I915_WRITE (PIPE_CSC_OUTPUT_COEFF_RU_GU (pipe ),
144
- CSC_RGB_TO_YUV_RU_GU );
145
- I915_WRITE (PIPE_CSC_OUTPUT_COEFF_BU (pipe ), CSC_RGB_TO_YUV_BU );
146
-
147
- I915_WRITE (PIPE_CSC_OUTPUT_COEFF_RY_GY (pipe ),
148
- CSC_RGB_TO_YUV_RY_GY );
149
- I915_WRITE (PIPE_CSC_OUTPUT_COEFF_BY (pipe ), CSC_RGB_TO_YUV_BY );
150
-
151
- I915_WRITE (PIPE_CSC_OUTPUT_COEFF_RV_GV (pipe ),
152
- CSC_RGB_TO_YUV_RV_GV );
153
- I915_WRITE (PIPE_CSC_OUTPUT_COEFF_BV (pipe ), CSC_RGB_TO_YUV_BV );
154
-
155
- I915_WRITE (PIPE_CSC_OUTPUT_POSTOFF_HI (pipe ),
156
- POSTOFF_RGB_TO_YUV_HI );
157
- I915_WRITE (PIPE_CSC_OUTPUT_POSTOFF_ME (pipe ),
158
- POSTOFF_RGB_TO_YUV_ME );
159
- I915_WRITE (PIPE_CSC_OUTPUT_POSTOFF_LO (pipe ),
160
- POSTOFF_RGB_TO_YUV_LO );
145
+ if (INTEL_GEN (dev_priv ) >= 7 ) {
146
+ I915_WRITE (PIPE_CSC_POSTOFF_HI (pipe ), postoff [0 ]);
147
+ I915_WRITE (PIPE_CSC_POSTOFF_ME (pipe ), postoff [1 ]);
148
+ I915_WRITE (PIPE_CSC_POSTOFF_LO (pipe ), postoff [2 ]);
161
149
}
162
150
}
163
151
152
+ static void icl_update_output_csc (struct intel_crtc * crtc ,
153
+ const u16 preoff [3 ],
154
+ const u16 coeff [9 ],
155
+ const u16 postoff [3 ])
156
+ {
157
+ struct drm_i915_private * dev_priv = to_i915 (crtc -> base .dev );
158
+ enum pipe pipe = crtc -> pipe ;
159
+
160
+ I915_WRITE (PIPE_CSC_OUTPUT_PREOFF_HI (pipe ), preoff [0 ]);
161
+ I915_WRITE (PIPE_CSC_OUTPUT_PREOFF_ME (pipe ), preoff [1 ]);
162
+ I915_WRITE (PIPE_CSC_OUTPUT_PREOFF_LO (pipe ), preoff [2 ]);
163
+
164
+ I915_WRITE (PIPE_CSC_OUTPUT_COEFF_RY_GY (pipe ), coeff [0 ] << 16 | coeff [1 ]);
165
+ I915_WRITE (PIPE_CSC_OUTPUT_COEFF_BY (pipe ), coeff [2 ]);
166
+
167
+ I915_WRITE (PIPE_CSC_OUTPUT_COEFF_RU_GU (pipe ), coeff [3 ] << 16 | coeff [4 ]);
168
+ I915_WRITE (PIPE_CSC_OUTPUT_COEFF_BU (pipe ), coeff [5 ]);
169
+
170
+ I915_WRITE (PIPE_CSC_OUTPUT_COEFF_RV_GV (pipe ), coeff [6 ] << 16 | coeff [7 ]);
171
+ I915_WRITE (PIPE_CSC_OUTPUT_COEFF_BV (pipe ), coeff [8 ]);
172
+
173
+ I915_WRITE (PIPE_CSC_OUTPUT_POSTOFF_HI (pipe ), postoff [0 ]);
174
+ I915_WRITE (PIPE_CSC_OUTPUT_POSTOFF_ME (pipe ), postoff [1 ]);
175
+ I915_WRITE (PIPE_CSC_OUTPUT_POSTOFF_LO (pipe ), postoff [2 ]);
176
+ }
177
+
164
178
static bool ilk_csc_limited_range (const struct intel_crtc_state * crtc_state )
165
179
{
166
180
struct drm_i915_private * dev_priv = to_i915 (crtc_state -> base .crtc -> dev );
@@ -185,7 +199,15 @@ static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
185
199
186
200
if (crtc_state -> output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
187
201
crtc_state -> output_format == INTEL_OUTPUT_FORMAT_YCBCR444 ) {
188
- ilk_load_ycbcr_conversion_matrix (crtc );
202
+ if (INTEL_GEN (dev_priv ) >= 11 )
203
+ icl_update_output_csc (crtc , ilk_csc_off_zero ,
204
+ ilk_csc_coeff_rgb_to_ycbcr ,
205
+ ilk_csc_postoff_rgb_to_ycbcr );
206
+ else
207
+ ilk_update_pipe_csc (crtc , ilk_csc_off_zero ,
208
+ ilk_csc_coeff_rgb_to_ycbcr ,
209
+ ilk_csc_postoff_rgb_to_ycbcr );
210
+
189
211
I915_WRITE (PIPE_CSC_MODE (pipe ), crtc_state -> csc_mode );
190
212
/*
191
213
* On pre GEN11 output CSC is not there, so with 1 pipe CSC
@@ -258,38 +280,12 @@ static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
258
280
}
259
281
}
260
282
261
- I915_WRITE (PIPE_CSC_COEFF_RY_GY (pipe ), coeffs [0 ] << 16 | coeffs [1 ]);
262
- I915_WRITE (PIPE_CSC_COEFF_BY (pipe ), coeffs [2 ] << 16 );
263
-
264
- I915_WRITE (PIPE_CSC_COEFF_RU_GU (pipe ), coeffs [3 ] << 16 | coeffs [4 ]);
265
- I915_WRITE (PIPE_CSC_COEFF_BU (pipe ), coeffs [5 ] << 16 );
266
-
267
- I915_WRITE (PIPE_CSC_COEFF_RV_GV (pipe ), coeffs [6 ] << 16 | coeffs [7 ]);
268
- I915_WRITE (PIPE_CSC_COEFF_BV (pipe ), coeffs [8 ] << 16 );
283
+ ilk_update_pipe_csc (crtc , ilk_csc_off_zero , coeffs ,
284
+ limited_color_range ?
285
+ ilk_csc_postoff_limited_range :
286
+ ilk_csc_off_zero );
269
287
270
- I915_WRITE (PIPE_CSC_PREOFF_HI (pipe ), 0 );
271
- I915_WRITE (PIPE_CSC_PREOFF_ME (pipe ), 0 );
272
- I915_WRITE (PIPE_CSC_PREOFF_LO (pipe ), 0 );
273
-
274
- if (INTEL_GEN (dev_priv ) > 6 ) {
275
- u16 postoff = 0 ;
276
-
277
- if (limited_color_range )
278
- postoff = (16 * (1 << 12 ) / 255 ) & 0x1fff ;
279
-
280
- I915_WRITE (PIPE_CSC_POSTOFF_HI (pipe ), postoff );
281
- I915_WRITE (PIPE_CSC_POSTOFF_ME (pipe ), postoff );
282
- I915_WRITE (PIPE_CSC_POSTOFF_LO (pipe ), postoff );
283
-
284
- I915_WRITE (PIPE_CSC_MODE (pipe ), crtc_state -> csc_mode );
285
- } else {
286
- u32 mode = CSC_MODE_YUV_TO_RGB ;
287
-
288
- if (limited_color_range )
289
- mode |= CSC_BLACK_SCREEN_OFFSET ;
290
-
291
- I915_WRITE (PIPE_CSC_MODE (pipe ), mode );
292
- }
288
+ I915_WRITE (PIPE_CSC_MODE (pipe ), crtc_state -> csc_mode );
293
289
}
294
290
295
291
/*
0 commit comments