Skip to content

Commit fa57924

Browse files
Wayne Linalexdeucher
authored andcommitted
drm/amd/display: Refactor function dm_dp_mst_is_port_support_mode()
[Why] dm_dp_mst_is_port_support_mode() is a bit not following the original design rule and cause light up issue with multiple 4k monitors after mst dsc hub. [How] Refactor function dm_dp_mst_is_port_support_mode() a bit to solve the light up issue. Reviewed-by: Jerry Zuo <[email protected]> Acked-by: Zaeem Mohamed <[email protected]> Signed-off-by: Wayne Lin <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent fcf6a49 commit fa57924

File tree

1 file changed

+146
-86
lines changed

1 file changed

+146
-86
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c

Lines changed: 146 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,111 +1597,171 @@ static bool is_dsc_common_config_possible(struct dc_stream_state *stream,
15971597
}
15981598
#endif
15991599

1600+
#if defined(CONFIG_DRM_AMD_DC_FP)
1601+
static bool dp_get_link_current_set_bw(struct drm_dp_aux *aux, uint32_t *cur_link_bw)
1602+
{
1603+
uint32_t total_data_bw_efficiency_x10000 = 0;
1604+
uint32_t link_rate_per_lane_kbps = 0;
1605+
enum dc_link_rate link_rate;
1606+
union lane_count_set lane_count;
1607+
u8 dp_link_encoding;
1608+
u8 link_bw_set = 0;
1609+
1610+
*cur_link_bw = 0;
1611+
1612+
if (drm_dp_dpcd_read(aux, DP_MAIN_LINK_CHANNEL_CODING_SET, &dp_link_encoding, 1) != 1 ||
1613+
drm_dp_dpcd_read(aux, DP_LANE_COUNT_SET, &lane_count.raw, 1) != 1 ||
1614+
drm_dp_dpcd_read(aux, DP_LINK_BW_SET, &link_bw_set, 1) != 1)
1615+
return false;
1616+
1617+
switch (dp_link_encoding) {
1618+
case DP_8b_10b_ENCODING:
1619+
link_rate = link_bw_set;
1620+
link_rate_per_lane_kbps = link_rate * LINK_RATE_REF_FREQ_IN_KHZ * BITS_PER_DP_BYTE;
1621+
total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_8b_10b_x10000;
1622+
total_data_bw_efficiency_x10000 /= 100;
1623+
total_data_bw_efficiency_x10000 *= DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100;
1624+
break;
1625+
case DP_128b_132b_ENCODING:
1626+
switch (link_bw_set) {
1627+
case DP_LINK_BW_10:
1628+
link_rate = LINK_RATE_UHBR10;
1629+
break;
1630+
case DP_LINK_BW_13_5:
1631+
link_rate = LINK_RATE_UHBR13_5;
1632+
break;
1633+
case DP_LINK_BW_20:
1634+
link_rate = LINK_RATE_UHBR20;
1635+
break;
1636+
default:
1637+
return false;
1638+
}
1639+
1640+
link_rate_per_lane_kbps = link_rate * 10000;
1641+
total_data_bw_efficiency_x10000 = DATA_EFFICIENCY_128b_132b_x10000;
1642+
break;
1643+
default:
1644+
return false;
1645+
}
1646+
1647+
*cur_link_bw = link_rate_per_lane_kbps * lane_count.bits.LANE_COUNT_SET / 10000 * total_data_bw_efficiency_x10000;
1648+
return true;
1649+
}
1650+
#endif
1651+
16001652
enum dc_status dm_dp_mst_is_port_support_mode(
16011653
struct amdgpu_dm_connector *aconnector,
16021654
struct dc_stream_state *stream)
16031655
{
1604-
int branch_max_throughput_mps = 0;
16051656
#if defined(CONFIG_DRM_AMD_DC_FP)
1657+
int branch_max_throughput_mps = 0;
16061658
struct dc_link_settings cur_link_settings;
1607-
int pbn;
1608-
unsigned int end_to_end_bw_in_kbps = 0;
1609-
unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0;
1659+
uint32_t end_to_end_bw_in_kbps = 0;
1660+
uint32_t root_link_bw_in_kbps = 0;
1661+
uint32_t virtual_channel_bw_in_kbps = 0;
16101662
struct dc_dsc_bw_range bw_range = {0};
16111663
struct dc_dsc_config_options dsc_options = {0};
1664+
uint32_t stream_kbps;
16121665

1613-
/*
1614-
* Consider the case with the depth of the mst topology tree is equal or less than 2
1615-
* A. When dsc bitstream can be transmitted along the entire path
1616-
* 1. dsc is possible between source and branch/leaf device (common dsc params is possible), AND
1617-
* 2. dsc passthrough supported at MST branch, or
1618-
* 3. dsc decoding supported at leaf MST device
1619-
* Use maximum dsc compression as bw constraint
1620-
* B. When dsc bitstream cannot be transmitted along the entire path
1621-
* Use native bw as bw constraint
1666+
/* DSC unnecessary case
1667+
* Check if timing could be supported within end-to-end BW
16221668
*/
1623-
if (is_dsc_common_config_possible(stream, &bw_range) &&
1624-
(aconnector->mst_output_port->passthrough_aux ||
1625-
aconnector->dsc_aux == &aconnector->mst_output_port->aux)) {
1626-
cur_link_settings = stream->link->verified_link_cap;
1627-
upper_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, &cur_link_settings);
1628-
down_link_bw_in_kbps = kbps_from_pbn(aconnector->mst_output_port->full_pbn);
1629-
1630-
/* pick the end to end bw bottleneck */
1631-
end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps, down_link_bw_in_kbps);
1632-
1633-
if (end_to_end_bw_in_kbps < bw_range.min_kbps) {
1634-
DRM_DEBUG_DRIVER("maximum dsc compression cannot fit into end-to-end bandwidth\n");
1669+
stream_kbps =
1670+
dc_bandwidth_in_kbps_from_timing(&stream->timing,
1671+
dc_link_get_highest_encoding_format(stream->link));
1672+
cur_link_settings = stream->link->verified_link_cap;
1673+
root_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, &cur_link_settings);
1674+
virtual_channel_bw_in_kbps = kbps_from_pbn(aconnector->mst_output_port->full_pbn);
1675+
1676+
/* pick the end to end bw bottleneck */
1677+
end_to_end_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
1678+
1679+
if (stream_kbps <= end_to_end_bw_in_kbps) {
1680+
DRM_DEBUG_DRIVER("No DSC needed. End-to-end bw sufficient.");
1681+
return DC_OK;
1682+
}
1683+
1684+
/*DSC necessary case*/
1685+
if (!aconnector->dsc_aux)
1686+
return DC_FAIL_BANDWIDTH_VALIDATE;
1687+
1688+
if (is_dsc_common_config_possible(stream, &bw_range)) {
1689+
1690+
/*capable of dsc passthough. dsc bitstream along the entire path*/
1691+
if (aconnector->mst_output_port->passthrough_aux) {
1692+
if (bw_range.min_kbps > end_to_end_bw_in_kbps) {
1693+
DRM_DEBUG_DRIVER("DSC passthrough. Max dsc compression can't fit into end-to-end bw\n");
16351694
return DC_FAIL_BANDWIDTH_VALIDATE;
1636-
}
1695+
}
1696+
} else {
1697+
/*dsc bitstream decoded at the dp last link*/
1698+
struct drm_dp_mst_port *immediate_upstream_port = NULL;
1699+
uint32_t end_link_bw = 0;
1700+
1701+
/*Get last DP link BW capability*/
1702+
if (dp_get_link_current_set_bw(&aconnector->mst_output_port->aux, &end_link_bw)) {
1703+
if (stream_kbps > end_link_bw) {
1704+
DRM_DEBUG_DRIVER("DSC decode at last link. Mode required bw can't fit into available bw\n");
1705+
return DC_FAIL_BANDWIDTH_VALIDATE;
1706+
}
1707+
}
16371708

1638-
if (end_to_end_bw_in_kbps < bw_range.stream_kbps) {
1639-
dc_dsc_get_default_config_option(stream->link->dc, &dsc_options);
1640-
dsc_options.max_target_bpp_limit_override_x16 = aconnector->base.display_info.max_dsc_bpp * 16;
1641-
if (dc_dsc_compute_config(stream->sink->ctx->dc->res_pool->dscs[0],
1642-
&stream->sink->dsc_caps.dsc_dec_caps,
1643-
&dsc_options,
1644-
end_to_end_bw_in_kbps,
1645-
&stream->timing,
1646-
dc_link_get_highest_encoding_format(stream->link),
1647-
&stream->timing.dsc_cfg)) {
1648-
stream->timing.flags.DSC = 1;
1649-
DRM_DEBUG_DRIVER("end-to-end bandwidth require dsc and dsc config found\n");
1650-
} else {
1651-
DRM_DEBUG_DRIVER("end-to-end bandwidth require dsc but dsc config not found\n");
1652-
return DC_FAIL_BANDWIDTH_VALIDATE;
1709+
/*Get virtual channel bandwidth between source and the link before the last link*/
1710+
if (aconnector->mst_output_port->parent->port_parent)
1711+
immediate_upstream_port = aconnector->mst_output_port->parent->port_parent;
1712+
1713+
if (immediate_upstream_port) {
1714+
virtual_channel_bw_in_kbps = kbps_from_pbn(immediate_upstream_port->full_pbn);
1715+
virtual_channel_bw_in_kbps = min(root_link_bw_in_kbps, virtual_channel_bw_in_kbps);
1716+
if (bw_range.min_kbps > virtual_channel_bw_in_kbps) {
1717+
DRM_DEBUG_DRIVER("DSC decode at last link. Max dsc compression can't fit into MST available bw\n");
1718+
return DC_FAIL_BANDWIDTH_VALIDATE;
1719+
}
16531720
}
16541721
}
1655-
} else {
1656-
/* Check if mode could be supported within max slot
1657-
* number of current mst link and full_pbn of mst links.
1658-
*/
1659-
int pbn_div, slot_num, max_slot_num;
1660-
enum dc_link_encoding_format link_encoding;
1661-
uint32_t stream_kbps =
1662-
dc_bandwidth_in_kbps_from_timing(&stream->timing,
1663-
dc_link_get_highest_encoding_format(stream->link));
1664-
1665-
pbn = kbps_to_peak_pbn(stream_kbps);
1666-
pbn_div = dm_mst_get_pbn_divider(stream->link);
1667-
slot_num = DIV_ROUND_UP(pbn, pbn_div);
1668-
1669-
link_encoding = dc_link_get_highest_encoding_format(stream->link);
1670-
if (link_encoding == DC_LINK_ENCODING_DP_8b_10b)
1671-
max_slot_num = 63;
1672-
else if (link_encoding == DC_LINK_ENCODING_DP_128b_132b)
1673-
max_slot_num = 64;
1674-
else {
1675-
DRM_DEBUG_DRIVER("Invalid link encoding format\n");
1722+
1723+
/*Confirm if we can obtain dsc config*/
1724+
dc_dsc_get_default_config_option(stream->link->dc, &dsc_options);
1725+
dsc_options.max_target_bpp_limit_override_x16 = aconnector->base.display_info.max_dsc_bpp * 16;
1726+
if (dc_dsc_compute_config(stream->sink->ctx->dc->res_pool->dscs[0],
1727+
&stream->sink->dsc_caps.dsc_dec_caps,
1728+
&dsc_options,
1729+
end_to_end_bw_in_kbps,
1730+
&stream->timing,
1731+
dc_link_get_highest_encoding_format(stream->link),
1732+
&stream->timing.dsc_cfg)) {
1733+
stream->timing.flags.DSC = 1;
1734+
DRM_DEBUG_DRIVER("Require dsc and dsc config found\n");
1735+
} else {
1736+
DRM_DEBUG_DRIVER("Require dsc but can't find appropriate dsc config\n");
16761737
return DC_FAIL_BANDWIDTH_VALIDATE;
16771738
}
16781739

1679-
if (slot_num > max_slot_num ||
1680-
pbn > aconnector->mst_output_port->full_pbn) {
1681-
DRM_DEBUG_DRIVER("Mode can not be supported within mst links!");
1682-
return DC_FAIL_BANDWIDTH_VALIDATE;
1740+
/* check is mst dsc output bandwidth branch_overall_throughput_0_mps */
1741+
switch (stream->timing.pixel_encoding) {
1742+
case PIXEL_ENCODING_RGB:
1743+
case PIXEL_ENCODING_YCBCR444:
1744+
branch_max_throughput_mps =
1745+
aconnector->dc_sink->dsc_caps.dsc_dec_caps.branch_overall_throughput_0_mps;
1746+
break;
1747+
case PIXEL_ENCODING_YCBCR422:
1748+
case PIXEL_ENCODING_YCBCR420:
1749+
branch_max_throughput_mps =
1750+
aconnector->dc_sink->dsc_caps.dsc_dec_caps.branch_overall_throughput_1_mps;
1751+
break;
1752+
default:
1753+
break;
16831754
}
1684-
}
1685-
/* check is mst dsc output bandwidth branch_overall_throughput_0_mps */
1686-
switch (stream->timing.pixel_encoding) {
1687-
case PIXEL_ENCODING_RGB:
1688-
case PIXEL_ENCODING_YCBCR444:
1689-
branch_max_throughput_mps =
1690-
aconnector->dc_sink->dsc_caps.dsc_dec_caps.branch_overall_throughput_0_mps;
1691-
break;
1692-
case PIXEL_ENCODING_YCBCR422:
1693-
case PIXEL_ENCODING_YCBCR420:
1694-
branch_max_throughput_mps =
1695-
aconnector->dc_sink->dsc_caps.dsc_dec_caps.branch_overall_throughput_1_mps;
1696-
break;
1697-
default:
1698-
break;
1699-
}
1700-
#endif
17011755

1702-
if (branch_max_throughput_mps != 0 &&
1703-
((stream->timing.pix_clk_100hz / 10) > branch_max_throughput_mps * 1000))
1756+
if (branch_max_throughput_mps != 0 &&
1757+
((stream->timing.pix_clk_100hz / 10) > branch_max_throughput_mps * 1000)) {
1758+
DRM_DEBUG_DRIVER("DSC is required but max throughput mps fails");
17041759
return DC_FAIL_BANDWIDTH_VALIDATE;
1705-
1760+
}
1761+
} else {
1762+
DRM_DEBUG_DRIVER("DSC is required but can't find common dsc config.");
1763+
return DC_FAIL_BANDWIDTH_VALIDATE;
1764+
}
1765+
#endif
17061766
return DC_OK;
17071767
}

0 commit comments

Comments
 (0)