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;
|
return psr_capable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DCN3_2_NEW_DET_OVERRIDE_MIN_MULTIPLIER 7
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* *******************************************************************************************
|
* *******************************************************************************************
|
||||||
* dcn32_determine_det_override: Determine DET allocation for each pipe
|
* 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
|
* 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.
|
* number of DET for that given plane will be split among the pipes driving that plane.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* High level algorithm:
|
* High level algorithm:
|
||||||
* 1. Split total DET among number of streams
|
* 1. Split total DET among number of streams
|
||||||
* 2. For each stream, split DET among the planes
|
* 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.
|
* among those pipes.
|
||||||
* 4. Assign the DET override to the DML 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]: dc: Current DC state
|
||||||
* @param [in]: context: New DC state to be programmed
|
* @param [in]: context: New DC state to be programmed
|
||||||
* @param [in]: pipes: Array of DML pipes
|
* @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;
|
struct dc_plane_state *current_plane = NULL;
|
||||||
uint8_t stream_count = 0;
|
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++) {
|
for (i = 0; i < context->stream_count; i++) {
|
||||||
/* Don't count SubVP streams for DET allocation */
|
/* Don't count SubVP streams for DET allocation */
|
||||||
if (context->streams[i]->mall_stream_config.type != SUBVP_PHANTOM) {
|
if (context->streams[i]->mall_stream_config.type != SUBVP_PHANTOM) {
|
||||||
|
phy_pix_clk[i] = context->streams[i]->phy_pix_clk;
|
||||||
stream_count++;
|
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) {
|
if (stream_count > 0) {
|
||||||
stream_segments = 18 / stream_count;
|
stream_segments = 18 / stream_count;
|
||||||
for (i = 0; i < context->stream_count; i++) {
|
for (i = 0; i < context->stream_count; i++) {
|
||||||
if (context->streams[i]->mall_stream_config.type == SUBVP_PHANTOM)
|
if (context->streams[i]->mall_stream_config.type == SUBVP_PHANTOM)
|
||||||
continue;
|
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)
|
if (context->stream_status[i].plane_count > 0)
|
||||||
plane_segments = stream_segments / context->stream_status[i].plane_count;
|
plane_segments = stream_segments / context->stream_status[i].plane_count;
|
||||||
else
|
else
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user