mirror of
https://github.com/torvalds/linux.git
synced 2024-12-03 01:21:28 +00:00
drm/amd/display: Fix flickering caused by dccg
Always allow un-gating. Follow legacy workaround for repeated dppclk dto updates Reviewed-by: Muhammad Ahmed <ahmed.ahmed@amd.com> Signed-off-by: Hansen Dsouza <Hansen.Dsouza@amd.com> Signed-off-by: Hamza Mahfooz <hamza.mahfooz@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
29d3d6af43
commit
9888773753
@ -328,6 +328,17 @@
|
||||
type DPSTREAMCLK1_GATE_DISABLE;\
|
||||
type DPSTREAMCLK2_GATE_DISABLE;\
|
||||
type DPSTREAMCLK3_GATE_DISABLE;\
|
||||
type SYMCLKA_FE_GATE_DISABLE;\
|
||||
type SYMCLKB_FE_GATE_DISABLE;\
|
||||
type SYMCLKC_FE_GATE_DISABLE;\
|
||||
type SYMCLKD_FE_GATE_DISABLE;\
|
||||
type SYMCLKE_FE_GATE_DISABLE;\
|
||||
type SYMCLKA_GATE_DISABLE;\
|
||||
type SYMCLKB_GATE_DISABLE;\
|
||||
type SYMCLKC_GATE_DISABLE;\
|
||||
type SYMCLKD_GATE_DISABLE;\
|
||||
type SYMCLKE_GATE_DISABLE;\
|
||||
|
||||
|
||||
#define DCCG401_REG_FIELD_LIST(type) \
|
||||
type OTG0_TMDS_PIXEL_RATE_DIV;\
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "reg_helper.h"
|
||||
#include "core_types.h"
|
||||
#include "resource.h"
|
||||
#include "dcn35_dccg.h"
|
||||
|
||||
#define TO_DCN_DCCG(dccg)\
|
||||
@ -136,7 +137,7 @@ static void dccg35_set_dsc_clk_rcg(struct dccg *dccg, int inst, bool enable)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dsc && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -165,7 +166,7 @@ static void dccg35_set_symclk32_se_rcg(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)
|
||||
return;
|
||||
|
||||
/* SYMCLK32_ROOT_SE#_GATE_DISABLE will clock gate in DCCG */
|
||||
@ -204,7 +205,7 @@ static void dccg35_set_symclk32_le_rcg(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_le && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -231,7 +232,7 @@ static void dccg35_set_physymclk_rcg(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -262,35 +263,45 @@ static void dccg35_set_physymclk_rcg(
|
||||
}
|
||||
|
||||
static void dccg35_set_symclk_fe_rcg(
|
||||
struct dccg *dccg,
|
||||
int inst,
|
||||
bool enable)
|
||||
struct dccg *dccg,
|
||||
int inst,
|
||||
bool enable)
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
case 0:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKA_FE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKA_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
SYMCLKA_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKB_FE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKB_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
SYMCLKB_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKC_FE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKC_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
SYMCLKC_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKD_FE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKD_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
SYMCLKD_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 4:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKE_FE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKE_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
SYMCLKE_FE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
default:
|
||||
BREAK_TO_DEBUGGER();
|
||||
@ -307,27 +318,37 @@ static void dccg35_set_symclk_be_rcg(
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
/* TBD add symclk_be in rcg control bits */
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.physymclk)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk_fe && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
case 0:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKA_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKA_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 1:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKB_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKB_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 2:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKC_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKC_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 3:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKD_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKD_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
case 4:
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2,
|
||||
SYMCLKE_GATE_DISABLE, enable ? 0 : 1);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL5,
|
||||
SYMCLKE_ROOT_GATE_DISABLE, enable ? 0 : 1);
|
||||
break;
|
||||
@ -342,7 +363,7 @@ static void dccg35_set_dtbclk_p_rcg(struct dccg *dccg, int inst, bool enable)
|
||||
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -370,7 +391,7 @@ static void dccg35_set_dppclk_rcg(struct dccg *dccg,
|
||||
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpp && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -399,7 +420,7 @@ static void dccg35_set_dpstreamclk_rcg(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.dpstream && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -436,7 +457,7 @@ static void dccg35_set_smclk32_se_rcg(
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se)
|
||||
if (!dccg->ctx->dc->debug.root_clock_optimization.bits.symclk32_se && enable)
|
||||
return;
|
||||
|
||||
switch (inst) {
|
||||
@ -1693,6 +1714,12 @@ static void dccg35_disable_symclk32_se(
|
||||
}
|
||||
}
|
||||
|
||||
static void dccg35_init_cb(struct dccg *dccg)
|
||||
{
|
||||
(void)dccg;
|
||||
/* Any RCG should be done when driver enter low power mode*/
|
||||
}
|
||||
|
||||
void dccg35_init(struct dccg *dccg)
|
||||
{
|
||||
int otg_inst;
|
||||
@ -2043,8 +2070,6 @@ static void dccg35_set_dpstreamclk_cb(
|
||||
enum dtbclk_source dtb_clk_src;
|
||||
enum dp_stream_clk_source dp_stream_clk_src;
|
||||
|
||||
ASSERT(otg_inst >= DP_STREAM_DTBCLK_P5);
|
||||
|
||||
switch (src) {
|
||||
case REFCLK:
|
||||
dtb_clk_src = DTBCLK_REFCLK;
|
||||
@ -2099,6 +2124,13 @@ static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst,
|
||||
{
|
||||
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
|
||||
|
||||
if (dccg->dpp_clock_gated[dpp_inst]) {
|
||||
/*
|
||||
* Do not update the DPPCLK DTO if the clock is stopped.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (dccg->ref_dppclk && req_dppclk) {
|
||||
int ref_dppclk = dccg->ref_dppclk;
|
||||
int modulo, phase;
|
||||
@ -2126,19 +2158,20 @@ static void dccg35_update_dpp_dto_cb(struct dccg *dccg, int dpp_inst,
|
||||
}
|
||||
|
||||
static void dccg35_dpp_root_clock_control_cb(
|
||||
struct dccg *dccg,
|
||||
unsigned int dpp_inst,
|
||||
bool power_on)
|
||||
struct dccg *dccg,
|
||||
unsigned int dpp_inst,
|
||||
bool power_on)
|
||||
{
|
||||
if (dccg->dpp_clock_gated[dpp_inst] == power_on)
|
||||
return;
|
||||
/* power_on set indicates we need to ungate
|
||||
* Currently called from optimize_bandwidth and prepare_bandwidth calls
|
||||
* Since clock source is not passed restore to refclock on ungate
|
||||
* Redundant as gating when enabled is acheived through update_dpp_dto
|
||||
*/
|
||||
if (power_on)
|
||||
dccg35_enable_dpp_clk_new(dccg, dpp_inst, DPP_REFCLK);
|
||||
else
|
||||
dccg35_disable_dpp_clk_new(dccg, dpp_inst);
|
||||
dccg35_set_dppclk_rcg(dccg, dpp_inst, !power_on);
|
||||
|
||||
dccg->dpp_clock_gated[dpp_inst] = !power_on;
|
||||
}
|
||||
|
||||
static void dccg35_enable_symclk32_se_cb(
|
||||
@ -2322,7 +2355,7 @@ static const struct dccg_funcs dccg35_funcs_new = {
|
||||
.update_dpp_dto = dccg35_update_dpp_dto_cb,
|
||||
.dpp_root_clock_control = dccg35_dpp_root_clock_control_cb,
|
||||
.get_dccg_ref_freq = dccg31_get_dccg_ref_freq,
|
||||
.dccg_init = dccg35_init,
|
||||
.dccg_init = dccg35_init_cb,
|
||||
.set_dpstreamclk = dccg35_set_dpstreamclk_cb,
|
||||
.set_dpstreamclk_root_clock_gating = dccg35_set_dpstreamclk_root_clock_gating_cb,
|
||||
.enable_symclk32_se = dccg35_enable_symclk32_se_cb,
|
||||
|
@ -147,37 +147,6 @@ void dcn35_init_hw(struct dc *dc)
|
||||
hws->funcs.bios_golden_init(dc);
|
||||
}
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);
|
||||
|
||||
/* Disable gating for PHYASYMCLK. This will be enabled in dccg if needed */
|
||||
REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, PHYASYMCLK_ROOT_GATE_DISABLE, 1,
|
||||
PHYBSYMCLK_ROOT_GATE_DISABLE, 1,
|
||||
PHYCSYMCLK_ROOT_GATE_DISABLE, 1,
|
||||
PHYDSYMCLK_ROOT_GATE_DISABLE, 1,
|
||||
PHYESYMCLK_ROOT_GATE_DISABLE, 1);
|
||||
|
||||
REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL4,
|
||||
DPIASYMCLK0_GATE_DISABLE, 0,
|
||||
DPIASYMCLK1_GATE_DISABLE, 0,
|
||||
DPIASYMCLK2_GATE_DISABLE, 0,
|
||||
DPIASYMCLK3_GATE_DISABLE, 0);
|
||||
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL5, 0xFFFFFFFF);
|
||||
REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL5,
|
||||
DTBCLK_P0_GATE_DISABLE, 0,
|
||||
DTBCLK_P1_GATE_DISABLE, 0,
|
||||
DTBCLK_P2_GATE_DISABLE, 0,
|
||||
DTBCLK_P3_GATE_DISABLE, 0);
|
||||
REG_UPDATE_4(DCCG_GATE_DISABLE_CNTL5,
|
||||
DPSTREAMCLK0_GATE_DISABLE, 0,
|
||||
DPSTREAMCLK1_GATE_DISABLE, 0,
|
||||
DPSTREAMCLK2_GATE_DISABLE, 0,
|
||||
DPSTREAMCLK3_GATE_DISABLE, 0);
|
||||
|
||||
}
|
||||
|
||||
// Initialize the dccg
|
||||
if (res_pool->dccg->funcs->dccg_init)
|
||||
res_pool->dccg->funcs->dccg_init(res_pool->dccg);
|
||||
@ -305,20 +274,6 @@ void dcn35_init_hw(struct dc *dc)
|
||||
|
||||
if (!dc->debug.disable_clock_gate) {
|
||||
/* enable all DCN clock gating */
|
||||
REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);
|
||||
|
||||
REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, SYMCLKA_FE_GATE_DISABLE, 0,
|
||||
SYMCLKB_FE_GATE_DISABLE, 0,
|
||||
SYMCLKC_FE_GATE_DISABLE, 0,
|
||||
SYMCLKD_FE_GATE_DISABLE, 0,
|
||||
SYMCLKE_FE_GATE_DISABLE, 0);
|
||||
REG_UPDATE(DCCG_GATE_DISABLE_CNTL2, HDMICHARCLK0_GATE_DISABLE, 0);
|
||||
REG_UPDATE_5(DCCG_GATE_DISABLE_CNTL2, SYMCLKA_GATE_DISABLE, 0,
|
||||
SYMCLKB_GATE_DISABLE, 0,
|
||||
SYMCLKC_GATE_DISABLE, 0,
|
||||
SYMCLKD_GATE_DISABLE, 0,
|
||||
SYMCLKE_GATE_DISABLE, 0);
|
||||
|
||||
REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user