OSDN Git Service

drm/i915: Introduce crtc_state->{pre,post}_csc_lut
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 24 Oct 2022 16:15:11 +0000 (19:15 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 25 Oct 2022 22:37:45 +0000 (01:37 +0300)
Add an extra remapping step between the logical state of the LUTs
(hw.(de)gamma_lut) as specified via uapi/bigjoiner copy vs.
the actual state of the LUTs programmed into the hardware.

With this we should be finally able finish the (de)gamma
readout/state checker support for the remaining platforms
(ilk-skl) where the same hardware LUT can be positioned
either before or after the pipe CSC unit. Where we position
it depends on factors such as presence of the logical degamma
LUT, RGB vs. YCbCr output, full vs. limited RGB quantization
range.

Without the extra remapping step the state readout doesn't
really know whether the LUT read from the hardware is the
degamma or gamma LUT, and so we is unable to accurately store
it into our crtc state. With the remapping step we know
exactly where to put it given the order of the LUT vs. CSC
in the hardware state.

Only the initial hw->uapi state readout done during driver
load/resume still has the problem of not really knowing
what to do with the LUT(s). But we can just assume 1:1
mapping there and let subsequent commits fix things up.

Another benefit is that we now have a place for purely
internal LUTs, without complicating the bigjoiner uapi->hw
copy logic. This should prove useful for streamlining
glk degamma LUT handling.

Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221024161514.5340-3-ville.syrjala@linux.intel.com
drivers/gpu/drm/i915/display/intel_atomic.c
drivers/gpu/drm/i915/display/intel_color.c
drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_modeset_setup.c

index 18f0a5a..6621aa2 100644 (file)
@@ -252,6 +252,11 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
        if (crtc_state->hw.gamma_lut)
                drm_property_blob_get(crtc_state->hw.gamma_lut);
 
+       if (crtc_state->pre_csc_lut)
+               drm_property_blob_get(crtc_state->pre_csc_lut);
+       if (crtc_state->post_csc_lut)
+               drm_property_blob_get(crtc_state->post_csc_lut);
+
        crtc_state->update_pipe = false;
        crtc_state->disable_lp_wm = false;
        crtc_state->disable_cxsr = false;
@@ -274,6 +279,9 @@ static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
        drm_property_blob_put(crtc_state->hw.degamma_lut);
        drm_property_blob_put(crtc_state->hw.gamma_lut);
        drm_property_blob_put(crtc_state->hw.ctm);
+
+       drm_property_blob_put(crtc_state->pre_csc_lut);
+       drm_property_blob_put(crtc_state->post_csc_lut);
 }
 
 void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
