0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/slab.h>
0009 #include "komeda_format_caps.h"
0010 #include "malidp_utils.h"
0011
0012 const struct komeda_format_caps *
0013 komeda_get_format_caps(struct komeda_format_caps_table *table,
0014 u32 fourcc, u64 modifier)
0015 {
0016 const struct komeda_format_caps *caps;
0017 u64 afbc_features = modifier & ~(AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
0018 u32 afbc_layout = modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK;
0019 int id;
0020
0021 for (id = 0; id < table->n_formats; id++) {
0022 caps = &table->format_caps[id];
0023
0024 if (fourcc != caps->fourcc)
0025 continue;
0026
0027 if ((modifier == 0ULL) && (caps->supported_afbc_layouts == 0))
0028 return caps;
0029
0030 if (has_bits(afbc_features, caps->supported_afbc_features) &&
0031 has_bit(afbc_layout, caps->supported_afbc_layouts))
0032 return caps;
0033 }
0034
0035 return NULL;
0036 }
0037
0038 u32 komeda_get_afbc_format_bpp(const struct drm_format_info *info, u64 modifier)
0039 {
0040 u32 bpp;
0041
0042 switch (info->format) {
0043 case DRM_FORMAT_YUV420_8BIT:
0044 bpp = 12;
0045 break;
0046 case DRM_FORMAT_YUV420_10BIT:
0047 bpp = 15;
0048 break;
0049 default:
0050 bpp = info->cpp[0] * 8;
0051 break;
0052 }
0053
0054 return bpp;
0055 }
0056
0057
0058
0059
0060
0061 u64 komeda_supported_modifiers[] = {
0062
0063 AFBC_16x16(0),
0064
0065 AFBC_16x16(_SPARSE),
0066
0067 AFBC_16x16(_YTR | _SPARSE),
0068 AFBC_16x16(_YTR),
0069
0070
0071 AFBC_16x16(_SPLIT | _SPARSE | _YTR),
0072
0073
0074 AFBC_16x16(_TILED | _SPARSE),
0075 AFBC_16x16(_TILED),
0076
0077 AFBC_16x16(_TILED | _SC | _SPLIT | _SPARSE | _YTR),
0078 AFBC_16x16(_TILED | _SC | _SPARSE | _YTR),
0079 AFBC_16x16(_TILED | _SC | _YTR),
0080
0081
0082 AFBC_32x8(_YTR | _SPARSE),
0083 AFBC_32x8(_YTR),
0084
0085
0086 AFBC_32x8(_SPLIT | _SPARSE | _YTR),
0087
0088 AFBC_32x8(_TILED | _SC | _SPLIT | _SPARSE | _YTR),
0089 AFBC_32x8(_TILED | _SC | _SPARSE | _YTR),
0090 AFBC_32x8(_TILED | _SC | _YTR),
0091 DRM_FORMAT_MOD_LINEAR,
0092 DRM_FORMAT_MOD_INVALID
0093 };
0094
0095 bool komeda_format_mod_supported(struct komeda_format_caps_table *table,
0096 u32 layer_type, u32 fourcc, u64 modifier,
0097 u32 rot)
0098 {
0099 const struct komeda_format_caps *caps;
0100
0101 caps = komeda_get_format_caps(table, fourcc, modifier);
0102 if (!caps)
0103 return false;
0104
0105 if (!(caps->supported_layer_types & layer_type))
0106 return false;
0107
0108 if (table->format_mod_supported)
0109 return table->format_mod_supported(caps, layer_type, modifier,
0110 rot);
0111
0112 return true;
0113 }
0114
0115 u32 *komeda_get_layer_fourcc_list(struct komeda_format_caps_table *table,
0116 u32 layer_type, u32 *n_fmts)
0117 {
0118 const struct komeda_format_caps *cap;
0119 u32 *fmts;
0120 int i, j, n = 0;
0121
0122 fmts = kcalloc(table->n_formats, sizeof(u32), GFP_KERNEL);
0123 if (!fmts)
0124 return NULL;
0125
0126 for (i = 0; i < table->n_formats; i++) {
0127 cap = &table->format_caps[i];
0128 if (!(layer_type & cap->supported_layer_types) ||
0129 (cap->fourcc == 0))
0130 continue;
0131
0132
0133
0134
0135 for (j = n - 1; j >= 0; j--)
0136 if (fmts[j] == cap->fourcc)
0137 break;
0138
0139 if (j < 0)
0140 fmts[n++] = cap->fourcc;
0141 }
0142
0143 if (n_fmts)
0144 *n_fmts = n;
0145
0146 return fmts;
0147 }
0148
0149 void komeda_put_fourcc_list(u32 *fourcc_list)
0150 {
0151 kfree(fourcc_list);
0152 }