This source file includes following definitions.
- cedrus_h264_write_sram
- cedrus_h264_mv_col_buf_addr
- cedrus_fill_ref_pic
- cedrus_write_frame_list
- _cedrus_write_ref_list
- cedrus_write_ref_list0
- cedrus_write_ref_list1
- cedrus_write_scaling_lists
- cedrus_write_pred_weight_table
- cedrus_set_params
- cedrus_h264_irq_status
- cedrus_h264_irq_clear
- cedrus_h264_irq_disable
- cedrus_h264_setup
- cedrus_h264_start
- cedrus_h264_stop
- cedrus_h264_trigger
1
2
3
4
5
6
7
8
9 #include <linux/types.h>
10
11 #include <media/videobuf2-dma-contig.h>
12
13 #include "cedrus.h"
14 #include "cedrus_hw.h"
15 #include "cedrus_regs.h"
16
17 enum cedrus_h264_sram_off {
18 CEDRUS_SRAM_H264_PRED_WEIGHT_TABLE = 0x000,
19 CEDRUS_SRAM_H264_FRAMEBUFFER_LIST = 0x100,
20 CEDRUS_SRAM_H264_REF_LIST_0 = 0x190,
21 CEDRUS_SRAM_H264_REF_LIST_1 = 0x199,
22 CEDRUS_SRAM_H264_SCALING_LIST_8x8_0 = 0x200,
23 CEDRUS_SRAM_H264_SCALING_LIST_8x8_1 = 0x210,
24 CEDRUS_SRAM_H264_SCALING_LIST_4x4 = 0x220,
25 };
26
27 struct cedrus_h264_sram_ref_pic {
28 __le32 top_field_order_cnt;
29 __le32 bottom_field_order_cnt;
30 __le32 frame_info;
31 __le32 luma_ptr;
32 __le32 chroma_ptr;
33 __le32 mv_col_top_ptr;
34 __le32 mv_col_bot_ptr;
35 __le32 reserved;
36 } __packed;
37
38 #define CEDRUS_H264_FRAME_NUM 18
39
40 #define CEDRUS_NEIGHBOR_INFO_BUF_SIZE (16 * SZ_1K)
41 #define CEDRUS_PIC_INFO_BUF_SIZE (128 * SZ_1K)
42
43 static void cedrus_h264_write_sram(struct cedrus_dev *dev,
44 enum cedrus_h264_sram_off off,
45 const void *data, size_t len)
46 {
47 const u32 *buffer = data;
48 size_t count = DIV_ROUND_UP(len, 4);
49
50 cedrus_write(dev, VE_AVC_SRAM_PORT_OFFSET, off << 2);
51
52 while (count--)
53 cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, *buffer++);
54 }
55
56 static dma_addr_t cedrus_h264_mv_col_buf_addr(struct cedrus_ctx *ctx,
57 unsigned int position,
58 unsigned int field)
59 {
60 dma_addr_t addr = ctx->codec.h264.mv_col_buf_dma;
61
62
63 addr += position * ctx->codec.h264.mv_col_buf_field_size * 2;
64
65
66 addr += field * ctx->codec.h264.mv_col_buf_field_size;
67
68 return addr;
69 }
70
71 static void cedrus_fill_ref_pic(struct cedrus_ctx *ctx,
72 struct cedrus_buffer *buf,
73 unsigned int top_field_order_cnt,
74 unsigned int bottom_field_order_cnt,
75 struct cedrus_h264_sram_ref_pic *pic)
76 {
77 struct vb2_buffer *vbuf = &buf->m2m_buf.vb.vb2_buf;
78 unsigned int position = buf->codec.h264.position;
79
80 pic->top_field_order_cnt = cpu_to_le32(top_field_order_cnt);
81 pic->bottom_field_order_cnt = cpu_to_le32(bottom_field_order_cnt);
82 pic->frame_info = cpu_to_le32(buf->codec.h264.pic_type << 8);
83
84 pic->luma_ptr = cpu_to_le32(cedrus_buf_addr(vbuf, &ctx->dst_fmt, 0));
85 pic->chroma_ptr = cpu_to_le32(cedrus_buf_addr(vbuf, &ctx->dst_fmt, 1));
86 pic->mv_col_top_ptr =
87 cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, position, 0));
88 pic->mv_col_bot_ptr =
89 cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, position, 1));
90 }
91
92 static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
93 struct cedrus_run *run)
94 {
95 struct cedrus_h264_sram_ref_pic pic_list[CEDRUS_H264_FRAME_NUM];
96 const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
97 const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
98 const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
99 struct vb2_queue *cap_q;
100 struct cedrus_buffer *output_buf;
101 struct cedrus_dev *dev = ctx->dev;
102 unsigned long used_dpbs = 0;
103 unsigned int position;
104 unsigned int output = 0;
105 unsigned int i;
106
107 cap_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
108
109 memset(pic_list, 0, sizeof(pic_list));
110
111 for (i = 0; i < ARRAY_SIZE(decode->dpb); i++) {
112 const struct v4l2_h264_dpb_entry *dpb = &decode->dpb[i];
113 struct cedrus_buffer *cedrus_buf;
114 int buf_idx;
115
116 if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID))
117 continue;
118
119 buf_idx = vb2_find_timestamp(cap_q, dpb->reference_ts, 0);
120 if (buf_idx < 0)
121 continue;
122
123 cedrus_buf = vb2_to_cedrus_buffer(cap_q->bufs[buf_idx]);
124 position = cedrus_buf->codec.h264.position;
125 used_dpbs |= BIT(position);
126
127 if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
128 continue;
129
130 cedrus_fill_ref_pic(ctx, cedrus_buf,
131 dpb->top_field_order_cnt,
132 dpb->bottom_field_order_cnt,
133 &pic_list[position]);
134
135 output = max(position, output);
136 }
137
138 position = find_next_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM,
139 output);
140 if (position >= CEDRUS_H264_FRAME_NUM)
141 position = find_first_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM);
142
143 output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
144 output_buf->codec.h264.position = position;
145
146 if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
147 output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FIELD;
148 else if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
149 output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_MBAFF;
150 else
151 output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FRAME;
152
153 cedrus_fill_ref_pic(ctx, output_buf,
154 decode->top_field_order_cnt,
155 decode->bottom_field_order_cnt,
156 &pic_list[position]);
157
158 cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_FRAMEBUFFER_LIST,
159 pic_list, sizeof(pic_list));
160
161 cedrus_write(dev, VE_H264_OUTPUT_FRAME_IDX, position);
162 }
163
164 #define CEDRUS_MAX_REF_IDX 32
165
166 static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
167 struct cedrus_run *run,
168 const u8 *ref_list, u8 num_ref,
169 enum cedrus_h264_sram_off sram)
170 {
171 const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
172 struct vb2_queue *cap_q;
173 struct cedrus_dev *dev = ctx->dev;
174 u8 sram_array[CEDRUS_MAX_REF_IDX];
175 unsigned int i;
176 size_t size;
177
178 cap_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
179
180 memset(sram_array, 0, sizeof(sram_array));
181
182 for (i = 0; i < num_ref; i++) {
183 const struct v4l2_h264_dpb_entry *dpb;
184 const struct cedrus_buffer *cedrus_buf;
185 const struct vb2_v4l2_buffer *ref_buf;
186 unsigned int position;
187 int buf_idx;
188 u8 dpb_idx;
189
190 dpb_idx = ref_list[i];
191 dpb = &decode->dpb[dpb_idx];
192
193 if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
194 continue;
195
196 buf_idx = vb2_find_timestamp(cap_q, dpb->reference_ts, 0);
197 if (buf_idx < 0)
198 continue;
199
200 ref_buf = to_vb2_v4l2_buffer(cap_q->bufs[buf_idx]);
201 cedrus_buf = vb2_v4l2_to_cedrus_buffer(ref_buf);
202 position = cedrus_buf->codec.h264.position;
203
204 sram_array[i] |= position << 1;
205 if (ref_buf->field == V4L2_FIELD_BOTTOM)
206 sram_array[i] |= BIT(0);
207 }
208
209 size = min_t(size_t, ALIGN(num_ref, 4), sizeof(sram_array));
210 cedrus_h264_write_sram(dev, sram, &sram_array, size);
211 }
212
213 static void cedrus_write_ref_list0(struct cedrus_ctx *ctx,
214 struct cedrus_run *run)
215 {
216 const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
217
218 _cedrus_write_ref_list(ctx, run,
219 slice->ref_pic_list0,
220 slice->num_ref_idx_l0_active_minus1 + 1,
221 CEDRUS_SRAM_H264_REF_LIST_0);
222 }
223
224 static void cedrus_write_ref_list1(struct cedrus_ctx *ctx,
225 struct cedrus_run *run)
226 {
227 const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
228
229 _cedrus_write_ref_list(ctx, run,
230 slice->ref_pic_list1,
231 slice->num_ref_idx_l1_active_minus1 + 1,
232 CEDRUS_SRAM_H264_REF_LIST_1);
233 }
234
235 static void cedrus_write_scaling_lists(struct cedrus_ctx *ctx,
236 struct cedrus_run *run)
237 {
238 const struct v4l2_ctrl_h264_scaling_matrix *scaling =
239 run->h264.scaling_matrix;
240 struct cedrus_dev *dev = ctx->dev;
241
242 cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_8x8_0,
243 scaling->scaling_list_8x8[0],
244 sizeof(scaling->scaling_list_8x8[0]));
245
246 cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_8x8_1,
247 scaling->scaling_list_8x8[1],
248 sizeof(scaling->scaling_list_8x8[1]));
249
250 cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_4x4,
251 scaling->scaling_list_4x4,
252 sizeof(scaling->scaling_list_4x4));
253 }
254
255 static void cedrus_write_pred_weight_table(struct cedrus_ctx *ctx,
256 struct cedrus_run *run)
257 {
258 const struct v4l2_ctrl_h264_slice_params *slice =
259 run->h264.slice_params;
260 const struct v4l2_h264_pred_weight_table *pred_weight =
261 &slice->pred_weight_table;
262 struct cedrus_dev *dev = ctx->dev;
263 int i, j, k;
264
265 cedrus_write(dev, VE_H264_SHS_WP,
266 ((pred_weight->chroma_log2_weight_denom & 0x7) << 4) |
267 ((pred_weight->luma_log2_weight_denom & 0x7) << 0));
268
269 cedrus_write(dev, VE_AVC_SRAM_PORT_OFFSET,
270 CEDRUS_SRAM_H264_PRED_WEIGHT_TABLE << 2);
271
272 for (i = 0; i < ARRAY_SIZE(pred_weight->weight_factors); i++) {
273 const struct v4l2_h264_weight_factors *factors =
274 &pred_weight->weight_factors[i];
275
276 for (j = 0; j < ARRAY_SIZE(factors->luma_weight); j++) {
277 u32 val;
278
279 val = (((u32)factors->luma_offset[j] & 0x1ff) << 16) |
280 (factors->luma_weight[j] & 0x1ff);
281 cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, val);
282 }
283
284 for (j = 0; j < ARRAY_SIZE(factors->chroma_weight); j++) {
285 for (k = 0; k < ARRAY_SIZE(factors->chroma_weight[0]); k++) {
286 u32 val;
287
288 val = (((u32)factors->chroma_offset[j][k] & 0x1ff) << 16) |
289 (factors->chroma_weight[j][k] & 0x1ff);
290 cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, val);
291 }
292 }
293 }
294 }
295
296 static void cedrus_set_params(struct cedrus_ctx *ctx,
297 struct cedrus_run *run)
298 {
299 const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
300 const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
301 const struct v4l2_ctrl_h264_pps *pps = run->h264.pps;
302 const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
303 struct vb2_buffer *src_buf = &run->src->vb2_buf;
304 struct cedrus_dev *dev = ctx->dev;
305 dma_addr_t src_buf_addr;
306 u32 offset = slice->header_bit_size;
307 u32 len = (slice->size * 8) - offset;
308 u32 reg;
309
310 cedrus_write(dev, VE_H264_VLD_LEN, len);
311 cedrus_write(dev, VE_H264_VLD_OFFSET, offset);
312
313 src_buf_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
314 cedrus_write(dev, VE_H264_VLD_END,
315 src_buf_addr + vb2_get_plane_payload(src_buf, 0));
316 cedrus_write(dev, VE_H264_VLD_ADDR,
317 VE_H264_VLD_ADDR_VAL(src_buf_addr) |
318 VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID |
319 VE_H264_VLD_ADDR_LAST);
320
321
322
323
324
325
326
327 cedrus_write(dev, VE_H264_TRIGGER_TYPE,
328 VE_H264_TRIGGER_TYPE_INIT_SWDEC);
329
330 if (((pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) &&
331 (slice->slice_type == V4L2_H264_SLICE_TYPE_P ||
332 slice->slice_type == V4L2_H264_SLICE_TYPE_SP)) ||
333 (pps->weighted_bipred_idc == 1 &&
334 slice->slice_type == V4L2_H264_SLICE_TYPE_B))
335 cedrus_write_pred_weight_table(ctx, run);
336
337 if ((slice->slice_type == V4L2_H264_SLICE_TYPE_P) ||
338 (slice->slice_type == V4L2_H264_SLICE_TYPE_SP) ||
339 (slice->slice_type == V4L2_H264_SLICE_TYPE_B))
340 cedrus_write_ref_list0(ctx, run);
341
342 if (slice->slice_type == V4L2_H264_SLICE_TYPE_B)
343 cedrus_write_ref_list1(ctx, run);
344
345
346 reg = 0;
347
348
349
350
351 reg |= (slice->num_ref_idx_l0_active_minus1 & 0x1f) << 10;
352 reg |= (slice->num_ref_idx_l1_active_minus1 & 0x1f) << 5;
353 reg |= (pps->weighted_bipred_idc & 0x3) << 2;
354 if (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE)
355 reg |= VE_H264_PPS_ENTROPY_CODING_MODE;
356 if (pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED)
357 reg |= VE_H264_PPS_WEIGHTED_PRED;
358 if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED)
359 reg |= VE_H264_PPS_CONSTRAINED_INTRA_PRED;
360 if (pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE)
361 reg |= VE_H264_PPS_TRANSFORM_8X8_MODE;
362 cedrus_write(dev, VE_H264_PPS, reg);
363
364
365 reg = 0;
366 reg |= (sps->chroma_format_idc & 0x7) << 19;
367 reg |= (sps->pic_width_in_mbs_minus1 & 0xff) << 8;
368 reg |= sps->pic_height_in_map_units_minus1 & 0xff;
369 if (sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)
370 reg |= VE_H264_SPS_MBS_ONLY;
371 if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
372 reg |= VE_H264_SPS_MB_ADAPTIVE_FRAME_FIELD;
373 if (sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)
374 reg |= VE_H264_SPS_DIRECT_8X8_INFERENCE;
375 cedrus_write(dev, VE_H264_SPS, reg);
376
377
378 reg = 0;
379 reg |= decode->nal_ref_idc ? BIT(12) : 0;
380 reg |= (slice->slice_type & 0xf) << 8;
381 reg |= slice->cabac_init_idc & 0x3;
382 reg |= VE_H264_SHS_FIRST_SLICE_IN_PIC;
383 if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
384 reg |= VE_H264_SHS_FIELD_PIC;
385 if (slice->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)
386 reg |= VE_H264_SHS_BOTTOM_FIELD;
387 if (slice->flags & V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED)
388 reg |= VE_H264_SHS_DIRECT_SPATIAL_MV_PRED;
389 cedrus_write(dev, VE_H264_SHS, reg);
390
391 reg = 0;
392 reg |= VE_H264_SHS2_NUM_REF_IDX_ACTIVE_OVRD;
393 reg |= (slice->num_ref_idx_l0_active_minus1 & 0x1f) << 24;
394 reg |= (slice->num_ref_idx_l1_active_minus1 & 0x1f) << 16;
395 reg |= (slice->disable_deblocking_filter_idc & 0x3) << 8;
396 reg |= (slice->slice_alpha_c0_offset_div2 & 0xf) << 4;
397 reg |= slice->slice_beta_offset_div2 & 0xf;
398 cedrus_write(dev, VE_H264_SHS2, reg);
399
400 reg = 0;
401 reg |= (pps->second_chroma_qp_index_offset & 0x3f) << 16;
402 reg |= (pps->chroma_qp_index_offset & 0x3f) << 8;
403 reg |= (pps->pic_init_qp_minus26 + 26 + slice->slice_qp_delta) & 0x3f;
404 cedrus_write(dev, VE_H264_SHS_QP, reg);
405
406
407 cedrus_write(dev, VE_H264_STATUS, cedrus_read(dev, VE_H264_STATUS));
408
409
410 cedrus_write(dev, VE_H264_CTRL,
411 VE_H264_CTRL_SLICE_DECODE_INT |
412 VE_H264_CTRL_DECODE_ERR_INT |
413 VE_H264_CTRL_VLD_DATA_REQ_INT);
414 }
415
416 static enum cedrus_irq_status
417 cedrus_h264_irq_status(struct cedrus_ctx *ctx)
418 {
419 struct cedrus_dev *dev = ctx->dev;
420 u32 reg = cedrus_read(dev, VE_H264_STATUS);
421
422 if (reg & (VE_H264_STATUS_DECODE_ERR_INT |
423 VE_H264_STATUS_VLD_DATA_REQ_INT))
424 return CEDRUS_IRQ_ERROR;
425
426 if (reg & VE_H264_CTRL_SLICE_DECODE_INT)
427 return CEDRUS_IRQ_OK;
428
429 return CEDRUS_IRQ_NONE;
430 }
431
432 static void cedrus_h264_irq_clear(struct cedrus_ctx *ctx)
433 {
434 struct cedrus_dev *dev = ctx->dev;
435
436 cedrus_write(dev, VE_H264_STATUS,
437 VE_H264_STATUS_INT_MASK);
438 }
439
440 static void cedrus_h264_irq_disable(struct cedrus_ctx *ctx)
441 {
442 struct cedrus_dev *dev = ctx->dev;
443 u32 reg = cedrus_read(dev, VE_H264_CTRL);
444
445 cedrus_write(dev, VE_H264_CTRL,
446 reg & ~VE_H264_CTRL_INT_MASK);
447 }
448
449 static void cedrus_h264_setup(struct cedrus_ctx *ctx,
450 struct cedrus_run *run)
451 {
452 struct cedrus_dev *dev = ctx->dev;
453
454 cedrus_engine_enable(dev, CEDRUS_CODEC_H264);
455
456 cedrus_write(dev, VE_H264_SDROT_CTRL, 0);
457 cedrus_write(dev, VE_H264_EXTRA_BUFFER1,
458 ctx->codec.h264.pic_info_buf_dma);
459 cedrus_write(dev, VE_H264_EXTRA_BUFFER2,
460 ctx->codec.h264.neighbor_info_buf_dma);
461
462 cedrus_write_scaling_lists(ctx, run);
463 cedrus_write_frame_list(ctx, run);
464
465 cedrus_set_params(ctx, run);
466 }
467
468 static int cedrus_h264_start(struct cedrus_ctx *ctx)
469 {
470 struct cedrus_dev *dev = ctx->dev;
471 unsigned int field_size;
472 unsigned int mv_col_size;
473 int ret;
474
475
476
477
478
479
480
481 ctx->codec.h264.pic_info_buf =
482 dma_alloc_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
483 &ctx->codec.h264.pic_info_buf_dma,
484 GFP_KERNEL);
485 if (!ctx->codec.h264.pic_info_buf)
486 return -ENOMEM;
487
488
489
490
491
492
493
494
495 ctx->codec.h264.neighbor_info_buf =
496 dma_alloc_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
497 &ctx->codec.h264.neighbor_info_buf_dma,
498 GFP_KERNEL);
499 if (!ctx->codec.h264.neighbor_info_buf) {
500 ret = -ENOMEM;
501 goto err_pic_buf;
502 }
503
504 field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) *
505 DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16;
506
507
508
509
510
511
512
513 field_size = field_size * 2;
514
515
516
517
518
519
520
521 field_size = field_size * 2;
522 ctx->codec.h264.mv_col_buf_field_size = field_size;
523
524 mv_col_size = field_size * 2 * CEDRUS_H264_FRAME_NUM;
525 ctx->codec.h264.mv_col_buf_size = mv_col_size;
526 ctx->codec.h264.mv_col_buf = dma_alloc_coherent(dev->dev,
527 ctx->codec.h264.mv_col_buf_size,
528 &ctx->codec.h264.mv_col_buf_dma,
529 GFP_KERNEL);
530 if (!ctx->codec.h264.mv_col_buf) {
531 ret = -ENOMEM;
532 goto err_neighbor_buf;
533 }
534
535 return 0;
536
537 err_neighbor_buf:
538 dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
539 ctx->codec.h264.neighbor_info_buf,
540 ctx->codec.h264.neighbor_info_buf_dma);
541
542 err_pic_buf:
543 dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
544 ctx->codec.h264.pic_info_buf,
545 ctx->codec.h264.pic_info_buf_dma);
546 return ret;
547 }
548
549 static void cedrus_h264_stop(struct cedrus_ctx *ctx)
550 {
551 struct cedrus_dev *dev = ctx->dev;
552
553 dma_free_coherent(dev->dev, ctx->codec.h264.mv_col_buf_size,
554 ctx->codec.h264.mv_col_buf,
555 ctx->codec.h264.mv_col_buf_dma);
556 dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
557 ctx->codec.h264.neighbor_info_buf,
558 ctx->codec.h264.neighbor_info_buf_dma);
559 dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
560 ctx->codec.h264.pic_info_buf,
561 ctx->codec.h264.pic_info_buf_dma);
562 }
563
564 static void cedrus_h264_trigger(struct cedrus_ctx *ctx)
565 {
566 struct cedrus_dev *dev = ctx->dev;
567
568 cedrus_write(dev, VE_H264_TRIGGER_TYPE,
569 VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE);
570 }
571
572 struct cedrus_dec_ops cedrus_dec_ops_h264 = {
573 .irq_clear = cedrus_h264_irq_clear,
574 .irq_disable = cedrus_h264_irq_disable,
575 .irq_status = cedrus_h264_irq_status,
576 .setup = cedrus_h264_setup,
577 .start = cedrus_h264_start,
578 .stop = cedrus_h264_stop,
579 .trigger = cedrus_h264_trigger,
580 };