601 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Rockchip VPU codec vp8 decode driver4 *5 * Copyright (C) 2014 Rockchip Electronics Co., Ltd.6 * ZhiChao Yu <zhichao.yu@rock-chips.com>7 *8 * Copyright (C) 2014 Google LLC.9 * Tomasz Figa <tfiga@chromium.org>10 *11 * Copyright (C) 2015 Rockchip Electronics Co., Ltd.12 * Alpha Lin <alpha.lin@rock-chips.com>13 */14 15#include <media/v4l2-mem2mem.h>16 17#include "hantro_hw.h"18#include "hantro.h"19#include "hantro_g1_regs.h"20 21#define VDPU_REG_DEC_CTRL0 0x0c822#define VDPU_REG_STREAM_LEN 0x0cc23#define VDPU_REG_DEC_FORMAT 0x0d424#define VDPU_REG_DEC_CTRL0_DEC_MODE(x) (((x) & 0xf) << 0)25#define VDPU_REG_DATA_ENDIAN 0x0d826#define VDPU_REG_CONFIG_DEC_STRENDIAN_E BIT(5)27#define VDPU_REG_CONFIG_DEC_STRSWAP32_E BIT(4)28#define VDPU_REG_CONFIG_DEC_OUTSWAP32_E BIT(3)29#define VDPU_REG_CONFIG_DEC_INSWAP32_E BIT(2)30#define VDPU_REG_CONFIG_DEC_OUT_ENDIAN BIT(1)31#define VDPU_REG_CONFIG_DEC_IN_ENDIAN BIT(0)32#define VDPU_REG_AXI_CTRL 0x0e033#define VDPU_REG_CONFIG_DEC_MAX_BURST(x) (((x) & 0x1f) << 16)34#define VDPU_REG_EN_FLAGS 0x0e435#define VDPU_REG_DEC_CTRL0_PIC_INTER_E BIT(14)36#define VDPU_REG_CONFIG_DEC_TIMEOUT_E BIT(5)37#define VDPU_REG_CONFIG_DEC_CLK_GATE_E BIT(4)38#define VDPU_REG_PRED_FLT 0x0ec39#define VDPU_REG_ADDR_QTABLE 0x0f440#define VDPU_REG_ADDR_DST 0x0fc41#define VDPU_REG_ADDR_STR 0x10042#define VDPU_REG_VP8_PIC_MB_SIZE 0x1e043#define VDPU_REG_VP8_DCT_START_BIT 0x1e444#define VDPU_REG_DEC_CTRL4_VC1_HEIGHT_EXT BIT(13)45#define VDPU_REG_DEC_CTRL4_BILIN_MC_E BIT(12)46#define VDPU_REG_VP8_CTRL0 0x1e847#define VDPU_REG_VP8_DATA_VAL 0x1f048#define VDPU_REG_PRED_FLT7 0x1f449#define VDPU_REG_PRED_FLT8 0x1f850#define VDPU_REG_PRED_FLT9 0x1fc51#define VDPU_REG_PRED_FLT10 0x20052#define VDPU_REG_FILTER_LEVEL 0x20453#define VDPU_REG_VP8_QUANTER0 0x20854#define VDPU_REG_VP8_ADDR_REF0 0x20c55#define VDPU_REG_FILTER_MB_ADJ 0x21056#define VDPU_REG_REF_PIC_FILT_TYPE_E BIT(31)57#define VDPU_REG_REF_PIC_FILT_SHARPNESS(x) (((x) & 0x7) << 28)58#define VDPU_REG_FILTER_REF_ADJ 0x21459#define VDPU_REG_VP8_ADDR_REF2_5(i) (0x218 + ((i) * 0x4))60#define VDPU_REG_VP8_GREF_SIGN_BIAS BIT(0)61#define VDPU_REG_VP8_AREF_SIGN_BIAS BIT(0)62#define VDPU_REG_VP8_DCT_BASE(i) \63 (0x230 + ((((i) < 5) ? (i) : ((i) + 1)) * 0x4))64#define VDPU_REG_VP8_ADDR_CTRL_PART 0x24465#define VDPU_REG_VP8_SEGMENT_VAL 0x25466#define VDPU_REG_FWD_PIC1_SEGMENT_BASE(x) ((x) << 0)67#define VDPU_REG_FWD_PIC1_SEGMENT_UPD_E BIT(1)68#define VDPU_REG_FWD_PIC1_SEGMENT_E BIT(0)69#define VDPU_REG_VP8_DCT_START_BIT2 0x25870#define VDPU_REG_VP8_QUANTER1 0x25c71#define VDPU_REG_VP8_QUANTER2 0x26072#define VDPU_REG_PRED_FLT1 0x26473#define VDPU_REG_PRED_FLT2 0x26874#define VDPU_REG_PRED_FLT3 0x26c75#define VDPU_REG_PRED_FLT4 0x27076#define VDPU_REG_PRED_FLT5 0x27477#define VDPU_REG_PRED_FLT6 0x27878 79static const struct hantro_reg vp8_dec_dct_base[8] = {80 { VDPU_REG_ADDR_STR, 0, 0xffffffff },81 { VDPU_REG_VP8_DCT_BASE(0), 0, 0xffffffff },82 { VDPU_REG_VP8_DCT_BASE(1), 0, 0xffffffff },83 { VDPU_REG_VP8_DCT_BASE(2), 0, 0xffffffff },84 { VDPU_REG_VP8_DCT_BASE(3), 0, 0xffffffff },85 { VDPU_REG_VP8_DCT_BASE(4), 0, 0xffffffff },86 { VDPU_REG_VP8_DCT_BASE(5), 0, 0xffffffff },87 { VDPU_REG_VP8_DCT_BASE(6), 0, 0xffffffff },88};89 90static const struct hantro_reg vp8_dec_lf_level[4] = {91 { VDPU_REG_FILTER_LEVEL, 18, 0x3f },92 { VDPU_REG_FILTER_LEVEL, 12, 0x3f },93 { VDPU_REG_FILTER_LEVEL, 6, 0x3f },94 { VDPU_REG_FILTER_LEVEL, 0, 0x3f },95};96 97static const struct hantro_reg vp8_dec_mb_adj[4] = {98 { VDPU_REG_FILTER_MB_ADJ, 21, 0x7f },99 { VDPU_REG_FILTER_MB_ADJ, 14, 0x7f },100 { VDPU_REG_FILTER_MB_ADJ, 7, 0x7f },101 { VDPU_REG_FILTER_MB_ADJ, 0, 0x7f },102};103 104static const struct hantro_reg vp8_dec_ref_adj[4] = {105 { VDPU_REG_FILTER_REF_ADJ, 21, 0x7f },106 { VDPU_REG_FILTER_REF_ADJ, 14, 0x7f },107 { VDPU_REG_FILTER_REF_ADJ, 7, 0x7f },108 { VDPU_REG_FILTER_REF_ADJ, 0, 0x7f },109};110 111static const struct hantro_reg vp8_dec_quant[4] = {112 { VDPU_REG_VP8_QUANTER0, 11, 0x7ff },113 { VDPU_REG_VP8_QUANTER0, 0, 0x7ff },114 { VDPU_REG_VP8_QUANTER1, 11, 0x7ff },115 { VDPU_REG_VP8_QUANTER1, 0, 0x7ff },116};117 118static const struct hantro_reg vp8_dec_quant_delta[5] = {119 { VDPU_REG_VP8_QUANTER0, 27, 0x1f },120 { VDPU_REG_VP8_QUANTER0, 22, 0x1f },121 { VDPU_REG_VP8_QUANTER1, 27, 0x1f },122 { VDPU_REG_VP8_QUANTER1, 22, 0x1f },123 { VDPU_REG_VP8_QUANTER2, 27, 0x1f },124};125 126static const struct hantro_reg vp8_dec_dct_start_bits[8] = {127 { VDPU_REG_VP8_CTRL0, 26, 0x3f },128 { VDPU_REG_VP8_DCT_START_BIT, 26, 0x3f },129 { VDPU_REG_VP8_DCT_START_BIT, 20, 0x3f },130 { VDPU_REG_VP8_DCT_START_BIT2, 24, 0x3f },131 { VDPU_REG_VP8_DCT_START_BIT2, 18, 0x3f },132 { VDPU_REG_VP8_DCT_START_BIT2, 12, 0x3f },133 { VDPU_REG_VP8_DCT_START_BIT2, 6, 0x3f },134 { VDPU_REG_VP8_DCT_START_BIT2, 0, 0x3f },135};136 137static const struct hantro_reg vp8_dec_pred_bc_tap[8][6] = {138 {139 { 0, 0, 0},140 { VDPU_REG_PRED_FLT, 22, 0x3ff },141 { VDPU_REG_PRED_FLT, 12, 0x3ff },142 { VDPU_REG_PRED_FLT, 2, 0x3ff },143 { VDPU_REG_PRED_FLT1, 22, 0x3ff },144 { 0, 0, 0},145 }, {146 { 0, 0, 0},147 { VDPU_REG_PRED_FLT1, 12, 0x3ff },148 { VDPU_REG_PRED_FLT1, 2, 0x3ff },149 { VDPU_REG_PRED_FLT2, 22, 0x3ff },150 { VDPU_REG_PRED_FLT2, 12, 0x3ff },151 { 0, 0, 0},152 }, {153 { VDPU_REG_PRED_FLT10, 10, 0x3 },154 { VDPU_REG_PRED_FLT2, 2, 0x3ff },155 { VDPU_REG_PRED_FLT3, 22, 0x3ff },156 { VDPU_REG_PRED_FLT3, 12, 0x3ff },157 { VDPU_REG_PRED_FLT3, 2, 0x3ff },158 { VDPU_REG_PRED_FLT10, 8, 0x3},159 }, {160 { 0, 0, 0},161 { VDPU_REG_PRED_FLT4, 22, 0x3ff },162 { VDPU_REG_PRED_FLT4, 12, 0x3ff },163 { VDPU_REG_PRED_FLT4, 2, 0x3ff },164 { VDPU_REG_PRED_FLT5, 22, 0x3ff },165 { 0, 0, 0},166 }, {167 { VDPU_REG_PRED_FLT10, 6, 0x3 },168 { VDPU_REG_PRED_FLT5, 12, 0x3ff },169 { VDPU_REG_PRED_FLT5, 2, 0x3ff },170 { VDPU_REG_PRED_FLT6, 22, 0x3ff },171 { VDPU_REG_PRED_FLT6, 12, 0x3ff },172 { VDPU_REG_PRED_FLT10, 4, 0x3 },173 }, {174 { 0, 0, 0},175 { VDPU_REG_PRED_FLT6, 2, 0x3ff },176 { VDPU_REG_PRED_FLT7, 22, 0x3ff },177 { VDPU_REG_PRED_FLT7, 12, 0x3ff },178 { VDPU_REG_PRED_FLT7, 2, 0x3ff },179 { 0, 0, 0},180 }, {181 { VDPU_REG_PRED_FLT10, 2, 0x3 },182 { VDPU_REG_PRED_FLT8, 22, 0x3ff },183 { VDPU_REG_PRED_FLT8, 12, 0x3ff },184 { VDPU_REG_PRED_FLT8, 2, 0x3ff },185 { VDPU_REG_PRED_FLT9, 22, 0x3ff },186 { VDPU_REG_PRED_FLT10, 0, 0x3 },187 }, {188 { 0, 0, 0},189 { VDPU_REG_PRED_FLT9, 12, 0x3ff },190 { VDPU_REG_PRED_FLT9, 2, 0x3ff },191 { VDPU_REG_PRED_FLT10, 22, 0x3ff },192 { VDPU_REG_PRED_FLT10, 12, 0x3ff },193 { 0, 0, 0},194 },195};196 197static const struct hantro_reg vp8_dec_mb_start_bit = {198 .base = VDPU_REG_VP8_CTRL0,199 .shift = 18,200 .mask = 0x3f201};202 203static const struct hantro_reg vp8_dec_mb_aligned_data_len = {204 .base = VDPU_REG_VP8_DATA_VAL,205 .shift = 0,206 .mask = 0x3fffff207};208 209static const struct hantro_reg vp8_dec_num_dct_partitions = {210 .base = VDPU_REG_VP8_DATA_VAL,211 .shift = 24,212 .mask = 0xf213};214 215static const struct hantro_reg vp8_dec_stream_len = {216 .base = VDPU_REG_STREAM_LEN,217 .shift = 0,218 .mask = 0xffffff219};220 221static const struct hantro_reg vp8_dec_mb_width = {222 .base = VDPU_REG_VP8_PIC_MB_SIZE,223 .shift = 23,224 .mask = 0x1ff225};226 227static const struct hantro_reg vp8_dec_mb_height = {228 .base = VDPU_REG_VP8_PIC_MB_SIZE,229 .shift = 11,230 .mask = 0xff231};232 233static const struct hantro_reg vp8_dec_mb_width_ext = {234 .base = VDPU_REG_VP8_PIC_MB_SIZE,235 .shift = 3,236 .mask = 0x7237};238 239static const struct hantro_reg vp8_dec_mb_height_ext = {240 .base = VDPU_REG_VP8_PIC_MB_SIZE,241 .shift = 0,242 .mask = 0x7243};244 245static const struct hantro_reg vp8_dec_bool_range = {246 .base = VDPU_REG_VP8_CTRL0,247 .shift = 0,248 .mask = 0xff249};250 251static const struct hantro_reg vp8_dec_bool_value = {252 .base = VDPU_REG_VP8_CTRL0,253 .shift = 8,254 .mask = 0xff255};256 257static const struct hantro_reg vp8_dec_filter_disable = {258 .base = VDPU_REG_DEC_CTRL0,259 .shift = 8,260 .mask = 1261};262 263static const struct hantro_reg vp8_dec_skip_mode = {264 .base = VDPU_REG_DEC_CTRL0,265 .shift = 9,266 .mask = 1267};268 269static const struct hantro_reg vp8_dec_start_dec = {270 .base = VDPU_REG_EN_FLAGS,271 .shift = 0,272 .mask = 1273};274 275static void cfg_lf(struct hantro_ctx *ctx,276 const struct v4l2_ctrl_vp8_frame *hdr)277{278 const struct v4l2_vp8_segment *seg = &hdr->segment;279 const struct v4l2_vp8_loop_filter *lf = &hdr->lf;280 struct hantro_dev *vpu = ctx->dev;281 unsigned int i;282 u32 reg;283 284 if (!(seg->flags & V4L2_VP8_SEGMENT_FLAG_ENABLED)) {285 hantro_reg_write(vpu, &vp8_dec_lf_level[0], lf->level);286 } else if (seg->flags & V4L2_VP8_SEGMENT_FLAG_DELTA_VALUE_MODE) {287 for (i = 0; i < 4; i++) {288 u32 lf_level = clamp(lf->level + seg->lf_update[i],289 0, 63);290 291 hantro_reg_write(vpu, &vp8_dec_lf_level[i], lf_level);292 }293 } else {294 for (i = 0; i < 4; i++)295 hantro_reg_write(vpu, &vp8_dec_lf_level[i],296 seg->lf_update[i]);297 }298 299 reg = VDPU_REG_REF_PIC_FILT_SHARPNESS(lf->sharpness_level);300 if (lf->flags & V4L2_VP8_LF_FILTER_TYPE_SIMPLE)301 reg |= VDPU_REG_REF_PIC_FILT_TYPE_E;302 vdpu_write_relaxed(vpu, reg, VDPU_REG_FILTER_MB_ADJ);303 304 if (lf->flags & V4L2_VP8_LF_ADJ_ENABLE) {305 for (i = 0; i < 4; i++) {306 hantro_reg_write(vpu, &vp8_dec_mb_adj[i],307 lf->mb_mode_delta[i]);308 hantro_reg_write(vpu, &vp8_dec_ref_adj[i],309 lf->ref_frm_delta[i]);310 }311 }312}313 314static void cfg_qp(struct hantro_ctx *ctx,315 const struct v4l2_ctrl_vp8_frame *hdr)316{317 const struct v4l2_vp8_quantization *q = &hdr->quant;318 const struct v4l2_vp8_segment *seg = &hdr->segment;319 struct hantro_dev *vpu = ctx->dev;320 unsigned int i;321 322 if (!(seg->flags & V4L2_VP8_SEGMENT_FLAG_ENABLED)) {323 hantro_reg_write(vpu, &vp8_dec_quant[0], q->y_ac_qi);324 } else if (seg->flags & V4L2_VP8_SEGMENT_FLAG_DELTA_VALUE_MODE) {325 for (i = 0; i < 4; i++) {326 u32 quant = clamp(q->y_ac_qi + seg->quant_update[i],327 0, 127);328 329 hantro_reg_write(vpu, &vp8_dec_quant[i], quant);330 }331 } else {332 for (i = 0; i < 4; i++)333 hantro_reg_write(vpu, &vp8_dec_quant[i],334 seg->quant_update[i]);335 }336 337 hantro_reg_write(vpu, &vp8_dec_quant_delta[0], q->y_dc_delta);338 hantro_reg_write(vpu, &vp8_dec_quant_delta[1], q->y2_dc_delta);339 hantro_reg_write(vpu, &vp8_dec_quant_delta[2], q->y2_ac_delta);340 hantro_reg_write(vpu, &vp8_dec_quant_delta[3], q->uv_dc_delta);341 hantro_reg_write(vpu, &vp8_dec_quant_delta[4], q->uv_ac_delta);342}343 344static void cfg_parts(struct hantro_ctx *ctx,345 const struct v4l2_ctrl_vp8_frame *hdr)346{347 struct hantro_dev *vpu = ctx->dev;348 struct vb2_v4l2_buffer *vb2_src;349 u32 first_part_offset = V4L2_VP8_FRAME_IS_KEY_FRAME(hdr) ? 10 : 3;350 u32 mb_size, mb_offset_bytes, mb_offset_bits, mb_start_bits;351 u32 dct_size_part_size, dct_part_offset;352 dma_addr_t src_dma;353 u32 dct_part_total_len = 0;354 u32 count = 0;355 unsigned int i;356 357 vb2_src = hantro_get_src_buf(ctx);358 src_dma = vb2_dma_contig_plane_dma_addr(&vb2_src->vb2_buf, 0);359 360 /*361 * Calculate control partition mb data info362 * @first_part_header_bits: bits offset of mb data from first363 * part start pos364 * @mb_offset_bits: bits offset of mb data from src_dma365 * base addr366 * @mb_offset_byte: bytes offset of mb data from src_dma367 * base addr368 * @mb_start_bits: bits offset of mb data from mb data369 * 64bits alignment addr370 */371 mb_offset_bits = first_part_offset * 8 +372 hdr->first_part_header_bits + 8;373 mb_offset_bytes = mb_offset_bits / 8;374 mb_start_bits = mb_offset_bits -375 (mb_offset_bytes & (~DEC_8190_ALIGN_MASK)) * 8;376 mb_size = hdr->first_part_size -377 (mb_offset_bytes - first_part_offset) +378 (mb_offset_bytes & DEC_8190_ALIGN_MASK);379 380 /* Macroblock data aligned base addr */381 vdpu_write_relaxed(vpu, (mb_offset_bytes & (~DEC_8190_ALIGN_MASK)) +382 src_dma, VDPU_REG_VP8_ADDR_CTRL_PART);383 hantro_reg_write(vpu, &vp8_dec_mb_start_bit, mb_start_bits);384 hantro_reg_write(vpu, &vp8_dec_mb_aligned_data_len, mb_size);385 386 /*387 * Calculate DCT partition info388 * @dct_size_part_size: Containing sizes of DCT part, every DCT part389 * has 3 bytes to store its size, except the last390 * DCT part391 * @dct_part_offset: bytes offset of DCT parts from src_dma base addr392 * @dct_part_total_len: total size of all DCT parts393 */394 dct_size_part_size = (hdr->num_dct_parts - 1) * 3;395 dct_part_offset = first_part_offset + hdr->first_part_size;396 for (i = 0; i < hdr->num_dct_parts; i++)397 dct_part_total_len += hdr->dct_part_sizes[i];398 dct_part_total_len += dct_size_part_size;399 dct_part_total_len += (dct_part_offset & DEC_8190_ALIGN_MASK);400 401 /* Number of DCT partitions */402 hantro_reg_write(vpu, &vp8_dec_num_dct_partitions,403 hdr->num_dct_parts - 1);404 405 /* DCT partition length */406 hantro_reg_write(vpu, &vp8_dec_stream_len, dct_part_total_len);407 408 /* DCT partitions base address */409 for (i = 0; i < hdr->num_dct_parts; i++) {410 u32 byte_offset = dct_part_offset + dct_size_part_size + count;411 u32 base_addr = byte_offset + src_dma;412 413 hantro_reg_write(vpu, &vp8_dec_dct_base[i],414 base_addr & (~DEC_8190_ALIGN_MASK));415 416 hantro_reg_write(vpu, &vp8_dec_dct_start_bits[i],417 (byte_offset & DEC_8190_ALIGN_MASK) * 8);418 419 count += hdr->dct_part_sizes[i];420 }421}422 423/*424 * prediction filter taps425 * normal 6-tap filters426 */427static void cfg_tap(struct hantro_ctx *ctx,428 const struct v4l2_ctrl_vp8_frame *hdr)429{430 struct hantro_dev *vpu = ctx->dev;431 int i, j;432 433 if ((hdr->version & 0x03) != 0)434 return; /* Tap filter not used. */435 436 for (i = 0; i < 8; i++) {437 for (j = 0; j < 6; j++) {438 if (vp8_dec_pred_bc_tap[i][j].base != 0)439 hantro_reg_write(vpu,440 &vp8_dec_pred_bc_tap[i][j],441 hantro_vp8_dec_mc_filter[i][j]);442 }443 }444}445 446static void cfg_ref(struct hantro_ctx *ctx,447 const struct v4l2_ctrl_vp8_frame *hdr,448 struct vb2_v4l2_buffer *vb2_dst)449{450 struct hantro_dev *vpu = ctx->dev;451 dma_addr_t ref;452 453 ref = hantro_get_ref(ctx, hdr->last_frame_ts);454 if (!ref) {455 vpu_debug(0, "failed to find last frame ts=%llu\n",456 hdr->last_frame_ts);457 ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);458 }459 vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF0);460 461 ref = hantro_get_ref(ctx, hdr->golden_frame_ts);462 if (!ref && hdr->golden_frame_ts)463 vpu_debug(0, "failed to find golden frame ts=%llu\n",464 hdr->golden_frame_ts);465 if (!ref)466 ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);467 if (hdr->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_GOLDEN)468 ref |= VDPU_REG_VP8_GREF_SIGN_BIAS;469 vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF2_5(2));470 471 ref = hantro_get_ref(ctx, hdr->alt_frame_ts);472 if (!ref && hdr->alt_frame_ts)473 vpu_debug(0, "failed to find alt frame ts=%llu\n",474 hdr->alt_frame_ts);475 if (!ref)476 ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);477 if (hdr->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_ALT)478 ref |= VDPU_REG_VP8_AREF_SIGN_BIAS;479 vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF2_5(3));480}481 482static void cfg_buffers(struct hantro_ctx *ctx,483 const struct v4l2_ctrl_vp8_frame *hdr,484 struct vb2_v4l2_buffer *vb2_dst)485{486 const struct v4l2_vp8_segment *seg = &hdr->segment;487 struct hantro_dev *vpu = ctx->dev;488 dma_addr_t dst_dma;489 u32 reg;490 491 /* Set probability table buffer address */492 vdpu_write_relaxed(vpu, ctx->vp8_dec.prob_tbl.dma,493 VDPU_REG_ADDR_QTABLE);494 495 /* Set segment map address */496 reg = VDPU_REG_FWD_PIC1_SEGMENT_BASE(ctx->vp8_dec.segment_map.dma);497 if (seg->flags & V4L2_VP8_SEGMENT_FLAG_ENABLED) {498 reg |= VDPU_REG_FWD_PIC1_SEGMENT_E;499 if (seg->flags & V4L2_VP8_SEGMENT_FLAG_UPDATE_MAP)500 reg |= VDPU_REG_FWD_PIC1_SEGMENT_UPD_E;501 }502 vdpu_write_relaxed(vpu, reg, VDPU_REG_VP8_SEGMENT_VAL);503 504 /* set output frame buffer address */505 dst_dma = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);506 vdpu_write_relaxed(vpu, dst_dma, VDPU_REG_ADDR_DST);507}508 509int rockchip_vpu2_vp8_dec_run(struct hantro_ctx *ctx)510{511 const struct v4l2_ctrl_vp8_frame *hdr;512 struct hantro_dev *vpu = ctx->dev;513 struct vb2_v4l2_buffer *vb2_dst;514 size_t height = ctx->dst_fmt.height;515 size_t width = ctx->dst_fmt.width;516 u32 mb_width, mb_height;517 u32 reg;518 519 hantro_start_prepare_run(ctx);520 521 hdr = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_VP8_FRAME);522 if (WARN_ON(!hdr))523 return -EINVAL;524 525 /* Reset segment_map buffer in keyframe */526 if (V4L2_VP8_FRAME_IS_KEY_FRAME(hdr) && ctx->vp8_dec.segment_map.cpu)527 memset(ctx->vp8_dec.segment_map.cpu, 0,528 ctx->vp8_dec.segment_map.size);529 530 hantro_vp8_prob_update(ctx, hdr);531 532 /*533 * Extensive testing shows that the hardware does not properly534 * clear the internal state from previous a decoding run. This535 * causes corruption in decoded frames for multi-instance use cases.536 * A soft reset before programming the registers has been found537 * to resolve those problems.538 */539 ctx->codec_ops->reset(ctx);540 541 reg = VDPU_REG_CONFIG_DEC_TIMEOUT_E542 | VDPU_REG_CONFIG_DEC_CLK_GATE_E;543 if (!V4L2_VP8_FRAME_IS_KEY_FRAME(hdr))544 reg |= VDPU_REG_DEC_CTRL0_PIC_INTER_E;545 vdpu_write_relaxed(vpu, reg, VDPU_REG_EN_FLAGS);546 547 reg = VDPU_REG_CONFIG_DEC_STRENDIAN_E548 | VDPU_REG_CONFIG_DEC_INSWAP32_E549 | VDPU_REG_CONFIG_DEC_STRSWAP32_E550 | VDPU_REG_CONFIG_DEC_OUTSWAP32_E551 | VDPU_REG_CONFIG_DEC_IN_ENDIAN552 | VDPU_REG_CONFIG_DEC_OUT_ENDIAN;553 vdpu_write_relaxed(vpu, reg, VDPU_REG_DATA_ENDIAN);554 555 reg = VDPU_REG_CONFIG_DEC_MAX_BURST(16);556 vdpu_write_relaxed(vpu, reg, VDPU_REG_AXI_CTRL);557 558 reg = VDPU_REG_DEC_CTRL0_DEC_MODE(10);559 vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_FORMAT);560 561 if (!(hdr->flags & V4L2_VP8_FRAME_FLAG_MB_NO_SKIP_COEFF))562 hantro_reg_write(vpu, &vp8_dec_skip_mode, 1);563 if (hdr->lf.level == 0)564 hantro_reg_write(vpu, &vp8_dec_filter_disable, 1);565 566 /* Frame dimensions */567 mb_width = MB_WIDTH(width);568 mb_height = MB_HEIGHT(height);569 570 hantro_reg_write(vpu, &vp8_dec_mb_width, mb_width);571 hantro_reg_write(vpu, &vp8_dec_mb_height, mb_height);572 hantro_reg_write(vpu, &vp8_dec_mb_width_ext, mb_width >> 9);573 hantro_reg_write(vpu, &vp8_dec_mb_height_ext, mb_height >> 8);574 575 /* Boolean decoder */576 hantro_reg_write(vpu, &vp8_dec_bool_range, hdr->coder_state.range);577 hantro_reg_write(vpu, &vp8_dec_bool_value, hdr->coder_state.value);578 579 reg = vdpu_read(vpu, VDPU_REG_VP8_DCT_START_BIT);580 if (hdr->version != 3)581 reg |= VDPU_REG_DEC_CTRL4_VC1_HEIGHT_EXT;582 if (hdr->version & 0x3)583 reg |= VDPU_REG_DEC_CTRL4_BILIN_MC_E;584 vdpu_write_relaxed(vpu, reg, VDPU_REG_VP8_DCT_START_BIT);585 586 cfg_lf(ctx, hdr);587 cfg_qp(ctx, hdr);588 cfg_parts(ctx, hdr);589 cfg_tap(ctx, hdr);590 591 vb2_dst = hantro_get_dst_buf(ctx);592 cfg_ref(ctx, hdr, vb2_dst);593 cfg_buffers(ctx, hdr, vb2_dst);594 595 hantro_end_prepare_run(ctx);596 597 hantro_reg_write(vpu, &vp8_dec_start_dec, 1);598 599 return 0;600}601