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.
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
dc_spl.hdc_spl_scl_easf_filters.hdc_spl_isharp_filters.hspl_debug.h
Detected Declarations
function spl_is_yuv420function spl_is_rgb8function spl_is_video_formatfunction spl_is_subsampled_formatfunction intersect_recfunction shift_recfunction spl_opp_adjust_rectfunction calculate_plane_rec_in_timing_activefunction calculate_mpc_slice_in_timing_activefunction onefunction calculate_odm_slice_in_timing_activefunction spl_calculate_recoutfunction spl_calculate_scaling_ratiosfunction spl_calculate_viewport_sizefunction spl_get_vp_scan_directionfunction spl_calculate_init_and_vpfunction spl_calculate_inits_and_viewportsfunction spl_handle_3d_recoutfunction spl_clamp_viewportfunction spl_get_dscl_modefunction spl_choose_lls_policyfunction enable_easffunction spl_is_video_fullscreenfunction spl_get_isharp_enfunction spl_get_taps_non_adaptive_scalerfunction spl_get_optimal_number_of_tapsfunction spl_set_black_color_datafunction spl_set_manual_ratio_init_datafunction spl_set_taps_datafunction spl_set_dscl_prog_datafunction spl_calculate_c0_c3_hdrfunction spl_set_easf_datafunction spl_set_isharp_noise_det_modefunction spl_set_isharp_datafunction spl_calculate_number_of_tapsfunction SPL_NAMESPACEfunction SPL_NAMESPACE
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
- Immediate include surface: `dc_spl.h`, `dc_spl_scl_easf_filters.h`, `dc_spl_isharp_filters.h`, `spl_debug.h`.
- Detected declarations: `function spl_is_yuv420`, `function spl_is_rgb8`, `function spl_is_video_format`, `function spl_is_subsampled_format`, `function intersect_rec`, `function shift_rec`, `function spl_opp_adjust_rect`, `function calculate_plane_rec_in_timing_active`, `function calculate_mpc_slice_in_timing_active`, `function one`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.