]>
Commit | Line | Data |
---|---|---|
f96f3cfa JP |
1 | /* |
2 | * drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | |
3 | * | |
4 | * Samsung MFC (Multi Function Codec - FIMV) driver | |
5 | * This file contains hw related functions. | |
6 | * | |
7 | * Copyright (c) 2012 Samsung Electronics Co., Ltd. | |
8 | * http://www.samsung.com/ | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License version 2 as | |
12 | * published by the Free Software Foundation. | |
13 | */ | |
14 | ||
15 | #undef DEBUG | |
16 | ||
17 | #include <linux/delay.h> | |
18 | #include <linux/mm.h> | |
19 | #include <linux/io.h> | |
20 | #include <linux/jiffies.h> | |
21 | #include <linux/firmware.h> | |
22 | #include <linux/err.h> | |
23 | #include <linux/sched.h> | |
24 | #include <linux/dma-mapping.h> | |
25 | ||
26 | #include <asm/cacheflush.h> | |
27 | ||
28 | #include "s5p_mfc_common.h" | |
29 | #include "s5p_mfc_cmd.h" | |
30 | #include "s5p_mfc_intr.h" | |
31 | #include "s5p_mfc_pm.h" | |
32 | #include "s5p_mfc_debug.h" | |
33 | #include "s5p_mfc_opr.h" | |
34 | #include "s5p_mfc_opr_v6.h" | |
35 | ||
36 | /* #define S5P_MFC_DEBUG_REGWRITE */ | |
37 | #ifdef S5P_MFC_DEBUG_REGWRITE | |
38 | #undef writel | |
39 | #define writel(v, r) \ | |
40 | do { \ | |
41 | pr_err("MFCWRITE(%p): %08x\n", r, (unsigned int)v); \ | |
42 | __raw_writel(v, r); \ | |
43 | } while (0) | |
44 | #endif /* S5P_MFC_DEBUG_REGWRITE */ | |
45 | ||
6a9c6f68 KA |
46 | #define READL(reg) \ |
47 | (WARN_ON_ONCE(!(reg)) ? 0 : readl(reg)) | |
48 | #define WRITEL(data, reg) \ | |
49 | (WARN_ON_ONCE(!(reg)) ? 0 : writel((data), (reg))) | |
f96f3cfa JP |
50 | |
51 | /* Allocate temporary buffers for decoding */ | |
b9571a57 | 52 | static int s5p_mfc_alloc_dec_temp_buffers_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
53 | { |
54 | /* NOP */ | |
55 | ||
56 | return 0; | |
57 | } | |
58 | ||
59 | /* Release temproary buffers for decoding */ | |
b9571a57 | 60 | static void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
61 | { |
62 | /* NOP */ | |
63 | } | |
64 | ||
f96f3cfa | 65 | /* Allocate codec buffers */ |
b9571a57 | 66 | static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
67 | { |
68 | struct s5p_mfc_dev *dev = ctx->dev; | |
69 | unsigned int mb_width, mb_height; | |
317b4ca4 | 70 | int ret; |
f96f3cfa JP |
71 | |
72 | mb_width = MB_WIDTH(ctx->img_width); | |
73 | mb_height = MB_HEIGHT(ctx->img_height); | |
74 | ||
75 | if (ctx->type == MFCINST_DECODER) { | |
76 | mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n", | |
77 | ctx->luma_size, ctx->chroma_size, ctx->mv_size); | |
78 | mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count); | |
79 | } else if (ctx->type == MFCINST_ENCODER) { | |
80 | ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 * | |
81 | ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height), | |
82 | S5P_FIMV_TMV_BUFFER_ALIGN_V6); | |
debe6267 | 83 | |
f96f3cfa JP |
84 | ctx->luma_dpb_size = ALIGN((mb_width * mb_height) * |
85 | S5P_FIMV_LUMA_MB_TO_PIXEL_V6, | |
86 | S5P_FIMV_LUMA_DPB_BUFFER_ALIGN_V6); | |
87 | ctx->chroma_dpb_size = ALIGN((mb_width * mb_height) * | |
88 | S5P_FIMV_CHROMA_MB_TO_PIXEL_V6, | |
89 | S5P_FIMV_CHROMA_DPB_BUFFER_ALIGN_V6); | |
90 | ctx->me_buffer_size = ALIGN(S5P_FIMV_ME_BUFFER_SIZE_V6( | |
91 | ctx->img_width, ctx->img_height, | |
92 | mb_width, mb_height), | |
93 | S5P_FIMV_ME_BUFFER_ALIGN_V6); | |
94 | ||
95 | mfc_debug(2, "recon luma size: %d chroma size: %d\n", | |
96 | ctx->luma_dpb_size, ctx->chroma_dpb_size); | |
97 | } else { | |
98 | return -EINVAL; | |
99 | } | |
100 | ||
101 | /* Codecs have different memory requirements */ | |
102 | switch (ctx->codec_mode) { | |
103 | case S5P_MFC_CODEC_H264_DEC: | |
104 | case S5P_MFC_CODEC_H264_MVC_DEC: | |
e2b9deb2 KA |
105 | if (IS_MFCV8(dev)) |
106 | ctx->scratch_buf_size = | |
107 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V8( | |
108 | mb_width, | |
109 | mb_height); | |
110 | else | |
111 | ctx->scratch_buf_size = | |
112 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V6( | |
f96f3cfa JP |
113 | mb_width, |
114 | mb_height); | |
115 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | |
116 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | |
317b4ca4 | 117 | ctx->bank1.size = |
f96f3cfa JP |
118 | ctx->scratch_buf_size + |
119 | (ctx->mv_count * ctx->mv_size); | |
120 | break; | |
121 | case S5P_MFC_CODEC_MPEG4_DEC: | |
109b794c | 122 | if (IS_MFCV7_PLUS(dev)) { |
debe6267 AK |
123 | ctx->scratch_buf_size = |
124 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V7( | |
125 | mb_width, | |
126 | mb_height); | |
127 | } else { | |
128 | ctx->scratch_buf_size = | |
129 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V6( | |
130 | mb_width, | |
131 | mb_height); | |
132 | } | |
133 | ||
f96f3cfa JP |
134 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
135 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | |
317b4ca4 | 136 | ctx->bank1.size = ctx->scratch_buf_size; |
f96f3cfa JP |
137 | break; |
138 | case S5P_MFC_CODEC_VC1RCV_DEC: | |
139 | case S5P_MFC_CODEC_VC1_DEC: | |
140 | ctx->scratch_buf_size = | |
141 | S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6( | |
142 | mb_width, | |
143 | mb_height); | |
144 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | |
145 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | |
317b4ca4 | 146 | ctx->bank1.size = ctx->scratch_buf_size; |
f96f3cfa JP |
147 | break; |
148 | case S5P_MFC_CODEC_MPEG2_DEC: | |
317b4ca4 KD |
149 | ctx->bank1.size = 0; |
150 | ctx->bank2.size = 0; | |
f96f3cfa JP |
151 | break; |
152 | case S5P_MFC_CODEC_H263_DEC: | |
153 | ctx->scratch_buf_size = | |
154 | S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6( | |
155 | mb_width, | |
156 | mb_height); | |
157 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | |
158 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | |
317b4ca4 | 159 | ctx->bank1.size = ctx->scratch_buf_size; |
f96f3cfa JP |
160 | break; |
161 | case S5P_MFC_CODEC_VP8_DEC: | |
e2b9deb2 KA |
162 | if (IS_MFCV8(dev)) |
163 | ctx->scratch_buf_size = | |
164 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V8( | |
165 | mb_width, | |
166 | mb_height); | |
167 | else | |
168 | ctx->scratch_buf_size = | |
169 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V6( | |
170 | mb_width, | |
171 | mb_height); | |
f96f3cfa JP |
172 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
173 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | |
317b4ca4 | 174 | ctx->bank1.size = ctx->scratch_buf_size; |
f96f3cfa JP |
175 | break; |
176 | case S5P_MFC_CODEC_H264_ENC: | |
177 | ctx->scratch_buf_size = | |
178 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V6( | |
179 | mb_width, | |
180 | mb_height); | |
181 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | |
182 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | |
317b4ca4 | 183 | ctx->bank1.size = |
f96f3cfa | 184 | ctx->scratch_buf_size + ctx->tmv_buffer_size + |
e9d98ddc | 185 | (ctx->pb_count * (ctx->luma_dpb_size + |
f96f3cfa | 186 | ctx->chroma_dpb_size + ctx->me_buffer_size)); |
317b4ca4 | 187 | ctx->bank2.size = 0; |
f96f3cfa JP |
188 | break; |
189 | case S5P_MFC_CODEC_MPEG4_ENC: | |
190 | case S5P_MFC_CODEC_H263_ENC: | |
191 | ctx->scratch_buf_size = | |
192 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_ENC_V6( | |
193 | mb_width, | |
194 | mb_height); | |
195 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | |
196 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | |
317b4ca4 | 197 | ctx->bank1.size = |
f96f3cfa | 198 | ctx->scratch_buf_size + ctx->tmv_buffer_size + |
e9d98ddc | 199 | (ctx->pb_count * (ctx->luma_dpb_size + |
f96f3cfa | 200 | ctx->chroma_dpb_size + ctx->me_buffer_size)); |
317b4ca4 | 201 | ctx->bank2.size = 0; |
f96f3cfa | 202 | break; |
3a967706 AK |
203 | case S5P_MFC_CODEC_VP8_ENC: |
204 | ctx->scratch_buf_size = | |
205 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V7( | |
206 | mb_width, | |
207 | mb_height); | |
208 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, | |
209 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); | |
210 | ctx->bank1.size = | |
211 | ctx->scratch_buf_size + ctx->tmv_buffer_size + | |
212 | (ctx->pb_count * (ctx->luma_dpb_size + | |
213 | ctx->chroma_dpb_size + ctx->me_buffer_size)); | |
214 | ctx->bank2.size = 0; | |
215 | break; | |
f96f3cfa JP |
216 | default: |
217 | break; | |
218 | } | |
219 | ||
220 | /* Allocate only if memory from bank 1 is necessary */ | |
317b4ca4 KD |
221 | if (ctx->bank1.size > 0) { |
222 | ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, &ctx->bank1); | |
223 | if (ret) { | |
224 | mfc_err("Failed to allocate Bank1 memory\n"); | |
225 | return ret; | |
f96f3cfa | 226 | } |
317b4ca4 | 227 | BUG_ON(ctx->bank1.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); |
f96f3cfa | 228 | } |
f96f3cfa JP |
229 | return 0; |
230 | } | |
231 | ||
232 | /* Release buffers allocated for codec */ | |
b9571a57 | 233 | static void s5p_mfc_release_codec_buffers_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa | 234 | { |
317b4ca4 | 235 | s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->bank1); |
f96f3cfa JP |
236 | } |
237 | ||
238 | /* Allocate memory for instance data buffer */ | |
b9571a57 | 239 | static int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
240 | { |
241 | struct s5p_mfc_dev *dev = ctx->dev; | |
242 | struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; | |
317b4ca4 | 243 | int ret; |
f96f3cfa JP |
244 | |
245 | mfc_debug_enter(); | |
246 | ||
247 | switch (ctx->codec_mode) { | |
248 | case S5P_MFC_CODEC_H264_DEC: | |
249 | case S5P_MFC_CODEC_H264_MVC_DEC: | |
250 | ctx->ctx.size = buf_size->h264_dec_ctx; | |
251 | break; | |
252 | case S5P_MFC_CODEC_MPEG4_DEC: | |
253 | case S5P_MFC_CODEC_H263_DEC: | |
254 | case S5P_MFC_CODEC_VC1RCV_DEC: | |
255 | case S5P_MFC_CODEC_VC1_DEC: | |
256 | case S5P_MFC_CODEC_MPEG2_DEC: | |
257 | case S5P_MFC_CODEC_VP8_DEC: | |
258 | ctx->ctx.size = buf_size->other_dec_ctx; | |
259 | break; | |
260 | case S5P_MFC_CODEC_H264_ENC: | |
261 | ctx->ctx.size = buf_size->h264_enc_ctx; | |
262 | break; | |
263 | case S5P_MFC_CODEC_MPEG4_ENC: | |
264 | case S5P_MFC_CODEC_H263_ENC: | |
3a967706 | 265 | case S5P_MFC_CODEC_VP8_ENC: |
f96f3cfa JP |
266 | ctx->ctx.size = buf_size->other_enc_ctx; |
267 | break; | |
268 | default: | |
269 | ctx->ctx.size = 0; | |
270 | mfc_err("Codec type(%d) should be checked!\n", ctx->codec_mode); | |
271 | break; | |
272 | } | |
273 | ||
317b4ca4 KD |
274 | ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, &ctx->ctx); |
275 | if (ret) { | |
276 | mfc_err("Failed to allocate instance buffer\n"); | |
277 | return ret; | |
f96f3cfa JP |
278 | } |
279 | ||
280 | memset(ctx->ctx.virt, 0, ctx->ctx.size); | |
281 | wmb(); | |
282 | ||
283 | mfc_debug_leave(); | |
284 | ||
285 | return 0; | |
286 | } | |
287 | ||
288 | /* Release instance buffer */ | |
b9571a57 | 289 | static void s5p_mfc_release_instance_buffer_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa | 290 | { |
317b4ca4 | 291 | s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->ctx); |
f96f3cfa JP |
292 | } |
293 | ||
294 | /* Allocate context buffers for SYS_INIT */ | |
b9571a57 | 295 | static int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev) |
f96f3cfa JP |
296 | { |
297 | struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; | |
317b4ca4 | 298 | int ret; |
f96f3cfa JP |
299 | |
300 | mfc_debug_enter(); | |
301 | ||
317b4ca4 KD |
302 | dev->ctx_buf.size = buf_size->dev_ctx; |
303 | ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, &dev->ctx_buf); | |
304 | if (ret) { | |
305 | mfc_err("Failed to allocate device context buffer\n"); | |
306 | return ret; | |
f96f3cfa JP |
307 | } |
308 | ||
309 | memset(dev->ctx_buf.virt, 0, buf_size->dev_ctx); | |
310 | wmb(); | |
311 | ||
312 | mfc_debug_leave(); | |
313 | ||
314 | return 0; | |
315 | } | |
316 | ||
317 | /* Release context buffers for SYS_INIT */ | |
b9571a57 | 318 | static void s5p_mfc_release_dev_context_buffer_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 319 | { |
317b4ca4 | 320 | s5p_mfc_release_priv_buf(dev->mem_dev_l, &dev->ctx_buf); |
f96f3cfa JP |
321 | } |
322 | ||
323 | static int calc_plane(int width, int height) | |
324 | { | |
325 | int mbX, mbY; | |
326 | ||
327 | mbX = DIV_ROUND_UP(width, S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6); | |
328 | mbY = DIV_ROUND_UP(height, S5P_FIMV_NUM_PIXELS_IN_MB_COL_V6); | |
329 | ||
330 | if (width * height < S5P_FIMV_MAX_FRAME_SIZE_V6) | |
331 | mbY = (mbY + 1) / 2 * 2; | |
332 | ||
333 | return (mbX * S5P_FIMV_NUM_PIXELS_IN_MB_COL_V6) * | |
334 | (mbY * S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6); | |
335 | } | |
336 | ||
b9571a57 | 337 | static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
338 | { |
339 | ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6); | |
340 | ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6); | |
341 | mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n" | |
342 | "buffer dimensions: %dx%d\n", ctx->img_width, | |
343 | ctx->img_height, ctx->buf_width, ctx->buf_height); | |
344 | ||
345 | ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height); | |
346 | ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1)); | |
e2b9deb2 KA |
347 | if (IS_MFCV8(ctx->dev)) { |
348 | /* MFCv8 needs additional 64 bytes for luma,chroma dpb*/ | |
349 | ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8; | |
350 | ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8; | |
351 | } | |
352 | ||
f96f3cfa JP |
353 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || |
354 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { | |
355 | ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width, | |
356 | ctx->img_height); | |
357 | ctx->mv_size = ALIGN(ctx->mv_size, 16); | |
358 | } else { | |
359 | ctx->mv_size = 0; | |
360 | } | |
361 | } | |
362 | ||
b9571a57 | 363 | static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
364 | { |
365 | unsigned int mb_width, mb_height; | |
366 | ||
367 | mb_width = MB_WIDTH(ctx->img_width); | |
368 | mb_height = MB_HEIGHT(ctx->img_height); | |
369 | ||
370 | ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN_V6); | |
371 | ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256); | |
372 | ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256); | |
debe6267 AK |
373 | |
374 | /* MFCv7 needs pad bytes for Luma and Chroma */ | |
109b794c | 375 | if (IS_MFCV7_PLUS(ctx->dev)) { |
debe6267 AK |
376 | ctx->luma_size += MFC_LUMA_PAD_BYTES_V7; |
377 | ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7; | |
378 | } | |
f96f3cfa JP |
379 | } |
380 | ||
381 | /* Set registers for decoding stream buffer */ | |
b9571a57 SK |
382 | static int s5p_mfc_set_dec_stream_buffer_v6(struct s5p_mfc_ctx *ctx, |
383 | int buf_addr, unsigned int start_num_byte, | |
384 | unsigned int strm_size) | |
f96f3cfa JP |
385 | { |
386 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 387 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
388 | struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size; |
389 | ||
390 | mfc_debug_enter(); | |
391 | mfc_debug(2, "inst_no: %d, buf_addr: 0x%08x,\n" | |
392 | "buf_size: 0x%08x (%d)\n", | |
393 | ctx->inst_no, buf_addr, strm_size, strm_size); | |
6a9c6f68 KA |
394 | WRITEL(strm_size, mfc_regs->d_stream_data_size); |
395 | WRITEL(buf_addr, mfc_regs->d_cpb_buffer_addr); | |
396 | WRITEL(buf_size->cpb, mfc_regs->d_cpb_buffer_size); | |
397 | WRITEL(start_num_byte, mfc_regs->d_cpb_buffer_offset); | |
f96f3cfa JP |
398 | |
399 | mfc_debug_leave(); | |
400 | return 0; | |
401 | } | |
402 | ||
403 | /* Set decoding frame buffer */ | |
b9571a57 | 404 | static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
405 | { |
406 | unsigned int frame_size, i; | |
407 | unsigned int frame_size_ch, frame_size_mv; | |
408 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 409 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
410 | size_t buf_addr1; |
411 | int buf_size1; | |
412 | int align_gap; | |
413 | ||
317b4ca4 KD |
414 | buf_addr1 = ctx->bank1.dma; |
415 | buf_size1 = ctx->bank1.size; | |
f96f3cfa JP |
416 | |
417 | mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); | |
418 | mfc_debug(2, "Total DPB COUNT: %d\n", ctx->total_dpb_count); | |
419 | mfc_debug(2, "Setting display delay to %d\n", ctx->display_delay); | |
420 | ||
6a9c6f68 KA |
421 | WRITEL(ctx->total_dpb_count, mfc_regs->d_num_dpb); |
422 | WRITEL(ctx->luma_size, mfc_regs->d_first_plane_dpb_size); | |
423 | WRITEL(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size); | |
f96f3cfa | 424 | |
6a9c6f68 KA |
425 | WRITEL(buf_addr1, mfc_regs->d_scratch_buffer_addr); |
426 | WRITEL(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size); | |
e2b9deb2 KA |
427 | |
428 | if (IS_MFCV8(dev)) { | |
429 | WRITEL(ctx->img_width, | |
430 | mfc_regs->d_first_plane_dpb_stride_size); | |
431 | WRITEL(ctx->img_width, | |
432 | mfc_regs->d_second_plane_dpb_stride_size); | |
433 | } | |
434 | ||
f96f3cfa JP |
435 | buf_addr1 += ctx->scratch_buf_size; |
436 | buf_size1 -= ctx->scratch_buf_size; | |
437 | ||
438 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC || | |
439 | ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC){ | |
6a9c6f68 KA |
440 | WRITEL(ctx->mv_size, mfc_regs->d_mv_buffer_size); |
441 | WRITEL(ctx->mv_count, mfc_regs->d_num_mv); | |
f96f3cfa JP |
442 | } |
443 | ||
444 | frame_size = ctx->luma_size; | |
445 | frame_size_ch = ctx->chroma_size; | |
446 | frame_size_mv = ctx->mv_size; | |
447 | mfc_debug(2, "Frame size: %d ch: %d mv: %d\n", | |
448 | frame_size, frame_size_ch, frame_size_mv); | |
449 | ||
450 | for (i = 0; i < ctx->total_dpb_count; i++) { | |
451 | /* Bank2 */ | |
452 | mfc_debug(2, "Luma %d: %x\n", i, | |
453 | ctx->dst_bufs[i].cookie.raw.luma); | |
454 | WRITEL(ctx->dst_bufs[i].cookie.raw.luma, | |
6a9c6f68 | 455 | mfc_regs->d_first_plane_dpb + i * 4); |
f96f3cfa JP |
456 | mfc_debug(2, "\tChroma %d: %x\n", i, |
457 | ctx->dst_bufs[i].cookie.raw.chroma); | |
458 | WRITEL(ctx->dst_bufs[i].cookie.raw.chroma, | |
6a9c6f68 | 459 | mfc_regs->d_second_plane_dpb + i * 4); |
f96f3cfa JP |
460 | } |
461 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || | |
462 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { | |
463 | for (i = 0; i < ctx->mv_count; i++) { | |
464 | /* To test alignment */ | |
465 | align_gap = buf_addr1; | |
466 | buf_addr1 = ALIGN(buf_addr1, 16); | |
467 | align_gap = buf_addr1 - align_gap; | |
468 | buf_size1 -= align_gap; | |
469 | ||
470 | mfc_debug(2, "\tBuf1: %x, size: %d\n", | |
471 | buf_addr1, buf_size1); | |
6a9c6f68 | 472 | WRITEL(buf_addr1, mfc_regs->d_mv_buffer + i * 4); |
f96f3cfa JP |
473 | buf_addr1 += frame_size_mv; |
474 | buf_size1 -= frame_size_mv; | |
475 | } | |
476 | } | |
477 | ||
478 | mfc_debug(2, "Buf1: %u, buf_size1: %d (frames %d)\n", | |
479 | buf_addr1, buf_size1, ctx->total_dpb_count); | |
480 | if (buf_size1 < 0) { | |
481 | mfc_debug(2, "Not enough memory has been allocated.\n"); | |
482 | return -ENOMEM; | |
483 | } | |
484 | ||
6a9c6f68 | 485 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
f96f3cfa JP |
486 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
487 | S5P_FIMV_CH_INIT_BUFS_V6, NULL); | |
488 | ||
489 | mfc_debug(2, "After setting buffers.\n"); | |
490 | return 0; | |
491 | } | |
492 | ||
493 | /* Set registers for encoding stream buffer */ | |
b9571a57 | 494 | static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx, |
f96f3cfa JP |
495 | unsigned long addr, unsigned int size) |
496 | { | |
497 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 498 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa | 499 | |
6a9c6f68 KA |
500 | WRITEL(addr, mfc_regs->e_stream_buffer_addr); /* 16B align */ |
501 | WRITEL(size, mfc_regs->e_stream_buffer_size); | |
f96f3cfa | 502 | |
4130eabc AH |
503 | mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d\n", |
504 | addr, size); | |
f96f3cfa JP |
505 | |
506 | return 0; | |
507 | } | |
508 | ||
b9571a57 | 509 | static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, |
f96f3cfa JP |
510 | unsigned long y_addr, unsigned long c_addr) |
511 | { | |
512 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 513 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa | 514 | |
6a9c6f68 KA |
515 | WRITEL(y_addr, mfc_regs->e_source_first_plane_addr); |
516 | WRITEL(c_addr, mfc_regs->e_source_second_plane_addr); | |
f96f3cfa | 517 | |
4130eabc AH |
518 | mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr); |
519 | mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr); | |
f96f3cfa JP |
520 | } |
521 | ||
b9571a57 | 522 | static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, |
f96f3cfa JP |
523 | unsigned long *y_addr, unsigned long *c_addr) |
524 | { | |
525 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 526 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
527 | unsigned long enc_recon_y_addr, enc_recon_c_addr; |
528 | ||
6a9c6f68 KA |
529 | *y_addr = READL(mfc_regs->e_encoded_source_first_plane_addr); |
530 | *c_addr = READL(mfc_regs->e_encoded_source_second_plane_addr); | |
f96f3cfa | 531 | |
6a9c6f68 KA |
532 | enc_recon_y_addr = READL(mfc_regs->e_recon_luma_dpb_addr); |
533 | enc_recon_c_addr = READL(mfc_regs->e_recon_chroma_dpb_addr); | |
f96f3cfa | 534 | |
4130eabc AH |
535 | mfc_debug(2, "recon y addr: 0x%08lx\n", enc_recon_y_addr); |
536 | mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr); | |
f96f3cfa JP |
537 | } |
538 | ||
539 | /* Set encoding ref & codec buffer */ | |
b9571a57 | 540 | static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
541 | { |
542 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 543 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
4a9c85aa SK |
544 | size_t buf_addr1; |
545 | int i, buf_size1; | |
f96f3cfa JP |
546 | |
547 | mfc_debug_enter(); | |
548 | ||
317b4ca4 KD |
549 | buf_addr1 = ctx->bank1.dma; |
550 | buf_size1 = ctx->bank1.size; | |
f96f3cfa JP |
551 | |
552 | mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); | |
553 | ||
e9d98ddc | 554 | for (i = 0; i < ctx->pb_count; i++) { |
6a9c6f68 | 555 | WRITEL(buf_addr1, mfc_regs->e_luma_dpb + (4 * i)); |
f96f3cfa | 556 | buf_addr1 += ctx->luma_dpb_size; |
6a9c6f68 | 557 | WRITEL(buf_addr1, mfc_regs->e_chroma_dpb + (4 * i)); |
f96f3cfa | 558 | buf_addr1 += ctx->chroma_dpb_size; |
6a9c6f68 | 559 | WRITEL(buf_addr1, mfc_regs->e_me_buffer + (4 * i)); |
f96f3cfa JP |
560 | buf_addr1 += ctx->me_buffer_size; |
561 | buf_size1 -= (ctx->luma_dpb_size + ctx->chroma_dpb_size + | |
562 | ctx->me_buffer_size); | |
563 | } | |
564 | ||
6a9c6f68 KA |
565 | WRITEL(buf_addr1, mfc_regs->e_scratch_buffer_addr); |
566 | WRITEL(ctx->scratch_buf_size, mfc_regs->e_scratch_buffer_size); | |
f96f3cfa JP |
567 | buf_addr1 += ctx->scratch_buf_size; |
568 | buf_size1 -= ctx->scratch_buf_size; | |
569 | ||
6a9c6f68 | 570 | WRITEL(buf_addr1, mfc_regs->e_tmv_buffer0); |
f96f3cfa | 571 | buf_addr1 += ctx->tmv_buffer_size >> 1; |
6a9c6f68 | 572 | WRITEL(buf_addr1, mfc_regs->e_tmv_buffer1); |
f96f3cfa JP |
573 | buf_addr1 += ctx->tmv_buffer_size >> 1; |
574 | buf_size1 -= ctx->tmv_buffer_size; | |
575 | ||
576 | mfc_debug(2, "Buf1: %u, buf_size1: %d (ref frames %d)\n", | |
e9d98ddc | 577 | buf_addr1, buf_size1, ctx->pb_count); |
f96f3cfa JP |
578 | if (buf_size1 < 0) { |
579 | mfc_debug(2, "Not enough memory has been allocated.\n"); | |
580 | return -ENOMEM; | |
581 | } | |
582 | ||
6a9c6f68 | 583 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
f96f3cfa JP |
584 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
585 | S5P_FIMV_CH_INIT_BUFS_V6, NULL); | |
586 | ||
587 | mfc_debug_leave(); | |
588 | ||
589 | return 0; | |
590 | } | |
591 | ||
592 | static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx) | |
593 | { | |
594 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 595 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
596 | |
597 | /* multi-slice control */ | |
598 | /* multi-slice MB number or bit size */ | |
6a9c6f68 | 599 | WRITEL(ctx->slice_mode, mfc_regs->e_mslice_mode); |
f96f3cfa | 600 | if (ctx->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { |
6a9c6f68 | 601 | WRITEL(ctx->slice_size.mb, mfc_regs->e_mslice_size_mb); |
f96f3cfa JP |
602 | } else if (ctx->slice_mode == |
603 | V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { | |
6a9c6f68 | 604 | WRITEL(ctx->slice_size.bits, mfc_regs->e_mslice_size_bits); |
f96f3cfa | 605 | } else { |
6a9c6f68 KA |
606 | WRITEL(0x0, mfc_regs->e_mslice_size_mb); |
607 | WRITEL(0x0, mfc_regs->e_mslice_size_bits); | |
f96f3cfa JP |
608 | } |
609 | ||
610 | return 0; | |
611 | } | |
612 | ||
613 | static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) | |
614 | { | |
615 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 616 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
617 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
618 | unsigned int reg = 0; | |
619 | ||
620 | mfc_debug_enter(); | |
621 | ||
622 | /* width */ | |
6a9c6f68 | 623 | WRITEL(ctx->img_width, mfc_regs->e_frame_width); /* 16 align */ |
f96f3cfa | 624 | /* height */ |
6a9c6f68 | 625 | WRITEL(ctx->img_height, mfc_regs->e_frame_height); /* 16 align */ |
f96f3cfa JP |
626 | |
627 | /* cropped width */ | |
6a9c6f68 | 628 | WRITEL(ctx->img_width, mfc_regs->e_cropped_frame_width); |
f96f3cfa | 629 | /* cropped height */ |
6a9c6f68 | 630 | WRITEL(ctx->img_height, mfc_regs->e_cropped_frame_height); |
f96f3cfa | 631 | /* cropped offset */ |
6a9c6f68 | 632 | WRITEL(0x0, mfc_regs->e_frame_crop_offset); |
f96f3cfa JP |
633 | |
634 | /* pictype : IDR period */ | |
635 | reg = 0; | |
636 | reg |= p->gop_size & 0xFFFF; | |
6a9c6f68 | 637 | WRITEL(reg, mfc_regs->e_gop_config); |
f96f3cfa JP |
638 | |
639 | /* multi-slice control */ | |
640 | /* multi-slice MB number or bit size */ | |
641 | ctx->slice_mode = p->slice_mode; | |
642 | reg = 0; | |
643 | if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { | |
644 | reg |= (0x1 << 3); | |
6a9c6f68 | 645 | WRITEL(reg, mfc_regs->e_enc_options); |
f96f3cfa JP |
646 | ctx->slice_size.mb = p->slice_mb; |
647 | } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { | |
648 | reg |= (0x1 << 3); | |
6a9c6f68 | 649 | WRITEL(reg, mfc_regs->e_enc_options); |
f96f3cfa JP |
650 | ctx->slice_size.bits = p->slice_bit; |
651 | } else { | |
652 | reg &= ~(0x1 << 3); | |
6a9c6f68 | 653 | WRITEL(reg, mfc_regs->e_enc_options); |
f96f3cfa JP |
654 | } |
655 | ||
656 | s5p_mfc_set_slice_mode(ctx); | |
657 | ||
658 | /* cyclic intra refresh */ | |
6a9c6f68 KA |
659 | WRITEL(p->intra_refresh_mb, mfc_regs->e_ir_size); |
660 | reg = READL(mfc_regs->e_enc_options); | |
f96f3cfa JP |
661 | if (p->intra_refresh_mb == 0) |
662 | reg &= ~(0x1 << 4); | |
663 | else | |
664 | reg |= (0x1 << 4); | |
6a9c6f68 | 665 | WRITEL(reg, mfc_regs->e_enc_options); |
f96f3cfa JP |
666 | |
667 | /* 'NON_REFERENCE_STORE_ENABLE' for debugging */ | |
6a9c6f68 | 668 | reg = READL(mfc_regs->e_enc_options); |
f96f3cfa | 669 | reg &= ~(0x1 << 9); |
6a9c6f68 | 670 | WRITEL(reg, mfc_regs->e_enc_options); |
f96f3cfa JP |
671 | |
672 | /* memory structure cur. frame */ | |
673 | if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) { | |
674 | /* 0: Linear, 1: 2D tiled*/ | |
6a9c6f68 | 675 | reg = READL(mfc_regs->e_enc_options); |
f96f3cfa | 676 | reg &= ~(0x1 << 7); |
6a9c6f68 | 677 | WRITEL(reg, mfc_regs->e_enc_options); |
f96f3cfa | 678 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
6a9c6f68 | 679 | WRITEL(0x0, mfc_regs->pixel_format); |
f96f3cfa JP |
680 | } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV21M) { |
681 | /* 0: Linear, 1: 2D tiled*/ | |
6a9c6f68 | 682 | reg = READL(mfc_regs->e_enc_options); |
f96f3cfa | 683 | reg &= ~(0x1 << 7); |
6a9c6f68 | 684 | WRITEL(reg, mfc_regs->e_enc_options); |
f96f3cfa | 685 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
6a9c6f68 | 686 | WRITEL(0x1, mfc_regs->pixel_format); |
f96f3cfa JP |
687 | } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) { |
688 | /* 0: Linear, 1: 2D tiled*/ | |
6a9c6f68 | 689 | reg = READL(mfc_regs->e_enc_options); |
f96f3cfa | 690 | reg |= (0x1 << 7); |
6a9c6f68 | 691 | WRITEL(reg, mfc_regs->e_enc_options); |
f96f3cfa | 692 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
6a9c6f68 | 693 | WRITEL(0x0, mfc_regs->pixel_format); |
f96f3cfa JP |
694 | } |
695 | ||
696 | /* memory structure recon. frame */ | |
697 | /* 0: Linear, 1: 2D tiled */ | |
6a9c6f68 | 698 | reg = READL(mfc_regs->e_enc_options); |
f96f3cfa | 699 | reg |= (0x1 << 8); |
6a9c6f68 | 700 | WRITEL(reg, mfc_regs->e_enc_options); |
f96f3cfa JP |
701 | |
702 | /* padding control & value */ | |
6a9c6f68 | 703 | WRITEL(0x0, mfc_regs->e_padding_ctrl); |
f96f3cfa JP |
704 | if (p->pad) { |
705 | reg = 0; | |
706 | /** enable */ | |
707 | reg |= (1 << 31); | |
708 | /** cr value */ | |
709 | reg |= ((p->pad_cr & 0xFF) << 16); | |
710 | /** cb value */ | |
711 | reg |= ((p->pad_cb & 0xFF) << 8); | |
712 | /** y value */ | |
713 | reg |= p->pad_luma & 0xFF; | |
6a9c6f68 | 714 | WRITEL(reg, mfc_regs->e_padding_ctrl); |
f96f3cfa JP |
715 | } |
716 | ||
717 | /* rate control config. */ | |
718 | reg = 0; | |
719 | /* frame-level rate control */ | |
720 | reg |= ((p->rc_frame & 0x1) << 9); | |
6a9c6f68 | 721 | WRITEL(reg, mfc_regs->e_rc_config); |
f96f3cfa JP |
722 | |
723 | /* bit rate */ | |
724 | if (p->rc_frame) | |
725 | WRITEL(p->rc_bitrate, | |
6a9c6f68 | 726 | mfc_regs->e_rc_bit_rate); |
f96f3cfa | 727 | else |
6a9c6f68 | 728 | WRITEL(1, mfc_regs->e_rc_bit_rate); |
f96f3cfa JP |
729 | |
730 | /* reaction coefficient */ | |
731 | if (p->rc_frame) { | |
732 | if (p->rc_reaction_coeff < TIGHT_CBR_MAX) /* tight CBR */ | |
6a9c6f68 | 733 | WRITEL(1, mfc_regs->e_rc_mode); |
f96f3cfa | 734 | else /* loose CBR */ |
6a9c6f68 | 735 | WRITEL(2, mfc_regs->e_rc_mode); |
f96f3cfa JP |
736 | } |
737 | ||
738 | /* seq header ctrl */ | |
6a9c6f68 | 739 | reg = READL(mfc_regs->e_enc_options); |
f96f3cfa JP |
740 | reg &= ~(0x1 << 2); |
741 | reg |= ((p->seq_hdr_mode & 0x1) << 2); | |
742 | ||
743 | /* frame skip mode */ | |
744 | reg &= ~(0x3); | |
745 | reg |= (p->frame_skip_mode & 0x3); | |
6a9c6f68 | 746 | WRITEL(reg, mfc_regs->e_enc_options); |
f96f3cfa JP |
747 | |
748 | /* 'DROP_CONTROL_ENABLE', disable */ | |
6a9c6f68 | 749 | reg = READL(mfc_regs->e_rc_config); |
f96f3cfa | 750 | reg &= ~(0x1 << 10); |
6a9c6f68 | 751 | WRITEL(reg, mfc_regs->e_rc_config); |
f96f3cfa JP |
752 | |
753 | /* setting for MV range [16, 256] */ | |
a378a320 | 754 | reg = (p->mv_h_range & S5P_FIMV_E_MV_RANGE_V6_MASK); |
6a9c6f68 | 755 | WRITEL(reg, mfc_regs->e_mv_hor_range); |
f96f3cfa | 756 | |
a378a320 | 757 | reg = (p->mv_v_range & S5P_FIMV_E_MV_RANGE_V6_MASK); |
6a9c6f68 | 758 | WRITEL(reg, mfc_regs->e_mv_ver_range); |
f96f3cfa | 759 | |
6a9c6f68 KA |
760 | WRITEL(0x0, mfc_regs->e_frame_insertion); |
761 | WRITEL(0x0, mfc_regs->e_roi_buffer_addr); | |
762 | WRITEL(0x0, mfc_regs->e_param_change); | |
763 | WRITEL(0x0, mfc_regs->e_rc_roi_ctrl); | |
764 | WRITEL(0x0, mfc_regs->e_picture_tag); | |
f96f3cfa | 765 | |
6a9c6f68 KA |
766 | WRITEL(0x0, mfc_regs->e_bit_count_enable); |
767 | WRITEL(0x0, mfc_regs->e_max_bit_count); | |
768 | WRITEL(0x0, mfc_regs->e_min_bit_count); | |
f96f3cfa | 769 | |
6a9c6f68 KA |
770 | WRITEL(0x0, mfc_regs->e_metadata_buffer_addr); |
771 | WRITEL(0x0, mfc_regs->e_metadata_buffer_size); | |
f96f3cfa JP |
772 | |
773 | mfc_debug_leave(); | |
774 | ||
775 | return 0; | |
776 | } | |
777 | ||
778 | static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) | |
779 | { | |
780 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 781 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
782 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
783 | struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264; | |
784 | unsigned int reg = 0; | |
785 | int i; | |
786 | ||
787 | mfc_debug_enter(); | |
788 | ||
789 | s5p_mfc_set_enc_params(ctx); | |
790 | ||
791 | /* pictype : number of B */ | |
6a9c6f68 | 792 | reg = READL(mfc_regs->e_gop_config); |
f96f3cfa JP |
793 | reg &= ~(0x3 << 16); |
794 | reg |= ((p->num_b_frame & 0x3) << 16); | |
6a9c6f68 | 795 | WRITEL(reg, mfc_regs->e_gop_config); |
f96f3cfa JP |
796 | |
797 | /* profile & level */ | |
798 | reg = 0; | |
799 | /** level */ | |
800 | reg |= ((p_h264->level & 0xFF) << 8); | |
801 | /** profile - 0 ~ 3 */ | |
802 | reg |= p_h264->profile & 0x3F; | |
6a9c6f68 | 803 | WRITEL(reg, mfc_regs->e_picture_profile); |
f96f3cfa JP |
804 | |
805 | /* rate control config. */ | |
6a9c6f68 | 806 | reg = READL(mfc_regs->e_rc_config); |
f96f3cfa JP |
807 | /** macroblock level rate control */ |
808 | reg &= ~(0x1 << 8); | |
809 | reg |= ((p->rc_mb & 0x1) << 8); | |
6a9c6f68 KA |
810 | WRITEL(reg, mfc_regs->e_rc_config); |
811 | ||
f96f3cfa JP |
812 | /** frame QP */ |
813 | reg &= ~(0x3F); | |
814 | reg |= p_h264->rc_frame_qp & 0x3F; | |
6a9c6f68 | 815 | WRITEL(reg, mfc_regs->e_rc_config); |
f96f3cfa JP |
816 | |
817 | /* max & min value of QP */ | |
818 | reg = 0; | |
819 | /** max QP */ | |
820 | reg |= ((p_h264->rc_max_qp & 0x3F) << 8); | |
821 | /** min QP */ | |
822 | reg |= p_h264->rc_min_qp & 0x3F; | |
6a9c6f68 | 823 | WRITEL(reg, mfc_regs->e_rc_qp_bound); |
f96f3cfa JP |
824 | |
825 | /* other QPs */ | |
6a9c6f68 | 826 | WRITEL(0x0, mfc_regs->e_fixed_picture_qp); |
f96f3cfa JP |
827 | if (!p->rc_frame && !p->rc_mb) { |
828 | reg = 0; | |
829 | reg |= ((p_h264->rc_b_frame_qp & 0x3F) << 16); | |
830 | reg |= ((p_h264->rc_p_frame_qp & 0x3F) << 8); | |
831 | reg |= p_h264->rc_frame_qp & 0x3F; | |
6a9c6f68 | 832 | WRITEL(reg, mfc_regs->e_fixed_picture_qp); |
f96f3cfa JP |
833 | } |
834 | ||
835 | /* frame rate */ | |
836 | if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) { | |
837 | reg = 0; | |
838 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); | |
839 | reg |= p->rc_framerate_denom & 0xFFFF; | |
6a9c6f68 | 840 | WRITEL(reg, mfc_regs->e_rc_frame_rate); |
f96f3cfa JP |
841 | } |
842 | ||
843 | /* vbv buffer size */ | |
844 | if (p->frame_skip_mode == | |
845 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { | |
846 | WRITEL(p_h264->cpb_size & 0xFFFF, | |
6a9c6f68 | 847 | mfc_regs->e_vbv_buffer_size); |
f96f3cfa JP |
848 | |
849 | if (p->rc_frame) | |
6a9c6f68 | 850 | WRITEL(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
f96f3cfa JP |
851 | } |
852 | ||
853 | /* interlace */ | |
854 | reg = 0; | |
855 | reg |= ((p_h264->interlace & 0x1) << 3); | |
6a9c6f68 | 856 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa JP |
857 | |
858 | /* height */ | |
859 | if (p_h264->interlace) { | |
860 | WRITEL(ctx->img_height >> 1, | |
6a9c6f68 | 861 | mfc_regs->e_frame_height); /* 32 align */ |
f96f3cfa JP |
862 | /* cropped height */ |
863 | WRITEL(ctx->img_height >> 1, | |
6a9c6f68 | 864 | mfc_regs->e_cropped_frame_height); |
f96f3cfa JP |
865 | } |
866 | ||
867 | /* loop filter ctrl */ | |
6a9c6f68 | 868 | reg = READL(mfc_regs->e_h264_options); |
f96f3cfa JP |
869 | reg &= ~(0x3 << 1); |
870 | reg |= ((p_h264->loop_filter_mode & 0x3) << 1); | |
6a9c6f68 | 871 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa JP |
872 | |
873 | /* loopfilter alpha offset */ | |
874 | if (p_h264->loop_filter_alpha < 0) { | |
875 | reg = 0x10; | |
876 | reg |= (0xFF - p_h264->loop_filter_alpha) + 1; | |
877 | } else { | |
878 | reg = 0x00; | |
879 | reg |= (p_h264->loop_filter_alpha & 0xF); | |
880 | } | |
6a9c6f68 | 881 | WRITEL(reg, mfc_regs->e_h264_lf_alpha_offset); |
f96f3cfa JP |
882 | |
883 | /* loopfilter beta offset */ | |
884 | if (p_h264->loop_filter_beta < 0) { | |
885 | reg = 0x10; | |
886 | reg |= (0xFF - p_h264->loop_filter_beta) + 1; | |
887 | } else { | |
888 | reg = 0x00; | |
889 | reg |= (p_h264->loop_filter_beta & 0xF); | |
890 | } | |
6a9c6f68 | 891 | WRITEL(reg, mfc_regs->e_h264_lf_beta_offset); |
f96f3cfa JP |
892 | |
893 | /* entropy coding mode */ | |
6a9c6f68 | 894 | reg = READL(mfc_regs->e_h264_options); |
f96f3cfa JP |
895 | reg &= ~(0x1); |
896 | reg |= p_h264->entropy_mode & 0x1; | |
6a9c6f68 | 897 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa JP |
898 | |
899 | /* number of ref. picture */ | |
6a9c6f68 | 900 | reg = READL(mfc_regs->e_h264_options); |
f96f3cfa JP |
901 | reg &= ~(0x1 << 7); |
902 | reg |= (((p_h264->num_ref_pic_4p - 1) & 0x1) << 7); | |
6a9c6f68 | 903 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa JP |
904 | |
905 | /* 8x8 transform enable */ | |
6a9c6f68 | 906 | reg = READL(mfc_regs->e_h264_options); |
f96f3cfa JP |
907 | reg &= ~(0x3 << 12); |
908 | reg |= ((p_h264->_8x8_transform & 0x3) << 12); | |
6a9c6f68 | 909 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa JP |
910 | |
911 | /* macroblock adaptive scaling features */ | |
6a9c6f68 | 912 | WRITEL(0x0, mfc_regs->e_mb_rc_config); |
f96f3cfa JP |
913 | if (p->rc_mb) { |
914 | reg = 0; | |
915 | /** dark region */ | |
916 | reg |= ((p_h264->rc_mb_dark & 0x1) << 3); | |
917 | /** smooth region */ | |
918 | reg |= ((p_h264->rc_mb_smooth & 0x1) << 2); | |
919 | /** static region */ | |
920 | reg |= ((p_h264->rc_mb_static & 0x1) << 1); | |
921 | /** high activity region */ | |
922 | reg |= p_h264->rc_mb_activity & 0x1; | |
6a9c6f68 | 923 | WRITEL(reg, mfc_regs->e_mb_rc_config); |
f96f3cfa JP |
924 | } |
925 | ||
926 | /* aspect ratio VUI */ | |
6a9c6f68 | 927 | READL(mfc_regs->e_h264_options); |
f96f3cfa JP |
928 | reg &= ~(0x1 << 5); |
929 | reg |= ((p_h264->vui_sar & 0x1) << 5); | |
6a9c6f68 | 930 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa | 931 | |
6a9c6f68 KA |
932 | WRITEL(0x0, mfc_regs->e_aspect_ratio); |
933 | WRITEL(0x0, mfc_regs->e_extended_sar); | |
f96f3cfa JP |
934 | if (p_h264->vui_sar) { |
935 | /* aspect ration IDC */ | |
936 | reg = 0; | |
937 | reg |= p_h264->vui_sar_idc & 0xFF; | |
6a9c6f68 | 938 | WRITEL(reg, mfc_regs->e_aspect_ratio); |
f96f3cfa JP |
939 | if (p_h264->vui_sar_idc == 0xFF) { |
940 | /* extended SAR */ | |
941 | reg = 0; | |
942 | reg |= (p_h264->vui_ext_sar_width & 0xFFFF) << 16; | |
943 | reg |= p_h264->vui_ext_sar_height & 0xFFFF; | |
6a9c6f68 | 944 | WRITEL(reg, mfc_regs->e_extended_sar); |
f96f3cfa JP |
945 | } |
946 | } | |
947 | ||
948 | /* intra picture period for H.264 open GOP */ | |
949 | /* control */ | |
6a9c6f68 | 950 | READL(mfc_regs->e_h264_options); |
f96f3cfa JP |
951 | reg &= ~(0x1 << 4); |
952 | reg |= ((p_h264->open_gop & 0x1) << 4); | |
6a9c6f68 KA |
953 | WRITEL(reg, mfc_regs->e_h264_options); |
954 | ||
f96f3cfa | 955 | /* value */ |
6a9c6f68 | 956 | WRITEL(0x0, mfc_regs->e_h264_i_period); |
f96f3cfa JP |
957 | if (p_h264->open_gop) { |
958 | reg = 0; | |
959 | reg |= p_h264->open_gop_size & 0xFFFF; | |
6a9c6f68 | 960 | WRITEL(reg, mfc_regs->e_h264_i_period); |
f96f3cfa JP |
961 | } |
962 | ||
963 | /* 'WEIGHTED_BI_PREDICTION' for B is disable */ | |
6a9c6f68 | 964 | READL(mfc_regs->e_h264_options); |
f96f3cfa | 965 | reg &= ~(0x3 << 9); |
6a9c6f68 | 966 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa JP |
967 | |
968 | /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */ | |
6a9c6f68 | 969 | READL(mfc_regs->e_h264_options); |
f96f3cfa | 970 | reg &= ~(0x1 << 14); |
6a9c6f68 | 971 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa JP |
972 | |
973 | /* ASO */ | |
6a9c6f68 | 974 | READL(mfc_regs->e_h264_options); |
f96f3cfa JP |
975 | reg &= ~(0x1 << 6); |
976 | reg |= ((p_h264->aso & 0x1) << 6); | |
6a9c6f68 | 977 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa JP |
978 | |
979 | /* hier qp enable */ | |
6a9c6f68 | 980 | READL(mfc_regs->e_h264_options); |
f96f3cfa JP |
981 | reg &= ~(0x1 << 8); |
982 | reg |= ((p_h264->open_gop & 0x1) << 8); | |
6a9c6f68 | 983 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa JP |
984 | reg = 0; |
985 | if (p_h264->hier_qp && p_h264->hier_qp_layer) { | |
986 | reg |= (p_h264->hier_qp_type & 0x1) << 0x3; | |
987 | reg |= p_h264->hier_qp_layer & 0x7; | |
6a9c6f68 | 988 | WRITEL(reg, mfc_regs->e_h264_num_t_layer); |
f96f3cfa | 989 | /* QP value for each layer */ |
6a9c6f68 KA |
990 | for (i = 0; i < p_h264->hier_qp_layer && |
991 | i < ARRAY_SIZE(p_h264->hier_qp_layer_qp); i++) { | |
f96f3cfa | 992 | WRITEL(p_h264->hier_qp_layer_qp[i], |
6a9c6f68 KA |
993 | mfc_regs->e_h264_hierarchical_qp_layer0 |
994 | + i * 4); | |
995 | } | |
f96f3cfa JP |
996 | } |
997 | /* number of coding layer should be zero when hierarchical is disable */ | |
6a9c6f68 | 998 | WRITEL(reg, mfc_regs->e_h264_num_t_layer); |
f96f3cfa JP |
999 | |
1000 | /* frame packing SEI generation */ | |
6a9c6f68 | 1001 | READL(mfc_regs->e_h264_options); |
f96f3cfa JP |
1002 | reg &= ~(0x1 << 25); |
1003 | reg |= ((p_h264->sei_frame_packing & 0x1) << 25); | |
6a9c6f68 | 1004 | WRITEL(reg, mfc_regs->e_h264_options); |
f96f3cfa JP |
1005 | if (p_h264->sei_frame_packing) { |
1006 | reg = 0; | |
1007 | /** current frame0 flag */ | |
1008 | reg |= ((p_h264->sei_fp_curr_frame_0 & 0x1) << 2); | |
1009 | /** arrangement type */ | |
1010 | reg |= p_h264->sei_fp_arrangement_type & 0x3; | |
6a9c6f68 | 1011 | WRITEL(reg, mfc_regs->e_h264_frame_packing_sei_info); |
f96f3cfa JP |
1012 | } |
1013 | ||
1014 | if (p_h264->fmo) { | |
1015 | switch (p_h264->fmo_map_type) { | |
1016 | case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES: | |
1017 | if (p_h264->fmo_slice_grp > 4) | |
1018 | p_h264->fmo_slice_grp = 4; | |
1019 | for (i = 0; i < (p_h264->fmo_slice_grp & 0xF); i++) | |
1020 | WRITEL(p_h264->fmo_run_len[i] - 1, | |
6a9c6f68 KA |
1021 | mfc_regs->e_h264_fmo_run_length_minus1_0 |
1022 | + i * 4); | |
f96f3cfa JP |
1023 | break; |
1024 | case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES: | |
1025 | if (p_h264->fmo_slice_grp > 4) | |
1026 | p_h264->fmo_slice_grp = 4; | |
1027 | break; | |
1028 | case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN: | |
1029 | case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN: | |
1030 | if (p_h264->fmo_slice_grp > 2) | |
1031 | p_h264->fmo_slice_grp = 2; | |
1032 | WRITEL(p_h264->fmo_chg_dir & 0x1, | |
6a9c6f68 | 1033 | mfc_regs->e_h264_fmo_slice_grp_change_dir); |
f96f3cfa JP |
1034 | /* the valid range is 0 ~ number of macroblocks -1 */ |
1035 | WRITEL(p_h264->fmo_chg_rate, | |
6a9c6f68 | 1036 | mfc_regs->e_h264_fmo_slice_grp_change_rate_minus1); |
f96f3cfa JP |
1037 | break; |
1038 | default: | |
1039 | mfc_err("Unsupported map type for FMO: %d\n", | |
1040 | p_h264->fmo_map_type); | |
1041 | p_h264->fmo_map_type = 0; | |
1042 | p_h264->fmo_slice_grp = 1; | |
1043 | break; | |
1044 | } | |
1045 | ||
1046 | WRITEL(p_h264->fmo_map_type, | |
6a9c6f68 | 1047 | mfc_regs->e_h264_fmo_slice_grp_map_type); |
f96f3cfa | 1048 | WRITEL(p_h264->fmo_slice_grp - 1, |
6a9c6f68 | 1049 | mfc_regs->e_h264_fmo_num_slice_grp_minus1); |
f96f3cfa | 1050 | } else { |
6a9c6f68 | 1051 | WRITEL(0, mfc_regs->e_h264_fmo_num_slice_grp_minus1); |
f96f3cfa JP |
1052 | } |
1053 | ||
1054 | mfc_debug_leave(); | |
1055 | ||
1056 | return 0; | |
1057 | } | |
1058 | ||
1059 | static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) | |
1060 | { | |
1061 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 1062 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
1063 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
1064 | struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4; | |
1065 | unsigned int reg = 0; | |
1066 | ||
1067 | mfc_debug_enter(); | |
1068 | ||
1069 | s5p_mfc_set_enc_params(ctx); | |
1070 | ||
1071 | /* pictype : number of B */ | |
6a9c6f68 | 1072 | reg = READL(mfc_regs->e_gop_config); |
f96f3cfa JP |
1073 | reg &= ~(0x3 << 16); |
1074 | reg |= ((p->num_b_frame & 0x3) << 16); | |
6a9c6f68 | 1075 | WRITEL(reg, mfc_regs->e_gop_config); |
f96f3cfa JP |
1076 | |
1077 | /* profile & level */ | |
1078 | reg = 0; | |
1079 | /** level */ | |
1080 | reg |= ((p_mpeg4->level & 0xFF) << 8); | |
1081 | /** profile - 0 ~ 1 */ | |
1082 | reg |= p_mpeg4->profile & 0x3F; | |
6a9c6f68 | 1083 | WRITEL(reg, mfc_regs->e_picture_profile); |
f96f3cfa JP |
1084 | |
1085 | /* rate control config. */ | |
6a9c6f68 | 1086 | reg = READL(mfc_regs->e_rc_config); |
f96f3cfa JP |
1087 | /** macroblock level rate control */ |
1088 | reg &= ~(0x1 << 8); | |
1089 | reg |= ((p->rc_mb & 0x1) << 8); | |
6a9c6f68 KA |
1090 | WRITEL(reg, mfc_regs->e_rc_config); |
1091 | ||
f96f3cfa JP |
1092 | /** frame QP */ |
1093 | reg &= ~(0x3F); | |
1094 | reg |= p_mpeg4->rc_frame_qp & 0x3F; | |
6a9c6f68 | 1095 | WRITEL(reg, mfc_regs->e_rc_config); |
f96f3cfa JP |
1096 | |
1097 | /* max & min value of QP */ | |
1098 | reg = 0; | |
1099 | /** max QP */ | |
1100 | reg |= ((p_mpeg4->rc_max_qp & 0x3F) << 8); | |
1101 | /** min QP */ | |
1102 | reg |= p_mpeg4->rc_min_qp & 0x3F; | |
6a9c6f68 | 1103 | WRITEL(reg, mfc_regs->e_rc_qp_bound); |
f96f3cfa JP |
1104 | |
1105 | /* other QPs */ | |
6a9c6f68 | 1106 | WRITEL(0x0, mfc_regs->e_fixed_picture_qp); |
f96f3cfa JP |
1107 | if (!p->rc_frame && !p->rc_mb) { |
1108 | reg = 0; | |
1109 | reg |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 16); | |
1110 | reg |= ((p_mpeg4->rc_p_frame_qp & 0x3F) << 8); | |
1111 | reg |= p_mpeg4->rc_frame_qp & 0x3F; | |
6a9c6f68 | 1112 | WRITEL(reg, mfc_regs->e_fixed_picture_qp); |
f96f3cfa JP |
1113 | } |
1114 | ||
1115 | /* frame rate */ | |
1116 | if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) { | |
1117 | reg = 0; | |
1118 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); | |
1119 | reg |= p->rc_framerate_denom & 0xFFFF; | |
6a9c6f68 | 1120 | WRITEL(reg, mfc_regs->e_rc_frame_rate); |
f96f3cfa JP |
1121 | } |
1122 | ||
1123 | /* vbv buffer size */ | |
1124 | if (p->frame_skip_mode == | |
1125 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { | |
6a9c6f68 | 1126 | WRITEL(p->vbv_size & 0xFFFF, mfc_regs->e_vbv_buffer_size); |
f96f3cfa JP |
1127 | |
1128 | if (p->rc_frame) | |
6a9c6f68 | 1129 | WRITEL(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
f96f3cfa JP |
1130 | } |
1131 | ||
1132 | /* Disable HEC */ | |
6a9c6f68 KA |
1133 | WRITEL(0x0, mfc_regs->e_mpeg4_options); |
1134 | WRITEL(0x0, mfc_regs->e_mpeg4_hec_period); | |
f96f3cfa JP |
1135 | |
1136 | mfc_debug_leave(); | |
1137 | ||
1138 | return 0; | |
1139 | } | |
1140 | ||
1141 | static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) | |
1142 | { | |
1143 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 1144 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
1145 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
1146 | struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4; | |
1147 | unsigned int reg = 0; | |
1148 | ||
1149 | mfc_debug_enter(); | |
1150 | ||
1151 | s5p_mfc_set_enc_params(ctx); | |
1152 | ||
1153 | /* profile & level */ | |
1154 | reg = 0; | |
1155 | /** profile */ | |
1156 | reg |= (0x1 << 4); | |
6a9c6f68 | 1157 | WRITEL(reg, mfc_regs->e_picture_profile); |
f96f3cfa JP |
1158 | |
1159 | /* rate control config. */ | |
6a9c6f68 | 1160 | reg = READL(mfc_regs->e_rc_config); |
f96f3cfa JP |
1161 | /** macroblock level rate control */ |
1162 | reg &= ~(0x1 << 8); | |
1163 | reg |= ((p->rc_mb & 0x1) << 8); | |
6a9c6f68 KA |
1164 | WRITEL(reg, mfc_regs->e_rc_config); |
1165 | ||
f96f3cfa JP |
1166 | /** frame QP */ |
1167 | reg &= ~(0x3F); | |
1168 | reg |= p_h263->rc_frame_qp & 0x3F; | |
6a9c6f68 | 1169 | WRITEL(reg, mfc_regs->e_rc_config); |
f96f3cfa JP |
1170 | |
1171 | /* max & min value of QP */ | |
1172 | reg = 0; | |
1173 | /** max QP */ | |
1174 | reg |= ((p_h263->rc_max_qp & 0x3F) << 8); | |
1175 | /** min QP */ | |
1176 | reg |= p_h263->rc_min_qp & 0x3F; | |
6a9c6f68 | 1177 | WRITEL(reg, mfc_regs->e_rc_qp_bound); |
f96f3cfa JP |
1178 | |
1179 | /* other QPs */ | |
6a9c6f68 | 1180 | WRITEL(0x0, mfc_regs->e_fixed_picture_qp); |
f96f3cfa JP |
1181 | if (!p->rc_frame && !p->rc_mb) { |
1182 | reg = 0; | |
1183 | reg |= ((p_h263->rc_b_frame_qp & 0x3F) << 16); | |
1184 | reg |= ((p_h263->rc_p_frame_qp & 0x3F) << 8); | |
1185 | reg |= p_h263->rc_frame_qp & 0x3F; | |
6a9c6f68 | 1186 | WRITEL(reg, mfc_regs->e_fixed_picture_qp); |
f96f3cfa JP |
1187 | } |
1188 | ||
1189 | /* frame rate */ | |
1190 | if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) { | |
1191 | reg = 0; | |
1192 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); | |
1193 | reg |= p->rc_framerate_denom & 0xFFFF; | |
6a9c6f68 | 1194 | WRITEL(reg, mfc_regs->e_rc_frame_rate); |
f96f3cfa JP |
1195 | } |
1196 | ||
1197 | /* vbv buffer size */ | |
1198 | if (p->frame_skip_mode == | |
1199 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { | |
6a9c6f68 | 1200 | WRITEL(p->vbv_size & 0xFFFF, mfc_regs->e_vbv_buffer_size); |
f96f3cfa JP |
1201 | |
1202 | if (p->rc_frame) | |
6a9c6f68 | 1203 | WRITEL(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
f96f3cfa JP |
1204 | } |
1205 | ||
1206 | mfc_debug_leave(); | |
1207 | ||
1208 | return 0; | |
1209 | } | |
1210 | ||
3a967706 AK |
1211 | static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx) |
1212 | { | |
1213 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 1214 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
3a967706 AK |
1215 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
1216 | struct s5p_mfc_vp8_enc_params *p_vp8 = &p->codec.vp8; | |
1217 | unsigned int reg = 0; | |
1218 | unsigned int val = 0; | |
1219 | ||
1220 | mfc_debug_enter(); | |
1221 | ||
1222 | s5p_mfc_set_enc_params(ctx); | |
1223 | ||
1224 | /* pictype : number of B */ | |
6a9c6f68 | 1225 | reg = READL(mfc_regs->e_gop_config); |
3a967706 AK |
1226 | reg &= ~(0x3 << 16); |
1227 | reg |= ((p->num_b_frame & 0x3) << 16); | |
6a9c6f68 | 1228 | WRITEL(reg, mfc_regs->e_gop_config); |
3a967706 | 1229 | |
bbd8f3fe KA |
1230 | /* profile - 0 ~ 3 */ |
1231 | reg = p_vp8->profile & 0x3; | |
6a9c6f68 | 1232 | WRITEL(reg, mfc_regs->e_picture_profile); |
3a967706 AK |
1233 | |
1234 | /* rate control config. */ | |
6a9c6f68 | 1235 | reg = READL(mfc_regs->e_rc_config); |
3a967706 AK |
1236 | /** macroblock level rate control */ |
1237 | reg &= ~(0x1 << 8); | |
1238 | reg |= ((p->rc_mb & 0x1) << 8); | |
6a9c6f68 | 1239 | WRITEL(reg, mfc_regs->e_rc_config); |
3a967706 AK |
1240 | |
1241 | /* frame rate */ | |
1242 | if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) { | |
1243 | reg = 0; | |
1244 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); | |
1245 | reg |= p->rc_framerate_denom & 0xFFFF; | |
6a9c6f68 | 1246 | WRITEL(reg, mfc_regs->e_rc_frame_rate); |
3a967706 AK |
1247 | } |
1248 | ||
4773ab99 AK |
1249 | /* frame QP */ |
1250 | reg &= ~(0x7F); | |
1251 | reg |= p_vp8->rc_frame_qp & 0x7F; | |
6a9c6f68 | 1252 | WRITEL(reg, mfc_regs->e_rc_config); |
4773ab99 AK |
1253 | |
1254 | /* other QPs */ | |
6a9c6f68 | 1255 | WRITEL(0x0, mfc_regs->e_fixed_picture_qp); |
4773ab99 AK |
1256 | if (!p->rc_frame && !p->rc_mb) { |
1257 | reg = 0; | |
1258 | reg |= ((p_vp8->rc_p_frame_qp & 0x7F) << 8); | |
1259 | reg |= p_vp8->rc_frame_qp & 0x7F; | |
6a9c6f68 | 1260 | WRITEL(reg, mfc_regs->e_fixed_picture_qp); |
4773ab99 AK |
1261 | } |
1262 | ||
1263 | /* max QP */ | |
1264 | reg = ((p_vp8->rc_max_qp & 0x7F) << 8); | |
1265 | /* min QP */ | |
1266 | reg |= p_vp8->rc_min_qp & 0x7F; | |
6a9c6f68 | 1267 | WRITEL(reg, mfc_regs->e_rc_qp_bound); |
4773ab99 | 1268 | |
3a967706 AK |
1269 | /* vbv buffer size */ |
1270 | if (p->frame_skip_mode == | |
1271 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { | |
6a9c6f68 | 1272 | WRITEL(p->vbv_size & 0xFFFF, mfc_regs->e_vbv_buffer_size); |
3a967706 AK |
1273 | |
1274 | if (p->rc_frame) | |
6a9c6f68 | 1275 | WRITEL(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
3a967706 AK |
1276 | } |
1277 | ||
1278 | /* VP8 specific params */ | |
1279 | reg = 0; | |
1280 | reg |= (p_vp8->imd_4x4 & 0x1) << 10; | |
1281 | switch (p_vp8->num_partitions) { | |
1282 | case V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION: | |
1283 | val = 0; | |
1284 | break; | |
1285 | case V4L2_CID_MPEG_VIDEO_VPX_2_PARTITIONS: | |
1286 | val = 2; | |
1287 | break; | |
1288 | case V4L2_CID_MPEG_VIDEO_VPX_4_PARTITIONS: | |
1289 | val = 4; | |
1290 | break; | |
1291 | case V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS: | |
1292 | val = 8; | |
1293 | break; | |
1294 | } | |
1295 | reg |= (val & 0xF) << 3; | |
1296 | reg |= (p_vp8->num_ref & 0x2); | |
6a9c6f68 | 1297 | WRITEL(reg, mfc_regs->e_vp8_options); |
3a967706 AK |
1298 | |
1299 | mfc_debug_leave(); | |
1300 | ||
1301 | return 0; | |
1302 | } | |
1303 | ||
f96f3cfa | 1304 | /* Initialize decoding */ |
b9571a57 | 1305 | static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
1306 | { |
1307 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 1308 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
1309 | unsigned int reg = 0; |
1310 | int fmo_aso_ctrl = 0; | |
1311 | ||
1312 | mfc_debug_enter(); | |
1313 | mfc_debug(2, "InstNo: %d/%d\n", ctx->inst_no, | |
1314 | S5P_FIMV_CH_SEQ_HEADER_V6); | |
1315 | mfc_debug(2, "BUFs: %08x %08x %08x\n", | |
6a9c6f68 KA |
1316 | READL(mfc_regs->d_cpb_buffer_addr), |
1317 | READL(mfc_regs->d_cpb_buffer_addr), | |
1318 | READL(mfc_regs->d_cpb_buffer_addr)); | |
f96f3cfa JP |
1319 | |
1320 | /* FMO_ASO_CTRL - 0: Enable, 1: Disable */ | |
1321 | reg |= (fmo_aso_ctrl << S5P_FIMV_D_OPT_FMO_ASO_CTRL_MASK_V6); | |
1322 | ||
1323 | /* When user sets desplay_delay to 0, | |
1324 | * It works as "display_delay enable" and delay set to 0. | |
1325 | * If user wants display_delay disable, It should be | |
1326 | * set to negative value. */ | |
1327 | if (ctx->display_delay >= 0) { | |
1328 | reg |= (0x1 << S5P_FIMV_D_OPT_DDELAY_EN_SHIFT_V6); | |
6a9c6f68 | 1329 | WRITEL(ctx->display_delay, mfc_regs->d_display_delay); |
f96f3cfa | 1330 | } |
debe6267 | 1331 | |
109b794c | 1332 | if (IS_MFCV7_PLUS(dev)) { |
6a9c6f68 | 1333 | WRITEL(reg, mfc_regs->d_dec_options); |
debe6267 AK |
1334 | reg = 0; |
1335 | } | |
1336 | ||
f96f3cfa JP |
1337 | /* Setup loop filter, for decoding this is only valid for MPEG4 */ |
1338 | if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_DEC) { | |
1339 | mfc_debug(2, "Set loop filter to: %d\n", | |
1340 | ctx->loop_filter_mpeg4); | |
1341 | reg |= (ctx->loop_filter_mpeg4 << | |
1342 | S5P_FIMV_D_OPT_LF_CTRL_SHIFT_V6); | |
1343 | } | |
1344 | if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) | |
1345 | reg |= (0x1 << S5P_FIMV_D_OPT_TILE_MODE_SHIFT_V6); | |
1346 | ||
109b794c | 1347 | if (IS_MFCV7_PLUS(dev)) |
6a9c6f68 | 1348 | WRITEL(reg, mfc_regs->d_init_buffer_options); |
debe6267 | 1349 | else |
6a9c6f68 | 1350 | WRITEL(reg, mfc_regs->d_dec_options); |
f96f3cfa JP |
1351 | |
1352 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ | |
1353 | if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M) | |
6a9c6f68 | 1354 | WRITEL(0x1, mfc_regs->pixel_format); |
f96f3cfa | 1355 | else |
6a9c6f68 | 1356 | WRITEL(0x0, mfc_regs->pixel_format); |
f96f3cfa | 1357 | |
debe6267 | 1358 | |
f96f3cfa | 1359 | /* sei parse */ |
6a9c6f68 | 1360 | WRITEL(ctx->sei_fp_parse & 0x1, mfc_regs->d_sei_enable); |
f96f3cfa | 1361 | |
6a9c6f68 | 1362 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
f96f3cfa JP |
1363 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
1364 | S5P_FIMV_CH_SEQ_HEADER_V6, NULL); | |
1365 | ||
1366 | mfc_debug_leave(); | |
1367 | return 0; | |
1368 | } | |
1369 | ||
1370 | static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush) | |
1371 | { | |
1372 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 1373 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
8f23cc02 AK |
1374 | |
1375 | if (flush) { | |
1376 | dev->curr_ctx = ctx->num; | |
1377 | s5p_mfc_clean_ctx_int_flags(ctx); | |
6a9c6f68 | 1378 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
8f23cc02 AK |
1379 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
1380 | S5P_FIMV_H2R_CMD_FLUSH_V6, NULL); | |
1381 | } | |
f96f3cfa JP |
1382 | } |
1383 | ||
1384 | /* Decode a single frame */ | |
b9571a57 | 1385 | static int s5p_mfc_decode_one_frame_v6(struct s5p_mfc_ctx *ctx, |
f96f3cfa JP |
1386 | enum s5p_mfc_decode_arg last_frame) |
1387 | { | |
1388 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 1389 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa | 1390 | |
6a9c6f68 KA |
1391 | WRITEL(ctx->dec_dst_flag, mfc_regs->d_available_dpb_flag_lower); |
1392 | WRITEL(ctx->slice_interface & 0x1, mfc_regs->d_slice_if_enable); | |
f96f3cfa | 1393 | |
6a9c6f68 | 1394 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
f96f3cfa JP |
1395 | /* Issue different commands to instance basing on whether it |
1396 | * is the last frame or not. */ | |
1397 | switch (last_frame) { | |
1398 | case 0: | |
1399 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, | |
1400 | S5P_FIMV_CH_FRAME_START_V6, NULL); | |
1401 | break; | |
1402 | case 1: | |
1403 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, | |
1404 | S5P_FIMV_CH_LAST_FRAME_V6, NULL); | |
1405 | break; | |
1406 | default: | |
1407 | mfc_err("Unsupported last frame arg.\n"); | |
1408 | return -EINVAL; | |
1409 | } | |
1410 | ||
1411 | mfc_debug(2, "Decoding a usual frame.\n"); | |
1412 | return 0; | |
1413 | } | |
1414 | ||
b9571a57 | 1415 | static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
1416 | { |
1417 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 1418 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
1419 | |
1420 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) | |
1421 | s5p_mfc_set_enc_params_h264(ctx); | |
1422 | else if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_ENC) | |
1423 | s5p_mfc_set_enc_params_mpeg4(ctx); | |
1424 | else if (ctx->codec_mode == S5P_MFC_CODEC_H263_ENC) | |
1425 | s5p_mfc_set_enc_params_h263(ctx); | |
3a967706 AK |
1426 | else if (ctx->codec_mode == S5P_MFC_CODEC_VP8_ENC) |
1427 | s5p_mfc_set_enc_params_vp8(ctx); | |
f96f3cfa JP |
1428 | else { |
1429 | mfc_err("Unknown codec for encoding (%x).\n", | |
1430 | ctx->codec_mode); | |
1431 | return -EINVAL; | |
1432 | } | |
1433 | ||
6a9c6f68 | 1434 | /* Set stride lengths for v7 & above */ |
109b794c | 1435 | if (IS_MFCV7_PLUS(dev)) { |
6a9c6f68 KA |
1436 | WRITEL(ctx->img_width, mfc_regs->e_source_first_plane_stride); |
1437 | WRITEL(ctx->img_width, mfc_regs->e_source_second_plane_stride); | |
debe6267 AK |
1438 | } |
1439 | ||
6a9c6f68 | 1440 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
f96f3cfa JP |
1441 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
1442 | S5P_FIMV_CH_SEQ_HEADER_V6, NULL); | |
1443 | ||
1444 | return 0; | |
1445 | } | |
1446 | ||
b9571a57 | 1447 | static int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
1448 | { |
1449 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 1450 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
1451 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
1452 | struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264; | |
1453 | int i; | |
1454 | ||
1455 | if (p_h264->aso) { | |
6a9c6f68 | 1456 | for (i = 0; i < ARRAY_SIZE(p_h264->aso_slice_order); i++) { |
f96f3cfa | 1457 | WRITEL(p_h264->aso_slice_order[i], |
6a9c6f68 KA |
1458 | mfc_regs->e_h264_aso_slice_order_0 + i * 4); |
1459 | } | |
f96f3cfa JP |
1460 | } |
1461 | return 0; | |
1462 | } | |
1463 | ||
1464 | /* Encode a single frame */ | |
b9571a57 | 1465 | static int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa JP |
1466 | { |
1467 | struct s5p_mfc_dev *dev = ctx->dev; | |
6a9c6f68 | 1468 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
f96f3cfa JP |
1469 | |
1470 | mfc_debug(2, "++\n"); | |
1471 | ||
1472 | /* memory structure cur. frame */ | |
1473 | ||
1474 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) | |
1475 | s5p_mfc_h264_set_aso_slice_order_v6(ctx); | |
1476 | ||
1477 | s5p_mfc_set_slice_mode(ctx); | |
1478 | ||
6a9c6f68 | 1479 | WRITEL(ctx->inst_no, mfc_regs->instance_id); |
f96f3cfa JP |
1480 | s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev, |
1481 | S5P_FIMV_CH_FRAME_START_V6, NULL); | |
1482 | ||
1483 | mfc_debug(2, "--\n"); | |
1484 | ||
1485 | return 0; | |
1486 | } | |
1487 | ||
1488 | static inline int s5p_mfc_get_new_ctx(struct s5p_mfc_dev *dev) | |
1489 | { | |
1490 | unsigned long flags; | |
1491 | int new_ctx; | |
1492 | int cnt; | |
1493 | ||
1494 | spin_lock_irqsave(&dev->condlock, flags); | |
1051e9b3 | 1495 | mfc_debug(2, "Previous context: %d (bits %08lx)\n", dev->curr_ctx, |
f96f3cfa JP |
1496 | dev->ctx_work_bits); |
1497 | new_ctx = (dev->curr_ctx + 1) % MFC_NUM_CONTEXTS; | |
1498 | cnt = 0; | |
1499 | while (!test_bit(new_ctx, &dev->ctx_work_bits)) { | |
1500 | new_ctx = (new_ctx + 1) % MFC_NUM_CONTEXTS; | |
1501 | cnt++; | |
1502 | if (cnt > MFC_NUM_CONTEXTS) { | |
1503 | /* No contexts to run */ | |
1504 | spin_unlock_irqrestore(&dev->condlock, flags); | |
1505 | return -EAGAIN; | |
1506 | } | |
1507 | } | |
1508 | spin_unlock_irqrestore(&dev->condlock, flags); | |
1509 | return new_ctx; | |
1510 | } | |
1511 | ||
1512 | static inline void s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx) | |
1513 | { | |
1514 | struct s5p_mfc_dev *dev = ctx->dev; | |
1515 | struct s5p_mfc_buf *temp_vb; | |
1516 | unsigned long flags; | |
1517 | ||
1518 | spin_lock_irqsave(&dev->irqlock, flags); | |
1519 | ||
1520 | /* Frames are being decoded */ | |
1521 | if (list_empty(&ctx->src_queue)) { | |
1522 | mfc_debug(2, "No src buffers.\n"); | |
1523 | spin_unlock_irqrestore(&dev->irqlock, flags); | |
1524 | return; | |
1525 | } | |
1526 | /* Get the next source buffer */ | |
1527 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); | |
1528 | temp_vb->flags |= MFC_BUF_FLAG_USED; | |
1529 | s5p_mfc_set_dec_stream_buffer_v6(ctx, | |
1530 | vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0, 0); | |
1531 | spin_unlock_irqrestore(&dev->irqlock, flags); | |
1532 | ||
1533 | dev->curr_ctx = ctx->num; | |
1534 | s5p_mfc_clean_ctx_int_flags(ctx); | |
1535 | s5p_mfc_decode_one_frame_v6(ctx, 1); | |
1536 | } | |
1537 | ||
1538 | static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx) | |
1539 | { | |
1540 | struct s5p_mfc_dev *dev = ctx->dev; | |
1541 | struct s5p_mfc_buf *temp_vb; | |
1542 | unsigned long flags; | |
1543 | int last_frame = 0; | |
f96f3cfa | 1544 | |
a34026e7 KD |
1545 | if (ctx->state == MFCINST_FINISHING) { |
1546 | last_frame = MFC_DEC_LAST_FRAME; | |
1547 | s5p_mfc_set_dec_stream_buffer_v6(ctx, 0, 0, 0); | |
1548 | dev->curr_ctx = ctx->num; | |
1549 | s5p_mfc_clean_ctx_int_flags(ctx); | |
1550 | s5p_mfc_decode_one_frame_v6(ctx, last_frame); | |
1551 | return 0; | |
1552 | } | |
f96f3cfa | 1553 | |
a34026e7 | 1554 | spin_lock_irqsave(&dev->irqlock, flags); |
f96f3cfa JP |
1555 | /* Frames are being decoded */ |
1556 | if (list_empty(&ctx->src_queue)) { | |
1557 | mfc_debug(2, "No src buffers.\n"); | |
1558 | spin_unlock_irqrestore(&dev->irqlock, flags); | |
1559 | return -EAGAIN; | |
1560 | } | |
1561 | /* Get the next source buffer */ | |
1562 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); | |
1563 | temp_vb->flags |= MFC_BUF_FLAG_USED; | |
1564 | s5p_mfc_set_dec_stream_buffer_v6(ctx, | |
1565 | vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), | |
1566 | ctx->consumed_stream, | |
1567 | temp_vb->b->v4l2_planes[0].bytesused); | |
1568 | spin_unlock_irqrestore(&dev->irqlock, flags); | |
1569 | ||
f96f3cfa JP |
1570 | dev->curr_ctx = ctx->num; |
1571 | s5p_mfc_clean_ctx_int_flags(ctx); | |
1572 | if (temp_vb->b->v4l2_planes[0].bytesused == 0) { | |
1573 | last_frame = 1; | |
1574 | mfc_debug(2, "Setting ctx->state to FINISHING\n"); | |
1575 | ctx->state = MFCINST_FINISHING; | |
1576 | } | |
1577 | s5p_mfc_decode_one_frame_v6(ctx, last_frame); | |
1578 | ||
1579 | return 0; | |
1580 | } | |
1581 | ||
1582 | static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) | |
1583 | { | |
1584 | struct s5p_mfc_dev *dev = ctx->dev; | |
1585 | unsigned long flags; | |
1586 | struct s5p_mfc_buf *dst_mb; | |
1587 | struct s5p_mfc_buf *src_mb; | |
1588 | unsigned long src_y_addr, src_c_addr, dst_addr; | |
1589 | /* | |
1590 | unsigned int src_y_size, src_c_size; | |
1591 | */ | |
1592 | unsigned int dst_size; | |
f96f3cfa JP |
1593 | |
1594 | spin_lock_irqsave(&dev->irqlock, flags); | |
1595 | ||
1596 | if (list_empty(&ctx->src_queue)) { | |
1597 | mfc_debug(2, "no src buffers.\n"); | |
1598 | spin_unlock_irqrestore(&dev->irqlock, flags); | |
1599 | return -EAGAIN; | |
1600 | } | |
1601 | ||
1602 | if (list_empty(&ctx->dst_queue)) { | |
1603 | mfc_debug(2, "no dst buffers.\n"); | |
1604 | spin_unlock_irqrestore(&dev->irqlock, flags); | |
1605 | return -EAGAIN; | |
1606 | } | |
1607 | ||
1608 | src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); | |
1609 | src_mb->flags |= MFC_BUF_FLAG_USED; | |
1610 | src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0); | |
1611 | src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1); | |
1612 | ||
4130eabc AH |
1613 | mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr); |
1614 | mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr); | |
f96f3cfa JP |
1615 | |
1616 | s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr); | |
1617 | ||
1618 | dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); | |
1619 | dst_mb->flags |= MFC_BUF_FLAG_USED; | |
1620 | dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0); | |
1621 | dst_size = vb2_plane_size(dst_mb->b, 0); | |
1622 | ||
1623 | s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size); | |
1624 | ||
1625 | spin_unlock_irqrestore(&dev->irqlock, flags); | |
1626 | ||
f96f3cfa JP |
1627 | dev->curr_ctx = ctx->num; |
1628 | s5p_mfc_clean_ctx_int_flags(ctx); | |
1629 | s5p_mfc_encode_one_frame_v6(ctx); | |
1630 | ||
1631 | return 0; | |
1632 | } | |
1633 | ||
1634 | static inline void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx) | |
1635 | { | |
1636 | struct s5p_mfc_dev *dev = ctx->dev; | |
1637 | unsigned long flags; | |
1638 | struct s5p_mfc_buf *temp_vb; | |
1639 | ||
1640 | /* Initializing decoding - parsing header */ | |
1641 | spin_lock_irqsave(&dev->irqlock, flags); | |
1642 | mfc_debug(2, "Preparing to init decoding.\n"); | |
1643 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); | |
1644 | mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused); | |
1645 | s5p_mfc_set_dec_stream_buffer_v6(ctx, | |
1646 | vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), 0, | |
1647 | temp_vb->b->v4l2_planes[0].bytesused); | |
1648 | spin_unlock_irqrestore(&dev->irqlock, flags); | |
1649 | dev->curr_ctx = ctx->num; | |
1650 | s5p_mfc_clean_ctx_int_flags(ctx); | |
1651 | s5p_mfc_init_decode_v6(ctx); | |
1652 | } | |
1653 | ||
1654 | static inline void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx) | |
1655 | { | |
1656 | struct s5p_mfc_dev *dev = ctx->dev; | |
1657 | unsigned long flags; | |
1658 | struct s5p_mfc_buf *dst_mb; | |
1659 | unsigned long dst_addr; | |
1660 | unsigned int dst_size; | |
1661 | ||
1662 | spin_lock_irqsave(&dev->irqlock, flags); | |
1663 | ||
1664 | dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); | |
1665 | dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0); | |
1666 | dst_size = vb2_plane_size(dst_mb->b, 0); | |
1667 | s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size); | |
1668 | spin_unlock_irqrestore(&dev->irqlock, flags); | |
1669 | dev->curr_ctx = ctx->num; | |
1670 | s5p_mfc_clean_ctx_int_flags(ctx); | |
1671 | s5p_mfc_init_encode_v6(ctx); | |
1672 | } | |
1673 | ||
1674 | static inline int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) | |
1675 | { | |
1676 | struct s5p_mfc_dev *dev = ctx->dev; | |
1677 | int ret; | |
1678 | /* Header was parsed now start processing | |
1679 | * First set the output frame buffers | |
1680 | * s5p_mfc_alloc_dec_buffers(ctx); */ | |
1681 | ||
1682 | if (ctx->capture_state != QUEUE_BUFS_MMAPED) { | |
1683 | mfc_err("It seems that not all destionation buffers were\n" | |
1684 | "mmaped.MFC requires that all destination are mmaped\n" | |
1685 | "before starting processing.\n"); | |
1686 | return -EAGAIN; | |
1687 | } | |
1688 | ||
1689 | dev->curr_ctx = ctx->num; | |
1690 | s5p_mfc_clean_ctx_int_flags(ctx); | |
1691 | ret = s5p_mfc_set_dec_frame_buffer_v6(ctx); | |
1692 | if (ret) { | |
1693 | mfc_err("Failed to alloc frame mem.\n"); | |
1694 | ctx->state = MFCINST_ERROR; | |
1695 | } | |
1696 | return ret; | |
1697 | } | |
1698 | ||
1699 | static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx) | |
1700 | { | |
1701 | struct s5p_mfc_dev *dev = ctx->dev; | |
1702 | int ret; | |
1703 | ||
f96f3cfa JP |
1704 | dev->curr_ctx = ctx->num; |
1705 | s5p_mfc_clean_ctx_int_flags(ctx); | |
1706 | ret = s5p_mfc_set_enc_ref_buffer_v6(ctx); | |
1707 | if (ret) { | |
1708 | mfc_err("Failed to alloc frame mem.\n"); | |
1709 | ctx->state = MFCINST_ERROR; | |
1710 | } | |
1711 | return ret; | |
1712 | } | |
1713 | ||
1714 | /* Try running an operation on hardware */ | |
b9571a57 | 1715 | static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) |
f96f3cfa JP |
1716 | { |
1717 | struct s5p_mfc_ctx *ctx; | |
1718 | int new_ctx; | |
1719 | unsigned int ret = 0; | |
1720 | ||
1721 | mfc_debug(1, "Try run dev: %p\n", dev); | |
1722 | ||
1723 | /* Check whether hardware is not running */ | |
1724 | if (test_and_set_bit(0, &dev->hw_lock) != 0) { | |
1725 | /* This is perfectly ok, the scheduled ctx should wait */ | |
1726 | mfc_debug(1, "Couldn't lock HW.\n"); | |
1727 | return; | |
1728 | } | |
1729 | ||
1730 | /* Choose the context to run */ | |
1731 | new_ctx = s5p_mfc_get_new_ctx(dev); | |
1732 | if (new_ctx < 0) { | |
1733 | /* No contexts to run */ | |
1734 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) { | |
1735 | mfc_err("Failed to unlock hardware.\n"); | |
1736 | return; | |
1737 | } | |
1738 | ||
1739 | mfc_debug(1, "No ctx is scheduled to be run.\n"); | |
1740 | return; | |
1741 | } | |
1742 | ||
1743 | mfc_debug(1, "New context: %d\n", new_ctx); | |
1744 | ctx = dev->ctx[new_ctx]; | |
1745 | mfc_debug(1, "Seting new context to %p\n", ctx); | |
1746 | /* Got context to run in ctx */ | |
1747 | mfc_debug(1, "ctx->dst_queue_cnt=%d ctx->dpb_count=%d ctx->src_queue_cnt=%d\n", | |
e9d98ddc | 1748 | ctx->dst_queue_cnt, ctx->pb_count, ctx->src_queue_cnt); |
f96f3cfa JP |
1749 | mfc_debug(1, "ctx->state=%d\n", ctx->state); |
1750 | /* Last frame has already been sent to MFC | |
1751 | * Now obtaining frames from MFC buffer */ | |
1752 | ||
1753 | s5p_mfc_clock_on(); | |
1754 | if (ctx->type == MFCINST_DECODER) { | |
1755 | switch (ctx->state) { | |
1756 | case MFCINST_FINISHING: | |
1757 | s5p_mfc_run_dec_last_frames(ctx); | |
1758 | break; | |
1759 | case MFCINST_RUNNING: | |
1760 | ret = s5p_mfc_run_dec_frame(ctx); | |
1761 | break; | |
1762 | case MFCINST_INIT: | |
1763 | s5p_mfc_clean_ctx_int_flags(ctx); | |
1764 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, | |
1765 | ctx); | |
1766 | break; | |
1767 | case MFCINST_RETURN_INST: | |
1768 | s5p_mfc_clean_ctx_int_flags(ctx); | |
1769 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, | |
1770 | ctx); | |
1771 | break; | |
1772 | case MFCINST_GOT_INST: | |
1773 | s5p_mfc_run_init_dec(ctx); | |
1774 | break; | |
1775 | case MFCINST_HEAD_PARSED: | |
1776 | ret = s5p_mfc_run_init_dec_buffers(ctx); | |
1777 | break; | |
8f23cc02 AK |
1778 | case MFCINST_FLUSH: |
1779 | s5p_mfc_set_flush(ctx, ctx->dpb_flush_flag); | |
1780 | break; | |
f96f3cfa JP |
1781 | case MFCINST_RES_CHANGE_INIT: |
1782 | s5p_mfc_run_dec_last_frames(ctx); | |
1783 | break; | |
1784 | case MFCINST_RES_CHANGE_FLUSH: | |
1785 | s5p_mfc_run_dec_last_frames(ctx); | |
1786 | break; | |
1787 | case MFCINST_RES_CHANGE_END: | |
1788 | mfc_debug(2, "Finished remaining frames after resolution change.\n"); | |
1789 | ctx->capture_state = QUEUE_FREE; | |
1790 | mfc_debug(2, "Will re-init the codec`.\n"); | |
1791 | s5p_mfc_run_init_dec(ctx); | |
1792 | break; | |
1793 | default: | |
1794 | ret = -EAGAIN; | |
1795 | } | |
1796 | } else if (ctx->type == MFCINST_ENCODER) { | |
1797 | switch (ctx->state) { | |
1798 | case MFCINST_FINISHING: | |
1799 | case MFCINST_RUNNING: | |
1800 | ret = s5p_mfc_run_enc_frame(ctx); | |
1801 | break; | |
1802 | case MFCINST_INIT: | |
1803 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, | |
1804 | ctx); | |
1805 | break; | |
1806 | case MFCINST_RETURN_INST: | |
1807 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, | |
1808 | ctx); | |
1809 | break; | |
1810 | case MFCINST_GOT_INST: | |
1811 | s5p_mfc_run_init_enc(ctx); | |
1812 | break; | |
e9d98ddc | 1813 | case MFCINST_HEAD_PRODUCED: |
f96f3cfa JP |
1814 | ret = s5p_mfc_run_init_enc_buffers(ctx); |
1815 | break; | |
1816 | default: | |
1817 | ret = -EAGAIN; | |
1818 | } | |
1819 | } else { | |
1820 | mfc_err("invalid context type: %d\n", ctx->type); | |
1821 | ret = -EAGAIN; | |
1822 | } | |
1823 | ||
1824 | if (ret) { | |
1825 | /* Free hardware lock */ | |
1826 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) | |
1827 | mfc_err("Failed to unlock hardware.\n"); | |
1828 | ||
1829 | /* This is in deed imporant, as no operation has been | |
1830 | * scheduled, reduce the clock count as no one will | |
1831 | * ever do this, because no interrupt related to this try_run | |
1832 | * will ever come from hardware. */ | |
1833 | s5p_mfc_clock_off(); | |
1834 | } | |
1835 | } | |
1836 | ||
1837 | ||
b9571a57 | 1838 | static void s5p_mfc_cleanup_queue_v6(struct list_head *lh, struct vb2_queue *vq) |
f96f3cfa JP |
1839 | { |
1840 | struct s5p_mfc_buf *b; | |
1841 | int i; | |
1842 | ||
1843 | while (!list_empty(lh)) { | |
1844 | b = list_entry(lh->next, struct s5p_mfc_buf, list); | |
1845 | for (i = 0; i < b->b->num_planes; i++) | |
1846 | vb2_set_plane_payload(b->b, i, 0); | |
1847 | vb2_buffer_done(b->b, VB2_BUF_STATE_ERROR); | |
1848 | list_del(&b->list); | |
1849 | } | |
1850 | } | |
1851 | ||
b9571a57 | 1852 | static void s5p_mfc_clear_int_flags_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1853 | { |
6a9c6f68 KA |
1854 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
1855 | WRITEL(0, mfc_regs->risc2host_command); | |
1856 | WRITEL(0, mfc_regs->risc2host_int); | |
f96f3cfa JP |
1857 | } |
1858 | ||
b9571a57 | 1859 | static void s5p_mfc_write_info_v6(struct s5p_mfc_ctx *ctx, unsigned int data, |
f96f3cfa JP |
1860 | unsigned int ofs) |
1861 | { | |
f96f3cfa | 1862 | s5p_mfc_clock_on(); |
6a9c6f68 | 1863 | WRITEL(data, (void *)ofs); |
f96f3cfa JP |
1864 | s5p_mfc_clock_off(); |
1865 | } | |
1866 | ||
b9571a57 SK |
1867 | static unsigned int |
1868 | s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned int ofs) | |
f96f3cfa | 1869 | { |
f96f3cfa JP |
1870 | int ret; |
1871 | ||
1872 | s5p_mfc_clock_on(); | |
6a9c6f68 | 1873 | ret = READL((void *)ofs); |
f96f3cfa JP |
1874 | s5p_mfc_clock_off(); |
1875 | ||
1876 | return ret; | |
1877 | } | |
1878 | ||
b9571a57 | 1879 | static int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1880 | { |
6a9c6f68 | 1881 | return READL(dev->mfc_regs->d_display_first_plane_addr); |
f96f3cfa JP |
1882 | } |
1883 | ||
b9571a57 | 1884 | static int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1885 | { |
6a9c6f68 | 1886 | return READL(dev->mfc_regs->d_decoded_first_plane_addr); |
f96f3cfa JP |
1887 | } |
1888 | ||
b9571a57 | 1889 | static int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1890 | { |
6a9c6f68 | 1891 | return READL(dev->mfc_regs->d_display_status); |
f96f3cfa JP |
1892 | } |
1893 | ||
644469ae | 1894 | static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1895 | { |
6a9c6f68 | 1896 | return READL(dev->mfc_regs->d_decoded_status); |
f96f3cfa JP |
1897 | } |
1898 | ||
b9571a57 | 1899 | static int s5p_mfc_get_dec_frame_type_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1900 | { |
6a9c6f68 | 1901 | return READL(dev->mfc_regs->d_decoded_frame_type) & |
f96f3cfa JP |
1902 | S5P_FIMV_DECODE_FRAME_MASK_V6; |
1903 | } | |
1904 | ||
b9571a57 | 1905 | static int s5p_mfc_get_disp_frame_type_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa | 1906 | { |
6a9c6f68 KA |
1907 | struct s5p_mfc_dev *dev = ctx->dev; |
1908 | return READL(dev->mfc_regs->d_display_frame_type) & | |
f96f3cfa JP |
1909 | S5P_FIMV_DECODE_FRAME_MASK_V6; |
1910 | } | |
1911 | ||
b9571a57 | 1912 | static int s5p_mfc_get_consumed_stream_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1913 | { |
6a9c6f68 | 1914 | return READL(dev->mfc_regs->d_decoded_nal_size); |
f96f3cfa JP |
1915 | } |
1916 | ||
b9571a57 | 1917 | static int s5p_mfc_get_int_reason_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1918 | { |
6a9c6f68 | 1919 | return READL(dev->mfc_regs->risc2host_command) & |
f96f3cfa JP |
1920 | S5P_FIMV_RISC2HOST_CMD_MASK; |
1921 | } | |
1922 | ||
b9571a57 | 1923 | static int s5p_mfc_get_int_err_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1924 | { |
6a9c6f68 | 1925 | return READL(dev->mfc_regs->error_code); |
f96f3cfa JP |
1926 | } |
1927 | ||
b9571a57 | 1928 | static int s5p_mfc_err_dec_v6(unsigned int err) |
f96f3cfa JP |
1929 | { |
1930 | return (err & S5P_FIMV_ERR_DEC_MASK_V6) >> S5P_FIMV_ERR_DEC_SHIFT_V6; | |
1931 | } | |
1932 | ||
b9571a57 | 1933 | static int s5p_mfc_err_dspl_v6(unsigned int err) |
f96f3cfa JP |
1934 | { |
1935 | return (err & S5P_FIMV_ERR_DSPL_MASK_V6) >> S5P_FIMV_ERR_DSPL_SHIFT_V6; | |
1936 | } | |
1937 | ||
b9571a57 | 1938 | static int s5p_mfc_get_img_width_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1939 | { |
6a9c6f68 | 1940 | return READL(dev->mfc_regs->d_display_frame_width); |
f96f3cfa JP |
1941 | } |
1942 | ||
b9571a57 | 1943 | static int s5p_mfc_get_img_height_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1944 | { |
6a9c6f68 | 1945 | return READL(dev->mfc_regs->d_display_frame_height); |
f96f3cfa JP |
1946 | } |
1947 | ||
b9571a57 | 1948 | static int s5p_mfc_get_dpb_count_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1949 | { |
6a9c6f68 | 1950 | return READL(dev->mfc_regs->d_min_num_dpb); |
f96f3cfa JP |
1951 | } |
1952 | ||
b9571a57 | 1953 | static int s5p_mfc_get_mv_count_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1954 | { |
6a9c6f68 | 1955 | return READL(dev->mfc_regs->d_min_num_mv); |
f96f3cfa JP |
1956 | } |
1957 | ||
b9571a57 | 1958 | static int s5p_mfc_get_inst_no_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1959 | { |
6a9c6f68 | 1960 | return READL(dev->mfc_regs->ret_instance_id); |
f96f3cfa JP |
1961 | } |
1962 | ||
b9571a57 | 1963 | static int s5p_mfc_get_enc_dpb_count_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1964 | { |
6a9c6f68 | 1965 | return READL(dev->mfc_regs->e_num_dpb); |
f96f3cfa JP |
1966 | } |
1967 | ||
b9571a57 | 1968 | static int s5p_mfc_get_enc_strm_size_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1969 | { |
6a9c6f68 | 1970 | return READL(dev->mfc_regs->e_stream_size); |
f96f3cfa JP |
1971 | } |
1972 | ||
b9571a57 | 1973 | static int s5p_mfc_get_enc_slice_type_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1974 | { |
6a9c6f68 | 1975 | return READL(dev->mfc_regs->e_slice_type); |
f96f3cfa JP |
1976 | } |
1977 | ||
b9571a57 | 1978 | static int s5p_mfc_get_enc_pic_count_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1979 | { |
6a9c6f68 | 1980 | return READL(dev->mfc_regs->e_picture_count); |
f96f3cfa JP |
1981 | } |
1982 | ||
b9571a57 | 1983 | static int s5p_mfc_get_sei_avail_status_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa | 1984 | { |
6a9c6f68 KA |
1985 | struct s5p_mfc_dev *dev = ctx->dev; |
1986 | return READL(dev->mfc_regs->d_frame_pack_sei_avail); | |
f96f3cfa JP |
1987 | } |
1988 | ||
b9571a57 | 1989 | static int s5p_mfc_get_mvc_num_views_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1990 | { |
6a9c6f68 | 1991 | return READL(dev->mfc_regs->d_mvc_num_views); |
f96f3cfa JP |
1992 | } |
1993 | ||
b9571a57 | 1994 | static int s5p_mfc_get_mvc_view_id_v6(struct s5p_mfc_dev *dev) |
f96f3cfa | 1995 | { |
6a9c6f68 | 1996 | return READL(dev->mfc_regs->d_mvc_view_id); |
f96f3cfa JP |
1997 | } |
1998 | ||
b9571a57 | 1999 | static unsigned int s5p_mfc_get_pic_type_top_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa | 2000 | { |
6a9c6f68 KA |
2001 | return s5p_mfc_read_info_v6(ctx, |
2002 | (unsigned int) ctx->dev->mfc_regs->d_ret_picture_tag_top); | |
f96f3cfa JP |
2003 | } |
2004 | ||
b9571a57 | 2005 | static unsigned int s5p_mfc_get_pic_type_bot_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa | 2006 | { |
6a9c6f68 KA |
2007 | return s5p_mfc_read_info_v6(ctx, |
2008 | (unsigned int) ctx->dev->mfc_regs->d_ret_picture_tag_bot); | |
f96f3cfa JP |
2009 | } |
2010 | ||
b9571a57 | 2011 | static unsigned int s5p_mfc_get_crop_info_h_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa | 2012 | { |
6a9c6f68 KA |
2013 | return s5p_mfc_read_info_v6(ctx, |
2014 | (unsigned int) ctx->dev->mfc_regs->d_display_crop_info1); | |
f96f3cfa JP |
2015 | } |
2016 | ||
b9571a57 | 2017 | static unsigned int s5p_mfc_get_crop_info_v_v6(struct s5p_mfc_ctx *ctx) |
f96f3cfa | 2018 | { |
6a9c6f68 KA |
2019 | return s5p_mfc_read_info_v6(ctx, |
2020 | (unsigned int) ctx->dev->mfc_regs->d_display_crop_info2); | |
2021 | } | |
2022 | ||
2023 | static struct s5p_mfc_regs mfc_regs; | |
2024 | ||
2025 | /* Initialize registers for MFC v6 onwards */ | |
2026 | const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev) | |
2027 | { | |
2028 | memset(&mfc_regs, 0, sizeof(mfc_regs)); | |
2029 | ||
2030 | #define S5P_MFC_REG_ADDR(dev, reg) ((dev)->regs_base + (reg)) | |
2031 | #define R(m, r) mfc_regs.m = S5P_MFC_REG_ADDR(dev, r) | |
2032 | /* codec common registers */ | |
2033 | R(risc_on, S5P_FIMV_RISC_ON_V6); | |
2034 | R(risc2host_int, S5P_FIMV_RISC2HOST_INT_V6); | |
2035 | R(host2risc_int, S5P_FIMV_HOST2RISC_INT_V6); | |
2036 | R(risc_base_address, S5P_FIMV_RISC_BASE_ADDRESS_V6); | |
2037 | R(mfc_reset, S5P_FIMV_MFC_RESET_V6); | |
2038 | R(host2risc_command, S5P_FIMV_HOST2RISC_CMD_V6); | |
2039 | R(risc2host_command, S5P_FIMV_RISC2HOST_CMD_V6); | |
2040 | R(firmware_version, S5P_FIMV_FW_VERSION_V6); | |
2041 | R(instance_id, S5P_FIMV_INSTANCE_ID_V6); | |
2042 | R(codec_type, S5P_FIMV_CODEC_TYPE_V6); | |
2043 | R(context_mem_addr, S5P_FIMV_CONTEXT_MEM_ADDR_V6); | |
2044 | R(context_mem_size, S5P_FIMV_CONTEXT_MEM_SIZE_V6); | |
2045 | R(pixel_format, S5P_FIMV_PIXEL_FORMAT_V6); | |
2046 | R(ret_instance_id, S5P_FIMV_RET_INSTANCE_ID_V6); | |
2047 | R(error_code, S5P_FIMV_ERROR_CODE_V6); | |
2048 | ||
2049 | /* decoder registers */ | |
2050 | R(d_crc_ctrl, S5P_FIMV_D_CRC_CTRL_V6); | |
2051 | R(d_dec_options, S5P_FIMV_D_DEC_OPTIONS_V6); | |
2052 | R(d_display_delay, S5P_FIMV_D_DISPLAY_DELAY_V6); | |
2053 | R(d_sei_enable, S5P_FIMV_D_SEI_ENABLE_V6); | |
2054 | R(d_min_num_dpb, S5P_FIMV_D_MIN_NUM_DPB_V6); | |
2055 | R(d_min_num_mv, S5P_FIMV_D_MIN_NUM_MV_V6); | |
2056 | R(d_mvc_num_views, S5P_FIMV_D_MVC_NUM_VIEWS_V6); | |
2057 | R(d_num_dpb, S5P_FIMV_D_NUM_DPB_V6); | |
2058 | R(d_num_mv, S5P_FIMV_D_NUM_MV_V6); | |
2059 | R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V6); | |
2060 | R(d_first_plane_dpb_size, S5P_FIMV_D_LUMA_DPB_SIZE_V6); | |
2061 | R(d_second_plane_dpb_size, S5P_FIMV_D_CHROMA_DPB_SIZE_V6); | |
2062 | R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V6); | |
2063 | R(d_first_plane_dpb, S5P_FIMV_D_LUMA_DPB_V6); | |
2064 | R(d_second_plane_dpb, S5P_FIMV_D_CHROMA_DPB_V6); | |
2065 | R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V6); | |
2066 | R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V6); | |
2067 | R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V6); | |
2068 | R(d_cpb_buffer_addr, S5P_FIMV_D_CPB_BUFFER_ADDR_V6); | |
2069 | R(d_cpb_buffer_size, S5P_FIMV_D_CPB_BUFFER_SIZE_V6); | |
2070 | R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V6); | |
2071 | R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V6); | |
2072 | R(d_slice_if_enable, S5P_FIMV_D_SLICE_IF_ENABLE_V6); | |
2073 | R(d_stream_data_size, S5P_FIMV_D_STREAM_DATA_SIZE_V6); | |
2074 | R(d_display_frame_width, S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6); | |
2075 | R(d_display_frame_height, S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V6); | |
2076 | R(d_display_status, S5P_FIMV_D_DISPLAY_STATUS_V6); | |
2077 | R(d_display_first_plane_addr, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6); | |
2078 | R(d_display_second_plane_addr, S5P_FIMV_D_DISPLAY_CHROMA_ADDR_V6); | |
2079 | R(d_display_frame_type, S5P_FIMV_D_DISPLAY_FRAME_TYPE_V6); | |
2080 | R(d_display_crop_info1, S5P_FIMV_D_DISPLAY_CROP_INFO1_V6); | |
2081 | R(d_display_crop_info2, S5P_FIMV_D_DISPLAY_CROP_INFO2_V6); | |
2082 | R(d_display_aspect_ratio, S5P_FIMV_D_DISPLAY_ASPECT_RATIO_V6); | |
2083 | R(d_display_extended_ar, S5P_FIMV_D_DISPLAY_EXTENDED_AR_V6); | |
2084 | R(d_decoded_status, S5P_FIMV_D_DECODED_STATUS_V6); | |
2085 | R(d_decoded_first_plane_addr, S5P_FIMV_D_DECODED_LUMA_ADDR_V6); | |
2086 | R(d_decoded_second_plane_addr, S5P_FIMV_D_DECODED_CHROMA_ADDR_V6); | |
2087 | R(d_decoded_frame_type, S5P_FIMV_D_DECODED_FRAME_TYPE_V6); | |
2088 | R(d_decoded_nal_size, S5P_FIMV_D_DECODED_NAL_SIZE_V6); | |
2089 | R(d_ret_picture_tag_top, S5P_FIMV_D_RET_PICTURE_TAG_TOP_V6); | |
2090 | R(d_ret_picture_tag_bot, S5P_FIMV_D_RET_PICTURE_TAG_BOT_V6); | |
2091 | R(d_h264_info, S5P_FIMV_D_H264_INFO_V6); | |
2092 | R(d_mvc_view_id, S5P_FIMV_D_MVC_VIEW_ID_V6); | |
2093 | R(d_frame_pack_sei_avail, S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V6); | |
2094 | ||
2095 | /* encoder registers */ | |
2096 | R(e_frame_width, S5P_FIMV_E_FRAME_WIDTH_V6); | |
2097 | R(e_frame_height, S5P_FIMV_E_FRAME_HEIGHT_V6); | |
2098 | R(e_cropped_frame_width, S5P_FIMV_E_CROPPED_FRAME_WIDTH_V6); | |
2099 | R(e_cropped_frame_height, S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6); | |
2100 | R(e_frame_crop_offset, S5P_FIMV_E_FRAME_CROP_OFFSET_V6); | |
2101 | R(e_enc_options, S5P_FIMV_E_ENC_OPTIONS_V6); | |
2102 | R(e_picture_profile, S5P_FIMV_E_PICTURE_PROFILE_V6); | |
2103 | R(e_vbv_buffer_size, S5P_FIMV_E_VBV_BUFFER_SIZE_V6); | |
2104 | R(e_vbv_init_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6); | |
2105 | R(e_fixed_picture_qp, S5P_FIMV_E_FIXED_PICTURE_QP_V6); | |
2106 | R(e_rc_config, S5P_FIMV_E_RC_CONFIG_V6); | |
2107 | R(e_rc_qp_bound, S5P_FIMV_E_RC_QP_BOUND_V6); | |
2108 | R(e_rc_mode, S5P_FIMV_E_RC_RPARAM_V6); | |
2109 | R(e_mb_rc_config, S5P_FIMV_E_MB_RC_CONFIG_V6); | |
2110 | R(e_padding_ctrl, S5P_FIMV_E_PADDING_CTRL_V6); | |
2111 | R(e_mv_hor_range, S5P_FIMV_E_MV_HOR_RANGE_V6); | |
2112 | R(e_mv_ver_range, S5P_FIMV_E_MV_VER_RANGE_V6); | |
2113 | R(e_num_dpb, S5P_FIMV_E_NUM_DPB_V6); | |
2114 | R(e_luma_dpb, S5P_FIMV_E_LUMA_DPB_V6); | |
2115 | R(e_chroma_dpb, S5P_FIMV_E_CHROMA_DPB_V6); | |
2116 | R(e_me_buffer, S5P_FIMV_E_ME_BUFFER_V6); | |
2117 | R(e_scratch_buffer_addr, S5P_FIMV_E_SCRATCH_BUFFER_ADDR_V6); | |
2118 | R(e_scratch_buffer_size, S5P_FIMV_E_SCRATCH_BUFFER_SIZE_V6); | |
2119 | R(e_tmv_buffer0, S5P_FIMV_E_TMV_BUFFER0_V6); | |
2120 | R(e_tmv_buffer1, S5P_FIMV_E_TMV_BUFFER1_V6); | |
2121 | R(e_source_first_plane_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR_V6); | |
2122 | R(e_source_second_plane_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6); | |
2123 | R(e_stream_buffer_addr, S5P_FIMV_E_STREAM_BUFFER_ADDR_V6); | |
2124 | R(e_stream_buffer_size, S5P_FIMV_E_STREAM_BUFFER_SIZE_V6); | |
2125 | R(e_roi_buffer_addr, S5P_FIMV_E_ROI_BUFFER_ADDR_V6); | |
2126 | R(e_param_change, S5P_FIMV_E_PARAM_CHANGE_V6); | |
2127 | R(e_ir_size, S5P_FIMV_E_IR_SIZE_V6); | |
2128 | R(e_gop_config, S5P_FIMV_E_GOP_CONFIG_V6); | |
2129 | R(e_mslice_mode, S5P_FIMV_E_MSLICE_MODE_V6); | |
2130 | R(e_mslice_size_mb, S5P_FIMV_E_MSLICE_SIZE_MB_V6); | |
2131 | R(e_mslice_size_bits, S5P_FIMV_E_MSLICE_SIZE_BITS_V6); | |
2132 | R(e_frame_insertion, S5P_FIMV_E_FRAME_INSERTION_V6); | |
2133 | R(e_rc_frame_rate, S5P_FIMV_E_RC_FRAME_RATE_V6); | |
2134 | R(e_rc_bit_rate, S5P_FIMV_E_RC_BIT_RATE_V6); | |
2135 | R(e_rc_roi_ctrl, S5P_FIMV_E_RC_ROI_CTRL_V6); | |
2136 | R(e_picture_tag, S5P_FIMV_E_PICTURE_TAG_V6); | |
2137 | R(e_bit_count_enable, S5P_FIMV_E_BIT_COUNT_ENABLE_V6); | |
2138 | R(e_max_bit_count, S5P_FIMV_E_MAX_BIT_COUNT_V6); | |
2139 | R(e_min_bit_count, S5P_FIMV_E_MIN_BIT_COUNT_V6); | |
2140 | R(e_metadata_buffer_addr, S5P_FIMV_E_METADATA_BUFFER_ADDR_V6); | |
2141 | R(e_metadata_buffer_size, S5P_FIMV_E_METADATA_BUFFER_SIZE_V6); | |
2142 | R(e_encoded_source_first_plane_addr, | |
2143 | S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR_V6); | |
2144 | R(e_encoded_source_second_plane_addr, | |
2145 | S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR_V6); | |
2146 | R(e_stream_size, S5P_FIMV_E_STREAM_SIZE_V6); | |
2147 | R(e_slice_type, S5P_FIMV_E_SLICE_TYPE_V6); | |
2148 | R(e_picture_count, S5P_FIMV_E_PICTURE_COUNT_V6); | |
2149 | R(e_ret_picture_tag, S5P_FIMV_E_RET_PICTURE_TAG_V6); | |
2150 | R(e_recon_luma_dpb_addr, S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6); | |
2151 | R(e_recon_chroma_dpb_addr, S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6); | |
2152 | R(e_mpeg4_options, S5P_FIMV_E_MPEG4_OPTIONS_V6); | |
2153 | R(e_mpeg4_hec_period, S5P_FIMV_E_MPEG4_HEC_PERIOD_V6); | |
2154 | R(e_aspect_ratio, S5P_FIMV_E_ASPECT_RATIO_V6); | |
2155 | R(e_extended_sar, S5P_FIMV_E_EXTENDED_SAR_V6); | |
2156 | R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V6); | |
2157 | R(e_h264_lf_alpha_offset, S5P_FIMV_E_H264_LF_ALPHA_OFFSET_V6); | |
2158 | R(e_h264_lf_beta_offset, S5P_FIMV_E_H264_LF_BETA_OFFSET_V6); | |
2159 | R(e_h264_i_period, S5P_FIMV_E_H264_I_PERIOD_V6); | |
2160 | R(e_h264_fmo_slice_grp_map_type, | |
2161 | S5P_FIMV_E_H264_FMO_SLICE_GRP_MAP_TYPE_V6); | |
2162 | R(e_h264_fmo_num_slice_grp_minus1, | |
2163 | S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6); | |
2164 | R(e_h264_fmo_slice_grp_change_dir, | |
2165 | S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_DIR_V6); | |
2166 | R(e_h264_fmo_slice_grp_change_rate_minus1, | |
2167 | S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1_V6); | |
2168 | R(e_h264_fmo_run_length_minus1_0, | |
2169 | S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_0_V6); | |
2170 | R(e_h264_aso_slice_order_0, S5P_FIMV_E_H264_ASO_SLICE_ORDER_0_V6); | |
2171 | R(e_h264_num_t_layer, S5P_FIMV_E_H264_NUM_T_LAYER_V6); | |
2172 | R(e_h264_hierarchical_qp_layer0, | |
2173 | S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0_V6); | |
2174 | R(e_h264_frame_packing_sei_info, | |
2175 | S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO_V6); | |
2176 | ||
109b794c | 2177 | if (!IS_MFCV7_PLUS(dev)) |
6a9c6f68 KA |
2178 | goto done; |
2179 | ||
e2b9deb2 | 2180 | /* Initialize registers used in MFC v7+ */ |
6a9c6f68 KA |
2181 | R(e_source_first_plane_addr, S5P_FIMV_E_SOURCE_FIRST_ADDR_V7); |
2182 | R(e_source_second_plane_addr, S5P_FIMV_E_SOURCE_SECOND_ADDR_V7); | |
2183 | R(e_source_third_plane_addr, S5P_FIMV_E_SOURCE_THIRD_ADDR_V7); | |
2184 | R(e_source_first_plane_stride, S5P_FIMV_E_SOURCE_FIRST_STRIDE_V7); | |
2185 | R(e_source_second_plane_stride, S5P_FIMV_E_SOURCE_SECOND_STRIDE_V7); | |
2186 | R(e_source_third_plane_stride, S5P_FIMV_E_SOURCE_THIRD_STRIDE_V7); | |
2187 | R(e_encoded_source_first_plane_addr, | |
2188 | S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7); | |
2189 | R(e_encoded_source_second_plane_addr, | |
2190 | S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7); | |
2191 | R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7); | |
2192 | ||
e2b9deb2 KA |
2193 | if (!IS_MFCV8(dev)) |
2194 | goto done; | |
2195 | ||
2196 | /* Initialize registers used in MFC v8 only. | |
2197 | * Also, over-write the registers which have | |
2198 | * a different offset for MFC v8. */ | |
2199 | R(d_stream_data_size, S5P_FIMV_D_STREAM_DATA_SIZE_V8); | |
2200 | R(d_cpb_buffer_addr, S5P_FIMV_D_CPB_BUFFER_ADDR_V8); | |
2201 | R(d_cpb_buffer_size, S5P_FIMV_D_CPB_BUFFER_SIZE_V8); | |
2202 | R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8); | |
2203 | R(d_first_plane_dpb_size, S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8); | |
2204 | R(d_second_plane_dpb_size, S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8); | |
2205 | R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8); | |
2206 | R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8); | |
2207 | R(d_first_plane_dpb_stride_size, | |
2208 | S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8); | |
2209 | R(d_second_plane_dpb_stride_size, | |
2210 | S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8); | |
2211 | R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8); | |
2212 | R(d_num_mv, S5P_FIMV_D_NUM_MV_V8); | |
2213 | R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8); | |
2214 | R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8); | |
2215 | R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8); | |
2216 | R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8); | |
2217 | R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8); | |
2218 | R(d_slice_if_enable, S5P_FIMV_D_SLICE_IF_ENABLE_V8); | |
2219 | R(d_display_first_plane_addr, S5P_FIMV_D_DISPLAY_FIRST_PLANE_ADDR_V8); | |
2220 | R(d_display_second_plane_addr, S5P_FIMV_D_DISPLAY_SECOND_PLANE_ADDR_V8); | |
2221 | R(d_decoded_first_plane_addr, S5P_FIMV_D_DECODED_FIRST_PLANE_ADDR_V8); | |
2222 | R(d_decoded_second_plane_addr, S5P_FIMV_D_DECODED_SECOND_PLANE_ADDR_V8); | |
2223 | R(d_display_status, S5P_FIMV_D_DISPLAY_STATUS_V8); | |
2224 | R(d_decoded_status, S5P_FIMV_D_DECODED_STATUS_V8); | |
2225 | R(d_decoded_frame_type, S5P_FIMV_D_DECODED_FRAME_TYPE_V8); | |
2226 | R(d_display_frame_type, S5P_FIMV_D_DISPLAY_FRAME_TYPE_V8); | |
2227 | R(d_decoded_nal_size, S5P_FIMV_D_DECODED_NAL_SIZE_V8); | |
2228 | R(d_display_frame_width, S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V8); | |
2229 | R(d_display_frame_height, S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V8); | |
2230 | R(d_frame_pack_sei_avail, S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V8); | |
2231 | R(d_mvc_num_views, S5P_FIMV_D_MVC_NUM_VIEWS_V8); | |
2232 | R(d_mvc_view_id, S5P_FIMV_D_MVC_VIEW_ID_V8); | |
2233 | R(d_ret_picture_tag_top, S5P_FIMV_D_RET_PICTURE_TAG_TOP_V8); | |
2234 | R(d_ret_picture_tag_bot, S5P_FIMV_D_RET_PICTURE_TAG_BOT_V8); | |
2235 | R(d_display_crop_info1, S5P_FIMV_D_DISPLAY_CROP_INFO1_V8); | |
2236 | R(d_display_crop_info2, S5P_FIMV_D_DISPLAY_CROP_INFO2_V8); | |
2237 | ||
6a9c6f68 KA |
2238 | done: |
2239 | return &mfc_regs; | |
2240 | #undef S5P_MFC_REG_ADDR | |
2241 | #undef R | |
f96f3cfa JP |
2242 | } |
2243 | ||
2244 | /* Initialize opr function pointers for MFC v6 */ | |
2245 | static struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = { | |
2246 | .alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v6, | |
2247 | .release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v6, | |
2248 | .alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v6, | |
2249 | .release_codec_buffers = s5p_mfc_release_codec_buffers_v6, | |
2250 | .alloc_instance_buffer = s5p_mfc_alloc_instance_buffer_v6, | |
2251 | .release_instance_buffer = s5p_mfc_release_instance_buffer_v6, | |
2252 | .alloc_dev_context_buffer = | |
2253 | s5p_mfc_alloc_dev_context_buffer_v6, | |
2254 | .release_dev_context_buffer = | |
2255 | s5p_mfc_release_dev_context_buffer_v6, | |
2256 | .dec_calc_dpb_size = s5p_mfc_dec_calc_dpb_size_v6, | |
2257 | .enc_calc_src_size = s5p_mfc_enc_calc_src_size_v6, | |
2258 | .set_dec_stream_buffer = s5p_mfc_set_dec_stream_buffer_v6, | |
2259 | .set_dec_frame_buffer = s5p_mfc_set_dec_frame_buffer_v6, | |
2260 | .set_enc_stream_buffer = s5p_mfc_set_enc_stream_buffer_v6, | |
2261 | .set_enc_frame_buffer = s5p_mfc_set_enc_frame_buffer_v6, | |
2262 | .get_enc_frame_buffer = s5p_mfc_get_enc_frame_buffer_v6, | |
2263 | .set_enc_ref_buffer = s5p_mfc_set_enc_ref_buffer_v6, | |
2264 | .init_decode = s5p_mfc_init_decode_v6, | |
2265 | .init_encode = s5p_mfc_init_encode_v6, | |
2266 | .encode_one_frame = s5p_mfc_encode_one_frame_v6, | |
2267 | .try_run = s5p_mfc_try_run_v6, | |
2268 | .cleanup_queue = s5p_mfc_cleanup_queue_v6, | |
2269 | .clear_int_flags = s5p_mfc_clear_int_flags_v6, | |
2270 | .write_info = s5p_mfc_write_info_v6, | |
2271 | .read_info = s5p_mfc_read_info_v6, | |
2272 | .get_dspl_y_adr = s5p_mfc_get_dspl_y_adr_v6, | |
2273 | .get_dec_y_adr = s5p_mfc_get_dec_y_adr_v6, | |
2274 | .get_dspl_status = s5p_mfc_get_dspl_status_v6, | |
2275 | .get_dec_status = s5p_mfc_get_dec_status_v6, | |
2276 | .get_dec_frame_type = s5p_mfc_get_dec_frame_type_v6, | |
2277 | .get_disp_frame_type = s5p_mfc_get_disp_frame_type_v6, | |
2278 | .get_consumed_stream = s5p_mfc_get_consumed_stream_v6, | |
2279 | .get_int_reason = s5p_mfc_get_int_reason_v6, | |
2280 | .get_int_err = s5p_mfc_get_int_err_v6, | |
2281 | .err_dec = s5p_mfc_err_dec_v6, | |
2282 | .err_dspl = s5p_mfc_err_dspl_v6, | |
2283 | .get_img_width = s5p_mfc_get_img_width_v6, | |
2284 | .get_img_height = s5p_mfc_get_img_height_v6, | |
2285 | .get_dpb_count = s5p_mfc_get_dpb_count_v6, | |
2286 | .get_mv_count = s5p_mfc_get_mv_count_v6, | |
2287 | .get_inst_no = s5p_mfc_get_inst_no_v6, | |
2288 | .get_enc_strm_size = s5p_mfc_get_enc_strm_size_v6, | |
2289 | .get_enc_slice_type = s5p_mfc_get_enc_slice_type_v6, | |
2290 | .get_enc_dpb_count = s5p_mfc_get_enc_dpb_count_v6, | |
2291 | .get_enc_pic_count = s5p_mfc_get_enc_pic_count_v6, | |
2292 | .get_sei_avail_status = s5p_mfc_get_sei_avail_status_v6, | |
2293 | .get_mvc_num_views = s5p_mfc_get_mvc_num_views_v6, | |
2294 | .get_mvc_view_id = s5p_mfc_get_mvc_view_id_v6, | |
2295 | .get_pic_type_top = s5p_mfc_get_pic_type_top_v6, | |
2296 | .get_pic_type_bot = s5p_mfc_get_pic_type_bot_v6, | |
2297 | .get_crop_info_h = s5p_mfc_get_crop_info_h_v6, | |
2298 | .get_crop_info_v = s5p_mfc_get_crop_info_v_v6, | |
2299 | }; | |
2300 | ||
2301 | struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void) | |
2302 | { | |
2303 | return &s5p_mfc_ops_v6; | |
2304 | } |