aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c79
-rw-r--r--drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h13
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h2
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 ba995d3f2318..3417100d51e4 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c
@@ -59,6 +59,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
@@ -373,6 +379,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
@@ -429,9 +436,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,
@@ -818,6 +839,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,
@@ -836,6 +872,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,
@@ -903,6 +959,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 eb91432621ab..32844cd50d09 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
@@ -1285,7 +1285,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 1042197f1859..ae1a250c2f7d 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 = {
@@ -1727,7 +1727,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 {