From 803d95182f195a176ca0ac6d7a99baeeace7225d Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Sat, 12 Oct 2019 16:06:19 -0400 Subject: [PATCH 4327/4736] drm/amd/display: Change dmcu init sequence for dmcub loading dmcu FW. [Why] DMCU isn't intiliazed properly by dmcub loading due to dmcub initialize sequence. [How] Change dmcu init sequece to meet dmcub initilize. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Nicholas Kazlauskas Reviewed-by: Hersen Wu Acked-by: Harry Wentland --- drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 79 +++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h | 13 +++ .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- .../drm/amd/display/dc/dcn21/dcn21_resource.c | 4 +- drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h | 2 + 5 files changed, 97 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index f86ad9865a48..66925c8f10d9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -56,6 +56,12 @@ #define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */ #define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK 0x00000001L +// PSP FW version +#define mmMP0_SMN_C2PMSG_58 0x1607A + +//Register access policy version +#define mmMP0_SMN_C2PMSG_91 0x1609B + static bool dce_dmcu_init(struct dmcu *dmcu) { // Do nothing @@ -370,6 +376,7 @@ static bool dcn10_dmcu_init(struct dmcu *dmcu) const struct dc_config *config = &dmcu->ctx->dc->config; bool status = false; + PERF_TRACE(); /* Definition of DC_DMCU_SCRATCH * 0 : firmare not loaded * 1 : PSP load DMCU FW but not initialized @@ -426,9 +433,23 @@ static bool dcn10_dmcu_init(struct dmcu *dmcu) break; } + PERF_TRACE(); return status; } +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) +static bool dcn21_dmcu_init(struct dmcu *dmcu) +{ + struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + uint32_t dmcub_psp_version = REG_READ(DMCUB_SCRATCH15); + + if (dmcu->auto_load_dmcu && dmcub_psp_version == 0) { + return false; + } + + return dcn10_dmcu_init(dmcu); +} +#endif static bool dcn10_dmcu_load_iram(struct dmcu *dmcu, unsigned int start_offset, @@ -815,6 +836,21 @@ static const struct dmcu_funcs dcn20_funcs = { }; #endif +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) +static const struct dmcu_funcs dcn21_funcs = { + .dmcu_init = dcn21_dmcu_init, + .load_iram = dcn10_dmcu_load_iram, + .set_psr_enable = dcn10_dmcu_set_psr_enable, + .setup_psr = dcn10_dmcu_setup_psr, + .get_psr_state = dcn10_get_dmcu_psr_state, + .set_psr_wait_loop = dcn10_psr_wait_loop, + .get_psr_wait_loop = dcn10_get_psr_wait_loop, + .is_dmcu_initialized = dcn10_is_dmcu_initialized, + .lock_phy = dcn20_lock_phy, + .unlock_phy = dcn20_unlock_phy +}; +#endif + static void dce_dmcu_construct( struct dce_dmcu *dmcu_dce, struct dc_context *ctx, @@ -833,6 +869,26 @@ static void dce_dmcu_construct( dmcu_dce->dmcu_mask = dmcu_mask; } +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) +static void dcn21_dmcu_construct( + struct dce_dmcu *dmcu_dce, + struct dc_context *ctx, + const struct dce_dmcu_registers *regs, + const struct dce_dmcu_shift *dmcu_shift, + const struct dce_dmcu_mask *dmcu_mask) +{ + uint32_t psp_version = 0; + + dce_dmcu_construct(dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask); + + if (!IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) { + psp_version = dm_read_reg(ctx, mmMP0_SMN_C2PMSG_58); + dmcu_dce->base.auto_load_dmcu = (psp_version > 0x00110029); + dmcu_dce->base.psp_version = psp_version; + } +} +#endif + struct dmcu *dce_dmcu_create( struct dc_context *ctx, const struct dce_dmcu_registers *regs, @@ -900,6 +956,29 @@ struct dmcu *dcn20_dmcu_create( } #endif +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) +struct dmcu *dcn21_dmcu_create( + struct dc_context *ctx, + const struct dce_dmcu_registers *regs, + const struct dce_dmcu_shift *dmcu_shift, + const struct dce_dmcu_mask *dmcu_mask) +{ + struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + + if (dmcu_dce == NULL) { + BREAK_TO_DEBUGGER(); + return NULL; + } + + dcn21_dmcu_construct( + dmcu_dce, ctx, regs, dmcu_shift, dmcu_mask); + + dmcu_dce->base.funcs = &dcn21_funcs; + + return &dmcu_dce->base; +} +#endif + void dce_dmcu_destroy(struct dmcu **dmcu) { struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(*dmcu); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h index cc8587683b4b..1a42b2cbb21b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h @@ -71,6 +71,10 @@ DMCU_COMMON_REG_LIST_DCE_BASE(), \ SR(DMU_MEM_PWR_CNTL) +#define DMCU_DCN20_REG_LIST()\ + DMCU_DCN10_REG_LIST(), \ + SR(DMCUB_SCRATCH15) + #define DMCU_SF(reg_name, field_name, post_fix)\ .field_name = reg_name ## __ ## field_name ## post_fix @@ -175,6 +179,7 @@ struct dce_dmcu_registers { uint32_t DMCU_INTERRUPT_TO_UC_EN_MASK; uint32_t SMU_INTERRUPT_CONTROL; uint32_t DC_DMCU_SCRATCH; + uint32_t DMCUB_SCRATCH15; }; struct dce_dmcu { @@ -269,6 +274,14 @@ struct dmcu *dcn20_dmcu_create( const struct dce_dmcu_mask *dmcu_mask); #endif +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) +struct dmcu *dcn21_dmcu_create( + struct dc_context *ctx, + const struct dce_dmcu_registers *regs, + const struct dce_dmcu_shift *dmcu_shift, + const struct dce_dmcu_mask *dmcu_mask); +#endif + void dce_dmcu_destroy(struct dmcu **dmcu); static const uint32_t abm_gain_stepsize = 0x0060; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index b61cc211e659..6d84239af593 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1284,7 +1284,7 @@ static void dcn10_init_hw(struct dc *dc) abm->funcs->abm_init(abm); } - if (dmcu != NULL) + if (dmcu != NULL && !dmcu->auto_load_dmcu) dmcu->funcs->dmcu_init(dmcu); if (abm != NULL && dmcu != NULL) diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c index 47367446f64c..0792b1c2e673 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -350,7 +350,7 @@ static const struct bios_registers bios_regs = { }; static const struct dce_dmcu_registers dmcu_regs = { - DMCU_DCN10_REG_LIST() + DMCU_DCN20_REG_LIST() }; static const struct dce_dmcu_shift dmcu_shift = { @@ -1748,7 +1748,7 @@ static bool construct( goto create_fail; } - pool->base.dmcu = dcn20_dmcu_create(ctx, + pool->base.dmcu = dcn21_dmcu_create(ctx, &dmcu_regs, &dmcu_shift, &dmcu_mask); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h index c68f0ce346c7..5315f1f86b21 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h @@ -52,6 +52,8 @@ struct dmcu { enum dmcu_state dmcu_state; struct dmcu_version dmcu_version; unsigned int cached_wait_loop_number; + uint32_t psp_version; + bool auto_load_dmcu; }; struct dmcu_funcs { -- 2.17.1