Commit 2de09ce4 authored by Aurabindo Pillai's avatar Aurabindo Pillai Committed by Alex Deucher

drm/amd/display: fix CAB allocation for multiple displays

[Why & How]
When multiple displays are used, the underlying framebuffers could be
two separate framebuffers, or a single large framebuffer. Fix the
calculation logic for CAB to account for large framebuffer. Current
logic assumes that any FB that the plane points to are independent. When
a single FB is used on the system, this does 2 times allocation.

Add a check to prevent duplicate allocation by checking if the base
addresses are the same, and then ensuring that the if we allocate using
the pitch, whole of the other fbs will be accounted for in the first
allocation.
Reviewed-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Acked-by: default avatarTom Chung <chiahsuan.chung@amd.com>
Signed-off-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 0af167f9
...@@ -250,6 +250,7 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c ...@@ -250,6 +250,7 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
uint32_t total_lines = 0; uint32_t total_lines = 0;
uint32_t lines_per_way = 0; uint32_t lines_per_way = 0;
uint32_t num_ways = 0; uint32_t num_ways = 0;
uint32_t prev_addr_low = 0;
for (i = 0; i < ctx->stream_count; i++) { for (i = 0; i < ctx->stream_count; i++) {
stream = ctx->streams[i]; stream = ctx->streams[i];
...@@ -267,10 +268,20 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c ...@@ -267,10 +268,20 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
plane = ctx->stream_status[i].plane_states[j]; plane = ctx->stream_status[i].plane_states[j];
// Calculate total surface size // Calculate total surface size
surface_size = plane->plane_size.surface_pitch * if (prev_addr_low != plane->address.grph.addr.u.low_part) {
/* if plane address are different from prev FB, then userspace allocated separate FBs*/
surface_size += plane->plane_size.surface_pitch *
plane->plane_size.surface_size.height * plane->plane_size.surface_size.height *
(plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4); (plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4);
prev_addr_low = plane->address.grph.addr.u.low_part;
} else {
/* We have the same fb for all the planes.
* Xorg always creates one giant fb that holds all surfaces,
* so allocating it once is sufficient.
* */
continue;
}
// Convert surface size + starting address to number of cache lines required // Convert surface size + starting address to number of cache lines required
// (alignment accounted for) // (alignment accounted for)
cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size, cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
......
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