aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/4777-drm-amd-display-add-safe_to_lower-support-to-dcn-wm-.patch
diff options
context:
space:
mode:
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-.patch463
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
+