Commit 4c3adc0b authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher

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: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 6dd8931b
......@@ -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
}
......@@ -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_ */
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment