1#ifndef __MEDIA_INFO_H__
2#define __MEDIA_INFO_H__
3
4#ifndef MSM_MEDIA_ALIGN
5#define MSM_MEDIA_ALIGN(__sz, __align) (((__sz) + (__align-1)) & (~(__align-1)))
6#endif
7
8enum color_fmts {
9	/* Venus NV12:
10	 * YUV 4:2:0 image with a plane of 8 bit Y samples followed
11	 * by an interleaved U/V plane containing 8 bit 2x2 subsampled
12	 * colour difference samples.
13	 *
14	 * <-------- Y/UV_Stride -------->
15	 * <------- Width ------->
16	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  ^           ^
17	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |
18	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  Height      |
19	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |          Y_Scanlines
20	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |
21	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |
22	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |
23	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  V           |
24	 * X X X X X X X X X X X X X X X X              |
25	 * X X X X X X X X X X X X X X X X              |
26	 * X X X X X X X X X X X X X X X X              |
27	 * X X X X X X X X X X X X X X X X              V
28	 * U V U V U V U V U V U V X X X X  ^
29	 * U V U V U V U V U V U V X X X X  |
30	 * U V U V U V U V U V U V X X X X  |
31	 * U V U V U V U V U V U V X X X X  UV_Scanlines
32	 * X X X X X X X X X X X X X X X X  |
33	 * X X X X X X X X X X X X X X X X  V
34	 * X X X X X X X X X X X X X X X X  --> Buffer size alignment
35	 *
36	 * Y_Stride : Width aligned to 128
37	 * UV_Stride : Width aligned to 128
38	 * Y_Scanlines: Height aligned to 32
39	 * UV_Scanlines: Height/2 aligned to 16
40	 * Total size = align((Y_Stride * Y_Scanlines
41	 *          + UV_Stride * UV_Scanlines + 4096), 4096)
42	 */
43	COLOR_FMT_NV12,
44
45	/* Venus NV21:
46	 * YUV 4:2:0 image with a plane of 8 bit Y samples followed
47	 * by an interleaved V/U plane containing 8 bit 2x2 subsampled
48	 * colour difference samples.
49	 *
50	 * <-------- Y/UV_Stride -------->
51	 * <------- Width ------->
52	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  ^           ^
53	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |
54	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  Height      |
55	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |          Y_Scanlines
56	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |
57	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |
58	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |
59	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  V           |
60	 * X X X X X X X X X X X X X X X X              |
61	 * X X X X X X X X X X X X X X X X              |
62	 * X X X X X X X X X X X X X X X X              |
63	 * X X X X X X X X X X X X X X X X              V
64	 * V U V U V U V U V U V U X X X X  ^
65	 * V U V U V U V U V U V U X X X X  |
66	 * V U V U V U V U V U V U X X X X  |
67	 * V U V U V U V U V U V U X X X X  UV_Scanlines
68	 * X X X X X X X X X X X X X X X X  |
69	 * X X X X X X X X X X X X X X X X  V
70	 * X X X X X X X X X X X X X X X X  --> Padding & Buffer size alignment
71	 *
72	 * Y_Stride : Width aligned to 128
73	 * UV_Stride : Width aligned to 128
74	 * Y_Scanlines: Height aligned to 32
75	 * UV_Scanlines: Height/2 aligned to 16
76	 * Total size = align((Y_Stride * Y_Scanlines
77	 *          + UV_Stride * UV_Scanlines + 4096), 4096)
78	 */
79	COLOR_FMT_NV21,
80	/* Venus NV12_MVTB:
81	 * Two YUV 4:2:0 images/views one after the other
82	 * in a top-bottom layout, same as NV12
83	 * with a plane of 8 bit Y samples followed
84	 * by an interleaved U/V plane containing 8 bit 2x2 subsampled
85	 * colour difference samples.
86	 *
87	 *
88	 * <-------- Y/UV_Stride -------->
89	 * <------- Width ------->
90	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  ^           ^               ^
91	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |               |
92	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  Height      |               |
93	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |          Y_Scanlines      |
94	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |               |
95	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |               |
96	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |               |
97	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  V           |               |
98	 * X X X X X X X X X X X X X X X X              |             View_1
99	 * X X X X X X X X X X X X X X X X              |               |
100	 * X X X X X X X X X X X X X X X X              |               |
101	 * X X X X X X X X X X X X X X X X              V               |
102	 * U V U V U V U V U V U V X X X X  ^                           |
103	 * U V U V U V U V U V U V X X X X  |                           |
104	 * U V U V U V U V U V U V X X X X  |                           |
105	 * U V U V U V U V U V U V X X X X  UV_Scanlines                |
106	 * X X X X X X X X X X X X X X X X  |                           |
107	 * X X X X X X X X X X X X X X X X  V                           V
108	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  ^           ^               ^
109	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |               |
110	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  Height      |               |
111	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |          Y_Scanlines      |
112	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |               |
113	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |               |
114	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  |           |               |
115	 * Y Y Y Y Y Y Y Y Y Y Y Y X X X X  V           |               |
116	 * X X X X X X X X X X X X X X X X              |             View_2
117	 * X X X X X X X X X X X X X X X X              |               |
118	 * X X X X X X X X X X X X X X X X              |               |
119	 * X X X X X X X X X X X X X X X X              V               |
120	 * U V U V U V U V U V U V X X X X  ^                           |
121	 * U V U V U V U V U V U V X X X X  |                           |
122	 * U V U V U V U V U V U V X X X X  |                           |
123	 * U V U V U V U V U V U V X X X X  UV_Scanlines                |
124	 * X X X X X X X X X X X X X X X X  |                           |
125	 * X X X X X X X X X X X X X X X X  V                           V
126	 * X X X X X X X X X X X X X X X X  --> Buffer size alignment
127	 *
128	 * Y_Stride : Width aligned to 128
129	 * UV_Stride : Width aligned to 128
130	 * Y_Scanlines: Height aligned to 32
131	 * UV_Scanlines: Height/2 aligned to 16
132	 * View_1 begin at: 0 (zero)
133	 * View_2 begin at: Y_Stride * Y_Scanlines + UV_Stride * UV_Scanlines
134	 * Total size = align((2*(Y_Stride * Y_Scanlines)
135	 *          + 2*(UV_Stride * UV_Scanlines) + 4096), 4096)
136	 */
137	COLOR_FMT_NV12_MVTB,
138};
139
140static inline unsigned int VENUS_EXTRADATA_SIZE(int width, int height)
141{
142	(void)height;
143	(void)width;
144
145	/*
146	 * In the future, calculate the size based on the w/h but just
147	 * hardcode it for now since 8K satisfies all current usecases.
148	 */
149	return 8 * 1024;
150}
151
152static inline unsigned int VENUS_Y_STRIDE(int color_fmt, int width)
153{
154	unsigned int alignment, stride = 0;
155	if (!width)
156		goto invalid_input;
157
158	switch (color_fmt) {
159	case COLOR_FMT_NV21:
160	case COLOR_FMT_NV12:
161	case COLOR_FMT_NV12_MVTB:
162		alignment = 128;
163		stride = MSM_MEDIA_ALIGN(width, alignment);
164		break;
165	default:
166		break;
167	}
168invalid_input:
169	return stride;
170}
171
172static inline unsigned int VENUS_UV_STRIDE(int color_fmt, int width)
173{
174	unsigned int alignment, stride = 0;
175	if (!width)
176		goto invalid_input;
177
178	switch (color_fmt) {
179	case COLOR_FMT_NV21:
180	case COLOR_FMT_NV12:
181	case COLOR_FMT_NV12_MVTB:
182		alignment = 128;
183		stride = MSM_MEDIA_ALIGN(width, alignment);
184		break;
185	default:
186		break;
187	}
188invalid_input:
189	return stride;
190}
191
192static inline unsigned int VENUS_Y_SCANLINES(int color_fmt, int height)
193{
194	unsigned int alignment, sclines = 0;
195	if (!height)
196		goto invalid_input;
197
198	switch (color_fmt) {
199	case COLOR_FMT_NV21:
200	case COLOR_FMT_NV12:
201	case COLOR_FMT_NV12_MVTB:
202		alignment = 32;
203		sclines = MSM_MEDIA_ALIGN(height, alignment);
204		break;
205	default:
206		break;
207	}
208invalid_input:
209	return sclines;
210}
211
212static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height)
213{
214	unsigned int alignment, sclines = 0;
215	if (!height)
216		goto invalid_input;
217
218	switch (color_fmt) {
219	case COLOR_FMT_NV21:
220	case COLOR_FMT_NV12:
221	case COLOR_FMT_NV12_MVTB:
222		alignment = 16;
223		sclines = MSM_MEDIA_ALIGN(((height + 1) >> 1), alignment);
224		break;
225	default:
226		break;
227	}
228invalid_input:
229	return sclines;
230}
231
232static inline unsigned int VENUS_BUFFER_SIZE(
233	int color_fmt, int width, int height)
234{
235	const unsigned int extra_size = VENUS_EXTRADATA_SIZE(width, height);
236	unsigned int uv_alignment = 0, size = 0;
237	unsigned int y_plane, uv_plane, y_stride,
238		uv_stride, y_sclines, uv_sclines;
239	if (!width || !height)
240		goto invalid_input;
241
242	y_stride = VENUS_Y_STRIDE(color_fmt, width);
243	uv_stride = VENUS_UV_STRIDE(color_fmt, width);
244	y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
245	uv_sclines = VENUS_UV_SCANLINES(color_fmt, height);
246	switch (color_fmt) {
247	case COLOR_FMT_NV21:
248	case COLOR_FMT_NV12:
249		uv_alignment = 4096;
250		y_plane = y_stride * y_sclines;
251		uv_plane = uv_stride * uv_sclines + uv_alignment;
252		size = y_plane + uv_plane + extra_size;
253		size = MSM_MEDIA_ALIGN(size, 4096);
254		break;
255	case COLOR_FMT_NV12_MVTB:
256		uv_alignment = 4096;
257		y_plane = y_stride * y_sclines;
258		uv_plane = uv_stride * uv_sclines + uv_alignment;
259		size = y_plane + uv_plane;
260		size = 2 * size + extra_size;
261		size = MSM_MEDIA_ALIGN(size, 4096);
262		break;
263	default:
264		break;
265	}
266invalid_input:
267	return size;
268}
269
270static inline unsigned int VENUS_VIEW2_OFFSET(
271	int color_fmt, int width, int height)
272{
273	unsigned int offset = 0;
274	unsigned int y_plane, uv_plane, y_stride,
275		uv_stride, y_sclines, uv_sclines;
276	if (!width || !height)
277		goto invalid_input;
278
279	y_stride = VENUS_Y_STRIDE(color_fmt, width);
280	uv_stride = VENUS_UV_STRIDE(color_fmt, width);
281	y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
282	uv_sclines = VENUS_UV_SCANLINES(color_fmt, height);
283	switch (color_fmt) {
284	case COLOR_FMT_NV12_MVTB:
285		y_plane = y_stride * y_sclines;
286		uv_plane = uv_stride * uv_sclines;
287		offset = y_plane + uv_plane;
288		break;
289	default:
290		break;
291	}
292invalid_input:
293	return offset;
294}
295
296#endif
297