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/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 * These are the sizes for side buffers required by the hardware for storing 21 * internal decoding metadata. They match the values used by the early BSP 22 * implementations, that were initially exposed in libvdpau-sunxi. 23 * Subsequent BSP implementations seem to double the neighbor info buffer size 24 * for the H6 SoC, which may be related to 10 bit H265 support. 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 30 struct 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 39 struct cedrus_h265_sram_pred_weight { 40 __s8 delta_weight; 41 __s8 offset; 42 } __packed; 43 44 static 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 59 static 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 66 static 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 76 static 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 81 static 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 92 static inline dma_addr_t 93 cedrus_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 101 static 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 135 static 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 156 static 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 /* Each SRAM word gathers up to 4 references. */ 176 word |= value << shift; 177 178 /* Write the word to SRAM and clear it for the next batch. */ 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 186 static 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 224 static 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 241 static 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 /* MV column buffer size and allocation. */ 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 * Each CTB requires a MV col buffer with a specific unit size. 279 * Since the address is given with missing lsb bits, 1 KiB is 280 * added to each buffer to ensure proper alignment. 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 // TODO: Abort the process here. 298 return; 299 } 300 } 301 302 /* Activate H265 engine. */ 303 cedrus_engine_enable(ctx, CEDRUS_CODEC_H265); 304 305 /* Source offset and length in bits. */ 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 /* Source beginning and end addresses. */ 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 /* Coding tree block address */ 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 /* Clear the number of correctly-decoded coding tree blocks. */ 338 if (ctx->fh.m2m_ctx->new_frame) 339 cedrus_write(dev, VE_DEC_H265_DEC_CTB_NUM, 0); 340 341 /* Initialize bitstream access. */ 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 /* Bitstream parameters. */ 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 /* SPS. */ 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 /* PPS. */ 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 /* TODO: VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TILES_ENABLED */ 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 /* Slice Parameters. */ 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 /* Decoded picture size. */ 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 /* Scaling list. */ 529 530 reg = VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT; 531 cedrus_write(dev, VE_DEC_H265_SCALING_LIST_CTRL0, reg); 532 533 /* Neightbor information address. */ 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 /* Write decoded picture buffer in pic list. */ 538 cedrus_h265_frame_info_write_dpb(ctx, decode_params->dpb, 539 decode_params->num_active_dpb_entries); 540 541 /* Output frame. */ 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 /* Reference picture list 0 (for P/B frames). */ 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 /* Reference picture list 1 (for B frames). */ 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 /* Enable appropriate interruptions. */ 592 cedrus_write(dev, VE_DEC_H265_CTRL, VE_DEC_H265_CTRL_IRQ_MASK); 593 } 594 595 static int cedrus_h265_start(struct cedrus_ctx *ctx) 596 { 597 struct cedrus_dev *dev = ctx->dev; 598 599 /* The buffer size is calculated at setup time. */ 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 612 static 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 629 static 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 636 struct 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