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

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
Loading
Loading
Loading
Loading
+119 −103
Original line number Diff line number Diff line
@@ -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);

	return offset ? (address + offset * 256) : 0;
		/* 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);
}

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,
validate_dcc(struct amdgpu_device *adev,
	     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)
	     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,
	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;