1 // SPDX-License-Identifier: GPL-2.0
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
8 #include <linux/slab.h>
9 #include "komeda_format_caps.h"
10 #include "malidp_utils.h"
12 const struct komeda_format_caps *
13 komeda_get_format_caps(struct komeda_format_caps_table *table,
14 u32 fourcc, u64 modifier)
16 const struct komeda_format_caps *caps;
17 u64 afbc_features = modifier & ~(AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
18 u32 afbc_layout = modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;
21 for (id = 0; id < table->n_formats; id++) {
22 caps = &table->format_caps[id];
24 if (fourcc != caps->fourcc)
27 if ((modifier == 0ULL) && (caps->supported_afbc_layouts == 0))
30 if (has_bits(afbc_features, caps->supported_afbc_features) &&
31 has_bit(afbc_layout, caps->supported_afbc_layouts))
39 * 1. RGB always has YTR
40 * 2. Tiled RGB always has SC
42 u64 komeda_supported_modifiers[] = {
43 /* AFBC_16x16 + features: YUV+RGB both */
48 AFBC_16x16(_YTR | _SPARSE),
50 /* SPLIT + SPARSE + YTR RGB only */
51 /* split mode is only allowed for sparse mode */
52 AFBC_16x16(_SPLIT | _SPARSE | _YTR),
53 /* TILED + (SPARSE) */
54 /* TILED YUV format only */
55 AFBC_16x16(_TILED | _SPARSE),
57 /* TILED + SC + (SPLIT+SPARSE | SPARSE) + (YTR) */
58 AFBC_16x16(_TILED | _SC | _SPLIT | _SPARSE | _YTR),
59 AFBC_16x16(_TILED | _SC | _SPARSE | _YTR),
60 AFBC_16x16(_TILED | _SC | _YTR),
61 /* AFBC_32x8 + features: which are RGB formats only */
63 AFBC_32x8(_YTR | _SPARSE),
65 /* SPLIT + SPARSE + (YTR) */
66 /* split mode is only allowed for sparse mode */
67 AFBC_32x8(_SPLIT | _SPARSE | _YTR),
68 /* TILED + SC + (SPLIT+SPARSE | SPARSE) + YTR */
69 AFBC_32x8(_TILED | _SC | _SPLIT | _SPARSE | _YTR),
70 AFBC_32x8(_TILED | _SC | _SPARSE | _YTR),
71 AFBC_32x8(_TILED | _SC | _YTR),
72 DRM_FORMAT_MOD_LINEAR,
73 DRM_FORMAT_MOD_INVALID
76 bool komeda_format_mod_supported(struct komeda_format_caps_table *table,
77 u32 layer_type, u32 fourcc, u64 modifier,
80 const struct komeda_format_caps *caps;
82 caps = komeda_get_format_caps(table, fourcc, modifier);
86 if (!(caps->supported_layer_types & layer_type))
89 if (table->format_mod_supported)
90 return table->format_mod_supported(caps, layer_type, modifier,
96 u32 *komeda_get_layer_fourcc_list(struct komeda_format_caps_table *table,
97 u32 layer_type, u32 *n_fmts)
99 const struct komeda_format_caps *cap;
103 fmts = kcalloc(table->n_formats, sizeof(u32), GFP_KERNEL);
107 for (i = 0; i < table->n_formats; i++) {
108 cap = &table->format_caps[i];
109 if (!(layer_type & cap->supported_layer_types) ||
113 /* one fourcc may has two caps items in table (afbc/none-afbc),
114 * so check the existing list to avoid adding a duplicated one.
116 for (j = n - 1; j >= 0; j--)
117 if (fmts[j] == cap->fourcc)
121 fmts[n++] = cap->fourcc;
130 void komeda_put_fourcc_list(u32 *fourcc_list)