Commit 21e471f0 authored by Eric Yang's avatar Eric Yang Committed by Alex Deucher

drm/amd/display: Set dispclk and dprefclock directly

[Why]
To simply logic for setting DCN specific clocks, we will send
SMU message directly through the VBIOS message box.

[How]
Add new structure in pp_smu to hold functions to set clocks
through vbios message box
Signed-off-by: default avatarEric Yang <Eric.Yang2@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4cd75ff0
...@@ -297,7 +297,7 @@ void generic_reg_wait(const struct dc_context *ctx, ...@@ -297,7 +297,7 @@ void generic_reg_wait(const struct dc_context *ctx,
int i; int i;
/* something is terribly wrong if time out is > 200ms. (5Hz) */ /* something is terribly wrong if time out is > 200ms. (5Hz) */
ASSERT(delay_between_poll_us * time_out_num_tries <= 200000); ASSERT(delay_between_poll_us * time_out_num_tries <= 3000000);
for (i = 0; i <= time_out_num_tries; i++) { for (i = 0; i <= time_out_num_tries; i++) {
if (i) { if (i) {
......
...@@ -782,22 +782,22 @@ static void dce12_update_clocks(struct clk_mgr *clk_mgr, ...@@ -782,22 +782,22 @@ static void dce12_update_clocks(struct clk_mgr *clk_mgr,
dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context);
} }
static const struct clk_mgr_funcs dce120_funcs = { static struct clk_mgr_funcs dce120_funcs = {
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
.update_clocks = dce12_update_clocks .update_clocks = dce12_update_clocks
}; };
static const struct clk_mgr_funcs dce112_funcs = { static struct clk_mgr_funcs dce112_funcs = {
.get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz,
.update_clocks = dce112_update_clocks .update_clocks = dce112_update_clocks
}; };
static const struct clk_mgr_funcs dce110_funcs = { static struct clk_mgr_funcs dce110_funcs = {
.get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz,
.update_clocks = dce11_update_clocks, .update_clocks = dce11_update_clocks,
}; };
static const struct clk_mgr_funcs dce_funcs = { static struct clk_mgr_funcs dce_funcs = {
.get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz, .get_dp_ref_clk_frequency = dce_get_dp_ref_freq_khz,
.update_clocks = dce_update_clocks .update_clocks = dce_update_clocks
}; };
......
...@@ -39,6 +39,11 @@ ...@@ -39,6 +39,11 @@
#define CLK_COMMON_REG_LIST_DCN_BASE() \ #define CLK_COMMON_REG_LIST_DCN_BASE() \
SR(DENTIST_DISPCLK_CNTL) SR(DENTIST_DISPCLK_CNTL)
#define VBIOS_SMU_MSG_BOX_REG_LIST_RV() \
.MP1_SMN_C2PMSG_91 = mmMP1_SMN_C2PMSG_91, \
.MP1_SMN_C2PMSG_83 = mmMP1_SMN_C2PMSG_83, \
.MP1_SMN_C2PMSG_67 = mmMP1_SMN_C2PMSG_67
#define CLK_SF(reg_name, field_name, post_fix)\ #define CLK_SF(reg_name, field_name, post_fix)\
.field_name = reg_name ## __ ## field_name ## post_fix .field_name = reg_name ## __ ## field_name ## post_fix
...@@ -50,23 +55,39 @@ ...@@ -50,23 +55,39 @@
CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\ CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, mask_sh),\
CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh) CLK_SF(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, mask_sh)
#define CLK_MASK_SH_LIST_RV1(mask_sh) \
CLK_COMMON_MASK_SH_LIST_DCN_COMMON_BASE(mask_sh),\
CLK_SF(MP1_SMN_C2PMSG_67, CONTENT, mask_sh),\
CLK_SF(MP1_SMN_C2PMSG_83, CONTENT, mask_sh),\
CLK_SF(MP1_SMN_C2PMSG_91, CONTENT, mask_sh),
#define CLK_REG_FIELD_LIST(type) \ #define CLK_REG_FIELD_LIST(type) \
type DPREFCLK_SRC_SEL; \ type DPREFCLK_SRC_SEL; \
type DENTIST_DPREFCLK_WDIVIDER; \ type DENTIST_DPREFCLK_WDIVIDER; \
type DENTIST_DISPCLK_WDIVIDER; \ type DENTIST_DISPCLK_WDIVIDER; \
type DENTIST_DISPCLK_CHG_DONE; type DENTIST_DISPCLK_CHG_DONE;
#define VBIOS_SMU_REG_FIELD_LIST(type) \
type CONTENT;
struct clk_mgr_shift { struct clk_mgr_shift {
CLK_REG_FIELD_LIST(uint8_t) CLK_REG_FIELD_LIST(uint8_t)
VBIOS_SMU_REG_FIELD_LIST(uint32_t)
}; };
struct clk_mgr_mask { struct clk_mgr_mask {
CLK_REG_FIELD_LIST(uint32_t) CLK_REG_FIELD_LIST(uint32_t)
VBIOS_SMU_REG_FIELD_LIST(uint32_t)
}; };
struct clk_mgr_registers { struct clk_mgr_registers {
uint32_t DPREFCLK_CNTL; uint32_t DPREFCLK_CNTL;
uint32_t DENTIST_DISPCLK_CNTL; uint32_t DENTIST_DISPCLK_CNTL;
uint32_t MP1_SMN_C2PMSG_67;
uint32_t MP1_SMN_C2PMSG_83;
uint32_t MP1_SMN_C2PMSG_91;
}; };
struct state_dependent_clocks { struct state_dependent_clocks {
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "reg_helper.h" #include "reg_helper.h"
#include "core_types.h" #include "core_types.h"
#include "dal_asic_id.h"
#define TO_DCE_CLK_MGR(clocks)\ #define TO_DCE_CLK_MGR(clocks)\
container_of(clocks, struct dce_clk_mgr, base) container_of(clocks, struct dce_clk_mgr, base)
...@@ -91,13 +92,18 @@ static int dcn1_determine_dppclk_threshold(struct clk_mgr *clk_mgr, struct dc_cl ...@@ -91,13 +92,18 @@ static int dcn1_determine_dppclk_threshold(struct clk_mgr *clk_mgr, struct dc_cl
static void dcn1_ramp_up_dispclk_with_dpp(struct clk_mgr *clk_mgr, struct dc_clocks *new_clocks) static void dcn1_ramp_up_dispclk_with_dpp(struct clk_mgr *clk_mgr, struct dc_clocks *new_clocks)
{ {
int i;
struct dc *dc = clk_mgr->ctx->dc; struct dc *dc = clk_mgr->ctx->dc;
int dispclk_to_dpp_threshold = dcn1_determine_dppclk_threshold(clk_mgr, new_clocks); int dispclk_to_dpp_threshold = dcn1_determine_dppclk_threshold(clk_mgr, new_clocks);
bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz;
int i;
/* set disp clk to dpp clk threshold */ /* set disp clk to dpp clk threshold */
dce112_set_clock(clk_mgr, dispclk_to_dpp_threshold);
if (clk_mgr->funcs->set_dispclk && clk_mgr->funcs->set_dprefclk) {
clk_mgr->funcs->set_dispclk(clk_mgr, dispclk_to_dpp_threshold);
clk_mgr->funcs->set_dprefclk(clk_mgr);
} else
dce112_set_clock(clk_mgr, dispclk_to_dpp_threshold);
/* update request dpp clk division option */ /* update request dpp clk division option */
for (i = 0; i < dc->res_pool->pipe_count; i++) { for (i = 0; i < dc->res_pool->pipe_count; i++) {
...@@ -113,8 +119,13 @@ static void dcn1_ramp_up_dispclk_with_dpp(struct clk_mgr *clk_mgr, struct dc_clo ...@@ -113,8 +119,13 @@ static void dcn1_ramp_up_dispclk_with_dpp(struct clk_mgr *clk_mgr, struct dc_clo
} }
/* If target clk not same as dppclk threshold, set to target clock */ /* If target clk not same as dppclk threshold, set to target clock */
if (dispclk_to_dpp_threshold != new_clocks->dispclk_khz) if (dispclk_to_dpp_threshold != new_clocks->dispclk_khz) {
dce112_set_clock(clk_mgr, new_clocks->dispclk_khz); if (clk_mgr->funcs->set_dispclk && clk_mgr->funcs->set_dprefclk) {
clk_mgr->funcs->set_dispclk(clk_mgr, new_clocks->dispclk_khz);
clk_mgr->funcs->set_dprefclk(clk_mgr);
} else
dce112_set_clock(clk_mgr, dispclk_to_dpp_threshold);
}
clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz; clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz;
clk_mgr->clks.dppclk_khz = new_clocks->dppclk_khz; clk_mgr->clks.dppclk_khz = new_clocks->dppclk_khz;
...@@ -242,7 +253,62 @@ static void dcn1_update_clocks(struct clk_mgr *clk_mgr, ...@@ -242,7 +253,62 @@ static void dcn1_update_clocks(struct clk_mgr *clk_mgr,
} }
} }
} }
static const struct clk_mgr_funcs dcn1_funcs = {
#define VBIOSSMC_MSG_SetDispclkFreq 0x4
#define VBIOSSMC_MSG_SetDprefclkFreq 0x5
int dcn10_set_dispclk(struct clk_mgr *clk_mgr_base, int requested_dispclk_khz)
{
int actual_dispclk_set_khz = -1;
struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr_base);
/* First clear response register */
//dm_write_reg(ctx, mmMP1_SMN_C2PMSG_91, 0);
REG_WRITE(MP1_SMN_C2PMSG_91, 0);
/* Set the parameter register for the SMU message, unit is Mhz */
//dm_write_reg(ctx, mmMP1_SMN_C2PMSG_83, requested_dispclk_khz / 1000);
REG_WRITE(MP1_SMN_C2PMSG_83, requested_dispclk_khz / 1000);
/* Trigger the message transaction by writing the message ID */
//dm_write_reg(ctx, mmMP1_SMN_C2PMSG_67, VBIOSSMC_MSG_SetDispclkFreq);
REG_WRITE(MP1_SMN_C2PMSG_67, VBIOSSMC_MSG_SetDispclkFreq);
REG_WAIT(MP1_SMN_C2PMSG_91, CONTENT, 1, 10, 200000);
/* Actual dispclk set is returned in the parameter register */
actual_dispclk_set_khz = REG_READ(MP1_SMN_C2PMSG_83) * 1000;
return actual_dispclk_set_khz;
}
int dcn10_set_dprefclk(struct clk_mgr *clk_mgr_base)
{
int actual_dprefclk_set_khz = -1;
struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr_base);
REG_WRITE(MP1_SMN_C2PMSG_91, 0);
/* Set the parameter register for the SMU message */
REG_WRITE(MP1_SMN_C2PMSG_83, clk_mgr_dce->dprefclk_khz / 1000);
/* Trigger the message transaction by writing the message ID */
REG_WRITE(MP1_SMN_C2PMSG_67, VBIOSSMC_MSG_SetDprefclkFreq);
/* Wait for SMU response */
REG_WAIT(MP1_SMN_C2PMSG_91, CONTENT, 1, 10, 200000);
actual_dprefclk_set_khz = REG_READ(MP1_SMN_C2PMSG_83) * 1000;
return actual_dprefclk_set_khz;
}
int (*set_dispclk)(struct pp_smu *pp_smu, int dispclk);
int (*set_dprefclk)(struct pp_smu *pp_smu);
static struct clk_mgr_funcs dcn1_funcs = {
.get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
.update_clocks = dcn1_update_clocks .update_clocks = dcn1_update_clocks
}; };
...@@ -266,8 +332,8 @@ struct clk_mgr *dcn1_clk_mgr_create(struct dc_context *ctx) ...@@ -266,8 +332,8 @@ struct clk_mgr *dcn1_clk_mgr_create(struct dc_context *ctx)
clk_mgr_dce->dprefclk_ss_percentage = 0; clk_mgr_dce->dprefclk_ss_percentage = 0;
clk_mgr_dce->dprefclk_ss_divider = 1000; clk_mgr_dce->dprefclk_ss_divider = 1000;
clk_mgr_dce->ss_on_dprefclk = false; clk_mgr_dce->ss_on_dprefclk = false;
clk_mgr_dce->dprefclk_khz = 600000; clk_mgr_dce->dprefclk_khz = 600000;
if (bp->integrated_info) if (bp->integrated_info)
clk_mgr_dce->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq; clk_mgr_dce->dentist_vco_freq_khz = bp->integrated_info->dentist_vco_freq;
if (clk_mgr_dce->dentist_vco_freq_khz == 0) { if (clk_mgr_dce->dentist_vco_freq_khz == 0) {
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include "resource.h" #include "resource.h"
#include "include/irq_service_interface.h" #include "include/irq_service_interface.h"
#include "dcn10_resource.h" #include "dcn10_resource.h"
#include "dcn10_ipp.h" #include "dcn10_ipp.h"
#include "dcn10_mpc.h" #include "dcn10_mpc.h"
#include "irq/dcn10/irq_service_dcn10.h" #include "irq/dcn10/irq_service_dcn10.h"
...@@ -445,7 +444,6 @@ static const struct bios_registers bios_regs = { ...@@ -445,7 +444,6 @@ static const struct bios_registers bios_regs = {
HUBP_REG_LIST_DCN10(id)\ HUBP_REG_LIST_DCN10(id)\
} }
static const struct dcn_mi_registers hubp_regs[] = { static const struct dcn_mi_registers hubp_regs[] = {
hubp_regs(0), hubp_regs(0),
hubp_regs(1), hubp_regs(1),
...@@ -461,7 +459,6 @@ static const struct dcn_mi_mask hubp_mask = { ...@@ -461,7 +459,6 @@ static const struct dcn_mi_mask hubp_mask = {
HUBP_MASK_SH_LIST_DCN10(_MASK) HUBP_MASK_SH_LIST_DCN10(_MASK)
}; };
static const struct dcn_hubbub_registers hubbub_reg = { static const struct dcn_hubbub_registers hubbub_reg = {
HUBBUB_REG_LIST_DCN10(0) HUBBUB_REG_LIST_DCN10(0)
}; };
...@@ -494,6 +491,27 @@ static const struct dce110_clk_src_mask cs_mask = { ...@@ -494,6 +491,27 @@ static const struct dce110_clk_src_mask cs_mask = {
CS_COMMON_MASK_SH_LIST_DCN1_0(_MASK) CS_COMMON_MASK_SH_LIST_DCN1_0(_MASK)
}; };
#define mmMP1_SMN_C2PMSG_91 0x1629B
#define mmMP1_SMN_C2PMSG_83 0x16293
#define mmMP1_SMN_C2PMSG_67 0x16283
#define MP1_SMN_C2PMSG_91__CONTENT_MASK 0xffffffffL
#define MP1_SMN_C2PMSG_83__CONTENT_MASK 0xffffffffL
#define MP1_SMN_C2PMSG_67__CONTENT_MASK 0xffffffffL
#define MP1_SMN_C2PMSG_91__CONTENT__SHIFT 0x00000000
#define MP1_SMN_C2PMSG_83__CONTENT__SHIFT 0x00000000
#define MP1_SMN_C2PMSG_67__CONTENT__SHIFT 0x00000000
static const struct clk_mgr_shift clk_mgr_shift = {
CLK_MASK_SH_LIST_RV1(__SHIFT)
};
static const struct clk_mgr_mask clk_mgr_mask = {
CLK_MASK_SH_LIST_RV1(_MASK)
};
static const struct resource_caps res_cap = { static const struct resource_caps res_cap = {
.num_timing_generator = 4, .num_timing_generator = 4,
.num_opp = 4, .num_opp = 4,
...@@ -1343,12 +1361,6 @@ static bool construct( ...@@ -1343,12 +1361,6 @@ static bool construct(
goto fail; goto fail;
} }
} }
pool->base.clk_mgr = dcn1_clk_mgr_create(ctx);
if (pool->base.clk_mgr == NULL) {
dm_error("DC: failed to create display clock!\n");
BREAK_TO_DEBUGGER();
goto fail;
}
pool->base.dmcu = dcn10_dmcu_create(ctx, pool->base.dmcu = dcn10_dmcu_create(ctx,
&dmcu_regs, &dmcu_regs,
...@@ -1410,6 +1422,13 @@ static bool construct( ...@@ -1410,6 +1422,13 @@ static bool construct(
pool->base.pp_smu = dcn10_pp_smu_create(ctx); pool->base.pp_smu = dcn10_pp_smu_create(ctx);
pool->base.clk_mgr = dcn1_clk_mgr_create(ctx);
if (pool->base.clk_mgr == NULL) {
dm_error("DC: failed to create display clock!\n");
BREAK_TO_DEBUGGER();
goto fail;
}
if (!dc->debug.disable_pplib_clock_request) if (!dc->debug.disable_pplib_clock_request)
dcn_bw_update_from_pplib(dc); dcn_bw_update_from_pplib(dc);
dcn_bw_sync_calcs_and_dml(dc); dcn_bw_sync_calcs_and_dml(dc);
......
...@@ -80,6 +80,7 @@ struct pp_smu_funcs_rv { ...@@ -80,6 +80,7 @@ struct pp_smu_funcs_rv {
/* PPSMC_MSG_SetDisplayCount /* PPSMC_MSG_SetDisplayCount
* 0 triggers S0i2 optimization * 0 triggers S0i2 optimization
*/ */
void (*set_display_count)(struct pp_smu *pp, int count); void (*set_display_count)(struct pp_smu *pp, int count);
/* reader and writer WM's are sent together as part of one table*/ /* reader and writer WM's are sent together as part of one table*/
...@@ -115,7 +116,6 @@ struct pp_smu_funcs_rv { ...@@ -115,7 +116,6 @@ struct pp_smu_funcs_rv {
/* PME w/a */ /* PME w/a */
void (*set_pme_wa_enable)(struct pp_smu *pp); void (*set_pme_wa_enable)(struct pp_smu *pp);
}; };
struct pp_smu_funcs { struct pp_smu_funcs {
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
struct clk_mgr { struct clk_mgr {
struct dc_context *ctx; struct dc_context *ctx;
const struct clk_mgr_funcs *funcs; struct clk_mgr_funcs *funcs;
struct dc_clocks clks; struct dc_clocks clks;
}; };
...@@ -44,6 +44,12 @@ struct clk_mgr_funcs { ...@@ -44,6 +44,12 @@ struct clk_mgr_funcs {
int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr); int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr);
void (*init_clocks)(struct clk_mgr *clk_mgr); void (*init_clocks)(struct clk_mgr *clk_mgr);
/* Returns actual clk that's set */
int (*set_dispclk)(struct clk_mgr *clk_mgr, int requested_dispclk_khz);
int (*set_dprefclk)(struct clk_mgr *clk_mgr);
}; };
#endif /* __DAL_CLK_MGR_H__ */ #endif /* __DAL_CLK_MGR_H__ */
...@@ -131,11 +131,12 @@ ...@@ -131,11 +131,12 @@
#define INTERNAL_REV_RAVEN_A0 0x00 /* First spin of Raven */ #define INTERNAL_REV_RAVEN_A0 0x00 /* First spin of Raven */
#define RAVEN_A0 0x01 #define RAVEN_A0 0x01
#define RAVEN_B0 0x21 #define RAVEN_B0 0x21
#define PICASSO_A0 0x41
#if defined(CONFIG_DRM_AMD_DC_DCN1_01) #if defined(CONFIG_DRM_AMD_DC_DCN1_01)
/* DCN1_01 */ /* DCN1_01 */
#define PICASSO_A0 0x41
#define RAVEN2_A0 0x81 #define RAVEN2_A0 0x81
#endif #endif
#define RAVEN1_F0 0xF0
#define RAVEN_UNKNOWN 0xFF #define RAVEN_UNKNOWN 0xFF
#if defined(CONFIG_DRM_AMD_DC_DCN1_01) #if defined(CONFIG_DRM_AMD_DC_DCN1_01)
......
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