index ff5f462..2b37e3c 100644 (file)
@@ -578,9 +578,9 @@ static void i9xx_load_lut_8(struct intel_crtc *crtc,
 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
 
-       i9xx_load_lut_8(crtc, gamma_lut);
+       i9xx_load_lut_8(crtc, post_csc_lut);
 }
 
 static void i965_load_lut_10p6(struct intel_crtc *crtc,
@@ -606,12 +606,12 @@ static void i965_load_lut_10p6(struct intel_crtc *crtc,
 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
 
        if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
-               i9xx_load_lut_8(crtc, gamma_lut);
+               i9xx_load_lut_8(crtc, post_csc_lut);
        else
-               i965_load_lut_10p6(crtc, gamma_lut);
+               i965_load_lut_10p6(crtc, post_csc_lut);
 }
 
 static void ilk_load_lut_8(struct intel_crtc *crtc,
@@ -648,9 +648,9 @@ static void ilk_load_lut_10(struct intel_crtc *crtc,
 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
-       const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
-       const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
@@ -764,19 +764,19 @@ static void ivb_load_lut_ext_max(const struct intel_crtc_state *crtc_state)
 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
-       const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
-       const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
                ilk_load_lut_8(crtc, blob);
                break;
        case GAMMA_MODE_MODE_SPLIT:
-               ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
+               ivb_load_lut_10(crtc, pre_csc_lut, PAL_PREC_SPLIT_MODE |
                                PAL_PREC_INDEX_VALUE(0));
                ivb_load_lut_ext_max(crtc_state);
-               ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
+               ivb_load_lut_10(crtc, post_csc_lut, PAL_PREC_SPLIT_MODE |
                                PAL_PREC_INDEX_VALUE(512));
                break;
        case GAMMA_MODE_MODE_10BIT:
@@ -793,19 +793,19 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
-       const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
-       const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
                ilk_load_lut_8(crtc, blob);
                break;
        case GAMMA_MODE_MODE_SPLIT:
-               bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
+               bdw_load_lut_10(crtc, pre_csc_lut, PAL_PREC_SPLIT_MODE |
                                PAL_PREC_INDEX_VALUE(0));
                ivb_load_lut_ext_max(crtc_state);
-               bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
+               bdw_load_lut_10(crtc, post_csc_lut, PAL_PREC_SPLIT_MODE |
                                PAL_PREC_INDEX_VALUE(512));
                break;
        case GAMMA_MODE_MODE_10BIT:
@@ -902,8 +902,8 @@ static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_stat
 
 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
 {
-       const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
        /*
@@ -914,17 +914,17 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state)
         * the degama LUT so that we don't have to reload
         * it every time the pipe CSC is being enabled.
         */
-       if (degamma_lut)
-               glk_load_degamma_lut(crtc_state, degamma_lut);
+       if (pre_csc_lut)
+               glk_load_degamma_lut(crtc_state, pre_csc_lut);
        else
                glk_load_degamma_lut_linear(crtc_state);
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
-               ilk_load_lut_8(crtc, gamma_lut);
+               ilk_load_lut_8(crtc, post_csc_lut);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
+               bdw_load_lut_10(crtc, post_csc_lut, PAL_PREC_INDEX_VALUE(0));
                ivb_load_lut_ext_max(crtc_state);
                break;
        default:
@@ -964,7 +964,7 @@ static void
 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *blob = crtc_state->post_csc_lut;
        const struct drm_color_lut *lut = blob->data;
        enum pipe pipe = crtc->pipe;
        int i;
@@ -993,7 +993,7 @@ static void
 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *blob = crtc_state->post_csc_lut;
        const struct drm_color_lut *lut = blob->data;
        const struct drm_color_lut *entry;
        enum pipe pipe = crtc->pipe;
@@ -1047,23 +1047,23 @@ icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
 
 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
 {
-       const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
-       if (degamma_lut)
-               glk_load_degamma_lut(crtc_state, degamma_lut);
+       if (pre_csc_lut)
+               glk_load_degamma_lut(crtc_state, pre_csc_lut);
 
        switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
        case GAMMA_MODE_MODE_8BIT:
-               ilk_load_lut_8(crtc, gamma_lut);
+               ilk_load_lut_8(crtc, post_csc_lut);
                break;
        case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
                icl_program_gamma_superfine_segment(crtc_state);
                icl_program_gamma_multi_segment(crtc_state);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
+               bdw_load_lut_10(crtc, post_csc_lut, PAL_PREC_INDEX_VALUE(0));
                ivb_load_lut_ext_max(crtc_state);
                break;
        default:
@@ -1139,18 +1139,18 @@ static void chv_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
        const struct drm_property_blob *ctm = crtc_state->hw.ctm;
 
        if (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC)
                chv_load_cgm_csc(crtc, ctm);
 
        if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
-               chv_load_cgm_degamma(crtc, degamma_lut);
+               chv_load_cgm_degamma(crtc, pre_csc_lut);
 
        if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
-               chv_load_cgm_gamma(crtc, gamma_lut);
+               chv_load_cgm_gamma(crtc, post_csc_lut);
        else
                i965_load_luts(crtc_state);
 
@@ -1188,8 +1188,8 @@ static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state
        const struct intel_crtc_state *old_crtc_state =
                intel_atomic_get_old_crtc_state(state, crtc);
 
-       return !old_crtc_state->hw.gamma_lut &&
-               !old_crtc_state->hw.degamma_lut;
+       return !old_crtc_state->post_csc_lut &&
+               !old_crtc_state->pre_csc_lut;
 }
 
 static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
@@ -1208,7 +1208,7 @@ static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
        if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
                return false;
 
-       return !old_crtc_state->hw.gamma_lut;
+       return !old_crtc_state->post_csc_lut;
 }
 
 static bool glk_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
@@ -1226,7 +1226,7 @@ static bool glk_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
         * linear hardware degamma mid scanout.
         */
        return !old_crtc_state->csc_enable &&
-               !old_crtc_state->hw.gamma_lut;
+               !old_crtc_state->post_csc_lut;
 }
 
 int intel_color_check(struct intel_crtc_state *crtc_state)
@@ -1359,6 +1359,14 @@ static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
                return GAMMA_MODE_MODE_10BIT; /* i965+ only */
 }
 
+static void intel_assign_luts(struct intel_crtc_state *crtc_state)
+{
+       drm_property_replace_blob(&crtc_state->pre_csc_lut,
+                                 crtc_state->hw.degamma_lut);
+       drm_property_replace_blob(&crtc_state->post_csc_lut,
+                                 crtc_state->hw.gamma_lut);
+}
+
 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
 {
        int ret;
@@ -1377,6 +1385,8 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
        if (ret)
                return ret;
 
+       intel_assign_luts(crtc_state);
+
        crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
 
        return 0;
@@ -1431,6 +1441,8 @@ static int chv_color_check(struct intel_crtc_state *crtc_state)
        if (ret)
                return ret;
 
+       intel_assign_luts(crtc_state);
+
        crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
 
        return 0;
@@ -1456,10 +1468,29 @@ static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
        if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
                return CSC_BLACK_SCREEN_OFFSET;
 
+       if (crtc_state->hw.degamma_lut)
+               return CSC_MODE_YUV_TO_RGB;
+
        return CSC_MODE_YUV_TO_RGB |
                CSC_POSITION_BEFORE_GAMMA;
 }
 
+static void ilk_assign_luts(struct intel_crtc_state *crtc_state)
+{
+       if (crtc_state->hw.degamma_lut ||
+           crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) {
+               drm_property_replace_blob(&crtc_state->pre_csc_lut,
+                                         crtc_state->hw.degamma_lut);
+               drm_property_replace_blob(&crtc_state->post_csc_lut,
+                                         crtc_state->hw.gamma_lut);
+       } else {
+               drm_property_replace_blob(&crtc_state->pre_csc_lut,
+                                         crtc_state->hw.gamma_lut);
+               drm_property_replace_blob(&crtc_state->post_csc_lut,
+                                         NULL);
+       }
+}
+
 static int ilk_color_check(struct intel_crtc_state *crtc_state)
 {
        int ret;
@@ -1487,6 +1518,8 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
        if (ret)
                return ret;
 
+       ilk_assign_luts(crtc_state);
+
        crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
 
        return 0;
@@ -1554,6 +1587,8 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
        if (ret)
                return ret;
 
+       ilk_assign_luts(crtc_state);
+
        crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
 
        return 0;
@@ -1602,6 +1637,8 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
        if (ret)
                return ret;
 
+       intel_assign_luts(crtc_state);
+
        crtc_state->preload_luts = glk_can_preload_luts(crtc_state);
 
        return 0;
@@ -1662,6 +1699,8 @@ static int icl_color_check(struct intel_crtc_state *crtc_state)
 
        crtc_state->csc_mode = icl_csc_mode(crtc_state);
 
+       intel_assign_luts(crtc_state);
+
        crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
 
        return 0;
@@ -1867,7 +1906,7 @@ static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
        if (!crtc_state->gamma_enable)
                return;
 
-       crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc);
+       crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
 }
 
 static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
