Commit e8027e08 authored by Noah Abradjian's avatar Noah Abradjian Committed by Alex Deucher

drm/amd/display: Add double buffering to dcn20 OCSC

[Why]
When rapidly adjusting colour properties (e.g. brightness), screen tearing was observed.
This was due to overwritten values in OCSC registers. In dcn10, this issue had been fixed by
implementing double buffering by alternating OCSC modes.

[How]
Alternate which OCSC registers are used by switching modes each time.
This double buffers the CSC writes.
Signed-off-by: default avatarNoah Abradjian <noah.abradjian@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 1295524e
......@@ -33,6 +33,9 @@
#define REG(reg)\
mpc20->mpc_regs->reg
#define IND_REG(index) \
(index)
#define CTX \
mpc20->base.ctx
......@@ -132,19 +135,32 @@ void mpc2_set_output_csc(
const uint16_t *regval,
enum mpc_output_csc_mode ocsc_mode)
{
uint32_t cur_mode;
struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc);
struct color_matrices_reg ocsc_regs;
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE)
if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) {
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
return;
}
if (regval == NULL) {
BREAK_TO_DEBUGGER();
return;
}
/* determine which CSC coefficients (A or B) we are using
* currently. select the alternate set to double buffer
* the CSC update so CSC is updated on frame boundary
*/
cur_mode = IX_REG_READ(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_DATA,
MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE_IDX);
if (cur_mode != MPC_OUTPUT_CSC_COEF_A)
ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
else
ocsc_mode = MPC_OUTPUT_CSC_COEF_B;
ocsc_regs.shifts.csc_c11 = mpc20->mpc_shift->MPC_OCSC_C11_A;
ocsc_regs.masks.csc_c11 = mpc20->mpc_mask->MPC_OCSC_C11_A;
ocsc_regs.shifts.csc_c12 = mpc20->mpc_shift->MPC_OCSC_C12_A;
......@@ -157,10 +173,13 @@ void mpc2_set_output_csc(
ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]);
ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]);
}
cm_helper_program_color_matrices(
mpc20->base.ctx,
regval,
&ocsc_regs);
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
}
void mpc2_set_ocsc_default(
......@@ -169,14 +188,16 @@ void mpc2_set_ocsc_default(
enum dc_color_space color_space,
enum mpc_output_csc_mode ocsc_mode)
{
uint32_t cur_mode;
struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc);
uint32_t arr_size;
struct color_matrices_reg ocsc_regs;
const uint16_t *regval = NULL;
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE)
if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE) {
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
return;
}
regval = find_color_matrix(color_space, &arr_size);
......@@ -185,6 +206,18 @@ void mpc2_set_ocsc_default(
return;
}
/* determine which CSC coefficients (A or B) we are using
* currently. select the alternate set to double buffer
* the CSC update so CSC is updated on frame boundary
*/
cur_mode = IX_REG_READ(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_DATA,
MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE_IDX);
if (cur_mode != MPC_OUTPUT_CSC_COEF_A)
ocsc_mode = MPC_OUTPUT_CSC_COEF_A;
else
ocsc_mode = MPC_OUTPUT_CSC_COEF_B;
ocsc_regs.shifts.csc_c11 = mpc20->mpc_shift->MPC_OCSC_C11_A;
ocsc_regs.masks.csc_c11 = mpc20->mpc_mask->MPC_OCSC_C11_A;
ocsc_regs.shifts.csc_c12 = mpc20->mpc_shift->MPC_OCSC_C12_A;
......@@ -203,6 +236,8 @@ void mpc2_set_ocsc_default(
mpc20->base.ctx,
regval,
&ocsc_regs);
REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
}
static void mpc2_ogam_get_reg_field(
......
......@@ -80,6 +80,10 @@
SRII(DENORM_CLAMP_G_Y, MPC_OUT, inst),\
SRII(DENORM_CLAMP_B_CB, MPC_OUT, inst)
#define MPC_DBG_REG_LIST_DCN2_0() \
SR(MPC_OCSC_TEST_DEBUG_DATA),\
SR(MPC_OCSC_TEST_DEBUG_INDEX)
#define MPC_REG_VARIABLE_LIST_DCN2_0 \
MPC_COMMON_REG_VARIABLE_LIST \
uint32_t MPCC_TOP_GAIN[MAX_MPCC]; \
......@@ -118,6 +122,8 @@
uint32_t MPCC_OGAM_LUT_RAM_CONTROL[MAX_MPCC];\
uint32_t MPCC_OGAM_LUT_DATA[MAX_MPCC];\
uint32_t MPCC_OGAM_MODE[MAX_MPCC];\
uint32_t MPC_OCSC_TEST_DEBUG_DATA;\
uint32_t MPC_OCSC_TEST_DEBUG_INDEX;\
uint32_t CSC_MODE[MAX_OPP]; \
uint32_t CSC_C11_C12_A[MAX_OPP]; \
uint32_t CSC_C33_C34_A[MAX_OPP]; \
......@@ -134,6 +140,8 @@
SF(MPCC0_MPCC_TOP_GAIN, MPCC_TOP_GAIN, mask_sh),\
SF(MPCC0_MPCC_BOT_GAIN_INSIDE, MPCC_BOT_GAIN_INSIDE, mask_sh),\
SF(MPCC0_MPCC_BOT_GAIN_OUTSIDE, MPCC_BOT_GAIN_OUTSIDE, mask_sh),\
SF(MPC_OCSC_TEST_DEBUG_DATA, MPC_OCSC_TEST_DEBUG_DATA, mask_sh),\
SF(MPC_OCSC_TEST_DEBUG_INDEX, MPC_OCSC_TEST_DEBUG_INDEX, mask_sh),\
SF(MPC_OUT0_CSC_MODE, MPC_OCSC_MODE, mask_sh),\
SF(MPC_OUT0_CSC_C11_C12_A, MPC_OCSC_C11_A, mask_sh),\
SF(MPC_OUT0_CSC_C11_C12_A, MPC_OCSC_C12_A, mask_sh),\
......@@ -174,6 +182,12 @@
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh)
/*
* DCN2 MPC_OCSC debug status register:
*
* Field describing current OCSC Mode has index 1 [1..0]
*/
#define MPC_OCSC_TEST_DEBUG_DATA_OCSC_MODE_IDX 1
#define MPC_REG_FIELD_LIST_DCN2_0(type) \
MPC_REG_FIELD_LIST(type)\
......@@ -182,6 +196,8 @@
type MPCC_TOP_GAIN;\
type MPCC_BOT_GAIN_INSIDE;\
type MPCC_BOT_GAIN_OUTSIDE;\
type MPC_OCSC_TEST_DEBUG_DATA;\
type MPC_OCSC_TEST_DEBUG_INDEX;\
type MPC_OCSC_MODE;\
type MPC_OCSC_C11_A;\
type MPC_OCSC_C12_A;\
......
......@@ -706,6 +706,7 @@ static const struct dcn20_mpc_registers mpc_regs = {
MPC_OUT_MUX_REG_LIST_DCN2_0(3),
MPC_OUT_MUX_REG_LIST_DCN2_0(4),
MPC_OUT_MUX_REG_LIST_DCN2_0(5),
MPC_DBG_REG_LIST_DCN2_0()
};
static const struct dcn20_mpc_shift mpc_shift = {
......
......@@ -465,7 +465,8 @@ static const struct dcn20_mpc_registers mpc_regs = {
MPC_OUT_MUX_REG_LIST_DCN2_0(0),
MPC_OUT_MUX_REG_LIST_DCN2_0(1),
MPC_OUT_MUX_REG_LIST_DCN2_0(2),
MPC_OUT_MUX_REG_LIST_DCN2_0(3)
MPC_OUT_MUX_REG_LIST_DCN2_0(3),
MPC_DBG_REG_LIST_DCN2_0()
};
static const struct dcn20_mpc_shift mpc_shift = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment