drm/amd/display: Engine-specific encoder allocation
[WHY] From DCE110 onward, we have the ability to assign DIG BE and FE separately for any display connector type; before, we could only do this for DP. Signed-off-by: Wesley Chalmers <Wesley.Chalmers@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
		
							parent
							
								
									eed928dcd8
								
							
						
					
					
						commit
						78cc70b1e4
					
				| @ -1646,46 +1646,6 @@ static int acquire_first_free_pipe( | ||||
| 	return -1; | ||||
| } | ||||
| 
 | ||||
| static struct stream_encoder *find_first_free_match_stream_enc_for_link( | ||||
| 		struct resource_context *res_ctx, | ||||
| 		const struct resource_pool *pool, | ||||
| 		struct dc_stream_state *stream) | ||||
| { | ||||
| 	int i; | ||||
| 	int j = -1; | ||||
| 	struct dc_link *link = stream->link; | ||||
| 
 | ||||
| 	for (i = 0; i < pool->stream_enc_count; i++) { | ||||
| 		if (!res_ctx->is_stream_enc_acquired[i] && | ||||
| 				pool->stream_enc[i]) { | ||||
| 			/* Store first available for MST second display
 | ||||
| 			 * in daisy chain use case */ | ||||
| 			j = i; | ||||
| 			if (pool->stream_enc[i]->id == | ||||
| 					link->link_enc->preferred_engine) | ||||
| 				return pool->stream_enc[i]; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * below can happen in cases when stream encoder is acquired: | ||||
| 	 * 1) for second MST display in chain, so preferred engine already | ||||
| 	 * acquired; | ||||
| 	 * 2) for another link, which preferred engine already acquired by any | ||||
| 	 * MST configuration. | ||||
| 	 * | ||||
| 	 * If signal is of DP type and preferred engine not found, return last available | ||||
| 	 * | ||||
| 	 * TODO - This is just a patch up and a generic solution is | ||||
| 	 * required for non DP connectors. | ||||
| 	 */ | ||||
| 
 | ||||
| 	if (j >= 0 && link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT) | ||||
| 		return pool->stream_enc[j]; | ||||
| 
 | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| static struct audio *find_first_free_audio( | ||||
| 		struct resource_context *res_ctx, | ||||
| 		const struct resource_pool *pool, | ||||
| @ -1997,7 +1957,7 @@ enum dc_status resource_map_pool_resources( | ||||
| 	pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; | ||||
| 
 | ||||
| 	pipe_ctx->stream_res.stream_enc = | ||||
| 		find_first_free_match_stream_enc_for_link( | ||||
| 		dc->res_pool->funcs->find_first_free_match_stream_enc_for_link( | ||||
| 			&context->res_ctx, pool, stream); | ||||
| 
 | ||||
| 	if (!pipe_ctx->stream_res.stream_enc) | ||||
|  | ||||
| @ -867,13 +867,55 @@ enum dc_status dce100_validate_plane(const struct dc_plane_state *plane_state, s | ||||
| 	return DC_FAIL_SURFACE_VALIDATE; | ||||
| } | ||||
| 
 | ||||
| struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link( | ||||
| 		struct resource_context *res_ctx, | ||||
| 		const struct resource_pool *pool, | ||||
| 		struct dc_stream_state *stream) | ||||
| { | ||||
| 	int i; | ||||
| 	int j = -1; | ||||
| 	struct dc_link *link = stream->link; | ||||
| 
 | ||||
| 	for (i = 0; i < pool->stream_enc_count; i++) { | ||||
| 		if (!res_ctx->is_stream_enc_acquired[i] && | ||||
| 				pool->stream_enc[i]) { | ||||
| 			/* Store first available for MST second display
 | ||||
| 			 * in daisy chain use case | ||||
| 			 */ | ||||
| 			j = i; | ||||
| 			if (pool->stream_enc[i]->id == | ||||
| 					link->link_enc->preferred_engine) | ||||
| 				return pool->stream_enc[i]; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * below can happen in cases when stream encoder is acquired: | ||||
| 	 * 1) for second MST display in chain, so preferred engine already | ||||
| 	 * acquired; | ||||
| 	 * 2) for another link, which preferred engine already acquired by any | ||||
| 	 * MST configuration. | ||||
| 	 * | ||||
| 	 * If signal is of DP type and preferred engine not found, return last available | ||||
| 	 * | ||||
| 	 * TODO - This is just a patch up and a generic solution is | ||||
| 	 * required for non DP connectors. | ||||
| 	 */ | ||||
| 
 | ||||
| 	if (j >= 0 && link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT) | ||||
| 		return pool->stream_enc[j]; | ||||
| 
 | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| static const struct resource_funcs dce100_res_pool_funcs = { | ||||
| 	.destroy = dce100_destroy_resource_pool, | ||||
| 	.link_enc_create = dce100_link_encoder_create, | ||||
| 	.validate_bandwidth = dce100_validate_bandwidth, | ||||
| 	.validate_plane = dce100_validate_plane, | ||||
| 	.add_stream_to_ctx = dce100_add_stream_to_ctx, | ||||
| 	.validate_global = dce100_validate_global | ||||
| 	.validate_global = dce100_validate_global, | ||||
| 	.find_first_free_match_stream_enc_for_link = dce100_find_first_free_match_stream_enc_for_link | ||||
| }; | ||||
| 
 | ||||
| static bool construct( | ||||
|  | ||||
| @ -46,4 +46,9 @@ enum dc_status dce100_add_stream_to_ctx( | ||||
| 		struct dc_state *new_ctx, | ||||
| 		struct dc_stream_state *dc_stream); | ||||
| 
 | ||||
| struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link( | ||||
| 		struct resource_context *res_ctx, | ||||
| 		const struct resource_pool *pool, | ||||
| 		struct dc_stream_state *stream); | ||||
| 
 | ||||
| #endif /* DCE100_RESOURCE_H_ */ | ||||
|  | ||||
| @ -1134,6 +1134,38 @@ static void dce110_destroy_resource_pool(struct resource_pool **pool) | ||||
| 	*pool = NULL; | ||||
| } | ||||
| 
 | ||||
| struct stream_encoder *dce110_find_first_free_match_stream_enc_for_link( | ||||
| 		struct resource_context *res_ctx, | ||||
| 		const struct resource_pool *pool, | ||||
| 		struct dc_stream_state *stream) | ||||
| { | ||||
| 	int i; | ||||
| 	int j = -1; | ||||
| 	struct dc_link *link = stream->link; | ||||
| 
 | ||||
| 	for (i = 0; i < pool->stream_enc_count; i++) { | ||||
| 		if (!res_ctx->is_stream_enc_acquired[i] && | ||||
| 				pool->stream_enc[i]) { | ||||
| 			/* Store first available for MST second display
 | ||||
| 			 * in daisy chain use case | ||||
| 			 */ | ||||
| 			j = i; | ||||
| 			if (pool->stream_enc[i]->id == | ||||
| 					link->link_enc->preferred_engine) | ||||
| 				return pool->stream_enc[i]; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * For CZ and later, we can allow DIG FE and BE to differ for all display types | ||||
| 	 */ | ||||
| 
 | ||||
| 	if (j >= 0) | ||||
| 		return pool->stream_enc[j]; | ||||
| 
 | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static const struct resource_funcs dce110_res_pool_funcs = { | ||||
| 	.destroy = dce110_destroy_resource_pool, | ||||
| @ -1142,7 +1174,8 @@ static const struct resource_funcs dce110_res_pool_funcs = { | ||||
| 	.validate_plane = dce110_validate_plane, | ||||
| 	.acquire_idle_pipe_for_layer = dce110_acquire_underlay, | ||||
| 	.add_stream_to_ctx = dce110_add_stream_to_ctx, | ||||
| 	.validate_global = dce110_validate_global | ||||
| 	.validate_global = dce110_validate_global, | ||||
| 	.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link | ||||
| }; | ||||
| 
 | ||||
| static bool underlay_create(struct dc_context *ctx, struct resource_pool *pool) | ||||
|  | ||||
| @ -45,5 +45,10 @@ struct resource_pool *dce110_create_resource_pool( | ||||
| 	struct dc *dc, | ||||
| 	struct hw_asic_id asic_id); | ||||
| 
 | ||||
| struct stream_encoder *dce110_find_first_free_match_stream_enc_for_link( | ||||
| 		struct resource_context *res_ctx, | ||||
| 		const struct resource_pool *pool, | ||||
| 		struct dc_stream_state *stream); | ||||
| 
 | ||||
| #endif /* __DC_RESOURCE_DCE110_H__ */ | ||||
| 
 | ||||
|  | ||||
| @ -993,7 +993,8 @@ static const struct resource_funcs dce112_res_pool_funcs = { | ||||
| 	.validate_bandwidth = dce112_validate_bandwidth, | ||||
| 	.validate_plane = dce100_validate_plane, | ||||
| 	.add_stream_to_ctx = dce112_add_stream_to_ctx, | ||||
| 	.validate_global = dce112_validate_global | ||||
| 	.validate_global = dce112_validate_global, | ||||
| 	.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link | ||||
| }; | ||||
| 
 | ||||
| static void bw_calcs_data_update_from_pplib(struct dc *dc) | ||||
|  | ||||
| @ -837,7 +837,8 @@ static const struct resource_funcs dce120_res_pool_funcs = { | ||||
| 	.link_enc_create = dce120_link_encoder_create, | ||||
| 	.validate_bandwidth = dce112_validate_bandwidth, | ||||
| 	.validate_plane = dce100_validate_plane, | ||||
| 	.add_stream_to_ctx = dce112_add_stream_to_ctx | ||||
| 	.add_stream_to_ctx = dce112_add_stream_to_ctx, | ||||
| 	.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link | ||||
| }; | ||||
| 
 | ||||
| static void bw_calcs_data_update_from_pplib(struct dc *dc) | ||||
|  | ||||
| @ -880,7 +880,8 @@ static const struct resource_funcs dce80_res_pool_funcs = { | ||||
| 	.validate_bandwidth = dce80_validate_bandwidth, | ||||
| 	.validate_plane = dce100_validate_plane, | ||||
| 	.add_stream_to_ctx = dce100_add_stream_to_ctx, | ||||
| 	.validate_global = dce80_validate_global | ||||
| 	.validate_global = dce80_validate_global, | ||||
| 	.find_first_free_match_stream_enc_for_link = dce100_find_first_free_match_stream_enc_for_link | ||||
| }; | ||||
| 
 | ||||
| static bool dce80_construct( | ||||
|  | ||||
| @ -1243,7 +1243,8 @@ static const struct resource_funcs dcn10_res_pool_funcs = { | ||||
| 	.validate_plane = dcn10_validate_plane, | ||||
| 	.validate_global = dcn10_validate_global, | ||||
| 	.add_stream_to_ctx = dcn10_add_stream_to_ctx, | ||||
| 	.get_default_swizzle_mode = dcn10_get_default_swizzle_mode | ||||
| 	.get_default_swizzle_mode = dcn10_get_default_swizzle_mode, | ||||
| 	.find_first_free_match_stream_enc_for_link = dce110_find_first_free_match_stream_enc_for_link | ||||
| }; | ||||
| 
 | ||||
| static uint32_t read_pipe_fuses(struct dc_context *ctx) | ||||
|  | ||||
| @ -123,6 +123,11 @@ struct resource_funcs { | ||||
| 	enum dc_status (*get_default_swizzle_mode)( | ||||
| 			struct dc_plane_state *plane_state); | ||||
| 
 | ||||
| 	struct stream_encoder *(*find_first_free_match_stream_enc_for_link)( | ||||
| 			struct resource_context *res_ctx, | ||||
| 			const struct resource_pool *pool, | ||||
| 			struct dc_stream_state *stream); | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| struct audio_support{ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user