drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
Extension
.c
Size
14520 bytes
Lines
449
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 (link->dc->debug.dpia_debug.bits.enable_usb4_bw_zero_alloc_patch) {
			/*
			 * During DP tunnel creation, the CM preallocates BW
			 * and reduces the estimated BW of other DPIAs.
			 * The CM releases the preallocation only when the allocation is complete.
			 * Perform a zero allocation to make the CM release the preallocation
			 * and correctly update the estimated BW for all DPIAs per host router.
			 */
			link_dp_dpia_allocate_usb4_bandwidth_for_stream(link, 0);
		}
	} else
		DC_LOG_DEBUG("%s:  link[%d] failed to enable DPTX BW allocation mode", __func__, link->link_index);

	return ret;
}

/*
 * Handle DP BW allocation status register
 *
 * @link: pointer to the dc_link struct instance
 * @status: content of DP tunneling status DPCD register
 *
 * return: none
 */
void link_dp_dpia_handle_bw_alloc_status(struct dc_link *link, uint8_t status)
{
	if (status & DP_TUNNELING_BW_REQUEST_SUCCEEDED) {
		DC_LOG_DEBUG("%s: BW Allocation request succeeded on link(%d)",
				__func__, link->link_index);
	}

	if (status & DP_TUNNELING_BW_REQUEST_FAILED) {
		DC_LOG_DEBUG("%s: BW Allocation request failed on link(%d)  allocated/estimated BW=%d",
				__func__, link->link_index, link->dpia_bw_alloc_config.estimated_bw);

		link_dpia_send_bw_alloc_request(link, link->dpia_bw_alloc_config.estimated_bw);
	}

	if (status & DP_TUNNELING_BW_ALLOC_CAP_CHANGED) {
		link->dpia_bw_alloc_config.bw_granularity = get_bw_granularity(link);

		DC_LOG_DEBUG("%s: Granularity changed on link(%d)  new granularity=%d",
				__func__, link->link_index, link->dpia_bw_alloc_config.bw_granularity);
	}

	if (status & DP_TUNNELING_ESTIMATED_BW_CHANGED) {
		link->dpia_bw_alloc_config.estimated_bw = get_estimated_bw(link);

		DC_LOG_DEBUG("%s: Estimated BW changed on link(%d)  new estimated BW=%d",
				__func__, link->link_index, link->dpia_bw_alloc_config.estimated_bw);
	}

	core_link_write_dpcd(
		link, DP_TUNNELING_STATUS,
		&status, sizeof(status));
}

/*
 * Handle the DP Bandwidth allocation for DPIA
 *
 */
void dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int peak_bw)
{
	if (link && link->dpcd_caps.usb4_dp_tun_info.dp_tun_cap.bits.dp_tunneling
			&& link->dpia_bw_alloc_config.bw_alloc_enabled) {
		if (peak_bw > 0) {
			// If DP over USB4 then we need to check BW allocation
			link->dpia_bw_alloc_config.link_max_bw = peak_bw;

			link_dpia_send_bw_alloc_request(link, peak_bw);
		} else
			dpia_bw_alloc_unplug(link);
	}
}

void link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw)
{
	link->dpia_bw_alloc_config.estimated_bw = get_estimated_bw(link);

	DC_LOG_DEBUG("%s: ENTER: link[%d] hpd(%d)  Allocated_BW: %d  Estimated_BW: %d  Req_BW: %d",
		__func__, link->link_index, link->hpd_status,
		link->dpia_bw_alloc_config.allocated_bw,
		link->dpia_bw_alloc_config.estimated_bw,
		req_bw);

	if (link_dp_is_bw_alloc_available(link))
		link_dpia_send_bw_alloc_request(link, req_bw);
	else
		DC_LOG_DEBUG("%s:  BW Allocation mode not available", __func__);
}

Annotation

Implementation Notes