Commit 35f33086 authored by Bhawanpreet Lakha's avatar Bhawanpreet Lakha Committed by Alex Deucher

drm/amd/display: Add support for multiple overlay planes

[Why]
We only allowed 1 overlay plane. But now some ASICS can support multiple
overlay planes.

[How]
Use max_slave_planes as the number of overlays we can support.

Also since we cannot draw cursor over a video plane, we need to make
sure that we reject commits where the topmost plane is a video plane
(overlay only).
Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5ca38a18
......@@ -4254,6 +4254,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
enum dc_connection_type new_connection_type = dc_connection_none;
const struct dc_plane_cap *plane;
bool psr_feature_enabled = false;
int max_overlay = dm->dc->caps.max_slave_planes;
dm->display_indexes_num = dm->dc->caps.max_streams;
/* Update the actual used number of crtc */
......@@ -4308,14 +4309,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
if (!plane->pixel_format_support.argb8888)
continue;
if (max_overlay-- == 0)
break;
if (initialize_plane(dm, NULL, primary_planes + i,
DRM_PLANE_TYPE_OVERLAY, plane)) {
DRM_ERROR("KMS: Failed to initialize overlay plane\n");
goto fail;
}
/* Only create one overlay plane. */
break;
}
for (i = 0; i < dm->dc->caps.max_streams; i++)
......@@ -9510,7 +9511,8 @@ static int dm_update_plane_state(struct dc *dc,
struct drm_plane_state *old_plane_state,
struct drm_plane_state *new_plane_state,
bool enable,
bool *lock_and_validation_needed)
bool *lock_and_validation_needed,
bool *is_top_most_overlay)
{
struct dm_atomic_state *dm_state = NULL;
......@@ -9618,6 +9620,14 @@ static int dm_update_plane_state(struct dc *dc,
if (!dc_new_plane_state)
return -ENOMEM;
/* Block top most plane from being a video plane */
if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
if (is_video_format(new_plane_state->fb->format->format) && *is_top_most_overlay)
return -EINVAL;
else
*is_top_most_overlay = false;
}
DRM_DEBUG_ATOMIC("Enabling DRM plane: %d on DRM crtc %d\n",
plane->base.id, new_plane_crtc->base.id);
......@@ -9814,6 +9824,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
enum dc_status status;
int ret, i;
bool lock_and_validation_needed = false;
bool is_top_most_overlay = true;
struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct drm_dp_mst_topology_mgr *mgr;
......@@ -9948,7 +9959,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
old_plane_state,
new_plane_state,
false,
&lock_and_validation_needed);
&lock_and_validation_needed,
&is_top_most_overlay);
if (ret) {
DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n");
goto fail;
......@@ -9987,7 +9999,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
old_plane_state,
new_plane_state,
true,
&lock_and_validation_needed);
&lock_and_validation_needed,
&is_top_most_overlay);
if (ret) {
DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n");
goto fail;
......
......@@ -67,7 +67,16 @@ static const uint32_t overlay_formats[] = {
DRM_FORMAT_RGBA8888,
DRM_FORMAT_XBGR8888,
DRM_FORMAT_ABGR8888,
DRM_FORMAT_RGB565
DRM_FORMAT_RGB565,
DRM_FORMAT_NV21,
DRM_FORMAT_NV12,
DRM_FORMAT_P010
};
static const uint32_t video_formats[] = {
DRM_FORMAT_NV21,
DRM_FORMAT_NV12,
DRM_FORMAT_P010
};
static const u32 cursor_formats[] = {
......@@ -1616,3 +1625,14 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
return 0;
}
bool is_video_format(uint32_t format)
{
int i;
for (i = 0; i < ARRAY_SIZE(video_formats); i++)
if (format == video_formats[i])
return true;
return false;
}
......@@ -62,4 +62,5 @@ void fill_blending_from_plane_state(const struct drm_plane_state *plane_state,
bool *per_pixel_alpha, bool *pre_multiplied_alpha,
bool *global_alpha, int *global_alpha_value);
bool is_video_format(uint32_t format);
#endif
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