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_hevc_pred_weight_table *pred_weight_table; 249 dma_addr_t src_buf_addr; 250 dma_addr_t src_buf_end_addr; 251 u32 chroma_log2_weight_denom; 252 u32 output_pic_list_index; 253 u32 pic_order_cnt[2]; 254 u32 reg; 255 256 sps = run->h265.sps; 257 pps = run->h265.pps; 258 slice_params = run->h265.slice_params; 259 pred_weight_table = &slice_params->pred_weight_table; 260 261 /* MV column buffer size and allocation. */ 262 if (!ctx->codec.h265.mv_col_buf_size) { 263 unsigned int num_buffers = 264 run->dst->vb2_buf.vb2_queue->num_buffers; 265 unsigned int 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 unsigned int ctb_size_luma = 269 1UL << log2_max_luma_coding_block_size; 270 271 /* 272 * Each CTB requires a MV col buffer with a specific unit size. 273 * Since the address is given with missing lsb bits, 1 KiB is 274 * added to each buffer to ensure proper alignment. 275 */ 276 ctx->codec.h265.mv_col_buf_unit_size = 277 DIV_ROUND_UP(ctx->src_fmt.width, ctb_size_luma) * 278 DIV_ROUND_UP(ctx->src_fmt.height, ctb_size_luma) * 279 CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE + SZ_1K; 280 281 ctx->codec.h265.mv_col_buf_size = num_buffers * 282 ctx->codec.h265.mv_col_buf_unit_size; 283 284 ctx->codec.h265.mv_col_buf = 285 dma_alloc_coherent(dev->dev, 286 ctx->codec.h265.mv_col_buf_size, 287 &ctx->codec.h265.mv_col_buf_addr, 288 GFP_KERNEL); 289 if (!ctx->codec.h265.mv_col_buf) { 290 ctx->codec.h265.mv_col_buf_size = 0; 291 // TODO: Abort the process here. 292 return; 293 } 294 } 295 296 /* Activate H265 engine. */ 297 cedrus_engine_enable(ctx, CEDRUS_CODEC_H265); 298 299 /* Source offset and length in bits. */ 300 301 cedrus_write(dev, VE_DEC_H265_BITS_OFFSET, 0); 302 303 reg = slice_params->bit_size; 304 cedrus_write(dev, VE_DEC_H265_BITS_LEN, reg); 305 306 /* Source beginning and end addresses. */ 307 308 src_buf_addr = vb2_dma_contig_plane_dma_addr(&run->src->vb2_buf, 0); 309 310 reg = VE_DEC_H265_BITS_ADDR_BASE(src_buf_addr); 311 reg |= VE_DEC_H265_BITS_ADDR_VALID_SLICE_DATA; 312 reg |= VE_DEC_H265_BITS_ADDR_LAST_SLICE_DATA; 313 reg |= VE_DEC_H265_BITS_ADDR_FIRST_SLICE_DATA; 314 315 cedrus_write(dev, VE_DEC_H265_BITS_ADDR, reg); 316 317 src_buf_end_addr = src_buf_addr + 318 DIV_ROUND_UP(slice_params->bit_size, 8); 319 320 reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_end_addr); 321 cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg); 322 323 /* Coding tree block address: start at the beginning. */ 324 reg = VE_DEC_H265_DEC_CTB_ADDR_X(0) | VE_DEC_H265_DEC_CTB_ADDR_Y(0); 325 cedrus_write(dev, VE_DEC_H265_DEC_CTB_ADDR, reg); 326 327 cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, 0); 328 cedrus_write(dev, VE_DEC_H265_TILE_END_CTB, 0); 329 330 /* Clear the number of correctly-decoded coding tree blocks. */ 331 cedrus_write(dev, VE_DEC_H265_DEC_CTB_NUM, 0); 332 333 /* Initialize bitstream access. */ 334 cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_INIT_SWDEC); 335 336 cedrus_h265_skip_bits(dev, slice_params->data_bit_offset); 337 338 /* Bitstream parameters. */ 339 340 reg = VE_DEC_H265_DEC_NAL_HDR_NAL_UNIT_TYPE(slice_params->nal_unit_type) | 341 VE_DEC_H265_DEC_NAL_HDR_NUH_TEMPORAL_ID_PLUS1(slice_params->nuh_temporal_id_plus1); 342 343 cedrus_write(dev, VE_DEC_H265_DEC_NAL_HDR, reg); 344 345 /* SPS. */ 346 347 reg = VE_DEC_H265_DEC_SPS_HDR_MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA(sps->max_transform_hierarchy_depth_intra) | 348 VE_DEC_H265_DEC_SPS_HDR_MAX_TRANSFORM_HIERARCHY_DEPTH_INTER(sps->max_transform_hierarchy_depth_inter) | 349 VE_DEC_H265_DEC_SPS_HDR_LOG2_DIFF_MAX_MIN_TRANSFORM_BLOCK_SIZE(sps->log2_diff_max_min_luma_transform_block_size) | 350 VE_DEC_H265_DEC_SPS_HDR_LOG2_MIN_TRANSFORM_BLOCK_SIZE_MINUS2(sps->log2_min_luma_transform_block_size_minus2) | 351 VE_DEC_H265_DEC_SPS_HDR_LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE(sps->log2_diff_max_min_luma_coding_block_size) | 352 VE_DEC_H265_DEC_SPS_HDR_LOG2_MIN_LUMA_CODING_BLOCK_SIZE_MINUS3(sps->log2_min_luma_coding_block_size_minus3) | 353 VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_CHROMA_MINUS8(sps->bit_depth_chroma_minus8) | 354 VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_LUMA_MINUS8(sps->bit_depth_luma_minus8) | 355 VE_DEC_H265_DEC_SPS_HDR_CHROMA_FORMAT_IDC(sps->chroma_format_idc); 356 357 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_STRONG_INTRA_SMOOTHING_ENABLE, 358 V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED, 359 sps->flags); 360 361 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_SPS_TEMPORAL_MVP_ENABLED, 362 V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED, 363 sps->flags); 364 365 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_SAMPLE_ADAPTIVE_OFFSET_ENABLED, 366 V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET, 367 sps->flags); 368 369 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_AMP_ENABLED, 370 V4L2_HEVC_SPS_FLAG_AMP_ENABLED, sps->flags); 371 372 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_SEPARATE_COLOUR_PLANE, 373 V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE, 374 sps->flags); 375 376 cedrus_write(dev, VE_DEC_H265_DEC_SPS_HDR, reg); 377 378 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) | 379 VE_DEC_H265_DEC_PCM_CTRL_LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE_MINUS3(sps->log2_min_pcm_luma_coding_block_size_minus3) | 380 VE_DEC_H265_DEC_PCM_CTRL_PCM_SAMPLE_BIT_DEPTH_CHROMA_MINUS1(sps->pcm_sample_bit_depth_chroma_minus1) | 381 VE_DEC_H265_DEC_PCM_CTRL_PCM_SAMPLE_BIT_DEPTH_LUMA_MINUS1(sps->pcm_sample_bit_depth_luma_minus1); 382 383 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PCM_CTRL_FLAG_PCM_ENABLED, 384 V4L2_HEVC_SPS_FLAG_PCM_ENABLED, sps->flags); 385 386 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PCM_CTRL_FLAG_PCM_LOOP_FILTER_DISABLED, 387 V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED, 388 sps->flags); 389 390 cedrus_write(dev, VE_DEC_H265_DEC_PCM_CTRL, reg); 391 392 /* PPS. */ 393 394 reg = VE_DEC_H265_DEC_PPS_CTRL0_PPS_CR_QP_OFFSET(pps->pps_cr_qp_offset) | 395 VE_DEC_H265_DEC_PPS_CTRL0_PPS_CB_QP_OFFSET(pps->pps_cb_qp_offset) | 396 VE_DEC_H265_DEC_PPS_CTRL0_INIT_QP_MINUS26(pps->init_qp_minus26) | 397 VE_DEC_H265_DEC_PPS_CTRL0_DIFF_CU_QP_DELTA_DEPTH(pps->diff_cu_qp_delta_depth); 398 399 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_CU_QP_DELTA_ENABLED, 400 V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED, 401 pps->flags); 402 403 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_TRANSFORM_SKIP_ENABLED, 404 V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED, 405 pps->flags); 406 407 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_CONSTRAINED_INTRA_PRED, 408 V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED, 409 pps->flags); 410 411 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_SIGN_DATA_HIDING_ENABLED, 412 V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED, 413 pps->flags); 414 415 cedrus_write(dev, VE_DEC_H265_DEC_PPS_CTRL0, reg); 416 417 reg = VE_DEC_H265_DEC_PPS_CTRL1_LOG2_PARALLEL_MERGE_LEVEL_MINUS2(pps->log2_parallel_merge_level_minus2); 418 419 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED, 420 V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED, 421 pps->flags); 422 423 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED, 424 V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED, 425 pps->flags); 426 427 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_ENTROPY_CODING_SYNC_ENABLED, 428 V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED, 429 pps->flags); 430 431 /* TODO: VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TILES_ENABLED */ 432 433 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TRANSQUANT_BYPASS_ENABLED, 434 V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED, 435 pps->flags); 436 437 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_WEIGHTED_BIPRED, 438 V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED, pps->flags); 439 440 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_WEIGHTED_PRED, 441 V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED, pps->flags); 442 443 cedrus_write(dev, VE_DEC_H265_DEC_PPS_CTRL1, reg); 444 445 /* Slice Parameters. */ 446 447 reg = VE_DEC_H265_DEC_SLICE_HDR_INFO0_PICTURE_TYPE(slice_params->pic_struct) | 448 VE_DEC_H265_DEC_SLICE_HDR_INFO0_FIVE_MINUS_MAX_NUM_MERGE_CAND(slice_params->five_minus_max_num_merge_cand) | 449 VE_DEC_H265_DEC_SLICE_HDR_INFO0_NUM_REF_IDX_L1_ACTIVE_MINUS1(slice_params->num_ref_idx_l1_active_minus1) | 450 VE_DEC_H265_DEC_SLICE_HDR_INFO0_NUM_REF_IDX_L0_ACTIVE_MINUS1(slice_params->num_ref_idx_l0_active_minus1) | 451 VE_DEC_H265_DEC_SLICE_HDR_INFO0_COLLOCATED_REF_IDX(slice_params->collocated_ref_idx) | 452 VE_DEC_H265_DEC_SLICE_HDR_INFO0_COLOUR_PLANE_ID(slice_params->colour_plane_id) | 453 VE_DEC_H265_DEC_SLICE_HDR_INFO0_SLICE_TYPE(slice_params->slice_type); 454 455 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_COLLOCATED_FROM_L0, 456 V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0, 457 slice_params->flags); 458 459 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_CABAC_INIT, 460 V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT, 461 slice_params->flags); 462 463 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_MVD_L1_ZERO, 464 V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO, 465 slice_params->flags); 466 467 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_SAO_CHROMA, 468 V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA, 469 slice_params->flags); 470 471 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_SAO_LUMA, 472 V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA, 473 slice_params->flags); 474 475 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_TEMPORAL_MVP_ENABLE, 476 V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED, 477 slice_params->flags); 478 479 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_DEPENDENT_SLICE_SEGMENT, 480 V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT, 481 pps->flags); 482 483 /* FIXME: For multi-slice support. */ 484 reg |= VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_FIRST_SLICE_SEGMENT_IN_PIC; 485 486 cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO0, reg); 487 488 reg = VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(slice_params->slice_tc_offset_div2) | 489 VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(slice_params->slice_beta_offset_div2) | 490 VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(slice_params->num_rps_poc_st_curr_after == 0) | 491 VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(slice_params->slice_cr_qp_offset) | 492 VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(slice_params->slice_cb_qp_offset) | 493 VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(slice_params->slice_qp_delta); 494 495 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED, 496 V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED, 497 slice_params->flags); 498 499 reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED, 500 V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED, 501 slice_params->flags); 502 503 cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO1, reg); 504 505 chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom + 506 pred_weight_table->delta_chroma_log2_weight_denom; 507 reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(0) | 508 VE_DEC_H265_DEC_SLICE_HDR_INFO2_CHROMA_LOG2_WEIGHT_DENOM(chroma_log2_weight_denom) | 509 VE_DEC_H265_DEC_SLICE_HDR_INFO2_LUMA_LOG2_WEIGHT_DENOM(pred_weight_table->luma_log2_weight_denom); 510 511 cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO2, reg); 512 513 /* Decoded picture size. */ 514 515 reg = VE_DEC_H265_DEC_PIC_SIZE_WIDTH(ctx->src_fmt.width) | 516 VE_DEC_H265_DEC_PIC_SIZE_HEIGHT(ctx->src_fmt.height); 517 518 cedrus_write(dev, VE_DEC_H265_DEC_PIC_SIZE, reg); 519 520 /* Scaling list. */ 521 522 reg = VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT; 523 cedrus_write(dev, VE_DEC_H265_SCALING_LIST_CTRL0, reg); 524 525 /* Neightbor information address. */ 526 reg = VE_DEC_H265_NEIGHBOR_INFO_ADDR_BASE(ctx->codec.h265.neighbor_info_buf_addr); 527 cedrus_write(dev, VE_DEC_H265_NEIGHBOR_INFO_ADDR, reg); 528 529 /* Write decoded picture buffer in pic list. */ 530 cedrus_h265_frame_info_write_dpb(ctx, slice_params->dpb, 531 slice_params->num_active_dpb_entries); 532 533 /* Output frame. */ 534 535 output_pic_list_index = V4L2_HEVC_DPB_ENTRIES_NUM_MAX; 536 pic_order_cnt[0] = slice_params->slice_pic_order_cnt; 537 pic_order_cnt[1] = slice_params->slice_pic_order_cnt; 538 539 cedrus_h265_frame_info_write_single(ctx, output_pic_list_index, 540 slice_params->pic_struct != 0, 541 pic_order_cnt, 542 run->dst->vb2_buf.index); 543 544 cedrus_write(dev, VE_DEC_H265_OUTPUT_FRAME_IDX, output_pic_list_index); 545 546 /* Reference picture list 0 (for P/B frames). */ 547 if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I) { 548 cedrus_h265_ref_pic_list_write(dev, slice_params->dpb, 549 slice_params->ref_idx_l0, 550 slice_params->num_ref_idx_l0_active_minus1 + 1, 551 VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0); 552 553 if ((pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED) || 554 (pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED)) 555 cedrus_h265_pred_weight_write(dev, 556 pred_weight_table->delta_luma_weight_l0, 557 pred_weight_table->luma_offset_l0, 558 pred_weight_table->delta_chroma_weight_l0, 559 pred_weight_table->chroma_offset_l0, 560 slice_params->num_ref_idx_l0_active_minus1 + 1, 561 VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0, 562 VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L0); 563 } 564 565 /* Reference picture list 1 (for B frames). */ 566 if (slice_params->slice_type == V4L2_HEVC_SLICE_TYPE_B) { 567 cedrus_h265_ref_pic_list_write(dev, slice_params->dpb, 568 slice_params->ref_idx_l1, 569 slice_params->num_ref_idx_l1_active_minus1 + 1, 570 VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1); 571 572 if (pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED) 573 cedrus_h265_pred_weight_write(dev, 574 pred_weight_table->delta_luma_weight_l1, 575 pred_weight_table->luma_offset_l1, 576 pred_weight_table->delta_chroma_weight_l1, 577 pred_weight_table->chroma_offset_l1, 578 slice_params->num_ref_idx_l1_active_minus1 + 1, 579 VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L1, 580 VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L1); 581 } 582 583 /* Enable appropriate interruptions. */ 584 cedrus_write(dev, VE_DEC_H265_CTRL, VE_DEC_H265_CTRL_IRQ_MASK); 585 } 586 587 static int cedrus_h265_start(struct cedrus_ctx *ctx) 588 { 589 struct cedrus_dev *dev = ctx->dev; 590 591 /* The buffer size is calculated at setup time. */ 592 ctx->codec.h265.mv_col_buf_size = 0; 593 594 ctx->codec.h265.neighbor_info_buf = 595 dma_alloc_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE, 596 &ctx->codec.h265.neighbor_info_buf_addr, 597 GFP_KERNEL); 598 if (!ctx->codec.h265.neighbor_info_buf) 599 return -ENOMEM; 600 601 return 0; 602 } 603 604 static void cedrus_h265_stop(struct cedrus_ctx *ctx) 605 { 606 struct cedrus_dev *dev = ctx->dev; 607 608 if (ctx->codec.h265.mv_col_buf_size > 0) { 609 dma_free_coherent(dev->dev, ctx->codec.h265.mv_col_buf_size, 610 ctx->codec.h265.mv_col_buf, 611 ctx->codec.h265.mv_col_buf_addr); 612 613 ctx->codec.h265.mv_col_buf_size = 0; 614 } 615 616 dma_free_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE, 617 ctx->codec.h265.neighbor_info_buf, 618 ctx->codec.h265.neighbor_info_buf_addr); 619 } 620 621 static void cedrus_h265_trigger(struct cedrus_ctx *ctx) 622 { 623 struct cedrus_dev *dev = ctx->dev; 624 625 cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_DEC_SLICE); 626 } 627 628 struct cedrus_dec_ops cedrus_dec_ops_h265 = { 629 .irq_clear = cedrus_h265_irq_clear, 630 .irq_disable = cedrus_h265_irq_disable, 631 .irq_status = cedrus_h265_irq_status, 632 .setup = cedrus_h265_setup, 633 .start = cedrus_h265_start, 634 .stop = cedrus_h265_stop, 635 .trigger = cedrus_h265_trigger, 636 }; 637