Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

media: rkvdec: Add H264 support for the VDPU383 variant

This variant is used on the RK3576 SoC.

The moving vectors size requirements are slightly different so support
for a colmv_size function per variant is added.

Also, the link registers are used to start the decoder and read IRQ status.

The fluster score is 128/135 for JVT-AVC_V1, with MPS_MW_A failing in
addition to the usual ones.
The other test suites are not supported yet.

Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>

authored by

Detlev Casanova and committed by
Hans Verkuil
fde24907 e5aa698e

+925 -5
+1
drivers/media/platform/rockchip/rkvdec/Makefile
··· 9 9 rkvdec-hevc-common.o \ 10 10 rkvdec-rcb.o \ 11 11 rkvdec-vdpu381-h264.o \ 12 + rkvdec-vdpu383-h264.o \ 12 13 rkvdec-vp9.o
+538
drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Rockchip Video Decoder VDPU383 H264 backend 4 + * 5 + * Copyright (C) 2024 Collabora, Ltd. 6 + * Detlev Casanova <detlev.casanova@collabora.com> 7 + */ 8 + 9 + #include <media/v4l2-h264.h> 10 + #include <media/v4l2-mem2mem.h> 11 + 12 + #include <linux/iopoll.h> 13 + 14 + #include "rkvdec-rcb.h" 15 + #include "rkvdec-cabac.h" 16 + #include "rkvdec-vdpu383-regs.h" 17 + #include "rkvdec-h264-common.h" 18 + 19 + struct rkvdec_sps { 20 + u16 seq_parameter_set_id: 4; 21 + u16 profile_idc: 8; 22 + u16 constraint_set3_flag: 1; 23 + u16 chroma_format_idc: 2; 24 + u16 bit_depth_luma: 3; 25 + u16 bit_depth_chroma: 3; 26 + u16 qpprime_y_zero_transform_bypass_flag: 1; 27 + u16 log2_max_frame_num_minus4: 4; 28 + u16 max_num_ref_frames: 5; 29 + u16 pic_order_cnt_type: 2; 30 + u16 log2_max_pic_order_cnt_lsb_minus4: 4; 31 + u16 delta_pic_order_always_zero_flag: 1; 32 + 33 + u16 pic_width_in_mbs: 16; 34 + u16 pic_height_in_mbs: 16; 35 + 36 + u16 frame_mbs_only_flag: 1; 37 + u16 mb_adaptive_frame_field_flag: 1; 38 + u16 direct_8x8_inference_flag: 1; 39 + u16 mvc_extension_enable: 1; 40 + u16 num_views: 2; 41 + u16 view_id0: 10; 42 + u16 view_id1: 10; 43 + } __packed; 44 + 45 + struct rkvdec_pps { 46 + u32 pic_parameter_set_id: 8; 47 + u32 pps_seq_parameter_set_id: 5; 48 + u32 entropy_coding_mode_flag: 1; 49 + u32 bottom_field_pic_order_in_frame_present_flag: 1; 50 + u32 num_ref_idx_l0_default_active_minus1: 5; 51 + u32 num_ref_idx_l1_default_active_minus1: 5; 52 + u32 weighted_pred_flag: 1; 53 + u32 weighted_bipred_idc: 2; 54 + u32 pic_init_qp_minus26: 7; 55 + u32 pic_init_qs_minus26: 6; 56 + u32 chroma_qp_index_offset: 5; 57 + u32 deblocking_filter_control_present_flag: 1; 58 + u32 constrained_intra_pred_flag: 1; 59 + u32 redundant_pic_cnt_present: 1; 60 + u32 transform_8x8_mode_flag: 1; 61 + u32 second_chroma_qp_index_offset: 5; 62 + u32 scaling_list_enable_flag: 1; 63 + u32 is_longterm: 16; 64 + u32 voidx: 16; 65 + 66 + // dpb 67 + u32 pic_field_flag: 1; 68 + u32 pic_associated_flag: 1; 69 + u32 cur_top_field: 32; 70 + u32 cur_bot_field: 32; 71 + 72 + u32 top_field_order_cnt0: 32; 73 + u32 bot_field_order_cnt0: 32; 74 + u32 top_field_order_cnt1: 32; 75 + u32 bot_field_order_cnt1: 32; 76 + u32 top_field_order_cnt2: 32; 77 + u32 bot_field_order_cnt2: 32; 78 + u32 top_field_order_cnt3: 32; 79 + u32 bot_field_order_cnt3: 32; 80 + u32 top_field_order_cnt4: 32; 81 + u32 bot_field_order_cnt4: 32; 82 + u32 top_field_order_cnt5: 32; 83 + u32 bot_field_order_cnt5: 32; 84 + u32 top_field_order_cnt6: 32; 85 + u32 bot_field_order_cnt6: 32; 86 + u32 top_field_order_cnt7: 32; 87 + u32 bot_field_order_cnt7: 32; 88 + u32 top_field_order_cnt8: 32; 89 + u32 bot_field_order_cnt8: 32; 90 + u32 top_field_order_cnt9: 32; 91 + u32 bot_field_order_cnt9: 32; 92 + u32 top_field_order_cnt10: 32; 93 + u32 bot_field_order_cnt10: 32; 94 + u32 top_field_order_cnt11: 32; 95 + u32 bot_field_order_cnt11: 32; 96 + u32 top_field_order_cnt12: 32; 97 + u32 bot_field_order_cnt12: 32; 98 + u32 top_field_order_cnt13: 32; 99 + u32 bot_field_order_cnt13: 32; 100 + u32 top_field_order_cnt14: 32; 101 + u32 bot_field_order_cnt14: 32; 102 + u32 top_field_order_cnt15: 32; 103 + u32 bot_field_order_cnt15: 32; 104 + 105 + u32 ref_field_flags: 16; 106 + u32 ref_topfield_used: 16; 107 + u32 ref_botfield_used: 16; 108 + u32 ref_colmv_use_flag: 16; 109 + 110 + u32 reserved0: 30; 111 + u32 reserved[3]; 112 + } __packed; 113 + 114 + struct rkvdec_sps_pps { 115 + struct rkvdec_sps sps; 116 + struct rkvdec_pps pps; 117 + } __packed; 118 + 119 + /* Data structure describing auxiliary buffer format. */ 120 + struct rkvdec_h264_priv_tbl { 121 + s8 cabac_table[4][464][2]; 122 + struct rkvdec_h264_scaling_list scaling_list; 123 + struct rkvdec_sps_pps param_set[256]; 124 + struct rkvdec_rps rps; 125 + } __packed; 126 + 127 + struct rkvdec_h264_ctx { 128 + struct rkvdec_aux_buf priv_tbl; 129 + struct rkvdec_h264_reflists reflists; 130 + struct vdpu383_regs_h26x regs; 131 + }; 132 + 133 + static void set_field_order_cnt(struct rkvdec_pps *pps, const struct v4l2_h264_dpb_entry *dpb) 134 + { 135 + pps->top_field_order_cnt0 = dpb[0].top_field_order_cnt; 136 + pps->bot_field_order_cnt0 = dpb[0].bottom_field_order_cnt; 137 + pps->top_field_order_cnt1 = dpb[1].top_field_order_cnt; 138 + pps->bot_field_order_cnt1 = dpb[1].bottom_field_order_cnt; 139 + pps->top_field_order_cnt2 = dpb[2].top_field_order_cnt; 140 + pps->bot_field_order_cnt2 = dpb[2].bottom_field_order_cnt; 141 + pps->top_field_order_cnt3 = dpb[3].top_field_order_cnt; 142 + pps->bot_field_order_cnt3 = dpb[3].bottom_field_order_cnt; 143 + pps->top_field_order_cnt4 = dpb[4].top_field_order_cnt; 144 + pps->bot_field_order_cnt4 = dpb[4].bottom_field_order_cnt; 145 + pps->top_field_order_cnt5 = dpb[5].top_field_order_cnt; 146 + pps->bot_field_order_cnt5 = dpb[5].bottom_field_order_cnt; 147 + pps->top_field_order_cnt6 = dpb[6].top_field_order_cnt; 148 + pps->bot_field_order_cnt6 = dpb[6].bottom_field_order_cnt; 149 + pps->top_field_order_cnt7 = dpb[7].top_field_order_cnt; 150 + pps->bot_field_order_cnt7 = dpb[7].bottom_field_order_cnt; 151 + pps->top_field_order_cnt8 = dpb[8].top_field_order_cnt; 152 + pps->bot_field_order_cnt8 = dpb[8].bottom_field_order_cnt; 153 + pps->top_field_order_cnt9 = dpb[9].top_field_order_cnt; 154 + pps->bot_field_order_cnt9 = dpb[9].bottom_field_order_cnt; 155 + pps->top_field_order_cnt10 = dpb[10].top_field_order_cnt; 156 + pps->bot_field_order_cnt10 = dpb[10].bottom_field_order_cnt; 157 + pps->top_field_order_cnt11 = dpb[11].top_field_order_cnt; 158 + pps->bot_field_order_cnt11 = dpb[11].bottom_field_order_cnt; 159 + pps->top_field_order_cnt12 = dpb[12].top_field_order_cnt; 160 + pps->bot_field_order_cnt12 = dpb[12].bottom_field_order_cnt; 161 + pps->top_field_order_cnt13 = dpb[13].top_field_order_cnt; 162 + pps->bot_field_order_cnt13 = dpb[13].bottom_field_order_cnt; 163 + pps->top_field_order_cnt14 = dpb[14].top_field_order_cnt; 164 + pps->bot_field_order_cnt14 = dpb[14].bottom_field_order_cnt; 165 + pps->top_field_order_cnt15 = dpb[15].top_field_order_cnt; 166 + pps->bot_field_order_cnt15 = dpb[15].bottom_field_order_cnt; 167 + } 168 + 169 + static void assemble_hw_pps(struct rkvdec_ctx *ctx, 170 + struct rkvdec_h264_run *run) 171 + { 172 + struct rkvdec_h264_ctx *h264_ctx = ctx->priv; 173 + const struct v4l2_ctrl_h264_sps *sps = run->sps; 174 + const struct v4l2_ctrl_h264_pps *pps = run->pps; 175 + const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; 176 + const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; 177 + struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu; 178 + struct rkvdec_sps_pps *hw_ps; 179 + u32 pic_width, pic_height; 180 + u32 i; 181 + 182 + /* 183 + * HW read the SPS/PPS information from PPS packet index by PPS id. 184 + * offset from the base can be calculated by PPS_id * 32 (size per PPS 185 + * packet unit). so the driver copy SPS/PPS information to the exact PPS 186 + * packet unit for HW accessing. 187 + */ 188 + hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id]; 189 + memset(hw_ps, 0, sizeof(*hw_ps)); 190 + 191 + /* write sps */ 192 + hw_ps->sps.seq_parameter_set_id = sps->seq_parameter_set_id; 193 + hw_ps->sps.profile_idc = sps->profile_idc; 194 + hw_ps->sps.constraint_set3_flag = !!(sps->constraint_set_flags & (1 << 3)); 195 + hw_ps->sps.chroma_format_idc = sps->chroma_format_idc; 196 + hw_ps->sps.bit_depth_luma = sps->bit_depth_luma_minus8; 197 + hw_ps->sps.bit_depth_chroma = sps->bit_depth_chroma_minus8; 198 + hw_ps->sps.qpprime_y_zero_transform_bypass_flag = 199 + !!(sps->flags & V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS); 200 + hw_ps->sps.log2_max_frame_num_minus4 = sps->log2_max_frame_num_minus4; 201 + hw_ps->sps.max_num_ref_frames = sps->max_num_ref_frames; 202 + hw_ps->sps.pic_order_cnt_type = sps->pic_order_cnt_type; 203 + hw_ps->sps.log2_max_pic_order_cnt_lsb_minus4 = 204 + sps->log2_max_pic_order_cnt_lsb_minus4; 205 + hw_ps->sps.delta_pic_order_always_zero_flag = 206 + !!(sps->flags & V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO); 207 + hw_ps->sps.mvc_extension_enable = 0; 208 + hw_ps->sps.num_views = 0; 209 + 210 + /* 211 + * Use the SPS values since they are already in macroblocks 212 + * dimensions, height can be field height (halved) if 213 + * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY is not set and also it allows 214 + * decoding smaller images into larger allocation which can be used 215 + * to implementing SVC spatial layer support. 216 + */ 217 + pic_width = 16 * (sps->pic_width_in_mbs_minus1 + 1); 218 + pic_height = 16 * (sps->pic_height_in_map_units_minus1 + 1); 219 + if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)) 220 + pic_height *= 2; 221 + if (!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)) 222 + pic_height /= 2; 223 + 224 + hw_ps->sps.pic_width_in_mbs = pic_width; 225 + hw_ps->sps.pic_height_in_mbs = pic_height; 226 + 227 + hw_ps->sps.frame_mbs_only_flag = 228 + !!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY); 229 + hw_ps->sps.mb_adaptive_frame_field_flag = 230 + !!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD); 231 + hw_ps->sps.direct_8x8_inference_flag = 232 + !!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE); 233 + 234 + /* write pps */ 235 + hw_ps->pps.pic_parameter_set_id = pps->pic_parameter_set_id; 236 + hw_ps->pps.pps_seq_parameter_set_id = pps->seq_parameter_set_id; 237 + hw_ps->pps.entropy_coding_mode_flag = 238 + !!(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE); 239 + hw_ps->pps.bottom_field_pic_order_in_frame_present_flag = 240 + !!(pps->flags & V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT); 241 + hw_ps->pps.num_ref_idx_l0_default_active_minus1 = 242 + pps->num_ref_idx_l0_default_active_minus1; 243 + hw_ps->pps.num_ref_idx_l1_default_active_minus1 = 244 + pps->num_ref_idx_l1_default_active_minus1; 245 + hw_ps->pps.weighted_pred_flag = 246 + !!(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED); 247 + hw_ps->pps.weighted_bipred_idc = pps->weighted_bipred_idc; 248 + hw_ps->pps.pic_init_qp_minus26 = pps->pic_init_qp_minus26; 249 + hw_ps->pps.pic_init_qs_minus26 = pps->pic_init_qs_minus26; 250 + hw_ps->pps.chroma_qp_index_offset = pps->chroma_qp_index_offset; 251 + hw_ps->pps.deblocking_filter_control_present_flag = 252 + !!(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT); 253 + hw_ps->pps.constrained_intra_pred_flag = 254 + !!(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED); 255 + hw_ps->pps.redundant_pic_cnt_present = 256 + !!(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT); 257 + hw_ps->pps.transform_8x8_mode_flag = 258 + !!(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE); 259 + hw_ps->pps.second_chroma_qp_index_offset = pps->second_chroma_qp_index_offset; 260 + hw_ps->pps.scaling_list_enable_flag = 261 + !!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT); 262 + 263 + set_field_order_cnt(&hw_ps->pps, dpb); 264 + 265 + for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { 266 + if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) 267 + hw_ps->pps.is_longterm |= (1 << i); 268 + 269 + hw_ps->pps.ref_field_flags |= 270 + (!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) << i; 271 + hw_ps->pps.ref_colmv_use_flag |= 272 + (!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) << i; 273 + hw_ps->pps.ref_topfield_used |= 274 + (!!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF)) << i; 275 + hw_ps->pps.ref_botfield_used |= 276 + (!!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)) << i; 277 + } 278 + 279 + hw_ps->pps.pic_field_flag = 280 + !!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC); 281 + hw_ps->pps.pic_associated_flag = 282 + !!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD); 283 + 284 + hw_ps->pps.cur_top_field = dec_params->top_field_order_cnt; 285 + hw_ps->pps.cur_bot_field = dec_params->bottom_field_order_cnt; 286 + } 287 + 288 + static void rkvdec_write_regs(struct rkvdec_ctx *ctx) 289 + { 290 + struct rkvdec_dev *rkvdec = ctx->dev; 291 + struct rkvdec_h264_ctx *h264_ctx = ctx->priv; 292 + 293 + rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_COMMON_REGS, 294 + &h264_ctx->regs.common, 295 + sizeof(h264_ctx->regs.common)); 296 + rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_COMMON_ADDR_REGS, 297 + &h264_ctx->regs.common_addr, 298 + sizeof(h264_ctx->regs.common_addr)); 299 + rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_CODEC_PARAMS_REGS, 300 + &h264_ctx->regs.h26x_params, 301 + sizeof(h264_ctx->regs.h26x_params)); 302 + rkvdec_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_CODEC_ADDR_REGS, 303 + &h264_ctx->regs.h26x_addr, 304 + sizeof(h264_ctx->regs.h26x_addr)); 305 + } 306 + 307 + static void config_registers(struct rkvdec_ctx *ctx, 308 + struct rkvdec_h264_run *run) 309 + { 310 + const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; 311 + struct rkvdec_h264_ctx *h264_ctx = ctx->priv; 312 + dma_addr_t priv_start_addr = h264_ctx->priv_tbl.dma; 313 + const struct v4l2_pix_format_mplane *dst_fmt; 314 + struct vb2_v4l2_buffer *src_buf = run->base.bufs.src; 315 + struct vb2_v4l2_buffer *dst_buf = run->base.bufs.dst; 316 + struct vdpu383_regs_h26x *regs = &h264_ctx->regs; 317 + const struct v4l2_format *f; 318 + dma_addr_t rlc_addr; 319 + dma_addr_t dst_addr; 320 + u32 hor_virstride; 321 + u32 ver_virstride; 322 + u32 y_virstride; 323 + u32 offset; 324 + u32 pixels; 325 + u32 i; 326 + 327 + memset(regs, 0, sizeof(*regs)); 328 + 329 + /* Set H264 mode */ 330 + regs->common.reg008_dec_mode = VDPU383_MODE_H264; 331 + 332 + /* Set input stream length */ 333 + regs->h26x_params.reg066_stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0); 334 + 335 + /* Set strides */ 336 + f = &ctx->decoded_fmt; 337 + dst_fmt = &f->fmt.pix_mp; 338 + hor_virstride = dst_fmt->plane_fmt[0].bytesperline; 339 + ver_virstride = dst_fmt->height; 340 + y_virstride = hor_virstride * ver_virstride; 341 + 342 + pixels = dst_fmt->height * dst_fmt->width; 343 + 344 + regs->h26x_params.reg068_hor_virstride = hor_virstride / 16; 345 + regs->h26x_params.reg069_raster_uv_hor_virstride = hor_virstride / 16; 346 + regs->h26x_params.reg070_y_virstride = y_virstride / 16; 347 + 348 + /* Activate block gating */ 349 + regs->common.reg010_block_gating_en.strmd_auto_gating_e = 1; 350 + regs->common.reg010_block_gating_en.inter_auto_gating_e = 1; 351 + regs->common.reg010_block_gating_en.intra_auto_gating_e = 1; 352 + regs->common.reg010_block_gating_en.transd_auto_gating_e = 1; 353 + regs->common.reg010_block_gating_en.recon_auto_gating_e = 1; 354 + regs->common.reg010_block_gating_en.filterd_auto_gating_e = 1; 355 + regs->common.reg010_block_gating_en.bus_auto_gating_e = 1; 356 + regs->common.reg010_block_gating_en.ctrl_auto_gating_e = 1; 357 + regs->common.reg010_block_gating_en.rcb_auto_gating_e = 1; 358 + regs->common.reg010_block_gating_en.err_prc_auto_gating_e = 1; 359 + 360 + /* Set timeout threshold */ 361 + if (pixels < RKVDEC_1080P_PIXELS) 362 + regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_1080p; 363 + else if (pixels < RKVDEC_4K_PIXELS) 364 + regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_4K; 365 + else if (pixels < RKVDEC_8K_PIXELS) 366 + regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_8K; 367 + else 368 + regs->common.reg013_core_timeout_threshold = VDPU383_TIMEOUT_MAX; 369 + 370 + regs->common.reg016_error_ctrl_set.error_proc_disable = 1; 371 + 372 + /* Set ref pic address & poc */ 373 + for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { 374 + struct vb2_buffer *vb_buf = run->ref_buf[i]; 375 + dma_addr_t buf_dma; 376 + 377 + /* 378 + * If a DPB entry is unused or invalid, address of current destination 379 + * buffer is returned. 380 + */ 381 + if (!vb_buf) 382 + vb_buf = &dst_buf->vb2_buf; 383 + 384 + buf_dma = vb2_dma_contig_plane_dma_addr(vb_buf, 0); 385 + 386 + /* Set reference addresses */ 387 + regs->h26x_addr.reg170_185_ref_base[i] = buf_dma; 388 + regs->h26x_addr.reg195_210_payload_st_ref_base[i] = buf_dma; 389 + 390 + /* Set COLMV addresses */ 391 + regs->h26x_addr.reg217_232_colmv_ref_base[i] = buf_dma + ctx->colmv_offset; 392 + } 393 + 394 + /* Set rlc base address (input stream) */ 395 + rlc_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); 396 + regs->common_addr.reg128_strm_base = rlc_addr; 397 + 398 + /* Set output base address */ 399 + dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); 400 + regs->h26x_addr.reg168_decout_base = dst_addr; 401 + regs->h26x_addr.reg169_error_ref_base = dst_addr; 402 + regs->h26x_addr.reg192_payload_st_cur_base = dst_addr; 403 + 404 + /* Set colmv address */ 405 + regs->h26x_addr.reg216_colmv_cur_base = dst_addr + ctx->colmv_offset; 406 + 407 + /* Set RCB addresses */ 408 + for (i = 0; i < rkvdec_rcb_buf_count(ctx); i++) { 409 + regs->common_addr.reg140_162_rcb_info[i].offset = rkvdec_rcb_buf_dma_addr(ctx, i); 410 + regs->common_addr.reg140_162_rcb_info[i].size = rkvdec_rcb_buf_size(ctx, i); 411 + } 412 + 413 + /* Set hw pps address */ 414 + offset = offsetof(struct rkvdec_h264_priv_tbl, param_set); 415 + regs->common_addr.reg131_gbl_base = priv_start_addr + offset; 416 + regs->h26x_params.reg067_global_len = sizeof(struct rkvdec_sps_pps) / 16; 417 + 418 + /* Set hw rps address */ 419 + offset = offsetof(struct rkvdec_h264_priv_tbl, rps); 420 + regs->common_addr.reg129_rps_base = priv_start_addr + offset; 421 + 422 + /* Set cabac table */ 423 + offset = offsetof(struct rkvdec_h264_priv_tbl, cabac_table); 424 + regs->common_addr.reg130_cabactbl_base = priv_start_addr + offset; 425 + 426 + /* Set scaling list address */ 427 + offset = offsetof(struct rkvdec_h264_priv_tbl, scaling_list); 428 + regs->common_addr.reg132_scanlist_addr = priv_start_addr + offset; 429 + 430 + rkvdec_write_regs(ctx); 431 + } 432 + 433 + static int rkvdec_h264_start(struct rkvdec_ctx *ctx) 434 + { 435 + struct rkvdec_dev *rkvdec = ctx->dev; 436 + struct rkvdec_h264_priv_tbl *priv_tbl; 437 + struct rkvdec_h264_ctx *h264_ctx; 438 + struct v4l2_ctrl *ctrl; 439 + int ret; 440 + 441 + ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, 442 + V4L2_CID_STATELESS_H264_SPS); 443 + if (!ctrl) 444 + return -EINVAL; 445 + 446 + ret = rkvdec_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps); 447 + if (ret) 448 + return ret; 449 + 450 + h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL); 451 + if (!h264_ctx) 452 + return -ENOMEM; 453 + 454 + priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl), 455 + &h264_ctx->priv_tbl.dma, GFP_KERNEL); 456 + if (!priv_tbl) { 457 + ret = -ENOMEM; 458 + goto err_free_ctx; 459 + } 460 + 461 + h264_ctx->priv_tbl.size = sizeof(*priv_tbl); 462 + h264_ctx->priv_tbl.cpu = priv_tbl; 463 + memcpy(priv_tbl->cabac_table, rkvdec_h264_cabac_table, 464 + sizeof(rkvdec_h264_cabac_table)); 465 + 466 + ctx->priv = h264_ctx; 467 + 468 + return 0; 469 + 470 + err_free_ctx: 471 + kfree(h264_ctx); 472 + return ret; 473 + } 474 + 475 + static void rkvdec_h264_stop(struct rkvdec_ctx *ctx) 476 + { 477 + struct rkvdec_h264_ctx *h264_ctx = ctx->priv; 478 + struct rkvdec_dev *rkvdec = ctx->dev; 479 + 480 + dma_free_coherent(rkvdec->dev, h264_ctx->priv_tbl.size, 481 + h264_ctx->priv_tbl.cpu, h264_ctx->priv_tbl.dma); 482 + kfree(h264_ctx); 483 + } 484 + 485 + static int rkvdec_h264_run(struct rkvdec_ctx *ctx) 486 + { 487 + struct v4l2_h264_reflist_builder reflist_builder; 488 + struct rkvdec_dev *rkvdec = ctx->dev; 489 + struct rkvdec_h264_ctx *h264_ctx = ctx->priv; 490 + struct rkvdec_h264_run run; 491 + struct rkvdec_h264_priv_tbl *tbl = h264_ctx->priv_tbl.cpu; 492 + u32 timeout_threshold; 493 + 494 + rkvdec_h264_run_preamble(ctx, &run); 495 + 496 + /* Build the P/B{0,1} ref lists. */ 497 + v4l2_h264_init_reflist_builder(&reflist_builder, run.decode_params, 498 + run.sps, run.decode_params->dpb); 499 + v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p); 500 + v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0, 501 + h264_ctx->reflists.b1); 502 + 503 + assemble_hw_scaling_list(&run, &tbl->scaling_list); 504 + assemble_hw_pps(ctx, &run); 505 + lookup_ref_buf_idx(ctx, &run); 506 + assemble_hw_rps(&reflist_builder, &run, &h264_ctx->reflists, &tbl->rps); 507 + 508 + config_registers(ctx, &run); 509 + 510 + rkvdec_run_postamble(ctx, &run.base); 511 + 512 + timeout_threshold = h264_ctx->regs.common.reg013_core_timeout_threshold; 513 + rkvdec_schedule_watchdog(rkvdec, timeout_threshold); 514 + 515 + /* Start decoding! */ 516 + writel(timeout_threshold, rkvdec->link + VDPU383_LINK_TIMEOUT_THRESHOLD); 517 + writel(0, rkvdec->link + VDPU383_LINK_IP_ENABLE); 518 + writel(VDPU383_DEC_E_BIT, rkvdec->link + VDPU383_LINK_DEC_ENABLE); 519 + 520 + return 0; 521 + } 522 + 523 + static int rkvdec_h264_try_ctrl(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl) 524 + { 525 + if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) 526 + return rkvdec_h264_validate_sps(ctx, ctrl->p_new.p_h264_sps); 527 + 528 + return 0; 529 + } 530 + 531 + const struct rkvdec_coded_fmt_ops rkvdec_vdpu383_h264_fmt_ops = { 532 + .adjust_fmt = rkvdec_h264_adjust_fmt, 533 + .get_image_fmt = rkvdec_h264_get_image_fmt, 534 + .start = rkvdec_h264_start, 535 + .stop = rkvdec_h264_stop, 536 + .run = rkvdec_h264_run, 537 + .try_ctrl = rkvdec_h264_try_ctrl, 538 + };
+281
drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-regs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Rockchip Video Decoder VDPU383 driver registers description 4 + * 5 + * Copyright (C) 2025 Collabora, Ltd. 6 + * Detlev Casanova <detlev.casanova@collabora.com> 7 + */ 8 + 9 + #ifndef _RKVDEC_VDPU838_REGS_H_ 10 + #define _RKVDEC_VDPU838_REGS_H_ 11 + 12 + #include <linux/types.h> 13 + 14 + #define VDPU383_OFFSET_COMMON_REGS (8 * sizeof(u32)) 15 + #define VDPU383_OFFSET_CODEC_PARAMS_REGS (64 * sizeof(u32)) 16 + #define VDPU383_OFFSET_COMMON_ADDR_REGS (128 * sizeof(u32)) 17 + #define VDPU383_OFFSET_CODEC_ADDR_REGS (168 * sizeof(u32)) 18 + #define VDPU383_OFFSET_POC_HIGHBIT_REGS (200 * sizeof(u32)) 19 + 20 + #define VDPU383_MODE_HEVC 0 21 + #define VDPU383_MODE_H264 1 22 + 23 + #define VDPU383_TIMEOUT_1080p (0xffffff) 24 + #define VDPU383_TIMEOUT_4K (0x2cfffff) 25 + #define VDPU383_TIMEOUT_8K (0x4ffffff) 26 + #define VDPU383_TIMEOUT_MAX (0xffffffff) 27 + 28 + #define VDPU383_LINK_TIMEOUT_THRESHOLD 0x54 29 + 30 + #define VDPU383_LINK_IP_ENABLE 0x58 31 + #define VDPU383_IP_CRU_MODE BIT(24) 32 + 33 + #define VDPU383_LINK_DEC_ENABLE 0x40 34 + #define VDPU383_DEC_E_BIT BIT(0) 35 + 36 + #define VDPU383_LINK_INT_EN 0x048 37 + #define VDPU383_INT_EN_IRQ BIT(0) 38 + #define VDPU383_INT_EN_LINE_IRQ BIT(1) 39 + 40 + #define VDPU383_LINK_STA_INT 0x04c 41 + #define VDPU383_STA_INT_DEC_RDY_STA BIT(0) 42 + #define VDPU383_STA_INT_SOFTRESET_RDY (BIT(10) | BIT(11)) 43 + #define VDPU383_STA_INT_ALL 0x3ff 44 + 45 + struct vdpu383_regs_common { 46 + u32 reg008_dec_mode; 47 + 48 + struct { 49 + u32 fbc_e : 1; 50 + u32 tile_e : 1; 51 + u32 reserve0 : 2; 52 + u32 buf_empty_en : 1; 53 + u32 scale_down_en : 1; 54 + u32 reserve1 : 1; 55 + u32 pix_range_det_e : 1; 56 + u32 av1_fgs_en : 1; 57 + u32 reserve2 : 7; 58 + u32 line_irq_en : 1; 59 + u32 out_cbcr_swap : 1; 60 + u32 fbc_force_uncompress : 1; 61 + u32 fbc_sparse_mode : 1; 62 + u32 reserve3 : 12; 63 + } reg009_important_en; 64 + 65 + struct { 66 + u32 strmd_auto_gating_e : 1; 67 + u32 inter_auto_gating_e : 1; 68 + u32 intra_auto_gating_e : 1; 69 + u32 transd_auto_gating_e : 1; 70 + u32 recon_auto_gating_e : 1; 71 + u32 filterd_auto_gating_e : 1; 72 + u32 bus_auto_gating_e : 1; 73 + u32 ctrl_auto_gating_e : 1; 74 + u32 rcb_auto_gating_e : 1; 75 + u32 err_prc_auto_gating_e : 1; 76 + u32 reserve0 : 22; 77 + } reg010_block_gating_en; 78 + 79 + struct { 80 + u32 reserve0 : 9; 81 + u32 dec_timeout_dis : 1; 82 + u32 reserve1 : 22; 83 + } reg011_cfg_para; 84 + 85 + struct { 86 + u32 reserve0 : 7; 87 + u32 cache_hash_mask : 25; 88 + } reg012_cache_hash_mask; 89 + 90 + u32 reg013_core_timeout_threshold; 91 + 92 + struct { 93 + u32 dec_line_irq_step : 16; 94 + u32 dec_line_offset_y_st : 16; 95 + } reg014_line_irq_ctrl; 96 + 97 + struct { 98 + u32 rkvdec_frame_rdy_sta : 1; 99 + u32 rkvdec_strm_error_sta : 1; 100 + u32 rkvdec_core_timeout_sta : 1; 101 + u32 rkvdec_ip_timeout_sta : 1; 102 + u32 rkvdec_bus_error_sta : 1; 103 + u32 rkvdec_buffer_empty_sta : 1; 104 + u32 rkvdec_colmv_ref_error_sta : 1; 105 + u32 rkvdec_error_spread_sta : 1; 106 + u32 create_core_timeout_sta : 1; 107 + u32 wlast_miss_match_sta : 1; 108 + u32 rkvdec_core_rst_rdy_sta : 1; 109 + u32 rkvdec_ip_rst_rdy_sta : 1; 110 + u32 force_busidle_rdy_sta : 1; 111 + u32 ltb_pause_rdy_sta : 1; 112 + u32 ltb_end_flag : 1; 113 + u32 unsupport_decmode_error_sta : 1; 114 + u32 wmask_bits : 15; 115 + u32 reserve0 : 1; 116 + } reg015_irq_sta; 117 + 118 + struct { 119 + u32 error_proc_disable : 1; 120 + u32 reserve0 : 7; 121 + u32 error_spread_disable : 1; 122 + u32 reserve1 : 15; 123 + u32 roi_error_ctu_cal_en : 1; 124 + u32 reserve2 : 7; 125 + } reg016_error_ctrl_set; 126 + 127 + struct { 128 + u32 roi_x_ctu_offset_st : 12; 129 + u32 reserve0 : 4; 130 + u32 roi_y_ctu_offset_st : 12; 131 + u32 reserve1 : 4; 132 + } reg017_err_roi_ctu_offset_start; 133 + 134 + struct { 135 + u32 roi_x_ctu_offset_end : 12; 136 + u32 reserve0 : 4; 137 + u32 roi_y_ctu_offset_end : 12; 138 + u32 reserve1 : 4; 139 + } reg018_err_roi_ctu_offset_end; 140 + 141 + struct { 142 + u32 avs2_ref_error_field : 1; 143 + u32 avs2_ref_error_topfield : 1; 144 + u32 ref_error_topfield_used : 1; 145 + u32 ref_error_botfield_used : 1; 146 + u32 reserve0 : 28; 147 + } reg019_error_ref_info; 148 + 149 + u32 reg020_cabac_error_en_lowbits; 150 + u32 reg021_cabac_error_en_highbits; 151 + 152 + u32 reg022_reserved; 153 + 154 + struct { 155 + u32 fill_y : 10; 156 + u32 fill_u : 10; 157 + u32 fill_v : 10; 158 + u32 reserve0 : 2; 159 + } reg023_invalid_pixel_fill; 160 + 161 + u32 reg024_026_reserved[3]; 162 + 163 + struct { 164 + u32 reserve0 : 4; 165 + u32 ctu_align_wr_en : 1; 166 + u32 reserve1 : 27; 167 + } reg027_align_en; 168 + 169 + struct { 170 + u32 axi_perf_work_e : 1; 171 + u32 reserve0 : 2; 172 + u32 axi_cnt_type : 1; 173 + u32 rd_latency_id : 8; 174 + u32 reserve1 : 4; 175 + u32 rd_latency_thr : 12; 176 + u32 reserve2 : 4; 177 + } reg028_debug_perf_latency_ctrl0; 178 + 179 + struct { 180 + u32 addr_align_type : 2; 181 + u32 ar_cnt_id_type : 1; 182 + u32 aw_cnt_id_type : 1; 183 + u32 ar_count_id : 8; 184 + u32 reserve0 : 4; 185 + u32 aw_count_id : 8; 186 + u32 rd_band_width_mode : 1; 187 + u32 reserve1 : 7; 188 + } reg029_debug_perf_latency_ctrl1; 189 + 190 + struct { 191 + u32 axi_wr_qos_level : 4; 192 + u32 reserve0 : 4; 193 + u32 axi_wr_qos : 4; 194 + u32 reserve1 : 4; 195 + u32 axi_rd_qos_level : 4; 196 + u32 reserve2 : 4; 197 + u32 axi_rd_qos : 4; 198 + u32 reserve3 : 4; 199 + } reg030_qos_ctrl; 200 + }; 201 + 202 + struct vdpu383_regs_common_addr { 203 + u32 reg128_strm_base; 204 + u32 reg129_rps_base; 205 + u32 reg130_cabactbl_base; 206 + u32 reg131_gbl_base; 207 + u32 reg132_scanlist_addr; 208 + u32 reg133_scale_down_base; 209 + u32 reg134_fgs_base; 210 + u32 reg135_139_reserved[5]; 211 + 212 + struct rcb_info { 213 + u32 offset; 214 + u32 size; 215 + } reg140_162_rcb_info[11]; 216 + }; 217 + 218 + struct vdpu383_regs_h26x_addr { 219 + u32 reg168_decout_base; 220 + u32 reg169_error_ref_base; 221 + u32 reg170_185_ref_base[16]; 222 + u32 reg186_191_reserved[6]; 223 + u32 reg192_payload_st_cur_base; 224 + u32 reg193_fbc_payload_offset; 225 + u32 reg194_payload_st_error_ref_base; 226 + u32 reg195_210_payload_st_ref_base[16]; 227 + u32 reg211_215_reserved[5]; 228 + u32 reg216_colmv_cur_base; 229 + u32 reg217_232_colmv_ref_base[16]; 230 + }; 231 + 232 + struct vdpu383_regs_h26x_params { 233 + u32 reg064_start_decoder; 234 + u32 reg065_strm_start_bit; 235 + u32 reg066_stream_len; 236 + u32 reg067_global_len; 237 + u32 reg068_hor_virstride; 238 + u32 reg069_raster_uv_hor_virstride; 239 + u32 reg070_y_virstride; 240 + u32 reg071_scl_ref_hor_virstride; 241 + u32 reg072_scl_ref_raster_uv_hor_virstride; 242 + u32 reg073_scl_ref_virstride; 243 + u32 reg074_fgs_ref_hor_virstride; 244 + u32 reg075_079_reserved[5]; 245 + u32 reg080_error_ref_hor_virstride; 246 + u32 reg081_error_ref_raster_uv_hor_virstride; 247 + u32 reg082_error_ref_virstride; 248 + u32 reg083_ref0_hor_virstride; 249 + u32 reg084_ref0_raster_uv_hor_virstride; 250 + u32 reg085_ref0_virstride; 251 + u32 reg086_ref1_hor_virstride; 252 + u32 reg087_ref1_raster_uv_hor_virstride; 253 + u32 reg088_ref1_virstride; 254 + u32 reg089_ref2_hor_virstride; 255 + u32 reg090_ref2_raster_uv_hor_virstride; 256 + u32 reg091_ref2_virstride; 257 + u32 reg092_ref3_hor_virstride; 258 + u32 reg093_ref3_raster_uv_hor_virstride; 259 + u32 reg094_ref3_virstride; 260 + u32 reg095_ref4_hor_virstride; 261 + u32 reg096_ref4_raster_uv_hor_virstride; 262 + u32 reg097_ref4_virstride; 263 + u32 reg098_ref5_hor_virstride; 264 + u32 reg099_ref5_raster_uv_hor_virstride; 265 + u32 reg100_ref5_virstride; 266 + u32 reg101_ref6_hor_virstride; 267 + u32 reg102_ref6_raster_uv_hor_virstride; 268 + u32 reg103_ref6_virstride; 269 + u32 reg104_ref7_hor_virstride; 270 + u32 reg105_ref7_raster_uv_hor_virstride; 271 + u32 reg106_ref7_virstride; 272 + }; 273 + 274 + struct vdpu383_regs_h26x { 275 + struct vdpu383_regs_common common; /* 8-30 */ 276 + struct vdpu383_regs_h26x_params h26x_params; /* 64-74, 80-106 */ 277 + struct vdpu383_regs_common_addr common_addr; /* 128-134, 140-161 */ 278 + struct vdpu383_regs_h26x_addr h26x_addr; /* 168-185, 192-210, 216-232 */ 279 + } __packed; 280 + 281 + #endif /* __RKVDEC_VDPU838_REGS_H__ */
+100 -5
drivers/media/platform/rockchip/rkvdec/rkvdec.c
··· 9 9 * Copyright (C) 2011 Samsung Electronics Co., Ltd. 10 10 */ 11 11 12 + #include <linux/hw_bitfield.h> 12 13 #include <linux/clk.h> 13 14 #include <linux/genalloc.h> 14 15 #include <linux/interrupt.h> ··· 31 30 #include "rkvdec.h" 32 31 #include "rkvdec-regs.h" 33 32 #include "rkvdec-vdpu381-regs.h" 33 + #include "rkvdec-vdpu383-regs.h" 34 34 #include "rkvdec-rcb.h" 35 35 36 36 static bool rkvdec_image_fmt_match(enum rkvdec_image_fmt fmt1, ··· 88 86 return false; 89 87 } 90 88 89 + static u32 rkvdec_colmv_size(u16 width, u16 height) 90 + { 91 + return 128 * DIV_ROUND_UP(width, 16) * DIV_ROUND_UP(height, 16); 92 + } 93 + 94 + static u32 vdpu383_colmv_size(u16 width, u16 height) 95 + { 96 + return ALIGN(width, 64) * ALIGN(height, 16); 97 + } 98 + 91 99 static void rkvdec_fill_decoded_pixfmt(struct rkvdec_ctx *ctx, 92 100 struct v4l2_pix_format_mplane *pix_mp) 93 101 { 94 - v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, 95 - pix_mp->width, pix_mp->height); 102 + const struct rkvdec_variant *variant = ctx->dev->variant; 103 + 104 + v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, pix_mp->width, pix_mp->height); 96 105 97 106 ctx->colmv_offset = pix_mp->plane_fmt[0].sizeimage; 98 107 99 - pix_mp->plane_fmt[0].sizeimage += 128 * 100 - DIV_ROUND_UP(pix_mp->width, 16) * 101 - DIV_ROUND_UP(pix_mp->height, 16); 108 + pix_mp->plane_fmt[0].sizeimage += variant->ops->colmv_size(pix_mp->width, pix_mp->height); 102 109 } 103 110 104 111 static void rkvdec_reset_fmt(struct rkvdec_ctx *ctx, struct v4l2_format *f, ··· 457 446 }, 458 447 .ctrls = &vdpu38x_h264_ctrls, 459 448 .ops = &rkvdec_vdpu381_h264_fmt_ops, 449 + .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts), 450 + .decoded_fmts = rkvdec_h264_decoded_fmts, 451 + .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF, 452 + }, 453 + }; 454 + 455 + static const struct rkvdec_coded_fmt_desc vdpu383_coded_fmts[] = { 456 + { 457 + .fourcc = V4L2_PIX_FMT_H264_SLICE, 458 + .frmsize = { 459 + .min_width = 64, 460 + .max_width = 65520, 461 + .step_width = 64, 462 + .min_height = 64, 463 + .max_height = 65520, 464 + .step_height = 16, 465 + }, 466 + .ctrls = &vdpu38x_h264_ctrls, 467 + .ops = &rkvdec_vdpu383_h264_fmt_ops, 460 468 .num_decoded_fmts = ARRAY_SIZE(rkvdec_h264_decoded_fmts), 461 469 .decoded_fmts = rkvdec_h264_decoded_fmts, 462 470 .subsystem_flags = VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF, ··· 1388 1358 return IRQ_HANDLED; 1389 1359 } 1390 1360 1361 + static irqreturn_t vdpu383_irq_handler(struct rkvdec_ctx *ctx) 1362 + { 1363 + struct rkvdec_dev *rkvdec = ctx->dev; 1364 + enum vb2_buffer_state state; 1365 + bool need_reset = 0; 1366 + u32 status; 1367 + 1368 + status = readl(rkvdec->link + VDPU383_LINK_STA_INT); 1369 + writel(FIELD_PREP_WM16(VDPU383_STA_INT_ALL, 0), rkvdec->link + VDPU383_LINK_STA_INT); 1370 + /* On vdpu383, the interrupts must be disabled */ 1371 + writel(FIELD_PREP_WM16(VDPU383_INT_EN_IRQ | VDPU383_INT_EN_LINE_IRQ, 0), 1372 + rkvdec->link + VDPU383_LINK_INT_EN); 1373 + 1374 + if (status & VDPU383_STA_INT_DEC_RDY_STA) { 1375 + state = VB2_BUF_STATE_DONE; 1376 + } else { 1377 + state = VB2_BUF_STATE_ERROR; 1378 + rkvdec_iommu_restore(rkvdec); 1379 + } 1380 + 1381 + if (need_reset) 1382 + rkvdec_iommu_restore(rkvdec); 1383 + 1384 + if (cancel_delayed_work(&rkvdec->watchdog_work)) 1385 + rkvdec_job_finish(ctx, state); 1386 + 1387 + return IRQ_HANDLED; 1388 + } 1389 + 1391 1390 static irqreturn_t rkvdec_irq_handler(int irq, void *priv) 1392 1391 { 1393 1392 struct rkvdec_dev *rkvdec = priv; ··· 1486 1427 1487 1428 static const struct rkvdec_variant_ops rk3399_variant_ops = { 1488 1429 .irq_handler = rk3399_irq_handler, 1430 + .colmv_size = rkvdec_colmv_size, 1489 1431 }; 1490 1432 1491 1433 static const struct rkvdec_variant rk3288_rkvdec_variant = { ··· 1529 1469 1530 1470 static const struct rkvdec_variant_ops vdpu381_variant_ops = { 1531 1471 .irq_handler = vdpu381_irq_handler, 1472 + .colmv_size = rkvdec_colmv_size, 1532 1473 }; 1533 1474 1534 1475 static const struct rkvdec_variant vdpu381_variant = { ··· 1538 1477 .rcb_sizes = vdpu381_rcb_sizes, 1539 1478 .num_rcb_sizes = ARRAY_SIZE(vdpu381_rcb_sizes), 1540 1479 .ops = &vdpu381_variant_ops, 1480 + }; 1481 + 1482 + static const struct rcb_size_info vdpu383_rcb_sizes[] = { 1483 + {6, PIC_WIDTH}, // streamd 1484 + {6, PIC_WIDTH}, // streamd_tile 1485 + {12, PIC_WIDTH}, // inter 1486 + {12, PIC_WIDTH}, // inter_tile 1487 + {16, PIC_WIDTH}, // intra 1488 + {10, PIC_WIDTH}, // intra_tile 1489 + {120, PIC_WIDTH}, // filterd 1490 + {120, PIC_WIDTH}, // filterd_protect 1491 + {120, PIC_WIDTH}, // filterd_tile_row 1492 + {180, PIC_HEIGHT}, // filterd_tile_col 1493 + }; 1494 + 1495 + static const struct rkvdec_variant_ops vdpu383_variant_ops = { 1496 + .irq_handler = vdpu383_irq_handler, 1497 + .colmv_size = vdpu383_colmv_size, 1498 + }; 1499 + 1500 + static const struct rkvdec_variant vdpu383_variant = { 1501 + .coded_fmts = vdpu383_coded_fmts, 1502 + .num_coded_fmts = ARRAY_SIZE(vdpu383_coded_fmts), 1503 + .rcb_sizes = vdpu383_rcb_sizes, 1504 + .num_rcb_sizes = ARRAY_SIZE(vdpu383_rcb_sizes), 1505 + .ops = &vdpu383_variant_ops, 1541 1506 }; 1542 1507 1543 1508 static const struct of_device_id of_rkvdec_match[] = { ··· 1582 1495 { 1583 1496 .compatible = "rockchip,rk3588-vdec", 1584 1497 .data = &vdpu381_variant, 1498 + }, 1499 + { 1500 + .compatible = "rockchip,rk3576-vdec", 1501 + .data = &vdpu383_variant, 1585 1502 }, 1586 1503 { /* sentinel */ } 1587 1504 }; ··· 1630 1539 rkvdec->regs = devm_platform_ioremap_resource_byname(pdev, "function"); 1631 1540 if (IS_ERR(rkvdec->regs)) 1632 1541 return PTR_ERR(rkvdec->regs); 1542 + 1543 + rkvdec->link = devm_platform_ioremap_resource_byname(pdev, "link"); 1544 + if (IS_ERR(rkvdec->link)) 1545 + return PTR_ERR(rkvdec->link); 1633 1546 } 1634 1547 1635 1548 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+5
drivers/media/platform/rockchip/rkvdec/rkvdec.h
··· 73 73 74 74 struct rkvdec_variant_ops { 75 75 irqreturn_t (*irq_handler)(struct rkvdec_ctx *ctx); 76 + u32 (*colmv_size)(u16 width, u16 height); 76 77 }; 77 78 78 79 struct rkvdec_variant { ··· 134 133 unsigned int num_clocks; 135 134 struct clk *axi_clk; 136 135 void __iomem *regs; 136 + void __iomem *link; 137 137 struct mutex vdev_lock; /* serializes ioctls */ 138 138 struct delayed_work watchdog_work; 139 139 struct gen_pool *sram_pool; ··· 187 185 188 186 /* VDPU381 ops */ 189 187 extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu381_h264_fmt_ops; 188 + 189 + /* VDPU383 ops */ 190 + extern const struct rkvdec_coded_fmt_ops rkvdec_vdpu383_h264_fmt_ops; 190 191 191 192 #endif /* RKVDEC_H_ */