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