@@ -1724,6 +1724,94 @@ static void update_hpo_dp_stream_engine_usage(
17241724 res_ctx -> is_hpo_dp_stream_enc_acquired [i ] = acquired ;
17251725 }
17261726}
1727+
1728+ static inline int find_acquired_hpo_dp_link_enc_for_link (
1729+ const struct resource_context * res_ctx ,
1730+ const struct dc_link * link )
1731+ {
1732+ int i ;
1733+
1734+ for (i = 0 ; i < ARRAY_SIZE (res_ctx -> hpo_dp_link_enc_to_link_idx ); i ++ )
1735+ if (res_ctx -> hpo_dp_link_enc_ref_cnts [i ] > 0 &&
1736+ res_ctx -> hpo_dp_link_enc_to_link_idx [i ] == link -> link_index )
1737+ return i ;
1738+
1739+ return -1 ;
1740+ }
1741+
1742+ static inline int find_free_hpo_dp_link_enc (const struct resource_context * res_ctx ,
1743+ const struct resource_pool * pool )
1744+ {
1745+ int i ;
1746+
1747+ for (i = 0 ; i < ARRAY_SIZE (res_ctx -> hpo_dp_link_enc_ref_cnts ); i ++ )
1748+ if (res_ctx -> hpo_dp_link_enc_ref_cnts [i ] == 0 )
1749+ break ;
1750+
1751+ return (i < ARRAY_SIZE (res_ctx -> hpo_dp_link_enc_ref_cnts ) &&
1752+ i < pool -> hpo_dp_link_enc_count ) ? i : -1 ;
1753+ }
1754+
1755+ static inline void acquire_hpo_dp_link_enc (
1756+ struct resource_context * res_ctx ,
1757+ unsigned int link_index ,
1758+ int enc_index )
1759+ {
1760+ res_ctx -> hpo_dp_link_enc_to_link_idx [enc_index ] = link_index ;
1761+ res_ctx -> hpo_dp_link_enc_ref_cnts [enc_index ] = 1 ;
1762+ }
1763+
1764+ static inline void retain_hpo_dp_link_enc (
1765+ struct resource_context * res_ctx ,
1766+ int enc_index )
1767+ {
1768+ res_ctx -> hpo_dp_link_enc_ref_cnts [enc_index ]++ ;
1769+ }
1770+
1771+ static inline void release_hpo_dp_link_enc (
1772+ struct resource_context * res_ctx ,
1773+ int enc_index )
1774+ {
1775+ ASSERT (res_ctx -> hpo_dp_link_enc_ref_cnts [enc_index ] > 0 );
1776+ res_ctx -> hpo_dp_link_enc_ref_cnts [enc_index ]-- ;
1777+ }
1778+
1779+ static bool add_hpo_dp_link_enc_to_ctx (struct resource_context * res_ctx ,
1780+ const struct resource_pool * pool ,
1781+ struct pipe_ctx * pipe_ctx ,
1782+ struct dc_stream_state * stream )
1783+ {
1784+ int enc_index ;
1785+
1786+ enc_index = find_acquired_hpo_dp_link_enc_for_link (res_ctx , stream -> link );
1787+
1788+ if (enc_index >= 0 ) {
1789+ retain_hpo_dp_link_enc (res_ctx , enc_index );
1790+ } else {
1791+ enc_index = find_free_hpo_dp_link_enc (res_ctx , pool );
1792+ if (enc_index >= 0 )
1793+ acquire_hpo_dp_link_enc (res_ctx , stream -> link -> link_index , enc_index );
1794+ }
1795+
1796+ if (enc_index >= 0 )
1797+ pipe_ctx -> link_res .hpo_dp_link_enc = pool -> hpo_dp_link_enc [enc_index ];
1798+
1799+ return pipe_ctx -> link_res .hpo_dp_link_enc != NULL ;
1800+ }
1801+
1802+ static void remove_hpo_dp_link_enc_from_ctx (struct resource_context * res_ctx ,
1803+ struct pipe_ctx * pipe_ctx ,
1804+ struct dc_stream_state * stream )
1805+ {
1806+ int enc_index ;
1807+
1808+ enc_index = find_acquired_hpo_dp_link_enc_for_link (res_ctx , stream -> link );
1809+
1810+ if (enc_index >= 0 ) {
1811+ release_hpo_dp_link_enc (res_ctx , enc_index );
1812+ pipe_ctx -> link_res .hpo_dp_link_enc = NULL ;
1813+ }
1814+ }
17271815#endif
17281816
17291817/* TODO: release audio object */
@@ -1886,6 +1974,7 @@ enum dc_status dc_remove_stream_from_ctx(
18861974 & new_ctx -> res_ctx , dc -> res_pool ,
18871975 del_pipe -> stream_res .hpo_dp_stream_enc ,
18881976 false);
1977+ remove_hpo_dp_link_enc_from_ctx (& new_ctx -> res_ctx , del_pipe , del_pipe -> stream );
18891978 }
18901979#endif
18911980
@@ -2161,7 +2250,8 @@ enum dc_status resource_map_pool_resources(
21612250 & context -> res_ctx , pool ,
21622251 pipe_ctx -> stream_res .hpo_dp_stream_enc ,
21632252 true);
2164- pipe_ctx -> link_res .hpo_dp_link_enc = stream -> link -> hpo_dp_link_enc ;
2253+ if (!add_hpo_dp_link_enc_to_ctx (& context -> res_ctx , pool , pipe_ctx , stream ))
2254+ return DC_NO_LINK_ENC_RESOURCE ;
21652255 }
21662256 }
21672257#endif
@@ -2837,6 +2927,8 @@ bool pipe_need_reprogram(
28372927#if defined(CONFIG_DRM_AMD_DC_DCN )
28382928 if (pipe_ctx_old -> stream_res .hpo_dp_stream_enc != pipe_ctx -> stream_res .hpo_dp_stream_enc )
28392929 return true;
2930+ if (pipe_ctx_old -> link_res .hpo_dp_link_enc != pipe_ctx -> link_res .hpo_dp_link_enc )
2931+ return true;
28402932#endif
28412933
28422934 /* DIG link encoder resource assignment for stream changed. */
@@ -3105,22 +3197,23 @@ void get_audio_check(struct audio_info *aud_modes,
31053197}
31063198
31073199#if defined(CONFIG_DRM_AMD_DC_DCN )
3108- struct hpo_dp_link_encoder * resource_get_unused_hpo_dp_link_encoder (
3109- const struct resource_pool * pool )
3200+ struct hpo_dp_link_encoder * resource_get_hpo_dp_link_enc_for_det_lt (
3201+ const struct resource_context * res_ctx ,
3202+ const struct resource_pool * pool ,
3203+ const struct dc_link * link )
31103204{
3111- uint8_t i ;
3112- struct hpo_dp_link_encoder * enc = NULL ;
3205+ struct hpo_dp_link_encoder * hpo_dp_link_enc = NULL ;
3206+ int enc_index ;
31133207
3114- ASSERT ( pool -> hpo_dp_link_enc_count <= MAX_HPO_DP2_LINK_ENCODERS );
3208+ enc_index = find_acquired_hpo_dp_link_enc_for_link ( res_ctx , link );
31153209
3116- for (i = 0 ; i < pool -> hpo_dp_link_enc_count ; i ++ ) {
3117- if (pool -> hpo_dp_link_enc [i ]-> transmitter == TRANSMITTER_UNKNOWN ) {
3118- enc = pool -> hpo_dp_link_enc [i ];
3119- break ;
3120- }
3121- }
3210+ if (enc_index < 0 )
3211+ enc_index = find_free_hpo_dp_link_enc (res_ctx , pool );
3212+
3213+ if (enc_index >= 0 )
3214+ hpo_dp_link_enc = pool -> hpo_dp_link_enc [enc_index ];
31223215
3123- return enc ;
3216+ return hpo_dp_link_enc ;
31243217}
31253218#endif
31263219
0 commit comments