drm/amd/display: fix yellow carp wm clamping
authorjsg <jsg@openbsd.org>
Thu, 24 Feb 2022 13:14:18 +0000 (13:14 +0000)
committerjsg <jsg@openbsd.org>
Thu, 24 Feb 2022 13:14:18 +0000 (13:14 +0000)
From Dmytro Laktyushkin
1ddab2ee882900df817dd89882618356b7ecbab3 in linux 5.15.y/5.15.25
60fdf98a774eee244a4e00c34a9e7729b61d0f44 in mainline linux

sys/dev/pci/drm/amd/display/dc/dcn31/dcn31_hubbub.c

index 90c73a1..5e3bcaf 100644 (file)
@@ -138,8 +138,11 @@ static uint32_t convert_and_clamp(
        ret_val = wm_ns * refclk_mhz;
        ret_val /= 1000;
 
-       if (ret_val > clamp_value)
+       if (ret_val > clamp_value) {
+               /* clamping WMs is abnormal, unexpected and may lead to underflow*/
+               ASSERT(0);
                ret_val = clamp_value;
+       }
 
        return ret_val;
 }
@@ -159,7 +162,7 @@ static bool hubbub31_program_urgent_watermarks(
        if (safe_to_lower || watermarks->a.urgent_ns > hubbub2->watermarks.a.urgent_ns) {
                hubbub2->watermarks.a.urgent_ns = watermarks->a.urgent_ns;
                prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0x3fff);
                REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0,
                                DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value);
 
@@ -193,7 +196,7 @@ static bool hubbub31_program_urgent_watermarks(
        if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub2->watermarks.a.urgent_latency_ns) {
                hubbub2->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns;
                prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0x3fff);
                REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0,
                                DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value);
        } else if (watermarks->a.urgent_latency_ns < hubbub2->watermarks.a.urgent_latency_ns)
@@ -203,7 +206,7 @@ static bool hubbub31_program_urgent_watermarks(
        if (safe_to_lower || watermarks->b.urgent_ns > hubbub2->watermarks.b.urgent_ns) {
                hubbub2->watermarks.b.urgent_ns = watermarks->b.urgent_ns;
                prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0x3fff);
                REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0,
                                DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value);
 
@@ -237,7 +240,7 @@ static bool hubbub31_program_urgent_watermarks(
        if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub2->watermarks.b.urgent_latency_ns) {
                hubbub2->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns;
                prog_wm_value = convert_and_clamp(watermarks->b.urgent_latency_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0x3fff);
                REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0,
                                DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value);
        } else if (watermarks->b.urgent_latency_ns < hubbub2->watermarks.b.urgent_latency_ns)
@@ -247,7 +250,7 @@ static bool hubbub31_program_urgent_watermarks(
        if (safe_to_lower || watermarks->c.urgent_ns > hubbub2->watermarks.c.urgent_ns) {
                hubbub2->watermarks.c.urgent_ns = watermarks->c.urgent_ns;
                prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0x3fff);
                REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0,
                                DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value);
 
@@ -281,7 +284,7 @@ static bool hubbub31_program_urgent_watermarks(
        if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub2->watermarks.c.urgent_latency_ns) {
                hubbub2->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns;
                prog_wm_value = convert_and_clamp(watermarks->c.urgent_latency_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0x3fff);
                REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0,
                                DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value);
        } else if (watermarks->c.urgent_latency_ns < hubbub2->watermarks.c.urgent_latency_ns)
@@ -291,7 +294,7 @@ static bool hubbub31_program_urgent_watermarks(
        if (safe_to_lower || watermarks->d.urgent_ns > hubbub2->watermarks.d.urgent_ns) {
                hubbub2->watermarks.d.urgent_ns = watermarks->d.urgent_ns;
                prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0x3fff);
                REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0,
                                DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value);
 
