linux/drivers/gpu/drm/i915/display/intel_color.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2016 Intel Corporation
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21 * DEALINGS IN THE SOFTWARE.
  22 *
  23 */
  24
  25#include "intel_color.h"
  26#include "intel_drv.h"
  27
  28#define CTM_COEFF_SIGN  (1ULL << 63)
  29
  30#define CTM_COEFF_1_0   (1ULL << 32)
  31#define CTM_COEFF_2_0   (CTM_COEFF_1_0 << 1)
  32#define CTM_COEFF_4_0   (CTM_COEFF_2_0 << 1)
  33#define CTM_COEFF_8_0   (CTM_COEFF_4_0 << 1)
  34#define CTM_COEFF_0_5   (CTM_COEFF_1_0 >> 1)
  35#define CTM_COEFF_0_25  (CTM_COEFF_0_5 >> 1)
  36#define CTM_COEFF_0_125 (CTM_COEFF_0_25 >> 1)
  37
  38#define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
  39
  40#define CTM_COEFF_NEGATIVE(coeff)       (((coeff) & CTM_COEFF_SIGN) != 0)
  41#define CTM_COEFF_ABS(coeff)            ((coeff) & (CTM_COEFF_SIGN - 1))
  42
  43#define LEGACY_LUT_LENGTH               256
  44
  45/*
  46 * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
  47 * format). This macro takes the coefficient we want transformed and the
  48 * number of fractional bits.
  49 *
  50 * We only have a 9 bits precision window which slides depending on the value
  51 * of the CTM coefficient and we write the value from bit 3. We also round the
  52 * value.
  53 */
  54#define ILK_CSC_COEFF_FP(coeff, fbits)  \
  55        (clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
  56
  57#define ILK_CSC_COEFF_LIMITED_RANGE 0x0dc0
  58#define ILK_CSC_COEFF_1_0 0x7800
  59
  60#define ILK_CSC_POSTOFF_LIMITED_RANGE (16 * (1 << 12) / 255)
  61
  62static const u16 ilk_csc_off_zero[3] = {};
  63
  64static const u16 ilk_csc_coeff_identity[9] = {
  65        ILK_CSC_COEFF_1_0, 0, 0,
  66        0, ILK_CSC_COEFF_1_0, 0,
  67        0, 0, ILK_CSC_COEFF_1_0,
  68};
  69
  70static const u16 ilk_csc_postoff_limited_range[3] = {
  71        ILK_CSC_POSTOFF_LIMITED_RANGE,
  72        ILK_CSC_POSTOFF_LIMITED_RANGE,
  73        ILK_CSC_POSTOFF_LIMITED_RANGE,
  74};
  75
  76static const u16 ilk_csc_coeff_limited_range[9] = {
  77        ILK_CSC_COEFF_LIMITED_RANGE, 0, 0,
  78        0, ILK_CSC_COEFF_LIMITED_RANGE, 0,
  79        0, 0, ILK_CSC_COEFF_LIMITED_RANGE,
  80};
  81
  82/*
  83 * These values are direct register values specified in the Bspec,
  84 * for RGB->YUV conversion matrix (colorspace BT709)
  85 */
  86static const u16 ilk_csc_coeff_rgb_to_ycbcr[9] = {
  87        0x1e08, 0x9cc0, 0xb528,
  88        0x2ba8, 0x09d8, 0x37e8,
  89        0xbce8, 0x9ad8, 0x1e08,
  90};
  91
  92/* Post offset values for RGB->YCBCR conversion */
  93static const u16 ilk_csc_postoff_rgb_to_ycbcr[3] = {
  94        0x0800, 0x0100, 0x0800,
  95};
  96
  97static bool lut_is_legacy(const struct drm_property_blob *lut)
  98{
  99        return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
 100}
 101
 102static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
 103{
 104        return !crtc_state->base.degamma_lut &&
 105                !crtc_state->base.ctm &&
 106                crtc_state->base.gamma_lut &&
 107                lut_is_legacy(crtc_state->base.gamma_lut);
 108}
 109
 110/*
 111 * When using limited range, multiply the matrix given by userspace by
 112 * the matrix that we would use for the limited range.
 113 */
 114static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
 115{
 116        int i;
 117
 118        for (i = 0; i < 9; i++) {
 119                u64 user_coeff = input[i];
 120                u32 limited_coeff = CTM_COEFF_LIMITED_RANGE;
 121                u32 abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), 0,
 122                                          CTM_COEFF_4_0 - 1) >> 2;
 123
 124                /*
 125                 * By scaling every co-efficient with limited range (16-235)
 126                 * vs full range (0-255) the final o/p will be scaled down to
 127                 * fit in the limited range supported by the panel.
 128                 */
 129                result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
 130                result[i] |= user_coeff & CTM_COEFF_SIGN;
 131        }
 132
 133        return result;
 134}
 135
 136static void ilk_update_pipe_csc(struct intel_crtc *crtc,
 137                                const u16 preoff[3],
 138                                const u16 coeff[9],
 139                                const u16 postoff[3])
 140{
 141        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 142        enum pipe pipe = crtc->pipe;
 143
 144        I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), preoff[0]);
 145        I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), preoff[1]);
 146        I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), preoff[2]);
 147
 148        I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]);
 149        I915_WRITE(PIPE_CSC_COEFF_BY(pipe), coeff[2] << 16);
 150
 151        I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]);
 152        I915_WRITE(PIPE_CSC_COEFF_BU(pipe), coeff[5] << 16);
 153
 154        I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]);
 155        I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff[8] << 16);
 156
 157        if (INTEL_GEN(dev_priv) >= 7) {
 158                I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff[0]);
 159                I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff[1]);
 160                I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff[2]);
 161        }
 162}
 163
 164static void icl_update_output_csc(struct intel_crtc *crtc,
 165                                  const u16 preoff[3],
 166                                  const u16 coeff[9],
 167                                  const u16 postoff[3])
 168{
 169        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 170        enum pipe pipe = crtc->pipe;
 171
 172        I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_HI(pipe), preoff[0]);
 173        I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_ME(pipe), preoff[1]);
 174        I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_LO(pipe), preoff[2]);
 175
 176        I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]);
 177        I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BY(pipe), coeff[2] << 16);
 178
 179        I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]);
 180        I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BU(pipe), coeff[5] << 16);
 181
 182        I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]);
 183        I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BV(pipe), coeff[8] << 16);
 184
 185        I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), postoff[0]);
 186        I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), postoff[1]);
 187        I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), postoff[2]);
 188}
 189
 190static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
 191{
 192        struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
 193
 194        /*
 195         * FIXME if there's a gamma LUT after the CSC, we should
 196         * do the range compression using the gamma LUT instead.
 197         */
 198        return crtc_state->limited_color_range &&
 199                (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
 200                 IS_GEN_RANGE(dev_priv, 9, 10));
 201}
 202
 203static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
 204                                u16 coeffs[9])
 205{
 206        const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
 207        const u64 *input;
 208        u64 temp[9];
 209        int i;
 210
 211        if (ilk_csc_limited_range(crtc_state))
 212                input = ctm_mult_by_limited(temp, ctm->matrix);
 213        else
 214                input = ctm->matrix;
 215
 216        /*
 217         * Convert fixed point S31.32 input to format supported by the
 218         * hardware.
 219         */
 220        for (i = 0; i < 9; i++) {
 221                u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
 222
 223                /*
 224                 * Clamp input value to min/max supported by
 225                 * hardware.
 226                 */
 227                abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
 228
 229                coeffs[i] = 0;
 230
 231                /* sign bit */
 232                if (CTM_COEFF_NEGATIVE(input[i]))
 233                        coeffs[i] |= 1 << 15;
 234
 235                if (abs_coeff < CTM_COEFF_0_125)
 236                        coeffs[i] |= (3 << 12) |
 237                                ILK_CSC_COEFF_FP(abs_coeff, 12);
 238                else if (abs_coeff < CTM_COEFF_0_25)
 239                        coeffs[i] |= (2 << 12) |
 240                                ILK_CSC_COEFF_FP(abs_coeff, 11);
 241                else if (abs_coeff < CTM_COEFF_0_5)
 242                        coeffs[i] |= (1 << 12) |
 243                                ILK_CSC_COEFF_FP(abs_coeff, 10);
 244                else if (abs_coeff < CTM_COEFF_1_0)
 245                        coeffs[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9);
 246                else if (abs_coeff < CTM_COEFF_2_0)
 247                        coeffs[i] |= (7 << 12) |
 248                                ILK_CSC_COEFF_FP(abs_coeff, 8);
 249                else
 250                        coeffs[i] |= (6 << 12) |
 251                                ILK_CSC_COEFF_FP(abs_coeff, 7);
 252        }
 253}
 254
 255static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
 256{
 257        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 258        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 259        bool limited_color_range = ilk_csc_limited_range(crtc_state);
 260
 261        if (crtc_state->base.ctm) {
 262                u16 coeff[9];
 263
 264                ilk_csc_convert_ctm(crtc_state, coeff);
 265                ilk_update_pipe_csc(crtc, ilk_csc_off_zero, coeff,
 266                                    limited_color_range ?
 267                                    ilk_csc_postoff_limited_range :
 268                                    ilk_csc_off_zero);
 269        } else if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
 270                ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
 271                                    ilk_csc_coeff_rgb_to_ycbcr,
 272                                    ilk_csc_postoff_rgb_to_ycbcr);
 273        } else if (limited_color_range) {
 274                ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
 275                                    ilk_csc_coeff_limited_range,
 276                                    ilk_csc_postoff_limited_range);
 277        } else if (crtc_state->csc_enable) {
 278                /*
 279                 * On GLK+ both pipe CSC and degamma LUT are controlled
 280                 * by csc_enable. Hence for the cases where the degama
 281                 * LUT is needed but CSC is not we need to load an
 282                 * identity matrix.
 283                 */
 284                WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_GEMINILAKE(dev_priv));
 285
 286                ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
 287                                    ilk_csc_coeff_identity,
 288                                    ilk_csc_off_zero);
 289        }
 290
 291        I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
 292}
 293
 294static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
 295{
 296        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 297        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 298
 299        if (crtc_state->base.ctm) {
 300                u16 coeff[9];
 301
 302                ilk_csc_convert_ctm(crtc_state, coeff);
 303                ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
 304                                    coeff, ilk_csc_off_zero);
 305        }
 306
 307        if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
 308                icl_update_output_csc(crtc, ilk_csc_off_zero,
 309                                      ilk_csc_coeff_rgb_to_ycbcr,
 310                                      ilk_csc_postoff_rgb_to_ycbcr);
 311        } else if (crtc_state->limited_color_range) {
 312                icl_update_output_csc(crtc, ilk_csc_off_zero,
 313                                      ilk_csc_coeff_limited_range,
 314                                      ilk_csc_postoff_limited_range);
 315        }
 316
 317        I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
 318}
 319
 320/*
 321 * Set up the pipe CSC unit on CherryView.
 322 */
 323static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state)
 324{
 325        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 326        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 327        enum pipe pipe = crtc->pipe;
 328
 329        if (crtc_state->base.ctm) {
 330                const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
 331                u16 coeffs[9] = {};
 332                int i;
 333
 334                for (i = 0; i < ARRAY_SIZE(coeffs); i++) {
 335                        u64 abs_coeff =
 336                                ((1ULL << 63) - 1) & ctm->matrix[i];
 337
 338                        /* Round coefficient. */
 339                        abs_coeff += 1 << (32 - 13);
 340                        /* Clamp to hardware limits. */
 341                        abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_8_0 - 1);
 342
 343                        /* Write coefficients in S3.12 format. */
 344                        if (ctm->matrix[i] & (1ULL << 63))
 345                                coeffs[i] = 1 << 15;
 346                        coeffs[i] |= ((abs_coeff >> 32) & 7) << 12;
 347                        coeffs[i] |= (abs_coeff >> 20) & 0xfff;
 348                }
 349
 350                I915_WRITE(CGM_PIPE_CSC_COEFF01(pipe),
 351                           coeffs[1] << 16 | coeffs[0]);
 352                I915_WRITE(CGM_PIPE_CSC_COEFF23(pipe),
 353                           coeffs[3] << 16 | coeffs[2]);
 354                I915_WRITE(CGM_PIPE_CSC_COEFF45(pipe),
 355                           coeffs[5] << 16 | coeffs[4]);
 356                I915_WRITE(CGM_PIPE_CSC_COEFF67(pipe),
 357                           coeffs[7] << 16 | coeffs[6]);
 358                I915_WRITE(CGM_PIPE_CSC_COEFF8(pipe), coeffs[8]);
 359        }
 360
 361        I915_WRITE(CGM_PIPE_MODE(pipe), crtc_state->cgm_mode);
 362}
 363
 364/* i965+ "10.6" bit interpolated format "even DW" (low 8 bits) */
 365static u32 i965_lut_10p6_ldw(const struct drm_color_lut *color)
 366{
 367        return (color->red & 0xff) << 16 |
 368                (color->green & 0xff) << 8 |
 369                (color->blue & 0xff);
 370}
 371
 372/* i965+ "10.6" interpolated format "odd DW" (high 8 bits) */
 373static u32 i965_lut_10p6_udw(const struct drm_color_lut *color)
 374{
 375        return (color->red >> 8) << 16 |
 376                (color->green >> 8) << 8 |
 377                (color->blue >> 8);
 378}
 379
 380static u32 ilk_lut_10(const struct drm_color_lut *color)
 381{
 382        return drm_color_lut_extract(color->red, 10) << 20 |
 383                drm_color_lut_extract(color->green, 10) << 10 |
 384                drm_color_lut_extract(color->blue, 10);
 385}
 386
 387/* Loads the legacy palette/gamma unit for the CRTC. */
 388static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
 389                                    const struct drm_property_blob *blob)
 390{
 391        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 392        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 393        enum pipe pipe = crtc->pipe;
 394        int i;
 395
 396        if (HAS_GMCH(dev_priv)) {
 397                if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
 398                        assert_dsi_pll_enabled(dev_priv);
 399                else
 400                        assert_pll_enabled(dev_priv, pipe);
 401        }
 402
 403        if (blob) {
 404                const struct drm_color_lut *lut = blob->data;
 405
 406                for (i = 0; i < 256; i++) {
 407                        u32 word =
 408                                (drm_color_lut_extract(lut[i].red, 8) << 16) |
 409                                (drm_color_lut_extract(lut[i].green, 8) << 8) |
 410                                drm_color_lut_extract(lut[i].blue, 8);
 411
 412                        if (HAS_GMCH(dev_priv))
 413                                I915_WRITE(PALETTE(pipe, i), word);
 414                        else
 415                                I915_WRITE(LGC_PALETTE(pipe, i), word);
 416                }
 417        }
 418}
 419
 420static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
 421{
 422        i9xx_load_luts_internal(crtc_state, crtc_state->base.gamma_lut);
 423}
 424
 425static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
 426{
 427        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 428        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 429        enum pipe pipe = crtc->pipe;
 430        u32 val;
 431
 432        val = I915_READ(PIPECONF(pipe));
 433        val &= ~PIPECONF_GAMMA_MODE_MASK_I9XX;
 434        val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
 435        I915_WRITE(PIPECONF(pipe), val);
 436}
 437
 438static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
 439{
 440        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 441        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 442        enum pipe pipe = crtc->pipe;
 443        u32 val;
 444
 445        val = I915_READ(PIPECONF(pipe));
 446        val &= ~PIPECONF_GAMMA_MODE_MASK_ILK;
 447        val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
 448        I915_WRITE(PIPECONF(pipe), val);
 449
 450        ilk_load_csc_matrix(crtc_state);
 451}
 452
 453static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
 454{
 455        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 456        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 457
 458        I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
 459
 460        ilk_load_csc_matrix(crtc_state);
 461}
 462
 463static void skl_color_commit(const struct intel_crtc_state *crtc_state)
 464{
 465        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 466        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 467        enum pipe pipe = crtc->pipe;
 468        u32 val = 0;
 469
 470        /*
 471         * We don't (yet) allow userspace to control the pipe background color,
 472         * so force it to black, but apply pipe gamma and CSC appropriately
 473         * so that its handling will match how we program our planes.
 474         */
 475        if (crtc_state->gamma_enable)
 476                val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
 477        if (crtc_state->csc_enable)
 478                val |= SKL_BOTTOM_COLOR_CSC_ENABLE;
 479        I915_WRITE(SKL_BOTTOM_COLOR(pipe), val);
 480
 481        I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
 482
 483        if (INTEL_GEN(dev_priv) >= 11)
 484                icl_load_csc_matrix(crtc_state);
 485        else
 486                ilk_load_csc_matrix(crtc_state);
 487}
 488
 489static void i965_load_lut_10p6(struct intel_crtc *crtc,
 490                               const struct drm_property_blob *blob)
 491{
 492        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 493        const struct drm_color_lut *lut = blob->data;
 494        int i, lut_size = drm_color_lut_size(blob);
 495        enum pipe pipe = crtc->pipe;
 496
 497        for (i = 0; i < lut_size - 1; i++) {
 498                I915_WRITE(PALETTE(pipe, 2 * i + 0),
 499                           i965_lut_10p6_ldw(&lut[i]));
 500                I915_WRITE(PALETTE(pipe, 2 * i + 1),
 501                           i965_lut_10p6_udw(&lut[i]));
 502        }
 503
 504        I915_WRITE(PIPEGCMAX(pipe, 0), lut[i].red);
 505        I915_WRITE(PIPEGCMAX(pipe, 1), lut[i].green);
 506        I915_WRITE(PIPEGCMAX(pipe, 2), lut[i].blue);
 507}
 508
 509static void i965_load_luts(const struct intel_crtc_state *crtc_state)
 510{
 511        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 512        const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
 513
 514        if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
 515                i9xx_load_luts(crtc_state);
 516        else
 517                i965_load_lut_10p6(crtc, gamma_lut);
 518}
 519
 520static void ilk_load_lut_10(struct intel_crtc *crtc,
 521                            const struct drm_property_blob *blob)
 522{
 523        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 524        const struct drm_color_lut *lut = blob->data;
 525        int i, lut_size = drm_color_lut_size(blob);
 526        enum pipe pipe = crtc->pipe;
 527
 528        for (i = 0; i < lut_size; i++)
 529                I915_WRITE(PREC_PALETTE(pipe, i), ilk_lut_10(&lut[i]));
 530}
 531
 532static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
 533{
 534        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 535        const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
 536
 537        if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
 538                i9xx_load_luts(crtc_state);
 539        else
 540                ilk_load_lut_10(crtc, gamma_lut);
 541}
 542
 543static int ivb_lut_10_size(u32 prec_index)
 544{
 545        if (prec_index & PAL_PREC_SPLIT_MODE)
 546                return 512;
 547        else
 548                return 1024;
 549}
 550
 551/*
 552 * IVB/HSW Bspec / PAL_PREC_INDEX:
 553 * "Restriction : Index auto increment mode is not
 554 *  supported and must not be enabled."
 555 */
 556static void ivb_load_lut_10(struct intel_crtc *crtc,
 557                            const struct drm_property_blob *blob,
 558                            u32 prec_index)
 559{
 560        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 561        int hw_lut_size = ivb_lut_10_size(prec_index);
 562        const struct drm_color_lut *lut = blob->data;
 563        int i, lut_size = drm_color_lut_size(blob);
 564        enum pipe pipe = crtc->pipe;
 565
 566        for (i = 0; i < hw_lut_size; i++) {
 567                /* We discard half the user entries in split gamma mode */
 568                const struct drm_color_lut *entry =
 569                        &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
 570
 571                I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
 572                I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
 573        }
 574
 575        /*
 576         * Reset the index, otherwise it prevents the legacy palette to be
 577         * written properly.
 578         */
 579        I915_WRITE(PREC_PAL_INDEX(pipe), 0);
 580}
 581
 582/* On BDW+ the index auto increment mode actually works */
 583static void bdw_load_lut_10(struct intel_crtc *crtc,
 584                            const struct drm_property_blob *blob,
 585                            u32 prec_index)
 586{
 587        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 588        int hw_lut_size = ivb_lut_10_size(prec_index);
 589        const struct drm_color_lut *lut = blob->data;
 590        int i, lut_size = drm_color_lut_size(blob);
 591        enum pipe pipe = crtc->pipe;
 592
 593        I915_WRITE(PREC_PAL_INDEX(pipe), prec_index |
 594                   PAL_PREC_AUTO_INCREMENT);
 595
 596        for (i = 0; i < hw_lut_size; i++) {
 597                /* We discard half the user entries in split gamma mode */
 598                const struct drm_color_lut *entry =
 599                        &lut[i * (lut_size - 1) / (hw_lut_size - 1)];
 600
 601                I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
 602        }
 603
 604        /*
 605         * Reset the index, otherwise it prevents the legacy palette to be
 606         * written properly.
 607         */
 608        I915_WRITE(PREC_PAL_INDEX(pipe), 0);
 609}
 610
 611static void ivb_load_lut_ext_max(struct intel_crtc *crtc)
 612{
 613        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 614        enum pipe pipe = crtc->pipe;
 615
 616        /* Program the max register to clamp values > 1.0. */
 617        I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16);
 618        I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16);
 619        I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16);
 620
 621        /*
 622         * Program the gc max 2 register to clamp values > 1.0.
 623         * ToDo: Extend the ABI to be able to program values
 624         * from 3.0 to 7.0
 625         */
 626        if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
 627                I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 0), 1 << 16);
 628                I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 1), 1 << 16);
 629                I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 2), 1 << 16);
 630        }
 631}
 632
 633static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
 634{
 635        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 636        const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
 637        const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
 638
 639        if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
 640                i9xx_load_luts(crtc_state);
 641        } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
 642                ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
 643                                PAL_PREC_INDEX_VALUE(0));
 644                ivb_load_lut_ext_max(crtc);
 645                ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
 646                                PAL_PREC_INDEX_VALUE(512));
 647        } else {
 648                const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
 649
 650                ivb_load_lut_10(crtc, blob,
 651                                PAL_PREC_INDEX_VALUE(0));
 652                ivb_load_lut_ext_max(crtc);
 653        }
 654}
 655
 656static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
 657{
 658        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 659        const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
 660        const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
 661
 662        if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
 663                i9xx_load_luts(crtc_state);
 664        } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
 665                bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
 666                                PAL_PREC_INDEX_VALUE(0));
 667                ivb_load_lut_ext_max(crtc);
 668                bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
 669                                PAL_PREC_INDEX_VALUE(512));
 670        } else {
 671                const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
 672
 673                bdw_load_lut_10(crtc, blob,
 674                                PAL_PREC_INDEX_VALUE(0));
 675                ivb_load_lut_ext_max(crtc);
 676        }
 677}
 678
 679static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
 680{
 681        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 682        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 683        enum pipe pipe = crtc->pipe;
 684        const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
 685        const struct drm_color_lut *lut = crtc_state->base.degamma_lut->data;
 686        u32 i;
 687
 688        /*
 689         * When setting the auto-increment bit, the hardware seems to
 690         * ignore the index bits, so we need to reset it to index 0
 691         * separately.
 692         */
 693        I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
 694        I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
 695
 696        for (i = 0; i < lut_size; i++) {
 697                /*
 698                 * First 33 entries represent range from 0 to 1.0
 699                 * 34th and 35th entry will represent extended range
 700                 * inputs 3.0 and 7.0 respectively, currently clamped
 701                 * at 1.0. Since the precision is 16bit, the user
 702                 * value can be directly filled to register.
 703                 * The pipe degamma table in GLK+ onwards doesn't
 704                 * support different values per channel, so this just
 705                 * programs green value which will be equal to Red and
 706                 * Blue into the lut registers.
 707                 * ToDo: Extend to max 7.0. Enable 32 bit input value
 708                 * as compared to just 16 to achieve this.
 709                 */
 710                I915_WRITE(PRE_CSC_GAMC_DATA(pipe), lut[i].green);
 711        }
 712
 713        /* Clamp values > 1.0. */
 714        while (i++ < 35)
 715                I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
 716}
 717
 718static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
 719{
 720        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 721        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 722        enum pipe pipe = crtc->pipe;
 723        const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
 724        u32 i;
 725
 726        /*
 727         * When setting the auto-increment bit, the hardware seems to
 728         * ignore the index bits, so we need to reset it to index 0
 729         * separately.
 730         */
 731        I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
 732        I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
 733
 734        for (i = 0; i < lut_size; i++) {
 735                u32 v = (i << 16) / (lut_size - 1);
 736
 737                I915_WRITE(PRE_CSC_GAMC_DATA(pipe), v);
 738        }
 739
 740        /* Clamp values > 1.0. */
 741        while (i++ < 35)
 742                I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
 743}
 744
 745static void glk_load_luts(const struct intel_crtc_state *crtc_state)
 746{
 747        const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
 748        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 749
 750        /*
 751         * On GLK+ both pipe CSC and degamma LUT are controlled
 752         * by csc_enable. Hence for the cases where the CSC is
 753         * needed but degamma LUT is not we need to load a
 754         * linear degamma LUT. In fact we'll just always load
 755         * the degama LUT so that we don't have to reload
 756         * it every time the pipe CSC is being enabled.
 757         */
 758        if (crtc_state->base.degamma_lut)
 759                glk_load_degamma_lut(crtc_state);
 760        else
 761                glk_load_degamma_lut_linear(crtc_state);
 762
 763        if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
 764                i9xx_load_luts(crtc_state);
 765        } else {
 766                bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
 767                ivb_load_lut_ext_max(crtc);
 768        }
 769}
 770
 771/* ilk+ "12.4" interpolated format (high 10 bits) */
 772static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color)
 773{
 774        return (color->red >> 6) << 20 | (color->green >> 6) << 10 |
 775                (color->blue >> 6);
 776}
 777
 778/* ilk+ "12.4" interpolated format (low 6 bits) */
 779static u32 ilk_lut_12p4_ldw(const struct drm_color_lut *color)
 780{
 781        return (color->red & 0x3f) << 24 | (color->green & 0x3f) << 14 |
 782                (color->blue & 0x3f) << 4;
 783}
 784
 785static void
 786icl_load_gcmax(const struct intel_crtc_state *crtc_state,
 787               const struct drm_color_lut *color)
 788{
 789        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 790        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 791        enum pipe pipe = crtc->pipe;
 792
 793        /* Fixme: LUT entries are 16 bit only, so we can prog 0xFFFF max */
 794        I915_WRITE(PREC_PAL_GC_MAX(pipe, 0), color->red);
 795        I915_WRITE(PREC_PAL_GC_MAX(pipe, 1), color->green);
 796        I915_WRITE(PREC_PAL_GC_MAX(pipe, 2), color->blue);
 797}
 798
 799static void
 800icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
 801{
 802        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 803        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 804        const struct drm_property_blob *blob = crtc_state->base.gamma_lut;
 805        const struct drm_color_lut *lut = blob->data;
 806        enum pipe pipe = crtc->pipe;
 807        u32 i;
 808
 809        /*
 810         * Every entry in the multi-segment LUT is corresponding to a superfine
 811         * segment step which is 1/(8 * 128 * 256).
 812         *
 813         * Superfine segment has 9 entries, corresponding to values
 814         * 0, 1/(8 * 128 * 256), 2/(8 * 128 * 256) .... 8/(8 * 128 * 256).
 815         */
 816        I915_WRITE(PREC_PAL_MULTI_SEG_INDEX(pipe), PAL_PREC_AUTO_INCREMENT);
 817
 818        for (i = 0; i < 9; i++) {
 819                const struct drm_color_lut *entry = &lut[i];
 820
 821                I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe),
 822                           ilk_lut_12p4_ldw(entry));
 823                I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe),
 824                           ilk_lut_12p4_udw(entry));
 825        }
 826}
 827
 828static void
 829icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
 830{
 831        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 832        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 833        const struct drm_property_blob *blob = crtc_state->base.gamma_lut;
 834        const struct drm_color_lut *lut = blob->data;
 835        const struct drm_color_lut *entry;
 836        enum pipe pipe = crtc->pipe;
 837        u32 i;
 838
 839        /*
 840         *
 841         * Program Fine segment (let's call it seg2)...
 842         *
 843         * Fine segment's step is 1/(128 * 256) ie 1/(128 * 256),  2/(128*256)
 844         * ... 256/(128*256). So in order to program fine segment of LUT we
 845         * need to pick every 8'th entry in LUT, and program 256 indexes.
 846         *
 847         * PAL_PREC_INDEX[0] and PAL_PREC_INDEX[1] map to seg2[1],
 848         * with seg2[0] being unused by the hardware.
 849         */
 850        I915_WRITE(PREC_PAL_INDEX(pipe), PAL_PREC_AUTO_INCREMENT);
 851        for (i = 1; i < 257; i++) {
 852                entry = &lut[i * 8];
 853                I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_12p4_ldw(entry));
 854                I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_12p4_udw(entry));
 855        }
 856
 857        /*
 858         * Program Coarse segment (let's call it seg3)...
 859         *
 860         * Coarse segment's starts from index 0 and it's step is 1/256 ie 0,
 861         * 1/256, 2/256 ...256/256. As per the description of each entry in LUT
 862         * above, we need to pick every (8 * 128)th entry in LUT, and
 863         * program 256 of those.
 864         *
 865         * Spec is not very clear about if entries seg3[0] and seg3[1] are
 866         * being used or not, but we still need to program these to advance
 867         * the index.
 868         */
 869        for (i = 0; i < 256; i++) {
 870                entry = &lut[i * 8 * 128];
 871                I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_12p4_ldw(entry));
 872                I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_12p4_udw(entry));
 873        }
 874
 875        /* The last entry in the LUT is to be programmed in GCMAX */
 876        entry = &lut[256 * 8 * 128];
 877        icl_load_gcmax(crtc_state, entry);
 878        ivb_load_lut_ext_max(crtc);
 879}
 880
 881static void icl_load_luts(const struct intel_crtc_state *crtc_state)
 882{
 883        const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
 884        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 885
 886        if (crtc_state->base.degamma_lut)
 887                glk_load_degamma_lut(crtc_state);
 888
 889        switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
 890        case GAMMA_MODE_MODE_8BIT:
 891                i9xx_load_luts(crtc_state);
 892                break;
 893
 894        case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
 895                icl_program_gamma_superfine_segment(crtc_state);
 896                icl_program_gamma_multi_segment(crtc_state);
 897                break;
 898
 899        default:
 900                bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
 901                ivb_load_lut_ext_max(crtc);
 902        }
 903}
 904
 905static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
 906{
 907        return drm_color_lut_extract(color->green, 14) << 16 |
 908                drm_color_lut_extract(color->blue, 14);
 909}
 910
 911static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
 912{
 913        return drm_color_lut_extract(color->red, 14);
 914}
 915
 916static void chv_load_cgm_degamma(struct intel_crtc *crtc,
 917                                 const struct drm_property_blob *blob)
 918{
 919        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 920        const struct drm_color_lut *lut = blob->data;
 921        int i, lut_size = drm_color_lut_size(blob);
 922        enum pipe pipe = crtc->pipe;
 923
 924        for (i = 0; i < lut_size; i++) {
 925                I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 0),
 926                           chv_cgm_degamma_ldw(&lut[i]));
 927                I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 1),
 928                           chv_cgm_degamma_udw(&lut[i]));
 929        }
 930}
 931
 932static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
 933{
 934        return drm_color_lut_extract(color->green, 10) << 16 |
 935                drm_color_lut_extract(color->blue, 10);
 936}
 937
 938static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
 939{
 940        return drm_color_lut_extract(color->red, 10);
 941}
 942
 943static void chv_load_cgm_gamma(struct intel_crtc *crtc,
 944                               const struct drm_property_blob *blob)
 945{
 946        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 947        const struct drm_color_lut *lut = blob->data;
 948        int i, lut_size = drm_color_lut_size(blob);
 949        enum pipe pipe = crtc->pipe;
 950
 951        for (i = 0; i < lut_size; i++) {
 952                I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 0),
 953                           chv_cgm_gamma_ldw(&lut[i]));
 954                I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 1),
 955                           chv_cgm_gamma_udw(&lut[i]));
 956        }
 957}
 958
 959static void chv_load_luts(const struct intel_crtc_state *crtc_state)
 960{
 961        struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 962        const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
 963        const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
 964
 965        cherryview_load_csc_matrix(crtc_state);
 966
 967        if (crtc_state_is_legacy_gamma(crtc_state)) {
 968                i9xx_load_luts(crtc_state);
 969                return;
 970        }
 971
 972        if (degamma_lut)
 973                chv_load_cgm_degamma(crtc, degamma_lut);
 974
 975        if (gamma_lut)
 976                chv_load_cgm_gamma(crtc, gamma_lut);
 977}
 978
 979void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
 980{
 981        struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
 982
 983        dev_priv->display.load_luts(crtc_state);
 984}
 985
 986void intel_color_commit(const struct intel_crtc_state *crtc_state)
 987{
 988        struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
 989
 990        dev_priv->display.color_commit(crtc_state);
 991}
 992
 993int intel_color_check(struct intel_crtc_state *crtc_state)
 994{
 995        struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
 996
 997        return dev_priv->display.color_check(crtc_state);
 998}
 999
