mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 22:21:42 +00:00
drm/amd/display: Adjust dprefclk by down spread percentage.
[Why] OLED panels show no display for large vtotal timings. [How] Check if ss is enabled and read from lut for spread spectrum percentage. Adjust dprefclk as required. DP_DTO adjustment is for edp only. Cc: stable@vger.kernel.org Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com> Signed-off-by: Zhongwei <zhongwei.zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
c3e2a5f2da
commit
e047dd448d
@ -73,6 +73,12 @@
|
||||
#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_SEL_MASK 0x00000007L
|
||||
#define CLK1_CLK2_BYPASS_CNTL__CLK2_BYPASS_DIV_MASK 0x000F0000L
|
||||
|
||||
#define regCLK5_0_CLK5_spll_field_8 0x464b
|
||||
#define regCLK5_0_CLK5_spll_field_8_BASE_IDX 0
|
||||
|
||||
#define CLK5_0_CLK5_spll_field_8__spll_ssc_en__SHIFT 0xd
|
||||
#define CLK5_0_CLK5_spll_field_8__spll_ssc_en_MASK 0x00002000L
|
||||
|
||||
#define SMU_VER_THRESHOLD 0x5D4A00 //93.74.0
|
||||
|
||||
#define REG(reg_name) \
|
||||
@ -411,6 +417,17 @@ static void dcn35_dump_clk_registers(struct clk_state_registers_and_bypass *regs
|
||||
{
|
||||
}
|
||||
|
||||
static bool dcn35_is_spll_ssc_enabled(struct clk_mgr *clk_mgr_base)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
|
||||
struct dc_context *ctx = clk_mgr->base.ctx;
|
||||
uint32_t ssc_enable;
|
||||
|
||||
REG_GET(CLK5_0_CLK5_spll_field_8, spll_ssc_en, &ssc_enable);
|
||||
|
||||
return ssc_enable == 1;
|
||||
}
|
||||
|
||||
static void init_clk_states(struct clk_mgr *clk_mgr)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr);
|
||||
@ -428,7 +445,16 @@ static void init_clk_states(struct clk_mgr *clk_mgr)
|
||||
|
||||
void dcn35_init_clocks(struct clk_mgr *clk_mgr)
|
||||
{
|
||||
struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr);
|
||||
init_clk_states(clk_mgr);
|
||||
|
||||
// to adjust dp_dto reference clock if ssc is enable otherwise to apply dprefclk
|
||||
if (dcn35_is_spll_ssc_enabled(clk_mgr))
|
||||
clk_mgr->dp_dto_source_clock_in_khz =
|
||||
dce_adjust_dp_ref_freq_for_ss(clk_mgr_int, clk_mgr->dprefclk_khz);
|
||||
else
|
||||
clk_mgr->dp_dto_source_clock_in_khz = clk_mgr->dprefclk_khz;
|
||||
|
||||
}
|
||||
static struct clk_bw_params dcn35_bw_params = {
|
||||
.vram_type = Ddr4MemType,
|
||||
@ -517,6 +543,28 @@ static DpmClocks_t_dcn35 dummy_clocks;
|
||||
|
||||
static struct dcn35_watermarks dummy_wms = { 0 };
|
||||
|
||||
static struct dcn35_ss_info_table ss_info_table = {
|
||||
.ss_divider = 1000,
|
||||
.ss_percentage = {0, 0, 375, 375, 375}
|
||||
};
|
||||
|
||||
static void dcn35_read_ss_info_from_lut(struct clk_mgr_internal *clk_mgr)
|
||||
{
|
||||
struct dc_context *ctx = clk_mgr->base.ctx;
|
||||
uint32_t clock_source;
|
||||
|
||||
REG_GET(CLK1_CLK2_BYPASS_CNTL, CLK2_BYPASS_SEL, &clock_source);
|
||||
// If it's DFS mode, clock_source is 0.
|
||||
if (dcn35_is_spll_ssc_enabled(&clk_mgr->base) && (clock_source < ARRAY_SIZE(ss_info_table.ss_percentage))) {
|
||||
clk_mgr->dprefclk_ss_percentage = ss_info_table.ss_percentage[clock_source];
|
||||
|
||||
if (clk_mgr->dprefclk_ss_percentage != 0) {
|
||||
clk_mgr->ss_on_dprefclk = true;
|
||||
clk_mgr->dprefclk_ss_divider = ss_info_table.ss_divider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dcn35_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn35_watermarks *table)
|
||||
{
|
||||
int i, num_valid_sets;
|
||||
@ -1061,6 +1109,8 @@ void dcn35_clk_mgr_construct(
|
||||
dce_clock_read_ss_info(&clk_mgr->base);
|
||||
/*when clk src is from FCH, it could have ss, same clock src as DPREF clk*/
|
||||
|
||||
dcn35_read_ss_info_from_lut(&clk_mgr->base);
|
||||
|
||||
clk_mgr->base.base.bw_params = &dcn35_bw_params;
|
||||
|
||||
if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) {
|
||||
|
@ -976,7 +976,10 @@ static bool dcn31_program_pix_clk(
|
||||
struct bp_pixel_clock_parameters bp_pc_params = {0};
|
||||
enum transmitter_color_depth bp_pc_colour_depth = TRANSMITTER_COLOR_DEPTH_24;
|
||||
|
||||
if (clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz != 0)
|
||||
// Apply ssed(spread spectrum) dpref clock for edp only.
|
||||
if (clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz != 0
|
||||
&& pix_clk_params->signal_type == SIGNAL_TYPE_EDP
|
||||
&& encoding == DP_8b_10b_ENCODING)
|
||||
dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz;
|
||||
// For these signal types Driver to program DP_DTO without calling VBIOS Command table
|
||||
if (dc_is_dp_signal(pix_clk_params->signal_type) || dc_is_virtual_signal(pix_clk_params->signal_type)) {
|
||||
@ -1093,9 +1096,6 @@ static bool get_pixel_clk_frequency_100hz(
|
||||
unsigned int modulo_hz = 0;
|
||||
unsigned int dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dprefclk_khz;
|
||||
|
||||
if (clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz != 0)
|
||||
dp_dto_ref_khz = clock_source->ctx->dc->clk_mgr->dp_dto_source_clock_in_khz;
|
||||
|
||||
if (clock_source->id == CLOCK_SOURCE_ID_DP_DTO) {
|
||||
clock_hz = REG_READ(PHASE[inst]);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user