diff options
author | Thierry Reding <treding@nvidia.com> | 2018-03-15 16:44:04 +0100 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2018-03-15 19:06:11 +0100 |
commit | e90124cb46bdb6b8dd642e0066207ace0fc3f972 (patch) | |
tree | 58692987e1538b2ee254ab48963e744e1c74dcf4 /drivers/gpu/drm/tegra | |
parent | drm/tegra: dc: Dedicate overlay plane to cursor on older Tegra's (diff) | |
download | linux-e90124cb46bdb6b8dd642e0066207ace0fc3f972.tar.xz linux-e90124cb46bdb6b8dd642e0066207ace0fc3f972.zip |
drm/tegra: plane: Support format modifiers
Pass the list of valid format modifiers to planes upon initialization
and implement the ->format_mod_supported() callback so that userspace
can query for the valid combinations of formats and modifiers.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra')
-rw-r--r-- | drivers/gpu/drm/tegra/dc.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/dc.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/hub.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/plane.c | 16 |
4 files changed, 56 insertions, 2 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index ead13ac325b0..dfa787e383cc 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -383,6 +383,12 @@ static const u32 tegra20_primary_formats[] = { DRM_FORMAT_XRGB8888, }; +static const u64 tegra20_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED, + DRM_FORMAT_MOD_INVALID +}; + static const u32 tegra114_primary_formats[] = { DRM_FORMAT_ARGB4444, DRM_FORMAT_ARGB1555, @@ -430,6 +436,17 @@ static const u32 tegra124_primary_formats[] = { DRM_FORMAT_BGRX8888, }; +static const u64 tegra124_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0), + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1), + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2), + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3), + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4), + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5), + DRM_FORMAT_MOD_INVALID +}; + static int tegra_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { @@ -596,6 +613,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm, enum drm_plane_type type = DRM_PLANE_TYPE_PRIMARY; struct tegra_plane *plane; unsigned int num_formats; + const u64 *modifiers; const u32 *formats; int err; @@ -610,10 +628,11 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm, num_formats = dc->soc->num_primary_formats; formats = dc->soc->primary_formats; + modifiers = dc->soc->modifiers; err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, &tegra_plane_funcs, formats, - num_formats, NULL, type, NULL); + num_formats, modifiers, type, NULL); if (err < 0) { kfree(plane); return ERR_PTR(err); @@ -1974,6 +1993,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = { .primary_formats = tegra20_primary_formats, .num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats), .overlay_formats = tegra20_overlay_formats, + .modifiers = tegra20_modifiers, }; static const struct tegra_dc_soc_info tegra30_dc_soc_info = { @@ -1990,6 +2010,7 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = { .primary_formats = tegra20_primary_formats, .num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats), .overlay_formats = tegra20_overlay_formats, + .modifiers = tegra20_modifiers, }; static const struct tegra_dc_soc_info tegra114_dc_soc_info = { @@ -2006,6 +2027,7 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = { .primary_formats = tegra114_primary_formats, .num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats), .overlay_formats = tegra114_overlay_formats, + .modifiers = tegra20_modifiers, }; static const struct tegra_dc_soc_info tegra124_dc_soc_info = { @@ -2022,6 +2044,7 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = { .primary_formats = tegra114_primary_formats, .num_overlay_formats = ARRAY_SIZE(tegra124_overlay_formats), .overlay_formats = tegra114_overlay_formats, + .modifiers = tegra124_modifiers, }; static const struct tegra_dc_soc_info tegra210_dc_soc_info = { @@ -2038,6 +2061,7 @@ static const struct tegra_dc_soc_info tegra210_dc_soc_info = { .primary_formats = tegra114_primary_formats, .num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats), .overlay_formats = tegra114_overlay_formats, + .modifiers = tegra124_modifiers, }; static const struct tegra_windowgroup_soc tegra186_dc_wgrps[] = { diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h index 096a81ad6d8d..d2b50d32de4d 100644 --- a/drivers/gpu/drm/tegra/dc.h +++ b/drivers/gpu/drm/tegra/dc.h @@ -66,6 +66,7 @@ struct tegra_dc_soc_info { unsigned int num_primary_formats; const u32 *overlay_formats; unsigned int num_overlay_formats; + const u64 *modifiers; }; struct tegra_dc { diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index e10a47d57313..094324daa917 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -49,6 +49,17 @@ static const u32 tegra_shared_plane_formats[] = { DRM_FORMAT_YUV422, }; +static const u64 tegra_shared_plane_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0), + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1), + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2), + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3), + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4), + DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5), + DRM_FORMAT_MOD_INVALID +}; + static inline unsigned int tegra_plane_offset(struct tegra_plane *plane, unsigned int offset) { @@ -527,6 +538,7 @@ struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, unsigned int possible_crtcs = 0x7; struct tegra_shared_plane *plane; unsigned int num_formats; + const u64 *modifiers; struct drm_plane *p; const u32 *formats; int err; @@ -545,10 +557,11 @@ struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, num_formats = ARRAY_SIZE(tegra_shared_plane_formats); formats = tegra_shared_plane_formats; + modifiers = tegra_shared_plane_modifiers; err = drm_universal_plane_init(drm, p, possible_crtcs, &tegra_plane_funcs, formats, - num_formats, NULL, type, NULL); + num_formats, modifiers, type, NULL); if (err < 0) { kfree(plane); return ERR_PTR(err); diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 95ffaae06f08..fcf7b8e3032d 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -68,6 +68,21 @@ static void tegra_plane_atomic_destroy_state(struct drm_plane *plane, kfree(state); } +static bool tegra_plane_format_mod_supported(struct drm_plane *plane, + uint32_t format, + uint64_t modifier) +{ + const struct drm_format_info *info = drm_format_info(format); + + if (modifier == DRM_FORMAT_MOD_LINEAR) + return true; + + if (info->num_planes == 1) + return true; + + return false; +} + const struct drm_plane_funcs tegra_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, @@ -75,6 +90,7 @@ const struct drm_plane_funcs tegra_plane_funcs = { .reset = tegra_plane_reset, .atomic_duplicate_state = tegra_plane_atomic_duplicate_state, .atomic_destroy_state = tegra_plane_atomic_destroy_state, + .format_mod_supported = tegra_plane_format_mod_supported, }; int tegra_plane_state_add(struct tegra_plane *plane, |