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