drm/amd/display: Expose support for NV12 on suitable planes

[Why]
Hardware can support video surfaces and DC tells us which planes are
suitable via DC plane caps.

[How]
The supported formats array will now vary based on what DC tells us,
so create an array and fill it dynamically based on plane types and
caps.

Ideally we'd query support for every format via DC plane caps, but for
the framework is in place to do so later with this.

Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: Sun peng Li <Sunpeng.Li@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Nicholas Kazlauskas 2019-03-15 15:45:34 -04:00 committed by Alex Deucher
parent 3be0a0b850
commit 37c6a93b7e
1 changed files with 58 additions and 34 deletions

View File

@ -4121,45 +4121,70 @@ static const u32 cursor_formats[] = {
DRM_FORMAT_ARGB8888 DRM_FORMAT_ARGB8888
}; };
static int get_plane_formats(const struct drm_plane *plane,
const struct dc_plane_cap *plane_cap,
uint32_t *formats, int max_formats)
{
int i, num_formats = 0;
/*
* TODO: Query support for each group of formats directly from
* DC plane caps. This will require adding more formats to the
* caps list.
*/
switch (plane->type) {
case DRM_PLANE_TYPE_PRIMARY:
for (i = 0; i < ARRAY_SIZE(rgb_formats); ++i) {
if (num_formats >= max_formats)
break;
formats[num_formats++] = rgb_formats[i];
}
if (plane_cap && plane_cap->supports_nv12)
formats[num_formats++] = DRM_FORMAT_NV12;
break;
case DRM_PLANE_TYPE_OVERLAY:
for (i = 0; i < ARRAY_SIZE(overlay_formats); ++i) {
if (num_formats >= max_formats)
break;
formats[num_formats++] = overlay_formats[i];
}
break;
case DRM_PLANE_TYPE_CURSOR:
for (i = 0; i < ARRAY_SIZE(cursor_formats); ++i) {
if (num_formats >= max_formats)
break;
formats[num_formats++] = cursor_formats[i];
}
break;
}
return num_formats;
}
static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
struct drm_plane *plane, struct drm_plane *plane,
unsigned long possible_crtcs, unsigned long possible_crtcs,
const struct dc_plane_cap *plane_cap) const struct dc_plane_cap *plane_cap)
{ {
uint32_t formats[32];
int num_formats;
int res = -EPERM; int res = -EPERM;
switch (plane->type) { num_formats = get_plane_formats(plane, plane_cap, formats,
case DRM_PLANE_TYPE_PRIMARY: ARRAY_SIZE(formats));
res = drm_universal_plane_init(
dm->adev->ddev, res = drm_universal_plane_init(dm->adev->ddev, plane, possible_crtcs,
plane, &dm_plane_funcs, formats, num_formats,
possible_crtcs, NULL, plane->type, NULL);
&dm_plane_funcs, if (res)
rgb_formats, return res;
ARRAY_SIZE(rgb_formats),
NULL, plane->type, NULL);
break;
case DRM_PLANE_TYPE_OVERLAY:
res = drm_universal_plane_init(
dm->adev->ddev,
plane,
possible_crtcs,
&dm_plane_funcs,
overlay_formats,
ARRAY_SIZE(overlay_formats),
NULL, plane->type, NULL);
break;
case DRM_PLANE_TYPE_CURSOR:
res = drm_universal_plane_init(
dm->adev->ddev,
plane,
possible_crtcs,
&dm_plane_funcs,
cursor_formats,
ARRAY_SIZE(cursor_formats),
NULL, plane->type, NULL);
break;
}
if (plane->type == DRM_PLANE_TYPE_OVERLAY && if (plane->type == DRM_PLANE_TYPE_OVERLAY &&
plane_cap && plane_cap->per_pixel_alpha) { plane_cap && plane_cap->per_pixel_alpha) {
@ -4176,8 +4201,7 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
if (plane->funcs->reset) if (plane->funcs->reset)
plane->funcs->reset(plane); plane->funcs->reset(plane);
return 0;
return res;
} }
static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,