Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   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}