drm/amd/display: Add CRC support for DCN
[Why] Regamma/CTM tests require CRC support [How] The CRC registers that were used in DCE exist under different names in DCN. The code was copied from DCE (in dc/dce110/dce110_timing_generator.c) into DCN, and changed to use the DCN register access helper functions. Signed-off-by: David Francis <David.Francis@amd.com> Reviewed-by: Charlene Liu <Charlene.Liu@amd.com> Acked-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
4e18814eee
commit
99a100ae32
@ -1324,6 +1324,72 @@ bool optc1_is_optc_underflow_occurred(struct timing_generator *optc)
|
||||
return (underflow_occurred == 1);
|
||||
}
|
||||
|
||||
bool optc1_configure_crc(struct timing_generator *optc,
|
||||
const struct crc_params *params)
|
||||
{
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
/* Cannot configure crc on a CRTC that is disabled */
|
||||
if (!optc1_is_tg_enabled(optc))
|
||||
return false;
|
||||
|
||||
REG_WRITE(OTG_CRC_CNTL, 0);
|
||||
|
||||
if (!params->enable)
|
||||
return true;
|
||||
|
||||
/* Program frame boundaries */
|
||||
/* Window A x axis start and end. */
|
||||
REG_UPDATE_2(OTG_CRC0_WINDOWA_X_CONTROL,
|
||||
OTG_CRC0_WINDOWA_X_START, params->windowa_x_start,
|
||||
OTG_CRC0_WINDOWA_X_END, params->windowa_x_end);
|
||||
|
||||
/* Window A y axis start and end. */
|
||||
REG_UPDATE_2(OTG_CRC0_WINDOWA_Y_CONTROL,
|
||||
OTG_CRC0_WINDOWA_Y_START, params->windowa_y_start,
|
||||
OTG_CRC0_WINDOWA_Y_END, params->windowa_y_end);
|
||||
|
||||
/* Window B x axis start and end. */
|
||||
REG_UPDATE_2(OTG_CRC0_WINDOWB_X_CONTROL,
|
||||
OTG_CRC0_WINDOWB_X_START, params->windowb_x_start,
|
||||
OTG_CRC0_WINDOWB_X_END, params->windowb_x_end);
|
||||
|
||||
/* Window B y axis start and end. */
|
||||
REG_UPDATE_2(OTG_CRC0_WINDOWB_Y_CONTROL,
|
||||
OTG_CRC0_WINDOWB_Y_START, params->windowb_y_start,
|
||||
OTG_CRC0_WINDOWB_Y_END, params->windowb_y_end);
|
||||
|
||||
/* Set crc mode and selection, and enable. Only using CRC0*/
|
||||
REG_UPDATE_3(OTG_CRC_CNTL,
|
||||
OTG_CRC_CONT_EN, params->continuous_mode ? 1 : 0,
|
||||
OTG_CRC0_SELECT, params->selection,
|
||||
OTG_CRC_EN, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool optc1_get_crc(struct timing_generator *optc,
|
||||
uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb)
|
||||
{
|
||||
uint32_t field = 0;
|
||||
struct optc *optc1 = DCN10TG_FROM_TG(optc);
|
||||
|
||||
REG_GET(OTG_CRC_CNTL, OTG_CRC_EN, &field);
|
||||
|
||||
/* Early return if CRC is not enabled for this CRTC */
|
||||
if (!field)
|
||||
return false;
|
||||
|
||||
REG_GET_2(OTG_CRC0_DATA_RG,
|
||||
CRC0_R_CR, r_cr,
|
||||
CRC0_G_Y, g_y);
|
||||
|
||||
REG_GET(OTG_CRC0_DATA_B,
|
||||
CRC0_B_CB, b_cb);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct timing_generator_funcs dcn10_tg_funcs = {
|
||||
.validate_timing = optc1_validate_timing,
|
||||
.program_timing = optc1_program_timing,
|
||||
@ -1360,6 +1426,8 @@ static const struct timing_generator_funcs dcn10_tg_funcs = {
|
||||
.is_tg_enabled = optc1_is_tg_enabled,
|
||||
.is_optc_underflow_occurred = optc1_is_optc_underflow_occurred,
|
||||
.clear_optc_underflow = optc1_clear_optc_underflow,
|
||||
.get_crc = optc1_get_crc,
|
||||
.configure_crc = optc1_configure_crc,
|
||||
};
|
||||
|
||||
void dcn10_timing_generator_init(struct optc *optc1)
|
||||
|
@ -75,7 +75,14 @@
|
||||
SRI(CONTROL, VTG, inst),\
|
||||
SRI(OTG_VERT_SYNC_CONTROL, OTG, inst),\
|
||||
SRI(OTG_MASTER_UPDATE_MODE, OTG, inst),\
|
||||
SRI(OTG_GSL_CONTROL, OTG, inst)
|
||||
SRI(OTG_GSL_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC_CNTL, OTG, inst),\
|
||||
SRI(OTG_CRC0_DATA_RG, OTG, inst),\
|
||||
SRI(OTG_CRC0_DATA_B, OTG, inst),\
|
||||
SRI(OTG_CRC0_WINDOWA_X_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst),\
|
||||
SRI(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst)
|
||||
|
||||
#define TG_COMMON_REG_LIST_DCN1_0(inst) \
|
||||
TG_COMMON_REG_LIST_DCN(inst),\
|
||||
@ -138,6 +145,13 @@ struct dcn_optc_registers {
|
||||
uint32_t OTG_GSL_WINDOW_X;
|
||||
uint32_t OTG_GSL_WINDOW_Y;
|
||||
uint32_t OTG_VUPDATE_KEEPOUT;
|
||||
uint32_t OTG_CRC_CNTL;
|
||||
uint32_t OTG_CRC0_DATA_RG;
|
||||
uint32_t OTG_CRC0_DATA_B;
|
||||
uint32_t OTG_CRC0_WINDOWA_X_CONTROL;
|
||||
uint32_t OTG_CRC0_WINDOWA_Y_CONTROL;
|
||||
uint32_t OTG_CRC0_WINDOWB_X_CONTROL;
|
||||
uint32_t OTG_CRC0_WINDOWB_Y_CONTROL;
|
||||
};
|
||||
|
||||
#define TG_COMMON_MASK_SH_LIST_DCN(mask_sh)\
|
||||
@ -232,7 +246,21 @@ struct dcn_optc_registers {
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL2_EN, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_MASTER_EN, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_FORCE_DELAY, mask_sh),\
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh)
|
||||
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh),\
|
||||
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
|
||||
SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
|
||||
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_DATA_RG, CRC0_R_CR, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_DATA_RG, CRC0_G_Y, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_DATA_B, CRC0_B_CB, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWA_X_CONTROL, OTG_CRC0_WINDOWA_X_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWA_X_CONTROL, OTG_CRC0_WINDOWA_X_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWA_Y_CONTROL, OTG_CRC0_WINDOWA_Y_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWA_Y_CONTROL, OTG_CRC0_WINDOWA_Y_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_END, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_START, mask_sh),\
|
||||
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_END, mask_sh)
|
||||
|
||||
|
||||
#define TG_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
|
||||
@ -363,7 +391,22 @@ struct dcn_optc_registers {
|
||||
type OTG_MASTER_UPDATE_LOCK_GSL_EN;\
|
||||
type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET;\
|
||||
type MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET;\
|
||||
type OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN;
|
||||
type OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN;\
|
||||
type OTG_CRC_CONT_EN;\
|
||||
type OTG_CRC0_SELECT;\
|
||||
type OTG_CRC_EN;\
|
||||
type CRC0_R_CR;\
|
||||
type CRC0_G_Y;\
|
||||
type CRC0_B_CB;\
|
||||
type OTG_CRC0_WINDOWA_X_START;\
|
||||
type OTG_CRC0_WINDOWA_X_END;\
|
||||
type OTG_CRC0_WINDOWA_Y_START;\
|
||||
type OTG_CRC0_WINDOWA_Y_END;\
|
||||
type OTG_CRC0_WINDOWB_X_START;\
|
||||
type OTG_CRC0_WINDOWB_X_END;\
|
||||
type OTG_CRC0_WINDOWB_Y_START;\
|
||||
type OTG_CRC0_WINDOWB_Y_END;
|
||||
|
||||
|
||||
#define TG_REG_FIELD_LIST(type) \
|
||||
TG_REG_FIELD_LIST_DCN1_0(type)
|
||||
|
Loading…
Reference in New Issue
Block a user