komeda_format_caps.c (3641B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved. 4 * Author: James.Qian.Wang <james.qian.wang@arm.com> 5 * 6 */ 7 8#include <linux/slab.h> 9#include "komeda_format_caps.h" 10#include "malidp_utils.h" 11 12const struct komeda_format_caps * 13komeda_get_format_caps(struct komeda_format_caps_table *table, 14 u32 fourcc, u64 modifier) 15{ 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; 19 int id; 20 21 for (id = 0; id < table->n_formats; id++) { 22 caps = &table->format_caps[id]; 23 24 if (fourcc != caps->fourcc) 25 continue; 26 27 if ((modifier == 0ULL) && (caps->supported_afbc_layouts == 0)) 28 return caps; 29 30 if (has_bits(afbc_features, caps->supported_afbc_features) && 31 has_bit(afbc_layout, caps->supported_afbc_layouts)) 32 return caps; 33 } 34 35 return NULL; 36} 37 38u32 komeda_get_afbc_format_bpp(const struct drm_format_info *info, u64 modifier) 39{ 40 u32 bpp; 41 42 switch (info->format) { 43 case DRM_FORMAT_YUV420_8BIT: 44 bpp = 12; 45 break; 46 case DRM_FORMAT_YUV420_10BIT: 47 bpp = 15; 48 break; 49 default: 50 bpp = info->cpp[0] * 8; 51 break; 52 } 53 54 return bpp; 55} 56 57/* Two assumptions 58 * 1. RGB always has YTR 59 * 2. Tiled RGB always has SC 60 */ 61u64 komeda_supported_modifiers[] = { 62 /* AFBC_16x16 + features: YUV+RGB both */ 63 AFBC_16x16(0), 64 /* SPARSE */ 65 AFBC_16x16(_SPARSE), 66 /* YTR + (SPARSE) */ 67 AFBC_16x16(_YTR | _SPARSE), 68 AFBC_16x16(_YTR), 69 /* SPLIT + SPARSE + YTR RGB only */ 70 /* split mode is only allowed for sparse mode */ 71 AFBC_16x16(_SPLIT | _SPARSE | _YTR), 72 /* TILED + (SPARSE) */ 73 /* TILED YUV format only */ 74 AFBC_16x16(_TILED | _SPARSE), 75 AFBC_16x16(_TILED), 76 /* TILED + SC + (SPLIT+SPARSE | SPARSE) + (YTR) */ 77 AFBC_16x16(_TILED | _SC | _SPLIT | _SPARSE | _YTR), 78 AFBC_16x16(_TILED | _SC | _SPARSE | _YTR), 79 AFBC_16x16(_TILED | _SC | _YTR), 80 /* AFBC_32x8 + features: which are RGB formats only */ 81 /* YTR + (SPARSE) */ 82 AFBC_32x8(_YTR | _SPARSE), 83 AFBC_32x8(_YTR), 84 /* SPLIT + SPARSE + (YTR) */ 85 /* split mode is only allowed for sparse mode */ 86 AFBC_32x8(_SPLIT | _SPARSE | _YTR), 87 /* TILED + SC + (SPLIT+SPARSE | SPARSE) + YTR */ 88 AFBC_32x8(_TILED | _SC | _SPLIT | _SPARSE | _YTR), 89 AFBC_32x8(_TILED | _SC | _SPARSE | _YTR), 90 AFBC_32x8(_TILED | _SC | _YTR), 91 DRM_FORMAT_MOD_LINEAR, 92 DRM_FORMAT_MOD_INVALID 93}; 94 95bool komeda_format_mod_supported(struct komeda_format_caps_table *table, 96 u32 layer_type, u32 fourcc, u64 modifier, 97 u32 rot) 98{ 99 const struct komeda_format_caps *caps; 100 101 caps = komeda_get_format_caps(table, fourcc, modifier); 102 if (!caps) 103 return false; 104 105 if (!(caps->supported_layer_types & layer_type)) 106 return false; 107 108 if (table->format_mod_supported) 109 return table->format_mod_supported(caps, layer_type, modifier, 110 rot); 111 112 return true; 113} 114 115u32 *komeda_get_layer_fourcc_list(struct komeda_format_caps_table *table, 116 u32 layer_type, u32 *n_fmts) 117{ 118 const struct komeda_format_caps *cap; 119 u32 *fmts; 120 int i, j, n = 0; 121 122 fmts = kcalloc(table->n_formats, sizeof(u32), GFP_KERNEL); 123 if (!fmts) 124 return NULL; 125 126 for (i = 0; i < table->n_formats; i++) { 127 cap = &table->format_caps[i]; 128 if (!(layer_type & cap->supported_layer_types) || 129 (cap->fourcc == 0)) 130 continue; 131 132 /* one fourcc may has two caps items in table (afbc/none-afbc), 133 * so check the existing list to avoid adding a duplicated one. 134 */ 135 for (j = n - 1; j >= 0; j--) 136 if (fmts[j] == cap->fourcc) 137 break; 138 139 if (j < 0) 140 fmts[n++] = cap->fourcc; 141 } 142 143 if (n_fmts) 144 *n_fmts = n; 145 146 return fmts; 147} 148 149void komeda_put_fourcc_list(u32 *fourcc_list) 150{ 151 kfree(fourcc_list); 152}