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