drm/amd/display: get and restore link res map

[why]
When reboot the link res map should be persisted.  So during boot up,
driver will look at the map to determine which link should take priority
to use certain link res.  This is to ensure that link res remains
unshuffled after a reboot.

Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Wenjing Liu 2021-12-10 14:22:19 -05:00 committed by Alex Deucher
parent 6dd8931b1c
commit 4c3adc0b84
3 changed files with 112 additions and 0 deletions

View File

@ -4890,3 +4890,106 @@ const struct link_resource *dc_link_get_cur_link_res(const struct dc_link *link)
return link_res;
}
/**
* dc_get_cur_link_res_map() - take a snapshot of current link resource allocation state
* @dc: pointer to dc of the dm calling this
* @map: a dc link resource snapshot defined internally to dc.
*
* DM needs to capture a snapshot of current link resource allocation mapping
* and store it in its persistent storage.
*
* Some of the link resource is using first come first serve policy.
* The allocation mapping depends on original hotplug order. This information
* is lost after driver is loaded next time. The snapshot is used in order to
* restore link resource to its previous state so user will get consistent
* link capability allocation across reboot.
*
* Return: none (void function)
*
*/
void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map)
{
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_link *link;
uint8_t i;
uint32_t hpo_dp_recycle_map = 0;
*map = 0;
if (dc->caps.dp_hpo) {
for (i = 0; i < dc->caps.max_links; i++) {
link = dc->links[i];
if (link->link_status.link_active &&
dp_get_link_encoding_format(&link->reported_link_cap) == DP_128b_132b_ENCODING &&
dp_get_link_encoding_format(&link->cur_link_settings) != DP_128b_132b_ENCODING)
/* hpo dp link encoder is considered as recycled, when RX reports 128b/132b encoding capability
* but current link doesn't use it.
*/
hpo_dp_recycle_map |= (1 << i);
}
*map |= (hpo_dp_recycle_map << LINK_RES_HPO_DP_REC_MAP__SHIFT);
}
#endif
}
/**
* dc_restore_link_res_map() - restore link resource allocation state from a snapshot
* @dc: pointer to dc of the dm calling this
* @map: a dc link resource snapshot defined internally to dc.
*
* DM needs to call this function after initial link detection on boot and
* before first commit streams to restore link resource allocation state
* from previous boot session.
*
* Some of the link resource is using first come first serve policy.
* The allocation mapping depends on original hotplug order. This information
* is lost after driver is loaded next time. The snapshot is used in order to
* restore link resource to its previous state so user will get consistent
* link capability allocation across reboot.
*
* Return: none (void function)
*
*/
void dc_restore_link_res_map(const struct dc *dc, uint32_t *map)
{
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_link *link;
uint8_t i;
unsigned int available_hpo_dp_count;
uint32_t hpo_dp_recycle_map = (*map & LINK_RES_HPO_DP_REC_MAP__MASK)
>> LINK_RES_HPO_DP_REC_MAP__SHIFT;
if (dc->caps.dp_hpo) {
available_hpo_dp_count = dc->res_pool->hpo_dp_link_enc_count;
/* remove excess 128b/132b encoding support for not recycled links */
for (i = 0; i < dc->caps.max_links; i++) {
if ((hpo_dp_recycle_map & (1 << i)) == 0) {
link = dc->links[i];
if (link->type != dc_connection_none &&
dp_get_link_encoding_format(&link->verified_link_cap) == DP_128b_132b_ENCODING) {
if (available_hpo_dp_count > 0)
available_hpo_dp_count--;
else
/* remove 128b/132b encoding capability by limiting verified link rate to HBR3 */
link->verified_link_cap.link_rate = LINK_RATE_HIGH3;
}
}
}
/* remove excess 128b/132b encoding support for recycled links */
for (i = 0; i < dc->caps.max_links; i++) {
if ((hpo_dp_recycle_map & (1 << i)) != 0) {
link = dc->links[i];
if (link->type != dc_connection_none &&
dp_get_link_encoding_format(&link->verified_link_cap) == DP_128b_132b_ENCODING) {
if (available_hpo_dp_count > 0)
available_hpo_dp_count--;
else
/* remove 128b/132b encoding capability by limiting verified link rate to HBR3 */
link->verified_link_cap.link_rate = LINK_RATE_HIGH3;
}
}
}
}
#endif
}

View File

@ -459,4 +459,8 @@ enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc
#endif
const struct link_resource *dc_link_get_cur_link_res(const struct dc_link *link);
/* take a snapshot of current link resource allocation state */
void dc_get_cur_link_res_map(const struct dc *dc, uint32_t *map);
/* restore link resource allocation state from a snapshot */
void dc_restore_link_res_map(const struct dc *dc, uint32_t *map);
#endif /* DC_LINK_H_ */

View File

@ -334,6 +334,11 @@ struct plane_resource {
struct dcn_fe_bandwidth bw;
};
#if defined(CONFIG_DRM_AMD_DC_DCN)
#define LINK_RES_HPO_DP_REC_MAP__MASK 0xFFFF
#define LINK_RES_HPO_DP_REC_MAP__SHIFT 0
#endif
/* all mappable hardware resources used to enable a link */
struct link_resource {
#if defined(CONFIG_DRM_AMD_DC_DCN)