1
2
3
4
5
6
7
8
9
10#include <linux/delay.h>
11#include <linux/types.h>
12
13#include <media/videobuf2-dma-contig.h>
14
15#include "cedrus.h"
16#include "cedrus_hw.h"
17#include "cedrus_regs.h"
18
19
20
21
22
23
24
25
26#define CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE (397 * SZ_1K)
27#define CEDRUS_H265_ENTRY_POINTS_BUF_SIZE (4 * SZ_1K)
28#define CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE 160
29
30struct cedrus_h265_sram_frame_info {
31 __le32 top_pic_order_cnt;
32 __le32 bottom_pic_order_cnt;
33 __le32 top_mv_col_buf_addr;
34 __le32 bottom_mv_col_buf_addr;
35 __le32 luma_addr;
36 __le32 chroma_addr;
37} __packed;
38
39struct cedrus_h265_sram_pred_weight {
40 __s8 delta_weight;
41 __s8 offset;
42} __packed;
43
44static enum cedrus_irq_status cedrus_h265_irq_status(struct cedrus_ctx *ctx)
45{
46 struct cedrus_dev *dev = ctx->dev;
47 u32 reg;
48
49 reg = cedrus_read(dev, VE_DEC_H265_STATUS);
50 reg &= VE_DEC_H265_STATUS_CHECK_MASK;
51
52 if (reg & VE_DEC_H265_STATUS_CHECK_ERROR ||
53 !(reg & VE_DEC_H265_STATUS_SUCCESS))
54 return CEDRUS_IRQ_ERROR;
55
56 return CEDRUS_IRQ_OK;
57}
58
59static void cedrus_h265_irq_clear(struct cedrus_ctx *ctx)
60{
61 struct cedrus_dev *dev = ctx->dev;
62
63 cedrus_write(dev, VE_DEC_H265_STATUS, VE_DEC_H265_STATUS_CHECK_MASK);
64}
65
66static void cedrus_h265_irq_disable(struct cedrus_ctx *ctx)
67{
68 struct cedrus_dev *dev = ctx->dev;
69 u32 reg = cedrus_read(dev, VE_DEC_H265_CTRL);
70
71 reg &= ~VE_DEC_H265_CTRL_IRQ_MASK;
72
73 cedrus_write(dev, VE_DEC_H265_CTRL, reg);
74}
75
76static void cedrus_h265_sram_write_offset(struct cedrus_dev *dev, u32 offset)
77{
78 cedrus_write(dev, VE_DEC_H265_SRAM_OFFSET, offset);
79}
80
81static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, void *data,
82 unsigned int size)
83{
84 u32 *word = data;
85
86 while (size >= sizeof(u32)) {
87 cedrus_write(dev, VE_DEC_H265_SRAM_DATA, *word++);
88 size -= sizeof(u32);
89 }
90}
91
92static inline dma_addr_t
93cedrus_h265_frame_info_mv_col_buf_addr(struct cedrus_ctx *ctx,
94 unsigned int index, unsigned int field)
95{
96 return ctx->codec.h265.mv_col_buf_addr + index *
97 ctx->codec.h265.mv_col_buf_unit_size +
98 field * ctx->codec.h265.mv_col_buf_unit_size / 2;
99}
100
101static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
102 unsigned int index,
103 bool field_pic,
104 u32 pic_order_cnt[],
105 int buffer_index)
106{
107 struct cedrus_dev *dev = ctx->dev;
108 dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 0);
109 dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 1);
110 dma_addr_t mv_col_buf_addr[2] = {
111 cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index, 0),
112 cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index,
113 field_pic ? 1 : 0)
114 };
115 u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO +
116 VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT * index;
117 struct cedrus_h265_sram_frame_info frame_info = {
118 .top_pic_order_cnt = cpu_to_le32(pic_order_cnt[0]),
119 .bottom_pic_order_cnt = cpu_to_le32(field_pic ?
120 pic_order_cnt[1] :
121 pic_order_cnt[0]),
122 .top_mv_col_buf_addr =
123 cpu_to_le32(VE_DEC_H265_SRAM_DATA_ADDR_BASE(mv_col_buf_addr[0])),
124 .bottom_mv_col_buf_addr = cpu_to_le32(field_pic ?
125 VE_DEC_H265_SRAM_DATA_ADDR_BASE(mv_col_buf_addr[1]) :
126 VE_DEC_H265_SRAM_DATA_ADDR_BASE(mv_col_buf_addr[0])),
127 .luma_addr = cpu_to_le32(VE_DEC_H265_SRAM_DATA_ADDR_BASE(dst_luma_addr)),
128 .chroma_addr = cpu_to_le32(VE_DEC_H265_SRAM_DATA_ADDR_BASE(dst_chroma_addr)),
129 };
130
131 cedrus_h265_sram_write_offset(dev, offset);
132 cedrus_h265_sram_write_data(dev, &frame_info, sizeof(frame_info));
133}
134
135static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx,
136 const struct v4l2_hevc_dpb_entry *dpb,
137 u8 num_active_dpb_entries)
138{
139 struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
140 V4L2_BUF_TYPE_VIDEO_CAPTURE);
141 unsigned int i;
142
143 for (i = 0; i < num_active_dpb_entries; i++) {
144 int buffer_index = vb2_find_timestamp(vq, dpb[i].timestamp, 0);
145 u32 pic_order_cnt[2] = {
146 dpb[i].pic_order_cnt[0],
147 dpb[i].pic_order_cnt[1]
148 };
149
150 cedrus_h265_frame_info_write_single(ctx, i, dpb[i].field_pic,
151 pic_order_cnt,
152 buffer_index);
153 }
154}
155
156static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
157 const struct v4l2_hevc_dpb_entry *dpb,
158 const u8 list[],
159 u8 num_ref_idx_active,
160 u32 sram_offset)
161{
162 unsigned int i;
163 u32 word = 0;
164
165 cedrus_h265_sram_write_offset(dev, sram_offset);
166
167 for (i = 0; i < num_ref_idx_active; i++) {
168 unsigned int shift = (i % 4) * 8;
169 unsigned int index = list[i];
170 u8 value = list[i];
171
172 if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
173 value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
174
175
176 word |= value << shift;
177
178
179 if ((i % 4) == 3 || i == (num_ref_idx_active - 1)) {
180 cedrus_h265_sram_write_data(dev, &word, sizeof(word));
181 word = 0;
182 }
183 }
184}
185
186static void cedrus_h265_pred_weight_write(struct cedrus_dev *dev,
187 const s8 delta_luma_weight[],
188 const s8 luma_offset[],
189 const s8 delta_chroma_weight[][2],
190 const s8 chroma_offset[][2],
191 u8 num_ref_idx_active,
192 u32 sram_luma_offset,
193 u32 sram_chroma_offset)
194{
195 struct cedrus_h265_sram_pred_weight pred_weight[2] = { { 0 } };
196 unsigned int i, j;
197
198 cedrus_h265_sram_write_offset(dev, sram_luma_offset);
199
200 for (i = 0; i < num_ref_idx_active; i++) {
201 unsigned int index = i % 2;
202
203 pred_weight[index].delta_weight = delta_luma_weight[i];
204 pred_weight[index].offset = luma_offset[i];
205
206 if (index == 1 || i == (num_ref_idx_active - 1))
207 cedrus_h265_sram_write_data(dev, (u32 *)&pred_weight,
208 sizeof(pred_weight));
209 }
210
211 cedrus_h265_sram_write_offset(dev, sram_chroma_offset);
212
213 for (i = 0; i < num_ref_idx_active; i++) {
214 for (j = 0; j < 2; j++) {
215 pred_weight[j].delta_weight = delta_chroma_weight[i][j];
216 pred_weight[j].offset = chroma_offset[i][j];
217 }
218
219 cedrus_h265_sram_write_data(dev, &pred_weight,
220 sizeof(pred_weight));
221 }
222}
223
224static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num)
225{
226 int count = 0;
227
228 while (count < num) {
229 int tmp = min(num - count, 32);
230
231 cedrus_write(dev, VE_DEC_H265_TRIGGER,
232 VE_DEC_H265_TRIGGER_FLUSH_BITS |
233 VE_DEC_H265_TRIGGER_TYPE_N_BITS(tmp));
234 while (cedrus_read(dev, VE_DEC_H265_STATUS) & VE_DEC_H265_STATUS_VLD_BUSY)
235 udelay(1);
236
237 count += tmp;
238 }
239}
240
241static void cedrus_h265_setup(struct cedrus_ctx *ctx,
242 struct cedrus_run *run)
243{
244 struct cedrus_dev *dev = ctx->dev;
245 const struct v4l2_ctrl_hevc_sps *sps;
246 const struct v4l2_ctrl_hevc_pps *pps;
247 const struct v4l2_ctrl_hevc_slice_params *slice_params;
248 const struct v4l2_ctrl_hevc_decode_params *decode_params;
249 const struct v4l2_hevc_pred_weight_table *pred_weight_table;
250 unsigned int width_in_ctb_luma, ctb_size_luma;
251 unsigned int log2_max_luma_coding_block_size;
252 dma_addr_t src_buf_addr;
253 dma_addr_t src_buf_end_addr;
254 u32 chroma_log2_weight_denom;
255 u32 output_pic_list_index;
256 u32 pic_order_cnt[2];
257 u32 reg;
258
259 sps = run->h265.sps;
260 pps = run->h265.pps;
261 slice_params = run->h265.slice_params;
262 decode_params = run->h265.decode_params;
263 pred_weight_table = &slice_params->pred_weight_table;
264
265 log2_max_luma_coding_block_size =
266 sps->log2_min_luma_coding_block_size_minus3 + 3 +
267 sps->log2_diff_max_min_luma_coding_block_size;
268 ctb_size_luma = 1UL << log2_max_luma_coding_block_size;
269 width_in_ctb_luma =
270 DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
271
272
273 if (!ctx->codec.h265.mv_col_buf_size) {
274 unsigned int num_buffers =
275 run->dst->vb2_buf.vb2_queue->num_buffers;
276
277
278
279
280
281
282 ctx->codec.h265.mv_col_buf_unit_size =
283 DIV_ROUND_UP(ctx->src_fmt.width, ctb_size_luma) *
284 DIV_ROUND_UP(ctx->src_fmt.height, ctb_size_luma) *
285 CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE + SZ_1K;
286
287 ctx->codec.h265.mv_col_buf_size = num_buffers *
288 ctx->codec.h265.mv_col_buf_unit_size;
289
290 ctx->codec.h265.mv_col_buf =
291 dma_alloc_coherent(dev->dev,
292 ctx->codec.h265.mv_col_buf_size,
293 &ctx->codec.h265.mv_col_buf_addr,
294 GFP_KERNEL);
295 if (!ctx->codec.h265.mv_col_buf) {
296 ctx->codec.h265.mv_col_buf_size = 0;
297
298 return;
299 }
300 }
301
302
303 cedrus_engine_enable(ctx, CEDRUS_CODEC_H265);
304
305
306
307 cedrus_write(dev, VE_DEC_H265_BITS_OFFSET, 0);
308
309 reg = slice_params->bit_size;
310 cedrus_write(dev, VE_DEC_H265_BITS_LEN, reg);
311
312
313
314 src_buf_addr = vb2_dma_contig_plane_dma_addr(&run->src->vb2_buf, 0);
315
316 reg = VE_DEC_H265_BITS_ADDR_BASE(src_buf_addr);
317 reg |= VE_DEC_H265_BITS_ADDR_VALID_SLICE_DATA;
318 reg |= VE_DEC_H265_BITS_ADDR_LAST_SLICE_DATA;
319 reg |= VE_DEC_H265_BITS_ADDR_FIRST_SLICE_DATA;
320
321 cedrus_write(dev, VE_DEC_H265_BITS_ADDR, reg);
322
323 src_buf_end_addr = src_buf_addr +
324 DIV_ROUND_UP(slice_params->bit_size, 8);
325
326 reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_end_addr);
327 cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg);
328
329
330 reg = VE_DEC_H265_DEC_CTB_ADDR_X(slice_params->slice_segment_addr % width_in_ctb_luma);
331 reg |= VE_DEC_H265_DEC_CTB_ADDR_Y(slice_params->slice_segment_addr / width_in_ctb_luma);
332 cedrus_write(dev, VE_DEC_H265_DEC_CTB_ADDR, reg);
333
334 cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, 0);
335 cedrus_write(dev, VE_DEC_H265_TILE_END_CTB, 0);
336
337
338 if (ctx->fh.m2m_ctx->new_frame)
339 cedrus_write(dev, VE_DEC_H265_DEC_CTB_NUM, 0);
340
341
342 cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_INIT_SWDEC);
343
344 cedrus_h265_skip_bits(dev, slice_params->data_bit_offset);
345
346
347
348 reg = VE_DEC_H265_DEC_NAL_HDR_NAL_UNIT_TYPE(slice_params->nal_unit_type) |
349 VE_DEC_H265_DEC_NAL_HDR_NUH_TEMPORAL_ID_PLUS1(slice_params->nuh_temporal_id_plus1);
350
351 cedrus_write(dev, VE_DEC_H265_DEC_NAL_HDR, reg);
352
353
354
355 reg = VE_DEC_H265_DEC_SPS_HDR_MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA(sps->max_transform_hierarchy_depth_intra) |
356 VE_DEC_H265_DEC_SPS_HDR_MAX_TRANSFORM_HIERARCHY_DEPTH_INTER(sps->max_transform_hierarchy_depth_inter) |
357 VE_DEC_H265_DEC_SPS_HDR_LOG2_DIFF_MAX_MIN_TRANSFORM_BLOCK_SIZE(sps->log2_diff_max_min_luma_transform_block_size) |
358 VE_DEC_H265_DEC_SPS_HDR_LOG2_MIN_TRANSFORM_BLOCK_SIZE_MINUS2(sps->log2_min_luma_transform_block_size_minus2) |
359 VE_DEC_H265_DEC_SPS_HDR_LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE(sps->log2_diff_max_min_luma_coding_block_size) |
360 VE_DEC_H265_DEC_SPS_HDR_LOG2_MIN_LUMA_CODING_BLOCK_SIZE_MINUS3(sps->log2_min_luma_coding_block_size_minus3) |
361 VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_CHROMA_MINUS8(sps->bit_depth_chroma_minus8) |
362 VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_LUMA_MINUS8(sps->bit_depth_luma_minus8) |
363 VE_DEC_H265_DEC_SPS_HDR_CHROMA_FORMAT_IDC(sps->chroma_format_idc);
364
365 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_STRONG_INTRA_SMOOTHING_ENABLE,
366 V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED,
367 sps->flags);
368
369 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_SPS_TEMPORAL_MVP_ENABLED,
370 V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED,
371 sps->flags);
372
373 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_SAMPLE_ADAPTIVE_OFFSET_ENABLED,
374 V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET,
375 sps->flags);
376
377 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_AMP_ENABLED,
378 V4L2_HEVC_SPS_FLAG_AMP_ENABLED, sps->flags);
379
380 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_SEPARATE_COLOUR_PLANE,
381 V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE,
382 sps->flags);
383
384 cedrus_write(dev, VE_DEC_H265_DEC_SPS_HDR, reg);
385
386 reg = VE_DEC_H265_DEC_PCM_CTRL_LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE(sps->log2_diff_max_min_pcm_luma_coding_block_size) |
387 VE_DEC_H265_DEC_PCM_CTRL_LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE_MINUS3(sps->log2_min_pcm_luma_coding_block_size_minus3) |
388 VE_DEC_H265_DEC_PCM_CTRL_PCM_SAMPLE_BIT_DEPTH_CHROMA_MINUS1(sps->pcm_sample_bit_depth_chroma_minus1) |
389 VE_DEC_H265_DEC_PCM_CTRL_PCM_SAMPLE_BIT_DEPTH_LUMA_MINUS1(sps->pcm_sample_bit_depth_luma_minus1);
390
391 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PCM_CTRL_FLAG_PCM_ENABLED,
392 V4L2_HEVC_SPS_FLAG_PCM_ENABLED, sps->flags);
393
394 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PCM_CTRL_FLAG_PCM_LOOP_FILTER_DISABLED,
395 V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED,
396 sps->flags);
397
398 cedrus_write(dev, VE_DEC_H265_DEC_PCM_CTRL, reg);
399
400
401
402 reg = VE_DEC_H265_DEC_PPS_CTRL0_PPS_CR_QP_OFFSET(pps->pps_cr_qp_offset) |
403 VE_DEC_H265_DEC_PPS_CTRL0_PPS_CB_QP_OFFSET(pps->pps_cb_qp_offset) |
404 VE_DEC_H265_DEC_PPS_CTRL0_INIT_QP_MINUS26(pps->init_qp_minus26) |
405 VE_DEC_H265_DEC_PPS_CTRL0_DIFF_CU_QP_DELTA_DEPTH(pps->diff_cu_qp_delta_depth);
406
407 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_CU_QP_DELTA_ENABLED,
408 V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED,
409 pps->flags);
410
411 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_TRANSFORM_SKIP_ENABLED,
412 V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED,
413 pps->flags);
414
415 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_CONSTRAINED_INTRA_PRED,
416 V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED,
417 pps->flags);
418
419 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_SIGN_DATA_HIDING_ENABLED,
420 V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED,
421 pps->flags);
422
423 cedrus_write(dev, VE_DEC_H265_DEC_PPS_CTRL0, reg);
424
425 reg = VE_DEC_H265_DEC_PPS_CTRL1_LOG2_PARALLEL_MERGE_LEVEL_MINUS2(pps->log2_parallel_merge_level_minus2);
426
427 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED,
428 V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED,
429 pps->flags);
430
431 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED,
432 V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED,
433 pps->flags);
434
435 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_ENTROPY_CODING_SYNC_ENABLED,
436 V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED,
437 pps->flags);
438
439
440
441 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TRANSQUANT_BYPASS_ENABLED,
442 V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED,
443 pps->flags);
444
445 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_WEIGHTED_BIPRED,
446 V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED, pps->flags);
447
448 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_WEIGHTED_PRED,
449 V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED, pps->flags);
450
451 cedrus_write(dev, VE_DEC_H265_DEC_PPS_CTRL1, reg);
452
453
454
455 reg = VE_DEC_H265_DEC_SLICE_HDR_INFO0_PICTURE_TYPE(slice_params->pic_struct) |
456 VE_DEC_H265_DEC_SLICE_HDR_INFO0_FIVE_MINUS_MAX_NUM_MERGE_CAND(slice_params->five_minus_max_num_merge_cand) |
457 VE_DEC_H265_DEC_SLICE_HDR_INFO0_NUM_REF_IDX_L1_ACTIVE_MINUS1(slice_params->num_ref_idx_l1_active_minus1) |
458 VE_DEC_H265_DEC_SLICE_HDR_INFO0_NUM_REF_IDX_L0_ACTIVE_MINUS1(slice_params->num_ref_idx_l0_active_minus1) |
459 VE_DEC_H265_DEC_SLICE_HDR_INFO0_COLLOCATED_REF_IDX(slice_params->collocated_ref_idx) |
460 VE_DEC_H265_DEC_SLICE_HDR_INFO0_COLOUR_PLANE_ID(slice_params->colour_plane_id) |
461 VE_DEC_H265_DEC_SLICE_HDR_INFO0_SLICE_TYPE(slice_params->slice_type);
462
463 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_COLLOCATED_FROM_L0,
464 V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0,
465 slice_params->flags);
466
467 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_CABAC_INIT,
468 V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT,
469 slice_params->flags);
470
471 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_MVD_L1_ZERO,
472 V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO,
473 slice_params->flags);
474
475 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_SAO_CHROMA,
476 V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA,
477 slice_params->flags);
478
479 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_SAO_LUMA,
480 V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA,
481 slice_params->flags);
482
483 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_TEMPORAL_MVP_ENABLE,
484 V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED,
485 slice_params->flags);
486
487 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_DEPENDENT_SLICE_SEGMENT,
488 V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT,
489 slice_params->flags);
490
491 if (ctx->fh.m2m_ctx->new_frame)
492 reg |= VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_FIRST_SLICE_SEGMENT_IN_PIC;
493
494 cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO0, reg);
495
496 reg = VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(slice_params->slice_tc_offset_div2) |
497 VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(slice_params->slice_beta_offset_div2) |
498 VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(decode_params->num_poc_st_curr_after == 0) |
499 VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(slice_params->slice_cr_qp_offset) |
500 VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(slice_params->slice_cb_qp_offset) |
501 VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(slice_params->slice_qp_delta);
502
503 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED,
504 V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED,
505 slice_params->flags);
506
507 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED,
508 V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED,
509 slice_params->flags);
510
511 cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO1, reg);
512
513 chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom +
514 pred_weight_table->delta_chroma_log2_weight_denom;
515 reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(0) |
516 VE_DEC_H265_DEC_SLICE_HDR_INFO2_CHROMA_LOG2_WEIGHT_DENOM(chroma_log2_weight_denom) |
517 VE_DEC_H265_DEC_SLICE_HDR_INFO2_LUMA_LOG2_WEIGHT_DENOM(pred_weight_table->luma_log2_weight_denom);
518
519 cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO2, reg);
520
521
522
523 reg = VE_DEC_H265_DEC_PIC_SIZE_WIDTH(ctx->src_fmt.width) |
524 VE_DEC_H265_DEC_PIC_SIZE_HEIGHT(ctx->src_fmt.height);
525
526 cedrus_write(dev, VE_DEC_H265_DEC_PIC_SIZE, reg);
527
528
529
530 reg = VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT;
531 cedrus_write(dev, VE_DEC_H265_SCALING_LIST_CTRL0, reg);
532
533
534 reg = VE_DEC_H265_NEIGHBOR_INFO_ADDR_BASE(ctx->codec.h265.neighbor_info_buf_addr);
535 cedrus_write(dev, VE_DEC_H265_NEIGHBOR_INFO_ADDR, reg);
536
537
538 cedrus_h265_frame_info_write_dpb(ctx, decode_params->dpb,
539 decode_params->num_active_dpb_entries);
540
541
542
543 output_pic_list_index = V4L2_HEVC_DPB_ENTRIES_NUM_MAX;
544 pic_order_cnt[0] = slice_params->slice_pic_order_cnt;
545 pic_order_cnt[1] = slice_params->slice_pic_order_cnt;
546
547 cedrus_h265_frame_info_write_single(ctx, output_pic_list_index,
548 slice_params->pic_struct != 0,
549 pic_order_cnt,
550 run->dst->vb2_buf.index);
551
552 cedrus_write(dev, VE_DEC_H265_OUTPUT_FRAME_IDX, output_pic_list_index);
553
554
555 if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I) {
556 cedrus_h265_ref_pic_list_write(dev, decode_params->dpb,
557 slice_params->ref_idx_l0,
558 slice_params->num_ref_idx_l0_active_minus1 + 1,
559 VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0);
560
561 if ((pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED) ||
562 (pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED))
563 cedrus_h265_pred_weight_write(dev,
564 pred_weight_table->delta_luma_weight_l0,
565 pred_weight_table->luma_offset_l0,
566 pred_weight_table->delta_chroma_weight_l0,
567 pred_weight_table->chroma_offset_l0,
568 slice_params->num_ref_idx_l0_active_minus1 + 1,
569 VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0,
570 VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L0);
571 }
572
573
574 if (slice_params->slice_type == V4L2_HEVC_SLICE_TYPE_B) {
575 cedrus_h265_ref_pic_list_write(dev, decode_params->dpb,
576 slice_params->ref_idx_l1,
577 slice_params->num_ref_idx_l1_active_minus1 + 1,
578 VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1);
579
580 if (pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED)
581 cedrus_h265_pred_weight_write(dev,
582 pred_weight_table->delta_luma_weight_l1,
583 pred_weight_table->luma_offset_l1,
584 pred_weight_table->delta_chroma_weight_l1,
585 pred_weight_table->chroma_offset_l1,
586 slice_params->num_ref_idx_l1_active_minus1 + 1,
587 VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L1,
588 VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L1);
589 }
590
591
592 cedrus_write(dev, VE_DEC_H265_CTRL, VE_DEC_H265_CTRL_IRQ_MASK);
593}
594
595static int cedrus_h265_start(struct cedrus_ctx *ctx)
596{
597 struct cedrus_dev *dev = ctx->dev;
598
599
600 ctx->codec.h265.mv_col_buf_size = 0;
601
602 ctx->codec.h265.neighbor_info_buf =
603 dma_alloc_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
604 &ctx->codec.h265.neighbor_info_buf_addr,
605 GFP_KERNEL);
606 if (!ctx->codec.h265.neighbor_info_buf)
607 return -ENOMEM;
608
609 return 0;
610}
611
612static void cedrus_h265_stop(struct cedrus_ctx *ctx)
613{
614 struct cedrus_dev *dev = ctx->dev;
615
616 if (ctx->codec.h265.mv_col_buf_size > 0) {
617 dma_free_coherent(dev->dev, ctx->codec.h265.mv_col_buf_size,
618 ctx->codec.h265.mv_col_buf,
619 ctx->codec.h265.mv_col_buf_addr);
620
621 ctx->codec.h265.mv_col_buf_size = 0;
622 }
623
624 dma_free_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
625 ctx->codec.h265.neighbor_info_buf,
626 ctx->codec.h265.neighbor_info_buf_addr);
627}
628
629static void cedrus_h265_trigger(struct cedrus_ctx *ctx)
630{
631 struct cedrus_dev *dev = ctx->dev;
632
633 cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_DEC_SLICE);
634}
635
636struct cedrus_dec_ops cedrus_dec_ops_h265 = {
637 .irq_clear = cedrus_h265_irq_clear,
638 .irq_disable = cedrus_h265_irq_disable,
639 .irq_status = cedrus_h265_irq_status,
640 .setup = cedrus_h265_setup,
641 .start = cedrus_h265_start,
642 .stop = cedrus_h265_stop,
643 .trigger = cedrus_h265_trigger,
644};
645