drivers/gpu/drm/i915/display/intel_link_bw.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/display/intel_link_bw.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/intel_link_bw.c
Extension
.c
Size
13158 bytes
Lines
498
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 (state->base.duplicated && crtc_state) {
			limits->max_bpp_x16[pipe] = crtc_state->max_link_bpp_x16;
			if (intel_dsc_enabled_on_link(crtc_state))
				limits->link_dsc_pipes |= BIT(pipe);
		} else {
			limits->max_bpp_x16[pipe] = INT_MAX;
		}

		if (forced_bpp_x16)
			limits->max_bpp_x16[pipe] = min(limits->max_bpp_x16[pipe], forced_bpp_x16);
	}
}

/**
 * __intel_link_bw_reduce_bpp - reduce maximum link bpp for a selected pipe
 * @state: atomic state
 * @limits: link BW limits
 * @pipe_mask: mask of pipes to select from
 * @reason: explanation of why bpp reduction is needed
 * @reduce_forced_bpp: allow reducing bpps below their forced link bpp
 *
 * Select the pipe from @pipe_mask with the biggest link bpp value and set the
 * maximum of link bpp in @limits below this value. Modeset the selected pipe,
 * so that its state will get recomputed.
 *
 * This function can be called to resolve a link's BW overallocation by reducing
 * the link bpp of one pipe on the link and hence reducing the total link BW.
 *
 * Returns
 *   - 0 in case of success
 *   - %-ENOSPC if no pipe can further reduce its link bpp
 *   - Other negative error, if modesetting the selected pipe failed
 */
static int __intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
				      struct intel_link_bw_limits *limits,
				      u8 pipe_mask,
				      const char *reason,
				      bool reduce_forced_bpp)
{
	struct intel_display *display = to_intel_display(state);
	enum pipe max_bpp_pipe = INVALID_PIPE;
	struct intel_crtc *crtc;
	int max_bpp_x16 = 0;

	for_each_intel_crtc_in_pipe_mask(display, crtc, pipe_mask) {
		struct intel_crtc_state *crtc_state;
		int link_bpp_x16;

		if (limits->bpp_limit_reached_pipes & BIT(crtc->pipe))
			continue;

		crtc_state = intel_atomic_get_crtc_state(&state->base,
							 crtc);
		if (IS_ERR(crtc_state))
			return PTR_ERR(crtc_state);

		if (crtc_state->dsc.compression_enable)
			link_bpp_x16 = crtc_state->dsc.compressed_bpp_x16;
		else
			/*
			 * TODO: for YUV420 the actual link bpp is only half
			 * of the pipe bpp value. The MST encoder's BW allocation
			 * is based on the pipe bpp value, set the actual link bpp
			 * limit here once the MST BW allocation is fixed.
			 */
			link_bpp_x16 = fxp_q4_from_int(crtc_state->pipe_bpp);

		if (!reduce_forced_bpp &&
		    link_bpp_x16 <= get_forced_link_bpp_x16(state, crtc))
			continue;

		if (link_bpp_x16 > max_bpp_x16) {
			max_bpp_x16 = link_bpp_x16;
			max_bpp_pipe = crtc->pipe;
		}
	}

	if (max_bpp_pipe == INVALID_PIPE)
		return -ENOSPC;

	limits->max_bpp_x16[max_bpp_pipe] = max_bpp_x16 - 1;

	return intel_modeset_pipes_in_mask_early(state, reason,
						 BIT(max_bpp_pipe));
}

int intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
			     struct intel_link_bw_limits *limits,
			     u8 pipe_mask,
			     const char *reason)

Annotation

Implementation Notes