drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
Extension
.c
Size
71587 bytes
Lines
2166
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (prim_bpp_444[i].vic == vid_id) {
				preset_found = true;
				*preset_bpp = prim_bpp_444[i].target_bpp;
				break;
			}
		}
	} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
		for (i = 0; i < table_size_422 ; i++) {
			if (prim_bpp_422[i].vic == vid_id) {
				preset_found = true;
				*preset_bpp = prim_bpp_422[i].target_bpp;
				break;
			}
		}
	} else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) {
		for (i = 0; i < table_size_420 ; i++) {
			if (prim_bpp_420[i].vic == vid_id) {
				preset_found = true;
				*preset_bpp = prim_bpp_420[i].target_bpp;
				break;
			}
		}
	} else {
		return false;
	}

	return preset_found;
}

static int hdmi_dsc_get_num_slices(const struct dc_crtc_timing *timing)
{
	int k_slice_adjust = 1;
	int adj_pix_clk_mhz;
	int min_slices;
	int slice_target;
	int slice_width = timing->h_addressable;
	int h_ratio_adj_pix_clk_mhz;

	if (timing->pixel_encoding == PIXEL_ENCODING_RGB ||
			timing->pixel_encoding == PIXEL_ENCODING_YCBCR444)
		k_slice_adjust = 2;

	adj_pix_clk_mhz = k_slice_adjust * timing->pix_clk_100hz / 10000 / 2;
	h_ratio_adj_pix_clk_mhz = adj_pix_clk_mhz * timing->h_addressable / timing->h_total;
	if (adj_pix_clk_mhz <= 2720) {
		min_slices = adj_pix_clk_mhz / 340;
		if (adj_pix_clk_mhz % 340 != 0)
			min_slices++;
	} else if (adj_pix_clk_mhz <= 4800) {
		min_slices = adj_pix_clk_mhz / 400;
		if (adj_pix_clk_mhz % 400 != 0)
			min_slices++;
	} else if (h_ratio_adj_pix_clk_mhz <= 4800) {
		min_slices = h_ratio_adj_pix_clk_mhz / 600;
		if (h_ratio_adj_pix_clk_mhz % 600 != 0)
			min_slices++;
	} else {
		min_slices = h_ratio_adj_pix_clk_mhz / 900;
		if (h_ratio_adj_pix_clk_mhz % 900 != 0)
			min_slices++;
	}

	do {
		if (min_slices <= 1)
			slice_target = 1;
		else if (min_slices <= 2)
			slice_target = 2;
		else if (min_slices <= 4)
			slice_target = 4;
		else if (min_slices <= 8)
			slice_target = 8;
		else if (min_slices <= 12)
			slice_target = 12;
		else if (min_slices <= 16)
			slice_target = 16;
		else
			return 0;

		slice_width = timing->h_addressable / slice_target;
		min_slices++;
	} while (slice_width > 2720);

	return slice_target;
}

static int hdmi_dsc_get_bpp(const struct dc_crtc_timing *timing,
		const struct dsc_enc_caps *dsc_common_caps)
{
	int max_dsc_bpp, min_dsc_bpp;
	int target_bytes;

Annotation

Implementation Notes