Commit a3241991 authored by Bas Nieuwenhuizen's avatar Bas Nieuwenhuizen Committed by Alex Deucher

drm/amd/display: Refactor surface tiling setup.

Prepare for inserting modifiers based configuration, while sharing
a bunch of DCC validation & initializing the device-based configuration.
Signed-off-by: default avatarBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 08d76915
......@@ -3760,46 +3760,86 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state,
return 0;
}
static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
static void
fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
uint64_t tiling_flags)
{
uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
/* Fill GFX8 params */
if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) {
unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
/* XXX fix me for VI */
tiling_info->gfx8.num_banks = num_banks;
tiling_info->gfx8.array_mode =
DC_ARRAY_2D_TILED_THIN1;
tiling_info->gfx8.tile_split = tile_split;
tiling_info->gfx8.bank_width = bankw;
tiling_info->gfx8.bank_height = bankh;
tiling_info->gfx8.tile_aspect = mtaspect;
tiling_info->gfx8.tile_mode =
DC_ADDR_SURF_MICRO_TILING_DISPLAY;
} else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
== DC_ARRAY_1D_TILED_THIN1) {
tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
}
return offset ? (address + offset * 256) : 0;
tiling_info->gfx8.pipe_config =
AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
}
static void
fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
union dc_tiling_info *tiling_info)
{
tiling_info->gfx9.num_pipes =
adev->gfx.config.gb_addr_config_fields.num_pipes;
tiling_info->gfx9.num_banks =
adev->gfx.config.gb_addr_config_fields.num_banks;
tiling_info->gfx9.pipe_interleave =
adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
tiling_info->gfx9.num_shader_engines =
adev->gfx.config.gb_addr_config_fields.num_se;
tiling_info->gfx9.max_compressed_frags =
adev->gfx.config.gb_addr_config_fields.max_compress_frags;
tiling_info->gfx9.num_rb_per_se =
adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
tiling_info->gfx9.shaderEnable = 1;
#ifdef CONFIG_DRM_AMD_DC_DCN3_0
if (adev->asic_type == CHIP_SIENNA_CICHLID ||
adev->asic_type == CHIP_NAVY_FLOUNDER ||
adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
adev->asic_type == CHIP_VANGOGH)
tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
#endif
}
static int
fill_plane_dcc_attributes(struct amdgpu_device *adev,
const struct amdgpu_framebuffer *afb,
const enum surface_pixel_format format,
const enum dc_rotation_angle rotation,
const struct plane_size *plane_size,
const union dc_tiling_info *tiling_info,
const uint64_t info,
struct dc_plane_dcc_param *dcc,
struct dc_plane_address *address,
bool force_disable_dcc)
validate_dcc(struct amdgpu_device *adev,
const enum surface_pixel_format format,
const enum dc_rotation_angle rotation,
const union dc_tiling_info *tiling_info,
const struct dc_plane_dcc_param *dcc,
const struct dc_plane_address *address,
const struct plane_size *plane_size)
{
struct dc *dc = adev->dm.dc;
struct dc_dcc_surface_param input;
struct dc_surface_dcc_cap output;
uint64_t plane_address = afb->address + afb->base.offsets[0];
uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
uint64_t dcc_address;
memset(&input, 0, sizeof(input));
memset(&output, 0, sizeof(output));
if (force_disable_dcc)
if (!dcc->enable)
return 0;
if (!offset)
return 0;
if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
return -EINVAL;
if (!dc->cap_funcs.get_dcc_compression_cap)
if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
!dc->cap_funcs.get_dcc_compression_cap)
return -EINVAL;
input.format = format;
......@@ -3818,17 +3858,60 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
if (!output.capable)
return -EINVAL;
if (i64b == 0 && output.grph.rgb.independent_64b_blks != 0)
if (dcc->independent_64b_blks == 0 &&
output.grph.rgb.independent_64b_blks != 0)
return -EINVAL;
return 0;
}
static void
fill_dcc_params_from_flags(const struct amdgpu_framebuffer *afb,
struct dc_plane_dcc_param *dcc,
struct dc_plane_address *address,
const uint64_t flags, bool force_disable_dcc)
{
uint64_t dcc_address;
uint64_t plane_address = afb->address + afb->base.offsets[0];
uint32_t offset = AMDGPU_TILING_GET(flags, DCC_OFFSET_256B);
uint32_t i64b = AMDGPU_TILING_GET(flags, DCC_INDEPENDENT_64B) != 0;
if (!offset || force_disable_dcc)
return;
dcc->enable = 1;
dcc->meta_pitch =
AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
dcc->meta_pitch = AMDGPU_TILING_GET(flags, DCC_PITCH_MAX) + 1;
dcc->independent_64b_blks = i64b;
dcc_address = get_dcc_address(plane_address, info);
dcc_address = plane_address + (uint64_t)offset * 256;
address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
}
static int
fill_gfx9_plane_attributes_from_flags(struct amdgpu_device *adev,
const struct amdgpu_framebuffer *afb,
const enum surface_pixel_format format,
const enum dc_rotation_angle rotation,
const struct plane_size *plane_size,
union dc_tiling_info *tiling_info,
struct dc_plane_dcc_param *dcc,
struct dc_plane_address *address,
uint64_t tiling_flags,
bool force_disable_dcc)
{
int ret;
fill_gfx9_tiling_info_from_device(adev, tiling_info);
tiling_info->gfx9.swizzle =
AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
fill_dcc_params_from_flags(afb, dcc, address, tiling_flags, force_disable_dcc);
ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size);
if (ret)
return ret;
return 0;
}
......@@ -3900,82 +3983,15 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
upper_32_bits(chroma_addr);
}
/* Fill GFX8 params */
if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) {
unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
/* XXX fix me for VI */
tiling_info->gfx8.num_banks = num_banks;
tiling_info->gfx8.array_mode =
DC_ARRAY_2D_TILED_THIN1;
tiling_info->gfx8.tile_split = tile_split;
tiling_info->gfx8.bank_width = bankw;
tiling_info->gfx8.bank_height = bankh;
tiling_info->gfx8.tile_aspect = mtaspect;
tiling_info->gfx8.tile_mode =
DC_ADDR_SURF_MICRO_TILING_DISPLAY;
} else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
== DC_ARRAY_1D_TILED_THIN1) {
tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
}
tiling_info->gfx8.pipe_config =
AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
if (adev->asic_type == CHIP_VEGA10 ||
adev->asic_type == CHIP_VEGA12 ||
adev->asic_type == CHIP_VEGA20 ||
adev->asic_type == CHIP_NAVI10 ||
adev->asic_type == CHIP_NAVI14 ||
adev->asic_type == CHIP_NAVI12 ||
#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
adev->asic_type == CHIP_SIENNA_CICHLID ||
adev->asic_type == CHIP_NAVY_FLOUNDER ||
#endif
#if defined(CONFIG_DRM_AMD_DC_DCN3_02)
adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
#endif
#if defined(CONFIG_DRM_AMD_DC_DCN3_01)
adev->asic_type == CHIP_VANGOGH ||
#endif
adev->asic_type == CHIP_RENOIR ||
adev->asic_type == CHIP_RAVEN) {
/* Fill GFX9 params */
tiling_info->gfx9.num_pipes =
adev->gfx.config.gb_addr_config_fields.num_pipes;
tiling_info->gfx9.num_banks =
adev->gfx.config.gb_addr_config_fields.num_banks;
tiling_info->gfx9.pipe_interleave =
adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
tiling_info->gfx9.num_shader_engines =
adev->gfx.config.gb_addr_config_fields.num_se;
tiling_info->gfx9.max_compressed_frags =
adev->gfx.config.gb_addr_config_fields.max_compress_frags;
tiling_info->gfx9.num_rb_per_se =
adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
tiling_info->gfx9.swizzle =
AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
tiling_info->gfx9.shaderEnable = 1;
#ifdef CONFIG_DRM_AMD_DC_DCN3_0
if (adev->asic_type == CHIP_SIENNA_CICHLID ||
adev->asic_type == CHIP_NAVY_FLOUNDER ||
adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
adev->asic_type == CHIP_VANGOGH)
tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
#endif
ret = fill_plane_dcc_attributes(adev, afb, format, rotation,
plane_size, tiling_info,
tiling_flags, dcc, address,
force_disable_dcc);
if (adev->family >= AMDGPU_FAMILY_AI) {
ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, rotation,
plane_size, tiling_info, dcc,
address, tiling_flags,
force_disable_dcc);
if (ret)
return ret;
} else {
fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
}
return 0;
......
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