diff options
author | Thierry Reding <treding@nvidia.com> | 2018-03-15 11:44:04 -0400 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2018-03-15 14:06:11 -0400 |
commit | e90124cb46bdb6b8dd642e0066207ace0fc3f972 (patch) | |
tree | 58692987e1538b2ee254ab48963e744e1c74dcf4 | |
parent | 9f446d83b233d2773fd934eed41d795484a08422 (diff) |
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>
-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[] = { | |||
383 | DRM_FORMAT_XRGB8888, | 383 | DRM_FORMAT_XRGB8888, |
384 | }; | 384 | }; |
385 | 385 | ||
386 | static const u64 tegra20_modifiers[] = { | ||
387 | DRM_FORMAT_MOD_LINEAR, | ||
388 | DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED, | ||
389 | DRM_FORMAT_MOD_INVALID | ||
390 | }; | ||
391 | |||
386 | static const u32 tegra114_primary_formats[] = { | 392 | static const u32 tegra114_primary_formats[] = { |
387 | DRM_FORMAT_ARGB4444, | 393 | DRM_FORMAT_ARGB4444, |
388 | DRM_FORMAT_ARGB1555, | 394 | DRM_FORMAT_ARGB1555, |
@@ -430,6 +436,17 @@ static const u32 tegra124_primary_formats[] = { | |||
430 | DRM_FORMAT_BGRX8888, | 436 | DRM_FORMAT_BGRX8888, |
431 | }; | 437 | }; |
432 | 438 | ||
439 | static const u64 tegra124_modifiers[] = { | ||
440 | DRM_FORMAT_MOD_LINEAR, | ||
441 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0), | ||
442 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1), | ||
443 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2), | ||
444 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3), | ||
445 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4), | ||
446 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5), | ||
447 | DRM_FORMAT_MOD_INVALID | ||
448 | }; | ||
449 | |||
433 | static int tegra_plane_atomic_check(struct drm_plane *plane, | 450 | static int tegra_plane_atomic_check(struct drm_plane *plane, |
434 | struct drm_plane_state *state) | 451 | struct drm_plane_state *state) |
435 | { | 452 | { |
@@ -596,6 +613,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm, | |||
596 | enum drm_plane_type type = DRM_PLANE_TYPE_PRIMARY; | 613 | enum drm_plane_type type = DRM_PLANE_TYPE_PRIMARY; |
597 | struct tegra_plane *plane; | 614 | struct tegra_plane *plane; |
598 | unsigned int num_formats; | 615 | unsigned int num_formats; |
616 | const u64 *modifiers; | ||
599 | const u32 *formats; | 617 | const u32 *formats; |
600 | int err; | 618 | int err; |
601 | 619 | ||
@@ -610,10 +628,11 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm, | |||
610 | 628 | ||
611 | num_formats = dc->soc->num_primary_formats; | 629 | num_formats = dc->soc->num_primary_formats; |
612 | formats = dc->soc->primary_formats; | 630 | formats = dc->soc->primary_formats; |
631 | modifiers = dc->soc->modifiers; | ||
613 | 632 | ||
614 | err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, | 633 | err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, |
615 | &tegra_plane_funcs, formats, | 634 | &tegra_plane_funcs, formats, |
616 | num_formats, NULL, type, NULL); | 635 | num_formats, modifiers, type, NULL); |
617 | if (err < 0) { | 636 | if (err < 0) { |
618 | kfree(plane); | 637 | kfree(plane); |
619 | return ERR_PTR(err); | 638 | return ERR_PTR(err); |
@@ -1974,6 +1993,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = { | |||
1974 | .primary_formats = tegra20_primary_formats, | 1993 | .primary_formats = tegra20_primary_formats, |
1975 | .num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats), | 1994 | .num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats), |
1976 | .overlay_formats = tegra20_overlay_formats, | 1995 | .overlay_formats = tegra20_overlay_formats, |
1996 | .modifiers = tegra20_modifiers, | ||
1977 | }; | 1997 | }; |
1978 | 1998 | ||
1979 | static const struct tegra_dc_soc_info tegra30_dc_soc_info = { | 1999 | 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 = { | |||
1990 | .primary_formats = tegra20_primary_formats, | 2010 | .primary_formats = tegra20_primary_formats, |
1991 | .num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats), | 2011 | .num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats), |
1992 | .overlay_formats = tegra20_overlay_formats, | 2012 | .overlay_formats = tegra20_overlay_formats, |
2013 | .modifiers = tegra20_modifiers, | ||
1993 | }; | 2014 | }; |
1994 | 2015 | ||
1995 | static const struct tegra_dc_soc_info tegra114_dc_soc_info = { | 2016 | 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 = { | |||
2006 | .primary_formats = tegra114_primary_formats, | 2027 | .primary_formats = tegra114_primary_formats, |
2007 | .num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats), | 2028 | .num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats), |
2008 | .overlay_formats = tegra114_overlay_formats, | 2029 | .overlay_formats = tegra114_overlay_formats, |
2030 | .modifiers = tegra20_modifiers, | ||
2009 | }; | 2031 | }; |
2010 | 2032 | ||
2011 | static const struct tegra_dc_soc_info tegra124_dc_soc_info = { | 2033 | 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 = { | |||
2022 | .primary_formats = tegra114_primary_formats, | 2044 | .primary_formats = tegra114_primary_formats, |
2023 | .num_overlay_formats = ARRAY_SIZE(tegra124_overlay_formats), | 2045 | .num_overlay_formats = ARRAY_SIZE(tegra124_overlay_formats), |
2024 | .overlay_formats = tegra114_overlay_formats, | 2046 | .overlay_formats = tegra114_overlay_formats, |
2047 | .modifiers = tegra124_modifiers, | ||
2025 | }; | 2048 | }; |
2026 | 2049 | ||
2027 | static const struct tegra_dc_soc_info tegra210_dc_soc_info = { | 2050 | 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 = { | |||
2038 | .primary_formats = tegra114_primary_formats, | 2061 | .primary_formats = tegra114_primary_formats, |
2039 | .num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats), | 2062 | .num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats), |
2040 | .overlay_formats = tegra114_overlay_formats, | 2063 | .overlay_formats = tegra114_overlay_formats, |
2064 | .modifiers = tegra124_modifiers, | ||
2041 | }; | 2065 | }; |
2042 | 2066 | ||
2043 | static const struct tegra_windowgroup_soc tegra186_dc_wgrps[] = { | 2067 | 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 { | |||
66 | unsigned int num_primary_formats; | 66 | unsigned int num_primary_formats; |
67 | const u32 *overlay_formats; | 67 | const u32 *overlay_formats; |
68 | unsigned int num_overlay_formats; | 68 | unsigned int num_overlay_formats; |
69 | const u64 *modifiers; | ||
69 | }; | 70 | }; |
70 | 71 | ||
71 | struct tegra_dc { | 72 | 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[] = { | |||
49 | DRM_FORMAT_YUV422, | 49 | DRM_FORMAT_YUV422, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | static const u64 tegra_shared_plane_modifiers[] = { | ||
53 | DRM_FORMAT_MOD_LINEAR, | ||
54 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0), | ||
55 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1), | ||
56 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2), | ||
57 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3), | ||
58 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4), | ||
59 | DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5), | ||
60 | DRM_FORMAT_MOD_INVALID | ||
61 | }; | ||
62 | |||
52 | static inline unsigned int tegra_plane_offset(struct tegra_plane *plane, | 63 | static inline unsigned int tegra_plane_offset(struct tegra_plane *plane, |
53 | unsigned int offset) | 64 | unsigned int offset) |
54 | { | 65 | { |
@@ -527,6 +538,7 @@ struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, | |||
527 | unsigned int possible_crtcs = 0x7; | 538 | unsigned int possible_crtcs = 0x7; |
528 | struct tegra_shared_plane *plane; | 539 | struct tegra_shared_plane *plane; |
529 | unsigned int num_formats; | 540 | unsigned int num_formats; |
541 | const u64 *modifiers; | ||
530 | struct drm_plane *p; | 542 | struct drm_plane *p; |
531 | const u32 *formats; | 543 | const u32 *formats; |
532 | int err; | 544 | int err; |
@@ -545,10 +557,11 @@ struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, | |||
545 | 557 | ||
546 | num_formats = ARRAY_SIZE(tegra_shared_plane_formats); | 558 | num_formats = ARRAY_SIZE(tegra_shared_plane_formats); |
547 | formats = tegra_shared_plane_formats; | 559 | formats = tegra_shared_plane_formats; |
560 | modifiers = tegra_shared_plane_modifiers; | ||
548 | 561 | ||
549 | err = drm_universal_plane_init(drm, p, possible_crtcs, | 562 | err = drm_universal_plane_init(drm, p, possible_crtcs, |
550 | &tegra_plane_funcs, formats, | 563 | &tegra_plane_funcs, formats, |
551 | num_formats, NULL, type, NULL); | 564 | num_formats, modifiers, type, NULL); |
552 | if (err < 0) { | 565 | if (err < 0) { |
553 | kfree(plane); | 566 | kfree(plane); |
554 | return ERR_PTR(err); | 567 | 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, | |||
68 | kfree(state); | 68 | kfree(state); |
69 | } | 69 | } |
70 | 70 | ||
71 | static bool tegra_plane_format_mod_supported(struct drm_plane *plane, | ||
72 | uint32_t format, | ||
73 | uint64_t modifier) | ||
74 | { | ||
75 | const struct drm_format_info *info = drm_format_info(format); | ||
76 | |||
77 | if (modifier == DRM_FORMAT_MOD_LINEAR) | ||
78 | return true; | ||
79 | |||
80 | if (info->num_planes == 1) | ||
81 | return true; | ||
82 | |||
83 | return false; | ||
84 | } | ||
85 | |||
71 | const struct drm_plane_funcs tegra_plane_funcs = { | 86 | const struct drm_plane_funcs tegra_plane_funcs = { |
72 | .update_plane = drm_atomic_helper_update_plane, | 87 | .update_plane = drm_atomic_helper_update_plane, |
73 | .disable_plane = drm_atomic_helper_disable_plane, | 88 | .disable_plane = drm_atomic_helper_disable_plane, |
@@ -75,6 +90,7 @@ const struct drm_plane_funcs tegra_plane_funcs = { | |||
75 | .reset = tegra_plane_reset, | 90 | .reset = tegra_plane_reset, |
76 | .atomic_duplicate_state = tegra_plane_atomic_duplicate_state, | 91 | .atomic_duplicate_state = tegra_plane_atomic_duplicate_state, |
77 | .atomic_destroy_state = tegra_plane_atomic_destroy_state, | 92 | .atomic_destroy_state = tegra_plane_atomic_destroy_state, |
93 | .format_mod_supported = tegra_plane_format_mod_supported, | ||
78 | }; | 94 | }; |
79 | 95 | ||
80 | int tegra_plane_state_add(struct tegra_plane *plane, | 96 | int tegra_plane_state_add(struct tegra_plane *plane, |