drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c
Extension
.c
Size
85915 bytes
Lines
1935
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 ((mpc_rec.width * (mpc_slice_idx + 1)) > plane_clip_rec->width) {
			mpc_rec.width = plane_clip_rec->width % recout_width_align;
			mpc_rec.x = plane_clip_rec->x + recout_width_align * mpc_slice_idx;
		} else
			mpc_rec.x = plane_clip_rec->x + mpc_rec.width * mpc_slice_idx;
		mpc_rec.height = plane_clip_rec->height;
		mpc_rec.y = plane_clip_rec->y;

	} else {
		mpc_rec.width = plane_clip_rec->width / mpc_slice_count;
		mpc_rec.x = plane_clip_rec->x + mpc_rec.width * mpc_slice_idx;
		mpc_rec.height = plane_clip_rec->height;
		mpc_rec.y = plane_clip_rec->y;
	}
	SPL_ASSERT(mpc_slice_count == 1 ||
			spl_in->basic_out.view_format != SPL_VIEW_3D_SIDE_BY_SIDE ||
			mpc_rec.width % 2 == 0);

	/* extra pixels in the division remainder need to go to pipes after
	 * the extra pixel index minus one(epimo) defined here as:
	 */
	if ((use_recout_width_aligned == false) &&
		mpc_slice_idx > epimo && spl_in->basic_in.custom_width == 0) {
		mpc_rec.x += mpc_slice_idx - epimo - 1;
		mpc_rec.width += 1;
	}

	if (spl_in->basic_out.view_format == SPL_VIEW_3D_TOP_AND_BOTTOM) {
		SPL_ASSERT(mpc_rec.height % 2 == 0);
		mpc_rec.height /= 2;
	}
	return mpc_rec;
}

static struct spl_rect calculate_odm_slice_in_timing_active(struct spl_in *spl_in)
{
	int odm_slice_count = spl_in->basic_out.odm_combine_factor;
	int odm_slice_idx = spl_in->odm_slice_index;
	bool is_last_odm_slice = (odm_slice_idx + 1) == odm_slice_count;
	int h_active = spl_in->basic_out.output_size.width;
	int v_active = spl_in->basic_out.output_size.height;
	int odm_slice_width;
	struct spl_rect odm_rec;

	if (spl_in->basic_out.odm_combine_factor > 0) {
		odm_slice_width = h_active / odm_slice_count;
		/*
		 * deprecated, caller must pass in odm slice rect i.e OPP input
		 * rect in timing active for the new interface.
		 */
		if (spl_in->basic_out.use_two_pixels_per_container && (odm_slice_width % 2))
			odm_slice_width++;

		odm_rec.x = odm_slice_width * odm_slice_idx;
		odm_rec.width = is_last_odm_slice ?
			/* last slice width is the reminder of h_active */
			h_active - odm_slice_width * (odm_slice_count - 1) :
			/* odm slice width is the floor of h_active / count */
			odm_slice_width;
		odm_rec.y = 0;
		odm_rec.height = v_active;

		return odm_rec;
	}

	return spl_in->basic_out.odm_slice_rect;
}

static void spl_calculate_recout(struct spl_in *spl_in, struct spl_scratch *spl_scratch, struct spl_out *spl_out)
{
	/*
	 * A plane clip represents the desired plane size and position in Stream
	 * Source Space. Stream Source is the destination where all planes are
	 * blended (i.e. positioned, scaled and overlaid). It is a canvas where
	 * all planes associated with the current stream are drawn together.
	 * After Stream Source is completed, we will further scale and
	 * reposition the entire canvas of the stream source to Stream
	 * Destination in Timing Active Space. This could be due to display
	 * overscan adjustment where we will need to rescale and reposition all
	 * the planes so they can fit into a TV with overscan or downscale
	 * upscale features such as GPU scaling or VSR.
	 *
	 * This two step blending is a virtual procedure in software. In
	 * hardware there is no such thing as Stream Source. all planes are
	 * blended once in Timing Active Space. Software virtualizes a Stream
	 * Source space to decouple the math complicity so scaling param
	 * calculation focuses on one step at a time.
	 *
	 * In the following two diagrams, user applied 10% overscan adjustment
	 * so the Stream Source needs to be scaled down a little before mapping

Annotation

Implementation Notes