linux/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
<<
>>
Prefs
   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
  30struct cedrus_h265_sram_frame_info {
  31        __le32  top_pic_order_cnt;
  32        __le32  bottom_pic_order_cnt;
  33        __le32  top_mv_col_buf_addr;
  34        __le32  bottom_mv_col_buf_addr;
  35        __le32  luma_addr;
  36        __le32  chroma_addr;
  37} __packed;
  38
  39struct cedrus_h265_sram_pred_weight {
  40        __s8    delta_weight;
  41        __s8    offset;
  42} __packed;
  43
  44static enum cedrus_irq_status cedrus_h265_irq_status(struct cedrus_ctx *ctx)
  45{
  46        struct cedrus_dev *dev = ctx->dev;
  47        u32 reg;
  48
  49        reg = cedrus_read(dev, VE_DEC_H265_STATUS);
  50        reg &= VE_DEC_H265_STATUS_CHECK_MASK;
  51
  52        if (reg & VE_DEC_H265_STATUS_CHECK_ERROR ||
  53            !(reg & VE_DEC_H265_STATUS_SUCCESS))
  54                return CEDRUS_IRQ_ERROR;
  55
  56        return CEDRUS_IRQ_OK;
  57}
  58
  59static void cedrus_h265_irq_clear(struct cedrus_ctx *ctx)
  60{
  61        struct cedrus_dev *dev = ctx->dev;
  62
  63        cedrus_write(dev, VE_DEC_H265_STATUS, VE_DEC_H265_STATUS_CHECK_MASK);
  64}
  65
  66static void cedrus_h265_irq_disable(struct cedrus_ctx *ctx)
  67{
  68        struct cedrus_dev *dev = ctx->dev;
  69        u32 reg = cedrus_read(dev, VE_DEC_H265_CTRL);
  70
  71        reg &= ~VE_DEC_H265_CTRL_IRQ_MASK;
  72
  73        cedrus_write(dev, VE_DEC_H265_CTRL, reg);
  74}
  75
  76static void cedrus_h265_sram_write_offset(struct cedrus_dev *dev, u32 offset)
  77{
  78        cedrus_write(dev, VE_DEC_H265_SRAM_OFFSET, offset);
  79}
  80
  81static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, void *data,
  82                                        unsigned int size)
  83{
  84        u32 *word = data;
  85
  86        while (size >= sizeof(u32)) {
  87                cedrus_write(dev, VE_DEC_H265_SRAM_DATA, *word++);
  88                size -= sizeof(u32);
  89        }
  90}
  91
  92static inline dma_addr_t
  93cedrus_h265_frame_info_mv_col_buf_addr(struct cedrus_ctx *ctx,
  94                                       unsigned int index, unsigned int field)
  95{
  96        return ctx->codec.h265.mv_col_buf_addr + index *
  97               ctx->codec.h265.mv_col_buf_unit_size +
  98               field * ctx->codec.h265.mv_col_buf_unit_size / 2;
  99}
 100
 101static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
 102                                                unsigned int index,
 103                                                bool field_pic,
 104                                                u32 pic_order_cnt[],
 105                                                int buffer_index)
 106{
 107        struct cedrus_dev *dev = ctx->dev;
 108        dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 0);
 109        dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 1);
 110        dma_addr_t mv_col_buf_addr[2] = {
 111                cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index, 0),
 112                cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index,
 113                                                       field_pic ? 1 : 0)
 114        };
 115        u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO +
 116                     VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT * index;
 117        struct cedrus_h265_sram_frame_info frame_info = {
 118                .top_pic_order_cnt = cpu_to_le32(pic_order_cnt[0]),
 119                .bottom_pic_order_cnt = cpu_to_le32(field_pic ?
 120                                                    pic_order_cnt[1] :
 121                                                    pic_order_cnt[0]),
 122                .top_mv_col_buf_addr =
 123                        cpu_to_le32(VE_DEC_H265_SRAM_DATA_ADDR_BASE(mv_col_buf_addr[0])),
 124                .bottom_mv_col_buf_addr = cpu_to_le32(field_pic ?
 125                        VE_DEC_H265_SRAM_DATA_ADDR_BASE(mv_col_buf_addr[1]) :
 126                        VE_DEC_H265_SRAM_DATA_ADDR_BASE(mv_col_buf_addr[0])),
 127                .luma_addr = cpu_to_le32(VE_DEC_H265_SRAM_DATA_ADDR_BASE(dst_luma_addr)),
 128                .chroma_addr = cpu_to_le32(VE_DEC_H265_SRAM_DATA_ADDR_BASE(dst_chroma_addr)),
 129        };
 130
 131        cedrus_h265_sram_write_offset(dev, offset);
 132        cedrus_h265_sram_write_data(dev, &frame_info, sizeof(frame_info));
 133}
 134
 135static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx,
 136                                             const struct v4l2_hevc_dpb_entry *dpb,
 137                                             u8 num_active_dpb_entries)
 138{
 139        struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
 140                                               V4L2_BUF_TYPE_VIDEO_CAPTURE);
 141        unsigned int i;
 142
 143        for (i = 0; i < num_active_dpb_entries; i++) {
 144                int buffer_index = vb2_find_timestamp(vq, dpb[i].timestamp, 0);
 145                u32 pic_order_cnt[2] = {
 146                        dpb[i].pic_order_cnt[0],
 147                        dpb[i].pic_order_cnt[1]
 148                };
 149
 150                cedrus_h265_frame_info_write_single(ctx, i, dpb[i].field_pic,
 151                                                    pic_order_cnt,
 152                                                    buffer_index);
 153        }
 154}
 155
 156static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
 157                                           const struct v4l2_hevc_dpb_entry *dpb,
 158                                           const u8 list[],
 159                                           u8 num_ref_idx_active,
 160                                           u32 sram_offset)
 161{
 162        unsigned int i;
 163        u32 word = 0;
 164
 165        cedrus_h265_sram_write_offset(dev, sram_offset);
 166
 167        for (i = 0; i < num_ref_idx_active; i++) {
 168                unsigned int shift = (i % 4) * 8;
 169                unsigned int index = list[i];
 170                u8 value = list[i];
 171
 172                if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
 173                        value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
 174
 175                /* 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
 186static void cedrus_h265_pred_weight_write(struct cedrus_dev *dev,
 187                                          const s8 delta_luma_weight[],
 188                                          const s8 luma_offset[],
 189                                          const s8 delta_chroma_weight[][2],
 190                                          const s8 chroma_offset[][2],
 191                                          u8 num_ref_idx_active,
 192                                          u32 sram_luma_offset,
 193                                          u32 sram_chroma_offset)
 194{
 195        struct cedrus_h265_sram_pred_weight pred_weight[2] = { { 0 } };
 196        unsigned int i, j;
 197
 198        cedrus_h265_sram_write_offset(dev, sram_luma_offset);
 199
 200        for (i = 0; i < num_ref_idx_active; i++) {
 201                unsigned int index = i % 2;
 202
 203                pred_weight[index].delta_weight = delta_luma_weight[i];
 204                pred_weight[index].offset = luma_offset[i];
 205
 206                if (index == 1 || i == (num_ref_idx_active - 1))
 207                        cedrus_h265_sram_write_data(dev, (u32 *)&pred_weight,
 208                                                    sizeof(pred_weight));
 209        }
 210
 211        cedrus_h265_sram_write_offset(dev, sram_chroma_offset);
 212
 213        for (i = 0; i < num_ref_idx_active; i++) {
 214                for (j = 0; j < 2; j++) {
 215                        pred_weight[j].delta_weight = delta_chroma_weight[i][j];
 216                        pred_weight[j].offset = chroma_offset[i][j];
 217                }
 218
 219                cedrus_h265_sram_write_data(dev, &pred_weight,
 220                                            sizeof(pred_weight));
 221        }
 222}
 223
 224static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num)
 225{
 226        int count = 0;
 227
 228        while (count < num) {
 229                int tmp = min(num - count, 32);
 230
 231                cedrus_write(dev, VE_DEC_H265_TRIGGER,
 232                             VE_DEC_H265_TRIGGER_FLUSH_BITS |
 233                             VE_DEC_H265_TRIGGER_TYPE_N_BITS(tmp));
 234                while (cedrus_read(dev, VE_DEC_H265_STATUS) & VE_DEC_H265_STATUS_VLD_BUSY)
 235                        udelay(1);
 236
 237                count += tmp;
 238        }
 239}
 240
 241static void cedrus_h265_setup(struct cedrus_ctx *ctx,
 242                              struct cedrus_run *run)
 243{
 244        struct cedrus_dev *dev = ctx->dev;
 245        const struct v4l2_ctrl_hevc_sps *sps;
 246        const struct v4l2_ctrl_hevc_pps *pps;
 247        const struct v4l2_ctrl_hevc_slice_params *slice_params;
 248        const struct v4l2_ctrl_hevc_decode_params *decode_params;
 249        const struct v4l2_hevc_pred_weight_table *pred_weight_table;
 250        unsigned int width_in_ctb_luma, ctb_size_luma;
 251        unsigned int log2_max_luma_coding_block_size;
 252        dma_addr_t src_buf_addr;
 253        dma_addr_t src_buf_end_addr;
 254        u32 chroma_log2_weight_denom;
 255        u32 output_pic_list_index;
 256        u32 pic_order_cnt[2];
 257        u32 reg;
 258
 259        sps = run->h265.sps;
 260        pps = run->h265.pps;
 261        slice_params = run->h265.slice_params;
 262        decode_params = run->h265.decode_params;
 263        pred_weight_table = &slice_params->pred_weight_table;
 264
 265        log2_max_luma_coding_block_size =
 266                sps->log2_min_luma_coding_block_size_minus3 + 3 +
 267                sps->log2_diff_max_min_luma_coding_block_size;
 268        ctb_size_luma = 1UL << log2_max_luma_coding_block_size;
 269        width_in_ctb_luma =
 270                DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
 271
 272        /* 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
 595static 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
 612static void cedrus_h265_stop(struct cedrus_ctx *ctx)
 613{
 614        struct cedrus_dev *dev = ctx->dev;
 615
 616        if (ctx->codec.h265.mv_col_buf_size > 0) {
 617                dma_free_coherent(dev->dev, ctx->codec.h265.mv_col_buf_size,
 618                                  ctx->codec.h265.mv_col_buf,
 619                                  ctx->codec.h265.mv_col_buf_addr);
 620
 621                ctx->codec.h265.mv_col_buf_size = 0;
 622        }
 623
 624        dma_free_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
 625                          ctx->codec.h265.neighbor_info_buf,
 626                          ctx->codec.h265.neighbor_info_buf_addr);
 627}
 628
 629static void cedrus_h265_trigger(struct cedrus_ctx *ctx)
 630{
 631        struct cedrus_dev *dev = ctx->dev;
 632
 633        cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_DEC_SLICE);
 634}
 635
 636struct cedrus_dec_ops cedrus_dec_ops_h265 = {
 637        .irq_clear      = cedrus_h265_irq_clear,
 638        .irq_disable    = cedrus_h265_irq_disable,
 639        .irq_status     = cedrus_h265_irq_status,
 640        .setup          = cedrus_h265_setup,
 641        .start          = cedrus_h265_start,
 642        .stop           = cedrus_h265_stop,
 643        .trigger        = cedrus_h265_trigger,
 644};
 645