@@ -325,7 +328,7 @@ static bool hubbub31_program_urgent_watermarks(
        if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub2->watermarks.d.urgent_latency_ns) {
                hubbub2->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns;
                prog_wm_value = convert_and_clamp(watermarks->d.urgent_latency_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0x3fff);
                REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0,
                                DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value);
        } else if (watermarks->d.urgent_latency_ns < hubbub2->watermarks.d.urgent_latency_ns)
@@ -351,7 +354,7 @@ static bool hubbub31_program_stutter_watermarks(
                                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);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0,
                                DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
@@ -367,7 +370,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->a.cstate_pstate.cstate_exit_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->a.cstate_pstate.cstate_exit_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0,
                                DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
@@ -383,7 +386,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->a.cstate_pstate.cstate_enter_plus_exit_z8_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, 0,
                                DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_A, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_A calculated =%d\n"
@@ -399,7 +402,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->a.cstate_pstate.cstate_exit_z8_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->a.cstate_pstate.cstate_exit_z8_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, 0,
                                DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_A, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_A calculated =%d\n"
@@ -416,7 +419,7 @@ static bool hubbub31_program_stutter_watermarks(
                                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);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0,
                                DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
@@ -432,7 +435,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->b.cstate_pstate.cstate_exit_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->b.cstate_pstate.cstate_exit_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0,
                                DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
@@ -448,7 +451,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->b.cstate_pstate.cstate_enter_plus_exit_z8_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, 0,
                                DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_B, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_B calculated =%d\n"
@@ -464,7 +467,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->b.cstate_pstate.cstate_exit_z8_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->b.cstate_pstate.cstate_exit_z8_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, 0,
                                DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_B, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_B calculated =%d\n"
@@ -481,7 +484,7 @@ static bool hubbub31_program_stutter_watermarks(
                                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);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0,
                                DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
@@ -497,7 +500,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->c.cstate_pstate.cstate_exit_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->c.cstate_pstate.cstate_exit_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0,
                                DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
@@ -513,7 +516,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->c.cstate_pstate.cstate_enter_plus_exit_z8_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, 0,
                                DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_C, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_C calculated =%d\n"
@@ -529,7 +532,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->c.cstate_pstate.cstate_exit_z8_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->c.cstate_pstate.cstate_exit_z8_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, 0,
                                DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_C, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_C calculated =%d\n"
@@ -546,7 +549,7 @@ static bool hubbub31_program_stutter_watermarks(
                                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);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0,
                                DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
@@ -562,7 +565,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->d.cstate_pstate.cstate_exit_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->d.cstate_pstate.cstate_exit_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0,
                                DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
@@ -578,7 +581,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->d.cstate_pstate.cstate_enter_plus_exit_z8_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, 0,
                                DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_Z8_D, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_ENTER_WATERMARK_Z8_D calculated =%d\n"
@@ -594,7 +597,7 @@ static bool hubbub31_program_stutter_watermarks(
                                watermarks->d.cstate_pstate.cstate_exit_z8_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->d.cstate_pstate.cstate_exit_z8_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, 0,
                                DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_Z8_D, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_Z8_D calculated =%d\n"
@@ -625,7 +628,7 @@ static bool hubbub31_program_pstate_watermarks(
                                watermarks->a.cstate_pstate.pstate_change_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->a.cstate_pstate.pstate_change_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0,
                                DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
@@ -642,7 +645,7 @@ static bool hubbub31_program_pstate_watermarks(
                                watermarks->b.cstate_pstate.pstate_change_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->b.cstate_pstate.pstate_change_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0,
                                DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
@@ -659,7 +662,7 @@ static bool hubbub31_program_pstate_watermarks(
                                watermarks->c.cstate_pstate.pstate_change_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->c.cstate_pstate.pstate_change_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0,
                                DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
@@ -676,7 +679,7 @@ static bool hubbub31_program_pstate_watermarks(
                                watermarks->d.cstate_pstate.pstate_change_ns;
                prog_wm_value = convert_and_clamp(
                                watermarks->d.cstate_pstate.pstate_change_ns,
-                               refclk_mhz, 0x1fffff);
+                               refclk_mhz, 0xffff);
                REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0,
                                DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value);
                DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"