Skip to content

Commit d2c19b0

Browse files
committed
drm/i915: Clean up ilk/icl pipe/output CSC programming
We have far too much messy duplicated code in the pipe/output CSC programming. Simply provide two functions (ilk_update_pipe_csc() and icl_update_output_csc()) to program the relevant CSC registers. The desired offsets and coefficients are passed in as parameters. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190218193137.22914-5-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar <uma.shankar@intel.com>
1 parent 386ba08 commit d2c19b0

File tree

1 file changed

+82
-86
lines changed

1 file changed

+82
-86
lines changed

drivers/gpu/drm/i915/intel_color.c

Lines changed: 82 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,6 @@
4040
#define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1))
4141

4242
#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-
6043
/*
6144
* Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
6245
* format). This macro takes the coefficient we want transformed and the
@@ -74,6 +57,31 @@
7457
#define ILK_CSC_COEFF_1_0 \
7558
((7 << 12) | ILK_CSC_COEFF_FP(CTM_COEFF_1_0, 8))
7659

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+
7785
static bool lut_is_legacy(const struct drm_property_blob *lut)
7886
{
7987
return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
@@ -113,54 +121,60 @@ static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
113121
return result;
114122
}
115123

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])
117128
{
118129
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
119130
enum pipe pipe = crtc->pipe;
120131

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]);
125135

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);
128138

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);
131141

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);
134144

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]);
161149
}
162150
}
163151

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+
164178
static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
165179
{
166180
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)
185199

186200
if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
187201
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+
189211
I915_WRITE(PIPE_CSC_MODE(pipe), crtc_state->csc_mode);
190212
/*
191213
* 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)
258280
}
259281
}
260282

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);
269287

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);
293289
}
294290

295291
/*

0 commit comments

Comments
 (0)