mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 12:53:04 -04:00
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: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com> Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
5ca38a18b5
commit
35f33086b1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user