Loading drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +135 −47 Original line number Diff line number Diff line Loading @@ -54,11 +54,18 @@ static bool get_bw_alloc_proceed_flag(struct dc_link *tmp) static void reset_bw_alloc_struct(struct dc_link *link) { link->dpia_bw_alloc_config.bw_alloc_enabled = false; link->dpia_bw_alloc_config.sink_verified_bw = 0; link->dpia_bw_alloc_config.sink_max_bw = 0; link->dpia_bw_alloc_config.link_verified_bw = 0; link->dpia_bw_alloc_config.link_max_bw = 0; link->dpia_bw_alloc_config.allocated_bw = 0; link->dpia_bw_alloc_config.estimated_bw = 0; link->dpia_bw_alloc_config.bw_granularity = 0; link->dpia_bw_alloc_config.dp_overhead = 0; link->dpia_bw_alloc_config.response_ready = false; link->dpia_bw_alloc_config.nrd_max_lane_count = 0; link->dpia_bw_alloc_config.nrd_max_link_rate = 0; for (int i = 0; i < MAX_SINKS_PER_LINK; i++) link->dpia_bw_alloc_config.remote_sink_req_bw[i] = 0; DC_LOG_DEBUG("reset usb4 bw alloc of link(%d)\n", link->link_index); } #define BW_GRANULARITY_0 4 // 0.25 Gbps Loading Loading @@ -104,6 +111,32 @@ static int get_estimated_bw(struct dc_link *link) return bw_estimated_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); } static int get_non_reduced_max_link_rate(struct dc_link *link) { uint8_t nrd_max_link_rate = 0; core_link_read_dpcd( link, DP_TUNNELING_MAX_LINK_RATE, &nrd_max_link_rate, sizeof(uint8_t)); return nrd_max_link_rate; } static int get_non_reduced_max_lane_count(struct dc_link *link) { uint8_t nrd_max_lane_count = 0; core_link_read_dpcd( link, DP_TUNNELING_MAX_LANE_COUNT, &nrd_max_lane_count, sizeof(uint8_t)); return nrd_max_lane_count; } /* * Read all New BW alloc configuration ex: estimated_bw, allocated_bw, * granuality, Driver_ID, CM_Group, & populate the BW allocation structs Loading @@ -111,13 +144,20 @@ static int get_estimated_bw(struct dc_link *link) */ static void init_usb4_bw_struct(struct dc_link *link) { // Init the known values reset_bw_alloc_struct(link); /* init the known values */ link->dpia_bw_alloc_config.bw_granularity = get_bw_granularity(link); link->dpia_bw_alloc_config.estimated_bw = get_estimated_bw(link); link->dpia_bw_alloc_config.nrd_max_link_rate = get_non_reduced_max_link_rate(link); link->dpia_bw_alloc_config.nrd_max_lane_count = get_non_reduced_max_lane_count(link); DC_LOG_DEBUG("%s: bw_granularity(%d), estimated_bw(%d)\n", __func__, link->dpia_bw_alloc_config.bw_granularity, link->dpia_bw_alloc_config.estimated_bw); DC_LOG_DEBUG("%s: nrd_max_link_rate(%d), nrd_max_lane_count(%d)\n", __func__, link->dpia_bw_alloc_config.nrd_max_link_rate, link->dpia_bw_alloc_config.nrd_max_lane_count); } static uint8_t get_lowest_dpia_index(struct dc_link *link) Loading @@ -142,39 +182,50 @@ static uint8_t get_lowest_dpia_index(struct dc_link *link) } /* * Get the Max Available BW or Max Estimated BW for each Host Router * Get the maximum dp tunnel banwidth of host router * * @link: pointer to the dc_link struct instance * @type: ESTIMATD BW or MAX AVAILABLE BW * @dc: pointer to the dc struct instance * @hr_index: host router index * * return: response_ready flag from dc_link struct * return: host router maximum dp tunnel bandwidth */ static int get_host_router_total_bw(struct dc_link *link, uint8_t type) static int get_host_router_total_dp_tunnel_bw(const struct dc *dc, uint8_t hr_index) { const struct dc *dc_struct = link->dc; uint8_t lowest_dpia_index = get_lowest_dpia_index(link); uint8_t idx = (link->link_index - lowest_dpia_index) / 2, idx_temp = 0; struct dc_link *link_temp; uint8_t lowest_dpia_index = get_lowest_dpia_index(dc->links[0]); uint8_t hr_index_temp = 0; struct dc_link *link_dpia_primary, *link_dpia_secondary; int total_bw = 0; int i; for (i = 0; i < MAX_PIPES * 2; ++i) { if (!dc_struct->links[i] || dc_struct->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) continue; for (uint8_t i = 0; i < (MAX_PIPES * 2) - 1; ++i) { link_temp = dc_struct->links[i]; if (!link_temp || !link_temp->hpd_status) if (!dc->links[i] || dc->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) continue; idx_temp = (link_temp->link_index - lowest_dpia_index) / 2; hr_index_temp = (dc->links[i]->link_index - lowest_dpia_index) / 2; if (idx_temp == idx) { if (hr_index_temp == hr_index) { link_dpia_primary = dc->links[i]; link_dpia_secondary = dc->links[i + 1]; if (type == HOST_ROUTER_BW_ESTIMATED) total_bw += link_temp->dpia_bw_alloc_config.estimated_bw; else if (type == HOST_ROUTER_BW_ALLOCATED) total_bw += link_temp->dpia_bw_alloc_config.sink_allocated_bw; /** * If BW allocation enabled on both DPIAs, then * HR BW = Estimated(dpia_primary) + Allocated(dpia_secondary) * otherwise HR BW = Estimated(bw alloc enabled dpia) */ if ((link_dpia_primary->hpd_status && link_dpia_primary->dpia_bw_alloc_config.bw_alloc_enabled) && (link_dpia_secondary->hpd_status && link_dpia_secondary->dpia_bw_alloc_config.bw_alloc_enabled)) { total_bw += link_dpia_primary->dpia_bw_alloc_config.estimated_bw + link_dpia_secondary->dpia_bw_alloc_config.allocated_bw; } else if (link_dpia_primary->hpd_status && link_dpia_primary->dpia_bw_alloc_config.bw_alloc_enabled) { total_bw = link_dpia_primary->dpia_bw_alloc_config.estimated_bw; } else if (link_dpia_secondary->hpd_status && link_dpia_secondary->dpia_bw_alloc_config.bw_alloc_enabled) { total_bw += link_dpia_secondary->dpia_bw_alloc_config.estimated_bw; } break; } } Loading @@ -194,7 +245,6 @@ static void dpia_bw_alloc_unplug(struct dc_link *link) if (link) { DC_LOG_DEBUG("%s: resetting bw alloc config for link(%d)\n", __func__, link->link_index); link->dpia_bw_alloc_config.sink_allocated_bw = 0; reset_bw_alloc_struct(link); } } Loading @@ -220,7 +270,7 @@ static void set_usb4_req_bw_req(struct dc_link *link, int req_bw) /* Error check whether requested and allocated are equal */ req_bw = requested_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); if (req_bw == link->dpia_bw_alloc_config.sink_allocated_bw) { if (req_bw == link->dpia_bw_alloc_config.allocated_bw) { DC_LOG_ERROR("%s: Request bw equals to allocated bw for link(%d)\n", __func__, link->link_index); } Loading Loading @@ -343,9 +393,9 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res DC_LOG_DEBUG("%s: BW REQ SUCCESS for DP-TX Request for link(%d)\n", __func__, link->link_index); DC_LOG_DEBUG("%s: current allocated_bw(%d), new allocated_bw(%d)\n", __func__, link->dpia_bw_alloc_config.sink_allocated_bw, bw_needed); __func__, link->dpia_bw_alloc_config.allocated_bw, bw_needed); link->dpia_bw_alloc_config.sink_allocated_bw = bw_needed; link->dpia_bw_alloc_config.allocated_bw = bw_needed; link->dpia_bw_alloc_config.response_ready = true; break; Loading Loading @@ -383,8 +433,8 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea if (link->hpd_status && peak_bw > 0) { // If DP over USB4 then we need to check BW allocation link->dpia_bw_alloc_config.sink_max_bw = peak_bw; set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.sink_max_bw); link->dpia_bw_alloc_config.link_max_bw = peak_bw; set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.link_max_bw); do { if (timeout > 0) Loading @@ -396,8 +446,8 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea if (!timeout) ret = 0;// ERROR TIMEOUT waiting for response for allocating bw else if (link->dpia_bw_alloc_config.sink_allocated_bw > 0) ret = get_host_router_total_bw(link, HOST_ROUTER_BW_ALLOCATED); else if (link->dpia_bw_alloc_config.allocated_bw > 0) ret = link->dpia_bw_alloc_config.allocated_bw; } //2. Cold Unplug else if (!link->hpd_status) Loading @@ -406,7 +456,6 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea out: return ret; } bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw) { bool ret = false; Loading @@ -414,7 +463,7 @@ bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int r DC_LOG_DEBUG("%s: ENTER: link(%d), hpd_status(%d), current allocated_bw(%d), req_bw(%d)\n", __func__, link->link_index, link->hpd_status, link->dpia_bw_alloc_config.sink_allocated_bw, req_bw); link->dpia_bw_alloc_config.allocated_bw, req_bw); if (!get_bw_alloc_proceed_flag(link)) goto out; Loading @@ -439,31 +488,70 @@ bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int r bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, const unsigned int num_dpias) { bool ret = true; int bw_needed_per_hr[MAX_HR_NUM] = { 0, 0 }; uint8_t lowest_dpia_index = 0, dpia_index = 0; uint8_t i; int bw_needed_per_hr[MAX_HR_NUM] = { 0, 0 }, host_router_total_dp_bw = 0; uint8_t lowest_dpia_index, i, hr_index; if (!num_dpias || num_dpias > MAX_DPIA_NUM) return ret; //Get total Host Router BW & Validate against each Host Router max BW lowest_dpia_index = get_lowest_dpia_index(link[0]); /* get total Host Router BW with granularity for the given modes */ for (i = 0; i < num_dpias; ++i) { int granularity_Gbps = 0; int bw_granularity = 0; if (!link[i]->dpia_bw_alloc_config.bw_alloc_enabled) continue; lowest_dpia_index = get_lowest_dpia_index(link[i]); if (link[i]->link_index < lowest_dpia_index) continue; dpia_index = (link[i]->link_index - lowest_dpia_index) / 2; bw_needed_per_hr[dpia_index] += bw_needed_per_dpia[i]; if (bw_needed_per_hr[dpia_index] > get_host_router_total_bw(link[i], HOST_ROUTER_BW_ALLOCATED)) { granularity_Gbps = (Kbps_TO_Gbps / link[i]->dpia_bw_alloc_config.bw_granularity); bw_granularity = (bw_needed_per_dpia[i] / granularity_Gbps) * granularity_Gbps + ((bw_needed_per_dpia[i] % granularity_Gbps) ? granularity_Gbps : 0); hr_index = (link[i]->link_index - lowest_dpia_index) / 2; bw_needed_per_hr[hr_index] += bw_granularity; } /* validate against each Host Router max BW */ for (hr_index = 0; hr_index < MAX_HR_NUM; ++hr_index) { if (bw_needed_per_hr[hr_index]) { host_router_total_dp_bw = get_host_router_total_dp_tunnel_bw(link[0]->dc, hr_index); if (bw_needed_per_hr[hr_index] > host_router_total_dp_bw) { ret = false; break; } } } return ret; } int link_dp_dpia_get_dp_overhead_in_dp_tunneling(struct dc_link *link) { int dp_overhead = 0, link_mst_overhead = 0; if (!get_bw_alloc_proceed_flag((link))) return dp_overhead; /* if its mst link, add MTPH overhead */ if ((link->type == dc_connection_mst_branch) && !link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) { /* For 8b/10b encoding: MTP is 64 time slots long, slot 0 is used for MTPH * MST overhead is 1/64 of link bandwidth (excluding any overhead) */ const struct dc_link_settings *link_cap = dc_link_get_link_cap(link); uint32_t link_bw_in_kbps = (uint32_t)link_cap->link_rate * (uint32_t)link_cap->lane_count * LINK_RATE_REF_FREQ_IN_KHZ * 8; link_mst_overhead = (link_bw_in_kbps / 64) + ((link_bw_in_kbps % 64) ? 1 : 0); } /* add all the overheads */ dp_overhead = link_mst_overhead; return dp_overhead; } Loading
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +135 −47 Original line number Diff line number Diff line Loading @@ -54,11 +54,18 @@ static bool get_bw_alloc_proceed_flag(struct dc_link *tmp) static void reset_bw_alloc_struct(struct dc_link *link) { link->dpia_bw_alloc_config.bw_alloc_enabled = false; link->dpia_bw_alloc_config.sink_verified_bw = 0; link->dpia_bw_alloc_config.sink_max_bw = 0; link->dpia_bw_alloc_config.link_verified_bw = 0; link->dpia_bw_alloc_config.link_max_bw = 0; link->dpia_bw_alloc_config.allocated_bw = 0; link->dpia_bw_alloc_config.estimated_bw = 0; link->dpia_bw_alloc_config.bw_granularity = 0; link->dpia_bw_alloc_config.dp_overhead = 0; link->dpia_bw_alloc_config.response_ready = false; link->dpia_bw_alloc_config.nrd_max_lane_count = 0; link->dpia_bw_alloc_config.nrd_max_link_rate = 0; for (int i = 0; i < MAX_SINKS_PER_LINK; i++) link->dpia_bw_alloc_config.remote_sink_req_bw[i] = 0; DC_LOG_DEBUG("reset usb4 bw alloc of link(%d)\n", link->link_index); } #define BW_GRANULARITY_0 4 // 0.25 Gbps Loading Loading @@ -104,6 +111,32 @@ static int get_estimated_bw(struct dc_link *link) return bw_estimated_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); } static int get_non_reduced_max_link_rate(struct dc_link *link) { uint8_t nrd_max_link_rate = 0; core_link_read_dpcd( link, DP_TUNNELING_MAX_LINK_RATE, &nrd_max_link_rate, sizeof(uint8_t)); return nrd_max_link_rate; } static int get_non_reduced_max_lane_count(struct dc_link *link) { uint8_t nrd_max_lane_count = 0; core_link_read_dpcd( link, DP_TUNNELING_MAX_LANE_COUNT, &nrd_max_lane_count, sizeof(uint8_t)); return nrd_max_lane_count; } /* * Read all New BW alloc configuration ex: estimated_bw, allocated_bw, * granuality, Driver_ID, CM_Group, & populate the BW allocation structs Loading @@ -111,13 +144,20 @@ static int get_estimated_bw(struct dc_link *link) */ static void init_usb4_bw_struct(struct dc_link *link) { // Init the known values reset_bw_alloc_struct(link); /* init the known values */ link->dpia_bw_alloc_config.bw_granularity = get_bw_granularity(link); link->dpia_bw_alloc_config.estimated_bw = get_estimated_bw(link); link->dpia_bw_alloc_config.nrd_max_link_rate = get_non_reduced_max_link_rate(link); link->dpia_bw_alloc_config.nrd_max_lane_count = get_non_reduced_max_lane_count(link); DC_LOG_DEBUG("%s: bw_granularity(%d), estimated_bw(%d)\n", __func__, link->dpia_bw_alloc_config.bw_granularity, link->dpia_bw_alloc_config.estimated_bw); DC_LOG_DEBUG("%s: nrd_max_link_rate(%d), nrd_max_lane_count(%d)\n", __func__, link->dpia_bw_alloc_config.nrd_max_link_rate, link->dpia_bw_alloc_config.nrd_max_lane_count); } static uint8_t get_lowest_dpia_index(struct dc_link *link) Loading @@ -142,39 +182,50 @@ static uint8_t get_lowest_dpia_index(struct dc_link *link) } /* * Get the Max Available BW or Max Estimated BW for each Host Router * Get the maximum dp tunnel banwidth of host router * * @link: pointer to the dc_link struct instance * @type: ESTIMATD BW or MAX AVAILABLE BW * @dc: pointer to the dc struct instance * @hr_index: host router index * * return: response_ready flag from dc_link struct * return: host router maximum dp tunnel bandwidth */ static int get_host_router_total_bw(struct dc_link *link, uint8_t type) static int get_host_router_total_dp_tunnel_bw(const struct dc *dc, uint8_t hr_index) { const struct dc *dc_struct = link->dc; uint8_t lowest_dpia_index = get_lowest_dpia_index(link); uint8_t idx = (link->link_index - lowest_dpia_index) / 2, idx_temp = 0; struct dc_link *link_temp; uint8_t lowest_dpia_index = get_lowest_dpia_index(dc->links[0]); uint8_t hr_index_temp = 0; struct dc_link *link_dpia_primary, *link_dpia_secondary; int total_bw = 0; int i; for (i = 0; i < MAX_PIPES * 2; ++i) { if (!dc_struct->links[i] || dc_struct->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) continue; for (uint8_t i = 0; i < (MAX_PIPES * 2) - 1; ++i) { link_temp = dc_struct->links[i]; if (!link_temp || !link_temp->hpd_status) if (!dc->links[i] || dc->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) continue; idx_temp = (link_temp->link_index - lowest_dpia_index) / 2; hr_index_temp = (dc->links[i]->link_index - lowest_dpia_index) / 2; if (idx_temp == idx) { if (hr_index_temp == hr_index) { link_dpia_primary = dc->links[i]; link_dpia_secondary = dc->links[i + 1]; if (type == HOST_ROUTER_BW_ESTIMATED) total_bw += link_temp->dpia_bw_alloc_config.estimated_bw; else if (type == HOST_ROUTER_BW_ALLOCATED) total_bw += link_temp->dpia_bw_alloc_config.sink_allocated_bw; /** * If BW allocation enabled on both DPIAs, then * HR BW = Estimated(dpia_primary) + Allocated(dpia_secondary) * otherwise HR BW = Estimated(bw alloc enabled dpia) */ if ((link_dpia_primary->hpd_status && link_dpia_primary->dpia_bw_alloc_config.bw_alloc_enabled) && (link_dpia_secondary->hpd_status && link_dpia_secondary->dpia_bw_alloc_config.bw_alloc_enabled)) { total_bw += link_dpia_primary->dpia_bw_alloc_config.estimated_bw + link_dpia_secondary->dpia_bw_alloc_config.allocated_bw; } else if (link_dpia_primary->hpd_status && link_dpia_primary->dpia_bw_alloc_config.bw_alloc_enabled) { total_bw = link_dpia_primary->dpia_bw_alloc_config.estimated_bw; } else if (link_dpia_secondary->hpd_status && link_dpia_secondary->dpia_bw_alloc_config.bw_alloc_enabled) { total_bw += link_dpia_secondary->dpia_bw_alloc_config.estimated_bw; } break; } } Loading @@ -194,7 +245,6 @@ static void dpia_bw_alloc_unplug(struct dc_link *link) if (link) { DC_LOG_DEBUG("%s: resetting bw alloc config for link(%d)\n", __func__, link->link_index); link->dpia_bw_alloc_config.sink_allocated_bw = 0; reset_bw_alloc_struct(link); } } Loading @@ -220,7 +270,7 @@ static void set_usb4_req_bw_req(struct dc_link *link, int req_bw) /* Error check whether requested and allocated are equal */ req_bw = requested_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); if (req_bw == link->dpia_bw_alloc_config.sink_allocated_bw) { if (req_bw == link->dpia_bw_alloc_config.allocated_bw) { DC_LOG_ERROR("%s: Request bw equals to allocated bw for link(%d)\n", __func__, link->link_index); } Loading Loading @@ -343,9 +393,9 @@ void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t res DC_LOG_DEBUG("%s: BW REQ SUCCESS for DP-TX Request for link(%d)\n", __func__, link->link_index); DC_LOG_DEBUG("%s: current allocated_bw(%d), new allocated_bw(%d)\n", __func__, link->dpia_bw_alloc_config.sink_allocated_bw, bw_needed); __func__, link->dpia_bw_alloc_config.allocated_bw, bw_needed); link->dpia_bw_alloc_config.sink_allocated_bw = bw_needed; link->dpia_bw_alloc_config.allocated_bw = bw_needed; link->dpia_bw_alloc_config.response_ready = true; break; Loading Loading @@ -383,8 +433,8 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea if (link->hpd_status && peak_bw > 0) { // If DP over USB4 then we need to check BW allocation link->dpia_bw_alloc_config.sink_max_bw = peak_bw; set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.sink_max_bw); link->dpia_bw_alloc_config.link_max_bw = peak_bw; set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.link_max_bw); do { if (timeout > 0) Loading @@ -396,8 +446,8 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea if (!timeout) ret = 0;// ERROR TIMEOUT waiting for response for allocating bw else if (link->dpia_bw_alloc_config.sink_allocated_bw > 0) ret = get_host_router_total_bw(link, HOST_ROUTER_BW_ALLOCATED); else if (link->dpia_bw_alloc_config.allocated_bw > 0) ret = link->dpia_bw_alloc_config.allocated_bw; } //2. Cold Unplug else if (!link->hpd_status) Loading @@ -406,7 +456,6 @@ int dpia_handle_usb4_bandwidth_allocation_for_link(struct dc_link *link, int pea out: return ret; } bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw) { bool ret = false; Loading @@ -414,7 +463,7 @@ bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int r DC_LOG_DEBUG("%s: ENTER: link(%d), hpd_status(%d), current allocated_bw(%d), req_bw(%d)\n", __func__, link->link_index, link->hpd_status, link->dpia_bw_alloc_config.sink_allocated_bw, req_bw); link->dpia_bw_alloc_config.allocated_bw, req_bw); if (!get_bw_alloc_proceed_flag(link)) goto out; Loading @@ -439,31 +488,70 @@ bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int r bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, const unsigned int num_dpias) { bool ret = true; int bw_needed_per_hr[MAX_HR_NUM] = { 0, 0 }; uint8_t lowest_dpia_index = 0, dpia_index = 0; uint8_t i; int bw_needed_per_hr[MAX_HR_NUM] = { 0, 0 }, host_router_total_dp_bw = 0; uint8_t lowest_dpia_index, i, hr_index; if (!num_dpias || num_dpias > MAX_DPIA_NUM) return ret; //Get total Host Router BW & Validate against each Host Router max BW lowest_dpia_index = get_lowest_dpia_index(link[0]); /* get total Host Router BW with granularity for the given modes */ for (i = 0; i < num_dpias; ++i) { int granularity_Gbps = 0; int bw_granularity = 0; if (!link[i]->dpia_bw_alloc_config.bw_alloc_enabled) continue; lowest_dpia_index = get_lowest_dpia_index(link[i]); if (link[i]->link_index < lowest_dpia_index) continue; dpia_index = (link[i]->link_index - lowest_dpia_index) / 2; bw_needed_per_hr[dpia_index] += bw_needed_per_dpia[i]; if (bw_needed_per_hr[dpia_index] > get_host_router_total_bw(link[i], HOST_ROUTER_BW_ALLOCATED)) { granularity_Gbps = (Kbps_TO_Gbps / link[i]->dpia_bw_alloc_config.bw_granularity); bw_granularity = (bw_needed_per_dpia[i] / granularity_Gbps) * granularity_Gbps + ((bw_needed_per_dpia[i] % granularity_Gbps) ? granularity_Gbps : 0); hr_index = (link[i]->link_index - lowest_dpia_index) / 2; bw_needed_per_hr[hr_index] += bw_granularity; } /* validate against each Host Router max BW */ for (hr_index = 0; hr_index < MAX_HR_NUM; ++hr_index) { if (bw_needed_per_hr[hr_index]) { host_router_total_dp_bw = get_host_router_total_dp_tunnel_bw(link[0]->dc, hr_index); if (bw_needed_per_hr[hr_index] > host_router_total_dp_bw) { ret = false; break; } } } return ret; } int link_dp_dpia_get_dp_overhead_in_dp_tunneling(struct dc_link *link) { int dp_overhead = 0, link_mst_overhead = 0; if (!get_bw_alloc_proceed_flag((link))) return dp_overhead; /* if its mst link, add MTPH overhead */ if ((link->type == dc_connection_mst_branch) && !link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) { /* For 8b/10b encoding: MTP is 64 time slots long, slot 0 is used for MTPH * MST overhead is 1/64 of link bandwidth (excluding any overhead) */ const struct dc_link_settings *link_cap = dc_link_get_link_cap(link); uint32_t link_bw_in_kbps = (uint32_t)link_cap->link_rate * (uint32_t)link_cap->lane_count * LINK_RATE_REF_FREQ_IN_KHZ * 8; link_mst_overhead = (link_bw_in_kbps / 64) + ((link_bw_in_kbps % 64) ? 1 : 0); } /* add all the overheads */ dp_overhead = link_mst_overhead; return dp_overhead; }