cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dpu_formats.c (34505B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
      3 */
      4
      5#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
      6
      7#include <uapi/drm/drm_fourcc.h>
      8
      9#include "msm_media_info.h"
     10#include "dpu_kms.h"
     11#include "dpu_formats.h"
     12
     13#define DPU_UBWC_META_MACRO_W_H		16
     14#define DPU_UBWC_META_BLOCK_SIZE	256
     15#define DPU_UBWC_PLANE_SIZE_ALIGNMENT	4096
     16
     17#define DPU_TILE_HEIGHT_DEFAULT	1
     18#define DPU_TILE_HEIGHT_TILED	4
     19#define DPU_TILE_HEIGHT_UBWC	4
     20#define DPU_TILE_HEIGHT_NV12	8
     21
     22#define DPU_MAX_IMG_WIDTH		0x3FFF
     23#define DPU_MAX_IMG_HEIGHT		0x3FFF
     24
     25/*
     26 * DPU supported format packing, bpp, and other format
     27 * information.
     28 * DPU currently only supports interleaved RGB formats
     29 * UBWC support for a pixel format is indicated by the flag,
     30 * there is additional meta data plane for such formats
     31 */
     32
     33#define INTERLEAVED_RGB_FMT(fmt, a, r, g, b, e0, e1, e2, e3, uc, alpha,   \
     34bp, flg, fm, np)                                                          \
     35{                                                                         \
     36	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
     37	.fetch_planes = DPU_PLANE_INTERLEAVED,                            \
     38	.alpha_enable = alpha,                                            \
     39	.element = { (e0), (e1), (e2), (e3) },                            \
     40	.bits = { g, b, r, a },                                           \
     41	.chroma_sample = DPU_CHROMA_RGB,                                  \
     42	.unpack_align_msb = 0,                                            \
     43	.unpack_tight = 1,                                                \
     44	.unpack_count = uc,                                               \
     45	.bpp = bp,                                                        \
     46	.fetch_mode = fm,                                                 \
     47	.flag = {(flg)},                                                  \
     48	.num_planes = np,                                                 \
     49	.tile_height = DPU_TILE_HEIGHT_DEFAULT                            \
     50}
     51
     52#define INTERLEAVED_RGB_FMT_TILED(fmt, a, r, g, b, e0, e1, e2, e3, uc,    \
     53alpha, bp, flg, fm, np, th)                                               \
     54{                                                                         \
     55	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
     56	.fetch_planes = DPU_PLANE_INTERLEAVED,                            \
     57	.alpha_enable = alpha,                                            \
     58	.element = { (e0), (e1), (e2), (e3) },                            \
     59	.bits = { g, b, r, a },                                           \
     60	.chroma_sample = DPU_CHROMA_RGB,                                  \
     61	.unpack_align_msb = 0,                                            \
     62	.unpack_tight = 1,                                                \
     63	.unpack_count = uc,                                               \
     64	.bpp = bp,                                                        \
     65	.fetch_mode = fm,                                                 \
     66	.flag = {(flg)},                                                  \
     67	.num_planes = np,                                                 \
     68	.tile_height = th                                                 \
     69}
     70
     71
     72#define INTERLEAVED_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, e3,              \
     73alpha, chroma, count, bp, flg, fm, np)                                    \
     74{                                                                         \
     75	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
     76	.fetch_planes = DPU_PLANE_INTERLEAVED,                            \
     77	.alpha_enable = alpha,                                            \
     78	.element = { (e0), (e1), (e2), (e3)},                             \
     79	.bits = { g, b, r, a },                                           \
     80	.chroma_sample = chroma,                                          \
     81	.unpack_align_msb = 0,                                            \
     82	.unpack_tight = 1,                                                \
     83	.unpack_count = count,                                            \
     84	.bpp = bp,                                                        \
     85	.fetch_mode = fm,                                                 \
     86	.flag = {(flg)},                                                  \
     87	.num_planes = np,                                                 \
     88	.tile_height = DPU_TILE_HEIGHT_DEFAULT                            \
     89}
     90
     91#define PSEUDO_YUV_FMT(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np)      \
     92{                                                                         \
     93	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
     94	.fetch_planes = DPU_PLANE_PSEUDO_PLANAR,                          \
     95	.alpha_enable = false,                                            \
     96	.element = { (e0), (e1), 0, 0 },                                  \
     97	.bits = { g, b, r, a },                                           \
     98	.chroma_sample = chroma,                                          \
     99	.unpack_align_msb = 0,                                            \
    100	.unpack_tight = 1,                                                \
    101	.unpack_count = 2,                                                \
    102	.bpp = 2,                                                         \
    103	.fetch_mode = fm,                                                 \
    104	.flag = {(flg)},                                                  \
    105	.num_planes = np,                                                 \
    106	.tile_height = DPU_TILE_HEIGHT_DEFAULT                            \
    107}
    108
    109#define PSEUDO_YUV_FMT_TILED(fmt, a, r, g, b, e0, e1, chroma,             \
    110flg, fm, np, th)                                                          \
    111{                                                                         \
    112	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
    113	.fetch_planes = DPU_PLANE_PSEUDO_PLANAR,                          \
    114	.alpha_enable = false,                                            \
    115	.element = { (e0), (e1), 0, 0 },                                  \
    116	.bits = { g, b, r, a },                                           \
    117	.chroma_sample = chroma,                                          \
    118	.unpack_align_msb = 0,                                            \
    119	.unpack_tight = 1,                                                \
    120	.unpack_count = 2,                                                \
    121	.bpp = 2,                                                         \
    122	.fetch_mode = fm,                                                 \
    123	.flag = {(flg)},                                                  \
    124	.num_planes = np,                                                 \
    125	.tile_height = th                                                 \
    126}
    127
    128#define PSEUDO_YUV_FMT_LOOSE(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np)\
    129{                                                                         \
    130	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
    131	.fetch_planes = DPU_PLANE_PSEUDO_PLANAR,                          \
    132	.alpha_enable = false,                                            \
    133	.element = { (e0), (e1), 0, 0 },                                  \
    134	.bits = { g, b, r, a },                                           \
    135	.chroma_sample = chroma,                                          \
    136	.unpack_align_msb = 1,                                            \
    137	.unpack_tight = 0,                                                \
    138	.unpack_count = 2,                                                \
    139	.bpp = 2,                                                         \
    140	.fetch_mode = fm,                                                 \
    141	.flag = {(flg)},                                                  \
    142	.num_planes = np,                                                 \
    143	.tile_height = DPU_TILE_HEIGHT_DEFAULT                            \
    144}
    145
    146#define PSEUDO_YUV_FMT_LOOSE_TILED(fmt, a, r, g, b, e0, e1, chroma,       \
    147flg, fm, np, th)                                                          \
    148{                                                                         \
    149	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
    150	.fetch_planes = DPU_PLANE_PSEUDO_PLANAR,                          \
    151	.alpha_enable = false,                                            \
    152	.element = { (e0), (e1), 0, 0 },                                  \
    153	.bits = { g, b, r, a },                                           \
    154	.chroma_sample = chroma,                                          \
    155	.unpack_align_msb = 1,                                            \
    156	.unpack_tight = 0,                                                \
    157	.unpack_count = 2,                                                \
    158	.bpp = 2,                                                         \
    159	.fetch_mode = fm,                                                 \
    160	.flag = {(flg)},                                                  \
    161	.num_planes = np,                                                 \
    162	.tile_height = th                                                 \
    163}
    164
    165
    166#define PLANAR_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, alpha, chroma, bp,    \
    167flg, fm, np)                                                      \
    168{                                                                         \
    169	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
    170	.fetch_planes = DPU_PLANE_PLANAR,                                 \
    171	.alpha_enable = alpha,                                            \
    172	.element = { (e0), (e1), (e2), 0 },                               \
    173	.bits = { g, b, r, a },                                           \
    174	.chroma_sample = chroma,                                          \
    175	.unpack_align_msb = 0,                                            \
    176	.unpack_tight = 1,                                                \
    177	.unpack_count = 1,                                                \
    178	.bpp = bp,                                                        \
    179	.fetch_mode = fm,                                                 \
    180	.flag = {(flg)},                                                  \
    181	.num_planes = np,                                                 \
    182	.tile_height = DPU_TILE_HEIGHT_DEFAULT                            \
    183}
    184
    185/*
    186 * struct dpu_media_color_map - maps drm format to media format
    187 * @format: DRM base pixel format
    188 * @color: Media API color related to DRM format
    189 */
    190struct dpu_media_color_map {
    191	uint32_t format;
    192	uint32_t color;
    193};
    194
    195static const struct dpu_format dpu_format_map[] = {
    196	INTERLEAVED_RGB_FMT(ARGB8888,
    197		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    198		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
    199		true, 4, 0,
    200		DPU_FETCH_LINEAR, 1),
    201
    202	INTERLEAVED_RGB_FMT(ABGR8888,
    203		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    204		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    205		true, 4, 0,
    206		DPU_FETCH_LINEAR, 1),
    207
    208	INTERLEAVED_RGB_FMT(XBGR8888,
    209		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    210		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    211		false, 4, 0,
    212		DPU_FETCH_LINEAR, 1),
    213
    214	INTERLEAVED_RGB_FMT(RGBA8888,
    215		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    216		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
    217		true, 4, 0,
    218		DPU_FETCH_LINEAR, 1),
    219
    220	INTERLEAVED_RGB_FMT(BGRA8888,
    221		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    222		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
    223		true, 4, 0,
    224		DPU_FETCH_LINEAR, 1),
    225
    226	INTERLEAVED_RGB_FMT(BGRX8888,
    227		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    228		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
    229		false, 4, 0,
    230		DPU_FETCH_LINEAR, 1),
    231
    232	INTERLEAVED_RGB_FMT(XRGB8888,
    233		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    234		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
    235		false, 4, 0,
    236		DPU_FETCH_LINEAR, 1),
    237
    238	INTERLEAVED_RGB_FMT(RGBX8888,
    239		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    240		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
    241		false, 4, 0,
    242		DPU_FETCH_LINEAR, 1),
    243
    244	INTERLEAVED_RGB_FMT(RGB888,
    245		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    246		C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
    247		false, 3, 0,
    248		DPU_FETCH_LINEAR, 1),
    249
    250	INTERLEAVED_RGB_FMT(BGR888,
    251		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    252		C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
    253		false, 3, 0,
    254		DPU_FETCH_LINEAR, 1),
    255
    256	INTERLEAVED_RGB_FMT(RGB565,
    257		0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
    258		C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
    259		false, 2, 0,
    260		DPU_FETCH_LINEAR, 1),
    261
    262	INTERLEAVED_RGB_FMT(BGR565,
    263		0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
    264		C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
    265		false, 2, 0,
    266		DPU_FETCH_LINEAR, 1),
    267
    268	INTERLEAVED_RGB_FMT(ARGB1555,
    269		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
    270		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
    271		true, 2, 0,
    272		DPU_FETCH_LINEAR, 1),
    273
    274	INTERLEAVED_RGB_FMT(ABGR1555,
    275		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
    276		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    277		true, 2, 0,
    278		DPU_FETCH_LINEAR, 1),
    279
    280	INTERLEAVED_RGB_FMT(RGBA5551,
    281		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
    282		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
    283		true, 2, 0,
    284		DPU_FETCH_LINEAR, 1),
    285
    286	INTERLEAVED_RGB_FMT(BGRA5551,
    287		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
    288		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
    289		true, 2, 0,
    290		DPU_FETCH_LINEAR, 1),
    291
    292	INTERLEAVED_RGB_FMT(XRGB1555,
    293		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
    294		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
    295		false, 2, 0,
    296		DPU_FETCH_LINEAR, 1),
    297
    298	INTERLEAVED_RGB_FMT(XBGR1555,
    299		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
    300		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    301		false, 2, 0,
    302		DPU_FETCH_LINEAR, 1),
    303
    304	INTERLEAVED_RGB_FMT(RGBX5551,
    305		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
    306		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
    307		false, 2, 0,
    308		DPU_FETCH_LINEAR, 1),
    309
    310	INTERLEAVED_RGB_FMT(BGRX5551,
    311		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
    312		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
    313		false, 2, 0,
    314		DPU_FETCH_LINEAR, 1),
    315
    316	INTERLEAVED_RGB_FMT(ARGB4444,
    317		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
    318		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
    319		true, 2, 0,
    320		DPU_FETCH_LINEAR, 1),
    321
    322	INTERLEAVED_RGB_FMT(ABGR4444,
    323		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
    324		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    325		true, 2, 0,
    326		DPU_FETCH_LINEAR, 1),
    327
    328	INTERLEAVED_RGB_FMT(RGBA4444,
    329		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
    330		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
    331		true, 2, 0,
    332		DPU_FETCH_LINEAR, 1),
    333
    334	INTERLEAVED_RGB_FMT(BGRA4444,
    335		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
    336		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
    337		true, 2, 0,
    338		DPU_FETCH_LINEAR, 1),
    339
    340	INTERLEAVED_RGB_FMT(XRGB4444,
    341		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
    342		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
    343		false, 2, 0,
    344		DPU_FETCH_LINEAR, 1),
    345
    346	INTERLEAVED_RGB_FMT(XBGR4444,
    347		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
    348		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    349		false, 2, 0,
    350		DPU_FETCH_LINEAR, 1),
    351
    352	INTERLEAVED_RGB_FMT(RGBX4444,
    353		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
    354		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
    355		false, 2, 0,
    356		DPU_FETCH_LINEAR, 1),
    357
    358	INTERLEAVED_RGB_FMT(BGRX4444,
    359		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
    360		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
    361		false, 2, 0,
    362		DPU_FETCH_LINEAR, 1),
    363
    364	INTERLEAVED_RGB_FMT(BGRA1010102,
    365		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    366		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
    367		true, 4, DPU_FORMAT_FLAG_DX,
    368		DPU_FETCH_LINEAR, 1),
    369
    370	INTERLEAVED_RGB_FMT(RGBA1010102,
    371		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    372		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
    373		true, 4, DPU_FORMAT_FLAG_DX,
    374		DPU_FETCH_LINEAR, 1),
    375
    376	INTERLEAVED_RGB_FMT(ABGR2101010,
    377		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    378		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    379		true, 4, DPU_FORMAT_FLAG_DX,
    380		DPU_FETCH_LINEAR, 1),
    381
    382	INTERLEAVED_RGB_FMT(ARGB2101010,
    383		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    384		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
    385		true, 4, DPU_FORMAT_FLAG_DX,
    386		DPU_FETCH_LINEAR, 1),
    387
    388	INTERLEAVED_RGB_FMT(XRGB2101010,
    389		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    390		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
    391		false, 4, DPU_FORMAT_FLAG_DX,
    392		DPU_FETCH_LINEAR, 1),
    393
    394	INTERLEAVED_RGB_FMT(BGRX1010102,
    395		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    396		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
    397		false, 4, DPU_FORMAT_FLAG_DX,
    398		DPU_FETCH_LINEAR, 1),
    399
    400	INTERLEAVED_RGB_FMT(XBGR2101010,
    401		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    402		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    403		false, 4, DPU_FORMAT_FLAG_DX,
    404		DPU_FETCH_LINEAR, 1),
    405
    406	INTERLEAVED_RGB_FMT(RGBX1010102,
    407		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    408		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
    409		false, 4, DPU_FORMAT_FLAG_DX,
    410		DPU_FETCH_LINEAR, 1),
    411
    412	PSEUDO_YUV_FMT(NV12,
    413		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    414		C1_B_Cb, C2_R_Cr,
    415		DPU_CHROMA_420, DPU_FORMAT_FLAG_YUV,
    416		DPU_FETCH_LINEAR, 2),
    417
    418	PSEUDO_YUV_FMT(NV21,
    419		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    420		C2_R_Cr, C1_B_Cb,
    421		DPU_CHROMA_420, DPU_FORMAT_FLAG_YUV,
    422		DPU_FETCH_LINEAR, 2),
    423
    424	PSEUDO_YUV_FMT(NV16,
    425		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    426		C1_B_Cb, C2_R_Cr,
    427		DPU_CHROMA_H2V1, DPU_FORMAT_FLAG_YUV,
    428		DPU_FETCH_LINEAR, 2),
    429
    430	PSEUDO_YUV_FMT(NV61,
    431		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    432		C2_R_Cr, C1_B_Cb,
    433		DPU_CHROMA_H2V1, DPU_FORMAT_FLAG_YUV,
    434		DPU_FETCH_LINEAR, 2),
    435
    436	INTERLEAVED_YUV_FMT(VYUY,
    437		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    438		C2_R_Cr, C0_G_Y, C1_B_Cb, C0_G_Y,
    439		false, DPU_CHROMA_H2V1, 4, 2, DPU_FORMAT_FLAG_YUV,
    440		DPU_FETCH_LINEAR, 2),
    441
    442	INTERLEAVED_YUV_FMT(UYVY,
    443		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    444		C1_B_Cb, C0_G_Y, C2_R_Cr, C0_G_Y,
    445		false, DPU_CHROMA_H2V1, 4, 2, DPU_FORMAT_FLAG_YUV,
    446		DPU_FETCH_LINEAR, 2),
    447
    448	INTERLEAVED_YUV_FMT(YUYV,
    449		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    450		C0_G_Y, C1_B_Cb, C0_G_Y, C2_R_Cr,
    451		false, DPU_CHROMA_H2V1, 4, 2, DPU_FORMAT_FLAG_YUV,
    452		DPU_FETCH_LINEAR, 2),
    453
    454	INTERLEAVED_YUV_FMT(YVYU,
    455		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    456		C0_G_Y, C2_R_Cr, C0_G_Y, C1_B_Cb,
    457		false, DPU_CHROMA_H2V1, 4, 2, DPU_FORMAT_FLAG_YUV,
    458		DPU_FETCH_LINEAR, 2),
    459
    460	PLANAR_YUV_FMT(YUV420,
    461		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    462		C2_R_Cr, C1_B_Cb, C0_G_Y,
    463		false, DPU_CHROMA_420, 1, DPU_FORMAT_FLAG_YUV,
    464		DPU_FETCH_LINEAR, 3),
    465
    466	PLANAR_YUV_FMT(YVU420,
    467		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    468		C1_B_Cb, C2_R_Cr, C0_G_Y,
    469		false, DPU_CHROMA_420, 1, DPU_FORMAT_FLAG_YUV,
    470		DPU_FETCH_LINEAR, 3),
    471};
    472
    473/*
    474 * UBWC formats table:
    475 * This table holds the UBWC formats supported.
    476 * If a compression ratio needs to be used for this or any other format,
    477 * the data will be passed by user-space.
    478 */
    479static const struct dpu_format dpu_format_map_ubwc[] = {
    480	INTERLEAVED_RGB_FMT_TILED(BGR565,
    481		0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
    482		C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
    483		false, 2, DPU_FORMAT_FLAG_COMPRESSED,
    484		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
    485
    486	INTERLEAVED_RGB_FMT_TILED(ABGR8888,
    487		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    488		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    489		true, 4, DPU_FORMAT_FLAG_COMPRESSED,
    490		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
    491
    492	/* ARGB8888 and ABGR8888 purposely have the same color
    493	 * ordering.  The hardware only supports ABGR8888 UBWC
    494	 * natively.
    495	 */
    496	INTERLEAVED_RGB_FMT_TILED(ARGB8888,
    497		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    498		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    499		true, 4, DPU_FORMAT_FLAG_COMPRESSED,
    500		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
    501
    502	INTERLEAVED_RGB_FMT_TILED(XBGR8888,
    503		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    504		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    505		false, 4, DPU_FORMAT_FLAG_COMPRESSED,
    506		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
    507
    508	INTERLEAVED_RGB_FMT_TILED(XRGB8888,
    509		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    510		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    511		false, 4, DPU_FORMAT_FLAG_COMPRESSED,
    512		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
    513
    514	INTERLEAVED_RGB_FMT_TILED(ABGR2101010,
    515		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    516		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    517		true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
    518		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
    519
    520	INTERLEAVED_RGB_FMT_TILED(XBGR2101010,
    521		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    522		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
    523		true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
    524		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
    525
    526	PSEUDO_YUV_FMT_TILED(NV12,
    527		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
    528		C1_B_Cb, C2_R_Cr,
    529		DPU_CHROMA_420, DPU_FORMAT_FLAG_YUV |
    530				DPU_FORMAT_FLAG_COMPRESSED,
    531		DPU_FETCH_UBWC, 4, DPU_TILE_HEIGHT_NV12),
    532};
    533
    534/* _dpu_get_v_h_subsample_rate - Get subsample rates for all formats we support
    535 *   Note: Not using the drm_format_*_subsampling since we have formats
    536 */
    537static void _dpu_get_v_h_subsample_rate(
    538	enum dpu_chroma_samp_type chroma_sample,
    539	uint32_t *v_sample,
    540	uint32_t *h_sample)
    541{
    542	if (!v_sample || !h_sample)
    543		return;
    544
    545	switch (chroma_sample) {
    546	case DPU_CHROMA_H2V1:
    547		*v_sample = 1;
    548		*h_sample = 2;
    549		break;
    550	case DPU_CHROMA_H1V2:
    551		*v_sample = 2;
    552		*h_sample = 1;
    553		break;
    554	case DPU_CHROMA_420:
    555		*v_sample = 2;
    556		*h_sample = 2;
    557		break;
    558	default:
    559		*v_sample = 1;
    560		*h_sample = 1;
    561		break;
    562	}
    563}
    564
    565static int _dpu_format_get_media_color_ubwc(const struct dpu_format *fmt)
    566{
    567	static const struct dpu_media_color_map dpu_media_ubwc_map[] = {
    568		{DRM_FORMAT_ABGR8888, COLOR_FMT_RGBA8888_UBWC},
    569		{DRM_FORMAT_ARGB8888, COLOR_FMT_RGBA8888_UBWC},
    570		{DRM_FORMAT_XBGR8888, COLOR_FMT_RGBA8888_UBWC},
    571		{DRM_FORMAT_XRGB8888, COLOR_FMT_RGBA8888_UBWC},
    572		{DRM_FORMAT_ABGR2101010, COLOR_FMT_RGBA1010102_UBWC},
    573		{DRM_FORMAT_XBGR2101010, COLOR_FMT_RGBA1010102_UBWC},
    574		{DRM_FORMAT_BGR565, COLOR_FMT_RGB565_UBWC},
    575	};
    576	int color_fmt = -1;
    577	int i;
    578
    579	if (fmt->base.pixel_format == DRM_FORMAT_NV12) {
    580		if (DPU_FORMAT_IS_DX(fmt)) {
    581			if (fmt->unpack_tight)
    582				color_fmt = COLOR_FMT_NV12_BPP10_UBWC;
    583			else
    584				color_fmt = COLOR_FMT_P010_UBWC;
    585		} else
    586			color_fmt = COLOR_FMT_NV12_UBWC;
    587		return color_fmt;
    588	}
    589
    590	for (i = 0; i < ARRAY_SIZE(dpu_media_ubwc_map); ++i)
    591		if (fmt->base.pixel_format == dpu_media_ubwc_map[i].format) {
    592			color_fmt = dpu_media_ubwc_map[i].color;
    593			break;
    594		}
    595	return color_fmt;
    596}
    597
    598static int _dpu_format_get_plane_sizes_ubwc(
    599		const struct dpu_format *fmt,
    600		const uint32_t width,
    601		const uint32_t height,
    602		struct dpu_hw_fmt_layout *layout)
    603{
    604	int i;
    605	int color;
    606	bool meta = DPU_FORMAT_IS_UBWC(fmt);
    607
    608	memset(layout, 0, sizeof(struct dpu_hw_fmt_layout));
    609	layout->format = fmt;
    610	layout->width = width;
    611	layout->height = height;
    612	layout->num_planes = fmt->num_planes;
    613
    614	color = _dpu_format_get_media_color_ubwc(fmt);
    615	if (color < 0) {
    616		DRM_ERROR("UBWC format not supported for fmt: %4.4s\n",
    617			(char *)&fmt->base.pixel_format);
    618		return -EINVAL;
    619	}
    620
    621	if (DPU_FORMAT_IS_YUV(layout->format)) {
    622		uint32_t y_sclines, uv_sclines;
    623		uint32_t y_meta_scanlines = 0;
    624		uint32_t uv_meta_scanlines = 0;
    625
    626		layout->num_planes = 2;
    627		layout->plane_pitch[0] = VENUS_Y_STRIDE(color, width);
    628		y_sclines = VENUS_Y_SCANLINES(color, height);
    629		layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] *
    630			y_sclines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
    631
    632		layout->plane_pitch[1] = VENUS_UV_STRIDE(color, width);
    633		uv_sclines = VENUS_UV_SCANLINES(color, height);
    634		layout->plane_size[1] = MSM_MEDIA_ALIGN(layout->plane_pitch[1] *
    635			uv_sclines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
    636
    637		if (!meta)
    638			goto done;
    639
    640		layout->num_planes += 2;
    641		layout->plane_pitch[2] = VENUS_Y_META_STRIDE(color, width);
    642		y_meta_scanlines = VENUS_Y_META_SCANLINES(color, height);
    643		layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] *
    644			y_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
    645
    646		layout->plane_pitch[3] = VENUS_UV_META_STRIDE(color, width);
    647		uv_meta_scanlines = VENUS_UV_META_SCANLINES(color, height);
    648		layout->plane_size[3] = MSM_MEDIA_ALIGN(layout->plane_pitch[3] *
    649			uv_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
    650
    651	} else {
    652		uint32_t rgb_scanlines, rgb_meta_scanlines;
    653
    654		layout->num_planes = 1;
    655
    656		layout->plane_pitch[0] = VENUS_RGB_STRIDE(color, width);
    657		rgb_scanlines = VENUS_RGB_SCANLINES(color, height);
    658		layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] *
    659			rgb_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
    660
    661		if (!meta)
    662			goto done;
    663		layout->num_planes += 2;
    664		layout->plane_pitch[2] = VENUS_RGB_META_STRIDE(color, width);
    665		rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color, height);
    666		layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] *
    667			rgb_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
    668	}
    669
    670done:
    671	for (i = 0; i < DPU_MAX_PLANES; i++)
    672		layout->total_size += layout->plane_size[i];
    673
    674	return 0;
    675}
    676
    677static int _dpu_format_get_plane_sizes_linear(
    678		const struct dpu_format *fmt,
    679		const uint32_t width,
    680		const uint32_t height,
    681		struct dpu_hw_fmt_layout *layout,
    682		const uint32_t *pitches)
    683{
    684	int i;
    685
    686	memset(layout, 0, sizeof(struct dpu_hw_fmt_layout));
    687	layout->format = fmt;
    688	layout->width = width;
    689	layout->height = height;
    690	layout->num_planes = fmt->num_planes;
    691
    692	/* Due to memset above, only need to set planes of interest */
    693	if (fmt->fetch_planes == DPU_PLANE_INTERLEAVED) {
    694		layout->num_planes = 1;
    695		layout->plane_size[0] = width * height * layout->format->bpp;
    696		layout->plane_pitch[0] = width * layout->format->bpp;
    697	} else {
    698		uint32_t v_subsample, h_subsample;
    699		uint32_t chroma_samp;
    700		uint32_t bpp = 1;
    701
    702		chroma_samp = fmt->chroma_sample;
    703		_dpu_get_v_h_subsample_rate(chroma_samp, &v_subsample,
    704				&h_subsample);
    705
    706		if (width % h_subsample || height % v_subsample) {
    707			DRM_ERROR("mismatch in subsample vs dimensions\n");
    708			return -EINVAL;
    709		}
    710
    711		if ((fmt->base.pixel_format == DRM_FORMAT_NV12) &&
    712			(DPU_FORMAT_IS_DX(fmt)))
    713			bpp = 2;
    714		layout->plane_pitch[0] = width * bpp;
    715		layout->plane_pitch[1] = layout->plane_pitch[0] / h_subsample;
    716		layout->plane_size[0] = layout->plane_pitch[0] * height;
    717		layout->plane_size[1] = layout->plane_pitch[1] *
    718				(height / v_subsample);
    719
    720		if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) {
    721			layout->num_planes = 2;
    722			layout->plane_size[1] *= 2;
    723			layout->plane_pitch[1] *= 2;
    724		} else {
    725			/* planar */
    726			layout->num_planes = 3;
    727			layout->plane_size[2] = layout->plane_size[1];
    728			layout->plane_pitch[2] = layout->plane_pitch[1];
    729		}
    730	}
    731
    732	/*
    733	 * linear format: allow user allocated pitches if they are greater than
    734	 * the requirement.
    735	 * ubwc format: pitch values are computed uniformly across
    736	 * all the components based on ubwc specifications.
    737	 */
    738	for (i = 0; i < layout->num_planes && i < DPU_MAX_PLANES; ++i) {
    739		if (pitches && layout->plane_pitch[i] < pitches[i])
    740			layout->plane_pitch[i] = pitches[i];
    741	}
    742
    743	for (i = 0; i < DPU_MAX_PLANES; i++)
    744		layout->total_size += layout->plane_size[i];
    745
    746	return 0;
    747}
    748
    749static int dpu_format_get_plane_sizes(
    750		const struct dpu_format *fmt,
    751		const uint32_t w,
    752		const uint32_t h,
    753		struct dpu_hw_fmt_layout *layout,
    754		const uint32_t *pitches)
    755{
    756	if (!layout || !fmt) {
    757		DRM_ERROR("invalid pointer\n");
    758		return -EINVAL;
    759	}
    760
    761	if ((w > DPU_MAX_IMG_WIDTH) || (h > DPU_MAX_IMG_HEIGHT)) {
    762		DRM_ERROR("image dimensions outside max range\n");
    763		return -ERANGE;
    764	}
    765
    766	if (DPU_FORMAT_IS_UBWC(fmt) || DPU_FORMAT_IS_TILE(fmt))
    767		return _dpu_format_get_plane_sizes_ubwc(fmt, w, h, layout);
    768
    769	return _dpu_format_get_plane_sizes_linear(fmt, w, h, layout, pitches);
    770}
    771
    772static int _dpu_format_populate_addrs_ubwc(
    773		struct msm_gem_address_space *aspace,
    774		struct drm_framebuffer *fb,
    775		struct dpu_hw_fmt_layout *layout)
    776{
    777	uint32_t base_addr = 0;
    778	bool meta;
    779
    780	if (!fb || !layout) {
    781		DRM_ERROR("invalid pointers\n");
    782		return -EINVAL;
    783	}
    784
    785	if (aspace)
    786		base_addr = msm_framebuffer_iova(fb, aspace, 0);
    787	if (!base_addr) {
    788		DRM_ERROR("failed to retrieve base addr\n");
    789		return -EFAULT;
    790	}
    791
    792	meta = DPU_FORMAT_IS_UBWC(layout->format);
    793
    794	/* Per-format logic for verifying active planes */
    795	if (DPU_FORMAT_IS_YUV(layout->format)) {
    796		/************************************************/
    797		/*      UBWC            **                      */
    798		/*      buffer          **      DPU PLANE       */
    799		/*      format          **                      */
    800		/************************************************/
    801		/* -------------------  ** -------------------- */
    802		/* |      Y meta     |  ** |    Y bitstream   | */
    803		/* |       data      |  ** |       plane      | */
    804		/* -------------------  ** -------------------- */
    805		/* |    Y bitstream  |  ** |  CbCr bitstream  | */
    806		/* |       data      |  ** |       plane      | */
    807		/* -------------------  ** -------------------- */
    808		/* |   Cbcr metadata |  ** |       Y meta     | */
    809		/* |       data      |  ** |       plane      | */
    810		/* -------------------  ** -------------------- */
    811		/* |  CbCr bitstream |  ** |     CbCr meta    | */
    812		/* |       data      |  ** |       plane      | */
    813		/* -------------------  ** -------------------- */
    814		/************************************************/
    815
    816		/* configure Y bitstream plane */
    817		layout->plane_addr[0] = base_addr + layout->plane_size[2];
    818
    819		/* configure CbCr bitstream plane */
    820		layout->plane_addr[1] = base_addr + layout->plane_size[0]
    821			+ layout->plane_size[2] + layout->plane_size[3];
    822
    823		if (!meta)
    824			return 0;
    825
    826		/* configure Y metadata plane */
    827		layout->plane_addr[2] = base_addr;
    828
    829		/* configure CbCr metadata plane */
    830		layout->plane_addr[3] = base_addr + layout->plane_size[0]
    831			+ layout->plane_size[2];
    832
    833	} else {
    834		/************************************************/
    835		/*      UBWC            **                      */
    836		/*      buffer          **      DPU PLANE       */
    837		/*      format          **                      */
    838		/************************************************/
    839		/* -------------------  ** -------------------- */
    840		/* |      RGB meta   |  ** |   RGB bitstream  | */
    841		/* |       data      |  ** |       plane      | */
    842		/* -------------------  ** -------------------- */
    843		/* |  RGB bitstream  |  ** |       NONE       | */
    844		/* |       data      |  ** |                  | */
    845		/* -------------------  ** -------------------- */
    846		/*                      ** |     RGB meta     | */
    847		/*                      ** |       plane      | */
    848		/*                      ** -------------------- */
    849		/************************************************/
    850
    851		layout->plane_addr[0] = base_addr + layout->plane_size[2];
    852		layout->plane_addr[1] = 0;
    853
    854		if (!meta)
    855			return 0;
    856
    857		layout->plane_addr[2] = base_addr;
    858		layout->plane_addr[3] = 0;
    859	}
    860	return 0;
    861}
    862
    863static int _dpu_format_populate_addrs_linear(
    864		struct msm_gem_address_space *aspace,
    865		struct drm_framebuffer *fb,
    866		struct dpu_hw_fmt_layout *layout)
    867{
    868	unsigned int i;
    869
    870	/* Can now check the pitches given vs pitches expected */
    871	for (i = 0; i < layout->num_planes; ++i) {
    872		if (layout->plane_pitch[i] > fb->pitches[i]) {
    873			DRM_ERROR("plane %u expected pitch %u, fb %u\n",
    874				i, layout->plane_pitch[i], fb->pitches[i]);
    875			return -EINVAL;
    876		}
    877	}
    878
    879	/* Populate addresses for simple formats here */
    880	for (i = 0; i < layout->num_planes; ++i) {
    881		if (aspace)
    882			layout->plane_addr[i] =
    883				msm_framebuffer_iova(fb, aspace, i);
    884		if (!layout->plane_addr[i]) {
    885			DRM_ERROR("failed to retrieve base addr\n");
    886			return -EFAULT;
    887		}
    888	}
    889
    890	return 0;
    891}
    892
    893int dpu_format_populate_layout(
    894		struct msm_gem_address_space *aspace,
    895		struct drm_framebuffer *fb,
    896		struct dpu_hw_fmt_layout *layout)
    897{
    898	uint32_t plane_addr[DPU_MAX_PLANES];
    899	int i, ret;
    900
    901	if (!fb || !layout) {
    902		DRM_ERROR("invalid arguments\n");
    903		return -EINVAL;
    904	}
    905
    906	if ((fb->width > DPU_MAX_IMG_WIDTH) ||
    907			(fb->height > DPU_MAX_IMG_HEIGHT)) {
    908		DRM_ERROR("image dimensions outside max range\n");
    909		return -ERANGE;
    910	}
    911
    912	layout->format = to_dpu_format(msm_framebuffer_format(fb));
    913
    914	/* Populate the plane sizes etc via get_format */
    915	ret = dpu_format_get_plane_sizes(layout->format, fb->width, fb->height,
    916			layout, fb->pitches);
    917	if (ret)
    918		return ret;
    919
    920	for (i = 0; i < DPU_MAX_PLANES; ++i)
    921		plane_addr[i] = layout->plane_addr[i];
    922
    923	/* Populate the addresses given the fb */
    924	if (DPU_FORMAT_IS_UBWC(layout->format) ||
    925			DPU_FORMAT_IS_TILE(layout->format))
    926		ret = _dpu_format_populate_addrs_ubwc(aspace, fb, layout);
    927	else
    928		ret = _dpu_format_populate_addrs_linear(aspace, fb, layout);
    929
    930	/* check if anything changed */
    931	if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
    932		ret = -EAGAIN;
    933
    934	return ret;
    935}
    936
    937int dpu_format_check_modified_format(
    938		const struct msm_kms *kms,
    939		const struct msm_format *msm_fmt,
    940		const struct drm_mode_fb_cmd2 *cmd,
    941		struct drm_gem_object **bos)
    942{
    943	const struct drm_format_info *info;
    944	const struct dpu_format *fmt;
    945	struct dpu_hw_fmt_layout layout;
    946	uint32_t bos_total_size = 0;
    947	int ret, i;
    948
    949	if (!msm_fmt || !cmd || !bos) {
    950		DRM_ERROR("invalid arguments\n");
    951		return -EINVAL;
    952	}
    953
    954	fmt = to_dpu_format(msm_fmt);
    955	info = drm_format_info(fmt->base.pixel_format);
    956	if (!info)
    957		return -EINVAL;
    958
    959	ret = dpu_format_get_plane_sizes(fmt, cmd->width, cmd->height,
    960			&layout, cmd->pitches);
    961	if (ret)
    962		return ret;
    963
    964	for (i = 0; i < info->num_planes; i++) {
    965		if (!bos[i]) {
    966			DRM_ERROR("invalid handle for plane %d\n", i);
    967			return -EINVAL;
    968		}
    969		if ((i == 0) || (bos[i] != bos[0]))
    970			bos_total_size += bos[i]->size;
    971	}
    972
    973	if (bos_total_size < layout.total_size) {
    974		DRM_ERROR("buffers total size too small %u expected %u\n",
    975				bos_total_size, layout.total_size);
    976		return -EINVAL;
    977	}
    978
    979	return 0;
    980}
    981
    982const struct dpu_format *dpu_get_dpu_format_ext(
    983		const uint32_t format,
    984		const uint64_t modifier)
    985{
    986	uint32_t i = 0;
    987	const struct dpu_format *fmt = NULL;
    988	const struct dpu_format *map = NULL;
    989	ssize_t map_size = 0;
    990
    991	/*
    992	 * Currently only support exactly zero or one modifier.
    993	 * All planes use the same modifier.
    994	 */
    995	DRM_DEBUG_ATOMIC("plane format modifier 0x%llX\n", modifier);
    996
    997	switch (modifier) {
    998	case 0:
    999		map = dpu_format_map;
   1000		map_size = ARRAY_SIZE(dpu_format_map);
   1001		break;
   1002	case DRM_FORMAT_MOD_QCOM_COMPRESSED:
   1003		map = dpu_format_map_ubwc;
   1004		map_size = ARRAY_SIZE(dpu_format_map_ubwc);
   1005		DRM_DEBUG_ATOMIC("found fmt: %4.4s  DRM_FORMAT_MOD_QCOM_COMPRESSED\n",
   1006				(char *)&format);
   1007		break;
   1008	default:
   1009		DPU_ERROR("unsupported format modifier %llX\n", modifier);
   1010		return NULL;
   1011	}
   1012
   1013	for (i = 0; i < map_size; i++) {
   1014		if (format == map[i].base.pixel_format) {
   1015			fmt = &map[i];
   1016			break;
   1017		}
   1018	}
   1019
   1020	if (fmt == NULL)
   1021		DPU_ERROR("unsupported fmt: %4.4s modifier 0x%llX\n",
   1022			(char *)&format, modifier);
   1023	else
   1024		DRM_DEBUG_ATOMIC("fmt %4.4s mod 0x%llX ubwc %d yuv %d\n",
   1025				(char *)&format, modifier,
   1026				DPU_FORMAT_IS_UBWC(fmt),
   1027				DPU_FORMAT_IS_YUV(fmt));
   1028
   1029	return fmt;
   1030}
   1031
   1032const struct msm_format *dpu_get_msm_format(
   1033		struct msm_kms *kms,
   1034		const uint32_t format,
   1035		const uint64_t modifiers)
   1036{
   1037	const struct dpu_format *fmt = dpu_get_dpu_format_ext(format,
   1038			modifiers);
   1039	if (fmt)
   1040		return &fmt->base;
   1041	return NULL;
   1042}