linux/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c
<<
>>
Prefs
   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}
 153