mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
drm/amd/display: reallocate DET for dual displays with high pixel rate ratio
[Why] For dual displays where pixel rate is much higher on one display, we may get underflow when DET is evenly allocated. [How] Allocate less DET segments for the lower pixel rate display and more DET segments for the higher pixel rate display Reviewed-by: Alvin Lee <Alvin.Lee2@amd.com> Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com> Signed-off-by: Samson Tam <Samson.Tam@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
562e08223a
commit
5f3401eeb0
@ -257,6 +257,8 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe)
|
||||
return psr_capable;
|
||||
}
|
||||
|
||||
#define DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER 7
|
||||
|
||||
/**
|
||||
* *******************************************************************************************
|
||||
* dcn32_determine_det_override: Determine DET allocation for each pipe
|
||||
@ -268,7 +270,6 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe)
|
||||
* If there is a plane that's driven by more than 1 pipe (i.e. pipe split), then the
|
||||
* number of DET for that given plane will be split among the pipes driving that plane.
|
||||
*
|
||||
*
|
||||
* High level algorithm:
|
||||
* 1. Split total DET among number of streams
|
||||
* 2. For each stream, split DET among the planes
|
||||
@ -276,6 +277,18 @@ bool dcn32_is_psr_capable(struct pipe_ctx *pipe)
|
||||
* among those pipes.
|
||||
* 4. Assign the DET override to the DML pipes.
|
||||
*
|
||||
* Special cases:
|
||||
*
|
||||
* For two displays that have a large difference in pixel rate, we may experience
|
||||
* underflow on the larger display when we divide the DET equally. For this, we
|
||||
* will implement a modified algorithm to assign more DET to larger display.
|
||||
*
|
||||
* 1. Calculate difference in pixel rates ( multiplier ) between two displays
|
||||
* 2. If the multiplier exceeds DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER, then
|
||||
* implement the modified DET override algorithm.
|
||||
* 3. Assign smaller DET size for lower pixel display and higher DET size for
|
||||
* higher pixel display
|
||||
*
|
||||
* @param [in]: dc: Current DC state
|
||||
* @param [in]: context: New DC state to be programmed
|
||||
* @param [in]: pipes: Array of DML pipes
|
||||
@ -295,18 +308,46 @@ void dcn32_determine_det_override(struct dc *dc,
|
||||
struct dc_plane_state *current_plane = NULL;
|
||||
uint8_t stream_count = 0;
|
||||
|
||||
int phy_pix_clk_mult, lower_mode_stream_index;
|
||||
int phy_pix_clk[MAX_PIPES] = {0};
|
||||
bool use_new_det_override_algorithm = false;
|
||||
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
/* Don't count SubVP streams for DET allocation */
|
||||
if (context->streams[i]->mall_stream_config.type != SUBVP_PHANTOM) {
|
||||
phy_pix_clk[i] = context->streams[i]->phy_pix_clk;
|
||||
stream_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for special case with two displays, one with much higher pixel rate */
|
||||
if (stream_count == 2) {
|
||||
ASSERT(!phy_pix_clk[0] || !phy_pix_clk[1]);
|
||||
if (phy_pix_clk[0] < phy_pix_clk[1]) {
|
||||
lower_mode_stream_index = 0;
|
||||
phy_pix_clk_mult = phy_pix_clk[1] / phy_pix_clk[0];
|
||||
} else {
|
||||
lower_mode_stream_index = 1;
|
||||
phy_pix_clk_mult = phy_pix_clk[0] / phy_pix_clk[1];
|
||||
}
|
||||
|
||||
if (phy_pix_clk_mult >= DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER)
|
||||
use_new_det_override_algorithm = true;
|
||||
}
|
||||
|
||||
if (stream_count > 0) {
|
||||
stream_segments = 18 / stream_count;
|
||||
for (i = 0; i < context->stream_count; i++) {
|
||||
if (context->streams[i]->mall_stream_config.type == SUBVP_PHANTOM)
|
||||
continue;
|
||||
|
||||
if (use_new_det_override_algorithm) {
|
||||
if (i == lower_mode_stream_index)
|
||||
stream_segments = 4;
|
||||
else
|
||||
stream_segments = 14;
|
||||
}
|
||||
|
||||
if (context->stream_status[i].plane_count > 0)
|
||||
plane_segments = stream_segments / context->stream_status[i].plane_count;
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user