blob: f0aabb3be99f247829c82213db5c39f0044abe13 [file] [log] [blame]
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04001/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -040013#include <uapi/drm/drm_fourcc.h>
14
Clarence Ipc475b082016-06-26 09:27:23 -040015#include "sde_kms.h"
16#include "sde_formats.h"
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -040017
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -040018#define SDE_UBWC_META_MACRO_W_H 16
19#define SDE_UBWC_META_BLOCK_SIZE 256
20#define SDE_MAX_IMG_WIDTH 0x3FFF
21#define SDE_MAX_IMG_HEIGHT 0x3FFF
22
23/**
24 * SDE supported format packing, bpp, and other format
25 * information.
26 * SDE currently only supports interleaved RGB formats
27 * UBWC support for a pixel format is indicated by the flag,
28 * there is additional meta data plane for such formats
29 */
30
31#define INTERLEAVED_RGB_FMT(fmt, a, r, g, b, e0, e1, e2, e3, uc, alpha, \
32bp, flg, fm, np) \
33{ \
34 .base.pixel_format = DRM_FORMAT_ ## fmt, \
35 .fetch_planes = SDE_PLANE_INTERLEAVED, \
36 .alpha_enable = alpha, \
37 .element = { (e0), (e1), (e2), (e3) }, \
38 .bits = { g, b, r, a }, \
39 .chroma_sample = SDE_CHROMA_RGB, \
40 .unpack_align_msb = 0, \
41 .unpack_tight = 1, \
42 .unpack_count = uc, \
43 .bpp = bp, \
44 .fetch_mode = fm, \
45 .flag = flg, \
46 .num_planes = np \
47}
48
49#define INTERLEAVED_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, e3, \
50alpha, chroma, count, bp, flg, fm, np) \
51{ \
52 .base.pixel_format = DRM_FORMAT_ ## fmt, \
53 .fetch_planes = SDE_PLANE_INTERLEAVED, \
54 .alpha_enable = alpha, \
55 .element = { (e0), (e1), (e2), (e3)}, \
56 .bits = { g, b, r, a }, \
57 .chroma_sample = chroma, \
58 .unpack_align_msb = 0, \
59 .unpack_tight = 1, \
60 .unpack_count = count, \
61 .bpp = bp, \
62 .fetch_mode = fm, \
63 .flag = flg, \
64 .num_planes = np \
65}
66
67#define PSEDUO_YUV_FMT(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np) \
68{ \
69 .base.pixel_format = DRM_FORMAT_ ## fmt, \
70 .fetch_planes = SDE_PLANE_PSEUDO_PLANAR, \
71 .alpha_enable = false, \
72 .element = { (e0), (e1), 0, 0 }, \
73 .bits = { g, b, r, a }, \
74 .chroma_sample = chroma, \
75 .unpack_align_msb = 0, \
76 .unpack_tight = 1, \
77 .unpack_count = 2, \
78 .bpp = 2, \
79 .fetch_mode = fm, \
80 .flag = flg, \
81 .num_planes = np \
82}
83
84#define PLANAR_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, alpha, chroma, bp, \
85flg, fm, np) \
86{ \
87 .base.pixel_format = DRM_FORMAT_ ## fmt, \
88 .fetch_planes = SDE_PLANE_PLANAR, \
89 .alpha_enable = alpha, \
90 .element = { (e0), (e1), (e2), 0 }, \
91 .bits = { g, b, r, a }, \
92 .chroma_sample = chroma, \
93 .unpack_align_msb = 0, \
94 .unpack_tight = 1, \
95 .unpack_count = 1, \
96 .bpp = bp, \
97 .fetch_mode = fm, \
98 .flag = flg, \
99 .num_planes = np \
100}
101
102static const struct sde_format sde_format_map[] = {
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400103 INTERLEAVED_RGB_FMT(ARGB8888,
104 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700105 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400106 true, 4, 0,
107 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400108
109 INTERLEAVED_RGB_FMT(ABGR8888,
110 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700111 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400112 true, 4, 0,
113 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400114
Narendra Muppalla88ad7262016-10-31 18:14:21 -0700115 INTERLEAVED_RGB_FMT(XBGR8888,
116 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
117 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
118 true, 4, 0,
119 SDE_FETCH_LINEAR, 1),
120
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400121 INTERLEAVED_RGB_FMT(RGBA8888,
122 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700123 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400124 true, 4, 0,
125 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400126
127 INTERLEAVED_RGB_FMT(BGRA8888,
128 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700129 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400130 true, 4, 0,
131 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400132
Alan Kwong3232ca52016-07-29 02:27:47 -0400133 INTERLEAVED_RGB_FMT(BGRX8888,
134 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700135 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Alan Kwong3232ca52016-07-29 02:27:47 -0400136 false, 4, 0,
137 SDE_FETCH_LINEAR, 1),
138
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400139 INTERLEAVED_RGB_FMT(XRGB8888,
140 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700141 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400142 false, 4, 0,
143 SDE_FETCH_LINEAR, 1),
144
145 INTERLEAVED_RGB_FMT(RGBX8888,
146 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700147 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400148 false, 4, 0,
149 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400150
151 INTERLEAVED_RGB_FMT(RGB888,
152 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700153 C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400154 false, 3, 0,
155 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400156
157 INTERLEAVED_RGB_FMT(BGR888,
158 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700159 C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400160 false, 3, 0,
161 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400162
163 INTERLEAVED_RGB_FMT(RGB565,
164 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700165 C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400166 false, 2, 0,
167 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400168
169 INTERLEAVED_RGB_FMT(BGR565,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400170 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700171 C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400172 false, 2, 0,
173 SDE_FETCH_LINEAR, 1),
174
175 INTERLEAVED_RGB_FMT(ARGB1555,
176 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700177 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400178 true, 2, 0,
179 SDE_FETCH_LINEAR, 1),
180
181 INTERLEAVED_RGB_FMT(ABGR1555,
182 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700183 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400184 true, 2, 0,
185 SDE_FETCH_LINEAR, 1),
186
187 INTERLEAVED_RGB_FMT(RGBA5551,
188 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700189 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400190 true, 2, 0,
191 SDE_FETCH_LINEAR, 1),
192
193 INTERLEAVED_RGB_FMT(BGRA5551,
194 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700195 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400196 true, 2, 0,
197 SDE_FETCH_LINEAR, 1),
198
199 INTERLEAVED_RGB_FMT(XRGB1555,
200 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700201 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400202 false, 2, 0,
203 SDE_FETCH_LINEAR, 1),
204
205 INTERLEAVED_RGB_FMT(XBGR1555,
206 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700207 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400208 false, 2, 0,
209 SDE_FETCH_LINEAR, 1),
210
211 INTERLEAVED_RGB_FMT(RGBX5551,
212 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700213 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400214 false, 2, 0,
215 SDE_FETCH_LINEAR, 1),
216
217 INTERLEAVED_RGB_FMT(BGRX5551,
218 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700219 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400220 false, 2, 0,
221 SDE_FETCH_LINEAR, 1),
222
223 INTERLEAVED_RGB_FMT(ARGB4444,
224 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700225 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400226 true, 2, 0,
227 SDE_FETCH_LINEAR, 1),
228
229 INTERLEAVED_RGB_FMT(ABGR4444,
230 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700231 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400232 true, 2, 0,
233 SDE_FETCH_LINEAR, 1),
234
235 INTERLEAVED_RGB_FMT(RGBA4444,
236 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700237 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400238 true, 2, 0,
239 SDE_FETCH_LINEAR, 1),
240
241 INTERLEAVED_RGB_FMT(BGRA4444,
242 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700243 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400244 true, 2, 0,
245 SDE_FETCH_LINEAR, 1),
246
247 INTERLEAVED_RGB_FMT(XRGB4444,
248 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700249 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400250 false, 2, 0,
251 SDE_FETCH_LINEAR, 1),
252
253 INTERLEAVED_RGB_FMT(XBGR4444,
254 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700255 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400256 false, 2, 0,
257 SDE_FETCH_LINEAR, 1),
258
259 INTERLEAVED_RGB_FMT(RGBX4444,
260 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700261 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400262 false, 2, 0,
263 SDE_FETCH_LINEAR, 1),
264
265 INTERLEAVED_RGB_FMT(BGRX4444,
266 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700267 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400268 false, 2, 0,
269 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400270
271 PSEDUO_YUV_FMT(NV12,
272 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
273 C1_B_Cb, C2_R_Cr,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400274 SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
275 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400276
277 PSEDUO_YUV_FMT(NV21,
278 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
279 C2_R_Cr, C1_B_Cb,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400280 SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
281 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400282
283 PSEDUO_YUV_FMT(NV16,
284 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
285 C1_B_Cb, C2_R_Cr,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400286 SDE_CHROMA_H2V1, SDE_FORMAT_FLAG_YUV,
287 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400288
289 PSEDUO_YUV_FMT(NV61,
290 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
291 C2_R_Cr, C1_B_Cb,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400292 SDE_CHROMA_H2V1, SDE_FORMAT_FLAG_YUV,
293 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400294
295 INTERLEAVED_YUV_FMT(VYUY,
296 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
297 C2_R_Cr, C0_G_Y, C1_B_Cb, C0_G_Y,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400298 false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
299 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400300
301 INTERLEAVED_YUV_FMT(UYVY,
302 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
303 C1_B_Cb, C0_G_Y, C2_R_Cr, C0_G_Y,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400304 false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
305 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400306
307 INTERLEAVED_YUV_FMT(YUYV,
308 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
309 C0_G_Y, C1_B_Cb, C0_G_Y, C2_R_Cr,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400310 false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
311 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400312
313 INTERLEAVED_YUV_FMT(YVYU,
314 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
315 C0_G_Y, C2_R_Cr, C0_G_Y, C1_B_Cb,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400316 false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
317 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400318
319 PLANAR_YUV_FMT(YUV420,
320 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700321 C0_G_Y, C1_B_Cb, C2_R_Cr,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400322 false, SDE_CHROMA_420, 1, SDE_FORMAT_FLAG_YUV,
323 SDE_FETCH_LINEAR, 3),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400324
325 PLANAR_YUV_FMT(YVU420,
326 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700327 C0_G_Y, C2_R_Cr, C1_B_Cb,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400328 false, SDE_CHROMA_420, 1, SDE_FORMAT_FLAG_YUV,
329 SDE_FETCH_LINEAR, 3),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400330};
331
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400332/*
333 * UBWC formats table:
334 * This table holds the UBWC formats supported.
335 * If a compression ratio needs to be used for this or any other format,
336 * the data will be passed by user-space.
337 */
338static const struct sde_format sde_format_map_ubwc[] = {
Dhaval Patel17ec9152016-08-30 17:49:07 -0700339 INTERLEAVED_RGB_FMT(RGB565,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400340 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
341 C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
342 false, 2, 0,
343 SDE_FETCH_UBWC, 2),
344
Dhaval Patel17ec9152016-08-30 17:49:07 -0700345 INTERLEAVED_RGB_FMT(RGBA8888,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400346 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
347 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
348 true, 4, 0,
349 SDE_FETCH_UBWC, 2),
350
Dhaval Patel17ec9152016-08-30 17:49:07 -0700351 INTERLEAVED_RGB_FMT(RGBX8888,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400352 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
353 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
354 false, 4, 0,
355 SDE_FETCH_UBWC, 2),
356
357 PSEDUO_YUV_FMT(NV12,
358 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
359 C1_B_Cb, C2_R_Cr,
360 SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
361 SDE_FETCH_UBWC, 4),
362};
363
364/* _sde_get_v_h_subsample_rate - Get subsample rates for all formats we support
365 * Note: Not using the drm_format_*_subsampling since we have formats
366 */
367static void _sde_get_v_h_subsample_rate(
368 enum sde_chroma_samp_type chroma_sample,
369 uint32_t *v_sample,
370 uint32_t *h_sample)
371{
Alan Kwongbb27c092016-07-20 16:41:25 -0400372 if (!v_sample || !h_sample)
373 return;
374
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400375 switch (chroma_sample) {
376 case SDE_CHROMA_H2V1:
377 *v_sample = 1;
378 *h_sample = 2;
379 break;
380 case SDE_CHROMA_H1V2:
381 *v_sample = 2;
382 *h_sample = 1;
383 break;
384 case SDE_CHROMA_420:
385 *v_sample = 2;
386 *h_sample = 2;
387 break;
388 default:
389 *v_sample = 1;
390 *h_sample = 1;
391 break;
392 }
393}
394
395static int _sde_format_get_plane_sizes_ubwc(
396 const struct sde_format *fmt,
397 const uint32_t width,
398 const uint32_t height,
399 struct sde_hw_fmt_layout *layout)
400{
401 int i;
402
403 memset(layout, 0, sizeof(struct sde_hw_fmt_layout));
404 layout->format = fmt;
405 layout->width = width;
406 layout->height = height;
407 layout->num_planes = fmt->num_planes;
408
409 if (fmt->base.pixel_format == DRM_FORMAT_NV12) {
410 uint32_t y_stride_alignment, uv_stride_alignment;
411 uint32_t y_height_alignment, uv_height_alignment;
412 uint32_t y_tile_width = 32;
413 uint32_t y_tile_height = 8;
414 uint32_t uv_tile_width = y_tile_width / 2;
415 uint32_t uv_tile_height = y_tile_height;
416 uint32_t y_bpp_numer = 1, y_bpp_denom = 1;
417 uint32_t uv_bpp_numer = 1, uv_bpp_denom = 1;
418
419 y_stride_alignment = 128;
420 uv_stride_alignment = 64;
421 y_height_alignment = 32;
422 uv_height_alignment = 32;
423 y_bpp_numer = 1;
424 uv_bpp_numer = 2;
425 y_bpp_denom = 1;
426 uv_bpp_denom = 1;
427
428 layout->num_planes = 4;
429 /* Y bitstream stride and plane size */
430 layout->plane_pitch[0] = ALIGN(width, y_stride_alignment);
431 layout->plane_pitch[0] = (layout->plane_pitch[0] * y_bpp_numer)
432 / y_bpp_denom;
433 layout->plane_size[0] = ALIGN(layout->plane_pitch[0] *
434 ALIGN(height, y_height_alignment), 4096);
435
436 /* CbCr bitstream stride and plane size */
437 layout->plane_pitch[1] = ALIGN(width / 2, uv_stride_alignment);
438 layout->plane_pitch[1] = (layout->plane_pitch[1] * uv_bpp_numer)
439 / uv_bpp_denom;
440 layout->plane_size[1] = ALIGN(layout->plane_pitch[1] *
441 ALIGN(height / 2, uv_height_alignment), 4096);
442
443 /* Y meta data stride and plane size */
444 layout->plane_pitch[2] = ALIGN(
445 DIV_ROUND_UP(width, y_tile_width), 64);
446 layout->plane_size[2] = ALIGN(layout->plane_pitch[2] *
447 ALIGN(DIV_ROUND_UP(height, y_tile_height), 16), 4096);
448
449 /* CbCr meta data stride and plane size */
450 layout->plane_pitch[3] = ALIGN(
451 DIV_ROUND_UP(width / 2, uv_tile_width), 64);
452 layout->plane_size[3] = ALIGN(layout->plane_pitch[3] *
453 ALIGN(DIV_ROUND_UP(height / 2, uv_tile_height), 16),
454 4096);
455
Dhaval Patel17ec9152016-08-30 17:49:07 -0700456 } else if (fmt->base.pixel_format == DRM_FORMAT_RGBA8888 ||
457 fmt->base.pixel_format == DRM_FORMAT_RGBX8888 ||
458 fmt->base.pixel_format == DRM_FORMAT_RGB565) {
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400459 uint32_t stride_alignment, aligned_bitstream_width;
460
Dhaval Patel17ec9152016-08-30 17:49:07 -0700461 if (fmt->base.pixel_format == DRM_FORMAT_RGB565)
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400462 stride_alignment = 128;
463 else
464 stride_alignment = 64;
465 layout->num_planes = 3;
466
467 /* Nothing in plane[1] */
468
469 /* RGB bitstream stride and plane size */
470 aligned_bitstream_width = ALIGN(width, stride_alignment);
471 layout->plane_pitch[0] = aligned_bitstream_width * fmt->bpp;
472 layout->plane_size[0] = ALIGN(fmt->bpp * aligned_bitstream_width
473 * ALIGN(height, 16), 4096);
474
475 /* RGB meta data stride and plane size */
476 layout->plane_pitch[2] = ALIGN(DIV_ROUND_UP(
477 aligned_bitstream_width, 16), 64);
478 layout->plane_size[2] = ALIGN(layout->plane_pitch[2] *
479 ALIGN(DIV_ROUND_UP(height, 4), 16), 4096);
480 } else {
481 DRM_ERROR("UBWC format not supported for fmt:0x%X\n",
482 fmt->base.pixel_format);
483 return -EINVAL;
484 }
485
486 for (i = 0; i < SDE_MAX_PLANES; i++)
487 layout->total_size += layout->plane_size[i];
488
489 return 0;
490}
491
492static int _sde_format_get_plane_sizes_linear(
493 const struct sde_format *fmt,
494 const uint32_t width,
495 const uint32_t height,
496 struct sde_hw_fmt_layout *layout)
497{
498 int i;
499
500 memset(layout, 0, sizeof(struct sde_hw_fmt_layout));
501 layout->format = fmt;
502 layout->width = width;
503 layout->height = height;
504 layout->num_planes = fmt->num_planes;
505
506 /* Due to memset above, only need to set planes of interest */
507 if (fmt->fetch_planes == SDE_PLANE_INTERLEAVED) {
508 layout->num_planes = 1;
509 layout->plane_size[0] = width * height * layout->format->bpp;
510 layout->plane_pitch[0] = width * layout->format->bpp;
511 } else {
512 uint32_t v_subsample, h_subsample;
513 uint32_t chroma_samp;
514
515 chroma_samp = fmt->chroma_sample;
516 _sde_get_v_h_subsample_rate(chroma_samp, &v_subsample,
517 &h_subsample);
518
519 if (width % h_subsample || height % v_subsample) {
520 DRM_ERROR("mismatch in subsample vs dimensions\n");
521 return -EINVAL;
522 }
523
524 layout->plane_pitch[0] = width;
525 layout->plane_pitch[1] = width / h_subsample;
526 layout->plane_size[0] = layout->plane_pitch[0] * height;
527 layout->plane_size[1] = layout->plane_pitch[1] *
528 (height / v_subsample);
529
530 if (fmt->fetch_planes == SDE_PLANE_PSEUDO_PLANAR) {
531 layout->num_planes = 2;
532 layout->plane_size[1] *= 2;
533 layout->plane_pitch[1] *= 2;
534 } else {
535 /* planar */
536 layout->num_planes = 3;
537 layout->plane_size[2] = layout->plane_size[1];
538 layout->plane_pitch[2] = layout->plane_pitch[1];
539 }
540 }
541
542 for (i = 0; i < SDE_MAX_PLANES; i++)
543 layout->total_size += layout->plane_size[i];
544
545 return 0;
546}
547
548static int _sde_format_get_plane_sizes(
549 const struct sde_format *fmt,
550 const uint32_t w,
551 const uint32_t h,
552 struct sde_hw_fmt_layout *layout)
553{
554 if (!layout || !fmt) {
555 DRM_ERROR("invalid pointer\n");
556 return -EINVAL;
557 }
558
559 if ((w > SDE_MAX_IMG_WIDTH) || (h > SDE_MAX_IMG_HEIGHT)) {
560 DRM_ERROR("image dimensions outside max range\n");
561 return -ERANGE;
562 }
563
564 if (SDE_FORMAT_IS_UBWC(fmt))
565 return _sde_format_get_plane_sizes_ubwc(fmt, w, h, layout);
566
567 return _sde_format_get_plane_sizes_linear(fmt, w, h, layout);
568}
569
570static int _sde_format_populate_addrs_ubwc(
571 int mmu_id,
572 struct drm_framebuffer *fb,
573 struct sde_hw_fmt_layout *layout)
574{
575 uint32_t base_addr;
576
577 if (!fb || !layout) {
578 DRM_ERROR("invalid pointers\n");
579 return -EINVAL;
580 }
581
582 base_addr = msm_framebuffer_iova(fb, mmu_id, 0);
583 if (!base_addr) {
584 DRM_ERROR("failed to retrieve base addr\n");
585 return -EFAULT;
586 }
587
588 /* Per-format logic for verifying active planes */
589 if (SDE_FORMAT_IS_YUV(layout->format)) {
590 /************************************************/
591 /* UBWC ** */
592 /* buffer ** SDE PLANE */
593 /* format ** */
594 /************************************************/
595 /* ------------------- ** -------------------- */
596 /* | Y meta | ** | Y bitstream | */
597 /* | data | ** | plane | */
598 /* ------------------- ** -------------------- */
599 /* | Y bitstream | ** | CbCr bitstream | */
600 /* | data | ** | plane | */
601 /* ------------------- ** -------------------- */
602 /* | Cbcr metadata | ** | Y meta | */
603 /* | data | ** | plane | */
604 /* ------------------- ** -------------------- */
605 /* | CbCr bitstream | ** | CbCr meta | */
606 /* | data | ** | plane | */
607 /* ------------------- ** -------------------- */
608 /************************************************/
609
610 /* configure Y bitstream plane */
611 layout->plane_addr[0] = base_addr + layout->plane_size[2];
612
613 /* configure CbCr bitstream plane */
614 layout->plane_addr[1] = base_addr + layout->plane_size[0]
615 + layout->plane_size[2] + layout->plane_size[3];
616
617 /* configure Y metadata plane */
618 layout->plane_addr[2] = base_addr;
619
620 /* configure CbCr metadata plane */
621 layout->plane_addr[3] = base_addr + layout->plane_size[0]
622 + layout->plane_size[2];
623
624 } else {
625 /************************************************/
626 /* UBWC ** */
627 /* buffer ** SDE PLANE */
628 /* format ** */
629 /************************************************/
630 /* ------------------- ** -------------------- */
631 /* | RGB meta | ** | RGB bitstream | */
632 /* | data | ** | plane | */
633 /* ------------------- ** -------------------- */
634 /* | RGB bitstream | ** | NONE | */
635 /* | data | ** | | */
636 /* ------------------- ** -------------------- */
637 /* ** | RGB meta | */
638 /* ** | plane | */
639 /* ** -------------------- */
640 /************************************************/
641
642 layout->plane_addr[0] = base_addr + layout->plane_size[2];
643 layout->plane_addr[1] = 0;
644 layout->plane_addr[2] = base_addr;
645 layout->plane_addr[3] = 0;
646 }
647
648 return 0;
649}
650
651static int _sde_format_populate_addrs_linear(
652 int mmu_id,
653 struct drm_framebuffer *fb,
654 struct sde_hw_fmt_layout *layout)
655{
656 unsigned int i;
657
658 /* Can now check the pitches given vs pitches expected */
659 for (i = 0; i < layout->num_planes; ++i) {
660 if (layout->plane_pitch[i] != fb->pitches[i]) {
661 DRM_ERROR("plane %u expected pitch %u, fb %u\n",
662 i, layout->plane_pitch[i], fb->pitches[i]);
663 return -EINVAL;
664 }
665 }
666
667 /* Populate addresses for simple formats here */
668 for (i = 0; i < layout->num_planes; ++i) {
669 layout->plane_addr[i] = msm_framebuffer_iova(fb, mmu_id, i);
670 if (!layout->plane_addr[i]) {
671 DRM_ERROR("failed to retrieve base addr\n");
672 return -EFAULT;
673 }
674 }
675
676 return 0;
677}
678
679int sde_format_populate_layout(
680 int mmu_id,
681 struct drm_framebuffer *fb,
682 struct sde_hw_fmt_layout *layout)
683{
Clarence Ipb6eb2362016-09-08 16:18:13 -0400684 uint32_t plane_addr[SDE_MAX_PLANES];
685 int i, ret;
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400686
687 if (!fb || !layout) {
688 DRM_ERROR("invalid arguments\n");
689 return -EINVAL;
690 }
691
692 if ((fb->width > SDE_MAX_IMG_WIDTH) ||
693 (fb->height > SDE_MAX_IMG_HEIGHT)) {
694 DRM_ERROR("image dimensions outside max range\n");
695 return -ERANGE;
696 }
697
698 layout->format = to_sde_format(msm_framebuffer_format(fb));
699
700 /* Populate the plane sizes etc via get_format */
701 ret = _sde_format_get_plane_sizes(layout->format, fb->width, fb->height,
702 layout);
703 if (ret)
704 return ret;
705
Clarence Ipb6eb2362016-09-08 16:18:13 -0400706 for (i = 0; i < SDE_MAX_PLANES; ++i)
707 plane_addr[i] = layout->plane_addr[i];
708
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400709 /* Populate the addresses given the fb */
710 if (SDE_FORMAT_IS_UBWC(layout->format))
711 ret = _sde_format_populate_addrs_ubwc(mmu_id, fb, layout);
712 else
713 ret = _sde_format_populate_addrs_linear(mmu_id, fb, layout);
714
Clarence Ipb6eb2362016-09-08 16:18:13 -0400715 /* check if anything changed */
716 if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
717 ret = -EAGAIN;
718
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400719 return ret;
720}
721
Alan Kwongbb27c092016-07-20 16:41:25 -0400722static void _sde_format_calc_offset_linear(struct sde_hw_fmt_layout *source,
723 u32 x, u32 y)
724{
725 if ((x == 0) && (y == 0))
726 return;
727
728 source->plane_addr[0] += y * source->plane_pitch[0];
729
730 if (source->num_planes == 1) {
731 source->plane_addr[0] += x * source->format->bpp;
732 } else {
733 uint32_t xoff, yoff;
734 uint32_t v_subsample = 1;
735 uint32_t h_subsample = 1;
736
737 _sde_get_v_h_subsample_rate(source->format->chroma_sample,
738 &v_subsample, &h_subsample);
739
740 xoff = x / h_subsample;
741 yoff = y / v_subsample;
742
743 source->plane_addr[0] += x;
744 source->plane_addr[1] += xoff +
745 (yoff * source->plane_pitch[1]);
746 if (source->num_planes == 2) /* pseudo planar */
747 source->plane_addr[1] += xoff;
748 else /* planar */
749 source->plane_addr[2] += xoff +
750 (yoff * source->plane_pitch[2]);
751 }
752}
753
754int sde_format_populate_layout_with_roi(
755 int mmu_id,
756 struct drm_framebuffer *fb,
757 struct sde_rect *roi,
758 struct sde_hw_fmt_layout *layout)
759{
760 int ret;
761
762 ret = sde_format_populate_layout(mmu_id, fb, layout);
763 if (ret || !roi)
764 return ret;
765
766 if (!roi->w || !roi->h || (roi->x + roi->w > fb->width) ||
767 (roi->y + roi->h > fb->height)) {
768 DRM_ERROR("invalid roi=[%d,%d,%d,%d], fb=[%u,%u]\n",
769 roi->x, roi->y, roi->w, roi->h,
770 fb->width, fb->height);
771 ret = -EINVAL;
772 } else if (SDE_FORMAT_IS_LINEAR(layout->format)) {
773 _sde_format_calc_offset_linear(layout, roi->x, roi->y);
774 layout->width = roi->w;
775 layout->height = roi->h;
776 } else if (roi->x || roi->y || (roi->w != fb->width) ||
777 (roi->h != fb->height)) {
778 DRM_ERROR("non-linear layout with roi not supported\n");
779 ret = -EINVAL;
780 }
781
782 return ret;
783}
784
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400785int sde_format_check_modified_format(
786 const struct msm_kms *kms,
787 const struct msm_format *msm_fmt,
788 const struct drm_mode_fb_cmd2 *cmd,
789 struct drm_gem_object **bos)
790{
791 int ret, i, num_base_fmt_planes;
792 const struct sde_format *fmt;
793 struct sde_hw_fmt_layout layout;
794 uint32_t bos_total_size = 0;
795
796 if (!msm_fmt || !cmd || !bos) {
797 DRM_ERROR("invalid arguments\n");
798 return -EINVAL;
799 }
800
801 fmt = to_sde_format(msm_fmt);
802 num_base_fmt_planes = drm_format_num_planes(fmt->base.pixel_format);
803
804 ret = _sde_format_get_plane_sizes(fmt, cmd->width, cmd->height,
805 &layout);
806 if (ret)
807 return ret;
808
809 for (i = 0; i < num_base_fmt_planes; i++) {
810 if (!bos[i]) {
811 DRM_ERROR("invalid handle for plane %d\n", i);
812 return -EINVAL;
813 }
814 bos_total_size += bos[i]->size;
815 }
816
817 if (bos_total_size < layout.total_size) {
818 DRM_ERROR("buffers total size too small %u expected %u\n",
819 bos_total_size, layout.total_size);
820 return -EINVAL;
821 }
822
823 return 0;
824}
825
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400826const struct sde_format *sde_get_sde_format_ext(
827 const uint32_t format,
828 const uint64_t *modifiers,
829 const uint32_t modifiers_len)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400830{
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400831 uint32_t i = 0;
832 uint64_t mod0 = 0;
833 const struct sde_format *fmt = NULL;
834 const struct sde_format *map = NULL;
835 ssize_t map_size = 0;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400836
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400837 /*
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400838 * Currently only support exactly zero or one modifier.
839 * All planes used must specify the same modifier.
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400840 */
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400841 if (modifiers_len && !modifiers) {
842 DRM_ERROR("invalid modifiers array\n");
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400843 return NULL;
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400844 } else if (modifiers && modifiers_len && modifiers[0]) {
845 mod0 = modifiers[0];
846 DBG("plane format modifier 0x%llX", mod0);
847 for (i = 1; i < modifiers_len; i++) {
848 if (modifiers[i] != mod0) {
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400849 DRM_ERROR("bad fmt mod 0x%llX on plane %d\n",
850 modifiers[i], i);
851 return NULL;
852 }
853 }
854 }
855
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400856 switch (mod0) {
857 case 0:
858 map = sde_format_map;
859 map_size = ARRAY_SIZE(sde_format_map);
860 break;
861 case DRM_FORMAT_MOD_QCOM_COMPRESSED:
862 map = sde_format_map_ubwc;
863 map_size = ARRAY_SIZE(sde_format_map_ubwc);
864 DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_COMPRESSED", format);
865 break;
866 default:
867 DRM_ERROR("unsupported format modifier %llX\n", mod0);
868 return NULL;
869 }
870
871 for (i = 0; i < map_size; i++) {
872 if (format == map[i].base.pixel_format) {
873 fmt = &map[i];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400874 break;
875 }
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400876 }
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400877
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400878 if (fmt == NULL)
879 DRM_ERROR("unsupported fmt 0x%X modifier 0x%llX\n",
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400880 format, mod0);
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400881 else
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400882 DBG("fmt %s mod 0x%llX ubwc %d yuv %d",
883 drm_get_format_name(format), mod0,
884 SDE_FORMAT_IS_UBWC(fmt),
885 SDE_FORMAT_IS_YUV(fmt));
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400886
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400887 return fmt;
888}
889
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400890const struct msm_format *sde_get_msm_format(
891 struct msm_kms *kms,
892 const uint32_t format,
893 const uint64_t *modifiers,
894 const uint32_t modifiers_len)
895{
896 const struct sde_format *fmt = sde_get_sde_format_ext(format,
897 modifiers, modifiers_len);
898 if (fmt)
899 return &fmt->base;
900 return NULL;
901}
902
Clarence Ipea3d6262016-07-15 16:20:11 -0400903uint32_t sde_populate_formats(
904 const struct sde_format_extended *format_list,
905 uint32_t *pixel_formats,
906 uint64_t *pixel_modifiers,
907 uint32_t pixel_formats_max)
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400908{
Clarence Ipea3d6262016-07-15 16:20:11 -0400909 uint32_t i, fourcc_format;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400910
Clarence Ipea3d6262016-07-15 16:20:11 -0400911 if (!format_list || !pixel_formats)
912 return 0;
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400913
Clarence Ipea3d6262016-07-15 16:20:11 -0400914 for (i = 0, fourcc_format = 0;
915 format_list->fourcc_format && i < pixel_formats_max;
916 ++format_list) {
917 /* verify if listed format is in sde_format_map? */
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400918
Clarence Ipea3d6262016-07-15 16:20:11 -0400919 /* optionally return modified formats */
920 if (pixel_modifiers) {
921 /* assume same modifier for all fb planes */
922 pixel_formats[i] = format_list->fourcc_format;
923 pixel_modifiers[i++] = format_list->modifier;
924 } else {
925 /* assume base formats grouped together */
926 if (fourcc_format != format_list->fourcc_format) {
927 fourcc_format = format_list->fourcc_format;
928 pixel_formats[i++] = fourcc_format;
929 }
930 }
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400931 }
932
933 return i;
934}