drm/amd/display: Add double buffer machanism to OCSC
authorXingyue Tao <xingyue.tao@amd.com>
Fri, 16 Mar 2018 19:20:48 +0000 (15:20 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 11 Apr 2018 18:07:46 +0000 (13:07 -0500)
- Added double buffer mechanism to output CSC
so that there's no tearing when adjusting brightness
from Radeon settings

Signed-off-by: Xingyue Tao <xingyue.tao@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_cm.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c

index b81b2aa3c49f03e060c9d15f8afa54ec5f7cf57d..9b5ff76a8027f77a532860a44b2d3dea040bf033 100644 (file)
        TF_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
        TF_SF(DPP_TOP0_DPP_CONTROL, DPPCLK_RATE_CONTROL, mask_sh)
 
+/*
+ *
+       DCN1 CM debug status register definition
+
+       register :ID9_CM_STATUS do
+       implement_ref :cm
+       map to:  :cmdebugind, at: j
+       width 32
+       disclosure   NEVER
+
+               field :ID9_VUPDATE_CFG, [0], R
+               field :ID9_IGAM_LUT_MODE, [2..1], R
+               field :ID9_BNS_BYPASS, [3], R
+               field :ID9_ICSC_MODE, [5..4], R
+               field :ID9_DGAM_LUT_MODE, [8..6], R
+               field :ID9_HDR_BYPASS, [9], R
+               field :ID9_GAMUT_REMAP_MODE, [11..10], R
+               field :ID9_RGAM_LUT_MODE, [14..12], R
+               #1 free bit
+               field :ID9_OCSC_MODE, [18..16], R
+               field :ID9_DENORM_MODE, [21..19], R
+               field :ID9_ROUND_TRUNC_MODE, [25..22], R
+               field :ID9_DITHER_EN, [26], R
+               field :ID9_DITHER_MODE, [28..27], R
+       end
+*/
+
+#define TF_DEBUG_REG_LIST_SH_DCN10 \
+       .CM_TEST_DEBUG_DATA_ID9_ICSC_MODE = 4, \
+       .CM_TEST_DEBUG_DATA_ID9_OCSC_MODE = 16
+
+#define TF_DEBUG_REG_LIST_MASK_DCN10 \
+       .CM_TEST_DEBUG_DATA_ID9_ICSC_MODE = 0x30, \
+       .CM_TEST_DEBUG_DATA_ID9_OCSC_MODE = 0x70000
+
 #define TF_REG_FIELD_LIST(type) \
        type EXT_OVERSCAN_LEFT; \
        type EXT_OVERSCAN_RIGHT; \
        type CM_BYPASS; \
        type CM_TEST_DEBUG_INDEX; \
        type CM_TEST_DEBUG_DATA_ID9_ICSC_MODE; \
+       type CM_TEST_DEBUG_DATA_ID9_OCSC_MODE;\
        type FORMAT_CONTROL__ALPHA_EN; \
        type CUR0_COLOR0; \
        type CUR0_COLOR1; \
index cc511415caeef92ca7dbf235220138cceadd042a..4f373c97804feec659096b3ba3bc83738f7c7cf5 100644 (file)
@@ -216,41 +216,55 @@ static void dpp1_cm_program_color_matrix(
                struct dcn10_dpp *dpp,
                const uint16_t *regval)
 {
-       uint32_t mode;
+       uint32_t ocsc_mode;
+       uint32_t cur_mode;
        struct color_matrices_reg gam_regs;
 
-       REG_GET(CM_OCSC_CONTROL, CM_OCSC_MODE, &mode);
-
        if (regval == NULL) {
                BREAK_TO_DEBUGGER();
                return;
        }
-       mode = 4;
+
+       /* determine which CSC matrix (ocsc or comb) we are using
+        * currently.  select the alternate set to double buffer
+        * the CSC update so CSC is updated on frame boundary
+        */
+       REG_SET(CM_TEST_DEBUG_INDEX, 0,
+                       CM_TEST_DEBUG_INDEX, 9);
+
+       REG_GET(CM_TEST_DEBUG_DATA,
+                       CM_TEST_DEBUG_DATA_ID9_OCSC_MODE, &cur_mode);
+
+       if (cur_mode != 4)
+               ocsc_mode = 4;
+       else
+               ocsc_mode = 5;
+
+
        gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_OCSC_C11;
        gam_regs.masks.csc_c11  = dpp->tf_mask->CM_OCSC_C11;
        gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_OCSC_C12;
        gam_regs.masks.csc_c12 = dpp->tf_mask->CM_OCSC_C12;
 
-       if (mode == 4) {
+       if (ocsc_mode == 4) {
 
                gam_regs.csc_c11_c12 = REG(CM_OCSC_C11_C12);
                gam_regs.csc_c33_c34 = REG(CM_OCSC_C33_C34);
 
-               cm_helper_program_color_matrices(
-                               dpp->base.ctx,
-                               regval,
-                               &gam_regs);
-
        } else {
 
                gam_regs.csc_c11_c12 = REG(CM_COMB_C11_C12);
                gam_regs.csc_c33_c34 = REG(CM_COMB_C33_C34);
 
-               cm_helper_program_color_matrices(
-                               dpp->base.ctx,
-                               regval,
-                               &gam_regs);
        }
+
+       cm_helper_program_color_matrices(
+                       dpp->base.ctx,
+                       regval,
+                       &gam_regs);
+
+       REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
+
 }
 
 void dpp1_cm_set_output_csc_default(
@@ -260,7 +274,6 @@ void dpp1_cm_set_output_csc_default(
        struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
        const uint16_t *regval = NULL;
        int arr_size;
-       uint32_t ocsc_mode = 4;
 
        regval = find_color_matrix(colorspace, &arr_size);
        if (regval == NULL) {
@@ -269,7 +282,6 @@ void dpp1_cm_set_output_csc_default(
        }
 
        dpp1_cm_program_color_matrix(dpp, regval);
-       REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
 }
 
 static void dpp1_cm_get_reg_field(
@@ -330,10 +342,8 @@ void dpp1_cm_set_output_csc_adjustment(
                const uint16_t *regval)
 {
        struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
-       uint32_t ocsc_mode = 4;
 
        dpp1_cm_program_color_matrix(dpp, regval);
-       REG_SET(CM_OCSC_CONTROL, 0, CM_OCSC_MODE, ocsc_mode);
 }
 
 void dpp1_cm_power_on_regamma_lut(struct dpp *dpp_base,
index d321da97217c2db29e10971652ec04df62349003..7ad290cbc7309eb77a147e2231570da9a1e22a81 100644 (file)
@@ -319,41 +319,15 @@ static const struct dcn_dpp_registers tf_regs[] = {
        tf_regs(3),
 };
 
-/*
- *
-       DCN1 CM debug status register definition
-
-       register :ID9_CM_STATUS do
-       implement_ref :cm
-       map to:  :cmdebugind, at: j
-       width 32
-       disclosure   NEVER
-
-               field :ID9_VUPDATE_CFG, [0], R
-               field :ID9_IGAM_LUT_MODE, [2..1], R
-               field :ID9_BNS_BYPASS, [3], R
-               field :ID9_ICSC_MODE, [5..4], R
-               field :ID9_DGAM_LUT_MODE, [8..6], R
-               field :ID9_HDR_BYPASS, [9], R
-               field :ID9_GAMUT_REMAP_MODE, [11..10], R
-               field :ID9_RGAM_LUT_MODE, [14..12], R
-               #1 free bit
-               field :ID9_OCSC_MODE, [18..16], R
-               field :ID9_DENORM_MODE, [21..19], R
-               field :ID9_ROUND_TRUNC_MODE, [25..22], R
-               field :ID9_DITHER_EN, [26], R
-               field :ID9_DITHER_MODE, [28..27], R
-       end
-*/
-
 static const struct dcn_dpp_shift tf_shift = {
        TF_REG_LIST_SH_MASK_DCN10(__SHIFT),
-       .CM_TEST_DEBUG_DATA_ID9_ICSC_MODE = 0x4
+       TF_DEBUG_REG_LIST_SH_DCN10
+
 };
 
 static const struct dcn_dpp_mask tf_mask = {
        TF_REG_LIST_SH_MASK_DCN10(_MASK),
-       .CM_TEST_DEBUG_DATA_ID9_ICSC_MODE = 0x30
+       TF_DEBUG_REG_LIST_MASK_DCN10
 };
 
 static const struct dcn_mpc_registers mpc_regs = {