Commit 89e94bc5 authored by Yongqiang Sun's avatar Yongqiang Sun Committed by Alex Deucher

drm/amd/display: optimize prgoram wm and clks

[Why]
In some display configuration like 1080P monitor playing a 1080P video,
if user use ALT+F4 to exit Movie and TV, there is a chance clocks are
same only water mark changed. Current clock optimization machanism will
result in water mark keeps high after exit Movie and TV app.

[How]
Return if watermark need to be optimized when doing program watermark,
perform the optimization after.
Signed-off-by: default avatarYongqiang Sun <yongqiang.sun@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c479912a
...@@ -1365,7 +1365,7 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) ...@@ -1365,7 +1365,7 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
int i; int i;
struct dc_state *context = dc->current_state; struct dc_state *context = dc->current_state;
if (!dc->optimized_required || dc->optimize_seamless_boot_streams > 0) if ((!dc->clk_optimized_required && !dc->wm_optimized_required) || dc->optimize_seamless_boot_streams > 0)
return true; return true;
post_surface_trace(dc); post_surface_trace(dc);
...@@ -1377,8 +1377,6 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) ...@@ -1377,8 +1377,6 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]); dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]);
} }
dc->optimized_required = false;
dc->hwss.optimize_bandwidth(dc, context); dc->hwss.optimize_bandwidth(dc, context);
return true; return true;
} }
...@@ -1826,10 +1824,10 @@ enum surface_update_type dc_check_update_surfaces_for_stream( ...@@ -1826,10 +1824,10 @@ enum surface_update_type dc_check_update_surfaces_for_stream(
// If there's an available clock comparator, we use that. // If there's an available clock comparator, we use that.
if (dc->clk_mgr->funcs->are_clock_states_equal) { if (dc->clk_mgr->funcs->are_clock_states_equal) {
if (!dc->clk_mgr->funcs->are_clock_states_equal(&dc->clk_mgr->clks, &dc->current_state->bw_ctx.bw.dcn.clk)) if (!dc->clk_mgr->funcs->are_clock_states_equal(&dc->clk_mgr->clks, &dc->current_state->bw_ctx.bw.dcn.clk))
dc->optimized_required = true; dc->clk_optimized_required = true;
// Else we fallback to mem compare. // Else we fallback to mem compare.
} else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) { } else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) {
dc->optimized_required = true; dc->clk_optimized_required = true;
} }
} }
...@@ -2200,7 +2198,7 @@ static void commit_planes_for_stream(struct dc *dc, ...@@ -2200,7 +2198,7 @@ static void commit_planes_for_stream(struct dc *dc,
dc->optimize_seamless_boot_streams--; dc->optimize_seamless_boot_streams--;
if (dc->optimize_seamless_boot_streams == 0) if (dc->optimize_seamless_boot_streams == 0)
dc->optimized_required = true; dc->clk_optimized_required = true;
} }
} }
......
...@@ -520,7 +520,8 @@ struct dc { ...@@ -520,7 +520,8 @@ struct dc {
struct dce_hwseq *hwseq; struct dce_hwseq *hwseq;
/* Require to optimize clocks and bandwidth for added/removed planes */ /* Require to optimize clocks and bandwidth for added/removed planes */
bool optimized_required; bool clk_optimized_required;
bool wm_optimized_required;
/* Require to maintain clocks and bandwidth for UEFI enabled HW */ /* Require to maintain clocks and bandwidth for UEFI enabled HW */
int optimize_seamless_boot_streams; int optimize_seamless_boot_streams;
......
...@@ -243,7 +243,7 @@ void hubbub1_wm_change_req_wa(struct hubbub *hubbub) ...@@ -243,7 +243,7 @@ void hubbub1_wm_change_req_wa(struct hubbub *hubbub)
DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
} }
void hubbub1_program_urgent_watermarks( bool hubbub1_program_urgent_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
...@@ -251,6 +251,7 @@ void hubbub1_program_urgent_watermarks( ...@@ -251,6 +251,7 @@ void hubbub1_program_urgent_watermarks(
{ {
struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
uint32_t prog_wm_value; uint32_t prog_wm_value;
bool wm_pending = false;
/* Repeat for water mark set A, B, C and D. */ /* Repeat for water mark set A, B, C and D. */
/* clock state A */ /* clock state A */
...@@ -264,7 +265,8 @@ void hubbub1_program_urgent_watermarks( ...@@ -264,7 +265,8 @@ void hubbub1_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->a.urgent_ns, prog_wm_value); watermarks->a.urgent_ns, prog_wm_value);
} } else if (watermarks->a.urgent_ns < hubbub1->watermarks.a.urgent_ns)
wm_pending = true;
if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub1->watermarks.a.pte_meta_urgent_ns) { if (safe_to_lower || watermarks->a.pte_meta_urgent_ns > hubbub1->watermarks.a.pte_meta_urgent_ns) {
hubbub1->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns; hubbub1->watermarks.a.pte_meta_urgent_ns = watermarks->a.pte_meta_urgent_ns;
...@@ -274,7 +276,8 @@ void hubbub1_program_urgent_watermarks( ...@@ -274,7 +276,8 @@ void hubbub1_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->a.pte_meta_urgent_ns, prog_wm_value); watermarks->a.pte_meta_urgent_ns, prog_wm_value);
} } else if (watermarks->a.pte_meta_urgent_ns < hubbub1->watermarks.a.pte_meta_urgent_ns)
wm_pending = true;
/* clock state B */ /* clock state B */
if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) { if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) {
...@@ -287,7 +290,8 @@ void hubbub1_program_urgent_watermarks( ...@@ -287,7 +290,8 @@ void hubbub1_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->b.urgent_ns, prog_wm_value); watermarks->b.urgent_ns, prog_wm_value);
} } else if (watermarks->b.urgent_ns < hubbub1->watermarks.b.urgent_ns)
wm_pending = true;
if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub1->watermarks.b.pte_meta_urgent_ns) { if (safe_to_lower || watermarks->b.pte_meta_urgent_ns > hubbub1->watermarks.b.pte_meta_urgent_ns) {
hubbub1->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns; hubbub1->watermarks.b.pte_meta_urgent_ns = watermarks->b.pte_meta_urgent_ns;
...@@ -297,7 +301,8 @@ void hubbub1_program_urgent_watermarks( ...@@ -297,7 +301,8 @@ void hubbub1_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->b.pte_meta_urgent_ns, prog_wm_value); watermarks->b.pte_meta_urgent_ns, prog_wm_value);
} } else if (watermarks->b.pte_meta_urgent_ns < hubbub1->watermarks.b.pte_meta_urgent_ns)
wm_pending = true;
/* clock state C */ /* clock state C */
if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) { if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) {
...@@ -310,7 +315,8 @@ void hubbub1_program_urgent_watermarks( ...@@ -310,7 +315,8 @@ void hubbub1_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->c.urgent_ns, prog_wm_value); watermarks->c.urgent_ns, prog_wm_value);
} } else if (watermarks->c.urgent_ns < hubbub1->watermarks.c.urgent_ns)
wm_pending = true;
if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub1->watermarks.c.pte_meta_urgent_ns) { if (safe_to_lower || watermarks->c.pte_meta_urgent_ns > hubbub1->watermarks.c.pte_meta_urgent_ns) {
hubbub1->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns; hubbub1->watermarks.c.pte_meta_urgent_ns = watermarks->c.pte_meta_urgent_ns;
...@@ -320,7 +326,8 @@ void hubbub1_program_urgent_watermarks( ...@@ -320,7 +326,8 @@ void hubbub1_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->c.pte_meta_urgent_ns, prog_wm_value); watermarks->c.pte_meta_urgent_ns, prog_wm_value);
} } else if (watermarks->c.pte_meta_urgent_ns < hubbub1->watermarks.c.pte_meta_urgent_ns)
wm_pending = true;
/* clock state D */ /* clock state D */
if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) { if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) {
...@@ -333,7 +340,8 @@ void hubbub1_program_urgent_watermarks( ...@@ -333,7 +340,8 @@ void hubbub1_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->d.urgent_ns, prog_wm_value); watermarks->d.urgent_ns, prog_wm_value);
} } else if (watermarks->d.urgent_ns < hubbub1->watermarks.d.urgent_ns)
wm_pending = true;
if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub1->watermarks.d.pte_meta_urgent_ns) { if (safe_to_lower || watermarks->d.pte_meta_urgent_ns > hubbub1->watermarks.d.pte_meta_urgent_ns) {
hubbub1->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns; hubbub1->watermarks.d.pte_meta_urgent_ns = watermarks->d.pte_meta_urgent_ns;
...@@ -343,10 +351,13 @@ void hubbub1_program_urgent_watermarks( ...@@ -343,10 +351,13 @@ void hubbub1_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("PTE_META_URGENCY_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->d.pte_meta_urgent_ns, prog_wm_value); watermarks->d.pte_meta_urgent_ns, prog_wm_value);
} } else if (watermarks->d.pte_meta_urgent_ns < hubbub1->watermarks.d.pte_meta_urgent_ns)
wm_pending = true;
return wm_pending;
} }
void hubbub1_program_stutter_watermarks( bool hubbub1_program_stutter_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
...@@ -354,6 +365,7 @@ void hubbub1_program_stutter_watermarks( ...@@ -354,6 +365,7 @@ void hubbub1_program_stutter_watermarks(
{ {
struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
uint32_t prog_wm_value; uint32_t prog_wm_value;
bool wm_pending = false;
/* clock state A */ /* clock state A */
if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
...@@ -368,7 +380,9 @@ void hubbub1_program_stutter_watermarks( ...@@ -368,7 +380,9 @@ void hubbub1_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
} } else if (watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
< hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns)
wm_pending = true;
if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
> hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) { > hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) {
...@@ -382,7 +396,9 @@ void hubbub1_program_stutter_watermarks( ...@@ -382,7 +396,9 @@ void hubbub1_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
} } else if (watermarks->a.cstate_pstate.cstate_exit_ns
< hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns)
wm_pending = true;
/* clock state B */ /* clock state B */
if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
...@@ -397,7 +413,9 @@ void hubbub1_program_stutter_watermarks( ...@@ -397,7 +413,9 @@ void hubbub1_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
} } else if (watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
< hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns)
wm_pending = true;
if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
> hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) { > hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) {
...@@ -411,7 +429,9 @@ void hubbub1_program_stutter_watermarks( ...@@ -411,7 +429,9 @@ void hubbub1_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
} } else if (watermarks->b.cstate_pstate.cstate_exit_ns
< hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns)
wm_pending = true;
/* clock state C */ /* clock state C */
if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
...@@ -426,7 +446,9 @@ void hubbub1_program_stutter_watermarks( ...@@ -426,7 +446,9 @@ void hubbub1_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
} } else if (watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
< hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns)
wm_pending = true;
if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
> hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) { > hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) {
...@@ -440,7 +462,9 @@ void hubbub1_program_stutter_watermarks( ...@@ -440,7 +462,9 @@ void hubbub1_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
} } else if (watermarks->c.cstate_pstate.cstate_exit_ns
< hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns)
wm_pending = true;
/* clock state D */ /* clock state D */
if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
...@@ -455,7 +479,9 @@ void hubbub1_program_stutter_watermarks( ...@@ -455,7 +479,9 @@ void hubbub1_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
} } else if (watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
< hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns)
wm_pending = true;
if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
> hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) { > hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) {
...@@ -469,11 +495,14 @@ void hubbub1_program_stutter_watermarks( ...@@ -469,11 +495,14 @@ void hubbub1_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
} } else if (watermarks->d.cstate_pstate.cstate_exit_ns
< hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns)
wm_pending = true;
return wm_pending;
} }
void hubbub1_program_pstate_watermarks( bool hubbub1_program_pstate_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
...@@ -481,6 +510,7 @@ void hubbub1_program_pstate_watermarks( ...@@ -481,6 +510,7 @@ void hubbub1_program_pstate_watermarks(
{ {
struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
uint32_t prog_wm_value; uint32_t prog_wm_value;
bool wm_pending = false;
/* clock state A */ /* clock state A */
if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
...@@ -495,7 +525,9 @@ void hubbub1_program_pstate_watermarks( ...@@ -495,7 +525,9 @@ void hubbub1_program_pstate_watermarks(
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n\n", "HW register value = 0x%x\n\n",
watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
} } else if (watermarks->a.cstate_pstate.pstate_change_ns
< hubbub1->watermarks.a.cstate_pstate.pstate_change_ns)
wm_pending = true;
/* clock state B */ /* clock state B */
if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
...@@ -510,7 +542,9 @@ void hubbub1_program_pstate_watermarks( ...@@ -510,7 +542,9 @@ void hubbub1_program_pstate_watermarks(
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n\n", "HW register value = 0x%x\n\n",
watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
} } else if (watermarks->b.cstate_pstate.pstate_change_ns
< hubbub1->watermarks.b.cstate_pstate.pstate_change_ns)
wm_pending = true;
/* clock state C */ /* clock state C */
if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
...@@ -525,7 +559,9 @@ void hubbub1_program_pstate_watermarks( ...@@ -525,7 +559,9 @@ void hubbub1_program_pstate_watermarks(
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n\n", "HW register value = 0x%x\n\n",
watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
} } else if (watermarks->c.cstate_pstate.pstate_change_ns
< hubbub1->watermarks.c.cstate_pstate.pstate_change_ns)
wm_pending = true;
/* clock state D */ /* clock state D */
if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
...@@ -540,23 +576,33 @@ void hubbub1_program_pstate_watermarks( ...@@ -540,23 +576,33 @@ void hubbub1_program_pstate_watermarks(
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n\n", "HW register value = 0x%x\n\n",
watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
} } else if (watermarks->d.cstate_pstate.pstate_change_ns
< hubbub1->watermarks.d.cstate_pstate.pstate_change_ns)
wm_pending = true;
return wm_pending;
} }
void hubbub1_program_watermarks( bool hubbub1_program_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
bool safe_to_lower) bool safe_to_lower)
{ {
struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub); struct dcn10_hubbub *hubbub1 = TO_DCN10_HUBBUB(hubbub);
bool wm_pending = false;
/* /*
* Need to clamp to max of the register values (i.e. no wrap) * Need to clamp to max of the register values (i.e. no wrap)
* for dcn1, all wm registers are 21-bit wide * for dcn1, all wm registers are 21-bit wide
*/ */
hubbub1_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); if (hubbub1_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
hubbub1_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); wm_pending = true;
hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
if (hubbub1_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
wm_pending = true;
if (hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
wm_pending = true;
REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL, REG_UPDATE(DCHUBBUB_ARB_SAT_LEVEL,
DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz); DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
...@@ -570,6 +616,7 @@ void hubbub1_program_watermarks( ...@@ -570,6 +616,7 @@ void hubbub1_program_watermarks(
DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1, DCHUBBUB_ARB_WATERMARK_CHANGE_DONE_INTERRUPT_DISABLE, 1,
DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1); DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, 1);
#endif #endif
return wm_pending;
} }
void hubbub1_update_dchub( void hubbub1_update_dchub(
......
...@@ -308,7 +308,7 @@ bool hubbub1_verify_allow_pstate_change_high( ...@@ -308,7 +308,7 @@ bool hubbub1_verify_allow_pstate_change_high(
void hubbub1_wm_change_req_wa(struct hubbub *hubbub); void hubbub1_wm_change_req_wa(struct hubbub *hubbub);
void hubbub1_program_watermarks( bool hubbub1_program_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
...@@ -331,17 +331,17 @@ void hubbub1_construct(struct hubbub *hubbub, ...@@ -331,17 +331,17 @@ void hubbub1_construct(struct hubbub *hubbub,
const struct dcn_hubbub_shift *hubbub_shift, const struct dcn_hubbub_shift *hubbub_shift,
const struct dcn_hubbub_mask *hubbub_mask); const struct dcn_hubbub_mask *hubbub_mask);
void hubbub1_program_urgent_watermarks( bool hubbub1_program_urgent_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
bool safe_to_lower); bool safe_to_lower);
void hubbub1_program_stutter_watermarks( bool hubbub1_program_stutter_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
bool safe_to_lower); bool safe_to_lower);
void hubbub1_program_pstate_watermarks( bool hubbub1_program_pstate_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
......
...@@ -1048,7 +1048,7 @@ void dcn10_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx) ...@@ -1048,7 +1048,7 @@ void dcn10_plane_atomic_disconnect(struct dc *dc, struct pipe_ctx *pipe_ctx)
if (opp != NULL) if (opp != NULL)
opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true; opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;
dc->optimized_required = true; dc->clk_optimized_required = true;
if (hubp->funcs->hubp_disconnect) if (hubp->funcs->hubp_disconnect)
hubp->funcs->hubp_disconnect(hubp); hubp->funcs->hubp_disconnect(hubp);
...@@ -1099,7 +1099,7 @@ void dcn10_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) ...@@ -1099,7 +1099,7 @@ void dcn10_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx)
false); false);
hubp->power_gated = true; hubp->power_gated = true;
dc->optimized_required = false; /* We're powering off, no need to optimize */ dc->clk_optimized_required = false; /* We're powering off, no need to optimize */
hws->funcs.plane_atomic_power_down(dc, hws->funcs.plane_atomic_power_down(dc,
pipe_ctx->plane_res.dpp, pipe_ctx->plane_res.dpp,
...@@ -2693,7 +2693,7 @@ void dcn10_prepare_bandwidth( ...@@ -2693,7 +2693,7 @@ void dcn10_prepare_bandwidth(
false); false);
} }
hubbub->funcs->program_watermarks(hubbub, dc->wm_optimized_required = hubbub->funcs->program_watermarks(hubbub,
&context->bw_ctx.bw.dcn.watermarks, &context->bw_ctx.bw.dcn.watermarks,
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
true); true);
...@@ -2717,19 +2717,30 @@ void dcn10_optimize_bandwidth( ...@@ -2717,19 +2717,30 @@ void dcn10_optimize_bandwidth(
hws->funcs.verify_allow_pstate_change_high(dc); hws->funcs.verify_allow_pstate_change_high(dc);
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
if (context->stream_count == 0) if (context->stream_count == 0) {
context->bw_ctx.bw.dcn.clk.phyclk_khz = 0; context->bw_ctx.bw.dcn.clk.phyclk_khz = 0;
dc->clk_mgr->funcs->update_clocks( dc->clk_mgr->funcs->update_clocks(
dc->clk_mgr, dc->clk_mgr,
context, context,
true);
} else if (dc->clk_optimized_required || IS_DIAG_DC(dc->ctx->dce_environment)) {
dc->clk_mgr->funcs->update_clocks(
dc->clk_mgr,
context,
true);
}
}
if (dc->wm_optimized_required || IS_DIAG_DC(dc->ctx->dce_environment)) {
hubbub->funcs->program_watermarks(hubbub,
&context->bw_ctx.bw.dcn.watermarks,
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
true); true);
} }
hubbub->funcs->program_watermarks(hubbub, dc->clk_optimized_required = false;
&context->bw_ctx.bw.dcn.watermarks, dc->wm_optimized_required = false;
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
true);
dcn10_stereo_hw_frame_pack_wa(dc, context); dcn10_stereo_hw_frame_pack_wa(dc, context);
if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE) if (dc->debug.pplib_wm_report_mode == WM_REPORT_OVERRIDE)
......
...@@ -562,19 +562,23 @@ void hubbub2_get_dchub_ref_freq(struct hubbub *hubbub, ...@@ -562,19 +562,23 @@ void hubbub2_get_dchub_ref_freq(struct hubbub *hubbub,
} }
} }
static void hubbub2_program_watermarks( static bool hubbub2_program_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
bool safe_to_lower) bool safe_to_lower)
{ {
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
bool wm_pending = false;
/* /*
* Need to clamp to max of the register values (i.e. no wrap) * Need to clamp to max of the register values (i.e. no wrap)
* for dcn1, all wm registers are 21-bit wide * for dcn1, all wm registers are 21-bit wide
*/ */
hubbub1_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); if (hubbub1_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
hubbub1_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); wm_pending = true;
if (hubbub1_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
wm_pending = true;
/* /*
* There's a special case when going from p-state support to p-state unsupported * There's a special case when going from p-state support to p-state unsupported
...@@ -592,6 +596,7 @@ static void hubbub2_program_watermarks( ...@@ -592,6 +596,7 @@ static void hubbub2_program_watermarks(
REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 180); REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 180);
hubbub->funcs->allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); hubbub->funcs->allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
return wm_pending;
} }
static const struct hubbub_funcs hubbub2_funcs = { static const struct hubbub_funcs hubbub2_funcs = {
......
...@@ -1627,7 +1627,7 @@ void dcn20_prepare_bandwidth( ...@@ -1627,7 +1627,7 @@ void dcn20_prepare_bandwidth(
false); false);
/* program dchubbub watermarks */ /* program dchubbub watermarks */
hubbub->funcs->program_watermarks(hubbub, dc->wm_optimized_required = hubbub->funcs->program_watermarks(hubbub,
&context->bw_ctx.bw.dcn.watermarks, &context->bw_ctx.bw.dcn.watermarks,
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
false); false);
...@@ -1639,16 +1639,22 @@ void dcn20_optimize_bandwidth( ...@@ -1639,16 +1639,22 @@ void dcn20_optimize_bandwidth(
{ {
struct hubbub *hubbub = dc->res_pool->hubbub; struct hubbub *hubbub = dc->res_pool->hubbub;
/* program dchubbub watermarks */ if (dc->wm_optimized_required || IS_DIAG_DC(dc->ctx->dce_environment)) {
hubbub->funcs->program_watermarks(hubbub, /* program dchubbub watermarks */
&context->bw_ctx.bw.dcn.watermarks, hubbub->funcs->program_watermarks(hubbub,
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, &context->bw_ctx.bw.dcn.watermarks,
true); dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
true);
dc->wm_optimized_required = false;
}
dc->clk_mgr->funcs->update_clocks( if (dc->clk_optimized_required || IS_DIAG_DC(dc->ctx->dce_environment)) {
dc->clk_mgr, dc->clk_mgr->funcs->update_clocks(
context, dc->clk_mgr,
true); context,
true);
dc->wm_optimized_required = false;
}
} }
bool dcn20_update_bandwidth( bool dcn20_update_bandwidth(
......
...@@ -141,7 +141,7 @@ int hubbub21_init_dchub(struct hubbub *hubbub, ...@@ -141,7 +141,7 @@ int hubbub21_init_dchub(struct hubbub *hubbub,
return NUM_VMID; return NUM_VMID;
} }
void hubbub21_program_urgent_watermarks( bool hubbub21_program_urgent_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
...@@ -149,6 +149,7 @@ void hubbub21_program_urgent_watermarks( ...@@ -149,6 +149,7 @@ void hubbub21_program_urgent_watermarks(
{ {
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
uint32_t prog_wm_value; uint32_t prog_wm_value;
bool wm_pending = false;
/* Repeat for water mark set A, B, C and D. */ /* Repeat for water mark set A, B, C and D. */
/* clock state A */ /* clock state A */
...@@ -163,7 +164,8 @@ void hubbub21_program_urgent_watermarks( ...@@ -163,7 +164,8 @@ void hubbub21_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->a.urgent_ns, prog_wm_value); watermarks->a.urgent_ns, prog_wm_value);
} } else if (watermarks->a.urgent_ns < hubbub1->watermarks.a.urgent_ns)
wm_pending = true;
/* determine the transfer time for a quantity of data for a particular requestor.*/ /* determine the transfer time for a quantity of data for a particular requestor.*/
if (safe_to_lower || watermarks->a.frac_urg_bw_flip if (safe_to_lower || watermarks->a.frac_urg_bw_flip
...@@ -172,7 +174,9 @@ void hubbub21_program_urgent_watermarks( ...@@ -172,7 +174,9 @@ void hubbub21_program_urgent_watermarks(
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0, REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, 0,
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->a.frac_urg_bw_flip); DCHUBBUB_ARB_FRAC_URG_BW_FLIP_A, watermarks->a.frac_urg_bw_flip);
} } else if (watermarks->a.frac_urg_bw_flip
< hubbub1->watermarks.a.frac_urg_bw_flip)
wm_pending = true;
if (safe_to_lower || watermarks->a.frac_urg_bw_nom if (safe_to_lower || watermarks->a.frac_urg_bw_nom
> hubbub1->watermarks.a.frac_urg_bw_nom) { > hubbub1->watermarks.a.frac_urg_bw_nom) {
...@@ -180,14 +184,18 @@ void hubbub21_program_urgent_watermarks( ...@@ -180,14 +184,18 @@ void hubbub21_program_urgent_watermarks(
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0, REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, 0,
DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom); DCHUBBUB_ARB_FRAC_URG_BW_NOM_A, watermarks->a.frac_urg_bw_nom);
} } else if (watermarks->a.frac_urg_bw_nom
< hubbub1->watermarks.a.frac_urg_bw_nom)
wm_pending = true;
if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub1->watermarks.a.urgent_latency_ns) { if (safe_to_lower || watermarks->a.urgent_latency_ns > hubbub1->watermarks.a.urgent_latency_ns) {
hubbub1->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns; hubbub1->watermarks.a.urgent_latency_ns = watermarks->a.urgent_latency_ns;
prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns, prog_wm_value = convert_and_clamp(watermarks->a.urgent_latency_ns,
refclk_mhz, 0x1fffff); refclk_mhz, 0x1fffff);
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0, REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, 0,
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value); DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_A, prog_wm_value);
} } else if (watermarks->a.urgent_latency_ns < hubbub1->watermarks.a.urgent_latency_ns)
wm_pending = true;
/* clock state B */ /* clock state B */
if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) { if (safe_to_lower || watermarks->b.urgent_ns > hubbub1->watermarks.b.urgent_ns) {
...@@ -201,7 +209,8 @@ void hubbub21_program_urgent_watermarks( ...@@ -201,7 +209,8 @@ void hubbub21_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->b.urgent_ns, prog_wm_value); watermarks->b.urgent_ns, prog_wm_value);
} } else if (watermarks->b.urgent_ns < hubbub1->watermarks.b.urgent_ns)
wm_pending = true;
/* determine the transfer time for a quantity of data for a particular requestor.*/ /* determine the transfer time for a quantity of data for a particular requestor.*/
if (safe_to_lower || watermarks->a.frac_urg_bw_flip if (safe_to_lower || watermarks->a.frac_urg_bw_flip
...@@ -210,7 +219,9 @@ void hubbub21_program_urgent_watermarks( ...@@ -210,7 +219,9 @@ void hubbub21_program_urgent_watermarks(
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0, REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, 0,
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->a.frac_urg_bw_flip); DCHUBBUB_ARB_FRAC_URG_BW_FLIP_B, watermarks->a.frac_urg_bw_flip);
} } else if (watermarks->a.frac_urg_bw_flip
< hubbub1->watermarks.a.frac_urg_bw_flip)
wm_pending = true;
if (safe_to_lower || watermarks->a.frac_urg_bw_nom if (safe_to_lower || watermarks->a.frac_urg_bw_nom
> hubbub1->watermarks.a.frac_urg_bw_nom) { > hubbub1->watermarks.a.frac_urg_bw_nom) {
...@@ -218,7 +229,9 @@ void hubbub21_program_urgent_watermarks( ...@@ -218,7 +229,9 @@ void hubbub21_program_urgent_watermarks(
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0, REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, 0,
DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom); DCHUBBUB_ARB_FRAC_URG_BW_NOM_B, watermarks->a.frac_urg_bw_nom);
} } else if (watermarks->a.frac_urg_bw_nom
< hubbub1->watermarks.a.frac_urg_bw_nom)
wm_pending = true;
if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub1->watermarks.b.urgent_latency_ns) { if (safe_to_lower || watermarks->b.urgent_latency_ns > hubbub1->watermarks.b.urgent_latency_ns) {
hubbub1->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns; hubbub1->watermarks.b.urgent_latency_ns = watermarks->b.urgent_latency_ns;
...@@ -226,7 +239,8 @@ void hubbub21_program_urgent_watermarks( ...@@ -226,7 +239,8 @@ void hubbub21_program_urgent_watermarks(
refclk_mhz, 0x1fffff); refclk_mhz, 0x1fffff);
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0, REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, 0,
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value); DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_B, prog_wm_value);
} } else if (watermarks->b.urgent_latency_ns < hubbub1->watermarks.b.urgent_latency_ns)
wm_pending = true;
/* clock state C */ /* clock state C */
if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) { if (safe_to_lower || watermarks->c.urgent_ns > hubbub1->watermarks.c.urgent_ns) {
...@@ -240,7 +254,8 @@ void hubbub21_program_urgent_watermarks( ...@@ -240,7 +254,8 @@ void hubbub21_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->c.urgent_ns, prog_wm_value); watermarks->c.urgent_ns, prog_wm_value);
} } else if (watermarks->c.urgent_ns < hubbub1->watermarks.c.urgent_ns)
wm_pending = true;
/* determine the transfer time for a quantity of data for a particular requestor.*/ /* determine the transfer time for a quantity of data for a particular requestor.*/
if (safe_to_lower || watermarks->a.frac_urg_bw_flip if (safe_to_lower || watermarks->a.frac_urg_bw_flip
...@@ -249,7 +264,9 @@ void hubbub21_program_urgent_watermarks( ...@@ -249,7 +264,9 @@ void hubbub21_program_urgent_watermarks(
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, 0, REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, 0,
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, watermarks->a.frac_urg_bw_flip); DCHUBBUB_ARB_FRAC_URG_BW_FLIP_C, watermarks->a.frac_urg_bw_flip);
} } else if (watermarks->a.frac_urg_bw_flip
< hubbub1->watermarks.a.frac_urg_bw_flip)
wm_pending = true;
if (safe_to_lower || watermarks->a.frac_urg_bw_nom if (safe_to_lower || watermarks->a.frac_urg_bw_nom
> hubbub1->watermarks.a.frac_urg_bw_nom) { > hubbub1->watermarks.a.frac_urg_bw_nom) {
...@@ -257,7 +274,9 @@ void hubbub21_program_urgent_watermarks( ...@@ -257,7 +274,9 @@ void hubbub21_program_urgent_watermarks(
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, 0, REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, 0,
DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom); DCHUBBUB_ARB_FRAC_URG_BW_NOM_C, watermarks->a.frac_urg_bw_nom);
} } else if (watermarks->a.frac_urg_bw_nom
< hubbub1->watermarks.a.frac_urg_bw_nom)
wm_pending = true;
if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub1->watermarks.c.urgent_latency_ns) { if (safe_to_lower || watermarks->c.urgent_latency_ns > hubbub1->watermarks.c.urgent_latency_ns) {
hubbub1->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns; hubbub1->watermarks.c.urgent_latency_ns = watermarks->c.urgent_latency_ns;
...@@ -265,7 +284,8 @@ void hubbub21_program_urgent_watermarks( ...@@ -265,7 +284,8 @@ void hubbub21_program_urgent_watermarks(
refclk_mhz, 0x1fffff); refclk_mhz, 0x1fffff);
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0, REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, 0,
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value); DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_C, prog_wm_value);
} } else if (watermarks->c.urgent_latency_ns < hubbub1->watermarks.c.urgent_latency_ns)
wm_pending = true;
/* clock state D */ /* clock state D */
if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) { if (safe_to_lower || watermarks->d.urgent_ns > hubbub1->watermarks.d.urgent_ns) {
...@@ -279,7 +299,8 @@ void hubbub21_program_urgent_watermarks( ...@@ -279,7 +299,8 @@ void hubbub21_program_urgent_watermarks(
DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->d.urgent_ns, prog_wm_value); watermarks->d.urgent_ns, prog_wm_value);
} } else if (watermarks->d.urgent_ns < hubbub1->watermarks.d.urgent_ns)
wm_pending = true;
/* determine the transfer time for a quantity of data for a particular requestor.*/ /* determine the transfer time for a quantity of data for a particular requestor.*/
if (safe_to_lower || watermarks->a.frac_urg_bw_flip if (safe_to_lower || watermarks->a.frac_urg_bw_flip
...@@ -288,7 +309,9 @@ void hubbub21_program_urgent_watermarks( ...@@ -288,7 +309,9 @@ void hubbub21_program_urgent_watermarks(
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, 0, REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, 0,
DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, watermarks->a.frac_urg_bw_flip); DCHUBBUB_ARB_FRAC_URG_BW_FLIP_D, watermarks->a.frac_urg_bw_flip);
} } else if (watermarks->a.frac_urg_bw_flip
< hubbub1->watermarks.a.frac_urg_bw_flip)
wm_pending = true;
if (safe_to_lower || watermarks->a.frac_urg_bw_nom if (safe_to_lower || watermarks->a.frac_urg_bw_nom
> hubbub1->watermarks.a.frac_urg_bw_nom) { > hubbub1->watermarks.a.frac_urg_bw_nom) {
...@@ -296,7 +319,9 @@ void hubbub21_program_urgent_watermarks( ...@@ -296,7 +319,9 @@ void hubbub21_program_urgent_watermarks(
REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0, REG_SET(DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, 0,
DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom); DCHUBBUB_ARB_FRAC_URG_BW_NOM_D, watermarks->a.frac_urg_bw_nom);
} } else if (watermarks->a.frac_urg_bw_nom
< hubbub1->watermarks.a.frac_urg_bw_nom)
wm_pending = true;
if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub1->watermarks.d.urgent_latency_ns) { if (safe_to_lower || watermarks->d.urgent_latency_ns > hubbub1->watermarks.d.urgent_latency_ns) {
hubbub1->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns; hubbub1->watermarks.d.urgent_latency_ns = watermarks->d.urgent_latency_ns;
...@@ -304,10 +329,13 @@ void hubbub21_program_urgent_watermarks( ...@@ -304,10 +329,13 @@ void hubbub21_program_urgent_watermarks(
refclk_mhz, 0x1fffff); refclk_mhz, 0x1fffff);
REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0, REG_SET(DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, 0,
DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value); DCHUBBUB_ARB_REFCYC_PER_TRIP_TO_MEMORY_D, prog_wm_value);
} } else if (watermarks->d.urgent_latency_ns < hubbub1->watermarks.d.urgent_latency_ns)
wm_pending = true;
return wm_pending;
} }
void hubbub21_program_stutter_watermarks( bool hubbub21_program_stutter_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
...@@ -315,6 +343,7 @@ void hubbub21_program_stutter_watermarks( ...@@ -315,6 +343,7 @@ void hubbub21_program_stutter_watermarks(
{ {
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
uint32_t prog_wm_value; uint32_t prog_wm_value;
bool wm_pending = false;
/* clock state A */ /* clock state A */
if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns if (safe_to_lower || watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
...@@ -330,7 +359,9 @@ void hubbub21_program_stutter_watermarks( ...@@ -330,7 +359,9 @@ void hubbub21_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
} } else if (watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns
< hubbub1->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns)
wm_pending = true;
if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns if (safe_to_lower || watermarks->a.cstate_pstate.cstate_exit_ns
> hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) { > hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns) {
...@@ -345,7 +376,9 @@ void hubbub21_program_stutter_watermarks( ...@@ -345,7 +376,9 @@ void hubbub21_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value);
} } else if (watermarks->a.cstate_pstate.cstate_exit_ns
< hubbub1->watermarks.a.cstate_pstate.cstate_exit_ns)
wm_pending = true;
/* clock state B */ /* clock state B */
if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns if (safe_to_lower || watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
...@@ -361,7 +394,9 @@ void hubbub21_program_stutter_watermarks( ...@@ -361,7 +394,9 @@ void hubbub21_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
} } else if (watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns
< hubbub1->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns)
wm_pending = true;
if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns if (safe_to_lower || watermarks->b.cstate_pstate.cstate_exit_ns
> hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) { > hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns) {
...@@ -376,7 +411,9 @@ void hubbub21_program_stutter_watermarks( ...@@ -376,7 +411,9 @@ void hubbub21_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value);
} } else if (watermarks->b.cstate_pstate.cstate_exit_ns
< hubbub1->watermarks.b.cstate_pstate.cstate_exit_ns)
wm_pending = true;
/* clock state C */ /* clock state C */
if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns if (safe_to_lower || watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
...@@ -392,7 +429,9 @@ void hubbub21_program_stutter_watermarks( ...@@ -392,7 +429,9 @@ void hubbub21_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
} } else if (watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns
< hubbub1->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns)
wm_pending = true;
if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns if (safe_to_lower || watermarks->c.cstate_pstate.cstate_exit_ns
> hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) { > hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns) {
...@@ -407,7 +446,9 @@ void hubbub21_program_stutter_watermarks( ...@@ -407,7 +446,9 @@ void hubbub21_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value);
} } else if (watermarks->c.cstate_pstate.cstate_exit_ns
< hubbub1->watermarks.c.cstate_pstate.cstate_exit_ns)
wm_pending = true;
/* clock state D */ /* clock state D */
if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns if (safe_to_lower || watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
...@@ -423,7 +464,9 @@ void hubbub21_program_stutter_watermarks( ...@@ -423,7 +464,9 @@ void hubbub21_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value);
} } else if (watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns
< hubbub1->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns)
wm_pending = true;
if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns if (safe_to_lower || watermarks->d.cstate_pstate.cstate_exit_ns
> hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) { > hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns) {
...@@ -438,10 +481,14 @@ void hubbub21_program_stutter_watermarks( ...@@ -438,10 +481,14 @@ void hubbub21_program_stutter_watermarks(
DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n", "HW register value = 0x%x\n",
watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value);
} } else if (watermarks->d.cstate_pstate.cstate_exit_ns
< hubbub1->watermarks.d.cstate_pstate.cstate_exit_ns)
wm_pending = true;
return wm_pending;
} }
void hubbub21_program_pstate_watermarks( bool hubbub21_program_pstate_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
...@@ -450,6 +497,8 @@ void hubbub21_program_pstate_watermarks( ...@@ -450,6 +497,8 @@ void hubbub21_program_pstate_watermarks(
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
uint32_t prog_wm_value; uint32_t prog_wm_value;
bool wm_pending = false;
/* clock state A */ /* clock state A */
if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns if (safe_to_lower || watermarks->a.cstate_pstate.pstate_change_ns
> hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) { > hubbub1->watermarks.a.cstate_pstate.pstate_change_ns) {
...@@ -464,7 +513,9 @@ void hubbub21_program_pstate_watermarks( ...@@ -464,7 +513,9 @@ void hubbub21_program_pstate_watermarks(
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n"
"HW register value = 0x%x\n\n", "HW register value = 0x%x\n\n",
watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value);
} } else if (watermarks->a.cstate_pstate.pstate_change_ns
< hubbub1->watermarks.a.cstate_pstate.pstate_change_ns)
wm_pending = true;
/* clock state B */ /* clock state B */
if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns if (safe_to_lower || watermarks->b.cstate_pstate.pstate_change_ns
...@@ -480,7 +531,9 @@ void hubbub21_program_pstate_watermarks( ...@@ -480,7 +531,9 @@ void hubbub21_program_pstate_watermarks(
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n"
"HW register value = 0x%x\n\n", "HW register value = 0x%x\n\n",
watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value);
} } else if (watermarks->b.cstate_pstate.pstate_change_ns
< hubbub1->watermarks.b.cstate_pstate.pstate_change_ns)
wm_pending = false;
/* clock state C */ /* clock state C */
if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns if (safe_to_lower || watermarks->c.cstate_pstate.pstate_change_ns
...@@ -496,7 +549,9 @@ void hubbub21_program_pstate_watermarks( ...@@ -496,7 +549,9 @@ void hubbub21_program_pstate_watermarks(
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n"
"HW register value = 0x%x\n\n", "HW register value = 0x%x\n\n",
watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value);
} } else if (watermarks->c.cstate_pstate.pstate_change_ns
< hubbub1->watermarks.c.cstate_pstate.pstate_change_ns)
wm_pending = true;
/* clock state D */ /* clock state D */
if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns if (safe_to_lower || watermarks->d.cstate_pstate.pstate_change_ns
...@@ -512,20 +567,30 @@ void hubbub21_program_pstate_watermarks( ...@@ -512,20 +567,30 @@ void hubbub21_program_pstate_watermarks(
DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n"
"HW register value = 0x%x\n\n", "HW register value = 0x%x\n\n",
watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value);
} } else if (watermarks->d.cstate_pstate.pstate_change_ns
< hubbub1->watermarks.d.cstate_pstate.pstate_change_ns)
wm_pending = true;
return wm_pending;
} }
void hubbub21_program_watermarks( bool hubbub21_program_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
bool safe_to_lower) bool safe_to_lower)
{ {
struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub);
bool wm_pending = false;
if (hubbub21_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
wm_pending = true;
hubbub21_program_urgent_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); if (hubbub21_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
hubbub21_program_stutter_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower); wm_pending = true;
hubbub21_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
if (hubbub21_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
wm_pending = true;
/* /*
* The DCHub arbiter has a mechanism to dynamically rate limit the DCHub request stream to the fabric. * The DCHub arbiter has a mechanism to dynamically rate limit the DCHub request stream to the fabric.
...@@ -549,6 +614,8 @@ void hubbub21_program_watermarks( ...@@ -549,6 +614,8 @@ void hubbub21_program_watermarks(
DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF); DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF);
hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter); hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
return wm_pending;
} }
void hubbub21_wm_read_state(struct hubbub *hubbub, void hubbub21_wm_read_state(struct hubbub *hubbub,
......
...@@ -113,22 +113,22 @@ ...@@ -113,22 +113,22 @@
void dcn21_dchvm_init(struct hubbub *hubbub); void dcn21_dchvm_init(struct hubbub *hubbub);
int hubbub21_init_dchub(struct hubbub *hubbub, int hubbub21_init_dchub(struct hubbub *hubbub,
struct dcn_hubbub_phys_addr_config *pa_config); struct dcn_hubbub_phys_addr_config *pa_config);
void hubbub21_program_watermarks( bool hubbub21_program_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
bool safe_to_lower); bool safe_to_lower);
void hubbub21_program_urgent_watermarks( bool hubbub21_program_urgent_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
bool safe_to_lower); bool safe_to_lower);
void hubbub21_program_stutter_watermarks( bool hubbub21_program_stutter_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
bool safe_to_lower); bool safe_to_lower);
void hubbub21_program_pstate_watermarks( bool hubbub21_program_pstate_watermarks(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
......
...@@ -134,7 +134,7 @@ struct hubbub_funcs { ...@@ -134,7 +134,7 @@ struct hubbub_funcs {
unsigned int dccg_ref_freq_inKhz, unsigned int dccg_ref_freq_inKhz,
unsigned int *dchub_ref_freq_inKhz); unsigned int *dchub_ref_freq_inKhz);
void (*program_watermarks)( bool (*program_watermarks)(
struct hubbub *hubbub, struct hubbub *hubbub,
struct dcn_watermark_set *watermarks, struct dcn_watermark_set *watermarks,
unsigned int refclk_mhz, unsigned int refclk_mhz,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment