// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016 MediaTek Inc. * Author: Jungchang Tsao <[email protected]> * PC Chen <[email protected]> */ #include <linux/slab.h> #include "../vdec_drv_if.h" #include "../mtk_vcodec_dec.h" #include "../../common/mtk_vcodec_intr.h" #include "../vdec_vpu_if.h" #include "../vdec_drv_base.h" /* Decoding picture buffer size (3 reference frames plus current frame) */ #define VP8_DPB_SIZE … /* HW working buffer size (bytes) */ #define VP8_WORKING_BUF_SZ … /* HW control register address */ #define VP8_SEGID_DRAM_ADDR … #define VP8_HW_VLD_ADDR … #define VP8_HW_VLD_VALUE … #define VP8_BSASET … #define VP8_BSDSET … #define VP8_RW_CKEN_SET … #define VP8_RW_DCM_CON … #define VP8_WO_VLD_SRST … #define VP8_RW_MISC_SYS_SEL … #define VP8_RW_MISC_SPEC_CON … #define VP8_WO_VLD_SRST … #define VP8_RW_VP8_CTRL … #define VP8_RW_MISC_DCM_CON … #define VP8_RW_MISC_SRST … #define VP8_RW_MISC_FUNC_CON … #define VP8_MAX_FRM_BUF_NUM … #define VP8_MAX_FRM_BUF_NODE_NUM … /* required buffer size (bytes) to store decode information */ #define VP8_HW_SEGMENT_DATA_SZ … #define VP8_HW_SEGMENT_UINT … #define VP8_DEC_TABLE_PROC_LOOP … #define VP8_DEC_TABLE_UNIT … #define VP8_DEC_TABLE_SZ … #define VP8_DEC_TABLE_OFFSET … #define VP8_DEC_TABLE_RW_UNIT … /** * struct vdec_vp8_dec_info - decode misc information * @working_buf_dma : working buffer dma address * @prev_y_dma : previous decoded frame buffer Y plane address * @cur_y_fb_dma : current plane Y frame buffer dma address * @cur_c_fb_dma : current plane C frame buffer dma address * @bs_dma : bitstream dma address * @bs_sz : bitstream size * @resolution_changed: resolution change flag 1 - changed, 0 - not changed * @show_frame : display this frame or not * @wait_key_frame : wait key frame coming */ struct vdec_vp8_dec_info { … }; /** * struct vdec_vp8_vsi - VPU shared information * @dec : decoding information * @pic : picture information * @dec_table : decoder coefficient table * @segment_buf : segmentation buffer * @load_data : flag to indicate reload decode data */ struct vdec_vp8_vsi { … }; /** * struct vdec_vp8_hw_reg_base - HW register base * @misc : base address for misc * @ld : base address for ld * @top : base address for top * @cm : base address for cm * @hwd : base address for hwd * @hwb : base address for hwb */ struct vdec_vp8_hw_reg_base { … }; /** * struct vdec_vp8_vpu_inst - VPU instance for VP8 decode * @wq_hd : Wait queue to wait VPU message ack * @signaled : 1 - Host has received ack message from VPU, 0 - not received * @failure : VPU execution result status 0 - success, others - fail * @inst_addr : VPU decoder instance address */ struct vdec_vp8_vpu_inst { … }; /* frame buffer (fb) list * [available_fb_node_list] - decode fb are initialized to 0 and populated in * [fb_use_list] - fb is set after decode and is moved to this list * [fb_free_list] - fb is not needed for reference will be moved from * [fb_use_list] to [fb_free_list] and * once user remove fb from [fb_free_list], * it is circulated back to [available_fb_node_list] * [fb_disp_list] - fb is set after decode and is moved to this list * once user remove fb from [fb_disp_list] it is * circulated back to [available_fb_node_list] */ /** * struct vdec_vp8_inst - VP8 decoder instance * @cur_fb : current frame buffer * @dec_fb : decode frame buffer node * @available_fb_node_list : list to store available frame buffer node * @fb_use_list : list to store frame buffer in use * @fb_free_list : list to store free frame buffer * @fb_disp_list : list to store display ready frame buffer * @working_buf : HW decoder working buffer * @reg_base : HW register base address * @frm_cnt : decode frame count * @ctx : V4L2 context * @vpu : VPU instance for decoder * @vsi : VPU share information */ struct vdec_vp8_inst { … }; static void get_hw_reg_base(struct vdec_vp8_inst *inst) { … } static void write_hw_segmentation_data(struct vdec_vp8_inst *inst) { … } static void read_hw_segmentation_data(struct vdec_vp8_inst *inst) { … } /* reset HW and enable HW read/write data function */ static void enable_hw_rw_function(struct vdec_vp8_inst *inst) { … } static void store_dec_table(struct vdec_vp8_inst *inst) { … } static void load_dec_table(struct vdec_vp8_inst *inst) { … } static void get_pic_info(struct vdec_vp8_inst *inst, struct vdec_pic_info *pic) { … } static void vp8_dec_finish(struct vdec_vp8_inst *inst) { … } static void move_fb_list_use_to_free(struct vdec_vp8_inst *inst) { … } static void init_list(struct vdec_vp8_inst *inst) { … } static void add_fb_to_free_list(struct vdec_vp8_inst *inst, void *fb) { … } static int alloc_working_buf(struct vdec_vp8_inst *inst) { … } static void free_working_buf(struct vdec_vp8_inst *inst) { … } static int vdec_vp8_init(struct mtk_vcodec_dec_ctx *ctx) { … } static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs, struct vdec_fb *fb, bool *res_chg) { … } static void get_disp_fb(struct vdec_vp8_inst *inst, struct vdec_fb **out_fb) { … } static void get_free_fb(struct vdec_vp8_inst *inst, struct vdec_fb **out_fb) { … } static void get_crop_info(struct vdec_vp8_inst *inst, struct v4l2_rect *cr) { … } static int vdec_vp8_get_param(void *h_vdec, enum vdec_get_param_type type, void *out) { … } static void vdec_vp8_deinit(void *h_vdec) { … } const struct vdec_common_if vdec_vp8_if = …;