1000void intel_color_get_config(struct intel_crtc_state *crtc_state)
1001{
1002        struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
1003
1004        if (dev_priv->display.read_luts)
1005                dev_priv->display.read_luts(crtc_state);
1006}
1007
1008static bool need_plane_update(struct intel_plane *plane,
1009                              const struct intel_crtc_state *crtc_state)
1010{
1011        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1012
1013        /*
1014         * On pre-SKL the pipe gamma enable and pipe csc enable for
1015         * the pipe bottom color are configured via the primary plane.
1016         * We have to reconfigure that even if the plane is inactive.
1017         */
1018        return crtc_state->active_planes & BIT(plane->id) ||
1019                (INTEL_GEN(dev_priv) < 9 &&
1020                 plane->id == PLANE_PRIMARY);
1021}
1022
1023static int
1024intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
1025{
1026        struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
1027        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1028        struct intel_atomic_state *state =
1029                to_intel_atomic_state(new_crtc_state->base.state);
1030        const struct intel_crtc_state *old_crtc_state =
1031                intel_atomic_get_old_crtc_state(state, crtc);
1032        struct intel_plane *plane;
1033
1034        if (!new_crtc_state->base.active ||
1035            drm_atomic_crtc_needs_modeset(&new_crtc_state->base))
1036                return 0;
1037
1038        if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
1039            new_crtc_state->csc_enable == old_crtc_state->csc_enable)
1040                return 0;
1041
1042        for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
1043                struct intel_plane_state *plane_state;
1044
1045                if (!need_plane_update(plane, new_crtc_state))
1046                        continue;
1047
1048                plane_state = intel_atomic_get_plane_state(state, plane);
1049                if (IS_ERR(plane_state))
1050                        return PTR_ERR(plane_state);
1051
1052                new_crtc_state->update_planes |= BIT(plane->id);
1053        }
1054
1055        return 0;
1056}
1057
1058static int check_lut_size(const struct drm_property_blob *lut, int expected)
1059{
1060        int len;
1061
1062        if (!lut)
1063                return 0;
1064
1065        len = drm_color_lut_size(lut);
1066        if (len != expected) {
1067                DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
1068                              len, expected);
1069                return -EINVAL;
1070        }
1071
1072        return 0;
1073}
1074
1075static int check_luts(const struct intel_crtc_state *crtc_state)
1076{
1077        struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
1078        const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
1079        const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
1080        int gamma_length, degamma_length;
1081        u32 gamma_tests, degamma_tests;
1082
1083        /* Always allow legacy gamma LUT with no further checking. */
1084        if (crtc_state_is_legacy_gamma(crtc_state))
1085                return 0;
1086
1087        /* C8 relies on its palette being stored in the legacy LUT */
1088        if (crtc_state->c8_planes) {
1089                DRM_DEBUG_KMS("C8 pixelformat requires the legacy LUT\n");
1090                return -EINVAL;
1091        }
1092
1093        degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
1094        gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
1095        degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
1096        gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
1097
1098        if (check_lut_size(degamma_lut, degamma_length) ||
1099            check_lut_size(gamma_lut, gamma_length))
1100                return -EINVAL;
1101
1102        if (drm_color_lut_check(degamma_lut, degamma_tests) ||
1103            drm_color_lut_check(gamma_lut, gamma_tests))
1104                return -EINVAL;
1105
1106        return 0;
1107}
1108
1109static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
1110{
1111        if (!crtc_state->gamma_enable ||
1112            crtc_state_is_legacy_gamma(crtc_state))
1113                return GAMMA_MODE_MODE_8BIT;
1114        else
1115                return GAMMA_MODE_MODE_10BIT; /* i965+ only */
1116}
1117
1118static int i9xx_color_check(struct intel_crtc_state *crtc_state)
1119{
1120        int ret;
1121
1122        ret = check_luts(crtc_state);
1123        if (ret)
1124                return ret;
1125
1126        crtc_state->gamma_enable =
1127                crtc_state->base.gamma_lut &&
1128                !crtc_state->c8_planes;
1129
1130        crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
1131
1132        ret = intel_color_add_affected_planes(crtc_state);
1133        if (ret)
1134                return ret;
1135
1136        return 0;
1137}
1138
1139static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
1140{
1141        u32 cgm_mode = 0;
1142
1143        if (crtc_state_is_legacy_gamma(crtc_state))
1144                return 0;
1145
1146        if (crtc_state->base.degamma_lut)
1147                cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
1148        if (crtc_state->base.ctm)
1149                cgm_mode |= CGM_PIPE_MODE_CSC;
1150        if (crtc_state->base.gamma_lut)
1151                cgm_mode |= CGM_PIPE_MODE_GAMMA;
1152
1153        return cgm_mode;
1154}
1155
1156/*
1157 * CHV color pipeline:
1158 * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
1159 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
1160 *
1161 * We always bypass the WGC csc and use the CGM csc
1162 * instead since it has degamma and better precision.
1163 */
1164static int chv_color_check(struct intel_crtc_state *crtc_state)
1165{
1166        int ret;
1167
1168        ret = check_luts(crtc_state);
1169        if (ret)
1170                return ret;
1171
1172        /*
1173         * Pipe gamma will be used only for the legacy LUT.
1174         * Otherwise we bypass it and use the CGM gamma instead.
1175         */
1176        crtc_state->gamma_enable =
1177                crtc_state_is_legacy_gamma(crtc_state) &&
1178                !crtc_state->c8_planes;
1179
1180        crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
1181
1182        crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
1183
1184        ret = intel_color_add_affected_planes(crtc_state);
1185        if (ret)
1186                return ret;
1187
1188        return 0;
1189}
1190
1191static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
1192{
1193        if (!crtc_state->gamma_enable ||
1194            crtc_state_is_legacy_gamma(crtc_state))
1195                return GAMMA_MODE_MODE_8BIT;
1196        else
1197                return GAMMA_MODE_MODE_10BIT;
1198}
1199
1200static int ilk_color_check(struct intel_crtc_state *crtc_state)
1201{
1202        int ret;
1203
1204        ret = check_luts(crtc_state);
1205        if (ret)
1206                return ret;
1207
1208        crtc_state->gamma_enable =
1209                crtc_state->base.gamma_lut &&
1210                !crtc_state->c8_planes;
1211
1212        /*
1213         * We don't expose the ctm on ilk/snb currently,
1214         * nor do we enable YCbCr output. Also RGB limited
1215         * range output is handled by the hw automagically.
1216         */
1217        crtc_state->csc_enable = false;
1218
1219        crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
1220
1221        crtc_state->csc_mode = 0;
1222
1223        ret = intel_color_add_affected_planes(crtc_state);
1224        if (ret)
1225                return ret;
1226
1227        return 0;
1228}
1229
1230static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
1231{
1232        if (!crtc_state->gamma_enable ||
1233            crtc_state_is_legacy_gamma(crtc_state))
1234                return GAMMA_MODE_MODE_8BIT;
1235        else if (crtc_state->base.gamma_lut &&
1236                 crtc_state->base.degamma_lut)
1237                return GAMMA_MODE_MODE_SPLIT;
1238        else
1239                return GAMMA_MODE_MODE_10BIT;
1240}
1241
1242static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
1243{
1244        bool limited_color_range = ilk_csc_limited_range(crtc_state);
1245
1246        /*
1247         * CSC comes after the LUT in degamma, RGB->YCbCr,
1248         * and RGB full->limited range mode.
1249         */
1250        if (crtc_state->base.degamma_lut ||
1251            crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1252            limited_color_range)
1253                return 0;
1254
1255        return CSC_POSITION_BEFORE_GAMMA;
1256}
1257
1258static int ivb_color_check(struct intel_crtc_state *crtc_state)
1259{
1260        bool limited_color_range = ilk_csc_limited_range(crtc_state);
1261        int ret;
1262
1263        ret = check_luts(crtc_state);
1264        if (ret)
1265                return ret;
1266
1267        crtc_state->gamma_enable =
1268                (crtc_state->base.gamma_lut ||
1269                 crtc_state->base.degamma_lut) &&
1270                !crtc_state->c8_planes;
1271
1272        crtc_state->csc_enable =
1273                crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1274                crtc_state->base.ctm || limited_color_range;
1275
1276        crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
1277
1278        crtc_state->csc_mode = ivb_csc_mode(crtc_state);
1279
1280        ret = intel_color_add_affected_planes(crtc_state);
1281        if (ret)
1282                return ret;
1283
1284        return 0;
1285}
1286
1287static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
1288{
1289        if (!crtc_state->gamma_enable ||
1290            crtc_state_is_legacy_gamma(crtc_state))
1291                return GAMMA_MODE_MODE_8BIT;
1292        else
1293                return GAMMA_MODE_MODE_10BIT;
1294}
1295
1296static int glk_color_check(struct intel_crtc_state *crtc_state)
1297{
1298        int ret;
1299
1300        ret = check_luts(crtc_state);
1301        if (ret)
1302                return ret;
1303
1304        crtc_state->gamma_enable =
1305                crtc_state->base.gamma_lut &&
1306                !crtc_state->c8_planes;
1307
1308        /* On GLK+ degamma LUT is controlled by csc_enable */
1309        crtc_state->csc_enable =
1310                crtc_state->base.degamma_lut ||
1311                crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1312                crtc_state->base.ctm || crtc_state->limited_color_range;
1313
1314        crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
1315
1316        crtc_state->csc_mode = 0;
1317
1318        ret = intel_color_add_affected_planes(crtc_state);
1319        if (ret)
1320                return ret;
1321
1322        return 0;
1323}
1324
1325static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
1326{
1327        u32 gamma_mode = 0;
1328
1329        if (crtc_state->base.degamma_lut)
1330                gamma_mode |= PRE_CSC_GAMMA_ENABLE;
1331
1332        if (crtc_state->base.gamma_lut &&
1333            !crtc_state->c8_planes)
1334                gamma_mode |= POST_CSC_GAMMA_ENABLE;
1335
1336        if (!crtc_state->base.gamma_lut ||
1337            crtc_state_is_legacy_gamma(crtc_state))
1338                gamma_mode |= GAMMA_MODE_MODE_8BIT;
1339        else
1340                gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED;
1341
1342        return gamma_mode;
1343}
1344
1345static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
1346{
1347        u32 csc_mode = 0;
1348
1349        if (crtc_state->base.ctm)
1350                csc_mode |= ICL_CSC_ENABLE;
1351
1352        if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
1353            crtc_state->limited_color_range)
1354                csc_mode |= ICL_OUTPUT_CSC_ENABLE;
1355
1356        return csc_mode;
1357}
1358
1359static int icl_color_check(struct intel_crtc_state *crtc_state)
1360{
1361        int ret;
1362
1363        ret = check_luts(crtc_state);
1364        if (ret)
1365                return ret;
1366
1367        crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
1368
1369        crtc_state->csc_mode = icl_csc_mode(crtc_state);
1370
1371        return 0;
1372}
1373
1374void intel_color_init(struct intel_crtc *crtc)
1375{
1376        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1377        bool has_ctm = INTEL_INFO(dev_priv)->color.degamma_lut_size != 0;
1378
1379        drm_mode_crtc_set_gamma_size(&crtc->base, 256);
1380
1381        if (HAS_GMCH(dev_priv)) {
1382                if (IS_CHERRYVIEW(dev_priv)) {
1383                        dev_priv->display.color_check = chv_color_check;
1384                        dev_priv->display.color_commit = i9xx_color_commit;
1385                        dev_priv->display.load_luts = chv_load_luts;
1386                } else if (INTEL_GEN(dev_priv) >= 4) {
1387                        dev_priv->display.color_check = i9xx_color_check;
1388                        dev_priv->display.color_commit = i9xx_color_commit;
1389                        dev_priv->display.load_luts = i965_load_luts;
1390                } else {
1391                        dev_priv->display.color_check = i9xx_color_check;
1392                        dev_priv->display.color_commit = i9xx_color_commit;
1393                        dev_priv->display.load_luts = i9xx_load_luts;
1394                }
1395        } else {
1396                if (INTEL_GEN(dev_priv) >= 11)
1397                        dev_priv->display.color_check = icl_color_check;
1398                else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1399                        dev_priv->display.color_check = glk_color_check;
1400                else if (INTEL_GEN(dev_priv) >= 7)
1401                        dev_priv->display.color_check = ivb_color_check;
1402                else
1403                        dev_priv->display.color_check = ilk_color_check;
1404
1405                if (INTEL_GEN(dev_priv) >= 9)
1406                        dev_priv->display.color_commit = skl_color_commit;
1407                else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
1408                        dev_priv->display.color_commit = hsw_color_commit;
1409                else
1410                        dev_priv->display.color_commit = ilk_color_commit;
1411
1412                if (INTEL_GEN(dev_priv) >= 11)
1413                        dev_priv->display.load_luts = icl_load_luts;
1414                else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
1415                        dev_priv->display.load_luts = glk_load_luts;
1416                else if (INTEL_GEN(dev_priv) >= 8)
1417                        dev_priv->display.load_luts = bdw_load_luts;
1418                else if (INTEL_GEN(dev_priv) >= 7)
1419                        dev_priv->display.load_luts = ivb_load_luts;
1420                else
1421                        dev_priv->display.load_luts = ilk_load_luts;
1422        }
1423
1424        drm_crtc_enable_color_mgmt(&crtc->base,
1425                                   INTEL_INFO(dev_priv)->color.degamma_lut_size,
1426                                   has_ctm,
1427                                   INTEL_INFO(dev_priv)->color.gamma_lut_size);
1428}
1429