diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1963-drm-amd-display-Hook-up-CRC-capture-support-for-dce1.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1963-drm-amd-display-Hook-up-CRC-capture-support-for-dce1.patch | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1963-drm-amd-display-Hook-up-CRC-capture-support-for-dce1.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1963-drm-amd-display-Hook-up-CRC-capture-support-for-dce1.patch new file mode 100644 index 00000000..a102ff8d --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1963-drm-amd-display-Hook-up-CRC-capture-support-for-dce1.patch @@ -0,0 +1,136 @@ +From 6c12dc8ef623ad046529cb2132732e6a460cebab Mon Sep 17 00:00:00 2001 +From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Date: Thu, 25 Apr 2019 12:11:08 -0400 +Subject: [PATCH 1963/2940] drm/amd/display: Hook up CRC capture support for + dce120 + +[Why] +Many IGT tests require CRC capture in order to confirm that the output +is visually correct. + +These skip on dce120 because configure_crc and get_crc aren't set. + +[How] +Hook up is_tg_enabled, configure_crc and get_crc functions on dce120's +timing generator. + +The logic should be the same as DCE and DCN with some minor register +naming differences. + +Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Reviewed-by: David Francis <David.Francis@amd.com> +Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> +--- + .../dc/dce120/dce120_timing_generator.c | 89 +++++++++++++++++++ + 1 file changed, 89 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c +index 5ebbbda77021..098e56962f2a 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c ++++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_timing_generator.c +@@ -1114,6 +1114,92 @@ static bool dce120_arm_vert_intr( + return true; + } + ++ ++static bool dce120_is_tg_enabled(struct timing_generator *tg) ++{ ++ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); ++ uint32_t value, field; ++ ++ value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CONTROL, ++ tg110->offsets.crtc); ++ field = get_reg_field_value(value, CRTC0_CRTC_CONTROL, ++ CRTC_CURRENT_MASTER_EN_STATE); ++ ++ return field == 1; ++} ++ ++static bool dce120_configure_crc(struct timing_generator *tg, ++ const struct crc_params *params) ++{ ++ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); ++ ++ /* Cannot configure crc on a CRTC that is disabled */ ++ if (!dce120_is_tg_enabled(tg)) ++ return false; ++ ++ /* First, disable CRC before we configure it. */ ++ dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC_CNTL, ++ tg110->offsets.crtc, 0); ++ ++ if (!params->enable) ++ return true; ++ ++ /* Program frame boundaries */ ++ /* Window A x axis start and end. */ ++ CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWA_X_CONTROL, ++ CRTC_CRC0_WINDOWA_X_START, params->windowa_x_start, ++ CRTC_CRC0_WINDOWA_X_END, params->windowa_x_end); ++ ++ /* Window A y axis start and end. */ ++ CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWA_Y_CONTROL, ++ CRTC_CRC0_WINDOWA_Y_START, params->windowa_y_start, ++ CRTC_CRC0_WINDOWA_Y_END, params->windowa_y_end); ++ ++ /* Window B x axis start and end. */ ++ CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWB_X_CONTROL, ++ CRTC_CRC0_WINDOWB_X_START, params->windowb_x_start, ++ CRTC_CRC0_WINDOWB_X_END, params->windowb_x_end); ++ ++ /* Window B y axis start and end. */ ++ CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWB_Y_CONTROL, ++ CRTC_CRC0_WINDOWB_Y_START, params->windowb_y_start, ++ CRTC_CRC0_WINDOWB_Y_END, params->windowb_y_end); ++ ++ /* Set crc mode and selection, and enable. Only using CRC0*/ ++ CRTC_REG_UPDATE_3(CRTC0_CRTC_CRC_CNTL, ++ CRTC_CRC_EN, params->continuous_mode ? 1 : 0, ++ CRTC_CRC0_SELECT, params->selection, ++ CRTC_CRC_EN, 1); ++ ++ return true; ++} ++ ++static bool dce120_get_crc(struct timing_generator *tg, uint32_t *r_cr, ++ uint32_t *g_y, uint32_t *b_cb) ++{ ++ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg); ++ uint32_t value, field; ++ ++ value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC_CNTL, ++ tg110->offsets.crtc); ++ field = get_reg_field_value(value, CRTC0_CRTC_CRC_CNTL, CRTC_CRC_EN); ++ ++ /* Early return if CRC is not enabled for this CRTC */ ++ if (!field) ++ return false; ++ ++ value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC0_DATA_RG, ++ tg110->offsets.crtc); ++ *r_cr = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_RG, CRC0_R_CR); ++ *g_y = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_RG, CRC0_G_Y); ++ ++ value = dm_read_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC0_DATA_B, ++ tg110->offsets.crtc); ++ *b_cb = get_reg_field_value(value, CRTC0_CRTC_CRC0_DATA_B, CRC0_B_CB); ++ ++ return true; ++} ++ + static const struct timing_generator_funcs dce120_tg_funcs = { + .validate_timing = dce120_tg_validate_timing, + .program_timing = dce120_tg_program_timing, +@@ -1145,6 +1231,9 @@ static const struct timing_generator_funcs dce120_tg_funcs = { + .set_static_screen_control = dce120_timing_generator_set_static_screen_control, + .set_test_pattern = dce120_timing_generator_set_test_pattern, + .arm_vert_intr = dce120_arm_vert_intr, ++ .is_tg_enabled = dce120_is_tg_enabled, ++ .configure_crc = dce120_configure_crc, ++ .get_crc = dce120_get_crc, + }; + + +-- +2.17.1 + |