diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/4777-drm-amd-display-add-safe_to_lower-support-to-dcn-wm-.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/4777-drm-amd-display-add-safe_to_lower-support-to-dcn-wm-.patch | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/4777-drm-amd-display-add-safe_to_lower-support-to-dcn-wm-.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/4777-drm-amd-display-add-safe_to_lower-support-to-dcn-wm-.patch new file mode 100644 index 00000000..c0f1becc --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/4777-drm-amd-display-add-safe_to_lower-support-to-dcn-wm-.patch @@ -0,0 +1,463 @@ +From 9c64a4e35d3a3709b40cc2686859421ef8a42282 Mon Sep 17 00:00:00 2001 +From: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Date: Thu, 24 May 2018 15:09:40 -0400 +Subject: [PATCH 4777/5725] drm/amd/display: add safe_to_lower support to dcn + wm programming + +This will prevent watermarks from lowering when unsafe to do so. + +Signed-off-by: Dmytro Laktyushkin <Dmytro.Laktyushkin@amd.com> +Reviewed-by: Charlene Liu <Charlene.Liu@amd.com> +Acked-by: Harry Wentland <harry.wentland@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + .../gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c | 346 +++++++++++++-------- + .../gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h | 4 +- + .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- + 3 files changed, 214 insertions(+), 138 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +index 943143e..63b75ac 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +@@ -193,7 +193,8 @@ static uint32_t convert_and_clamp( + void hubbub1_program_watermarks( + struct hubbub *hubbub, + struct dcn_watermark_set *watermarks, +- unsigned int refclk_mhz) ++ unsigned int refclk_mhz, ++ bool safe_to_lower) + { + uint32_t force_en = hubbub->ctx->dc->debug.disable_stutter ? 1 : 0; + /* +@@ -207,184 +208,257 @@ void hubbub1_program_watermarks( + + /* Repeat for water mark set A, B, C and D. */ + /* clock state A */ +- prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, +- refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); +- +- DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->a.urgent_ns, prog_wm_value); ++ if (safe_to_lower || watermarks->a.urgent_ns > hubbub->watermarks.a.urgent_ns) { ++ hubbub->watermarks.a.urgent_ns = watermarks->a.urgent_ns; ++ prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); + +- prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, +- refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->a.pte_meta_urgent_ns, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->a.urgent_ns, prog_wm_value); ++ } + +- if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) { +- prog_wm_value = convert_and_clamp( +- watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, ++ if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub->watermarks.a.pte_meta_urgent_ns) { ++ hubbub->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns; ++ prog_wm_value = convert_and_clamp(watermarks->a.pte_meta_urgent_ns, + refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" ++ REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n" + "HW register value = 0x%x\n", +- watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); ++ watermarks->a.pte_meta_urgent_ns, prog_wm_value); ++ } + ++ if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A)) { ++ if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns ++ > hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns) { ++ hubbub->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = ++ watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns; ++ prog_wm_value = convert_and_clamp( ++ watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); ++ } ++ ++ if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns ++ > hubbub->watermarks.a.cstate_pstate.cstate_exit_ns) { ++ hubbub->watermarks.a.cstate_pstate.cstate_exit_ns = ++ watermarks->a.cstate_pstate.cstate_exit_ns; ++ prog_wm_value = convert_and_clamp( ++ watermarks->a.cstate_pstate.cstate_exit_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); ++ } ++ } + ++ if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns ++ > hubbub->watermarks.a.cstate_pstate.pstate_change_ns) { ++ hubbub->watermarks.a.cstate_pstate.pstate_change_ns = ++ watermarks->a.cstate_pstate.pstate_change_ns; + prog_wm_value = convert_and_clamp( +- watermarks->a.cstate_pstate.cstate_exit_ns, ++ watermarks->a.cstate_pstate.pstate_change_ns, + refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" ++ "HW register value = 0x%x\n\n", ++ watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); + } + +- prog_wm_value = convert_and_clamp( +- watermarks->a.cstate_pstate.pstate_change_ns, +- refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" +- "HW register value = 0x%x\n\n", +- watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); +- +- + /* clock state B */ +- prog_wm_value = convert_and_clamp( +- watermarks->b.urgent_ns, refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->b.urgent_ns, prog_wm_value); +- +- +- prog_wm_value = convert_and_clamp( +- watermarks->b.pte_meta_urgent_ns, +- refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->b.pte_meta_urgent_ns, prog_wm_value); ++ if (safe_to_lower || watermarks->b.urgent_ns > hubbub->watermarks.b.urgent_ns) { ++ hubbub->watermarks.b.urgent_ns = watermarks->b.urgent_ns; ++ prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); + ++ DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->b.urgent_ns, prog_wm_value); ++ } + +- if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) { +- prog_wm_value = convert_and_clamp( +- watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, ++ if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub->watermarks.b.pte_meta_urgent_ns) { ++ hubbub->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns; ++ prog_wm_value = convert_and_clamp(watermarks->b.pte_meta_urgent_ns, + refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_B calculated =%d\n" ++ REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n" + "HW register value = 0x%x\n", +- watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); ++ watermarks->b.pte_meta_urgent_ns, prog_wm_value); ++ } + ++ if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B)) { ++ if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns ++ > hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns) { ++ hubbub->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = ++ watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns; ++ prog_wm_value = convert_and_clamp( ++ watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); ++ } + ++ if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns ++ > hubbub->watermarks.b.cstate_pstate.cstate_exit_ns) { ++ hubbub->watermarks.b.cstate_pstate.cstate_exit_ns = ++ watermarks->b.cstate_pstate.cstate_exit_ns; ++ prog_wm_value = convert_and_clamp( ++ watermarks->b.cstate_pstate.cstate_exit_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); ++ } ++ } ++ ++ if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns ++ > hubbub->watermarks.b.cstate_pstate.pstate_change_ns) { ++ hubbub->watermarks.b.cstate_pstate.pstate_change_ns = ++ watermarks->b.cstate_pstate.pstate_change_ns; + prog_wm_value = convert_and_clamp( +- watermarks->b.cstate_pstate.cstate_exit_ns, ++ watermarks->b.cstate_pstate.pstate_change_ns, + refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" ++ "HW register value = 0x%x\n\n", ++ watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); + } + +- prog_wm_value = convert_and_clamp( +- watermarks->b.cstate_pstate.pstate_change_ns, +- refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n\n" +- "HW register value = 0x%x\n", +- watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); +- + /* clock state C */ +- prog_wm_value = convert_and_clamp( +- watermarks->c.urgent_ns, refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->c.urgent_ns, prog_wm_value); +- +- +- prog_wm_value = convert_and_clamp( +- watermarks->c.pte_meta_urgent_ns, +- refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->c.pte_meta_urgent_ns, prog_wm_value); ++ if (safe_to_lower || watermarks->c.urgent_ns > hubbub->watermarks.c.urgent_ns) { ++ hubbub->watermarks.c.urgent_ns = watermarks->c.urgent_ns; ++ prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); + ++ DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->c.urgent_ns, prog_wm_value); ++ } + +- if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) { +- prog_wm_value = convert_and_clamp( +- watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, ++ if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub->watermarks.c.pte_meta_urgent_ns) { ++ hubbub->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns; ++ prog_wm_value = convert_and_clamp(watermarks->c.pte_meta_urgent_ns, + refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_C calculated =%d\n" ++ REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n" + "HW register value = 0x%x\n", +- watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); ++ watermarks->c.pte_meta_urgent_ns, prog_wm_value); ++ } + ++ if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C)) { ++ if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns ++ > hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns) { ++ hubbub->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = ++ watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns; ++ prog_wm_value = convert_and_clamp( ++ watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); ++ } + ++ if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns ++ > hubbub->watermarks.c.cstate_pstate.cstate_exit_ns) { ++ hubbub->watermarks.c.cstate_pstate.cstate_exit_ns = ++ watermarks->c.cstate_pstate.cstate_exit_ns; ++ prog_wm_value = convert_and_clamp( ++ watermarks->c.cstate_pstate.cstate_exit_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); ++ } ++ } ++ ++ if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns ++ > hubbub->watermarks.c.cstate_pstate.pstate_change_ns) { ++ hubbub->watermarks.c.cstate_pstate.pstate_change_ns = ++ watermarks->c.cstate_pstate.pstate_change_ns; + prog_wm_value = convert_and_clamp( +- watermarks->c.cstate_pstate.cstate_exit_ns, ++ watermarks->c.cstate_pstate.pstate_change_ns, + refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" ++ "HW register value = 0x%x\n\n", ++ watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); + } + +- prog_wm_value = convert_and_clamp( +- watermarks->c.cstate_pstate.pstate_change_ns, +- refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n\n" +- "HW register value = 0x%x\n", +- watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); +- + /* clock state D */ +- prog_wm_value = convert_and_clamp( +- watermarks->d.urgent_ns, refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->d.urgent_ns, prog_wm_value); +- +- prog_wm_value = convert_and_clamp( +- watermarks->d.pte_meta_urgent_ns, +- refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->d.pte_meta_urgent_ns, prog_wm_value); ++ if (safe_to_lower || watermarks->d.urgent_ns > hubbub->watermarks.d.urgent_ns) { ++ hubbub->watermarks.d.urgent_ns = watermarks->d.urgent_ns; ++ prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); + ++ DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->d.urgent_ns, prog_wm_value); ++ } + +- if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) { +- prog_wm_value = convert_and_clamp( +- watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, ++ if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub->watermarks.d.pte_meta_urgent_ns) { ++ hubbub->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns; ++ prog_wm_value = convert_and_clamp(watermarks->d.pte_meta_urgent_ns, + refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_D calculated =%d\n" ++ REG_WRITE(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n" + "HW register value = 0x%x\n", +- watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); ++ watermarks->d.pte_meta_urgent_ns, prog_wm_value); ++ } ++ ++ if (REG(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D)) { ++ if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns ++ > hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns) { ++ hubbub->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = ++ watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns; ++ prog_wm_value = convert_and_clamp( ++ watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); ++ } + ++ if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns ++ > hubbub->watermarks.d.cstate_pstate.cstate_exit_ns) { ++ hubbub->watermarks.d.cstate_pstate.cstate_exit_ns = ++ watermarks->d.cstate_pstate.cstate_exit_ns; ++ prog_wm_value = convert_and_clamp( ++ watermarks->d.cstate_pstate.cstate_exit_ns, ++ refclk_mhz, 0x1fffff); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" ++ "HW register value = 0x%x\n", ++ watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); ++ } ++ } + ++ if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns ++ > hubbub->watermarks.d.cstate_pstate.pstate_change_ns) { ++ hubbub->watermarks.d.cstate_pstate.pstate_change_ns = ++ watermarks->d.cstate_pstate.pstate_change_ns; + prog_wm_value = convert_and_clamp( +- watermarks->d.cstate_pstate.cstate_exit_ns, ++ watermarks->d.cstate_pstate.pstate_change_ns, + refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" +- "HW register value = 0x%x\n", +- watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); ++ REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); ++ DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" ++ "HW register value = 0x%x\n\n", ++ watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); + } + +- +- prog_wm_value = convert_and_clamp( +- watermarks->d.cstate_pstate.pstate_change_ns, +- refclk_mhz, 0x1fffff); +- REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); +- DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" +- "HW register value = 0x%x\n\n", +- watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); +- + REG_UPDATE(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, + DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); + +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h +index 6315a0e..0ca39cb 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h +@@ -185,6 +185,7 @@ struct hubbub { + const struct dcn_hubbub_shift *shifts; + const struct dcn_hubbub_mask *masks; + unsigned int debug_test_index_pstate; ++ struct dcn_watermark_set watermarks; + }; + + void hubbub1_update_dchub( +@@ -197,7 +198,8 @@ bool hubbub1_verify_allow_pstate_change_high( + void hubbub1_program_watermarks( + struct hubbub *hubbub, + struct dcn_watermark_set *watermarks, +- unsigned int refclk_mhz); ++ unsigned int refclk_mhz, ++ bool safe_to_lower); + + void hubbub1_toggle_watermark_change_req( + struct hubbub *hubbub); +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 db72b4d..1170ea0 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 +@@ -2314,7 +2314,7 @@ static void dcn10_apply_ctx_for_surface( + + /* watermark is for all pipes */ + hubbub1_program_watermarks(dc->res_pool->hubbub, +- &context->bw.dcn.watermarks, ref_clk_mhz); ++ &context->bw.dcn.watermarks, ref_clk_mhz, true); + + if (dc->debug.sanity_checks) { + /* pstate stuck check after watermark update */ +-- +2.7.4 + |