From: Alvin Lee <[email protected]> [Description] - Align calculation with addrlib (need to align to macro tiled widht/height) - Align the copy size / addr to 256KB for SW_256KB modes
Reviewed-by: Dillon Varone <[email protected]> Signed-off-by: Alvin Lee <[email protected]> Signed-off-by: Ivan Lipski <[email protected]> --- .../amd/display/dc/dml2_0/dml21/dml21_utils.c | 15 +++--- .../dml2_core/dml2_core_dcn6_calcs_dchub.c | 47 +++++++++++++------ .../dml2_core_dcn6_funcs_mode_support.c | 3 ++ .../src/dml2_core/dml2_core_shared_types.h | 2 + 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c index 1ade48b8b621a..125ca619c8abb 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/dml21_utils.c @@ -375,11 +375,12 @@ void dml21_handle_phantom_streams_planes(const struct dc *dc, struct dc_state *c dml2_map_dc_pipes(dml_ctx, context, NULL, &dml_ctx->v21.dml_to_dc_pipe_mapping, dc->current_state); } -static uint32_t calc_svp_size_64kb(uint32_t total_size_bytes) +static uint32_t calc_svp_size_256kb(uint64_t addr_bytes) { - return (total_size_bytes + 0xFFFF) >> 16; + return (uint32_t)(((addr_bytes + 0x3FFFFull) >> 18) << 2); // ceil to 256KB, then return bits [47:16] } + static unsigned int dml21_build_fams2_stream_programming_v3(const struct dc *dc, struct dc_state *context, struct dml2_context *dml_ctx) @@ -387,7 +388,7 @@ static unsigned int dml21_build_fams2_stream_programming_v3(const struct dc *dc, int dml_stream_idx, dc_stream_idx, dc_plane_idx, svp_idx; unsigned int dc_pipe_idx; unsigned int num_fams2_streams = 0; - unsigned int svp_size_64kb[2] = {0}; + unsigned int svp_size_256kb[2] = {0}; struct pipe_ctx *pipe; for (dc_stream_idx = 0; dc_stream_idx < context->stream_count; dc_stream_idx++) { @@ -477,12 +478,12 @@ static unsigned int dml21_build_fams2_stream_programming_v3(const struct dc *dc, } for (svp_idx = 0; svp_idx < 2; svp_idx++) { alternate_static_state->pipe_copy_addr_47_16[svp_idx][dc_pipe_idx] = - dml_ctx->config.alt_ch_cfg.region_base_addr_47_16[svp_idx] + svp_size_64kb[svp_idx]; - svp_size_64kb[svp_idx] += calc_svp_size_64kb(alternate_static_state->pipe_copy_max_size[svp_idx][dc_plane_idx]); + dml_ctx->config.alt_ch_cfg.region_base_addr_47_16[svp_idx] + svp_size_256kb[svp_idx]; + svp_size_256kb[svp_idx] += calc_svp_size_256kb(alternate_static_state->pipe_copy_max_size[svp_idx][dc_plane_idx]); if (alternate_static_state->config[dc_plane_idx].bits.is_multi_planar) { alternate_static_state->pipe_copy_addr_47_16_c[svp_idx][dc_pipe_idx] = - dml_ctx->config.alt_ch_cfg.region_base_addr_47_16[svp_idx] + svp_size_64kb[svp_idx]; - svp_size_64kb[svp_idx] += calc_svp_size_64kb(alternate_static_state->pipe_copy_max_size_c[svp_idx][dc_plane_idx]); + dml_ctx->config.alt_ch_cfg.region_base_addr_47_16[svp_idx] + svp_size_256kb[svp_idx]; + svp_size_256kb[svp_idx] += calc_svp_size_256kb(alternate_static_state->pipe_copy_max_size_c[svp_idx][dc_plane_idx]); } } } diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c index cae6bee93fe30..83fada0608724 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_calcs_dchub.c @@ -203,14 +203,32 @@ static unsigned int calculate_copy_swaths(double pre_first_hdl, return num_swaths; } +/** + * ******************************************************************************************************************************************************* + * calculate_tile_aligned_size: Applies tiled-surface padding / alignment rules to an unaligned copy region + * + * Given the unaligned copy region dimensions (copy_width in pixels, copy_height in lines) and the plane's macro tile + * (swizzle block) dimensions, this returns the number of bytes reserved for the region following addrlib sizing rules: + * - The pitch is padded up to the macro tile width and the height is padded up to the macro tile height. + * size = alignedPitch * alignedHeight * bpp, which is inherently macro-tile (block) aligned + * - The final ceil2 to 256 is a harmless floor for degenerate tile sizes. + * + * ******************************************************************************************************************************************************* + */ +static unsigned int calculate_tile_aligned_size(unsigned int copy_width, unsigned int copy_height, unsigned int tile_width, unsigned int tile_height, unsigned int byte_per_pixel) +{ + unsigned int mem_width = (unsigned int)math_ceil2(copy_width, tile_width); + unsigned int mem_height = (unsigned int)math_ceil2(copy_height, tile_height); + + return (unsigned int)math_ceil2(mem_width * mem_height * byte_per_pixel, 256); +} + /** * ******************************************************************************************************************************************************* * calculate_max_mem_size_per_plane_per_dpp: Calculate (loose) upper bound for total number of bytes reserved in memory for the copy given number of swaths * * - The copy width / height is the min of the vp_width/height and maximum number of pixels that can fit across an ODM slice * - This is to account for recout positions that cross the ODM seam but are "mostly" within the same ODM slice - * - For mem width assume an extra block width and tile width is required (the memory reserved must take into account pitch which must be tiled aligned) - * - For mem height assumes two extra block heights are required * * ******************************************************************************************************************************************************* */ @@ -222,12 +240,11 @@ static unsigned int calculate_max_mem_size_per_plane_per_dpp(const struct dml2_c unsigned int copy_src_lines = copy_swaths * (chroma ? p->SwathHeightC[plane_idx] : p->SwathHeightY[plane_idx]); unsigned int vp_width = chroma ? p->display_cfg->plane_descriptors[plane_idx].composition.viewport.plane1.width : p->display_cfg->plane_descriptors[plane_idx].composition.viewport.plane0.width; unsigned int vp_height = chroma ? p->display_cfg->plane_descriptors[plane_idx].composition.viewport.plane1.height : p->display_cfg->plane_descriptors[plane_idx].composition.viewport.plane0.height; - unsigned int block256_width = chroma ? p->Read256BlockWidthC[plane_idx] : p->Read256BlockWidthY[plane_idx]; - unsigned int block256_height = chroma ? p->Read256BlockHeightC[plane_idx] : p->Read256BlockHeightY[plane_idx]; unsigned int tile_width = chroma ? p->MacroTileWidthC[plane_idx] : p->MacroTileWidthY[plane_idx]; + unsigned int tile_height = chroma ? p->MacroTileHeightC[plane_idx] : p->MacroTileHeightY[plane_idx]; unsigned int byte_per_pixel = chroma ? p->BytePerPixelC[plane_idx] : p->BytePerPixelY[plane_idx]; - unsigned int mem_width; - unsigned int mem_height; + unsigned int copy_width; + unsigned int copy_height; unsigned int odm_combine_factor; double odm_slice_pixels; @@ -241,12 +258,14 @@ static unsigned int calculate_max_mem_size_per_plane_per_dpp(const struct dml2_c odm_combine_factor = 1; odm_slice_pixels = (double)h_active / odm_combine_factor * h_ratio + (odm_combine_factor == 3 ? 2 : 0); - mem_width = (vertical_access ? copy_src_lines : (unsigned int)math_ceil(math_min2(odm_slice_pixels, vp_width))) + block256_width + tile_width; - mem_height = (vertical_access ? (unsigned int)math_ceil(math_min2(odm_slice_pixels, vp_height)) : copy_src_lines) + 2 * block256_height; - return (unsigned int)math_ceil2(mem_width * mem_height * byte_per_pixel, 256); -} + /* Unaligned copy region dimensions (in pixels / lines) prior to tile alignment. + * Also divide vp_widht/height by NoOfDPP for MPC combine scenarios (i.e., MPC split within an ODM slice). */ + copy_width = vertical_access ? copy_src_lines : (unsigned int)math_ceil(math_min2(odm_slice_pixels, vp_width / p->NoOfDPP[plane_idx])); + copy_height = vertical_access ? (unsigned int)math_ceil(math_min2(odm_slice_pixels, vp_height / p->NoOfDPP[plane_idx])) : copy_src_lines; + return calculate_tile_aligned_size(copy_width, copy_height, tile_width, tile_height, byte_per_pixel); +} /** * **************************************************************************************************************************************** * calculate_ub_copy_size_per_plane_per_dpp: Calculate tight upper bound for total number of bytes required for the copy given number of swaths. @@ -422,9 +441,9 @@ static void calculate_swath_params(const struct dml2_core_calcs_calculate_altern out->prefetch_hdl_delta = (double)swath_height / vratio_pre; } -static unsigned int calc_svp_size_64kb_aligned(unsigned int total_size_bytes) +static unsigned int calc_svp_size_256kb_aligned(unsigned int total_size_bytes) { - return ((total_size_bytes + 0xFFFF) >> 16) << 16; // Round up to nearest 64KB boundary + return ((total_size_bytes + 0x3FFFFu) >> 18) << 18; // Round up to nearest 256KB boundary } void dcn6_calculate_alternate_params(struct dml2_core_calcs_calculate_alternate_params *p) @@ -471,7 +490,7 @@ void dcn6_calculate_alternate_params(struct dml2_core_calcs_calculate_alternate_ p->prefetch_hdl_delta[j] = swath_params.prefetch_hdl_delta; for (k = 0; k < 2; k++) { svp_max_bytes_per_dpp[k] = calculate_ub_copy_size_per_plane_per_dpp_per_svp(p, svp_dst_lines[k], j, false); - svp_max_bytes[k] += calc_svp_size_64kb_aligned(svp_max_bytes_per_dpp[k]) * p->NoOfDPP[j]; + svp_max_bytes[k] += calc_svp_size_256kb_aligned(svp_max_bytes_per_dpp[k]) * p->NoOfDPP[j]; } p->svp0_max_bytes_per_dpp[j] = svp_max_bytes_per_dpp[0]; p->svp1_max_bytes_per_dpp[j] = svp_max_bytes_per_dpp[1]; @@ -485,7 +504,7 @@ void dcn6_calculate_alternate_params(struct dml2_core_calcs_calculate_alternate_ for (k = 0; k < 2; k++) { svp_max_bytes_per_dpp[k] = calculate_ub_copy_size_per_plane_per_dpp_per_svp(p, svp_dst_lines[k], j, true); - svp_max_bytes[k] += calc_svp_size_64kb_aligned(svp_max_bytes_per_dpp[k]) * p->NoOfDPP[j]; + svp_max_bytes[k] += calc_svp_size_256kb_aligned(svp_max_bytes_per_dpp[k]) * p->NoOfDPP[j]; } p->svp0_max_bytes_per_dpp_c[j] = svp_max_bytes_per_dpp[0]; p->svp1_max_bytes_per_dpp_c[j] = svp_max_bytes_per_dpp[1]; diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c index cb3cff316b0e8..01bbf4aacbe3c 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn6_funcs_mode_support.c @@ -2246,6 +2246,8 @@ static void dcn6_ms_calculate_alternate_params(const struct dml2_core_calculate_ p->Read256BlockHeightC = inputs->Read256BlockHeightC; p->MacroTileWidthY = inputs->MacroTileWidthY; p->MacroTileWidthC = inputs->MacroTileWidthC; + p->MacroTileHeightY = inputs->MacroTileHeightY; + p->MacroTileHeightC = inputs->MacroTileHeightC; p->VInitPrefillY = inputs->PrefillY; p->VInitPrefillC = inputs->PrefillC; p->VRatioPrefetchY = inputs->VRatioPreY; @@ -2316,6 +2318,7 @@ static void dcn6_ms_calculate_alternate_svp_lines(const struct dml2_core_calcula struct dml2_core_internal_mode_support *outputs = states; DML_LOG_FUNC_ENTER(); + p->display_cfg = ctx->display_cfg; p->SwathHeightY = inputs->SwathHeightY; p->SwathHeightC = inputs->SwathHeightC; diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h index 55118fd484ce8..36250f3d83aaf 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h @@ -2300,6 +2300,8 @@ struct dml2_core_calcs_calculate_alternate_params { unsigned int *Read256BlockHeightC; unsigned int *MacroTileWidthY; unsigned int *MacroTileWidthC; + unsigned int *MacroTileHeightY; + unsigned int *MacroTileHeightC; unsigned int *VInitPrefillY; unsigned int *VInitPrefillC; double *VRatioPrefetchY; -- 2.43.0
