blob: 39a239e01f0d4a582a7806d2c7e0a87c3d99d3b1 [file] [log] [blame]
abeykunadfec292016-08-26 10:48:09 -04001/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04002 *
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>
abeykunadfec292016-08-26 10:48:09 -040014#include <uapi/media/msm_media_info.h>
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -040015
Clarence Ipc475b082016-06-26 09:27:23 -040016#include "sde_kms.h"
17#include "sde_formats.h"
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -040018
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -040019#define SDE_UBWC_META_MACRO_W_H 16
20#define SDE_UBWC_META_BLOCK_SIZE 256
abeykunadfec292016-08-26 10:48:09 -040021#define SDE_UBWC_PLANE_SIZE_ALIGNMENT 4096
22
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -040023#define SDE_MAX_IMG_WIDTH 0x3FFF
24#define SDE_MAX_IMG_HEIGHT 0x3FFF
25
26/**
27 * SDE supported format packing, bpp, and other format
28 * information.
29 * SDE 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, \
35bp, flg, fm, np) \
36{ \
37 .base.pixel_format = DRM_FORMAT_ ## fmt, \
38 .fetch_planes = SDE_PLANE_INTERLEAVED, \
39 .alpha_enable = alpha, \
40 .element = { (e0), (e1), (e2), (e3) }, \
41 .bits = { g, b, r, a }, \
42 .chroma_sample = SDE_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}
51
52#define INTERLEAVED_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, e3, \
53alpha, chroma, count, bp, flg, fm, np) \
54{ \
55 .base.pixel_format = DRM_FORMAT_ ## fmt, \
56 .fetch_planes = SDE_PLANE_INTERLEAVED, \
57 .alpha_enable = alpha, \
58 .element = { (e0), (e1), (e2), (e3)}, \
59 .bits = { g, b, r, a }, \
60 .chroma_sample = chroma, \
61 .unpack_align_msb = 0, \
62 .unpack_tight = 1, \
63 .unpack_count = count, \
64 .bpp = bp, \
65 .fetch_mode = fm, \
66 .flag = flg, \
67 .num_planes = np \
68}
69
abeykun5ed42e12016-08-24 17:09:26 -040070#define PSEUDO_YUV_FMT(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np) \
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -040071{ \
72 .base.pixel_format = DRM_FORMAT_ ## fmt, \
73 .fetch_planes = SDE_PLANE_PSEUDO_PLANAR, \
74 .alpha_enable = false, \
75 .element = { (e0), (e1), 0, 0 }, \
76 .bits = { g, b, r, a }, \
77 .chroma_sample = chroma, \
78 .unpack_align_msb = 0, \
79 .unpack_tight = 1, \
80 .unpack_count = 2, \
81 .bpp = 2, \
82 .fetch_mode = fm, \
83 .flag = flg, \
84 .num_planes = np \
85}
86
abeykunadfec292016-08-26 10:48:09 -040087#define PSEUDO_YUV_FMT_LOOSE(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np)\
88{ \
89 .base.pixel_format = DRM_FORMAT_ ## fmt, \
90 .fetch_planes = SDE_PLANE_PSEUDO_PLANAR, \
91 .alpha_enable = false, \
92 .element = { (e0), (e1), 0, 0 }, \
93 .bits = { g, b, r, a }, \
94 .chroma_sample = chroma, \
95 .unpack_align_msb = 1, \
96 .unpack_tight = 0, \
97 .unpack_count = 2, \
98 .bpp = 2, \
99 .fetch_mode = fm, \
100 .flag = flg, \
101 .num_planes = np \
102}
103
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400104#define PLANAR_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, alpha, chroma, bp, \
105flg, fm, np) \
106{ \
107 .base.pixel_format = DRM_FORMAT_ ## fmt, \
108 .fetch_planes = SDE_PLANE_PLANAR, \
109 .alpha_enable = alpha, \
110 .element = { (e0), (e1), (e2), 0 }, \
111 .bits = { g, b, r, a }, \
112 .chroma_sample = chroma, \
113 .unpack_align_msb = 0, \
114 .unpack_tight = 1, \
115 .unpack_count = 1, \
116 .bpp = bp, \
117 .fetch_mode = fm, \
118 .flag = flg, \
119 .num_planes = np \
120}
121
abeykunadfec292016-08-26 10:48:09 -0400122/*
123 * struct sde_media_color_map - maps drm format to media format
124 * @format: DRM base pixel format
125 * @color: Media API color related to DRM format
126 */
127struct sde_media_color_map {
128 uint32_t format;
129 uint32_t color;
130};
131
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400132static const struct sde_format sde_format_map[] = {
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400133 INTERLEAVED_RGB_FMT(ARGB8888,
134 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700135 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400136 true, 4, 0,
137 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400138
139 INTERLEAVED_RGB_FMT(ABGR8888,
140 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700141 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400142 true, 4, 0,
143 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400144
Narendra Muppalla88ad7262016-10-31 18:14:21 -0700145 INTERLEAVED_RGB_FMT(XBGR8888,
146 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
147 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
148 true, 4, 0,
149 SDE_FETCH_LINEAR, 1),
150
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400151 INTERLEAVED_RGB_FMT(RGBA8888,
152 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700153 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400154 true, 4, 0,
155 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400156
157 INTERLEAVED_RGB_FMT(BGRA8888,
158 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700159 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400160 true, 4, 0,
161 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400162
Alan Kwong3232ca52016-07-29 02:27:47 -0400163 INTERLEAVED_RGB_FMT(BGRX8888,
164 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700165 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Alan Kwong3232ca52016-07-29 02:27:47 -0400166 false, 4, 0,
167 SDE_FETCH_LINEAR, 1),
168
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400169 INTERLEAVED_RGB_FMT(XRGB8888,
170 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700171 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400172 false, 4, 0,
173 SDE_FETCH_LINEAR, 1),
174
175 INTERLEAVED_RGB_FMT(RGBX8888,
176 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700177 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400178 false, 4, 0,
179 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400180
181 INTERLEAVED_RGB_FMT(RGB888,
182 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700183 C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400184 false, 3, 0,
185 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400186
187 INTERLEAVED_RGB_FMT(BGR888,
188 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700189 C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400190 false, 3, 0,
191 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400192
193 INTERLEAVED_RGB_FMT(RGB565,
194 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700195 C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400196 false, 2, 0,
197 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400198
199 INTERLEAVED_RGB_FMT(BGR565,
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400200 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700201 C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400202 false, 2, 0,
203 SDE_FETCH_LINEAR, 1),
204
205 INTERLEAVED_RGB_FMT(ARGB1555,
206 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700207 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400208 true, 2, 0,
209 SDE_FETCH_LINEAR, 1),
210
211 INTERLEAVED_RGB_FMT(ABGR1555,
212 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700213 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400214 true, 2, 0,
215 SDE_FETCH_LINEAR, 1),
216
217 INTERLEAVED_RGB_FMT(RGBA5551,
218 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700219 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400220 true, 2, 0,
221 SDE_FETCH_LINEAR, 1),
222
223 INTERLEAVED_RGB_FMT(BGRA5551,
224 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700225 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400226 true, 2, 0,
227 SDE_FETCH_LINEAR, 1),
228
229 INTERLEAVED_RGB_FMT(XRGB1555,
230 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700231 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400232 false, 2, 0,
233 SDE_FETCH_LINEAR, 1),
234
235 INTERLEAVED_RGB_FMT(XBGR1555,
236 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700237 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400238 false, 2, 0,
239 SDE_FETCH_LINEAR, 1),
240
241 INTERLEAVED_RGB_FMT(RGBX5551,
242 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700243 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400244 false, 2, 0,
245 SDE_FETCH_LINEAR, 1),
246
247 INTERLEAVED_RGB_FMT(BGRX5551,
248 COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700249 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400250 false, 2, 0,
251 SDE_FETCH_LINEAR, 1),
252
253 INTERLEAVED_RGB_FMT(ARGB4444,
254 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700255 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400256 true, 2, 0,
257 SDE_FETCH_LINEAR, 1),
258
259 INTERLEAVED_RGB_FMT(ABGR4444,
260 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700261 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400262 true, 2, 0,
263 SDE_FETCH_LINEAR, 1),
264
265 INTERLEAVED_RGB_FMT(RGBA4444,
266 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700267 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400268 true, 2, 0,
269 SDE_FETCH_LINEAR, 1),
270
271 INTERLEAVED_RGB_FMT(BGRA4444,
272 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700273 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400274 true, 2, 0,
275 SDE_FETCH_LINEAR, 1),
276
277 INTERLEAVED_RGB_FMT(XRGB4444,
278 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700279 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400280 false, 2, 0,
281 SDE_FETCH_LINEAR, 1),
282
283 INTERLEAVED_RGB_FMT(XBGR4444,
284 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700285 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400286 false, 2, 0,
287 SDE_FETCH_LINEAR, 1),
288
289 INTERLEAVED_RGB_FMT(RGBX4444,
290 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700291 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400292 false, 2, 0,
293 SDE_FETCH_LINEAR, 1),
294
295 INTERLEAVED_RGB_FMT(BGRX4444,
296 COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700297 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400298 false, 2, 0,
299 SDE_FETCH_LINEAR, 1),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400300
abeykun5ed42e12016-08-24 17:09:26 -0400301 INTERLEAVED_RGB_FMT(BGRA1010102,
302 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
303 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
304 true, 4, SDE_FORMAT_FLAG_DX,
305 SDE_FETCH_LINEAR, 1),
306
307 INTERLEAVED_RGB_FMT(RGBA1010102,
308 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
309 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
310 true, 4, SDE_FORMAT_FLAG_DX,
311 SDE_FETCH_LINEAR, 1),
312
313 INTERLEAVED_RGB_FMT(ABGR2101010,
314 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
315 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
316 true, 4, SDE_FORMAT_FLAG_DX,
317 SDE_FETCH_LINEAR, 1),
318
319 INTERLEAVED_RGB_FMT(ARGB2101010,
320 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
321 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
322 true, 4, SDE_FORMAT_FLAG_DX,
323 SDE_FETCH_LINEAR, 1),
324
325 INTERLEAVED_RGB_FMT(XRGB2101010,
326 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
327 C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
328 false, 4, SDE_FORMAT_FLAG_DX,
329 SDE_FETCH_LINEAR, 1),
330
331 INTERLEAVED_RGB_FMT(BGRX1010102,
332 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
333 C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
334 false, 4, SDE_FORMAT_FLAG_DX,
335 SDE_FETCH_LINEAR, 1),
336
337 INTERLEAVED_RGB_FMT(XBGR2101010,
338 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
339 C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
340 false, 4, SDE_FORMAT_FLAG_DX,
341 SDE_FETCH_LINEAR, 1),
342
343 INTERLEAVED_RGB_FMT(RGBX1010102,
344 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
345 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
346 false, 4, SDE_FORMAT_FLAG_DX,
347 SDE_FETCH_LINEAR, 1),
348
349 PSEUDO_YUV_FMT(NV12,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400350 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
351 C1_B_Cb, C2_R_Cr,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400352 SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
353 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400354
abeykun5ed42e12016-08-24 17:09:26 -0400355 PSEUDO_YUV_FMT(NV21,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400356 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
357 C2_R_Cr, C1_B_Cb,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400358 SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
359 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400360
abeykun5ed42e12016-08-24 17:09:26 -0400361 PSEUDO_YUV_FMT(NV16,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400362 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
363 C1_B_Cb, C2_R_Cr,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400364 SDE_CHROMA_H2V1, SDE_FORMAT_FLAG_YUV,
365 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400366
abeykun5ed42e12016-08-24 17:09:26 -0400367 PSEUDO_YUV_FMT(NV61,
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400368 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
369 C2_R_Cr, C1_B_Cb,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400370 SDE_CHROMA_H2V1, SDE_FORMAT_FLAG_YUV,
371 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400372
373 INTERLEAVED_YUV_FMT(VYUY,
374 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
375 C2_R_Cr, C0_G_Y, C1_B_Cb, C0_G_Y,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400376 false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
377 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400378
379 INTERLEAVED_YUV_FMT(UYVY,
380 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
381 C1_B_Cb, C0_G_Y, C2_R_Cr, C0_G_Y,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400382 false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
383 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400384
385 INTERLEAVED_YUV_FMT(YUYV,
386 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
387 C0_G_Y, C1_B_Cb, C0_G_Y, C2_R_Cr,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400388 false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
389 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400390
391 INTERLEAVED_YUV_FMT(YVYU,
392 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
393 C0_G_Y, C2_R_Cr, C0_G_Y, C1_B_Cb,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400394 false, SDE_CHROMA_H2V1, 4, 2, SDE_FORMAT_FLAG_YUV,
395 SDE_FETCH_LINEAR, 2),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400396
397 PLANAR_YUV_FMT(YUV420,
398 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700399 C0_G_Y, C1_B_Cb, C2_R_Cr,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400400 false, SDE_CHROMA_420, 1, SDE_FORMAT_FLAG_YUV,
401 SDE_FETCH_LINEAR, 3),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400402
403 PLANAR_YUV_FMT(YVU420,
404 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
Dhaval Patel17ec9152016-08-30 17:49:07 -0700405 C0_G_Y, C2_R_Cr, C1_B_Cb,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400406 false, SDE_CHROMA_420, 1, SDE_FORMAT_FLAG_YUV,
407 SDE_FETCH_LINEAR, 3),
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400408};
409
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400410/*
411 * UBWC formats table:
412 * This table holds the UBWC formats supported.
413 * If a compression ratio needs to be used for this or any other format,
414 * the data will be passed by user-space.
415 */
416static const struct sde_format sde_format_map_ubwc[] = {
Dhaval Patel17ec9152016-08-30 17:49:07 -0700417 INTERLEAVED_RGB_FMT(RGB565,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400418 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
419 C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
420 false, 2, 0,
421 SDE_FETCH_UBWC, 2),
422
Dhaval Patel17ec9152016-08-30 17:49:07 -0700423 INTERLEAVED_RGB_FMT(RGBA8888,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400424 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
425 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
426 true, 4, 0,
427 SDE_FETCH_UBWC, 2),
428
Dhaval Patel17ec9152016-08-30 17:49:07 -0700429 INTERLEAVED_RGB_FMT(RGBX8888,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400430 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
431 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
432 false, 4, 0,
433 SDE_FETCH_UBWC, 2),
434
abeykun5ed42e12016-08-24 17:09:26 -0400435 INTERLEAVED_RGB_FMT(RGBA1010102,
436 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
437 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
438 true, 4, SDE_FORMAT_FLAG_DX,
439 SDE_FETCH_UBWC, 2),
440
441 INTERLEAVED_RGB_FMT(RGBX1010102,
442 COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
443 C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
444 true, 4, SDE_FORMAT_FLAG_DX,
445 SDE_FETCH_UBWC, 2),
446
447 PSEUDO_YUV_FMT(NV12,
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400448 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
449 C1_B_Cb, C2_R_Cr,
450 SDE_CHROMA_420, SDE_FORMAT_FLAG_YUV,
451 SDE_FETCH_UBWC, 4),
452};
453
abeykunadfec292016-08-26 10:48:09 -0400454static const struct sde_format sde_format_map_p010[] = {
455 PSEUDO_YUV_FMT_LOOSE(NV12,
456 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
457 C1_B_Cb, C2_R_Cr,
458 SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
459 SDE_FETCH_LINEAR, 2),
460};
461
462static const struct sde_format sde_format_map_p010_ubwc[] = {
463 PSEUDO_YUV_FMT_LOOSE(NV12,
464 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
465 C1_B_Cb, C2_R_Cr,
466 SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
467 SDE_FETCH_UBWC, 4),
468};
469
abeykun1d4ff032016-08-26 11:31:44 -0400470static const struct sde_format sde_format_map_tp10_ubwc[] = {
471 PSEUDO_YUV_FMT(NV12,
472 0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
473 C1_B_Cb, C2_R_Cr,
474 SDE_CHROMA_420, (SDE_FORMAT_FLAG_YUV | SDE_FORMAT_FLAG_DX),
475 SDE_FETCH_UBWC, 4),
476};
477
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400478/* _sde_get_v_h_subsample_rate - Get subsample rates for all formats we support
479 * Note: Not using the drm_format_*_subsampling since we have formats
480 */
481static void _sde_get_v_h_subsample_rate(
482 enum sde_chroma_samp_type chroma_sample,
483 uint32_t *v_sample,
484 uint32_t *h_sample)
485{
Alan Kwongbb27c092016-07-20 16:41:25 -0400486 if (!v_sample || !h_sample)
487 return;
488
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400489 switch (chroma_sample) {
490 case SDE_CHROMA_H2V1:
491 *v_sample = 1;
492 *h_sample = 2;
493 break;
494 case SDE_CHROMA_H1V2:
495 *v_sample = 2;
496 *h_sample = 1;
497 break;
498 case SDE_CHROMA_420:
499 *v_sample = 2;
500 *h_sample = 2;
501 break;
502 default:
503 *v_sample = 1;
504 *h_sample = 1;
505 break;
506 }
507}
508
abeykunadfec292016-08-26 10:48:09 -0400509static int _sde_format_get_media_color_ubwc(const struct sde_format *fmt)
510{
511 static const struct sde_media_color_map sde_media_ubwc_map[] = {
512 {DRM_FORMAT_RGBA8888, COLOR_FMT_RGBA8888_UBWC},
513 {DRM_FORMAT_RGBX8888, COLOR_FMT_RGBA8888_UBWC},
514 {DRM_FORMAT_RGBA1010102, COLOR_FMT_RGBA1010102_UBWC},
515 {DRM_FORMAT_RGBX1010102, COLOR_FMT_RGBA1010102_UBWC},
516 {DRM_FORMAT_RGB565, COLOR_FMT_RGB565_UBWC},
517 };
518 int color_fmt = -1;
519 int i;
520
521 if (fmt->base.pixel_format == DRM_FORMAT_NV12) {
522 if (SDE_FORMAT_IS_DX(fmt)) {
523 if (fmt->unpack_tight)
524 color_fmt = COLOR_FMT_NV12_BPP10_UBWC;
525 else
526 color_fmt = COLOR_FMT_P010_UBWC;
527 } else
528 color_fmt = COLOR_FMT_NV12_UBWC;
529 return color_fmt;
530 }
531
532 for (i = 0; i < ARRAY_SIZE(sde_media_ubwc_map); ++i)
533 if (fmt->base.pixel_format == sde_media_ubwc_map[i].format) {
534 color_fmt = sde_media_ubwc_map[i].color;
535 break;
536 }
537 return color_fmt;
538}
539
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400540static int _sde_format_get_plane_sizes_ubwc(
541 const struct sde_format *fmt,
542 const uint32_t width,
543 const uint32_t height,
544 struct sde_hw_fmt_layout *layout)
545{
546 int i;
abeykunadfec292016-08-26 10:48:09 -0400547 int color;
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400548
549 memset(layout, 0, sizeof(struct sde_hw_fmt_layout));
550 layout->format = fmt;
551 layout->width = width;
552 layout->height = height;
553 layout->num_planes = fmt->num_planes;
554
abeykunadfec292016-08-26 10:48:09 -0400555 color = _sde_format_get_media_color_ubwc(fmt);
556 if (color < 0) {
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400557 DRM_ERROR("UBWC format not supported for fmt:0x%X\n",
558 fmt->base.pixel_format);
559 return -EINVAL;
560 }
561
abeykunadfec292016-08-26 10:48:09 -0400562 if (SDE_FORMAT_IS_YUV(layout->format)) {
563 uint32_t y_sclines, uv_sclines;
564 uint32_t y_meta_scanlines = 0;
565 uint32_t uv_meta_scanlines = 0;
566
567 layout->num_planes = 4;
568 layout->plane_pitch[0] = VENUS_Y_STRIDE(color, width);
569 y_sclines = VENUS_Y_SCANLINES(color, height);
570 layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] *
571 y_sclines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
572
573 layout->plane_pitch[1] = VENUS_UV_STRIDE(color, width);
574 uv_sclines = VENUS_UV_SCANLINES(color, height);
575 layout->plane_size[1] = MSM_MEDIA_ALIGN(layout->plane_pitch[1] *
576 uv_sclines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
577
578 layout->plane_pitch[2] = VENUS_Y_META_STRIDE(color, width);
579 y_meta_scanlines = VENUS_Y_META_SCANLINES(color, height);
580 layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] *
581 y_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
582
583 layout->plane_pitch[3] = VENUS_UV_META_STRIDE(color, width);
584 uv_meta_scanlines = VENUS_UV_META_SCANLINES(color, height);
585 layout->plane_size[3] = MSM_MEDIA_ALIGN(layout->plane_pitch[3] *
586 uv_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
587
588 } else {
589 uint32_t rgb_scanlines, rgb_meta_scanlines;
590
591 layout->num_planes = 3;
592
593 layout->plane_pitch[0] = VENUS_RGB_STRIDE(color, width);
594 rgb_scanlines = VENUS_RGB_SCANLINES(color, height);
595 layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] *
596 rgb_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
597
598 layout->plane_pitch[2] = VENUS_RGB_META_STRIDE(color, width);
599 rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color, height);
600 layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] *
601 rgb_meta_scanlines, SDE_UBWC_PLANE_SIZE_ALIGNMENT);
602 }
603
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400604 for (i = 0; i < SDE_MAX_PLANES; i++)
605 layout->total_size += layout->plane_size[i];
606
607 return 0;
608}
609
610static int _sde_format_get_plane_sizes_linear(
611 const struct sde_format *fmt,
612 const uint32_t width,
613 const uint32_t height,
614 struct sde_hw_fmt_layout *layout)
615{
616 int i;
617
618 memset(layout, 0, sizeof(struct sde_hw_fmt_layout));
619 layout->format = fmt;
620 layout->width = width;
621 layout->height = height;
622 layout->num_planes = fmt->num_planes;
623
624 /* Due to memset above, only need to set planes of interest */
625 if (fmt->fetch_planes == SDE_PLANE_INTERLEAVED) {
626 layout->num_planes = 1;
627 layout->plane_size[0] = width * height * layout->format->bpp;
628 layout->plane_pitch[0] = width * layout->format->bpp;
629 } else {
630 uint32_t v_subsample, h_subsample;
631 uint32_t chroma_samp;
abeykunadfec292016-08-26 10:48:09 -0400632 uint32_t bpp = 1;
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400633
634 chroma_samp = fmt->chroma_sample;
635 _sde_get_v_h_subsample_rate(chroma_samp, &v_subsample,
636 &h_subsample);
637
638 if (width % h_subsample || height % v_subsample) {
639 DRM_ERROR("mismatch in subsample vs dimensions\n");
640 return -EINVAL;
641 }
642
abeykunadfec292016-08-26 10:48:09 -0400643 if ((fmt->base.pixel_format == DRM_FORMAT_NV12) &&
644 (SDE_FORMAT_IS_DX(fmt)))
645 bpp = 2;
646 layout->plane_pitch[0] = width * bpp;
647 layout->plane_pitch[1] = layout->plane_pitch[0] / h_subsample;
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400648 layout->plane_size[0] = layout->plane_pitch[0] * height;
649 layout->plane_size[1] = layout->plane_pitch[1] *
650 (height / v_subsample);
651
652 if (fmt->fetch_planes == SDE_PLANE_PSEUDO_PLANAR) {
653 layout->num_planes = 2;
654 layout->plane_size[1] *= 2;
655 layout->plane_pitch[1] *= 2;
656 } else {
657 /* planar */
658 layout->num_planes = 3;
659 layout->plane_size[2] = layout->plane_size[1];
660 layout->plane_pitch[2] = layout->plane_pitch[1];
661 }
662 }
663
664 for (i = 0; i < SDE_MAX_PLANES; i++)
665 layout->total_size += layout->plane_size[i];
666
667 return 0;
668}
669
670static int _sde_format_get_plane_sizes(
671 const struct sde_format *fmt,
672 const uint32_t w,
673 const uint32_t h,
674 struct sde_hw_fmt_layout *layout)
675{
676 if (!layout || !fmt) {
677 DRM_ERROR("invalid pointer\n");
678 return -EINVAL;
679 }
680
681 if ((w > SDE_MAX_IMG_WIDTH) || (h > SDE_MAX_IMG_HEIGHT)) {
682 DRM_ERROR("image dimensions outside max range\n");
683 return -ERANGE;
684 }
685
686 if (SDE_FORMAT_IS_UBWC(fmt))
687 return _sde_format_get_plane_sizes_ubwc(fmt, w, h, layout);
688
689 return _sde_format_get_plane_sizes_linear(fmt, w, h, layout);
690}
691
692static int _sde_format_populate_addrs_ubwc(
693 int mmu_id,
694 struct drm_framebuffer *fb,
695 struct sde_hw_fmt_layout *layout)
696{
697 uint32_t base_addr;
698
699 if (!fb || !layout) {
700 DRM_ERROR("invalid pointers\n");
701 return -EINVAL;
702 }
703
704 base_addr = msm_framebuffer_iova(fb, mmu_id, 0);
705 if (!base_addr) {
706 DRM_ERROR("failed to retrieve base addr\n");
707 return -EFAULT;
708 }
709
710 /* Per-format logic for verifying active planes */
711 if (SDE_FORMAT_IS_YUV(layout->format)) {
712 /************************************************/
713 /* UBWC ** */
714 /* buffer ** SDE PLANE */
715 /* format ** */
716 /************************************************/
717 /* ------------------- ** -------------------- */
718 /* | Y meta | ** | Y bitstream | */
719 /* | data | ** | plane | */
720 /* ------------------- ** -------------------- */
721 /* | Y bitstream | ** | CbCr bitstream | */
722 /* | data | ** | plane | */
723 /* ------------------- ** -------------------- */
724 /* | Cbcr metadata | ** | Y meta | */
725 /* | data | ** | plane | */
726 /* ------------------- ** -------------------- */
727 /* | CbCr bitstream | ** | CbCr meta | */
728 /* | data | ** | plane | */
729 /* ------------------- ** -------------------- */
730 /************************************************/
731
732 /* configure Y bitstream plane */
733 layout->plane_addr[0] = base_addr + layout->plane_size[2];
734
735 /* configure CbCr bitstream plane */
736 layout->plane_addr[1] = base_addr + layout->plane_size[0]
737 + layout->plane_size[2] + layout->plane_size[3];
738
739 /* configure Y metadata plane */
740 layout->plane_addr[2] = base_addr;
741
742 /* configure CbCr metadata plane */
743 layout->plane_addr[3] = base_addr + layout->plane_size[0]
744 + layout->plane_size[2];
745
746 } else {
747 /************************************************/
748 /* UBWC ** */
749 /* buffer ** SDE PLANE */
750 /* format ** */
751 /************************************************/
752 /* ------------------- ** -------------------- */
753 /* | RGB meta | ** | RGB bitstream | */
754 /* | data | ** | plane | */
755 /* ------------------- ** -------------------- */
756 /* | RGB bitstream | ** | NONE | */
757 /* | data | ** | | */
758 /* ------------------- ** -------------------- */
759 /* ** | RGB meta | */
760 /* ** | plane | */
761 /* ** -------------------- */
762 /************************************************/
763
764 layout->plane_addr[0] = base_addr + layout->plane_size[2];
765 layout->plane_addr[1] = 0;
766 layout->plane_addr[2] = base_addr;
767 layout->plane_addr[3] = 0;
768 }
769
770 return 0;
771}
772
773static int _sde_format_populate_addrs_linear(
774 int mmu_id,
775 struct drm_framebuffer *fb,
776 struct sde_hw_fmt_layout *layout)
777{
778 unsigned int i;
779
780 /* Can now check the pitches given vs pitches expected */
781 for (i = 0; i < layout->num_planes; ++i) {
782 if (layout->plane_pitch[i] != fb->pitches[i]) {
783 DRM_ERROR("plane %u expected pitch %u, fb %u\n",
784 i, layout->plane_pitch[i], fb->pitches[i]);
785 return -EINVAL;
786 }
787 }
788
789 /* Populate addresses for simple formats here */
790 for (i = 0; i < layout->num_planes; ++i) {
791 layout->plane_addr[i] = msm_framebuffer_iova(fb, mmu_id, i);
792 if (!layout->plane_addr[i]) {
793 DRM_ERROR("failed to retrieve base addr\n");
794 return -EFAULT;
795 }
796 }
797
798 return 0;
799}
800
801int sde_format_populate_layout(
802 int mmu_id,
803 struct drm_framebuffer *fb,
804 struct sde_hw_fmt_layout *layout)
805{
Clarence Ipb6eb2362016-09-08 16:18:13 -0400806 uint32_t plane_addr[SDE_MAX_PLANES];
807 int i, ret;
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400808
809 if (!fb || !layout) {
810 DRM_ERROR("invalid arguments\n");
811 return -EINVAL;
812 }
813
814 if ((fb->width > SDE_MAX_IMG_WIDTH) ||
815 (fb->height > SDE_MAX_IMG_HEIGHT)) {
816 DRM_ERROR("image dimensions outside max range\n");
817 return -ERANGE;
818 }
819
820 layout->format = to_sde_format(msm_framebuffer_format(fb));
821
822 /* Populate the plane sizes etc via get_format */
823 ret = _sde_format_get_plane_sizes(layout->format, fb->width, fb->height,
824 layout);
825 if (ret)
826 return ret;
827
Clarence Ipb6eb2362016-09-08 16:18:13 -0400828 for (i = 0; i < SDE_MAX_PLANES; ++i)
829 plane_addr[i] = layout->plane_addr[i];
830
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400831 /* Populate the addresses given the fb */
832 if (SDE_FORMAT_IS_UBWC(layout->format))
833 ret = _sde_format_populate_addrs_ubwc(mmu_id, fb, layout);
834 else
835 ret = _sde_format_populate_addrs_linear(mmu_id, fb, layout);
836
Clarence Ipb6eb2362016-09-08 16:18:13 -0400837 /* check if anything changed */
838 if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
839 ret = -EAGAIN;
840
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400841 return ret;
842}
843
Alan Kwongbb27c092016-07-20 16:41:25 -0400844static void _sde_format_calc_offset_linear(struct sde_hw_fmt_layout *source,
845 u32 x, u32 y)
846{
847 if ((x == 0) && (y == 0))
848 return;
849
850 source->plane_addr[0] += y * source->plane_pitch[0];
851
852 if (source->num_planes == 1) {
853 source->plane_addr[0] += x * source->format->bpp;
854 } else {
855 uint32_t xoff, yoff;
856 uint32_t v_subsample = 1;
857 uint32_t h_subsample = 1;
858
859 _sde_get_v_h_subsample_rate(source->format->chroma_sample,
860 &v_subsample, &h_subsample);
861
862 xoff = x / h_subsample;
863 yoff = y / v_subsample;
864
865 source->plane_addr[0] += x;
866 source->plane_addr[1] += xoff +
867 (yoff * source->plane_pitch[1]);
868 if (source->num_planes == 2) /* pseudo planar */
869 source->plane_addr[1] += xoff;
870 else /* planar */
871 source->plane_addr[2] += xoff +
872 (yoff * source->plane_pitch[2]);
873 }
874}
875
876int sde_format_populate_layout_with_roi(
877 int mmu_id,
878 struct drm_framebuffer *fb,
879 struct sde_rect *roi,
880 struct sde_hw_fmt_layout *layout)
881{
882 int ret;
883
884 ret = sde_format_populate_layout(mmu_id, fb, layout);
885 if (ret || !roi)
886 return ret;
887
888 if (!roi->w || !roi->h || (roi->x + roi->w > fb->width) ||
889 (roi->y + roi->h > fb->height)) {
890 DRM_ERROR("invalid roi=[%d,%d,%d,%d], fb=[%u,%u]\n",
891 roi->x, roi->y, roi->w, roi->h,
892 fb->width, fb->height);
893 ret = -EINVAL;
894 } else if (SDE_FORMAT_IS_LINEAR(layout->format)) {
895 _sde_format_calc_offset_linear(layout, roi->x, roi->y);
896 layout->width = roi->w;
897 layout->height = roi->h;
898 } else if (roi->x || roi->y || (roi->w != fb->width) ||
899 (roi->h != fb->height)) {
900 DRM_ERROR("non-linear layout with roi not supported\n");
901 ret = -EINVAL;
902 }
903
904 return ret;
905}
906
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400907int sde_format_check_modified_format(
908 const struct msm_kms *kms,
909 const struct msm_format *msm_fmt,
910 const struct drm_mode_fb_cmd2 *cmd,
911 struct drm_gem_object **bos)
912{
913 int ret, i, num_base_fmt_planes;
914 const struct sde_format *fmt;
915 struct sde_hw_fmt_layout layout;
916 uint32_t bos_total_size = 0;
917
918 if (!msm_fmt || !cmd || !bos) {
919 DRM_ERROR("invalid arguments\n");
920 return -EINVAL;
921 }
922
923 fmt = to_sde_format(msm_fmt);
924 num_base_fmt_planes = drm_format_num_planes(fmt->base.pixel_format);
925
926 ret = _sde_format_get_plane_sizes(fmt, cmd->width, cmd->height,
927 &layout);
928 if (ret)
929 return ret;
930
931 for (i = 0; i < num_base_fmt_planes; i++) {
932 if (!bos[i]) {
933 DRM_ERROR("invalid handle for plane %d\n", i);
934 return -EINVAL;
935 }
936 bos_total_size += bos[i]->size;
937 }
938
939 if (bos_total_size < layout.total_size) {
940 DRM_ERROR("buffers total size too small %u expected %u\n",
941 bos_total_size, layout.total_size);
942 return -EINVAL;
943 }
944
945 return 0;
946}
947
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400948const struct sde_format *sde_get_sde_format_ext(
949 const uint32_t format,
950 const uint64_t *modifiers,
951 const uint32_t modifiers_len)
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400952{
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400953 uint32_t i = 0;
954 uint64_t mod0 = 0;
955 const struct sde_format *fmt = NULL;
956 const struct sde_format *map = NULL;
957 ssize_t map_size = 0;
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -0400958
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400959 /*
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400960 * Currently only support exactly zero or one modifier.
961 * All planes used must specify the same modifier.
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400962 */
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400963 if (modifiers_len && !modifiers) {
964 DRM_ERROR("invalid modifiers array\n");
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400965 return NULL;
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400966 } else if (modifiers && modifiers_len && modifiers[0]) {
967 mod0 = modifiers[0];
968 DBG("plane format modifier 0x%llX", mod0);
969 for (i = 1; i < modifiers_len; i++) {
970 if (modifiers[i] != mod0) {
Lloyd Atkinson9a673492016-07-05 11:41:57 -0400971 DRM_ERROR("bad fmt mod 0x%llX on plane %d\n",
972 modifiers[i], i);
973 return NULL;
974 }
975 }
976 }
977
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -0400978 switch (mod0) {
979 case 0:
980 map = sde_format_map;
981 map_size = ARRAY_SIZE(sde_format_map);
982 break;
983 case DRM_FORMAT_MOD_QCOM_COMPRESSED:
984 map = sde_format_map_ubwc;
985 map_size = ARRAY_SIZE(sde_format_map_ubwc);
986 DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_COMPRESSED", format);
987 break;
abeykunadfec292016-08-26 10:48:09 -0400988 case DRM_FORMAT_MOD_QCOM_DX:
989 map = sde_format_map_p010;
990 map_size = ARRAY_SIZE(sde_format_map_p010);
991 DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_DX", format);
992 break;
993 case (DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_COMPRESSED):
994 map = sde_format_map_p010_ubwc;
995 map_size = ARRAY_SIZE(sde_format_map_p010_ubwc);
996 DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_COMPRESSED/DX", format);
997 break;
abeykun1d4ff032016-08-26 11:31:44 -0400998 case (DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_COMPRESSED |
999 DRM_FORMAT_MOD_QCOM_TIGHT):
1000 map = sde_format_map_tp10_ubwc;
1001 map_size = ARRAY_SIZE(sde_format_map_tp10_ubwc);
1002 DBG("found fmt 0x%X DRM_FORMAT_MOD_QCOM_COMPRESSED/DX/TIGHT",
1003 format);
1004 break;
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -04001005 default:
1006 DRM_ERROR("unsupported format modifier %llX\n", mod0);
1007 return NULL;
1008 }
1009
1010 for (i = 0; i < map_size; i++) {
1011 if (format == map[i].base.pixel_format) {
1012 fmt = &map[i];
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04001013 break;
1014 }
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -04001015 }
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04001016
Lloyd Atkinson9a673492016-07-05 11:41:57 -04001017 if (fmt == NULL)
1018 DRM_ERROR("unsupported fmt 0x%X modifier 0x%llX\n",
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -04001019 format, mod0);
Lloyd Atkinson9a673492016-07-05 11:41:57 -04001020 else
Lloyd Atkinsonfa2489c2016-05-25 15:16:03 -04001021 DBG("fmt %s mod 0x%llX ubwc %d yuv %d",
1022 drm_get_format_name(format), mod0,
1023 SDE_FORMAT_IS_UBWC(fmt),
1024 SDE_FORMAT_IS_YUV(fmt));
Lloyd Atkinson9a673492016-07-05 11:41:57 -04001025
Abhijit Kulkarni3e3e0d22016-06-24 17:56:13 -04001026 return fmt;
1027}
1028
Lloyd Atkinson9a673492016-07-05 11:41:57 -04001029const struct msm_format *sde_get_msm_format(
1030 struct msm_kms *kms,
1031 const uint32_t format,
1032 const uint64_t *modifiers,
1033 const uint32_t modifiers_len)
1034{
1035 const struct sde_format *fmt = sde_get_sde_format_ext(format,
1036 modifiers, modifiers_len);
1037 if (fmt)
1038 return &fmt->base;
1039 return NULL;
1040}
1041
Clarence Ipea3d6262016-07-15 16:20:11 -04001042uint32_t sde_populate_formats(
1043 const struct sde_format_extended *format_list,
1044 uint32_t *pixel_formats,
1045 uint64_t *pixel_modifiers,
1046 uint32_t pixel_formats_max)
Lloyd Atkinson9a673492016-07-05 11:41:57 -04001047{
Clarence Ipea3d6262016-07-15 16:20:11 -04001048 uint32_t i, fourcc_format;
Lloyd Atkinson9a673492016-07-05 11:41:57 -04001049
Clarence Ipea3d6262016-07-15 16:20:11 -04001050 if (!format_list || !pixel_formats)
1051 return 0;
Lloyd Atkinson9a673492016-07-05 11:41:57 -04001052
Clarence Ipea3d6262016-07-15 16:20:11 -04001053 for (i = 0, fourcc_format = 0;
1054 format_list->fourcc_format && i < pixel_formats_max;
1055 ++format_list) {
1056 /* verify if listed format is in sde_format_map? */
Lloyd Atkinson9a673492016-07-05 11:41:57 -04001057
Clarence Ipea3d6262016-07-15 16:20:11 -04001058 /* optionally return modified formats */
1059 if (pixel_modifiers) {
1060 /* assume same modifier for all fb planes */
1061 pixel_formats[i] = format_list->fourcc_format;
1062 pixel_modifiers[i++] = format_list->modifier;
1063 } else {
1064 /* assume base formats grouped together */
1065 if (fourcc_format != format_list->fourcc_format) {
1066 fourcc_format = format_list->fourcc_format;
1067 pixel_formats[i++] = fourcc_format;
1068 }
1069 }
Lloyd Atkinson9a673492016-07-05 11:41:57 -04001070 }
1071
1072 return i;
1073}