@@ -1908,9 +1947,9 @@ static void i965_read_luts(struct intel_crtc_state *crtc_state)
                return;
 
        if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
-               crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc);
+               crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
        else
-               crtc_state->hw.gamma_lut = i965_read_lut_10p6(crtc);
+               crtc_state->post_csc_lut = i965_read_lut_10p6(crtc);
 }
 
 static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc)
@@ -1944,7 +1983,7 @@ static void chv_read_luts(struct intel_crtc_state *crtc_state)
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
        if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
-               crtc_state->hw.gamma_lut = chv_read_cgm_gamma(crtc);
+               crtc_state->post_csc_lut = chv_read_cgm_gamma(crtc);
        else
                i965_read_luts(crtc_state);
 }
@@ -2011,10 +2050,10 @@ static void ilk_read_luts(struct intel_crtc_state *crtc_state)
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
-               crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
+               crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               crtc_state->hw.gamma_lut = ilk_read_lut_10(crtc);
+               crtc_state->post_csc_lut = ilk_read_lut_10(crtc);
                break;
        default:
                MISSING_CASE(crtc_state->gamma_mode);
@@ -2066,10 +2105,10 @@ static void glk_read_luts(struct intel_crtc_state *crtc_state)
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
-               crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
+               crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
+               crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
                break;
        default:
                MISSING_CASE(crtc_state->gamma_mode);
