aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
diff options
context:
space:
mode:
authorAlvin Lee <Alvin.Lee2@amd.com>2022-05-02 15:04:31 -0400
committerAlex Deucher <alexander.deucher@amd.com>2022-07-05 16:10:38 -0400
commit85f4bc0c333ceed24cbc9f69a2a77fab1ae3d4d1 (patch)
treebf72bbc683ca2ac64dd033a1e6306599c1d13b20 /drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
parentdrm/amd/display: Add missing registers for ACP (diff)
downloadwireguard-linux-85f4bc0c333ceed24cbc9f69a2a77fab1ae3d4d1.tar.xz
wireguard-linux-85f4bc0c333ceed24cbc9f69a2a77fab1ae3d4d1.zip
drm/amd/display: Add SubVP required code
This commit enables the SubVP feature. To achieve that, we need to: - Don't force p-state disallow on SubVP (can't block dummy p-state) - Send calculated watermark to DMCUB for SubVP - Adjust CAB mode message to PMFW - Add a proper locking sequence for SubVP - Various fixes to SubVP static analysis and determining SubVP config - Currently SubVP not supported with pipe split so merge all pipes before setting up SubVp Reviewed-by: Jun Lei <Jun.Lei@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Acked-by: Alan Liu <HaoPing.Liu@amd.com> Signed-off-by: Alvin Lee <Alvin.Lee2@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c')
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 76f8b40b2165..9f07c1b170c9 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1308,6 +1308,15 @@ static void dcn20_detect_pipe_changes(struct pipe_ctx *old_pipe, struct pipe_ctx
}
return;
}
+
+ /* For SubVP we need to unconditionally enable because any phantom pipes are
+ * always removed then newly added for every full updates whenever SubVP is in use.
+ * The remove-add sequence of the phantom pipe always results in the pipe
+ * being blanked in enable_stream_timing (DPG).
+ */
+ if (new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM)
+ new_pipe->update_flags.bits.enable = 1;
+
if (old_pipe->plane_state && !new_pipe->plane_state) {
new_pipe->update_flags.bits.disable = 1;
return;
@@ -1810,7 +1819,9 @@ void dcn20_post_unlock_program_front_end(
*/
for (i = 0; i < dc->res_pool->pipe_count; i++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
- if (pipe->plane_state && !pipe->top_pipe && pipe->update_flags.bits.enable) {
+ // Don't check flip pending on phantom pipes
+ if (pipe->plane_state && !pipe->top_pipe && pipe->update_flags.bits.enable &&
+ pipe->stream->mall_stream_config.type != SUBVP_PHANTOM) {
struct hubp *hubp = pipe->plane_res.hubp;
int j = 0;
@@ -1864,18 +1875,34 @@ void dcn20_prepare_bandwidth(
{
struct hubbub *hubbub = dc->res_pool->hubbub;
unsigned int compbuf_size_kb = 0;
+ unsigned int cache_wm_a = context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns;
+ unsigned int i;
dc->clk_mgr->funcs->update_clocks(
dc->clk_mgr,
context,
false);
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+ // At optimize don't restore the original watermark value
+ if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_NONE) {
+ context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 4U * 1000U * 1000U * 1000U;
+ break;
+ }
+ }
+
/* program dchubbub watermarks */
dc->wm_optimized_required = hubbub->funcs->program_watermarks(hubbub,
&context->bw_ctx.bw.dcn.watermarks,
dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
false);
+ // Restore the real watermark so we can commit the value to DMCUB
+ // DMCUB uses the "original" watermark value in SubVP MCLK switch
+ context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = cache_wm_a;
+
/* decrease compbuf size */
if (hubbub->funcs->program_compbuf_size) {
if (context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes)
@@ -1894,6 +1921,16 @@ void dcn20_optimize_bandwidth(
struct hubbub *hubbub = dc->res_pool->hubbub;
int i;
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+ // At optimize don't need to restore the original watermark value
+ if (pipe->stream && pipe->stream->mall_stream_config.type != SUBVP_NONE) {
+ context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = 4U * 1000U * 1000U * 1000U;
+ break;
+ }
+ }
+
/* program dchubbub watermarks */
hubbub->funcs->program_watermarks(hubbub,
&context->bw_ctx.bw.dcn.watermarks,