From 22aa56145f71a271ac1f0151bc90d0366b41928e Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Tue, 17 Dec 2019 16:26:48 -0500 Subject: [PATCH] drm/amd/display: Refactor surface flip programming Rework surface programming for RN to separate preparing parameters and register programming. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Harry Wentland Acked-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c | 324 ++++++++-------------- drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 16 +- 2 files changed, 127 insertions(+), 213 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c index 1f4e2cd08d4c..12396c371569 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c @@ -690,28 +690,114 @@ void hubp21_validate_dml_output(struct hubp *hubp, dml_dlg_attr->refcyc_per_meta_chunk_flip_l, dlg_attr.refcyc_per_meta_chunk_flip_l); } -static void program_video_progressive_dmcub( - struct dc_dmub_srv *dmcub, +static void program_surface_flip_and_addr(struct hubp *hubp, struct dmub_rb_cmd_flip *surface_flip) +{ + struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); + + REG_UPDATE_3(DCSURF_FLIP_CONTROL, + SURFACE_FLIP_TYPE, surface_flip->flip.flip_params.immediate, + SURFACE_FLIP_MODE_FOR_STEREOSYNC, surface_flip->flip.flip_params.grph_stereo, + SURFACE_FLIP_IN_STEREOSYNC, surface_flip->flip.flip_params.grph_stereo); + + REG_UPDATE(VMID_SETTINGS_0, + VMID, surface_flip->flip.flip_params.vmid); + + REG_UPDATE_8(DCSURF_SURFACE_CONTROL, + PRIMARY_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, + PRIMARY_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface, + PRIMARY_META_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, + PRIMARY_META_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface, + SECONDARY_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, + SECONDARY_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface, + SECONDARY_META_SURFACE_TMZ, surface_flip->flip.flip_params.tmz_surface, + SECONDARY_META_SURFACE_TMZ_C, surface_flip->flip.flip_params.tmz_surface); + + REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0, + PRIMARY_META_SURFACE_ADDRESS_HIGH_C, + surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C); + + REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0, + PRIMARY_META_SURFACE_ADDRESS_C, + surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_C); + + REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0, + PRIMARY_META_SURFACE_ADDRESS_HIGH, + surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH); + + REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0, + PRIMARY_META_SURFACE_ADDRESS, + surface_flip->flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS); + + REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0, + SECONDARY_META_SURFACE_ADDRESS_HIGH, + surface_flip->flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH); + + REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0, + SECONDARY_META_SURFACE_ADDRESS, + surface_flip->flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS); + + + REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0, + SECONDARY_SURFACE_ADDRESS_HIGH, + surface_flip->flip.DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH); + + REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0, + SECONDARY_SURFACE_ADDRESS, + surface_flip->flip.DCSURF_SECONDARY_SURFACE_ADDRESS); + + + REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0, + PRIMARY_SURFACE_ADDRESS_HIGH_C, + surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C); + + REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0, + PRIMARY_SURFACE_ADDRESS_C, + surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C); + + REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, + PRIMARY_SURFACE_ADDRESS_HIGH, + surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH); + + REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, + PRIMARY_SURFACE_ADDRESS, + surface_flip->flip.DCSURF_PRIMARY_SURFACE_ADDRESS); +} + +void program_surface_flip_and_addr_dmcub(struct hubp *hubp, struct dmub_rb_cmd_flip *surface_flip) +{ + struct dc_dmub_srv *dmcub = hubp->ctx->dmub_srv; + struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); + + PERF_TRACE(); // TODO: remove after performance is stable. + dc_dmub_srv_cmd_queue(dmcub, &surface_flip->header); + PERF_TRACE(); // TODO: remove after performance is stable. + dc_dmub_srv_cmd_execute(dmcub); + PERF_TRACE(); // TODO: remove after performance is stable. + dc_dmub_srv_wait_idle(dmcub); + PERF_TRACE(); // TODO: remove after performance is stable. +} + +bool hubp21_program_surface_flip_and_addr( struct hubp *hubp, const struct dc_plane_address *address, bool flip_immediate) { - struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); struct dmub_rb_cmd_flip surface_flip = { 0 }; + bool grph_stereo = false; + struct dc_debug_options *debug = &hubp->ctx->dc->debug; + struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); surface_flip.header.type = DMUB_CMD__SURFACE_FLIP; - surface_flip.flip.addr_type = address->type; - surface_flip.flip.immediate = flip_immediate; - surface_flip.flip.vmid = address->vmid; - - surface_flip.flip.hubp_inst = hubp->inst; - surface_flip.flip.tmz_surface = address->tmz_surface; + surface_flip.flip.flip_params.vmid = address->vmid; + surface_flip.flip.flip_params.hubp_inst = hubp->inst; switch (address->type) { case PLN_ADDR_TYPE_GRAPHICS: - if (address->grph.addr.quad_part == 0) - return; + if (address->grph.addr.quad_part == 0) { + BREAK_TO_DEBUGGER(); + break; + } if (address->grph.meta_addr.quad_part != 0) { surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS = @@ -728,7 +814,7 @@ static void program_video_progressive_dmcub( case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: if (address->video_progressive.luma_addr.quad_part == 0 || address->video_progressive.chroma_addr.quad_part == 0) - return; + break; if (address->video_progressive.luma_meta_addr.quad_part != 0) { surface_flip.flip.DCSURF_PRIMARY_META_SURFACE_ADDRESS = @@ -747,19 +833,24 @@ static void program_video_progressive_dmcub( surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH = address->video_progressive.luma_addr.high_part; - surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C = - address->video_progressive.chroma_addr.low_part; + if (debug->nv12_iflip_vm_wa) { + surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C = + address->video_progressive.chroma_addr.low_part + hubp21->PLAT_54186_wa_chroma_addr_offset; + } else + surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_C = + address->video_progressive.chroma_addr.low_part; + surface_flip.flip.DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C = address->video_progressive.chroma_addr.high_part; break; case PLN_ADDR_TYPE_GRPH_STEREO: if (address->grph_stereo.left_addr.quad_part == 0) - return; + break; if (address->grph_stereo.right_addr.quad_part == 0) - return; + break; - surface_flip.flip.grph_stereo = true; + grph_stereo = true; if (address->grph_stereo.right_meta_addr.quad_part != 0) { surface_flip.flip.DCSURF_SECONDARY_META_SURFACE_ADDRESS = @@ -786,200 +877,21 @@ static void program_video_progressive_dmcub( address->grph_stereo.right_addr.high_part; break; - - } - - PERF_TRACE(); // TODO: remove after performance is stable. - dc_dmub_srv_cmd_queue(dmcub, &surface_flip.header); - PERF_TRACE(); // TODO: remove after performance is stable. - dc_dmub_srv_cmd_execute(dmcub); - PERF_TRACE(); // TODO: remove after performance is stable. - dc_dmub_srv_wait_idle(dmcub); -} - -bool hubp21_program_surface_flip_and_addr( - struct hubp *hubp, - const struct dc_plane_address *address, - bool flip_immediate) -{ - struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); - struct dc_debug_options *debug = &hubp->ctx->dc->debug; - - - if (hubp->ctx->dc->debug.enable_dmcub_surface_flip) { - program_video_progressive_dmcub(hubp->ctx->dmub_srv, hubp, address, flip_immediate); - hubp->request_address = *address; - return true; - } - - //program flip type - REG_UPDATE(DCSURF_FLIP_CONTROL, - SURFACE_FLIP_TYPE, flip_immediate); - - // Program VMID reg - REG_UPDATE(VMID_SETTINGS_0, - VMID, address->vmid); - - if (address->type == PLN_ADDR_TYPE_GRPH_STEREO) { - REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x1); - REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x1); - - } else { - // turn off stereo if not in stereo - REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x0); - REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x0); - } - - - - /* HW automatically latch rest of address register on write to - * DCSURF_PRIMARY_SURFACE_ADDRESS if SURFACE_UPDATE_LOCK is not used - * - * program high first and then the low addr, order matters! - */ - switch (address->type) { - case PLN_ADDR_TYPE_GRAPHICS: - /* DCN1.0 does not support const color - * TODO: program DCHUBBUB_RET_PATH_DCC_CFGx_0/1 - * base on address->grph.dcc_const_color - * x = 0, 2, 4, 6 for pipe 0, 1, 2, 3 for rgb and luma - * x = 1, 3, 5, 7 for pipe 0, 1, 2, 3 for chroma - */ - - if (address->grph.addr.quad_part == 0) - break; - - REG_UPDATE_2(DCSURF_SURFACE_CONTROL, - PRIMARY_SURFACE_TMZ, address->tmz_surface, - PRIMARY_META_SURFACE_TMZ, address->tmz_surface); - - if (address->grph.meta_addr.quad_part != 0) { - REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0, - PRIMARY_META_SURFACE_ADDRESS_HIGH, - address->grph.meta_addr.high_part); - - REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0, - PRIMARY_META_SURFACE_ADDRESS, - address->grph.meta_addr.low_part); - } - - REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, - PRIMARY_SURFACE_ADDRESS_HIGH, - address->grph.addr.high_part); - - REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, - PRIMARY_SURFACE_ADDRESS, - address->grph.addr.low_part); - break; - case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE: - if (address->video_progressive.luma_addr.quad_part == 0 - || address->video_progressive.chroma_addr.quad_part == 0) - break; - - REG_UPDATE_4(DCSURF_SURFACE_CONTROL, - PRIMARY_SURFACE_TMZ, address->tmz_surface, - PRIMARY_SURFACE_TMZ_C, address->tmz_surface, - PRIMARY_META_SURFACE_TMZ, address->tmz_surface, - PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface); - - if (address->video_progressive.luma_meta_addr.quad_part != 0) { - REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH_C, 0, - PRIMARY_META_SURFACE_ADDRESS_HIGH_C, - address->video_progressive.chroma_meta_addr.high_part); - - REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_C, 0, - PRIMARY_META_SURFACE_ADDRESS_C, - address->video_progressive.chroma_meta_addr.low_part); - - REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0, - PRIMARY_META_SURFACE_ADDRESS_HIGH, - address->video_progressive.luma_meta_addr.high_part); - - REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0, - PRIMARY_META_SURFACE_ADDRESS, - address->video_progressive.luma_meta_addr.low_part); - } - - REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0, - PRIMARY_SURFACE_ADDRESS_HIGH_C, - address->video_progressive.chroma_addr.high_part); - - if (debug->nv12_iflip_vm_wa) { - REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0, - PRIMARY_SURFACE_ADDRESS_C, - address->video_progressive.chroma_addr.low_part + hubp21->PLAT_54186_wa_chroma_addr_offset); - } else { - REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0, - PRIMARY_SURFACE_ADDRESS_C, - address->video_progressive.chroma_addr.low_part); - } - - REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, - PRIMARY_SURFACE_ADDRESS_HIGH, - address->video_progressive.luma_addr.high_part); - - REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, - PRIMARY_SURFACE_ADDRESS, - address->video_progressive.luma_addr.low_part); - break; - case PLN_ADDR_TYPE_GRPH_STEREO: - if (address->grph_stereo.left_addr.quad_part == 0) - break; - if (address->grph_stereo.right_addr.quad_part == 0) - break; - - REG_UPDATE_8(DCSURF_SURFACE_CONTROL, - PRIMARY_SURFACE_TMZ, address->tmz_surface, - PRIMARY_SURFACE_TMZ_C, address->tmz_surface, - PRIMARY_META_SURFACE_TMZ, address->tmz_surface, - PRIMARY_META_SURFACE_TMZ_C, address->tmz_surface, - SECONDARY_SURFACE_TMZ, address->tmz_surface, - SECONDARY_SURFACE_TMZ_C, address->tmz_surface, - SECONDARY_META_SURFACE_TMZ, address->tmz_surface, - SECONDARY_META_SURFACE_TMZ_C, address->tmz_surface); - - if (address->grph_stereo.right_meta_addr.quad_part != 0) { - - REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS_HIGH, 0, - SECONDARY_META_SURFACE_ADDRESS_HIGH, - address->grph_stereo.right_meta_addr.high_part); - - REG_SET(DCSURF_SECONDARY_META_SURFACE_ADDRESS, 0, - SECONDARY_META_SURFACE_ADDRESS, - address->grph_stereo.right_meta_addr.low_part); - } - if (address->grph_stereo.left_meta_addr.quad_part != 0) { - - REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS_HIGH, 0, - PRIMARY_META_SURFACE_ADDRESS_HIGH, - address->grph_stereo.left_meta_addr.high_part); - - REG_SET(DCSURF_PRIMARY_META_SURFACE_ADDRESS, 0, - PRIMARY_META_SURFACE_ADDRESS, - address->grph_stereo.left_meta_addr.low_part); - } - - REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0, - SECONDARY_SURFACE_ADDRESS_HIGH, - address->grph_stereo.right_addr.high_part); - - REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0, - SECONDARY_SURFACE_ADDRESS, - address->grph_stereo.right_addr.low_part); - - REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0, - PRIMARY_SURFACE_ADDRESS_HIGH, - address->grph_stereo.left_addr.high_part); - - REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0, - PRIMARY_SURFACE_ADDRESS, - address->grph_stereo.left_addr.low_part); - break; default: BREAK_TO_DEBUGGER(); break; } + surface_flip.flip.flip_params.vmid = address->vmid; + surface_flip.flip.flip_params.grph_stereo = grph_stereo; + surface_flip.flip.flip_params.tmz_surface = address->tmz_surface; + surface_flip.flip.flip_params.immediate = flip_immediate; + + if (hubp->ctx->dc->debug.enable_dmcub_surface_flip) + program_surface_flip_and_addr_dmcub(hubp, &surface_flip); + else + program_surface_flip_and_addr(hubp, &surface_flip); + hubp->request_address = *address; return true; diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 3b79079ec9b8..0c3ae02148a6 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -30,7 +30,7 @@ #include "dmub_cmd_dal.h" #include "dmub_cmd_vbios.h" #include "atomfirmware.h" -#include "dc_hw_types.h" + #define DMUB_RB_CMD_SIZE 64 #define DMUB_RB_MAX_ENTRY 128 #define DMUB_RB_SIZE (DMUB_RB_CMD_SIZE * DMUB_RB_MAX_ENTRY) @@ -165,12 +165,14 @@ struct dmub_cmd_surface_flip { uint32_t DCSURF_SECONDARY_META_SURFACE_ADDRESS; uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH; uint32_t DCSURF_SECONDARY_SURFACE_ADDRESS; - enum dc_plane_addr_type addr_type; - uint8_t hubp_inst; - bool tmz_surface; - bool immediate; - uint8_t vmid; - bool grph_stereo; + struct { + uint8_t hubp_inst : 4; + uint8_t tmz_surface : 1; + uint8_t immediate :1; + uint8_t vmid : 4; + uint8_t grph_stereo : 1; + uint32_t reserved : 21; + } flip_params; }; struct dmub_rb_cmd_flip { -- 2.11.0