drm/amd/display: add safe_to_lower support to dcn wm programming
authorDmytro Laktyushkin <Dmytro.Laktyushkin@amd.com>
Thu, 24 May 2018 19:09:40 +0000 (15:09 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 5 Jul 2018 21:38:36 +0000 (16:38 -0500)
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>
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c

index 943143efbb823ae11e5096f21bfa7670d6914a5b..63b75ac4a1d520c2801b2532d79b14aad3c2da9b 100644 (file)
@@ -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);
 
index 6315a0e6b0d69aca4833fa5ea5ea286268b5964d..0ca39cb71968d2dea573702252006e9e865ed256 100644 (file)
@@ -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);
index 5b40c1c4d9e65b70c67247519ec16b6e243d751f..7d9c10b6d99b6f59a97611890939824d42bd26d0 100644 (file)
@@ -2299,7 +2299,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 */