linux/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
<<
>>
Prefs
   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}
1043