@@ -2124,13 +2163,13 @@ static void icl_read_luts(struct intel_crtc_state *crtc_state)
 
        switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
        case GAMMA_MODE_MODE_8BIT:
-               crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
+               crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
+               crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
                break;
        case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
-               crtc_state->hw.gamma_lut = icl_read_lut_multi_segment(crtc);
+               crtc_state->post_csc_lut = icl_read_lut_multi_segment(crtc);
                break;
        default:
                MISSING_CASE(crtc_state->gamma_mode);
index e9212f6..98e36ab 100644 (file)
@@ -298,11 +298,11 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
                            pipe_config->csc_mode, pipe_config->gamma_mode,
                            pipe_config->gamma_enable, pipe_config->csc_enable);
 
-       drm_dbg_kms(&i915->drm, "degamma lut: %d entries, gamma lut: %d entries\n",
-                   pipe_config->hw.degamma_lut ?
-                   drm_color_lut_size(pipe_config->hw.degamma_lut) : 0,
-                   pipe_config->hw.gamma_lut ?
-                   drm_color_lut_size(pipe_config->hw.gamma_lut) : 0);
+       drm_dbg_kms(&i915->drm, "pre csc lut: %d entries, post csc lut: %d entries\n",
+                   pipe_config->pre_csc_lut ?
+                   drm_color_lut_size(pipe_config->pre_csc_lut) : 0,
+                   pipe_config->post_csc_lut ?
+                   drm_color_lut_size(pipe_config->post_csc_lut) : 0);
 
 dump_planes:
        if (!state)
index c4132a9..e7a72d1 100644 (file)
@@ -5789,7 +5789,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
                bp_gamma = intel_color_get_gamma_bit_precision(pipe_config);
                if (bp_gamma)
-                       PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, hw.gamma_lut, bp_gamma);
+                       PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, post_csc_lut, bp_gamma);
 
                if (current_config->active_planes) {
                        PIPE_CONF_CHECK_BOOL(has_psr);
index 8450bb5..5b38937 100644 (file)
@@ -1001,11 +1001,15 @@ struct intel_crtc_state {
         */
        struct {
                bool active, enable;
+               /* logical state of LUTs */
                struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
                struct drm_display_mode mode, pipe_mode, adjusted_mode;
                enum drm_scaling_filter scaling_filter;
        } hw;
 
+       /* actual state of LUTs */
+       struct drm_property_blob *pre_csc_lut, *post_csc_lut;
+
        /**
         * quirks - bitfield with hw state readout quirks
         *
index 5f56e03..9d8ca23 100644 (file)
@@ -155,6 +155,12 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
        crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
        crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
 
+       /* assume 1:1 mapping */
+       drm_property_replace_blob(&crtc_state->hw.degamma_lut,
+                                 crtc_state->pre_csc_lut);
+       drm_property_replace_blob(&crtc_state->hw.gamma_lut,
+                                 crtc_state->post_csc_lut);
+
        drm_property_replace_blob(&crtc_state->uapi.degamma_lut,
                                  crtc_state->hw.degamma_lut);
        drm_property_replace_blob(&crtc_state->uapi.gamma_lut,