Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
0004  * Author: James.Qian.Wang <james.qian.wang@arm.com>
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 /* Two assumptions
0058  * 1. RGB always has YTR
0059  * 2. Tiled RGB always has SC
0060  */
0061 u64 komeda_supported_modifiers[] = {
0062     /* AFBC_16x16 + features: YUV+RGB both */
0063     AFBC_16x16(0),
0064     /* SPARSE */
0065     AFBC_16x16(_SPARSE),
0066     /* YTR + (SPARSE) */
0067     AFBC_16x16(_YTR | _SPARSE),
0068     AFBC_16x16(_YTR),
0069     /* SPLIT + SPARSE + YTR RGB only */
0070     /* split mode is only allowed for sparse mode */
0071     AFBC_16x16(_SPLIT | _SPARSE | _YTR),
0072     /* TILED + (SPARSE) */
0073     /* TILED YUV format only */
0074     AFBC_16x16(_TILED | _SPARSE),
0075     AFBC_16x16(_TILED),
0076     /* TILED + SC + (SPLIT+SPARSE | SPARSE) + (YTR) */
0077     AFBC_16x16(_TILED | _SC | _SPLIT | _SPARSE | _YTR),
0078     AFBC_16x16(_TILED | _SC | _SPARSE | _YTR),
0079     AFBC_16x16(_TILED | _SC | _YTR),
0080     /* AFBC_32x8 + features: which are RGB formats only */
0081     /* YTR + (SPARSE) */
0082     AFBC_32x8(_YTR | _SPARSE),
0083     AFBC_32x8(_YTR),
0084     /* SPLIT + SPARSE + (YTR) */
0085     /* split mode is only allowed for sparse mode */
0086     AFBC_32x8(_SPLIT | _SPARSE | _YTR),
0087     /* TILED + SC + (SPLIT+SPARSE | SPARSE) + YTR */
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         /* one fourcc may has two caps items in table (afbc/none-afbc),
0133          * so check the existing list to avoid adding a duplicated one.
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 }