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 /* XRGB2101010 and ARGB2101010 purposely have the same color 540 * ordering. The hardware only supports ARGB2101010 UBWC 541 * natively. 542 */ 543 INTERLEAVED_RGB_FMT_TILED(ARGB2101010, 544 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, 545 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4, 546 true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED, 547 DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC), 548 549 PSEUDO_YUV_FMT_TILED(NV12, 550 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, 551 C1_B_Cb, C2_R_Cr, 552 DPU_CHROMA_420, DPU_FORMAT_FLAG_YUV | 553 DPU_FORMAT_FLAG_COMPRESSED, 554 DPU_FETCH_UBWC, 4, DPU_TILE_HEIGHT_NV12), 555 556 PSEUDO_YUV_FMT_TILED(P010, 557 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, 558 C1_B_Cb, C2_R_Cr, 559 DPU_CHROMA_420, DPU_FORMAT_FLAG_DX | 560 DPU_FORMAT_FLAG_YUV | 561 DPU_FORMAT_FLAG_COMPRESSED, 562 DPU_FETCH_UBWC, 4, DPU_TILE_HEIGHT_UBWC), 563 }; 564 565 /* _dpu_get_v_h_subsample_rate - Get subsample rates for all formats we support 566 * Note: Not using the drm_format_*_subsampling since we have formats 567 */ 568 static void _dpu_get_v_h_subsample_rate( 569 enum dpu_chroma_samp_type chroma_sample, 570 uint32_t *v_sample, 571 uint32_t *h_sample) 572 { 573 if (!v_sample || !h_sample) 574 return; 575 576 switch (chroma_sample) { 577 case DPU_CHROMA_H2V1: 578 *v_sample = 1; 579 *h_sample = 2; 580 break; 581 case DPU_CHROMA_H1V2: 582 *v_sample = 2; 583 *h_sample = 1; 584 break; 585 case DPU_CHROMA_420: 586 *v_sample = 2; 587 *h_sample = 2; 588 break; 589 default: 590 *v_sample = 1; 591 *h_sample = 1; 592 break; 593 } 594 } 595 596 static int _dpu_format_get_media_color_ubwc(const struct dpu_format *fmt) 597 { 598 static const struct dpu_media_color_map dpu_media_ubwc_map[] = { 599 {DRM_FORMAT_ABGR8888, COLOR_FMT_RGBA8888_UBWC}, 600 {DRM_FORMAT_ARGB8888, COLOR_FMT_RGBA8888_UBWC}, 601 {DRM_FORMAT_XBGR8888, COLOR_FMT_RGBA8888_UBWC}, 602 {DRM_FORMAT_XRGB8888, COLOR_FMT_RGBA8888_UBWC}, 603 {DRM_FORMAT_ABGR2101010, COLOR_FMT_RGBA1010102_UBWC}, 604 {DRM_FORMAT_ARGB2101010, COLOR_FMT_RGBA1010102_UBWC}, 605 {DRM_FORMAT_XRGB2101010, COLOR_FMT_RGBA1010102_UBWC}, 606 {DRM_FORMAT_XBGR2101010, COLOR_FMT_RGBA1010102_UBWC}, 607 {DRM_FORMAT_BGR565, COLOR_FMT_RGB565_UBWC}, 608 }; 609 int color_fmt = -1; 610 int i; 611 612 if (fmt->base.pixel_format == DRM_FORMAT_NV12 || 613 fmt->base.pixel_format == DRM_FORMAT_P010) { 614 if (DPU_FORMAT_IS_DX(fmt)) { 615 if (fmt->unpack_tight) 616 color_fmt = COLOR_FMT_NV12_BPP10_UBWC; 617 else 618 color_fmt = COLOR_FMT_P010_UBWC; 619 } else 620 color_fmt = COLOR_FMT_NV12_UBWC; 621 return color_fmt; 622 } 623 624 for (i = 0; i < ARRAY_SIZE(dpu_media_ubwc_map); ++i) 625 if (fmt->base.pixel_format == dpu_media_ubwc_map[i].format) { 626 color_fmt = dpu_media_ubwc_map[i].color; 627 break; 628 } 629 return color_fmt; 630 } 631 632 static int _dpu_format_get_plane_sizes_ubwc( 633 const struct dpu_format *fmt, 634 const uint32_t width, 635 const uint32_t height, 636 struct dpu_hw_fmt_layout *layout) 637 { 638 int i; 639 int color; 640 bool meta = DPU_FORMAT_IS_UBWC(fmt); 641 642 memset(layout, 0, sizeof(struct dpu_hw_fmt_layout)); 643 layout->format = fmt; 644 layout->width = width; 645 layout->height = height; 646 layout->num_planes = fmt->num_planes; 647 648 color = _dpu_format_get_media_color_ubwc(fmt); 649 if (color < 0) { 650 DRM_ERROR("UBWC format not supported for fmt: %4.4s\n", 651 (char *)&fmt->base.pixel_format); 652 return -EINVAL; 653 } 654 655 if (DPU_FORMAT_IS_YUV(layout->format)) { 656 uint32_t y_sclines, uv_sclines; 657 uint32_t y_meta_scanlines = 0; 658 uint32_t uv_meta_scanlines = 0; 659 660 layout->num_planes = 2; 661 layout->plane_pitch[0] = VENUS_Y_STRIDE(color, width); 662 y_sclines = VENUS_Y_SCANLINES(color, height); 663 layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] * 664 y_sclines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); 665 666 layout->plane_pitch[1] = VENUS_UV_STRIDE(color, width); 667 uv_sclines = VENUS_UV_SCANLINES(color, height); 668 layout->plane_size[1] = MSM_MEDIA_ALIGN(layout->plane_pitch[1] * 669 uv_sclines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); 670 671 if (!meta) 672 goto done; 673 674 layout->num_planes += 2; 675 layout->plane_pitch[2] = VENUS_Y_META_STRIDE(color, width); 676 y_meta_scanlines = VENUS_Y_META_SCANLINES(color, height); 677 layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] * 678 y_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); 679 680 layout->plane_pitch[3] = VENUS_UV_META_STRIDE(color, width); 681 uv_meta_scanlines = VENUS_UV_META_SCANLINES(color, height); 682 layout->plane_size[3] = MSM_MEDIA_ALIGN(layout->plane_pitch[3] * 683 uv_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); 684 685 } else { 686 uint32_t rgb_scanlines, rgb_meta_scanlines; 687 688 layout->num_planes = 1; 689 690 layout->plane_pitch[0] = VENUS_RGB_STRIDE(color, width); 691 rgb_scanlines = VENUS_RGB_SCANLINES(color, height); 692 layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] * 693 rgb_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); 694 695 if (!meta) 696 goto done; 697 layout->num_planes += 2; 698 layout->plane_pitch[2] = VENUS_RGB_META_STRIDE(color, width); 699 rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color, height); 700 layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] * 701 rgb_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT); 702 } 703 704 done: 705 for (i = 0; i < DPU_MAX_PLANES; i++) 706 layout->total_size += layout->plane_size[i]; 707 708 return 0; 709 } 710 711 static int _dpu_format_get_plane_sizes_linear( 712 const struct dpu_format *fmt, 713 const uint32_t width, 714 const uint32_t height, 715 struct dpu_hw_fmt_layout *layout, 716 const uint32_t *pitches) 717 { 718 int i; 719 720 memset(layout, 0, sizeof(struct dpu_hw_fmt_layout)); 721 layout->format = fmt; 722 layout->width = width; 723 layout->height = height; 724 layout->num_planes = fmt->num_planes; 725 726 /* Due to memset above, only need to set planes of interest */ 727 if (fmt->fetch_planes == DPU_PLANE_INTERLEAVED) { 728 layout->num_planes = 1; 729 layout->plane_size[0] = width * height * layout->format->bpp; 730 layout->plane_pitch[0] = width * layout->format->bpp; 731 } else { 732 uint32_t v_subsample, h_subsample; 733 uint32_t chroma_samp; 734 uint32_t bpp = 1; 735 736 chroma_samp = fmt->chroma_sample; 737 _dpu_get_v_h_subsample_rate(chroma_samp, &v_subsample, 738 &h_subsample); 739 740 if (width % h_subsample || height % v_subsample) { 741 DRM_ERROR("mismatch in subsample vs dimensions\n"); 742 return -EINVAL; 743 } 744 745 if ((fmt->base.pixel_format == DRM_FORMAT_NV12) && 746 (DPU_FORMAT_IS_DX(fmt))) 747 bpp = 2; 748 layout->plane_pitch[0] = width * bpp; 749 layout->plane_pitch[1] = layout->plane_pitch[0] / h_subsample; 750 layout->plane_size[0] = layout->plane_pitch[0] * height; 751 layout->plane_size[1] = layout->plane_pitch[1] * 752 (height / v_subsample); 753 754 if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) { 755 layout->num_planes = 2; 756 layout->plane_size[1] *= 2; 757 layout->plane_pitch[1] *= 2; 758 } else { 759 /* planar */ 760 layout->num_planes = 3; 761 layout->plane_size[2] = layout->plane_size[1]; 762 layout->plane_pitch[2] = layout->plane_pitch[1]; 763 } 764 } 765 766 /* 767 * linear format: allow user allocated pitches if they are greater than 768 * the requirement. 769 * ubwc format: pitch values are computed uniformly across 770 * all the components based on ubwc specifications. 771 */ 772 for (i = 0; i < layout->num_planes && i < DPU_MAX_PLANES; ++i) { 773 if (pitches && layout->plane_pitch[i] < pitches[i]) 774 layout->plane_pitch[i] = pitches[i]; 775 } 776 777 for (i = 0; i < DPU_MAX_PLANES; i++) 778 layout->total_size += layout->plane_size[i]; 779 780 return 0; 781 } 782 783 static int dpu_format_get_plane_sizes( 784 const struct dpu_format *fmt, 785 const uint32_t w, 786 const uint32_t h, 787 struct dpu_hw_fmt_layout *layout, 788 const uint32_t *pitches) 789 { 790 if (!layout || !fmt) { 791 DRM_ERROR("invalid pointer\n"); 792 return -EINVAL; 793 } 794 795 if ((w > DPU_MAX_IMG_WIDTH) || (h > DPU_MAX_IMG_HEIGHT)) { 796 DRM_ERROR("image dimensions outside max range\n"); 797 return -ERANGE; 798 } 799 800 if (DPU_FORMAT_IS_UBWC(fmt) || DPU_FORMAT_IS_TILE(fmt)) 801 return _dpu_format_get_plane_sizes_ubwc(fmt, w, h, layout); 802 803 return _dpu_format_get_plane_sizes_linear(fmt, w, h, layout, pitches); 804 } 805 806 static int _dpu_format_populate_addrs_ubwc( 807 struct msm_gem_address_space *aspace, 808 struct drm_framebuffer *fb, 809 struct dpu_hw_fmt_layout *layout) 810 { 811 uint32_t base_addr = 0; 812 bool meta; 813 814 if (!fb || !layout) { 815 DRM_ERROR("invalid pointers\n"); 816 return -EINVAL; 817 } 818 819 if (aspace) 820 base_addr = msm_framebuffer_iova(fb, aspace, 0); 821 if (!base_addr) { 822 DRM_ERROR("failed to retrieve base addr\n"); 823 return -EFAULT; 824 } 825 826 meta = DPU_FORMAT_IS_UBWC(layout->format); 827 828 /* Per-format logic for verifying active planes */ 829 if (DPU_FORMAT_IS_YUV(layout->format)) { 830 /************************************************/ 831 /* UBWC ** */ 832 /* buffer ** DPU PLANE */ 833 /* format ** */ 834 /************************************************/ 835 /* ------------------- ** -------------------- */ 836 /* | Y meta | ** | Y bitstream | */ 837 /* | data | ** | plane | */ 838 /* ------------------- ** -------------------- */ 839 /* | Y bitstream | ** | CbCr bitstream | */ 840 /* | data | ** | plane | */ 841 /* ------------------- ** -------------------- */ 842 /* | Cbcr metadata | ** | Y meta | */ 843 /* | data | ** | plane | */ 844 /* ------------------- ** -------------------- */ 845 /* | CbCr bitstream | ** | CbCr meta | */ 846 /* | data | ** | plane | */ 847 /* ------------------- ** -------------------- */ 848 /************************************************/ 849 850 /* configure Y bitstream plane */ 851 layout->plane_addr[0] = base_addr + layout->plane_size[2]; 852 853 /* configure CbCr bitstream plane */ 854 layout->plane_addr[1] = base_addr + layout->plane_size[0] 855 + layout->plane_size[2] + layout->plane_size[3]; 856 857 if (!meta) 858 return 0; 859 860 /* configure Y metadata plane */ 861 layout->plane_addr[2] = base_addr; 862 863 /* configure CbCr metadata plane */ 864 layout->plane_addr[3] = base_addr + layout->plane_size[0] 865 + layout->plane_size[2]; 866 867 } else { 868 /************************************************/ 869 /* UBWC ** */ 870 /* buffer ** DPU PLANE */ 871 /* format ** */ 872 /************************************************/ 873 /* ------------------- ** -------------------- */ 874 /* | RGB meta | ** | RGB bitstream | */ 875 /* | data | ** | plane | */ 876 /* ------------------- ** -------------------- */ 877 /* | RGB bitstream | ** | NONE | */ 878 /* | data | ** | | */ 879 /* ------------------- ** -------------------- */ 880 /* ** | RGB meta | */ 881 /* ** | plane | */ 882 /* ** -------------------- */ 883 /************************************************/ 884 885 layout->plane_addr[0] = base_addr + layout->plane_size[2]; 886 layout->plane_addr[1] = 0; 887 888 if (!meta) 889 return 0; 890 891 layout->plane_addr[2] = base_addr; 892 layout->plane_addr[3] = 0; 893 } 894 return 0; 895 } 896 897 static int _dpu_format_populate_addrs_linear( 898 struct msm_gem_address_space *aspace, 899 struct drm_framebuffer *fb, 900 struct dpu_hw_fmt_layout *layout) 901 { 902 unsigned int i; 903 904 /* Can now check the pitches given vs pitches expected */ 905 for (i = 0; i < layout->num_planes; ++i) { 906 if (layout->plane_pitch[i] > fb->pitches[i]) { 907 DRM_ERROR("plane %u expected pitch %u, fb %u\n", 908 i, layout->plane_pitch[i], fb->pitches[i]); 909 return -EINVAL; 910 } 911 } 912 913 /* Populate addresses for simple formats here */ 914 for (i = 0; i < layout->num_planes; ++i) { 915 if (aspace) 916 layout->plane_addr[i] = 917 msm_framebuffer_iova(fb, aspace, i); 918 if (!layout->plane_addr[i]) { 919 DRM_ERROR("failed to retrieve base addr\n"); 920 return -EFAULT; 921 } 922 } 923 924 return 0; 925 } 926 927 int dpu_format_populate_layout( 928 struct msm_gem_address_space *aspace, 929 struct drm_framebuffer *fb, 930 struct dpu_hw_fmt_layout *layout) 931 { 932 int ret; 933 934 if (!fb || !layout) { 935 DRM_ERROR("invalid arguments\n"); 936 return -EINVAL; 937 } 938 939 if ((fb->width > DPU_MAX_IMG_WIDTH) || 940 (fb->height > DPU_MAX_IMG_HEIGHT)) { 941 DRM_ERROR("image dimensions outside max range\n"); 942 return -ERANGE; 943 } 944 945 layout->format = to_dpu_format(msm_framebuffer_format(fb)); 946 947 /* Populate the plane sizes etc via get_format */ 948 ret = dpu_format_get_plane_sizes(layout->format, fb->width, fb->height, 949 layout, fb->pitches); 950 if (ret) 951 return ret; 952 953 /* Populate the addresses given the fb */ 954 if (DPU_FORMAT_IS_UBWC(layout->format) || 955 DPU_FORMAT_IS_TILE(layout->format)) 956 ret = _dpu_format_populate_addrs_ubwc(aspace, fb, layout); 957 else 958 ret = _dpu_format_populate_addrs_linear(aspace, fb, layout); 959 960 return ret; 961 } 962 963 int dpu_format_check_modified_format( 964 const struct msm_kms *kms, 965 const struct msm_format *msm_fmt, 966 const struct drm_mode_fb_cmd2 *cmd, 967 struct drm_gem_object **bos) 968 { 969 const struct drm_format_info *info; 970 const struct dpu_format *fmt; 971 struct dpu_hw_fmt_layout layout; 972 uint32_t bos_total_size = 0; 973 int ret, i; 974 975 if (!msm_fmt || !cmd || !bos) { 976 DRM_ERROR("invalid arguments\n"); 977 return -EINVAL; 978 } 979 980 fmt = to_dpu_format(msm_fmt); 981 info = drm_format_info(fmt->base.pixel_format); 982 if (!info) 983 return -EINVAL; 984 985 ret = dpu_format_get_plane_sizes(fmt, cmd->width, cmd->height, 986 &layout, cmd->pitches); 987 if (ret) 988 return ret; 989 990 for (i = 0; i < info->num_planes; i++) { 991 if (!bos[i]) { 992 DRM_ERROR("invalid handle for plane %d\n", i); 993 return -EINVAL; 994 } 995 if ((i == 0) || (bos[i] != bos[0])) 996 bos_total_size += bos[i]->size; 997 } 998 999 if (bos_total_size < layout.total_size) { 1000 DRM_ERROR("buffers total size too small %u expected %u\n", 1001 bos_total_size, layout.total_size); 1002 return -EINVAL; 1003 } 1004 1005 return 0; 1006 } 1007 1008 const struct dpu_format *dpu_get_dpu_format_ext( 1009 const uint32_t format, 1010 const uint64_t modifier) 1011 { 1012 uint32_t i = 0; 1013 const struct dpu_format *fmt = NULL; 1014 const struct dpu_format *map = NULL; 1015 ssize_t map_size = 0; 1016 1017 /* 1018 * Currently only support exactly zero or one modifier. 1019 * All planes use the same modifier. 1020 */ 1021 DRM_DEBUG_ATOMIC("plane format modifier 0x%llX\n", modifier); 1022 1023 switch (modifier) { 1024 case 0: 1025 map = dpu_format_map; 1026 map_size = ARRAY_SIZE(dpu_format_map); 1027 break; 1028 case DRM_FORMAT_MOD_QCOM_COMPRESSED: 1029 map = dpu_format_map_ubwc; 1030 map_size = ARRAY_SIZE(dpu_format_map_ubwc); 1031 DRM_DEBUG_ATOMIC("found fmt: %4.4s DRM_FORMAT_MOD_QCOM_COMPRESSED\n", 1032 (char *)&format); 1033 break; 1034 default: 1035 DPU_ERROR("unsupported format modifier %llX\n", modifier); 1036 return NULL; 1037 } 1038 1039 for (i = 0; i < map_size; i++) { 1040 if (format == map[i].base.pixel_format) { 1041 fmt = &map[i]; 1042 break; 1043 } 1044 } 1045 1046 if (fmt == NULL) 1047 DPU_ERROR("unsupported fmt: %4.4s modifier 0x%llX\n", 1048 (char *)&format, modifier); 1049 else 1050 DRM_DEBUG_ATOMIC("fmt %4.4s mod 0x%llX ubwc %d yuv %d\n", 1051 (char *)&format, modifier, 1052 DPU_FORMAT_IS_UBWC(fmt), 1053 DPU_FORMAT_IS_YUV(fmt)); 1054 1055 return fmt; 1056 } 1057 1058 const struct msm_format *dpu_get_msm_format( 1059 struct msm_kms *kms, 1060 const uint32_t format, 1061 const uint64_t modifiers) 1062 { 1063 const struct dpu_format *fmt = dpu_get_dpu_format_ext(format, 1064 modifiers); 1065 if (fmt) 1066 return &fmt->base; 1067 return NULL; 1068 } 1069