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