linux/drivers/gpu/drm/msm/disp/mdp_format.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2014 The Linux Foundation. All rights reserved.
   4 * Copyright (C) 2013 Red Hat
   5 * Author: Rob Clark <robdclark@gmail.com>
   6 */
   7
   8
   9#include "msm_drv.h"
  10#include "mdp_kms.h"
  11
  12static struct csc_cfg csc_convert[CSC_MAX] = {
  13        [CSC_RGB2RGB] = {
  14                .type = CSC_RGB2RGB,
  15                .matrix = {
  16                        0x0200, 0x0000, 0x0000,
  17                        0x0000, 0x0200, 0x0000,
  18                        0x0000, 0x0000, 0x0200
  19                },
  20                .pre_bias =     { 0x0, 0x0, 0x0 },
  21                .post_bias =    { 0x0, 0x0, 0x0 },
  22                .pre_clamp =    { 0x0, 0xff, 0x0, 0xff, 0x0, 0xff },
  23                .post_clamp =   { 0x0, 0xff, 0x0, 0xff, 0x0, 0xff },
  24        },
  25        [CSC_YUV2RGB] = {
  26                .type = CSC_YUV2RGB,
  27                .matrix = {
  28                        0x0254, 0x0000, 0x0331,
  29                        0x0254, 0xff37, 0xfe60,
  30                        0x0254, 0x0409, 0x0000
  31                },
  32                .pre_bias =     { 0xfff0, 0xff80, 0xff80 },
  33                .post_bias =    { 0x00, 0x00, 0x00 },
  34                .pre_clamp =    { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
  35                .post_clamp =   { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
  36        },
  37        [CSC_RGB2YUV] = {
  38                .type = CSC_RGB2YUV,
  39                .matrix = {
  40                        0x0083, 0x0102, 0x0032,
  41                        0x1fb5, 0x1f6c, 0x00e1,
  42                        0x00e1, 0x1f45, 0x1fdc
  43                },
  44                .pre_bias =     { 0x00, 0x00, 0x00 },
  45                .post_bias =    { 0x10, 0x80, 0x80 },
  46                .pre_clamp =    { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
  47                .post_clamp =   { 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0 },
  48        },
  49        [CSC_YUV2YUV] = {
  50                .type = CSC_YUV2YUV,
  51                .matrix = {
  52                        0x0200, 0x0000, 0x0000,
  53                        0x0000, 0x0200, 0x0000,
  54                        0x0000, 0x0000, 0x0200
  55                },
  56                .pre_bias =     { 0x00, 0x00, 0x00 },
  57                .post_bias =    { 0x00, 0x00, 0x00 },
  58                .pre_clamp =    { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
  59                .post_clamp =   { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
  60        },
  61};
  62
  63#define FMT(name, a, r, g, b, e0, e1, e2, e3, alpha, tight, c, cnt, fp, cs, yuv) { \
  64                .base = { .pixel_format = DRM_FORMAT_ ## name }, \
  65                .bpc_a = BPC ## a ## A,                          \
  66                .bpc_r = BPC ## r,                               \
  67                .bpc_g = BPC ## g,                               \
  68                .bpc_b = BPC ## b,                               \
  69                .unpack = { e0, e1, e2, e3 },                    \
  70                .alpha_enable = alpha,                           \
  71                .unpack_tight = tight,                           \
  72                .cpp = c,                                        \
  73                .unpack_count = cnt,                             \
  74                .fetch_type = fp,                                \
  75                .chroma_sample = cs,                             \
  76                .is_yuv = yuv,                                   \
  77}
  78
  79#define BPC0A 0
  80
  81/*
  82 * Note: Keep RGB formats 1st, followed by YUV formats to avoid breaking
  83 * mdp_get_rgb_formats()'s implementation.
  84 */
  85static const struct mdp_format formats[] = {
  86        /*  name      a  r  g  b   e0 e1 e2 e3  alpha   tight  cpp cnt ... */
  87        FMT(ARGB8888, 8, 8, 8, 8,  1, 0, 2, 3,  true,   true,  4,  4,
  88                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
  89        FMT(ABGR8888, 8, 8, 8, 8,  2, 0, 1, 3,  true,   true,  4,  4,
  90                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
  91        FMT(RGBA8888, 8, 8, 8, 8,  3, 1, 0, 2,  true,   true,  4,  4,
  92                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
  93        FMT(BGRA8888, 8, 8, 8, 8,  3, 2, 0, 1,  true,   true,  4,  4,
  94                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
  95        FMT(XRGB8888, 8, 8, 8, 8,  1, 0, 2, 3,  false,  true,  4,  4,
  96                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
  97        FMT(XBGR8888, 8, 8, 8, 8,  2, 0, 1, 3,  false,   true,  4,  4,
  98                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
  99        FMT(RGBX8888, 8, 8, 8, 8,  3, 1, 0, 2,  false,   true,  4,  4,
 100                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
 101        FMT(BGRX8888, 8, 8, 8, 8,  3, 2, 0, 1,  false,   true,  4,  4,
 102                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
 103        FMT(RGB888,   0, 8, 8, 8,  1, 0, 2, 0,  false,  true,  3,  3,
 104                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
 105        FMT(BGR888,   0, 8, 8, 8,  2, 0, 1, 0,  false,  true,  3,  3,
 106                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
 107        FMT(RGB565,   0, 5, 6, 5,  1, 0, 2, 0,  false,  true,  2,  3,
 108                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
 109        FMT(BGR565,   0, 5, 6, 5,  2, 0, 1, 0,  false,  true,  2,  3,
 110                        MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
 111
 112        /* --- RGB formats above / YUV formats below this line --- */
 113
 114        /* 2 plane YUV */
 115        FMT(NV12,     0, 8, 8, 8,  1, 2, 0, 0,  false,  true,  2, 2,
 116                        MDP_PLANE_PSEUDO_PLANAR, CHROMA_420, true),
 117        FMT(NV21,     0, 8, 8, 8,  2, 1, 0, 0,  false,  true,  2, 2,
 118                        MDP_PLANE_PSEUDO_PLANAR, CHROMA_420, true),
 119        FMT(NV16,     0, 8, 8, 8,  1, 2, 0, 0,  false,  true,  2, 2,
 120                        MDP_PLANE_PSEUDO_PLANAR, CHROMA_H2V1, true),
 121        FMT(NV61,     0, 8, 8, 8,  2, 1, 0, 0,  false,  true,  2, 2,
 122                        MDP_PLANE_PSEUDO_PLANAR, CHROMA_H2V1, true),
 123        /* 1 plane YUV */
 124        FMT(VYUY,     0, 8, 8, 8,  2, 0, 1, 0,  false,  true,  2, 4,
 125                        MDP_PLANE_INTERLEAVED, CHROMA_H2V1, true),
 126        FMT(UYVY,     0, 8, 8, 8,  1, 0, 2, 0,  false,  true,  2, 4,
 127                        MDP_PLANE_INTERLEAVED, CHROMA_H2V1, true),
 128        FMT(YUYV,     0, 8, 8, 8,  0, 1, 0, 2,  false,  true,  2, 4,
 129                        MDP_PLANE_INTERLEAVED, CHROMA_H2V1, true),
 130        FMT(YVYU,     0, 8, 8, 8,  0, 2, 0, 1,  false,  true,  2, 4,
 131                        MDP_PLANE_INTERLEAVED, CHROMA_H2V1, true),
 132        /* 3 plane YUV */
 133        FMT(YUV420,   0, 8, 8, 8,  2, 1, 0, 0,  false,  true,  1, 1,
 134                        MDP_PLANE_PLANAR, CHROMA_420, true),
 135        FMT(YVU420,   0, 8, 8, 8,  1, 2, 0, 0,  false,  true,  1, 1,
 136                        MDP_PLANE_PLANAR, CHROMA_420, true),
 137};
 138
 139/*
 140 * Note:
 141 * @rgb_only must be set to true, when requesting
 142 * supported formats for RGB pipes.
 143 */
 144uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats,
 145                bool rgb_only)
 146{
 147        uint32_t i;
 148        for (i = 0; i < ARRAY_SIZE(formats); i++) {
 149                const struct mdp_format *f = &formats[i];
 150
 151                if (i == max_formats)
 152                        break;
 153
 154                if (rgb_only && MDP_FORMAT_IS_YUV(f))
 155                        break;
 156
 157                pixel_formats[i] = f->base.pixel_format;
 158        }
 159
 160        return i;
 161}
 162
 163const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format,
 164                uint64_t modifier)
 165{
 166        int i;
 167        for (i = 0; i < ARRAY_SIZE(formats); i++) {
 168                const struct mdp_format *f = &formats[i];
 169                if (f->base.pixel_format == format)
 170                        return &f->base;
 171        }
 172        return NULL;
 173}
 174
 175struct csc_cfg *mdp_get_default_csc_cfg(enum csc_type type)
 176{
 177        if (WARN_ON(type >= CSC_MAX))
 178                return NULL;
 179
 180        return &csc_convert[type];
 181}
 182